Parse.cpp 445 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282
  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::IsES6DestructuringEnabled() const
  24. {
  25. return m_scriptContext->GetConfig()->IsES6DestructuringEnabled();
  26. }
  27. struct DeferredFunctionStub
  28. {
  29. RestorePoint restorePoint;
  30. uint fncFlags;
  31. uint nestedCount;
  32. DeferredFunctionStub *deferredStubs;
  33. charcount_t ichMin;
  34. };
  35. struct StmtNest
  36. {
  37. union
  38. {
  39. struct
  40. {
  41. ParseNodePtr pnodeStmt; // This statement node.
  42. ParseNodePtr pnodeLab; // Labels for this statement.
  43. };
  44. struct
  45. {
  46. bool isDeferred : 1;
  47. OpCode op; // This statement operation.
  48. LabelId* pLabelId; // Labels for this statement.
  49. };
  50. };
  51. StmtNest *pstmtOuter; // Enclosing statement.
  52. };
  53. struct BlockInfoStack
  54. {
  55. StmtNest pstmt;
  56. ParseNode *pnodeBlock;
  57. ParseNodePtr *m_ppnodeLex; // lexical variable list tail
  58. BlockInfoStack *pBlockInfoOuter; // containing block's BlockInfoStack
  59. BlockInfoStack *pBlockInfoFunction; // nearest function's BlockInfoStack (if pnodeBlock is a function, this points to itself)
  60. };
  61. #if DEBUG
  62. Parser::Parser(Js::ScriptContext* scriptContext, BOOL strictMode, PageAllocator *alloc, bool isBackground, size_t size)
  63. #else
  64. Parser::Parser(Js::ScriptContext* scriptContext, BOOL strictMode, PageAllocator *alloc, bool isBackground)
  65. #endif
  66. : m_nodeAllocator(_u("Parser"), alloc ? alloc : scriptContext->GetThreadContext()->GetPageAllocator(), Parser::OutOfMemory),
  67. // use the GuestArena directly for keeping the RegexPattern* alive during byte code generation
  68. m_registeredRegexPatterns(scriptContext->GetGuestArena())
  69. {
  70. AssertMsg(size == sizeof(Parser), "verify conditionals affecting the size of Parser agree");
  71. Assert(scriptContext != nullptr);
  72. m_isInBackground = isBackground;
  73. m_phtbl = nullptr;
  74. m_pscan = nullptr;
  75. m_deferringAST = FALSE;
  76. m_stoppedDeferredParse = FALSE;
  77. m_hasParallelJob = false;
  78. m_doingFastScan = false;
  79. m_scriptContext = scriptContext;
  80. m_pCurrentAstSize = nullptr;
  81. m_arrayDepth = 0;
  82. m_funcInArrayDepth = 0;
  83. m_parenDepth = 0;
  84. m_funcInArray = 0;
  85. m_tryCatchOrFinallyDepth = 0;
  86. m_UsesArgumentsAtGlobal = false;
  87. m_currentNodeFunc = nullptr;
  88. m_currentNodeDeferredFunc = nullptr;
  89. m_currentNodeNonLambdaFunc = nullptr;
  90. m_currentNodeNonLambdaDeferredFunc = nullptr;
  91. m_currentNodeProg = nullptr;
  92. m_currDeferredStub = nullptr;
  93. m_prevSiblingDeferredStub = nullptr;
  94. m_pstmtCur = nullptr;
  95. m_currentBlockInfo = nullptr;
  96. m_currentScope = nullptr;
  97. m_currentDynamicBlock = nullptr;
  98. m_grfscr = fscrNil;
  99. m_length = 0;
  100. m_originalLength = 0;
  101. m_nextFunctionId = nullptr;
  102. m_errorCallback = nullptr;
  103. m_uncertainStructure = FALSE;
  104. currBackgroundParseItem = nullptr;
  105. backgroundParseItems = nullptr;
  106. fastScannedRegExpNodes = nullptr;
  107. m_fUseStrictMode = strictMode;
  108. m_InAsmMode = false;
  109. m_deferAsmJs = true;
  110. m_scopeCountNoAst = 0;
  111. m_fExpectExternalSource = 0;
  112. m_parseType = ParseType_Upfront;
  113. m_deferEllipsisError = false;
  114. m_hasDeferredShorthandInitError = false;
  115. m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperDisallowed;
  116. }
  117. Parser::~Parser(void)
  118. {
  119. if (m_scriptContext == nullptr || m_scriptContext->GetGuestArena() == nullptr)
  120. {
  121. // If the scriptContext or guestArena have gone away, there is no point clearing each item of this list.
  122. // Just reset it so that destructor of the SList will be no-op
  123. m_registeredRegexPatterns.Reset();
  124. }
  125. if (this->m_hasParallelJob)
  126. {
  127. #if ENABLE_BACKGROUND_PARSING
  128. // Let the background threads know that they can decommit their arena pages.
  129. BackgroundParser *bgp = m_scriptContext->GetBackgroundParser();
  130. Assert(bgp);
  131. if (bgp->Processor()->ProcessesInBackground())
  132. {
  133. JsUtil::BackgroundJobProcessor *processor = static_cast<JsUtil::BackgroundJobProcessor*>(bgp->Processor());
  134. bool result = processor->IterateBackgroundThreads([&](JsUtil::ParallelThreadData *threadData)->bool {
  135. threadData->canDecommit = true;
  136. return false;
  137. });
  138. Assert(result);
  139. }
  140. #endif
  141. }
  142. Release();
  143. }
  144. void Parser::OutOfMemory()
  145. {
  146. throw ParseExceptionObject(ERRnoMemory);
  147. }
  148. void Parser::Error(HRESULT hr)
  149. {
  150. Assert(FAILED(hr));
  151. m_err.Throw(hr);
  152. }
  153. void Parser::Error(HRESULT hr, ParseNodePtr pnode)
  154. {
  155. if (pnode && pnode->ichLim)
  156. {
  157. Error(hr, pnode->ichMin, pnode->ichLim);
  158. }
  159. else
  160. {
  161. Error(hr);
  162. }
  163. }
  164. void Parser::Error(HRESULT hr, charcount_t ichMin, charcount_t ichLim)
  165. {
  166. m_pscan->SetErrorPosition(ichMin, ichLim);
  167. Error(hr);
  168. }
  169. void Parser::IdentifierExpectedError(const Token& token)
  170. {
  171. Assert(token.tk != tkID);
  172. HRESULT hr;
  173. if (token.IsReservedWord())
  174. {
  175. if (token.IsKeyword())
  176. {
  177. hr = ERRKeywordNotId;
  178. }
  179. else
  180. {
  181. Assert(token.IsFutureReservedWord(true));
  182. if (token.IsFutureReservedWord(false))
  183. {
  184. // Future reserved word in strict and non-strict modes
  185. hr = ERRFutureReservedWordNotId;
  186. }
  187. else
  188. {
  189. // Future reserved word only in strict mode. The token would have been converted to tkID by the scanner if not
  190. // in strict mode.
  191. Assert(IsStrictMode());
  192. hr = ERRFutureReservedWordInStrictModeNotId;
  193. }
  194. }
  195. }
  196. else
  197. {
  198. hr = ERRnoIdent;
  199. }
  200. Error(hr);
  201. }
  202. HRESULT Parser::ValidateSyntax(LPCUTF8 pszSrc, size_t encodedCharCount, bool isGenerator, bool isAsync, CompileScriptException *pse, void (Parser::*validateFunction)())
  203. {
  204. AssertPsz(pszSrc);
  205. AssertMemN(pse);
  206. if (this->IsBackgroundParser())
  207. {
  208. PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackDefault);
  209. }
  210. else
  211. {
  212. PROBE_STACK(m_scriptContext, Js::Constants::MinStackDefault);
  213. }
  214. HRESULT hr;
  215. SmartFPUControl smartFpuControl;
  216. DebugOnly( m_err.fInited = TRUE; )
  217. BOOL fDeferSave = m_deferringAST;
  218. try
  219. {
  220. hr = NOERROR;
  221. this->PrepareScanner(false);
  222. m_length = encodedCharCount;
  223. m_originalLength = encodedCharCount;
  224. // make sure deferred parsing is turned off
  225. ULONG grfscr = fscrNil;
  226. // Give the scanner the source and get the first token
  227. m_pscan->SetText(pszSrc, 0, encodedCharCount, 0, grfscr);
  228. m_pscan->SetYieldIsKeyword(isGenerator);
  229. m_pscan->SetAwaitIsKeyword(isAsync);
  230. m_pscan->Scan();
  231. uint nestedCount = 0;
  232. m_pnestedCount = &nestedCount;
  233. ParseNodePtr pnodeScope = nullptr;
  234. m_ppnodeScope = &pnodeScope;
  235. m_ppnodeExprScope = nullptr;
  236. uint nextFunctionId = 0;
  237. m_nextFunctionId = &nextFunctionId;
  238. m_inDeferredNestedFunc = false;
  239. m_deferringAST = true;
  240. m_nextBlockId = 0;
  241. ParseNode *pnodeFnc = CreateNode(knopFncDecl);
  242. pnodeFnc->sxFnc.ClearFlags();
  243. pnodeFnc->sxFnc.SetDeclaration(false);
  244. pnodeFnc->sxFnc.astSize = 0;
  245. pnodeFnc->sxFnc.pnodeVars = nullptr;
  246. pnodeFnc->sxFnc.pnodeParams = nullptr;
  247. pnodeFnc->sxFnc.pnodeBody = nullptr;
  248. pnodeFnc->sxFnc.pnodeName = nullptr;
  249. pnodeFnc->sxFnc.pnodeRest = nullptr;
  250. pnodeFnc->sxFnc.deferredStub = nullptr;
  251. pnodeFnc->sxFnc.SetIsGenerator(isGenerator);
  252. pnodeFnc->sxFnc.SetIsAsync(isAsync);
  253. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  254. m_currentNodeFunc = pnodeFnc;
  255. m_currentNodeDeferredFunc = NULL;
  256. AssertMsg(m_pstmtCur == NULL, "Statement stack should be empty when we start parse function body");
  257. ParseNodePtr block = StartParseBlock<false>(PnodeBlockType::Function, ScopeType_FunctionBody);
  258. (this->*validateFunction)();
  259. FinishParseBlock(block);
  260. pnodeFnc->ichLim = m_pscan->IchLimTok();
  261. pnodeFnc->sxFnc.cbLim = m_pscan->IecpLimTok();
  262. pnodeFnc->sxFnc.pnodeVars = nullptr;
  263. // there should be nothing after successful parsing for a given construct
  264. if (m_token.tk != tkEOF)
  265. Error(ERRsyntax);
  266. RELEASEPTR(m_pscan);
  267. m_deferringAST = fDeferSave;
  268. }
  269. catch(ParseExceptionObject& e)
  270. {
  271. m_deferringAST = fDeferSave;
  272. m_err.m_hr = e.GetError();
  273. hr = pse->ProcessError( m_pscan, m_err.m_hr, /* pnodeBase */ NULL);
  274. }
  275. return hr;
  276. }
  277. HRESULT Parser::ParseSourceInternal(
  278. __out ParseNodePtr* parseTree, LPCUTF8 pszSrc, size_t offsetInBytes, size_t encodedCharCount, charcount_t offsetInChars,
  279. bool fromExternal, ULONG grfscr, CompileScriptException *pse, Js::LocalFunctionId * nextFunctionId, ULONG lineNumber, SourceContextInfo * sourceContextInfo)
  280. {
  281. AssertMem(parseTree);
  282. AssertPsz(pszSrc);
  283. AssertMemN(pse);
  284. double startTime = m_scriptContext->GetThreadContext()->ParserTelemetry.Now();
  285. if (this->IsBackgroundParser())
  286. {
  287. PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackDefault);
  288. }
  289. else
  290. {
  291. PROBE_STACK(m_scriptContext, Js::Constants::MinStackDefault);
  292. }
  293. #ifdef PROFILE_EXEC
  294. m_scriptContext->ProfileBegin(Js::ParsePhase);
  295. #endif
  296. JS_ETW(EventWriteJSCRIPT_PARSE_START(m_scriptContext,0));
  297. *parseTree = NULL;
  298. m_sourceLim = 0;
  299. m_grfscr = grfscr;
  300. m_sourceContextInfo = sourceContextInfo;
  301. ParseNodePtr pnodeBase = NULL;
  302. HRESULT hr;
  303. SmartFPUControl smartFpuControl;
  304. DebugOnly( m_err.fInited = TRUE; )
  305. try
  306. {
  307. this->PrepareScanner(fromExternal);
  308. if ((grfscr & fscrEvalCode) != 0)
  309. {
  310. // This makes the parser to believe when eval() is called, it accept any super access in global scope.
  311. this->m_parsingSuperRestrictionState = Parser::ParsingSuperRestrictionState_SuperCallAndPropertyAllowed;
  312. }
  313. if ((grfscr & fscrIsModuleCode) != 0)
  314. {
  315. // Module source flag should not be enabled unless module is enabled
  316. Assert(m_scriptContext->GetConfig()->IsES6ModuleEnabled());
  317. // Module code is always strict mode code.
  318. this->m_fUseStrictMode = TRUE;
  319. }
  320. // parse the source
  321. pnodeBase = Parse(pszSrc, offsetInBytes, encodedCharCount, offsetInChars, grfscr, lineNumber, nextFunctionId, pse);
  322. AssertNodeMem(pnodeBase);
  323. // Record the actual number of words parsed.
  324. m_sourceLim = pnodeBase->ichLim - offsetInChars;
  325. // TODO: The assert can be false positive in some scenarios and chuckj to fix it later
  326. // Assert(utf8::ByteIndexIntoCharacterIndex(pszSrc + offsetInBytes, encodedCharCount, fromExternal ? utf8::doDefault : utf8::doAllowThreeByteSurrogates) == m_sourceLim);
  327. #if DBG_DUMP
  328. if (Js::Configuration::Global.flags.Trace.IsEnabled(Js::ParsePhase))
  329. {
  330. PrintPnodeWIndent(pnodeBase,4);
  331. fflush(stdout);
  332. }
  333. #endif
  334. *parseTree = pnodeBase;
  335. hr = NOERROR;
  336. }
  337. catch(ParseExceptionObject& e)
  338. {
  339. m_err.m_hr = e.GetError();
  340. hr = pse->ProcessError( m_pscan, m_err.m_hr, pnodeBase);
  341. }
  342. if (this->m_hasParallelJob)
  343. {
  344. #if ENABLE_BACKGROUND_PARSING
  345. ///// Wait here for remaining jobs to finish. Then look for errors, do final const bindings.
  346. // pleath TODO: If there are remaining jobs, let the main thread help finish them.
  347. BackgroundParser *bgp = m_scriptContext->GetBackgroundParser();
  348. Assert(bgp);
  349. CompileScriptException se;
  350. this->WaitForBackgroundJobs(bgp, &se);
  351. BackgroundParseItem *failedItem = bgp->GetFailedBackgroundParseItem();
  352. if (failedItem)
  353. {
  354. CompileScriptException *bgPse = failedItem->GetPSE();
  355. Assert(bgPse);
  356. *pse = *bgPse;
  357. hr = failedItem->GetHR();
  358. bgp->SetFailedBackgroundParseItem(nullptr);
  359. }
  360. if (this->fastScannedRegExpNodes != nullptr)
  361. {
  362. this->FinishBackgroundRegExpNodes();
  363. }
  364. for (BackgroundParseItem *item = this->backgroundParseItems; item; item = item->GetNext())
  365. {
  366. Parser *parser = item->GetParser();
  367. parser->FinishBackgroundPidRefs(item, this != parser);
  368. }
  369. #endif
  370. }
  371. // done with the scanner
  372. RELEASEPTR(m_pscan);
  373. #ifdef PROFILE_EXEC
  374. m_scriptContext->ProfileEnd(Js::ParsePhase);
  375. #endif
  376. JS_ETW(EventWriteJSCRIPT_PARSE_STOP(m_scriptContext, 0));
  377. ThreadContext *threadContext = m_scriptContext->GetThreadContext();
  378. threadContext->ParserTelemetry.LogTime(threadContext->ParserTelemetry.Now() - startTime);
  379. return hr;
  380. }
  381. #if ENABLE_BACKGROUND_PARSING
  382. void Parser::WaitForBackgroundJobs(BackgroundParser *bgp, CompileScriptException *pse)
  383. {
  384. // The scan of the script is done, but there may be unfinished background jobs in the queue.
  385. // Enlist the main thread to help with those.
  386. BackgroundParseItem *item;
  387. if (!*bgp->GetPendingBackgroundItemsPtr())
  388. {
  389. // We're done.
  390. return;
  391. }
  392. // Save parser state, since we'll need to restore it in order to bind references correctly later.
  393. this->m_isInBackground = true;
  394. this->SetCurrBackgroundParseItem(nullptr);
  395. uint blockIdSave = this->m_nextBlockId;
  396. uint functionIdSave = *this->m_nextFunctionId;
  397. StmtNest *pstmtSave = this->m_pstmtCur;
  398. if (!bgp->Processor()->ProcessesInBackground())
  399. {
  400. // No background thread. Just walk the jobs with no locking and process them.
  401. for (item = bgp->GetNextUnprocessedItem(); item; item = bgp->GetNextUnprocessedItem())
  402. {
  403. bgp->Processor()->RemoveJob(item);
  404. bool succeeded = bgp->Process(item, this, pse);
  405. bgp->JobProcessed(item, succeeded);
  406. }
  407. Assert(!*bgp->GetPendingBackgroundItemsPtr());
  408. }
  409. else
  410. {
  411. // Background threads. We need to have the critical section in order to:
  412. // - Check for unprocessed jobs;
  413. // - Remove jobs from the processor queue;
  414. // - Do JobsProcessed work (such as removing jobs from the BackgroundParser's unprocessed list).
  415. CriticalSection *pcs = static_cast<JsUtil::BackgroundJobProcessor*>(bgp->Processor())->GetCriticalSection();
  416. pcs->Enter();
  417. for (;;)
  418. {
  419. // Grab a job (in lock)
  420. item = bgp->GetNextUnprocessedItem();
  421. if (item == nullptr)
  422. {
  423. break;
  424. }
  425. bgp->Processor()->RemoveJob(item);
  426. pcs->Leave();
  427. // Process job (if there is one) (outside lock)
  428. bool succeeded = bgp->Process(item, this, pse);
  429. pcs->Enter();
  430. bgp->JobProcessed(item, succeeded);
  431. }
  432. pcs->Leave();
  433. // Wait for the background threads to finish jobs they're already processing (if any).
  434. // TODO: Replace with a proper semaphore.
  435. while(*bgp->GetPendingBackgroundItemsPtr());
  436. }
  437. Assert(!*bgp->GetPendingBackgroundItemsPtr());
  438. // Restore parser state.
  439. this->m_pstmtCur = pstmtSave;
  440. this->m_isInBackground = false;
  441. this->m_nextBlockId = blockIdSave;
  442. *this->m_nextFunctionId = functionIdSave;
  443. }
  444. void Parser::FinishBackgroundPidRefs(BackgroundParseItem *item, bool isOtherParser)
  445. {
  446. for (BlockInfoStack *blockInfo = item->GetParseContext()->currentBlockInfo; blockInfo; blockInfo = blockInfo->pBlockInfoOuter)
  447. {
  448. if (isOtherParser)
  449. {
  450. this->BindPidRefs<true>(blockInfo, item->GetMaxBlockId());
  451. }
  452. else
  453. {
  454. this->BindPidRefs<false>(blockInfo, item->GetMaxBlockId());
  455. }
  456. }
  457. }
  458. void Parser::FinishBackgroundRegExpNodes()
  459. {
  460. // We have a list of RegExp nodes that we saw on the UI thread in functions we're parallel parsing,
  461. // and for each background job we have a list of RegExp nodes for which we couldn't allocate patterns.
  462. // We need to copy the pattern pointers from the UI thread nodes to the corresponding nodes on the
  463. // background nodes.
  464. // There may be UI thread nodes for which there are no background thread equivalents, because the UI thread
  465. // has to assume that the background thread won't defer anything.
  466. // Note that because these lists (and the list of background jobs) are SList's built by prepending, they are
  467. // all in reverse lexical order.
  468. Assert(!this->IsBackgroundParser());
  469. Assert(this->fastScannedRegExpNodes);
  470. Assert(this->backgroundParseItems != nullptr);
  471. BackgroundParseItem *currBackgroundItem;
  472. #if DBG
  473. for (currBackgroundItem = this->backgroundParseItems;
  474. currBackgroundItem;
  475. currBackgroundItem = currBackgroundItem->GetNext())
  476. {
  477. if (currBackgroundItem->RegExpNodeList())
  478. {
  479. FOREACH_DLIST_ENTRY(ParseNodePtr, ArenaAllocator, pnode, currBackgroundItem->RegExpNodeList())
  480. {
  481. Assert(pnode->sxPid.regexPattern == nullptr);
  482. }
  483. NEXT_DLIST_ENTRY;
  484. }
  485. }
  486. #endif
  487. // Hook up the patterns allocated on the main thread to the nodes created on the background thread.
  488. // Walk the list of foreground nodes, advancing through the work items and looking up each item.
  489. // Note that the background thread may have chosen to defer a given RegEx literal, so not every foreground
  490. // node will have a matching background node. Doesn't matter for correctness.
  491. // (It's inefficient, of course, to have to restart the inner loop from the beginning of the work item's
  492. // list, but it should be unusual to have many RegExes in a single work item's chunk of code. Figure out how
  493. // to start the inner loop from a known internal node within the list if that turns out to be important.)
  494. currBackgroundItem = this->backgroundParseItems;
  495. FOREACH_DLIST_ENTRY(ParseNodePtr, ArenaAllocator, pnodeFgnd, this->fastScannedRegExpNodes)
  496. {
  497. Assert(pnodeFgnd->nop == knopRegExp);
  498. Assert(pnodeFgnd->sxPid.regexPattern != nullptr);
  499. bool quit = false;
  500. while (!quit)
  501. {
  502. // Find the next work item with a RegEx in it.
  503. while (currBackgroundItem && currBackgroundItem->RegExpNodeList() == nullptr)
  504. {
  505. currBackgroundItem = currBackgroundItem->GetNext();
  506. }
  507. if (!currBackgroundItem)
  508. {
  509. break;
  510. }
  511. // Walk the RegExps in the work item.
  512. FOREACH_DLIST_ENTRY(ParseNodePtr, ArenaAllocator, pnodeBgnd, currBackgroundItem->RegExpNodeList())
  513. {
  514. Assert(pnodeBgnd->nop == knopRegExp);
  515. if (pnodeFgnd->ichMin <= pnodeBgnd->ichMin)
  516. {
  517. // Either we found a match, or the next background node is past the foreground node.
  518. // In any case, we can stop searching.
  519. if (pnodeFgnd->ichMin == pnodeBgnd->ichMin)
  520. {
  521. Assert(pnodeFgnd->ichLim == pnodeBgnd->ichLim);
  522. pnodeBgnd->sxPid.regexPattern = pnodeFgnd->sxPid.regexPattern;
  523. }
  524. quit = true;
  525. break;
  526. }
  527. }
  528. NEXT_DLIST_ENTRY;
  529. if (!quit)
  530. {
  531. // Need to advance to the next work item.
  532. currBackgroundItem = currBackgroundItem->GetNext();
  533. }
  534. }
  535. }
  536. NEXT_DLIST_ENTRY;
  537. #if DBG
  538. for (currBackgroundItem = this->backgroundParseItems;
  539. currBackgroundItem;
  540. currBackgroundItem = currBackgroundItem->GetNext())
  541. {
  542. if (currBackgroundItem->RegExpNodeList())
  543. {
  544. FOREACH_DLIST_ENTRY(ParseNodePtr, ArenaAllocator, pnode, currBackgroundItem->RegExpNodeList())
  545. {
  546. Assert(pnode->sxPid.regexPattern != nullptr);
  547. }
  548. NEXT_DLIST_ENTRY;
  549. }
  550. }
  551. #endif
  552. }
  553. #endif
  554. LabelId* Parser::CreateLabelId(IdentToken* pToken)
  555. {
  556. LabelId* pLabelId;
  557. pLabelId = (LabelId*)m_nodeAllocator.Alloc(sizeof(LabelId));
  558. if (NULL == pLabelId)
  559. Error(ERRnoMemory);
  560. pLabelId->pid = pToken->pid;
  561. pLabelId->next = NULL;
  562. return pLabelId;
  563. }
  564. /*****************************************************************************
  565. The following set of routines allocate parse tree nodes of various kinds.
  566. They catch an exception on out of memory.
  567. *****************************************************************************/
  568. static const int g_mpnopcbNode[] =
  569. {
  570. #define PTNODE(nop,sn,pc,nk,ok,json) kcbPn##nk,
  571. #include "ptlist.h"
  572. };
  573. const Js::RegSlot NoRegister = (Js::RegSlot)-1;
  574. const Js::RegSlot OneByteRegister = (Js::RegSlot_OneByte)-1;
  575. void Parser::InitNode(OpCode nop,ParseNodePtr pnode) {
  576. pnode->nop = nop;
  577. pnode->grfpn = PNodeFlags::fpnNone;
  578. pnode->location = NoRegister;
  579. pnode->emitLabels = false;
  580. pnode->isUsed = true;
  581. pnode->notEscapedUse = false;
  582. pnode->isInList = false;
  583. pnode->isCallApplyTargetLoad = false;
  584. }
  585. // Create nodes using Arena
  586. template <OpCode nop>
  587. ParseNodePtr Parser::StaticCreateNodeT(ArenaAllocator* alloc, charcount_t ichMin, charcount_t ichLim)
  588. {
  589. ParseNodePtr pnode = StaticAllocNode<nop>(alloc);
  590. InitNode(nop,pnode);
  591. // default - may be changed
  592. pnode->ichMin = ichMin;
  593. pnode->ichLim = ichLim;
  594. return pnode;
  595. }
  596. ParseNodePtr
  597. Parser::StaticCreateBlockNode(ArenaAllocator* alloc, charcount_t ichMin , charcount_t ichLim, int blockId, PnodeBlockType blockType)
  598. {
  599. ParseNodePtr pnode = StaticCreateNodeT<knopBlock>(alloc, ichMin, ichLim);
  600. InitBlockNode(pnode, blockId, blockType);
  601. return pnode;
  602. }
  603. void Parser::InitBlockNode(ParseNodePtr pnode, int blockId, PnodeBlockType blockType)
  604. {
  605. Assert(pnode->nop == knopBlock);
  606. pnode->sxBlock.pnodeScopes = nullptr;
  607. pnode->sxBlock.pnodeNext = nullptr;
  608. pnode->sxBlock.scope = nullptr;
  609. pnode->sxBlock.enclosingBlock = nullptr;
  610. pnode->sxBlock.pnodeLexVars = nullptr;
  611. pnode->sxBlock.pnodeStmt = nullptr;
  612. pnode->sxBlock.pnodeLastValStmt = nullptr;
  613. pnode->sxBlock.callsEval = false;
  614. pnode->sxBlock.childCallsEval = false;
  615. pnode->sxBlock.blockType = blockType;
  616. pnode->sxBlock.blockId = blockId;
  617. if (blockType != PnodeBlockType::Regular)
  618. {
  619. pnode->grfpn |= PNodeFlags::fpnSyntheticNode;
  620. }
  621. }
  622. // Create Node with limit
  623. template <OpCode nop>
  624. ParseNodePtr Parser::CreateNodeT(charcount_t ichMin,charcount_t ichLim)
  625. {
  626. Assert(!this->m_deferringAST);
  627. ParseNodePtr pnode = StaticCreateNodeT<nop>(&m_nodeAllocator, ichMin, ichLim);
  628. Assert(m_pCurrentAstSize != NULL);
  629. *m_pCurrentAstSize += GetNodeSize<nop>();
  630. return pnode;
  631. }
  632. ParseNodePtr Parser::CreateDeclNode(OpCode nop, IdentPtr pid, SymbolType symbolType, bool errorOnRedecl)
  633. {
  634. ParseNodePtr pnode = CreateNode(nop);
  635. pnode->sxVar.InitDeclNode(pid, NULL);
  636. if (symbolType != STUnknown)
  637. {
  638. pnode->sxVar.sym = AddDeclForPid(pnode, pid, symbolType, errorOnRedecl);
  639. }
  640. return pnode;
  641. }
  642. Symbol* Parser::AddDeclForPid(ParseNodePtr pnode, IdentPtr pid, SymbolType symbolType, bool errorOnRedecl)
  643. {
  644. Assert(pnode->IsVarLetOrConst());
  645. PidRefStack *refForUse = nullptr, *refForDecl = nullptr;
  646. BlockInfoStack *blockInfo;
  647. bool fBlockScope = false;
  648. if (pnode->nop != knopVarDecl || symbolType == STFunction)
  649. {
  650. Assert(m_pstmtCur);
  651. if (m_pstmtCur->isDeferred)
  652. {
  653. // Deferred parsing: there's no pnodeStmt node, only an opcode on the Stmt struct.
  654. if (m_pstmtCur->op != knopBlock)
  655. {
  656. // Let/const declared in a bare statement context.
  657. Error(ERRDeclOutOfStmt);
  658. }
  659. if (m_pstmtCur->pstmtOuter && m_pstmtCur->pstmtOuter->op == knopSwitch)
  660. {
  661. // Let/const declared inside a switch block (requiring conservative use-before-decl check).
  662. pnode->sxVar.isSwitchStmtDecl = true;
  663. }
  664. }
  665. else
  666. {
  667. if (m_pstmtCur->pnodeStmt->nop != knopBlock)
  668. {
  669. // Let/const declared in a bare statement context.
  670. Error(ERRDeclOutOfStmt);
  671. }
  672. if (m_pstmtCur->pstmtOuter && m_pstmtCur->pstmtOuter->pnodeStmt->nop == knopSwitch)
  673. {
  674. // Let/const declared inside a switch block (requiring conservative use-before-decl check).
  675. pnode->sxVar.isSwitchStmtDecl = true;
  676. }
  677. }
  678. fBlockScope = pnode->nop != knopVarDecl ||
  679. (
  680. !GetCurrentBlockInfo()->pnodeBlock->sxBlock.scope ||
  681. GetCurrentBlockInfo()->pnodeBlock->sxBlock.scope->GetScopeType() != ScopeType_GlobalEvalBlock
  682. );
  683. }
  684. if (fBlockScope)
  685. {
  686. blockInfo = GetCurrentBlockInfo();
  687. }
  688. else
  689. {
  690. blockInfo = GetCurrentFunctionBlockInfo();
  691. }
  692. // If we are creating an 'arguments' Sym at function block scope, create it in
  693. // the parameter scope instead. That way, if we need to reuse the Sym for the
  694. // actual arguments object at the end of the function, we don't need to move it
  695. // into the parameter scope.
  696. if (pid == wellKnownPropertyPids.arguments
  697. && pnode->nop == knopVarDecl
  698. && blockInfo->pnodeBlock->sxBlock.blockType == PnodeBlockType::Function
  699. && blockInfo->pBlockInfoOuter != nullptr
  700. && blockInfo->pBlockInfoOuter->pnodeBlock->sxBlock.blockType == PnodeBlockType::Parameter
  701. && blockInfo->pnodeBlock->sxBlock.scope->GetScopeType() != ScopeType_FuncExpr
  702. && blockInfo->pBlockInfoOuter->pnodeBlock->sxBlock.scope->GetCanMergeWithBodyScope())
  703. {
  704. blockInfo = blockInfo->pBlockInfoOuter;
  705. }
  706. refForDecl = this->FindOrAddPidRef(pid, blockInfo->pnodeBlock->sxBlock.blockId);
  707. if (refForDecl == nullptr)
  708. {
  709. Error(ERRnoMemory);
  710. }
  711. if (blockInfo == GetCurrentBlockInfo())
  712. {
  713. refForUse = refForDecl;
  714. }
  715. else
  716. {
  717. refForUse = this->PushPidRef(pid);
  718. }
  719. pnode->sxVar.symRef = refForUse->GetSymRef();
  720. Symbol *sym = refForDecl->GetSym();
  721. if (sym != nullptr)
  722. {
  723. // Multiple declarations in the same scope. 3 possibilities: error, existing one wins, new one wins.
  724. switch (pnode->nop)
  725. {
  726. case knopLetDecl:
  727. case knopConstDecl:
  728. if (!sym->GetDecl()->sxVar.isBlockScopeFncDeclVar)
  729. {
  730. Assert(errorOnRedecl);
  731. // Redeclaration error.
  732. Error(ERRRedeclaration);
  733. }
  734. else
  735. {
  736. // (New) let/const hides the (old) var
  737. sym->SetSymbolType(symbolType);
  738. sym->SetDecl(pnode);
  739. }
  740. break;
  741. case knopVarDecl:
  742. if (m_currentScope->GetScopeType() == ScopeType_Parameter)
  743. {
  744. // If this is a parameter list, mark the scope to indicate that it has duplicate definition.
  745. // 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.
  746. m_currentScope->SetHasDuplicateFormals();
  747. }
  748. if (sym->GetDecl() == nullptr)
  749. {
  750. Assert(symbolType == STFunction);
  751. sym->SetDecl(pnode);
  752. break;
  753. }
  754. switch (sym->GetDecl()->nop)
  755. {
  756. case knopLetDecl:
  757. case knopConstDecl:
  758. // Destructuring made possible to have the formals to be the let bind. But that shouldn't throw the error.
  759. if (errorOnRedecl && (!IsES6DestructuringEnabled() || sym->GetSymbolType() != STFormal))
  760. {
  761. Error(ERRRedeclaration);
  762. }
  763. // If !errorOnRedecl, (old) let/const hides the (new) var, so do nothing.
  764. break;
  765. case knopVarDecl:
  766. // Legal redeclaration. Who wins?
  767. if (errorOnRedecl || sym->GetDecl()->sxVar.isBlockScopeFncDeclVar)
  768. {
  769. if (symbolType == STFormal ||
  770. (symbolType == STFunction && sym->GetSymbolType() != STFormal) ||
  771. sym->GetSymbolType() == STVariable)
  772. {
  773. // New decl wins.
  774. sym->SetSymbolType(symbolType);
  775. sym->SetDecl(pnode);
  776. }
  777. }
  778. break;
  779. }
  780. break;
  781. }
  782. }
  783. else
  784. {
  785. Scope *scope = blockInfo->pnodeBlock->sxBlock.scope;
  786. if (scope == nullptr)
  787. {
  788. Assert(blockInfo->pnodeBlock->sxBlock.blockType == PnodeBlockType::Regular);
  789. scope = Anew(&m_nodeAllocator, Scope, &m_nodeAllocator, ScopeType_Block);
  790. blockInfo->pnodeBlock->sxBlock.scope = scope;
  791. PushScope(scope);
  792. }
  793. if (scope->GetScopeType() == ScopeType_GlobalEvalBlock)
  794. {
  795. Assert(fBlockScope);
  796. Assert(scope->GetEnclosingScope() == m_currentNodeProg->sxProg.scope);
  797. // Check for same-named decl in Global scope.
  798. PidRefStack *pidRefOld = pid->GetPidRefForScopeId(0);
  799. if (pidRefOld && pidRefOld->GetSym())
  800. {
  801. Error(ERRRedeclaration);
  802. }
  803. }
  804. else if (scope->GetScopeType() == ScopeType_Global && (this->m_grfscr & fscrEvalCode) &&
  805. !(m_functionBody && m_functionBody->GetScopeInfo()))
  806. {
  807. // Check for same-named decl in GlobalEvalBlock scope. Note that this is not necessary
  808. // if we're compiling a deferred nested function and the global scope was restored from cached info,
  809. // because in that case we don't need a GlobalEvalScope.
  810. Assert(!fBlockScope || (this->m_grfscr & fscrConsoleScopeEval) == fscrConsoleScopeEval);
  811. PidRefStack *pidRefOld = pid->GetPidRefForScopeId(1);
  812. if (pidRefOld && pidRefOld->GetSym())
  813. {
  814. Error(ERRRedeclaration);
  815. }
  816. }
  817. if ((scope->GetScopeType() == ScopeType_FunctionBody || scope->GetScopeType() == ScopeType_Parameter) && symbolType != STFunction)
  818. {
  819. ParseNodePtr pnodeFnc = GetCurrentFunctionNode();
  820. AnalysisAssert(pnodeFnc);
  821. if (pnodeFnc->sxFnc.pnodeName &&
  822. pnodeFnc->sxFnc.pnodeName->nop == knopVarDecl &&
  823. pnodeFnc->sxFnc.pnodeName->sxVar.pid == pid)
  824. {
  825. // Named function expression has its name hidden by a local declaration.
  826. // This is important to know if we don't know whether nested deferred functions refer to it,
  827. // because if the name has a non-local reference then we have to create a scope object.
  828. m_currentNodeFunc->sxFnc.SetNameIsHidden();
  829. }
  830. }
  831. if (!sym)
  832. {
  833. const char16 *name = reinterpret_cast<const char16*>(pid->Psz());
  834. int nameLength = pid->Cch();
  835. SymbolName const symName(name, nameLength);
  836. Assert(!scope->FindLocalSymbol(symName));
  837. sym = Anew(&m_nodeAllocator, Symbol, symName, pnode, symbolType);
  838. scope->AddNewSymbol(sym);
  839. sym->SetPid(pid);
  840. }
  841. refForDecl->SetSym(sym);
  842. }
  843. return sym;
  844. }
  845. void Parser::RestorePidRefForSym(Symbol *sym)
  846. {
  847. IdentPtr pid = m_pscan->m_phtbl->PidHashNameLen(sym->GetName().GetBuffer(), sym->GetName().GetLength());
  848. Assert(pid);
  849. sym->SetPid(pid);
  850. PidRefStack *ref = this->PushPidRef(pid);
  851. ref->SetSym(sym);
  852. }
  853. IdentPtr Parser::GenerateIdentPtr(__ecount(len) char16* name, long len)
  854. {
  855. return m_phtbl->PidHashNameLen(name,len);
  856. }
  857. IdentPtr Parser::PidFromNode(ParseNodePtr pnode)
  858. {
  859. for (;;)
  860. {
  861. switch (pnode->nop)
  862. {
  863. case knopName:
  864. return pnode->sxPid.pid;
  865. case knopVarDecl:
  866. return pnode->sxVar.pid;
  867. case knopDot:
  868. Assert(pnode->sxBin.pnode2->nop == knopName);
  869. return pnode->sxBin.pnode2->sxPid.pid;
  870. case knopComma:
  871. // Advance to the RHS and iterate.
  872. pnode = pnode->sxBin.pnode2;
  873. break;
  874. default:
  875. return nullptr;
  876. }
  877. }
  878. }
  879. #if DBG
  880. void VerifyNodeSize(OpCode nop, int size)
  881. {
  882. Assert(nop >= 0 && nop < knopLim);
  883. __analysis_assume(nop < knopLim);
  884. Assert(g_mpnopcbNode[nop] == size);
  885. }
  886. #endif
  887. ParseNodePtr Parser::StaticCreateBinNode(OpCode nop, ParseNodePtr pnode1,
  888. ParseNodePtr pnode2,ArenaAllocator* alloc)
  889. {
  890. DebugOnly(VerifyNodeSize(nop, kcbPnBin));
  891. ParseNodePtr pnode = (ParseNodePtr)alloc->Alloc(kcbPnBin);
  892. InitNode(nop, pnode);
  893. pnode->sxBin.pnodeNext = nullptr;
  894. pnode->sxBin.pnode1 = pnode1;
  895. pnode->sxBin.pnode2 = pnode2;
  896. // Statically detect if the add is a concat
  897. if (!PHASE_OFF1(Js::ByteCodeConcatExprOptPhase))
  898. {
  899. // We can't flatten the concat expression if the LHS is not a flatten concat already
  900. // e.g. a + (<str> + b)
  901. // Side effect of ToStr(b) need to happen first before ToStr(a)
  902. // If we flatten the concat expression, we will do ToStr(a) before ToStr(b)
  903. if ((nop == knopAdd) && (pnode1->CanFlattenConcatExpr() || pnode2->nop == knopStr))
  904. {
  905. pnode->grfpn |= fpnCanFlattenConcatExpr;
  906. }
  907. }
  908. return pnode;
  909. }
  910. // Create nodes using parser allocator
  911. ParseNodePtr Parser::CreateNode(OpCode nop, charcount_t ichMin)
  912. {
  913. bool nodeAllowed = IsNodeAllowedForDeferParse(nop);
  914. Assert(nodeAllowed);
  915. Assert(nop >= 0 && nop < knopLim);
  916. ParseNodePtr pnode;
  917. int cb = (nop >= knopNone && nop < knopLim) ? g_mpnopcbNode[nop] : g_mpnopcbNode[knopEmpty];
  918. pnode = (ParseNodePtr)m_nodeAllocator.Alloc(cb);
  919. Assert(pnode != nullptr);
  920. if (!m_deferringAST)
  921. {
  922. Assert(m_pCurrentAstSize != nullptr);
  923. *m_pCurrentAstSize += cb;
  924. }
  925. InitNode(nop,pnode);
  926. // default - may be changed
  927. pnode->ichMin = ichMin;
  928. if (m_pscan!= nullptr) {
  929. pnode->ichLim = m_pscan->IchLimTok();
  930. }
  931. else pnode->ichLim=0;
  932. return pnode;
  933. }
  934. ParseNodePtr Parser::CreateUniNode(OpCode nop, ParseNodePtr pnode1)
  935. {
  936. Assert(!this->m_deferringAST);
  937. DebugOnly(VerifyNodeSize(nop, kcbPnUni));
  938. ParseNodePtr pnode = (ParseNodePtr)m_nodeAllocator.Alloc(kcbPnUni);
  939. Assert(m_pCurrentAstSize != nullptr);
  940. *m_pCurrentAstSize += kcbPnUni;
  941. InitNode(nop, pnode);
  942. pnode->sxUni.pnode1 = pnode1;
  943. if (nullptr == pnode1)
  944. {
  945. // no ops
  946. pnode->ichMin = m_pscan->IchMinTok();
  947. pnode->ichLim = m_pscan->IchLimTok();
  948. }
  949. else
  950. {
  951. // 1 op
  952. pnode->ichMin = pnode1->ichMin;
  953. pnode->ichLim = pnode1->ichLim;
  954. this->CheckArguments(pnode);
  955. }
  956. return pnode;
  957. }
  958. ParseNodePtr Parser::CreateBinNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2)
  959. {
  960. Assert(!this->m_deferringAST);
  961. charcount_t ichMin;
  962. charcount_t ichLim;
  963. if (nullptr == pnode1)
  964. {
  965. // no ops
  966. Assert(nullptr == pnode2);
  967. ichMin = m_pscan->IchMinTok();
  968. ichLim = m_pscan->IchLimTok();
  969. }
  970. else
  971. {
  972. if (nullptr == pnode2)
  973. {
  974. // 1 op
  975. ichMin = pnode1->ichMin;
  976. ichLim = pnode1->ichLim;
  977. }
  978. else
  979. {
  980. // 2 ops
  981. ichMin = pnode1->ichMin;
  982. ichLim = pnode2->ichLim;
  983. if (nop != knopDot && nop != knopIndex)
  984. {
  985. this->CheckArguments(pnode2);
  986. }
  987. }
  988. if (nop != knopDot && nop != knopIndex)
  989. {
  990. this->CheckArguments(pnode1);
  991. }
  992. }
  993. return CreateBinNode(nop, pnode1, pnode2, ichMin, ichLim);
  994. }
  995. ParseNodePtr Parser::CreateTriNode(OpCode nop, ParseNodePtr pnode1,
  996. ParseNodePtr pnode2, ParseNodePtr pnode3)
  997. {
  998. charcount_t ichMin;
  999. charcount_t ichLim;
  1000. if (nullptr == pnode1)
  1001. {
  1002. // no ops
  1003. Assert(nullptr == pnode2);
  1004. Assert(nullptr == pnode3);
  1005. ichMin = m_pscan->IchMinTok();
  1006. ichLim = m_pscan->IchLimTok();
  1007. }
  1008. else if (nullptr == pnode2)
  1009. {
  1010. // 1 op
  1011. Assert(nullptr == pnode3);
  1012. ichMin = pnode1->ichMin;
  1013. ichLim = pnode1->ichLim;
  1014. }
  1015. else if (nullptr == pnode3)
  1016. {
  1017. // 2 op
  1018. ichMin = pnode1->ichMin;
  1019. ichLim = pnode2->ichLim;
  1020. }
  1021. else
  1022. {
  1023. // 3 ops
  1024. ichMin = pnode1->ichMin;
  1025. ichLim = pnode3->ichLim;
  1026. }
  1027. return CreateTriNode(nop, pnode1, pnode2, pnode3, ichMin, ichLim);
  1028. }
  1029. ParseNodePtr Parser::CreateBlockNode(charcount_t ichMin,charcount_t ichLim, PnodeBlockType blockType)
  1030. {
  1031. return StaticCreateBlockNode(&m_nodeAllocator, ichMin, ichLim, this->m_nextBlockId++, blockType);
  1032. }
  1033. ParseNodePtr
  1034. Parser::CreateCallNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2,charcount_t ichMin,charcount_t ichLim)
  1035. {
  1036. Assert(!this->m_deferringAST);
  1037. DebugOnly(VerifyNodeSize(nop, kcbPnCall));
  1038. ParseNodePtr pnode = (ParseNodePtr)m_nodeAllocator.Alloc(kcbPnCall);
  1039. Assert(m_pCurrentAstSize != nullptr);
  1040. *m_pCurrentAstSize += kcbPnCall;
  1041. InitNode(nop, pnode);
  1042. pnode->sxCall.pnodeTarget = pnode1;
  1043. pnode->sxCall.pnodeArgs = pnode2;
  1044. pnode->sxCall.argCount = 0;
  1045. pnode->sxCall.spreadArgCount = 0;
  1046. pnode->sxCall.callOfConstants = false;
  1047. pnode->sxCall.isApplyCall = false;
  1048. pnode->sxCall.isEvalCall = false;
  1049. pnode->ichMin = ichMin;
  1050. pnode->ichLim = ichLim;
  1051. return pnode;
  1052. }
  1053. ParseNodePtr Parser::CreateStrNode(IdentPtr pid)
  1054. {
  1055. Assert(!this->m_deferringAST);
  1056. ParseNodePtr pnode = CreateNode(knopStr);
  1057. pnode->sxPid.pid=pid;
  1058. pnode->grfpn |= PNodeFlags::fpnCanFlattenConcatExpr;
  1059. return pnode;
  1060. }
  1061. ParseNodePtr Parser::CreateIntNode(long lw)
  1062. {
  1063. ParseNodePtr pnode = CreateNode(knopInt);
  1064. pnode->sxInt.lw = lw;
  1065. return pnode;
  1066. }
  1067. // Create Node with scanner limit
  1068. template <OpCode nop>
  1069. ParseNodePtr Parser::CreateNodeWithScanner()
  1070. {
  1071. Assert(m_pscan != nullptr);
  1072. return CreateNodeWithScanner<nop>(m_pscan->IchMinTok());
  1073. }
  1074. template <OpCode nop>
  1075. ParseNodePtr Parser::CreateNodeWithScanner(charcount_t ichMin)
  1076. {
  1077. Assert(m_pscan != nullptr);
  1078. return CreateNodeT<nop>(ichMin, m_pscan->IchLimTok());
  1079. }
  1080. ParseNodePtr Parser::CreateProgNodeWithScanner(bool isModuleSource)
  1081. {
  1082. ParseNodePtr pnodeProg;
  1083. if (isModuleSource)
  1084. {
  1085. pnodeProg = CreateNodeWithScanner<knopModule>();
  1086. // knopModule is not actually handled anywhere since we would need to handle it everywhere we could
  1087. // have knopProg and it would be treated exactly the same except for import/export statements.
  1088. // We are only using it as a way to get the correct size for PnModule.
  1089. // Consider: Should we add a flag to PnProg which is false but set to true in PnModule?
  1090. // If we do, it can't be a virtual method since the parse nodes are all in a union.
  1091. pnodeProg->nop = knopProg;
  1092. }
  1093. else
  1094. {
  1095. pnodeProg = CreateNodeWithScanner<knopProg>();
  1096. }
  1097. return pnodeProg;
  1098. }
  1099. ParseNodePtr Parser::CreateCallNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2)
  1100. {
  1101. charcount_t ichMin;
  1102. charcount_t ichLim;
  1103. if (nullptr == pnode1)
  1104. {
  1105. Assert(nullptr == pnode2);
  1106. ichMin = m_pscan->IchMinTok();
  1107. ichLim = m_pscan->IchLimTok();
  1108. }
  1109. else
  1110. {
  1111. if (nullptr == pnode2)
  1112. {
  1113. ichMin = pnode1->ichMin;
  1114. ichLim = pnode1->ichLim;
  1115. }
  1116. else
  1117. {
  1118. ichMin = pnode1->ichMin;
  1119. ichLim = pnode2->ichLim;
  1120. }
  1121. if (pnode1->nop == knopDot || pnode1->nop == knopIndex)
  1122. {
  1123. this->CheckArguments(pnode1->sxBin.pnode1);
  1124. }
  1125. }
  1126. return CreateCallNode(nop, pnode1, pnode2, ichMin, ichLim);
  1127. }
  1128. ParseNodePtr Parser::CreateStrNodeWithScanner(IdentPtr pid)
  1129. {
  1130. Assert(!this->m_deferringAST);
  1131. ParseNodePtr pnode = CreateNodeWithScanner<knopStr>();
  1132. pnode->sxPid.pid=pid;
  1133. pnode->grfpn |= PNodeFlags::fpnCanFlattenConcatExpr;
  1134. return pnode;
  1135. }
  1136. ParseNodePtr Parser::CreateIntNodeWithScanner(long lw)
  1137. {
  1138. Assert(!this->m_deferringAST);
  1139. ParseNodePtr pnode = CreateNodeWithScanner<knopInt>();
  1140. pnode->sxInt.lw = lw;
  1141. return pnode;
  1142. }
  1143. ParseNodePtr Parser::CreateTempNode(ParseNode* initExpr)
  1144. {
  1145. ParseNodePtr pnode = CreateNode(knopTemp, (charcount_t)0);
  1146. pnode->sxVar.pnodeInit =initExpr;
  1147. pnode->sxVar.pnodeNext = nullptr;
  1148. return pnode;
  1149. }
  1150. ParseNodePtr Parser::CreateTempRef(ParseNode* tempNode)
  1151. {
  1152. ParseNodePtr pnode = CreateUniNode(knopTempRef, tempNode);
  1153. return pnode;
  1154. }
  1155. void Parser::CheckPidIsValid(IdentPtr pid, bool autoArgumentsObject)
  1156. {
  1157. if (IsStrictMode())
  1158. {
  1159. // in strict mode, variable named 'eval' cannot be created
  1160. if (pid == wellKnownPropertyPids.eval)
  1161. {
  1162. Error(ERREvalUsage);
  1163. }
  1164. else if (pid == wellKnownPropertyPids.arguments && !autoArgumentsObject)
  1165. {
  1166. Error(ERRArgsUsage);
  1167. }
  1168. }
  1169. }
  1170. // CreateVarDecl needs m_ppnodeVar to be pointing to the right function.
  1171. // Post-parsing rewriting during bytecode gen may have m_ppnodeVar pointing to the last parsed function.
  1172. // This function sets up m_ppnodeVar to point to the given pnodeFnc and creates the new var declaration.
  1173. // This prevents accidentally adding var declarations to the last parsed function.
  1174. ParseNodePtr Parser::AddVarDeclNode(IdentPtr pid, ParseNodePtr pnodeFnc)
  1175. {
  1176. AnalysisAssert(pnodeFnc);
  1177. ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
  1178. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  1179. while (*m_ppnodeVar != nullptr)
  1180. {
  1181. m_ppnodeVar = &(*m_ppnodeVar)->sxVar.pnodeNext;
  1182. }
  1183. ParseNodePtr pnode = CreateVarDeclNode(pid, STUnknown, false, 0, /* checkReDecl = */ false);
  1184. m_ppnodeVar = ppnodeVarSave;
  1185. return pnode;
  1186. }
  1187. ParseNodePtr Parser::CreateModuleImportDeclNode(IdentPtr localName)
  1188. {
  1189. ParseNodePtr declNode = CreateBlockScopedDeclNode(localName, knopConstDecl);
  1190. Symbol* sym = declNode->sxVar.sym;
  1191. sym->SetIsModuleExportStorage(true);
  1192. sym->SetIsModuleImport(true);
  1193. return declNode;
  1194. }
  1195. void Parser::MarkIdentifierReferenceIsModuleExport(IdentPtr localName)
  1196. {
  1197. PidRefStack* pidRef = this->PushPidRef(localName);
  1198. Assert(pidRef != nullptr);
  1199. pidRef->SetModuleExport();
  1200. }
  1201. ParseNodePtr Parser::CreateVarDeclNode(IdentPtr pid, SymbolType symbolType, bool autoArgumentsObject, ParseNodePtr pnodeFnc, bool errorOnRedecl)
  1202. {
  1203. ParseNodePtr pnode = CreateDeclNode(knopVarDecl, pid, symbolType, errorOnRedecl);
  1204. // Append the variable to the end of the current variable list.
  1205. AssertMem(m_ppnodeVar);
  1206. pnode->sxVar.pnodeNext = *m_ppnodeVar;
  1207. *m_ppnodeVar = pnode;
  1208. if (nullptr != pid)
  1209. {
  1210. // this is not a temp - make sure temps go after this node
  1211. AssertMem(pid);
  1212. m_ppnodeVar = &pnode->sxVar.pnodeNext;
  1213. CheckPidIsValid(pid, autoArgumentsObject);
  1214. }
  1215. return pnode;
  1216. }
  1217. ParseNodePtr Parser::CreateBlockScopedDeclNode(IdentPtr pid, OpCode nodeType)
  1218. {
  1219. Assert(nodeType == knopConstDecl || nodeType == knopLetDecl);
  1220. ParseNodePtr pnode = CreateDeclNode(nodeType, pid, STVariable, true);
  1221. if (nullptr != pid)
  1222. {
  1223. AssertMem(pid);
  1224. pid->SetIsLetOrConst();
  1225. AddVarDeclToBlock(pnode);
  1226. CheckPidIsValid(pid);
  1227. }
  1228. return pnode;
  1229. }
  1230. void Parser::AddVarDeclToBlock(ParseNode *pnode)
  1231. {
  1232. Assert(pnode->nop == knopConstDecl || pnode->nop == knopLetDecl);
  1233. // Maintain a combined list of let and const declarations to keep
  1234. // track of declaration order.
  1235. AssertMem(m_currentBlockInfo->m_ppnodeLex);
  1236. *m_currentBlockInfo->m_ppnodeLex = pnode;
  1237. m_currentBlockInfo->m_ppnodeLex = &pnode->sxVar.pnodeNext;
  1238. pnode->sxVar.pnodeNext = nullptr;
  1239. }
  1240. void Parser::SetCurrentStatement(StmtNest *stmt)
  1241. {
  1242. m_pstmtCur = stmt;
  1243. }
  1244. template<bool buildAST>
  1245. ParseNodePtr Parser::StartParseBlockWithCapacity(PnodeBlockType blockType, ScopeType scopeType, int capacity)
  1246. {
  1247. Scope *scope = nullptr;
  1248. // Block scopes are created lazily when we discover block-scoped content.
  1249. if (scopeType != ScopeType_Unknown && scopeType != ScopeType_Block)
  1250. {
  1251. scope = Anew(&m_nodeAllocator, Scope, &m_nodeAllocator, scopeType, PHASE_OFF1(Js::ParserBindPhase), capacity);
  1252. PushScope(scope);
  1253. }
  1254. return StartParseBlockHelper<buildAST>(blockType, scope, nullptr, nullptr);
  1255. }
  1256. template<bool buildAST>
  1257. ParseNodePtr Parser::StartParseBlock(PnodeBlockType blockType, ScopeType scopeType, ParseNodePtr pnodeLabel, LabelId* pLabelId)
  1258. {
  1259. Scope *scope = nullptr;
  1260. // Block scopes are created lazily when we discover block-scoped content.
  1261. if (scopeType != ScopeType_Unknown && scopeType != ScopeType_Block)
  1262. {
  1263. scope = Anew(&m_nodeAllocator, Scope, &m_nodeAllocator, scopeType);
  1264. PushScope(scope);
  1265. }
  1266. return StartParseBlockHelper<buildAST>(blockType, scope, pnodeLabel, pLabelId);
  1267. }
  1268. template<bool buildAST>
  1269. ParseNodePtr Parser::StartParseBlockHelper(PnodeBlockType blockType, Scope *scope, ParseNodePtr pnodeLabel, LabelId* pLabelId)
  1270. {
  1271. ParseNodePtr pnodeBlock = CreateBlockNode(blockType);
  1272. pnodeBlock->sxBlock.scope = scope;
  1273. BlockInfoStack *newBlockInfo = PushBlockInfo(pnodeBlock);
  1274. PushStmt<buildAST>(&newBlockInfo->pstmt, pnodeBlock, knopBlock, pnodeLabel, pLabelId);
  1275. return pnodeBlock;
  1276. }
  1277. void Parser::PushScope(Scope *scope)
  1278. {
  1279. Assert(scope);
  1280. scope->SetEnclosingScope(m_currentScope);
  1281. m_currentScope = scope;
  1282. }
  1283. void Parser::PopScope(Scope *scope)
  1284. {
  1285. Assert(scope == m_currentScope);
  1286. m_currentScope = scope->GetEnclosingScope();
  1287. scope->SetEnclosingScope(nullptr);
  1288. }
  1289. void Parser::PushFuncBlockScope(ParseNodePtr pnodeBlock, ParseNodePtr **ppnodeScopeSave, ParseNodePtr **ppnodeExprScopeSave)
  1290. {
  1291. // Maintain the scope tree.
  1292. pnodeBlock->sxBlock.pnodeScopes = nullptr;
  1293. pnodeBlock->sxBlock.pnodeNext = nullptr;
  1294. // Insert this block into the active list of scopes (m_ppnodeExprScope or m_ppnodeScope).
  1295. // Save the current block's "next" pointer as the new endpoint of that list.
  1296. if (m_ppnodeExprScope)
  1297. {
  1298. *ppnodeScopeSave = m_ppnodeScope;
  1299. Assert(*m_ppnodeExprScope == nullptr);
  1300. *m_ppnodeExprScope = pnodeBlock;
  1301. *ppnodeExprScopeSave = &pnodeBlock->sxBlock.pnodeNext;
  1302. }
  1303. else
  1304. {
  1305. Assert(m_ppnodeScope);
  1306. Assert(*m_ppnodeScope == nullptr);
  1307. *m_ppnodeScope = pnodeBlock;
  1308. *ppnodeScopeSave = &pnodeBlock->sxBlock.pnodeNext;
  1309. *ppnodeExprScopeSave = m_ppnodeExprScope;
  1310. }
  1311. // Advance the global scope list pointer to the new block's child list.
  1312. m_ppnodeScope = &pnodeBlock->sxBlock.pnodeScopes;
  1313. // Set m_ppnodeExprScope to NULL to make that list inactive.
  1314. m_ppnodeExprScope = nullptr;
  1315. }
  1316. void Parser::PopFuncBlockScope(ParseNodePtr *ppnodeScopeSave, ParseNodePtr *ppnodeExprScopeSave)
  1317. {
  1318. Assert(m_ppnodeExprScope == nullptr || *m_ppnodeExprScope == nullptr);
  1319. m_ppnodeExprScope = ppnodeExprScopeSave;
  1320. AssertMem(m_ppnodeScope);
  1321. Assert(nullptr == *m_ppnodeScope);
  1322. m_ppnodeScope = ppnodeScopeSave;
  1323. }
  1324. template<bool buildAST>
  1325. ParseNodePtr Parser::ParseBlock(ParseNodePtr pnodeLabel, LabelId* pLabelId)
  1326. {
  1327. ParseNodePtr pnodeBlock = nullptr;
  1328. ParseNodePtr *ppnodeScopeSave = nullptr;
  1329. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  1330. pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block, pnodeLabel, pLabelId);
  1331. BlockInfoStack* outerBlockInfo = m_currentBlockInfo->pBlockInfoOuter;
  1332. if (outerBlockInfo != nullptr && outerBlockInfo->pnodeBlock != nullptr
  1333. && outerBlockInfo->pnodeBlock->sxBlock.scope != nullptr
  1334. && outerBlockInfo->pnodeBlock->sxBlock.scope->GetScopeType() == ScopeType_CatchParamPattern)
  1335. {
  1336. // If we are parsing the catch block then destructured params can have let declrations. Let's add them to the new block.
  1337. for (ParseNodePtr pnode = m_currentBlockInfo->pBlockInfoOuter->pnodeBlock->sxBlock.pnodeLexVars; pnode; pnode = pnode->sxVar.pnodeNext)
  1338. {
  1339. PidRefStack* ref = PushPidRef(pnode->sxVar.sym->GetPid());
  1340. ref->SetSym(pnode->sxVar.sym);
  1341. }
  1342. }
  1343. ChkCurTok(tkLCurly, ERRnoLcurly);
  1344. ParseNodePtr * ppnodeList = nullptr;
  1345. if (buildAST)
  1346. {
  1347. PushFuncBlockScope(pnodeBlock, &ppnodeScopeSave, &ppnodeExprScopeSave);
  1348. ppnodeList = &pnodeBlock->sxBlock.pnodeStmt;
  1349. }
  1350. ParseStmtList<buildAST>(ppnodeList);
  1351. if (buildAST)
  1352. {
  1353. PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
  1354. }
  1355. FinishParseBlock(pnodeBlock);
  1356. ChkCurTok(tkRCurly, ERRnoRcurly);
  1357. return pnodeBlock;
  1358. }
  1359. void Parser::FinishParseBlock(ParseNode *pnodeBlock, bool needScanRCurly)
  1360. {
  1361. Assert(m_currentBlockInfo != nullptr && pnodeBlock == m_currentBlockInfo->pnodeBlock);
  1362. if (needScanRCurly)
  1363. {
  1364. // Only update the ichLim if we were expecting an RCurly. If there is an
  1365. // expression body without a necessary RCurly, the correct ichLim will
  1366. // have been set already.
  1367. pnodeBlock->ichLim = m_pscan->IchLimTok();
  1368. }
  1369. BindPidRefs<false>(GetCurrentBlockInfo(), m_nextBlockId - 1);
  1370. PopStmt(&m_currentBlockInfo->pstmt);
  1371. PopBlockInfo();
  1372. Scope *scope = pnodeBlock->sxBlock.scope;
  1373. if (scope)
  1374. {
  1375. PopScope(scope);
  1376. }
  1377. }
  1378. void Parser::FinishParseFncExprScope(ParseNodePtr pnodeFnc, ParseNodePtr pnodeFncExprScope)
  1379. {
  1380. int fncExprScopeId = pnodeFncExprScope->sxBlock.blockId;
  1381. ParseNodePtr pnodeName = pnodeFnc->sxFnc.pnodeName;
  1382. if (pnodeName)
  1383. {
  1384. Assert(pnodeName->nop == knopVarDecl);
  1385. BindPidRefsInScope(pnodeName->sxVar.pid, pnodeName->sxVar.sym, fncExprScopeId);
  1386. }
  1387. FinishParseBlock(pnodeFncExprScope);
  1388. }
  1389. template <const bool backgroundPidRef>
  1390. void Parser::BindPidRefs(BlockInfoStack *blockInfo, uint maxBlockId)
  1391. {
  1392. // We need to bind all assignments in order to emit assignment to 'const' error
  1393. int blockId = blockInfo->pnodeBlock->sxBlock.blockId;
  1394. Scope *scope = blockInfo->pnodeBlock->sxBlock.scope;
  1395. if (scope)
  1396. {
  1397. auto bindPidRefs = [blockId, maxBlockId, this](Symbol *sym)
  1398. {
  1399. ParseNodePtr pnode = sym->GetDecl();
  1400. IdentPtr pid;
  1401. #if PROFILE_DICTIONARY
  1402. int depth = 0;
  1403. #endif
  1404. Assert(pnode);
  1405. switch (pnode->nop)
  1406. {
  1407. case knopLetDecl:
  1408. case knopVarDecl:
  1409. pid = pnode->sxVar.pid;
  1410. if (backgroundPidRef)
  1411. {
  1412. pid = this->m_pscan->m_phtbl->FindExistingPid(pid->Psz(), pid->Cch(), pid->Hash(), nullptr, nullptr
  1413. #if PROFILE_DICTIONARY
  1414. , depth
  1415. #endif
  1416. );
  1417. if (pid == nullptr)
  1418. {
  1419. break;
  1420. }
  1421. }
  1422. this->BindPidRefsInScope(pid, sym, blockId, maxBlockId);
  1423. break;
  1424. case knopConstDecl:
  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->BindConstPidRefsInScope(pid, sym, blockId, maxBlockId);
  1439. break;
  1440. case knopName:
  1441. pid = pnode->sxPid.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->BindPidRefsInScope(pid, sym, blockId, maxBlockId);
  1455. break;
  1456. default:
  1457. Assert(0);
  1458. break;
  1459. }
  1460. };
  1461. scope->ForEachSymbol(bindPidRefs);
  1462. }
  1463. }
  1464. void Parser::BindPidRefsInScope(IdentPtr pid, Symbol *sym, int blockId, uint maxBlockId)
  1465. {
  1466. this->BindPidRefsInScopeImpl<false>(pid, sym, blockId, maxBlockId);
  1467. }
  1468. void Parser::BindConstPidRefsInScope(IdentPtr pid, Symbol *sym, int blockId, uint maxBlockId)
  1469. {
  1470. this->BindPidRefsInScopeImpl<true>(pid, sym, blockId, maxBlockId);
  1471. }
  1472. template<const bool isConstBinding>
  1473. void Parser::BindPidRefsInScopeImpl(IdentPtr pid, Symbol *sym, int blockId, uint maxBlockId)
  1474. {
  1475. PidRefStack *ref, *nextRef, *lastRef = nullptr;
  1476. Assert(sym);
  1477. for (ref = pid->GetTopRef(); ref && ref->GetScopeId() >= blockId; ref = nextRef)
  1478. {
  1479. // Fix up sym* on PID ref.
  1480. Assert(!ref->GetSym() || ref->GetSym() == sym);
  1481. nextRef = ref->prev;
  1482. Assert(ref->GetScopeId() >= 0);
  1483. if ((uint)ref->GetScopeId() > maxBlockId)
  1484. {
  1485. lastRef = ref;
  1486. continue;
  1487. }
  1488. ref->SetSym(sym);
  1489. this->RemovePrevPidRef(pid, lastRef);
  1490. if (ref->IsModuleExport())
  1491. {
  1492. Assert(sym->GetIsGlobal());
  1493. sym->SetIsModuleExportStorage(true);
  1494. }
  1495. if (ref->GetScopeId() == blockId)
  1496. {
  1497. break;
  1498. }
  1499. }
  1500. }
  1501. void Parser::PopStmt(StmtNest *pStmt)
  1502. {
  1503. Assert(pStmt == m_pstmtCur);
  1504. SetCurrentStatement(m_pstmtCur->pstmtOuter);
  1505. }
  1506. BlockInfoStack *Parser::PushBlockInfo(ParseNodePtr pnodeBlock)
  1507. {
  1508. BlockInfoStack *newBlockInfo = (BlockInfoStack *)m_nodeAllocator.Alloc(sizeof(BlockInfoStack));
  1509. Assert(nullptr != newBlockInfo);
  1510. newBlockInfo->pnodeBlock = pnodeBlock;
  1511. newBlockInfo->pBlockInfoOuter = m_currentBlockInfo;
  1512. newBlockInfo->m_ppnodeLex = &pnodeBlock->sxBlock.pnodeLexVars;
  1513. if (pnodeBlock->sxBlock.blockType != PnodeBlockType::Regular)
  1514. {
  1515. newBlockInfo->pBlockInfoFunction = newBlockInfo;
  1516. }
  1517. else
  1518. {
  1519. Assert(m_currentBlockInfo);
  1520. newBlockInfo->pBlockInfoFunction = m_currentBlockInfo->pBlockInfoFunction;
  1521. }
  1522. m_currentBlockInfo = newBlockInfo;
  1523. return newBlockInfo;
  1524. }
  1525. void Parser::PopBlockInfo()
  1526. {
  1527. Assert(m_currentBlockInfo);
  1528. PopDynamicBlock();
  1529. m_currentBlockInfo = m_currentBlockInfo->pBlockInfoOuter;
  1530. }
  1531. void Parser::PushDynamicBlock()
  1532. {
  1533. Assert(GetCurrentBlock());
  1534. int blockId = GetCurrentBlock()->sxBlock.blockId;
  1535. if (m_currentDynamicBlock && m_currentDynamicBlock->id == blockId)
  1536. {
  1537. return;
  1538. }
  1539. BlockIdsStack *info = (BlockIdsStack *)m_nodeAllocator.Alloc(sizeof(BlockIdsStack));
  1540. if (nullptr == info)
  1541. {
  1542. Error(ERRnoMemory);
  1543. }
  1544. info->id = blockId;
  1545. info->prev = m_currentDynamicBlock;
  1546. m_currentDynamicBlock = info;
  1547. }
  1548. void Parser::PopDynamicBlock()
  1549. {
  1550. int blockId = GetCurrentDynamicBlockId();
  1551. if (GetCurrentBlock()->sxBlock.blockId != blockId || blockId == -1)
  1552. {
  1553. return;
  1554. }
  1555. Assert(m_currentDynamicBlock);
  1556. for (BlockInfoStack *blockInfo = m_currentBlockInfo; blockInfo; blockInfo = blockInfo->pBlockInfoOuter)
  1557. {
  1558. for (ParseNodePtr pnodeDecl = blockInfo->pnodeBlock->sxBlock.pnodeLexVars;
  1559. pnodeDecl;
  1560. pnodeDecl = pnodeDecl->sxVar.pnodeNext)
  1561. {
  1562. this->SetPidRefsInScopeDynamic(pnodeDecl->sxVar.pid, blockId);
  1563. }
  1564. }
  1565. m_currentDynamicBlock = m_currentDynamicBlock->prev;
  1566. }
  1567. int Parser::GetCurrentDynamicBlockId() const
  1568. {
  1569. return m_currentDynamicBlock ? m_currentDynamicBlock->id : -1;
  1570. }
  1571. ParseNode *Parser::GetCurrentFunctionNode()
  1572. {
  1573. if (m_currentNodeDeferredFunc != nullptr)
  1574. {
  1575. return m_currentNodeDeferredFunc;
  1576. }
  1577. else if (m_currentNodeFunc != nullptr)
  1578. {
  1579. return m_currentNodeFunc;
  1580. }
  1581. else
  1582. {
  1583. AssertMsg(GetFunctionBlock()->sxBlock.blockType == PnodeBlockType::Global,
  1584. "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'");
  1585. return m_currentNodeProg;
  1586. }
  1587. }
  1588. ParseNode *Parser::GetCurrentNonLamdaFunctionNode()
  1589. {
  1590. if (m_currentNodeNonLambdaDeferredFunc != nullptr)
  1591. {
  1592. return m_currentNodeNonLambdaDeferredFunc;
  1593. }
  1594. return m_currentNodeNonLambdaFunc;
  1595. }
  1596. void Parser::RegisterRegexPattern(UnifiedRegex::RegexPattern *const regexPattern)
  1597. {
  1598. Assert(regexPattern);
  1599. // ensure a no-throw add behavior here, to catch out of memory exceptions, using the guest arena allocator
  1600. if (!m_registeredRegexPatterns.PrependNoThrow(m_scriptContext->GetGuestArena(), regexPattern))
  1601. {
  1602. Parser::Error(ERRnoMemory);
  1603. }
  1604. }
  1605. void Parser::CaptureState(ParserState *state)
  1606. {
  1607. Assert(state != nullptr);
  1608. state->m_funcInArraySave = m_funcInArray;
  1609. state->m_funcInArrayDepthSave = m_funcInArrayDepth;
  1610. state->m_nestedCountSave = *m_pnestedCount;
  1611. state->m_ppnodeScopeSave = m_ppnodeScope;
  1612. state->m_ppnodeExprScopeSave = m_ppnodeExprScope;
  1613. state->m_pCurrentAstSizeSave = m_pCurrentAstSize;
  1614. Assert(state->m_ppnodeScopeSave == nullptr || *state->m_ppnodeScopeSave == nullptr);
  1615. Assert(state->m_ppnodeExprScopeSave == nullptr || *state->m_ppnodeExprScopeSave == nullptr);
  1616. #if DEBUG
  1617. state->m_currentBlockInfo = m_currentBlockInfo;
  1618. #endif
  1619. }
  1620. void Parser::RestoreStateFrom(ParserState *state)
  1621. {
  1622. Assert(state != nullptr);
  1623. Assert(state->m_currentBlockInfo == m_currentBlockInfo);
  1624. m_funcInArray = state->m_funcInArraySave;
  1625. m_funcInArrayDepth = state->m_funcInArrayDepthSave;
  1626. *m_pnestedCount = state->m_nestedCountSave;
  1627. m_pCurrentAstSize = state->m_pCurrentAstSizeSave;
  1628. if (state->m_ppnodeScopeSave != nullptr)
  1629. {
  1630. *state->m_ppnodeScopeSave = nullptr;
  1631. }
  1632. if (state->m_ppnodeExprScopeSave != nullptr)
  1633. {
  1634. *state->m_ppnodeExprScopeSave = nullptr;
  1635. }
  1636. m_ppnodeScope = state->m_ppnodeScopeSave;
  1637. m_ppnodeExprScope = state->m_ppnodeExprScopeSave;
  1638. }
  1639. void Parser::AddToNodeListEscapedUse(ParseNode ** ppnodeList, ParseNode *** pppnodeLast,
  1640. ParseNode * pnodeAdd)
  1641. {
  1642. AddToNodeList(ppnodeList, pppnodeLast, pnodeAdd);
  1643. pnodeAdd->SetIsInList();
  1644. }
  1645. void Parser::AddToNodeList(ParseNode ** ppnodeList, ParseNode *** pppnodeLast,
  1646. ParseNode * pnodeAdd)
  1647. {
  1648. Assert(!this->m_deferringAST);
  1649. if (nullptr == *pppnodeLast)
  1650. {
  1651. // should be an empty list
  1652. Assert(nullptr == *ppnodeList);
  1653. *ppnodeList = pnodeAdd;
  1654. *pppnodeLast = ppnodeList;
  1655. }
  1656. else
  1657. {
  1658. //
  1659. AssertNodeMem(*ppnodeList);
  1660. AssertNodeMem(**pppnodeLast);
  1661. ParseNode *pnodeT = CreateBinNode(knopList, **pppnodeLast, pnodeAdd);
  1662. **pppnodeLast = pnodeT;
  1663. *pppnodeLast = &pnodeT->sxBin.pnode2;
  1664. }
  1665. }
  1666. // Check reference to "arguments" that indicates the object may escape.
  1667. void Parser::CheckArguments(ParseNodePtr pnode)
  1668. {
  1669. if (m_currentNodeFunc && this->NodeIsIdent(pnode, wellKnownPropertyPids.arguments))
  1670. {
  1671. m_currentNodeFunc->sxFnc.SetHasHeapArguments();
  1672. }
  1673. }
  1674. // Check use of "arguments" that requires instantiation of the object.
  1675. void Parser::CheckArgumentsUse(IdentPtr pid, ParseNodePtr pnodeFnc)
  1676. {
  1677. if (pid == wellKnownPropertyPids.arguments)
  1678. {
  1679. if (pnodeFnc != nullptr && pnodeFnc != m_currentNodeProg)
  1680. {
  1681. pnodeFnc->sxFnc.SetUsesArguments(TRUE);
  1682. }
  1683. else
  1684. {
  1685. m_UsesArgumentsAtGlobal = true;
  1686. }
  1687. }
  1688. }
  1689. void Parser::CheckStrictModeEvalArgumentsUsage(IdentPtr pid, ParseNodePtr pnode)
  1690. {
  1691. if (pid != nullptr)
  1692. {
  1693. // In strict mode, 'eval' / 'arguments' cannot be assigned to.
  1694. if ( pid == wellKnownPropertyPids.eval)
  1695. {
  1696. Error(ERREvalUsage, pnode);
  1697. }
  1698. if (pid == wellKnownPropertyPids.arguments)
  1699. {
  1700. Error(ERRArgsUsage, pnode);
  1701. }
  1702. }
  1703. }
  1704. void Parser::ReduceDeferredScriptLength(size_t chars)
  1705. {
  1706. // If we're in deferred mode, subtract the given char count from the total length,
  1707. // and see if this puts us under the deferral threshold.
  1708. if ((m_grfscr & fscrDeferFncParse) &&
  1709. (
  1710. PHASE_OFF1(Js::DeferEventHandlersPhase) ||
  1711. (m_grfscr & fscrGlobalCode)
  1712. )
  1713. )
  1714. {
  1715. if (m_length > chars)
  1716. {
  1717. m_length -= chars;
  1718. }
  1719. else
  1720. {
  1721. m_length = 0;
  1722. }
  1723. if (m_length < Parser::GetDeferralThreshold(this->m_sourceContextInfo->IsSourceProfileLoaded()))
  1724. {
  1725. // Stop deferring.
  1726. m_grfscr &= ~fscrDeferFncParse;
  1727. m_stoppedDeferredParse = TRUE;
  1728. }
  1729. }
  1730. }
  1731. /***************************************************************************
  1732. Look for an existing label with the given name.
  1733. ***************************************************************************/
  1734. BOOL Parser::PnodeLabelNoAST(IdentToken* pToken, LabelId* pLabelIdList)
  1735. {
  1736. StmtNest* pStmt;
  1737. LabelId* pLabelId;
  1738. // Look in the label stack.
  1739. for (pStmt = m_pstmtCur; pStmt != nullptr; pStmt = pStmt->pstmtOuter)
  1740. {
  1741. for (pLabelId = pStmt->pLabelId; pLabelId != nullptr; pLabelId = pLabelId->next)
  1742. {
  1743. if (pLabelId->pid == pToken->pid)
  1744. return TRUE;
  1745. }
  1746. }
  1747. // Also look in the pnodeLabels list.
  1748. for (pLabelId = pLabelIdList; pLabelId != nullptr; pLabelId = pLabelId->next)
  1749. {
  1750. if (pLabelId->pid == pToken->pid)
  1751. return TRUE;
  1752. }
  1753. return FALSE;
  1754. }
  1755. void Parser::EnsureStackAvailable()
  1756. {
  1757. if (!m_scriptContext->GetThreadContext()->IsStackAvailable(Js::Constants::MinStackCompile))
  1758. {
  1759. Error(ERRnoMemory);
  1760. }
  1761. }
  1762. void Parser::ThrowNewTargetSyntaxErrForGlobalScope()
  1763. {
  1764. //TODO: (falotfi) we need reliably distinguish eval in global scope vs in a function
  1765. // The rule for this syntax error is any time new.target is called at global scope
  1766. // we are excluding new.target in eval at global scope for now.
  1767. if(GetCurrentNonLamdaFunctionNode() == nullptr && (this->m_grfscr & fscrEvalCode) == 0)
  1768. {
  1769. Error(ERRInvalidNewTarget);
  1770. }
  1771. }
  1772. template<bool buildAST>
  1773. ParseNodePtr Parser::ParseMetaProperty(tokens metaParentKeyword, charcount_t ichMin, _Out_opt_ BOOL* pfCanAssign)
  1774. {
  1775. AssertMsg(metaParentKeyword == tkNEW, "Only supported for tkNEW parent keywords");
  1776. AssertMsg(this->m_token.tk == tkDot, "We must be currently sitting on the dot after the parent keyword");
  1777. m_pscan->Scan();
  1778. if (this->m_token.tk == tkID && this->m_token.GetIdentifier(m_phtbl) == this->GetTargetPid())
  1779. {
  1780. ThrowNewTargetSyntaxErrForGlobalScope();
  1781. if (pfCanAssign)
  1782. {
  1783. *pfCanAssign = FALSE;
  1784. }
  1785. if (buildAST)
  1786. {
  1787. return CreateNodeWithScanner<knopNewTarget>(ichMin);
  1788. }
  1789. }
  1790. else
  1791. {
  1792. Error(ERRsyntax);
  1793. }
  1794. return nullptr;
  1795. }
  1796. template<bool buildAST>
  1797. void Parser::ParseNamedImportOrExportClause(ModuleImportOrExportEntryList* importOrExportEntryList, bool isExportClause)
  1798. {
  1799. Assert(m_token.tk == tkLCurly);
  1800. Assert(importOrExportEntryList != nullptr);
  1801. m_pscan->Scan();
  1802. while (m_token.tk != tkRCurly && m_token.tk != tkEOF)
  1803. {
  1804. tokens firstToken = m_token.tk;
  1805. if (!(m_token.IsIdentifier() || m_token.IsReservedWord()))
  1806. {
  1807. Error(ERRsyntax);
  1808. }
  1809. IdentPtr identifierName = m_token.GetIdentifier(m_phtbl);
  1810. IdentPtr identifierAs = identifierName;
  1811. m_pscan->Scan();
  1812. if (m_token.tk == tkID)
  1813. {
  1814. // We have the pattern "IdentifierName as"
  1815. if (wellKnownPropertyPids.as != m_token.GetIdentifier(m_phtbl))
  1816. {
  1817. Error(ERRsyntax);
  1818. }
  1819. m_pscan->Scan();
  1820. // If we are parsing an import statement, the token after 'as' must be a BindingIdentifier.
  1821. if (!isExportClause)
  1822. {
  1823. ChkCurTokNoScan(tkID, ERRsyntax);
  1824. }
  1825. if (!(m_token.IsIdentifier() || m_token.IsReservedWord()))
  1826. {
  1827. Error(ERRsyntax);
  1828. }
  1829. identifierAs = m_token.GetIdentifier(m_phtbl);
  1830. // Scan to the next token.
  1831. m_pscan->Scan();
  1832. }
  1833. else if (!isExportClause && firstToken != tkID)
  1834. {
  1835. // If we are parsing an import statement and this ImportSpecifier clause did not have
  1836. // 'as ImportedBinding' at the end of it, identifierName must be a BindingIdentifier.
  1837. Error(ERRsyntax);
  1838. }
  1839. if (m_token.tk == tkComma)
  1840. {
  1841. // Consume a trailing comma
  1842. m_pscan->Scan();
  1843. }
  1844. if (buildAST)
  1845. {
  1846. // The name we will use 'as' this import/export is a binding identifier in import statements.
  1847. if (!isExportClause)
  1848. {
  1849. CreateModuleImportDeclNode(identifierAs);
  1850. AddModuleImportOrExportEntry(importOrExportEntryList, identifierName, identifierAs, nullptr, nullptr);
  1851. }
  1852. else
  1853. {
  1854. MarkIdentifierReferenceIsModuleExport(identifierName);
  1855. AddModuleImportOrExportEntry(importOrExportEntryList, nullptr, identifierName, identifierAs, nullptr);
  1856. }
  1857. }
  1858. }
  1859. // Final token in a named import or export clause must be a '}'
  1860. ChkCurTokNoScan(tkRCurly, ERRsyntax);
  1861. }
  1862. IdentPtrList* Parser::GetRequestedModulesList()
  1863. {
  1864. return m_currentNodeProg->sxModule.requestedModules;
  1865. }
  1866. ModuleImportOrExportEntryList* Parser::GetModuleImportEntryList()
  1867. {
  1868. return m_currentNodeProg->sxModule.importEntries;
  1869. }
  1870. ModuleImportOrExportEntryList* Parser::GetModuleLocalExportEntryList()
  1871. {
  1872. return m_currentNodeProg->sxModule.localExportEntries;
  1873. }
  1874. ModuleImportOrExportEntryList* Parser::GetModuleIndirectExportEntryList()
  1875. {
  1876. return m_currentNodeProg->sxModule.indirectExportEntries;
  1877. }
  1878. ModuleImportOrExportEntryList* Parser::GetModuleStarExportEntryList()
  1879. {
  1880. return m_currentNodeProg->sxModule.starExportEntries;
  1881. }
  1882. IdentPtrList* Parser::EnsureRequestedModulesList()
  1883. {
  1884. if (m_currentNodeProg->sxModule.requestedModules == nullptr)
  1885. {
  1886. m_currentNodeProg->sxModule.requestedModules = Anew(&m_nodeAllocator, IdentPtrList, &m_nodeAllocator);
  1887. }
  1888. return m_currentNodeProg->sxModule.requestedModules;
  1889. }
  1890. ModuleImportOrExportEntryList* Parser::EnsureModuleImportEntryList()
  1891. {
  1892. if (m_currentNodeProg->sxModule.importEntries == nullptr)
  1893. {
  1894. m_currentNodeProg->sxModule.importEntries = Anew(&m_nodeAllocator, ModuleImportOrExportEntryList, &m_nodeAllocator);
  1895. }
  1896. return m_currentNodeProg->sxModule.importEntries;
  1897. }
  1898. ModuleImportOrExportEntryList* Parser::EnsureModuleLocalExportEntryList()
  1899. {
  1900. if (m_currentNodeProg->sxModule.localExportEntries == nullptr)
  1901. {
  1902. m_currentNodeProg->sxModule.localExportEntries = Anew(&m_nodeAllocator, ModuleImportOrExportEntryList, &m_nodeAllocator);
  1903. }
  1904. return m_currentNodeProg->sxModule.localExportEntries;
  1905. }
  1906. ModuleImportOrExportEntryList* Parser::EnsureModuleIndirectExportEntryList()
  1907. {
  1908. if (m_currentNodeProg->sxModule.indirectExportEntries == nullptr)
  1909. {
  1910. m_currentNodeProg->sxModule.indirectExportEntries = Anew(&m_nodeAllocator, ModuleImportOrExportEntryList, &m_nodeAllocator);
  1911. }
  1912. return m_currentNodeProg->sxModule.indirectExportEntries;
  1913. }
  1914. ModuleImportOrExportEntryList* Parser::EnsureModuleStarExportEntryList()
  1915. {
  1916. if (m_currentNodeProg->sxModule.starExportEntries == nullptr)
  1917. {
  1918. m_currentNodeProg->sxModule.starExportEntries = Anew(&m_nodeAllocator, ModuleImportOrExportEntryList, &m_nodeAllocator);
  1919. }
  1920. return m_currentNodeProg->sxModule.starExportEntries;
  1921. }
  1922. void Parser::AddModuleSpecifier(IdentPtr moduleRequest)
  1923. {
  1924. IdentPtrList* requestedModulesList = EnsureRequestedModulesList();
  1925. if (!requestedModulesList->Has(moduleRequest))
  1926. {
  1927. requestedModulesList->Prepend(moduleRequest);
  1928. }
  1929. }
  1930. ModuleImportOrExportEntry* Parser::AddModuleImportOrExportEntry(ModuleImportOrExportEntryList* importOrExportEntryList, ModuleImportOrExportEntry* importOrExportEntry)
  1931. {
  1932. if (importOrExportEntry->exportName != nullptr)
  1933. {
  1934. CheckForDuplicateExportEntry(importOrExportEntryList, importOrExportEntry->exportName);
  1935. }
  1936. importOrExportEntryList->Prepend(*importOrExportEntry);
  1937. return importOrExportEntry;
  1938. }
  1939. ModuleImportOrExportEntry* Parser::AddModuleImportOrExportEntry(ModuleImportOrExportEntryList* importOrExportEntryList, IdentPtr importName, IdentPtr localName, IdentPtr exportName, IdentPtr moduleRequest)
  1940. {
  1941. ModuleImportOrExportEntry* importOrExportEntry = Anew(&m_nodeAllocator, ModuleImportOrExportEntry);
  1942. importOrExportEntry->importName = importName;
  1943. importOrExportEntry->localName = localName;
  1944. importOrExportEntry->exportName = exportName;
  1945. importOrExportEntry->moduleRequest = moduleRequest;
  1946. return AddModuleImportOrExportEntry(importOrExportEntryList, importOrExportEntry);
  1947. }
  1948. void Parser::AddModuleLocalExportEntry(ParseNodePtr varDeclNode)
  1949. {
  1950. Assert(varDeclNode->nop == knopVarDecl || varDeclNode->nop == knopLetDecl || varDeclNode->nop == knopConstDecl);
  1951. IdentPtr localName = varDeclNode->sxVar.pid;
  1952. varDeclNode->sxVar.sym->SetIsModuleExportStorage(true);
  1953. AddModuleImportOrExportEntry(EnsureModuleLocalExportEntryList(), nullptr, localName, localName, nullptr);
  1954. }
  1955. void Parser::CheckForDuplicateExportEntry(ModuleImportOrExportEntryList* exportEntryList, IdentPtr exportName)
  1956. {
  1957. ModuleImportOrExportEntry* findResult = exportEntryList->Find([&](ModuleImportOrExportEntry exportEntry)
  1958. {
  1959. if (exportName == exportEntry.exportName)
  1960. {
  1961. return true;
  1962. }
  1963. return false;
  1964. });
  1965. if (findResult != nullptr)
  1966. {
  1967. Error(ERRsyntax);
  1968. }
  1969. }
  1970. template<bool buildAST>
  1971. void Parser::ParseImportClause(ModuleImportOrExportEntryList* importEntryList, bool parsingAfterComma)
  1972. {
  1973. bool parsedNamespaceOrNamedImport = false;
  1974. switch (m_token.tk)
  1975. {
  1976. case tkID:
  1977. // This is the default binding identifier.
  1978. // If we already saw a comma in the import clause, this is a syntax error.
  1979. if (parsingAfterComma)
  1980. {
  1981. Error(ERRsyntax);
  1982. }
  1983. if (buildAST)
  1984. {
  1985. IdentPtr localName = m_token.GetIdentifier(m_phtbl);
  1986. IdentPtr importName = wellKnownPropertyPids.default;
  1987. CreateModuleImportDeclNode(localName);
  1988. AddModuleImportOrExportEntry(importEntryList, importName, localName, nullptr, nullptr);
  1989. }
  1990. break;
  1991. case tkLCurly:
  1992. // This begins a list of named imports.
  1993. ParseNamedImportOrExportClause<buildAST>(importEntryList, false);
  1994. parsedNamespaceOrNamedImport = true;
  1995. break;
  1996. case tkStar:
  1997. // This begins a namespace import clause.
  1998. // "* as ImportedBinding"
  1999. // Token following * must be the identifier 'as'
  2000. m_pscan->Scan();
  2001. if (m_token.tk != tkID || wellKnownPropertyPids.as != m_token.GetIdentifier(m_phtbl))
  2002. {
  2003. Error(ERRsyntax);
  2004. }
  2005. // Token following 'as' must be a binding identifier.
  2006. m_pscan->Scan();
  2007. ChkCurTokNoScan(tkID, ERRsyntax);
  2008. if (buildAST)
  2009. {
  2010. IdentPtr localName = m_token.GetIdentifier(m_phtbl);
  2011. IdentPtr importName = wellKnownPropertyPids._star;
  2012. CreateModuleImportDeclNode(localName);
  2013. AddModuleImportOrExportEntry(importEntryList, importName, localName, nullptr, nullptr);
  2014. }
  2015. parsedNamespaceOrNamedImport = true;
  2016. break;
  2017. default:
  2018. Error(ERRsyntax);
  2019. }
  2020. m_pscan->Scan();
  2021. if (m_token.tk == tkComma)
  2022. {
  2023. // There cannot be more than one comma in a module import clause.
  2024. // There cannot be a namespace import or named imports list on the left of the comma in a module import clause.
  2025. if (parsingAfterComma || parsedNamespaceOrNamedImport)
  2026. {
  2027. Error(ERRsyntax);
  2028. }
  2029. m_pscan->Scan();
  2030. ParseImportClause<buildAST>(importEntryList, true);
  2031. }
  2032. }
  2033. bool Parser::IsImportOrExportStatementValidHere()
  2034. {
  2035. // Import must be located in the global scope of the module.
  2036. return GetCurrentFunctionNode()->nop == knopProg
  2037. && (this->m_grfscr & fscrEvalCode) != fscrEvalCode
  2038. && this->m_tryCatchOrFinallyDepth == 0
  2039. && this->m_currentBlockInfo->pBlockInfoOuter == nullptr;
  2040. }
  2041. template<bool buildAST>
  2042. ParseNodePtr Parser::ParseImportDeclaration()
  2043. {
  2044. Assert(m_scriptContext->GetConfig()->IsES6ModuleEnabled());
  2045. Assert(m_token.tk == tkIMPORT);
  2046. if (!IsImportOrExportStatementValidHere())
  2047. {
  2048. Error(ERRInvalidModuleImportOrExport);
  2049. }
  2050. // We just parsed an import token. Next valid token is *, {, string constant, or binding identifier.
  2051. m_pscan->Scan();
  2052. if (m_token.tk == tkStrCon)
  2053. {
  2054. // This import declaration has no import clause.
  2055. // "import ModuleSpecifier;"
  2056. if (buildAST)
  2057. {
  2058. AddModuleSpecifier(m_token.GetStr());
  2059. }
  2060. // Scan past the module identifier.
  2061. m_pscan->Scan();
  2062. }
  2063. else
  2064. {
  2065. ModuleImportOrExportEntryList importEntryList(&m_nodeAllocator);
  2066. // Parse the import clause (default binding can only exist before the comma).
  2067. ParseImportClause<buildAST>(&importEntryList);
  2068. // Token following import clause must be the identifier 'from'
  2069. IdentPtr moduleSpecifier = ParseImportOrExportFromClause<buildAST>(true);
  2070. if (buildAST)
  2071. {
  2072. Assert(moduleSpecifier != nullptr);
  2073. AddModuleSpecifier(moduleSpecifier);
  2074. importEntryList.Map([this, moduleSpecifier](ModuleImportOrExportEntry& importEntry) {
  2075. importEntry.moduleRequest = moduleSpecifier;
  2076. AddModuleImportOrExportEntry(EnsureModuleImportEntryList(), &importEntry);
  2077. });
  2078. }
  2079. importEntryList.Clear();
  2080. }
  2081. // Import statement is actually a nop, we hoist all the imported bindings to the top of the module.
  2082. return nullptr;
  2083. }
  2084. template<bool buildAST>
  2085. IdentPtr Parser::ParseImportOrExportFromClause(bool throwIfNotFound)
  2086. {
  2087. IdentPtr moduleSpecifier = nullptr;
  2088. if (m_token.tk == tkID && wellKnownPropertyPids.from == m_token.GetIdentifier(m_phtbl))
  2089. {
  2090. m_pscan->Scan();
  2091. // Token following the 'from' token must be a string constant - the module specifier.
  2092. ChkCurTokNoScan(tkStrCon, ERRsyntax);
  2093. if (buildAST)
  2094. {
  2095. moduleSpecifier = m_token.GetStr();
  2096. }
  2097. m_pscan->Scan();
  2098. }
  2099. else if (throwIfNotFound)
  2100. {
  2101. Error(ERRsyntax);
  2102. }
  2103. return moduleSpecifier;
  2104. }
  2105. template<bool buildAST>
  2106. ParseNodePtr Parser::ParseDefaultExportClause()
  2107. {
  2108. Assert(m_token.tk == tkDEFAULT);
  2109. m_pscan->Scan();
  2110. ParseNodePtr pnode = nullptr;
  2111. ushort flags = fFncNoFlgs;
  2112. switch (m_token.tk)
  2113. {
  2114. case tkCLASS:
  2115. {
  2116. if (!m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
  2117. {
  2118. goto LDefault;
  2119. }
  2120. // Before we parse the class itself we need to know if the class has an identifier name.
  2121. // If it does, we'll treat this class as an ordinary class declaration which will bind
  2122. // it to that name. Otherwise the class should parse as a nameless class expression and
  2123. // bind only to the export binding.
  2124. BOOL classHasName = false;
  2125. RestorePoint parsedClass;
  2126. m_pscan->Capture(&parsedClass);
  2127. m_pscan->Scan();
  2128. if (m_token.tk == tkID)
  2129. {
  2130. classHasName = true;
  2131. }
  2132. m_pscan->SeekTo(parsedClass);
  2133. pnode = ParseClassDecl<buildAST>(classHasName, nullptr, nullptr, nullptr);
  2134. if (buildAST)
  2135. {
  2136. AnalysisAssert(pnode != nullptr);
  2137. Assert(pnode->nop == knopClassDecl);
  2138. pnode->sxClass.SetIsDefaultModuleExport(true);
  2139. }
  2140. break;
  2141. }
  2142. case tkID:
  2143. // If we parsed an async token, it could either modify the next token (if it is a
  2144. // function token) or it could be an identifier (let async = 0; export default async;).
  2145. // To handle both cases, when we parse an async token we need to keep the parser state
  2146. // and rewind if the next token is not function.
  2147. if (wellKnownPropertyPids.async == m_token.GetIdentifier(m_phtbl))
  2148. {
  2149. RestorePoint parsedAsync;
  2150. m_pscan->Capture(&parsedAsync);
  2151. m_pscan->Scan();
  2152. if (m_token.tk == tkFUNCTION)
  2153. {
  2154. // Token after async is function, consume the async token and continue to parse the
  2155. // function as an async function.
  2156. flags |= fFncAsync;
  2157. goto LFunction;
  2158. }
  2159. // Token after async is not function, no idea what the async token is supposed to mean
  2160. // so rewind and let the default case handle it.
  2161. m_pscan->SeekTo(parsedAsync);
  2162. }
  2163. goto LDefault;
  2164. break;
  2165. case tkFUNCTION:
  2166. {
  2167. LFunction:
  2168. // We just parsed a function token but we need to figure out if the function
  2169. // has an identifier name or not before we call the helper.
  2170. RestorePoint parsedFunction;
  2171. m_pscan->Capture(&parsedFunction);
  2172. m_pscan->Scan();
  2173. if (m_token.tk == tkStar)
  2174. {
  2175. // If we saw 'function*' that indicates we are going to parse a generator,
  2176. // but doesn't tell us if the generator has an identifier or not.
  2177. // Skip the '*' token for now as it doesn't matter yet.
  2178. m_pscan->Scan();
  2179. }
  2180. // We say that if the function has an identifier name, it is a 'normal' declaration
  2181. // and should create a binding to that identifier as well as one for our default export.
  2182. if (m_token.tk == tkID)
  2183. {
  2184. flags |= fFncDeclaration;
  2185. }
  2186. else
  2187. {
  2188. flags |= fFncNoName;
  2189. }
  2190. // Rewind back to the function token and let the helper handle the parsing.
  2191. m_pscan->SeekTo(parsedFunction);
  2192. pnode = ParseFncDecl<buildAST>(flags);
  2193. if (buildAST)
  2194. {
  2195. AnalysisAssert(pnode != nullptr);
  2196. Assert(pnode->nop == knopFncDecl);
  2197. pnode->sxFnc.SetIsDefaultModuleExport(true);
  2198. }
  2199. break;
  2200. }
  2201. default:
  2202. LDefault:
  2203. {
  2204. ParseNodePtr pnodeExpression = ParseExpr<buildAST>();
  2205. // Consider: Can we detect this syntax error earlier?
  2206. if (pnodeExpression && pnodeExpression->nop == knopComma)
  2207. {
  2208. Error(ERRsyntax);
  2209. }
  2210. if (buildAST)
  2211. {
  2212. AnalysisAssert(pnodeExpression != nullptr);
  2213. // Mark this node as the default module export. We need to make sure it is put into the correct
  2214. // module export slot when we emit the node.
  2215. pnode = CreateNode(knopExportDefault);
  2216. pnode->sxExportDefault.pnodeExpr = pnodeExpression;
  2217. }
  2218. break;
  2219. }
  2220. }
  2221. IdentPtr exportName = wellKnownPropertyPids.default;
  2222. IdentPtr localName = wellKnownPropertyPids._starDefaultStar;
  2223. AddModuleImportOrExportEntry(EnsureModuleLocalExportEntryList(), nullptr, localName, exportName, nullptr);
  2224. return pnode;
  2225. }
  2226. template<bool buildAST>
  2227. ParseNodePtr Parser::ParseExportDeclaration()
  2228. {
  2229. Assert(m_scriptContext->GetConfig()->IsES6ModuleEnabled());
  2230. Assert(m_token.tk == tkEXPORT);
  2231. if (!IsImportOrExportStatementValidHere())
  2232. {
  2233. Error(ERRInvalidModuleImportOrExport);
  2234. }
  2235. ParseNodePtr pnode = nullptr;
  2236. IdentPtr moduleIdentifier = nullptr;
  2237. tokens declarationType;
  2238. // We just parsed an export token. Next valid tokens are *, {, var, let, const, async, function, class, default.
  2239. m_pscan->Scan();
  2240. switch (m_token.tk)
  2241. {
  2242. case tkStar:
  2243. m_pscan->Scan();
  2244. // A star token in an export declaration must be followed by a from clause which begins with a token 'from'.
  2245. moduleIdentifier = ParseImportOrExportFromClause<buildAST>(true);
  2246. if (buildAST)
  2247. {
  2248. Assert(moduleIdentifier != nullptr);
  2249. AddModuleSpecifier(moduleIdentifier);
  2250. IdentPtr importName = wellKnownPropertyPids._star;
  2251. AddModuleImportOrExportEntry(EnsureModuleStarExportEntryList(), importName, nullptr, nullptr, moduleIdentifier);
  2252. }
  2253. break;
  2254. case tkLCurly:
  2255. {
  2256. ModuleImportOrExportEntryList exportEntryList(&m_nodeAllocator);
  2257. ParseNamedImportOrExportClause<buildAST>(&exportEntryList, true);
  2258. m_pscan->Scan();
  2259. // Export clause may be followed by a from clause.
  2260. moduleIdentifier = ParseImportOrExportFromClause<buildAST>(false);
  2261. if (buildAST)
  2262. {
  2263. if (moduleIdentifier != nullptr)
  2264. {
  2265. AddModuleSpecifier(moduleIdentifier);
  2266. }
  2267. exportEntryList.Map([this, moduleIdentifier](ModuleImportOrExportEntry& exportEntry) {
  2268. if (moduleIdentifier != nullptr)
  2269. {
  2270. exportEntry.moduleRequest = moduleIdentifier;
  2271. // We need to swap localname and importname when this is a re-export.
  2272. exportEntry.importName = exportEntry.localName;
  2273. exportEntry.localName = nullptr;
  2274. AddModuleImportOrExportEntry(EnsureModuleIndirectExportEntryList(), &exportEntry);
  2275. }
  2276. else
  2277. {
  2278. AddModuleImportOrExportEntry(EnsureModuleLocalExportEntryList(), &exportEntry);
  2279. }
  2280. });
  2281. exportEntryList.Clear();
  2282. }
  2283. }
  2284. break;
  2285. case tkID:
  2286. {
  2287. IdentPtr pid = m_token.GetIdentifier(m_phtbl);
  2288. if (wellKnownPropertyPids.let == pid)
  2289. {
  2290. declarationType = tkLET;
  2291. goto ParseVarDecl;
  2292. }
  2293. if (wellKnownPropertyPids.async == pid && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  2294. {
  2295. // In module export statements, async token is only valid if it's followed by function.
  2296. // We need to check here because ParseStatement would think 'async = 20' is a var decl.
  2297. RestorePoint parsedAsync;
  2298. m_pscan->Capture(&parsedAsync);
  2299. m_pscan->Scan();
  2300. if (m_token.tk == tkFUNCTION)
  2301. {
  2302. // Token after async is function, rewind to the async token and let ParseStatement handle it.
  2303. m_pscan->SeekTo(parsedAsync);
  2304. goto ParseFunctionDecl;
  2305. }
  2306. // Token after async is not function, it's a syntax error.
  2307. }
  2308. goto ErrorToken;
  2309. }
  2310. case tkVAR:
  2311. case tkLET:
  2312. case tkCONST:
  2313. {
  2314. declarationType = m_token.tk;
  2315. ParseVarDecl:
  2316. m_pscan->Scan();
  2317. pnode = ParseVariableDeclaration<buildAST>(declarationType, m_pscan->IchMinTok());
  2318. if (buildAST)
  2319. {
  2320. ParseNodePtr temp = pnode;
  2321. while (temp->nop == knopList)
  2322. {
  2323. ParseNodePtr varDeclNode = temp->sxBin.pnode1;
  2324. temp = temp->sxBin.pnode2;
  2325. AddModuleLocalExportEntry(varDeclNode);
  2326. }
  2327. AddModuleLocalExportEntry(temp);
  2328. }
  2329. }
  2330. break;
  2331. case tkFUNCTION:
  2332. case tkCLASS:
  2333. {
  2334. ParseFunctionDecl:
  2335. pnode = ParseStatement<buildAST>();
  2336. if (buildAST)
  2337. {
  2338. IdentPtr localName;
  2339. if (pnode->nop == knopClassDecl)
  2340. {
  2341. pnode->sxClass.pnodeName->sxVar.sym->SetIsModuleExportStorage(true);
  2342. pnode->sxClass.pnodeDeclName->sxVar.sym->SetIsModuleExportStorage(true);
  2343. localName = pnode->sxClass.pnodeName->sxVar.pid;
  2344. }
  2345. else
  2346. {
  2347. Assert(pnode->nop == knopFncDecl);
  2348. pnode->sxFnc.GetFuncSymbol()->SetIsModuleExportStorage(true);
  2349. localName = pnode->sxFnc.pid;
  2350. }
  2351. Assert(localName != nullptr);
  2352. AddModuleImportOrExportEntry(EnsureModuleLocalExportEntryList(), nullptr, localName, localName, nullptr);
  2353. }
  2354. }
  2355. break;
  2356. case tkDEFAULT:
  2357. {
  2358. pnode = ParseDefaultExportClause<buildAST>();
  2359. }
  2360. break;
  2361. default:
  2362. {
  2363. ErrorToken:
  2364. Error(ERRsyntax);
  2365. }
  2366. }
  2367. return pnode;
  2368. }
  2369. /***************************************************************************
  2370. Parse an expression term.
  2371. ***************************************************************************/
  2372. template<bool buildAST>
  2373. ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
  2374. LPCOLESTR pNameHint,
  2375. ulong *pHintLength,
  2376. ulong *pShortNameOffset,
  2377. _Inout_opt_ IdentToken* pToken /*= nullptr*/,
  2378. bool fUnaryOrParen /*= false*/,
  2379. _Out_opt_ BOOL* pfCanAssign /*= nullptr*/,
  2380. _Inout_opt_ BOOL* pfLikelyPattern /*= nullptr*/)
  2381. {
  2382. ParseNodePtr pnode = nullptr;
  2383. charcount_t ichMin = 0;
  2384. size_t iecpMin = 0;
  2385. size_t iuMin;
  2386. IdentToken term;
  2387. BOOL fInNew = FALSE;
  2388. BOOL fCanAssign = TRUE;
  2389. bool isAsyncExpr = false;
  2390. bool isLambdaExpr = false;
  2391. Assert(pToken == nullptr || pToken->tk == tkNone); // Must be empty initially
  2392. if (this->IsBackgroundParser())
  2393. {
  2394. PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackParseOneTerm);
  2395. }
  2396. else
  2397. {
  2398. PROBE_STACK(m_scriptContext, Js::Constants::MinStackParseOneTerm);
  2399. }
  2400. switch (m_token.tk)
  2401. {
  2402. case tkID:
  2403. {
  2404. PidRefStack *ref = nullptr;
  2405. IdentPtr pid = m_token.GetIdentifier(m_phtbl);
  2406. charcount_t ichLim = m_pscan->IchLimTok();
  2407. size_t iecpLim = m_pscan->IecpLimTok();
  2408. ichMin = m_pscan->IchMinTok();
  2409. iecpMin = m_pscan->IecpMinTok();
  2410. m_pscan->Scan();
  2411. // We search for an Async expression (a function declaration or an async lambda expression)
  2412. if (pid == wellKnownPropertyPids.async &&
  2413. !m_pscan->FHadNewLine() &&
  2414. m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  2415. {
  2416. if (m_token.tk == tkFUNCTION)
  2417. {
  2418. isAsyncExpr = true;
  2419. goto LFunction;
  2420. }
  2421. else if (m_token.tk == tkID)
  2422. {
  2423. isLambdaExpr = true;
  2424. isAsyncExpr = true;
  2425. goto LFunction;
  2426. }
  2427. }
  2428. ref = this->PushPidRef(pid);
  2429. if (buildAST)
  2430. {
  2431. pnode = CreateNameNode(pid);
  2432. pnode->ichMin = ichMin;
  2433. pnode->ichLim = ichLim;
  2434. pnode->sxPid.SetSymRef(ref);
  2435. }
  2436. else
  2437. {
  2438. // Remember the identifier start and end in case it turns out to be a statement label.
  2439. term.tk = tkID;
  2440. term.pid = pid; // Record the identifier for detection of eval
  2441. term.ichMin = static_cast<charcount_t>(iecpMin);
  2442. term.ichLim = static_cast<charcount_t>(iecpLim);
  2443. }
  2444. CheckArgumentsUse(pid, GetCurrentFunctionNode());
  2445. break;
  2446. }
  2447. case tkTHIS:
  2448. if (buildAST)
  2449. {
  2450. pnode = CreateNodeWithScanner<knopThis>();
  2451. }
  2452. fCanAssign = FALSE;
  2453. m_pscan->Scan();
  2454. break;
  2455. case tkLParen:
  2456. ichMin = m_pscan->IchMinTok();
  2457. iuMin = m_pscan->IecpMinTok();
  2458. m_pscan->Scan();
  2459. if (m_token.tk == tkRParen)
  2460. {
  2461. // Empty parens can only be legal as an empty parameter list to a lambda declaration.
  2462. // We're in a lambda if the next token is =>.
  2463. fAllowCall = FALSE;
  2464. m_pscan->Scan();
  2465. // If the token after the right paren is not => or if there was a newline between () and => this is a syntax error
  2466. if (!m_doingFastScan && (m_token.tk != tkDArrow || m_pscan->FHadNewLine()))
  2467. {
  2468. Error(ERRsyntax);
  2469. }
  2470. if (buildAST)
  2471. {
  2472. pnode = CreateNodeWithScanner<knopEmpty>();
  2473. }
  2474. break;
  2475. }
  2476. this->m_parenDepth++;
  2477. pnode = ParseExpr<buildAST>(koplNo, &fCanAssign, TRUE, FALSE, nullptr, nullptr /*nameLength*/, nullptr /*pShortNameOffset*/, &term, true);
  2478. this->m_parenDepth--;
  2479. ChkCurTok(tkRParen, ERRnoRparen);
  2480. // Emit a deferred ... error if one was parsed.
  2481. if (m_deferEllipsisError && m_token.tk != tkDArrow)
  2482. {
  2483. m_pscan->SeekTo(m_EllipsisErrLoc);
  2484. Error(ERRInvalidSpreadUse);
  2485. }
  2486. else
  2487. {
  2488. m_deferEllipsisError = false;
  2489. }
  2490. break;
  2491. case tkIntCon:
  2492. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  2493. {
  2494. Error(ERRES5NoOctal);
  2495. }
  2496. if (buildAST)
  2497. {
  2498. pnode = CreateIntNodeWithScanner(m_token.GetLong());
  2499. }
  2500. fCanAssign = FALSE;
  2501. m_pscan->Scan();
  2502. break;
  2503. case tkFltCon:
  2504. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  2505. {
  2506. Error(ERRES5NoOctal);
  2507. }
  2508. if (buildAST)
  2509. {
  2510. pnode = CreateNodeWithScanner<knopFlt>();
  2511. pnode->sxFlt.dbl = m_token.GetDouble();
  2512. pnode->sxFlt.maybeInt = m_token.GetDoubleMayBeInt();
  2513. }
  2514. fCanAssign = FALSE;
  2515. m_pscan->Scan();
  2516. break;
  2517. case tkStrCon:
  2518. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  2519. {
  2520. Error(ERRES5NoOctal);
  2521. }
  2522. if (buildAST)
  2523. {
  2524. pnode = CreateStrNodeWithScanner(m_token.GetStr());
  2525. }
  2526. else
  2527. {
  2528. // Subtract the string literal length from the total char count for the purpose
  2529. // of deciding whether to defer parsing and byte code generation.
  2530. this->ReduceDeferredScriptLength(m_pscan->IchLimTok() - m_pscan->IchMinTok());
  2531. }
  2532. fCanAssign = FALSE;
  2533. m_pscan->Scan();
  2534. break;
  2535. case tkTRUE:
  2536. if (buildAST)
  2537. {
  2538. pnode = CreateNodeWithScanner<knopTrue>();
  2539. }
  2540. fCanAssign = FALSE;
  2541. m_pscan->Scan();
  2542. break;
  2543. case tkFALSE:
  2544. if (buildAST)
  2545. {
  2546. pnode = CreateNodeWithScanner<knopFalse>();
  2547. }
  2548. fCanAssign = FALSE;
  2549. m_pscan->Scan();
  2550. break;
  2551. case tkNULL:
  2552. if (buildAST)
  2553. {
  2554. pnode = CreateNodeWithScanner<knopNull>();
  2555. }
  2556. fCanAssign = FALSE;
  2557. m_pscan->Scan();
  2558. break;
  2559. case tkDiv:
  2560. case tkAsgDiv:
  2561. pnode = ParseRegExp<buildAST>();
  2562. fCanAssign = FALSE;
  2563. m_pscan->Scan();
  2564. break;
  2565. case tkNEW:
  2566. {
  2567. ichMin = m_pscan->IchMinTok();
  2568. m_pscan->Scan();
  2569. if (m_token.tk == tkDot && m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
  2570. {
  2571. pnode = ParseMetaProperty<buildAST>(tkNEW, ichMin, &fCanAssign);
  2572. m_pscan->Scan();
  2573. }
  2574. else
  2575. {
  2576. ParseNodePtr pnodeExpr = ParseTerm<buildAST>(FALSE, pNameHint, pHintLength, pShortNameOffset);
  2577. if (buildAST)
  2578. {
  2579. pnode = CreateCallNode(knopNew, pnodeExpr, nullptr);
  2580. pnode->ichMin = ichMin;
  2581. }
  2582. fInNew = TRUE;
  2583. fCanAssign = FALSE;
  2584. }
  2585. break;
  2586. }
  2587. case tkLBrack:
  2588. {
  2589. ichMin = m_pscan->IchMinTok();
  2590. m_pscan->Scan();
  2591. pnode = ParseArrayLiteral<buildAST>();
  2592. if (buildAST)
  2593. {
  2594. pnode->ichMin = ichMin;
  2595. pnode->ichLim = m_pscan->IchLimTok();
  2596. }
  2597. if (this->m_arrayDepth == 0)
  2598. {
  2599. Assert(m_pscan->IchLimTok() - ichMin > m_funcInArray);
  2600. this->ReduceDeferredScriptLength(m_pscan->IchLimTok() - ichMin - this->m_funcInArray);
  2601. this->m_funcInArray = 0;
  2602. this->m_funcInArrayDepth = 0;
  2603. }
  2604. ChkCurTok(tkRBrack, ERRnoRbrack);
  2605. if (!IsES6DestructuringEnabled())
  2606. {
  2607. fCanAssign = FALSE;
  2608. }
  2609. else if (pfLikelyPattern != nullptr && !IsPostFixOperators())
  2610. {
  2611. *pfLikelyPattern = TRUE;
  2612. }
  2613. break;
  2614. }
  2615. case tkLCurly:
  2616. {
  2617. ichMin = m_pscan->IchMinTok();
  2618. m_pscan->ScanForcingPid();
  2619. ParseNodePtr pnodeMemberList = ParseMemberList<buildAST>(pNameHint, pHintLength);
  2620. if (buildAST)
  2621. {
  2622. pnode = CreateUniNode(knopObject, pnodeMemberList);
  2623. pnode->ichMin = ichMin;
  2624. pnode->ichLim = m_pscan->IchLimTok();
  2625. }
  2626. ChkCurTok(tkRCurly, ERRnoRcurly);
  2627. if (!IsES6DestructuringEnabled())
  2628. {
  2629. fCanAssign = FALSE;
  2630. }
  2631. else if (pfLikelyPattern != nullptr && !IsPostFixOperators())
  2632. {
  2633. *pfLikelyPattern = TRUE;
  2634. }
  2635. break;
  2636. }
  2637. case tkFUNCTION:
  2638. {
  2639. LFunction :
  2640. if (m_grfscr & fscrDeferredFncExpression)
  2641. {
  2642. // The top-level deferred function body was defined by a function expression whose parsing was deferred. We are now
  2643. // parsing it, so unset the flag so that any nested functions are parsed normally. This flag is only applicable the
  2644. // first time we see it.
  2645. //
  2646. // Normally, deferred functions will be parsed in ParseStatement upon encountering the 'function' token. The first
  2647. // token of the source code of the function may not a 'function' token though, so we still need to reset this flag
  2648. // for the first function we parse. This can happen in compat modes, for instance, for a function expression enclosed
  2649. // in parentheses, where the legacy behavior was to include the parentheses in the function's source code.
  2650. m_grfscr &= ~fscrDeferredFncExpression;
  2651. }
  2652. ushort flags = fFncNoFlgs;
  2653. if (isLambdaExpr)
  2654. {
  2655. flags |= fFncLambda;
  2656. }
  2657. if (isAsyncExpr)
  2658. {
  2659. flags |= fFncAsync;
  2660. }
  2661. pnode = ParseFncDecl<buildAST>(flags, pNameHint, false, true, fUnaryOrParen);
  2662. if (isAsyncExpr)
  2663. {
  2664. pnode->sxFnc.cbMin = iecpMin;
  2665. pnode->ichMin = ichMin;
  2666. }
  2667. fCanAssign = FALSE;
  2668. break;
  2669. }
  2670. case tkCLASS:
  2671. fAllowCall = FALSE;
  2672. if (m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
  2673. {
  2674. pnode = ParseClassDecl<buildAST>(FALSE, pNameHint, pHintLength, pShortNameOffset);
  2675. }
  2676. else
  2677. {
  2678. goto LUnknown;
  2679. }
  2680. fCanAssign = FALSE;
  2681. break;
  2682. case tkStrTmplBasic:
  2683. case tkStrTmplBegin:
  2684. pnode = ParseStringTemplateDecl<buildAST>(nullptr);
  2685. fCanAssign = FALSE;
  2686. break;
  2687. case tkSUPER:
  2688. if (m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
  2689. {
  2690. pnode = ParseSuper<buildAST>(pnode, !!fAllowCall);
  2691. }
  2692. else
  2693. {
  2694. goto LUnknown;
  2695. }
  2696. break;
  2697. case tkCASE:
  2698. {
  2699. if (!m_doingFastScan)
  2700. {
  2701. goto LUnknown;
  2702. }
  2703. ParseNodePtr pnodeUnused;
  2704. pnode = ParseCase<buildAST>(&pnodeUnused);
  2705. break;
  2706. }
  2707. case tkELSE:
  2708. if (!m_doingFastScan)
  2709. {
  2710. goto LUnknown;
  2711. }
  2712. m_pscan->Scan();
  2713. ParseStatement<buildAST>();
  2714. break;
  2715. default:
  2716. LUnknown :
  2717. Error(ERRsyntax);
  2718. break;
  2719. }
  2720. pnode = ParsePostfixOperators<buildAST>(pnode, fAllowCall, fInNew, &fCanAssign, &term);
  2721. // Pass back identifier if requested
  2722. if (pToken && term.tk == tkID)
  2723. {
  2724. *pToken = term;
  2725. }
  2726. if (pfCanAssign)
  2727. {
  2728. *pfCanAssign = fCanAssign;
  2729. }
  2730. return pnode;
  2731. }
  2732. template <bool buildAST>
  2733. ParseNodePtr Parser::ParseRegExp()
  2734. {
  2735. ParseNodePtr pnode = nullptr;
  2736. if (buildAST || m_doingFastScan)
  2737. {
  2738. m_pscan->RescanRegExp();
  2739. BOOL saveDeferringAST = this->m_deferringAST;
  2740. if (m_doingFastScan)
  2741. {
  2742. this->m_deferringAST = false;
  2743. }
  2744. pnode = CreateNodeWithScanner<knopRegExp>();
  2745. pnode->sxPid.regexPattern = m_token.GetRegex();
  2746. if (m_doingFastScan)
  2747. {
  2748. this->m_deferringAST = saveDeferringAST;
  2749. this->AddFastScannedRegExpNode(pnode);
  2750. if (!buildAST)
  2751. {
  2752. pnode = nullptr;
  2753. }
  2754. }
  2755. #if ENABLE_BACKGROUND_PARSING
  2756. else if (this->IsBackgroundParser())
  2757. {
  2758. Assert(pnode->sxPid.regexPattern == nullptr);
  2759. this->AddBackgroundRegExpNode(pnode);
  2760. }
  2761. #endif
  2762. }
  2763. else
  2764. {
  2765. m_pscan->RescanRegExpNoAST();
  2766. }
  2767. Assert(m_token.tk == tkRegExp);
  2768. return pnode;
  2769. }
  2770. BOOL Parser::NodeIsEvalName(ParseNodePtr pnode)
  2771. {
  2772. //WOOB 1107758 Special case of indirect eval binds to local scope in standards mode
  2773. return pnode->nop == knopName && (pnode->sxPid.pid == wellKnownPropertyPids.eval);
  2774. }
  2775. BOOL Parser::NodeEqualsName(ParseNodePtr pnode, LPCOLESTR sz, ulong cch)
  2776. {
  2777. return pnode->nop == knopName &&
  2778. pnode->sxPid.pid->Cch() == cch &&
  2779. !wmemcmp(pnode->sxPid.pid->Psz(), sz, cch);
  2780. }
  2781. BOOL Parser::NodeIsIdent(ParseNodePtr pnode, IdentPtr pid)
  2782. {
  2783. for (;;)
  2784. {
  2785. switch (pnode->nop)
  2786. {
  2787. case knopName:
  2788. return (pnode->sxPid.pid == pid);
  2789. case knopComma:
  2790. pnode = pnode->sxBin.pnode2;
  2791. break;
  2792. default:
  2793. return FALSE;
  2794. }
  2795. }
  2796. }
  2797. template<bool buildAST>
  2798. ParseNodePtr Parser::ParsePostfixOperators(
  2799. ParseNodePtr pnode,
  2800. BOOL fAllowCall,
  2801. BOOL fInNew,
  2802. BOOL *pfCanAssign,
  2803. _Inout_ IdentToken* pToken)
  2804. {
  2805. uint16 count = 0;
  2806. bool callOfConstants = false;
  2807. for (;;)
  2808. {
  2809. uint16 spreadArgCount = 0;
  2810. switch (m_token.tk)
  2811. {
  2812. case tkLParen:
  2813. {
  2814. if (fInNew)
  2815. {
  2816. ParseNodePtr pnodeArgs = ParseArgList<buildAST>(&callOfConstants, &spreadArgCount, &count);
  2817. if (buildAST)
  2818. {
  2819. Assert(pnode->nop == knopNew);
  2820. Assert(pnode->sxCall.pnodeArgs == nullptr);
  2821. pnode->sxCall.pnodeArgs = pnodeArgs;
  2822. pnode->sxCall.callOfConstants = callOfConstants;
  2823. pnode->sxCall.isApplyCall = false;
  2824. pnode->sxCall.isEvalCall = false;
  2825. pnode->sxCall.argCount = count;
  2826. pnode->sxCall.spreadArgCount = spreadArgCount;
  2827. pnode->ichLim = m_pscan->IchLimTok();
  2828. }
  2829. else
  2830. {
  2831. pToken->tk = tkNone; // This is no longer an identifier
  2832. }
  2833. fInNew = FALSE;
  2834. }
  2835. else
  2836. {
  2837. bool fCallIsEval = false;
  2838. if (!fAllowCall)
  2839. {
  2840. return pnode;
  2841. }
  2842. ParseNodePtr pnodeArgs = ParseArgList<buildAST>(&callOfConstants, &spreadArgCount, &count);
  2843. // We used to un-defer a deferred function body here if it was called as part of the expression that declared it.
  2844. // We now detect this case up front in ParseFncDecl, which is cheaper and simpler.
  2845. if (buildAST)
  2846. {
  2847. pnode = CreateCallNode(knopCall, pnode, pnodeArgs);
  2848. Assert(pnode);
  2849. // Detect call to "eval" and record it on the function.
  2850. // Note: we used to leave it up to the byte code generator to detect eval calls
  2851. // at global scope, but now it relies on the flag the parser sets, so set it here.
  2852. if (count > 0 && this->NodeIsEvalName(pnode->sxCall.pnodeTarget))
  2853. {
  2854. this->MarkEvalCaller();
  2855. fCallIsEval = true;
  2856. }
  2857. pnode->sxCall.callOfConstants = callOfConstants;
  2858. pnode->sxCall.spreadArgCount = spreadArgCount;
  2859. pnode->sxCall.isApplyCall = false;
  2860. pnode->sxCall.isEvalCall = fCallIsEval;
  2861. pnode->sxCall.argCount = count;
  2862. pnode->ichLim = m_pscan->IchLimTok();
  2863. }
  2864. else
  2865. {
  2866. if (pToken->tk == tkID && pToken->pid == wellKnownPropertyPids.eval && count > 0) // Detect eval
  2867. {
  2868. this->MarkEvalCaller();
  2869. }
  2870. pToken->tk = tkNone; // This is no longer an identifier
  2871. }
  2872. }
  2873. ChkCurTok(tkRParen, ERRnoRparen);
  2874. if (pfCanAssign)
  2875. {
  2876. *pfCanAssign = FALSE;
  2877. }
  2878. break;
  2879. }
  2880. case tkLBrack:
  2881. {
  2882. m_pscan->Scan();
  2883. ParseNodePtr pnodeExpr = ParseExpr<buildAST>();
  2884. if (buildAST)
  2885. {
  2886. pnode = CreateBinNode(knopIndex, pnode, pnodeExpr);
  2887. pnode->ichLim = m_pscan->IchLimTok();
  2888. }
  2889. else
  2890. {
  2891. pToken->tk = tkNone; // This is no longer an identifier
  2892. }
  2893. ChkCurTok(tkRBrack, ERRnoRbrack);
  2894. if (pfCanAssign)
  2895. {
  2896. *pfCanAssign = TRUE;
  2897. }
  2898. if (!buildAST)
  2899. {
  2900. break;
  2901. }
  2902. bool shouldConvertToDot = false;
  2903. if (pnode->sxBin.pnode2->nop == knopStr)
  2904. {
  2905. // if the string is empty or contains escape character, we will not convert them to dot node
  2906. shouldConvertToDot = pnode->sxBin.pnode2->sxPid.pid->Cch() > 0 && !m_pscan->IsEscapeOnLastTkStrCon();
  2907. }
  2908. if (shouldConvertToDot)
  2909. {
  2910. LPCOLESTR str = pnode->sxBin.pnode2->sxPid.pid->Psz();
  2911. // See if we can convert o["p"] into o.p and o["0"] into o[0] since they're equivalent and the latter forms
  2912. // are faster
  2913. uint32 uintValue;
  2914. if(Js::JavascriptOperators::TryConvertToUInt32(
  2915. str,
  2916. pnode->sxBin.pnode2->sxPid.pid->Cch(),
  2917. &uintValue) &&
  2918. !Js::TaggedInt::IsOverflow(uintValue)) // the optimization is not very useful if the number can't be represented as a TaggedInt
  2919. {
  2920. // No need to verify that uintValue != JavascriptArray::InvalidIndex since all nonnegative TaggedInts are valid indexes
  2921. auto intNode = CreateIntNodeWithScanner(uintValue); // implicit conversion from uint32 to long
  2922. pnode->sxBin.pnode2 = intNode;
  2923. }
  2924. // Field optimization (see GlobOpt::KillLiveElems) checks for value being a Number,
  2925. // and since NaN/Infinity is a number it won't kill o.NaN/o.Infinity which would cause a problem
  2926. // if we decide to hoist o.NaN/o.Infinity.
  2927. // We need to keep o["NaN"] and o["+/-Infinity"] as array element access (we don't hoist that but we may hoist field access),
  2928. // so no matter if it's killed by o[x] inside a loop, we make sure that we never hoist these.
  2929. // We need to follow same logic for strings that convert to a floating point number.
  2930. else
  2931. {
  2932. bool doConvertToProperty = false; // Convert a["x"] -> a.x.
  2933. if (!Parser::IsNaNOrInfinityLiteral<true>(str))
  2934. {
  2935. const OLECHAR* terminalChar;
  2936. double dbl = Js::NumberUtilities::StrToDbl(str, &terminalChar, m_scriptContext);
  2937. bool convertsToFloat = !Js::NumberUtilities::IsNan(dbl);
  2938. doConvertToProperty = !convertsToFloat;
  2939. }
  2940. if (doConvertToProperty)
  2941. {
  2942. pnode->sxBin.pnode2->nop = knopName;
  2943. pnode->nop = knopDot;
  2944. pnode->grfpn |= PNodeFlags::fpnIndexOperator;
  2945. }
  2946. }
  2947. }
  2948. }
  2949. break;
  2950. case tkDot:
  2951. {
  2952. ParseNodePtr name = nullptr;
  2953. OpCode opCode = knopDot;
  2954. m_pscan->Scan();
  2955. if (!m_token.IsIdentifier())
  2956. {
  2957. //allow reserved words in ES5 mode
  2958. if (!(m_token.IsReservedWord()))
  2959. {
  2960. IdentifierExpectedError(m_token);
  2961. }
  2962. }
  2963. // Note: see comment above about field optimization WRT NaN/Infinity/-Infinity.
  2964. // Convert a.Nan, a.Infinity into a["NaN"], a["Infinity"].
  2965. // We don't care about -Infinity case here because x.-Infinity is invalid in JavaScript.
  2966. // Both NaN and Infinity are identifiers.
  2967. else if (buildAST && Parser::IsNaNOrInfinityLiteral<false>(m_token.GetIdentifier(m_phtbl)->Psz()))
  2968. {
  2969. opCode = knopIndex;
  2970. }
  2971. if (buildAST)
  2972. {
  2973. if (opCode == knopDot)
  2974. {
  2975. name = CreateNameNode(m_token.GetIdentifier(m_phtbl));
  2976. }
  2977. else
  2978. {
  2979. Assert(opCode == knopIndex);
  2980. name = CreateStrNodeWithScanner(m_token.GetIdentifier(m_phtbl));
  2981. }
  2982. pnode = CreateBinNode(opCode, pnode, name);
  2983. }
  2984. else
  2985. {
  2986. pToken->tk = tkNone;
  2987. }
  2988. if (pfCanAssign)
  2989. {
  2990. *pfCanAssign = TRUE;
  2991. }
  2992. m_pscan->Scan();
  2993. break;
  2994. }
  2995. case tkStrTmplBasic:
  2996. case tkStrTmplBegin:
  2997. {
  2998. ParseNode* templateNode = ParseStringTemplateDecl<buildAST>(pnode);
  2999. if (!buildAST)
  3000. {
  3001. pToken->tk = tkNone; // This is no longer an identifier
  3002. }
  3003. pnode = templateNode;
  3004. if (pfCanAssign)
  3005. {
  3006. *pfCanAssign = FALSE;
  3007. }
  3008. break;
  3009. }
  3010. default:
  3011. return pnode;
  3012. }
  3013. }
  3014. }
  3015. /***************************************************************************
  3016. Look for an existing label with the given name.
  3017. ***************************************************************************/
  3018. ParseNodePtr Parser::PnodeLabel(IdentPtr pid, ParseNodePtr pnodeLabels)
  3019. {
  3020. AssertMem(pid);
  3021. AssertNodeMemN(pnodeLabels);
  3022. StmtNest *pstmt;
  3023. ParseNodePtr pnodeT;
  3024. // Look in the statement stack.
  3025. for (pstmt = m_pstmtCur; nullptr != pstmt; pstmt = pstmt->pstmtOuter)
  3026. {
  3027. AssertNodeMem(pstmt->pnodeStmt);
  3028. AssertNodeMemN(pstmt->pnodeLab);
  3029. for (pnodeT = pstmt->pnodeLab; nullptr != pnodeT;
  3030. pnodeT = pnodeT->sxLabel.pnodeNext)
  3031. {
  3032. Assert(knopLabel == pnodeT->nop);
  3033. if (pid == pnodeT->sxLabel.pid)
  3034. return pnodeT;
  3035. }
  3036. }
  3037. // Also look in the pnodeLabels list.
  3038. for (pnodeT = pnodeLabels; nullptr != pnodeT;
  3039. pnodeT = pnodeT->sxLabel.pnodeNext)
  3040. {
  3041. Assert(knopLabel == pnodeT->nop);
  3042. if (pid == pnodeT->sxLabel.pid)
  3043. return pnodeT;
  3044. }
  3045. return nullptr;
  3046. }
  3047. // Currently only ints and floats are treated as constants in function call
  3048. // TODO: Check if we need for other constants as well
  3049. BOOL Parser::IsConstantInFunctionCall(ParseNodePtr pnode)
  3050. {
  3051. if (pnode->nop == knopInt && !Js::TaggedInt::IsOverflow(pnode->sxInt.lw))
  3052. {
  3053. return TRUE;
  3054. }
  3055. if (pnode->nop == knopFlt)
  3056. {
  3057. return TRUE;
  3058. }
  3059. return FALSE;
  3060. }
  3061. /***************************************************************************
  3062. Parse a list of arguments.
  3063. ***************************************************************************/
  3064. template<bool buildAST>
  3065. ParseNodePtr Parser::ParseArgList( bool *pCallOfConstants, uint16 *pSpreadArgCount, uint16 * pCount)
  3066. {
  3067. ParseNodePtr pnodeArg;
  3068. ParseNodePtr pnodeList = nullptr;
  3069. ParseNodePtr *lastNodeRef = nullptr;
  3070. // Check for an empty list
  3071. Assert(m_token.tk == tkLParen);
  3072. if (m_pscan->Scan() == tkRParen)
  3073. {
  3074. return nullptr;
  3075. }
  3076. *pCallOfConstants = true;
  3077. *pSpreadArgCount = 0;
  3078. int count=0;
  3079. while (true)
  3080. {
  3081. // the count of arguments has to fit in an unsigned short
  3082. if (count > 0xffffU)
  3083. Error(ERRnoMemory);
  3084. // Allow spread in argument lists.
  3085. pnodeArg = ParseExpr<buildAST>(koplCma, nullptr, TRUE, /* fAllowEllipsis */TRUE);
  3086. ++count;
  3087. if (buildAST)
  3088. {
  3089. this->CheckArguments(pnodeArg);
  3090. if (*pCallOfConstants && !IsConstantInFunctionCall(pnodeArg))
  3091. {
  3092. *pCallOfConstants = false;
  3093. }
  3094. if (pnodeArg->nop == knopEllipsis)
  3095. {
  3096. (*pSpreadArgCount)++;
  3097. }
  3098. AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeArg);
  3099. }
  3100. if (m_token.tk != tkComma)
  3101. {
  3102. break;
  3103. }
  3104. m_pscan->Scan();
  3105. if (m_token.tk == tkRParen && m_scriptContext->GetConfig()->IsES7TrailingCommaEnabled())
  3106. {
  3107. break;
  3108. }
  3109. }
  3110. if (pSpreadArgCount!=nullptr && (*pSpreadArgCount) > 0){
  3111. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(SpreadFeatureCount, m_scriptContext);
  3112. }
  3113. *pCount = static_cast<uint16>(count);
  3114. if (buildAST)
  3115. {
  3116. AssertMem(lastNodeRef);
  3117. AssertNodeMem(*lastNodeRef);
  3118. pnodeList->ichLim = (*lastNodeRef)->ichLim;
  3119. }
  3120. return pnodeList;
  3121. }
  3122. // Currently only ints are treated as constants in ArrayLiterals
  3123. BOOL Parser::IsConstantInArrayLiteral(ParseNodePtr pnode)
  3124. {
  3125. if (pnode->nop == knopInt && !Js::TaggedInt::IsOverflow(pnode->sxInt.lw))
  3126. {
  3127. return TRUE;
  3128. }
  3129. return FALSE;
  3130. }
  3131. template<bool buildAST>
  3132. ParseNodePtr Parser::ParseArrayLiteral()
  3133. {
  3134. ParseNodePtr pnode = nullptr;
  3135. bool arrayOfTaggedInts = false;
  3136. bool arrayOfInts = false;
  3137. bool arrayOfNumbers = false;
  3138. bool hasMissingValues = false;
  3139. uint count = 0;
  3140. uint spreadCount = 0;
  3141. ParseNodePtr pnode1 = ParseArrayList<buildAST>(&arrayOfTaggedInts, &arrayOfInts, &arrayOfNumbers, &hasMissingValues, &count, &spreadCount);
  3142. if (buildAST)
  3143. {
  3144. pnode = CreateNodeWithScanner<knopArray>();
  3145. pnode->sxArrLit.pnode1 = pnode1;
  3146. pnode->sxArrLit.arrayOfTaggedInts = arrayOfTaggedInts;
  3147. pnode->sxArrLit.arrayOfInts = arrayOfInts;
  3148. pnode->sxArrLit.arrayOfNumbers = arrayOfNumbers;
  3149. pnode->sxArrLit.hasMissingValues = hasMissingValues;
  3150. pnode->sxArrLit.count = count;
  3151. pnode->sxArrLit.spreadCount = spreadCount;
  3152. if (pnode->sxArrLit.pnode1)
  3153. {
  3154. this->CheckArguments(pnode->sxArrLit.pnode1);
  3155. }
  3156. }
  3157. return pnode;
  3158. }
  3159. /***************************************************************************
  3160. Create an ArrayLiteral node
  3161. Parse a list of array elements. [ a, b, , c, ]
  3162. ***************************************************************************/
  3163. template<bool buildAST>
  3164. ParseNodePtr Parser::ParseArrayList(bool *pArrayOfTaggedInts, bool *pArrayOfInts, bool *pArrayOfNumbers, bool *pHasMissingValues, uint *count, uint *spreadCount)
  3165. {
  3166. ParseNodePtr pnodeArg = nullptr;
  3167. ParseNodePtr pnodeList = nullptr;
  3168. ParseNodePtr *lastNodeRef = nullptr;
  3169. *count = 0;
  3170. // Check for an empty list
  3171. if (tkRBrack == m_token.tk)
  3172. {
  3173. return nullptr;
  3174. }
  3175. this->m_arrayDepth++;
  3176. bool arrayOfTaggedInts = buildAST;
  3177. bool arrayOfInts = buildAST;
  3178. bool arrayOfNumbers = buildAST;
  3179. bool arrayOfVarInts = false;
  3180. bool hasMissingValues = false;
  3181. for (;;)
  3182. {
  3183. (*count)++;
  3184. if (tkComma == m_token.tk || tkRBrack == m_token.tk)
  3185. {
  3186. hasMissingValues = true;
  3187. arrayOfTaggedInts = false;
  3188. arrayOfInts = false;
  3189. arrayOfNumbers = false;
  3190. if (buildAST)
  3191. {
  3192. pnodeArg = CreateNodeWithScanner<knopEmpty>();
  3193. }
  3194. }
  3195. else
  3196. {
  3197. // Allow Spread in array literals.
  3198. pnodeArg = ParseExpr<buildAST>(koplCma, nullptr, TRUE, /* fAllowEllipsis */ TRUE);
  3199. if (buildAST)
  3200. {
  3201. if (pnodeArg->nop == knopEllipsis)
  3202. {
  3203. (*spreadCount)++;
  3204. }
  3205. this->CheckArguments(pnodeArg);
  3206. }
  3207. }
  3208. #if DEBUG
  3209. if(m_grfscr & fscrEnforceJSON && !IsJSONValid(pnodeArg))
  3210. {
  3211. Error(ERRsyntax);
  3212. }
  3213. #endif
  3214. if (buildAST)
  3215. {
  3216. if (arrayOfNumbers)
  3217. {
  3218. if (pnodeArg->nop != knopInt)
  3219. {
  3220. arrayOfTaggedInts = false;
  3221. if (pnodeArg->nop != knopFlt)
  3222. {
  3223. // Not an array of constants.
  3224. arrayOfInts = false;
  3225. arrayOfNumbers = false;
  3226. }
  3227. else if (arrayOfInts && Js::JavascriptNumber::IsInt32OrUInt32(pnodeArg->sxFlt.dbl) && (!Js::JavascriptNumber::IsInt32(pnodeArg->sxFlt.dbl) || pnodeArg->sxFlt.dbl == -2147483648.0))
  3228. {
  3229. // We've seen nothing but ints, and this is a uint32 but not an int32.
  3230. // Unless we see an actual float at some point, we want an array of vars
  3231. // so we can work with tagged ints.
  3232. arrayOfVarInts = true;
  3233. }
  3234. else
  3235. {
  3236. // Not an int array, but it may still be a float array.
  3237. arrayOfInts = false;
  3238. }
  3239. }
  3240. else
  3241. {
  3242. if (Js::SparseArraySegment<int32>::IsMissingItem((int32*)&pnodeArg->sxInt.lw))
  3243. {
  3244. arrayOfInts = false;
  3245. }
  3246. if (Js::TaggedInt::IsOverflow(pnodeArg->sxInt.lw))
  3247. {
  3248. arrayOfTaggedInts = false;
  3249. }
  3250. }
  3251. }
  3252. AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeArg);
  3253. }
  3254. if (tkComma != m_token.tk)
  3255. {
  3256. break;
  3257. }
  3258. m_pscan->Scan();
  3259. if (tkRBrack == m_token.tk)
  3260. {
  3261. break;
  3262. }
  3263. }
  3264. if (spreadCount != nullptr && *spreadCount > 0){
  3265. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(SpreadFeatureCount, m_scriptContext);
  3266. }
  3267. if (buildAST)
  3268. {
  3269. AssertMem(lastNodeRef);
  3270. AssertNodeMem(*lastNodeRef);
  3271. pnodeList->ichLim = (*lastNodeRef)->ichLim;
  3272. if (arrayOfVarInts && arrayOfInts)
  3273. {
  3274. arrayOfInts = false;
  3275. arrayOfNumbers = false;
  3276. }
  3277. *pArrayOfTaggedInts = arrayOfTaggedInts;
  3278. *pArrayOfInts = arrayOfInts;
  3279. *pArrayOfNumbers = arrayOfNumbers;
  3280. *pHasMissingValues = hasMissingValues;
  3281. }
  3282. this->m_arrayDepth--;
  3283. return pnodeList;
  3284. }
  3285. Parser::MemberNameToTypeMap* Parser::CreateMemberNameMap(ArenaAllocator* pAllocator)
  3286. {
  3287. Assert(pAllocator);
  3288. return Anew(pAllocator, MemberNameToTypeMap, pAllocator, 5);
  3289. }
  3290. template<bool buildAST> void Parser::ParseComputedName(ParseNodePtr* ppnodeName, LPCOLESTR* ppNameHint, LPCOLESTR* ppFullNameHint, ulong *pNameLength, ulong *pShortNameOffset)
  3291. {
  3292. m_pscan->Scan();
  3293. ParseNodePtr pnodeNameExpr = ParseExpr<buildAST>(koplCma, nullptr, TRUE, FALSE, *ppNameHint, pNameLength, pShortNameOffset);
  3294. if (buildAST)
  3295. {
  3296. *ppnodeName = CreateNodeT<knopComputedName>(pnodeNameExpr->ichMin, pnodeNameExpr->ichLim);
  3297. (*ppnodeName)->sxUni.pnode1 = pnodeNameExpr;
  3298. }
  3299. if (ppFullNameHint && buildAST && CONFIG_FLAG(UseFullName))
  3300. {
  3301. *ppFullNameHint = FormatPropertyString(*ppNameHint, pnodeNameExpr, pNameLength, pShortNameOffset);
  3302. }
  3303. ChkCurTokNoScan(tkRBrack, ERRnoRbrack);
  3304. }
  3305. /***************************************************************************
  3306. Parse a list of object set/get members, e.g.:
  3307. { get foo(){ ... }, set bar(arg) { ... } }
  3308. ***************************************************************************/
  3309. template<bool buildAST>
  3310. ParseNodePtr Parser::ParseMemberGetSet(OpCode nop, LPCOLESTR* ppNameHint)
  3311. {
  3312. ParseNodePtr pnodeName = nullptr;
  3313. Assert(nop == knopGetMember || nop == knopSetMember);
  3314. AssertMem(ppNameHint);
  3315. IdentPtr pid = nullptr;
  3316. bool isComputedName = false;
  3317. *ppNameHint=nullptr;
  3318. switch(m_token.tk)
  3319. {
  3320. default:
  3321. if (!m_token.IsReservedWord())
  3322. {
  3323. Error(ERRnoMemberIdent);
  3324. }
  3325. // fall through
  3326. case tkID:
  3327. pid = m_token.GetIdentifier(m_phtbl);
  3328. *ppNameHint = pid->Psz();
  3329. if (buildAST)
  3330. {
  3331. pnodeName = CreateStrNodeWithScanner(pid);
  3332. }
  3333. break;
  3334. case tkStrCon:
  3335. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  3336. {
  3337. Error(ERRES5NoOctal);
  3338. }
  3339. pid = m_token.GetStr();
  3340. *ppNameHint = pid->Psz();
  3341. if (buildAST)
  3342. {
  3343. pnodeName = CreateStrNodeWithScanner(pid);
  3344. }
  3345. break;
  3346. case tkIntCon:
  3347. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  3348. {
  3349. Error(ERRES5NoOctal);
  3350. }
  3351. pid = m_pscan->PidFromLong(m_token.GetLong());
  3352. if (buildAST)
  3353. {
  3354. pnodeName = CreateStrNodeWithScanner(pid);
  3355. }
  3356. break;
  3357. case tkFltCon:
  3358. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  3359. {
  3360. Error(ERRES5NoOctal);
  3361. }
  3362. pid = m_pscan->PidFromDbl(m_token.GetDouble());
  3363. if (buildAST)
  3364. {
  3365. pnodeName = CreateStrNodeWithScanner(pid);
  3366. }
  3367. break;
  3368. case tkLBrack:
  3369. // Computed property name: get|set [expr] () { }
  3370. if (!m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  3371. {
  3372. Error(ERRnoMemberIdent);
  3373. }
  3374. LPCOLESTR emptyHint = nullptr;
  3375. ulong offset = 0;
  3376. ParseComputedName<buildAST>(&pnodeName, &emptyHint, ppNameHint, &offset);
  3377. isComputedName = true;
  3378. break;
  3379. }
  3380. MemberType memberType;
  3381. ushort flags = fFncMethod | fFncNoName;
  3382. if (nop == knopGetMember)
  3383. {
  3384. memberType = MemberTypeGetter;
  3385. flags |= fFncNoArg;
  3386. }
  3387. else
  3388. {
  3389. Assert(nop == knopSetMember);
  3390. memberType = MemberTypeSetter;
  3391. flags |= fFncOneArg;
  3392. }
  3393. this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperPropertyAllowed;
  3394. ParseNodePtr pnodeFnc = ParseFncDecl<buildAST>(flags, *ppNameHint,
  3395. /*needsPIDOnRCurlyScan*/ false, /*resetParsingSuperRestrictionState*/ false);
  3396. if (buildAST)
  3397. {
  3398. pnodeFnc->sxFnc.SetIsAccessor();
  3399. return CreateBinNode(nop, pnodeName, pnodeFnc);
  3400. }
  3401. else
  3402. {
  3403. return nullptr;
  3404. }
  3405. }
  3406. /***************************************************************************
  3407. Parse a list of object members. e.g. { x:foo, 'y me':bar }
  3408. ***************************************************************************/
  3409. template<bool buildAST>
  3410. ParseNodePtr Parser::ParseMemberList(LPCOLESTR pNameHint, ulong* pNameHintLength, tokens declarationType)
  3411. {
  3412. ParseNodePtr pnodeArg = nullptr;
  3413. ParseNodePtr pnodeName = nullptr;
  3414. ParseNodePtr pnodeList = nullptr;
  3415. ParseNodePtr *lastNodeRef = nullptr;
  3416. LPCOLESTR pFullNameHint = nullptr; // A calculated full name
  3417. ulong fullNameHintLength = pNameHintLength ? *pNameHintLength : 0;
  3418. ulong shortNameOffset = 0;
  3419. bool isProtoDeclared = false;
  3420. // we get declaration tkLCurly - when the possible object pattern found under the expression.
  3421. bool isObjectPattern = (declarationType == tkVAR || declarationType == tkLET || declarationType == tkCONST || declarationType == tkLCurly) && IsES6DestructuringEnabled();
  3422. // Check for an empty list
  3423. if (tkRCurly == m_token.tk)
  3424. {
  3425. return nullptr;
  3426. }
  3427. ArenaAllocator tempAllocator(_u("MemberNames"), m_nodeAllocator.GetPageAllocator(), Parser::OutOfMemory);
  3428. bool hasDeferredInitError = false;
  3429. for (;;)
  3430. {
  3431. bool isComputedName = false;
  3432. #if DEBUG
  3433. if((m_grfscr & fscrEnforceJSON) && (tkStrCon != m_token.tk || !(m_pscan->IsDoubleQuoteOnLastTkStrCon())))
  3434. {
  3435. Error(ERRsyntax);
  3436. }
  3437. #endif
  3438. bool isAsyncMethod = false;
  3439. charcount_t ichMin = 0;
  3440. size_t iecpMin = 0;
  3441. if (m_token.tk == tkID && m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.async && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  3442. {
  3443. RestorePoint parsedAsync;
  3444. m_pscan->Capture(&parsedAsync);
  3445. ichMin = m_pscan->IchMinTok();
  3446. iecpMin = m_pscan->IecpMinTok();
  3447. m_pscan->ScanForcingPid();
  3448. if (m_token.tk == tkLParen || m_token.tk == tkColon || m_token.tk == tkRCurly || m_pscan->FHadNewLine())
  3449. {
  3450. m_pscan->SeekTo(parsedAsync);
  3451. }
  3452. else
  3453. {
  3454. isAsyncMethod = true;
  3455. }
  3456. }
  3457. bool isGenerator = m_scriptContext->GetConfig()->IsES6GeneratorsEnabled() &&
  3458. m_token.tk == tkStar;
  3459. ushort fncDeclFlags = fFncNoName | fFncMethod;
  3460. if (isGenerator)
  3461. {
  3462. if (isAsyncMethod)
  3463. {
  3464. Error(ERRsyntax);
  3465. }
  3466. m_pscan->ScanForcingPid();
  3467. fncDeclFlags |= fFncGenerator;
  3468. }
  3469. IdentPtr pidHint = nullptr; // A name scoped to current expression
  3470. Token tkHint = m_token;
  3471. charcount_t idHintIchMin = static_cast<charcount_t>(m_pscan->IecpMinTok());
  3472. charcount_t idHintIchLim = static_cast< charcount_t >(m_pscan->IecpLimTok());
  3473. bool wrapInBrackets = false;
  3474. switch (m_token.tk)
  3475. {
  3476. default:
  3477. if (!m_token.IsReservedWord())
  3478. {
  3479. Error(ERRnoMemberIdent);
  3480. }
  3481. // allow reserved words
  3482. wrapInBrackets = true;
  3483. // fall-through
  3484. case tkID:
  3485. pidHint = m_token.GetIdentifier(m_phtbl);
  3486. if (buildAST)
  3487. {
  3488. pnodeName = CreateStrNodeWithScanner(pidHint);
  3489. }
  3490. break;
  3491. case tkStrCon:
  3492. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  3493. {
  3494. Error(ERRES5NoOctal);
  3495. }
  3496. wrapInBrackets = true;
  3497. pidHint = m_token.GetStr();
  3498. if (buildAST)
  3499. {
  3500. pnodeName = CreateStrNodeWithScanner(pidHint);
  3501. }
  3502. break;
  3503. case tkIntCon:
  3504. // Object initializers with numeric labels allowed in JS6
  3505. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  3506. {
  3507. Error(ERRES5NoOctal);
  3508. }
  3509. pidHint = m_pscan->PidFromLong(m_token.GetLong());
  3510. if (buildAST)
  3511. {
  3512. pnodeName = CreateStrNodeWithScanner(pidHint);
  3513. }
  3514. break;
  3515. case tkFltCon:
  3516. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  3517. {
  3518. Error(ERRES5NoOctal);
  3519. }
  3520. pidHint = m_pscan->PidFromDbl(m_token.GetDouble());
  3521. if (buildAST)
  3522. {
  3523. pnodeName = CreateStrNodeWithScanner(pidHint);
  3524. }
  3525. wrapInBrackets = true;
  3526. break;
  3527. case tkLBrack:
  3528. // Computed property name: [expr] : value
  3529. if (!m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  3530. {
  3531. Error(ERRnoMemberIdent);
  3532. }
  3533. ParseComputedName<buildAST>(&pnodeName, &pNameHint, &pFullNameHint, &fullNameHintLength, &shortNameOffset);
  3534. isComputedName = true;
  3535. break;
  3536. }
  3537. if (pFullNameHint == nullptr)
  3538. {
  3539. if (CONFIG_FLAG(UseFullName))
  3540. {
  3541. pFullNameHint = AppendNameHints(pNameHint, pidHint, &fullNameHintLength, &shortNameOffset, false, wrapInBrackets);
  3542. }
  3543. else
  3544. {
  3545. pFullNameHint = pidHint? pidHint->Psz() : nullptr;
  3546. fullNameHintLength = pidHint ? pidHint->Cch() : 0;
  3547. shortNameOffset = 0;
  3548. }
  3549. }
  3550. RestorePoint atPid;
  3551. m_pscan->Capture(&atPid);
  3552. m_pscan->ScanForcingPid();
  3553. if (isGenerator && m_token.tk != tkLParen)
  3554. {
  3555. Error(ERRnoLparen);
  3556. }
  3557. if (tkColon == m_token.tk)
  3558. {
  3559. // It is a syntax error is the production of the form __proto__ : <> occurs more than once. From B.3.1 in spec.
  3560. // Note that previous scan is important because only after that we can determine we have a variable.
  3561. if (!isComputedName && pidHint == wellKnownPropertyPids.__proto__)
  3562. {
  3563. if (isProtoDeclared)
  3564. {
  3565. Error(ERRsyntax);
  3566. }
  3567. else
  3568. {
  3569. isProtoDeclared = true;
  3570. }
  3571. }
  3572. m_pscan->Scan();
  3573. ParseNodePtr pnodeExpr = nullptr;
  3574. if (isObjectPattern)
  3575. {
  3576. if (m_token.tk == tkEllipsis)
  3577. {
  3578. Error(ERRUnexpectedEllipsis);
  3579. }
  3580. pnodeExpr = ParseDestructuredVarDecl<buildAST>(declarationType, declarationType != tkLCurly, nullptr/* *hasSeenRest*/, false /*topLevel*/, false /*allowEmptyExpression*/);
  3581. if (m_token.tk != tkComma && m_token.tk != tkRCurly)
  3582. {
  3583. if (m_token.IsOperator())
  3584. {
  3585. Error(ERRDestructNoOper);
  3586. }
  3587. Error(ERRsyntax);
  3588. }
  3589. }
  3590. else
  3591. {
  3592. pnodeExpr = ParseExpr<buildAST>(koplCma, nullptr, TRUE, FALSE, pFullNameHint, &fullNameHintLength, &shortNameOffset);
  3593. }
  3594. #if DEBUG
  3595. if((m_grfscr & fscrEnforceJSON) && !IsJSONValid(pnodeExpr))
  3596. {
  3597. Error(ERRsyntax);
  3598. }
  3599. #endif
  3600. if (buildAST)
  3601. {
  3602. pnodeArg = CreateBinNode(isObjectPattern ? knopObjectPatternMember : knopMember, pnodeName, pnodeExpr);
  3603. if (pnodeArg->sxBin.pnode1->nop == knopStr)
  3604. {
  3605. pnodeArg->sxBin.pnode1->sxPid.pid->PromoteAssignmentState();
  3606. }
  3607. }
  3608. }
  3609. else if (m_token.tk == tkLParen && m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  3610. {
  3611. if (isObjectPattern)
  3612. {
  3613. Error(ERRInvalidAssignmentTarget);
  3614. }
  3615. // Shorthand syntax: foo() {} -> foo: function() {}
  3616. // Rewind to the PID and parse a function expression.
  3617. m_pscan->SeekTo(atPid);
  3618. this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperPropertyAllowed;
  3619. ParseNodePtr pnodeFunc = ParseFncDecl<buildAST>(fncDeclFlags | (isAsyncMethod ? fFncAsync : fFncNoFlgs), pFullNameHint,
  3620. /*needsPIDOnRCurlyScan*/ false, /*resetParsingSuperRestrictionState*/ false);
  3621. if (isAsyncMethod)
  3622. {
  3623. pnodeFunc->sxFnc.cbMin = iecpMin;
  3624. pnodeFunc->ichMin = ichMin;
  3625. }
  3626. if (buildAST)
  3627. {
  3628. pnodeArg = CreateBinNode(knopMember, pnodeName, pnodeFunc);
  3629. }
  3630. }
  3631. else if (nullptr != pidHint) //Its either tkID/tkStrCon/tkFloatCon/tkIntCon
  3632. {
  3633. Assert(pidHint->Psz() != nullptr);
  3634. if ((pidHint == wellKnownPropertyPids.get || pidHint == wellKnownPropertyPids.set) &&
  3635. // get/set are only pseudo keywords when they are identifiers (i.e. not strings)
  3636. tkHint.tk == tkID && NextTokenIsPropertyNameStart())
  3637. {
  3638. if (isObjectPattern)
  3639. {
  3640. Error(ERRInvalidAssignmentTarget);
  3641. }
  3642. LPCOLESTR pNameGetOrSet = nullptr;
  3643. OpCode op = pidHint == wellKnownPropertyPids.get ? knopGetMember : knopSetMember;
  3644. pnodeArg = ParseMemberGetSet<buildAST>(op, &pNameGetOrSet);
  3645. if (CONFIG_FLAG(UseFullName) && buildAST && pnodeArg->sxBin.pnode2->nop == knopFncDecl)
  3646. {
  3647. if (m_scriptContext->GetConfig()->IsES6FunctionNameEnabled())
  3648. {
  3649. // displays as "get object.funcname" or "set object.funcname"
  3650. ulong getOrSetOffset = 0;
  3651. LPCOLESTR intermediateHint = AppendNameHints(pNameHint, pNameGetOrSet, &fullNameHintLength, &shortNameOffset);
  3652. pFullNameHint = AppendNameHints(pidHint, intermediateHint, &fullNameHintLength, &getOrSetOffset, true);
  3653. shortNameOffset += getOrSetOffset;
  3654. }
  3655. else
  3656. {
  3657. // displays as "object.funcname.get" or "object.funcname.set"
  3658. LPCOLESTR intermediateHint = AppendNameHints(pNameGetOrSet, pidHint, &fullNameHintLength, &shortNameOffset);
  3659. pFullNameHint = AppendNameHints(pNameHint, intermediateHint, &fullNameHintLength, &shortNameOffset);
  3660. }
  3661. }
  3662. }
  3663. else if ((m_token.tk == tkRCurly || m_token.tk == tkComma || m_token.tk == tkAsg) && m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  3664. {
  3665. // Shorthand {foo} -> {foo:foo} syntax.
  3666. // {foo = <initializer>} supported only when on object pattern rules are being applied
  3667. if (tkHint.tk != tkID)
  3668. {
  3669. Assert(tkHint.IsReservedWord()
  3670. || tkHint.tk == tkIntCon || tkHint.tk == tkFltCon || tkHint.tk == tkStrCon);
  3671. // All keywords are banned in non-strict mode.
  3672. // Future reserved words are banned in strict mode.
  3673. if (IsStrictMode() || !tkHint.IsFutureReservedWord(true))
  3674. {
  3675. IdentifierExpectedError(tkHint);
  3676. }
  3677. }
  3678. if (buildAST)
  3679. {
  3680. CheckArgumentsUse(pidHint, GetCurrentFunctionNode());
  3681. }
  3682. bool couldBeObjectPattern = !isObjectPattern && m_token.tk == tkAsg;
  3683. if (couldBeObjectPattern)
  3684. {
  3685. declarationType = tkLCurly;
  3686. isObjectPattern = true;
  3687. // This may be an error but we are deferring for favouring destructuring.
  3688. hasDeferredInitError = true;
  3689. }
  3690. ParseNodePtr pnodeIdent = nullptr;
  3691. if (isObjectPattern)
  3692. {
  3693. m_pscan->SeekTo(atPid);
  3694. pnodeIdent = ParseDestructuredVarDecl<buildAST>(declarationType, declarationType != tkLCurly, nullptr/* *hasSeenRest*/, false /*topLevel*/, false /*allowEmptyExpression*/);
  3695. if (m_token.tk != tkComma && m_token.tk != tkRCurly)
  3696. {
  3697. if (m_token.IsOperator())
  3698. {
  3699. Error(ERRDestructNoOper);
  3700. }
  3701. Error(ERRsyntax);
  3702. }
  3703. }
  3704. if (buildAST)
  3705. {
  3706. if (!isObjectPattern)
  3707. {
  3708. pnodeIdent = CreateNameNode(pidHint, idHintIchMin, idHintIchLim);
  3709. PidRefStack *ref = PushPidRef(pidHint);
  3710. pnodeIdent->sxPid.SetSymRef(ref);
  3711. }
  3712. pnodeArg = CreateBinNode(isObjectPattern && !couldBeObjectPattern ? knopObjectPatternMember : knopMemberShort, pnodeName, pnodeIdent);
  3713. }
  3714. }
  3715. else
  3716. {
  3717. Error(ERRnoColon);
  3718. }
  3719. }
  3720. else
  3721. {
  3722. Error(ERRnoColon);
  3723. }
  3724. if (buildAST)
  3725. {
  3726. Assert(pnodeArg->sxBin.pnode2 != nullptr);
  3727. if (pnodeArg->sxBin.pnode2->nop == knopFncDecl)
  3728. {
  3729. Assert(fullNameHintLength >= shortNameOffset);
  3730. pnodeArg->sxBin.pnode2->sxFnc.hint = pFullNameHint;
  3731. pnodeArg->sxBin.pnode2->sxFnc.hintLength = fullNameHintLength;
  3732. pnodeArg->sxBin.pnode2->sxFnc.hintOffset = shortNameOffset;
  3733. }
  3734. AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeArg);
  3735. }
  3736. pidHint = nullptr;
  3737. pFullNameHint = nullptr;
  3738. if (tkComma != m_token.tk)
  3739. {
  3740. break;
  3741. }
  3742. m_pscan->ScanForcingPid();
  3743. if (tkRCurly == m_token.tk)
  3744. {
  3745. break;
  3746. }
  3747. }
  3748. m_hasDeferredShorthandInitError = m_hasDeferredShorthandInitError || hasDeferredInitError;
  3749. if (buildAST)
  3750. {
  3751. AssertMem(lastNodeRef);
  3752. AssertNodeMem(*lastNodeRef);
  3753. pnodeList->ichLim = (*lastNodeRef)->ichLim;
  3754. }
  3755. return pnodeList;
  3756. }
  3757. BOOL Parser::DeferredParse(Js::LocalFunctionId functionId)
  3758. {
  3759. if ((m_grfscr & fscrDeferFncParse) != 0)
  3760. {
  3761. if (m_stoppedDeferredParse)
  3762. {
  3763. return false;
  3764. }
  3765. if (PHASE_OFF_RAW(Js::DeferParsePhase, m_sourceContextInfo->sourceContextId, functionId))
  3766. {
  3767. return false;
  3768. }
  3769. if (PHASE_FORCE_RAW(Js::DeferParsePhase, m_sourceContextInfo->sourceContextId, functionId))
  3770. {
  3771. return true;
  3772. }
  3773. #if ENABLE_PROFILE_INFO
  3774. #ifndef DISABLE_DYNAMIC_PROFILE_DEFER_PARSE
  3775. if (m_sourceContextInfo->sourceDynamicProfileManager != nullptr)
  3776. {
  3777. Js::ExecutionFlags flags = m_sourceContextInfo->sourceDynamicProfileManager->IsFunctionExecuted(functionId);
  3778. return flags != Js::ExecutionFlags_Executed;
  3779. }
  3780. #endif
  3781. #endif
  3782. return true;
  3783. }
  3784. return false;
  3785. }
  3786. //
  3787. // Call this in ParseFncDecl only to check (and reset) if ParseFncDecl is re-parsing a deferred
  3788. // function body. If a deferred function is called and being re-parsed, it shouldn't be deferred again.
  3789. //
  3790. BOOL Parser::IsDeferredFnc()
  3791. {
  3792. if (m_grfscr & fscrDeferredFnc)
  3793. {
  3794. m_grfscr &= ~fscrDeferredFnc;
  3795. return true;
  3796. }
  3797. return false;
  3798. }
  3799. template<bool buildAST>
  3800. ParseNodePtr Parser::ParseFncDecl(ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool resetParsingSuperRestrictionState, bool fUnaryOrParen)
  3801. {
  3802. AutoParsingSuperRestrictionStateRestorer restorer(this);
  3803. if (resetParsingSuperRestrictionState)
  3804. {
  3805. // ParseFncDecl will always reset m_parsingSuperRestrictionState to super disallowed unless explicitly disabled
  3806. this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperDisallowed;
  3807. }
  3808. ParseNodePtr pnodeFnc = nullptr;
  3809. ParseNodePtr *ppnodeVarSave = nullptr;
  3810. ParseNodePtr pnodeFncSave = nullptr;
  3811. ParseNodePtr pnodeFncSaveNonLambda = nullptr;
  3812. ParseNodePtr pnodeFncBlockScope = nullptr;
  3813. ParseNodePtr *ppnodeScopeSave = nullptr;
  3814. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  3815. bool funcHasName = false;
  3816. bool fDeclaration = flags & fFncDeclaration;
  3817. bool fLambda = (flags & fFncLambda) != 0;
  3818. charcount_t ichMin = this->m_pscan->IchMinTok();
  3819. bool wasInDeferredNestedFunc = false;
  3820. uint tryCatchOrFinallyDepthSave = this->m_tryCatchOrFinallyDepth;
  3821. this->m_tryCatchOrFinallyDepth = 0;
  3822. if (this->m_arrayDepth)
  3823. {
  3824. this->m_funcInArrayDepth++; // Count function depth within array literal
  3825. }
  3826. // Update the count of functions nested in the current parent.
  3827. Assert(m_pnestedCount || !buildAST);
  3828. uint *pnestedCountSave = m_pnestedCount;
  3829. if (buildAST || m_pnestedCount)
  3830. {
  3831. (*m_pnestedCount)++;
  3832. }
  3833. uint scopeCountNoAstSave = m_scopeCountNoAst;
  3834. m_scopeCountNoAst = 0;
  3835. long* pAstSizeSave = m_pCurrentAstSize;
  3836. bool noStmtContext = false;
  3837. if (fDeclaration)
  3838. {
  3839. AnalysisAssert(m_pstmtCur->isDeferred || m_pstmtCur->pnodeStmt != nullptr);
  3840. noStmtContext =
  3841. (m_pstmtCur->isDeferred && m_pstmtCur->op != knopBlock) ||
  3842. (!m_pstmtCur->isDeferred && m_pstmtCur->pnodeStmt->nop != knopBlock);
  3843. if (noStmtContext)
  3844. {
  3845. // We have a function declaration like "if (a) function f() {}". We didn't see
  3846. // a block scope on the way in, so we need to pretend we did. Note that this is a syntax error
  3847. // in strict mode.
  3848. if (!this->FncDeclAllowedWithoutContext(flags))
  3849. {
  3850. Error(ERRsyntax);
  3851. }
  3852. pnodeFncBlockScope = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block);
  3853. if (buildAST)
  3854. {
  3855. PushFuncBlockScope(pnodeFncBlockScope, &ppnodeScopeSave, &ppnodeExprScopeSave);
  3856. }
  3857. }
  3858. }
  3859. // Create the node.
  3860. pnodeFnc = CreateNode(knopFncDecl);
  3861. pnodeFnc->sxFnc.ClearFlags();
  3862. pnodeFnc->sxFnc.SetDeclaration(fDeclaration);
  3863. pnodeFnc->sxFnc.astSize = 0;
  3864. pnodeFnc->sxFnc.pnodeName = nullptr;
  3865. pnodeFnc->sxFnc.pnodeScopes = nullptr;
  3866. pnodeFnc->sxFnc.pnodeRest = nullptr;
  3867. pnodeFnc->sxFnc.pid = nullptr;
  3868. pnodeFnc->sxFnc.hint = nullptr;
  3869. pnodeFnc->sxFnc.hintOffset = 0;
  3870. pnodeFnc->sxFnc.hintLength = 0;
  3871. pnodeFnc->sxFnc.isNameIdentifierRef = true;
  3872. pnodeFnc->sxFnc.pnodeNext = nullptr;
  3873. pnodeFnc->sxFnc.pnodeParams = nullptr;
  3874. pnodeFnc->sxFnc.pnodeVars = nullptr;
  3875. pnodeFnc->sxFnc.funcInfo = nullptr;
  3876. pnodeFnc->sxFnc.deferredStub = nullptr;
  3877. pnodeFnc->sxFnc.nestedCount = 0;
  3878. pnodeFnc->sxFnc.cbMin = m_pscan->IecpMinTok();
  3879. pnodeFnc->sxFnc.functionId = (*m_nextFunctionId)++;
  3880. // Push new parser state with this new function node
  3881. AppendFunctionToScopeList(fDeclaration, pnodeFnc);
  3882. // Start the argument list.
  3883. ppnodeVarSave = m_ppnodeVar;
  3884. if (buildAST)
  3885. {
  3886. pnodeFnc->sxFnc.lineNumber = m_pscan->LineCur();
  3887. pnodeFnc->sxFnc.columnNumber = CalculateFunctionColumnNumber();
  3888. pnodeFnc->sxFnc.SetNested(m_currentNodeFunc != nullptr); // If there is a current function, then we're a nested function.
  3889. pnodeFnc->sxFnc.SetStrictMode(IsStrictMode()); // Inherit current strict mode -- may be overridden by the function itself if it contains a strict mode directive.
  3890. pnodeFnc->sxFnc.firstDefaultArg = 0;
  3891. m_pCurrentAstSize = &pnodeFnc->sxFnc.astSize;
  3892. // Make this the current function and start its sub-function list.
  3893. pnodeFncSave = m_currentNodeFunc;
  3894. m_currentNodeFunc = pnodeFnc;
  3895. Assert(m_currentNodeDeferredFunc == nullptr);
  3896. if (!fLambda)
  3897. {
  3898. pnodeFncSaveNonLambda = m_currentNodeNonLambdaFunc;
  3899. m_currentNodeNonLambdaFunc = pnodeFnc;
  3900. }
  3901. m_pnestedCount = &pnodeFnc->sxFnc.nestedCount;
  3902. }
  3903. else // if !buildAST
  3904. {
  3905. wasInDeferredNestedFunc = m_inDeferredNestedFunc;
  3906. m_inDeferredNestedFunc = true;
  3907. AnalysisAssert(pnodeFnc);
  3908. if (!fLambda)
  3909. {
  3910. pnodeFncSaveNonLambda = m_currentNodeNonLambdaDeferredFunc;
  3911. m_currentNodeNonLambdaDeferredFunc = pnodeFnc;
  3912. }
  3913. pnodeFncSave = m_currentNodeDeferredFunc;
  3914. m_currentNodeDeferredFunc = pnodeFnc;
  3915. m_pnestedCount = &pnodeFnc->sxFnc.nestedCount;
  3916. }
  3917. AnalysisAssert(pnodeFnc);
  3918. pnodeFnc->sxFnc.SetIsAsync((flags & fFncAsync) != 0);
  3919. pnodeFnc->sxFnc.SetIsLambda(fLambda);
  3920. pnodeFnc->sxFnc.SetIsMethod((flags & fFncMethod) != 0);
  3921. pnodeFnc->sxFnc.SetIsClassMember((flags & fFncClassMember) != 0);
  3922. bool needScanRCurly = true;
  3923. bool result = ParseFncDeclHelper<buildAST>(pnodeFnc, pnodeFncSave, pNameHint, flags, &funcHasName, fUnaryOrParen, noStmtContext, &needScanRCurly);
  3924. if (!result)
  3925. {
  3926. Assert(!pnodeFncBlockScope);
  3927. return pnodeFnc;
  3928. }
  3929. AnalysisAssert(pnodeFnc);
  3930. *m_ppnodeVar = nullptr;
  3931. m_ppnodeVar = ppnodeVarSave;
  3932. // Restore the current function.
  3933. if (buildAST)
  3934. {
  3935. Assert(pnodeFnc == m_currentNodeFunc);
  3936. m_currentNodeFunc = pnodeFncSave;
  3937. m_pCurrentAstSize = pAstSizeSave;
  3938. if (!fLambda)
  3939. {
  3940. Assert(pnodeFnc == m_currentNodeNonLambdaFunc);
  3941. m_currentNodeNonLambdaFunc = pnodeFncSaveNonLambda;
  3942. }
  3943. }
  3944. else
  3945. {
  3946. Assert(pnodeFnc == m_currentNodeDeferredFunc);
  3947. if (!fLambda)
  3948. {
  3949. Assert(pnodeFnc == m_currentNodeNonLambdaDeferredFunc);
  3950. m_currentNodeNonLambdaDeferredFunc = pnodeFncSaveNonLambda;
  3951. }
  3952. m_currentNodeDeferredFunc = pnodeFncSave;
  3953. }
  3954. if (m_currentNodeFunc && pnodeFnc->sxFnc.HasWithStmt())
  3955. {
  3956. GetCurrentFunctionNode()->sxFnc.SetHasWithStmt(true);
  3957. }
  3958. if (m_currentNodeFunc && (pnodeFnc->sxFnc.CallsEval() || pnodeFnc->sxFnc.ChildCallsEval()))
  3959. {
  3960. GetCurrentFunctionNode()->sxFnc.SetChildCallsEval(true);
  3961. }
  3962. // Lambdas do not have "arguments" and instead capture their parent's
  3963. // binding of "arguments. To ensure the arguments object of the enclosing
  3964. // non-lambda function is loaded propagate the UsesArguments flag up to
  3965. // the parent function
  3966. if ((flags & fFncLambda) != 0 && pnodeFnc->sxFnc.UsesArguments())
  3967. {
  3968. if (pnodeFncSave != nullptr)
  3969. {
  3970. pnodeFncSave->sxFnc.SetUsesArguments();
  3971. }
  3972. else
  3973. {
  3974. m_UsesArgumentsAtGlobal = true;
  3975. }
  3976. }
  3977. if (needScanRCurly)
  3978. {
  3979. // Consume the next token now that we're back in the enclosing function (whose strictness may be
  3980. // different from the function we just finished).
  3981. #if DBG
  3982. bool expectedTokenValid = m_token.tk == tkRCurly;
  3983. AssertMsg(expectedTokenValid, "Invalid token expected for RCurly match");
  3984. #endif
  3985. // The next token may need to have a PID created in !buildAST mode, as we may be parsing a method with a string name.
  3986. if (needsPIDOnRCurlyScan)
  3987. {
  3988. m_pscan->ScanForcingPid();
  3989. }
  3990. else
  3991. {
  3992. m_pscan->Scan();
  3993. }
  3994. }
  3995. m_pnestedCount = pnestedCountSave;
  3996. Assert(!buildAST || !wasInDeferredNestedFunc);
  3997. m_inDeferredNestedFunc = wasInDeferredNestedFunc;
  3998. if (this->m_arrayDepth)
  3999. {
  4000. this->m_funcInArrayDepth--;
  4001. if (this->m_funcInArrayDepth == 0)
  4002. {
  4003. // We disable deferred parsing if array literals dominate.
  4004. // But don't do this if the array literal is dominated by function bodies.
  4005. if (flags & (fFncMethod | fFncClassMember) && m_token.tk != tkSColon)
  4006. {
  4007. // Class member methods have optional separators. We need to check whether we are
  4008. // getting the IchLim of the correct token.
  4009. Assert(m_pscan->m_tkPrevious == tkRCurly && needScanRCurly);
  4010. this->m_funcInArray += m_pscan->IchMinTok() - /*tkRCurly*/ 1 - ichMin;
  4011. }
  4012. else
  4013. {
  4014. this->m_funcInArray += m_pscan->IchLimTok() - ichMin;
  4015. }
  4016. }
  4017. }
  4018. m_scopeCountNoAst = scopeCountNoAstSave;
  4019. if (buildAST && fDeclaration && !IsStrictMode())
  4020. {
  4021. if (pnodeFnc->sxFnc.pnodeName != nullptr && pnodeFnc->sxFnc.pnodeName->nop == knopVarDecl &&
  4022. GetCurrentBlock()->sxBlock.blockType == PnodeBlockType::Regular)
  4023. {
  4024. // Add a function-scoped VarDecl with the same name as the function for
  4025. // back compat with pre-ES6 code that declares functions in blocks. The
  4026. // idea is that the last executed declaration wins at the function scope
  4027. // level and we accomplish this by having each block scoped function
  4028. // declaration assign to both the block scoped "let" binding, as well
  4029. // as the function scoped "var" binding.
  4030. ParseNodePtr vardecl = CreateVarDeclNode(pnodeFnc->sxFnc.pnodeName->sxVar.pid, STVariable, false, nullptr, false);
  4031. vardecl->sxVar.isBlockScopeFncDeclVar = true;
  4032. }
  4033. }
  4034. if (pnodeFncBlockScope)
  4035. {
  4036. Assert(pnodeFncBlockScope->sxBlock.pnodeStmt == nullptr);
  4037. pnodeFncBlockScope->sxBlock.pnodeStmt = pnodeFnc;
  4038. if (buildAST)
  4039. {
  4040. PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
  4041. }
  4042. FinishParseBlock(pnodeFncBlockScope);
  4043. return pnodeFncBlockScope;
  4044. }
  4045. this->m_tryCatchOrFinallyDepth = tryCatchOrFinallyDepthSave;
  4046. return pnodeFnc;
  4047. }
  4048. bool Parser::FncDeclAllowedWithoutContext(ushort flags)
  4049. {
  4050. // Statement context required for strict mode, async functions, and generators.
  4051. // Note that generators aren't detected yet when this method is called; they're checked elsewhere.
  4052. return !IsStrictMode() && !(flags & fFncAsync);
  4053. }
  4054. uint Parser::CalculateFunctionColumnNumber()
  4055. {
  4056. uint columnNumber;
  4057. if (m_pscan->IchMinTok() >= m_pscan->IchMinLine())
  4058. {
  4059. // In scenarios involving defer parse IchMinLine() can be incorrect for the first line after defer parse
  4060. columnNumber = m_pscan->IchMinTok() - m_pscan->IchMinLine();
  4061. if (m_functionBody != nullptr && m_functionBody->GetRelativeLineNumber() == m_pscan->LineCur())
  4062. {
  4063. // Adjust the column if it falls on the first line, where the re-parse is happening.
  4064. columnNumber += m_functionBody->GetRelativeColumnNumber();
  4065. }
  4066. }
  4067. else if (m_currentNodeFunc)
  4068. {
  4069. // For the first line after defer parse, compute the column relative to the column number
  4070. // of the lexically parent function.
  4071. ULONG offsetFromCurrentFunction = m_pscan->IchMinTok() - m_currentNodeFunc->ichMin;
  4072. columnNumber = m_currentNodeFunc->sxFnc.columnNumber + offsetFromCurrentFunction ;
  4073. }
  4074. else
  4075. {
  4076. // if there is no current function, lets give a default of 0.
  4077. columnNumber = 0;
  4078. }
  4079. return columnNumber;
  4080. }
  4081. void Parser::AppendFunctionToScopeList(bool fDeclaration, ParseNodePtr pnodeFnc)
  4082. {
  4083. if (!fDeclaration && m_ppnodeExprScope)
  4084. {
  4085. // We're tracking function expressions separately from declarations in this scope
  4086. // (e.g., inside a catch scope in standards mode).
  4087. Assert(*m_ppnodeExprScope == nullptr);
  4088. *m_ppnodeExprScope = pnodeFnc;
  4089. m_ppnodeExprScope = &pnodeFnc->sxFnc.pnodeNext;
  4090. }
  4091. else
  4092. {
  4093. Assert(*m_ppnodeScope == nullptr);
  4094. *m_ppnodeScope = pnodeFnc;
  4095. m_ppnodeScope = &pnodeFnc->sxFnc.pnodeNext;
  4096. }
  4097. }
  4098. /***************************************************************************
  4099. Parse a function definition.
  4100. ***************************************************************************/
  4101. template<bool buildAST>
  4102. bool Parser::ParseFncDeclHelper(ParseNodePtr pnodeFnc, ParseNodePtr pnodeFncParent, LPCOLESTR pNameHint, ushort flags, bool *pHasName, bool fUnaryOrParen, bool noStmtContext, bool *pNeedScanRCurly)
  4103. {
  4104. bool fDeclaration = (flags & fFncDeclaration) != 0;
  4105. bool fLambda = (flags & fFncLambda) != 0;
  4106. bool fAsync = (flags & fFncAsync) != 0;
  4107. bool fDeferred = false;
  4108. StmtNest *pstmtSave;
  4109. ParseNodePtr *lastNodeRef = nullptr;
  4110. bool fFunctionInBlock = false;
  4111. if (buildAST)
  4112. {
  4113. fFunctionInBlock = GetCurrentBlockInfo() != GetCurrentFunctionBlockInfo() &&
  4114. (GetCurrentBlockInfo()->pnodeBlock->sxBlock.scope == nullptr ||
  4115. GetCurrentBlockInfo()->pnodeBlock->sxBlock.scope->GetScopeType() != ScopeType_GlobalEvalBlock);
  4116. }
  4117. // Save the position of the scanner in case we need to inspect the name hint later
  4118. RestorePoint beginNameHint;
  4119. m_pscan->Capture(&beginNameHint);
  4120. ParseNodePtr pnodeFncExprScope = nullptr;
  4121. Scope *fncExprScope = nullptr;
  4122. if (!fDeclaration)
  4123. {
  4124. pnodeFncExprScope = StartParseBlock<buildAST>(PnodeBlockType::Function, ScopeType_FuncExpr);
  4125. fncExprScope = pnodeFncExprScope->sxBlock.scope;
  4126. }
  4127. *pHasName = !fLambda && this->ParseFncNames<buildAST>(pnodeFnc, pnodeFncParent, flags, &lastNodeRef);
  4128. if (noStmtContext && pnodeFnc->sxFnc.IsGenerator())
  4129. {
  4130. // Generator decl not allowed outside stmt context. (We have to wait until we've parsed the '*' to
  4131. // detect generator.)
  4132. Error(ERRsyntax, pnodeFnc);
  4133. }
  4134. // switch scanner to treat 'yield' as keyword in generator functions
  4135. // or as an identifier in non-generator functions
  4136. bool fPreviousYieldIsKeyword = m_pscan->SetYieldIsKeyword(pnodeFnc && pnodeFnc->sxFnc.IsGenerator());
  4137. bool fPreviousAwaitIsKeyword = m_pscan->SetAwaitIsKeyword(fAsync);
  4138. if (pnodeFnc && pnodeFnc->sxFnc.IsGenerator())
  4139. {
  4140. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(GeneratorCount, m_scriptContext);
  4141. }
  4142. if (fncExprScope && !*pHasName)
  4143. {
  4144. FinishParseBlock(pnodeFncExprScope);
  4145. m_nextBlockId--;
  4146. Adelete(&m_nodeAllocator, fncExprScope);
  4147. fncExprScope = nullptr;
  4148. pnodeFncExprScope = nullptr;
  4149. }
  4150. if (pnodeFnc)
  4151. {
  4152. pnodeFnc->sxFnc.scope = fncExprScope;
  4153. }
  4154. // Start a new statement stack.
  4155. bool topLevelStmt =
  4156. buildAST &&
  4157. !fFunctionInBlock &&
  4158. (this->m_pstmtCur == nullptr || this->m_pstmtCur->pnodeStmt->nop == knopBlock);
  4159. pstmtSave = m_pstmtCur;
  4160. SetCurrentStatement(nullptr);
  4161. // Function definition is inside the parent function's parameter scope
  4162. bool isEnclosedInParamScope = this->m_currentScope->GetScopeType() == ScopeType_Parameter;
  4163. if (this->m_currentScope->GetScopeType() == ScopeType_FuncExpr || this->m_currentScope->GetScopeType() == ScopeType_Block)
  4164. {
  4165. // Or this is a function expression or class enclosed in a parameter scope
  4166. isEnclosedInParamScope = this->m_currentScope->GetEnclosingScope() && this->m_currentScope->GetEnclosingScope()->GetScopeType() == ScopeType_Parameter;
  4167. }
  4168. Assert(!isEnclosedInParamScope || pnodeFncParent->sxFnc.HasNonSimpleParameterList());
  4169. RestorePoint beginFormals;
  4170. m_pscan->Capture(&beginFormals);
  4171. BOOL fWasAlreadyStrictMode = IsStrictMode();
  4172. BOOL oldStrictMode = this->m_fUseStrictMode;
  4173. if (fLambda)
  4174. {
  4175. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(LambdaCount, m_scriptContext);
  4176. }
  4177. uint uDeferSave = m_grfscr & fscrDeferFncParse;
  4178. if ((!fDeclaration && m_ppnodeExprScope) ||
  4179. fFunctionInBlock ||
  4180. isEnclosedInParamScope ||
  4181. (flags & (fFncNoName | fFncLambda)))
  4182. {
  4183. // NOTE: Don't defer if this is a function expression inside a construct that induces
  4184. // a scope nested within the current function (like a with, or a catch in ES5 mode, or
  4185. // any function declared inside a nested lexical block or param scope in ES6 mode).
  4186. // We won't be able to reconstruct the scope chain properly when we come back and
  4187. // try to compile just the function expression.
  4188. // Also shut off deferring on getter/setter or other construct with unusual text bounds
  4189. // (fFncNoName|fFncLambda) as these are usually trivial, and re-parsing is problematic.
  4190. m_grfscr &= ~fscrDeferFncParse;
  4191. }
  4192. bool isTopLevelDeferredFunc = false;
  4193. struct AutoFastScanFlag {
  4194. bool savedDoingFastScan;
  4195. AutoFastScanFlag(Parser *parser) : m_parser(parser) { savedDoingFastScan = m_parser->m_doingFastScan; }
  4196. ~AutoFastScanFlag() { m_parser->m_doingFastScan = savedDoingFastScan; }
  4197. Parser *m_parser;
  4198. } flag(this);
  4199. bool doParallel = false;
  4200. bool parallelJobStarted = false;
  4201. if (buildAST)
  4202. {
  4203. bool isLikelyModulePattern =
  4204. !fDeclaration && pnodeFnc && pnodeFnc->sxFnc.pnodeName == nullptr && fUnaryOrParen;
  4205. BOOL isDeferredFnc = IsDeferredFnc();
  4206. AnalysisAssert(isDeferredFnc || pnodeFnc);
  4207. isTopLevelDeferredFunc =
  4208. (!isDeferredFnc
  4209. && DeferredParse(pnodeFnc->sxFnc.functionId)
  4210. && (!pnodeFnc->sxFnc.IsNested() || CONFIG_FLAG(DeferNested))
  4211. // Don't defer if this is a function expression not contained in a statement or other expression.
  4212. // Assume it will be called as part of this expression.
  4213. && (!isLikelyModulePattern || !topLevelStmt || PHASE_FORCE_RAW(Js::DeferParsePhase, m_sourceContextInfo->sourceContextId, pnodeFnc->sxFnc.functionId))
  4214. && !m_InAsmMode
  4215. );
  4216. if (!fLambda &&
  4217. !isDeferredFnc &&
  4218. !isLikelyModulePattern &&
  4219. !this->IsBackgroundParser() &&
  4220. !this->m_doingFastScan &&
  4221. !(pnodeFncParent && m_currDeferredStub) &&
  4222. !(this->m_parseType == ParseType_Deferred && this->m_functionBody && this->m_functionBody->GetScopeInfo() && !isTopLevelDeferredFunc))
  4223. {
  4224. doParallel = DoParallelParse(pnodeFnc);
  4225. #if ENABLE_BACKGROUND_PARSING
  4226. if (doParallel)
  4227. {
  4228. BackgroundParser *bgp = m_scriptContext->GetBackgroundParser();
  4229. Assert(bgp);
  4230. if (bgp->HasFailedBackgroundParseItem())
  4231. {
  4232. Error(ERRsyntax);
  4233. }
  4234. doParallel = bgp->ParseBackgroundItem(this, pnodeFnc, isTopLevelDeferredFunc);
  4235. if (doParallel)
  4236. {
  4237. parallelJobStarted = true;
  4238. this->m_hasParallelJob = true;
  4239. this->m_doingFastScan = true;
  4240. doParallel = FastScanFormalsAndBody();
  4241. if (doParallel)
  4242. {
  4243. // Let the foreground thread take care of marking the limit on the function node,
  4244. // because in some cases this function's caller will want to change that limit,
  4245. // so we don't want the background thread to try and touch it.
  4246. pnodeFnc->ichLim = m_pscan->IchLimTok();
  4247. pnodeFnc->sxFnc.cbLim = m_pscan->IecpLimTok();
  4248. }
  4249. }
  4250. }
  4251. #endif
  4252. }
  4253. }
  4254. if (!doParallel)
  4255. {
  4256. // We don't want to, or couldn't, let the main thread scan past this function body, so parse
  4257. // it for real.
  4258. ParseNodePtr pnodeRealFnc = pnodeFnc;
  4259. if (parallelJobStarted)
  4260. {
  4261. // We have to deal with a failure to fast-scan the function (due to syntax error? "/"?) when
  4262. // a background thread may already have begun to work on the job. Both threads can't be allowed to
  4263. // operate on the same node.
  4264. pnodeFnc = CreateDummyFuncNode(fDeclaration);
  4265. }
  4266. AnalysisAssert(pnodeFnc);
  4267. ParseNodePtr pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Parameter, ScopeType_Parameter);
  4268. AnalysisAssert(pnodeBlock != nullptr);
  4269. pnodeFnc->sxFnc.pnodeScopes = pnodeBlock;
  4270. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeParams;
  4271. ParseNodePtr *ppnodeScopeSave = nullptr;
  4272. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  4273. ppnodeScopeSave = m_ppnodeScope;
  4274. if (pnodeBlock)
  4275. {
  4276. // This synthetic block scope will contain all the nested scopes.
  4277. m_ppnodeScope = &pnodeBlock->sxBlock.pnodeScopes;
  4278. pnodeBlock->sxBlock.pnodeStmt = pnodeFnc;
  4279. }
  4280. // Keep nested function declarations and expressions in the same list at function scope.
  4281. // (Indicate this by nulling out the current function expressions list.)
  4282. ppnodeExprScopeSave = m_ppnodeExprScope;
  4283. m_ppnodeExprScope = nullptr;
  4284. this->ParseFncFormals<buildAST>(pnodeFnc, flags);
  4285. // Create function body scope
  4286. ParseNodePtr pnodeInnerBlock = StartParseBlock<buildAST>(PnodeBlockType::Function, ScopeType_FunctionBody);
  4287. // Set the parameter block's child to the function body block.
  4288. // The pnodeFnc->sxFnc.pnodeScopes list is constructed in such a way that it includes all the scopes in this list.
  4289. // For example if the param scope has one function and body scope has one function then the list will look like below,
  4290. // param scope block -> function decl from param scope -> body socpe block -> function decl from body scope.
  4291. *m_ppnodeScope = pnodeInnerBlock;
  4292. pnodeFnc->sxFnc.pnodeBodyScope = pnodeInnerBlock;
  4293. // This synthetic block scope will contain all the nested scopes.
  4294. m_ppnodeScope = &pnodeInnerBlock->sxBlock.pnodeScopes;
  4295. pnodeInnerBlock->sxBlock.pnodeStmt = pnodeFnc;
  4296. // DEFER: Begin deferral here (after names are parsed and name nodes created).
  4297. // Create no more AST nodes until we're done.
  4298. // Try to defer this func if all these are true:
  4299. // 0. We are not already in deferred parsing (i.e. buildAST is true)
  4300. // 1. We are not re-parsing a deferred func which is being invoked.
  4301. // 2. Dynamic profile suggests this func can be deferred (and deferred parse is on).
  4302. // 3. This func is top level or defer nested func is on.
  4303. // 4. Optionally, the function is non-nested and not in eval, or the deferral decision was based on cached profile info,
  4304. // or the function is sufficiently long. (I.e., don't defer little nested functions unless we're
  4305. // confident they'll never be executed, because un-deferring nested functions is more expensive.)
  4306. // NOTE: I'm disabling #4 by default, because we've found other ways to reduce the cost of un-deferral,
  4307. // and we don't want to create function bodies aggressively for little functions.
  4308. // We will also temporarily defer all asm.js functions, except for the asm.js
  4309. // module itself, which we will never defer
  4310. bool strictModeTurnedOn = false;
  4311. if (isTopLevelDeferredFunc &&
  4312. !(this->m_grfscr & fscrEvalCode) &&
  4313. pnodeFnc->sxFnc.IsNested() &&
  4314. #ifndef DISABLE_DYNAMIC_PROFILE_DEFER_PARSE
  4315. m_sourceContextInfo->sourceDynamicProfileManager == nullptr &&
  4316. #endif
  4317. PHASE_ON_RAW(Js::ScanAheadPhase, m_sourceContextInfo->sourceContextId, pnodeFnc->sxFnc.functionId) &&
  4318. (
  4319. !PHASE_FORCE_RAW(Js::DeferParsePhase, m_sourceContextInfo->sourceContextId, pnodeFnc->sxFnc.functionId) ||
  4320. PHASE_FORCE_RAW(Js::ScanAheadPhase, m_sourceContextInfo->sourceContextId, pnodeFnc->sxFnc.functionId)
  4321. ))
  4322. {
  4323. // Try to scan ahead to the end of the function. If we get there before we've scanned a minimum
  4324. // number of tokens, don't bother deferring, because it's too small.
  4325. if (this->ScanAheadToFunctionEnd(CONFIG_FLAG(MinDeferredFuncTokenCount)))
  4326. {
  4327. isTopLevelDeferredFunc = false;
  4328. }
  4329. }
  4330. if (fAsync)
  4331. {
  4332. if (!buildAST || isTopLevelDeferredFunc)
  4333. {
  4334. // 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
  4335. (*m_nextFunctionId)++;
  4336. }
  4337. // Same than before, we increment the nestedCount because we will have a Generator inside any async function.
  4338. pnodeFnc->sxFnc.nestedCount++;
  4339. }
  4340. Scope* paramScope = pnodeFnc->sxFnc.pnodeScopes ? pnodeFnc->sxFnc.pnodeScopes->sxBlock.scope : nullptr;
  4341. if (paramScope != nullptr && !fAsync)
  4342. {
  4343. if (CONFIG_FLAG(ForceSplitScope))
  4344. {
  4345. paramScope->SetCannotMergeWithBodyScope();
  4346. }
  4347. else if (pnodeFnc->sxFnc.HasNonSimpleParameterList())
  4348. {
  4349. if (paramScope->GetCanMergeWithBodyScope())
  4350. {
  4351. paramScope->ForEachSymbolUntil([this, paramScope](Symbol* sym) {
  4352. if (sym->GetPid()->GetTopRef()->sym == nullptr)
  4353. {
  4354. // One of the symbol has non local reference. Mark the param scope as we can't merge it with body scope.
  4355. paramScope->SetCannotMergeWithBodyScope();
  4356. return true;
  4357. }
  4358. else
  4359. {
  4360. // If no non-local references are there then the top of the ref stack should point to the same symbol.
  4361. Assert(sym->GetPid()->GetTopRef()->sym == sym);
  4362. }
  4363. return false;
  4364. });
  4365. if (wellKnownPropertyPids.arguments->GetTopRef() && wellKnownPropertyPids.arguments->GetTopRef()->GetScopeId() > pnodeFnc->sxFnc.pnodeScopes->sxBlock.blockId)
  4366. {
  4367. Assert(pnodeFnc->sxFnc.UsesArguments());
  4368. // Arguments symbol is captured in the param scope
  4369. paramScope->SetCannotMergeWithBodyScope();
  4370. }
  4371. }
  4372. }
  4373. }
  4374. if (!fLambda && paramScope != nullptr && !paramScope->GetCanMergeWithBodyScope()
  4375. && (pnodeFnc->sxFnc.UsesArguments() || pnodeFnc->grfpn & fpnArguments_overriddenByDecl))
  4376. {
  4377. Error(ERRNonSimpleParamListArgumentsUse);
  4378. }
  4379. // If the param scope is merged with the body scope we want to use the param scope symbols in the body scope.
  4380. // So add a pid ref for the body using the param scope symbol. Note that in this case the same symbol will occur twice
  4381. // in the same pid ref stack.
  4382. if (paramScope != nullptr && paramScope->GetCanMergeWithBodyScope() && (isTopLevelDeferredFunc || !fAsync))
  4383. {
  4384. paramScope->ForEachSymbol([this](Symbol* paramSym)
  4385. {
  4386. PidRefStack* ref = PushPidRef(paramSym->GetPid());
  4387. ref->SetSym(paramSym);
  4388. });
  4389. }
  4390. if (isTopLevelDeferredFunc || (m_InAsmMode && m_deferAsmJs))
  4391. {
  4392. AssertMsg(!fLambda, "Deferring function parsing of a function does not handle lambda syntax");
  4393. fDeferred = true;
  4394. this->ParseTopLevelDeferredFunc(pnodeFnc, pnodeFncParent, pNameHint);
  4395. }
  4396. else
  4397. {
  4398. if (m_token.tk == tkRParen) // This might be false due to error recovery or lambda.
  4399. {
  4400. m_pscan->Scan();
  4401. }
  4402. if (fLambda)
  4403. {
  4404. BOOL hadNewLine = m_pscan->FHadNewLine();
  4405. // it can be the case we do not have a fat arrow here if there is a valid expression on the left hand side
  4406. // of the fat arrow, but that expression does not parse as a parameter list. E.g.
  4407. // a.x => { }
  4408. // Therefore check for it and error if not found.
  4409. // 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.
  4410. ChkCurTok(tkDArrow, ERRnoDArrow);
  4411. // Newline character between arrow parameters and fat arrow is a syntax error but we want to check for
  4412. // this after verifying there was a => token. Otherwise we would throw the wrong error.
  4413. if (hadNewLine)
  4414. {
  4415. Error(ERRsyntax);
  4416. }
  4417. }
  4418. AnalysisAssert(pnodeFnc);
  4419. // Shouldn't be any temps in the arg list.
  4420. Assert(*m_ppnodeVar == nullptr);
  4421. // Start the var list.
  4422. pnodeFnc->sxFnc.pnodeVars = nullptr;
  4423. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  4424. if (paramScope != nullptr && !paramScope->GetCanMergeWithBodyScope())
  4425. {
  4426. OUTPUT_TRACE_DEBUGONLY(Js::ParsePhase, _u("The param and body scope of the function %s cannot be merged\n"), pnodeFnc->sxFnc.pnodeName ? pnodeFnc->sxFnc.pnodeName->sxVar.pid->Psz() : _u("Anonymous function"));
  4427. // Add a new symbol reference for each formal in the param scope to the body scope.
  4428. paramScope->ForEachSymbol([this](Symbol* param) {
  4429. OUTPUT_TRACE_DEBUGONLY(Js::ParsePhase, _u("Creating a duplicate symbol for the parameter %s in the body scope\n"), param->GetPid()->Psz());
  4430. ParseNodePtr paramNode = this->CreateVarDeclNode(param->GetPid(), STVariable, false, nullptr, false);
  4431. Assert(paramNode && paramNode->sxVar.sym->GetScope()->GetScopeType() == ScopeType_FunctionBody);
  4432. paramNode->sxVar.sym->SetHasInit(true);
  4433. });
  4434. if (!fLambda)
  4435. {
  4436. // In split scope case ideally the arguments object should be in the param scope.
  4437. // Right now referring to arguments in the param scope is a SyntaxError, so we have to
  4438. // add a duplicate symbol in the body scope and copy over the value in BeginBodySope.
  4439. ParseNodePtr argumentsNode = this->CreateVarDeclNode(wellKnownPropertyPids.arguments, STVariable, true, nullptr, false);
  4440. Assert(argumentsNode && argumentsNode->sxVar.sym->GetScope()->GetScopeType() == ScopeType_FunctionBody);
  4441. }
  4442. }
  4443. // Keep nested function declarations and expressions in the same list at function scope.
  4444. // (Indicate this by nulling out the current function expressions list.)
  4445. m_ppnodeExprScope = nullptr;
  4446. if (buildAST)
  4447. {
  4448. DeferredFunctionStub *saveCurrentStub = m_currDeferredStub;
  4449. if (isEnclosedInParamScope)
  4450. {
  4451. // if the enclosed scope is the param scope we would not have created the deferred stub.
  4452. m_currDeferredStub = nullptr;
  4453. }
  4454. else if (pnodeFncParent && m_currDeferredStub)
  4455. {
  4456. // the Deferred stub will not match for the function which are defined on lambda formals.
  4457. // Since this is not determined upfront that the current function is a part of outer function or part of lambda formal until we have seen the Arrow token.
  4458. // Due to that the current function may be fetching stubs from the outer function (outer of the lambda) - rather then the lambda function. The way to fix is to match
  4459. // the function start with the stub. Because they should match. We need to have previous sibling concept as the lambda formals can have more than one
  4460. // functions and we want to avoid getting wrong stub.
  4461. if (pnodeFncParent->sxFnc.nestedCount == 1)
  4462. {
  4463. m_prevSiblingDeferredStub = nullptr;
  4464. }
  4465. if (m_prevSiblingDeferredStub == nullptr)
  4466. {
  4467. m_prevSiblingDeferredStub = (m_currDeferredStub + (pnodeFncParent->sxFnc.nestedCount - 1));
  4468. }
  4469. if (m_prevSiblingDeferredStub->ichMin == pnodeFnc->ichMin)
  4470. {
  4471. m_currDeferredStub = m_prevSiblingDeferredStub->deferredStubs;
  4472. m_prevSiblingDeferredStub = nullptr;
  4473. }
  4474. else
  4475. {
  4476. m_currDeferredStub = nullptr;
  4477. }
  4478. }
  4479. if (m_token.tk != tkLCurly && fLambda)
  4480. {
  4481. if (fAsync)
  4482. {
  4483. TransformAsyncFncDeclAST(&pnodeFnc, true);
  4484. }
  4485. else
  4486. {
  4487. ParseExpressionLambdaBody<true>(pnodeFnc);
  4488. }
  4489. *pNeedScanRCurly = false;
  4490. }
  4491. else
  4492. {
  4493. this->FinishFncDecl(pnodeFnc, pNameHint, lastNodeRef);
  4494. }
  4495. m_currDeferredStub = saveCurrentStub;
  4496. }
  4497. else
  4498. {
  4499. this->ParseNestedDeferredFunc(pnodeFnc, fLambda, pNeedScanRCurly, &strictModeTurnedOn);
  4500. }
  4501. }
  4502. if (pnodeInnerBlock)
  4503. {
  4504. FinishParseBlock(pnodeInnerBlock, *pNeedScanRCurly);
  4505. }
  4506. if (m_token.tk == tkLCurly || !fLambda)
  4507. {
  4508. this->AddArgumentsNodeToVars(pnodeFnc);
  4509. }
  4510. // Restore the lists of scopes that contain function expressions.
  4511. Assert(m_ppnodeExprScope == nullptr || *m_ppnodeExprScope == nullptr);
  4512. m_ppnodeExprScope = ppnodeExprScopeSave;
  4513. AssertMem(m_ppnodeScope);
  4514. Assert(nullptr == *m_ppnodeScope);
  4515. m_ppnodeScope = ppnodeScopeSave;
  4516. if (pnodeBlock)
  4517. {
  4518. FinishParseBlock(pnodeBlock, *pNeedScanRCurly);
  4519. }
  4520. if (IsStrictMode() || strictModeTurnedOn)
  4521. {
  4522. this->m_fUseStrictMode = TRUE; // Now we know this function is in strict mode
  4523. if (!fWasAlreadyStrictMode)
  4524. {
  4525. // If this function turned on strict mode then we didn't check the formal
  4526. // parameters or function name hint for future reserved word usage. So do that now.
  4527. RestorePoint afterFnc;
  4528. m_pscan->Capture(&afterFnc);
  4529. if (*pHasName)
  4530. {
  4531. // Rewind to the function name hint and check if the token is a reserved word.
  4532. m_pscan->SeekTo(beginNameHint);
  4533. m_pscan->Scan();
  4534. if (pnodeFnc->sxFnc.IsGenerator())
  4535. {
  4536. Assert(m_token.tk == tkStar);
  4537. Assert(m_scriptContext->GetConfig()->IsES6GeneratorsEnabled());
  4538. Assert(!(flags & fFncClassMember));
  4539. m_pscan->Scan();
  4540. }
  4541. if (m_token.IsReservedWord())
  4542. {
  4543. IdentifierExpectedError(m_token);
  4544. }
  4545. CheckStrictModeEvalArgumentsUsage(m_token.GetIdentifier(m_phtbl));
  4546. }
  4547. // Fast forward to formal parameter list, check for future reserved words,
  4548. // then restore scanner as it was.
  4549. m_pscan->SeekToForcingPid(beginFormals);
  4550. CheckStrictFormalParameters();
  4551. m_pscan->SeekTo(afterFnc);
  4552. }
  4553. if (buildAST)
  4554. {
  4555. if (pnodeFnc->sxFnc.pnodeName != nullptr && knopVarDecl == pnodeFnc->sxFnc.pnodeName->nop)
  4556. {
  4557. CheckStrictModeEvalArgumentsUsage(pnodeFnc->sxFnc.pnodeName->sxVar.pid, pnodeFnc->sxFnc.pnodeName);
  4558. }
  4559. }
  4560. this->m_fUseStrictMode = oldStrictMode;
  4561. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(StrictModeFunctionCount, m_scriptContext);
  4562. }
  4563. if (fDeferred)
  4564. {
  4565. AnalysisAssert(pnodeFnc);
  4566. pnodeFnc->sxFnc.pnodeVars = nullptr;
  4567. }
  4568. if (parallelJobStarted)
  4569. {
  4570. pnodeFnc = pnodeRealFnc;
  4571. m_currentNodeFunc = pnodeRealFnc;
  4572. // Let the foreground thread take care of marking the limit on the function node,
  4573. // because in some cases this function's caller will want to change that limit,
  4574. // so we don't want the background thread to try and touch it.
  4575. pnodeFnc->ichLim = m_pscan->IchLimTok();
  4576. pnodeFnc->sxFnc.cbLim = m_pscan->IecpLimTok();
  4577. }
  4578. }
  4579. // after parsing asm.js module, we want to reset asm.js state before continuing
  4580. AnalysisAssert(pnodeFnc);
  4581. if (pnodeFnc->sxFnc.GetAsmjsMode())
  4582. {
  4583. m_InAsmMode = false;
  4584. }
  4585. // Restore the statement stack.
  4586. Assert(nullptr == m_pstmtCur);
  4587. SetCurrentStatement(pstmtSave);
  4588. if (pnodeFncExprScope)
  4589. {
  4590. FinishParseFncExprScope(pnodeFnc, pnodeFncExprScope);
  4591. }
  4592. if (!m_stoppedDeferredParse)
  4593. {
  4594. m_grfscr |= uDeferSave;
  4595. }
  4596. m_pscan->SetYieldIsKeyword(fPreviousYieldIsKeyword);
  4597. m_pscan->SetAwaitIsKeyword(fPreviousAwaitIsKeyword);
  4598. return true;
  4599. }
  4600. void Parser::ParseTopLevelDeferredFunc(ParseNodePtr pnodeFnc, ParseNodePtr pnodeFncParent, LPCOLESTR pNameHint)
  4601. {
  4602. // Parse a function body that is a transition point from building AST to doing fast syntax check.
  4603. pnodeFnc->sxFnc.pnodeVars = nullptr;
  4604. pnodeFnc->sxFnc.pnodeBody = nullptr;
  4605. this->m_deferringAST = TRUE;
  4606. // Put the scanner into "no hashing" mode.
  4607. BYTE deferFlags = m_pscan->SetDeferredParse(TRUE);
  4608. m_pscan->Scan();
  4609. ChkCurTok(tkLCurly, ERRnoLcurly);
  4610. ParseNodePtr *ppnodeVarSave = m_ppnodeVar;
  4611. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  4612. if (pnodeFncParent != nullptr
  4613. && m_currDeferredStub != nullptr
  4614. // We don't create stubs for function bodies in parameter scope.
  4615. && pnodeFnc->sxFnc.pnodeScopes->sxBlock.blockType != PnodeBlockType::Parameter)
  4616. {
  4617. // We've already parsed this function body for syntax errors on the initial parse of the script.
  4618. // We have information that allows us to skip it, so do so.
  4619. DeferredFunctionStub *stub = m_currDeferredStub + (pnodeFncParent->sxFnc.nestedCount - 1);
  4620. Assert(pnodeFnc->ichMin == stub->ichMin);
  4621. if (stub->fncFlags & kFunctionCallsEval)
  4622. {
  4623. this->MarkEvalCaller();
  4624. }
  4625. if (stub->fncFlags & kFunctionChildCallsEval)
  4626. {
  4627. pnodeFnc->sxFnc.SetChildCallsEval(true);
  4628. }
  4629. if (stub->fncFlags & kFunctionHasWithStmt)
  4630. {
  4631. pnodeFnc->sxFnc.SetHasWithStmt(true);
  4632. }
  4633. PHASE_PRINT_TRACE1(
  4634. Js::SkipNestedDeferredPhase,
  4635. _u("Skipping nested deferred function %d. %s: %d...%d\n"),
  4636. pnodeFnc->sxFnc.functionId, GetFunctionName(pnodeFnc, pNameHint), pnodeFnc->ichMin, stub->restorePoint.m_ichMinTok);
  4637. m_pscan->SeekTo(stub->restorePoint, m_nextFunctionId);
  4638. pnodeFnc->sxFnc.nestedCount = stub->nestedCount;
  4639. pnodeFnc->sxFnc.deferredStub = stub->deferredStubs;
  4640. if (stub->fncFlags & kFunctionStrictMode)
  4641. {
  4642. pnodeFnc->sxFnc.SetStrictMode(true);
  4643. }
  4644. }
  4645. else
  4646. {
  4647. ParseStmtList<false>(nullptr, nullptr, SM_DeferredParse, true /* isSourceElementList */);
  4648. }
  4649. pnodeFnc->ichLim = m_pscan->IchLimTok();
  4650. pnodeFnc->sxFnc.cbLim = m_pscan->IecpLimTok();
  4651. m_ppnodeVar = ppnodeVarSave;
  4652. // Restore the scanner's default hashing mode.
  4653. // Do this before we consume the next token.
  4654. m_pscan->SetDeferredParseFlags(deferFlags);
  4655. ChkCurTokNoScan(tkRCurly, ERRnoRcurly);
  4656. #if DBG
  4657. pnodeFnc->sxFnc.deferredParseNextFunctionId = *this->m_nextFunctionId;
  4658. #endif
  4659. this->m_deferringAST = FALSE;
  4660. }
  4661. bool Parser::DoParallelParse(ParseNodePtr pnodeFnc) const
  4662. {
  4663. #if ENABLE_BACKGROUND_PARSING
  4664. if (!PHASE_ON_RAW(Js::ParallelParsePhase, m_sourceContextInfo->sourceContextId, pnodeFnc->sxFnc.functionId))
  4665. {
  4666. return false;
  4667. }
  4668. BackgroundParser *bgp = m_scriptContext->GetBackgroundParser();
  4669. return bgp != nullptr;
  4670. #else
  4671. return false;
  4672. #endif
  4673. }
  4674. bool Parser::ScanAheadToFunctionEnd(uint count)
  4675. {
  4676. bool found = false;
  4677. uint curlyDepth = 0;
  4678. RestorePoint funcStart;
  4679. m_pscan->Capture(&funcStart);
  4680. for (uint i = 0; i < count; i++)
  4681. {
  4682. switch (m_token.tk)
  4683. {
  4684. case tkStrTmplBegin:
  4685. case tkStrTmplMid:
  4686. case tkStrTmplEnd:
  4687. case tkDiv:
  4688. case tkAsgDiv:
  4689. case tkScanError:
  4690. case tkEOF:
  4691. goto LEnd;
  4692. case tkLCurly:
  4693. UInt32Math::Inc(curlyDepth, Parser::OutOfMemory);
  4694. break;
  4695. case tkRCurly:
  4696. if (curlyDepth == 1)
  4697. {
  4698. found = true;
  4699. goto LEnd;
  4700. }
  4701. if (curlyDepth == 0)
  4702. {
  4703. goto LEnd;
  4704. }
  4705. curlyDepth--;
  4706. break;
  4707. }
  4708. m_pscan->ScanAhead();
  4709. }
  4710. LEnd:
  4711. m_pscan->SeekTo(funcStart);
  4712. return found;
  4713. }
  4714. bool Parser::FastScanFormalsAndBody()
  4715. {
  4716. // The scanner is currently pointing just past the name of a function.
  4717. // The idea here is to find the end of the function body as quickly as possible,
  4718. // by tokenizing and tracking {}'s if possible.
  4719. // String templates require some extra logic but can be handled.
  4720. // The real wrinkle is "/" and "/=", which may indicate either a RegExp literal or a division, depending
  4721. // on the context.
  4722. // To handle this with minimal work, keep track of the last ";" seen at each {} depth. If we see one of the
  4723. // difficult tokens, rewind to the last ";" at the current {} depth and parse statements until we pass the
  4724. // point where we had to rewind. This will process the "/" as required.
  4725. RestorePoint funcStart;
  4726. m_pscan->Capture(&funcStart);
  4727. const int maxRestorePointDepth = 16;
  4728. struct FastScanRestorePoint
  4729. {
  4730. RestorePoint restorePoint;
  4731. uint parenDepth;
  4732. Js::LocalFunctionId functionId;
  4733. int blockId;
  4734. FastScanRestorePoint() : restorePoint(), parenDepth(0) {};
  4735. };
  4736. FastScanRestorePoint lastSColonAtCurlyDepth[maxRestorePointDepth];
  4737. charcount_t ichStart = m_pscan->IchMinTok();
  4738. uint blockIdSave = m_nextBlockId;
  4739. uint functionIdSave = *m_nextFunctionId;
  4740. uint curlyDepth = 0;
  4741. uint strTmplDepth = 0;
  4742. for (;;)
  4743. {
  4744. switch (m_token.tk)
  4745. {
  4746. case tkStrTmplBegin:
  4747. UInt32Math::Inc(strTmplDepth, Parser::OutOfMemory);
  4748. // Fall through
  4749. case tkStrTmplMid:
  4750. case tkLCurly:
  4751. UInt32Math::Inc(curlyDepth, Parser::OutOfMemory);
  4752. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  4753. break;
  4754. case tkStrTmplEnd:
  4755. // We can assert here, because the scanner will only return this token if we've told it we're
  4756. // in a string template.
  4757. Assert(strTmplDepth > 0);
  4758. strTmplDepth--;
  4759. break;
  4760. case tkRCurly:
  4761. if (curlyDepth == 1)
  4762. {
  4763. Assert(strTmplDepth == 0);
  4764. if (PHASE_TRACE1(Js::ParallelParsePhase))
  4765. {
  4766. Output::Print(_u("Finished fast seek: %d. %s -- %d...%d\n"),
  4767. m_currentNodeFunc->sxFnc.functionId,
  4768. GetFunctionName(m_currentNodeFunc, m_currentNodeFunc->sxFnc.hint),
  4769. ichStart, m_pscan->IchLimTok());
  4770. }
  4771. return true;
  4772. }
  4773. if (curlyDepth < maxRestorePointDepth)
  4774. {
  4775. lastSColonAtCurlyDepth[curlyDepth].restorePoint.m_ichMinTok = (uint)-1;
  4776. }
  4777. curlyDepth--;
  4778. if (strTmplDepth > 0)
  4779. {
  4780. m_pscan->SetScanState(Scanner_t::ScanState::ScanStateStringTemplateMiddleOrEnd);
  4781. }
  4782. break;
  4783. case tkSColon:
  4784. // Track the location of the ";" (if it's outside parens, as we don't, for instance, want
  4785. // to track the ";"'s in a for-loop header. If we find it's important to rewind within a paren
  4786. // expression, we can do something more sophisticated.)
  4787. if (curlyDepth < maxRestorePointDepth && lastSColonAtCurlyDepth[curlyDepth].parenDepth == 0)
  4788. {
  4789. m_pscan->Capture(&lastSColonAtCurlyDepth[curlyDepth].restorePoint);
  4790. lastSColonAtCurlyDepth[curlyDepth].functionId = *this->m_nextFunctionId;
  4791. lastSColonAtCurlyDepth[curlyDepth].blockId = m_nextBlockId;
  4792. }
  4793. break;
  4794. case tkLParen:
  4795. if (curlyDepth < maxRestorePointDepth)
  4796. {
  4797. UInt32Math::Inc(lastSColonAtCurlyDepth[curlyDepth].parenDepth);
  4798. }
  4799. break;
  4800. case tkRParen:
  4801. if (curlyDepth < maxRestorePointDepth)
  4802. {
  4803. Assert(lastSColonAtCurlyDepth[curlyDepth].parenDepth != 0);
  4804. lastSColonAtCurlyDepth[curlyDepth].parenDepth--;
  4805. }
  4806. break;
  4807. case tkID:
  4808. {
  4809. charcount_t tokLength = m_pscan->IchLimTok() - m_pscan->IchMinTok();
  4810. // Detect the function and class keywords so we can track function ID's.
  4811. // (In fast mode, the scanner doesn't distinguish keywords and doesn't point the token
  4812. // to a PID.)
  4813. // Detect try/catch/for to increment block count for them.
  4814. switch (tokLength)
  4815. {
  4816. case 3:
  4817. if (!memcmp(m_pscan->PchMinTok(), "try", 3) || !memcmp(m_pscan->PchMinTok(), "for", 3))
  4818. {
  4819. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  4820. }
  4821. break;
  4822. case 5:
  4823. if (!memcmp(m_pscan->PchMinTok(), "catch", 5))
  4824. {
  4825. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  4826. }
  4827. else if (!memcmp(m_pscan->PchMinTok(), "class", 5))
  4828. {
  4829. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  4830. Int32Math::Inc(*this->m_nextFunctionId, (int*)this->m_nextFunctionId);
  4831. }
  4832. break;
  4833. case 8:
  4834. if (!memcmp(m_pscan->PchMinTok(), "function", 8))
  4835. {
  4836. // Account for the possible func expr scope or dummy block for missing {}'s around a declaration
  4837. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  4838. Int32Math::Inc(*this->m_nextFunctionId, (int*)this->m_nextFunctionId);
  4839. }
  4840. break;
  4841. }
  4842. break;
  4843. }
  4844. case tkDArrow:
  4845. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  4846. Int32Math::Inc(*this->m_nextFunctionId, (int*)this->m_nextFunctionId);
  4847. break;
  4848. case tkDiv:
  4849. case tkAsgDiv:
  4850. {
  4851. int opl;
  4852. OpCode nop;
  4853. tokens tkPrev = m_pscan->m_tkPrevious;
  4854. if ((m_pscan->m_phtbl->TokIsBinop(tkPrev, &opl, &nop) && nop != knopNone) ||
  4855. (m_pscan->m_phtbl->TokIsUnop(tkPrev, &opl, &nop) &&
  4856. nop != knopNone &&
  4857. tkPrev != tkInc &&
  4858. tkPrev != tkDec) ||
  4859. tkPrev == tkColon ||
  4860. tkPrev == tkLParen ||
  4861. tkPrev == tkLBrack ||
  4862. tkPrev == tkRETURN)
  4863. {
  4864. // Previous token indicates that we're starting an expression here and can't have a
  4865. // binary operator now.
  4866. // Assume this is a RegExp.
  4867. ParseRegExp<false>();
  4868. break;
  4869. }
  4870. uint tempCurlyDepth = curlyDepth < maxRestorePointDepth ? curlyDepth : maxRestorePointDepth - 1;
  4871. for (; tempCurlyDepth != (uint)-1; tempCurlyDepth--)
  4872. {
  4873. // We don't know whether we've got a RegExp or a divide. Rewind to the last safe ";"
  4874. // if we can and parse statements until we pass this point.
  4875. if (lastSColonAtCurlyDepth[tempCurlyDepth].restorePoint.m_ichMinTok != -1)
  4876. {
  4877. break;
  4878. }
  4879. }
  4880. if (tempCurlyDepth != (uint)-1)
  4881. {
  4882. ParseNodePtr pnodeFncSave = m_currentNodeFunc;
  4883. long *pastSizeSave = m_pCurrentAstSize;
  4884. uint *pnestedCountSave = m_pnestedCount;
  4885. ParseNodePtr *ppnodeScopeSave = m_ppnodeScope;
  4886. ParseNodePtr *ppnodeExprScopeSave = m_ppnodeExprScope;
  4887. ParseNodePtr pnodeFnc = CreateDummyFuncNode(true);
  4888. m_ppnodeScope = &pnodeFnc->sxFnc.pnodeScopes;
  4889. m_ppnodeExprScope = nullptr;
  4890. charcount_t ichStop = m_pscan->IchLimTok();
  4891. curlyDepth = tempCurlyDepth;
  4892. m_pscan->SeekTo(lastSColonAtCurlyDepth[tempCurlyDepth].restorePoint);
  4893. m_nextBlockId = lastSColonAtCurlyDepth[tempCurlyDepth].blockId;
  4894. *this->m_nextFunctionId = lastSColonAtCurlyDepth[tempCurlyDepth].functionId;
  4895. ParseNodePtr pnodeBlock = StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FunctionBody);
  4896. m_pscan->Scan();
  4897. do
  4898. {
  4899. ParseStatement<false>();
  4900. }
  4901. while(m_pscan->IchMinTok() < ichStop);
  4902. FinishParseBlock(pnodeBlock);
  4903. m_currentNodeFunc = pnodeFncSave;
  4904. m_pCurrentAstSize = pastSizeSave;
  4905. m_pnestedCount = pnestedCountSave;
  4906. m_ppnodeScope = ppnodeScopeSave;
  4907. m_ppnodeExprScope = ppnodeExprScopeSave;
  4908. // We've already consumed the first token of the next statement, so just continue
  4909. // without a further scan.
  4910. continue;
  4911. }
  4912. }
  4913. // fall through to rewind to function start
  4914. case tkScanError:
  4915. case tkEOF:
  4916. // Unexpected token.
  4917. if (PHASE_TRACE1(Js::ParallelParsePhase))
  4918. {
  4919. Output::Print(_u("Failed fast seek: %d. %s -- %d...%d\n"),
  4920. m_currentNodeFunc->sxFnc.functionId,
  4921. GetFunctionName(m_currentNodeFunc, m_currentNodeFunc->sxFnc.hint),
  4922. ichStart, m_pscan->IchLimTok());
  4923. }
  4924. m_nextBlockId = blockIdSave;
  4925. *m_nextFunctionId = functionIdSave;
  4926. m_pscan->SeekTo(funcStart);
  4927. return false;
  4928. }
  4929. m_pscan->ScanNoKeywords();
  4930. }
  4931. }
  4932. ParseNodePtr Parser::CreateDummyFuncNode(bool fDeclaration)
  4933. {
  4934. // Create a dummy node and make it look like the current function declaration.
  4935. // Do this in situations where we want to parse statements without impacting
  4936. // the state of the "real" AST.
  4937. ParseNodePtr pnodeFnc = CreateNode(knopFncDecl);
  4938. pnodeFnc->sxFnc.ClearFlags();
  4939. pnodeFnc->sxFnc.SetDeclaration(fDeclaration);
  4940. pnodeFnc->sxFnc.astSize = 0;
  4941. pnodeFnc->sxFnc.pnodeName = nullptr;
  4942. pnodeFnc->sxFnc.pnodeScopes = nullptr;
  4943. pnodeFnc->sxFnc.pnodeRest = nullptr;
  4944. pnodeFnc->sxFnc.pid = nullptr;
  4945. pnodeFnc->sxFnc.hint = nullptr;
  4946. pnodeFnc->sxFnc.hintOffset = 0;
  4947. pnodeFnc->sxFnc.hintLength = 0;
  4948. pnodeFnc->sxFnc.isNameIdentifierRef = true;
  4949. pnodeFnc->sxFnc.pnodeNext = nullptr;
  4950. pnodeFnc->sxFnc.pnodeParams = nullptr;
  4951. pnodeFnc->sxFnc.pnodeVars = nullptr;
  4952. pnodeFnc->sxFnc.funcInfo = nullptr;
  4953. pnodeFnc->sxFnc.deferredStub = nullptr;
  4954. pnodeFnc->sxFnc.nestedCount = 0;
  4955. pnodeFnc->sxFnc.SetNested(m_currentNodeFunc != nullptr); // If there is a current function, then we're a nested function.
  4956. pnodeFnc->sxFnc.SetStrictMode(IsStrictMode()); // Inherit current strict mode -- may be overridden by the function itself if it contains a strict mode directive.
  4957. pnodeFnc->sxFnc.firstDefaultArg = 0;
  4958. m_pCurrentAstSize = &pnodeFnc->sxFnc.astSize;
  4959. m_currentNodeFunc = pnodeFnc;
  4960. m_pnestedCount = &pnodeFnc->sxFnc.nestedCount;
  4961. return pnodeFnc;
  4962. }
  4963. void Parser::ParseNestedDeferredFunc(ParseNodePtr pnodeFnc, bool fLambda, bool *pNeedScanRCurly, bool *pStrictModeTurnedOn)
  4964. {
  4965. // Parse a function nested inside another deferred function.
  4966. size_t lengthBeforeBody = this->GetSourceLength();
  4967. if (m_token.tk != tkLCurly && fLambda)
  4968. {
  4969. ParseExpressionLambdaBody<false>(pnodeFnc);
  4970. *pNeedScanRCurly = false;
  4971. }
  4972. else
  4973. {
  4974. ChkCurTok(tkLCurly, ERRnoLcurly);
  4975. bool* detectStrictModeOn = IsStrictMode() ? nullptr : pStrictModeTurnedOn;
  4976. m_ppnodeVar = &m_currentNodeDeferredFunc->sxFnc.pnodeVars;
  4977. ParseStmtList<false>(nullptr, nullptr, SM_DeferredParse, true /* isSourceElementList */, detectStrictModeOn);
  4978. ChkCurTokNoScan(tkRCurly, ERRnoRcurly);
  4979. }
  4980. pnodeFnc->ichLim = m_pscan->IchLimTok();
  4981. pnodeFnc->sxFnc.cbLim = m_pscan->IecpLimTok();
  4982. if (*pStrictModeTurnedOn)
  4983. {
  4984. pnodeFnc->sxFnc.SetStrictMode(true);
  4985. }
  4986. if (!PHASE_OFF1(Js::SkipNestedDeferredPhase))
  4987. {
  4988. // Record the end of the function and the function ID increment that happens inside the function.
  4989. // Byte code gen will use this to build stub information to allow us to skip this function when the
  4990. // enclosing function is fully parsed.
  4991. RestorePoint *restorePoint = Anew(&m_nodeAllocator, RestorePoint);
  4992. m_pscan->Capture(restorePoint,
  4993. *m_nextFunctionId - pnodeFnc->sxFnc.functionId - 1,
  4994. lengthBeforeBody - this->GetSourceLength());
  4995. pnodeFnc->sxFnc.pRestorePoint = restorePoint;
  4996. }
  4997. }
  4998. template<bool buildAST>
  4999. bool Parser::ParseFncNames(ParseNodePtr pnodeFnc, ParseNodePtr pnodeFncParent, ushort flags, ParseNodePtr **pLastNodeRef)
  5000. {
  5001. BOOL fDeclaration = flags & fFncDeclaration;
  5002. BOOL fIsAsync = flags & fFncAsync;
  5003. ParseNodePtr pnodeT;
  5004. charcount_t ichMinNames, ichLimNames;
  5005. // Get the names to bind to.
  5006. /*
  5007. * KaushiS [5/15/08]:
  5008. * ECMAScript defines a FunctionExpression as follows:
  5009. *
  5010. * "function" [Identifier] ( [FormalParameterList] ) { FunctionBody }
  5011. *
  5012. * The function name being optional is omitted by most real world
  5013. * code that uses a FunctionExpression to define a function. This however
  5014. * is problematic for tools because there isn't a function name that
  5015. * the runtime can provide.
  5016. *
  5017. * To fix this (primarily for the profiler), I'm adding simple, static
  5018. * name inferencing logic to the parser. When it encounters the following
  5019. * productions
  5020. *
  5021. * "var" Identifier "=" FunctionExpression
  5022. * "var" IdentifierA.IdentifierB...Identifier "=" FunctionExpression
  5023. * Identifier = FunctionExpression
  5024. * "{" Identifier: FunctionExpression "}"
  5025. *
  5026. * it associates Identifier with the function created by the
  5027. * FunctionExpression. This identifier is *not* the function's name. It
  5028. * is ignored by the runtime and is only an additional piece of information
  5029. * about the function (function name hint) that tools could opt to
  5030. * surface.
  5031. */
  5032. m_pscan->Scan();
  5033. // If generators are enabled then we are in a recent enough version
  5034. // that deferred parsing will create a parse node for pnodeFnc and
  5035. // it is safe to assume it is not null.
  5036. if (flags & fFncGenerator)
  5037. {
  5038. Assert(m_scriptContext->GetConfig()->IsES6GeneratorsEnabled());
  5039. pnodeFnc->sxFnc.SetIsGenerator();
  5040. }
  5041. else if (m_scriptContext->GetConfig()->IsES6GeneratorsEnabled() &&
  5042. m_token.tk == tkStar &&
  5043. !(flags & fFncClassMember))
  5044. {
  5045. if (!fDeclaration)
  5046. {
  5047. bool fPreviousYieldIsKeyword = m_pscan->SetYieldIsKeyword(!fDeclaration);
  5048. m_pscan->Scan();
  5049. m_pscan->SetYieldIsKeyword(fPreviousYieldIsKeyword);
  5050. }
  5051. else
  5052. {
  5053. m_pscan->Scan();
  5054. }
  5055. pnodeFnc->sxFnc.SetIsGenerator();
  5056. }
  5057. if (fIsAsync)
  5058. {
  5059. if (pnodeFnc->sxFnc.IsGenerator())
  5060. {
  5061. Error(ERRsyntax);
  5062. }
  5063. pnodeFnc->sxFnc.SetIsAsync();
  5064. }
  5065. if (pnodeFnc)
  5066. {
  5067. pnodeFnc->sxFnc.pnodeName = nullptr;
  5068. }
  5069. if ((m_token.tk != tkID || flags & fFncNoName)
  5070. && (IsStrictMode() || (pnodeFnc && pnodeFnc->sxFnc.IsGenerator()) || m_token.tk != tkYIELD || fDeclaration)) // Function expressions can have the name yield even inside generator functions
  5071. {
  5072. if (fDeclaration ||
  5073. m_token.IsReservedWord()) // For example: var x = (function break(){});
  5074. {
  5075. IdentifierExpectedError(m_token);
  5076. }
  5077. return false;
  5078. }
  5079. ichMinNames = m_pscan->IchMinTok();
  5080. Assert(m_token.tk == tkID || (m_token.tk == tkYIELD && !fDeclaration));
  5081. if (IsStrictMode())
  5082. {
  5083. CheckStrictModeEvalArgumentsUsage(m_token.GetIdentifier(m_phtbl));
  5084. }
  5085. Token tokenBase = m_token;
  5086. charcount_t ichMinBase = m_pscan->IchMinTok();
  5087. charcount_t ichLimBase = m_pscan->IchLimTok();
  5088. m_pscan->Scan();
  5089. IdentPtr pidBase = tokenBase.GetIdentifier(m_phtbl);
  5090. pnodeT = CreateDeclNode(knopVarDecl, pidBase, STFunction);
  5091. pnodeT->ichMin = ichMinBase;
  5092. pnodeT->ichLim = ichLimBase;
  5093. if (fDeclaration &&
  5094. pnodeFncParent &&
  5095. pnodeFncParent->sxFnc.pnodeName &&
  5096. pnodeFncParent->sxFnc.pnodeName->nop == knopVarDecl &&
  5097. pnodeFncParent->sxFnc.pnodeName->sxVar.pid == pidBase)
  5098. {
  5099. pnodeFncParent->sxFnc.SetNameIsHidden();
  5100. }
  5101. if (buildAST)
  5102. {
  5103. AnalysisAssert(pnodeFnc);
  5104. ichLimNames = pnodeT->ichLim;
  5105. AddToNodeList(&pnodeFnc->sxFnc.pnodeName, pLastNodeRef, pnodeT);
  5106. pnodeFnc->sxFnc.pnodeName->ichMin = ichMinNames;
  5107. pnodeFnc->sxFnc.pnodeName->ichLim = ichLimNames;
  5108. if (knopVarDecl == pnodeFnc->sxFnc.pnodeName->nop)
  5109. {
  5110. // Only one name (the common case).
  5111. pnodeFnc->sxFnc.pid = pnodeFnc->sxFnc.pnodeName->sxVar.pid;
  5112. }
  5113. else
  5114. {
  5115. // Multiple names. Turn the source into an IdentPtr.
  5116. pnodeFnc->sxFnc.pid = m_phtbl->PidHashNameLen(
  5117. m_pscan->PchBase() + ichMinNames, ichLimNames - ichMinNames);
  5118. }
  5119. }
  5120. return true;
  5121. }
  5122. void Parser::ValidateFormals()
  5123. {
  5124. ParseFncFormals<false>(NULL, fFncNoFlgs);
  5125. // Eat the tkRParen. The ParseFncDeclHelper caller expects to see it.
  5126. m_pscan->Scan();
  5127. }
  5128. void Parser::ValidateSourceElementList()
  5129. {
  5130. ParseStmtList<false>(NULL, NULL, SM_NotUsed, true);
  5131. }
  5132. void Parser::UpdateOrCheckForDuplicateInFormals(IdentPtr pid, SList<IdentPtr> *formals)
  5133. {
  5134. bool isStrictMode = IsStrictMode();
  5135. if (isStrictMode)
  5136. {
  5137. CheckStrictModeEvalArgumentsUsage(pid);
  5138. }
  5139. if (formals->Has(pid))
  5140. {
  5141. if (isStrictMode)
  5142. {
  5143. Error(ERRES5ArgSame);
  5144. }
  5145. else
  5146. {
  5147. Error(ERRFormalSame);
  5148. }
  5149. }
  5150. else
  5151. {
  5152. formals->Prepend(pid);
  5153. }
  5154. }
  5155. template<bool buildAST>
  5156. void Parser::ParseFncFormals(ParseNodePtr pnodeFnc, ushort flags)
  5157. {
  5158. bool fLambda = (flags & fFncLambda) != 0;
  5159. bool fMethod = (flags & fFncMethod) != 0;
  5160. bool fNoArg = (flags & fFncNoArg) != 0;
  5161. bool fOneArg = (flags & fFncOneArg) != 0;
  5162. Assert(!fNoArg || !fOneArg); // fNoArg and fOneArg can never be true at the same time.
  5163. // strictFormals corresponds to the StrictFormalParameters grammar production
  5164. // in the ES spec which just means duplicate names are not allowed
  5165. bool fStrictFormals = IsStrictMode() || fLambda || fMethod;
  5166. // When detecting duplicated formals pids are needed so force PID creation (unless the function should take 0 or 1 arg).
  5167. bool forcePid = fStrictFormals && !fNoArg && !fOneArg;
  5168. AutoTempForcePid autoForcePid(m_pscan, forcePid);
  5169. // Lambda's allow single formal specified by a single binding identifier without parentheses, special case it.
  5170. if (fLambda && m_token.tk == tkID)
  5171. {
  5172. IdentPtr pid = m_token.GetIdentifier(m_phtbl);
  5173. CreateVarDeclNode(pid, STFormal, false, nullptr, false);
  5174. CheckPidIsValid(pid);
  5175. m_pscan->Scan();
  5176. if (m_token.tk != tkDArrow)
  5177. {
  5178. Error(ERRsyntax, m_pscan->IchMinTok(), m_pscan->IchLimTok());
  5179. }
  5180. return;
  5181. }
  5182. // Otherwise, must have a parameter list within parens.
  5183. ChkCurTok(tkLParen, ERRnoLparen);
  5184. // Now parse the list of arguments, if present
  5185. if (m_token.tk == tkRParen)
  5186. {
  5187. if (fOneArg)
  5188. {
  5189. Error(ERRSetterMustHaveOneParameter);
  5190. }
  5191. }
  5192. else
  5193. {
  5194. if (fNoArg)
  5195. {
  5196. Error(ERRGetterMustHaveNoParameters);
  5197. }
  5198. SList<IdentPtr> formals(&m_nodeAllocator);
  5199. ParseNodePtr pnodeT = nullptr;
  5200. bool seenRestParameter = false;
  5201. bool isNonSimpleParameterList = false;
  5202. for (Js::ArgSlot argPos = 0; ; ++argPos)
  5203. {
  5204. bool isBindingPattern = false;
  5205. if (m_scriptContext->GetConfig()->IsES6RestEnabled() && m_token.tk == tkEllipsis)
  5206. {
  5207. // Possible rest parameter
  5208. m_pscan->Scan();
  5209. seenRestParameter = true;
  5210. }
  5211. if (m_token.tk != tkID)
  5212. {
  5213. if (IsES6DestructuringEnabled() && IsPossiblePatternStart())
  5214. {
  5215. // Mark that the function has a non simple parameter list before parsing the pattern since the pattern can have function definitions.
  5216. this->GetCurrentFunctionNode()->sxFnc.SetHasNonSimpleParameterList();
  5217. ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
  5218. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  5219. ParseNodePtr * ppNodeLex = m_currentBlockInfo->m_ppnodeLex;
  5220. Assert(ppNodeLex != nullptr);
  5221. ParseNodePtr paramPattern = nullptr;
  5222. ParseNodePtr pnodePattern = ParseDestructuredLiteral<buildAST>(tkLET, true /*isDecl*/, false /*topLevel*/);
  5223. // Instead of passing the STFormal all the way on many methods, it seems it is better to change the symbol type afterward.
  5224. for (ParseNodePtr lexNode = *ppNodeLex; lexNode != nullptr; lexNode = lexNode->sxVar.pnodeNext)
  5225. {
  5226. Assert(lexNode->IsVarLetOrConst());
  5227. UpdateOrCheckForDuplicateInFormals(lexNode->sxVar.pid, &formals);
  5228. lexNode->sxVar.sym->SetSymbolType(STFormal);
  5229. if (m_currentNodeFunc != nullptr && lexNode->sxVar.pid == wellKnownPropertyPids.arguments)
  5230. {
  5231. m_currentNodeFunc->grfpn |= PNodeFlags::fpnArguments_overriddenByDecl;
  5232. }
  5233. }
  5234. m_ppnodeVar = ppnodeVarSave;
  5235. if (buildAST)
  5236. {
  5237. paramPattern = CreateParamPatternNode(pnodePattern);
  5238. // Linking the current formal parameter (which is pattern parameter) with other formals.
  5239. *m_ppnodeVar = paramPattern;
  5240. paramPattern->sxParamPattern.pnodeNext = nullptr;
  5241. m_ppnodeVar = &paramPattern->sxParamPattern.pnodeNext;
  5242. }
  5243. isBindingPattern = true;
  5244. isNonSimpleParameterList = true;
  5245. }
  5246. else
  5247. {
  5248. IdentifierExpectedError(m_token);
  5249. }
  5250. }
  5251. if (!isBindingPattern)
  5252. {
  5253. IdentPtr pid = m_token.GetIdentifier(m_phtbl);
  5254. LPCOLESTR pNameHint = pid->Psz();
  5255. ulong nameHintLength = pid->Cch();
  5256. ulong nameHintOffset = 0;
  5257. if (seenRestParameter)
  5258. {
  5259. this->GetCurrentFunctionNode()->sxFnc.SetHasNonSimpleParameterList();
  5260. if (flags & fFncOneArg)
  5261. {
  5262. // The parameter of a setter cannot be a rest parameter.
  5263. Error(ERRUnexpectedEllipsis);
  5264. }
  5265. pnodeT = CreateDeclNode(knopVarDecl, pid, STFormal, false);
  5266. pnodeT->sxVar.sym->SetIsNonSimpleParameter(true);
  5267. if (buildAST)
  5268. {
  5269. // When only validating formals, we won't have a function node.
  5270. pnodeFnc->sxFnc.pnodeRest = pnodeT;
  5271. if (!isNonSimpleParameterList)
  5272. {
  5273. // This is the first non-simple parameter we've seen. We need to go back
  5274. // and set the Symbols of all previous parameters.
  5275. MapFormalsWithoutRest(m_currentNodeFunc, [&](ParseNodePtr pnodeArg) { pnodeArg->sxVar.sym->SetIsNonSimpleParameter(true); });
  5276. }
  5277. }
  5278. isNonSimpleParameterList = true;
  5279. }
  5280. else
  5281. {
  5282. pnodeT = CreateVarDeclNode(pid, STFormal, false, nullptr, false);
  5283. if (isNonSimpleParameterList)
  5284. {
  5285. pnodeT->sxVar.sym->SetIsNonSimpleParameter(true);
  5286. }
  5287. }
  5288. if (buildAST && pid == wellKnownPropertyPids.arguments)
  5289. {
  5290. // This formal parameter overrides the built-in 'arguments' object
  5291. m_currentNodeFunc->grfpn |= PNodeFlags::fpnArguments_overriddenByDecl;
  5292. }
  5293. if (fStrictFormals)
  5294. {
  5295. UpdateOrCheckForDuplicateInFormals(pid, &formals);
  5296. }
  5297. m_pscan->Scan();
  5298. if (seenRestParameter && m_token.tk != tkRParen && m_token.tk != tkAsg)
  5299. {
  5300. Error(ERRRestLastArg);
  5301. }
  5302. if (m_token.tk == tkAsg && m_scriptContext->GetConfig()->IsES6DefaultArgsEnabled())
  5303. {
  5304. if (seenRestParameter && m_scriptContext->GetConfig()->IsES6RestEnabled())
  5305. {
  5306. Error(ERRRestWithDefault);
  5307. }
  5308. // In defer parse mode we have to flag the function node to indicate that it has default arguments
  5309. // so that it will be considered for any syntax error scenario.
  5310. // Also mark it before parsing the expression as it may contain functions.
  5311. ParseNode* currentFncNode = GetCurrentFunctionNode();
  5312. if (!currentFncNode->sxFnc.HasDefaultArguments())
  5313. {
  5314. currentFncNode->sxFnc.SetHasDefaultArguments();
  5315. currentFncNode->sxFnc.SetHasNonSimpleParameterList();
  5316. currentFncNode->sxFnc.firstDefaultArg = argPos;
  5317. }
  5318. m_pscan->Scan();
  5319. ParseNodePtr pnodeInit = ParseExpr<buildAST>(koplCma, nullptr, TRUE, FALSE, pNameHint, &nameHintLength, &nameHintOffset);
  5320. if (buildAST && pnodeInit->nop == knopFncDecl)
  5321. {
  5322. Assert(nameHintLength >= nameHintOffset);
  5323. pnodeInit->sxFnc.hint = pNameHint;
  5324. pnodeInit->sxFnc.hintLength = nameHintLength;
  5325. pnodeInit->sxFnc.hintOffset = nameHintOffset;
  5326. }
  5327. AnalysisAssert(pnodeT);
  5328. pnodeT->sxVar.sym->SetIsNonSimpleParameter(true);
  5329. if (!isNonSimpleParameterList)
  5330. {
  5331. if (buildAST)
  5332. {
  5333. // This is the first non-simple parameter we've seen. We need to go back
  5334. // and set the Symbols of all previous parameters.
  5335. MapFormalsWithoutRest(m_currentNodeFunc, [&](ParseNodePtr pnodeArg) { pnodeArg->sxVar.sym->SetIsNonSimpleParameter(true); });
  5336. }
  5337. // There may be previous parameters that need to be checked for duplicates.
  5338. isNonSimpleParameterList = true;
  5339. }
  5340. if (buildAST)
  5341. {
  5342. if (!m_currentNodeFunc->sxFnc.HasDefaultArguments())
  5343. {
  5344. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(DefaultArgFunctionCount, m_scriptContext);
  5345. }
  5346. pnodeT->sxVar.pnodeInit = pnodeInit;
  5347. pnodeT->ichLim = m_pscan->IchLimTok();
  5348. }
  5349. }
  5350. }
  5351. if (isNonSimpleParameterList && m_currentScope->GetHasDuplicateFormals())
  5352. {
  5353. Error(ERRFormalSame);
  5354. }
  5355. if (flags & fFncOneArg)
  5356. {
  5357. if (m_token.tk != tkRParen)
  5358. {
  5359. Error(ERRSetterMustHaveOneParameter);
  5360. }
  5361. break; //enforce only one arg
  5362. }
  5363. if (m_token.tk != tkComma)
  5364. {
  5365. break;
  5366. }
  5367. m_pscan->Scan();
  5368. if (m_token.tk == tkRParen && m_scriptContext->GetConfig()->IsES7TrailingCommaEnabled())
  5369. {
  5370. break;
  5371. }
  5372. }
  5373. if (seenRestParameter)
  5374. {
  5375. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(RestCount, m_scriptContext);
  5376. }
  5377. if (m_token.tk != tkRParen)
  5378. {
  5379. Error(ERRnoRparen);
  5380. }
  5381. if ((this->GetCurrentFunctionNode()->sxFnc.CallsEval() || this->GetCurrentFunctionNode()->sxFnc.ChildCallsEval())
  5382. && !m_scriptContext->GetConfig()->IsES6DefaultArgsSplitScopeEnabled())
  5383. {
  5384. Error(ERREvalNotSupportedInParamScope);
  5385. }
  5386. }
  5387. Assert(m_token.tk == tkRParen);
  5388. }
  5389. template<bool buildAST>
  5390. ParseNodePtr Parser::GenerateEmptyConstructor(bool extends)
  5391. {
  5392. ParseNodePtr pnodeFnc;
  5393. // Create the node.
  5394. pnodeFnc = CreateNode(knopFncDecl);
  5395. pnodeFnc->sxFnc.ClearFlags();
  5396. pnodeFnc->sxFnc.SetNested(NULL != m_currentNodeFunc);
  5397. pnodeFnc->sxFnc.SetStrictMode();
  5398. pnodeFnc->sxFnc.SetDeclaration(TRUE);
  5399. pnodeFnc->sxFnc.SetIsMethod(TRUE);
  5400. pnodeFnc->sxFnc.SetIsClassMember(TRUE);
  5401. pnodeFnc->sxFnc.SetIsClassConstructor(TRUE);
  5402. pnodeFnc->sxFnc.SetIsBaseClassConstructor(!extends);
  5403. pnodeFnc->sxFnc.SetHasNonThisStmt(extends);
  5404. pnodeFnc->sxFnc.SetIsGeneratedDefault(TRUE);
  5405. pnodeFnc->ichLim = m_pscan->IchLimTok();
  5406. pnodeFnc->ichMin = m_pscan->IchMinTok();
  5407. pnodeFnc->sxFnc.cbLim = m_pscan->IecpLimTok();
  5408. pnodeFnc->sxFnc.cbMin = m_pscan->IecpMinTok();
  5409. pnodeFnc->sxFnc.astSize = 0;
  5410. pnodeFnc->sxFnc.lineNumber = m_pscan->LineCur();
  5411. pnodeFnc->sxFnc.functionId = (*m_nextFunctionId);
  5412. pnodeFnc->sxFnc.pid = nullptr;
  5413. pnodeFnc->sxFnc.hint = nullptr;
  5414. pnodeFnc->sxFnc.hintOffset = 0;
  5415. pnodeFnc->sxFnc.hintLength = 0;
  5416. pnodeFnc->sxFnc.isNameIdentifierRef = true;
  5417. pnodeFnc->sxFnc.pnodeName = nullptr;
  5418. pnodeFnc->sxFnc.pnodeScopes = nullptr;
  5419. pnodeFnc->sxFnc.pnodeParams = nullptr;
  5420. pnodeFnc->sxFnc.pnodeVars = nullptr;
  5421. pnodeFnc->sxFnc.pnodeBody = nullptr;
  5422. pnodeFnc->sxFnc.nestedCount = 0;
  5423. pnodeFnc->sxFnc.pnodeNext = nullptr;
  5424. pnodeFnc->sxFnc.pnodeRest = nullptr;
  5425. pnodeFnc->sxFnc.deferredStub = nullptr;
  5426. pnodeFnc->sxFnc.funcInfo = nullptr;
  5427. #ifdef DBG
  5428. pnodeFnc->sxFnc.deferredParseNextFunctionId = *(this->m_nextFunctionId);
  5429. #endif
  5430. AppendFunctionToScopeList(true, pnodeFnc);
  5431. if (m_nextFunctionId)
  5432. {
  5433. (*m_nextFunctionId)++;
  5434. }
  5435. // Update the count of functions nested in the current parent.
  5436. if (m_pnestedCount)
  5437. {
  5438. (*m_pnestedCount)++;
  5439. }
  5440. if (!buildAST)
  5441. {
  5442. return NULL;
  5443. }
  5444. if (m_pscan->IchMinTok() >= m_pscan->IchMinLine())
  5445. {
  5446. // In scenarios involving defer parse IchMinLine() can be incorrect for the first line after defer parse
  5447. pnodeFnc->sxFnc.columnNumber = m_pscan->IchMinTok() - m_pscan->IchMinLine();
  5448. }
  5449. else if (m_currentNodeFunc)
  5450. {
  5451. // For the first line after defer parse, compute the column relative to the column number
  5452. // of the lexically parent function.
  5453. ULONG offsetFromCurrentFunction = m_pscan->IchMinTok() - m_currentNodeFunc->ichMin;
  5454. pnodeFnc->sxFnc.columnNumber = m_currentNodeFunc->sxFnc.columnNumber + offsetFromCurrentFunction;
  5455. }
  5456. else
  5457. {
  5458. // if there is no current function, lets give a default of 0.
  5459. pnodeFnc->sxFnc.columnNumber = 0;
  5460. }
  5461. long * pAstSizeSave = m_pCurrentAstSize;
  5462. m_pCurrentAstSize = &(pnodeFnc->sxFnc.astSize);
  5463. // Make this the current function.
  5464. ParseNodePtr pnodeFncSave = m_currentNodeFunc;
  5465. m_currentNodeFunc = pnodeFnc;
  5466. ParseNodePtr pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Parameter, ScopeType_Parameter);
  5467. ParseNodePtr pnodeInnerBlock = StartParseBlock<buildAST>(PnodeBlockType::Function, ScopeType_FunctionBody);
  5468. pnodeBlock->sxBlock.pnodeScopes = pnodeInnerBlock;
  5469. pnodeFnc->sxFnc.pnodeBodyScope = pnodeInnerBlock;
  5470. pnodeFnc->sxFnc.pnodeScopes = pnodeBlock;
  5471. ParseNodePtr *lastNodeRef = nullptr;
  5472. if (extends)
  5473. {
  5474. // constructor() { super(...arguments); } (equivalent to constructor(...args) { super(...args); } )
  5475. PidRefStack *ref = this->PushPidRef(wellKnownPropertyPids.arguments);
  5476. ParseNodePtr argumentsId = CreateNameNode(wellKnownPropertyPids.arguments, pnodeFnc->ichMin, pnodeFnc->ichLim);
  5477. argumentsId->sxPid.symRef = ref->GetSymRef();
  5478. pnodeFnc->sxFnc.SetUsesArguments(true);
  5479. pnodeFnc->sxFnc.SetHasReferenceableBuiltInArguments(true);
  5480. ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
  5481. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  5482. CreateVarDeclNode(wellKnownPropertyPids.arguments, STVariable, true, pnodeFnc)->grfpn |= PNodeFlags::fpnArguments;
  5483. m_ppnodeVar = ppnodeVarSave;
  5484. ParseNodePtr spreadArg = CreateUniNode(knopEllipsis, argumentsId, pnodeFnc->ichMin, pnodeFnc->ichLim);
  5485. ParseNodePtr superRef = CreateNodeWithScanner<knopSuper>();
  5486. pnodeFnc->sxFnc.SetHasSuperReference(TRUE);
  5487. ParseNodePtr callNode = CreateCallNode(knopCall, superRef, spreadArg);
  5488. callNode->sxCall.spreadArgCount = 1;
  5489. AddToNodeList(&pnodeFnc->sxFnc.pnodeBody, &lastNodeRef, callNode);
  5490. }
  5491. AddToNodeList(&pnodeFnc->sxFnc.pnodeBody, &lastNodeRef, CreateNodeWithScanner<knopEndCode>());
  5492. FinishParseBlock(pnodeInnerBlock);
  5493. FinishParseBlock(pnodeBlock);
  5494. m_currentNodeFunc = pnodeFncSave;
  5495. m_pCurrentAstSize = pAstSizeSave;
  5496. return pnodeFnc;
  5497. }
  5498. template<bool buildAST>
  5499. void Parser::ParseExpressionLambdaBody(ParseNodePtr pnodeLambda)
  5500. {
  5501. ParseNodePtr *lastNodeRef = nullptr;
  5502. // The lambda body is a single expression, the result of which is the return value.
  5503. ParseNodePtr pnodeRet = nullptr;
  5504. if (buildAST)
  5505. {
  5506. pnodeRet = CreateNodeWithScanner<knopReturn>();
  5507. pnodeRet->grfpn |= PNodeFlags::fpnSyntheticNode;
  5508. pnodeLambda->sxFnc.pnodeScopes->sxBlock.pnodeStmt = pnodeRet;
  5509. }
  5510. ParseNodePtr result = ParseExpr<buildAST>(koplAsg, nullptr, TRUE, FALSE, nullptr);
  5511. if (buildAST)
  5512. {
  5513. pnodeRet->sxReturn.pnodeExpr = result;
  5514. pnodeRet->ichMin = pnodeRet->sxReturn.pnodeExpr->ichMin;
  5515. pnodeRet->ichLim = pnodeRet->sxReturn.pnodeExpr->ichLim;
  5516. // Pushing a statement node with PushStmt<>() normally does this initialization
  5517. // but do it here manually since we know there is no outer statement node.
  5518. pnodeRet->sxStmt.grfnop = 0;
  5519. pnodeRet->sxStmt.pnodeOuter = nullptr;
  5520. pnodeLambda->ichLim = pnodeRet->ichLim;
  5521. pnodeLambda->sxFnc.cbLim = m_pscan->IecpLimTokPrevious();
  5522. pnodeLambda->sxFnc.pnodeScopes->ichLim = pnodeRet->ichLim;
  5523. pnodeLambda->sxFnc.pnodeBody = nullptr;
  5524. AddToNodeList(&pnodeLambda->sxFnc.pnodeBody, &lastNodeRef, pnodeLambda->sxFnc.pnodeScopes);
  5525. // Append an EndCode node.
  5526. ParseNodePtr end = CreateNodeWithScanner<knopEndCode>(pnodeRet->ichLim);
  5527. end->ichLim = end->ichMin; // make end code zero width at the immediate end of lambda body
  5528. AddToNodeList(&pnodeLambda->sxFnc.pnodeBody, &lastNodeRef, end);
  5529. // Lambda's do not have arguments binding
  5530. pnodeLambda->sxFnc.SetHasReferenceableBuiltInArguments(false);
  5531. }
  5532. }
  5533. void Parser::CheckStrictFormalParameters()
  5534. {
  5535. if (m_token.tk == tkID)
  5536. {
  5537. // single parameter arrow function case
  5538. IdentPtr pid = m_token.GetIdentifier(m_phtbl);
  5539. CheckStrictModeEvalArgumentsUsage(pid);
  5540. return;
  5541. }
  5542. Assert(m_token.tk == tkLParen);
  5543. m_pscan->ScanForcingPid();
  5544. if (m_token.tk != tkRParen)
  5545. {
  5546. SList<IdentPtr> formals(&m_nodeAllocator);
  5547. for (;;)
  5548. {
  5549. if (m_token.tk != tkID)
  5550. {
  5551. IdentifierExpectedError(m_token);
  5552. }
  5553. IdentPtr pid = m_token.GetIdentifier(m_phtbl);
  5554. CheckStrictModeEvalArgumentsUsage(pid);
  5555. if (formals.Has(pid))
  5556. {
  5557. Error(ERRES5ArgSame, m_pscan->IchMinTok(), m_pscan->IchLimTok());
  5558. }
  5559. else
  5560. {
  5561. formals.Prepend(pid);
  5562. }
  5563. m_pscan->Scan();
  5564. if (m_token.tk == tkAsg && m_scriptContext->GetConfig()->IsES6DefaultArgsEnabled())
  5565. {
  5566. m_pscan->Scan();
  5567. // We can avoid building the AST since we are just checking the default expression.
  5568. ParseNodePtr pnodeInit = ParseExpr<false>(koplCma);
  5569. Assert(pnodeInit == nullptr);
  5570. }
  5571. if (m_token.tk != tkComma)
  5572. {
  5573. break;
  5574. }
  5575. m_pscan->ScanForcingPid();
  5576. if (m_token.tk == tkRParen && m_scriptContext->GetConfig()->IsES7TrailingCommaEnabled())
  5577. {
  5578. break;
  5579. }
  5580. }
  5581. }
  5582. Assert(m_token.tk == tkRParen);
  5583. }
  5584. void Parser::FinishFncNode(ParseNodePtr pnodeFnc)
  5585. {
  5586. AnalysisAssert(pnodeFnc);
  5587. // Finish the AST for a function that was deferred earlier, but which we decided
  5588. // to finish after the fact.
  5589. // We assume that the name(s) and arg(s) have already got parse nodes, so
  5590. // we just have to do the function body.
  5591. // Save the current next function Id, and resume from the old one.
  5592. Js::LocalFunctionId * nextFunctionIdSave = m_nextFunctionId;
  5593. Js::LocalFunctionId tempNextFunctionId = pnodeFnc->sxFnc.functionId + 1;
  5594. this->m_nextFunctionId = &tempNextFunctionId;
  5595. ParseNodePtr pnodeFncSave = m_currentNodeFunc;
  5596. uint *pnestedCountSave = m_pnestedCount;
  5597. long* pAstSizeSave = m_pCurrentAstSize;
  5598. m_currentNodeFunc = pnodeFnc;
  5599. m_pCurrentAstSize = & (pnodeFnc->sxFnc.astSize);
  5600. pnodeFnc->sxFnc.nestedCount = 0;
  5601. m_pnestedCount = &pnodeFnc->sxFnc.nestedCount;
  5602. // Cue up the parser to the start of the function body.
  5603. if (pnodeFnc->sxFnc.pnodeName)
  5604. {
  5605. // Skip the name(s).
  5606. m_pscan->SetCurrentCharacter(pnodeFnc->sxFnc.pnodeName->ichLim, pnodeFnc->sxFnc.lineNumber);
  5607. }
  5608. else
  5609. {
  5610. m_pscan->SetCurrentCharacter(pnodeFnc->ichMin, pnodeFnc->sxFnc.lineNumber);
  5611. if (pnodeFnc->sxFnc.IsAccessor())
  5612. {
  5613. // Getter/setter. The node text starts with the name, so eat that.
  5614. m_pscan->ScanNoKeywords();
  5615. }
  5616. else
  5617. {
  5618. // Anonymous function. Skip any leading "("'s and "function".
  5619. for (;;)
  5620. {
  5621. m_pscan->Scan();
  5622. if (m_token.tk == tkFUNCTION)
  5623. {
  5624. break;
  5625. }
  5626. Assert(m_token.tk == tkLParen || m_token.tk == tkStar);
  5627. }
  5628. }
  5629. }
  5630. // switch scanner to treat 'yield' as keyword in generator functions
  5631. // or as an identifier in non-generator functions
  5632. bool fPreviousYieldIsKeyword = m_pscan->SetYieldIsKeyword(pnodeFnc && pnodeFnc->sxFnc.IsGenerator());
  5633. bool fPreviousAwaitIsKeyword = m_pscan->SetAwaitIsKeyword(pnodeFnc && pnodeFnc->sxFnc.IsAsync());
  5634. // Skip the arg list.
  5635. m_pscan->ScanNoKeywords();
  5636. if (m_token.tk == tkStar)
  5637. {
  5638. Assert(pnodeFnc->sxFnc.IsGenerator());
  5639. m_pscan->ScanNoKeywords();
  5640. }
  5641. Assert(m_token.tk == tkLParen);
  5642. m_pscan->ScanNoKeywords();
  5643. if (m_token.tk != tkRParen)
  5644. {
  5645. for (;;)
  5646. {
  5647. if (m_token.tk == tkEllipsis)
  5648. {
  5649. m_pscan->ScanNoKeywords();
  5650. }
  5651. if (m_token.tk == tkID)
  5652. {
  5653. m_pscan->ScanNoKeywords();
  5654. if (m_token.tk == tkAsg)
  5655. {
  5656. // Eat the default expression
  5657. m_pscan->Scan();
  5658. ParseExpr<false>(koplCma);
  5659. }
  5660. }
  5661. else if (IsPossiblePatternStart())
  5662. {
  5663. ParseDestructuredLiteralWithScopeSave(tkLET, false/*isDecl*/, false /*topLevel*/);
  5664. }
  5665. else
  5666. {
  5667. AssertMsg(false, "Unexpected identifier prefix while fast-scanning formals");
  5668. }
  5669. if (m_token.tk != tkComma)
  5670. {
  5671. break;
  5672. }
  5673. m_pscan->ScanNoKeywords();
  5674. if (m_token.tk == tkRParen && m_scriptContext->GetConfig()->IsES7TrailingCommaEnabled())
  5675. {
  5676. break;
  5677. }
  5678. }
  5679. }
  5680. if (m_token.tk == tkRParen) // This might be false due to a lambda => token.
  5681. {
  5682. m_pscan->Scan();
  5683. }
  5684. // Finish the function body.
  5685. {
  5686. // Note that in IE8- modes, surrounding parentheses are considered part of function body. e.g. "( function x(){} )".
  5687. // We lose that context here since we start from middle of function body. So save and restore source range info.
  5688. ParseNodePtr* lastNodeRef = NULL;
  5689. const charcount_t ichLim = pnodeFnc->ichLim;
  5690. const size_t cbLim = pnodeFnc->sxFnc.cbLim;
  5691. this->FinishFncDecl(pnodeFnc, NULL, lastNodeRef);
  5692. #if DBG
  5693. // The pnode extent may not match the original extent.
  5694. // We expect this to happen only when there are trailing ")"'s.
  5695. // Consume them and make sure that's all we've got.
  5696. if (pnodeFnc->ichLim != ichLim)
  5697. {
  5698. Assert(pnodeFnc->ichLim < ichLim);
  5699. m_pscan->SetCurrentCharacter(pnodeFnc->ichLim);
  5700. while (m_pscan->IchLimTok() != ichLim)
  5701. {
  5702. m_pscan->ScanNoKeywords();
  5703. Assert(m_token.tk == tkRParen);
  5704. }
  5705. }
  5706. #endif
  5707. pnodeFnc->ichLim = ichLim;
  5708. pnodeFnc->sxFnc.cbLim = cbLim;
  5709. }
  5710. m_currentNodeFunc = pnodeFncSave;
  5711. m_pCurrentAstSize = pAstSizeSave;
  5712. m_pnestedCount = pnestedCountSave;
  5713. Assert(m_pnestedCount);
  5714. Assert(tempNextFunctionId == pnodeFnc->sxFnc.deferredParseNextFunctionId);
  5715. this->m_nextFunctionId = nextFunctionIdSave;
  5716. m_pscan->SetYieldIsKeyword(fPreviousYieldIsKeyword);
  5717. m_pscan->SetAwaitIsKeyword(fPreviousAwaitIsKeyword);
  5718. }
  5719. void Parser::FinishFncDecl(ParseNodePtr pnodeFnc, LPCOLESTR pNameHint, ParseNodePtr *lastNodeRef)
  5720. {
  5721. LPCOLESTR name = NULL;
  5722. JS_ETW(long startAstSize = *m_pCurrentAstSize);
  5723. if(IS_JS_ETW(EventEnabledJSCRIPT_PARSE_METHOD_START()) || PHASE_TRACE1(Js::DeferParsePhase))
  5724. {
  5725. name = GetFunctionName(pnodeFnc, pNameHint);
  5726. m_functionBody = NULL; // for nested functions we do not want to get the name of the top deferred function return name;
  5727. JS_ETW(EventWriteJSCRIPT_PARSE_METHOD_START(m_sourceContextInfo->dwHostSourceContext, GetScriptContext(), pnodeFnc->sxFnc.functionId, 0, m_parseType, name));
  5728. OUTPUT_TRACE(Js::DeferParsePhase, _u("Parsing function (%s) : %s (%d)\n"), GetParseType(), name, pnodeFnc->sxFnc.functionId);
  5729. }
  5730. JS_ETW(EventWriteJSCRIPT_PARSE_FUNC(GetScriptContext(), pnodeFnc->sxFnc.functionId, /*Undefer*/FALSE));
  5731. // Do the work of creating an AST for a function body.
  5732. // This is common to the un-deferred case and the case in which we un-defer late in the game.
  5733. Assert(pnodeFnc->nop == knopFncDecl);
  5734. ChkCurTok(tkLCurly, ERRnoLcurly);
  5735. if (pnodeFnc->sxFnc.IsAsync())
  5736. {
  5737. TransformAsyncFncDeclAST(&pnodeFnc->sxFnc.pnodeBody, false);
  5738. }
  5739. else
  5740. {
  5741. ParseStmtList<true>(&pnodeFnc->sxFnc.pnodeBody, &lastNodeRef, SM_OnFunctionCode, true /* isSourceElementList */);
  5742. // Append an EndCode node.
  5743. AddToNodeList(&pnodeFnc->sxFnc.pnodeBody, &lastNodeRef, CreateNodeWithScanner<knopEndCode>());
  5744. }
  5745. ChkCurTokNoScan(tkRCurly, ERRnoRcurly);
  5746. pnodeFnc->ichLim = m_pscan->IchLimTok();
  5747. pnodeFnc->sxFnc.cbLim = m_pscan->IecpLimTok();
  5748. // Restore the lists of scopes that contain function expressions.
  5749. // Save the temps and restore the outer scope's list.
  5750. // NOTE: Eze makes no use of this.
  5751. //pnodeFnc->sxFnc.pnodeTmps = *m_ppnodeVar;
  5752. #ifdef ENABLE_JS_ETW
  5753. long astSize = *m_pCurrentAstSize - startAstSize;
  5754. EventWriteJSCRIPT_PARSE_METHOD_STOP(m_sourceContextInfo->dwHostSourceContext, GetScriptContext(), pnodeFnc->sxFnc.functionId, astSize, m_parseType, name);
  5755. #endif
  5756. }
  5757. void Parser::AddArgumentsNodeToVars(ParseNodePtr pnodeFnc)
  5758. {
  5759. if((pnodeFnc->grfpn & PNodeFlags::fpnArguments_overriddenByDecl) || pnodeFnc->sxFnc.IsLambda())
  5760. {
  5761. // In any of the following cases, there is no way to reference the built-in 'arguments' variable (in the order of checks
  5762. // above):
  5763. // - A function parameter is named 'arguments'
  5764. // - There is a nested function declaration (or named function expression in compat modes) named 'arguments'
  5765. // - In compat modes, the function is named arguments, does not have a var declaration named 'arguments', and does
  5766. // not call 'eval'
  5767. pnodeFnc->sxFnc.SetHasReferenceableBuiltInArguments(false);
  5768. }
  5769. else
  5770. {
  5771. ParseNodePtr argNode = nullptr;
  5772. if(m_ppnodeVar == &pnodeFnc->sxFnc.pnodeVars)
  5773. {
  5774. // There were no var declarations in the function
  5775. argNode = CreateVarDeclNode(wellKnownPropertyPids.arguments, STVariable, true, pnodeFnc);
  5776. }
  5777. else
  5778. {
  5779. // There were var declarations in the function, so insert an 'arguments' local at the beginning of the var list.
  5780. // This is done because the built-in 'arguments' variable overrides an 'arguments' var declaration until the
  5781. // 'arguments' variable is assigned. By putting our built-in var declaration at the beginning, an 'arguments'
  5782. // identifier will resolve to this symbol, which has the fpnArguments flag set, and will be the built-in arguments
  5783. // object until it is replaced with something else.
  5784. ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
  5785. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  5786. argNode = CreateVarDeclNode(wellKnownPropertyPids.arguments, STVariable, true, pnodeFnc);
  5787. m_ppnodeVar = ppnodeVarSave;
  5788. }
  5789. Assert(argNode);
  5790. argNode->grfpn |= PNodeFlags::fpnArguments;
  5791. // When a function definition with the name arguments occurs in the body the declaration of the arguments symbol will
  5792. // be set to that function declaration. We should change it to arguments declaration from the param scope as it may be
  5793. // used in the param scope and we have to load the arguments.
  5794. argNode->sxVar.sym->SetDecl(argNode);
  5795. pnodeFnc->sxFnc.SetHasReferenceableBuiltInArguments(true);
  5796. }
  5797. }
  5798. LPCOLESTR Parser::GetFunctionName(ParseNodePtr pnodeFnc, LPCOLESTR pNameHint)
  5799. {
  5800. LPCOLESTR name = nullptr;
  5801. if(pnodeFnc->sxFnc.pnodeName != nullptr && knopVarDecl == pnodeFnc->sxFnc.pnodeName->nop)
  5802. {
  5803. name = pnodeFnc->sxFnc.pnodeName->sxVar.pid->Psz();
  5804. }
  5805. if(name == nullptr && pNameHint != nullptr)
  5806. {
  5807. name = pNameHint;
  5808. }
  5809. if(name == nullptr && m_functionBody != nullptr)
  5810. {
  5811. name = m_functionBody->GetExternalDisplayName();
  5812. }
  5813. else if(name == nullptr)
  5814. {
  5815. name = Js::Constants::AnonymousFunction;
  5816. }
  5817. return name;
  5818. }
  5819. IdentPtr Parser::ParseClassPropertyName(IdentPtr * pidHint)
  5820. {
  5821. if (m_token.tk == tkID || m_token.tk == tkStrCon || m_token.IsReservedWord())
  5822. {
  5823. IdentPtr pid;
  5824. if (m_token.tk == tkStrCon)
  5825. {
  5826. if (m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  5827. {
  5828. Error(ERRES5NoOctal);
  5829. }
  5830. pid = m_token.GetStr();
  5831. }
  5832. else
  5833. {
  5834. pid = m_token.GetIdentifier(m_phtbl);
  5835. }
  5836. *pidHint = pid;
  5837. return pid;
  5838. }
  5839. else if (m_token.tk == tkIntCon)
  5840. {
  5841. if (m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  5842. {
  5843. Error(ERRES5NoOctal);
  5844. }
  5845. return m_pscan->PidFromLong(m_token.GetLong());
  5846. }
  5847. else if (m_token.tk == tkFltCon)
  5848. {
  5849. if (m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  5850. {
  5851. Error(ERRES5NoOctal);
  5852. }
  5853. return m_pscan->PidFromDbl(m_token.GetDouble());
  5854. }
  5855. Error(ERRnoMemberIdent);
  5856. }
  5857. LPCOLESTR Parser::ConstructFinalHintNode(IdentPtr pClassName, IdentPtr pMemberName, IdentPtr pGetSet, bool isStatic, ulong* nameLength, ulong* pShortNameOffset, bool isComputedName, LPCOLESTR pMemberNameHint)
  5858. {
  5859. if ((pMemberName == nullptr && !isComputedName) ||
  5860. (pMemberNameHint == nullptr && isComputedName) ||
  5861. !CONFIG_FLAG(UseFullName))
  5862. {
  5863. return nullptr;
  5864. }
  5865. LPCOLESTR pFinalName = isComputedName? pMemberNameHint : pMemberName->Psz();
  5866. ulong fullNameHintLength = 0;
  5867. ulong shortNameOffset = 0;
  5868. if (!isStatic)
  5869. {
  5870. // Add prototype.
  5871. pFinalName = AppendNameHints(wellKnownPropertyPids.prototype, pFinalName, &fullNameHintLength, &shortNameOffset);
  5872. }
  5873. if (pClassName)
  5874. {
  5875. ulong classNameOffset = 0;
  5876. pFinalName = AppendNameHints(pClassName, pFinalName, &fullNameHintLength, &classNameOffset);
  5877. shortNameOffset += classNameOffset;
  5878. }
  5879. if (pGetSet)
  5880. {
  5881. if (m_scriptContext->GetConfig()->IsES6FunctionNameEnabled())
  5882. {
  5883. // displays as get/set prototype.funcname
  5884. ulong getSetOffset = 0;
  5885. pFinalName = AppendNameHints(pGetSet, pFinalName, &fullNameHintLength, &getSetOffset, true);
  5886. shortNameOffset += getSetOffset;
  5887. }
  5888. else
  5889. {
  5890. pFinalName = AppendNameHints(pFinalName, pGetSet, &fullNameHintLength, &shortNameOffset);
  5891. }
  5892. }
  5893. if (fullNameHintLength > *nameLength)
  5894. {
  5895. *nameLength = fullNameHintLength;
  5896. }
  5897. if (shortNameOffset > *pShortNameOffset)
  5898. {
  5899. *pShortNameOffset = shortNameOffset;
  5900. }
  5901. return pFinalName;
  5902. }
  5903. class AutoParsingSuperRestrictionStateRestorer
  5904. {
  5905. public:
  5906. AutoParsingSuperRestrictionStateRestorer(Parser* parser) : m_parser(parser)
  5907. {
  5908. AssertMsg(this->m_parser != nullptr, "This just should not happen");
  5909. this->m_originalParsingSuperRestrictionState = this->m_parser->m_parsingSuperRestrictionState;
  5910. }
  5911. ~AutoParsingSuperRestrictionStateRestorer()
  5912. {
  5913. AssertMsg(this->m_parser != nullptr, "This just should not happen");
  5914. this->m_parser->m_parsingSuperRestrictionState = m_originalParsingSuperRestrictionState;
  5915. }
  5916. private:
  5917. Parser* m_parser;
  5918. int m_originalParsingSuperRestrictionState;
  5919. };
  5920. template<bool buildAST>
  5921. ParseNodePtr Parser::ParseClassDecl(BOOL isDeclaration, LPCOLESTR pNameHint, ulong *pHintLength, ulong *pShortNameOffset)
  5922. {
  5923. bool hasConstructor = false;
  5924. bool hasExtends = false;
  5925. IdentPtr name = nullptr;
  5926. ParseNodePtr pnodeName = nullptr;
  5927. ParseNodePtr pnodeConstructor = nullptr;
  5928. ParseNodePtr pnodeExtends = nullptr;
  5929. ParseNodePtr pnodeMembers = nullptr;
  5930. ParseNodePtr *lastMemberNodeRef = nullptr;
  5931. ParseNodePtr pnodeStaticMembers = nullptr;
  5932. ParseNodePtr *lastStaticMemberNodeRef = nullptr;
  5933. ulong nameHintLength = pHintLength ? *pHintLength : 0;
  5934. ulong nameHintOffset = pShortNameOffset ? *pShortNameOffset : 0;
  5935. ArenaAllocator tempAllocator(_u("ClassMemberNames"), m_nodeAllocator.GetPageAllocator(), Parser::OutOfMemory);
  5936. ParseNodePtr pnodeClass = nullptr;
  5937. if (buildAST)
  5938. {
  5939. pnodeClass = CreateNode(knopClassDecl);
  5940. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ClassCount, m_scriptContext);
  5941. }
  5942. m_pscan->Scan();
  5943. if (m_token.tk == tkID)
  5944. {
  5945. name = m_token.GetIdentifier(m_phtbl);
  5946. m_pscan->Scan();
  5947. }
  5948. else if (isDeclaration)
  5949. {
  5950. IdentifierExpectedError(m_token);
  5951. }
  5952. if (isDeclaration && name == wellKnownPropertyPids.arguments && GetCurrentBlockInfo()->pnodeBlock->sxBlock.blockType == Function)
  5953. {
  5954. GetCurrentFunctionNode()->grfpn |= PNodeFlags::fpnArguments_overriddenByDecl;
  5955. }
  5956. BOOL strictSave = m_fUseStrictMode;
  5957. m_fUseStrictMode = TRUE;
  5958. if (m_token.tk == tkEXTENDS)
  5959. {
  5960. m_pscan->Scan();
  5961. pnodeExtends = ParseExpr<buildAST>();
  5962. hasExtends = true;
  5963. }
  5964. if (m_token.tk != tkLCurly)
  5965. {
  5966. Error(ERRnoLcurly);
  5967. }
  5968. OUTPUT_TRACE_DEBUGONLY(Js::ES6VerboseFlag, _u("Parsing class (%s) : %s\n"), GetParseType(), name ? name->Psz() : _u("anonymous class"));
  5969. ParseNodePtr pnodeDeclName = nullptr;
  5970. if (isDeclaration)
  5971. {
  5972. pnodeDeclName = CreateBlockScopedDeclNode(name, knopLetDecl);
  5973. }
  5974. ParseNodePtr *ppnodeScopeSave = nullptr;
  5975. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  5976. ParseNodePtr pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block);
  5977. if (buildAST)
  5978. {
  5979. PushFuncBlockScope(pnodeBlock, &ppnodeScopeSave, &ppnodeExprScopeSave);
  5980. pnodeClass->sxClass.pnodeBlock = pnodeBlock;
  5981. }
  5982. if (name)
  5983. {
  5984. pnodeName = CreateBlockScopedDeclNode(name, knopConstDecl);
  5985. }
  5986. RestorePoint beginClass;
  5987. m_pscan->Capture(&beginClass);
  5988. m_pscan->ScanForcingPid();
  5989. IdentPtr pClassNamePid = pnodeName ? pnodeName->sxVar.pid : nullptr;
  5990. for (;;)
  5991. {
  5992. if (m_token.tk == tkSColon)
  5993. {
  5994. m_pscan->ScanForcingPid();
  5995. continue;
  5996. }
  5997. if (m_token.tk == tkRCurly)
  5998. {
  5999. break;
  6000. }
  6001. bool isStatic = m_token.tk == tkSTATIC;
  6002. if (isStatic)
  6003. {
  6004. m_pscan->ScanForcingPid();
  6005. }
  6006. ushort fncDeclFlags = fFncNoName | fFncMethod | fFncClassMember;
  6007. charcount_t ichMin = 0;
  6008. size_t iecpMin = 0;
  6009. ParseNodePtr pnodeMemberName = nullptr;
  6010. IdentPtr pidHint = nullptr;
  6011. IdentPtr memberPid = nullptr;
  6012. LPCOLESTR pMemberNameHint = nullptr;
  6013. ulong memberNameHintLength = 0;
  6014. ulong memberNameOffset = 0;
  6015. bool isComputedName = false;
  6016. bool isAsyncMethod = false;
  6017. if (m_token.tk == tkID && m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.async && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  6018. {
  6019. RestorePoint parsedAsync;
  6020. m_pscan->Capture(&parsedAsync);
  6021. ichMin = m_pscan->IchMinTok();
  6022. iecpMin = m_pscan->IecpMinTok();
  6023. m_pscan->Scan();
  6024. if (m_token.tk == tkLParen || m_pscan->FHadNewLine())
  6025. {
  6026. m_pscan->SeekTo(parsedAsync);
  6027. }
  6028. else
  6029. {
  6030. isAsyncMethod = true;
  6031. }
  6032. }
  6033. bool isGenerator = m_scriptContext->GetConfig()->IsES6GeneratorsEnabled() &&
  6034. m_token.tk == tkStar;
  6035. if (isGenerator)
  6036. {
  6037. fncDeclFlags |= fFncGenerator;
  6038. m_pscan->ScanForcingPid();
  6039. }
  6040. if (m_token.tk == tkLBrack && m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  6041. {
  6042. // Computed member name: [expr] () { }
  6043. LPCOLESTR emptyHint = nullptr;
  6044. ParseComputedName<buildAST>(&pnodeMemberName, &emptyHint, &pMemberNameHint, &memberNameHintLength, &memberNameOffset);
  6045. isComputedName = true;
  6046. }
  6047. else // not computed name
  6048. {
  6049. memberPid = this->ParseClassPropertyName(&pidHint);
  6050. if (pidHint)
  6051. {
  6052. pMemberNameHint = pidHint->Psz();
  6053. memberNameHintLength = pidHint->Cch();
  6054. }
  6055. }
  6056. if (buildAST && memberPid)
  6057. {
  6058. pnodeMemberName = CreateStrNodeWithScanner(memberPid);
  6059. }
  6060. if (!isStatic && memberPid == wellKnownPropertyPids.constructor)
  6061. {
  6062. if (hasConstructor || isAsyncMethod)
  6063. {
  6064. Error(ERRsyntax);
  6065. }
  6066. hasConstructor = true;
  6067. LPCOLESTR pConstructorName = nullptr;
  6068. ulong constructorNameLength = 0;
  6069. ulong constructorShortNameHintOffset = 0;
  6070. if (pnodeName && pnodeName->sxVar.pid)
  6071. {
  6072. pConstructorName = pnodeName->sxVar.pid->Psz();
  6073. constructorNameLength = pnodeName->sxVar.pid->Cch();
  6074. }
  6075. else
  6076. {
  6077. pConstructorName = pNameHint;
  6078. constructorNameLength = nameHintLength;
  6079. constructorShortNameHintOffset = nameHintOffset;
  6080. }
  6081. {
  6082. AutoParsingSuperRestrictionStateRestorer restorer(this);
  6083. this->m_parsingSuperRestrictionState = hasExtends ? ParsingSuperRestrictionState_SuperCallAndPropertyAllowed : ParsingSuperRestrictionState_SuperPropertyAllowed;
  6084. pnodeConstructor = ParseFncDecl<buildAST>(fncDeclFlags, pConstructorName, /* needsPIDOnRCurlyScan */ true, /* resetParsingSuperRestrictionState = */false);
  6085. }
  6086. if (pnodeConstructor->sxFnc.IsGenerator())
  6087. {
  6088. Error(ERRConstructorCannotBeGenerator);
  6089. }
  6090. Assert(constructorNameLength >= constructorShortNameHintOffset);
  6091. // The constructor function will get the same name as class.
  6092. pnodeConstructor->sxFnc.hint = pConstructorName;
  6093. pnodeConstructor->sxFnc.hintLength = constructorNameLength;
  6094. pnodeConstructor->sxFnc.hintOffset = constructorShortNameHintOffset;
  6095. pnodeConstructor->sxFnc.pid = pnodeName && pnodeName->sxVar.pid ? pnodeName->sxVar.pid : wellKnownPropertyPids.constructor;
  6096. pnodeConstructor->sxFnc.SetIsClassConstructor(TRUE);
  6097. pnodeConstructor->sxFnc.SetIsBaseClassConstructor(pnodeExtends == nullptr);
  6098. }
  6099. else
  6100. {
  6101. ParseNodePtr pnodeMember = nullptr;
  6102. bool isMemberNamedGetOrSet = false;
  6103. RestorePoint beginMethodName;
  6104. m_pscan->Capture(&beginMethodName);
  6105. if (memberPid == wellKnownPropertyPids.get || memberPid == wellKnownPropertyPids.set)
  6106. {
  6107. m_pscan->ScanForcingPid();
  6108. }
  6109. if (m_token.tk == tkLParen)
  6110. {
  6111. m_pscan->SeekTo(beginMethodName);
  6112. isMemberNamedGetOrSet = true;
  6113. }
  6114. if ((memberPid == wellKnownPropertyPids.get || memberPid == wellKnownPropertyPids.set) && !isMemberNamedGetOrSet)
  6115. {
  6116. bool isGetter = (memberPid == wellKnownPropertyPids.get);
  6117. if (m_token.tk == tkLBrack && m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  6118. {
  6119. // Computed get/set member name: get|set [expr] () { }
  6120. LPCOLESTR emptyHint = nullptr;
  6121. ParseComputedName<buildAST>(&pnodeMemberName, &emptyHint, &pMemberNameHint, &memberNameHintLength, &memberNameOffset);
  6122. isComputedName = true;
  6123. }
  6124. else // not computed name
  6125. {
  6126. memberPid = this->ParseClassPropertyName(&pidHint);
  6127. }
  6128. if ((isStatic ? (memberPid == wellKnownPropertyPids.prototype) : (memberPid == wellKnownPropertyPids.constructor)) || isAsyncMethod)
  6129. {
  6130. Error(ERRsyntax);
  6131. }
  6132. if (buildAST && memberPid && !isComputedName)
  6133. {
  6134. pnodeMemberName = CreateStrNodeWithScanner(memberPid);
  6135. }
  6136. ParseNodePtr pnodeFnc = nullptr;
  6137. {
  6138. AutoParsingSuperRestrictionStateRestorer restorer(this);
  6139. this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperPropertyAllowed;
  6140. pnodeFnc = ParseFncDecl<buildAST>(fncDeclFlags | (isGetter ? fFncNoArg : fFncOneArg),
  6141. pidHint ? pidHint->Psz() : nullptr, /* needsPIDOnRCurlyScan */ true,
  6142. /* resetParsingSuperRestrictionState */false);
  6143. }
  6144. pnodeFnc->sxFnc.SetIsStaticMember(isStatic);
  6145. if (buildAST)
  6146. {
  6147. pnodeFnc->sxFnc.SetIsAccessor();
  6148. pnodeMember = CreateBinNode(isGetter ? knopGetMember : knopSetMember, pnodeMemberName, pnodeFnc);
  6149. pMemberNameHint = ConstructFinalHintNode(pClassNamePid, pidHint,
  6150. isGetter ? wellKnownPropertyPids.get : wellKnownPropertyPids.set, isStatic,
  6151. &memberNameHintLength, &memberNameOffset, isComputedName, pMemberNameHint);
  6152. }
  6153. }
  6154. else
  6155. {
  6156. if (isStatic && (memberPid == wellKnownPropertyPids.prototype))
  6157. {
  6158. Error(ERRsyntax);
  6159. }
  6160. ParseNodePtr pnodeFnc = nullptr;
  6161. {
  6162. AutoParsingSuperRestrictionStateRestorer restorer(this);
  6163. this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperPropertyAllowed;
  6164. if (isAsyncMethod)
  6165. {
  6166. fncDeclFlags |= fFncAsync;
  6167. }
  6168. pnodeFnc = ParseFncDecl<buildAST>(fncDeclFlags, pidHint ? pidHint->Psz() : nullptr, /* needsPIDOnRCurlyScan */ true, /* resetParsingSuperRestrictionState */false);
  6169. if (isAsyncMethod)
  6170. {
  6171. pnodeFnc->sxFnc.cbMin = iecpMin;
  6172. pnodeFnc->ichMin = ichMin;
  6173. }
  6174. }
  6175. pnodeFnc->sxFnc.SetIsStaticMember(isStatic);
  6176. if (buildAST)
  6177. {
  6178. pnodeMember = CreateBinNode(knopMember, pnodeMemberName, pnodeFnc);
  6179. pMemberNameHint = ConstructFinalHintNode(pClassNamePid, pidHint, nullptr /*pgetset*/, isStatic, &memberNameHintLength, &memberNameOffset, isComputedName, pMemberNameHint);
  6180. }
  6181. }
  6182. if (buildAST)
  6183. {
  6184. Assert(memberNameHintLength >= memberNameOffset);
  6185. pnodeMember->sxBin.pnode2->sxFnc.hint = pMemberNameHint; // Fully qualified name
  6186. pnodeMember->sxBin.pnode2->sxFnc.hintLength = memberNameHintLength;
  6187. pnodeMember->sxBin.pnode2->sxFnc.hintOffset = memberNameOffset;
  6188. pnodeMember->sxBin.pnode2->sxFnc.pid = memberPid; // Short name
  6189. AddToNodeList(isStatic ? &pnodeStaticMembers : &pnodeMembers, isStatic ? &lastStaticMemberNodeRef : &lastMemberNodeRef, pnodeMember);
  6190. }
  6191. }
  6192. }
  6193. if (buildAST)
  6194. {
  6195. pnodeClass->ichLim = m_pscan->IchLimTok();
  6196. }
  6197. if (!hasConstructor)
  6198. {
  6199. OUTPUT_TRACE_DEBUGONLY(Js::ES6VerboseFlag, _u("Generating constructor (%s) : %s\n"), GetParseType(), name ? name->Psz() : _u("anonymous class"));
  6200. RestorePoint endClass;
  6201. m_pscan->Capture(&endClass);
  6202. m_pscan->SeekTo(beginClass);
  6203. pnodeConstructor = GenerateEmptyConstructor<buildAST>(pnodeExtends != nullptr);
  6204. if (buildAST)
  6205. {
  6206. if (pClassNamePid)
  6207. {
  6208. pnodeConstructor->sxFnc.hint = pClassNamePid->Psz();
  6209. pnodeConstructor->sxFnc.hintLength = pClassNamePid->Cch();
  6210. pnodeConstructor->sxFnc.hintOffset = 0;
  6211. }
  6212. else
  6213. {
  6214. Assert(nameHintLength >= nameHintOffset);
  6215. pnodeConstructor->sxFnc.hint = pNameHint;
  6216. pnodeConstructor->sxFnc.hintLength = nameHintLength;
  6217. pnodeConstructor->sxFnc.hintOffset = nameHintOffset;
  6218. }
  6219. pnodeConstructor->sxFnc.pid = pClassNamePid;
  6220. }
  6221. m_pscan->SeekTo(endClass);
  6222. }
  6223. if (buildAST)
  6224. {
  6225. pnodeConstructor->sxFnc.cbMin = pnodeClass->ichMin;
  6226. pnodeConstructor->sxFnc.cbLim = pnodeClass->ichLim;
  6227. pnodeConstructor->ichMin = pnodeClass->ichMin;
  6228. pnodeConstructor->ichLim = pnodeClass->ichLim;
  6229. PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
  6230. pnodeClass->sxClass.pnodeDeclName = pnodeDeclName;
  6231. pnodeClass->sxClass.pnodeName = pnodeName;
  6232. pnodeClass->sxClass.pnodeConstructor = pnodeConstructor;
  6233. pnodeClass->sxClass.pnodeExtends = pnodeExtends;
  6234. pnodeClass->sxClass.pnodeMembers = pnodeMembers;
  6235. pnodeClass->sxClass.pnodeStaticMembers = pnodeStaticMembers;
  6236. pnodeClass->sxClass.isDefaultModuleExport = false;
  6237. }
  6238. FinishParseBlock(pnodeBlock);
  6239. m_fUseStrictMode = strictSave;
  6240. m_pscan->Scan();
  6241. return pnodeClass;
  6242. }
  6243. template<bool buildAST>
  6244. ParseNodePtr Parser::ParseStringTemplateDecl(ParseNodePtr pnodeTagFnc)
  6245. {
  6246. ParseNodePtr pnodeStringLiterals = nullptr;
  6247. ParseNodePtr* lastStringLiteralNodeRef = nullptr;
  6248. ParseNodePtr pnodeRawStringLiterals = nullptr;
  6249. ParseNodePtr* lastRawStringLiteralNodeRef = nullptr;
  6250. ParseNodePtr pnodeSubstitutionExpressions = nullptr;
  6251. ParseNodePtr* lastSubstitutionExpressionNodeRef = nullptr;
  6252. ParseNodePtr pnodeTagFncArgs = nullptr;
  6253. ParseNodePtr* lastTagFncArgNodeRef = nullptr;
  6254. ParseNodePtr stringLiteral = nullptr;
  6255. ParseNodePtr stringLiteralRaw = nullptr;
  6256. ParseNodePtr pnodeStringTemplate = nullptr;
  6257. bool templateClosed = false;
  6258. const bool isTagged = pnodeTagFnc != nullptr;
  6259. uint16 stringConstantCount = 0;
  6260. charcount_t ichMin = 0;
  6261. Assert(m_token.tk == tkStrTmplBasic || m_token.tk == tkStrTmplBegin);
  6262. if (buildAST)
  6263. {
  6264. pnodeStringTemplate = CreateNode(knopStrTemplate);
  6265. pnodeStringTemplate->sxStrTemplate.countStringLiterals = 0;
  6266. pnodeStringTemplate->sxStrTemplate.isTaggedTemplate = isTagged ? TRUE : FALSE;
  6267. // If this is a tagged string template, we need to start building the arg list for the call
  6268. if (isTagged)
  6269. {
  6270. ichMin = pnodeTagFnc->ichMin;
  6271. AddToNodeListEscapedUse(&pnodeTagFncArgs, &lastTagFncArgNodeRef, pnodeStringTemplate);
  6272. }
  6273. }
  6274. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(StringTemplatesCount, m_scriptContext);
  6275. OUTPUT_TRACE_DEBUGONLY(
  6276. Js::StringTemplateParsePhase,
  6277. _u("Starting to parse a string template (%s)...\n\tis tagged = %s\n"),
  6278. GetParseType(),
  6279. isTagged ? _u("true") : _u("false (Raw and cooked strings will not differ!)"));
  6280. // String template grammar
  6281. // `...` Simple string template
  6282. // `...${ String template beginning
  6283. // }...${ String template middle
  6284. // }...` String template end
  6285. while (!templateClosed)
  6286. {
  6287. // First, extract the string constant part - we always have one
  6288. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  6289. {
  6290. Error(ERRES5NoOctal);
  6291. }
  6292. // We are not able to pass more than a ushort worth of arguments to the tag
  6293. // so use that as a logical limit on the number of string constant pieces.
  6294. if (stringConstantCount >= USHORT_MAX)
  6295. {
  6296. Error(ERRnoMemory);
  6297. }
  6298. // Keep track of the string literal count (must be the same for raw strings)
  6299. // We use this in code gen so we don't need to count the string literals list
  6300. stringConstantCount++;
  6301. // If we are not creating parse nodes, there is no need to create strings
  6302. if (buildAST)
  6303. {
  6304. stringLiteral = CreateStrNodeWithScanner(m_token.GetStr());
  6305. AddToNodeList(&pnodeStringLiterals, &lastStringLiteralNodeRef, stringLiteral);
  6306. // We only need to collect a raw string when we are going to pass the string template to a tag
  6307. if (isTagged)
  6308. {
  6309. // Make the scanner create a PID for the raw string constant for the preceding scan
  6310. IdentPtr pid = m_pscan->GetSecondaryBufferAsPid();
  6311. stringLiteralRaw = CreateStrNodeWithScanner(pid);
  6312. // Should have gotten a raw string literal above
  6313. AddToNodeList(&pnodeRawStringLiterals, &lastRawStringLiteralNodeRef, stringLiteralRaw);
  6314. }
  6315. else
  6316. {
  6317. #if DBG
  6318. // Assign the raw string for debug tracing below
  6319. stringLiteralRaw = stringLiteral;
  6320. #endif
  6321. }
  6322. OUTPUT_TRACE_DEBUGONLY(
  6323. Js::StringTemplateParsePhase,
  6324. _u("Parsed string constant: \n\tcooked = \"%s\" \n\traw = \"%s\" \n\tdiffer = %d\n"),
  6325. stringLiteral->sxPid.pid->Psz(),
  6326. stringLiteralRaw->sxPid.pid->Psz(),
  6327. stringLiteral->sxPid.pid->Psz() == stringLiteralRaw->sxPid.pid->Psz() ? 0 : 1);
  6328. }
  6329. switch (m_token.tk)
  6330. {
  6331. case tkStrTmplEnd:
  6332. case tkStrTmplBasic:
  6333. // We do not need to parse an expression for either the end or basic string template tokens
  6334. templateClosed = true;
  6335. break;
  6336. case tkStrTmplBegin:
  6337. case tkStrTmplMid:
  6338. {
  6339. // In the middle or begin string template token case, we need to parse an expression next
  6340. m_pscan->Scan();
  6341. // Parse the contents of the curly braces as an expression
  6342. ParseNodePtr expression = ParseExpr<buildAST>(0);
  6343. // After parsing expression, scan should leave us with an RCurly token.
  6344. // Use the NoScan version so we do not automatically perform a scan - we need to
  6345. // set the scan state before next scan but we don't want to set that state if
  6346. // the token is not as expected since we'll error in that case.
  6347. ChkCurTokNoScan(tkRCurly, ERRnoRcurly);
  6348. // Notify the scanner that it should scan for a middle or end string template token
  6349. m_pscan->SetScanState(Scanner_t::ScanState::ScanStateStringTemplateMiddleOrEnd);
  6350. m_pscan->Scan();
  6351. if (buildAST)
  6352. {
  6353. // If we are going to call the tag function, add this expression into the list of args
  6354. if (isTagged)
  6355. {
  6356. AddToNodeListEscapedUse(&pnodeTagFncArgs, &lastTagFncArgNodeRef, expression);
  6357. }
  6358. else
  6359. {
  6360. // Otherwise add it to the substitution expression list
  6361. // TODO: Store the arguments and substitution expressions in a single list?
  6362. AddToNodeList(&pnodeSubstitutionExpressions, &lastSubstitutionExpressionNodeRef, expression);
  6363. }
  6364. }
  6365. if (!(m_token.tk == tkStrTmplMid || m_token.tk == tkStrTmplEnd))
  6366. {
  6367. // Scan with ScanState ScanStateStringTemplateMiddleOrEnd should only return
  6368. // tkStrTmpMid/End unless it is EOF or tkScanError
  6369. Assert(m_token.tk == tkEOF || m_token.tk == tkScanError);
  6370. Error(ERRsyntax);
  6371. }
  6372. OUTPUT_TRACE_DEBUGONLY(Js::StringTemplateParsePhase, _u("Parsed expression\n"));
  6373. }
  6374. break;
  6375. default:
  6376. Assert(false);
  6377. break;
  6378. }
  6379. }
  6380. if (buildAST)
  6381. {
  6382. pnodeStringTemplate->sxStrTemplate.pnodeStringLiterals = pnodeStringLiterals;
  6383. pnodeStringTemplate->sxStrTemplate.pnodeStringRawLiterals = pnodeRawStringLiterals;
  6384. pnodeStringTemplate->sxStrTemplate.pnodeSubstitutionExpressions = pnodeSubstitutionExpressions;
  6385. pnodeStringTemplate->sxStrTemplate.countStringLiterals = stringConstantCount;
  6386. // We should still have the last string literal.
  6387. // Use the char offset of the end of that constant as the end of the string template.
  6388. pnodeStringTemplate->ichLim = stringLiteral->ichLim;
  6389. // If this is a tagged template, we now have the argument list and can construct a call node
  6390. if (isTagged)
  6391. {
  6392. // Return the call node here and let the byte code generator Emit the string template automagically
  6393. pnodeStringTemplate = CreateCallNode(knopCall, pnodeTagFnc, pnodeTagFncArgs, ichMin, pnodeStringTemplate->ichLim);
  6394. // We need to set the arg count explicitly
  6395. pnodeStringTemplate->sxCall.argCount = stringConstantCount;
  6396. }
  6397. }
  6398. m_pscan->Scan();
  6399. return pnodeStringTemplate;
  6400. }
  6401. void Parser::TransformAsyncFncDeclAST(ParseNodePtr *pnodeBody, bool fLambda)
  6402. {
  6403. StmtNest *pstmtSave;
  6404. ParseNodePtr pnodeReturn;
  6405. ParseNodePtr pnodeAsyncSpawn;
  6406. ParseNodePtr pnodeFncGenerator = nullptr;
  6407. ParseNodePtr pnodeFncSave = nullptr;
  6408. ParseNodePtr pnodeDeferredFncSave = nullptr;
  6409. ParseNodePtr pnodeInnerBlock = nullptr;
  6410. ParseNodePtr pnodeBlock = nullptr;
  6411. ParseNodePtr *lastNodeRef = nullptr;
  6412. ParseNodePtr *ppnodeScopeSave = nullptr;
  6413. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  6414. AutoParsingSuperRestrictionStateRestorer restorer(this);
  6415. // Create the generator : function*() {}
  6416. uint tryCatchOrFinallyDepthSave = this->m_tryCatchOrFinallyDepth;
  6417. this->m_tryCatchOrFinallyDepth = 0;
  6418. uint scopeCountNoAstSave = m_scopeCountNoAst;
  6419. m_scopeCountNoAst = 0;
  6420. long* pAstSizeSave = m_pCurrentAstSize;
  6421. pnodeFncSave = m_currentNodeFunc;
  6422. pnodeDeferredFncSave = m_currentNodeDeferredFunc;
  6423. bool hasNonSimpleParameterList = m_currentNodeFunc->sxFnc.HasNonSimpleParameterList();
  6424. pnodeFncGenerator = CreateAsyncSpawnGenerator();
  6425. pstmtSave = m_pstmtCur;
  6426. SetCurrentStatement(nullptr);
  6427. bool fPreviousYieldIsKeyword = m_pscan->SetYieldIsKeyword(FALSE);
  6428. uint uDeferSave = m_grfscr & fscrDeferFncParse;
  6429. pnodeBlock = StartParseBlock<true>(PnodeBlockType::Parameter, ScopeType_Parameter);
  6430. pnodeFncGenerator->sxFnc.pnodeScopes = pnodeBlock;
  6431. m_ppnodeVar = &pnodeFncGenerator->sxFnc.pnodeParams;
  6432. ppnodeScopeSave = m_ppnodeScope;
  6433. m_ppnodeScope = &pnodeBlock->sxBlock.pnodeScopes;
  6434. pnodeBlock->sxBlock.pnodeStmt = pnodeFncGenerator;
  6435. ppnodeExprScopeSave = m_ppnodeExprScope;
  6436. m_ppnodeExprScope = nullptr;
  6437. // Push the formal parameter symbols again for the inner generator to get proper
  6438. // redeclaration semantics (error for let/const locals, merge for var locals)
  6439. Scope* paramScope = pnodeFncSave->sxFnc.pnodeScopes->sxBlock.scope;
  6440. paramScope->ForEachSymbol([this](Symbol* paramSym)
  6441. {
  6442. Symbol* sym = paramSym->GetPid()->GetTopRef()->GetSym();
  6443. PidRefStack* ref = PushPidRef(paramSym->GetPid());
  6444. ref->SetSym(sym);
  6445. });
  6446. pnodeInnerBlock = StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FunctionBody);
  6447. *m_ppnodeScope = pnodeInnerBlock;
  6448. pnodeFncGenerator->sxFnc.pnodeBodyScope = pnodeInnerBlock;
  6449. m_ppnodeScope = &pnodeInnerBlock->sxBlock.pnodeScopes;
  6450. pnodeInnerBlock->sxBlock.pnodeStmt = pnodeFncGenerator;
  6451. Assert(*m_ppnodeVar == nullptr);
  6452. pnodeFncGenerator->sxFnc.pnodeVars = nullptr;
  6453. m_ppnodeVar = &pnodeFncGenerator->sxFnc.pnodeVars;
  6454. DeferredFunctionStub *saveCurrentStub = m_currDeferredStub;
  6455. if (pnodeFncSave && m_currDeferredStub)
  6456. {
  6457. m_currDeferredStub = (m_currDeferredStub + (pnodeFncSave->sxFnc.nestedCount - 1))->deferredStubs;
  6458. }
  6459. // It is an error if the async function contains a "use strict" directive and has
  6460. // a non simple parameter list. Since we split the body from the parameters by the
  6461. // synthetic inner generator function, temporarily set the HasNonSimpleParameterList
  6462. // flag on the inner generator for the duration of parsing the body so that "use strict"
  6463. // will trigger the corresponding syntax error. Unset it afterwards since it has
  6464. // meaning post-parsing that won't match the actual parameter list of the generator.
  6465. pnodeFncGenerator->sxFnc.SetHasNonSimpleParameterList(hasNonSimpleParameterList);
  6466. // We always merge the param scope and body scope for async methods right now.
  6467. // So adding an additional reference for the param symbols to the body.
  6468. paramScope->ForEachSymbol([this] (Symbol* param)
  6469. {
  6470. Symbol* sym = param->GetPid()->GetTopRef()->GetSym();
  6471. PidRefStack* ref = PushPidRef(param->GetPid());
  6472. ref->SetSym(sym);
  6473. });
  6474. pnodeFncGenerator->sxFnc.pnodeBody = nullptr;
  6475. if (fLambda)
  6476. {
  6477. // Parse and set the function body
  6478. ParseExpressionLambdaBody<true>(*pnodeBody);
  6479. AddToNodeList(&pnodeFncGenerator->sxFnc.pnodeBody, &lastNodeRef, (*pnodeBody)->sxFnc.pnodeScopes->sxBlock.pnodeStmt);
  6480. }
  6481. else
  6482. {
  6483. // Parse the function body
  6484. ParseStmtList<true>(&pnodeFncGenerator->sxFnc.pnodeBody, &lastNodeRef, SM_OnFunctionCode, true);
  6485. ChkCurTokNoScan(tkRCurly, ERRnoRcurly);
  6486. }
  6487. AddToNodeList(&pnodeFncGenerator->sxFnc.pnodeBody, &lastNodeRef, CreateNodeWithScanner<knopEndCode>());
  6488. lastNodeRef = NULL;
  6489. pnodeFncGenerator->sxFnc.SetHasNonSimpleParameterList(false);
  6490. pnodeFncGenerator->ichLim = m_pscan->IchLimTok();
  6491. pnodeFncGenerator->sxFnc.cbLim = m_pscan->IecpLimTok();
  6492. m_currDeferredStub = saveCurrentStub;
  6493. FinishParseBlock(pnodeInnerBlock, true);
  6494. this->AddArgumentsNodeToVars(pnodeFncGenerator);
  6495. Assert(m_ppnodeExprScope == nullptr || *m_ppnodeExprScope == nullptr);
  6496. m_ppnodeExprScope = ppnodeExprScopeSave;
  6497. AssertMem(m_ppnodeScope);
  6498. Assert(nullptr == *m_ppnodeScope);
  6499. m_ppnodeScope = ppnodeScopeSave;
  6500. FinishParseBlock(pnodeBlock, true);
  6501. Assert(nullptr == m_pstmtCur);
  6502. SetCurrentStatement(pstmtSave);
  6503. if (!m_stoppedDeferredParse)
  6504. {
  6505. m_grfscr |= uDeferSave;
  6506. }
  6507. m_pscan->SetYieldIsKeyword(fPreviousYieldIsKeyword);
  6508. Assert(pnodeFncGenerator == m_currentNodeFunc);
  6509. m_currentNodeFunc = pnodeFncSave;
  6510. m_currentNodeDeferredFunc = pnodeDeferredFncSave;
  6511. m_pCurrentAstSize = pAstSizeSave;
  6512. m_inDeferredNestedFunc = false;
  6513. m_scopeCountNoAst = scopeCountNoAstSave;
  6514. this->m_tryCatchOrFinallyDepth = tryCatchOrFinallyDepthSave;
  6515. // Create the call : spawn(function*() {}, this)
  6516. pnodeAsyncSpawn = CreateBinNode(knopAsyncSpawn, pnodeFncGenerator, CreateNodeWithScanner<knopThis>());
  6517. // Create the return : return spawn(function*() {}, this)
  6518. pnodeReturn = CreateNodeWithScanner<knopReturn>();
  6519. pnodeReturn->sxStmt.grfnop = 0;
  6520. pnodeReturn->sxStmt.pnodeOuter = nullptr;
  6521. pnodeReturn->sxReturn.pnodeExpr = pnodeAsyncSpawn;
  6522. if (fLambda)
  6523. {
  6524. (*pnodeBody)->sxFnc.pnodeScopes->sxBlock.pnodeStmt = nullptr;
  6525. AddToNodeList(&(*pnodeBody)->sxFnc.pnodeScopes->sxBlock.pnodeStmt, &lastNodeRef, pnodeReturn);
  6526. }
  6527. else
  6528. {
  6529. *pnodeBody = nullptr;
  6530. AddToNodeList(pnodeBody, &lastNodeRef, pnodeReturn);
  6531. AddToNodeList(pnodeBody, &lastNodeRef, CreateNodeWithScanner<knopEndCode>());
  6532. }
  6533. if (pnodeFncGenerator->sxFnc.GetStrictMode())
  6534. {
  6535. GetCurrentFunctionNode()->sxFnc.SetStrictMode();
  6536. }
  6537. if (pnodeFncGenerator->sxFnc.UsesArguments())
  6538. {
  6539. GetCurrentFunctionNode()->sxFnc.SetUsesArguments();
  6540. }
  6541. if (pnodeFncGenerator->sxFnc.CallsEval() || pnodeFncGenerator->sxFnc.ChildCallsEval())
  6542. {
  6543. GetCurrentFunctionNode()->sxFnc.SetChildCallsEval();
  6544. }
  6545. lastNodeRef = NULL;
  6546. }
  6547. ParseNodePtr Parser::CreateAsyncSpawnGenerator()
  6548. {
  6549. ParseNodePtr pnodeFncGenerator = nullptr;
  6550. pnodeFncGenerator = CreateDummyFuncNode(false);
  6551. pnodeFncGenerator->sxFnc.functionId = (*m_nextFunctionId)++;
  6552. pnodeFncGenerator->sxFnc.cbMin = m_pscan->IecpMinTok();
  6553. pnodeFncGenerator->sxFnc.cbLim = m_pscan->IecpLimTok();
  6554. pnodeFncGenerator->sxFnc.lineNumber = m_pscan->LineCur();
  6555. pnodeFncGenerator->sxFnc.columnNumber = CalculateFunctionColumnNumber();
  6556. pnodeFncGenerator->sxFnc.SetNested(m_currentNodeFunc != nullptr);
  6557. pnodeFncGenerator->sxFnc.SetStrictMode(IsStrictMode());
  6558. pnodeFncGenerator->sxFnc.SetIsGenerator();
  6559. pnodeFncGenerator->sxFnc.SetIsLambda();
  6560. pnodeFncGenerator->sxFnc.scope = nullptr;
  6561. AppendFunctionToScopeList(false, pnodeFncGenerator);
  6562. return pnodeFncGenerator;
  6563. }
  6564. LPCOLESTR Parser::FormatPropertyString(LPCOLESTR propertyString, ParseNodePtr pNode, ulong *fullNameHintLength, ulong *pShortNameOffset)
  6565. {
  6566. // propertyString could be null, such as 'this.foo' =
  6567. // propertyString could be empty, found in pattern as in (-1)[""][(x = z)]
  6568. OpCode op = pNode->nop;
  6569. LPCOLESTR rightNode = nullptr;
  6570. if (propertyString == nullptr)
  6571. {
  6572. propertyString = _u("");
  6573. }
  6574. if (op != knopInt && op != knopFlt && op != knopName && op != knopStr)
  6575. {
  6576. rightNode = _u("");
  6577. }
  6578. else if (op == knopStr)
  6579. {
  6580. return AppendNameHints(propertyString, pNode->sxPid.pid, fullNameHintLength, pShortNameOffset, false, true/*add brackets*/);
  6581. }
  6582. else if(op == knopFlt)
  6583. {
  6584. rightNode = m_pscan->StringFromDbl(pNode->sxFlt.dbl);
  6585. }
  6586. else
  6587. {
  6588. rightNode = op == knopInt ? m_pscan->StringFromLong(pNode->sxInt.lw)
  6589. : pNode->sxPid.pid->Psz();
  6590. }
  6591. return AppendNameHints(propertyString, rightNode, fullNameHintLength, pShortNameOffset, false, true/*add brackets*/);
  6592. }
  6593. LPCOLESTR Parser::ConstructNameHint(ParseNodePtr pNode, ulong* fullNameHintLength, ulong *pShortNameOffset)
  6594. {
  6595. Assert(pNode != nullptr);
  6596. Assert(pNode->nop == knopDot || pNode->nop == knopIndex);
  6597. LPCOLESTR leftNode = nullptr;
  6598. if (pNode->sxBin.pnode1->nop == knopDot || pNode->sxBin.pnode1->nop == knopIndex)
  6599. {
  6600. leftNode = ConstructNameHint(pNode->sxBin.pnode1, fullNameHintLength, pShortNameOffset);
  6601. }
  6602. else if (pNode->sxBin.pnode1->nop == knopName)
  6603. {
  6604. leftNode = pNode->sxBin.pnode1->sxPid.pid->Psz();
  6605. *fullNameHintLength = pNode->sxBin.pnode1->sxPid.pid->Cch();
  6606. *pShortNameOffset = 0;
  6607. }
  6608. if (pNode->nop == knopIndex)
  6609. {
  6610. return FormatPropertyString(
  6611. leftNode ? leftNode : Js::Constants::AnonymousFunction, // e.g. f()[0] = function () {}
  6612. pNode->sxBin.pnode2, fullNameHintLength, pShortNameOffset);
  6613. }
  6614. Assert(pNode->sxBin.pnode2->nop == knopDot || pNode->sxBin.pnode2->nop == knopName);
  6615. LPCOLESTR rightNode = nullptr;
  6616. bool wrapWithBrackets = false;
  6617. if (pNode->sxBin.pnode2->nop == knopDot)
  6618. {
  6619. rightNode = ConstructNameHint(pNode->sxBin.pnode2, fullNameHintLength, pShortNameOffset);
  6620. }
  6621. else
  6622. {
  6623. rightNode = pNode->sxBin.pnode2->sxPid.pid->Psz();
  6624. wrapWithBrackets = PNodeFlags::fpnIndexOperator == (pNode->grfpn & PNodeFlags::fpnIndexOperator);
  6625. }
  6626. Assert(rightNode != nullptr);
  6627. return AppendNameHints(leftNode, rightNode, fullNameHintLength, pShortNameOffset, false, wrapWithBrackets);
  6628. }
  6629. LPCOLESTR Parser::AppendNameHints(LPCOLESTR leftStr, ulong leftLen, LPCOLESTR rightStr, ulong rightLen, ulong *pNameLength, ulong *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
  6630. {
  6631. Assert(rightStr != nullptr);
  6632. Assert(leftLen != 0 || wrapInBrackets);
  6633. Assert(rightLen != 0 || wrapInBrackets);
  6634. bool ignoreDot = rightStr[0] == _u('[') && !wrapInBrackets;//if we wrap in brackets it can be a string literal which can have brackets at the first char
  6635. ulong totalLength = leftLen + rightLen + ((ignoreDot) ? 1 : 2); // 1 (for dot or [) + 1 (for null termination)
  6636. if (wrapInBrackets)
  6637. {
  6638. totalLength++; //1 for ']';
  6639. }
  6640. WCHAR * finalName = AllocateStringOfLength(totalLength);
  6641. if (leftStr != nullptr && leftLen != 0)
  6642. {
  6643. wcscpy_s(finalName, leftLen + 1, leftStr);
  6644. }
  6645. if (ignoreAddDotWithSpace)
  6646. {
  6647. finalName[leftLen++] = (OLECHAR)_u(' ');
  6648. }
  6649. // mutually exclusive from ignoreAddDotWithSpace which is used for getters/setters
  6650. else if (wrapInBrackets)
  6651. {
  6652. finalName[leftLen++] = (OLECHAR)_u('[');
  6653. finalName[totalLength-2] = (OLECHAR)_u(']');
  6654. }
  6655. else if (!ignoreDot)
  6656. {
  6657. finalName[leftLen++] = (OLECHAR)_u('.');
  6658. }
  6659. //ignore case falls through
  6660. js_wmemcpy_s(finalName + leftLen, rightLen, rightStr, rightLen);
  6661. finalName[totalLength-1] = (OLECHAR)_u('\0');
  6662. if (pNameLength != nullptr)
  6663. {
  6664. *pNameLength = totalLength - 1;
  6665. }
  6666. if (pShortNameOffset != nullptr)
  6667. {
  6668. *pShortNameOffset = leftLen;
  6669. }
  6670. return finalName;
  6671. }
  6672. WCHAR * Parser::AllocateStringOfLength(ulong length)
  6673. {
  6674. Assert(length > 0);
  6675. ULONG totalBytes;
  6676. if (ULongMult(length, sizeof(OLECHAR), &totalBytes) != S_OK)
  6677. {
  6678. Error(ERRnoMemory);
  6679. }
  6680. WCHAR* finalName = (WCHAR*)m_phtbl->GetAllocator()->Alloc(totalBytes);
  6681. if (finalName == nullptr)
  6682. {
  6683. Error(ERRnoMemory);
  6684. }
  6685. return finalName;
  6686. }
  6687. LPCOLESTR Parser::AppendNameHints(IdentPtr left, IdentPtr right, ulong *pNameLength, ulong *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
  6688. {
  6689. if (pShortNameOffset != nullptr)
  6690. {
  6691. *pShortNameOffset = 0;
  6692. }
  6693. if (left == nullptr && !wrapInBrackets)
  6694. {
  6695. if (right)
  6696. {
  6697. *pNameLength = right->Cch();
  6698. return right->Psz();
  6699. }
  6700. return nullptr;
  6701. }
  6702. ulong leftLen = 0;
  6703. LPCOLESTR leftStr = _u("");
  6704. if (left != nullptr) // if wrapInBrackets is true
  6705. {
  6706. leftStr = left->Psz();
  6707. leftLen = left->Cch();
  6708. }
  6709. if (right == nullptr)
  6710. {
  6711. *pNameLength = leftLen;
  6712. return left->Psz();
  6713. }
  6714. ulong rightLen = right->Cch();
  6715. return AppendNameHints(leftStr, leftLen, right->Psz(), rightLen, pNameLength, pShortNameOffset, ignoreAddDotWithSpace, wrapInBrackets);
  6716. }
  6717. LPCOLESTR Parser::AppendNameHints(IdentPtr left, LPCOLESTR right, ulong *pNameLength, ulong *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
  6718. {
  6719. ulong rightLen = (right == nullptr) ? 0 : (ulong) wcslen(right);
  6720. if (pShortNameOffset != nullptr)
  6721. {
  6722. *pShortNameOffset = 0;
  6723. }
  6724. Assert(rightLen <= ULONG_MAX); // name hints should not exceed ULONG_MAX characters
  6725. if (left == nullptr && !wrapInBrackets)
  6726. {
  6727. *pNameLength = rightLen;
  6728. return right;
  6729. }
  6730. LPCOLESTR leftStr = _u("");
  6731. ulong leftLen = 0;
  6732. if (left != nullptr) // if wrapInBrackets is true
  6733. {
  6734. leftStr = left->Psz();
  6735. leftLen = left->Cch();
  6736. }
  6737. if (rightLen == 0 && !wrapInBrackets)
  6738. {
  6739. *pNameLength = leftLen;
  6740. return left->Psz();
  6741. }
  6742. return AppendNameHints(leftStr, leftLen, right, rightLen, pNameLength, pShortNameOffset, ignoreAddDotWithSpace, wrapInBrackets);
  6743. }
  6744. LPCOLESTR Parser::AppendNameHints(LPCOLESTR left, IdentPtr right, ulong *pNameLength, ulong *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
  6745. {
  6746. ulong leftLen = (left == nullptr) ? 0 : (ulong) wcslen(left);
  6747. if (pShortNameOffset != nullptr)
  6748. {
  6749. *pShortNameOffset = 0;
  6750. }
  6751. Assert(leftLen <= ULONG_MAX); // name hints should not exceed ULONG_MAX characters
  6752. if (left == nullptr || leftLen == 0 && !wrapInBrackets)
  6753. {
  6754. if (right != nullptr)
  6755. {
  6756. *pNameLength = right->Cch();
  6757. return right->Psz();
  6758. }
  6759. return nullptr;
  6760. }
  6761. if (right == nullptr)
  6762. {
  6763. *pNameLength = leftLen;
  6764. return left;
  6765. }
  6766. ulong rightLen = right->Cch();
  6767. return AppendNameHints(left, leftLen, right->Psz(), rightLen, pNameLength, pShortNameOffset, ignoreAddDotWithSpace, wrapInBrackets);
  6768. }
  6769. LPCOLESTR Parser::AppendNameHints(LPCOLESTR left, LPCOLESTR right, ulong *pNameLength, ulong *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
  6770. {
  6771. ulong leftLen = (left == nullptr) ? 0 : (ulong) wcslen(left);
  6772. ulong rightLen = (right == nullptr) ? 0 : (ulong) wcslen(right);
  6773. if (pShortNameOffset != nullptr)
  6774. {
  6775. *pShortNameOffset = 0;
  6776. }
  6777. Assert(rightLen <= ULONG_MAX && leftLen <= ULONG_MAX); // name hints should not exceed ULONG_MAX characters
  6778. if (leftLen == 0 && !wrapInBrackets)
  6779. {
  6780. *pNameLength = right ? rightLen : 0;
  6781. return right;
  6782. }
  6783. if (rightLen == 0 && !wrapInBrackets)
  6784. {
  6785. *pNameLength = leftLen;
  6786. return left;
  6787. }
  6788. return AppendNameHints(left, leftLen, right, rightLen, pNameLength, pShortNameOffset, ignoreAddDotWithSpace, wrapInBrackets);
  6789. }
  6790. /**
  6791. * Emits a spread error if there is no ambiguity, or marks defers the error for
  6792. * when we can determine if it is a rest error or a spread error.
  6793. *
  6794. * The ambiguity arises when we are parsing a lambda parameter list but we have
  6795. * not seen the => token. At this point, we are either in a parenthesized
  6796. * expression or a parameter list, and cannot issue an error until the matching
  6797. * RParen has been scanned.
  6798. *
  6799. * The actual emission of the error happens in ParseExpr, when we first know if
  6800. * the expression is a lambda parameter list or not.
  6801. *
  6802. */
  6803. void Parser::DeferOrEmitPotentialSpreadError(ParseNodePtr pnodeT)
  6804. {
  6805. if (m_parenDepth > 0)
  6806. {
  6807. if (m_token.tk == tkRParen)
  6808. {
  6809. if (!m_deferEllipsisError)
  6810. {
  6811. // Capture only the first error instance.
  6812. m_pscan->Capture(&m_EllipsisErrLoc);
  6813. m_deferEllipsisError = true;
  6814. }
  6815. }
  6816. else
  6817. {
  6818. Error(ERRUnexpectedEllipsis);
  6819. }
  6820. }
  6821. else
  6822. {
  6823. Error(ERRInvalidSpreadUse);
  6824. }
  6825. }
  6826. /***************************************************************************
  6827. Parse an optional sub expression returning null if there was no expression.
  6828. Checks for no expression by looking for a token that can follow an
  6829. Expression grammar production.
  6830. ***************************************************************************/
  6831. template<bool buildAST>
  6832. bool Parser::ParseOptionalExpr(ParseNodePtr* pnode, bool fUnaryOrParen, int oplMin, BOOL *pfCanAssign, BOOL fAllowIn, BOOL fAllowEllipsis, _Inout_opt_ IdentToken* pToken)
  6833. {
  6834. *pnode = nullptr;
  6835. if (m_token.tk == tkRCurly ||
  6836. m_token.tk == tkRBrack ||
  6837. m_token.tk == tkRParen ||
  6838. m_token.tk == tkSColon ||
  6839. m_token.tk == tkColon ||
  6840. m_token.tk == tkComma ||
  6841. m_token.tk == tkLimKwd ||
  6842. m_pscan->FHadNewLine())
  6843. {
  6844. return false;
  6845. }
  6846. *pnode = ParseExpr<buildAST>(oplMin, pfCanAssign, fAllowIn, fAllowEllipsis, nullptr /*pNameHint*/, nullptr /*pHintLength*/, nullptr /*pShortNameOffset*/, pToken, fUnaryOrParen);
  6847. return true;
  6848. }
  6849. /***************************************************************************
  6850. Parse a sub expression.
  6851. 'fAllowIn' indicates if the 'in' operator should be allowed in the initializing
  6852. expression ( it is not allowed in the context of the first expression in a 'for' loop).
  6853. ***************************************************************************/
  6854. template<bool buildAST>
  6855. ParseNodePtr Parser::ParseExpr(int oplMin,
  6856. BOOL *pfCanAssign,
  6857. BOOL fAllowIn,
  6858. BOOL fAllowEllipsis,
  6859. LPCOLESTR pNameHint,
  6860. ulong *pHintLength,
  6861. ulong *pShortNameOffset,
  6862. _Inout_opt_ IdentToken* pToken,
  6863. bool fUnaryOrParen,
  6864. _Inout_opt_ bool* pfLikelyPattern)
  6865. {
  6866. Assert(pToken == nullptr || pToken->tk == tkNone); // Must be empty initially
  6867. int opl;
  6868. OpCode nop;
  6869. charcount_t ichMin;
  6870. ParseNodePtr pnode = nullptr;
  6871. ParseNodePtr pnodeT = nullptr;
  6872. BOOL fCanAssign = TRUE;
  6873. bool assignmentStmt = false;
  6874. IdentToken term;
  6875. RestorePoint termStart;
  6876. ulong hintLength = 0;
  6877. ulong hintOffset = 0;
  6878. ParserState parserState;
  6879. if (pHintLength != nullptr)
  6880. {
  6881. hintLength = *pHintLength;
  6882. }
  6883. if (pShortNameOffset != nullptr)
  6884. {
  6885. hintOffset = *pShortNameOffset;
  6886. }
  6887. EnsureStackAvailable();
  6888. // Storing the state here as we need to restore this state back when we need to reparse the grammar under lambda syntax.
  6889. CaptureState(&parserState);
  6890. m_pscan->Capture(&termStart);
  6891. bool deferredErrorFoundOnLeftSide = false;
  6892. bool savedDeferredInitError = m_hasDeferredShorthandInitError;
  6893. m_hasDeferredShorthandInitError = false;
  6894. // Is the current token a unary operator?
  6895. if (m_phtbl->TokIsUnop(m_token.tk, &opl, &nop) && nop != knopNone)
  6896. {
  6897. IdentToken operandToken;
  6898. ichMin = m_pscan->IchMinTok();
  6899. if (nop == knopYield)
  6900. {
  6901. if (!m_pscan->YieldIsKeyword() || oplMin > opl)
  6902. {
  6903. // The case where 'yield' is scanned as a keyword (tkYIELD) but the scanner
  6904. // is not treating yield as a keyword (!m_pscan->YieldIsKeyword()) occurs
  6905. // in strict mode non-generator function contexts.
  6906. //
  6907. // That is, 'yield' is a keyword because of strict mode, but YieldExpression
  6908. // is not a grammar production outside of generator functions.
  6909. //
  6910. // Otherwise it is an error for a yield to appear in the context of a higher level
  6911. // binding operator, be it unary or binary.
  6912. Error(ERRsyntax);
  6913. }
  6914. if (GetCurrentFunctionNode()->sxFnc.IsGenerator()
  6915. && m_currentBlockInfo->pnodeBlock->sxBlock.blockType == PnodeBlockType::Parameter)
  6916. {
  6917. Error(ERRsyntax);
  6918. }
  6919. }
  6920. else if (nop == knopAwait)
  6921. {
  6922. if (!m_pscan->AwaitIsKeyword() ||
  6923. (GetCurrentFunctionNode()->sxFnc.IsAsync() && m_currentScope->GetScopeType() == ScopeType_Parameter))
  6924. {
  6925. // As with the 'yield' keyword, the case where 'await' is scanned as a keyword (tkAWAIT)
  6926. // but the scanner is not treating await as a keyword (!m_pscan->AwaitIsKeyword())
  6927. // occurs in strict mode non-async function contexts.
  6928. //
  6929. // That is, 'await' is a keyword because of strict mode, but AwaitExpression
  6930. // is not a grammar production outside of async functions.
  6931. //
  6932. // Further, await expressions are disallowed within parameter scopes.
  6933. Error(ERRBadAwait);
  6934. }
  6935. }
  6936. m_pscan->Scan();
  6937. if (m_token.tk == tkEllipsis) {
  6938. // ... cannot have a unary prefix.
  6939. Error(ERRUnexpectedEllipsis);
  6940. }
  6941. if (nop == knopYield && !m_pscan->FHadNewLine() && m_token.tk == tkStar)
  6942. {
  6943. m_pscan->Scan();
  6944. nop = knopYieldStar;
  6945. }
  6946. if (nop == knopYield)
  6947. {
  6948. if (!ParseOptionalExpr<buildAST>(&pnodeT, false, opl, NULL, TRUE, fAllowEllipsis))
  6949. {
  6950. nop = knopYieldLeaf;
  6951. if (buildAST)
  6952. {
  6953. pnode = CreateNodeT<knopYieldLeaf>(ichMin, m_pscan->IchLimTok());
  6954. }
  6955. }
  6956. }
  6957. else
  6958. {
  6959. // Disallow spread after a unary operator.
  6960. pnodeT = ParseExpr<buildAST>(opl, &fCanAssign, TRUE, FALSE, nullptr /*hint*/, nullptr /*hintLength*/, nullptr /*hintOffset*/, &operandToken, true);
  6961. }
  6962. if (nop != knopYieldLeaf)
  6963. {
  6964. if (nop == knopIncPre || nop == knopDecPre)
  6965. {
  6966. if (!fCanAssign && PHASE_ON1(Js::EarlyReferenceErrorsPhase))
  6967. {
  6968. Error(JSERR_CantAssignTo);
  6969. }
  6970. if (buildAST)
  6971. {
  6972. if (IsStrictMode() && pnodeT->nop == knopName)
  6973. {
  6974. CheckStrictModeEvalArgumentsUsage(pnodeT->sxPid.pid);
  6975. }
  6976. }
  6977. else
  6978. {
  6979. if (IsStrictMode() && operandToken.tk == tkID)
  6980. {
  6981. CheckStrictModeEvalArgumentsUsage(operandToken.pid);
  6982. }
  6983. }
  6984. }
  6985. else if (nop == knopEllipsis)
  6986. {
  6987. if (!fAllowEllipsis)
  6988. {
  6989. DeferOrEmitPotentialSpreadError(pnodeT);
  6990. }
  6991. }
  6992. else if (m_token.tk == tkExpo)
  6993. {
  6994. //Unary operator on the left hand-side of ** is unexpected, except ++, -- or ...
  6995. Error(ERRInvalidUseofExponentiationOperator);
  6996. }
  6997. if (buildAST)
  6998. {
  6999. //Do not do the folding for Asm in case of KnopPos as we need this to determine the type
  7000. if (nop == knopPos && (pnodeT->nop == knopInt || pnodeT->nop == knopFlt) && !this->m_InAsmMode)
  7001. {
  7002. // Fold away a unary '+' on a number.
  7003. pnode = pnodeT;
  7004. }
  7005. else if (nop == knopNeg &&
  7006. ((pnodeT->nop == knopInt && pnodeT->sxInt.lw != 0) ||
  7007. (pnodeT->nop == knopFlt && (pnodeT->sxFlt.dbl != 0 || this->m_InAsmMode))))
  7008. {
  7009. // Fold a unary '-' on a number into the value of the number itself.
  7010. pnode = pnodeT;
  7011. if (pnode->nop == knopInt)
  7012. {
  7013. pnode->sxInt.lw = -pnode->sxInt.lw;
  7014. }
  7015. else
  7016. {
  7017. pnode->sxFlt.dbl = -pnode->sxFlt.dbl;
  7018. }
  7019. }
  7020. else
  7021. {
  7022. pnode = CreateUniNode(nop, pnodeT);
  7023. this->CheckArguments(pnode->sxUni.pnode1);
  7024. }
  7025. pnode->ichMin = ichMin;
  7026. }
  7027. if (nop == knopDelete)
  7028. {
  7029. if (IsStrictMode())
  7030. {
  7031. if ((buildAST && pnode->sxUni.pnode1->nop == knopName) ||
  7032. (!buildAST && operandToken.tk == tkID))
  7033. {
  7034. Error(ERRInvalidDelete);
  7035. }
  7036. }
  7037. if (buildAST)
  7038. {
  7039. ParseNodePtr pnode1 = pnode->sxUni.pnode1;
  7040. if (m_currentNodeFunc)
  7041. {
  7042. if (pnode1->nop == knopDot || pnode1->nop == knopIndex)
  7043. {
  7044. // If we delete an arguments property, use the conservative,
  7045. // heap-allocated arguments object.
  7046. this->CheckArguments(pnode1->sxBin.pnode1);
  7047. }
  7048. }
  7049. }
  7050. }
  7051. }
  7052. fCanAssign = FALSE;
  7053. }
  7054. else
  7055. {
  7056. ichMin = m_pscan->IchMinTok();
  7057. BOOL fLikelyPattern = FALSE;
  7058. pnode = ParseTerm<buildAST>(TRUE, pNameHint, &hintLength, &hintOffset, &term, fUnaryOrParen, &fCanAssign, IsES6DestructuringEnabled() ? &fLikelyPattern : nullptr);
  7059. if (pfLikelyPattern != nullptr)
  7060. {
  7061. *pfLikelyPattern = !!fLikelyPattern;
  7062. }
  7063. if (m_token.tk == tkAsg && oplMin <= koplAsg && fLikelyPattern)
  7064. {
  7065. m_pscan->SeekTo(termStart);
  7066. ParseDestructuredLiteralWithScopeSave(tkLCurly, false/*isDecl*/, false /*topLevel*/, DIC_ShouldNotParseInitializer);
  7067. if (buildAST)
  7068. {
  7069. pnode = ConvertToPattern(pnode);
  7070. }
  7071. // The left-hand side is found to be destructuring pattern - so the shorthand can have initializer.
  7072. m_hasDeferredShorthandInitError = false;
  7073. }
  7074. if (buildAST)
  7075. {
  7076. pNameHint = NULL;
  7077. if (pnode->nop == knopName)
  7078. {
  7079. pNameHint = pnode->sxPid.pid->Psz();
  7080. hintLength = pnode->sxPid.pid->Cch();
  7081. hintOffset = 0;
  7082. }
  7083. else if (pnode->nop == knopDot || pnode->nop == knopIndex)
  7084. {
  7085. if (CONFIG_FLAG(UseFullName))
  7086. {
  7087. pNameHint = ConstructNameHint(pnode, &hintLength, &hintOffset);
  7088. }
  7089. else
  7090. {
  7091. ParseNodePtr pnodeName = pnode;
  7092. while (pnodeName->nop == knopDot)
  7093. {
  7094. pnodeName = pnodeName->sxBin.pnode2;
  7095. }
  7096. if (pnodeName->nop == knopName)
  7097. {
  7098. pNameHint = pnodeName->sxPid.pid->Psz();
  7099. hintLength = pnodeName->sxPid.pid->Cch();
  7100. hintOffset = 0;
  7101. }
  7102. }
  7103. }
  7104. }
  7105. // Check for postfix unary operators.
  7106. if (!m_pscan->FHadNewLine() &&
  7107. (tkInc == m_token.tk || tkDec == m_token.tk))
  7108. {
  7109. if (!fCanAssign && PHASE_ON1(Js::EarlyReferenceErrorsPhase))
  7110. {
  7111. Error(JSERR_CantAssignTo);
  7112. }
  7113. fCanAssign = FALSE;
  7114. if (buildAST)
  7115. {
  7116. if (IsStrictMode() && pnode->nop == knopName)
  7117. {
  7118. CheckStrictModeEvalArgumentsUsage(pnode->sxPid.pid);
  7119. }
  7120. this->CheckArguments(pnode);
  7121. pnode = CreateUniNode(tkInc == m_token.tk ? knopIncPost : knopDecPost, pnode);
  7122. pnode->ichLim = m_pscan->IchLimTok();
  7123. }
  7124. else
  7125. {
  7126. if (IsStrictMode() && term.tk == tkID)
  7127. {
  7128. CheckStrictModeEvalArgumentsUsage(term.pid);
  7129. }
  7130. // This expression is not an identifier
  7131. term.tk = tkNone;
  7132. }
  7133. m_pscan->Scan();
  7134. }
  7135. }
  7136. deferredErrorFoundOnLeftSide = m_hasDeferredShorthandInitError;
  7137. // Process a sequence of operators and operands.
  7138. for (;;)
  7139. {
  7140. if (!m_phtbl->TokIsBinop(m_token.tk, &opl, &nop) || nop == knopNone)
  7141. {
  7142. break;
  7143. }
  7144. if ( ! fAllowIn && nop == knopIn )
  7145. {
  7146. break;
  7147. }
  7148. Assert(opl != koplNo);
  7149. if (opl == koplAsg)
  7150. {
  7151. if (m_token.tk != tkDArrow)
  7152. {
  7153. // Assignment operator. These are the only right associative
  7154. // binary operators. We also need to special case the left
  7155. // operand - it should only be a LeftHandSideExpression.
  7156. Assert(ParseNode::Grfnop(nop) & fnopAsg || nop == knopFncDecl);
  7157. if (buildAST)
  7158. {
  7159. if (IsStrictMode() && pnode->nop == knopName)
  7160. {
  7161. CheckStrictModeEvalArgumentsUsage(pnode->sxPid.pid);
  7162. }
  7163. // Assignment stmt of the form "this.<id> = <expr>"
  7164. if (nop == knopAsg && pnode->nop == knopDot && pnode->sxBin.pnode1->nop == knopThis && pnode->sxBin.pnode2->nop == knopName)
  7165. {
  7166. if (pnode->sxBin.pnode2->sxPid.pid != wellKnownPropertyPids.__proto__)
  7167. {
  7168. assignmentStmt = true;
  7169. }
  7170. }
  7171. }
  7172. else
  7173. {
  7174. if (IsStrictMode() && term.tk == tkID)
  7175. {
  7176. CheckStrictModeEvalArgumentsUsage(term.pid);
  7177. }
  7178. }
  7179. }
  7180. if (opl < oplMin)
  7181. {
  7182. break;
  7183. }
  7184. if (m_token.tk != tkDArrow && !fCanAssign && PHASE_ON1(Js::EarlyReferenceErrorsPhase))
  7185. {
  7186. Error(JSERR_CantAssignTo);
  7187. // No recovery necessary since this is a semantic, not structural, error.
  7188. }
  7189. }
  7190. else if (opl == koplExpo)
  7191. {
  7192. // ** operator is right associative
  7193. if (opl < oplMin)
  7194. {
  7195. break;
  7196. }
  7197. }
  7198. else if (opl <= oplMin)
  7199. {
  7200. break;
  7201. }
  7202. // This expression is not an identifier
  7203. term.tk = tkNone;
  7204. // Precedence is high enough. Consume the operator token.
  7205. m_pscan->Scan();
  7206. fCanAssign = FALSE;
  7207. // Special case the "?:" operator
  7208. if (nop == knopQmark)
  7209. {
  7210. pnodeT = ParseExpr<buildAST>(koplAsg, NULL, fAllowIn);
  7211. ChkCurTok(tkColon, ERRnoColon);
  7212. ParseNodePtr pnodeT2 = ParseExpr<buildAST>(koplAsg, NULL, fAllowIn);
  7213. if (buildAST)
  7214. {
  7215. pnode = CreateTriNode(nop, pnode, pnodeT, pnodeT2);
  7216. this->CheckArguments(pnode->sxTri.pnode2);
  7217. this->CheckArguments(pnode->sxTri.pnode3);
  7218. }
  7219. }
  7220. else if (nop == knopFncDecl)
  7221. {
  7222. ushort flags = fFncLambda;
  7223. size_t iecpMin = 0;
  7224. bool isAsyncMethod = false;
  7225. RestoreStateFrom(&parserState);
  7226. m_pscan->SeekTo(termStart);
  7227. if (m_token.tk == tkID && m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.async && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  7228. {
  7229. ichMin = m_pscan->IchMinTok();
  7230. iecpMin = m_pscan->IecpMinTok();
  7231. m_pscan->Scan();
  7232. if ((m_token.tk == tkID || m_token.tk == tkLParen) && !m_pscan->FHadNewLine())
  7233. {
  7234. flags |= fFncAsync;
  7235. isAsyncMethod = true;
  7236. }
  7237. else
  7238. {
  7239. m_pscan->SeekTo(termStart);
  7240. }
  7241. }
  7242. pnode = ParseFncDecl<buildAST>(flags, nullptr, /* needsPIDOnRCurlyScan = */false, /* resetParsingSuperRestrictionState = */false);
  7243. if (isAsyncMethod)
  7244. {
  7245. pnode->sxFnc.cbMin = iecpMin;
  7246. pnode->ichMin = ichMin;
  7247. }
  7248. }
  7249. else
  7250. {
  7251. // Parse the operand, make a new node, and look for more
  7252. pnodeT = ParseExpr<buildAST>(opl, NULL, fAllowIn, FALSE, pNameHint, &hintLength, &hintOffset, nullptr);
  7253. if (buildAST)
  7254. {
  7255. pnode = CreateBinNode(nop, pnode, pnodeT);
  7256. Assert(pnode->sxBin.pnode2 != NULL);
  7257. if (pnode->sxBin.pnode2->nop == knopFncDecl)
  7258. {
  7259. Assert(hintLength >= hintOffset);
  7260. pnode->sxBin.pnode2->sxFnc.hint = pNameHint;
  7261. pnode->sxBin.pnode2->sxFnc.hintLength = hintLength;
  7262. pnode->sxBin.pnode2->sxFnc.hintOffset = hintOffset;
  7263. if (pnode->sxBin.pnode1->nop == knopDot)
  7264. {
  7265. pnode->sxBin.pnode2->sxFnc.isNameIdentifierRef = false;
  7266. }
  7267. }
  7268. if (pnode->sxBin.pnode2->nop == knopClassDecl && pnode->sxBin.pnode1->nop == knopDot)
  7269. {
  7270. Assert(pnode->sxBin.pnode2->sxClass.pnodeConstructor);
  7271. pnode->sxBin.pnode2->sxClass.pnodeConstructor->sxFnc.isNameIdentifierRef = false;
  7272. }
  7273. }
  7274. pNameHint = NULL;
  7275. }
  7276. }
  7277. if (buildAST)
  7278. {
  7279. if (!assignmentStmt)
  7280. {
  7281. // Don't set the flag for following nodes
  7282. switch (pnode->nop)
  7283. {
  7284. case knopName:
  7285. case knopInt:
  7286. case knopFlt:
  7287. case knopStr:
  7288. case knopRegExp:
  7289. case knopNull:
  7290. case knopFalse:
  7291. case knopTrue:
  7292. break;
  7293. default:
  7294. if (m_currentNodeFunc)
  7295. {
  7296. m_currentNodeFunc->sxFnc.SetHasNonThisStmt();
  7297. }
  7298. else if (m_currentNodeProg)
  7299. {
  7300. m_currentNodeProg->sxFnc.SetHasNonThisStmt();
  7301. }
  7302. }
  7303. }
  7304. }
  7305. if (m_hasDeferredShorthandInitError && !deferredErrorFoundOnLeftSide)
  7306. {
  7307. // Raise error only if it is found not on the right side of the expression.
  7308. // such as <expr> = {x = 1}
  7309. Error(ERRnoColon);
  7310. }
  7311. m_hasDeferredShorthandInitError = m_hasDeferredShorthandInitError || savedDeferredInitError;
  7312. if (NULL != pfCanAssign)
  7313. {
  7314. *pfCanAssign = fCanAssign;
  7315. }
  7316. // Pass back identifier if requested
  7317. if (pToken && term.tk == tkID)
  7318. {
  7319. *pToken = term;
  7320. }
  7321. //Track "obj.a" assignment patterns here - Promote the Assignment state for the property's PID.
  7322. // This includes =, += etc.
  7323. if (pnode != NULL)
  7324. {
  7325. uint nodeType = ParseNode::Grfnop(pnode->nop);
  7326. if (nodeType & fnopAsg)
  7327. {
  7328. if (nodeType & fnopBin)
  7329. {
  7330. ParseNodePtr lhs = pnode->sxBin.pnode1;
  7331. Assert(lhs);
  7332. if (lhs->nop == knopDot)
  7333. {
  7334. ParseNodePtr propertyNode = lhs->sxBin.pnode2;
  7335. if (propertyNode->nop == knopName)
  7336. {
  7337. propertyNode->sxPid.pid->PromoteAssignmentState();
  7338. }
  7339. }
  7340. }
  7341. else if (nodeType & fnopUni)
  7342. {
  7343. // cases like obj.a++, ++obj.a
  7344. ParseNodePtr lhs = pnode->sxUni.pnode1;
  7345. if (lhs->nop == knopDot)
  7346. {
  7347. ParseNodePtr propertyNode = lhs->sxBin.pnode2;
  7348. if (propertyNode->nop == knopName)
  7349. {
  7350. propertyNode->sxPid.pid->PromoteAssignmentState();
  7351. }
  7352. }
  7353. }
  7354. }
  7355. }
  7356. return pnode;
  7357. }
  7358. void PnPid::SetSymRef(PidRefStack *ref)
  7359. {
  7360. Assert(symRef == nullptr);
  7361. this->symRef = ref->GetSymRef();
  7362. }
  7363. Js::PropertyId PnPid::PropertyIdFromNameNode() const
  7364. {
  7365. Js::PropertyId propertyId;
  7366. Symbol *sym = this->sym;
  7367. if (sym)
  7368. {
  7369. propertyId = sym->GetPosition();
  7370. }
  7371. else
  7372. {
  7373. propertyId = this->pid->GetPropertyId();
  7374. }
  7375. return propertyId;
  7376. }
  7377. PidRefStack* Parser::PushPidRef(IdentPtr pid)
  7378. {
  7379. if (PHASE_ON1(Js::ParallelParsePhase))
  7380. {
  7381. // NOTE: the phase check is here to protect perf. See OSG 1020424.
  7382. // In some LS AST-rewrite cases we lose a lot of perf searching the PID ref stack rather
  7383. // than just pushing on the top. This hasn't shown up as a perf issue in non-LS benchmarks.
  7384. return pid->FindOrAddPidRef(&m_nodeAllocator, GetCurrentBlock()->sxBlock.blockId);
  7385. }
  7386. Assert(GetCurrentBlock() != nullptr);
  7387. AssertMsg(pid != nullptr, "PID should be created");
  7388. PidRefStack *ref = pid->GetTopRef();
  7389. if (!ref || (ref->GetScopeId() < GetCurrentBlock()->sxBlock.blockId))
  7390. {
  7391. ref = Anew(&m_nodeAllocator, PidRefStack);
  7392. if (ref == nullptr)
  7393. {
  7394. Error(ERRnoMemory);
  7395. }
  7396. pid->PushPidRef(GetCurrentBlock()->sxBlock.blockId, ref);
  7397. }
  7398. return ref;
  7399. }
  7400. PidRefStack* Parser::FindOrAddPidRef(IdentPtr pid, int scopeId)
  7401. {
  7402. PidRefStack *ref = pid->FindOrAddPidRef(&m_nodeAllocator, scopeId);
  7403. if (ref == NULL)
  7404. {
  7405. Error(ERRnoMemory);
  7406. }
  7407. return ref;
  7408. }
  7409. void Parser::RemovePrevPidRef(IdentPtr pid, PidRefStack *ref)
  7410. {
  7411. PidRefStack *prevRef = pid->RemovePrevPidRef(ref);
  7412. Assert(prevRef);
  7413. if (prevRef->GetSym() == nullptr)
  7414. {
  7415. AllocatorDelete(ArenaAllocator, &m_nodeAllocator, prevRef);
  7416. }
  7417. }
  7418. void Parser::SetPidRefsInScopeDynamic(IdentPtr pid, int blockId)
  7419. {
  7420. PidRefStack *ref = pid->GetTopRef();
  7421. while (ref && ref->GetScopeId() >= blockId)
  7422. {
  7423. ref->SetDynamicBinding();
  7424. ref = ref->prev;
  7425. }
  7426. }
  7427. ParseNode* Parser::GetFunctionBlock()
  7428. {
  7429. Assert(m_currentBlockInfo != nullptr);
  7430. return m_currentBlockInfo->pBlockInfoFunction->pnodeBlock;
  7431. }
  7432. ParseNode* Parser::GetCurrentBlock()
  7433. {
  7434. return m_currentBlockInfo != nullptr ? m_currentBlockInfo->pnodeBlock : nullptr;
  7435. }
  7436. BlockInfoStack* Parser::GetCurrentBlockInfo()
  7437. {
  7438. return m_currentBlockInfo;
  7439. }
  7440. BlockInfoStack* Parser::GetCurrentFunctionBlockInfo()
  7441. {
  7442. return m_currentBlockInfo->pBlockInfoFunction;
  7443. }
  7444. /***************************************************************************
  7445. Parse a variable declaration.
  7446. 'fAllowIn' indicates if the 'in' operator should be allowed in the initializing
  7447. expression ( it is not allowed in the context of the first expression in a 'for' loop).
  7448. ***************************************************************************/
  7449. template<bool buildAST>
  7450. ParseNodePtr Parser::ParseVariableDeclaration(
  7451. tokens declarationType, charcount_t ichMin,
  7452. BOOL fAllowIn/* = TRUE*/,
  7453. BOOL* pfForInOk/* = nullptr*/,
  7454. BOOL singleDefOnly/* = FALSE*/,
  7455. BOOL allowInit/* = TRUE*/,
  7456. BOOL isTopVarParse/* = TRUE*/,
  7457. BOOL isFor/* = FALSE*/,
  7458. BOOL* nativeForOk /*= nullptr*/)
  7459. {
  7460. ParseNodePtr pnodeThis = nullptr;
  7461. ParseNodePtr pnodeInit;
  7462. ParseNodePtr pnodeList = nullptr;
  7463. ParseNodePtr *lastNodeRef = nullptr;
  7464. LPCOLESTR pNameHint = nullptr;
  7465. ulong nameHintLength = 0;
  7466. ulong nameHintOffset = 0;
  7467. Assert(declarationType == tkVAR || declarationType == tkCONST || declarationType == tkLET);
  7468. for (;;)
  7469. {
  7470. if (IsES6DestructuringEnabled() && IsPossiblePatternStart())
  7471. {
  7472. pnodeThis = ParseDestructuredLiteral<buildAST>(declarationType, true, !!isTopVarParse, DIC_None, !!fAllowIn, pfForInOk, nativeForOk);
  7473. if (pnodeThis != nullptr)
  7474. {
  7475. pnodeThis->ichMin = ichMin;
  7476. }
  7477. }
  7478. else
  7479. {
  7480. if (m_token.tk != tkID)
  7481. {
  7482. IdentifierExpectedError(m_token);
  7483. }
  7484. IdentPtr pid = m_token.GetIdentifier(m_phtbl);
  7485. Assert(pid);
  7486. pNameHint = pid->Psz();
  7487. nameHintLength = pid->Cch();
  7488. nameHintOffset = 0;
  7489. if (pid == wellKnownPropertyPids.let && (declarationType == tkCONST || declarationType == tkLET))
  7490. {
  7491. Error(ERRLetIDInLexicalDecl, pnodeThis);
  7492. }
  7493. if (declarationType == tkVAR)
  7494. {
  7495. pnodeThis = CreateVarDeclNode(pid, STVariable);
  7496. }
  7497. else if (declarationType == tkCONST)
  7498. {
  7499. pnodeThis = CreateBlockScopedDeclNode(pid, knopConstDecl);
  7500. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ConstCount, m_scriptContext);
  7501. }
  7502. else
  7503. {
  7504. pnodeThis = CreateBlockScopedDeclNode(pid, knopLetDecl);
  7505. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(LetCount, m_scriptContext);
  7506. }
  7507. if (pid == wellKnownPropertyPids.arguments && m_currentNodeFunc)
  7508. {
  7509. // This var declaration may change the way an 'arguments' identifier in the function is resolved
  7510. if (declarationType == tkVAR)
  7511. {
  7512. m_currentNodeFunc->grfpn |= PNodeFlags::fpnArguments_varDeclaration;
  7513. }
  7514. else
  7515. {
  7516. if (GetCurrentBlockInfo()->pnodeBlock->sxBlock.blockType == Function)
  7517. {
  7518. // Only override arguments if we are at the function block level.
  7519. m_currentNodeFunc->grfpn |= PNodeFlags::fpnArguments_overriddenByDecl;
  7520. }
  7521. }
  7522. }
  7523. if (pnodeThis)
  7524. {
  7525. pnodeThis->ichMin = ichMin;
  7526. }
  7527. m_pscan->Scan();
  7528. if (m_token.tk == tkAsg)
  7529. {
  7530. if (!allowInit)
  7531. {
  7532. Error(ERRUnexpectedDefault);
  7533. }
  7534. if (pfForInOk && (declarationType == tkLET || declarationType == tkCONST))
  7535. {
  7536. *pfForInOk = FALSE;
  7537. }
  7538. m_pscan->Scan();
  7539. pnodeInit = ParseExpr<buildAST>(koplCma, nullptr, fAllowIn, FALSE, pNameHint, &nameHintLength, &nameHintOffset);
  7540. if (buildAST)
  7541. {
  7542. AnalysisAssert(pnodeThis);
  7543. pnodeThis->sxVar.pnodeInit = pnodeInit;
  7544. pnodeThis->ichLim = pnodeInit->ichLim;
  7545. if (pnodeInit->nop == knopFncDecl)
  7546. {
  7547. Assert(nameHintLength >= nameHintOffset);
  7548. pnodeInit->sxFnc.hint = pNameHint;
  7549. pnodeInit->sxFnc.hintLength = nameHintLength;
  7550. pnodeInit->sxFnc.hintOffset = nameHintOffset;
  7551. }
  7552. else
  7553. {
  7554. this->CheckArguments(pnodeInit);
  7555. }
  7556. pNameHint = nullptr;
  7557. }
  7558. //Track var a =, let a= , const a =
  7559. // This is for FixedFields Constant Heuristics
  7560. if (pnodeThis && pnodeThis->sxVar.pnodeInit != nullptr)
  7561. {
  7562. pnodeThis->sxVar.sym->PromoteAssignmentState();
  7563. }
  7564. }
  7565. else if (declarationType == tkCONST /*pnodeThis->nop == knopConstDecl*/
  7566. && !singleDefOnly
  7567. && !(isFor && TokIsForInOrForOf()))
  7568. {
  7569. Error(ERRUninitializedConst);
  7570. }
  7571. }
  7572. if (singleDefOnly)
  7573. {
  7574. return pnodeThis;
  7575. }
  7576. if (buildAST)
  7577. {
  7578. AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeThis);
  7579. }
  7580. if (m_token.tk != tkComma)
  7581. {
  7582. return pnodeList;
  7583. }
  7584. if (pfForInOk)
  7585. {
  7586. // don't allow "for (var a, b in c)"
  7587. *pfForInOk = FALSE;
  7588. }
  7589. m_pscan->Scan();
  7590. ichMin = m_pscan->IchMinTok();
  7591. }
  7592. }
  7593. /***************************************************************************
  7594. Parse try-catch-finally statement
  7595. ***************************************************************************/
  7596. // Eze try-catch-finally tree nests the try-catch within a try-finally.
  7597. // This matches the new runtime implementation.
  7598. template<bool buildAST>
  7599. ParseNodePtr Parser::ParseTryCatchFinally()
  7600. {
  7601. this->m_tryCatchOrFinallyDepth++;
  7602. ParseNodePtr pnodeT = ParseTry<buildAST>();
  7603. ParseNodePtr pnodeTC = nullptr;
  7604. StmtNest stmt;
  7605. bool hasCatch = false;
  7606. if (tkCATCH == m_token.tk)
  7607. {
  7608. hasCatch = true;
  7609. if (buildAST)
  7610. {
  7611. pnodeTC = CreateNodeWithScanner<knopTryCatch>();
  7612. pnodeT->sxStmt.pnodeOuter = pnodeTC;
  7613. pnodeTC->sxTryCatch.pnodeTry = pnodeT;
  7614. }
  7615. PushStmt<buildAST>(&stmt, pnodeTC, knopTryCatch, nullptr, nullptr);
  7616. ParseNodePtr pnodeCatch = ParseCatch<buildAST>();
  7617. if (buildAST)
  7618. {
  7619. pnodeTC->sxTryCatch.pnodeCatch = pnodeCatch;
  7620. }
  7621. PopStmt(&stmt);
  7622. }
  7623. if (tkFINALLY != m_token.tk)
  7624. {
  7625. if (!hasCatch)
  7626. {
  7627. Error(ERRnoCatch);
  7628. }
  7629. Assert(!buildAST || pnodeTC);
  7630. return pnodeTC;
  7631. }
  7632. ParseNodePtr pnodeTF = nullptr;
  7633. if (buildAST)
  7634. {
  7635. pnodeTF = CreateNode(knopTryFinally);
  7636. }
  7637. PushStmt<buildAST>(&stmt, pnodeTF, knopTryFinally, nullptr, nullptr);
  7638. ParseNodePtr pnodeFinally = ParseFinally<buildAST>();
  7639. if (buildAST)
  7640. {
  7641. if (!hasCatch)
  7642. {
  7643. pnodeTF->sxTryFinally.pnodeTry = pnodeT;
  7644. pnodeT->sxStmt.pnodeOuter = pnodeTF;
  7645. }
  7646. else
  7647. {
  7648. pnodeTF->sxTryFinally.pnodeTry = CreateNode(knopTry);
  7649. pnodeTF->sxTryFinally.pnodeTry->sxStmt.pnodeOuter = pnodeTF;
  7650. pnodeTF->sxTryFinally.pnodeTry->sxTry.pnodeBody = pnodeTC;
  7651. pnodeTC->sxStmt.pnodeOuter = pnodeTF->sxTryFinally.pnodeTry;
  7652. }
  7653. pnodeTF->sxTryFinally.pnodeFinally = pnodeFinally;
  7654. }
  7655. PopStmt(&stmt);
  7656. this->m_tryCatchOrFinallyDepth--;
  7657. return pnodeTF;
  7658. }
  7659. template<bool buildAST>
  7660. ParseNodePtr Parser::ParseTry()
  7661. {
  7662. ParseNodePtr pnode = nullptr;
  7663. StmtNest stmt;
  7664. Assert(tkTRY == m_token.tk);
  7665. if (buildAST)
  7666. {
  7667. pnode = CreateNode(knopTry);
  7668. }
  7669. m_pscan->Scan();
  7670. if (tkLCurly != m_token.tk)
  7671. {
  7672. Error(ERRnoLcurly);
  7673. }
  7674. PushStmt<buildAST>(&stmt, pnode, knopTry, nullptr, nullptr);
  7675. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  7676. if (buildAST)
  7677. {
  7678. pnode->sxTry.pnodeBody = pnodeBody;
  7679. if (pnode->sxTry.pnodeBody)
  7680. pnode->ichLim = pnode->sxTry.pnodeBody->ichLim;
  7681. }
  7682. PopStmt(&stmt);
  7683. return pnode;
  7684. }
  7685. template<bool buildAST>
  7686. ParseNodePtr Parser::ParseFinally()
  7687. {
  7688. ParseNodePtr pnode = nullptr;
  7689. StmtNest stmt;
  7690. Assert(tkFINALLY == m_token.tk);
  7691. if (buildAST)
  7692. {
  7693. pnode = CreateNode(knopFinally);
  7694. }
  7695. m_pscan->Scan();
  7696. if (tkLCurly != m_token.tk)
  7697. {
  7698. Error(ERRnoLcurly);
  7699. }
  7700. PushStmt<buildAST>(&stmt, pnode, knopFinally, nullptr, nullptr);
  7701. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  7702. if (buildAST)
  7703. {
  7704. pnode->sxFinally.pnodeBody = pnodeBody;
  7705. if (!pnode->sxFinally.pnodeBody)
  7706. // Will only occur due to error correction.
  7707. pnode->sxFinally.pnodeBody = CreateNodeWithScanner<knopEmpty>();
  7708. else
  7709. pnode->ichLim = pnode->sxFinally.pnodeBody->ichLim;
  7710. }
  7711. PopStmt(&stmt);
  7712. return pnode;
  7713. }
  7714. template<bool buildAST>
  7715. ParseNodePtr Parser::ParseCatch()
  7716. {
  7717. ParseNodePtr rootNode = nullptr;
  7718. ParseNodePtr* ppnode = &rootNode;
  7719. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  7720. ParseNodePtr pnode = nullptr;
  7721. ParseNodePtr pnodeCatchScope = nullptr;
  7722. StmtNest stmt;
  7723. IdentPtr pidCatch = nullptr;
  7724. //while (tkCATCH == m_token.tk)
  7725. if (tkCATCH == m_token.tk)
  7726. {
  7727. charcount_t ichMin;
  7728. if (buildAST)
  7729. {
  7730. ichMin = m_pscan->IchMinTok();
  7731. }
  7732. m_pscan->Scan(); //catch
  7733. ChkCurTok(tkLParen, ERRnoLparen); //catch(
  7734. bool isPattern = false;
  7735. if (tkID != m_token.tk)
  7736. {
  7737. isPattern = IsES6DestructuringEnabled() && IsPossiblePatternStart();
  7738. if (!isPattern)
  7739. {
  7740. IdentifierExpectedError(m_token);
  7741. }
  7742. }
  7743. if (buildAST)
  7744. {
  7745. pnode = CreateNodeWithScanner<knopCatch>(ichMin);
  7746. PushStmt<buildAST>(&stmt, pnode, knopCatch, nullptr, nullptr);
  7747. *ppnode = pnode;
  7748. ppnode = &pnode->sxCatch.pnodeNext;
  7749. *ppnode = nullptr;
  7750. }
  7751. pnodeCatchScope = StartParseBlock<buildAST>(PnodeBlockType::Regular, isPattern ? ScopeType_CatchParamPattern : ScopeType_Catch);
  7752. if (isPattern)
  7753. {
  7754. ParseNodePtr pnodePattern = ParseDestructuredLiteral<buildAST>(tkLET, true /*isDecl*/, true /*topLevel*/, DIC_ForceErrorOnInitializer);
  7755. if (buildAST)
  7756. {
  7757. pnode->sxCatch.pnodeParam = CreateParamPatternNode(pnodePattern);
  7758. Scope *scope = pnodeCatchScope->sxBlock.scope;
  7759. pnode->sxCatch.scope = scope;
  7760. }
  7761. }
  7762. else
  7763. {
  7764. if (IsStrictMode())
  7765. {
  7766. IdentPtr pid = m_token.GetIdentifier(m_phtbl);
  7767. if (pid == wellKnownPropertyPids.eval)
  7768. {
  7769. Error(ERREvalUsage);
  7770. }
  7771. else if (pid == wellKnownPropertyPids.arguments)
  7772. {
  7773. Error(ERRArgsUsage);
  7774. }
  7775. }
  7776. if (buildAST)
  7777. {
  7778. pidCatch = m_token.GetIdentifier(m_phtbl);
  7779. PidRefStack *ref = this->PushPidRef(pidCatch);
  7780. ParseNodePtr pnodeParam = CreateNameNode(pidCatch);
  7781. pnodeParam->sxPid.symRef = ref->GetSymRef();
  7782. pnode->sxCatch.pnodeParam = pnodeParam;
  7783. const char16 *name = reinterpret_cast<const char16*>(pidCatch->Psz());
  7784. int nameLength = pidCatch->Cch();
  7785. SymbolName const symName(name, nameLength);
  7786. Symbol *sym = Anew(&m_nodeAllocator, Symbol, symName, pnodeParam, STVariable);
  7787. sym->SetPid(pidCatch);
  7788. if (sym == nullptr)
  7789. {
  7790. Error(ERRnoMemory);
  7791. }
  7792. Assert(ref->GetSym() == nullptr);
  7793. ref->SetSym(sym);
  7794. Scope *scope = pnodeCatchScope->sxBlock.scope;
  7795. scope->AddNewSymbol(sym);
  7796. pnode->sxCatch.scope = scope;
  7797. }
  7798. m_pscan->Scan();
  7799. }
  7800. if (buildAST)
  7801. {
  7802. // Add this catch to the current scope list.
  7803. if (m_ppnodeExprScope)
  7804. {
  7805. Assert(*m_ppnodeExprScope == nullptr);
  7806. *m_ppnodeExprScope = pnode;
  7807. m_ppnodeExprScope = &pnode->sxCatch.pnodeNext;
  7808. }
  7809. else
  7810. {
  7811. Assert(m_ppnodeScope);
  7812. Assert(*m_ppnodeScope == nullptr);
  7813. *m_ppnodeScope = pnode;
  7814. m_ppnodeScope = &pnode->sxCatch.pnodeNext;
  7815. }
  7816. // Keep a list of function expressions (not declarations) at this scope.
  7817. ppnodeExprScopeSave = m_ppnodeExprScope;
  7818. m_ppnodeExprScope = &pnode->sxCatch.pnodeScopes;
  7819. pnode->sxCatch.pnodeScopes = nullptr;
  7820. }
  7821. charcount_t ichLim;
  7822. if (buildAST)
  7823. {
  7824. ichLim = m_pscan->IchLimTok();
  7825. }
  7826. ChkCurTok(tkRParen, ERRnoRparen); //catch(id[:expr])
  7827. if (tkLCurly != m_token.tk)
  7828. {
  7829. Error(ERRnoLcurly);
  7830. }
  7831. ParseNodePtr pnodeBody = ParseStatement<buildAST>(); //catch(id[:expr]) {block}
  7832. if (buildAST)
  7833. {
  7834. pnode->sxCatch.pnodeBody = pnodeBody;
  7835. pnode->ichLim = ichLim;
  7836. }
  7837. if (pnodeCatchScope != nullptr)
  7838. {
  7839. FinishParseBlock(pnodeCatchScope);
  7840. }
  7841. if (buildAST)
  7842. {
  7843. PopStmt(&stmt);
  7844. // Restore the lists of function expression scopes.
  7845. AssertMem(m_ppnodeExprScope);
  7846. Assert(*m_ppnodeExprScope == nullptr);
  7847. m_ppnodeExprScope = ppnodeExprScopeSave;
  7848. }
  7849. }
  7850. return rootNode;
  7851. }
  7852. template<bool buildAST>
  7853. ParseNodePtr Parser::ParseCase(ParseNodePtr *ppnodeBody)
  7854. {
  7855. ParseNodePtr pnodeT = nullptr;
  7856. charcount_t ichMinT = m_pscan->IchMinTok();
  7857. m_pscan->Scan();
  7858. ParseNodePtr pnodeExpr = ParseExpr<buildAST>();
  7859. charcount_t ichLim = m_pscan->IchLimTok();
  7860. ChkCurTok(tkColon, ERRnoColon);
  7861. if (buildAST)
  7862. {
  7863. pnodeT = CreateNodeWithScanner<knopCase>(ichMinT);
  7864. pnodeT->sxCase.pnodeExpr = pnodeExpr;
  7865. pnodeT->ichLim = ichLim;
  7866. }
  7867. ParseStmtList<buildAST>(ppnodeBody);
  7868. return pnodeT;
  7869. }
  7870. /***************************************************************************
  7871. Parse a single statement. Digest a trailing semicolon.
  7872. ***************************************************************************/
  7873. template<bool buildAST>
  7874. ParseNodePtr Parser::ParseStatement()
  7875. {
  7876. ParseNodePtr *ppnodeT;
  7877. ParseNodePtr pnodeT;
  7878. ParseNodePtr pnode = nullptr;
  7879. LabelId* pLabelIdList = nullptr;
  7880. charcount_t ichMin = 0;
  7881. size_t iecpMin = 0;
  7882. StmtNest stmt;
  7883. StmtNest *pstmt;
  7884. BOOL fForInOrOfOkay;
  7885. BOOL fCanAssign;
  7886. IdentPtr pid;
  7887. uint fnop;
  7888. ParseNodePtr pnodeLabel = nullptr;
  7889. bool expressionStmt = false;
  7890. bool isAsyncMethod = false;
  7891. tokens tok;
  7892. #if EXCEPTION_RECOVERY
  7893. ParseNodePtr pParentTryCatch = nullptr;
  7894. ParseNodePtr pTryBlock = nullptr;
  7895. ParseNodePtr pTry = nullptr;
  7896. ParseNodePtr pParentTryCatchBlock = nullptr;
  7897. StmtNest stmtTryCatchBlock;
  7898. StmtNest stmtTryCatch;
  7899. StmtNest stmtTry;
  7900. StmtNest stmtTryBlock;
  7901. #endif
  7902. if (buildAST)
  7903. {
  7904. #if EXCEPTION_RECOVERY
  7905. if(Js::Configuration::Global.flags.SwallowExceptions)
  7906. {
  7907. // If we're swallowing exceptions, surround this statement with a try/catch block:
  7908. //
  7909. // Before: x.y = 3;
  7910. // After: try { x.y = 3; } catch(__ehobj) { }
  7911. //
  7912. // This is done to force the runtime to recover from exceptions at the most granular
  7913. // possible point. Recovering from EH dramatically improves coverage of testing via
  7914. // fault injection.
  7915. // create and push the try-catch node
  7916. pParentTryCatchBlock = CreateBlockNode();
  7917. PushStmt<buildAST>(&stmtTryCatchBlock, pParentTryCatchBlock, knopBlock, nullptr, nullptr);
  7918. pParentTryCatch = CreateNodeWithScanner<knopTryCatch>();
  7919. PushStmt<buildAST>(&stmtTryCatch, pParentTryCatch, knopTryCatch, nullptr, nullptr);
  7920. // create and push a try node
  7921. pTry = CreateNodeWithScanner<knopTry>();
  7922. PushStmt<buildAST>(&stmtTry, pTry, knopTry, nullptr, nullptr);
  7923. pTryBlock = CreateBlockNode();
  7924. PushStmt<buildAST>(&stmtTryBlock, pTryBlock, knopBlock, nullptr, nullptr);
  7925. // these nodes will be closed after the statement is parsed.
  7926. }
  7927. #endif // EXCEPTION_RECOVERY
  7928. }
  7929. EnsureStackAvailable();
  7930. LRestart:
  7931. tok = m_token.tk;
  7932. switch (tok)
  7933. {
  7934. case tkEOF:
  7935. if (buildAST)
  7936. {
  7937. pnode = nullptr;
  7938. }
  7939. break;
  7940. case tkFUNCTION:
  7941. {
  7942. LFunctionStatement:
  7943. if (m_grfscr & fscrDeferredFncExpression)
  7944. {
  7945. // The top-level deferred function body was defined by a function expression whose parsing was deferred. We are now
  7946. // parsing it, so unset the flag so that any nested functions are parsed normally. This flag is only applicable the
  7947. // first time we see it.
  7948. m_grfscr &= ~fscrDeferredFncExpression;
  7949. pnode = ParseFncDecl<buildAST>(isAsyncMethod ? fFncAsync : fFncNoFlgs, nullptr);
  7950. }
  7951. else
  7952. {
  7953. pnode = ParseFncDecl<buildAST>(fFncDeclaration | (isAsyncMethod ? fFncAsync : fFncNoFlgs), nullptr);
  7954. }
  7955. if (isAsyncMethod)
  7956. {
  7957. pnode->sxFnc.cbMin = iecpMin;
  7958. pnode->ichMin = ichMin;
  7959. }
  7960. break;
  7961. }
  7962. case tkCLASS:
  7963. if (m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
  7964. {
  7965. pnode = ParseClassDecl<buildAST>(TRUE, nullptr, nullptr, nullptr);
  7966. }
  7967. else
  7968. {
  7969. goto LDefaultToken;
  7970. }
  7971. break;
  7972. case tkID:
  7973. if (m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.let)
  7974. {
  7975. // We see "let" at the start of a statement. This could either be a declaration or an identifier
  7976. // reference. The next token determines which.
  7977. RestorePoint parsedLet;
  7978. m_pscan->Capture(&parsedLet);
  7979. ichMin = m_pscan->IchMinTok();
  7980. m_pscan->Scan();
  7981. if (this->NextTokenConfirmsLetDecl())
  7982. {
  7983. pnode = ParseVariableDeclaration<buildAST>(tkLET, ichMin);
  7984. goto LNeedTerminator;
  7985. }
  7986. m_pscan->SeekTo(parsedLet);
  7987. }
  7988. else if (m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.async && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  7989. {
  7990. RestorePoint parsedAsync;
  7991. m_pscan->Capture(&parsedAsync);
  7992. ichMin = m_pscan->IchMinTok();
  7993. iecpMin = m_pscan->IecpMinTok();
  7994. m_pscan->Scan();
  7995. if (m_token.tk == tkFUNCTION && !m_pscan->FHadNewLine())
  7996. {
  7997. isAsyncMethod = true;
  7998. goto LFunctionStatement;
  7999. }
  8000. m_pscan->SeekTo(parsedAsync);
  8001. }
  8002. goto LDefaultToken;
  8003. case tkCONST:
  8004. case tkLET:
  8005. ichMin = m_pscan->IchMinTok();
  8006. m_pscan->Scan();
  8007. pnode = ParseVariableDeclaration<buildAST>(tok, ichMin);
  8008. goto LNeedTerminator;
  8009. case tkVAR:
  8010. ichMin = m_pscan->IchMinTok();
  8011. m_pscan->Scan();
  8012. pnode = ParseVariableDeclaration<buildAST>(tok, ichMin);
  8013. goto LNeedTerminator;
  8014. case tkFOR:
  8015. {
  8016. ParseNodePtr pnodeBlock = nullptr;
  8017. ParseNodePtr *ppnodeScopeSave = nullptr;
  8018. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  8019. ichMin = m_pscan->IchMinTok();
  8020. ChkNxtTok(tkLParen, ERRnoLparen);
  8021. pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block);
  8022. if (buildAST)
  8023. {
  8024. PushFuncBlockScope(pnodeBlock, &ppnodeScopeSave, &ppnodeExprScopeSave);
  8025. }
  8026. RestorePoint startExprOrIdentifier;
  8027. fForInOrOfOkay = TRUE;
  8028. fCanAssign = TRUE;
  8029. tok = m_token.tk;
  8030. BOOL nativeForOkay = TRUE;
  8031. switch (tok)
  8032. {
  8033. case tkID:
  8034. if (m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.let)
  8035. {
  8036. // We see "let" in the init part of a for loop. This could either be a declaration or an identifier
  8037. // reference. The next token determines which.
  8038. RestorePoint parsedLet;
  8039. m_pscan->Capture(&parsedLet);
  8040. auto ichMin = m_pscan->IchMinTok();
  8041. m_pscan->Scan();
  8042. if (IsPossiblePatternStart())
  8043. {
  8044. m_pscan->Capture(&startExprOrIdentifier);
  8045. }
  8046. if (this->NextTokenConfirmsLetDecl() && m_token.tk != tkIN)
  8047. {
  8048. pnodeT = ParseVariableDeclaration<buildAST>(tkLET, ichMin
  8049. , /*fAllowIn = */FALSE
  8050. , /*pfForInOk = */&fForInOrOfOkay
  8051. , /*singleDefOnly*/FALSE
  8052. , /*allowInit*/TRUE
  8053. , /*isTopVarParse*/TRUE
  8054. , /*isFor*/TRUE
  8055. , &nativeForOkay);
  8056. break;
  8057. }
  8058. m_pscan->SeekTo(parsedLet);
  8059. }
  8060. goto LDefaultTokenFor;
  8061. case tkLET:
  8062. case tkCONST:
  8063. case tkVAR:
  8064. {
  8065. auto ichMin = m_pscan->IchMinTok();
  8066. m_pscan->Scan();
  8067. if (IsPossiblePatternStart())
  8068. {
  8069. m_pscan->Capture(&startExprOrIdentifier);
  8070. }
  8071. pnodeT = ParseVariableDeclaration<buildAST>(tok, ichMin
  8072. , /*fAllowIn = */FALSE
  8073. , /*pfForInOk = */&fForInOrOfOkay
  8074. , /*singleDefOnly*/FALSE
  8075. , /*allowInit*/TRUE
  8076. , /*isTopVarParse*/TRUE
  8077. , /*isFor*/TRUE
  8078. , &nativeForOkay);
  8079. }
  8080. break;
  8081. case tkSColon:
  8082. pnodeT = nullptr;
  8083. fForInOrOfOkay = FALSE;
  8084. break;
  8085. default:
  8086. {
  8087. LDefaultTokenFor:
  8088. RestorePoint exprStart;
  8089. tokens beforeToken = tok;
  8090. m_pscan->Capture(&exprStart);
  8091. if (IsPossiblePatternStart())
  8092. {
  8093. m_pscan->Capture(&startExprOrIdentifier);
  8094. }
  8095. bool fLikelyPattern = false;
  8096. if (IsES6DestructuringEnabled() && (beforeToken == tkLBrack || beforeToken == tkLCurly))
  8097. {
  8098. pnodeT = ParseExpr<buildAST>(koplNo,
  8099. &fCanAssign,
  8100. /*fAllowIn = */FALSE,
  8101. /*fAllowEllipsis*/FALSE,
  8102. /*pHint*/nullptr,
  8103. /*pHintLength*/nullptr,
  8104. /*pShortNameOffset*/nullptr,
  8105. /*pToken*/nullptr,
  8106. /**fUnaryOrParen*/false,
  8107. &fLikelyPattern);
  8108. }
  8109. else
  8110. {
  8111. pnodeT = ParseExpr<buildAST>(koplNo, &fCanAssign, /*fAllowIn = */FALSE);
  8112. }
  8113. // 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
  8114. // has already converted them appropriately.
  8115. if (fLikelyPattern && TokIsForInOrForOf())
  8116. {
  8117. m_pscan->SeekTo(exprStart);
  8118. ParseDestructuredLiteralWithScopeSave(tkNone, false/*isDecl*/, false /*topLevel*/, DIC_None, false /*allowIn*/);
  8119. if (buildAST)
  8120. {
  8121. pnodeT = ConvertToPattern(pnodeT);
  8122. }
  8123. }
  8124. if (buildAST)
  8125. {
  8126. Assert(pnodeT);
  8127. pnodeT->isUsed = false;
  8128. }
  8129. }
  8130. break;
  8131. }
  8132. if (TokIsForInOrForOf())
  8133. {
  8134. bool isForOf = (m_token.tk != tkIN);
  8135. Assert(!isForOf || (m_token.tk == tkID && m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.of));
  8136. if ((buildAST && nullptr == pnodeT) || !fForInOrOfOkay)
  8137. {
  8138. if (isForOf)
  8139. {
  8140. Error(ERRForOfNoInitAllowed);
  8141. }
  8142. else
  8143. {
  8144. Error(ERRForInNoInitAllowed);
  8145. }
  8146. }
  8147. if (!fCanAssign && PHASE_ON1(Js::EarlyReferenceErrorsPhase))
  8148. {
  8149. Error(JSERR_CantAssignTo);
  8150. }
  8151. m_pscan->Scan();
  8152. ParseNodePtr pnodeObj = ParseExpr<buildAST>(isForOf ? koplCma : koplNo);
  8153. charcount_t ichLim = m_pscan->IchLimTok();
  8154. ChkCurTok(tkRParen, ERRnoRparen);
  8155. if (buildAST)
  8156. {
  8157. if (isForOf)
  8158. {
  8159. pnode = CreateNodeWithScanner<knopForOf>(ichMin);
  8160. }
  8161. else
  8162. {
  8163. pnode = CreateNodeWithScanner<knopForIn>(ichMin);
  8164. }
  8165. pnode->sxForInOrForOf.pnodeBlock = pnodeBlock;
  8166. pnode->sxForInOrForOf.pnodeLval = pnodeT;
  8167. pnode->sxForInOrForOf.pnodeObj = pnodeObj;
  8168. pnode->ichLim = ichLim;
  8169. }
  8170. PushStmt<buildAST>(&stmt, pnode, isForOf ? knopForOf : knopForIn, pnodeLabel, pLabelIdList);
  8171. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  8172. if (buildAST)
  8173. {
  8174. pnode->sxForInOrForOf.pnodeBody = pnodeBody;
  8175. }
  8176. PopStmt(&stmt);
  8177. }
  8178. else
  8179. {
  8180. if (!nativeForOkay)
  8181. {
  8182. Error(ERRDestructInit);
  8183. }
  8184. ChkCurTok(tkSColon, ERRnoSemic);
  8185. ParseNodePtr pnodeCond = nullptr;
  8186. if (m_token.tk != tkSColon)
  8187. {
  8188. pnodeCond = ParseExpr<buildAST>();
  8189. if (m_token.tk != tkSColon)
  8190. {
  8191. Error(ERRnoSemic);
  8192. }
  8193. }
  8194. tokens tk;
  8195. tk = m_pscan->Scan();
  8196. ParseNodePtr pnodeIncr = nullptr;
  8197. if (tk != tkRParen)
  8198. {
  8199. pnodeIncr = ParseExpr<buildAST>();
  8200. if(pnodeIncr)
  8201. {
  8202. pnodeIncr->isUsed = false;
  8203. }
  8204. }
  8205. charcount_t ichLim = m_pscan->IchLimTok();
  8206. ChkCurTok(tkRParen, ERRnoRparen);
  8207. if (buildAST)
  8208. {
  8209. pnode = CreateNodeWithScanner<knopFor>(ichMin);
  8210. pnode->sxFor.pnodeBlock = pnodeBlock;
  8211. pnode->sxFor.pnodeInverted= nullptr;
  8212. pnode->sxFor.pnodeInit = pnodeT;
  8213. pnode->sxFor.pnodeCond = pnodeCond;
  8214. pnode->sxFor.pnodeIncr = pnodeIncr;
  8215. pnode->ichLim = ichLim;
  8216. }
  8217. PushStmt<buildAST>(&stmt, pnode, knopFor, pnodeLabel, pLabelIdList);
  8218. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  8219. if (buildAST)
  8220. {
  8221. pnode->sxFor.pnodeBody = pnodeBody;
  8222. }
  8223. PopStmt(&stmt);
  8224. }
  8225. if (buildAST)
  8226. {
  8227. PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
  8228. }
  8229. FinishParseBlock(pnodeBlock);
  8230. break;
  8231. }
  8232. case tkSWITCH:
  8233. {
  8234. BOOL fSeenDefault = FALSE;
  8235. ParseNodePtr pnodeBlock = nullptr;
  8236. ParseNodePtr *ppnodeScopeSave = nullptr;
  8237. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  8238. ichMin = m_pscan->IchMinTok();
  8239. ChkNxtTok(tkLParen, ERRnoLparen);
  8240. ParseNodePtr pnodeVal = ParseExpr<buildAST>();
  8241. charcount_t ichLim = m_pscan->IchLimTok();
  8242. ChkCurTok(tkRParen, ERRnoRparen);
  8243. ChkCurTok(tkLCurly, ERRnoLcurly);
  8244. if (buildAST)
  8245. {
  8246. pnode = CreateNodeWithScanner<knopSwitch>(ichMin);
  8247. }
  8248. PushStmt<buildAST>(&stmt, pnode, knopSwitch, pnodeLabel, pLabelIdList);
  8249. pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block, nullptr, pLabelIdList);
  8250. if (buildAST)
  8251. {
  8252. pnode->sxSwitch.pnodeVal = pnodeVal;
  8253. pnode->sxSwitch.pnodeBlock = pnodeBlock;
  8254. pnode->ichLim = ichLim;
  8255. PushFuncBlockScope(pnode->sxSwitch.pnodeBlock, &ppnodeScopeSave, &ppnodeExprScopeSave);
  8256. pnode->sxSwitch.pnodeDefault = nullptr;
  8257. ppnodeT = &pnode->sxSwitch.pnodeCases;
  8258. }
  8259. for (;;)
  8260. {
  8261. ParseNodePtr pnodeBody = nullptr;
  8262. switch (m_token.tk)
  8263. {
  8264. default:
  8265. goto LEndSwitch;
  8266. case tkCASE:
  8267. {
  8268. pnodeT = this->ParseCase<buildAST>(&pnodeBody);
  8269. break;
  8270. }
  8271. case tkDEFAULT:
  8272. if (fSeenDefault)
  8273. {
  8274. Error(ERRdupDefault);
  8275. // No recovery necessary since this is a semantic, not structural, error
  8276. }
  8277. fSeenDefault = TRUE;
  8278. charcount_t ichMinT = m_pscan->IchMinTok();
  8279. m_pscan->Scan();
  8280. charcount_t ichLim = m_pscan->IchLimTok();
  8281. ChkCurTok(tkColon, ERRnoColon);
  8282. if (buildAST)
  8283. {
  8284. pnodeT = CreateNodeWithScanner<knopCase>(ichMinT);
  8285. pnode->sxSwitch.pnodeDefault = pnodeT;
  8286. pnodeT->ichLim = ichLim;
  8287. pnodeT->sxCase.pnodeExpr = nullptr;
  8288. }
  8289. ParseStmtList<buildAST>(&pnodeBody);
  8290. break;
  8291. }
  8292. if (buildAST)
  8293. {
  8294. if (pnodeBody)
  8295. {
  8296. // Create a block node to contain the statement list for this case.
  8297. // This helps us insert byte code to return the right value from
  8298. // global/eval code.
  8299. pnodeT->sxCase.pnodeBody = CreateBlockNode(pnodeT->ichMin, pnodeT->ichLim);
  8300. pnodeT->sxCase.pnodeBody->grfpn |= PNodeFlags::fpnSyntheticNode; // block is not a user specifier block
  8301. pnodeT->sxCase.pnodeBody->sxBlock.pnodeStmt = pnodeBody;
  8302. }
  8303. else
  8304. {
  8305. pnodeT->sxCase.pnodeBody = nullptr;
  8306. }
  8307. *ppnodeT = pnodeT;
  8308. ppnodeT = &pnodeT->sxCase.pnodeNext;
  8309. }
  8310. }
  8311. LEndSwitch:
  8312. ChkCurTok(tkRCurly, ERRnoRcurly);
  8313. if (buildAST)
  8314. {
  8315. *ppnodeT = nullptr;
  8316. PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
  8317. FinishParseBlock(pnode->sxSwitch.pnodeBlock);
  8318. }
  8319. else
  8320. {
  8321. FinishParseBlock(pnodeBlock);
  8322. }
  8323. PopStmt(&stmt);
  8324. break;
  8325. }
  8326. case tkWHILE:
  8327. {
  8328. ichMin = m_pscan->IchMinTok();
  8329. ChkNxtTok(tkLParen, ERRnoLparen);
  8330. ParseNodePtr pnodeCond = ParseExpr<buildAST>();
  8331. charcount_t ichLim = m_pscan->IchLimTok();
  8332. ChkCurTok(tkRParen, ERRnoRparen);
  8333. if (buildAST)
  8334. {
  8335. pnode = CreateNodeWithScanner<knopWhile>(ichMin);
  8336. pnode->sxWhile.pnodeCond = pnodeCond;
  8337. pnode->ichLim = ichLim;
  8338. }
  8339. PushStmt<buildAST>(&stmt, pnode, knopWhile, pnodeLabel, pLabelIdList);
  8340. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  8341. PopStmt(&stmt);
  8342. if (buildAST)
  8343. {
  8344. pnode->sxWhile.pnodeBody = pnodeBody;
  8345. }
  8346. break;
  8347. }
  8348. case tkDO:
  8349. {
  8350. if (buildAST)
  8351. {
  8352. pnode = CreateNodeWithScanner<knopDoWhile>();
  8353. }
  8354. PushStmt<buildAST>(&stmt, pnode, knopDoWhile, pnodeLabel, pLabelIdList);
  8355. m_pscan->Scan();
  8356. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  8357. PopStmt(&stmt);
  8358. charcount_t ichMinT = m_pscan->IchMinTok();
  8359. ChkCurTok(tkWHILE, ERRnoWhile);
  8360. ChkCurTok(tkLParen, ERRnoLparen);
  8361. ParseNodePtr pnodeCond = ParseExpr<buildAST>();
  8362. charcount_t ichLim = m_pscan->IchLimTok();
  8363. ChkCurTok(tkRParen, ERRnoRparen);
  8364. if (buildAST)
  8365. {
  8366. pnode->sxWhile.pnodeBody = pnodeBody;
  8367. pnode->sxWhile.pnodeCond = pnodeCond;
  8368. pnode->ichLim = ichLim;
  8369. pnode->ichMin = ichMinT;
  8370. }
  8371. // REVIEW: Allow do...while statements to be embedded in other compound statements like if..else, or do..while?
  8372. // goto LNeedTerminator;
  8373. // For now just eat the trailing semicolon if present.
  8374. if (m_token.tk == tkSColon)
  8375. {
  8376. if (pnode)
  8377. {
  8378. pnode->grfpn |= PNodeFlags::fpnExplicitSemicolon;
  8379. }
  8380. m_pscan->Scan();
  8381. }
  8382. else if (pnode)
  8383. {
  8384. pnode->grfpn |= PNodeFlags::fpnAutomaticSemicolon;
  8385. }
  8386. break;
  8387. }
  8388. case tkIF:
  8389. {
  8390. ichMin = m_pscan->IchMinTok();
  8391. ChkNxtTok(tkLParen, ERRnoLparen);
  8392. ParseNodePtr pnodeCond = ParseExpr<buildAST>();
  8393. if (buildAST)
  8394. {
  8395. pnode = CreateNodeWithScanner<knopIf>(ichMin);
  8396. pnode->ichLim = m_pscan->IchLimTok();
  8397. pnode->sxIf.pnodeCond = pnodeCond;
  8398. }
  8399. ChkCurTok(tkRParen, ERRnoRparen);
  8400. PushStmt<buildAST>(&stmt, pnode, knopIf, pnodeLabel, pLabelIdList);
  8401. ParseNodePtr pnodeTrue = ParseStatement<buildAST>();
  8402. ParseNodePtr pnodeFalse = nullptr;
  8403. if (m_token.tk == tkELSE)
  8404. {
  8405. m_pscan->Scan();
  8406. pnodeFalse = ParseStatement<buildAST>();
  8407. }
  8408. if (buildAST)
  8409. {
  8410. pnode->sxIf.pnodeTrue = pnodeTrue;
  8411. pnode->sxIf.pnodeFalse = pnodeFalse;
  8412. }
  8413. PopStmt(&stmt);
  8414. break;
  8415. }
  8416. case tkTRY:
  8417. {
  8418. if (buildAST)
  8419. {
  8420. pnode = CreateBlockNode();
  8421. pnode->grfpn |= PNodeFlags::fpnSyntheticNode; // block is not a user specifier block
  8422. }
  8423. PushStmt<buildAST>(&stmt, pnode, knopBlock, pnodeLabel, pLabelIdList);
  8424. ParseNodePtr pnodeStmt = ParseTryCatchFinally<buildAST>();
  8425. if (buildAST)
  8426. {
  8427. pnode->sxBlock.pnodeStmt = pnodeStmt;
  8428. }
  8429. PopStmt(&stmt);
  8430. break;
  8431. }
  8432. case tkWITH:
  8433. {
  8434. if ( IsStrictMode() )
  8435. {
  8436. Error(ERRES5NoWith);
  8437. }
  8438. if (m_currentNodeFunc)
  8439. {
  8440. GetCurrentFunctionNode()->sxFnc.SetHasWithStmt(); // Used by DeferNested
  8441. }
  8442. ichMin = m_pscan->IchMinTok();
  8443. ChkNxtTok(tkLParen, ERRnoLparen);
  8444. ParseNodePtr pnodeObj = ParseExpr<buildAST>();
  8445. if (!buildAST)
  8446. {
  8447. m_scopeCountNoAst++;
  8448. }
  8449. charcount_t ichLim = m_pscan->IchLimTok();
  8450. ChkCurTok(tkRParen, ERRnoRparen);
  8451. if (buildAST)
  8452. {
  8453. pnode = CreateNodeWithScanner<knopWith>(ichMin);
  8454. }
  8455. PushStmt<buildAST>(&stmt, pnode, knopWith, pnodeLabel, pLabelIdList);
  8456. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  8457. if (buildAST)
  8458. {
  8459. pnode->sxWith.pnodeObj = pnodeObj;
  8460. this->CheckArguments(pnode->sxWith.pnodeObj);
  8461. if (m_ppnodeExprScope)
  8462. {
  8463. Assert(*m_ppnodeExprScope == nullptr);
  8464. *m_ppnodeExprScope = pnode;
  8465. m_ppnodeExprScope = &pnode->sxWith.pnodeNext;
  8466. }
  8467. else
  8468. {
  8469. Assert(m_ppnodeScope);
  8470. Assert(*m_ppnodeScope == nullptr);
  8471. *m_ppnodeScope = pnode;
  8472. m_ppnodeScope = &pnode->sxWith.pnodeNext;
  8473. }
  8474. pnode->sxWith.pnodeNext = nullptr;
  8475. pnode->sxWith.scope = nullptr;
  8476. ppnodeExprScopeSave = m_ppnodeExprScope;
  8477. m_ppnodeExprScope = &pnode->sxWith.pnodeScopes;
  8478. pnode->sxWith.pnodeScopes = nullptr;
  8479. pnode->ichLim = ichLim;
  8480. }
  8481. PushBlockInfo(CreateBlockNode());
  8482. PushDynamicBlock();
  8483. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  8484. if (buildAST)
  8485. {
  8486. pnode->sxWith.pnodeBody = pnodeBody;
  8487. m_ppnodeExprScope = ppnodeExprScopeSave;
  8488. }
  8489. else
  8490. {
  8491. m_scopeCountNoAst--;
  8492. }
  8493. // The dynamic block is not stored in the actual parse tree and so will not
  8494. // be visited by the byte code generator. Grab the callsEval flag off it and
  8495. // pass on to outer block in case of:
  8496. // with (...) eval(...); // i.e. blockless form of with
  8497. bool callsEval = GetCurrentBlock()->sxBlock.GetCallsEval();
  8498. PopBlockInfo();
  8499. if (callsEval)
  8500. {
  8501. // be careful not to overwrite an existing true with false
  8502. GetCurrentBlock()->sxBlock.SetCallsEval(true);
  8503. }
  8504. PopStmt(&stmt);
  8505. break;
  8506. }
  8507. case tkLCurly:
  8508. pnode = ParseBlock<buildAST>(pnodeLabel, pLabelIdList);
  8509. break;
  8510. case tkSColon:
  8511. pnode = nullptr;
  8512. m_pscan->Scan();
  8513. break;
  8514. case tkBREAK:
  8515. if (buildAST)
  8516. {
  8517. pnode = CreateNodeWithScanner<knopBreak>();
  8518. }
  8519. fnop = fnopBreak;
  8520. goto LGetJumpStatement;
  8521. case tkCONTINUE:
  8522. if (buildAST)
  8523. {
  8524. pnode = CreateNode(knopContinue);
  8525. }
  8526. fnop = fnopContinue;
  8527. LGetJumpStatement:
  8528. m_pscan->ScanForcingPid();
  8529. if (tkID == m_token.tk && !m_pscan->FHadNewLine())
  8530. {
  8531. // Labeled break or continue.
  8532. pid = m_token.GetIdentifier(m_phtbl);
  8533. AssertMem(pid);
  8534. if (buildAST)
  8535. {
  8536. pnode->sxJump.hasExplicitTarget=true;
  8537. pnode->ichLim = m_pscan->IchLimTok();
  8538. m_pscan->Scan();
  8539. PushStmt<buildAST>(&stmt, pnode, pnode->nop, pnodeLabel, nullptr);
  8540. Assert(pnode->sxStmt.grfnop == 0);
  8541. for (pstmt = m_pstmtCur; nullptr != pstmt; pstmt = pstmt->pstmtOuter)
  8542. {
  8543. AssertNodeMem(pstmt->pnodeStmt);
  8544. AssertNodeMemN(pstmt->pnodeLab);
  8545. for (pnodeT = pstmt->pnodeLab; nullptr != pnodeT;
  8546. pnodeT = pnodeT->sxLabel.pnodeNext)
  8547. {
  8548. Assert(knopLabel == pnodeT->nop);
  8549. if (pid == pnodeT->sxLabel.pid)
  8550. {
  8551. // Found the label. Make sure we can use it. We can
  8552. // break out of any statement, but we can only
  8553. // continue loops.
  8554. if (fnop == fnopContinue &&
  8555. !(pstmt->pnodeStmt->Grfnop() & fnop))
  8556. {
  8557. Error(ERRbadContinue);
  8558. }
  8559. else
  8560. {
  8561. pstmt->pnodeStmt->sxStmt.grfnop |= fnop;
  8562. pnode->sxJump.pnodeTarget = pstmt->pnodeStmt;
  8563. }
  8564. PopStmt(&stmt);
  8565. goto LNeedTerminator;
  8566. }
  8567. }
  8568. pnode->sxStmt.grfnop |=
  8569. (pstmt->pnodeStmt->Grfnop() & fnopCleanup);
  8570. }
  8571. }
  8572. else
  8573. {
  8574. m_pscan->Scan();
  8575. for (pstmt = m_pstmtCur; pstmt; pstmt = pstmt->pstmtOuter)
  8576. {
  8577. LabelId* pLabelId;
  8578. for (pLabelId = pstmt->pLabelId; pLabelId; pLabelId = pLabelId->next)
  8579. {
  8580. if (pid == pLabelId->pid)
  8581. {
  8582. // Found the label. Make sure we can use it. We can
  8583. // break out of any statement, but we can only
  8584. // continue loops.
  8585. if (fnop == fnopContinue &&
  8586. !(ParseNode::Grfnop(pstmt->op) & fnop))
  8587. {
  8588. Error(ERRbadContinue);
  8589. }
  8590. goto LNeedTerminator;
  8591. }
  8592. }
  8593. }
  8594. }
  8595. Error(ERRnoLabel);
  8596. }
  8597. else
  8598. {
  8599. // If we're doing a fast scan, we're not tracking labels, so we can't accurately do this analysis.
  8600. // Let the thread that's doing the full parse detect the error, if there is one.
  8601. if (!this->m_doingFastScan)
  8602. {
  8603. // Unlabeled break or continue.
  8604. if (buildAST)
  8605. {
  8606. pnode->sxJump.hasExplicitTarget=false;
  8607. PushStmt<buildAST>(&stmt, pnode, pnode->nop, pnodeLabel, nullptr);
  8608. Assert(pnode->sxStmt.grfnop == 0);
  8609. }
  8610. for (pstmt = m_pstmtCur; nullptr != pstmt; pstmt = pstmt->pstmtOuter)
  8611. {
  8612. if (buildAST)
  8613. {
  8614. AnalysisAssert(pstmt->pnodeStmt);
  8615. if (pstmt->pnodeStmt->Grfnop() & fnop)
  8616. {
  8617. pstmt->pnodeStmt->sxStmt.grfnop |= fnop;
  8618. pnode->sxJump.pnodeTarget = pstmt->pnodeStmt;
  8619. PopStmt(&stmt);
  8620. goto LNeedTerminator;
  8621. }
  8622. pnode->sxStmt.grfnop |=
  8623. (pstmt->pnodeStmt->Grfnop() & fnopCleanup);
  8624. }
  8625. else
  8626. {
  8627. if (pstmt->isDeferred)
  8628. {
  8629. if (ParseNode::Grfnop(pstmt->op) & fnop)
  8630. {
  8631. goto LNeedTerminator;
  8632. }
  8633. }
  8634. else
  8635. {
  8636. AnalysisAssert(pstmt->pnodeStmt);
  8637. if (pstmt->pnodeStmt->Grfnop() & fnop)
  8638. {
  8639. pstmt->pnodeStmt->sxStmt.grfnop |= fnop;
  8640. goto LNeedTerminator;
  8641. }
  8642. }
  8643. }
  8644. }
  8645. Error(fnop == fnopBreak ? ERRbadBreak : ERRbadContinue);
  8646. }
  8647. goto LNeedTerminator;
  8648. }
  8649. case tkRETURN:
  8650. {
  8651. if (buildAST)
  8652. {
  8653. if (nullptr == m_currentNodeFunc)
  8654. {
  8655. Error(ERRbadReturn);
  8656. }
  8657. pnode = CreateNodeWithScanner<knopReturn>();
  8658. }
  8659. m_pscan->Scan();
  8660. ParseNodePtr pnodeExpr = nullptr;
  8661. ParseOptionalExpr<buildAST>(&pnodeExpr, true);
  8662. if (buildAST)
  8663. {
  8664. pnode->sxReturn.pnodeExpr = pnodeExpr;
  8665. if (pnodeExpr)
  8666. {
  8667. this->CheckArguments(pnode->sxReturn.pnodeExpr);
  8668. pnode->ichLim = pnode->sxReturn.pnodeExpr->ichLim;
  8669. }
  8670. // See if return should call finally
  8671. PushStmt<buildAST>(&stmt, pnode, knopReturn, pnodeLabel, nullptr);
  8672. Assert(pnode->sxStmt.grfnop == 0);
  8673. for (pstmt = m_pstmtCur; nullptr != pstmt; pstmt = pstmt->pstmtOuter)
  8674. {
  8675. AssertNodeMem(pstmt->pnodeStmt);
  8676. AssertNodeMemN(pstmt->pnodeLab);
  8677. if (pstmt->pnodeStmt->Grfnop() & fnopCleanup)
  8678. {
  8679. pnode->sxStmt.grfnop |= fnopCleanup;
  8680. break;
  8681. }
  8682. }
  8683. PopStmt(&stmt);
  8684. }
  8685. goto LNeedTerminator;
  8686. }
  8687. case tkTHROW:
  8688. {
  8689. if (buildAST)
  8690. {
  8691. pnode = CreateUniNode(knopThrow, nullptr);
  8692. }
  8693. m_pscan->Scan();
  8694. ParseNodePtr pnode1 = nullptr;
  8695. if (m_token.tk != tkSColon &&
  8696. m_token.tk != tkRCurly &&
  8697. !m_pscan->FHadNewLine())
  8698. {
  8699. pnode1 = ParseExpr<buildAST>();
  8700. }
  8701. else
  8702. {
  8703. Error(ERRdanglingThrow);
  8704. }
  8705. if (buildAST)
  8706. {
  8707. pnode->sxUni.pnode1 = pnode1;
  8708. if (pnode1)
  8709. {
  8710. this->CheckArguments(pnode->sxUni.pnode1);
  8711. pnode->ichLim = pnode->sxUni.pnode1->ichLim;
  8712. }
  8713. }
  8714. goto LNeedTerminator;
  8715. }
  8716. case tkDEBUGGER:
  8717. if (buildAST)
  8718. {
  8719. pnode = CreateNodeWithScanner<knopDebugger>();
  8720. }
  8721. m_pscan->Scan();
  8722. goto LNeedTerminator;
  8723. case tkIMPORT:
  8724. if (!(m_grfscr & fscrIsModuleCode))
  8725. {
  8726. goto LDefaultToken;
  8727. }
  8728. pnode = ParseImportDeclaration<buildAST>();
  8729. goto LNeedTerminator;
  8730. case tkEXPORT:
  8731. if (!(m_grfscr & fscrIsModuleCode))
  8732. {
  8733. goto LDefaultToken;
  8734. }
  8735. pnode = ParseExportDeclaration<buildAST>();
  8736. goto LNeedTerminator;
  8737. LDefaultToken:
  8738. default:
  8739. {
  8740. // An expression statement or a label.
  8741. IdentToken tok;
  8742. pnode = ParseExpr<buildAST>(koplNo, nullptr, TRUE, FALSE, nullptr, nullptr /*hintLength*/, nullptr /*hintOffset*/, &tok);
  8743. if (m_hasDeferredShorthandInitError)
  8744. {
  8745. Error(ERRnoColon);
  8746. }
  8747. if (buildAST)
  8748. {
  8749. // Check for a label.
  8750. if (tkColon == m_token.tk &&
  8751. nullptr != pnode && knopName == pnode->nop)
  8752. {
  8753. // We have a label. See if it is already defined.
  8754. if (nullptr != PnodeLabel(pnode->sxPid.pid, pnodeLabel))
  8755. {
  8756. Error(ERRbadLabel);
  8757. // No recovery is necessary since this is a semantic, not structural, error
  8758. }
  8759. pnodeT = CreateNodeWithScanner<knopLabel>();
  8760. pnodeT->sxLabel.pid = pnode->sxPid.pid;
  8761. pnodeT->sxLabel.pnodeNext = pnodeLabel;
  8762. pnodeLabel = pnodeT;
  8763. m_pscan->Scan();
  8764. goto LRestart;
  8765. }
  8766. expressionStmt = true;
  8767. AnalysisAssert(pnode);
  8768. pnode->isUsed = false;
  8769. }
  8770. else
  8771. {
  8772. // Check for a label.
  8773. if (tkColon == m_token.tk && tok.tk == tkID)
  8774. {
  8775. tok.pid = m_pscan->PidAt(tok.ichMin, tok.ichLim);
  8776. if (PnodeLabelNoAST(&tok, pLabelIdList))
  8777. {
  8778. Error(ERRbadLabel);
  8779. }
  8780. LabelId* pLabelId = CreateLabelId(&tok);
  8781. pLabelId->next = pLabelIdList;
  8782. pLabelIdList = pLabelId;
  8783. m_pscan->Scan();
  8784. goto LRestart;
  8785. }
  8786. }
  8787. }
  8788. LNeedTerminator:
  8789. // Need a semicolon, new-line, } or end-of-file.
  8790. // We digest a semicolon if it's there.
  8791. switch (m_token.tk)
  8792. {
  8793. case tkSColon:
  8794. m_pscan->Scan();
  8795. if (pnode!= nullptr) pnode->grfpn |= PNodeFlags::fpnExplicitSemicolon;
  8796. break;
  8797. case tkEOF:
  8798. case tkRCurly:
  8799. if (pnode!= nullptr) pnode->grfpn |= PNodeFlags::fpnAutomaticSemicolon;
  8800. break;
  8801. default:
  8802. if (!m_pscan->FHadNewLine())
  8803. {
  8804. Error(ERRnoSemic);
  8805. }
  8806. else
  8807. {
  8808. if (pnode!= nullptr) pnode->grfpn |= PNodeFlags::fpnAutomaticSemicolon;
  8809. }
  8810. break;
  8811. }
  8812. break;
  8813. }
  8814. if (m_hasDeferredShorthandInitError)
  8815. {
  8816. Error(ERRnoColon);
  8817. }
  8818. if (buildAST)
  8819. {
  8820. // All non expression statements excluded from the "this.x" optimization
  8821. // Another check while parsing expressions
  8822. if (!expressionStmt)
  8823. {
  8824. if (m_currentNodeFunc)
  8825. {
  8826. m_currentNodeFunc->sxFnc.SetHasNonThisStmt();
  8827. }
  8828. else if (m_currentNodeProg)
  8829. {
  8830. m_currentNodeProg->sxFnc.SetHasNonThisStmt();
  8831. }
  8832. }
  8833. #if EXCEPTION_RECOVERY
  8834. // close the try/catch block
  8835. if(Js::Configuration::Global.flags.SwallowExceptions)
  8836. {
  8837. // pop the try block and fill in the body
  8838. PopStmt(&stmtTryBlock);
  8839. pTryBlock->sxBlock.pnodeStmt = pnode;
  8840. PopStmt(&stmtTry);
  8841. if(pnode != nullptr)
  8842. {
  8843. pTry->ichLim = pnode->ichLim;
  8844. }
  8845. pTry->sxTry.pnodeBody = pTryBlock;
  8846. // create a catch block with an empty body
  8847. StmtNest stmtCatch;
  8848. ParseNodePtr pCatch;
  8849. pCatch = CreateNodeWithScanner<knopCatch>();
  8850. PushStmt<buildAST>(&stmtCatch, pCatch, knopCatch, nullptr, nullptr);
  8851. pCatch->sxCatch.pnodeBody = nullptr;
  8852. if(pnode != nullptr)
  8853. {
  8854. pCatch->ichLim = pnode->ichLim;
  8855. }
  8856. pCatch->sxCatch.grfnop = 0;
  8857. pCatch->sxCatch.pnodeNext = nullptr;
  8858. // create a fake name for the catch var.
  8859. WCHAR *uniqueNameStr = _u("__ehobj");
  8860. IdentPtr uniqueName = m_phtbl->PidHashNameLen(uniqueNameStr, static_cast<long>(wcslen(uniqueNameStr)));
  8861. pCatch->sxCatch.pnodeParam = CreateNameNode(uniqueName);
  8862. // Add this catch to the current list. We don't bother adjusting the catch and function expression
  8863. // lists here because the catch is just an empty statement.
  8864. if (m_ppnodeExprScope)
  8865. {
  8866. Assert(*m_ppnodeExprScope == nullptr);
  8867. *m_ppnodeExprScope = pCatch;
  8868. m_ppnodeExprScope = &pCatch->sxCatch.pnodeNext;
  8869. }
  8870. else
  8871. {
  8872. Assert(m_ppnodeScope);
  8873. Assert(*m_ppnodeScope == nullptr);
  8874. *m_ppnodeScope = pCatch;
  8875. m_ppnodeScope = &pCatch->sxCatch.pnodeNext;
  8876. }
  8877. pCatch->sxCatch.pnodeScopes = nullptr;
  8878. PopStmt(&stmtCatch);
  8879. // fill in and pop the try-catch
  8880. pParentTryCatch->sxTryCatch.pnodeTry = pTry;
  8881. pParentTryCatch->sxTryCatch.pnodeCatch = pCatch;
  8882. PopStmt(&stmtTryCatch);
  8883. PopStmt(&stmtTryCatchBlock);
  8884. // replace the node that's being returned
  8885. pParentTryCatchBlock->sxBlock.pnodeStmt = pParentTryCatch;
  8886. pnode = pParentTryCatchBlock;
  8887. }
  8888. #endif // EXCEPTION_RECOVERY
  8889. }
  8890. return pnode;
  8891. }
  8892. BOOL
  8893. Parser::TokIsForInOrForOf()
  8894. {
  8895. return m_token.tk == tkIN ||
  8896. (m_token.tk == tkID &&
  8897. m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.of);
  8898. }
  8899. /***************************************************************************
  8900. Parse a sequence of statements.
  8901. ***************************************************************************/
  8902. template<bool buildAST>
  8903. void Parser::ParseStmtList(ParseNodePtr *ppnodeList, ParseNodePtr **pppnodeLast, StrictModeEnvironment smEnvironment, const bool isSourceElementList, bool* strictModeOn)
  8904. {
  8905. BOOL doneDirectives = !isSourceElementList; // directives may only exist in a SourceElementList, not a StatementList
  8906. BOOL seenDirectiveContainingOctal = false; // Have we seen an octal directive before a use strict directive?
  8907. BOOL old_UseStrictMode = m_fUseStrictMode;
  8908. ParseNodePtr pnodeStmt;
  8909. ParseNodePtr *lastNodeRef = nullptr;
  8910. if (buildAST)
  8911. {
  8912. AssertMem(ppnodeList);
  8913. AssertMemN(pppnodeLast);
  8914. *ppnodeList = nullptr;
  8915. }
  8916. if(CONFIG_FLAG(ForceStrictMode))
  8917. {
  8918. m_fUseStrictMode = TRUE;
  8919. }
  8920. for (;;)
  8921. {
  8922. switch (m_token.tk)
  8923. {
  8924. case tkCASE:
  8925. case tkDEFAULT:
  8926. case tkRCurly:
  8927. case tkEOF:
  8928. if (buildAST && nullptr != pppnodeLast)
  8929. {
  8930. *pppnodeLast = lastNodeRef;
  8931. }
  8932. if (!buildAST)
  8933. {
  8934. m_fUseStrictMode = old_UseStrictMode;
  8935. }
  8936. return;
  8937. }
  8938. if (doneDirectives == FALSE)
  8939. {
  8940. bool isOctalInString = false;
  8941. bool isUseStrictDirective = false;
  8942. bool isUseAsmDirective = false;
  8943. if (smEnvironment != SM_NotUsed && CheckForDirective(&isUseStrictDirective, &isUseAsmDirective, &isOctalInString))
  8944. {
  8945. // Ignore "use asm" statement when not building the AST
  8946. isUseAsmDirective &= buildAST;
  8947. if (isUseStrictDirective)
  8948. {
  8949. // Functions with non-simple parameter list cannot be made strict mode
  8950. if (GetCurrentFunctionNode()->sxFnc.HasNonSimpleParameterList())
  8951. {
  8952. Error(ERRNonSimpleParamListInStrictMode);
  8953. }
  8954. if (seenDirectiveContainingOctal)
  8955. {
  8956. // Directives seen before a "use strict" cannot contain an octal.
  8957. Error(ERRES5NoOctal);
  8958. }
  8959. if (!buildAST)
  8960. {
  8961. // Turning on strict mode in deferred code.
  8962. m_fUseStrictMode = TRUE;
  8963. if (!m_inDeferredNestedFunc)
  8964. {
  8965. // Top-level deferred function, so there's a parse node
  8966. Assert(m_currentNodeFunc != nullptr);
  8967. m_currentNodeFunc->sxFnc.SetStrictMode();
  8968. }
  8969. else if (strictModeOn)
  8970. {
  8971. // This turns on strict mode in a deferred function, we need to go back
  8972. // and re-check duplicated formals.
  8973. *strictModeOn = true;
  8974. }
  8975. }
  8976. else
  8977. {
  8978. if (smEnvironment == SM_OnGlobalCode)
  8979. {
  8980. // Turning on strict mode at the top level
  8981. m_fUseStrictMode = TRUE;
  8982. }
  8983. else
  8984. {
  8985. // i.e. smEnvironment == SM_OnFunctionCode
  8986. Assert(m_currentNodeFunc != nullptr);
  8987. m_currentNodeFunc->sxFnc.SetStrictMode();
  8988. }
  8989. }
  8990. }
  8991. else if (isUseAsmDirective)
  8992. {
  8993. if (smEnvironment != SM_OnGlobalCode) //Top level use asm doesn't mean anything.
  8994. {
  8995. // i.e. smEnvironment == SM_OnFunctionCode
  8996. Assert(m_currentNodeFunc != nullptr);
  8997. m_currentNodeFunc->sxFnc.SetAsmjsMode();
  8998. m_InAsmMode = true;
  8999. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(AsmJSFunctionCount, m_scriptContext);
  9000. }
  9001. }
  9002. else if (isOctalInString)
  9003. {
  9004. seenDirectiveContainingOctal = TRUE;
  9005. }
  9006. }
  9007. else
  9008. {
  9009. // The first time we see anything other than a directive we can have no more directives.
  9010. doneDirectives = TRUE;
  9011. }
  9012. }
  9013. if (nullptr != (pnodeStmt = ParseStatement<buildAST>()))
  9014. {
  9015. if (buildAST)
  9016. {
  9017. AddToNodeList(ppnodeList, &lastNodeRef, pnodeStmt);
  9018. }
  9019. }
  9020. }
  9021. }
  9022. template <class Fn>
  9023. void Parser::VisitFunctionsInScope(ParseNodePtr pnodeScopeList, Fn fn)
  9024. {
  9025. ParseNodePtr pnodeScope;
  9026. for (pnodeScope = pnodeScopeList; pnodeScope;)
  9027. {
  9028. switch (pnodeScope->nop)
  9029. {
  9030. case knopBlock:
  9031. VisitFunctionsInScope(pnodeScope->sxBlock.pnodeScopes, fn);
  9032. pnodeScope = pnodeScope->sxBlock.pnodeNext;
  9033. break;
  9034. case knopFncDecl:
  9035. fn(pnodeScope);
  9036. pnodeScope = pnodeScope->sxFnc.pnodeNext;
  9037. break;
  9038. case knopCatch:
  9039. VisitFunctionsInScope(pnodeScope->sxCatch.pnodeScopes, fn);
  9040. pnodeScope = pnodeScope->sxCatch.pnodeNext;
  9041. break;
  9042. case knopWith:
  9043. VisitFunctionsInScope(pnodeScope->sxWith.pnodeScopes, fn);
  9044. pnodeScope = pnodeScope->sxWith.pnodeNext;
  9045. break;
  9046. default:
  9047. AssertMsg(false, "Unexpected node with scope list");
  9048. return;
  9049. }
  9050. }
  9051. }
  9052. // Scripts above this size (minus string literals and comments) will have parsing of
  9053. // function bodies deferred.
  9054. ULONG Parser::GetDeferralThreshold(bool isProfileLoaded)
  9055. {
  9056. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  9057. if (CONFIG_FLAG(ForceDeferParse) ||
  9058. PHASE_FORCE1(Js::DeferParsePhase) ||
  9059. Js::Configuration::Global.flags.IsEnabled(Js::ForceUndoDeferFlag))
  9060. {
  9061. return 0;
  9062. }
  9063. else if (Js::Configuration::Global.flags.IsEnabled(Js::DeferParseFlag))
  9064. {
  9065. return Js::Configuration::Global.flags.DeferParse;
  9066. }
  9067. else
  9068. #endif
  9069. {
  9070. if (isProfileLoaded)
  9071. {
  9072. return DEFAULT_CONFIG_ProfileBasedDeferParseThreshold;
  9073. }
  9074. return DEFAULT_CONFIG_DeferParseThreshold;
  9075. }
  9076. }
  9077. void Parser::FinishDeferredFunction(ParseNodePtr pnodeScopeList)
  9078. {
  9079. VisitFunctionsInScope(pnodeScopeList,
  9080. [this](ParseNodePtr pnodeFnc)
  9081. {
  9082. Assert(pnodeFnc->nop == knopFncDecl);
  9083. // Non-simple params (such as default) require a good amount of logic to put vars on appriopriate scopes. ParseFncDecl handles it
  9084. // properly (both on defer and non-defer case). This is to avoid write duplicated logic here as well. Function with non-simple-param
  9085. // will remain deferred untill they are called.
  9086. if (pnodeFnc->sxFnc.pnodeBody == nullptr && !pnodeFnc->sxFnc.HasNonSimpleParameterList())
  9087. {
  9088. // Go back and generate an AST for this function.
  9089. JS_ETW(EventWriteJSCRIPT_PARSE_FUNC(this->GetScriptContext(), pnodeFnc->sxFnc.functionId, /*Undefer*/TRUE));
  9090. ParseNodePtr pnodeFncSave = this->m_currentNodeFunc;
  9091. this->m_currentNodeFunc = pnodeFnc;
  9092. ParseNodePtr pnodeFncExprBlock = nullptr;
  9093. if (pnodeFnc->sxFnc.pnodeName &&
  9094. !pnodeFnc->sxFnc.IsDeclaration())
  9095. {
  9096. // Set up the named function expression symbol so references inside the function can be bound.
  9097. ParseNodePtr pnodeName = pnodeFnc->sxFnc.pnodeName;
  9098. Assert(pnodeName->nop == knopVarDecl);
  9099. Assert(pnodeName->sxVar.pnodeNext == nullptr);
  9100. pnodeFncExprBlock = this->StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FuncExpr);
  9101. PidRefStack *ref = this->PushPidRef(pnodeName->sxVar.pid);
  9102. pnodeName->sxVar.symRef = ref->GetSymRef();
  9103. ref->SetSym(pnodeName->sxVar.sym);
  9104. Scope *fncExprScope = pnodeFncExprBlock->sxBlock.scope;
  9105. fncExprScope->AddNewSymbol(pnodeName->sxVar.sym);
  9106. pnodeFnc->sxFnc.scope = fncExprScope;
  9107. }
  9108. ParseNodePtr pnodeBlock = this->StartParseBlock<true>(PnodeBlockType::Parameter, ScopeType_Parameter);
  9109. pnodeFnc->sxFnc.pnodeScopes = pnodeBlock;
  9110. m_ppnodeScope = &pnodeBlock->sxBlock.pnodeScopes;
  9111. pnodeBlock->sxBlock.pnodeStmt = pnodeFnc;
  9112. // Add the args to the scope, since we won't re-parse those.
  9113. Scope *scope = pnodeBlock->sxBlock.scope;
  9114. auto addArgsToScope = [&](ParseNodePtr pnodeArg) {
  9115. if (pnodeArg->IsVarLetOrConst())
  9116. {
  9117. PidRefStack *ref = this->PushPidRef(pnodeArg->sxVar.pid);
  9118. pnodeArg->sxVar.symRef = ref->GetSymRef();
  9119. if (ref->GetSym() != nullptr)
  9120. {
  9121. // Duplicate parameter in a configuration that allows them.
  9122. // The symbol is already in the scope, just point it to the right declaration.
  9123. Assert(ref->GetSym() == pnodeArg->sxVar.sym);
  9124. ref->GetSym()->SetDecl(pnodeArg);
  9125. }
  9126. else
  9127. {
  9128. ref->SetSym(pnodeArg->sxVar.sym);
  9129. scope->AddNewSymbol(pnodeArg->sxVar.sym);
  9130. }
  9131. }
  9132. };
  9133. MapFormals(pnodeFnc, addArgsToScope);
  9134. MapFormalsFromPattern(pnodeFnc, addArgsToScope);
  9135. ParseNodePtr pnodeInnerBlock = this->StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FunctionBody);
  9136. pnodeFnc->sxFnc.pnodeBodyScope = pnodeInnerBlock;
  9137. // Set the parameter block's child to the function body block.
  9138. *m_ppnodeScope = pnodeInnerBlock;
  9139. ParseNodePtr *ppnodeScopeSave = nullptr;
  9140. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  9141. ppnodeScopeSave = m_ppnodeScope;
  9142. // This synthetic block scope will contain all the nested scopes.
  9143. m_ppnodeScope = &pnodeInnerBlock->sxBlock.pnodeScopes;
  9144. pnodeInnerBlock->sxBlock.pnodeStmt = pnodeFnc;
  9145. // Keep nested function declarations and expressions in the same list at function scope.
  9146. // (Indicate this by nulling out the current function expressions list.)
  9147. ppnodeExprScopeSave = m_ppnodeExprScope;
  9148. m_ppnodeExprScope = nullptr;
  9149. // Shouldn't be any temps in the arg list.
  9150. Assert(*m_ppnodeVar == nullptr);
  9151. // Start the var list.
  9152. pnodeFnc->sxFnc.pnodeVars = nullptr;
  9153. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  9154. if (scope != nullptr && !pnodeFnc->sxFnc.IsAsync())
  9155. {
  9156. if (scope->GetCanMergeWithBodyScope())
  9157. {
  9158. scope->ForEachSymbol([this](Symbol* paramSym)
  9159. {
  9160. PidRefStack* ref = PushPidRef(paramSym->GetPid());
  9161. ref->SetSym(paramSym);
  9162. });
  9163. }
  9164. else
  9165. {
  9166. OUTPUT_TRACE_DEBUGONLY(Js::ParsePhase, _u("The param and body scope of the function %s cannot be merged\n"), pnodeFnc->sxFnc.pnodeName ? pnodeFnc->sxFnc.pnodeName->sxVar.pid->Psz() : _u("Anonymous function"));
  9167. // Add a new symbol reference for each formal in the param scope to the body scope.
  9168. scope->ForEachSymbol([this](Symbol* param) {
  9169. OUTPUT_TRACE_DEBUGONLY(Js::ParsePhase, _u("Creating a duplicate symbol for the parameter %s in the body scope\n"), param->GetPid()->Psz());
  9170. ParseNodePtr paramNode = this->CreateVarDeclNode(param->GetPid(), STVariable, false, nullptr, false);
  9171. Assert(paramNode && paramNode->sxVar.sym->GetScope()->GetScopeType() == ScopeType_FunctionBody);
  9172. paramNode->sxVar.sym->SetHasInit(true);
  9173. });
  9174. }
  9175. }
  9176. Assert(m_currentNodeNonLambdaFunc == nullptr);
  9177. m_currentNodeNonLambdaFunc = pnodeFnc;
  9178. this->FinishFncNode(pnodeFnc);
  9179. Assert(pnodeFnc == m_currentNodeNonLambdaFunc);
  9180. m_currentNodeNonLambdaFunc = nullptr;
  9181. m_ppnodeExprScope = ppnodeExprScopeSave;
  9182. AssertMem(m_ppnodeScope);
  9183. Assert(nullptr == *m_ppnodeScope);
  9184. m_ppnodeScope = ppnodeScopeSave;
  9185. this->FinishParseBlock(pnodeInnerBlock);
  9186. this->AddArgumentsNodeToVars(pnodeFnc);
  9187. this->FinishParseBlock(pnodeBlock);
  9188. if (pnodeFncExprBlock)
  9189. {
  9190. this->FinishParseBlock(pnodeFncExprBlock);
  9191. }
  9192. this->m_currentNodeFunc = pnodeFncSave;
  9193. }
  9194. });
  9195. }
  9196. void Parser::InitPids()
  9197. {
  9198. AssertMemN(m_phtbl);
  9199. wellKnownPropertyPids.arguments = m_phtbl->PidHashNameLen(g_ssym_arguments.sz, g_ssym_arguments.cch);
  9200. wellKnownPropertyPids.async = m_phtbl->PidHashNameLen(g_ssym_async.sz, g_ssym_async.cch);
  9201. wellKnownPropertyPids.eval = m_phtbl->PidHashNameLen(g_ssym_eval.sz, g_ssym_eval.cch);
  9202. wellKnownPropertyPids.get = m_phtbl->PidHashNameLen(g_ssym_get.sz, g_ssym_get.cch);
  9203. wellKnownPropertyPids.set = m_phtbl->PidHashNameLen(g_ssym_set.sz, g_ssym_set.cch);
  9204. wellKnownPropertyPids.let = m_phtbl->PidHashNameLen(g_ssym_let.sz, g_ssym_let.cch);
  9205. wellKnownPropertyPids.constructor = m_phtbl->PidHashNameLen(g_ssym_constructor.sz, g_ssym_constructor.cch);
  9206. wellKnownPropertyPids.prototype = m_phtbl->PidHashNameLen(g_ssym_prototype.sz, g_ssym_prototype.cch);
  9207. wellKnownPropertyPids.__proto__ = m_phtbl->PidHashNameLen(_u("__proto__"), sizeof("__proto__") - 1);
  9208. wellKnownPropertyPids.of = m_phtbl->PidHashNameLen(_u("of"), sizeof("of") - 1);
  9209. wellKnownPropertyPids.target = m_phtbl->PidHashNameLen(_u("target"), sizeof("target") - 1);
  9210. wellKnownPropertyPids.as = m_phtbl->PidHashNameLen(_u("as"), sizeof("as") - 1);
  9211. wellKnownPropertyPids.from = m_phtbl->PidHashNameLen(_u("from"), sizeof("from") - 1);
  9212. wellKnownPropertyPids.default = m_phtbl->PidHashNameLen(_u("default"), sizeof("default") - 1);
  9213. wellKnownPropertyPids._starDefaultStar = m_phtbl->PidHashNameLen(_u("*default*"), sizeof("*default*") - 1);
  9214. wellKnownPropertyPids._star = m_phtbl->PidHashNameLen(_u("*"), sizeof("*") - 1);
  9215. }
  9216. void Parser::RestoreScopeInfo(Js::FunctionBody* functionBody)
  9217. {
  9218. if (!functionBody)
  9219. {
  9220. return;
  9221. }
  9222. Js::ScopeInfo* scopeInfo = functionBody->GetScopeInfo();
  9223. if (!scopeInfo)
  9224. {
  9225. return;
  9226. }
  9227. if (this->IsBackgroundParser())
  9228. {
  9229. PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackByteCodeVisitor);
  9230. }
  9231. else
  9232. {
  9233. PROBE_STACK(m_scriptContext, Js::Constants::MinStackByteCodeVisitor);
  9234. }
  9235. RestoreScopeInfo(scopeInfo->GetParent()); // Recursively restore outer func scope info
  9236. Js::ScopeInfo* funcExprScopeInfo = scopeInfo->GetFuncExprScopeInfo();
  9237. if (funcExprScopeInfo)
  9238. {
  9239. funcExprScopeInfo->SetScopeId(m_nextBlockId);
  9240. ParseNodePtr pnodeFncExprScope = StartParseBlockWithCapacity<true>(PnodeBlockType::Function, ScopeType_FuncExpr, funcExprScopeInfo->GetSymbolCount());
  9241. Scope *scope = pnodeFncExprScope->sxBlock.scope;
  9242. funcExprScopeInfo->GetScopeInfo(this, nullptr, nullptr, scope);
  9243. }
  9244. Js::ScopeInfo* paramScopeInfo = scopeInfo->GetParamScopeInfo();
  9245. if (paramScopeInfo)
  9246. {
  9247. paramScopeInfo->SetScopeId(m_nextBlockId);
  9248. ParseNodePtr pnodeFncExprScope = StartParseBlockWithCapacity<true>(PnodeBlockType::Parameter, ScopeType_Parameter, paramScopeInfo->GetSymbolCount());
  9249. Scope *scope = pnodeFncExprScope->sxBlock.scope;
  9250. paramScopeInfo->GetScopeInfo(this, nullptr, nullptr, scope);
  9251. }
  9252. scopeInfo->SetScopeId(m_nextBlockId);
  9253. ParseNodePtr pnodeFncScope = nullptr;
  9254. if (scopeInfo->IsGlobalEval())
  9255. {
  9256. pnodeFncScope = StartParseBlockWithCapacity<true>(PnodeBlockType::Regular, ScopeType_GlobalEvalBlock, scopeInfo->GetSymbolCount());
  9257. }
  9258. else
  9259. {
  9260. pnodeFncScope = StartParseBlockWithCapacity<true>(PnodeBlockType::Function, ScopeType_FunctionBody, scopeInfo->GetSymbolCount());
  9261. }
  9262. Scope *scope = pnodeFncScope->sxBlock.scope;
  9263. scopeInfo->GetScopeInfo(this, nullptr, nullptr, scope);
  9264. }
  9265. void Parser::FinishScopeInfo(Js::FunctionBody *functionBody)
  9266. {
  9267. if (!functionBody)
  9268. {
  9269. return;
  9270. }
  9271. Js::ScopeInfo* scopeInfo = functionBody->GetScopeInfo();
  9272. if (!scopeInfo)
  9273. {
  9274. return;
  9275. }
  9276. if (this->IsBackgroundParser())
  9277. {
  9278. PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackByteCodeVisitor);
  9279. }
  9280. else
  9281. {
  9282. PROBE_STACK(m_scriptContext, Js::Constants::MinStackByteCodeVisitor);
  9283. }
  9284. int scopeId = scopeInfo->GetScopeId();
  9285. scopeInfo->GetScope()->ForEachSymbol([this, scopeId](Symbol *sym)
  9286. {
  9287. this->BindPidRefsInScope(sym->GetPid(), sym, scopeId);
  9288. });
  9289. PopScope(scopeInfo->GetScope());
  9290. PopStmt(&m_currentBlockInfo->pstmt);
  9291. PopBlockInfo();
  9292. Js::ScopeInfo *paramScopeInfo = scopeInfo->GetParamScopeInfo();
  9293. if (paramScopeInfo)
  9294. {
  9295. scopeId = paramScopeInfo->GetScopeId();
  9296. paramScopeInfo->GetScope()->ForEachSymbol([this, scopeId](Symbol *sym)
  9297. {
  9298. this->BindPidRefsInScope(sym->GetPid(), sym, scopeId);
  9299. });
  9300. PopScope(paramScopeInfo->GetScope());
  9301. PopStmt(&m_currentBlockInfo->pstmt);
  9302. PopBlockInfo();
  9303. }
  9304. Js::ScopeInfo *funcExprScopeInfo = scopeInfo->GetFuncExprScopeInfo();
  9305. if (funcExprScopeInfo)
  9306. {
  9307. scopeId = funcExprScopeInfo->GetScopeId();
  9308. funcExprScopeInfo->GetScope()->ForEachSymbol([this, scopeId](Symbol *sym)
  9309. {
  9310. this->BindPidRefsInScope(sym->GetPid(), sym, scopeId);
  9311. });
  9312. PopScope(funcExprScopeInfo->GetScope());
  9313. PopStmt(&m_currentBlockInfo->pstmt);
  9314. PopBlockInfo();
  9315. }
  9316. FinishScopeInfo(scopeInfo->GetParent());
  9317. }
  9318. /***************************************************************************
  9319. Parse the code.
  9320. ***************************************************************************/
  9321. ParseNodePtr Parser::Parse(LPCUTF8 pszSrc, size_t offset, size_t length, charcount_t charOffset, ULONG grfscr, ULONG lineNumber, Js::LocalFunctionId * nextFunctionId, CompileScriptException *pse)
  9322. {
  9323. ParseNodePtr pnodeProg;
  9324. ParseNodePtr *lastNodeRef = nullptr;
  9325. m_nextBlockId = 0;
  9326. // Scanner should run in Running mode and not syntax coloring mode
  9327. grfscr &= ~fscrSyntaxColor;
  9328. if (this->m_scriptContext->IsScriptContextInDebugMode()
  9329. #ifdef ENABLE_PREJIT
  9330. || Js::Configuration::Global.flags.Prejit
  9331. #endif
  9332. || ((grfscr & fscrNoDeferParse) != 0)
  9333. )
  9334. {
  9335. // Don't do deferred parsing if debugger is attached or feature is disabled
  9336. // by command-line switch.
  9337. grfscr &= ~fscrDeferFncParse;
  9338. }
  9339. else if (!(grfscr & fscrGlobalCode) &&
  9340. (
  9341. PHASE_OFF1(Js::Phase::DeferEventHandlersPhase) ||
  9342. this->m_scriptContext->IsScriptContextInSourceRundownOrDebugMode()
  9343. )
  9344. )
  9345. {
  9346. // Don't defer event handlers in debug/rundown mode, because we need to register the document,
  9347. // so we need to create a full FunctionBody for the script body.
  9348. grfscr &= ~fscrDeferFncParse;
  9349. }
  9350. bool isDeferred = (grfscr & fscrDeferredFnc) != 0;
  9351. bool isModuleSource = (grfscr & fscrIsModuleCode) != 0;
  9352. m_grfscr = grfscr;
  9353. m_length = length;
  9354. m_originalLength = length;
  9355. m_nextFunctionId = nextFunctionId;
  9356. if(m_parseType != ParseType_Deferred)
  9357. {
  9358. JS_ETW(EventWriteJSCRIPT_PARSE_METHOD_START(m_sourceContextInfo->dwHostSourceContext, GetScriptContext(), *m_nextFunctionId, 0, m_parseType, Js::Constants::GlobalFunction));
  9359. OUTPUT_TRACE(Js::DeferParsePhase, _u("Parsing function (%s) : %s (%d)\n"), GetParseType(), Js::Constants::GlobalFunction, *m_nextFunctionId);
  9360. }
  9361. // Give the scanner the source and get the first token
  9362. m_pscan->SetText(pszSrc, offset, length, charOffset, grfscr, lineNumber);
  9363. m_pscan->Scan();
  9364. // Make the main 'knopProg' node
  9365. long initSize = 0;
  9366. m_pCurrentAstSize = &initSize;
  9367. pnodeProg = CreateProgNodeWithScanner(isModuleSource);
  9368. pnodeProg->grfpn = PNodeFlags::fpnNone;
  9369. pnodeProg->sxFnc.pid = nullptr;
  9370. pnodeProg->sxFnc.pnodeName = nullptr;
  9371. pnodeProg->sxFnc.pnodeRest = nullptr;
  9372. pnodeProg->sxFnc.ClearFlags();
  9373. pnodeProg->sxFnc.SetNested(FALSE);
  9374. pnodeProg->sxFnc.astSize = 0;
  9375. pnodeProg->sxFnc.cbMin = m_pscan->IecpMinTok();
  9376. pnodeProg->sxFnc.lineNumber = lineNumber;
  9377. pnodeProg->sxFnc.columnNumber = 0;
  9378. if (!isDeferred || (isDeferred && grfscr & fscrGlobalCode))
  9379. {
  9380. // In the deferred case, if the global function is deferred parse (which is in no-refresh case),
  9381. // we will re-use the same function body, so start with the correct functionId.
  9382. pnodeProg->sxFnc.functionId = (*m_nextFunctionId)++;
  9383. }
  9384. else
  9385. {
  9386. pnodeProg->sxFnc.functionId = Js::Constants::NoFunctionId;
  9387. }
  9388. if (isModuleSource)
  9389. {
  9390. Assert(m_scriptContext->GetConfig()->IsES6ModuleEnabled());
  9391. pnodeProg->sxModule.localExportEntries = nullptr;
  9392. pnodeProg->sxModule.indirectExportEntries = nullptr;
  9393. pnodeProg->sxModule.starExportEntries = nullptr;
  9394. pnodeProg->sxModule.importEntries = nullptr;
  9395. pnodeProg->sxModule.requestedModules = nullptr;
  9396. }
  9397. m_pCurrentAstSize = & (pnodeProg->sxFnc.astSize);
  9398. pnodeProg->sxFnc.hint = nullptr;
  9399. pnodeProg->sxFnc.hintLength = 0;
  9400. pnodeProg->sxFnc.hintOffset = 0;
  9401. pnodeProg->sxFnc.isNameIdentifierRef = true;
  9402. // initialize parsing variables
  9403. pnodeProg->sxFnc.pnodeNext = nullptr;
  9404. m_currentNodeFunc = nullptr;
  9405. m_currentNodeDeferredFunc = nullptr;
  9406. m_currentNodeProg = pnodeProg;
  9407. m_cactIdentToNodeLookup = 1;
  9408. pnodeProg->sxFnc.nestedCount = 0;
  9409. m_pnestedCount = &pnodeProg->sxFnc.nestedCount;
  9410. m_inDeferredNestedFunc = false;
  9411. pnodeProg->sxFnc.pnodeParams = nullptr;
  9412. pnodeProg->sxFnc.pnodeVars = nullptr;
  9413. pnodeProg->sxFnc.pnodeRest = nullptr;
  9414. m_ppnodeVar = &pnodeProg->sxFnc.pnodeVars;
  9415. SetCurrentStatement(nullptr);
  9416. AssertMsg(m_pstmtCur == nullptr, "Statement stack should be empty when we start parse global code");
  9417. // Create block for const's and let's
  9418. ParseNodePtr pnodeGlobalBlock = StartParseBlock<true>(PnodeBlockType::Global, ScopeType_Global);
  9419. pnodeProg->sxProg.scope = pnodeGlobalBlock->sxBlock.scope;
  9420. ParseNodePtr pnodeGlobalEvalBlock = nullptr;
  9421. // Don't track function expressions separately from declarations at global scope.
  9422. m_ppnodeExprScope = nullptr;
  9423. // This synthetic block scope will contain all the nested scopes.
  9424. pnodeProg->sxFnc.pnodeBodyScope = nullptr;
  9425. pnodeProg->sxFnc.pnodeScopes = pnodeGlobalBlock;
  9426. m_ppnodeScope = &pnodeGlobalBlock->sxBlock.pnodeScopes;
  9427. if ((this->m_grfscr & fscrEvalCode) &&
  9428. !(this->m_functionBody && this->m_functionBody->GetScopeInfo()))
  9429. {
  9430. pnodeGlobalEvalBlock = StartParseBlock<true>(PnodeBlockType::Regular, ScopeType_GlobalEvalBlock);
  9431. pnodeProg->sxFnc.pnodeScopes = pnodeGlobalEvalBlock;
  9432. m_ppnodeScope = &pnodeGlobalEvalBlock->sxBlock.pnodeScopes;
  9433. }
  9434. Js::ScopeInfo *scopeInfo = nullptr;
  9435. if (m_parseType == ParseType_Deferred && m_functionBody)
  9436. {
  9437. // this->m_functionBody can be cleared during parsing, but we need access to the scope info later.
  9438. scopeInfo = m_functionBody->GetScopeInfo();
  9439. if (scopeInfo)
  9440. {
  9441. this->RestoreScopeInfo(scopeInfo->GetParent());
  9442. }
  9443. }
  9444. // Process a sequence of statements/declarations
  9445. ParseStmtList<true>(
  9446. &pnodeProg->sxFnc.pnodeBody,
  9447. &lastNodeRef,
  9448. SM_OnGlobalCode,
  9449. !(m_grfscr & fscrDeferredFncExpression) /* isSourceElementList */);
  9450. if (m_parseType == ParseType_Deferred)
  9451. {
  9452. if (scopeInfo)
  9453. {
  9454. this->FinishScopeInfo(scopeInfo->GetParent());
  9455. }
  9456. }
  9457. pnodeProg->sxProg.m_UsesArgumentsAtGlobal = m_UsesArgumentsAtGlobal;
  9458. if (IsStrictMode())
  9459. {
  9460. pnodeProg->sxFnc.SetStrictMode();
  9461. }
  9462. #if DEBUG
  9463. if(m_grfscr & fscrEnforceJSON && !IsJSONValid(pnodeProg->sxFnc.pnodeBody))
  9464. {
  9465. Error(ERRsyntax);
  9466. }
  9467. #endif
  9468. if (tkEOF != m_token.tk)
  9469. Error(ERRsyntax);
  9470. // Append an EndCode node.
  9471. AddToNodeList(&pnodeProg->sxFnc.pnodeBody, &lastNodeRef,
  9472. CreateNodeWithScanner<knopEndCode>());
  9473. AssertMem(lastNodeRef);
  9474. AssertNodeMem(*lastNodeRef);
  9475. Assert((*lastNodeRef)->nop == knopEndCode);
  9476. (*lastNodeRef)->ichMin = 0;
  9477. (*lastNodeRef)->ichLim = 0;
  9478. // Get the extent of the code.
  9479. pnodeProg->ichLim = m_pscan->IchLimTok();
  9480. pnodeProg->sxFnc.cbLim = m_pscan->IecpLimTok();
  9481. // save the temps and terminate the local list
  9482. // NOTE: Eze makes no use of this.
  9483. //pnodeProg->sxFnc.pnodeTmps = *m_ppnodeVar;
  9484. *m_ppnodeVar = nullptr;
  9485. Assert(nullptr == *m_ppnodeScope);
  9486. Assert(nullptr == pnodeProg->sxFnc.pnodeNext);
  9487. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  9488. if (Js::Configuration::Global.flags.IsEnabled(Js::ForceUndoDeferFlag))
  9489. {
  9490. m_stoppedDeferredParse = true;
  9491. }
  9492. #endif
  9493. if (m_stoppedDeferredParse)
  9494. {
  9495. if (this->m_hasParallelJob)
  9496. {
  9497. #if ENABLE_BACKGROUND_PARSING
  9498. BackgroundParser *bgp = static_cast<BackgroundParser*>(m_scriptContext->GetBackgroundParser());
  9499. Assert(bgp);
  9500. this->WaitForBackgroundJobs(bgp, pse);
  9501. #endif
  9502. }
  9503. // Finally, see if there are any function bodies we now want to generate because we
  9504. // decided to stop deferring.
  9505. FinishDeferredFunction(pnodeProg->sxFnc.pnodeScopes);
  9506. }
  9507. if (pnodeGlobalEvalBlock)
  9508. {
  9509. FinishParseBlock(pnodeGlobalEvalBlock);
  9510. }
  9511. // Append block as body of pnodeProg
  9512. FinishParseBlock(pnodeGlobalBlock);
  9513. m_scriptContext->AddSourceSize(m_length);
  9514. if(!m_parseType != ParseType_Deferred)
  9515. {
  9516. JS_ETW(EventWriteJSCRIPT_PARSE_METHOD_STOP(m_sourceContextInfo->dwHostSourceContext, GetScriptContext(), pnodeProg->sxFnc.functionId, *m_pCurrentAstSize, false, Js::Constants::GlobalFunction));
  9517. }
  9518. return pnodeProg;
  9519. }
  9520. bool Parser::CheckForDirective(bool* pIsUseStrict, bool *pIsUseAsm, bool* pIsOctalInString)
  9521. {
  9522. // A directive is a string constant followed by a statement terminating token
  9523. if (m_token.tk != tkStrCon)
  9524. return false;
  9525. // Careful, need to check for octal before calling m_pscan->Scan()
  9526. // because Scan() clears the "had octal" flag on the scanner and
  9527. // m_pscan->Restore() does not restore this flag.
  9528. if (pIsOctalInString != nullptr)
  9529. {
  9530. *pIsOctalInString = m_pscan->IsOctOrLeadingZeroOnLastTKNumber();
  9531. }
  9532. Ident* pidDirective = m_token.GetStr();
  9533. RestorePoint start;
  9534. m_pscan->Capture(&start);
  9535. m_pscan->Scan();
  9536. bool isDirective = true;
  9537. switch (m_token.tk)
  9538. {
  9539. case tkSColon:
  9540. case tkEOF:
  9541. case tkLCurly:
  9542. case tkRCurly:
  9543. break;
  9544. default:
  9545. if (!m_pscan->FHadNewLine())
  9546. {
  9547. isDirective = false;
  9548. }
  9549. break;
  9550. }
  9551. if (isDirective)
  9552. {
  9553. if (pIsUseStrict != nullptr)
  9554. {
  9555. *pIsUseStrict = CheckStrictModeStrPid(pidDirective);
  9556. }
  9557. if (pIsUseAsm != nullptr)
  9558. {
  9559. *pIsUseAsm = CheckAsmjsModeStrPid(pidDirective);
  9560. }
  9561. }
  9562. m_pscan->SeekTo(start);
  9563. return isDirective;
  9564. }
  9565. bool Parser::CheckStrictModeStrPid(IdentPtr pid)
  9566. {
  9567. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  9568. if (Js::Configuration::Global.flags.NoStrictMode)
  9569. return false;
  9570. #endif
  9571. return pid != nullptr &&
  9572. pid->Cch() == 10 &&
  9573. !m_pscan->IsEscapeOnLastTkStrCon() &&
  9574. wcsncmp(pid->Psz(), _u("use strict"), 10) == 0;
  9575. }
  9576. bool Parser::CheckAsmjsModeStrPid(IdentPtr pid)
  9577. {
  9578. #ifdef ASMJS_PLAT
  9579. if (!CONFIG_FLAG_RELEASE(Asmjs))
  9580. {
  9581. return false;
  9582. }
  9583. bool isAsmCandidate = (pid != nullptr &&
  9584. AutoSystemInfo::Data.SSE2Available() &&
  9585. pid->Cch() == 7 &&
  9586. !m_pscan->IsEscapeOnLastTkStrCon() &&
  9587. wcsncmp(pid->Psz(), _u("use asm"), 10) == 0);
  9588. if (isAsmCandidate && m_scriptContext->IsScriptContextInDebugMode())
  9589. {
  9590. // We would like to report this to debugger - they may choose to disable debugging.
  9591. // TODO : localization of the string?
  9592. m_scriptContext->RaiseMessageToDebugger(DEIT_ASMJS_IN_DEBUGGING, _u("AsmJs initialization error - AsmJs disabled due to script debugger"), !m_sourceContextInfo->IsDynamic() ? m_sourceContextInfo->url : nullptr);
  9593. return false;
  9594. }
  9595. return isAsmCandidate && !(m_grfscr & fscrNoAsmJs);
  9596. #else
  9597. return false;
  9598. #endif
  9599. }
  9600. HRESULT Parser::ParseUtf8Source(__out ParseNodePtr* parseTree, LPCUTF8 pSrc, size_t length, ULONG grfsrc, CompileScriptException *pse,
  9601. Js::LocalFunctionId * nextFunctionId, SourceContextInfo * sourceContextInfo)
  9602. {
  9603. m_functionBody = nullptr;
  9604. m_parseType = ParseType_Upfront;
  9605. return ParseSourceInternal( parseTree, pSrc, 0, length, 0, true, grfsrc, pse, nextFunctionId, 0, sourceContextInfo);
  9606. }
  9607. HRESULT Parser::ParseCesu8Source(__out ParseNodePtr* parseTree, LPCUTF8 pSrc, size_t length, ULONG grfsrc, CompileScriptException *pse,
  9608. Js::LocalFunctionId * nextFunctionId, SourceContextInfo * sourceContextInfo)
  9609. {
  9610. m_functionBody = nullptr;
  9611. m_parseType = ParseType_Upfront;
  9612. return ParseSourceInternal( parseTree, pSrc, 0, length, 0, false, grfsrc, pse, nextFunctionId, 0, sourceContextInfo);
  9613. }
  9614. void Parser::PrepareScanner(bool fromExternal)
  9615. {
  9616. // NOTE: HashTbl and Scanner are currently allocated from the CRT heap. If we want to allocate them from the
  9617. // parser arena, then we also need to change the way the HashTbl allocates PID's from its underlying
  9618. // allocator (which also currently uses the CRT heap). This is not trivial, because we still need to support
  9619. // heap allocation for the colorizer interface.
  9620. // create the hash table and init PID members
  9621. if (nullptr == (m_phtbl = HashTbl::Create(HASH_TABLE_SIZE, &m_err)))
  9622. Error(ERRnoMemory);
  9623. InitPids();
  9624. // create the scanner
  9625. if (nullptr == (m_pscan = Scanner_t::Create(this, m_phtbl, &m_token, &m_err, m_scriptContext)))
  9626. Error(ERRnoMemory);
  9627. if (fromExternal)
  9628. m_pscan->FromExternalSource();
  9629. }
  9630. #if ENABLE_BACKGROUND_PARSING
  9631. void Parser::PrepareForBackgroundParse()
  9632. {
  9633. m_pscan->PrepareForBackgroundParse(m_scriptContext);
  9634. }
  9635. void Parser::AddBackgroundParseItem(BackgroundParseItem *const item)
  9636. {
  9637. if (currBackgroundParseItem == nullptr)
  9638. {
  9639. backgroundParseItems = item;
  9640. }
  9641. else
  9642. {
  9643. currBackgroundParseItem->SetNext(item);
  9644. }
  9645. currBackgroundParseItem = item;
  9646. }
  9647. #endif
  9648. void Parser::AddFastScannedRegExpNode(ParseNodePtr const pnode)
  9649. {
  9650. Assert(!IsBackgroundParser());
  9651. Assert(m_doingFastScan);
  9652. if (fastScannedRegExpNodes == nullptr)
  9653. {
  9654. fastScannedRegExpNodes = Anew(&m_nodeAllocator, NodeDList, &m_nodeAllocator);
  9655. }
  9656. fastScannedRegExpNodes->Append(pnode);
  9657. }
  9658. #if ENABLE_BACKGROUND_PARSING
  9659. void Parser::AddBackgroundRegExpNode(ParseNodePtr const pnode)
  9660. {
  9661. Assert(IsBackgroundParser());
  9662. Assert(currBackgroundParseItem != nullptr);
  9663. currBackgroundParseItem->AddRegExpNode(pnode, &m_nodeAllocator);
  9664. }
  9665. #endif
  9666. HRESULT Parser::ParseFunctionInBackground(ParseNodePtr pnodeFnc, ParseContext *parseContext, bool topLevelDeferred, CompileScriptException *pse)
  9667. {
  9668. m_functionBody = nullptr;
  9669. m_parseType = ParseType_Upfront;
  9670. HRESULT hr = S_OK;
  9671. SmartFPUControl smartFpuControl;
  9672. uint nextFunctionId = pnodeFnc->sxFnc.functionId + 1;
  9673. this->RestoreContext(parseContext);
  9674. DebugOnly( m_err.fInited = TRUE; )
  9675. m_nextFunctionId = &nextFunctionId;
  9676. m_deferringAST = topLevelDeferred;
  9677. m_inDeferredNestedFunc = false;
  9678. m_scopeCountNoAst = 0;
  9679. SetCurrentStatement(nullptr);
  9680. pnodeFnc->sxFnc.pnodeVars = nullptr;
  9681. pnodeFnc->sxFnc.pnodeParams = nullptr;
  9682. pnodeFnc->sxFnc.pnodeBody = nullptr;
  9683. pnodeFnc->sxFnc.nestedCount = 0;
  9684. m_currentNodeFunc = pnodeFnc;
  9685. m_currentNodeDeferredFunc = nullptr;
  9686. m_ppnodeScope = nullptr;
  9687. m_ppnodeExprScope = nullptr;
  9688. m_pnestedCount = &pnodeFnc->sxFnc.nestedCount;
  9689. m_pCurrentAstSize = &pnodeFnc->sxFnc.astSize;
  9690. ParseNodePtr pnodeBlock = StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FunctionBody);
  9691. pnodeFnc->sxFnc.pnodeScopes = pnodeBlock;
  9692. m_ppnodeScope = &pnodeBlock->sxBlock.pnodeScopes;
  9693. uint uDeferSave = m_grfscr & fscrDeferFncParse;
  9694. try
  9695. {
  9696. m_pscan->Scan();
  9697. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeParams;
  9698. this->ParseFncFormals<true>(pnodeFnc, fFncNoFlgs);
  9699. if (m_token.tk == tkRParen)
  9700. {
  9701. m_pscan->Scan();
  9702. }
  9703. ChkCurTok(tkLCurly, ERRnoLcurly);
  9704. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  9705. // Put the scanner into "no hashing" mode.
  9706. BYTE deferFlags = m_pscan->SetDeferredParse(topLevelDeferred);
  9707. // Process a sequence of statements/declarations
  9708. if (topLevelDeferred)
  9709. {
  9710. ParseStmtList<false>(nullptr, nullptr, SM_DeferredParse, true);
  9711. }
  9712. else
  9713. {
  9714. ParseNodePtr *lastNodeRef = nullptr;
  9715. ParseStmtList<true>(&pnodeFnc->sxFnc.pnodeBody, &lastNodeRef, SM_OnFunctionCode, true);
  9716. AddArgumentsNodeToVars(pnodeFnc);
  9717. // Append an EndCode node.
  9718. AddToNodeList(&pnodeFnc->sxFnc.pnodeBody, &lastNodeRef, CreateNodeWithScanner<knopEndCode>());
  9719. }
  9720. // Restore the scanner's default hashing mode.
  9721. m_pscan->SetDeferredParseFlags(deferFlags);
  9722. #if DBG
  9723. pnodeFnc->sxFnc.deferredParseNextFunctionId = *this->m_nextFunctionId;
  9724. #endif
  9725. this->m_deferringAST = FALSE;
  9726. // Append block as body of pnodeProg
  9727. FinishParseBlock(pnodeBlock);
  9728. }
  9729. catch(ParseExceptionObject& e)
  9730. {
  9731. m_err.m_hr = e.GetError();
  9732. hr = pse->ProcessError( m_pscan, m_err.m_hr, nullptr);
  9733. }
  9734. if (IsStrictMode())
  9735. {
  9736. pnodeFnc->sxFnc.SetStrictMode();
  9737. }
  9738. if (topLevelDeferred)
  9739. {
  9740. pnodeFnc->sxFnc.pnodeVars = nullptr;
  9741. }
  9742. m_grfscr |= uDeferSave;
  9743. Assert(nullptr == *m_ppnodeScope);
  9744. return hr;
  9745. }
  9746. HRESULT Parser::ParseSourceWithOffset(__out ParseNodePtr* parseTree, LPCUTF8 pSrc, size_t offset, size_t cbLength, charcount_t cchOffset,
  9747. bool isCesu8, ULONG grfscr, CompileScriptException *pse, Js::LocalFunctionId * nextFunctionId, ULONG lineNumber, SourceContextInfo * sourceContextInfo,
  9748. Js::ParseableFunctionInfo* functionInfo)
  9749. {
  9750. m_functionBody = functionInfo;
  9751. if (m_functionBody)
  9752. {
  9753. m_currDeferredStub = m_functionBody->GetDeferredStubs();
  9754. m_InAsmMode = grfscr & fscrNoAsmJs ? false : m_functionBody->GetIsAsmjsMode();
  9755. }
  9756. m_deferAsmJs = !m_InAsmMode;
  9757. m_parseType = ParseType_Deferred;
  9758. return ParseSourceInternal( parseTree, pSrc, offset, cbLength, cchOffset, !isCesu8, grfscr, pse, nextFunctionId, lineNumber, sourceContextInfo);
  9759. }
  9760. bool Parser::IsStrictMode() const
  9761. {
  9762. return (m_fUseStrictMode ||
  9763. (m_currentNodeFunc != nullptr && m_currentNodeFunc->sxFnc.GetStrictMode()));
  9764. }
  9765. BOOL Parser::ExpectingExternalSource()
  9766. {
  9767. return m_fExpectExternalSource;
  9768. }
  9769. Symbol *PnFnc::GetFuncSymbol()
  9770. {
  9771. if (pnodeName &&
  9772. pnodeName->nop == knopVarDecl)
  9773. {
  9774. return pnodeName->sxVar.sym;
  9775. }
  9776. return nullptr;
  9777. }
  9778. void PnFnc::SetFuncSymbol(Symbol *sym)
  9779. {
  9780. Assert(pnodeName &&
  9781. pnodeName->nop == knopVarDecl);
  9782. pnodeName->sxVar.sym = sym;
  9783. }
  9784. ParseNodePtr PnFnc::GetParamScope() const
  9785. {
  9786. if (this->pnodeScopes == nullptr)
  9787. {
  9788. return nullptr;
  9789. }
  9790. Assert(this->pnodeScopes->nop == knopBlock &&
  9791. this->pnodeScopes->sxBlock.pnodeNext == nullptr);
  9792. return this->pnodeScopes->sxBlock.pnodeScopes;
  9793. }
  9794. ParseNodePtr PnFnc::GetBodyScope() const
  9795. {
  9796. if (this->pnodeBodyScope == nullptr)
  9797. {
  9798. return nullptr;
  9799. }
  9800. Assert(this->pnodeBodyScope->nop == knopBlock &&
  9801. this->pnodeBodyScope->sxBlock.pnodeNext == nullptr);
  9802. return this->pnodeBodyScope->sxBlock.pnodeScopes;
  9803. }
  9804. // Create node versions with explicit token limits
  9805. ParseNodePtr Parser::CreateNode(OpCode nop, charcount_t ichMin, charcount_t ichLim)
  9806. {
  9807. Assert(!this->m_deferringAST);
  9808. Assert(nop >= 0 && nop < knopLim);
  9809. ParseNodePtr pnode;
  9810. __analysis_assume(nop < knopLim);
  9811. int cb = nop >= 0 && nop < knopLim ? g_mpnopcbNode[nop] : kcbPnNone;
  9812. pnode = (ParseNodePtr)m_nodeAllocator.Alloc(cb);
  9813. Assert(pnode);
  9814. Assert(m_pCurrentAstSize != NULL);
  9815. *m_pCurrentAstSize += cb;
  9816. InitNode(nop,pnode);
  9817. pnode->ichMin = ichMin;
  9818. pnode->ichLim = ichLim;
  9819. return pnode;
  9820. }
  9821. ParseNodePtr Parser::CreateNameNode(IdentPtr pid,charcount_t ichMin,charcount_t ichLim) {
  9822. ParseNodePtr pnode = CreateNodeT<knopName>(ichMin,ichLim);
  9823. pnode->sxPid.pid = pid;
  9824. pnode->sxPid.sym=NULL;
  9825. pnode->sxPid.symRef=NULL;
  9826. return pnode;
  9827. }
  9828. ParseNodePtr Parser::CreateUniNode(OpCode nop, ParseNodePtr pnode1, charcount_t ichMin,charcount_t ichLim)
  9829. {
  9830. Assert(!this->m_deferringAST);
  9831. DebugOnly(VerifyNodeSize(nop, kcbPnUni));
  9832. ParseNodePtr pnode = (ParseNodePtr)m_nodeAllocator.Alloc(kcbPnUni);
  9833. Assert(m_pCurrentAstSize != NULL);
  9834. *m_pCurrentAstSize += kcbPnUni;
  9835. InitNode(nop, pnode);
  9836. pnode->sxUni.pnode1 = pnode1;
  9837. pnode->ichMin = ichMin;
  9838. pnode->ichLim = ichLim;
  9839. return pnode;
  9840. }
  9841. ParseNodePtr Parser::CreateBinNode(OpCode nop, ParseNodePtr pnode1,
  9842. ParseNodePtr pnode2,charcount_t ichMin,charcount_t ichLim)
  9843. {
  9844. Assert(!this->m_deferringAST);
  9845. ParseNodePtr pnode = StaticCreateBinNode(nop, pnode1, pnode2, &m_nodeAllocator);
  9846. Assert(m_pCurrentAstSize != NULL);
  9847. *m_pCurrentAstSize += kcbPnBin;
  9848. pnode->ichMin = ichMin;
  9849. pnode->ichLim = ichLim;
  9850. return pnode;
  9851. }
  9852. ParseNodePtr Parser::CreateTriNode(OpCode nop, ParseNodePtr pnode1,
  9853. ParseNodePtr pnode2, ParseNodePtr pnode3,
  9854. charcount_t ichMin,charcount_t ichLim)
  9855. {
  9856. Assert(!this->m_deferringAST);
  9857. DebugOnly(VerifyNodeSize(nop, kcbPnTri));
  9858. ParseNodePtr pnode = (ParseNodePtr)m_nodeAllocator.Alloc(kcbPnTri);
  9859. Assert(m_pCurrentAstSize != NULL);
  9860. *m_pCurrentAstSize += kcbPnTri;
  9861. InitNode(nop, pnode);
  9862. pnode->sxTri.pnodeNext = NULL;
  9863. pnode->sxTri.pnode1 = pnode1;
  9864. pnode->sxTri.pnode2 = pnode2;
  9865. pnode->sxTri.pnode3 = pnode3;
  9866. pnode->ichMin = ichMin;
  9867. pnode->ichLim = ichLim;
  9868. return pnode;
  9869. }
  9870. bool PnBlock::HasBlockScopedContent() const
  9871. {
  9872. // A block has its own content if a let, const, or function is declared there.
  9873. if (this->pnodeLexVars != nullptr || this->blockType == Parameter)
  9874. {
  9875. return true;
  9876. }
  9877. // The enclosing scopes can contain functions and other things, so walk the list
  9878. // looking specifically for functions.
  9879. for (ParseNodePtr pnode = this->pnodeScopes; pnode;)
  9880. {
  9881. switch (pnode->nop) {
  9882. case knopFncDecl:
  9883. return true;
  9884. case knopBlock:
  9885. pnode = pnode->sxBlock.pnodeNext;
  9886. break;
  9887. case knopCatch:
  9888. pnode = pnode->sxCatch.pnodeNext;
  9889. break;
  9890. case knopWith:
  9891. pnode = pnode->sxWith.pnodeNext;
  9892. break;
  9893. default:
  9894. Assert(UNREACHED);
  9895. return true;
  9896. }
  9897. }
  9898. return false;
  9899. }
  9900. class ByteCodeGenerator;
  9901. // Copy AST; this works mostly on expressions for now
  9902. ParseNode* Parser::CopyPnode(ParseNode *pnode) {
  9903. if (pnode==NULL)
  9904. return NULL;
  9905. switch (pnode->nop) {
  9906. //PTNODE(knopName , "name" ,None ,Pid ,fnopLeaf)
  9907. case knopName: {
  9908. ParseNode* nameNode=CreateNameNode(pnode->sxPid.pid,pnode->ichMin,pnode->ichLim);
  9909. nameNode->sxPid.sym=pnode->sxPid.sym;
  9910. return nameNode;
  9911. }
  9912. //PTNODE(knopInt , "int const" ,None ,Int ,fnopLeaf|fnopConst)
  9913. case knopInt:
  9914. return pnode;
  9915. //PTNODE(knopFlt , "flt const" ,None ,Flt ,fnopLeaf|fnopConst)
  9916. case knopFlt:
  9917. return pnode;
  9918. //PTNODE(knopStr , "str const" ,None ,Pid ,fnopLeaf|fnopConst)
  9919. case knopStr:
  9920. return pnode;
  9921. //PTNODE(knopRegExp , "reg expr" ,None ,Pid ,fnopLeaf|fnopConst)
  9922. case knopRegExp:
  9923. return pnode;
  9924. break;
  9925. //PTNODE(knopThis , "this" ,None ,None ,fnopLeaf)
  9926. case knopThis:
  9927. return CreateNodeT<knopThis>(pnode->ichMin,pnode->ichLim);
  9928. //PTNODE(knopNull , "null" ,Null ,None ,fnopLeaf)
  9929. case knopNull:
  9930. return pnode;
  9931. //PTNODE(knopFalse , "false" ,False ,None ,fnopLeaf)
  9932. case knopFalse:
  9933. return CreateNodeT<knopFalse>(pnode->ichMin,pnode->ichLim);
  9934. break;
  9935. //PTNODE(knopTrue , "true" ,True ,None ,fnopLeaf)
  9936. case knopTrue:
  9937. return CreateNodeT<knopTrue>(pnode->ichMin,pnode->ichLim);
  9938. //PTNODE(knopEmpty , "empty" ,Empty ,None ,fnopLeaf)
  9939. case knopEmpty:
  9940. return CreateNodeT<knopEmpty>(pnode->ichMin,pnode->ichLim);
  9941. // Unary operators.
  9942. //PTNODE(knopNot , "~" ,BitNot ,Uni ,fnopUni)
  9943. //PTNODE(knopNeg , "unary -" ,Neg ,Uni ,fnopUni)
  9944. //PTNODE(knopPos , "unary +" ,Pos ,Uni ,fnopUni)
  9945. //PTNODE(knopLogNot , "!" ,LogNot ,Uni ,fnopUni)
  9946. //PTNODE(knopEllipsis , "..." ,Spread ,Uni , fnopUni)
  9947. //PTNODE(knopDecPost , "-- post" ,Dec ,Uni ,fnopUni|fnopAsg)
  9948. //PTNODE(knopIncPre , "++ pre" ,Inc ,Uni ,fnopUni|fnopAsg)
  9949. //PTNODE(knopDecPre , "-- pre" ,Dec ,Uni ,fnopUni|fnopAsg)
  9950. //PTNODE(knopTypeof , "typeof" ,None ,Uni ,fnopUni)
  9951. //PTNODE(knopVoid , "void" ,Void ,Uni ,fnopUni)
  9952. //PTNODE(knopDelete , "delete" ,None ,Uni ,fnopUni)
  9953. case knopNot:
  9954. case knopNeg:
  9955. case knopPos:
  9956. case knopLogNot:
  9957. case knopEllipsis:
  9958. case knopIncPost:
  9959. case knopDecPost:
  9960. case knopIncPre:
  9961. case knopDecPre:
  9962. case knopTypeof:
  9963. case knopVoid:
  9964. case knopDelete:
  9965. return CreateUniNode(pnode->nop,CopyPnode(pnode->sxUni.pnode1),pnode->ichMin,pnode->ichLim);
  9966. //PTNODE(knopArray , "arr cnst" ,None ,Uni ,fnopUni)
  9967. //PTNODE(knopObject , "obj cnst" ,None ,Uni ,fnopUni)
  9968. case knopArray:
  9969. case knopObject:
  9970. // TODO: need to copy arr
  9971. Assert(false);
  9972. break;
  9973. // Binary operators
  9974. //PTNODE(knopAdd , "+" ,Add ,Bin ,fnopBin)
  9975. //PTNODE(knopSub , "-" ,Sub ,Bin ,fnopBin)
  9976. //PTNODE(knopMul , "*" ,Mul ,Bin ,fnopBin)
  9977. //PTNODE(knopExpo , "**" ,Expo ,Bin ,fnopBin)
  9978. //PTNODE(knopDiv , "/" ,Div ,Bin ,fnopBin)
  9979. //PTNODE(knopMod , "%" ,Mod ,Bin ,fnopBin)
  9980. //PTNODE(knopOr , "|" ,BitOr ,Bin ,fnopBin)
  9981. //PTNODE(knopXor , "^" ,BitXor ,Bin ,fnopBin)
  9982. //PTNODE(knopAnd , "&" ,BitAnd ,Bin ,fnopBin)
  9983. //PTNODE(knopEq , "==" ,EQ ,Bin ,fnopBin|fnopRel)
  9984. //PTNODE(knopNe , "!=" ,NE ,Bin ,fnopBin|fnopRel)
  9985. //PTNODE(knopLt , "<" ,LT ,Bin ,fnopBin|fnopRel)
  9986. //PTNODE(knopLe , "<=" ,LE ,Bin ,fnopBin|fnopRel)
  9987. //PTNODE(knopGe , ">=" ,GE ,Bin ,fnopBin|fnopRel)
  9988. //PTNODE(knopGt , ">" ,GT ,Bin ,fnopBin|fnopRel)
  9989. //PTNODE(knopEqv , "===" ,Eqv ,Bin ,fnopBin|fnopRel)
  9990. //PTNODE(knopIn , "in" ,In ,Bin ,fnopBin|fnopRel)
  9991. //PTNODE(knopInstOf , "instanceof",InstOf ,Bin ,fnopBin|fnopRel)
  9992. //PTNODE(knopNEqv , "!==" ,NEqv ,Bin ,fnopBin|fnopRel)
  9993. //PTNODE(knopComma , "," ,None ,Bin ,fnopBin)
  9994. //PTNODE(knopLogOr , "||" ,None ,Bin ,fnopBin)
  9995. //PTNODE(knopLogAnd , "&&" ,None ,Bin ,fnopBin)
  9996. //PTNODE(knopLsh , "<<" ,Lsh ,Bin ,fnopBin)
  9997. //PTNODE(knopRsh , ">>" ,Rsh ,Bin ,fnopBin)
  9998. //PTNODE(knopRs2 , ">>>" ,Rs2 ,Bin ,fnopBin)
  9999. case knopAdd:
  10000. case knopSub:
  10001. case knopMul:
  10002. case knopExpo:
  10003. case knopDiv:
  10004. case knopMod:
  10005. case knopOr:
  10006. case knopXor:
  10007. case knopAnd:
  10008. case knopEq:
  10009. case knopNe:
  10010. case knopLt:
  10011. case knopLe:
  10012. case knopGe:
  10013. case knopGt:
  10014. case knopEqv:
  10015. case knopIn:
  10016. case knopInstOf:
  10017. case knopNEqv:
  10018. case knopComma:
  10019. case knopLogOr:
  10020. case knopLogAnd:
  10021. case knopLsh:
  10022. case knopRsh:
  10023. case knopRs2:
  10024. //PTNODE(knopAsg , "=" ,None ,Bin ,fnopBin|fnopAsg)
  10025. case knopAsg:
  10026. //PTNODE(knopDot , "." ,None ,Bin ,fnopBin)
  10027. case knopDot:
  10028. //PTNODE(knopAsgAdd , "+=" ,Add ,Bin ,fnopBin|fnopAsg)
  10029. case knopAsgAdd:
  10030. //PTNODE(knopAsgSub , "-=" ,Sub ,Bin ,fnopBin|fnopAsg)
  10031. case knopAsgSub:
  10032. //PTNODE(knopAsgMul , "*=" ,Mul ,Bin ,fnopBin|fnopAsg)
  10033. case knopAsgMul:
  10034. //PTNODE(knopAsgDiv , "/=" ,Div ,Bin ,fnopBin|fnopAsg)
  10035. case knopAsgExpo:
  10036. //PTNODE(knopAsgExpo , "**=" ,Expo ,Bin ,fnopBin|fnopAsg)
  10037. case knopAsgDiv:
  10038. //PTNODE(knopAsgMod , "%=" ,Mod ,Bin ,fnopBin|fnopAsg)
  10039. case knopAsgMod:
  10040. //PTNODE(knopAsgAnd , "&=" ,BitAnd ,Bin ,fnopBin|fnopAsg)
  10041. case knopAsgAnd:
  10042. //PTNODE(knopAsgXor , "^=" ,BitXor ,Bin ,fnopBin|fnopAsg)
  10043. case knopAsgXor:
  10044. //PTNODE(knopAsgOr , "|=" ,BitOr ,Bin ,fnopBin|fnopAsg)
  10045. case knopAsgOr:
  10046. //PTNODE(knopAsgLsh , "<<=" ,Lsh ,Bin ,fnopBin|fnopAsg)
  10047. case knopAsgLsh:
  10048. //PTNODE(knopAsgRsh , ">>=" ,Rsh ,Bin ,fnopBin|fnopAsg)
  10049. case knopAsgRsh:
  10050. //PTNODE(knopAsgRs2 , ">>>=" ,Rs2 ,Bin ,fnopBin|fnopAsg)
  10051. case knopAsgRs2:
  10052. //PTNODE(knopMember , ":" ,None ,Bin ,fnopBin)
  10053. case knopMember:
  10054. case knopMemberShort:
  10055. //PTNODE(knopIndex , "[]" ,None ,Bin ,fnopBin)
  10056. //PTNODE(knopList , "<list>" ,None ,Bin ,fnopNone)
  10057. case knopIndex:
  10058. case knopList:
  10059. return CreateBinNode(pnode->nop,CopyPnode(pnode->sxBin.pnode1),
  10060. CopyPnode(pnode->sxBin.pnode2),pnode->ichMin,pnode->ichLim);
  10061. //PTNODE(knopCall , "()" ,None ,Bin ,fnopBin)
  10062. //PTNODE(knopNew , "new" ,None ,Bin ,fnopBin)
  10063. case knopNew:
  10064. case knopCall:
  10065. return CreateCallNode(pnode->nop,CopyPnode(pnode->sxBin.pnode1),
  10066. CopyPnode(pnode->sxBin.pnode2),pnode->ichMin,pnode->ichLim);
  10067. //PTNODE(knopQmark , "?" ,None ,Tri ,fnopBin)
  10068. case knopQmark:
  10069. return CreateTriNode(pnode->nop,CopyPnode(pnode->sxTri.pnode1),
  10070. CopyPnode(pnode->sxTri.pnode2),CopyPnode(pnode->sxTri.pnode3),
  10071. pnode->ichMin,pnode->ichLim);
  10072. // General nodes.
  10073. //PTNODE(knopVarDecl , "varDcl" ,None ,Var ,fnopNone)
  10074. case knopVarDecl: {
  10075. ParseNode* copyNode=CreateNodeT<knopVarDecl>(pnode->ichMin,pnode->ichLim);
  10076. copyNode->sxVar.pnodeInit=CopyPnode(pnode->sxVar.pnodeInit);
  10077. copyNode->sxVar.sym=pnode->sxVar.sym;
  10078. // TODO: mult-decl
  10079. Assert(pnode->sxVar.pnodeNext==NULL);
  10080. copyNode->sxVar.pnodeNext=NULL;
  10081. return copyNode;
  10082. }
  10083. //PTNODE(knopFncDecl , "fncDcl" ,None ,Fnc ,fnopLeaf)
  10084. //PTNODE(knopProg , "program" ,None ,Fnc ,fnopNone)
  10085. case knopFncDecl:
  10086. case knopProg:
  10087. Assert(false);
  10088. break;
  10089. //PTNODE(knopEndCode , "<endcode>" ,None ,None ,fnopNone)
  10090. case knopEndCode:
  10091. break;
  10092. //PTNODE(knopDebugger , "debugger" ,None ,None ,fnopNone)
  10093. case knopDebugger:
  10094. break;
  10095. //PTNODE(knopFor , "for" ,None ,For ,fnopBreak|fnopContinue)
  10096. case knopFor: {
  10097. ParseNode* copyNode=CreateNodeT<knopFor>(pnode->ichMin,pnode->ichLim);
  10098. copyNode->sxFor.pnodeInverted=NULL;
  10099. copyNode->sxFor.pnodeInit=CopyPnode(pnode->sxFor.pnodeInit);
  10100. copyNode->sxFor.pnodeCond=CopyPnode(pnode->sxFor.pnodeCond);
  10101. copyNode->sxFor.pnodeIncr=CopyPnode(pnode->sxFor.pnodeIncr);
  10102. copyNode->sxFor.pnodeBody=CopyPnode(pnode->sxFor.pnodeBody);
  10103. return copyNode;
  10104. }
  10105. //PTNODE(knopIf , "if" ,None ,If ,fnopNone)
  10106. case knopIf:
  10107. Assert(false);
  10108. break;
  10109. //PTNODE(knopWhile , "while" ,None ,While,fnopBreak|fnopContinue)
  10110. case knopWhile:
  10111. Assert(false);
  10112. break;
  10113. //PTNODE(knopDoWhile , "do-while" ,None ,While,fnopBreak|fnopContinue)
  10114. case knopDoWhile:
  10115. Assert(false);
  10116. break;
  10117. //PTNODE(knopForIn , "for in" ,None ,ForIn,fnopBreak|fnopContinue|fnopCleanup)
  10118. case knopForIn:
  10119. Assert(false);
  10120. break;
  10121. case knopForOf:
  10122. Assert(false);
  10123. break;
  10124. //PTNODE(knopReturn , "return" ,None ,Uni ,fnopNone)
  10125. case knopReturn: {
  10126. ParseNode* copyNode=CreateNodeT<knopReturn>(pnode->ichMin,pnode->ichLim);
  10127. copyNode->sxReturn.pnodeExpr=CopyPnode(pnode->sxReturn.pnodeExpr);
  10128. return copyNode;
  10129. }
  10130. //PTNODE(knopBlock , "{}" ,None ,Block,fnopNone)
  10131. case knopBlock: {
  10132. ParseNode* copyNode=CreateBlockNode(pnode->ichMin,pnode->ichLim,pnode->sxBlock.blockType);
  10133. if (pnode->grfpn & PNodeFlags::fpnSyntheticNode) {
  10134. // fpnSyntheticNode is sometimes set on PnodeBlockType::Regular blocks which
  10135. // CreateBlockNode() will not automatically set for us, so set it here if it's
  10136. // specified on the source node.
  10137. copyNode->grfpn |= PNodeFlags::fpnSyntheticNode;
  10138. }
  10139. copyNode->sxBlock.pnodeStmt=CopyPnode(pnode->sxBlock.pnodeStmt);
  10140. return copyNode;
  10141. }
  10142. //PTNODE(knopWith , "with" ,None ,With ,fnopCleanup)
  10143. case knopWith:
  10144. Assert(false);
  10145. break;
  10146. //PTNODE(knopBreak , "break" ,None ,Jump ,fnopNone)
  10147. case knopBreak:
  10148. Assert(false);
  10149. break;
  10150. //PTNODE(knopContinue , "continue" ,None ,Jump ,fnopNone)
  10151. case knopContinue:
  10152. Assert(false);
  10153. break;
  10154. //PTNODE(knopLabel , "label" ,None ,Label,fnopNone)
  10155. case knopLabel:
  10156. Assert(false);
  10157. break;
  10158. //PTNODE(knopSwitch , "switch" ,None ,Switch,fnopBreak)
  10159. case knopSwitch:
  10160. Assert(false);
  10161. break;
  10162. //PTNODE(knopCase , "case" ,None ,Case ,fnopNone)
  10163. case knopCase:
  10164. Assert(false);
  10165. break;
  10166. //PTNODE(knopTryFinally,"try-finally",None,TryFinally,fnopCleanup)
  10167. case knopTryFinally:
  10168. Assert(false);
  10169. break;
  10170. case knopFinally:
  10171. Assert(false);
  10172. break;
  10173. //PTNODE(knopCatch , "catch" ,None ,Catch,fnopNone)
  10174. case knopCatch:
  10175. Assert(false);
  10176. break;
  10177. //PTNODE(knopTryCatch , "try-catch" ,None ,TryCatch ,fnopCleanup)
  10178. case knopTryCatch:
  10179. Assert(false);
  10180. break;
  10181. //PTNODE(knopTry , "try" ,None ,Try ,fnopCleanup)
  10182. case knopTry:
  10183. Assert(false);
  10184. break;
  10185. //PTNODE(knopThrow , "throw" ,None ,Uni ,fnopNone)
  10186. case knopThrow:
  10187. Assert(false);
  10188. break;
  10189. default:
  10190. Assert(false);
  10191. break;
  10192. }
  10193. return NULL;
  10194. }
  10195. // Returns true when str is string for Nan, Infinity or -Infinity.
  10196. // Does not check for double number value being in NaN/Infinity range.
  10197. // static
  10198. template<bool CheckForNegativeInfinity>
  10199. inline bool Parser::IsNaNOrInfinityLiteral(LPCOLESTR str)
  10200. {
  10201. // Note: wcscmp crashes when one of the parameters is NULL.
  10202. return str &&
  10203. (wcscmp(_u("NaN"), str) == 0 ||
  10204. wcscmp(_u("Infinity"), str) == 0 ||
  10205. CheckForNegativeInfinity && wcscmp(_u("-Infinity"), str) == 0);
  10206. }
  10207. template <bool buildAST>
  10208. ParseNodePtr Parser::ParseSuper(ParseNodePtr pnode, bool fAllowCall)
  10209. {
  10210. ParseNodePtr currentNodeFunc = GetCurrentFunctionNode();
  10211. if (buildAST) {
  10212. pnode = CreateNodeWithScanner<knopSuper>();
  10213. }
  10214. m_pscan->ScanForcingPid();
  10215. switch (m_token.tk)
  10216. {
  10217. case tkDot: // super.prop
  10218. case tkLBrack: // super[foo]
  10219. case tkLParen: // super(args)
  10220. break;
  10221. default:
  10222. Error(ERRInvalidSuper);
  10223. break;
  10224. }
  10225. if (!fAllowCall && (m_token.tk == tkLParen))
  10226. {
  10227. Error(ERRInvalidSuper); // new super() is not allowed
  10228. }
  10229. else if (this->m_parsingSuperRestrictionState == ParsingSuperRestrictionState_SuperCallAndPropertyAllowed)
  10230. {
  10231. // Any super access is good within a class constructor
  10232. }
  10233. else if (this->m_parsingSuperRestrictionState == ParsingSuperRestrictionState_SuperPropertyAllowed)
  10234. {
  10235. // Cannot call super within a class member
  10236. if (m_token.tk == tkLParen)
  10237. {
  10238. Error(ERRInvalidSuper);
  10239. }
  10240. }
  10241. else
  10242. {
  10243. // Anything else is an error
  10244. Error(ERRInvalidSuper);
  10245. }
  10246. currentNodeFunc->sxFnc.SetHasSuperReference(TRUE);
  10247. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(SuperCount, m_scriptContext);
  10248. return pnode;
  10249. }
  10250. void Parser::AppendToList(ParseNodePtr *node, ParseNodePtr nodeToAppend)
  10251. {
  10252. Assert(nodeToAppend);
  10253. ParseNodePtr* lastPtr = node;
  10254. while ((*lastPtr) && (*lastPtr)->nop == knopList)
  10255. {
  10256. lastPtr = &(*lastPtr)->sxBin.pnode2;
  10257. }
  10258. auto last = (*lastPtr);
  10259. if (last)
  10260. {
  10261. *lastPtr = CreateBinNode(knopList, last, nodeToAppend, last->ichMin, nodeToAppend->ichLim);
  10262. }
  10263. else
  10264. {
  10265. *lastPtr = nodeToAppend;
  10266. }
  10267. }
  10268. ParseNodePtr Parser::ConvertArrayToArrayPattern(ParseNodePtr pnode)
  10269. {
  10270. Assert(pnode->nop == knopArray);
  10271. pnode->nop = knopArrayPattern;
  10272. ForEachItemRefInList(&pnode->sxArrLit.pnode1, [&](ParseNodePtr *itemRef) {
  10273. ParseNodePtr item = *itemRef;
  10274. if (item->nop == knopEllipsis)
  10275. {
  10276. itemRef = &item->sxUni.pnode1;
  10277. item = *itemRef;
  10278. if (!(item->nop == knopName
  10279. || item->nop == knopDot
  10280. || item->nop == knopIndex
  10281. || item->nop == knopArray
  10282. || item->nop == knopObject))
  10283. {
  10284. Error(ERRInvalidAssignmentTarget);
  10285. }
  10286. }
  10287. else if (item->nop == knopAsg)
  10288. {
  10289. itemRef = &item->sxBin.pnode1;
  10290. item = *itemRef;
  10291. }
  10292. if (item->nop == knopArray)
  10293. {
  10294. ConvertArrayToArrayPattern(item);
  10295. }
  10296. else if (item->nop == knopObject)
  10297. {
  10298. *itemRef = ConvertObjectToObjectPattern(item);
  10299. }
  10300. });
  10301. return pnode;
  10302. }
  10303. ParseNodePtr Parser::CreateParamPatternNode(ParseNodePtr pnode1)
  10304. {
  10305. ParseNodePtr paramPatternNode = CreateNode(knopParamPattern, pnode1->ichMin, pnode1->ichLim);
  10306. paramPatternNode->sxParamPattern.pnode1 = pnode1;
  10307. paramPatternNode->sxParamPattern.pnodeNext = nullptr;
  10308. paramPatternNode->sxParamPattern.location = Js::Constants::NoRegister;
  10309. return paramPatternNode;
  10310. }
  10311. ParseNodePtr Parser::ConvertObjectToObjectPattern(ParseNodePtr pnodeMemberList)
  10312. {
  10313. charcount_t ichMin = m_pscan->IchMinTok();
  10314. charcount_t ichLim = m_pscan->IchLimTok();
  10315. ParseNodePtr pnodeMemberNodeList = nullptr;
  10316. if (pnodeMemberList != nullptr && pnodeMemberList->nop == knopObject)
  10317. {
  10318. ichMin = pnodeMemberList->ichMin;
  10319. ichLim = pnodeMemberList->ichLim;
  10320. pnodeMemberList = pnodeMemberList->sxUni.pnode1;
  10321. }
  10322. ForEachItemInList(pnodeMemberList, [&](ParseNodePtr item) {
  10323. ParseNodePtr memberNode = ConvertMemberToMemberPattern(item);
  10324. AppendToList(&pnodeMemberNodeList, memberNode);
  10325. });
  10326. return CreateUniNode(knopObjectPattern, pnodeMemberNodeList, ichMin, ichLim);
  10327. }
  10328. ParseNodePtr Parser::GetRightSideNodeFromPattern(ParseNodePtr pnode)
  10329. {
  10330. Assert(pnode != nullptr);
  10331. ParseNodePtr rightNode = nullptr;
  10332. OpCode op = pnode->nop;
  10333. if (op == knopObject)
  10334. {
  10335. rightNode = ConvertObjectToObjectPattern(pnode);
  10336. }
  10337. else if (op == knopArray)
  10338. {
  10339. rightNode = ConvertArrayToArrayPattern(pnode);
  10340. }
  10341. else
  10342. {
  10343. rightNode = pnode;
  10344. }
  10345. return rightNode;
  10346. }
  10347. ParseNodePtr Parser::ConvertMemberToMemberPattern(ParseNodePtr pnodeMember)
  10348. {
  10349. if (pnodeMember->nop == knopObjectPatternMember)
  10350. {
  10351. return pnodeMember;
  10352. }
  10353. Assert(pnodeMember->nop == knopMember || pnodeMember->nop == knopMemberShort);
  10354. ParseNodePtr rightNode = GetRightSideNodeFromPattern(pnodeMember->sxBin.pnode2);
  10355. ParseNodePtr resultNode = CreateBinNode(knopObjectPatternMember, pnodeMember->sxBin.pnode1, rightNode);
  10356. resultNode->ichMin = pnodeMember->ichMin;
  10357. resultNode->ichLim = pnodeMember->ichLim;
  10358. return resultNode;
  10359. }
  10360. ParseNodePtr Parser::ConvertToPattern(ParseNodePtr pnode)
  10361. {
  10362. if (pnode != nullptr)
  10363. {
  10364. if (pnode->nop == knopArray)
  10365. {
  10366. ConvertArrayToArrayPattern(pnode);
  10367. }
  10368. else if (pnode->nop == knopObject)
  10369. {
  10370. pnode = ConvertObjectToObjectPattern(pnode);
  10371. }
  10372. }
  10373. return pnode;
  10374. }
  10375. // This essentially be called for verifying the structure of the current tree with satisfying the destructuring grammar.
  10376. void Parser::ParseDestructuredLiteralWithScopeSave(tokens declarationType,
  10377. bool isDecl,
  10378. bool topLevel,
  10379. DestructuringInitializerContext initializerContext/* = DIC_None*/,
  10380. bool allowIn /*= true*/)
  10381. {
  10382. // We are going to parse the text again to validate the current grammar as Destructuring. Saving some scopes and
  10383. // AST related information before the validation parsing and later they will be restored.
  10384. ParseNodePtr pnodeFncSave = m_currentNodeFunc;
  10385. ParseNodePtr pnodeDeferredFncSave = m_currentNodeDeferredFunc;
  10386. if (m_currentNodeDeferredFunc == nullptr)
  10387. {
  10388. m_currentNodeDeferredFunc = m_currentNodeFunc;
  10389. }
  10390. long *pAstSizeSave = m_pCurrentAstSize;
  10391. uint *pNestedCountSave = m_pnestedCount;
  10392. ParseNodePtr *ppnodeScopeSave = m_ppnodeScope;
  10393. ParseNodePtr *ppnodeExprScopeSave = m_ppnodeExprScope;
  10394. ParseNodePtr newTempScope = nullptr;
  10395. m_ppnodeScope = &newTempScope;
  10396. long newTempAstSize = 0;
  10397. m_pCurrentAstSize = &newTempAstSize;
  10398. uint newTempNestedCount = 0;
  10399. m_pnestedCount = &newTempNestedCount;
  10400. m_ppnodeExprScope = nullptr;
  10401. charcount_t funcInArraySave = m_funcInArray;
  10402. uint funcInArrayDepthSave = m_funcInArrayDepth;
  10403. // we need to reset this as we are going to parse the grammar again.
  10404. m_hasDeferredShorthandInitError = false;
  10405. ParseDestructuredLiteral<false>(declarationType, isDecl, topLevel, initializerContext, allowIn);
  10406. m_currentNodeFunc = pnodeFncSave;
  10407. m_currentNodeDeferredFunc = pnodeDeferredFncSave;
  10408. m_pCurrentAstSize = pAstSizeSave;
  10409. m_pnestedCount = pNestedCountSave;
  10410. m_ppnodeScope = ppnodeScopeSave;
  10411. m_ppnodeExprScope = ppnodeExprScopeSave;
  10412. m_funcInArray = funcInArraySave;
  10413. m_funcInArrayDepth = funcInArrayDepthSave;
  10414. }
  10415. template <bool buildAST>
  10416. ParseNodePtr Parser::ParseDestructuredLiteral(tokens declarationType,
  10417. bool isDecl,
  10418. bool topLevel/* = true*/,
  10419. DestructuringInitializerContext initializerContext/* = DIC_None*/,
  10420. bool allowIn/* = true*/,
  10421. BOOL *forInOfOkay/* = nullptr*/,
  10422. BOOL *nativeForOkay/* = nullptr*/)
  10423. {
  10424. ParseNodePtr pnode = nullptr;
  10425. Assert(IsPossiblePatternStart());
  10426. if (m_token.tk == tkLCurly)
  10427. {
  10428. pnode = ParseDestructuredObjectLiteral<buildAST>(declarationType, isDecl, topLevel);
  10429. }
  10430. else
  10431. {
  10432. pnode = ParseDestructuredArrayLiteral<buildAST>(declarationType, isDecl, topLevel);
  10433. }
  10434. return ParseDestructuredInitializer<buildAST>(pnode, isDecl, topLevel, initializerContext, allowIn, forInOfOkay, nativeForOkay);
  10435. }
  10436. template <bool buildAST>
  10437. ParseNodePtr Parser::ParseDestructuredInitializer(ParseNodePtr lhsNode,
  10438. bool isDecl,
  10439. bool topLevel,
  10440. DestructuringInitializerContext initializerContext,
  10441. bool allowIn,
  10442. BOOL *forInOfOkay,
  10443. BOOL *nativeForOkay)
  10444. {
  10445. m_pscan->Scan();
  10446. if (topLevel && nativeForOkay == nullptr)
  10447. {
  10448. if (initializerContext != DIC_ForceErrorOnInitializer && m_token.tk != tkAsg)
  10449. {
  10450. // e.g. var {x};
  10451. Error(ERRDestructInit);
  10452. }
  10453. else if (initializerContext == DIC_ForceErrorOnInitializer && m_token.tk == tkAsg)
  10454. {
  10455. // e.g. catch([x] = [0])
  10456. Error(ERRDestructNotInit);
  10457. }
  10458. }
  10459. if (m_token.tk != tkAsg || initializerContext == DIC_ShouldNotParseInitializer)
  10460. {
  10461. if (topLevel && nativeForOkay != nullptr)
  10462. {
  10463. // Native loop should have destructuring initializer
  10464. *nativeForOkay = FALSE;
  10465. }
  10466. return lhsNode;
  10467. }
  10468. if (forInOfOkay)
  10469. {
  10470. *forInOfOkay = FALSE;
  10471. }
  10472. m_pscan->Scan();
  10473. bool alreadyHasInitError = m_hasDeferredShorthandInitError;
  10474. ParseNodePtr pnodeDefault = ParseExpr<buildAST>(koplCma, nullptr, allowIn);
  10475. if (m_hasDeferredShorthandInitError && !alreadyHasInitError)
  10476. {
  10477. Error(ERRnoColon);
  10478. }
  10479. ParseNodePtr pnodeDestructAsg = nullptr;
  10480. if (buildAST)
  10481. {
  10482. Assert(lhsNode != nullptr);
  10483. pnodeDestructAsg = CreateNodeWithScanner<knopAsg>();
  10484. pnodeDestructAsg->sxBin.pnode1 = lhsNode;
  10485. pnodeDestructAsg->sxBin.pnode2 = pnodeDefault;
  10486. pnodeDestructAsg->ichMin = lhsNode->ichMin;
  10487. pnodeDestructAsg->ichLim = pnodeDefault->ichLim;
  10488. }
  10489. return pnodeDestructAsg;
  10490. }
  10491. template <bool buildAST>
  10492. ParseNodePtr Parser::ParseDestructuredObjectLiteral(tokens declarationType, bool isDecl, bool topLevel/* = true*/)
  10493. {
  10494. Assert(m_token.tk == tkLCurly);
  10495. charcount_t ichMin = m_pscan->IchMinTok();
  10496. m_pscan->Scan();
  10497. if (!isDecl)
  10498. {
  10499. declarationType = tkLCurly;
  10500. }
  10501. ParseNodePtr pnodeMemberList = ParseMemberList<buildAST>(nullptr/*pNameHint*/, nullptr/*pHintLength*/, declarationType);
  10502. Assert(m_token.tk == tkRCurly);
  10503. ParseNodePtr objectPatternNode = nullptr;
  10504. if (buildAST)
  10505. {
  10506. charcount_t ichLim = m_pscan->IchLimTok();
  10507. objectPatternNode = CreateUniNode(knopObjectPattern, pnodeMemberList, ichMin, ichLim);
  10508. }
  10509. return objectPatternNode;
  10510. }
  10511. template <bool buildAST>
  10512. ParseNodePtr Parser::ParseDestructuredVarDecl(tokens declarationType, bool isDecl, bool *hasSeenRest, bool topLevel/* = true*/, bool allowEmptyExpression/* = true*/)
  10513. {
  10514. ParseNodePtr pnodeElem = nullptr;
  10515. int parenCount = 0;
  10516. bool seenRest = false;
  10517. while (m_token.tk == tkLParen)
  10518. {
  10519. m_pscan->Scan();
  10520. ++parenCount;
  10521. }
  10522. if (m_token.tk == tkEllipsis)
  10523. {
  10524. // As per ES 2015 : Rest can have left-hand-side-expression when on assignment expression, but under declaration only binding identifier is allowed
  10525. // But spec is going to change for this one to allow LHS-expression both on expression and declaration - so making that happen early.
  10526. seenRest = true;
  10527. m_pscan->Scan();
  10528. while (m_token.tk == tkLParen)
  10529. {
  10530. m_pscan->Scan();
  10531. ++parenCount;
  10532. }
  10533. if (m_token.tk != tkID && m_token.tk != tkSUPER && m_token.tk != tkLCurly && m_token.tk != tkLBrack)
  10534. {
  10535. if (isDecl)
  10536. {
  10537. Error(ERRnoIdent);
  10538. }
  10539. else
  10540. {
  10541. Error(ERRInvalidAssignmentTarget);
  10542. }
  10543. }
  10544. }
  10545. if (IsPossiblePatternStart())
  10546. {
  10547. // Go recursively
  10548. pnodeElem = ParseDestructuredLiteral<buildAST>(declarationType, isDecl, false /*topLevel*/, seenRest ? DIC_ShouldNotParseInitializer : DIC_None);
  10549. }
  10550. else if (m_token.tk == tkSUPER || m_token.tk == tkID)
  10551. {
  10552. if (isDecl)
  10553. {
  10554. charcount_t ichMin = m_pscan->IchMinTok();
  10555. pnodeElem = ParseVariableDeclaration<buildAST>(declarationType, ichMin
  10556. ,/* fAllowIn */false, /* pfForInOk */nullptr, /* singleDefOnly */true, /* allowInit */!seenRest, false /*topLevelParse*/);
  10557. }
  10558. else
  10559. {
  10560. BOOL fCanAssign;
  10561. IdentToken token;
  10562. // We aren't declaring anything, so scan the ID reference manually.
  10563. pnodeElem = ParseTerm<buildAST>(/* fAllowCall */ m_token.tk != tkSUPER, nullptr /*pNameHint*/, nullptr /*pHintLength*/, nullptr /*pShortNameOffset*/, &token, false,
  10564. &fCanAssign);
  10565. // In this destructuring case we can force error here as we cannot assign.
  10566. if (!fCanAssign)
  10567. {
  10568. Error(ERRInvalidAssignmentTarget);
  10569. }
  10570. if (buildAST)
  10571. {
  10572. if (IsStrictMode() && pnodeElem != nullptr && pnodeElem->nop == knopName)
  10573. {
  10574. CheckStrictModeEvalArgumentsUsage(pnodeElem->sxPid.pid);
  10575. }
  10576. }
  10577. else
  10578. {
  10579. if (IsStrictMode() && token.tk == tkID)
  10580. {
  10581. CheckStrictModeEvalArgumentsUsage(token.pid);
  10582. }
  10583. token.tk = tkNone;
  10584. }
  10585. }
  10586. }
  10587. else if (!((m_token.tk == tkComma || m_token.tk == tkRBrack || m_token.tk == tkRCurly) && allowEmptyExpression))
  10588. {
  10589. if (m_token.IsOperator())
  10590. {
  10591. Error(ERRDestructNoOper);
  10592. }
  10593. Error(ERRDestructIDRef);
  10594. }
  10595. // Swallow RParens before a default expression, if any.
  10596. while (m_token.tk == tkRParen)
  10597. {
  10598. m_pscan->Scan();
  10599. --parenCount;
  10600. }
  10601. if (hasSeenRest != nullptr)
  10602. {
  10603. *hasSeenRest = seenRest;
  10604. }
  10605. if (m_token.tk == tkAsg)
  10606. {
  10607. // Parse the initializer.
  10608. if (seenRest)
  10609. {
  10610. Error(ERRRestWithDefault);
  10611. }
  10612. m_pscan->Scan();
  10613. bool alreadyHasInitError = m_hasDeferredShorthandInitError;
  10614. ParseNodePtr pnodeInit = ParseExpr<buildAST>(koplCma);
  10615. if (m_hasDeferredShorthandInitError && !alreadyHasInitError)
  10616. {
  10617. Error(ERRnoColon);
  10618. }
  10619. if (buildAST)
  10620. {
  10621. pnodeElem = CreateBinNode(knopAsg, pnodeElem, pnodeInit);
  10622. }
  10623. }
  10624. if (buildAST && seenRest)
  10625. {
  10626. ParseNodePtr pnodeRest = CreateNodeWithScanner<knopEllipsis>();
  10627. pnodeRest->sxUni.pnode1 = pnodeElem;
  10628. pnodeElem = pnodeRest;
  10629. }
  10630. while (m_token.tk == tkRParen)
  10631. {
  10632. m_pscan->Scan();
  10633. --parenCount;
  10634. }
  10635. if (!(m_token.tk == tkComma || m_token.tk == tkRBrack || m_token.tk == tkRCurly))
  10636. {
  10637. if (m_token.IsOperator())
  10638. {
  10639. Error(ERRDestructNoOper);
  10640. }
  10641. Error(ERRsyntax);
  10642. }
  10643. if (parenCount != 0)
  10644. {
  10645. Error(ERRnoRparen);
  10646. }
  10647. return pnodeElem;
  10648. }
  10649. template <bool buildAST>
  10650. ParseNodePtr Parser::ParseDestructuredArrayLiteral(tokens declarationType, bool isDecl, bool topLevel)
  10651. {
  10652. Assert(m_token.tk == tkLBrack);
  10653. charcount_t ichMin = m_pscan->IchMinTok();
  10654. m_pscan->Scan();
  10655. ParseNodePtr pnodeDestructArr = nullptr;
  10656. ParseNodePtr pnodeList = nullptr;
  10657. ParseNodePtr *lastNodeRef = nullptr;
  10658. uint count = 0;
  10659. bool hasMissingValues = false;
  10660. bool seenRest = false;
  10661. while (true)
  10662. {
  10663. if (seenRest) // Rest must be in the last position.
  10664. {
  10665. Error(ERRDestructRestLast);
  10666. }
  10667. ParseNodePtr pnodeElem = ParseDestructuredVarDecl<buildAST>(declarationType, isDecl, &seenRest, topLevel);
  10668. if (buildAST)
  10669. {
  10670. if (pnodeElem == nullptr && buildAST)
  10671. {
  10672. pnodeElem = CreateNodeWithScanner<knopEmpty>();
  10673. hasMissingValues = true;
  10674. }
  10675. AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeElem);
  10676. }
  10677. count++;
  10678. if (m_token.tk == tkRBrack)
  10679. {
  10680. break;
  10681. }
  10682. if (m_token.tk != tkComma)
  10683. {
  10684. Error(ERRDestructNoOper);
  10685. }
  10686. m_pscan->Scan();
  10687. }
  10688. if (buildAST)
  10689. {
  10690. pnodeDestructArr = CreateNodeWithScanner<knopArrayPattern>();
  10691. pnodeDestructArr->sxArrLit.pnode1 = pnodeList;
  10692. pnodeDestructArr->sxArrLit.arrayOfTaggedInts = false;
  10693. pnodeDestructArr->sxArrLit.arrayOfInts = false;
  10694. pnodeDestructArr->sxArrLit.arrayOfNumbers = false;
  10695. pnodeDestructArr->sxArrLit.hasMissingValues = hasMissingValues;
  10696. pnodeDestructArr->sxArrLit.count = count;
  10697. pnodeDestructArr->sxArrLit.spreadCount = seenRest ? 1 : 0;
  10698. pnodeDestructArr->ichMin = ichMin;
  10699. pnodeDestructArr->ichLim = m_pscan->IchLimTok();
  10700. if (pnodeDestructArr->sxArrLit.pnode1)
  10701. {
  10702. this->CheckArguments(pnodeDestructArr->sxArrLit.pnode1);
  10703. }
  10704. }
  10705. return pnodeDestructArr;
  10706. }
  10707. void Parser::CaptureContext(ParseContext *parseContext) const
  10708. {
  10709. parseContext->pszSrc = m_pscan->PchBase();
  10710. parseContext->length = this->m_originalLength;
  10711. parseContext->characterOffset = m_pscan->IchMinTok();
  10712. parseContext->offset = parseContext->characterOffset + m_pscan->m_cMultiUnits;
  10713. parseContext->grfscr = this->m_grfscr;
  10714. parseContext->lineNumber = m_pscan->LineCur();
  10715. parseContext->pnodeProg = this->m_currentNodeProg;
  10716. parseContext->fromExternal = m_pscan->IsFromExternalSource();
  10717. parseContext->strictMode = this->IsStrictMode();
  10718. parseContext->sourceContextInfo = this->m_sourceContextInfo;
  10719. parseContext->currentBlockInfo = this->m_currentBlockInfo;
  10720. parseContext->nextBlockId = this->m_nextBlockId;
  10721. }
  10722. void Parser::RestoreContext(ParseContext *const parseContext)
  10723. {
  10724. m_sourceContextInfo = parseContext->sourceContextInfo;
  10725. m_currentBlockInfo = parseContext->currentBlockInfo;
  10726. m_nextBlockId = parseContext->nextBlockId;
  10727. m_grfscr = parseContext->grfscr;
  10728. m_length = parseContext->length;
  10729. m_pscan->SetText(parseContext->pszSrc, parseContext->offset, parseContext->length, parseContext->characterOffset, parseContext->grfscr, parseContext->lineNumber);
  10730. m_currentNodeProg = parseContext->pnodeProg;
  10731. m_fUseStrictMode = parseContext->strictMode;
  10732. }
  10733. class ByteCodeGenerator;
  10734. #if DBG_DUMP
  10735. #define INDENT_SIZE 2
  10736. void PrintPnodeListWIndent(ParseNode *pnode,int indentAmt);
  10737. void PrintFormalsWIndent(ParseNode *pnode, int indentAmt);
  10738. void Indent(int indentAmt) {
  10739. for (int i=0;i<indentAmt;i++) {
  10740. Output::Print(_u(" "));
  10741. }
  10742. }
  10743. void PrintBlockType(PnodeBlockType type)
  10744. {
  10745. switch (type)
  10746. {
  10747. case Global:
  10748. Output::Print(_u("(Global)"));
  10749. break;
  10750. case Function:
  10751. Output::Print(_u("(Function)"));
  10752. break;
  10753. case Regular:
  10754. Output::Print(_u("(Regular)"));
  10755. break;
  10756. case Parameter:
  10757. Output::Print(_u("(Parameter)"));
  10758. break;
  10759. default:
  10760. Output::Print(_u("(unknown blocktype)"));
  10761. break;
  10762. }
  10763. }
  10764. void PrintScopesWIndent(ParseNode *pnode,int indentAmt) {
  10765. ParseNode *scope = nullptr;
  10766. bool firstOnly = false;
  10767. switch(pnode->nop)
  10768. {
  10769. case knopProg:
  10770. case knopFncDecl: scope = pnode->sxFnc.pnodeScopes; break;
  10771. case knopBlock: scope = pnode->sxBlock.pnodeScopes; break;
  10772. case knopCatch: scope = pnode->sxCatch.pnodeScopes; break;
  10773. case knopWith: scope = pnode->sxWith.pnodeScopes; break;
  10774. case knopSwitch: scope = pnode->sxSwitch.pnodeBlock; firstOnly = true; break;
  10775. case knopFor: scope = pnode->sxFor.pnodeBlock; firstOnly = true; break;
  10776. case knopForIn: scope = pnode->sxForInOrForOf.pnodeBlock; firstOnly = true; break;
  10777. case knopForOf: scope = pnode->sxForInOrForOf.pnodeBlock; firstOnly = true; break;
  10778. }
  10779. if (scope) {
  10780. Output::Print(_u("[%4d, %4d): "), scope->ichMin, scope->ichLim);
  10781. Indent(indentAmt);
  10782. Output::Print(_u("Scopes: "));
  10783. ParseNode *next = nullptr;
  10784. ParseNode *syntheticBlock = nullptr;
  10785. while (scope) {
  10786. switch (scope->nop) {
  10787. case knopFncDecl: Output::Print(_u("knopFncDecl")); next = scope->sxFnc.pnodeNext; break;
  10788. case knopBlock: Output::Print(_u("knopBlock")); PrintBlockType(scope->sxBlock.blockType); next = scope->sxBlock.pnodeNext; break;
  10789. case knopCatch: Output::Print(_u("knopCatch")); next = scope->sxCatch.pnodeNext; break;
  10790. case knopWith: Output::Print(_u("knopWith")); next = scope->sxWith.pnodeNext; break;
  10791. default: Output::Print(_u("unknown")); break;
  10792. }
  10793. if (firstOnly) {
  10794. next = nullptr;
  10795. syntheticBlock = scope;
  10796. }
  10797. if (scope->grfpn & fpnSyntheticNode) {
  10798. Output::Print(_u(" synthetic"));
  10799. if (scope->nop == knopBlock)
  10800. syntheticBlock = scope;
  10801. }
  10802. Output::Print(_u(" (%d-%d)"), scope->ichMin, scope->ichLim);
  10803. if (next) Output::Print(_u(", "));
  10804. scope = next;
  10805. }
  10806. Output::Print(_u("\n"));
  10807. if (syntheticBlock || firstOnly) {
  10808. PrintScopesWIndent(syntheticBlock, indentAmt + INDENT_SIZE);
  10809. }
  10810. }
  10811. }
  10812. void PrintPnodeWIndent(ParseNode *pnode,int indentAmt) {
  10813. if (pnode==NULL)
  10814. return;
  10815. Output::Print(_u("[%4d, %4d): "), pnode->ichMin, pnode->ichLim);
  10816. switch (pnode->nop) {
  10817. //PTNODE(knopName , "name" ,None ,Pid ,fnopLeaf)
  10818. case knopName:
  10819. Indent(indentAmt);
  10820. if (pnode->sxPid.pid!=NULL) {
  10821. Output::Print(_u("id: %s\n"),pnode->sxPid.pid->Psz());
  10822. }
  10823. else {
  10824. Output::Print(_u("name node\n"));
  10825. }
  10826. break;
  10827. //PTNODE(knopInt , "int const" ,None ,Int ,fnopLeaf|fnopConst)
  10828. case knopInt:
  10829. Indent(indentAmt);
  10830. Output::Print(_u("%d\n"),pnode->sxInt.lw);
  10831. break;
  10832. //PTNODE(knopFlt , "flt const" ,None ,Flt ,fnopLeaf|fnopConst)
  10833. case knopFlt:
  10834. Indent(indentAmt);
  10835. Output::Print(_u("%lf\n"),pnode->sxFlt.dbl);
  10836. break;
  10837. //PTNODE(knopStr , "str const" ,None ,Pid ,fnopLeaf|fnopConst)
  10838. case knopStr:
  10839. Indent(indentAmt);
  10840. Output::Print(_u("\"%s\"\n"),pnode->sxPid.pid->Psz());
  10841. break;
  10842. //PTNODE(knopRegExp , "reg expr" ,None ,Pid ,fnopLeaf|fnopConst)
  10843. case knopRegExp:
  10844. Indent(indentAmt);
  10845. Output::Print(_u("/%x/\n"),pnode->sxPid.regexPattern);
  10846. break;
  10847. //PTNODE(knopThis , "this" ,None ,None ,fnopLeaf)
  10848. case knopThis:
  10849. Indent(indentAmt);
  10850. Output::Print(_u("this\n"));
  10851. break;
  10852. //PTNODE(knopSuper , "super" ,None ,None ,fnopLeaf)
  10853. case knopSuper:
  10854. Indent(indentAmt);
  10855. Output::Print(_u("super\n"));
  10856. break;
  10857. //PTNODE(knopNewTarget , "new.target" ,None ,None ,fnopLeaf)
  10858. case knopNewTarget:
  10859. Indent(indentAmt);
  10860. Output::Print(_u("new.target\n"));
  10861. break;
  10862. //PTNODE(knopNull , "null" ,Null ,None ,fnopLeaf)
  10863. case knopNull:
  10864. Indent(indentAmt);
  10865. Output::Print(_u("null\n"));
  10866. break;
  10867. //PTNODE(knopFalse , "false" ,False ,None ,fnopLeaf)
  10868. case knopFalse:
  10869. Indent(indentAmt);
  10870. Output::Print(_u("false\n"));
  10871. break;
  10872. //PTNODE(knopTrue , "true" ,True ,None ,fnopLeaf)
  10873. case knopTrue:
  10874. Indent(indentAmt);
  10875. Output::Print(_u("true\n"));
  10876. break;
  10877. //PTNODE(knopEmpty , "empty" ,Empty ,None ,fnopLeaf)
  10878. case knopEmpty:
  10879. Indent(indentAmt);
  10880. Output::Print(_u("empty\n"));
  10881. break;
  10882. // Unary operators.
  10883. //PTNODE(knopNot , "~" ,BitNot ,Uni ,fnopUni)
  10884. case knopNot:
  10885. Indent(indentAmt);
  10886. Output::Print(_u("~\n"));
  10887. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10888. break;
  10889. //PTNODE(knopNeg , "unary -" ,Neg ,Uni ,fnopUni)
  10890. case knopNeg:
  10891. Indent(indentAmt);
  10892. Output::Print(_u("U-\n"));
  10893. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10894. break;
  10895. //PTNODE(knopPos , "unary +" ,Pos ,Uni ,fnopUni)
  10896. case knopPos:
  10897. Indent(indentAmt);
  10898. Output::Print(_u("U+\n"));
  10899. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10900. break;
  10901. //PTNODE(knopLogNot , "!" ,LogNot ,Uni ,fnopUni)
  10902. case knopLogNot:
  10903. Indent(indentAmt);
  10904. Output::Print(_u("!\n"));
  10905. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10906. break;
  10907. //PTNODE(knopEllipsis , "..." ,Spread ,Uni , fnopUni)
  10908. case knopEllipsis:
  10909. Indent(indentAmt);
  10910. Output::Print(_u("...<expr>\n"));
  10911. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10912. break;
  10913. //PTNODE(knopIncPost , "++ post" ,Inc ,Uni ,fnopUni|fnopAsg)
  10914. case knopIncPost:
  10915. Indent(indentAmt);
  10916. Output::Print(_u("<expr>++\n"));
  10917. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10918. break;
  10919. //PTNODE(knopDecPost , "-- post" ,Dec ,Uni ,fnopUni|fnopAsg)
  10920. case knopDecPost:
  10921. Indent(indentAmt);
  10922. Output::Print(_u("<expr>--\n"));
  10923. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10924. break;
  10925. //PTNODE(knopIncPre , "++ pre" ,Inc ,Uni ,fnopUni|fnopAsg)
  10926. case knopIncPre:
  10927. Indent(indentAmt);
  10928. Output::Print(_u("++<expr>\n"));
  10929. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10930. break;
  10931. //PTNODE(knopDecPre , "-- pre" ,Dec ,Uni ,fnopUni|fnopAsg)
  10932. case knopDecPre:
  10933. Indent(indentAmt);
  10934. Output::Print(_u("--<expr>\n"));
  10935. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10936. break;
  10937. //PTNODE(knopTypeof , "typeof" ,None ,Uni ,fnopUni)
  10938. case knopTypeof:
  10939. Indent(indentAmt);
  10940. Output::Print(_u("typeof\n"));
  10941. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10942. break;
  10943. //PTNODE(knopVoid , "void" ,Void ,Uni ,fnopUni)
  10944. case knopVoid:
  10945. Indent(indentAmt);
  10946. Output::Print(_u("void\n"));
  10947. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10948. break;
  10949. //PTNODE(knopDelete , "delete" ,None ,Uni ,fnopUni)
  10950. case knopDelete:
  10951. Indent(indentAmt);
  10952. Output::Print(_u("delete\n"));
  10953. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10954. break;
  10955. //PTNODE(knopArray , "arr cnst" ,None ,Uni ,fnopUni)
  10956. case knopArrayPattern:
  10957. Indent(indentAmt);
  10958. Output::Print(_u("Array Pattern\n"));
  10959. PrintPnodeListWIndent(pnode->sxUni.pnode1, indentAmt + INDENT_SIZE);
  10960. break;
  10961. case knopObjectPattern:
  10962. Indent(indentAmt);
  10963. Output::Print(_u("Object Pattern\n"));
  10964. PrintPnodeListWIndent(pnode->sxUni.pnode1, indentAmt + INDENT_SIZE);
  10965. break;
  10966. case knopArray:
  10967. Indent(indentAmt);
  10968. Output::Print(_u("Array Literal\n"));
  10969. PrintPnodeListWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10970. break;
  10971. //PTNODE(knopObject , "obj cnst" ,None ,Uni ,fnopUni)
  10972. case knopObject:
  10973. Indent(indentAmt);
  10974. Output::Print(_u("Object Literal\n"));
  10975. PrintPnodeListWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10976. break;
  10977. // Binary and Ternary Operators
  10978. //PTNODE(knopAdd , "+" ,Add ,Bin ,fnopBin)
  10979. case knopAdd:
  10980. Indent(indentAmt);
  10981. Output::Print(_u("+\n"));
  10982. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10983. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10984. break;
  10985. //PTNODE(knopSub , "-" ,Sub ,Bin ,fnopBin)
  10986. case knopSub:
  10987. Indent(indentAmt);
  10988. Output::Print(_u("-\n"));
  10989. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10990. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10991. break;
  10992. //PTNODE(knopMul , "*" ,Mul ,Bin ,fnopBin)
  10993. case knopMul:
  10994. Indent(indentAmt);
  10995. Output::Print(_u("*\n"));
  10996. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10997. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10998. break;
  10999. //PTNODE(knopDiv , "/" ,Div ,Bin ,fnopBin)
  11000. case knopExpo:
  11001. Indent(indentAmt);
  11002. Output::Print(_u("**\n"));
  11003. PrintPnodeWIndent(pnode->sxBin.pnode1, indentAmt + INDENT_SIZE);
  11004. PrintPnodeWIndent(pnode->sxBin.pnode2, indentAmt + INDENT_SIZE);
  11005. break;
  11006. //PTNODE(knopExpo , "**" ,Expo ,Bin ,fnopBin)
  11007. case knopDiv:
  11008. Indent(indentAmt);
  11009. Output::Print(_u("/\n"));
  11010. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11011. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11012. break;
  11013. //PTNODE(knopMod , "%" ,Mod ,Bin ,fnopBin)
  11014. case knopMod:
  11015. Indent(indentAmt);
  11016. Output::Print(_u("%\n"));
  11017. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11018. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11019. break;
  11020. //PTNODE(knopOr , "|" ,BitOr ,Bin ,fnopBin)
  11021. case knopOr:
  11022. Indent(indentAmt);
  11023. Output::Print(_u("|\n"));
  11024. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11025. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11026. break;
  11027. //PTNODE(knopXor , "^" ,BitXor ,Bin ,fnopBin)
  11028. case knopXor:
  11029. Indent(indentAmt);
  11030. Output::Print(_u("^\n"));
  11031. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11032. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11033. break;
  11034. //PTNODE(knopAnd , "&" ,BitAnd ,Bin ,fnopBin)
  11035. case knopAnd:
  11036. Indent(indentAmt);
  11037. Output::Print(_u("&\n"));
  11038. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11039. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11040. break;
  11041. //PTNODE(knopEq , "==" ,EQ ,Bin ,fnopBin|fnopRel)
  11042. case knopEq:
  11043. Indent(indentAmt);
  11044. Output::Print(_u("==\n"));
  11045. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11046. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11047. break;
  11048. //PTNODE(knopNe , "!=" ,NE ,Bin ,fnopBin|fnopRel)
  11049. case knopNe:
  11050. Indent(indentAmt);
  11051. Output::Print(_u("!=\n"));
  11052. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11053. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11054. break;
  11055. //PTNODE(knopLt , "<" ,LT ,Bin ,fnopBin|fnopRel)
  11056. case knopLt:
  11057. Indent(indentAmt);
  11058. Output::Print(_u("<\n"));
  11059. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11060. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11061. break;
  11062. //PTNODE(knopLe , "<=" ,LE ,Bin ,fnopBin|fnopRel)
  11063. case knopLe:
  11064. Indent(indentAmt);
  11065. Output::Print(_u("<=\n"));
  11066. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11067. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11068. break;
  11069. //PTNODE(knopGe , ">=" ,GE ,Bin ,fnopBin|fnopRel)
  11070. case knopGe:
  11071. Indent(indentAmt);
  11072. Output::Print(_u(">=\n"));
  11073. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11074. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11075. break;
  11076. //PTNODE(knopGt , ">" ,GT ,Bin ,fnopBin|fnopRel)
  11077. case knopGt:
  11078. Indent(indentAmt);
  11079. Output::Print(_u(">\n"));
  11080. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11081. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11082. break;
  11083. //PTNODE(knopCall , "()" ,None ,Bin ,fnopBin)
  11084. case knopCall:
  11085. Indent(indentAmt);
  11086. Output::Print(_u("Call\n"));
  11087. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11088. PrintPnodeListWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11089. break;
  11090. //PTNODE(knopDot , "." ,None ,Bin ,fnopBin)
  11091. case knopDot:
  11092. Indent(indentAmt);
  11093. Output::Print(_u(".\n"));
  11094. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11095. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11096. break;
  11097. //PTNODE(knopAsg , "=" ,None ,Bin ,fnopBin|fnopAsg)
  11098. case knopAsg:
  11099. Indent(indentAmt);
  11100. Output::Print(_u("=\n"));
  11101. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11102. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11103. break;
  11104. //PTNODE(knopInstOf , "instanceof",InstOf ,Bin ,fnopBin|fnopRel)
  11105. case knopInstOf:
  11106. Indent(indentAmt);
  11107. Output::Print(_u("instanceof\n"));
  11108. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11109. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11110. break;
  11111. //PTNODE(knopIn , "in" ,In ,Bin ,fnopBin|fnopRel)
  11112. case knopIn:
  11113. Indent(indentAmt);
  11114. Output::Print(_u("in\n"));
  11115. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11116. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11117. break;
  11118. //PTNODE(knopEqv , "===" ,Eqv ,Bin ,fnopBin|fnopRel)
  11119. case knopEqv:
  11120. Indent(indentAmt);
  11121. Output::Print(_u("===\n"));
  11122. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11123. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11124. break;
  11125. //PTNODE(knopNEqv , "!==" ,NEqv ,Bin ,fnopBin|fnopRel)
  11126. case knopNEqv:
  11127. Indent(indentAmt);
  11128. Output::Print(_u("!==\n"));
  11129. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11130. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11131. break;
  11132. //PTNODE(knopComma , "," ,None ,Bin ,fnopBin)
  11133. case knopComma:
  11134. Indent(indentAmt);
  11135. Output::Print(_u(",\n"));
  11136. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11137. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11138. break;
  11139. //PTNODE(knopLogOr , "||" ,None ,Bin ,fnopBin)
  11140. case knopLogOr:
  11141. Indent(indentAmt);
  11142. Output::Print(_u("||\n"));
  11143. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11144. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11145. break;
  11146. //PTNODE(knopLogAnd , "&&" ,None ,Bin ,fnopBin)
  11147. case knopLogAnd:
  11148. Indent(indentAmt);
  11149. Output::Print(_u("&&\n"));
  11150. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11151. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11152. break;
  11153. //PTNODE(knopLsh , "<<" ,Lsh ,Bin ,fnopBin)
  11154. case knopLsh:
  11155. Indent(indentAmt);
  11156. Output::Print(_u("<<\n"));
  11157. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11158. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11159. break;
  11160. //PTNODE(knopRsh , ">>" ,Rsh ,Bin ,fnopBin)
  11161. case knopRsh:
  11162. Indent(indentAmt);
  11163. Output::Print(_u(">>\n"));
  11164. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11165. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11166. break;
  11167. //PTNODE(knopRs2 , ">>>" ,Rs2 ,Bin ,fnopBin)
  11168. case knopRs2:
  11169. Indent(indentAmt);
  11170. Output::Print(_u(">>>\n"));
  11171. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11172. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11173. break;
  11174. //PTNODE(knopNew , "new" ,None ,Bin ,fnopBin)
  11175. case knopNew:
  11176. Indent(indentAmt);
  11177. Output::Print(_u("new\n"));
  11178. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11179. PrintPnodeListWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11180. break;
  11181. //PTNODE(knopIndex , "[]" ,None ,Bin ,fnopBin)
  11182. case knopIndex:
  11183. Indent(indentAmt);
  11184. Output::Print(_u("[]\n"));
  11185. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11186. PrintPnodeListWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11187. break;
  11188. //PTNODE(knopQmark , "?" ,None ,Tri ,fnopBin)
  11189. case knopQmark:
  11190. Indent(indentAmt);
  11191. Output::Print(_u("?:\n"));
  11192. PrintPnodeWIndent(pnode->sxTri.pnode1,indentAmt+INDENT_SIZE);
  11193. PrintPnodeWIndent(pnode->sxTri.pnode2,indentAmt+INDENT_SIZE);
  11194. PrintPnodeWIndent(pnode->sxTri.pnode3,indentAmt+INDENT_SIZE);
  11195. break;
  11196. //PTNODE(knopAsgAdd , "+=" ,Add ,Bin ,fnopBin|fnopAsg)
  11197. case knopAsgAdd:
  11198. Indent(indentAmt);
  11199. Output::Print(_u("+=\n"));
  11200. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11201. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11202. break;
  11203. //PTNODE(knopAsgSub , "-=" ,Sub ,Bin ,fnopBin|fnopAsg)
  11204. case knopAsgSub:
  11205. Indent(indentAmt);
  11206. Output::Print(_u("-=\n"));
  11207. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11208. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11209. break;
  11210. //PTNODE(knopAsgMul , "*=" ,Mul ,Bin ,fnopBin|fnopAsg)
  11211. case knopAsgMul:
  11212. Indent(indentAmt);
  11213. Output::Print(_u("*=\n"));
  11214. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11215. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11216. break;
  11217. //PTNODE(knopAsgDiv , "/=" ,Div ,Bin ,fnopBin|fnopAsg)
  11218. case knopAsgExpo:
  11219. Indent(indentAmt);
  11220. Output::Print(_u("**=\n"));
  11221. PrintPnodeWIndent(pnode->sxBin.pnode1, indentAmt + INDENT_SIZE);
  11222. PrintPnodeWIndent(pnode->sxBin.pnode2, indentAmt + INDENT_SIZE);
  11223. break;
  11224. //PTNODE(knopAsgExpo , "**=" ,Expo ,Bin ,fnopBin|fnopAsg)
  11225. case knopAsgDiv:
  11226. Indent(indentAmt);
  11227. Output::Print(_u("/=\n"));
  11228. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11229. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11230. break;
  11231. //PTNODE(knopAsgMod , "%=" ,Mod ,Bin ,fnopBin|fnopAsg)
  11232. case knopAsgMod:
  11233. Indent(indentAmt);
  11234. Output::Print(_u("%=\n"));
  11235. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11236. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11237. break;
  11238. //PTNODE(knopAsgAnd , "&=" ,BitAnd ,Bin ,fnopBin|fnopAsg)
  11239. case knopAsgAnd:
  11240. Indent(indentAmt);
  11241. Output::Print(_u("&=\n"));
  11242. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11243. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11244. break;
  11245. //PTNODE(knopAsgXor , "^=" ,BitXor ,Bin ,fnopBin|fnopAsg)
  11246. case knopAsgXor:
  11247. Indent(indentAmt);
  11248. Output::Print(_u("^=\n"));
  11249. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11250. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11251. break;
  11252. //PTNODE(knopAsgOr , "|=" ,BitOr ,Bin ,fnopBin|fnopAsg)
  11253. case knopAsgOr:
  11254. Indent(indentAmt);
  11255. Output::Print(_u("|=\n"));
  11256. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11257. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11258. break;
  11259. //PTNODE(knopAsgLsh , "<<=" ,Lsh ,Bin ,fnopBin|fnopAsg)
  11260. case knopAsgLsh:
  11261. Indent(indentAmt);
  11262. Output::Print(_u("<<=\n"));
  11263. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11264. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11265. break;
  11266. //PTNODE(knopAsgRsh , ">>=" ,Rsh ,Bin ,fnopBin|fnopAsg)
  11267. case knopAsgRsh:
  11268. Indent(indentAmt);
  11269. Output::Print(_u(">>=\n"));
  11270. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11271. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11272. break;
  11273. //PTNODE(knopAsgRs2 , ">>>=" ,Rs2 ,Bin ,fnopBin|fnopAsg)
  11274. case knopAsgRs2:
  11275. Indent(indentAmt);
  11276. Output::Print(_u(">>>=\n"));
  11277. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11278. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11279. break;
  11280. case knopComputedName:
  11281. Indent(indentAmt);
  11282. Output::Print(_u("ComputedProperty\n"));
  11283. PrintPnodeWIndent(pnode->sxUni.pnode1, indentAmt + INDENT_SIZE);
  11284. break;
  11285. //PTNODE(knopMember , ":" ,None ,Bin ,fnopBin)
  11286. case knopMember:
  11287. case knopMemberShort:
  11288. case knopObjectPatternMember:
  11289. Indent(indentAmt);
  11290. Output::Print(_u(":\n"));
  11291. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  11292. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  11293. break;
  11294. // General nodes.
  11295. //PTNODE(knopList , "<list>" ,None ,Bin ,fnopNone)
  11296. case knopList:
  11297. Indent(indentAmt);
  11298. Output::Print(_u("List\n"));
  11299. PrintPnodeListWIndent(pnode,indentAmt+INDENT_SIZE);
  11300. break;
  11301. //PTNODE(knopVarDecl , "varDcl" ,None ,Var ,fnopNone)
  11302. case knopVarDecl:
  11303. Indent(indentAmt);
  11304. Output::Print(_u("var %s\n"),pnode->sxVar.pid->Psz());
  11305. if (pnode->sxVar.pnodeInit!=NULL)
  11306. PrintPnodeWIndent(pnode->sxVar.pnodeInit,indentAmt+INDENT_SIZE);
  11307. break;
  11308. case knopConstDecl:
  11309. Indent(indentAmt);
  11310. Output::Print(_u("const %s\n"),pnode->sxVar.pid->Psz());
  11311. if (pnode->sxVar.pnodeInit!=NULL)
  11312. PrintPnodeWIndent(pnode->sxVar.pnodeInit,indentAmt+INDENT_SIZE);
  11313. break;
  11314. case knopLetDecl:
  11315. Indent(indentAmt);
  11316. Output::Print(_u("let %s\n"),pnode->sxVar.pid->Psz());
  11317. if (pnode->sxVar.pnodeInit!=NULL)
  11318. PrintPnodeWIndent(pnode->sxVar.pnodeInit,indentAmt+INDENT_SIZE);
  11319. break;
  11320. //PTNODE(knopFncDecl , "fncDcl" ,None ,Fnc ,fnopLeaf)
  11321. case knopFncDecl:
  11322. Indent(indentAmt);
  11323. if (pnode->sxFnc.pid!=NULL)
  11324. {
  11325. Output::Print(_u("fn decl %d nested %d name %s (%d-%d)\n"),pnode->sxFnc.IsDeclaration(),pnode->sxFnc.IsNested(),
  11326. pnode->sxFnc.pid->Psz(), pnode->ichMin, pnode->ichLim);
  11327. }
  11328. else
  11329. {
  11330. Output::Print(_u("fn decl %d nested %d anonymous (%d-%d)\n"),pnode->sxFnc.IsDeclaration(),pnode->sxFnc.IsNested(),pnode->ichMin,pnode->ichLim);
  11331. }
  11332. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  11333. PrintFormalsWIndent(pnode->sxFnc.pnodeParams, indentAmt + INDENT_SIZE);
  11334. PrintPnodeWIndent(pnode->sxFnc.pnodeRest, indentAmt + INDENT_SIZE);
  11335. PrintPnodeWIndent(pnode->sxFnc.pnodeBody, indentAmt + INDENT_SIZE);
  11336. if (pnode->sxFnc.pnodeBody == nullptr)
  11337. {
  11338. Output::Print(_u("[%4d, %4d): "), pnode->ichMin, pnode->ichLim);
  11339. Indent(indentAmt + INDENT_SIZE);
  11340. Output::Print(_u("<parse deferred body>\n"));
  11341. }
  11342. break;
  11343. //PTNODE(knopProg , "program" ,None ,Fnc ,fnopNone)
  11344. case knopProg:
  11345. Indent(indentAmt);
  11346. Output::Print(_u("program\n"));
  11347. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  11348. PrintPnodeListWIndent(pnode->sxFnc.pnodeBody,indentAmt+INDENT_SIZE);
  11349. break;
  11350. //PTNODE(knopEndCode , "<endcode>" ,None ,None ,fnopNone)
  11351. case knopEndCode:
  11352. Indent(indentAmt);
  11353. Output::Print(_u("<endcode>\n"));
  11354. break;
  11355. //PTNODE(knopDebugger , "debugger" ,None ,None ,fnopNone)
  11356. case knopDebugger:
  11357. Indent(indentAmt);
  11358. Output::Print(_u("<debugger>\n"));
  11359. break;
  11360. //PTNODE(knopFor , "for" ,None ,For ,fnopBreak|fnopContinue)
  11361. case knopFor:
  11362. Indent(indentAmt);
  11363. Output::Print(_u("for\n"));
  11364. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  11365. PrintPnodeWIndent(pnode->sxFor.pnodeInit,indentAmt+INDENT_SIZE);
  11366. PrintPnodeWIndent(pnode->sxFor.pnodeCond,indentAmt+INDENT_SIZE);
  11367. PrintPnodeWIndent(pnode->sxFor.pnodeIncr,indentAmt+INDENT_SIZE);
  11368. PrintPnodeWIndent(pnode->sxFor.pnodeBody,indentAmt+INDENT_SIZE);
  11369. break;
  11370. //PTNODE(knopIf , "if" ,None ,If ,fnopNone)
  11371. case knopIf:
  11372. Indent(indentAmt);
  11373. Output::Print(_u("if\n"));
  11374. PrintPnodeWIndent(pnode->sxIf.pnodeCond,indentAmt+INDENT_SIZE);
  11375. PrintPnodeWIndent(pnode->sxIf.pnodeTrue,indentAmt+INDENT_SIZE);
  11376. if (pnode->sxIf.pnodeFalse!=NULL)
  11377. PrintPnodeWIndent(pnode->sxIf.pnodeFalse,indentAmt+INDENT_SIZE);
  11378. break;
  11379. //PTNODE(knopWhile , "while" ,None ,While,fnopBreak|fnopContinue)
  11380. case knopWhile:
  11381. Indent(indentAmt);
  11382. Output::Print(_u("while\n"));
  11383. PrintPnodeWIndent(pnode->sxWhile.pnodeCond,indentAmt+INDENT_SIZE);
  11384. PrintPnodeWIndent(pnode->sxWhile.pnodeBody,indentAmt+INDENT_SIZE);
  11385. break;
  11386. //PTNODE(knopDoWhile , "do-while" ,None ,While,fnopBreak|fnopContinue)
  11387. case knopDoWhile:
  11388. Indent(indentAmt);
  11389. Output::Print(_u("do\n"));
  11390. PrintPnodeWIndent(pnode->sxWhile.pnodeCond,indentAmt+INDENT_SIZE);
  11391. PrintPnodeWIndent(pnode->sxWhile.pnodeBody,indentAmt+INDENT_SIZE);
  11392. break;
  11393. //PTNODE(knopForIn , "for in" ,None ,ForIn,fnopBreak|fnopContinue|fnopCleanup)
  11394. case knopForIn:
  11395. Indent(indentAmt);
  11396. Output::Print(_u("forIn\n"));
  11397. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  11398. PrintPnodeWIndent(pnode->sxForInOrForOf.pnodeLval,indentAmt+INDENT_SIZE);
  11399. PrintPnodeWIndent(pnode->sxForInOrForOf.pnodeObj,indentAmt+INDENT_SIZE);
  11400. PrintPnodeWIndent(pnode->sxForInOrForOf.pnodeBody,indentAmt+INDENT_SIZE);
  11401. break;
  11402. case knopForOf:
  11403. Indent(indentAmt);
  11404. Output::Print(_u("forOf\n"));
  11405. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  11406. PrintPnodeWIndent(pnode->sxForInOrForOf.pnodeLval,indentAmt+INDENT_SIZE);
  11407. PrintPnodeWIndent(pnode->sxForInOrForOf.pnodeObj,indentAmt+INDENT_SIZE);
  11408. PrintPnodeWIndent(pnode->sxForInOrForOf.pnodeBody,indentAmt+INDENT_SIZE);
  11409. break;
  11410. //PTNODE(knopReturn , "return" ,None ,Uni ,fnopNone)
  11411. case knopReturn:
  11412. Indent(indentAmt);
  11413. Output::Print(_u("return\n"));
  11414. if (pnode->sxReturn.pnodeExpr!=NULL)
  11415. PrintPnodeWIndent(pnode->sxReturn.pnodeExpr,indentAmt+INDENT_SIZE);
  11416. break;
  11417. //PTNODE(knopBlock , "{}" ,None ,Block,fnopNone)
  11418. case knopBlock:
  11419. Indent(indentAmt);
  11420. Output::Print(_u("block "));
  11421. if (pnode->grfpn & fpnSyntheticNode)
  11422. Output::Print(_u("synthetic "));
  11423. PrintBlockType(pnode->sxBlock.blockType);
  11424. Output::Print(_u("(%d-%d)\n"),pnode->ichMin,pnode->ichLim);
  11425. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  11426. if (pnode->sxBlock.pnodeStmt!=NULL)
  11427. PrintPnodeWIndent(pnode->sxBlock.pnodeStmt,indentAmt+INDENT_SIZE);
  11428. break;
  11429. //PTNODE(knopWith , "with" ,None ,With ,fnopCleanup)
  11430. case knopWith:
  11431. Indent(indentAmt);
  11432. Output::Print(_u("with (%d-%d)\n"), pnode->ichMin,pnode->ichLim);
  11433. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  11434. PrintPnodeWIndent(pnode->sxWith.pnodeObj,indentAmt+INDENT_SIZE);
  11435. PrintPnodeWIndent(pnode->sxWith.pnodeBody,indentAmt+INDENT_SIZE);
  11436. break;
  11437. //PTNODE(knopBreak , "break" ,None ,Jump ,fnopNone)
  11438. case knopBreak:
  11439. Indent(indentAmt);
  11440. Output::Print(_u("break\n"));
  11441. // TODO: some representation of target
  11442. break;
  11443. //PTNODE(knopContinue , "continue" ,None ,Jump ,fnopNone)
  11444. case knopContinue:
  11445. Indent(indentAmt);
  11446. Output::Print(_u("continue\n"));
  11447. // TODO: some representation of target
  11448. break;
  11449. //PTNODE(knopLabel , "label" ,None ,Label,fnopNone)
  11450. case knopLabel:
  11451. Indent(indentAmt);
  11452. Output::Print(_u("label %s"),pnode->sxLabel.pid->Psz());
  11453. // TODO: print labeled statement
  11454. break;
  11455. //PTNODE(knopSwitch , "switch" ,None ,Switch,fnopBreak)
  11456. case knopSwitch:
  11457. Indent(indentAmt);
  11458. Output::Print(_u("switch\n"));
  11459. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  11460. for (ParseNode *pnodeT = pnode->sxSwitch.pnodeCases; NULL != pnodeT;pnodeT = pnodeT->sxCase.pnodeNext) {
  11461. PrintPnodeWIndent(pnodeT,indentAmt+2);
  11462. }
  11463. break;
  11464. //PTNODE(knopCase , "case" ,None ,Case ,fnopNone)
  11465. case knopCase:
  11466. Indent(indentAmt);
  11467. Output::Print(_u("case\n"));
  11468. PrintPnodeWIndent(pnode->sxCase.pnodeExpr,indentAmt+INDENT_SIZE);
  11469. PrintPnodeWIndent(pnode->sxCase.pnodeBody,indentAmt+INDENT_SIZE);
  11470. break;
  11471. //PTNODE(knopTryFinally,"try-finally",None,TryFinally,fnopCleanup)
  11472. case knopTryFinally:
  11473. PrintPnodeWIndent(pnode->sxTryFinally.pnodeTry,indentAmt);
  11474. PrintPnodeWIndent(pnode->sxTryFinally.pnodeFinally,indentAmt);
  11475. break;
  11476. case knopFinally:
  11477. Indent(indentAmt);
  11478. Output::Print(_u("finally\n"));
  11479. PrintPnodeWIndent(pnode->sxFinally.pnodeBody,indentAmt+INDENT_SIZE);
  11480. break;
  11481. //PTNODE(knopCatch , "catch" ,None ,Catch,fnopNone)
  11482. case knopCatch:
  11483. Indent(indentAmt);
  11484. Output::Print(_u("catch (%d-%d)\n"), pnode->ichMin,pnode->ichLim);
  11485. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  11486. PrintPnodeWIndent(pnode->sxCatch.pnodeParam,indentAmt+INDENT_SIZE);
  11487. // if (pnode->sxCatch.pnodeGuard!=NULL)
  11488. // PrintPnodeWIndent(pnode->sxCatch.pnodeGuard,indentAmt+INDENT_SIZE);
  11489. PrintPnodeWIndent(pnode->sxCatch.pnodeBody,indentAmt+INDENT_SIZE);
  11490. break;
  11491. //PTNODE(knopTryCatch , "try-catch" ,None ,TryCatch ,fnopCleanup)
  11492. case knopTryCatch:
  11493. PrintPnodeWIndent(pnode->sxTryCatch.pnodeTry,indentAmt);
  11494. PrintPnodeWIndent(pnode->sxTryCatch.pnodeCatch,indentAmt);
  11495. break;
  11496. //PTNODE(knopTry , "try" ,None ,Try ,fnopCleanup)
  11497. case knopTry:
  11498. Indent(indentAmt);
  11499. Output::Print(_u("try\n"));
  11500. PrintPnodeWIndent(pnode->sxTry.pnodeBody,indentAmt+INDENT_SIZE);
  11501. break;
  11502. //PTNODE(knopThrow , "throw" ,None ,Uni ,fnopNone)
  11503. case knopThrow:
  11504. Indent(indentAmt);
  11505. Output::Print(_u("throw\n"));
  11506. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  11507. break;
  11508. //PTNODE(knopClassDecl, "classDecl", None , Class, fnopLeaf)
  11509. case knopClassDecl:
  11510. Indent(indentAmt);
  11511. Output::Print(_u("class %s"), pnode->sxClass.pnodeName->sxVar.pid->Psz());
  11512. if (pnode->sxClass.pnodeExtends != nullptr)
  11513. {
  11514. Output::Print(_u(" extends "));
  11515. PrintPnodeWIndent(pnode->sxClass.pnodeExtends, 0);
  11516. }
  11517. else {
  11518. Output::Print(_u("\n"));
  11519. }
  11520. PrintPnodeWIndent(pnode->sxClass.pnodeConstructor, indentAmt + INDENT_SIZE);
  11521. PrintPnodeWIndent(pnode->sxClass.pnodeMembers, indentAmt + INDENT_SIZE);
  11522. PrintPnodeWIndent(pnode->sxClass.pnodeStaticMembers, indentAmt + INDENT_SIZE);
  11523. break;
  11524. case knopStrTemplate:
  11525. Indent(indentAmt);
  11526. Output::Print(_u("string template\n"));
  11527. PrintPnodeListWIndent(pnode->sxStrTemplate.pnodeSubstitutionExpressions, indentAmt + INDENT_SIZE);
  11528. break;
  11529. case knopYieldStar:
  11530. Indent(indentAmt);
  11531. Output::Print(_u("yield*\n"));
  11532. PrintPnodeListWIndent(pnode->sxUni.pnode1, indentAmt + INDENT_SIZE);
  11533. break;
  11534. case knopYield:
  11535. case knopYieldLeaf:
  11536. Indent(indentAmt);
  11537. Output::Print(_u("yield\n"));
  11538. PrintPnodeListWIndent(pnode->sxUni.pnode1, indentAmt + INDENT_SIZE);
  11539. break;
  11540. case knopAwait:
  11541. Indent(indentAmt);
  11542. Output::Print(_u("await\n"));
  11543. PrintPnodeListWIndent(pnode->sxUni.pnode1, indentAmt + INDENT_SIZE);
  11544. break;
  11545. case knopExportDefault:
  11546. Indent(indentAmt);
  11547. Output::Print(_u("export default\n"));
  11548. PrintPnodeListWIndent(pnode->sxExportDefault.pnodeExpr, indentAmt + INDENT_SIZE);
  11549. break;
  11550. default:
  11551. Output::Print(_u("unhandled pnode op %d\n"),pnode->nop);
  11552. break;
  11553. }
  11554. }
  11555. void PrintPnodeListWIndent(ParseNode *pnode,int indentAmt) {
  11556. if (pnode!=NULL) {
  11557. while(pnode->nop==knopList) {
  11558. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt);
  11559. pnode = pnode->sxBin.pnode2;
  11560. }
  11561. PrintPnodeWIndent(pnode,indentAmt);
  11562. }
  11563. }
  11564. void PrintFormalsWIndent(ParseNode *pnodeArgs, int indentAmt)
  11565. {
  11566. for (ParseNode *pnode = pnodeArgs; pnode != nullptr; pnode = pnode->GetFormalNext())
  11567. {
  11568. PrintPnodeWIndent(pnode->nop == knopParamPattern ? pnode->sxParamPattern.pnode1 : pnode, indentAmt);
  11569. }
  11570. }
  11571. void PrintPnode(ParseNode *pnode) {
  11572. PrintPnodeWIndent(pnode,0);
  11573. }
  11574. void ParseNode::Dump()
  11575. {
  11576. switch(nop)
  11577. {
  11578. case knopFncDecl:
  11579. case knopProg:
  11580. LPCOLESTR name = Js::Constants::AnonymousFunction;
  11581. if(this->sxFnc.pnodeName)
  11582. {
  11583. name = this->sxFnc.pnodeName->sxVar.pid->Psz();
  11584. }
  11585. Output::Print(_u("%s (%d) [%d, %d]:\n"), name, this->sxFnc.functionId, this->sxFnc.lineNumber, this->sxFnc.columnNumber);
  11586. Output::Print(_u("hasArguments: %s callsEval:%s childCallsEval:%s HasReferenceableBuiltInArguments:%s ArgumentsObjectEscapes:%s HasWith:%s HasThis:%s HasOnlyThis:%s \n"),
  11587. IsTrueOrFalse(this->sxFnc.HasHeapArguments()),
  11588. IsTrueOrFalse(this->sxFnc.CallsEval()),
  11589. IsTrueOrFalse(this->sxFnc.ChildCallsEval()),
  11590. IsTrueOrFalse(this->sxFnc.HasReferenceableBuiltInArguments()),
  11591. IsTrueOrFalse(this->sxFnc.GetArgumentsObjectEscapes()),
  11592. IsTrueOrFalse(this->sxFnc.HasWithStmt()),
  11593. IsTrueOrFalse(this->sxFnc.HasThisStmt()),
  11594. IsTrueOrFalse(this->sxFnc.HasOnlyThisStmts()));
  11595. if(this->sxFnc.funcInfo)
  11596. {
  11597. this->sxFnc.funcInfo->Dump();
  11598. }
  11599. break;
  11600. }
  11601. }
  11602. #endif
  11603. DeferredFunctionStub * BuildDeferredStubTree(ParseNode *pnodeFnc, Recycler *recycler)
  11604. {
  11605. Assert(pnodeFnc->nop == knopFncDecl);
  11606. uint nestedCount = pnodeFnc->sxFnc.nestedCount;
  11607. if (nestedCount == 0)
  11608. {
  11609. return nullptr;
  11610. }
  11611. if (pnodeFnc->sxFnc.deferredStub)
  11612. {
  11613. return pnodeFnc->sxFnc.deferredStub;
  11614. }
  11615. DeferredFunctionStub *deferredStubs = RecyclerNewArray(recycler, DeferredFunctionStub, nestedCount);
  11616. uint i = 0;
  11617. ParseNode *pnodeBlock = pnodeFnc->sxFnc.pnodeBodyScope;
  11618. Assert(pnodeBlock != nullptr
  11619. && pnodeBlock->nop == knopBlock
  11620. && (pnodeBlock->sxBlock.blockType == PnodeBlockType::Function
  11621. || pnodeBlock->sxBlock.blockType == PnodeBlockType::Parameter));
  11622. for (ParseNode *pnodeChild = pnodeBlock->sxBlock.pnodeScopes; pnodeChild != nullptr;)
  11623. {
  11624. if (pnodeChild->nop != knopFncDecl)
  11625. {
  11626. // We only expect to find a function body block in a parameter scope block.
  11627. Assert(pnodeChild->nop == knopBlock
  11628. && (pnodeBlock->sxBlock.blockType == PnodeBlockType::Parameter
  11629. || pnodeChild->sxBlock.blockType == PnodeBlockType::Function));
  11630. pnodeChild = pnodeChild->sxBlock.pnodeNext;
  11631. continue;
  11632. }
  11633. Assert(i < nestedCount);
  11634. if (pnodeChild->sxFnc.IsGeneratedDefault())
  11635. {
  11636. ++i;
  11637. pnodeChild = pnodeChild->sxFnc.pnodeNext;
  11638. continue;
  11639. }
  11640. __analysis_assume(i < nestedCount);
  11641. deferredStubs[i].fncFlags = pnodeChild->sxFnc.fncFlags;
  11642. deferredStubs[i].nestedCount = pnodeChild->sxFnc.nestedCount;
  11643. deferredStubs[i].restorePoint = *pnodeChild->sxFnc.pRestorePoint;
  11644. deferredStubs[i].deferredStubs = BuildDeferredStubTree(pnodeChild, recycler);
  11645. deferredStubs[i].ichMin = pnodeChild->ichMin;
  11646. ++i;
  11647. pnodeChild = pnodeChild->sxFnc.pnodeNext;
  11648. }
  11649. return deferredStubs;
  11650. }