CeMachine.cpp 317 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909
  1. #include "CeMachine.h"
  2. #include "CeDebugger.h"
  3. #include "BfModule.h"
  4. #include "BfCompiler.h"
  5. #include "BfIRBuilder.h"
  6. #include "BfParser.h"
  7. #include "BfReducer.h"
  8. #include "BfExprEvaluator.h"
  9. #include "BfResolvePass.h"
  10. #include "BfMangler.h"
  11. #include "../Backend/BeIRCodeGen.h"
  12. #include "BeefySysLib/platform/PlatformHelper.h"
  13. #include "../DebugManager.h"
  14. #include "BeefySysLib/util/StackHelper.h"
  15. extern "C"
  16. {
  17. #include "BeefySysLib/third_party/utf8proc/utf8proc.h"
  18. }
  19. #define CE_ENABLE_HEAP
  20. USING_NS_BF;
  21. enum CeOpInfoFlag
  22. {
  23. CeOpInfoFlag_None,
  24. CeOpInfoFlag_SizeX,
  25. };
  26. struct CeOpInfo
  27. {
  28. const char* mName;
  29. CeOperandInfoKind mResultKind;
  30. CeOperandInfoKind mOperandA;
  31. CeOperandInfoKind mOperandB;
  32. CeOperandInfoKind mOperandC;
  33. CeOpInfoFlag mFlags;
  34. };
  35. #define CEOPINFO_SIZED_1(OPNAME, OPINFOA) \
  36. {OPNAME "_8", OPINFOA##8}, \
  37. {OPNAME "_16", OPINFOA##16}, \
  38. {OPNAME "_32", OPINFOA##32}, \
  39. {OPNAME "_64", OPINFOA##64}, \
  40. {OPNAME "_X", OPINFOA, CEOI_None, CEOI_None, CEOI_None, CeOpInfoFlag_SizeX}
  41. #define CEOPINFO_SIZED_2(OPNAME, OPINFOA, OPINFOB) \
  42. {OPNAME "_8", OPINFOA##8, OPINFOB##8}, \
  43. {OPNAME "_16", OPINFOA##16, OPINFOB##16}, \
  44. {OPNAME "_32", OPINFOA##32, OPINFOB##32}, \
  45. {OPNAME "_64", OPINFOA##64, OPINFOB##64}, \
  46. {OPNAME "_X", OPINFOA, OPINFOB, CEOI_None, CEOI_None, CeOpInfoFlag_SizeX}
  47. #define CEOPINFO_SIZED_3(OPNAME, OPINFOA, OPINFOB, OPINFOC) \
  48. {OPNAME "_8", OPINFOA##8, OPINFOB##8, OPINFOC##8}, \
  49. {OPNAME "_16", OPINFOA##16, OPINFOB##16, OPINFOC##16}, \
  50. {OPNAME "_32", OPINFOA##32, OPINFOB##32, OPINFOC##32}, \
  51. {OPNAME "_64", OPINFOA##64, OPINFOB##64, OPINFOC##64}, \
  52. {OPNAME "_X", OPINFOA, OPINFOB, OPINFOC, CEOI_None, CeOpInfoFlag_SizeX}
  53. #define CEOPINFO_SIZED_NUMERIC_2(OPNAME, OPINFOA, OPINFOB) \
  54. {OPNAME "_I8", OPINFOA##8, OPINFOB##8}, \
  55. {OPNAME "_I16", OPINFOA##16, OPINFOB##16}, \
  56. {OPNAME "_I32", OPINFOA##32, OPINFOB##32}, \
  57. {OPNAME "_I64", OPINFOA##64, OPINFOB##64}
  58. #define CEOPINFO_SIZED_NUMERIC_PLUSF_2(OPNAME, OPINFOA, OPINFOB) \
  59. {OPNAME "_I8", OPINFOA##8, OPINFOB##8}, \
  60. {OPNAME "_I16", OPINFOA##16, OPINFOB##16}, \
  61. {OPNAME "_I32", OPINFOA##32, OPINFOB##32}, \
  62. {OPNAME "_I64", OPINFOA##64, OPINFOB##64}, \
  63. {OPNAME "_F32", OPINFOA##F32, OPINFOB##F64}, \
  64. {OPNAME "_F64", OPINFOA##F64, OPINFOB##F64}
  65. #define CEOPINFO_SIZED_NUMERIC_PLUSF_2_RESULT8(OPNAME, OPINFOA, OPINFOB) \
  66. {OPNAME "_I8", OPINFOA##8, OPINFOB##8}, \
  67. {OPNAME "_I16", OPINFOA##8, OPINFOB##16}, \
  68. {OPNAME "_I32", OPINFOA##8, OPINFOB##32}, \
  69. {OPNAME "_I64", OPINFOA##8, OPINFOB##64}, \
  70. {OPNAME "_F32", OPINFOA##8, OPINFOB##F64}, \
  71. {OPNAME "_F64", OPINFOA##8, OPINFOB##F64}
  72. #define CEOPINFO_SIZED_NUMERIC_3(OPNAME, OPINFOA, OPINFOB, OPINFOC) \
  73. {OPNAME "_I8", OPINFOA##8, OPINFOB##8, OPINFOC##8}, \
  74. {OPNAME "_I16", OPINFOA##16, OPINFOB##16, OPINFOC##16}, \
  75. {OPNAME "_I32", OPINFOA##32, OPINFOB##32, OPINFOC##32}, \
  76. {OPNAME "_I64", OPINFOA##64, OPINFOB##64, OPINFOC##64}
  77. #define CEOPINFO_SIZED_NUMERIC_3_RESULT8(OPNAME, OPINFOA, OPINFOB, OPINFOC) \
  78. {OPNAME "_I8", OPINFOA##8, OPINFOB##8, OPINFOC##8}, \
  79. {OPNAME "_I16", OPINFOA##8, OPINFOB##16, OPINFOC##16}, \
  80. {OPNAME "_I32", OPINFOA##8, OPINFOB##32, OPINFOC##32}, \
  81. {OPNAME "_I64", OPINFOA##8, OPINFOB##64, OPINFOC##64}
  82. #define CEOPINFO_SIZED_UNUMERIC_3(OPNAME, OPINFOA, OPINFOB, OPINFOC) \
  83. {OPNAME "_U8", OPINFOA##8, OPINFOB##8, OPINFOC##8}, \
  84. {OPNAME "_U16", OPINFOA##16, OPINFOB##16, OPINFOC##16}, \
  85. {OPNAME "_U32", OPINFOA##32, OPINFOB##32, OPINFOC##32}, \
  86. {OPNAME "_U64", OPINFOA##64, OPINFOB##64, OPINFOC##64}
  87. #define CEOPINFO_SIZED_NUMERIC_PLUSF_3(OPNAME, OPINFOA, OPINFOB, OPINFOC) \
  88. {OPNAME "_I8", OPINFOA##8, OPINFOB##8, OPINFOC##8}, \
  89. {OPNAME "_I16", OPINFOA##16, OPINFOB##16, OPINFOC##16}, \
  90. {OPNAME "_I32", OPINFOA##32, OPINFOB##32, OPINFOC##32}, \
  91. {OPNAME "_I64", OPINFOA##64, OPINFOB##64, OPINFOC##64}, \
  92. {OPNAME "_F32", OPINFOA##F32, OPINFOB##F32, OPINFOC##F32}, \
  93. {OPNAME "_F64", OPINFOA##F64, OPINFOB##F64, OPINFOC##F64}
  94. #define CEOPINFO_SIZED_NUMERIC_PLUSF_3_RESULT8(OPNAME, OPINFOA, OPINFOB, OPINFOC) \
  95. {OPNAME "_I8", OPINFOA##8, OPINFOB##8, OPINFOC##8}, \
  96. {OPNAME "_I16", OPINFOA##8, OPINFOB##16, OPINFOC##16}, \
  97. {OPNAME "_I32", OPINFOA##8, OPINFOB##32, OPINFOC##32}, \
  98. {OPNAME "_I64", OPINFOA##8, OPINFOB##64, OPINFOC##64}, \
  99. {OPNAME "_F32", OPINFOA##8, OPINFOB##F32, OPINFOC##F32}, \
  100. {OPNAME "_F64", OPINFOA##8, OPINFOB##F64, OPINFOC##F64}
  101. #define CEOPINFO_SIZED_FLOAT_2(OPNAME, OPINFOA, OPINFOB) \
  102. {OPNAME "_F32", OPINFOA##F32, OPINFOB##F32}, \
  103. {OPNAME "_F64", OPINFOA##F64, OPINFOB##F64}
  104. #define CEOPINFO_SIZED_FLOAT_3(OPNAME, OPINFOA, OPINFOB, OPINFOC) \
  105. {OPNAME "_F32", OPINFOA##F32, OPINFOB##F32, OPINFOC##F32}, \
  106. {OPNAME "_F64", OPINFOA##F64, OPINFOB##F64, OPINFOC##F64}
  107. static CeOpInfo gOpInfo[] =
  108. {
  109. {"InvalidOp"},
  110. {"Nop"},
  111. {"DbgBreak"},
  112. {"Ret"},
  113. {"SetRet", CEOI_None, CEOI_IMM32},
  114. {"Jmp", CEOI_None, CEOI_JMPREL},
  115. {"JmpIf", CEOI_None, CEOI_JMPREL, CEOI_FrameRef8},
  116. {"JmpIfNot", CEOI_None, CEOI_JMPREL, CEOI_FrameRef8},
  117. {"Error", CEOI_None, CEOI_IMM32},
  118. {"DynamicCastCheck", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM32},
  119. {"GetReflectType", CEOI_FrameRef, CEOI_IMM32},
  120. {"GetString", CEOI_FrameRef, CEOI_IMM32},
  121. {"Malloc", CEOI_FrameRef, CEOI_FrameRef},
  122. {"Free", CEOI_None, CEOI_FrameRef},
  123. {"MemSet", CEOI_None, CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef},
  124. {"MemSet_Const", CEOI_None, CEOI_FrameRef, CEOI_IMM8, CEOI_IMM32},
  125. {"MemCpy", CEOI_None, CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef},
  126. {"FrameAddr_32", CEOI_FrameRef, CEOI_FrameRef},
  127. {"FrameAddr_64", CEOI_FrameRef, CEOI_FrameRef},
  128. {"FrameAddrOfs_32", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM32},
  129. {"ConstData", CEOI_FrameRef, CEOI_IMM32},
  130. {"ConstDataRef", CEOI_FrameRef, CEOI_IMM32},
  131. {"Zero", CEOI_None, CEOI_FrameRef, CEOI_IMM32},
  132. {"Const_8", CEOI_FrameRef8, CEOI_IMM8},
  133. {"Const_16", CEOI_FrameRef16, CEOI_IMM16},
  134. {"Const_32", CEOI_FrameRef32, CEOI_IMM32},
  135. {"Const_64", CEOI_FrameRef64, CEOI_IMM64},
  136. {"Const_X", CEOI_FrameRef, CEOI_IMM_VAR},
  137. CEOPINFO_SIZED_2("Load", CEOI_FrameRef, CEOI_FrameRef),
  138. CEOPINFO_SIZED_3("Store", CEOI_None, CEOI_FrameRef, CEOI_FrameRef),
  139. CEOPINFO_SIZED_3("Move", CEOI_None, CEOI_FrameRef, CEOI_FrameRef),
  140. CEOPINFO_SIZED_2("Push", CEOI_None, CEOI_FrameRef),
  141. CEOPINFO_SIZED_1("Pop", CEOI_FrameRef),
  142. {"AdjustSP", CEOI_None, CEOI_FrameRef},
  143. {"AdjustSPNeg", CEOI_None, CEOI_FrameRef},
  144. {"AdjustSPConst", CEOI_None, CEOI_IMM32},
  145. {"CeOp_GetSP", CEOI_FrameRef},
  146. {"CeOp_SetSP", CEOI_None, CEOI_FrameRef},
  147. {"GetStaticField", CEOI_FrameRef, CEOI_IMM32},
  148. {"GetStaticField_Initializer", CEOI_FrameRef, CEOI_IMM32, CEOI_FrameRef},
  149. {"GetMethod", CEOI_FrameRef, CEOI_IMM32},
  150. {"GetMethod_Inner", CEOI_FrameRef, CEOI_IMM32},
  151. {"GetMethod_Virt", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM32},
  152. {"GetMethod_IFace", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM32, CEOI_IMM32},
  153. {"Call", CEOI_None, CEOI_FrameRef},
  154. {"CeOp_Conv_I8_I16", CEOI_FrameRef16, CEOI_FrameRef8},
  155. {"CeOp_Conv_I8_I32", CEOI_FrameRef32, CEOI_FrameRef8},
  156. {"CeOp_Conv_I8_I64", CEOI_FrameRef64, CEOI_FrameRef8},
  157. {"CeOp_Conv_I8_F32", CEOI_FrameRefF32, CEOI_FrameRef8},
  158. {"CeOp_Conv_I8_F64", CEOI_FrameRefF64, CEOI_FrameRef8},
  159. {"CeOp_Conv_I16_I32", CEOI_FrameRef32, CEOI_FrameRef16},
  160. {"CeOp_Conv_I16_I64", CEOI_FrameRef64, CEOI_FrameRef16},
  161. {"CeOp_Conv_I16_F32", CEOI_FrameRefF32, CEOI_FrameRef16},
  162. {"CeOp_Conv_I16_F64", CEOI_FrameRefF64, CEOI_FrameRef16},
  163. {"CeOp_Conv_I32_I64", CEOI_FrameRef64, CEOI_FrameRef32},
  164. {"CeOp_Conv_I32_F32", CEOI_FrameRefF32, CEOI_FrameRef32},
  165. {"CeOp_Conv_I32_F64", CEOI_FrameRefF64, CEOI_FrameRef32},
  166. {"CeOp_Conv_I64_F32", CEOI_FrameRefF32, CEOI_FrameRef64},
  167. {"CeOp_Conv_I64_F64", CEOI_FrameRefF64, CEOI_FrameRef64},
  168. {"CeOp_Conv_U8_U16", CEOI_FrameRef16, CEOI_FrameRef8},
  169. {"CeOp_Conv_U8_U32", CEOI_FrameRef32, CEOI_FrameRef8},
  170. {"CeOp_Conv_U8_U64", CEOI_FrameRef64, CEOI_FrameRef8},
  171. {"CeOp_Conv_U8_F32", CEOI_FrameRefF32, CEOI_FrameRef8},
  172. {"CeOp_Conv_U8_F64", CEOI_FrameRefF64, CEOI_FrameRef8},
  173. {"CeOp_Conv_U16_U32", CEOI_FrameRef32, CEOI_FrameRef16},
  174. {"CeOp_Conv_U16_U64", CEOI_FrameRef64, CEOI_FrameRef16},
  175. {"CeOp_Conv_U16_F32", CEOI_FrameRefF32, CEOI_FrameRef16},
  176. {"CeOp_Conv_U16_F64", CEOI_FrameRefF64, CEOI_FrameRef16},
  177. {"CeOp_Conv_U32_U64", CEOI_FrameRef64, CEOI_FrameRef32},
  178. {"CeOp_Conv_U32_F32", CEOI_FrameRefF32, CEOI_FrameRef32},
  179. {"CeOp_Conv_U32_F64", CEOI_FrameRefF64, CEOI_FrameRef32},
  180. {"CeOp_Conv_U64_F32", CEOI_FrameRefF32, CEOI_FrameRef64},
  181. {"CeOp_Conv_U64_F64", CEOI_FrameRefF64, CEOI_FrameRef64},
  182. {"CeOp_Conv_F32_I8", CEOI_FrameRef8, CEOI_FrameRefF32},
  183. {"CeOp_Conv_F32_I16", CEOI_FrameRef16, CEOI_FrameRefF32},
  184. {"CeOp_Conv_F32_I32", CEOI_FrameRef32, CEOI_FrameRefF32},
  185. {"CeOp_Conv_F32_I64", CEOI_FrameRef64, CEOI_FrameRefF32},
  186. {"CeOp_Conv_F32_U8", CEOI_FrameRef8, CEOI_FrameRefF32},
  187. {"CeOp_Conv_F32_U16", CEOI_FrameRef16, CEOI_FrameRefF32},
  188. {"CeOp_Conv_F32_U32", CEOI_FrameRef32, CEOI_FrameRefF32},
  189. {"CeOp_Conv_F32_U64", CEOI_FrameRef64, CEOI_FrameRefF32},
  190. {"CeOp_Conv_F32_F64", CEOI_FrameRefF64, CEOI_FrameRefF32},
  191. {"CeOp_Conv_F64_I8", CEOI_FrameRef8, CEOI_FrameRefF64},
  192. {"CeOp_Conv_F64_I16", CEOI_FrameRef16, CEOI_FrameRefF64},
  193. {"CeOp_Conv_F64_I32", CEOI_FrameRef32, CEOI_FrameRefF64},
  194. {"CeOp_Conv_F64_I64", CEOI_FrameRef64, CEOI_FrameRefF64},
  195. {"CeOp_Conv_F64_U8", CEOI_FrameRef8, CEOI_FrameRefF64},
  196. {"CeOp_Conv_F64_U16", CEOI_FrameRef16, CEOI_FrameRefF64},
  197. {"CeOp_Conv_F64_U32", CEOI_FrameRef32, CEOI_FrameRefF64},
  198. {"CeOp_Conv_F64_U64", CEOI_FrameRef64, CEOI_FrameRefF64},
  199. {"CeOp_Conv_F64_F32", CEOI_FrameRefF32, CEOI_FrameRefF64},
  200. CEOPINFO_SIZED_NUMERIC_PLUSF_2("Abs", CEOI_FrameRef, CEOI_FrameRef),
  201. {"AddConst_I8", CEOI_FrameRef8, CEOI_FrameRef8, CEOI_IMM8},
  202. {"AddConst_I16", CEOI_FrameRef16, CEOI_FrameRef16, CEOI_IMM16},
  203. {"AddConst_I32", CEOI_FrameRef32, CEOI_FrameRef32, CEOI_IMM32},
  204. {"AddConst_I64", CEOI_FrameRef64, CEOI_FrameRef64, CEOI_IMM64},
  205. {"AddConst_F32", CEOI_FrameRefF32, CEOI_FrameRefF32, CEOI_IMMF32},
  206. {"AddConst_F64", CEOI_FrameRefF64, CEOI_FrameRefF64, CEOI_IMMF64},
  207. CEOPINFO_SIZED_NUMERIC_PLUSF_3("Add", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  208. CEOPINFO_SIZED_NUMERIC_PLUSF_3("Sub", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  209. CEOPINFO_SIZED_NUMERIC_PLUSF_3("Mul", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  210. CEOPINFO_SIZED_NUMERIC_PLUSF_3("SDiv", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  211. CEOPINFO_SIZED_NUMERIC_3("UDiv", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  212. CEOPINFO_SIZED_NUMERIC_PLUSF_3("SMod", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  213. CEOPINFO_SIZED_NUMERIC_3("UMod", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  214. CEOPINFO_SIZED_NUMERIC_3("And", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  215. CEOPINFO_SIZED_NUMERIC_3("Or", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  216. CEOPINFO_SIZED_NUMERIC_3("Xor", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  217. CEOPINFO_SIZED_NUMERIC_3("Shl", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  218. CEOPINFO_SIZED_NUMERIC_3("Shr", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  219. CEOPINFO_SIZED_UNUMERIC_3("Shr", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  220. CEOPINFO_SIZED_FLOAT_2("Acos", CEOI_FrameRef, CEOI_FrameRef),
  221. CEOPINFO_SIZED_FLOAT_2("Asin", CEOI_FrameRef, CEOI_FrameRef),
  222. CEOPINFO_SIZED_FLOAT_2("Atan", CEOI_FrameRef, CEOI_FrameRef),
  223. CEOPINFO_SIZED_FLOAT_3("Atan2", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  224. CEOPINFO_SIZED_FLOAT_2("Ceiling", CEOI_FrameRef, CEOI_FrameRef),
  225. CEOPINFO_SIZED_FLOAT_2("Cos", CEOI_FrameRef, CEOI_FrameRef),
  226. CEOPINFO_SIZED_FLOAT_2("Cosh", CEOI_FrameRef, CEOI_FrameRef),
  227. CEOPINFO_SIZED_FLOAT_2("Exp", CEOI_FrameRef, CEOI_FrameRef),
  228. CEOPINFO_SIZED_FLOAT_2("Floor", CEOI_FrameRef, CEOI_FrameRef),
  229. CEOPINFO_SIZED_FLOAT_2("Log", CEOI_FrameRef, CEOI_FrameRef),
  230. CEOPINFO_SIZED_FLOAT_2("Log10", CEOI_FrameRef, CEOI_FrameRef),
  231. CEOPINFO_SIZED_FLOAT_3("Pow", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  232. CEOPINFO_SIZED_FLOAT_2("Round", CEOI_FrameRef, CEOI_FrameRef),
  233. CEOPINFO_SIZED_FLOAT_2("Sin", CEOI_FrameRef, CEOI_FrameRef),
  234. CEOPINFO_SIZED_FLOAT_2("Sinh", CEOI_FrameRef, CEOI_FrameRef),
  235. CEOPINFO_SIZED_FLOAT_2("Sqrt", CEOI_FrameRef, CEOI_FrameRef),
  236. CEOPINFO_SIZED_FLOAT_2("Tan", CEOI_FrameRef, CEOI_FrameRef),
  237. CEOPINFO_SIZED_FLOAT_2("Tanh", CEOI_FrameRef, CEOI_FrameRef),
  238. CEOPINFO_SIZED_NUMERIC_PLUSF_3_RESULT8("Cmp_EQ", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  239. CEOPINFO_SIZED_NUMERIC_PLUSF_3_RESULT8("Cmp_NE", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  240. CEOPINFO_SIZED_NUMERIC_PLUSF_3_RESULT8("Cmp_SLT", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  241. CEOPINFO_SIZED_NUMERIC_3_RESULT8("Cmp_ULT", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  242. CEOPINFO_SIZED_NUMERIC_PLUSF_3_RESULT8("Cmp_SLE", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  243. CEOPINFO_SIZED_NUMERIC_3_RESULT8("Cmp_ULE", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  244. CEOPINFO_SIZED_NUMERIC_PLUSF_3_RESULT8("Cmp_SGT", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  245. CEOPINFO_SIZED_NUMERIC_3_RESULT8("Cmp_UGT", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  246. CEOPINFO_SIZED_NUMERIC_PLUSF_3_RESULT8("Cmp_SGE", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  247. CEOPINFO_SIZED_NUMERIC_3_RESULT8("Cmp_UGE", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
  248. CEOPINFO_SIZED_NUMERIC_PLUSF_2_RESULT8("Neg", CEOI_FrameRef, CEOI_FrameRef),
  249. {"Not_I1", CEOI_FrameRef8, CEOI_FrameRef8},
  250. CEOPINFO_SIZED_NUMERIC_2("Not", CEOI_FrameRef, CEOI_FrameRef),
  251. };
  252. static_assert(BF_ARRAY_COUNT(gOpInfo) == (int)CeOp_COUNT, "gOpName incorrect size");
  253. //////////////////////////////////////////////////////////////////////////
  254. static int ToString(float d, char* outStr, bool roundTrip)
  255. {
  256. if (!roundTrip)
  257. {
  258. int digits;
  259. if (d > 100000)
  260. digits = 1;
  261. else if (d > 10000)
  262. digits = 2;
  263. else if (d > 1000)
  264. digits = 3;
  265. else if (d > 100)
  266. digits = 4;
  267. else if (d > 10)
  268. digits = 5;
  269. else
  270. digits = 6;
  271. sprintf(outStr, "%1.*f", digits, d);
  272. }
  273. else
  274. sprintf(outStr, "%1.9g", d);
  275. int len = (int)strlen(outStr);
  276. for (int i = 0; outStr[i] != 0; i++)
  277. {
  278. if (outStr[i] == '.')
  279. {
  280. int checkC = len - 1;
  281. while (true)
  282. {
  283. char c = outStr[checkC];
  284. if (c == '.')
  285. {
  286. return checkC;
  287. }
  288. else if (c == 'e')
  289. {
  290. return len;
  291. }
  292. else if (c != '0')
  293. {
  294. for (int j = i + 1; j <= checkC; j++)
  295. if (outStr[j] == 'e')
  296. return len;
  297. return checkC + 1;
  298. }
  299. checkC--;
  300. }
  301. }
  302. }
  303. if ((len == 3) && (outStr[0] == 'i'))
  304. {
  305. strcpy(outStr, "Infinity");
  306. return 8;
  307. }
  308. if ((len == 4) && (outStr[0] == '-') && (outStr[1] == 'i'))
  309. {
  310. strcpy(outStr, "-Infinity");
  311. return 9;
  312. }
  313. if ((len == 9) && (outStr[0] == '-') && (outStr[1] == 'n')) //-nan(xxx)
  314. {
  315. strcpy(outStr, "NaN");
  316. return 3;
  317. }
  318. return len;
  319. }
  320. static int ToString(double d, char* outStr, bool roundTrip)
  321. {
  322. if (!roundTrip)
  323. {
  324. int digits;
  325. if (d < 0)
  326. {
  327. if (d < -10000000000)
  328. {
  329. sprintf(outStr, "%g", d);
  330. }
  331. else
  332. {
  333. if (d < -1000000000)
  334. digits = 1;
  335. else if (d < -100000000)
  336. digits = 2;
  337. else if (d < -10000000)
  338. digits = 3;
  339. else if (d < -1000000)
  340. digits = 4;
  341. else if (d < -100000)
  342. digits = 5;
  343. else if (d < -10000)
  344. digits = 6;
  345. else if (d < -1000)
  346. digits = 7;
  347. else if (d < -100)
  348. digits = 8;
  349. else if (d < -10)
  350. digits = 9;
  351. else
  352. digits = 10;
  353. sprintf(outStr, "%1.*f", digits, d);
  354. }
  355. }
  356. else
  357. {
  358. if (d > 10000000000)
  359. {
  360. sprintf(outStr, "%g", d);
  361. }
  362. else
  363. {
  364. if (d > 1000000000)
  365. digits = 1;
  366. else if (d > 100000000)
  367. digits = 2;
  368. else if (d > 10000000)
  369. digits = 3;
  370. else if (d > 1000000)
  371. digits = 4;
  372. else if (d > 100000)
  373. digits = 5;
  374. else if (d > 10000)
  375. digits = 6;
  376. else if (d > 1000)
  377. digits = 7;
  378. else if (d > 100)
  379. digits = 8;
  380. else if (d > 10)
  381. digits = 9;
  382. else
  383. digits = 10;
  384. sprintf(outStr, "%1.*f", digits, d);
  385. }
  386. }
  387. }
  388. else
  389. sprintf(outStr, "%1.17g", d);
  390. int len = (int)strlen(outStr);
  391. for (int i = 0; outStr[i] != 0; i++)
  392. {
  393. if (outStr[i] == '.')
  394. {
  395. int checkC = len - 1;
  396. while (true)
  397. {
  398. char c = outStr[checkC];
  399. if (c == '.')
  400. {
  401. return checkC;
  402. }
  403. else if (c == 'e')
  404. {
  405. return len;
  406. }
  407. else if (c != '0')
  408. {
  409. for (int j = i + 1; j <= checkC; j++)
  410. if (outStr[j] == 'e')
  411. return len;
  412. return checkC + 1;
  413. }
  414. checkC--;
  415. }
  416. }
  417. }
  418. if ((len == 3) && (outStr[0] == 'i'))
  419. {
  420. strcpy(outStr, "Infinity");
  421. return 8;
  422. }
  423. if ((len == 4) && (outStr[0] == '-') && (outStr[1] == 'i'))
  424. {
  425. strcpy(outStr, "-Infinity");
  426. return 9;
  427. }
  428. if ((len == 9) && (outStr[0] == '-') && (outStr[1] == 'n')) //-nan(xxx)
  429. {
  430. strcpy(outStr, "NaN");
  431. return 3;
  432. }
  433. return len;
  434. }
  435. static int FloatToString(float d, char* outStr)
  436. {
  437. return ::ToString(d, outStr, false);
  438. }
  439. static int DoubleToString(double d, char* outStr)
  440. {
  441. return ::ToString(d, outStr, false);
  442. }
  443. //////////////////////////////////////////////////////////////////////////
  444. String CeDbgMethodRef::ToString()
  445. {
  446. if (!mMethodRef)
  447. return mNameMod;
  448. BfMethodInstance* methodInstance = mMethodRef;
  449. auto module = methodInstance->GetOwner()->mModule;
  450. String name = module->MethodToString(methodInstance);
  451. if (!mNameMod.IsEmpty())
  452. {
  453. for (int i = 1; i < (int)name.length(); i++)
  454. {
  455. if (name[i] == '(')
  456. {
  457. char prevC = name[i - 1];
  458. if ((::isalnum((uint8)prevC)) || (prevC == '_'))
  459. {
  460. name.Insert(i, mNameMod);
  461. break;
  462. }
  463. }
  464. }
  465. }
  466. return name;
  467. }
  468. //////////////////////////////////////////////////////////////////////////
  469. CeInternalData::~CeInternalData()
  470. {
  471. switch (mKind)
  472. {
  473. case Kind_File:
  474. BfpFile_Release(mFile);
  475. break;
  476. case Kind_FindFileData:
  477. BfpFindFileData_Release(mFindFileData);
  478. break;
  479. case Kind_Spawn:
  480. BfpSpawn_Release(mSpawn);
  481. break;
  482. }
  483. }
  484. //////////////////////////////////////////////////////////////////////////
  485. CeFunction::~CeFunction()
  486. {
  487. BF_ASSERT(mId == -1);
  488. for (auto innerFunc : mInnerFunctions)
  489. delete innerFunc;
  490. delete mCeInnerFunctionInfo;
  491. delete mDbgInfo;
  492. BfLogSys(mCeMachine->mCompiler->mSystem, "CeFunction::~CeFunction %p\n", this);
  493. }
  494. BfTypeInstance* CeFunction::GetOwner()
  495. {
  496. if (mCeFunctionInfo != NULL)
  497. return mCeFunctionInfo->GetOwner();
  498. if (mCeInnerFunctionInfo != NULL)
  499. return mCeInnerFunctionInfo->mOwner->GetOwner();
  500. return NULL;
  501. }
  502. void CeFunction::Print()
  503. {
  504. CeDumpContext dumpCtx;
  505. dumpCtx.mCeFunction = this;
  506. dumpCtx.mStart = &mCode[0];
  507. dumpCtx.mPtr = dumpCtx.mStart;
  508. dumpCtx.mEnd = dumpCtx.mPtr + mCode.mSize;
  509. dumpCtx.Dump();
  510. String methodName;
  511. if (mMethodInstance != NULL)
  512. methodName = mMethodInstance->GetOwner()->mModule->MethodToString(mMethodInstance);
  513. OutputDebugStrF("Code for %s:\n%s\n", methodName.c_str(), dumpCtx.mStr.c_str());
  514. }
  515. void CeFunction::UnbindBreakpoints()
  516. {
  517. for (auto kv : mBreakpoints)
  518. mCode[kv.mKey] = kv.mValue.mPrevOpCode;
  519. mBreakpoints.Clear();
  520. }
  521. CeEmitEntry* CeFunction::FindEmitEntry(int instIdx, int* entryIdx)
  522. {
  523. int i = 0;
  524. CeEmitEntry* emitEntry = NULL;
  525. if (!mCode.IsEmpty())
  526. {
  527. int lo = 0;
  528. int hi = mEmitTable.size() - 1;
  529. while (lo <= hi)
  530. {
  531. i = (lo + hi) / 2;
  532. emitEntry = &mEmitTable.mVals[i];
  533. //int c = midVal <=> value;
  534. if (emitEntry->mCodePos == instIdx) break;
  535. if (emitEntry->mCodePos < instIdx)
  536. lo = i + 1;
  537. else
  538. hi = i - 1;
  539. }
  540. if ((emitEntry != NULL) && (emitEntry->mCodePos > instIdx) && (i > 0))
  541. {
  542. emitEntry = &mEmitTable.mVals[i - 1];
  543. if (entryIdx != NULL)
  544. *entryIdx = i - 1;
  545. }
  546. else if (entryIdx != NULL)
  547. *entryIdx = i;
  548. }
  549. return emitEntry;
  550. }
  551. // This is for "safe" retrieval from within CeDebugger
  552. int CeFunction::SafeGetId()
  553. {
  554. #ifdef BF_PLATFORM_WINDOWS
  555. __try
  556. {
  557. return mId;
  558. }
  559. __except (EXCEPTION_EXECUTE_HANDLER)
  560. {
  561. }
  562. return 0;
  563. #else
  564. return mId;
  565. #endif
  566. }
  567. //////////////////////////////////////////////////////////////////////////
  568. CeFunctionInfo::~CeFunctionInfo()
  569. {
  570. delete mCeFunction;
  571. }
  572. //////////////////////////////////////////////////////////////////////////
  573. #define CE_GET(T) *((T*)(mPtr += sizeof(T)) - 1)
  574. void CeDumpContext::DumpOperandInfo(CeOperandInfoKind operandInfoKind)
  575. {
  576. switch (operandInfoKind)
  577. {
  578. case CEOI_FrameRef:
  579. case CEOI_FrameRef8:
  580. case CEOI_FrameRef16:
  581. case CEOI_FrameRef32:
  582. case CEOI_FrameRef64:
  583. case CEOI_FrameRefF32:
  584. case CEOI_FrameRefF64:
  585. {
  586. int32 addr = CE_GET(int32);
  587. if (mCeFunction->mDbgInfo != NULL)
  588. {
  589. CeDbgVariable* dbgVar = NULL;
  590. if (mVarMap.TryGetValue(addr, &dbgVar))
  591. {
  592. mStr += dbgVar->mName;
  593. mStr += "@";
  594. }
  595. }
  596. switch (operandInfoKind)
  597. {
  598. case CEOI_FrameRef8:
  599. mStr += "int8";
  600. break;
  601. case CEOI_FrameRef16:
  602. mStr += "int16";
  603. break;
  604. case CEOI_FrameRef32:
  605. mStr += "int32";
  606. break;
  607. case CEOI_FrameRef64:
  608. mStr += "int64";
  609. break;
  610. case CEOI_FrameRefF32:
  611. mStr += "float";
  612. break;
  613. case CEOI_FrameRefF64:
  614. mStr += "double";
  615. break;
  616. }
  617. char str[64];
  618. if (addr >= 0)
  619. sprintf(str, "[FR+0x%X]", addr);
  620. else
  621. sprintf(str, "[FR-0x%X]", -addr);
  622. mStr += str;
  623. }
  624. break;
  625. case CEOI_IMM8:
  626. {
  627. int32 val = CE_GET(int8);
  628. char str[64];
  629. sprintf(str, "%d", val);
  630. mStr += str;
  631. }
  632. break;
  633. case CEOI_IMM16:
  634. {
  635. int32 val = CE_GET(int16);
  636. char str[64];
  637. sprintf(str, "%d", val);
  638. mStr += str;
  639. }
  640. break;
  641. case CEOI_IMM32:
  642. {
  643. int32 val = CE_GET(int32);
  644. char str[64];
  645. sprintf(str, "%d", val);
  646. mStr += str;
  647. }
  648. break;
  649. case CEOI_IMM64:
  650. {
  651. int64 val = CE_GET(int64);
  652. char str[64];
  653. sprintf(str, "%lld", (long long)val);
  654. mStr += str;
  655. }
  656. break;
  657. case CEOI_IMM_VAR:
  658. {
  659. mStr += '[';
  660. int32 size = CE_GET(int32);
  661. for (int i = 0; i < size; i++)
  662. {
  663. if (i != 0)
  664. mStr += ", ";
  665. uint8 val = CE_GET(uint8);
  666. char str[64];
  667. sprintf(str, "%X", val);
  668. mStr += str;
  669. }
  670. mStr += ']';
  671. }
  672. break;
  673. case CEOI_JMPREL:
  674. {
  675. int32 val = CE_GET(int32);
  676. char str[64];
  677. sprintf(str, "JMP:%04X", (int32)(val + (mPtr - mStart)));
  678. mStr += str;
  679. mJmp = (int32)(val + (mPtr - mStart));
  680. }
  681. break;
  682. }
  683. }
  684. void CeDumpContext::Next()
  685. {
  686. CeOp op = CE_GET(CeOp);
  687. if (op == CeOp_DbgBreak)
  688. {
  689. int instIdx = mPtr - mCeFunction->mCode.mVals - 2;
  690. CeBreakpointBind* breakpointEntry = NULL;
  691. if (mCeFunction->mBreakpoints.TryGetValue(instIdx, &breakpointEntry))
  692. {
  693. op = breakpointEntry->mPrevOpCode;
  694. }
  695. }
  696. CeOpInfo& opInfo = gOpInfo[op];
  697. auto argPtr = mPtr;
  698. if (mCeFunction->mDbgInfo != NULL)
  699. {
  700. for (auto& dbgVar : mCeFunction->mDbgInfo->mVariables)
  701. {
  702. mVarMap[dbgVar.mValue.mFrameOfs] = &dbgVar;
  703. }
  704. }
  705. int32 sizeX = -1;
  706. if ((opInfo.mFlags & CeOpInfoFlag_SizeX) != 0)
  707. {
  708. sizeX = CE_GET(int);
  709. }
  710. if (opInfo.mResultKind != CEOI_None)
  711. {
  712. DumpOperandInfo(opInfo.mResultKind);
  713. mStr += " = ";
  714. }
  715. mStr += opInfo.mName;
  716. if (sizeX != -1)
  717. {
  718. mStr += StrFormat(":%d", sizeX);
  719. }
  720. if (opInfo.mOperandA != CEOI_None)
  721. {
  722. mStr += " ";
  723. DumpOperandInfo(opInfo.mOperandA);
  724. }
  725. if (opInfo.mOperandB != CEOI_None)
  726. {
  727. mStr += ", ";
  728. DumpOperandInfo(opInfo.mOperandB);
  729. }
  730. if (opInfo.mOperandC != CEOI_None)
  731. {
  732. mStr += ", ";
  733. DumpOperandInfo(opInfo.mOperandC);
  734. }
  735. auto endPtr = mPtr;
  736. if (op == CeOp_GetMethod)
  737. {
  738. mPtr = argPtr;
  739. CE_GET(int32);
  740. int methodIdx = CE_GET(int32);
  741. auto& callEntry = mCeFunction->mCallTable[methodIdx];
  742. auto methodInstance = callEntry.mFunctionInfo->mMethodInstance;
  743. auto ceModule = mCeFunction->mCeMachine->mCeModule;
  744. if (!callEntry.mFunctionInfo->mMethodRef.IsNull())
  745. {
  746. auto methodRef = callEntry.mFunctionInfo->mMethodRef;
  747. auto methodDef = methodRef.mTypeInstance->mTypeDef->mMethods[methodRef.mMethodNum];
  748. methodInstance = ceModule->GetMethodInstance(methodRef.mTypeInstance, methodDef,
  749. methodRef.mMethodGenericArguments).mMethodInstance;
  750. }
  751. if (methodInstance != NULL)
  752. mStr += StrFormat(" ; %s", ceModule->MethodToString(methodInstance).c_str());
  753. mPtr = endPtr;
  754. }
  755. }
  756. void CeDumpContext::Dump()
  757. {
  758. if (!mCeFunction->mGenError.IsEmpty())
  759. mStr += StrFormat("Gen Error: %s\n", mCeFunction->mGenError.c_str());
  760. mStr += StrFormat("Frame Size: %d\n", mCeFunction->mFrameSize);
  761. uint8* start = mPtr;
  762. int curEmitIdx = 0;
  763. CeEmitEntry* curEmitEntry = NULL;
  764. while (mPtr < mEnd)
  765. {
  766. int ofs = mPtr - start;
  767. while ((curEmitIdx < mCeFunction->mEmitTable.mSize - 1) && (ofs >= mCeFunction->mEmitTable[curEmitIdx + 1].mCodePos))
  768. curEmitIdx++;
  769. if (curEmitIdx < mCeFunction->mEmitTable.mSize)
  770. curEmitEntry = &mCeFunction->mEmitTable[curEmitIdx];
  771. mStr += StrFormat("%04X: ", ofs);
  772. Next();
  773. if ((curEmitEntry != NULL) && (curEmitEntry->mScope != -1))
  774. {
  775. mStr += StrFormat(" @%d[%s:%d]", curEmitIdx, GetFileName(mCeFunction->mDbgScopes[curEmitEntry->mScope].mFilePath).c_str(),
  776. curEmitEntry->mLine + 1, curEmitEntry->mColumn + 1);
  777. }
  778. mStr += "\n";
  779. }
  780. }
  781. //////////////////////////////////////////////////////////////////////////
  782. void CeBuilder::Fail(const StringImpl& str)
  783. {
  784. if (!mCeFunction->mGenError.IsEmpty())
  785. return;
  786. String errStr = StrFormat("Failure during comptime generation of %s: %s", mBeFunction->mName.c_str(), str.c_str());
  787. if (mCurDbgLoc != NULL)
  788. {
  789. String filePath;
  790. mCurDbgLoc->GetDbgFile()->GetFilePath(filePath);
  791. errStr += StrFormat(" at line %d:%d in %s", mCurDbgLoc->mLine + 1, mCurDbgLoc->mColumn + 1, filePath.c_str());
  792. }
  793. mCeFunction->mGenError = errStr;
  794. }
  795. void CeBuilder::Emit(uint8 val)
  796. {
  797. mCeFunction->mCode.Add((uint8)val);
  798. }
  799. void CeBuilder::Emit(CeOp val)
  800. {
  801. *(CeOp*)mCeFunction->mCode.GrowUninitialized(sizeof(CeOp)) = val;
  802. }
  803. void CeBuilder::EmitSizedOp(CeOp val, int size)
  804. {
  805. CeSizeClass sizeClass = GetSizeClass(size);
  806. Emit((CeOp)(val + sizeClass));
  807. if (sizeClass == CeSizeClass_X)
  808. Emit((int32)size);
  809. if ((CeOp)(val + sizeClass) == CeOp_AddConst_I64)
  810. {
  811. NOP;
  812. }
  813. }
  814. void CeBuilder::Emit(int32 val)
  815. {
  816. *(int32*)mCeFunction->mCode.GrowUninitialized(4) = val;
  817. }
  818. void CeBuilder::Emit(int64 val)
  819. {
  820. *(int64*)mCeFunction->mCode.GrowUninitialized(8) = val;
  821. }
  822. void CeBuilder::Emit(bool val)
  823. {
  824. BF_FATAL("Invalid emit");
  825. }
  826. void CeBuilder::Emit(void* ptr, int size)
  827. {
  828. memcpy(mCeFunction->mCode.GrowUninitialized(size), ptr, size);
  829. }
  830. void CeBuilder::EmitZeroes(int size)
  831. {
  832. for (int i = 0; i < size; i++)
  833. Emit((uint8)0);
  834. }
  835. void CeBuilder::EmitJump(CeOp op, const CeOperand& block)
  836. {
  837. BF_ASSERT(block.mKind == CeOperandKind_Block);
  838. Emit(op);
  839. CeJumpEntry jumpEntry;
  840. jumpEntry.mBlockIdx = block.mBlockIdx;
  841. jumpEntry.mEmitPos = GetCodePos();
  842. mJumpTable.Add(jumpEntry);
  843. Emit((int32)0);
  844. }
  845. void CeBuilder::EmitBinarySwitchSection(BeSwitchInst* switchInst, int startIdx, int endIdx)
  846. {
  847. // This is an empirically determined binary switching limit
  848. if (endIdx - startIdx >= 18)
  849. {
  850. // int gteLabel = mCurLabelIdx++;
  851. //
  852. // auto mcDefaultBlock = GetOperand(switchInst->mDefaultBlock);
  853. //
  854. // int midIdx = startIdx + (endIdx - startIdx) / 2;
  855. // auto& switchCase = switchInst->mCases[midIdx];
  856. // auto switchBlock = GetOperand(switchCase.mBlock);
  857. // auto mcValue = GetOperand(switchInst->mValue);
  858. // auto valueType = GetType(mcValue);
  859. //
  860. // AllocInst(BeMCInstKind_Cmp, mcValue, GetOperand(switchCase.mValue));
  861. // AllocInst(BeMCInstKind_CondBr, BeMCOperand::FromLabel(gteLabel), BeMCOperand::FromCmpKind(BeCmpKind_SGE));
  862. // switchBlock.mBlock->AddPred(mActiveBlock);
  863. //
  864. // CreateBinarySwitchSection(switchInst, startIdx, midIdx);
  865. // AllocInst(BeMCInstKind_Br, mcDefaultBlock);
  866. // CreateLabel(-1, gteLabel);
  867. // CreateBinarySwitchSection(switchInst, midIdx, endIdx);
  868. // return;
  869. }
  870. for (int caseIdx = startIdx; caseIdx < endIdx; caseIdx++)
  871. {
  872. auto& switchCase = switchInst->mCases[caseIdx];
  873. auto switchBlock = GetOperand(switchCase.mBlock);
  874. auto mcValue = GetOperand(switchInst->mValue);
  875. CeOperand result;
  876. EmitBinaryOp(CeOp_Cmp_EQ_I8, CeOp_Cmp_EQ_F32, mcValue, GetOperand(switchCase.mValue), result);
  877. EmitJump(CeOp_JmpIf, switchBlock);
  878. EmitFrameOffset(result);
  879. }
  880. }
  881. CeOperand CeBuilder::EmitLoad(CeOperand ceTarget, int loadRefCount)
  882. {
  883. CeOperand result;
  884. if (ceTarget.mKind == CeOperandKind_AllocaAddr)
  885. {
  886. if (loadRefCount <= 1)
  887. {
  888. result = ceTarget;
  889. result.mKind = CeOperandKind_FrameOfs;
  890. }
  891. else
  892. {
  893. ceTarget.mKind = CeOperandKind_FrameOfs;
  894. result = FrameAlloc(ceTarget.mType);
  895. EmitSizedOp(CeOp_Move_8, ceTarget, NULL, true);
  896. Emit((int32)result.mFrameOfs);
  897. }
  898. }
  899. else
  900. {
  901. BF_ASSERT(ceTarget.mType->IsPointer());
  902. auto pointerType = (BePointerType*)ceTarget.mType;
  903. auto elemType = pointerType->mElementType;
  904. CeOperand refOperand = ceTarget;
  905. refOperand.mType = elemType;
  906. EmitSizedOp(CeOp_Load_8, refOperand, &result, true);
  907. }
  908. return result;
  909. }
  910. int CeBuilder::GetCodePos()
  911. {
  912. return (int)mCeFunction->mCode.size();
  913. }
  914. void CeBuilder::EmitFrameOffset(const CeOperand& val)
  915. {
  916. BF_ASSERT(val.mKind == CeOperandKind_FrameOfs);
  917. Emit((int32)val.mFrameOfs);
  918. }
  919. void CeBuilder::FlushPhi(CeBlock* ceBlock, int targetBlockIdx)
  920. {
  921. for (int i = 0; i < (int)ceBlock->mPhiOutgoing.size(); i++)
  922. {
  923. auto& phiOutgoing = ceBlock->mPhiOutgoing[i];
  924. if (phiOutgoing.mPhiBlockIdx == targetBlockIdx)
  925. {
  926. auto targetPhi = GetOperand(phiOutgoing.mPhiInst);
  927. auto mcVal = GetOperand(phiOutgoing.mPhiValue);
  928. EmitSizedOp(CeOp_Move_8, mcVal, NULL, true);
  929. EmitFrameOffset(targetPhi);
  930. ceBlock->mPhiOutgoing.RemoveAt(i);
  931. break;
  932. }
  933. }
  934. }
  935. void CeBuilder::EmitBinaryOp(CeOp iOp, CeOp fOp, const CeOperand& lhs, const CeOperand& rhs, CeOperand& result)
  936. {
  937. CeOp op = iOp;
  938. if (lhs.mType->IsIntable())
  939. {
  940. if (lhs.mType->mSize == 1)
  941. op = iOp;
  942. else if (lhs.mType->mSize == 2)
  943. op = (CeOp)(iOp + 1);
  944. else if (lhs.mType->mSize == 4)
  945. op = (CeOp)(iOp + 2);
  946. else if (lhs.mType->mSize == 8)
  947. op = (CeOp)(iOp + 3);
  948. else
  949. Fail("Invalid int operand size");
  950. }
  951. else if (lhs.mType->IsFloat())
  952. {
  953. BF_ASSERT(fOp != CeOp_InvalidOp);
  954. if (lhs.mType->mSize == 4)
  955. op = fOp;
  956. else if (lhs.mType->mSize == 8)
  957. op = (CeOp)(fOp + 1);
  958. else
  959. Fail("Invalid float operand size");
  960. }
  961. else
  962. Fail("Invalid binary operand");
  963. Emit(op);
  964. if (!result)
  965. result = FrameAlloc(lhs.mType);
  966. EmitFrameOffset(result);
  967. EmitFrameOffset(lhs);
  968. EmitFrameOffset(rhs);
  969. }
  970. CeOperand CeBuilder::EmitNumericCast(const CeOperand& ceValue, BeType* toType, bool valSigned, bool toSigned)
  971. {
  972. if (ceValue.mKind == CeOperandKind_Immediate)
  973. {
  974. CeOperand newVal = ceValue;
  975. newVal.mType = toType;
  976. return newVal;
  977. }
  978. CeOperand result;
  979. auto fromType = ceValue.mType;
  980. if (fromType == toType)
  981. {
  982. // If it's just a sign change then leave it alone
  983. result = ceValue;
  984. }
  985. else
  986. {
  987. if ((toType->IsIntable()) && (fromType->IsIntable()) && (toType->mSize <= fromType->mSize))
  988. {
  989. // For truncating values, no actual instructions are needed
  990. // Note that a copy is not needed because of SSA rules
  991. result = ceValue;
  992. result.mType = toType;
  993. }
  994. else
  995. {
  996. result = FrameAlloc(toType);
  997. CeOp op = CeOp_InvalidOp;
  998. BeTypeCode fromTypeCode = fromType->mTypeCode;
  999. BeTypeCode toTypeCode = toType->mTypeCode;
  1000. if ((valSigned) && (toSigned))
  1001. {
  1002. switch (fromTypeCode)
  1003. {
  1004. case BeTypeCode_Int8:
  1005. switch (toTypeCode)
  1006. {
  1007. case BeTypeCode_Int16:
  1008. op = CeOp_Conv_I8_I16;
  1009. break;
  1010. case BeTypeCode_Int32:
  1011. op = CeOp_Conv_I8_I32;
  1012. break;
  1013. case BeTypeCode_Int64:
  1014. op = CeOp_Conv_I8_I64;
  1015. break;
  1016. case BeTypeCode_Float:
  1017. op = CeOp_Conv_I8_F32;
  1018. break;
  1019. case BeTypeCode_Double:
  1020. op = CeOp_Conv_I8_F64;
  1021. break;
  1022. }
  1023. break;
  1024. case BeTypeCode_Int16:
  1025. switch (toTypeCode)
  1026. {
  1027. case BeTypeCode_Int32:
  1028. op = CeOp_Conv_I16_I32;
  1029. break;
  1030. case BeTypeCode_Int64:
  1031. op = CeOp_Conv_I16_I64;
  1032. break;
  1033. case BeTypeCode_Float:
  1034. op = CeOp_Conv_I16_F32;
  1035. break;
  1036. case BeTypeCode_Double:
  1037. op = CeOp_Conv_I16_F64;
  1038. break;
  1039. }
  1040. break;
  1041. case BeTypeCode_Int32:
  1042. switch (toTypeCode)
  1043. {
  1044. case BeTypeCode_Int64:
  1045. op = CeOp_Conv_I32_I64;
  1046. break;
  1047. case BeTypeCode_Float:
  1048. op = CeOp_Conv_I32_F32;
  1049. break;
  1050. case BeTypeCode_Double:
  1051. op = CeOp_Conv_I32_F64;
  1052. break;
  1053. }
  1054. break;
  1055. case BeTypeCode_Int64:
  1056. switch (toTypeCode)
  1057. {
  1058. case BeTypeCode_Float:
  1059. op = CeOp_Conv_I64_F32;
  1060. break;
  1061. case BeTypeCode_Double:
  1062. op = CeOp_Conv_I64_F64;
  1063. break;
  1064. }
  1065. break;
  1066. case BeTypeCode_Float:
  1067. switch (toTypeCode)
  1068. {
  1069. case BeTypeCode_Int8:
  1070. op = CeOp_Conv_F32_I8;
  1071. break;
  1072. case BeTypeCode_Int16:
  1073. op = CeOp_Conv_F32_I16;
  1074. break;
  1075. case BeTypeCode_Int32:
  1076. op = CeOp_Conv_F32_I32;
  1077. break;
  1078. case BeTypeCode_Int64:
  1079. op = CeOp_Conv_F32_I64;
  1080. break;
  1081. case BeTypeCode_Double:
  1082. op = CeOp_Conv_F32_F64;
  1083. break;
  1084. }
  1085. break;
  1086. case BeTypeCode_Double:
  1087. switch (toTypeCode)
  1088. {
  1089. case BeTypeCode_Int8:
  1090. op = CeOp_Conv_F64_I8;
  1091. break;
  1092. case BeTypeCode_Int16:
  1093. op = CeOp_Conv_F64_I16;
  1094. break;
  1095. case BeTypeCode_Int32:
  1096. op = CeOp_Conv_F64_I32;
  1097. break;
  1098. case BeTypeCode_Int64:
  1099. op = CeOp_Conv_F64_I64;
  1100. break;
  1101. case BeTypeCode_Float:
  1102. op = CeOp_Conv_F64_F32;
  1103. break;
  1104. }
  1105. break;
  1106. }
  1107. }
  1108. else
  1109. {
  1110. switch (fromTypeCode)
  1111. {
  1112. case BeTypeCode_Int8:
  1113. switch (toTypeCode)
  1114. {
  1115. case BeTypeCode_Int16:
  1116. op = CeOp_Conv_U8_U16;
  1117. break;
  1118. case BeTypeCode_Int32:
  1119. op = CeOp_Conv_U8_U32;
  1120. break;
  1121. case BeTypeCode_Int64:
  1122. op = CeOp_Conv_U8_U64;
  1123. break;
  1124. case BeTypeCode_Float:
  1125. op = CeOp_Conv_U8_F32;
  1126. break;
  1127. case BeTypeCode_Double:
  1128. op = CeOp_Conv_U8_F64;
  1129. break;
  1130. }
  1131. break;
  1132. case BeTypeCode_Int16:
  1133. switch (toTypeCode)
  1134. {
  1135. case BeTypeCode_Int32:
  1136. op = CeOp_Conv_U16_U32;
  1137. break;
  1138. case BeTypeCode_Int64:
  1139. op = CeOp_Conv_U16_U64;
  1140. break;
  1141. case BeTypeCode_Float:
  1142. op = CeOp_Conv_U16_F32;
  1143. break;
  1144. case BeTypeCode_Double:
  1145. op = CeOp_Conv_U16_F64;
  1146. break;
  1147. }
  1148. break;
  1149. case BeTypeCode_Int32:
  1150. switch (toTypeCode)
  1151. {
  1152. case BeTypeCode_Int64:
  1153. op = CeOp_Conv_U32_U64;
  1154. break;
  1155. case BeTypeCode_Float:
  1156. op = CeOp_Conv_U32_F32;
  1157. break;
  1158. case BeTypeCode_Double:
  1159. op = CeOp_Conv_U32_F64;
  1160. break;
  1161. }
  1162. break;
  1163. case BeTypeCode_Int64:
  1164. switch (toTypeCode)
  1165. {
  1166. case BeTypeCode_Float:
  1167. op = CeOp_Conv_I64_F32;
  1168. break;
  1169. case BeTypeCode_Double:
  1170. op = CeOp_Conv_I64_F64;
  1171. break;
  1172. }
  1173. break;
  1174. case BeTypeCode_Float:
  1175. switch (toTypeCode)
  1176. {
  1177. case BeTypeCode_Int8:
  1178. op = CeOp_Conv_F32_U8;
  1179. break;
  1180. case BeTypeCode_Int16:
  1181. op = CeOp_Conv_F32_U16;
  1182. break;
  1183. case BeTypeCode_Int32:
  1184. op = CeOp_Conv_F32_U32;
  1185. break;
  1186. case BeTypeCode_Int64:
  1187. op = CeOp_Conv_F32_U64;
  1188. break;
  1189. }
  1190. break;
  1191. case BeTypeCode_Double:
  1192. switch (toTypeCode)
  1193. {
  1194. case BeTypeCode_Int8:
  1195. op = CeOp_Conv_F64_U8;
  1196. break;
  1197. case BeTypeCode_Int16:
  1198. op = CeOp_Conv_F64_U16;
  1199. break;
  1200. case BeTypeCode_Int32:
  1201. op = CeOp_Conv_F64_U32;
  1202. break;
  1203. case BeTypeCode_Int64:
  1204. op = CeOp_Conv_F64_U64;
  1205. break;
  1206. }
  1207. break;
  1208. }
  1209. }
  1210. if (op == CeOp_InvalidOp)
  1211. {
  1212. Fail("Invalid conversion op");
  1213. }
  1214. else
  1215. {
  1216. Emit(op);
  1217. EmitFrameOffset(result);
  1218. EmitFrameOffset(ceValue);
  1219. }
  1220. }
  1221. }
  1222. return result;
  1223. }
  1224. void CeBuilder::EmitUnaryOp(CeOp iOp, CeOp fOp, const CeOperand& val, CeOperand& result)
  1225. {
  1226. CeOp op = iOp;
  1227. if (val.mType->IsIntable())
  1228. {
  1229. if (val.mType->mSize == 1)
  1230. op = iOp;
  1231. else if (val.mType->mSize == 2)
  1232. op = (CeOp)(iOp + 1);
  1233. else if (val.mType->mSize == 4)
  1234. op = (CeOp)(iOp + 2);
  1235. else if (val.mType->mSize == 8)
  1236. op = (CeOp)(iOp + 3);
  1237. else
  1238. Fail("Invalid int operand size");
  1239. }
  1240. else if (val.mType->IsFloat())
  1241. {
  1242. if (val.mType->mSize == 4)
  1243. op = fOp;
  1244. else if (val.mType->mSize == 8)
  1245. op = (CeOp)(fOp + 1);
  1246. else
  1247. Fail("Invalid float operand size");
  1248. }
  1249. else
  1250. Fail("Invalid unary operand");
  1251. Emit(op);
  1252. result = FrameAlloc(val.mType);
  1253. EmitFrameOffset(result);
  1254. EmitFrameOffset(val);
  1255. }
  1256. void CeBuilder::EmitSizedOp(CeOp baseOp, const CeOperand& operand, CeOperand* outResult, bool allowNonStdSize)
  1257. {
  1258. bool isStdSize = true;
  1259. CeOp op = CeOp_InvalidOp;
  1260. if (operand.mType->mSize == 1)
  1261. op = baseOp;
  1262. else if (operand.mType->mSize == 2)
  1263. op = (CeOp)(baseOp + 1);
  1264. else if (operand.mType->mSize == 4)
  1265. op = (CeOp)(baseOp + 2);
  1266. else if (operand.mType->mSize == 8)
  1267. op = (CeOp)(baseOp + 3);
  1268. else
  1269. {
  1270. isStdSize = false;
  1271. op = (CeOp)(baseOp + 4);
  1272. }
  1273. Emit(op);
  1274. if (!isStdSize)
  1275. {
  1276. if (!allowNonStdSize)
  1277. Fail("Invalid operand size");
  1278. Emit((int32)operand.mType->mSize);
  1279. }
  1280. if (outResult != NULL)
  1281. {
  1282. *outResult = FrameAlloc(operand.mType);
  1283. EmitFrameOffset(*outResult);
  1284. }
  1285. EmitFrameOffset(operand);
  1286. }
  1287. CeOperand CeBuilder::FrameAlloc(BeType* type)
  1288. {
  1289. mFrameSize += type->mSize;
  1290. CeOperand result;
  1291. result.mKind = CeOperandKind_FrameOfs;
  1292. result.mFrameOfs = -mFrameSize;
  1293. result.mType = type;
  1294. return result;
  1295. }
  1296. CeOperand CeBuilder::EmitConst(int64 val, int size)
  1297. {
  1298. BeType* type = mIntPtrType;
  1299. switch (size)
  1300. {
  1301. case 1:
  1302. type = mCeMachine->GetBeContext()->GetPrimitiveType(BeTypeCode_Int8);
  1303. break;
  1304. case 2:
  1305. type = mCeMachine->GetBeContext()->GetPrimitiveType(BeTypeCode_Int16);
  1306. break;
  1307. case 4:
  1308. type = mCeMachine->GetBeContext()->GetPrimitiveType(BeTypeCode_Int32);
  1309. break;
  1310. case 8:
  1311. type = mCeMachine->GetBeContext()->GetPrimitiveType(BeTypeCode_Int64);
  1312. break;
  1313. default:
  1314. Fail("Bad const size");
  1315. }
  1316. auto result = FrameAlloc(type);
  1317. EmitSizedOp(CeOp_Const_8, type->mSize);
  1318. EmitFrameOffset(result);
  1319. Emit(&val, size);
  1320. return result;
  1321. }
  1322. int CeBuilder::GetCallTableIdx(BeFunction* beFunction, CeOperand* outOperand)
  1323. {
  1324. int* callIdxPtr = NULL;
  1325. if (mFunctionMap.TryAdd(beFunction, NULL, &callIdxPtr))
  1326. {
  1327. CeFunctionInfo* ceFunctionInfo = NULL;
  1328. mCeMachine->mNamedFunctionMap.TryGetValue(beFunction->mName, &ceFunctionInfo);
  1329. if (ceFunctionInfo != NULL)
  1330. ceFunctionInfo->mRefCount++;
  1331. else
  1332. {
  1333. if (outOperand != NULL)
  1334. {
  1335. auto checkBuilder = this;
  1336. if (checkBuilder->mParentBuilder != NULL)
  1337. checkBuilder = checkBuilder->mParentBuilder;
  1338. int innerFunctionIdx = 0;
  1339. if (checkBuilder->mInnerFunctionMap.TryGetValue(beFunction, &innerFunctionIdx))
  1340. {
  1341. auto innerFunction = checkBuilder->mCeFunction->mInnerFunctions[innerFunctionIdx];
  1342. if (innerFunction->mInitializeState < CeFunction::InitializeState_Initialized)
  1343. mCeMachine->PrepareFunction(innerFunction, checkBuilder);
  1344. CeOperand result = FrameAlloc(mCeMachine->GetBeContext()->GetPrimitiveType((sizeof(BfMethodInstance*) == 8) ? BeTypeCode_Int64 : BeTypeCode_Int32));
  1345. Emit(CeOp_GetMethod_Inner);
  1346. EmitFrameOffset(result);
  1347. Emit((int32)innerFunctionIdx);
  1348. *outOperand = result;
  1349. return -1;
  1350. }
  1351. }
  1352. Fail(StrFormat("Unable to locate method %s", beFunction->mName.c_str()));
  1353. }
  1354. CeCallEntry callEntry;
  1355. callEntry.mFunctionInfo = ceFunctionInfo;
  1356. *callIdxPtr = (int)mCeFunction->mCallTable.size();
  1357. mCeFunction->mCallTable.Add(callEntry);
  1358. if ((ceFunctionInfo != NULL) && (mCeFunction->mCeFunctionInfo != NULL))
  1359. {
  1360. auto callerType = mCeFunction->GetOwner();
  1361. auto calleeType = ceFunctionInfo->GetOwner();
  1362. if ((callerType != NULL) && (calleeType != NULL))
  1363. {
  1364. // This will generally already be set, but there are some error cases (such as duplicate type names)
  1365. // where this will not be set yet
  1366. callerType->mModule->AddDependency(calleeType, callerType, BfDependencyMap::DependencyFlag_Calls);
  1367. }
  1368. }
  1369. }
  1370. return *callIdxPtr;
  1371. }
  1372. CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImmediate)
  1373. {
  1374. if (value == NULL)
  1375. return CeOperand();
  1376. BeType* errorType = mIntPtrType;
  1377. CeErrorKind errorKind = CeErrorKind_None;
  1378. switch (value->GetTypeId())
  1379. {
  1380. case BeGlobalVariable::TypeId:
  1381. {
  1382. auto globalVar = (BeGlobalVariable*)value;
  1383. if (globalVar->mName.StartsWith("__bfStrObj"))
  1384. {
  1385. int stringId = atoi(globalVar->mName.c_str() + 10);
  1386. int* stringTableIdxPtr = NULL;
  1387. if (mStringMap.TryAdd(stringId, NULL, &stringTableIdxPtr))
  1388. {
  1389. *stringTableIdxPtr = (int)mCeFunction->mStringTable.size();
  1390. CeStringEntry ceStringEntry;
  1391. ceStringEntry.mStringId = stringId;
  1392. mCeFunction->mStringTable.Add(ceStringEntry);
  1393. }
  1394. auto result = FrameAlloc(mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType));
  1395. Emit(CeOp_GetString);
  1396. EmitFrameOffset(result);
  1397. Emit((int32)*stringTableIdxPtr);
  1398. return result;
  1399. }
  1400. else if (globalVar->mName.StartsWith("__bfStrData"))
  1401. {
  1402. int stringId = atoi(globalVar->mName.c_str() + 11);
  1403. int* stringTableIdxPtr = NULL;
  1404. if (mStringMap.TryAdd(stringId, NULL, &stringTableIdxPtr))
  1405. {
  1406. *stringTableIdxPtr = (int)mCeFunction->mStringTable.size();
  1407. CeStringEntry ceStringEntry;
  1408. ceStringEntry.mStringId = stringId;
  1409. mCeFunction->mStringTable.Add(ceStringEntry);
  1410. }
  1411. auto result = FrameAlloc(mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType));
  1412. Emit(CeOp_GetString);
  1413. EmitFrameOffset(result);
  1414. Emit((int32)*stringTableIdxPtr);
  1415. BfTypeInstance* stringTypeInst = (BfTypeInstance*)mCeMachine->mCeModule->ResolveTypeDef(
  1416. mCeMachine->mCeModule->mCompiler->mStringTypeDef, BfPopulateType_Data);
  1417. Emit(CeOp_AddConst_I32);
  1418. EmitFrameOffset(result);
  1419. EmitFrameOffset(result);
  1420. Emit((int32)stringTypeInst->mInstSize);
  1421. return result;
  1422. }
  1423. CeOperand initializerValue;
  1424. if (globalVar->mIsConstant)
  1425. {
  1426. if (globalVar->mInitializer != NULL)
  1427. {
  1428. auto result = GetOperand(globalVar->mInitializer, false, true);
  1429. if (result.mKind == CeOperandKind_ConstStructTableIdx)
  1430. {
  1431. auto& constTableEntry = mCeFunction->mConstStructTable[result.mStructTableIdx];
  1432. auto ptrType = mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType);
  1433. auto dataResult = FrameAlloc(ptrType);
  1434. Emit(CeOp_ConstDataRef);
  1435. EmitFrameOffset(dataResult);
  1436. Emit((int32)result.mCallTableIdx);
  1437. return dataResult;
  1438. }
  1439. return result;
  1440. }
  1441. }
  1442. else
  1443. {
  1444. initializerValue = GetOperand(globalVar->mInitializer);
  1445. BfFieldInstance** fieldInstancePtr = NULL;
  1446. mStaticFieldInstanceMap.TryGetValue(globalVar->mName, &fieldInstancePtr);
  1447. int* staticFieldTableIdxPtr = NULL;
  1448. if (mStaticFieldMap.TryAdd(globalVar, NULL, &staticFieldTableIdxPtr))
  1449. {
  1450. CeStaticFieldEntry staticFieldEntry;
  1451. if (fieldInstancePtr != NULL)
  1452. staticFieldEntry.mTypeId = (*fieldInstancePtr)->mOwner->mTypeId;
  1453. staticFieldEntry.mName = globalVar->mName;
  1454. if (globalVar->mLinkageType == Beefy::BfIRLinkageType_Internal)
  1455. {
  1456. staticFieldEntry.mName += "@";
  1457. staticFieldEntry.mName += mCeFunction->mMethodInstance->GetOwner()->mModule->mModuleName;
  1458. }
  1459. staticFieldEntry.mSize = globalVar->mType->mSize;
  1460. *staticFieldTableIdxPtr = (int)mCeFunction->mStaticFieldTable.size();
  1461. mCeFunction->mStaticFieldTable.Add(staticFieldEntry);
  1462. }
  1463. auto result = FrameAlloc(mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType));
  1464. if (initializerValue)
  1465. {
  1466. Emit(CeOp_GetStaticField_Initializer);
  1467. EmitFrameOffset(result);
  1468. Emit((int32)*staticFieldTableIdxPtr);
  1469. EmitFrameOffset(initializerValue);
  1470. }
  1471. else
  1472. {
  1473. Emit(CeOp_GetStaticField);
  1474. EmitFrameOffset(result);
  1475. Emit((int32)*staticFieldTableIdxPtr);
  1476. }
  1477. return result;
  1478. }
  1479. errorKind = CeErrorKind_GlobalVariable;
  1480. errorType = mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType);
  1481. }
  1482. break;
  1483. case BeCastConstant::TypeId:
  1484. {
  1485. auto constant = (BeCastConstant*)value;
  1486. CeOperand mcOperand;
  1487. auto result = GetOperand(constant->mTarget);
  1488. result.mType = constant->mType;
  1489. return result;
  1490. }
  1491. break;
  1492. case BeUndefConstant::TypeId:
  1493. case BeConstant::TypeId:
  1494. {
  1495. uint64 u64Val = 0;
  1496. float fVal = 0;
  1497. void* dataPtr = NULL;
  1498. int dataSize = 0;
  1499. auto constant = (BeConstant*)value;
  1500. CeOperand mcOperand;
  1501. switch (constant->mType->mTypeCode)
  1502. {
  1503. case BeTypeCode_Int8:
  1504. case BeTypeCode_Int16:
  1505. case BeTypeCode_Int32:
  1506. case BeTypeCode_Int64:
  1507. if (allowImmediate)
  1508. {
  1509. CeOperand result;
  1510. result.mKind = CeOperandKind_Immediate;
  1511. result.mImmediate = constant->mInt32;
  1512. result.mType = constant->mType;
  1513. return result;
  1514. }
  1515. case BeTypeCode_Boolean:
  1516. case BeTypeCode_Double:
  1517. dataPtr = &constant->mUInt64;
  1518. dataSize = constant->mType->mSize;
  1519. break;
  1520. case BeTypeCode_Float:
  1521. fVal = (float)constant->mDouble;
  1522. dataPtr = &fVal;
  1523. dataSize = 4;
  1524. break;
  1525. case BeTypeCode_Pointer:
  1526. {
  1527. if (constant->mTarget == NULL)
  1528. {
  1529. dataPtr = &u64Val;
  1530. dataSize = mPtrSize;
  1531. }
  1532. else
  1533. {
  1534. auto relTo = GetOperand(constant->mTarget);
  1535. if (relTo)
  1536. {
  1537. auto result = relTo;
  1538. result.mType = constant->mType;
  1539. return result;
  1540. }
  1541. // if (relTo.mKind == CeOperandKind_Immediate_Null)
  1542. // {
  1543. // mcOperand.mKind = CeOperandKind_Immediate_Null;
  1544. // mcOperand.mType = constant->mType;
  1545. // return mcOperand;
  1546. // }
  1547. //
  1548. // mcOperand = AllocVirtualReg(constant->mType);
  1549. // auto vregInfo = GetVRegInfo(mcOperand);
  1550. // vregInfo->mDefOnFirstUse = true;
  1551. // vregInfo->mRelTo = relTo;
  1552. // vregInfo->mIsExpr = true;
  1553. //
  1554. //return mcOperand;
  1555. }
  1556. }
  1557. break;
  1558. case BeTypeCode_Struct:
  1559. case BeTypeCode_SizedArray:
  1560. case BeTypeCode_Vector:
  1561. {
  1562. auto beType = constant->mType;
  1563. auto result = FrameAlloc(beType);
  1564. Emit(CeOp_Zero);
  1565. EmitFrameOffset(result);
  1566. Emit((int32)beType->mSize);
  1567. return result;
  1568. }
  1569. //mcOperand.mImmediate = constant->mInt64;
  1570. //mcOperand.mKind = CeOperandKind_Immediate_i64;
  1571. break;
  1572. // default:
  1573. // Fail("Unhandled constant type");
  1574. }
  1575. if (dataSize != 0)
  1576. {
  1577. auto beType = constant->mType;
  1578. auto result = FrameAlloc(beType);
  1579. CeSizeClass sizeClass = GetSizeClass(dataSize);
  1580. Emit((CeOp)(CeOp_Const_8 + sizeClass));
  1581. EmitFrameOffset(result);
  1582. if (sizeClass == CeSizeClass_X)
  1583. Emit((int32)dataSize);
  1584. if (dataPtr != 0)
  1585. Emit(dataPtr, dataSize);
  1586. else
  1587. {
  1588. for (int i = 0; i < dataSize; i++)
  1589. Emit((uint8)0);
  1590. }
  1591. return result;
  1592. }
  1593. }
  1594. break;
  1595. case BeStructConstant::TypeId:
  1596. {
  1597. int* constDataPtr = NULL;
  1598. auto structConstant = (BeStructConstant*)value;
  1599. if (mConstDataMap.TryAdd(structConstant, NULL, &constDataPtr))
  1600. {
  1601. CeConstStructData constStructData;
  1602. constStructData.mQueueFixups = true;
  1603. errorKind = mCeMachine->WriteConstant(constStructData, structConstant, NULL, this);
  1604. if (errorKind == CeErrorKind_None)
  1605. {
  1606. *constDataPtr = (int)mCeFunction->mConstStructTable.size();
  1607. mCeFunction->mConstStructTable.Add(constStructData);
  1608. }
  1609. else
  1610. {
  1611. *constDataPtr = -1;
  1612. }
  1613. }
  1614. if (*constDataPtr != -1)
  1615. {
  1616. if (!allowImmediate)
  1617. {
  1618. auto result = FrameAlloc(structConstant->mType);
  1619. Emit(CeOp_ConstData);
  1620. EmitFrameOffset(result);
  1621. Emit((int32)*constDataPtr);
  1622. return result;
  1623. }
  1624. else
  1625. {
  1626. CeOperand result;
  1627. result.mKind = CeOperandKind_ConstStructTableIdx;
  1628. result.mCallTableIdx = *constDataPtr;
  1629. result.mType = structConstant->mType;
  1630. return result;
  1631. }
  1632. }
  1633. else
  1634. {
  1635. errorKind = CeErrorKind_GlobalVariable;
  1636. }
  1637. }
  1638. break;
  1639. case BeGEP1Constant::TypeId:
  1640. {
  1641. auto gepConstant = (BeGEP1Constant*)value;
  1642. auto mcVal = GetOperand(gepConstant->mTarget);
  1643. BePointerType* ptrType = (BePointerType*)mcVal.mType;
  1644. BF_ASSERT(ptrType->mTypeCode == BeTypeCode_Pointer);
  1645. auto result = mcVal;
  1646. // We assume we never do both an idx0 and idx1 at once. Fix if we change that.
  1647. int64 byteOffset = 0;
  1648. BeType* elementType = NULL;
  1649. byteOffset += gepConstant->mIdx0 * ptrType->mElementType->mSize;
  1650. result = FrameAlloc(ptrType);
  1651. EmitSizedOp(CeOp_AddConst_I8, mPtrSize);
  1652. EmitFrameOffset(result);
  1653. EmitFrameOffset(mcVal);
  1654. Emit(&byteOffset, mPtrSize);
  1655. return result;
  1656. }
  1657. break;
  1658. case BeGEP2Constant::TypeId:
  1659. {
  1660. auto gepConstant = (BeGEP2Constant*)value;
  1661. auto mcVal = GetOperand(gepConstant->mTarget);
  1662. BePointerType* ptrType = (BePointerType*)mcVal.mType;
  1663. BF_ASSERT(ptrType->mTypeCode == BeTypeCode_Pointer);
  1664. auto result = mcVal;
  1665. // We assume we never do both an idx0 and idx1 at once. Fix if we change that.
  1666. int64 byteOffset = 0;
  1667. BeType* elementType = NULL;
  1668. byteOffset += gepConstant->mIdx0 * ptrType->mElementType->mSize;
  1669. if (ptrType->mElementType->mTypeCode == BeTypeCode_Struct)
  1670. {
  1671. BeStructType* structType = (BeStructType*)ptrType->mElementType;
  1672. auto& structMember = structType->mMembers[gepConstant->mIdx1];
  1673. elementType = structMember.mType;
  1674. byteOffset = structMember.mByteOffset;
  1675. }
  1676. else
  1677. {
  1678. BF_ASSERT(ptrType->mElementType->mTypeCode == BeTypeCode_SizedArray);
  1679. auto arrayType = (BeSizedArrayType*)ptrType->mElementType;
  1680. elementType = arrayType->mElementType;
  1681. byteOffset = gepConstant->mIdx1 * elementType->GetStride();
  1682. }
  1683. auto elementPtrType = mCeMachine->GetBeContext()->GetPointerTo(elementType);
  1684. result = FrameAlloc(elementPtrType);
  1685. EmitSizedOp(CeOp_AddConst_I8, mPtrSize);
  1686. EmitFrameOffset(result);
  1687. EmitFrameOffset(mcVal);
  1688. Emit(&byteOffset, mPtrSize);
  1689. return result;
  1690. }
  1691. break;
  1692. case BeExtractValueConstant::TypeId:
  1693. {
  1694. // Note: this only handles zero-aggregates
  1695. auto extractConstant = (BeExtractValueConstant*)value;
  1696. auto elementType = extractConstant->GetType();
  1697. auto mcVal = GetOperand(extractConstant->mTarget);
  1698. BeConstant beConstant;
  1699. beConstant.mType = elementType;
  1700. beConstant.mUInt64 = 0;
  1701. return GetOperand(&beConstant);
  1702. }
  1703. break;
  1704. case BeFunction::TypeId:
  1705. {
  1706. auto beFunction = (BeFunction*)value;
  1707. CeOperand operand;
  1708. int callIdx = GetCallTableIdx(beFunction, &operand);
  1709. if (operand)
  1710. return operand;
  1711. if (allowImmediate)
  1712. {
  1713. CeOperand result;
  1714. result.mKind = CeOperandKind_CallTableIdx;
  1715. result.mCallTableIdx = callIdx;
  1716. return result;
  1717. }
  1718. BF_ASSERT(callIdx <= mCeFunction->mCallTable.mSize);
  1719. CeOperand result = FrameAlloc(mCeMachine->GetBeContext()->GetPrimitiveType((sizeof(BfMethodInstance*) == 8) ? BeTypeCode_Int64 : BeTypeCode_Int32));
  1720. Emit(CeOp_GetMethod);
  1721. EmitFrameOffset(result);
  1722. Emit((int32)callIdx);
  1723. return result;
  1724. }
  1725. break;
  1726. case BeCallInst::TypeId:
  1727. {
  1728. // auto callInst = (BeCallInst*)value;
  1729. // if (callInst->mInlineResult != NULL)
  1730. // return GetOperand(callInst->mInlineResult);
  1731. }
  1732. break;
  1733. case BeTypeOfConstant::TypeId:
  1734. {
  1735. auto beTypeOf = (BeTypeOfConstant*)value;
  1736. auto ptrType = mCeMachine->GetBeContext()->GetVoidPtrType();
  1737. CeOperand result = FrameAlloc(ptrType);
  1738. Emit(CeOp_GetReflectType);
  1739. EmitFrameOffset(result);
  1740. Emit((int32)beTypeOf->mBfTypeId);
  1741. return result;
  1742. }
  1743. break;
  1744. }
  1745. CeOperand* operandPtr = NULL;
  1746. mValueToOperand.TryGetValue(value, &operandPtr);
  1747. if (errorKind != CeErrorKind_None)
  1748. {
  1749. Emit(CeOp_Error);
  1750. Emit((int32)errorKind);
  1751. }
  1752. else
  1753. {
  1754. if (operandPtr == NULL)
  1755. {
  1756. BeDumpContext dumpCtx;
  1757. String str;
  1758. dumpCtx.ToString(str, value);
  1759. Fail(StrFormat("Unable to find bevalue for operand: %s", str.c_str()));
  1760. }
  1761. }
  1762. if (operandPtr == NULL)
  1763. {
  1764. return FrameAlloc(errorType);
  1765. }
  1766. auto operand = *operandPtr;
  1767. if ((operand.mKind == CeOperandKind_AllocaAddr) && (!allowAlloca))
  1768. {
  1769. auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen;
  1770. auto ptrType = mCeMachine->GetBeContext()->GetPointerTo(operand.mType);
  1771. auto result = FrameAlloc(ptrType);
  1772. Emit((mPtrSize == 4) ? CeOp_FrameAddr_32 : CeOp_FrameAddr_64);
  1773. EmitFrameOffset(result);
  1774. Emit((int32)operand.mFrameOfs);
  1775. return result;
  1776. }
  1777. return operand;
  1778. }
  1779. CeSizeClass CeBuilder::GetSizeClass(int size)
  1780. {
  1781. switch (size)
  1782. {
  1783. case 1:
  1784. return CeSizeClass_8;
  1785. case 2:
  1786. return CeSizeClass_16;
  1787. case 4:
  1788. return CeSizeClass_32;
  1789. case 8:
  1790. return CeSizeClass_64;
  1791. default:
  1792. return CeSizeClass_X;
  1793. }
  1794. }
  1795. int CeBuilder::DbgCreateMethodRef(BfMethodInstance* methodInstance, const StringImpl& nameMod)
  1796. {
  1797. CeDbgMethodRef dbgMethodRef;
  1798. dbgMethodRef.mNameMod = nameMod;
  1799. dbgMethodRef.mMethodRef = methodInstance;
  1800. int* valuePtr = NULL;
  1801. if (mDbgMethodRefMap.TryAdd(dbgMethodRef, NULL, &valuePtr))
  1802. {
  1803. *valuePtr = mCeFunction->mDbgMethodRefTable.mSize;
  1804. mCeFunction->mDbgMethodRefTable.Add(dbgMethodRef);
  1805. }
  1806. return *valuePtr;
  1807. }
  1808. void CeBuilder::HandleParams()
  1809. {
  1810. auto beModule = mBeFunction->mModule;
  1811. // int regIdxOfs = 0;
  1812. // int paramOfs = 0;
  1813. auto retType = mBeFunction->GetFuncType()->mReturnType;
  1814. int frameOffset = 0;
  1815. if (mCeFunction->mMaxReturnSize > 0)
  1816. {
  1817. mReturnVal.mKind = CeOperandKind_AllocaAddr;
  1818. mReturnVal.mFrameOfs = frameOffset;
  1819. frameOffset += mCeFunction->mMaxReturnSize;
  1820. }
  1821. int paramOfs = 0;
  1822. //for (int paramIdx = (int)mBeFunction->mParams.size() - 1; paramIdx >= 0; paramIdx--)
  1823. for (int paramIdx = 0; paramIdx < mBeFunction->mParams.size(); paramIdx++)
  1824. {
  1825. auto funcType = mBeFunction->GetFuncType();
  1826. auto& typeParam = funcType->mParams[paramIdx + paramOfs];
  1827. auto& param = mBeFunction->mParams[paramIdx + paramOfs];
  1828. auto beArg = beModule->GetArgument(paramIdx + paramOfs);
  1829. auto paramType = typeParam.mType;
  1830. CeOperand ceOperand;
  1831. ceOperand.mKind = CeOperandKind_FrameOfs;
  1832. ceOperand.mFrameOfs = frameOffset;
  1833. ceOperand.mType = paramType;
  1834. frameOffset += paramType->mSize;
  1835. mValueToOperand[beArg] = ceOperand;
  1836. }
  1837. }
  1838. void CeBuilder::ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance* dupMethodInstance, bool forceIRWrites)
  1839. {
  1840. SetAndRestoreValue<BfMethodState*> prevMethodStateInConstEval(mCeMachine->mCeModule->mCurMethodState, NULL);
  1841. BfAutoComplete* prevAutoComplete = NULL;
  1842. if (mCeMachine->mCeModule->mCompiler->mResolvePassData != NULL)
  1843. {
  1844. prevAutoComplete = mCeMachine->mCeModule->mCompiler->mResolvePassData->mAutoComplete;
  1845. mCeMachine->mCeModule->mCompiler->mResolvePassData->mAutoComplete = NULL;
  1846. }
  1847. auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen;
  1848. auto irBuilder = mCeMachine->mCeModule->mBfIRBuilder;
  1849. auto beModule = irCodeGen->mBeModule;
  1850. beModule->mCeMachine = mCeMachine;
  1851. dupMethodInstance->mIsReified = true;
  1852. dupMethodInstance->mInCEMachine = false; // Only have the original one
  1853. // We can't use methodInstance->mMethodInstanceGroup because we may add foreign method instances which
  1854. // would reallocate the methodInstanceGroup
  1855. BfMethodInstanceGroup methodInstanceGroup;
  1856. methodInstanceGroup.mOwner = methodInstance->mMethodInstanceGroup->mOwner;
  1857. methodInstanceGroup.mDefault = methodInstance->mMethodInstanceGroup->mDefault;
  1858. methodInstanceGroup.mMethodIdx = methodInstance->mMethodInstanceGroup->mMethodIdx;
  1859. methodInstanceGroup.mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude;
  1860. dupMethodInstance->mMethodInstanceGroup = &methodInstanceGroup;
  1861. mCeMachine->mCeModule->mHadBuildError = false;
  1862. auto irState = irBuilder->GetState();
  1863. auto beState = irCodeGen->GetState();
  1864. mCeMachine->mCeModule->ProcessMethod(dupMethodInstance, true, forceIRWrites);
  1865. irCodeGen->SetState(beState);
  1866. irBuilder->SetState(irState);
  1867. if (mCeMachine->mCeModule->mCompiler->mResolvePassData != NULL)
  1868. mCeMachine->mCeModule->mCompiler->mResolvePassData->mAutoComplete = prevAutoComplete;
  1869. methodInstanceGroup.mDefault = NULL;
  1870. dupMethodInstance->mMethodInstanceGroup = methodInstance->mMethodInstanceGroup;
  1871. }
  1872. void CeBuilder::Build()
  1873. {
  1874. SetAndRestoreValue<CeDbgState*> prevDbgState;
  1875. if (mCeMachine->mDebugger != NULL)
  1876. prevDbgState.Init(mCeMachine->mDebugger->mCurDbgState, NULL);
  1877. auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen;
  1878. auto irBuilder = mCeMachine->mCeModule->mBfIRBuilder;
  1879. auto beModule = irCodeGen->mBeModule;
  1880. mCeFunction->mFailed = true;
  1881. auto methodInstance = mCeFunction->mMethodInstance;
  1882. if ((methodInstance != NULL) && (!mCeMachine->HasFailed()))
  1883. {
  1884. BfMethodInstance dupMethodInstance;
  1885. dupMethodInstance.CopyFrom(methodInstance);
  1886. auto methodDef = methodInstance->mMethodDef;
  1887. bool isGenericVariation = (methodInstance->mIsUnspecializedVariation) || (methodInstance->GetOwner()->IsUnspecializedTypeVariation());
  1888. int dependentGenericStartIdx = 0;
  1889. if ((((methodInstance->mMethodInfoEx != NULL) && ((int)methodInstance->mMethodInfoEx->mMethodGenericArguments.size() > dependentGenericStartIdx)) ||
  1890. ((methodInstance->GetOwner()->IsGenericTypeInstance()) && (!isGenericVariation) && (!methodInstance->mMethodDef->mIsLocalMethod) && (!methodInstance->mIsUnspecialized))))
  1891. {
  1892. auto unspecializedMethodInstance = mCeMachine->mCeModule->GetUnspecializedMethodInstance(methodInstance, !methodInstance->mMethodDef->mIsLocalMethod);
  1893. if (!unspecializedMethodInstance->mHasBeenProcessed)
  1894. {
  1895. BfMethodInstance dupUnspecMethodInstance;
  1896. dupUnspecMethodInstance.CopyFrom(unspecializedMethodInstance);
  1897. ProcessMethod(unspecializedMethodInstance, &dupUnspecMethodInstance, false);
  1898. if (dupUnspecMethodInstance.mMethodInfoEx != NULL)
  1899. dupMethodInstance.GetMethodInfoEx()->mGenericTypeBindings = dupUnspecMethodInstance.mMethodInfoEx->mGenericTypeBindings;
  1900. }
  1901. }
  1902. // Clear this so we can properly get QueueStaticField calls
  1903. mCeMachine->mCeModule->mStaticFieldRefs.Clear();
  1904. int startFunctionCount = (int)beModule->mFunctions.size();
  1905. ProcessMethod(methodInstance, &dupMethodInstance, true);
  1906. if (mCeFunction->mInitializeState == CeFunction::InitializeState_Initialized)
  1907. return;
  1908. if (!dupMethodInstance.mIRFunction)
  1909. {
  1910. mCeFunction->mFailed = true;
  1911. return;
  1912. }
  1913. mBeFunction = (BeFunction*)irCodeGen->TryGetBeValue(dupMethodInstance.mIRFunction.mId);
  1914. if (mBeFunction == NULL)
  1915. {
  1916. mCeFunction->mFailed = true;
  1917. return;
  1918. }
  1919. mIntPtrType = irCodeGen->mBeContext->GetPrimitiveType((mPtrSize == 4) ? BeTypeCode_Int32 : BeTypeCode_Int64);
  1920. for (int funcIdx = startFunctionCount; funcIdx < (int)beModule->mFunctions.size(); funcIdx++)
  1921. {
  1922. auto beFunction = beModule->mFunctions[funcIdx];
  1923. if (beFunction == mBeFunction)
  1924. continue;
  1925. if (beFunction->mBlocks.IsEmpty())
  1926. continue;
  1927. CeFunction* innerFunction = new CeFunction();
  1928. innerFunction->mCeMachine = mCeMachine;
  1929. innerFunction->mIsVarReturn = beFunction->mIsVarReturn;
  1930. innerFunction->mCeInnerFunctionInfo = new CeInnerFunctionInfo();
  1931. innerFunction->mCeInnerFunctionInfo->mName = beFunction->mName;
  1932. innerFunction->mCeInnerFunctionInfo->mBeFunction = beFunction;
  1933. innerFunction->mCeInnerFunctionInfo->mOwner = mCeFunction;
  1934. if (mCeMachine->mDebugger != NULL)
  1935. innerFunction->mDbgInfo = new CeDbgFunctionInfo();
  1936. mInnerFunctionMap[beFunction] = (int)mCeFunction->mInnerFunctions.size();
  1937. mCeFunction->mInnerFunctions.Add(innerFunction);
  1938. mCeMachine->MapFunctionId(innerFunction);
  1939. }
  1940. if (!mCeFunction->mCeFunctionInfo->mName.IsEmpty())
  1941. {
  1942. BF_ASSERT(mCeFunction->mCeFunctionInfo->mName == mBeFunction->mName);
  1943. }
  1944. else
  1945. {
  1946. mCeFunction->mCeFunctionInfo->mName = mBeFunction->mName;
  1947. mCeMachine->mNamedFunctionMap[mCeFunction->mCeFunctionInfo->mName] = mCeFunction->mCeFunctionInfo;
  1948. }
  1949. if (mCeMachine->mCeModule->mHadBuildError)
  1950. {
  1951. mCeFunction->mGenError = "Method had errors";
  1952. mCeMachine->mCeModule->mHadBuildError = false;
  1953. return;
  1954. }
  1955. }
  1956. else
  1957. {
  1958. BF_ASSERT(mCeFunction->mCeInnerFunctionInfo != NULL);
  1959. mBeFunction = mCeFunction->mCeInnerFunctionInfo->mBeFunction;
  1960. BF_ASSERT(mBeFunction != NULL);
  1961. mCeFunction->mCeInnerFunctionInfo->mBeFunction = NULL;
  1962. }
  1963. SetAndRestoreValue<BeFunction*> prevBeFunction(beModule->mActiveFunction, mBeFunction);
  1964. // Create blocks
  1965. for (int blockIdx = 0; blockIdx < (int)mBeFunction->mBlocks.size(); blockIdx++)
  1966. {
  1967. auto beBlock = mBeFunction->mBlocks[blockIdx];
  1968. CeBlock ceBlock;
  1969. mBlocks.Add(ceBlock);
  1970. CeOperand ceOperand;
  1971. ceOperand.mKind = CeOperandKind_Block;
  1972. ceOperand.mBlockIdx = blockIdx;
  1973. mValueToOperand[beBlock] = ceOperand;
  1974. }
  1975. // Instruction pre-pass
  1976. for (int blockIdx = 0; blockIdx < (int)mBeFunction->mBlocks.size(); blockIdx++)
  1977. {
  1978. auto beBlock = mBeFunction->mBlocks[blockIdx];
  1979. auto& ceBlock = mBlocks[blockIdx];
  1980. for (int instIdx = 0; instIdx < (int)beBlock->mInstructions.size(); instIdx++)
  1981. {
  1982. auto inst = beBlock->mInstructions[instIdx];
  1983. int instType = inst->GetTypeId();
  1984. switch (instType)
  1985. {
  1986. case BePhiInst::TypeId:
  1987. {
  1988. auto castedInst = (BePhiInst*)inst;
  1989. auto resultType = castedInst->GetType();
  1990. auto phiResult = FrameAlloc(resultType);
  1991. mValueToOperand[castedInst] = phiResult;
  1992. for (auto& phiIncoming : castedInst->mIncoming)
  1993. {
  1994. auto incomingBlockOpr = GetOperand(phiIncoming->mBlock);
  1995. auto& incomingBlock = mBlocks[incomingBlockOpr.mBlockIdx];
  1996. CePhiOutgoing phiOutgoing;
  1997. phiOutgoing.mPhiValue = phiIncoming->mValue;
  1998. phiOutgoing.mPhiInst = castedInst;
  1999. phiOutgoing.mPhiBlockIdx = blockIdx;
  2000. incomingBlock.mPhiOutgoing.Add(phiOutgoing);
  2001. }
  2002. }
  2003. break;
  2004. case BeRetInst::TypeId:
  2005. case BeSetRetInst::TypeId:
  2006. {
  2007. auto castedInst = (BeRetInst*)inst;
  2008. if (castedInst->mRetValue != NULL)
  2009. {
  2010. auto retType = castedInst->mRetValue->GetType();
  2011. mCeFunction->mMaxReturnSize = BF_MAX(retType->mSize, mCeFunction->mMaxReturnSize);
  2012. }
  2013. }
  2014. break;
  2015. }
  2016. }
  2017. }
  2018. int scopeIdx = -1;
  2019. // Primary instruction pass
  2020. BeDbgLoc* prevEmitDbgPos = NULL;
  2021. bool inHeadAlloca = true;
  2022. for (int blockIdx = 0; blockIdx < (int)mBeFunction->mBlocks.size(); blockIdx++)
  2023. {
  2024. auto beBlock = mBeFunction->mBlocks[blockIdx];
  2025. auto ceBlock = &mBlocks[blockIdx];
  2026. ceBlock->mEmitOfs = GetCodePos();
  2027. if (blockIdx == 0)
  2028. HandleParams();
  2029. for (int instIdx = 0; instIdx < (int)beBlock->mInstructions.size(); instIdx++)
  2030. {
  2031. auto inst = beBlock->mInstructions[instIdx];
  2032. CeOperand result;
  2033. int startCodePos = GetCodePos();
  2034. mCurDbgLoc = inst->mDbgLoc;
  2035. if ((prevEmitDbgPos != mCurDbgLoc) && (mCurDbgLoc != NULL))
  2036. {
  2037. auto _GetScope = [&](BeMDNode* mdNode, int inlinedAt)
  2038. {
  2039. BeDbgFile* dbgFile;
  2040. BeDbgFunction* dbgFunc = NULL;
  2041. String nameAdd;
  2042. while (auto dbgLexicalBlock = BeValueDynCast<BeDbgLexicalBlock>(mdNode))
  2043. mdNode = dbgLexicalBlock->mScope;
  2044. if (dbgFunc = BeValueDynCast<BeDbgFunction>(mdNode))
  2045. {
  2046. dbgFile = dbgFunc->mFile;
  2047. }
  2048. else if (auto dbgLoc = BeValueDynCast<BeDbgLoc>(mdNode))
  2049. dbgFile = dbgLoc->GetDbgFile();
  2050. else
  2051. dbgFile = BeValueDynCast<BeDbgFile>(mdNode);
  2052. int* valuePtr = NULL;
  2053. CeDbgInlineLookup lookupPair(dbgFile, inlinedAt);
  2054. if (mDbgScopeMap.TryAdd(lookupPair, NULL, &valuePtr))
  2055. {
  2056. int scopeIdx = (int)mCeFunction->mDbgScopes.size();
  2057. String filePath = dbgFile->mDirectory;
  2058. filePath.Append(DIR_SEP_CHAR);
  2059. filePath += dbgFile->mFileName;
  2060. CeDbgScope dbgScope;
  2061. dbgScope.mFilePath = filePath;
  2062. dbgScope.mInlinedAt = inlinedAt;
  2063. dbgScope.mMethodVal = -1;
  2064. if (dbgFunc != NULL)
  2065. {
  2066. if (dbgFunc->mValue == NULL)
  2067. {
  2068. if (!dbgFunc->mLinkageName.IsEmpty())
  2069. {
  2070. int methodRefIdx = atoi(dbgFunc->mLinkageName.c_str());
  2071. dbgScope.mMethodVal = methodRefIdx | CeDbgScope::MethodValFlag_MethodRef;
  2072. }
  2073. else
  2074. {
  2075. CeDbgMethodRef dbgMethodRef;
  2076. dbgMethodRef.mNameMod = dbgFunc->mName;
  2077. int* valuePtr = NULL;
  2078. if (mDbgMethodRefMap.TryAdd(dbgMethodRef, NULL, &valuePtr))
  2079. {
  2080. *valuePtr = mCeFunction->mDbgMethodRefTable.mSize;
  2081. mCeFunction->mDbgMethodRefTable.Add(dbgMethodRef);
  2082. }
  2083. dbgScope.mMethodVal = *valuePtr | CeDbgScope::MethodValFlag_MethodRef;
  2084. }
  2085. }
  2086. else if (dbgFunc->mValue != mBeFunction)
  2087. dbgScope.mMethodVal = GetCallTableIdx(dbgFunc->mValue, NULL);
  2088. }
  2089. mCeFunction->mDbgScopes.Add(dbgScope);
  2090. *valuePtr = scopeIdx;
  2091. return scopeIdx;
  2092. }
  2093. else
  2094. return *valuePtr;
  2095. };
  2096. std::function<int(BeDbgLoc*)> _GetInlinedScope = [&](BeDbgLoc* dbgLoc)
  2097. {
  2098. if (dbgLoc == NULL)
  2099. return -1;
  2100. int* valuePtr = NULL;
  2101. if (mDbgInlineMap.TryAdd(dbgLoc, NULL, &valuePtr))
  2102. {
  2103. CeDbgInlineEntry inlineEntry;
  2104. inlineEntry.mLine = dbgLoc->mLine;
  2105. inlineEntry.mColumn = dbgLoc->mColumn;
  2106. auto inlinedAt = _GetInlinedScope(dbgLoc->mDbgInlinedAt);
  2107. inlineEntry.mScope = _GetScope(dbgLoc->mDbgScope, inlinedAt);
  2108. *valuePtr = mCeFunction->mDbgInlineTable.mSize;
  2109. mCeFunction->mDbgInlineTable.Add(inlineEntry);
  2110. }
  2111. return *valuePtr;
  2112. };
  2113. int inlinedAt = _GetInlinedScope(mCurDbgLoc->mDbgInlinedAt);
  2114. scopeIdx = _GetScope(mCurDbgLoc->mDbgScope, inlinedAt);
  2115. }
  2116. int instType = inst->GetTypeId();
  2117. switch (instType)
  2118. {
  2119. case BeAllocaInst::TypeId:
  2120. case BeNumericCastInst::TypeId:
  2121. case BeBitCastInst::TypeId:
  2122. break;
  2123. default:
  2124. inHeadAlloca = false;
  2125. break;
  2126. }
  2127. switch (instType)
  2128. {
  2129. case BeNopInst::TypeId:
  2130. case BeLifetimeSoftEndInst::TypeId:
  2131. case BeLifetimeStartInst::TypeId:
  2132. case BeLifetimeExtendInst::TypeId:
  2133. case BeValueScopeStartInst::TypeId:
  2134. case BeValueScopeEndInst::TypeId:
  2135. case BeValueScopeRetainInst::TypeId:
  2136. case BeComptimeGetVirtualFunc::TypeId:
  2137. case BeComptimeGetInterfaceFunc::TypeId:
  2138. break;
  2139. case BeUnreachableInst::TypeId:
  2140. Emit(CeOp_InvalidOp);
  2141. break;
  2142. case BeUndefValueInst::TypeId:
  2143. {
  2144. auto castedInst = (BeUndefValueInst*)inst;
  2145. result = FrameAlloc(castedInst->mType);
  2146. }
  2147. break;
  2148. case BeAllocaInst::TypeId:
  2149. {
  2150. auto castedInst = (BeAllocaInst*)inst;
  2151. CeOperand ceSize;
  2152. ceSize.mKind = CeOperandKind_Immediate;
  2153. ceSize.mImmediate = castedInst->mType->mSize;
  2154. ceSize.mType = mIntPtrType;
  2155. bool isAligned16 = false;
  2156. int align = castedInst->mAlign;
  2157. BeType* allocType = castedInst->mType;
  2158. bool preservedVolatiles = false;
  2159. if (castedInst->mArraySize != NULL)
  2160. {
  2161. auto mcArraySize = GetOperand(castedInst->mArraySize, false, true);
  2162. if (mcArraySize.IsImmediate())
  2163. {
  2164. ceSize.mImmediate = ceSize.mImmediate * mcArraySize.mImmediate;
  2165. }
  2166. else
  2167. {
  2168. inHeadAlloca = false;
  2169. if (ceSize.mImmediate == 1)
  2170. {
  2171. ceSize = mcArraySize;
  2172. }
  2173. else
  2174. {
  2175. ceSize = EmitConst(ceSize.mImmediate, mcArraySize.mType->mSize);
  2176. EmitSizedOp(CeOp_Mul_I8, ceSize.mType->mSize);
  2177. EmitFrameOffset(ceSize);
  2178. EmitFrameOffset(ceSize);
  2179. EmitFrameOffset(mcArraySize);
  2180. }
  2181. }
  2182. }
  2183. if (inHeadAlloca)
  2184. {
  2185. BF_ASSERT(ceSize.mKind == CeOperandKind_Immediate);
  2186. mFrameSize += ceSize.mImmediate;
  2187. result.mKind = CeOperandKind_AllocaAddr;
  2188. result.mFrameOfs = -mFrameSize;
  2189. result.mType = castedInst->mType;
  2190. }
  2191. else
  2192. {
  2193. if (ceSize.mKind == CeOperandKind_Immediate)
  2194. {
  2195. Emit(CeOp_AdjustSPConst);
  2196. Emit((int32)-ceSize.mImmediate);
  2197. }
  2198. else
  2199. {
  2200. Emit(CeOp_AdjustSPNeg);
  2201. EmitFrameOffset(ceSize);
  2202. }
  2203. auto ptrType = beModule->mContext->GetPointerTo(allocType);
  2204. result = FrameAlloc(ptrType);
  2205. Emit(CeOp_GetSP);
  2206. EmitFrameOffset(result);
  2207. }
  2208. }
  2209. break;
  2210. case BeLoadInst::TypeId:
  2211. {
  2212. auto castedInst = (BeLoadInst*)inst;
  2213. auto ceTarget = GetOperand(castedInst->mTarget, true);
  2214. result = EmitLoad(ceTarget, inst->mRefCount);
  2215. }
  2216. break;
  2217. case BeBinaryOpInst::TypeId:
  2218. {
  2219. auto castedInst = (BeBinaryOpInst*)inst;
  2220. auto ceLHS = GetOperand(castedInst->mLHS);
  2221. auto ceRHS = GetOperand(castedInst->mRHS);
  2222. switch (castedInst->mOpKind)
  2223. {
  2224. case BeBinaryOpKind_Add:
  2225. EmitBinaryOp(CeOp_Add_I8, CeOp_Add_F32, ceLHS, ceRHS, result);
  2226. break;
  2227. case BeBinaryOpKind_Subtract:
  2228. EmitBinaryOp(CeOp_Sub_I8, CeOp_Sub_F32, ceLHS, ceRHS, result);
  2229. break;
  2230. case BeBinaryOpKind_Multiply:
  2231. EmitBinaryOp(CeOp_Mul_I8, CeOp_Mul_F32, ceLHS, ceRHS, result);
  2232. break;
  2233. case BeBinaryOpKind_SDivide:
  2234. EmitBinaryOp(CeOp_Div_I8, CeOp_Div_F32, ceLHS, ceRHS, result);
  2235. break;
  2236. case BeBinaryOpKind_UDivide:
  2237. EmitBinaryOp(CeOp_Div_U8, CeOp_InvalidOp, ceLHS, ceRHS, result);
  2238. break;
  2239. case BeBinaryOpKind_SModulus:
  2240. EmitBinaryOp(CeOp_Mod_I8, CeOp_Mod_F32, ceLHS, ceRHS, result);
  2241. break;
  2242. case BeBinaryOpKind_UModulus:
  2243. EmitBinaryOp(CeOp_Mod_U8, CeOp_InvalidOp, ceLHS, ceRHS, result);
  2244. break;
  2245. case BeBinaryOpKind_BitwiseAnd:
  2246. EmitBinaryOp(CeOp_And_I8, CeOp_InvalidOp, ceLHS, ceRHS, result);
  2247. break;
  2248. case BeBinaryOpKind_BitwiseOr:
  2249. EmitBinaryOp(CeOp_Or_I8, CeOp_InvalidOp, ceLHS, ceRHS, result);
  2250. break;
  2251. case BeBinaryOpKind_ExclusiveOr:
  2252. EmitBinaryOp(CeOp_Xor_I8, CeOp_InvalidOp, ceLHS, ceRHS, result);
  2253. break;
  2254. case BeBinaryOpKind_LeftShift:
  2255. EmitBinaryOp(CeOp_Shl_I8, CeOp_InvalidOp, ceLHS, ceRHS, result);
  2256. break;
  2257. case BeBinaryOpKind_RightShift:
  2258. EmitBinaryOp(CeOp_Shr_U8, CeOp_InvalidOp, ceLHS, ceRHS, result);
  2259. break;
  2260. case BeBinaryOpKind_ARightShift:
  2261. EmitBinaryOp(CeOp_Shr_I8, CeOp_InvalidOp, ceLHS, ceRHS, result);
  2262. break;
  2263. default:
  2264. Fail("Invalid binary op");
  2265. }
  2266. }
  2267. break;
  2268. case BeBitCastInst::TypeId:
  2269. {
  2270. auto castedInst = (BeBitCastInst*)inst;
  2271. auto mcValue = GetOperand(castedInst->mValue, false, true);
  2272. if (castedInst->mToType->IsInt())
  2273. {
  2274. BF_ASSERT(castedInst->mToType->mSize == 8);
  2275. }
  2276. else
  2277. BF_ASSERT(castedInst->mToType->IsPointer());
  2278. auto toType = castedInst->mToType;
  2279. if (mcValue.IsImmediate())
  2280. {
  2281. if (mcValue.mImmediate == 0)
  2282. {
  2283. CeOperand newImmediate;
  2284. newImmediate.mKind = CeOperandKind_Immediate;
  2285. newImmediate.mType = toType;
  2286. result = newImmediate;
  2287. }
  2288. else
  2289. {
  2290. // Non-zero constant. Weird case, just do an actual MOV
  2291. result = FrameAlloc(toType);
  2292. EmitSizedOp(CeOp_Const_8, result, NULL, true);
  2293. int64 val = mcValue.mImmediate;
  2294. Emit(&val, toType->mSize);
  2295. }
  2296. }
  2297. else
  2298. {
  2299. if (toType->mSize != mcValue.mType->mSize)
  2300. Fail("Invalid bitcast");
  2301. result = mcValue;
  2302. result.mType = toType;
  2303. }
  2304. }
  2305. break;
  2306. case BeNumericCastInst::TypeId:
  2307. {
  2308. auto castedInst = (BeNumericCastInst*)inst;
  2309. auto ceValue = GetOperand(castedInst->mValue);
  2310. result = EmitNumericCast(ceValue, castedInst->mToType, castedInst->mValSigned, castedInst->mToSigned);
  2311. }
  2312. break;
  2313. case BeStoreInst::TypeId:
  2314. {
  2315. auto castedInst = (BeStoreInst*)inst;
  2316. auto mcVal = GetOperand(castedInst->mVal);
  2317. auto mcPtr = GetOperand(castedInst->mPtr, true);
  2318. if (mcPtr.mKind == CeOperandKind_AllocaAddr)
  2319. {
  2320. EmitSizedOp(CeOp_Move_8, mcVal, NULL, true);
  2321. Emit((int32)mcPtr.mFrameOfs);
  2322. }
  2323. else
  2324. {
  2325. EmitSizedOp(CeOp_Store_8, mcVal, NULL, true);
  2326. EmitFrameOffset(mcPtr);
  2327. }
  2328. }
  2329. break;
  2330. case BeRetInst::TypeId:
  2331. case BeSetRetInst::TypeId:
  2332. {
  2333. auto castedInst = (BeRetInst*)inst;
  2334. if (castedInst->mRetValue != NULL)
  2335. {
  2336. auto mcVal = GetOperand(castedInst->mRetValue);
  2337. if (mcVal.mType->mSize > 0)
  2338. {
  2339. BF_ASSERT(mReturnVal.mKind == CeOperandKind_AllocaAddr);
  2340. EmitSizedOp(CeOp_Move_8, mcVal, NULL, true);
  2341. Emit((int32)mReturnVal.mFrameOfs);
  2342. }
  2343. }
  2344. if (instType == BeRetInst::TypeId)
  2345. Emit(CeOp_Ret);
  2346. else
  2347. {
  2348. auto setRetInst = (BeSetRetInst*)inst;
  2349. Emit(CeOp_SetRetType);
  2350. Emit((int32)setRetInst->mReturnTypeId);
  2351. }
  2352. }
  2353. break;
  2354. case BeCmpInst::TypeId:
  2355. {
  2356. auto castedInst = (BeCmpInst*)inst;
  2357. auto ceLHS = GetOperand(castedInst->mLHS);
  2358. auto ceRHS = GetOperand(castedInst->mRHS);
  2359. CeOp iOp = CeOp_InvalidOp;
  2360. CeOp fOp = CeOp_InvalidOp;
  2361. switch (castedInst->mCmpKind)
  2362. {
  2363. case BeCmpKind_EQ:
  2364. iOp = CeOp_Cmp_EQ_I8;
  2365. fOp = CeOp_Cmp_EQ_F32;
  2366. break;
  2367. case BeCmpKind_NE:
  2368. iOp = CeOp_Cmp_NE_I8;
  2369. fOp = CeOp_Cmp_NE_F32;
  2370. break;
  2371. case BeCmpKind_SLT:
  2372. iOp = CeOp_Cmp_SLT_I8;
  2373. fOp = CeOp_Cmp_SLT_F32;
  2374. break;
  2375. case BeCmpKind_ULT:
  2376. iOp = CeOp_Cmp_ULT_I8;
  2377. break;
  2378. case BeCmpKind_SLE:
  2379. iOp = CeOp_Cmp_SLE_I8;
  2380. fOp = CeOp_Cmp_SLE_F32;
  2381. break;
  2382. case BeCmpKind_ULE:
  2383. iOp = CeOp_Cmp_ULE_I8;
  2384. break;
  2385. case BeCmpKind_SGT:
  2386. iOp = CeOp_Cmp_SGT_I8;
  2387. fOp = CeOp_Cmp_SGT_F32;
  2388. break;
  2389. case BeCmpKind_UGT:
  2390. iOp = CeOp_Cmp_UGT_I8;
  2391. break;
  2392. case BeCmpKind_SGE:
  2393. iOp = CeOp_Cmp_SGE_I8;
  2394. fOp = CeOp_Cmp_SGE_F32;
  2395. break;
  2396. case BeCmpKind_UGE:
  2397. iOp = CeOp_Cmp_UGE_I8;
  2398. break;
  2399. }
  2400. if (iOp == CeOp_InvalidOp)
  2401. {
  2402. Fail("Invalid cmp");
  2403. break;
  2404. }
  2405. auto boolType = inst->GetType();
  2406. result = FrameAlloc(boolType);
  2407. EmitBinaryOp(iOp, fOp, ceLHS, ceRHS, result);
  2408. // auto mcInst = AllocInst(BeMCInstKind_Cmp, mcLHS, mcRHS);
  2409. //
  2410. // auto cmpResultIdx = (int)mCmpResults.size();
  2411. // BeCmpResult cmpResult;
  2412. // cmpResult.mCmpKind = castedInst->mCmpKind;
  2413. // mCmpResults.push_back(cmpResult);
  2414. //
  2415. // result.mKind = BeMCOperandKind_CmpResult;
  2416. // result.mCmpResultIdx = cmpResultIdx;
  2417. //
  2418. // mcInst->mResult = result;
  2419. }
  2420. break;
  2421. case BeGEPInst::TypeId:
  2422. {
  2423. auto castedInst = (BeGEPInst*)inst;
  2424. auto ceVal = GetOperand(castedInst->mPtr);
  2425. auto ceIdx0 = GetOperand(castedInst->mIdx0, false, true);
  2426. if ((ceIdx0.mType != NULL) && (ceIdx0.mType->mSize < mPtrSize))
  2427. ceIdx0 = EmitNumericCast(ceIdx0, mIntPtrType, true, true);
  2428. BePointerType* ptrType = (BePointerType*)ceVal.mType;
  2429. BF_ASSERT(ptrType->mTypeCode == BeTypeCode_Pointer);
  2430. result = ceVal;
  2431. if (castedInst->mIdx1 != NULL)
  2432. {
  2433. // We assume we never do both an idx0 and idx1 at once. Fix if we change that.
  2434. BF_ASSERT(castedInst->mIdx0);
  2435. auto ceIdx1 = GetOperand(castedInst->mIdx1, false, true);
  2436. if ((ceIdx1.mType != NULL) && (ceIdx1.mType->mSize < mPtrSize))
  2437. ceIdx1 = EmitNumericCast(ceIdx1, mIntPtrType, true, true);
  2438. if (!ceIdx1.IsImmediate())
  2439. {
  2440. // This path is used when we have a const array that gets indexed by a non-const index value
  2441. if (ptrType->mElementType->mTypeCode == BeTypeCode_SizedArray)
  2442. {
  2443. auto arrayType = (BeSizedArrayType*)ptrType->mElementType;
  2444. auto elementPtrType = beModule->mContext->GetPointerTo(arrayType->mElementType);
  2445. if (ceIdx1.IsImmediate())
  2446. {
  2447. if (ceIdx1.mImmediate == 0)
  2448. {
  2449. result = ceVal;
  2450. result.mType = elementPtrType;
  2451. }
  2452. else
  2453. {
  2454. auto ptrValue = FrameAlloc(elementPtrType);
  2455. result = ptrValue;
  2456. result = FrameAlloc(elementPtrType);
  2457. EmitSizedOp(CeOp_AddConst_I8, mPtrSize);
  2458. EmitFrameOffset(result);
  2459. EmitFrameOffset(ceVal);
  2460. int32 byteOffset = (int32)(ceIdx1.mImmediate * arrayType->mElementType->GetStride());
  2461. if (mPtrSize == 8)
  2462. Emit((int64)byteOffset);
  2463. else
  2464. Emit((int32)byteOffset);
  2465. }
  2466. }
  2467. else
  2468. {
  2469. auto ptrValue = FrameAlloc(elementPtrType);
  2470. result = ptrValue;
  2471. if (ceIdx1.mType->mSize < 4)
  2472. {
  2473. auto ceNewIdx = FrameAlloc(mIntPtrType);
  2474. if (mIntPtrType->mSize == 8)
  2475. {
  2476. if (ceIdx1.mType->mSize == 1)
  2477. Emit(CeOp_Conv_I8_I64);
  2478. else
  2479. Emit(CeOp_Conv_I16_I64);
  2480. }
  2481. else
  2482. {
  2483. if (ceIdx1.mType->mSize == 1)
  2484. Emit(CeOp_Conv_I8_I32);
  2485. else
  2486. Emit(CeOp_Conv_I16_I32);
  2487. }
  2488. EmitFrameOffset(ceNewIdx);
  2489. EmitFrameOffset(ceIdx1);
  2490. ceIdx1 = ceNewIdx;
  2491. }
  2492. result = FrameAlloc(elementPtrType);
  2493. if (mPtrSize == 4)
  2494. {
  2495. auto mcElementSize = FrameAlloc(mIntPtrType);
  2496. Emit(CeOp_Const_32);
  2497. EmitFrameOffset(mcElementSize);
  2498. Emit((int32)arrayType->mElementType->GetStride());
  2499. auto ofsValue = FrameAlloc(mIntPtrType);
  2500. Emit(CeOp_Mul_I32);
  2501. EmitFrameOffset(ofsValue);
  2502. EmitFrameOffset(ceIdx1);
  2503. EmitFrameOffset(mcElementSize);
  2504. Emit(CeOp_Add_I32);
  2505. EmitFrameOffset(result);
  2506. EmitFrameOffset(ceVal);
  2507. EmitFrameOffset(ofsValue);
  2508. }
  2509. else
  2510. {
  2511. auto mcElementSize = FrameAlloc(mIntPtrType);
  2512. Emit(CeOp_Const_64);
  2513. EmitFrameOffset(mcElementSize);
  2514. Emit((int64)arrayType->mElementType->GetStride());
  2515. auto ofsValue = FrameAlloc(mIntPtrType);
  2516. Emit(CeOp_Mul_I64);
  2517. EmitFrameOffset(ofsValue);
  2518. EmitFrameOffset(ceIdx1);
  2519. EmitFrameOffset(mcElementSize);
  2520. Emit(CeOp_Add_I64);
  2521. EmitFrameOffset(result);
  2522. EmitFrameOffset(ceVal);
  2523. EmitFrameOffset(ofsValue);
  2524. }
  2525. }
  2526. }
  2527. else
  2528. Fail("Invalid GEP");
  2529. }
  2530. else
  2531. {
  2532. BF_ASSERT(ceIdx1.IsImmediate());
  2533. int byteOffset = 0;
  2534. BeType* elementType = NULL;
  2535. if (ptrType->mElementType->mTypeCode == BeTypeCode_Struct)
  2536. {
  2537. BeStructType* structType = (BeStructType*)ptrType->mElementType;
  2538. auto& structMember = structType->mMembers[ceIdx1.mImmediate];
  2539. elementType = structMember.mType;
  2540. byteOffset = structMember.mByteOffset;
  2541. }
  2542. else if (ptrType->mElementType->mTypeCode == BeTypeCode_SizedArray)
  2543. {
  2544. auto arrayType = (BeSizedArrayType*)ptrType->mElementType;
  2545. elementType = arrayType->mElementType;
  2546. byteOffset = ceIdx1.mImmediate * elementType->GetStride();
  2547. }
  2548. else if (ptrType->mElementType->mTypeCode == BeTypeCode_Vector)
  2549. {
  2550. auto arrayType = (BeVectorType*)ptrType->mElementType;
  2551. elementType = arrayType->mElementType;
  2552. byteOffset = ceIdx1.mImmediate * elementType->GetStride();
  2553. }
  2554. else
  2555. {
  2556. Fail("Invalid gep target");
  2557. }
  2558. auto elementPtrType = beModule->mContext->GetPointerTo(elementType);
  2559. if (byteOffset != 0)
  2560. {
  2561. result = FrameAlloc(elementPtrType);
  2562. EmitSizedOp(CeOp_AddConst_I8, mPtrSize);
  2563. EmitFrameOffset(result);
  2564. EmitFrameOffset(ceVal);
  2565. if (mPtrSize == 8)
  2566. Emit((int64)byteOffset);
  2567. else
  2568. Emit((int32)byteOffset);
  2569. }
  2570. else
  2571. {
  2572. result.mType = elementPtrType;
  2573. }
  2574. }
  2575. }
  2576. else
  2577. {
  2578. CeOperand mcRelOffset;
  2579. int relScale = 1;
  2580. if (ceIdx0.IsImmediate())
  2581. {
  2582. int byteOffset = ceIdx0.mImmediate * ptrType->mElementType->GetStride();
  2583. if (byteOffset != 0)
  2584. {
  2585. result = FrameAlloc(ptrType);
  2586. EmitSizedOp(CeOp_AddConst_I8, mPtrSize);
  2587. EmitFrameOffset(result);
  2588. EmitFrameOffset(ceVal);
  2589. if (mPtrSize == 8)
  2590. Emit((int64)byteOffset);
  2591. else
  2592. Emit((int32)byteOffset);
  2593. }
  2594. }
  2595. else
  2596. {
  2597. result = FrameAlloc(ptrType);
  2598. if (mPtrSize == 4)
  2599. {
  2600. auto mcElementSize = FrameAlloc(mIntPtrType);
  2601. Emit(CeOp_Const_32);
  2602. EmitFrameOffset(mcElementSize);
  2603. Emit((int32)ptrType->mElementType->GetStride());
  2604. auto ofsValue = FrameAlloc(mIntPtrType);
  2605. Emit(CeOp_Mul_I32);
  2606. EmitFrameOffset(ofsValue);
  2607. EmitFrameOffset(ceIdx0);
  2608. EmitFrameOffset(mcElementSize);
  2609. Emit(CeOp_Add_I32);
  2610. EmitFrameOffset(result);
  2611. EmitFrameOffset(ceVal);
  2612. EmitFrameOffset(ofsValue);
  2613. }
  2614. else
  2615. {
  2616. auto mcElementSize = FrameAlloc(mIntPtrType);
  2617. Emit(CeOp_Const_64);
  2618. EmitFrameOffset(mcElementSize);
  2619. Emit((int64)ptrType->mElementType->GetStride());
  2620. auto ofsValue = FrameAlloc(mIntPtrType);
  2621. Emit(CeOp_Mul_I64);
  2622. EmitFrameOffset(ofsValue);
  2623. EmitFrameOffset(ceIdx0);
  2624. EmitFrameOffset(mcElementSize);
  2625. Emit(CeOp_Add_I64);
  2626. EmitFrameOffset(result);
  2627. EmitFrameOffset(ceVal);
  2628. EmitFrameOffset(ofsValue);
  2629. }
  2630. }
  2631. }
  2632. }
  2633. break;
  2634. case BeExtractValueInst::TypeId:
  2635. {
  2636. auto castedInst = (BeExtractValueInst*)inst;
  2637. BeConstant* constant = BeValueDynCast<BeConstant>(castedInst->mAggVal);
  2638. CeOperand mcAgg;
  2639. if (constant != NULL)
  2640. {
  2641. result.mImmediate = 0;
  2642. BeType* wantDefaultType = NULL;
  2643. if (constant->mType->IsStruct())
  2644. {
  2645. BeStructType* structType = (BeStructType*)constant->mType;
  2646. auto& member = structType->mMembers[castedInst->mIdx];
  2647. wantDefaultType = member.mType;
  2648. }
  2649. else if (constant->mType->IsSizedArray())
  2650. {
  2651. BeSizedArrayType* arrayType = (BeSizedArrayType*)constant->mType;
  2652. wantDefaultType = arrayType->mElementType;
  2653. }
  2654. if (wantDefaultType != NULL)
  2655. {
  2656. // switch (wantDefaultType->mTypeCode)
  2657. // {
  2658. // case BeTypeCode_Boolean:
  2659. // case BeTypeCode_Int8:
  2660. // result.mKind = BeMCOperandKind_Immediate_i8;
  2661. // break;
  2662. // case BeTypeCode_Int16:
  2663. // result.mKind = BeMCOperandKind_Immediate_i16;
  2664. // break;
  2665. // case BeTypeCode_Int32:
  2666. // result.mKind = BeMCOperandKind_Immediate_i32;
  2667. // break;
  2668. // case BeTypeCode_Int64:
  2669. // result.mKind = BeMCOperandKind_Immediate_i64;
  2670. // break;
  2671. // case BeTypeCode_Float:
  2672. // result.mKind = BeMCOperandKind_Immediate_f32;
  2673. // break;
  2674. // case BeTypeCode_Double:
  2675. // result.mKind = BeMCOperandKind_Immediate_f64;
  2676. // break;
  2677. // case BeTypeCode_Pointer:
  2678. // result.mKind = BeMCOperandKind_Immediate_Null;
  2679. // result.mType = wantDefaultType;
  2680. // break;
  2681. // case BeTypeCode_Struct:
  2682. // case BeTypeCode_SizedArray:
  2683. // {
  2684. // auto subConst = mAlloc.Alloc<BeConstant>();
  2685. // subConst->mType = wantDefaultType;
  2686. // result.mConstant = subConst;
  2687. // result.mKind = BeMCOperandKind_ConstAgg;
  2688. // }
  2689. // break;
  2690. // default:
  2691. // NotImpl();
  2692. // }
  2693. Fail("Unhandled extract");
  2694. }
  2695. break;
  2696. }
  2697. else
  2698. {
  2699. mcAgg = GetOperand(castedInst->mAggVal);
  2700. }
  2701. auto aggType = mcAgg.mType;
  2702. int byteOffset = 0;
  2703. BeType* memberType = NULL;
  2704. if (aggType->IsSizedArray())
  2705. {
  2706. auto sizedArray = (BeSizedArrayType*)aggType;
  2707. memberType = sizedArray->mElementType;
  2708. byteOffset = memberType->GetStride() * castedInst->mIdx;
  2709. }
  2710. else
  2711. {
  2712. BF_ASSERT(aggType->IsStruct());
  2713. BeStructType* structType = (BeStructType*)aggType;
  2714. auto& structMember = structType->mMembers[castedInst->mIdx];
  2715. byteOffset = structMember.mByteOffset;
  2716. memberType = structMember.mType;
  2717. }
  2718. if (byteOffset != 0)
  2719. {
  2720. auto ptrVal = FrameAlloc(beModule->mContext->GetPrimitiveType(BeTypeCode_Int32));
  2721. Emit(CeOp_FrameAddrOfs_32);
  2722. EmitFrameOffset(ptrVal);
  2723. EmitFrameOffset(mcAgg);
  2724. Emit((int32)byteOffset);
  2725. result = FrameAlloc(memberType);
  2726. EmitSizedOp(CeOp_Load_8, memberType->mSize);
  2727. EmitFrameOffset(result);
  2728. EmitFrameOffset(ptrVal);
  2729. }
  2730. else
  2731. {
  2732. result = mcAgg;
  2733. result.mType = memberType;
  2734. }
  2735. }
  2736. break;
  2737. case BeBrInst::TypeId:
  2738. {
  2739. auto castedInst = (BeBrInst*)inst;
  2740. auto targetBlock = GetOperand(castedInst->mTargetBlock);
  2741. BF_ASSERT(targetBlock.mKind == CeOperandKind_Block);
  2742. FlushPhi(ceBlock, targetBlock.mBlockIdx);
  2743. if (targetBlock.mBlockIdx == blockIdx + 1)
  2744. {
  2745. // Do nothing - just continuing to next block
  2746. break;
  2747. }
  2748. EmitJump(CeOp_Jmp, targetBlock);
  2749. }
  2750. break;
  2751. case BeCondBrInst::TypeId:
  2752. {
  2753. auto castedInst = (BeCondBrInst*)inst;
  2754. auto testVal = GetOperand(castedInst->mCond, true);
  2755. auto trueBlock = GetOperand(castedInst->mTrueBlock);
  2756. auto falseBlock = GetOperand(castedInst->mFalseBlock);
  2757. FlushPhi(ceBlock, trueBlock.mBlockIdx);
  2758. EmitJump(CeOp_JmpIf, trueBlock);
  2759. EmitFrameOffset(testVal);
  2760. FlushPhi(ceBlock, falseBlock.mBlockIdx);
  2761. EmitJump(CeOp_Jmp, falseBlock);
  2762. }
  2763. break;
  2764. case BePhiInst::TypeId:
  2765. result = GetOperand(inst);
  2766. BF_ASSERT(result);
  2767. break;
  2768. case BeNegInst::TypeId:
  2769. {
  2770. auto castedInst = (BeNegInst*)inst;
  2771. auto ceValue = GetOperand(castedInst->mValue);
  2772. EmitUnaryOp(CeOp_Neg_I8, CeOp_Neg_F32, ceValue, result);
  2773. }
  2774. break;
  2775. case BeNotInst::TypeId:
  2776. {
  2777. auto castedInst = (BeNotInst*)inst;
  2778. auto ceValue = GetOperand(castedInst->mValue);
  2779. if (ceValue.mType->mTypeCode == BeTypeCode_Boolean)
  2780. EmitUnaryOp(CeOp_Not_I1, CeOp_InvalidOp, ceValue, result);
  2781. else
  2782. EmitUnaryOp(CeOp_Not_I8, CeOp_InvalidOp, ceValue, result);
  2783. }
  2784. break;
  2785. case BeSwitchInst::TypeId:
  2786. {
  2787. auto castedInst = (BeSwitchInst*)inst;
  2788. std::stable_sort(castedInst->mCases.begin(), castedInst->mCases.end(), [&](const BeSwitchCase& lhs, const BeSwitchCase& rhs)
  2789. {
  2790. return lhs.mValue->mInt64 < rhs.mValue->mInt64;
  2791. });
  2792. int numVals = castedInst->mCases.size();
  2793. if (numVals > 0)
  2794. {
  2795. EmitBinarySwitchSection(castedInst, 0, castedInst->mCases.size());
  2796. }
  2797. auto mcDefaultBlock = GetOperand(castedInst->mDefaultBlock);
  2798. EmitJump(CeOp_Jmp, mcDefaultBlock);
  2799. }
  2800. break;
  2801. case BeCallInst::TypeId:
  2802. {
  2803. auto castedInst = (BeCallInst*)inst;
  2804. BeType* returnType = NULL;
  2805. bool isVarArg = false;
  2806. bool useAltArgs = false;
  2807. CeOperand ceFunc;
  2808. BeFunctionType* beFuncType = NULL;
  2809. CeOperand virtTarget;
  2810. int ifaceTypeId = -1;
  2811. int virtualTableIdx = -1;
  2812. if (auto intrin = BeValueDynCast<BeIntrinsic>(castedInst->mFunc))
  2813. {
  2814. switch (intrin->mKind)
  2815. {
  2816. case BfIRIntrinsic_Abs:
  2817. EmitUnaryOp(CeOp_Abs_I8, CeOp_Abs_F32, GetOperand(castedInst->mArgs[0].mValue), result);
  2818. break;
  2819. case BfIRIntrinsic_Cast:
  2820. {
  2821. result = GetOperand(castedInst->mArgs[0].mValue);
  2822. result.mType = intrin->mReturnType;
  2823. }
  2824. break;
  2825. case BfIRIntrinsic_MemCpy:
  2826. case BfIRIntrinsic_MemMove:
  2827. {
  2828. CeOperand ceDestPtr = GetOperand(castedInst->mArgs[0].mValue);
  2829. CeOperand ceSrcPtr = GetOperand(castedInst->mArgs[1].mValue);
  2830. CeOperand ceSize = GetOperand(castedInst->mArgs[2].mValue);
  2831. Emit(CeOp_MemCpy);
  2832. EmitFrameOffset(ceDestPtr);
  2833. EmitFrameOffset(ceSrcPtr);
  2834. EmitFrameOffset(ceSize);
  2835. }
  2836. break;
  2837. case BfIRIntrinsic_MemSet:
  2838. {
  2839. CeOperand ceDestPtr = GetOperand(castedInst->mArgs[0].mValue);
  2840. CeOperand ceValue = GetOperand(castedInst->mArgs[1].mValue);
  2841. CeOperand ceSize = GetOperand(castedInst->mArgs[2].mValue);
  2842. Emit(CeOp_MemSet);
  2843. EmitFrameOffset(ceDestPtr);
  2844. EmitFrameOffset(ceValue);
  2845. EmitFrameOffset(ceSize);
  2846. }
  2847. break;
  2848. case BfIRIntrinsic_AtomicFence:
  2849. // Nothing to do
  2850. break;
  2851. case BfIRIntrinsic_AtomicAdd:
  2852. EmitBinaryOp(CeOp_Add_I8, CeOp_Add_F32, GetOperand(castedInst->mArgs[0].mValue), GetOperand(castedInst->mArgs[1].mValue), result);
  2853. break;
  2854. case BfIRIntrinsic_AtomicOr:
  2855. EmitBinaryOp(CeOp_Or_I8, CeOp_InvalidOp, GetOperand(castedInst->mArgs[0].mValue), GetOperand(castedInst->mArgs[1].mValue), result);
  2856. break;
  2857. case BfIRIntrinsic_AtomicSub:
  2858. EmitBinaryOp(CeOp_Sub_I8, CeOp_Sub_F32, GetOperand(castedInst->mArgs[0].mValue), GetOperand(castedInst->mArgs[1].mValue), result);
  2859. break;
  2860. case BfIRIntrinsic_AtomicXor:
  2861. EmitBinaryOp(CeOp_Xor_I8, CeOp_InvalidOp, GetOperand(castedInst->mArgs[0].mValue), GetOperand(castedInst->mArgs[1].mValue), result);
  2862. break;
  2863. case BfIRIntrinsic_DebugTrap:
  2864. Emit(CeOp_DbgBreak);
  2865. break;
  2866. case BfIRIntrinsic_AtomicCmpXChg:
  2867. {
  2868. auto mcPtr = GetOperand(castedInst->mArgs[0].mValue, true);
  2869. auto mcComparand = GetOperand(castedInst->mArgs[1].mValue);
  2870. auto mcValue = GetOperand(castedInst->mArgs[2].mValue);
  2871. CeOperand mcPrev = EmitLoad(mcPtr);
  2872. CeOperand cmpResult;
  2873. EmitBinaryOp(CeOp_Cmp_EQ_I8, CeOp_InvalidOp, mcPrev, mcComparand, cmpResult);
  2874. Emit(CeOp_JmpIfNot);
  2875. Emit((int32)14);
  2876. EmitFrameOffset(cmpResult);
  2877. if (mcPtr.mKind == CeOperandKind_AllocaAddr)
  2878. {
  2879. EmitSizedOp(CeOp_Move_8, mcValue, NULL, true);
  2880. Emit((int32)mcPtr.mFrameOfs);
  2881. }
  2882. else
  2883. {
  2884. EmitSizedOp(CeOp_Store_8, mcValue, NULL, true);
  2885. EmitFrameOffset(mcPtr);
  2886. }
  2887. result = mcPrev;
  2888. }
  2889. break;
  2890. default:
  2891. Emit(CeOp_Error);
  2892. Emit((int32)CeErrorKind_Intrinsic);
  2893. break;
  2894. }
  2895. }
  2896. else if (auto beFunction = BeValueDynCast<BeFunction>(castedInst->mFunc))
  2897. {
  2898. beFuncType = beFunction->GetFuncType();
  2899. CeFunctionInfo* ceFunctionInfo = NULL;
  2900. mCeMachine->mNamedFunctionMap.TryGetValue(beFunction->mName, &ceFunctionInfo);
  2901. if (ceFunctionInfo != NULL)
  2902. {
  2903. CeOp ceOp = CeOp_InvalidOp;
  2904. if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_NotSet)
  2905. mCeMachine->CheckFunctionKind(ceFunctionInfo->mCeFunction);
  2906. if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Abs)
  2907. ceOp = CeOp_Abs_F32;
  2908. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Acos)
  2909. ceOp = CeOp_Acos_F32;
  2910. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Asin)
  2911. ceOp = CeOp_Asin_F32;
  2912. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Atan)
  2913. ceOp = CeOp_Atan_F32;
  2914. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Atan2)
  2915. ceOp = CeOp_Atan2_F32;
  2916. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Ceiling)
  2917. ceOp = CeOp_Ceiling_F32;
  2918. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Cos)
  2919. ceOp = CeOp_Cos_F32;
  2920. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Cosh)
  2921. ceOp = CeOp_Cosh_F32;
  2922. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Exp)
  2923. ceOp = CeOp_Exp_F32;
  2924. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Floor)
  2925. ceOp = CeOp_Floor_F32;
  2926. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Log)
  2927. ceOp = CeOp_Log_F32;
  2928. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Log10)
  2929. ceOp = CeOp_Log10_F32;
  2930. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Pow)
  2931. ceOp = CeOp_Pow_F32;
  2932. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Round)
  2933. ceOp = CeOp_Round_F32;
  2934. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Sin)
  2935. ceOp = CeOp_Sin_F32;
  2936. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Sinh)
  2937. ceOp = CeOp_Sinh_F32;
  2938. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Sqrt)
  2939. ceOp = CeOp_Sqrt_F32;
  2940. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Tan)
  2941. ceOp = CeOp_Tan_F32;
  2942. else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Tanh)
  2943. ceOp = CeOp_Tanh_F32;
  2944. if (ceOp != CeOp_InvalidOp)
  2945. {
  2946. if (beFuncType->mReturnType->mSize == 8)
  2947. ceOp = (CeOp)(ceOp + 1);
  2948. result = FrameAlloc(beFuncType->mReturnType);
  2949. if (beFuncType->mParams.size() == 1)
  2950. {
  2951. auto arg0 = GetOperand(castedInst->mArgs[0].mValue);
  2952. Emit(ceOp);
  2953. EmitFrameOffset(result);
  2954. EmitFrameOffset(arg0);
  2955. }
  2956. else
  2957. {
  2958. auto arg0 = GetOperand(castedInst->mArgs[0].mValue);
  2959. auto arg1 = GetOperand(castedInst->mArgs[1].mValue);
  2960. Emit(ceOp);
  2961. EmitFrameOffset(result);
  2962. EmitFrameOffset(arg0);
  2963. EmitFrameOffset(arg1);
  2964. }
  2965. break;
  2966. }
  2967. }
  2968. if (beFunction->mName == "malloc")
  2969. {
  2970. result = FrameAlloc(beFuncType->mReturnType);
  2971. auto ceSize = GetOperand(castedInst->mArgs[0].mValue);
  2972. Emit(CeOp_Malloc);
  2973. EmitFrameOffset(result);
  2974. EmitFrameOffset(ceSize);
  2975. break;
  2976. }
  2977. if (beFunction->mName == "free")
  2978. {
  2979. auto cePtr = GetOperand(castedInst->mArgs[0].mValue);
  2980. Emit(CeOp_Free);
  2981. EmitFrameOffset(cePtr);
  2982. break;
  2983. }
  2984. ceFunc = GetOperand(beFunction, false, true);
  2985. }
  2986. else if (auto beGetVirtualFunc = BeValueDynCast<BeComptimeGetVirtualFunc>(castedInst->mFunc))
  2987. {
  2988. virtTarget = GetOperand(beGetVirtualFunc->mValue);
  2989. virtualTableIdx = beGetVirtualFunc->mVirtualTableIdx;
  2990. auto resultType = beGetVirtualFunc->GetType();
  2991. BF_ASSERT(resultType->IsPointer());
  2992. beFuncType = (BeFunctionType*)((BePointerType*)resultType)->mElementType;
  2993. }
  2994. else if (auto beGetInterfaceFunc = BeValueDynCast<BeComptimeGetInterfaceFunc>(castedInst->mFunc))
  2995. {
  2996. virtTarget = GetOperand(beGetInterfaceFunc->mValue);
  2997. ifaceTypeId = beGetInterfaceFunc->mIFaceTypeId;
  2998. virtualTableIdx = beGetInterfaceFunc->mMethodIdx;
  2999. auto resultType = beGetInterfaceFunc->GetType();
  3000. BF_ASSERT(resultType->IsPointer());
  3001. beFuncType = (BeFunctionType*)((BePointerType*)resultType)->mElementType;
  3002. }
  3003. else
  3004. {
  3005. ceFunc = GetOperand(castedInst->mFunc, false, true);
  3006. auto funcType = castedInst->mFunc->GetType();
  3007. if (funcType->IsPointer())
  3008. {
  3009. auto ptrType = (BePointerType*)funcType;
  3010. if (ptrType->mElementType->mTypeCode == BeTypeCode_Function)
  3011. {
  3012. beFuncType = (BeFunctionType*)ptrType->mElementType;
  3013. }
  3014. }
  3015. }
  3016. if ((ceFunc) || (virtualTableIdx != -1))
  3017. {
  3018. CeOperand thisOperand;
  3019. int stackAdjust = 0;
  3020. for (int argIdx = (int)castedInst->mArgs.size() - 1; argIdx >= 0; argIdx--)
  3021. {
  3022. auto& arg = castedInst->mArgs[argIdx];
  3023. auto ceArg = GetOperand(arg.mValue);
  3024. if (!ceArg)
  3025. continue;
  3026. if (argIdx == 0)
  3027. thisOperand = ceArg;
  3028. EmitSizedOp(CeOp_Push_8, ceArg, NULL, true);
  3029. stackAdjust += ceArg.mType->mSize;
  3030. }
  3031. if (beFuncType->mReturnType->mSize > 0)
  3032. {
  3033. Emit(CeOp_AdjustSPConst);
  3034. Emit((int32)-beFuncType->mReturnType->mSize);
  3035. }
  3036. if (!ceFunc)
  3037. ceFunc = FrameAlloc(beModule->mContext->GetPrimitiveType((sizeof(BfMethodInstance*) == 8) ? BeTypeCode_Int64 : BeTypeCode_Int32));
  3038. if (ifaceTypeId != -1)
  3039. {
  3040. Emit(CeOp_GetMethod_IFace);
  3041. EmitFrameOffset(ceFunc);
  3042. EmitFrameOffset(thisOperand);
  3043. Emit((int32)ifaceTypeId);
  3044. Emit((int32)virtualTableIdx);
  3045. }
  3046. else if (virtualTableIdx != -1)
  3047. {
  3048. Emit(CeOp_GetMethod_Virt);
  3049. EmitFrameOffset(ceFunc);
  3050. EmitFrameOffset(thisOperand);
  3051. Emit((int32)virtualTableIdx);
  3052. }
  3053. if (ceFunc.mKind == CeOperandKind_CallTableIdx)
  3054. {
  3055. CeOperand result = FrameAlloc(mCeMachine->GetBeContext()->GetPrimitiveType((sizeof(BfMethodInstance*) == 8) ? BeTypeCode_Int64 : BeTypeCode_Int32));
  3056. Emit(CeOp_GetMethod);
  3057. EmitFrameOffset(result);
  3058. Emit((int32)ceFunc.mCallTableIdx);
  3059. ceFunc = result;
  3060. }
  3061. Emit(CeOp_Call);
  3062. EmitFrameOffset(ceFunc);
  3063. if (beFuncType->mReturnType->mSize > 0)
  3064. {
  3065. result = FrameAlloc(beFuncType->mReturnType);
  3066. EmitSizedOp(CeOp_Pop_8, result, NULL, true);
  3067. }
  3068. if (stackAdjust > 0)
  3069. {
  3070. Emit(CeOp_AdjustSPConst);
  3071. Emit(stackAdjust);
  3072. }
  3073. }
  3074. }
  3075. break;
  3076. case BeMemSetInst::TypeId:
  3077. {
  3078. auto castedInst = (BeMemSetInst*)inst;
  3079. auto ceAddr = GetOperand(castedInst->mAddr);
  3080. if (auto constVal = BeValueDynCast<BeConstant>(castedInst->mVal))
  3081. {
  3082. if (auto constSize = BeValueDynCast<BeConstant>(castedInst->mSize))
  3083. {
  3084. if (constVal->mUInt8 == 0)
  3085. {
  3086. Emit(CeOp_MemSet_Const);
  3087. EmitFrameOffset(ceAddr);
  3088. Emit((uint8)0);
  3089. Emit((int32)constSize->mUInt32);
  3090. break;
  3091. }
  3092. }
  3093. }
  3094. auto ceVal = GetOperand(castedInst->mVal);
  3095. auto ceSize = GetOperand(castedInst->mSize);
  3096. Emit(CeOp_MemSet);
  3097. EmitFrameOffset(ceAddr);
  3098. EmitFrameOffset(ceVal);
  3099. EmitFrameOffset(ceSize);
  3100. }
  3101. break;
  3102. case BeFenceInst::TypeId:
  3103. break;
  3104. case BeStackSaveInst::TypeId:
  3105. {
  3106. result = FrameAlloc(mIntPtrType);
  3107. Emit(CeOp_GetSP);
  3108. EmitFrameOffset(result);
  3109. }
  3110. break;
  3111. case BeStackRestoreInst::TypeId:
  3112. {
  3113. auto castedInst = (BeStackRestoreInst*)inst;
  3114. auto mcStackVal = GetOperand(castedInst->mStackVal);
  3115. Emit(CeOp_SetSP);
  3116. EmitFrameOffset(mcStackVal);
  3117. }
  3118. break;
  3119. case BeComptimeError::TypeId:
  3120. {
  3121. auto castedInst = (BeComptimeError*)inst;
  3122. Emit(CeOp_Error);
  3123. Emit(castedInst->mError);
  3124. }
  3125. break;
  3126. case BeComptimeGetType::TypeId:
  3127. {
  3128. auto castedInst = (BeComptimeGetType*)inst;
  3129. result.mKind = CeOperandKind_Immediate;
  3130. result.mImmediate = castedInst->mTypeId;
  3131. result.mType = beModule->mContext->GetPrimitiveType(BeTypeCode_Int32);
  3132. }
  3133. break;
  3134. case BeComptimeGetReflectType::TypeId:
  3135. {
  3136. auto castedInst = (BeComptimeGetReflectType*)inst;
  3137. auto ptrType = beModule->mContext->GetVoidPtrType();
  3138. result = FrameAlloc(ptrType);
  3139. Emit(CeOp_GetReflectType);
  3140. EmitFrameOffset(result);
  3141. Emit((int32)castedInst->mTypeId);
  3142. }
  3143. break;
  3144. case BeComptimeDynamicCastCheck::TypeId:
  3145. {
  3146. auto castedInst = (BeComptimeDynamicCastCheck*)inst;
  3147. auto mcValue = GetOperand(castedInst->mValue);
  3148. auto ptrType = beModule->mContext->GetVoidPtrType();
  3149. result = FrameAlloc(ptrType);
  3150. Emit(CeOp_DynamicCastCheck);
  3151. EmitFrameOffset(result);
  3152. EmitFrameOffset(mcValue);
  3153. Emit((int32)castedInst->mTypeId);
  3154. }
  3155. break;
  3156. case BeDbgDeclareInst::TypeId:
  3157. {
  3158. auto castedInst = (BeDbgDeclareInst*)inst;
  3159. auto mcValue = GetOperand(castedInst->mValue, true);
  3160. if (mCeFunction->mDbgInfo != NULL)
  3161. {
  3162. bool isConst = false;
  3163. auto beType = castedInst->mDbgVar->mType;
  3164. if (auto dbgConstType = BeValueDynCast<BeDbgConstType>(beType))
  3165. {
  3166. isConst = true;
  3167. beType = dbgConstType->mElement;
  3168. }
  3169. if (auto dbgTypeId = BeValueDynCast<BeDbgTypeId>(beType))
  3170. {
  3171. mDbgVariableMap[castedInst->mValue] = mCeFunction->mDbgInfo->mVariables.mSize;
  3172. CeDbgVariable dbgVariable;
  3173. dbgVariable.mName = castedInst->mDbgVar->mName;
  3174. dbgVariable.mValue = mcValue;
  3175. dbgVariable.mType = mCeMachine->mCeModule->mContext->mTypes[dbgTypeId->mTypeId];
  3176. dbgVariable.mScope = scopeIdx;
  3177. dbgVariable.mIsConst = isConst;
  3178. dbgVariable.mStartCodePos = mCeFunction->mCode.mSize;
  3179. dbgVariable.mEndCodePos = -1;
  3180. mCeFunction->mDbgInfo->mVariables.Add(dbgVariable);
  3181. }
  3182. }
  3183. }
  3184. break;
  3185. case BeLifetimeEndInst::TypeId:
  3186. {
  3187. auto castedInst = (BeLifetimeEndInst*)inst;
  3188. int varIdx = 0;
  3189. if (mDbgVariableMap.TryGetValue(castedInst->mPtr, &varIdx))
  3190. {
  3191. auto dbgVar = &mCeFunction->mDbgInfo->mVariables[varIdx];
  3192. dbgVar->mEndCodePos = mCeFunction->mCode.mSize;
  3193. }
  3194. }
  3195. break;
  3196. case BeEnsureInstructionAtInst::TypeId:
  3197. {
  3198. if (mCeMachine->mDebugger != NULL)
  3199. {
  3200. Emit(CeOp_Nop);
  3201. }
  3202. }
  3203. break;
  3204. default:
  3205. Fail("Unhandled instruction");
  3206. return;
  3207. }
  3208. if (result.mKind != CeOperandKind_None)
  3209. mValueToOperand[inst] = result;
  3210. if ((startCodePos != GetCodePos()) && (prevEmitDbgPos != mCurDbgLoc))
  3211. {
  3212. CeEmitEntry emitEntry;
  3213. emitEntry.mCodePos = startCodePos;
  3214. emitEntry.mScope = scopeIdx;
  3215. if ((mCurDbgLoc != NULL) && (mCurDbgLoc->mLine != -1))
  3216. {
  3217. emitEntry.mLine = mCurDbgLoc->mLine;
  3218. emitEntry.mColumn = mCurDbgLoc->mColumn;
  3219. }
  3220. else if (!mCeFunction->mEmitTable.IsEmpty())
  3221. {
  3222. auto& prevEmitEntry = mCeFunction->mEmitTable.back();
  3223. emitEntry.mScope = prevEmitEntry.mScope;
  3224. emitEntry.mLine = prevEmitEntry.mLine;
  3225. emitEntry.mColumn = -1;
  3226. }
  3227. else
  3228. {
  3229. emitEntry.mLine = -1;
  3230. emitEntry.mColumn = -1;
  3231. }
  3232. mCeFunction->mEmitTable.Add(emitEntry);
  3233. prevEmitDbgPos = mCurDbgLoc;
  3234. }
  3235. }
  3236. }
  3237. if (mCeFunction->mDbgInfo != NULL)
  3238. {
  3239. for (auto& dbgVar : mCeFunction->mDbgInfo->mVariables)
  3240. if (dbgVar.mEndCodePos == -1)
  3241. dbgVar.mEndCodePos = mCeFunction->mCode.mSize;
  3242. }
  3243. for (auto& jumpEntry : mJumpTable)
  3244. {
  3245. auto& ceBlock = mBlocks[jumpEntry.mBlockIdx];
  3246. *((int32*)(&mCeFunction->mCode[0] + jumpEntry.mEmitPos)) = ceBlock.mEmitOfs - jumpEntry.mEmitPos - 4;
  3247. }
  3248. if (irCodeGen->mFailed)
  3249. {
  3250. mCeMachine->Fail(StrFormat("IRCodeGen Failed: %s", irCodeGen->mErrorMsg.c_str()));
  3251. irCodeGen->mFailed = false;
  3252. }
  3253. if (mCeMachine->HasFailed())
  3254. {
  3255. Fail("ConstEval machine failed");
  3256. return;
  3257. }
  3258. if (mCeFunction->mCode.size() == 0)
  3259. {
  3260. Fail("No method definition available");
  3261. return;
  3262. }
  3263. if (mCeFunction->mGenError.IsEmpty())
  3264. mCeFunction->mFailed = false;
  3265. mCeFunction->mFrameSize = mFrameSize;
  3266. }
  3267. //////////////////////////////////////////////////////////////////////////
  3268. CeContext::CeContext()
  3269. {
  3270. mPrevContext = NULL;
  3271. mCurEvalFlags = CeEvalFlags_None;
  3272. mCeMachine = NULL;
  3273. mReflectTypeIdOffset = -1;
  3274. mExecuteId = -1;
  3275. mStackSize = -1;
  3276. mRecursiveDepth = -1;
  3277. mCurCallSource = NULL;
  3278. mHeap = new ContiguousHeap();
  3279. mCurFrame = NULL;
  3280. mCurModule = NULL;
  3281. mCurMethodInstance = NULL;
  3282. mCallerMethodInstance = NULL;
  3283. mCallerTypeInstance = NULL;
  3284. mCallerActiveTypeDef = NULL;
  3285. mCurExpectingType = NULL;
  3286. mCurEmitContext = NULL;
  3287. mTypeDeclState = NULL;
  3288. }
  3289. CeContext::~CeContext()
  3290. {
  3291. delete mHeap;
  3292. delete mTypeDeclState;
  3293. BF_ASSERT(mInternalDataMap.IsEmpty());
  3294. }
  3295. BfError* CeContext::Fail(const StringImpl& error)
  3296. {
  3297. if (mCurModule == NULL)
  3298. return NULL;
  3299. if (mCurEmitContext != NULL)
  3300. mCurEmitContext->mFailed = true;
  3301. SetAndRestoreValue<BfTypeInstance*> prevTypeInst(mCurModule->mCurTypeInstance, mCallerTypeInstance);
  3302. auto bfError = mCurModule->Fail(StrFormat("Unable to comptime %s", mCurModule->MethodToString(mCurMethodInstance).c_str()), mCurCallSource->mRefNode, (mCurEvalFlags & CeEvalFlags_PersistantError) != 0);
  3303. if (bfError == NULL)
  3304. return NULL;
  3305. bool forceQueue = mCeMachine->mCompiler->GetAutoComplete() != NULL;
  3306. if ((mCeMachine->mDebugger != NULL) && (mCeMachine->mDebugger->mCurDbgState != NULL))
  3307. forceQueue = true;
  3308. mCeMachine->mCompiler->mPassInstance->MoreInfo(error, forceQueue);
  3309. return bfError;
  3310. }
  3311. BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str)
  3312. {
  3313. if (mCurEmitContext != NULL)
  3314. mCurEmitContext->mFailed = true;
  3315. SetAndRestoreValue<BfTypeInstance*> prevTypeInst(mCurModule->mCurTypeInstance, mCallerTypeInstance);
  3316. auto bfError = mCurModule->Fail(StrFormat("Unable to comptime %s", mCurModule->MethodToString(mCurMethodInstance).c_str()), mCurCallSource->mRefNode,
  3317. (mCurEvalFlags & CeEvalFlags_PersistantError) != 0,
  3318. ((mCurEvalFlags & CeEvalFlags_DeferIfNotOnlyError) != 0) && !mCurModule->mHadBuildError);
  3319. if (bfError == NULL)
  3320. return NULL;
  3321. auto passInstance = mCeMachine->mCompiler->mPassInstance;
  3322. for (int stackIdx = mCallStack.size(); stackIdx >= 0; stackIdx--)
  3323. {
  3324. bool isHeadEntry = stackIdx == mCallStack.size();
  3325. auto* ceFrame = (isHeadEntry) ? &curFrame : &mCallStack[stackIdx];
  3326. auto ceFunction = ceFrame->mFunction;
  3327. CeEmitEntry* emitEntry = ceFunction->FindEmitEntry(ceFrame->mInstPtr - ceFunction->mCode.mVals - 1);
  3328. StringT<256> err;
  3329. if (isHeadEntry)
  3330. {
  3331. err = str;
  3332. err += " ";
  3333. }
  3334. auto contextMethodInstance = mCallerMethodInstance;
  3335. auto contextTypeInstance = mCallerTypeInstance;
  3336. if (stackIdx > 1)
  3337. {
  3338. auto func = mCallStack[stackIdx - 1].mFunction;
  3339. contextMethodInstance = func->mCeFunctionInfo->mMethodInstance;
  3340. contextTypeInstance = contextMethodInstance->GetOwner();
  3341. }
  3342. auto _AddCeMethodInstance = [&](BfMethodInstance* methodInstance)
  3343. {
  3344. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCeMachine->mCeModule->mCurTypeInstance, contextTypeInstance);
  3345. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, contextMethodInstance);
  3346. err += mCeMachine->mCeModule->MethodToString(methodInstance, BfMethodNameFlag_OmitParams);
  3347. };
  3348. auto _AddError = [&](const StringImpl& filePath, int line, int column)
  3349. {
  3350. err += StrFormat(" at line% d:%d in %s", line + 1, column + 1, filePath.c_str());
  3351. auto moreInfo = passInstance->MoreInfo(err, mCeMachine->mCeModule->mCompiler->GetAutoComplete() != NULL);
  3352. if ((moreInfo != NULL))
  3353. {
  3354. BfErrorLocation* location = new BfErrorLocation();
  3355. location->mFile = filePath;
  3356. location->mLine = line;
  3357. location->mColumn = column;
  3358. moreInfo->mLocation = location;
  3359. }
  3360. };
  3361. if (emitEntry != NULL)
  3362. {
  3363. int scopeIdx = emitEntry->mScope;
  3364. int prevInlineIdx = -1;
  3365. while (scopeIdx != -1)
  3366. {
  3367. err += StrFormat("in comptime ");
  3368. int line = emitEntry->mLine;
  3369. int column = emitEntry->mColumn;
  3370. String fileName;
  3371. if (prevInlineIdx != -1)
  3372. {
  3373. auto dbgInlineInfo = &ceFunction->mDbgInlineTable[prevInlineIdx];
  3374. line = dbgInlineInfo->mLine;
  3375. column = dbgInlineInfo->mColumn;
  3376. }
  3377. CeDbgScope* ceScope = &ceFunction->mDbgScopes[scopeIdx];
  3378. if (ceScope->mMethodVal == -1)
  3379. {
  3380. if (ceFunction->mMethodInstance != NULL)
  3381. _AddCeMethodInstance(ceFunction->mMethodInstance);
  3382. else
  3383. _AddCeMethodInstance(ceFunction->mCeInnerFunctionInfo->mOwner->mMethodInstance);
  3384. }
  3385. else
  3386. {
  3387. if ((ceScope->mMethodVal & CeDbgScope::MethodValFlag_MethodRef) != 0)
  3388. {
  3389. auto dbgMethodRef = &ceFunction->mDbgMethodRefTable[ceScope->mMethodVal & CeDbgScope::MethodValFlag_IdxMask];
  3390. err += dbgMethodRef->ToString();
  3391. }
  3392. else
  3393. {
  3394. auto callTableEntry = &ceFunction->mCallTable[ceScope->mMethodVal];
  3395. _AddCeMethodInstance(callTableEntry->mFunctionInfo->mMethodInstance);
  3396. }
  3397. }
  3398. _AddError(ceFunction->mDbgScopes[emitEntry->mScope].mFilePath, line, column);
  3399. if (ceScope->mInlinedAt == -1)
  3400. break;
  3401. auto inlineInfo = &ceFrame->mFunction->mDbgInlineTable[ceScope->mInlinedAt];
  3402. scopeIdx = inlineInfo->mScope;
  3403. prevInlineIdx = ceScope->mInlinedAt;
  3404. err.Clear();
  3405. }
  3406. }
  3407. else
  3408. {
  3409. err += StrFormat("in comptime ");
  3410. if (ceFunction->mMethodInstance != NULL)
  3411. _AddCeMethodInstance(ceFunction->mMethodInstance);
  3412. else
  3413. _AddCeMethodInstance(ceFunction->mCeInnerFunctionInfo->mOwner->mMethodInstance);
  3414. if ((emitEntry != NULL) && (emitEntry->mScope != -1))
  3415. {
  3416. _AddError(ceFunction->mDbgScopes[emitEntry->mScope].mFilePath, emitEntry->mLine, emitEntry->mColumn);
  3417. }
  3418. else
  3419. {
  3420. auto moreInfo = passInstance->MoreInfo(err, mCeMachine->mCeModule->mCompiler->GetAutoComplete() != NULL);
  3421. }
  3422. }
  3423. }
  3424. return bfError;
  3425. }
  3426. //////////////////////////////////////////////////////////////////////////
  3427. void CeContext::CalcWorkingDir()
  3428. {
  3429. if (mWorkingDir.IsEmpty())
  3430. {
  3431. BfProject* activeProject = NULL;
  3432. auto activeTypeDef = mCallerActiveTypeDef;
  3433. if (activeTypeDef != NULL)
  3434. activeProject = activeTypeDef->mProject;
  3435. if (activeProject != NULL)
  3436. mWorkingDir = activeProject->mDirectory;
  3437. }
  3438. }
  3439. void CeContext::FixRelativePath(StringImpl& path)
  3440. {
  3441. CalcWorkingDir();
  3442. if (!mWorkingDir.IsEmpty())
  3443. path = GetAbsPath(path, mWorkingDir);
  3444. }
  3445. bool CeContext::AddRebuild(const CeRebuildKey& key, const CeRebuildValue& value)
  3446. {
  3447. if (mCurModule == NULL)
  3448. return false;
  3449. if (mCallerTypeInstance == NULL)
  3450. return false;
  3451. if ((mCurEvalFlags & CeEvalFlags_NoRebuild) != 0)
  3452. return false;
  3453. if (mCallerTypeInstance->mCeTypeInfo == NULL)
  3454. mCallerTypeInstance->mCeTypeInfo = new BfCeTypeInfo();
  3455. mCallerTypeInstance->mCeTypeInfo->mRebuildMap[key] = value;
  3456. mCurModule->mCompiler->mHasComptimeRebuilds = true;
  3457. return true;
  3458. }
  3459. void CeContext::AddFileRebuild(const StringImpl& path)
  3460. {
  3461. auto timeStamp = BfpFile_GetTime_LastWrite(path.c_str());
  3462. if (timeStamp != 0)
  3463. {
  3464. String fixedPath = FixPathAndCase(path);
  3465. CeRebuildKey rebuildKey;
  3466. rebuildKey.mKind = CeRebuildKey::Kind_File;
  3467. rebuildKey.mString = fixedPath;
  3468. CeRebuildValue rebuildValue;
  3469. rebuildValue.mInt = timeStamp;
  3470. if (AddRebuild(rebuildKey, rebuildValue))
  3471. mCurModule->mCompiler->mRebuildFileSet.Add(fixedPath);
  3472. }
  3473. }
  3474. void CeContext::AddTypeSigRebuild(BfType* type)
  3475. {
  3476. mCurModule->AddDependency(type, mCurModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeSignature);
  3477. }
  3478. uint8* CeContext::CeMalloc(int size)
  3479. {
  3480. #ifdef CE_ENABLE_HEAP
  3481. auto heapRef = mHeap->Alloc(size);
  3482. auto ceAddr = mStackSize + heapRef;
  3483. int sizeDelta = (ceAddr + size) - mMemory.mSize;
  3484. if (sizeDelta > 0)
  3485. mMemory.GrowUninitialized(sizeDelta);
  3486. return mMemory.mVals + ceAddr;
  3487. #else
  3488. return mMemory.GrowUninitialized(size);
  3489. #endif
  3490. }
  3491. uint8* CeContext::CeMallocZero(int size)
  3492. {
  3493. uint8* ptr = CeMalloc(size);
  3494. memset(ptr, 0, size);
  3495. return ptr;
  3496. }
  3497. bool CeContext::CeFree(addr_ce addr)
  3498. {
  3499. #ifdef CE_ENABLE_HEAP
  3500. ContiguousHeap::AllocRef heapRef = addr - mStackSize;
  3501. return mHeap->Free(heapRef);
  3502. #else
  3503. return true;
  3504. #endif
  3505. }
  3506. addr_ce CeContext::CeAllocArray(BfArrayType* arrayType, int count, addr_ce& elemsAddr)
  3507. {
  3508. mCeMachine->mCeModule->PopulateType(arrayType);
  3509. BfType* elemType = arrayType->GetUnderlyingType();
  3510. auto countOffset = arrayType->mBaseType->mFieldInstances[0].mDataOffset;
  3511. auto elemOffset = arrayType->mFieldInstances[0].mDataOffset;
  3512. int allocSize = elemOffset + elemType->GetStride() * count;
  3513. uint8* mem = CeMalloc(allocSize);
  3514. memset(mem, 0, allocSize);
  3515. *(int32*)(mem) = arrayType->mTypeId;
  3516. *(int32*)(mem + countOffset) = count;
  3517. elemsAddr = (addr_ce)(mem + elemOffset - mMemory.mVals);
  3518. return (addr_ce)(mem - mMemory.mVals);
  3519. }
  3520. addr_ce CeContext::GetConstantData(BeConstant* constant)
  3521. {
  3522. auto writeConstant = constant;
  3523. if (auto gvConstant = BeValueDynCast<BeGlobalVariable>(writeConstant))
  3524. {
  3525. if (gvConstant->mInitializer != NULL)
  3526. writeConstant = gvConstant->mInitializer;
  3527. }
  3528. CeConstStructData structData;
  3529. auto result = mCeMachine->WriteConstant(structData, writeConstant, this, NULL);
  3530. BF_ASSERT(result == CeErrorKind_None);
  3531. uint8* ptr = CeMallocZero(structData.mData.mSize);
  3532. memcpy(ptr, structData.mData.mVals, structData.mData.mSize);
  3533. return (addr_ce)(ptr - mMemory.mVals);
  3534. }
  3535. addr_ce CeContext::GetReflectTypeDecl(int typeId)
  3536. {
  3537. if (mTypeDeclState == NULL)
  3538. mTypeDeclState = new CeTypeDeclState();
  3539. if (mTypeDeclState->mReflectDeclMap.IsEmpty())
  3540. {
  3541. CeRebuildKey rebuildKey;
  3542. rebuildKey.mKind = CeRebuildKey::Kind_TypeDeclListHash;
  3543. CeRebuildValue rebuildValue;
  3544. rebuildValue.mInt = mCeMachine->mCompiler->mSystem->GetTypeDeclListHash();
  3545. AddRebuild(rebuildKey, rebuildValue);
  3546. }
  3547. addr_ce* addrPtr = NULL;
  3548. if (!mTypeDeclState->mReflectDeclMap.TryAdd(typeId, NULL, &addrPtr))
  3549. return *addrPtr;
  3550. auto ceModule = mCeMachine->mCeModule;
  3551. SetAndRestoreValue<bool> ignoreWrites(ceModule->mBfIRBuilder->mIgnoreWrites, false);
  3552. if (ceModule->mContext->mBfTypeType == NULL)
  3553. ceModule->mContext->ReflectInit();
  3554. if ((uintptr)typeId >= (uintptr)mCeMachine->mCeModule->mContext->mTypes.mSize)
  3555. return 0;
  3556. auto bfType = mCeMachine->mCeModule->mContext->mTypes[typeId];
  3557. if (bfType == NULL)
  3558. return 0;
  3559. if (bfType->mDefineState < BfTypeDefineState_HasCustomAttributes)
  3560. ceModule->PopulateType(bfType, BfPopulateType_CustomAttributes);
  3561. BfProject* curProject = NULL;
  3562. auto activeTypeDef = mCurModule->GetActiveTypeDef();
  3563. if (activeTypeDef != NULL)
  3564. curProject = activeTypeDef->mProject;
  3565. if (curProject == NULL)
  3566. return 0;
  3567. BfCreateTypeDataContext createTypeDataCtx;
  3568. auto irData = ceModule->CreateTypeDeclData(bfType, curProject);
  3569. BeValue* beValue = NULL;
  3570. if (auto constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstant(irData))
  3571. {
  3572. if (constant->mConstType == BfConstType_BitCast)
  3573. {
  3574. auto bitcast = (BfConstantBitCast*)constant;
  3575. constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstantById(bitcast->mTarget);
  3576. }
  3577. if (constant->mConstType == BfConstType_GlobalVar)
  3578. {
  3579. auto globalVar = (BfGlobalVar*)constant;
  3580. beValue = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen->GetBeValue(globalVar->mStreamId);
  3581. }
  3582. }
  3583. if (auto constant = BeValueDynCast<BeConstant>(beValue))
  3584. *addrPtr = GetConstantData(constant);
  3585. // We need to 'get' again because we might have resized
  3586. return *addrPtr;
  3587. }
  3588. addr_ce CeContext::GetReflectType(int typeId)
  3589. {
  3590. addr_ce* addrPtr = NULL;
  3591. if (!mReflectMap.TryAdd(typeId, NULL, &addrPtr))
  3592. return *addrPtr;
  3593. auto ceModule = mCeMachine->mCeModule;
  3594. SetAndRestoreValue<bool> ignoreWrites(ceModule->mBfIRBuilder->mIgnoreWrites, false);
  3595. if (ceModule->mContext->mBfTypeType == NULL)
  3596. ceModule->mContext->ReflectInit();
  3597. if ((uintptr)typeId >= (uintptr)mCeMachine->mCeModule->mContext->mTypes.mSize)
  3598. return 0;
  3599. auto bfType = mCeMachine->mCeModule->mContext->mTypes[typeId];
  3600. if (bfType == NULL)
  3601. return 0;
  3602. if (bfType->mDefineState != BfTypeDefineState_CETypeInit)
  3603. ceModule->PopulateType(bfType, BfPopulateType_DataAndMethods);
  3604. BfCreateTypeDataContext createTypeDataCtx;
  3605. auto irData = ceModule->CreateTypeData(bfType, createTypeDataCtx, true, true, true, false);
  3606. BeValue* beValue = NULL;
  3607. if (auto constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstant(irData))
  3608. {
  3609. if (constant->mConstType == BfConstType_BitCast)
  3610. {
  3611. auto bitcast = (BfConstantBitCast*)constant;
  3612. constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstantById(bitcast->mTarget);
  3613. }
  3614. if (constant->mConstType == BfConstType_GlobalVar)
  3615. {
  3616. auto globalVar = (BfGlobalVar*)constant;
  3617. beValue = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen->GetBeValue(globalVar->mStreamId);
  3618. }
  3619. }
  3620. if (auto constant = BeValueDynCast<BeConstant>(beValue))
  3621. *addrPtr = GetConstantData(constant);
  3622. // We need to 'get' again because we might have resized
  3623. return *addrPtr;
  3624. }
  3625. addr_ce CeContext::GetReflectType(const String& typeName, bool useDeclaration)
  3626. {
  3627. if (mCeMachine->mTempParser == NULL)
  3628. {
  3629. mCeMachine->mTempPassInstance = new BfPassInstance(mCeMachine->mCompiler->mSystem);
  3630. mCeMachine->mTempParser = new BfParser(mCeMachine->mCompiler->mSystem);
  3631. mCeMachine->mTempParser->mIsEmitted = true;
  3632. mCeMachine->mTempParser->SetSource(NULL, 4096);
  3633. mCeMachine->mTempReducer = new BfReducer();
  3634. mCeMachine->mTempReducer->mPassInstance = mCeMachine->mTempPassInstance;
  3635. mCeMachine->mTempReducer->mSource = mCeMachine->mTempParser;
  3636. mCeMachine->mTempReducer->mAlloc = mCeMachine->mTempParser->mAlloc;
  3637. mCeMachine->mTempReducer->mSystem = mCeMachine->mCompiler->mSystem;
  3638. }
  3639. int copyLen = BF_MIN(typeName.mLength, 4096);
  3640. memcpy((char*)mCeMachine->mTempParser->mSrc, typeName.c_str(), copyLen);
  3641. ((char*)mCeMachine->mTempParser->mSrc)[copyLen] = 0;
  3642. mCeMachine->mTempParser->mSrcLength = typeName.mLength;
  3643. mCeMachine->mTempParser->mSrcIdx = 0;
  3644. mCeMachine->mTempParser->Parse(mCeMachine->mTempPassInstance);
  3645. BfType* type = NULL;
  3646. if (mCeMachine->mTempParser->mRootNode->mChildArr.mSize > 0)
  3647. {
  3648. mCeMachine->mTempReducer->mVisitorPos = BfReducer::BfVisitorPos(mCeMachine->mTempParser->mRootNode);
  3649. mCeMachine->mTempReducer->mVisitorPos.mReadPos = 0;
  3650. auto typeRef = mCeMachine->mTempReducer->CreateTypeRef(mCeMachine->mTempParser->mRootNode->mChildArr[0]);
  3651. if ((mCeMachine->mTempPassInstance->mErrors.mSize == 0) && (mCeMachine->mTempReducer->mVisitorPos.mReadPos == mCeMachine->mTempParser->mRootNode->mChildArr.mSize - 1))
  3652. {
  3653. SetAndRestoreValue<bool> prevIgnoreErrors(mCeMachine->mCeModule->mIgnoreErrors, true);
  3654. type = mCeMachine->mCeModule->ResolveTypeRefAllowUnboundGenerics(typeRef, BfPopulateType_Identity);
  3655. }
  3656. }
  3657. mCeMachine->mTempPassInstance->ClearErrors();
  3658. if (type == NULL)
  3659. return 0;
  3660. return useDeclaration ? GetReflectTypeDecl(type->mTypeId) : GetReflectType(type->mTypeId);
  3661. }
  3662. int CeContext::GetTypeIdFromType(addr_ce typeAddr)
  3663. {
  3664. if (!CheckMemory(typeAddr, 8))
  3665. return 0;
  3666. if (mReflectTypeIdOffset == -1)
  3667. {
  3668. auto typeTypeInst = mCeMachine->mCeModule->ResolveTypeDef(mCeMachine->mCompiler->mTypeTypeDef)->ToTypeInstance();
  3669. auto typeIdField = typeTypeInst->mTypeDef->GetFieldByName("mTypeId");
  3670. mReflectTypeIdOffset = typeTypeInst->mFieldInstances[typeIdField->mIdx].mDataOffset;
  3671. }
  3672. return *(int32*)(mMemory.mVals + typeAddr + mReflectTypeIdOffset);
  3673. }
  3674. addr_ce CeContext::GetReflectSpecializedType(addr_ce unspecializedTypeAddr, addr_ce typeArgsSpanAddr)
  3675. {
  3676. BfType* unspecializedType = GetBfType(GetTypeIdFromType(unspecializedTypeAddr));
  3677. if (unspecializedType == NULL)
  3678. return 0;
  3679. BfTypeInstance* unspecializedTypeInst = unspecializedType->ToGenericTypeInstance();
  3680. if (unspecializedType == NULL)
  3681. return 0;
  3682. int ptrSize = mCeMachine->mCompiler->mSystem->mPtrSize;
  3683. if (!CheckMemory(typeArgsSpanAddr, ptrSize * 2))
  3684. return 0;
  3685. addr_ce spanPtr = *(addr_ce*)(mMemory.mVals + typeArgsSpanAddr);
  3686. int32 spanSize = *(int32*)(mMemory.mVals + typeArgsSpanAddr + ptrSize);
  3687. if (spanSize < 0)
  3688. return 0;
  3689. if (!CheckMemory(spanPtr, spanSize * ptrSize))
  3690. return 0;
  3691. Array<BfType*> typeGenericArgs;
  3692. for (int argIdx = 0; argIdx < spanSize; argIdx++)
  3693. {
  3694. addr_ce argPtr = *(addr_ce*)(mMemory.mVals + spanPtr + argIdx * ptrSize);
  3695. BfType* typeGenericArg = GetBfType(GetTypeIdFromType(argPtr));
  3696. if (typeGenericArg == NULL)
  3697. return 0;
  3698. typeGenericArgs.Add(typeGenericArg);
  3699. }
  3700. SetAndRestoreValue<bool> prevIgnoreErrors(mCeMachine->mCeModule->mIgnoreErrors, true);
  3701. auto specializedType = mCeMachine->mCeModule->ResolveTypeDef(unspecializedTypeInst->mTypeDef, typeGenericArgs, BfPopulateType_Identity);
  3702. if (specializedType == NULL)
  3703. return 0;
  3704. return GetReflectType(specializedType->mTypeId);
  3705. }
  3706. addr_ce CeContext::GetString(int stringId)
  3707. {
  3708. addr_ce* ceAddrPtr = NULL;
  3709. if (!mStringMap.TryAdd(stringId, NULL, &ceAddrPtr))
  3710. return *ceAddrPtr;
  3711. BfTypeInstance* stringTypeInst = (BfTypeInstance*)mCeMachine->mCeModule->ResolveTypeDef(mCeMachine->mCompiler->mStringTypeDef, BfPopulateType_Data);
  3712. String str;
  3713. BfStringPoolEntry* entry = NULL;
  3714. if (mCeMachine->mCeModule->mContext->mStringObjectIdMap.TryGetValue(stringId, &entry))
  3715. {
  3716. entry->mLastUsedRevision = mCeMachine->mCompiler->mRevision;
  3717. str = entry->mString;
  3718. }
  3719. int allocSize = stringTypeInst->mInstSize + (int)str.length() + 1;
  3720. int charsOffset = stringTypeInst->mInstSize;
  3721. uint8* mem = CeMallocZero(allocSize);
  3722. auto lenByteCount = stringTypeInst->mFieldInstances[0].mResolvedType->mSize;
  3723. auto lenOffset = stringTypeInst->mFieldInstances[0].mDataOffset;
  3724. auto allocSizeOffset = stringTypeInst->mFieldInstances[1].mDataOffset;
  3725. auto ptrOffset = stringTypeInst->mFieldInstances[2].mDataOffset;
  3726. // Write TypeId into there
  3727. *(int32*)(mem) = stringTypeInst->mTypeId;
  3728. *(int32*)(mem + lenOffset) = (int)str.length();
  3729. if (lenByteCount == 4)
  3730. *(int32*)(mem + allocSizeOffset) = 0x40000000 + (int)str.length() + 1;
  3731. else
  3732. *(int64*)(mem + allocSizeOffset) = 0x4000000000000000LL + (int)str.length() + 1;
  3733. *(int32*)(mem + ptrOffset) = (mem + charsOffset) - mMemory.mVals;
  3734. memcpy(mem + charsOffset, str.c_str(), str.length());
  3735. *ceAddrPtr = mem - mMemory.mVals;
  3736. return *ceAddrPtr;
  3737. }
  3738. addr_ce CeContext::GetString(const StringImpl& str)
  3739. {
  3740. int stringId = mCeMachine->mCeModule->mContext->GetStringLiteralId(str);
  3741. return GetString(stringId);
  3742. }
  3743. BfType* CeContext::GetBfType(int typeId)
  3744. {
  3745. if ((uintptr)typeId < (uintptr)mCeMachine->mCeModule->mContext->mTypes.size())
  3746. return mCeMachine->mCeModule->mContext->mTypes[typeId];
  3747. return NULL;
  3748. }
  3749. BfType* CeContext::GetBfType(BfIRType irType)
  3750. {
  3751. if (irType.mKind == BfIRTypeData::TypeKind_TypeId)
  3752. return GetBfType(irType.mId);
  3753. return NULL;
  3754. }
  3755. void CeContext::PrepareConstStructEntry(CeConstStructData& constEntry)
  3756. {
  3757. if (constEntry.mHash.IsZero())
  3758. {
  3759. constEntry.mHash = Hash128(constEntry.mData.mVals, constEntry.mData.mSize);
  3760. if (!constEntry.mFixups.IsEmpty())
  3761. constEntry.mHash = Hash128(&constEntry.mFixups[0], constEntry.mFixups.mSize * sizeof(CeConstStructFixup), constEntry.mHash);
  3762. }
  3763. if (!constEntry.mFixups.IsEmpty())
  3764. {
  3765. if (constEntry.mFixedData.IsEmpty())
  3766. constEntry.mFixedData = constEntry.mData;
  3767. for (auto& fixup : constEntry.mFixups)
  3768. {
  3769. if (fixup.mKind == CeConstStructFixup::Kind_StringPtr)
  3770. {
  3771. BfTypeInstance* stringTypeInst = (BfTypeInstance*)mCeMachine->mCeModule->ResolveTypeDef(mCeMachine->mCompiler->mStringTypeDef, BfPopulateType_Data);
  3772. addr_ce addrPtr = GetString(fixup.mValue);
  3773. *(addr_ce*)(constEntry.mFixedData.mVals + fixup.mOffset) = addrPtr;
  3774. }
  3775. else if (fixup.mKind == CeConstStructFixup::Kind_StringCharPtr)
  3776. {
  3777. BfTypeInstance* stringTypeInst = (BfTypeInstance*)mCeMachine->mCeModule->ResolveTypeDef(mCeMachine->mCompiler->mStringTypeDef, BfPopulateType_Data);
  3778. addr_ce addrPtr = GetString(fixup.mValue);
  3779. *(addr_ce*)(constEntry.mFixedData.mVals + fixup.mOffset) = addrPtr + stringTypeInst->mInstSize;
  3780. }
  3781. }
  3782. }
  3783. constEntry.mBindExecuteId = mExecuteId;
  3784. }
  3785. bool CeContext::CheckMemory(addr_ce addr, int32 size)
  3786. {
  3787. if ((addr < 0x10000) || (addr + size > mMemory.mSize))
  3788. return false;
  3789. return true;
  3790. }
  3791. uint8* CeContext::GetMemoryPtr(addr_ce addr, int32 size)
  3792. {
  3793. if (CheckMemory(addr, size))
  3794. return mMemory.mVals + addr;
  3795. return NULL;
  3796. }
  3797. bool CeContext::GetStringFromAddr(addr_ce strInstAddr, StringImpl& str)
  3798. {
  3799. if (!CheckMemory(strInstAddr, 0))
  3800. return false;
  3801. BfTypeInstance* stringTypeInst = (BfTypeInstance*)mCeMachine->mCeModule->ResolveTypeDef(mCeMachine->mCompiler->mStringTypeDef, BfPopulateType_Data);
  3802. auto lenByteCount = stringTypeInst->mFieldInstances[0].mResolvedType->mSize;
  3803. auto lenOffset = stringTypeInst->mFieldInstances[0].mDataOffset;
  3804. auto allocSizeOffset = stringTypeInst->mFieldInstances[1].mDataOffset;
  3805. auto ptrOffset = stringTypeInst->mFieldInstances[2].mDataOffset;
  3806. uint8* strInst = (uint8*)(strInstAddr + mMemory.mVals);
  3807. int32 lenVal = *(int32*)(strInst + lenOffset);
  3808. char* charPtr = NULL;
  3809. if (lenByteCount == 4)
  3810. {
  3811. int32 allocSizeVal = *(int32*)(strInst + allocSizeOffset);
  3812. if ((allocSizeVal & 0x40000000) != 0)
  3813. {
  3814. int32 ptrVal = *(int32*)(strInst + ptrOffset);
  3815. charPtr = (char*)(ptrVal + mMemory.mVals);
  3816. }
  3817. else
  3818. {
  3819. charPtr = (char*)(strInst + ptrOffset);
  3820. }
  3821. }
  3822. else
  3823. {
  3824. int64 allocSizeVal = *(int64*)(strInst + allocSizeOffset);
  3825. if ((allocSizeVal & 0x4000000000000000LL) != 0)
  3826. {
  3827. int32 ptrVal = *(int32*)(strInst + ptrOffset);
  3828. charPtr = (char*)(ptrVal + mMemory.mVals);
  3829. }
  3830. else
  3831. {
  3832. charPtr = (char*)(strInst + ptrOffset);
  3833. }
  3834. }
  3835. int32 ptrVal = *(int32*)(strInst + ptrOffset);
  3836. if (charPtr != NULL)
  3837. str.Insert(str.length(), charPtr, lenVal);
  3838. return true;
  3839. }
  3840. bool CeContext::GetStringFromStringView(addr_ce addr, StringImpl& str)
  3841. {
  3842. int ptrSize = mCeMachine->mCeModule->mSystem->mPtrSize;
  3843. if (!CheckMemory(addr, ptrSize * 2))
  3844. return false;
  3845. addr_ce charsPtr = *(addr_ce*)(mMemory.mVals + addr);
  3846. int32 len = *(int32*)(mMemory.mVals + addr + ptrSize);
  3847. if (len > 0)
  3848. {
  3849. if (!CheckMemory(charsPtr, len))
  3850. return false;
  3851. str.Append((const char*)(mMemory.mVals + charsPtr), len);
  3852. }
  3853. return true;
  3854. }
  3855. bool CeContext::GetCustomAttribute(BfModule* module, BfIRConstHolder* constHolder, BfCustomAttributes* customAttributes, int attributeIdx, addr_ce resultAddr)
  3856. {
  3857. if (customAttributes == NULL)
  3858. return false;
  3859. auto customAttr = customAttributes->Get(attributeIdx);
  3860. if (customAttr == NULL)
  3861. return false;
  3862. auto ceContext = mCeMachine->AllocContext();
  3863. BfIRValue foreignValue = ceContext->CreateAttribute(mCurCallSource->mRefNode, module, constHolder, customAttr);
  3864. auto foreignConstant = module->mBfIRBuilder->GetConstant(foreignValue);
  3865. if (foreignConstant->mConstType == BfConstType_AggCE)
  3866. {
  3867. auto constAggData = (BfConstantAggCE*)foreignConstant;
  3868. auto value = ceContext->CreateConstant(module, ceContext->mMemory.mVals + constAggData->mCEAddr, customAttr->mType);
  3869. if (!value)
  3870. Fail("Failed to encoded attribute");
  3871. auto attrConstant = module->mBfIRBuilder->GetConstant(value);
  3872. if ((attrConstant == NULL) || (!WriteConstant(module, resultAddr, attrConstant, customAttr->mType)))
  3873. Fail("Failed to decode attribute");
  3874. }
  3875. mCeMachine->ReleaseContext(ceContext);
  3876. return true;
  3877. }
  3878. BfType* CeContext::GetCustomAttributeType(BfCustomAttributes* customAttributes, int attributeIdx)
  3879. {
  3880. if (customAttributes == NULL)
  3881. return NULL;
  3882. auto customAttr = customAttributes->Get(attributeIdx);
  3883. if (customAttr == NULL)
  3884. return NULL;
  3885. return customAttr->mType;
  3886. }
  3887. //#define CE_GETC(T) *((T*)(addr += sizeof(T)) - 1)
  3888. #define CE_GETC(T) *(T*)(mMemory.mVals + addr)
  3889. bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* constant, BfType* type, bool isParams)
  3890. {
  3891. int ptrSize = mCeMachine->mCeModule->mSystem->mPtrSize;
  3892. switch (constant->mTypeCode)
  3893. {
  3894. case BfTypeCode_None:
  3895. return true;
  3896. case BfTypeCode_Int8:
  3897. case BfTypeCode_UInt8:
  3898. case BfTypeCode_Boolean:
  3899. case BfTypeCode_Char8:
  3900. CE_GETC(int8) = constant->mInt8;
  3901. return true;
  3902. case BfTypeCode_Int16:
  3903. case BfTypeCode_UInt16:
  3904. case BfTypeCode_Char16:
  3905. CE_GETC(int16) = constant->mInt16;
  3906. return true;
  3907. case BfTypeCode_Int32:
  3908. case BfTypeCode_UInt32:
  3909. case BfTypeCode_Char32:
  3910. CE_GETC(int32) = constant->mInt32;
  3911. return true;
  3912. case BfTypeCode_Int64:
  3913. case BfTypeCode_UInt64:
  3914. CE_GETC(int64) = constant->mInt64;
  3915. return true;
  3916. case BfTypeCode_NullPtr:
  3917. if (ptrSize == 4)
  3918. CE_GETC(int32) = 0;
  3919. else
  3920. CE_GETC(int64) = 0;
  3921. return true;
  3922. case BfTypeCode_Float:
  3923. CE_GETC(float) = (float)constant->mDouble;
  3924. return true;
  3925. case BfTypeCode_Double:
  3926. CE_GETC(double) = constant->mDouble;
  3927. return true;
  3928. }
  3929. if (constant->mConstType == BfConstType_Agg)
  3930. {
  3931. if (type->IsPointer())
  3932. {
  3933. auto elementType = type->GetUnderlyingType();
  3934. auto toPtr = CeMallocZero(elementType->mSize);
  3935. addr_ce toAddr = (addr_ce)(toPtr - mMemory.mVals);
  3936. if (ptrSize == 4)
  3937. CE_GETC(int32) = (int32)toAddr;
  3938. else
  3939. CE_GETC(int64) = (int64)toAddr;
  3940. return WriteConstant(module, toAddr, constant, elementType, isParams);
  3941. }
  3942. auto aggConstant = (BfConstantAgg*)constant;
  3943. if (type->IsSizedArray())
  3944. {
  3945. auto sizedArrayType = (BfSizedArrayType*)type;
  3946. for (int i = 0; i < sizedArrayType->mElementCount; i++)
  3947. {
  3948. auto fieldConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[i]);
  3949. if (fieldConstant == NULL)
  3950. return false;
  3951. if (!WriteConstant(module, addr + i * sizedArrayType->mElementType->mSize, fieldConstant, sizedArrayType->mElementType))
  3952. return false;
  3953. }
  3954. return true;
  3955. }
  3956. else if (type->IsArray())
  3957. {
  3958. auto elemType = type->GetUnderlyingType();
  3959. addr_ce elemsAddr = 0;
  3960. addr_ce arrayAddr = CeAllocArray((BfArrayType*)type, aggConstant->mValues.size(), elemsAddr);
  3961. for (int i = 0; i < (int)aggConstant->mValues.size(); i++)
  3962. {
  3963. auto fieldConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[i]);
  3964. if (fieldConstant == NULL)
  3965. return false;
  3966. if (!WriteConstant(module, elemsAddr + i * elemType->GetStride(), fieldConstant, elemType))
  3967. return false;
  3968. }
  3969. if (ptrSize == 4)
  3970. CE_GETC(int32) = arrayAddr;
  3971. else
  3972. CE_GETC(int64) = arrayAddr;
  3973. return true;
  3974. }
  3975. else if ((type->IsInstanceOf(module->mCompiler->mSpanTypeDef)) && (isParams))
  3976. {
  3977. auto elemType = type->GetUnderlyingType();
  3978. addr_ce elemsAddr = CeMalloc(elemType->GetStride() * aggConstant->mValues.size()) - mMemory.mVals;
  3979. for (int i = 0; i < (int)aggConstant->mValues.size(); i++)
  3980. {
  3981. auto fieldConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[i]);
  3982. if (fieldConstant == NULL)
  3983. return false;
  3984. if (!WriteConstant(module, elemsAddr + i * elemType->GetStride(), fieldConstant, elemType))
  3985. return false;
  3986. }
  3987. if (ptrSize == 4)
  3988. {
  3989. CE_GETC(int32) = elemsAddr;
  3990. addr += 4;
  3991. CE_GETC(int32) = (int32)aggConstant->mValues.size();
  3992. }
  3993. else
  3994. {
  3995. CE_GETC(int32) = elemsAddr;
  3996. addr += 8;
  3997. CE_GETC(int64) = (int32)aggConstant->mValues.size();
  3998. }
  3999. }
  4000. else
  4001. {
  4002. BF_ASSERT(type->IsStruct());
  4003. module->PopulateType(type);
  4004. auto typeInst = type->ToTypeInstance();
  4005. int idx = 0;
  4006. auto baseType = typeInst->GetBaseType(true);
  4007. if (baseType != NULL)
  4008. {
  4009. auto baseConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[0]);
  4010. if (!WriteConstant(module, addr, baseConstant, baseType))
  4011. return false;
  4012. }
  4013. BfType* innerType = NULL;
  4014. BfType* payloadType = NULL;
  4015. if (typeInst->IsUnion())
  4016. innerType = typeInst->GetUnionInnerType();
  4017. if (typeInst->IsPayloadEnum())
  4018. {
  4019. auto& dscrFieldInstance = typeInst->mFieldInstances.back();
  4020. auto fieldConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[dscrFieldInstance.mDataIdx]);
  4021. if (fieldConstant == NULL)
  4022. return false;
  4023. if (!WriteConstant(module, addr + dscrFieldInstance.mDataOffset, fieldConstant, dscrFieldInstance.mResolvedType))
  4024. return false;
  4025. for (auto& fieldInstance : typeInst->mFieldInstances)
  4026. {
  4027. auto fieldDef = fieldInstance.GetFieldDef();
  4028. if (!fieldInstance.mIsEnumPayloadCase)
  4029. continue;
  4030. int tagIdx = -fieldInstance.mDataIdx - 1;
  4031. if (fieldConstant->mInt32 == tagIdx)
  4032. payloadType = fieldInstance.mResolvedType;
  4033. }
  4034. }
  4035. if (typeInst->IsUnion())
  4036. {
  4037. if (!innerType->IsValuelessType())
  4038. {
  4039. BfIRValue dataVal = aggConstant->mValues[1];
  4040. if ((payloadType != NULL) && (innerType != NULL))
  4041. {
  4042. Array<uint8> memArr;
  4043. memArr.Resize(innerType->mSize);
  4044. if (!module->mBfIRBuilder->WriteConstant(dataVal, memArr.mVals, innerType))
  4045. return false;
  4046. dataVal = module->mBfIRBuilder->ReadConstant(memArr.mVals, payloadType);
  4047. if (!dataVal)
  4048. return false;
  4049. innerType = payloadType;
  4050. }
  4051. auto fieldConstant = module->mBfIRBuilder->GetConstant(dataVal);
  4052. if (fieldConstant == NULL)
  4053. return false;
  4054. if (!WriteConstant(module, addr, fieldConstant, innerType))
  4055. return false;
  4056. }
  4057. }
  4058. if (!typeInst->IsUnion())
  4059. {
  4060. for (auto& fieldInstance : typeInst->mFieldInstances)
  4061. {
  4062. if (fieldInstance.mDataOffset < 0)
  4063. continue;
  4064. auto fieldConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[fieldInstance.mDataIdx]);
  4065. if (fieldConstant == NULL)
  4066. return false;
  4067. if (!WriteConstant(module, addr + fieldInstance.mDataOffset, fieldConstant, fieldInstance.mResolvedType))
  4068. return false;
  4069. }
  4070. }
  4071. }
  4072. return true;
  4073. }
  4074. if (constant->mConstType == BfConstType_AggZero)
  4075. {
  4076. BF_ASSERT(type->IsComposite());
  4077. memset(mMemory.mVals + addr, 0, type->mSize);
  4078. return true;
  4079. }
  4080. if (constant->mConstType == BfConstType_ArrayZero8)
  4081. {
  4082. memset(mMemory.mVals + addr, 0, constant->mInt32);
  4083. return true;
  4084. }
  4085. if (constant->mConstType == BfConstType_Undef)
  4086. {
  4087. memset(mMemory.mVals + addr, 0, type->mSize);
  4088. return true;
  4089. }
  4090. if (constant->mConstType == BfConstType_AggCE)
  4091. {
  4092. auto constAggData = (BfConstantAggCE*)constant;
  4093. if (type->IsPointer())
  4094. {
  4095. if (ptrSize == 4)
  4096. CE_GETC(int32) = constAggData->mCEAddr;
  4097. else
  4098. CE_GETC(int64) = constAggData->mCEAddr;
  4099. }
  4100. else
  4101. {
  4102. BF_ASSERT(type->IsComposite());
  4103. memcpy(mMemory.mVals + addr, mMemory.mVals + constAggData->mCEAddr, type->mSize);
  4104. }
  4105. return true;
  4106. }
  4107. if (constant->mConstType == BfConstType_BitCast)
  4108. {
  4109. auto constBitCast = (BfConstantBitCast*)constant;
  4110. auto constTarget = module->mBfIRBuilder->GetConstantById(constBitCast->mTarget);
  4111. return WriteConstant(module, addr, constTarget, type);
  4112. }
  4113. if (constant->mConstType == BfConstType_Box)
  4114. {
  4115. auto constBox = (BfConstantBox*)constant;
  4116. auto boxedType = GetBfType(constBox->mToType);
  4117. if (boxedType == NULL)
  4118. return false;
  4119. auto boxedTypeInst = boxedType->ToTypeInstance();
  4120. if (boxedTypeInst == NULL)
  4121. return false;
  4122. module->PopulateType(boxedTypeInst);
  4123. if (boxedTypeInst->mFieldInstances.IsEmpty())
  4124. return false;
  4125. auto& fieldInstance = boxedTypeInst->mFieldInstances.back();
  4126. auto boxedMem = CeMalloc(boxedTypeInst->mInstSize);
  4127. memset(boxedMem, 0, ptrSize*2);
  4128. *(int32*)boxedMem = boxedTypeInst->mTypeId;
  4129. auto constTarget = module->mBfIRBuilder->GetConstantById(constBox->mTarget);
  4130. WriteConstant(module, boxedMem - mMemory.mVals + fieldInstance.mDataOffset, constTarget, fieldInstance.mResolvedType);
  4131. if (ptrSize == 4)
  4132. CE_GETC(int32) = (int32)(boxedMem - mMemory.mVals);
  4133. else
  4134. CE_GETC(int64) = (int64)(boxedMem - mMemory.mVals);
  4135. return true;
  4136. }
  4137. if (constant->mConstType == BfConstType_PtrToInt)
  4138. {
  4139. auto ptrToIntConst = (BfConstantPtrToInt*)constant;
  4140. auto constTarget = module->mBfIRBuilder->GetConstantById(ptrToIntConst->mTarget);
  4141. return WriteConstant(module, addr, constTarget, type);
  4142. }
  4143. if (constant->mConstType == BfConstType_IntToPtr)
  4144. {
  4145. auto ptrToIntConst = (BfConstantIntToPtr*)constant;
  4146. auto intType = mCeMachine->mCeModule->GetPrimitiveType(BfTypeCode_IntPtr);
  4147. auto constTarget = module->mBfIRBuilder->GetConstantById(ptrToIntConst->mTarget);
  4148. return WriteConstant(module, addr, constTarget, intType);
  4149. }
  4150. if (constant->mConstType == BfConstType_BitCastNull)
  4151. {
  4152. BF_ASSERT(type->IsPointer() || type->IsObjectOrInterface());
  4153. memset(mMemory.mVals + addr, 0, type->mSize);
  4154. return true;
  4155. }
  4156. if (constant->mConstType == BfConstType_GEP32_2)
  4157. {
  4158. auto gepConst = (BfConstantGEP32_2*)constant;
  4159. auto constTarget = module->mBfIRBuilder->GetConstantById(gepConst->mTarget);
  4160. if (constTarget->mConstType == BfConstType_GlobalVar)
  4161. {
  4162. auto globalVar = (BfGlobalVar*)constTarget;
  4163. if (strncmp(globalVar->mName, "__bfStrData", 10) == 0)
  4164. {
  4165. BfTypeInstance* stringTypeInst = (BfTypeInstance*)mCeMachine->mCeModule->ResolveTypeDef(mCeMachine->mCompiler->mStringTypeDef, BfPopulateType_Data);
  4166. int stringId = atoi(globalVar->mName + 11);
  4167. addr_ce strAddr = GetString(stringId) + stringTypeInst->mInstSize;
  4168. if (ptrSize == 4)
  4169. CE_GETC(int32) = strAddr;
  4170. else
  4171. CE_GETC(int64) = strAddr;
  4172. return true;
  4173. }
  4174. }
  4175. }
  4176. if (constant->mConstType == BfConstType_GlobalVar)
  4177. {
  4178. auto globalVar = (BfGlobalVar*)constant;
  4179. if (strncmp(globalVar->mName, "__bfStrObj", 10) == 0)
  4180. {
  4181. int stringId = atoi(globalVar->mName + 10);
  4182. addr_ce strAddr = GetString(stringId);
  4183. if (ptrSize == 4)
  4184. CE_GETC(int32) = strAddr;
  4185. else
  4186. CE_GETC(int64) = strAddr;
  4187. return true;
  4188. }
  4189. }
  4190. if (constant->mTypeCode == BfTypeCode_StringId)
  4191. {
  4192. addr_ce strAddr = GetString(constant->mInt32);
  4193. if (type->IsPointer())
  4194. {
  4195. BfTypeInstance* stringTypeInst = (BfTypeInstance*)mCeMachine->mCeModule->ResolveTypeDef(mCeMachine->mCompiler->mStringTypeDef, BfPopulateType_Data);
  4196. strAddr += stringTypeInst->mInstSize;
  4197. }
  4198. if (ptrSize == 4)
  4199. CE_GETC(int32) = strAddr;
  4200. else
  4201. CE_GETC(int64) = strAddr;
  4202. return true;
  4203. }
  4204. if ((constant->mConstType == BfConstType_TypeOf) || (constant->mConstType == BfConstType_TypeOf_WithData))
  4205. {
  4206. auto constTypeOf = (BfTypeOf_Const*)constant;
  4207. addr_ce typeAddr = GetReflectType(constTypeOf->mType->mTypeId);
  4208. if (ptrSize == 4)
  4209. CE_GETC(int32) = typeAddr;
  4210. else
  4211. CE_GETC(int64) = typeAddr;
  4212. return true;
  4213. }
  4214. if (constant->mConstType == BfConstType_ExtractValue)
  4215. {
  4216. Array<BfConstantExtractValue*> extractStack;
  4217. auto checkConstant = constant;
  4218. while (true)
  4219. {
  4220. if (checkConstant == NULL)
  4221. break;
  4222. if (checkConstant->mConstType == BfConstType_ExtractValue)
  4223. {
  4224. auto gepConst = (BfConstantExtractValue*)constant;
  4225. BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget);
  4226. checkConstant = module->mBfIRBuilder->GetConstant(targetConst);
  4227. extractStack.Add(gepConst);
  4228. continue;
  4229. }
  4230. if (checkConstant->mConstType == BfConstType_AggCE)
  4231. return WriteConstant(module, addr, checkConstant, type, isParams);
  4232. // Unhandled
  4233. break;
  4234. }
  4235. }
  4236. return false;
  4237. }
  4238. #define CE_CREATECONST_CHECKPTR(PTR, SIZE) \
  4239. if ((((uint8*)(PTR) - memStart) - 0x10000) + (SIZE) > (memSize - 0x10000)) \
  4240. { \
  4241. Fail("Access violation creating constant result"); \
  4242. return BfIRValue(); \
  4243. }
  4244. BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType, BfType** outType)
  4245. {
  4246. auto ceModule = mCeMachine->mCeModule;
  4247. BfIRBuilder* irBuilder = module->mBfIRBuilder;
  4248. int32 ptrSize = module->mSystem->mPtrSize;
  4249. uint8* memStart = mMemory.mVals;
  4250. int memSize = mMemory.mSize;
  4251. if (bfType->IsPrimitiveType())
  4252. {
  4253. auto primType = (BfPrimitiveType*)bfType;
  4254. auto typeCode = primType->mTypeDef->mTypeCode;
  4255. if (typeCode == BfTypeCode_IntPtr)
  4256. typeCode = (ceModule->mCompiler->mSystem->mPtrSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64;
  4257. else if (typeCode == BfTypeCode_UIntPtr)
  4258. typeCode = (ceModule->mCompiler->mSystem->mPtrSize == 4) ? BfTypeCode_UInt32 : BfTypeCode_UInt64;
  4259. switch (typeCode)
  4260. {
  4261. case BfTypeCode_None:
  4262. return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, 0);
  4263. case BfTypeCode_Int8:
  4264. CE_CREATECONST_CHECKPTR(ptr, sizeof(int8));
  4265. return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(int8*)ptr);
  4266. case BfTypeCode_UInt8:
  4267. case BfTypeCode_Boolean:
  4268. case BfTypeCode_Char8:
  4269. CE_CREATECONST_CHECKPTR(ptr, sizeof(uint8));
  4270. return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(uint8*)ptr);
  4271. case BfTypeCode_Int16:
  4272. CE_CREATECONST_CHECKPTR(ptr, sizeof(int16));
  4273. return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(int16*)ptr);
  4274. case BfTypeCode_UInt16:
  4275. case BfTypeCode_Char16:
  4276. CE_CREATECONST_CHECKPTR(ptr, sizeof(uint16));
  4277. return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(uint16*)ptr);
  4278. case BfTypeCode_Int32:
  4279. CE_CREATECONST_CHECKPTR(ptr, sizeof(int32));
  4280. return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(int32*)ptr);
  4281. case BfTypeCode_UInt32:
  4282. case BfTypeCode_Char32:
  4283. CE_CREATECONST_CHECKPTR(ptr, sizeof(uint32));
  4284. return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, (uint64) * (uint32*)ptr);
  4285. case BfTypeCode_Int64:
  4286. case BfTypeCode_UInt64:
  4287. CE_CREATECONST_CHECKPTR(ptr, sizeof(int64));
  4288. return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(uint64*)ptr);
  4289. case BfTypeCode_Float:
  4290. CE_CREATECONST_CHECKPTR(ptr, sizeof(float));
  4291. return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(float*)ptr);
  4292. case BfTypeCode_Double:
  4293. CE_CREATECONST_CHECKPTR(ptr, sizeof(double));
  4294. return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(double*)ptr);
  4295. }
  4296. return BfIRValue();
  4297. }
  4298. if (bfType->IsTypedPrimitive())
  4299. return CreateConstant(module, ptr, bfType->GetUnderlyingType(), outType);
  4300. if (bfType->IsGenericParam())
  4301. return irBuilder->GetUndefConstValue(irBuilder->MapType(bfType));
  4302. if (bfType->IsTypeInstance())
  4303. {
  4304. auto typeInst = bfType->ToTypeInstance();
  4305. uint8* instData = ptr;
  4306. // if ((typeInst->IsObject()) && (!isBaseType))
  4307. // {
  4308. // CE_CREATECONST_CHECKPTR(ptr, sizeof(addr_ce));
  4309. // instData = mMemory.mVals + *(addr_ce*)ptr;
  4310. // CE_CREATECONST_CHECKPTR(instData, typeInst->mInstSize);
  4311. // }
  4312. if (typeInst->IsObjectOrInterface())
  4313. {
  4314. addr_ce addr = *(addr_ce*)(ptr);
  4315. if (addr == 0)
  4316. {
  4317. return irBuilder->CreateConstNull(irBuilder->MapType(typeInst));
  4318. }
  4319. instData = memStart + addr;
  4320. if (typeInst->IsInstanceOf(mCeMachine->mCompiler->mStringTypeDef))
  4321. {
  4322. BfTypeInstance* stringTypeInst = (BfTypeInstance*)ceModule->ResolveTypeDef(mCeMachine->mCompiler->mStringTypeDef, BfPopulateType_Data);
  4323. module->PopulateType(stringTypeInst);
  4324. auto lenByteCount = stringTypeInst->mFieldInstances[0].mResolvedType->mSize;
  4325. auto lenOffset = stringTypeInst->mFieldInstances[0].mDataOffset;
  4326. auto allocSizeOffset = stringTypeInst->mFieldInstances[1].mDataOffset;
  4327. auto ptrOffset = stringTypeInst->mFieldInstances[2].mDataOffset;
  4328. if (addr + ptrOffset + 4 > memSize)
  4329. {
  4330. // Memory error
  4331. return irBuilder->CreateConstNull(irBuilder->MapType(typeInst));
  4332. }
  4333. int32 lenVal = *(int32*)(instData + lenOffset);
  4334. char* charPtr = NULL;
  4335. if (lenByteCount == 4)
  4336. {
  4337. int32 allocSizeVal = *(int32*)(instData + allocSizeOffset);
  4338. if ((allocSizeVal & 0x40000000) != 0)
  4339. {
  4340. int32 ptrVal = *(int32*)(instData + ptrOffset);
  4341. charPtr = (char*)(ptrVal + memStart);
  4342. }
  4343. else
  4344. {
  4345. charPtr = (char*)(instData + ptrOffset);
  4346. }
  4347. }
  4348. else
  4349. {
  4350. int64 allocSizeVal = *(int64*)(instData + allocSizeOffset);
  4351. if ((allocSizeVal & 0x4000000000000000LL) != 0)
  4352. {
  4353. int32 ptrVal = *(int32*)(instData + ptrOffset);
  4354. charPtr = (char*)(ptrVal + memStart);
  4355. }
  4356. else
  4357. {
  4358. charPtr = (char*)(instData + ptrOffset);
  4359. }
  4360. }
  4361. CE_CREATECONST_CHECKPTR(charPtr, lenVal);
  4362. String str(charPtr, lenVal);
  4363. return module->GetStringObjectValue(str);
  4364. }
  4365. }
  4366. if (typeInst->IsInstanceOf(mCeMachine->mCompiler->mStringViewTypeDef))
  4367. {
  4368. char* charPtr = (char*)memStart + *(addr_ce*)(ptr);
  4369. int32 lenVal = *(int32*)(ptr + ptrSize);
  4370. CE_CREATECONST_CHECKPTR(charPtr, lenVal);
  4371. String str(charPtr, lenVal);
  4372. auto stringViewType = ceModule->ResolveTypeDef(mCeMachine->mCompiler->mStringViewTypeDef, BfPopulateType_Data)->ToTypeInstance();
  4373. auto spanType = stringViewType->mBaseType;
  4374. auto valueTypeType = spanType->mBaseType;
  4375. SizedArray<BfIRValue, 1> valueTypeValues;
  4376. BfIRValue valueTypeVal = irBuilder->CreateConstAgg(irBuilder->MapType(valueTypeType, BfIRPopulateType_Full), valueTypeValues);
  4377. SizedArray<BfIRValue, 3> spanValues;
  4378. spanValues.Add(valueTypeVal);
  4379. spanValues.Add(module->GetStringCharPtr(str));
  4380. spanValues.Add(irBuilder->CreateConst(BfTypeCode_IntPtr, lenVal));
  4381. BfIRValue spanVal = irBuilder->CreateConstAgg(irBuilder->MapType(spanType, BfIRPopulateType_Full), spanValues);
  4382. SizedArray<BfIRValue, 1> stringViewValues;
  4383. stringViewValues.Add(spanVal);
  4384. return irBuilder->CreateConstAgg(irBuilder->MapType(stringViewType, BfIRPopulateType_Full), stringViewValues);
  4385. }
  4386. SizedArray<BfIRValue, 8> fieldVals;
  4387. if (typeInst->IsInstanceOf(ceModule->mCompiler->mSpanTypeDef))
  4388. {
  4389. if ((outType != NULL) && ((mCurExpectingType == NULL) || (mCurExpectingType->IsSizedArray())))
  4390. {
  4391. module->PopulateType(typeInst);
  4392. auto ptrOffset = typeInst->mFieldInstances[0].mDataOffset;
  4393. auto lenOffset = typeInst->mFieldInstances[1].mDataOffset;
  4394. BfType* elemType = typeInst->GetUnderlyingType();
  4395. CE_CREATECONST_CHECKPTR(instData, ceModule->mSystem->mPtrSize * 2);
  4396. addr_ce addr = *(addr_ce*)(instData + ptrOffset);
  4397. int32 lenVal = *(int32*)(instData + lenOffset);
  4398. CE_CREATECONST_CHECKPTR(memStart + addr, lenVal);
  4399. for (int i = 0; i < lenVal; i++)
  4400. {
  4401. auto result = CreateConstant(module, memStart + addr + i * elemType->GetStride(), elemType);
  4402. if (!result)
  4403. return BfIRValue();
  4404. fieldVals.Add(result);
  4405. }
  4406. auto irArrayType = irBuilder->GetSizedArrayType(irBuilder->MapType(elemType, BfIRPopulateType_Full), lenVal);
  4407. auto instResult = irBuilder->CreateConstAgg(irArrayType, fieldVals);
  4408. *outType = module->CreateSizedArrayType(elemType, lenVal);
  4409. return instResult;
  4410. }
  4411. if ((mCurEvalFlags & CeEvalFlags_IgnoreConstEncodeFailure) == 0)
  4412. Fail(StrFormat("Span return type '%s' must be received by a sized array", module->TypeToString(typeInst).c_str()));
  4413. return irBuilder->CreateConstAggZero(irBuilder->MapType(typeInst));
  4414. }
  4415. if (typeInst->IsInstanceOf(ceModule->mCompiler->mTypeTypeDef))
  4416. {
  4417. int typeId = GetTypeIdFromType(instData - mMemory.mVals);
  4418. if (typeId <= 0)
  4419. {
  4420. Fail("Unable to locate return type type");
  4421. return BfIRValue();
  4422. }
  4423. return module->CreateTypeDataRef(module->mContext->mTypes[typeId]);
  4424. }
  4425. if (typeInst == module->mContext->mBfObjectType)
  4426. {
  4427. // Allow boxing
  4428. CE_CREATECONST_CHECKPTR(instData, ceModule->mSystem->mPtrSize);
  4429. addr_ce typeId = *(int*)(instData);
  4430. BfType* type = GetBfType(typeId);
  4431. if (type == NULL)
  4432. {
  4433. Fail("Unable to locate type");
  4434. return BfIRValue();
  4435. }
  4436. if (type->IsInstanceOf(mCeMachine->mCompiler->mStringTypeDef))
  4437. {
  4438. return CreateConstant(module, ptr, type, outType);
  4439. }
  4440. else if (type->IsBoxed())
  4441. {
  4442. auto underlyingType = type->GetUnderlyingType();
  4443. module->PopulateType(type);
  4444. auto boxedType = (BfBoxedType*)type;
  4445. int dataOffset = boxedType->mFieldInstances.back().mDataOffset;
  4446. auto origValue = CreateConstant(module, ptr + dataOffset, underlyingType, outType);
  4447. if (origValue)
  4448. {
  4449. if (outType != NULL)
  4450. *outType = typeInst;
  4451. return irBuilder->CreateConstBox(origValue, irBuilder->MapType(boxedType));
  4452. }
  4453. }
  4454. // else if (type->IsValueType())
  4455. // {
  4456. // auto origValue = CreateConstant(module, ptr, type, outType);
  4457. // if (origValue)
  4458. // {
  4459. // auto boxedType = module->CreateBoxedType(type);
  4460. // irBuilder->PopulateType(boxedType);
  4461. // return irBuilder->CreateConstBox(origValue, irBuilder->MapType(boxedType));
  4462. // }
  4463. // }
  4464. }
  4465. if (typeInst->IsObjectOrInterface())
  4466. {
  4467. if ((mCurEvalFlags & CeEvalFlags_IgnoreConstEncodeFailure) == 0)
  4468. Fail(StrFormat("Reference type '%s' return value not allowed", module->TypeToString(typeInst).c_str()));
  4469. return irBuilder->CreateConstNull(irBuilder->MapType(typeInst));
  4470. }
  4471. auto baseType = typeInst->GetBaseType(true);
  4472. if (baseType != NULL)
  4473. {
  4474. auto result = CreateConstant(module, instData, baseType);
  4475. if (!result)
  4476. return BfIRValue();
  4477. fieldVals.Add(result);
  4478. }
  4479. if (typeInst->IsUnion())
  4480. {
  4481. auto innerType = typeInst->GetUnionInnerType();
  4482. if (!innerType->IsValuelessType())
  4483. {
  4484. auto result = CreateConstant(module, instData, innerType);
  4485. if (!result)
  4486. return BfIRValue();
  4487. fieldVals.Add(result);
  4488. }
  4489. }
  4490. if ((!typeInst->IsUnion()) || (typeInst->IsPayloadEnum()))
  4491. {
  4492. for (int fieldIdx = 0; fieldIdx < typeInst->mFieldInstances.size(); fieldIdx++)
  4493. {
  4494. auto& fieldInstance = typeInst->mFieldInstances[fieldIdx];
  4495. if (fieldInstance.mDataOffset < 0)
  4496. continue;
  4497. if ((fieldInstance.mDataOffset == 0) && (typeInst == mCeMachine->mCompiler->mContext->mBfObjectType))
  4498. {
  4499. auto vdataPtr = module->GetClassVDataPtr(typeInst);
  4500. if (fieldInstance.mResolvedType->IsInteger())
  4501. fieldVals.Add(irBuilder->CreatePtrToInt(vdataPtr, ((BfPrimitiveType*)fieldInstance.mResolvedType)->mTypeDef->mTypeCode));
  4502. else
  4503. fieldVals.Add(vdataPtr);
  4504. continue;
  4505. }
  4506. auto result = CreateConstant(module, instData + fieldInstance.mDataOffset, fieldInstance.mResolvedType);
  4507. if (!result)
  4508. return BfIRValue();
  4509. if (fieldInstance.mDataIdx == fieldVals.mSize)
  4510. {
  4511. fieldVals.Add(result);
  4512. }
  4513. else
  4514. {
  4515. while (fieldInstance.mDataIdx >= fieldVals.mSize)
  4516. fieldVals.Add(BfIRValue());
  4517. fieldVals[fieldInstance.mDataIdx] = result;
  4518. }
  4519. }
  4520. }
  4521. for (auto& fieldVal : fieldVals)
  4522. {
  4523. if (!fieldVal)
  4524. fieldVal = irBuilder->CreateConstArrayZero(0);
  4525. }
  4526. auto instResult = irBuilder->CreateConstAgg(irBuilder->MapTypeInst(typeInst, BfIRPopulateType_Identity), fieldVals);
  4527. return instResult;
  4528. }
  4529. if (bfType->IsPointer())
  4530. {
  4531. addr_ce addr = *(addr_ce*)(ptr);
  4532. if ((addr != 0) && ((mCurEvalFlags & CeEvalFlags_IgnoreConstEncodeFailure) == 0))
  4533. Fail(StrFormat("Pointer type '%s' return value not allowed", module->TypeToString(bfType).c_str()));
  4534. return irBuilder->CreateConstNull(irBuilder->MapType(bfType));
  4535. }
  4536. if ((bfType->IsSizedArray()) && (!bfType->IsUnknownSizedArrayType()))
  4537. {
  4538. SizedArray<BfIRValue, 8> values;
  4539. auto sizedArrayType = (BfSizedArrayType*)bfType;
  4540. for (int i = 0; i < sizedArrayType->mElementCount; i++)
  4541. {
  4542. auto elemValue = CreateConstant(module, ptr + i * sizedArrayType->mElementType->GetStride(), sizedArrayType->mElementType);
  4543. if (!elemValue)
  4544. return BfIRValue();
  4545. values.Add(elemValue);
  4546. }
  4547. return irBuilder->CreateConstAgg(irBuilder->MapType(sizedArrayType, BfIRPopulateType_Full), values);
  4548. }
  4549. return BfIRValue();
  4550. }
  4551. BfIRValue CeContext::CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfIRConstHolder* constHolder, BfCustomAttribute* customAttribute, addr_ce ceAttrAddr)
  4552. {
  4553. SetAndRestoreValue<bool> prevIgnoreWrites(module->mBfIRBuilder->mIgnoreWrites, true);
  4554. module->mContext->mUnreifiedModule->PopulateType(customAttribute->mType);
  4555. if (ceAttrAddr == 0)
  4556. ceAttrAddr = CeMallocZero(customAttribute->mType->mSize) - mMemory.mVals;
  4557. BfIRValue ceAttrVal = module->mBfIRBuilder->CreateConstAggCE(module->mBfIRBuilder->MapType(customAttribute->mType, BfIRPopulateType_Identity), ceAttrAddr);
  4558. BfTypedValue ceAttrTypedValue(ceAttrVal, customAttribute->mType);
  4559. auto ctorMethodInstance = module->GetRawMethodInstance(customAttribute->mType, customAttribute->mCtor);
  4560. if (ctorMethodInstance == NULL)
  4561. {
  4562. module->Fail("Attribute ctor failed", targetSrc);
  4563. return ceAttrVal;
  4564. }
  4565. SizedArray<BfIRValue, 8> ctorArgs;
  4566. if (!customAttribute->mType->IsValuelessType())
  4567. ctorArgs.Add(ceAttrVal);
  4568. int paramIdx = 0;
  4569. for (auto& arg : customAttribute->mCtorArgs)
  4570. {
  4571. auto constant = constHolder->GetConstant(arg);
  4572. if (!constant)
  4573. {
  4574. module->AssertErrorState();
  4575. return ceAttrVal;
  4576. }
  4577. auto paramType = ctorMethodInstance->GetParamType(paramIdx);
  4578. ctorArgs.Add(module->ConstantToCurrent(constant, constHolder, paramType, true));
  4579. paramIdx++;
  4580. }
  4581. BfTypedValue retValue = Call(CeCallSource(targetSrc), module, ctorMethodInstance, ctorArgs, CeEvalFlags_None, NULL);
  4582. if (!retValue)
  4583. return ceAttrVal;
  4584. for (auto& setProperty : customAttribute->mSetProperties)
  4585. {
  4586. BfExprEvaluator exprEvaluator(module);
  4587. BfMethodDef* setMethodDef = exprEvaluator.GetPropertyMethodDef(setProperty.mPropertyRef, BfMethodType_PropertySetter, BfCheckedKind_NotSet, ceAttrTypedValue);
  4588. BfMethodInstance* setMethodInstance = NULL;
  4589. if (setMethodDef != NULL)
  4590. setMethodInstance = module->GetRawMethodInstance(customAttribute->mType, setMethodDef);
  4591. if ((setMethodInstance == NULL) || (!setProperty.mParam))
  4592. {
  4593. module->Fail("Attribute prop failed", targetSrc);
  4594. return ceAttrVal;
  4595. }
  4596. SizedArray<BfIRValue, 1> setArgs;
  4597. if (!customAttribute->mType->IsValuelessType())
  4598. setArgs.Add(ceAttrVal);
  4599. if (!setProperty.mParam.mType->IsValuelessType())
  4600. {
  4601. auto constant = constHolder->GetConstant(setProperty.mParam.mValue);
  4602. if (!constant)
  4603. {
  4604. module->AssertErrorState();
  4605. return ceAttrVal;
  4606. }
  4607. setArgs.Add(module->ConstantToCurrent(constant, constHolder, setProperty.mParam.mType, true));
  4608. }
  4609. BfTypedValue retValue = Call(targetSrc, module, setMethodInstance, setArgs, CeEvalFlags_None, NULL);
  4610. if (!retValue)
  4611. return ceAttrVal;
  4612. }
  4613. for (auto& setField : customAttribute->mSetField)
  4614. {
  4615. BfFieldInstance* fieldInstance = setField.mFieldRef;
  4616. if (fieldInstance->mDataOffset < 0)
  4617. continue;
  4618. auto constant = constHolder->GetConstant(setField.mParam.mValue);
  4619. WriteConstant(module, ceAttrAddr + fieldInstance->mDataOffset, constant, fieldInstance->mResolvedType);
  4620. }
  4621. return ceAttrVal;
  4622. }
  4623. BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags, BfType* expectingType)
  4624. {
  4625. // DISABLED
  4626. //return BfTypedValue();
  4627. //
  4628. {
  4629. StackHelper stackHelper;
  4630. if (!stackHelper.CanStackExpand(256 * 1024))
  4631. {
  4632. BfTypedValue result;
  4633. if (!stackHelper.Execute([&]()
  4634. {
  4635. result = Call(callSource, module, methodInstance, args, flags, expectingType);
  4636. }))
  4637. {
  4638. module->Fail("Stack exhausted in CeContext::Call", callSource.mRefNode);
  4639. }
  4640. return result;
  4641. }
  4642. }
  4643. //auto ceModule = mCeMachine->mCeModule;
  4644. AutoTimer autoTimer(mCeMachine->mRevisionExecuteTime);
  4645. SetAndRestoreValue<CeContext*> curPrevContext(mPrevContext, mCeMachine->mCurContext);
  4646. SetAndRestoreValue<CeContext*> prevContext(mCeMachine->mCurContext, this);
  4647. SetAndRestoreValue<CeEvalFlags> prevEvalFlags(mCurEvalFlags, flags);
  4648. SetAndRestoreValue<CeCallSource*> prevCallSource(mCurCallSource, &callSource);
  4649. SetAndRestoreValue<BfModule*> prevModule(mCurModule, module);
  4650. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, methodInstance);
  4651. SetAndRestoreValue<BfMethodInstance*> prevCallerMethodInstance(mCallerMethodInstance, module->mCurMethodInstance);
  4652. SetAndRestoreValue<BfTypeInstance*> prevCallerTypeInstance(mCallerTypeInstance, module->mCurTypeInstance);
  4653. SetAndRestoreValue<BfTypeDef*> prevCallerActiveTypeDef(mCallerActiveTypeDef, module->GetActiveTypeDef());
  4654. SetAndRestoreValue<BfType*> prevExpectingType(mCurExpectingType, expectingType);
  4655. SetAndRestoreValue<bool> prevCtxResolvingVar(module->mContext->mResolvingVarField, false);
  4656. SetAndRestoreValue<BfMethodInstance*> moduleCurMethodInstance(module->mCurMethodInstance, methodInstance);
  4657. SetAndRestoreValue<BfTypeInstance*> moduleCurTypeInstance(module->mCurTypeInstance, methodInstance->GetOwner());
  4658. SetAndRestoreValue<int> prevCurExecuteId(mCurModule->mCompiler->mCurCEExecuteId, mCeMachine->mExecuteId);
  4659. // Reentrancy may occur as methods need defining
  4660. //SetAndRestoreValue<BfMethodState*> prevMethodStateInConstEval(module->mCurMethodState, NULL);
  4661. if (mCeMachine->mAppendAllocInfo != NULL)
  4662. {
  4663. if (mCeMachine->mAppendAllocInfo->mAppendSizeValue)
  4664. {
  4665. bool isConst = mCeMachine->mAppendAllocInfo->mAppendSizeValue.IsConst();
  4666. if (isConst)
  4667. {
  4668. auto constant = module->mBfIRBuilder->GetConstant(mCeMachine->mAppendAllocInfo->mAppendSizeValue);
  4669. if (constant->mConstType == BfConstType_Undef)
  4670. isConst = false;
  4671. }
  4672. if (!isConst)
  4673. {
  4674. Fail("Non-constant append alloc");
  4675. return BfTypedValue();
  4676. }
  4677. }
  4678. }
  4679. if (mCeMachine->HasFailed())
  4680. {
  4681. Fail("ConstEval machine failed");
  4682. return BfTypedValue();
  4683. }
  4684. int thisArgIdx = -1;
  4685. int appendAllocIdx = -1;
  4686. bool hasAggData = false;
  4687. if (!methodInstance->mMethodDef->mIsStatic)
  4688. {
  4689. if (!methodInstance->GetOwner()->IsValuelessType())
  4690. {
  4691. thisArgIdx = 0;
  4692. auto checkConstant = module->mBfIRBuilder->GetConstant(args[0]);
  4693. while (checkConstant != NULL)
  4694. {
  4695. if ((checkConstant != NULL) && (checkConstant->mConstType == BfConstType_AggCE))
  4696. {
  4697. hasAggData = true;
  4698. break;
  4699. }
  4700. if (checkConstant->mConstType == BfConstType_ExtractValue)
  4701. {
  4702. auto gepConst = (BfConstantExtractValue*)checkConstant;
  4703. BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget);
  4704. checkConstant = module->mBfIRBuilder->GetConstant(targetConst);
  4705. continue;
  4706. }
  4707. break;
  4708. }
  4709. }
  4710. if ((methodInstance->GetParamCount() >= 1) && (methodInstance->GetParamKind(0) == BfParamKind_AppendIdx))
  4711. appendAllocIdx = 1;
  4712. }
  4713. int paramCompositeSize = 0;
  4714. int paramIdx = methodInstance->GetParamCount();
  4715. for (int argIdx = (int)args.size() - 1; argIdx >= 0; argIdx--)
  4716. {
  4717. BfType* paramType = NULL;
  4718. while (true)
  4719. {
  4720. paramIdx--;
  4721. paramType = methodInstance->GetParamType(paramIdx);
  4722. if (paramType->IsTypedPrimitive())
  4723. paramType = paramType->GetUnderlyingType();
  4724. if ((!paramType->IsValuelessType()) && (!paramType->IsVar()))
  4725. break;
  4726. }
  4727. BfType* compositeType = paramType->IsComposite() ? paramType : NULL;
  4728. auto arg = args[argIdx];
  4729. bool isConst = arg.IsConst();
  4730. if (isConst)
  4731. {
  4732. auto constant = module->mBfIRBuilder->GetConstant(arg);
  4733. if (constant->mConstType == BfConstType_Undef)
  4734. {
  4735. if (paramType->IsInstanceOf(module->mCompiler->mTypeTypeDef))
  4736. {
  4737. args[argIdx] = module->CreateTypeDataRef(module->GetPrimitiveType(BfTypeCode_None));
  4738. }
  4739. // else
  4740. // isConst = false;
  4741. }
  4742. else if (((constant->mConstType == BfConstType_AggZero) || (constant->mConstType == BfConstType_Agg)) &&
  4743. ((paramType->IsPointer()) || (paramType->IsRef())))
  4744. compositeType = paramType->GetUnderlyingType();
  4745. }
  4746. if (compositeType != NULL)
  4747. {
  4748. if ((paramType->IsPointer()) || (paramType->IsRef()))
  4749. paramCompositeSize += paramType->GetUnderlyingType()->mSize;
  4750. else
  4751. paramCompositeSize += paramType->mSize;
  4752. }
  4753. if (!isConst)
  4754. {
  4755. if ((argIdx == thisArgIdx) && (methodInstance->mMethodDef->mMethodType == BfMethodType_Ctor))
  4756. {
  4757. // Allow non-const 'this' for ctor
  4758. }
  4759. else if (argIdx != appendAllocIdx)
  4760. {
  4761. Fail(StrFormat("Non-constant argument for param '%s'", methodInstance->GetParamName(paramIdx).c_str()));
  4762. return BfTypedValue();
  4763. }
  4764. }
  4765. }
  4766. auto methodDef = methodInstance->mMethodDef;
  4767. if (mCeMachine->mCeModule == NULL)
  4768. mCeMachine->Init();
  4769. auto ceModule = mCeMachine->mCeModule;
  4770. bool added = false;
  4771. CeFunction* ceFunction = mCeMachine->GetFunction(methodInstance, BfIRValue(), added);
  4772. if (ceFunction->mInitializeState == CeFunction::InitializeState_Initializing_ReEntry)
  4773. {
  4774. String error = "Comptime method preparation recursion";
  4775. auto curContext = this;
  4776. while (curContext != NULL)
  4777. {
  4778. if (curContext->mCurMethodInstance != NULL)
  4779. error += StrFormat("\n %s", module->MethodToString(curContext->mCurMethodInstance).c_str());
  4780. curContext = curContext->mPrevContext;
  4781. if ((curContext != NULL) && (curContext->mCurMethodInstance == mCurMethodInstance))
  4782. break;
  4783. }
  4784. Fail(error);
  4785. return BfTypedValue();
  4786. }
  4787. if (ceFunction->mInitializeState < CeFunction::InitializeState_Initialized)
  4788. mCeMachine->PrepareFunction(ceFunction, NULL);
  4789. Array<CeFrame> prevCallStack;
  4790. auto stackPtr = &mMemory[0] + mStackSize;
  4791. auto* memStart = &mMemory[0];
  4792. if (!mCallStack.IsEmpty())
  4793. {
  4794. BF_ASSERT((flags & CeEvalFlags_DbgCall) != 0);
  4795. prevCallStack = mCallStack;
  4796. stackPtr = &mMemory[0] + mCallStack.back().mStackAddr;
  4797. mCallStack.Clear();
  4798. }
  4799. BfTypeInstance* thisType = methodInstance->GetOwner();
  4800. addr_ce allocThisInstAddr = 0;
  4801. addr_ce allocThisAddr = 0;
  4802. addr_ce thisAddr = 0;
  4803. int allocThisSize = -1;
  4804. if ((thisArgIdx != -1) && (!hasAggData))
  4805. {
  4806. allocThisSize = thisType->mInstSize;
  4807. if ((mCeMachine->mAppendAllocInfo != NULL) && (mCeMachine->mAppendAllocInfo->mAppendSizeValue))
  4808. {
  4809. BF_ASSERT(mCeMachine->mAppendAllocInfo->mModule == module);
  4810. BF_ASSERT(mCeMachine->mAppendAllocInfo->mAppendSizeValue.IsConst());
  4811. auto appendSizeConstant = module->mBfIRBuilder->GetConstant(mCeMachine->mAppendAllocInfo->mAppendSizeValue);
  4812. BF_ASSERT(module->mBfIRBuilder->IsInt(appendSizeConstant->mTypeCode));
  4813. allocThisSize += appendSizeConstant->mInt32;
  4814. }
  4815. if (allocThisSize >= mStackSize / 4)
  4816. {
  4817. // Resize stack a reasonable size
  4818. mStackSize = BF_ALIGN(allocThisSize, 0x100000) + BF_CE_DEFAULT_STACK_SIZE;
  4819. int64 memSize = mStackSize + BF_CE_DEFAULT_HEAP_SIZE;
  4820. if (memSize > BF_CE_MAX_MEMORY)
  4821. {
  4822. Fail("Return value too large (>2GB)");
  4823. return BfTypedValue();
  4824. }
  4825. if (memSize > mMemory.mSize)
  4826. mMemory.Resize(memSize);
  4827. stackPtr = &mMemory[0] + mStackSize;
  4828. memStart = &mMemory[0];
  4829. }
  4830. stackPtr -= allocThisSize;
  4831. auto allocThisPtr = stackPtr;
  4832. memset(allocThisPtr, 0, allocThisSize);
  4833. if (thisType->IsObject())
  4834. *(int32*)(allocThisPtr) = thisType->mTypeId;
  4835. allocThisInstAddr = allocThisPtr - memStart;
  4836. allocThisAddr = allocThisInstAddr;
  4837. thisAddr = allocThisAddr;
  4838. }
  4839. addr_ce allocAppendIdxAddr = 0;
  4840. if (appendAllocIdx != -1)
  4841. {
  4842. stackPtr -= ceModule->mSystem->mPtrSize;
  4843. memset(stackPtr, 0, ceModule->mSystem->mPtrSize);
  4844. *(addr_ce*)(stackPtr) = (addr_ce)(allocThisInstAddr + thisType->mInstSize);
  4845. allocAppendIdxAddr = stackPtr - memStart;
  4846. }
  4847. auto _FixVariables = [&]()
  4848. {
  4849. intptr memOffset = &mMemory[0] - memStart;
  4850. if (memOffset == 0)
  4851. return;
  4852. memStart += memOffset;
  4853. stackPtr += memOffset;
  4854. };
  4855. addr_ce compositeStartAddr = stackPtr - memStart;
  4856. stackPtr -= paramCompositeSize;
  4857. addr_ce useCompositeAddr = compositeStartAddr;
  4858. paramIdx = methodInstance->GetParamCount();
  4859. for (int argIdx = (int)args.size() - 1; argIdx >= 0; argIdx--)
  4860. {
  4861. BfType* paramType = NULL;
  4862. while (true)
  4863. {
  4864. paramIdx--;
  4865. paramType = methodInstance->GetParamType(paramIdx);
  4866. if (paramType->IsTypedPrimitive())
  4867. paramType = paramType->GetUnderlyingType();
  4868. if ((!paramType->IsValuelessType()) && (!paramType->IsVar()))
  4869. break;
  4870. }
  4871. bool isParams = methodInstance->GetParamKind(paramIdx) == BfParamKind_Params;
  4872. auto arg = args[argIdx];
  4873. if (!arg.IsConst())
  4874. {
  4875. if (argIdx == thisArgIdx)
  4876. {
  4877. if (mCeMachine->mAppendAllocInfo != NULL)
  4878. BF_ASSERT(mCeMachine->mAppendAllocInfo->mAllocValue == arg);
  4879. stackPtr -= ceModule->mSystem->mPtrSize;
  4880. int64 addr64 = allocThisAddr;
  4881. memcpy(stackPtr, &addr64, ceModule->mSystem->mPtrSize);
  4882. continue;
  4883. }
  4884. else if (argIdx == appendAllocIdx)
  4885. {
  4886. stackPtr -= ceModule->mSystem->mPtrSize;
  4887. int64 addr64 = allocAppendIdxAddr;
  4888. memcpy(stackPtr, &addr64, ceModule->mSystem->mPtrSize);
  4889. continue;
  4890. }
  4891. else
  4892. return BfTypedValue();
  4893. }
  4894. auto constant = module->mBfIRBuilder->GetConstant(arg);
  4895. BfType* compositeType = paramType->IsComposite() ? paramType : NULL;
  4896. if (((constant->mConstType == BfConstType_AggZero) || (constant->mConstType == BfConstType_Agg)) &&
  4897. ((paramType->IsPointer()) || (paramType->IsRef())))
  4898. compositeType = paramType->GetUnderlyingType();
  4899. if (compositeType != NULL)
  4900. {
  4901. useCompositeAddr -= compositeType->mSize;
  4902. if (!WriteConstant(module, useCompositeAddr, constant, compositeType, isParams))
  4903. {
  4904. Fail(StrFormat("Failed to process argument for param '%s'", methodInstance->GetParamName(paramIdx).c_str()));
  4905. return BfTypedValue();
  4906. }
  4907. _FixVariables();
  4908. stackPtr -= ceModule->mSystem->mPtrSize;
  4909. int64 addr64 = useCompositeAddr;
  4910. if (argIdx == thisArgIdx)
  4911. thisAddr = addr64;
  4912. memcpy(stackPtr, &addr64, ceModule->mSystem->mPtrSize);
  4913. }
  4914. else
  4915. {
  4916. stackPtr -= paramType->mSize;
  4917. auto useCompositeAddr = stackPtr - memStart;
  4918. if (!WriteConstant(module, useCompositeAddr, constant, paramType, isParams))
  4919. {
  4920. Fail(StrFormat("Failed to process argument for param '%s'", methodInstance->GetParamName(paramIdx).c_str()));
  4921. return BfTypedValue();
  4922. }
  4923. _FixVariables();
  4924. if (argIdx == thisArgIdx)
  4925. {
  4926. auto checkConstant = constant;
  4927. while (checkConstant != NULL)
  4928. {
  4929. if ((checkConstant != NULL) && (checkConstant->mConstType == BfConstType_AggCE))
  4930. {
  4931. auto constAggData = (BfConstantAggCE*)checkConstant;
  4932. if (paramType->IsPointer())
  4933. thisAddr = constAggData->mCEAddr;
  4934. else
  4935. thisAddr = useCompositeAddr;
  4936. break;
  4937. }
  4938. if (checkConstant->mConstType == BfConstType_ExtractValue)
  4939. {
  4940. auto gepConst = (BfConstantExtractValue*)checkConstant;
  4941. BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget);
  4942. checkConstant = module->mBfIRBuilder->GetConstant(targetConst);
  4943. continue;
  4944. }
  4945. break;
  4946. }
  4947. }
  4948. }
  4949. }
  4950. addr_ce retAddr = 0;
  4951. if (ceFunction->mMaxReturnSize > 0)
  4952. {
  4953. int retSize = ceFunction->mMaxReturnSize;
  4954. stackPtr -= retSize;
  4955. retAddr = stackPtr - memStart;
  4956. }
  4957. delete mCeMachine->mAppendAllocInfo;
  4958. mCeMachine->mAppendAllocInfo = NULL;
  4959. BfType* returnType = NULL;
  4960. BfType* castReturnType = NULL;
  4961. bool success = Execute(ceFunction, stackPtr - ceFunction->mFrameSize, stackPtr, returnType, castReturnType);
  4962. memStart = &mMemory[0];
  4963. addr_ce retInstAddr = retAddr;
  4964. if ((returnType->IsObject()) || (returnType->IsPointer()))
  4965. {
  4966. // Or pointer?
  4967. retInstAddr = *(addr_ce*)(memStart + retAddr);
  4968. }
  4969. if ((flags & CeEvalFlags_ForceReturnThis) != 0)
  4970. {
  4971. returnType = thisType;
  4972. retInstAddr = thisAddr;
  4973. }
  4974. BfTypedValue returnValue;
  4975. if (success)
  4976. {
  4977. BfTypedValue retValue;
  4978. if (returnType->IsObject())
  4979. {
  4980. BfType* usedReturnType = returnType;
  4981. BfIRValue constVal = CreateConstant(module, (uint8*)&retInstAddr, returnType, &usedReturnType);
  4982. if (constVal)
  4983. returnValue = BfTypedValue(constVal, usedReturnType);
  4984. else
  4985. {
  4986. Fail("Failed to encode return argument");
  4987. }
  4988. }
  4989. else if ((retInstAddr != 0) || (allocThisInstAddr != 0))
  4990. {
  4991. auto* retPtr = memStart + retInstAddr;
  4992. if ((allocThisInstAddr != 0) && (methodInstance->mMethodDef->mMethodType == BfMethodType_Ctor))
  4993. {
  4994. retPtr = memStart + allocThisAddr;
  4995. returnType = thisType;
  4996. }
  4997. BfType* usedReturnType = returnType;
  4998. BfIRValue constVal;
  4999. if (returnType->IsObject())
  5000. {
  5001. addr_ce retAddr = retPtr - memStart;
  5002. constVal = CreateConstant(module, (uint8*)&retAddr, returnType, &usedReturnType);
  5003. }
  5004. else
  5005. constVal = CreateConstant(module, retPtr, returnType, &usedReturnType);
  5006. if (constVal)
  5007. returnValue = BfTypedValue(constVal, usedReturnType);
  5008. else
  5009. {
  5010. Fail("Failed to encode return argument");
  5011. }
  5012. }
  5013. else if ((methodInstance->mMethodDef->mMethodType == BfMethodType_Ctor) && (thisType != NULL) && (thisType->IsValuelessType()))
  5014. {
  5015. returnValue = BfTypedValue(module->mBfIRBuilder->CreateConstAggZero(module->mBfIRBuilder->MapType(returnType, BfIRPopulateType_Identity)), thisType);
  5016. }
  5017. else if ((returnType->IsComposite()) || (returnType->IsValuelessType()))
  5018. {
  5019. returnValue = BfTypedValue(module->mBfIRBuilder->CreateConstAggZero(module->mBfIRBuilder->MapType(returnType, BfIRPopulateType_Identity)), returnType);
  5020. }
  5021. }
  5022. mCallStack.Clear();
  5023. moduleCurMethodInstance.Restore();
  5024. moduleCurTypeInstance.Restore();
  5025. module->AddDependency(methodInstance->GetOwner(), module->mCurTypeInstance, BfDependencyMap::DependencyFlag_ConstEval);
  5026. if (!prevCallStack.IsEmpty())
  5027. {
  5028. BF_ASSERT((flags& CeEvalFlags_DbgCall) != 0);
  5029. mCallStack = prevCallStack;
  5030. }
  5031. if ((castReturnType != NULL) && (returnValue))
  5032. {
  5033. auto castedReturnValue = module->Cast(callSource.mRefNode, returnValue, castReturnType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromComptimeReturn));
  5034. if (castedReturnValue)
  5035. return castedReturnValue;
  5036. }
  5037. return returnValue;
  5038. }
  5039. #define CE_CHECKSTACK() \
  5040. if (stackPtr < memStart) \
  5041. { \
  5042. _Fail("Stack overflow"); \
  5043. return false; \
  5044. }
  5045. #define CE_CHECKALLOC(SIZE) \
  5046. if ((SIZE < 0) || (SIZE >= 0x80000000LL) || ((uintptr)memSize + (uintptr)SIZE > BF_CE_MAX_MEMORY)) \
  5047. { \
  5048. _Fail("Maximum memory size exceeded (2GB)"); \
  5049. return false; \
  5050. }
  5051. // This check will fail for addresses < 64K (null pointer), or out-of-bounds
  5052. #define CE_CHECKSIZE(SIZE) \
  5053. if ((SIZE) < 0) \
  5054. { \
  5055. _Fail("Invalid memory size"); \
  5056. return false; \
  5057. }
  5058. #define CE_CHECKADDR(ADDR, SIZE) \
  5059. if (((ADDR) < 0x10000) || ((ADDR) + (SIZE) > memSize)) \
  5060. { \
  5061. _Fail("Access violation"); \
  5062. return false; \
  5063. }
  5064. #define CE_CHECKADDR_STR(STRNAME, ADDR) \
  5065. { \
  5066. addr_ce checkAddr = ADDR; \
  5067. while (true) \
  5068. { \
  5069. if ((uintptr)checkAddr >= (uintptr)memSize) \
  5070. { \
  5071. break; \
  5072. } \
  5073. if (memStart[checkAddr] == 0) \
  5074. { \
  5075. CE_CHECKADDR(ADDR, checkAddr - ADDR + 1); \
  5076. STRNAME = String::MakeRef((char*)memStart + ADDR, checkAddr - ADDR + 1); \
  5077. break; \
  5078. } \
  5079. checkAddr++; \
  5080. } \
  5081. }
  5082. #define CE_GET_INTERNAL(VAR, ID, KIND) \
  5083. if (!mInternalDataMap.TryGetValue((int)ID, &VAR)) \
  5084. { \
  5085. _Fail("Invalid internal resource id"); \
  5086. return false; \
  5087. } \
  5088. if (VAR->mKind != KIND) \
  5089. { \
  5090. _Fail("Invalid internal resource kind"); \
  5091. return false; \
  5092. } \
  5093. if (VAR->mReleased) \
  5094. { \
  5095. _Fail("Resource already released"); \
  5096. return false; \
  5097. }
  5098. #define CE_REMOVE_INTERNAL(VAR, ID, KIND) \
  5099. if (!mInternalDataMap.Remove((int)ID, &VAR)) \
  5100. { \
  5101. _Fail("Invalid internal resource id"); \
  5102. return false; \
  5103. } \
  5104. if (VAR->mKind != KIND) \
  5105. { \
  5106. _Fail("Invalid internal resource kind"); \
  5107. return false; \
  5108. } \
  5109. if (VAR->mReleased) \
  5110. { \
  5111. _Fail("Resource already released"); \
  5112. return false; \
  5113. }
  5114. #define CE_GETINST(T) *((T*)(instPtr += sizeof(T)) - 1)
  5115. #define CE_GETFRAME(T) *(T*)(framePtr + *((int32*)(instPtr += sizeof(int32)) - 1))
  5116. #define CEOP_BIN(OP, T) \
  5117. { \
  5118. auto& result = CE_GETFRAME(T); \
  5119. auto lhs = CE_GETFRAME(T); \
  5120. auto rhs = CE_GETFRAME(T); \
  5121. result = lhs OP rhs; \
  5122. }
  5123. #define CEOP_BIN_DIV(OP, T) \
  5124. { \
  5125. auto& result = CE_GETFRAME(T); \
  5126. auto lhs = CE_GETFRAME(T); \
  5127. auto rhs = CE_GETFRAME(T); \
  5128. if (rhs == 0) \
  5129. { \
  5130. _Fail("Division by zero"); \
  5131. return false; \
  5132. } \
  5133. result = lhs OP rhs; \
  5134. }
  5135. #define CEOP_BIN2(OP, TLHS, TRHS) \
  5136. { \
  5137. auto& result = CE_GETFRAME(TLHS); \
  5138. auto lhs = CE_GETFRAME(TLHS); \
  5139. auto rhs = CE_GETFRAME(TRHS); \
  5140. result = lhs OP rhs; \
  5141. }
  5142. #define CEOP_BIN_CONST(OP, T) \
  5143. { \
  5144. auto& result = CE_GETFRAME(T); \
  5145. auto lhs = CE_GETFRAME(T); \
  5146. auto rhs = CE_GETINST(T); \
  5147. result = lhs OP rhs; \
  5148. }
  5149. #define CEOP_UNARY_FUNC(OP, T) \
  5150. { \
  5151. auto& result = CE_GETFRAME(T); \
  5152. auto lhs = CE_GETFRAME(T); \
  5153. result = OP(lhs); \
  5154. }
  5155. #define CEOP_BIN_FUNC(OP, T) \
  5156. { \
  5157. auto& result = CE_GETFRAME(T); \
  5158. auto lhs = CE_GETFRAME(T); \
  5159. auto rhs = CE_GETFRAME(T); \
  5160. result = OP(lhs, rhs); \
  5161. }
  5162. #define CEOP_UNARY(OP, T) \
  5163. { \
  5164. auto& result = CE_GETFRAME(T); \
  5165. auto val = CE_GETFRAME(T); \
  5166. result = OP val; \
  5167. }
  5168. #define CEOP_CMP(OP, T) \
  5169. { \
  5170. auto& result = CE_GETFRAME(bool); \
  5171. auto lhs = CE_GETFRAME(T); \
  5172. auto rhs = CE_GETFRAME(T); \
  5173. result = lhs OP rhs; \
  5174. }
  5175. #define CE_CAST(TFROM, TTO) \
  5176. { \
  5177. auto& result = CE_GETFRAME(TTO); \
  5178. auto val = CE_GETFRAME(TFROM); \
  5179. result = (TTO)val; \
  5180. }
  5181. #define CE_LOAD(T) \
  5182. { \
  5183. auto& result = CE_GETFRAME(T); \
  5184. auto ceAddr = CE_GETFRAME(addr_ce); \
  5185. CE_CHECKADDR(ceAddr, sizeof(T)); \
  5186. result = *(T*)(memStart + ceAddr); \
  5187. }
  5188. #define CE_STORE(T) \
  5189. { \
  5190. auto val = CE_GETFRAME(T); \
  5191. auto ceAddr = CE_GETFRAME(addr_ce); \
  5192. CE_CHECKADDR(ceAddr, sizeof(T)); \
  5193. *(T*)(memStart + ceAddr) = val; \
  5194. }
  5195. #define CEOP_MOVE(T) \
  5196. { \
  5197. auto val = CE_GETFRAME(T); \
  5198. auto& ptr = CE_GETFRAME(T); \
  5199. ptr = val; \
  5200. }
  5201. #define CEOP_PUSH(T) \
  5202. { \
  5203. stackPtr -= sizeof(T); \
  5204. auto val = CE_GETFRAME(T); \
  5205. *((T*)stackPtr) = val; \
  5206. CE_CHECKSTACK(); \
  5207. }
  5208. #define CEOP_POP(T) \
  5209. { \
  5210. auto& result = CE_GETFRAME(T); \
  5211. result = *((T*)stackPtr); \
  5212. stackPtr += sizeof(T); \
  5213. }
  5214. #define CE_CALL(CEFUNC) \
  5215. if (CEFUNC == NULL) \
  5216. { \
  5217. _Fail("Unable to locate function entry"); \
  5218. return false; \
  5219. } \
  5220. mCallStack.Add(_GetCurFrame()); \
  5221. ceFunction = CEFUNC; \
  5222. framePtr = stackPtr; \
  5223. stackPtr -= ceFunction->mFrameSize; \
  5224. if (isDebugging) \
  5225. memset(stackPtr, 0, ceFunction->mFrameSize); \
  5226. instPtr = &ceFunction->mCode[0]; \
  5227. CE_CHECKSTACK();
  5228. static void CeSetAddrVal(void* ptr, int64 val, int32 ptrSize)
  5229. {
  5230. if (ptrSize == 4)
  5231. *(int32*)(ptr) = (int32)val;
  5232. else
  5233. *(int64*)(ptr) = (int64)val;
  5234. }
  5235. class CeAsyncOperation
  5236. {
  5237. public:
  5238. CeInternalData* mInternalData;
  5239. int mRefCount;
  5240. uint8* mData;
  5241. int mDataSize;
  5242. int mReadSize;
  5243. BfpFileResult mResult;
  5244. public:
  5245. CeAsyncOperation()
  5246. {
  5247. mInternalData = NULL;
  5248. mRefCount = 1;
  5249. mData = NULL;
  5250. mDataSize = 0;
  5251. mReadSize = 0;
  5252. mResult = BfpFileResult_Ok;
  5253. }
  5254. ~CeAsyncOperation()
  5255. {
  5256. mInternalData->Release();
  5257. delete mData;
  5258. }
  5259. void AddRef()
  5260. {
  5261. BfpSystem_InterlockedExchangeAdd32((uint32*)&mRefCount, 1);
  5262. }
  5263. void Release()
  5264. {
  5265. if (BfpSystem_InterlockedExchangeAdd32((uint32*)&mRefCount, (uint32)-1) == 1)
  5266. delete this;
  5267. }
  5268. void Run()
  5269. {
  5270. mReadSize = BfpFile_Read(mInternalData->mFile, mData, mDataSize, -1, &mResult);
  5271. Release();
  5272. }
  5273. static void RunProc(void* ptr)
  5274. {
  5275. ((CeAsyncOperation*)ptr)->Run();
  5276. }
  5277. };
  5278. bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr, BfType*& returnType, BfType*& castReturnType)
  5279. {
  5280. auto ceModule = mCeMachine->mCeModule;
  5281. SetAndRestoreValue<bool> ignoreWrites(ceModule->mBfIRBuilder->mIgnoreWrites, false);
  5282. CeFunction* ceFunction = startFunction;
  5283. returnType = startFunction->mMethodInstance->mReturnType;
  5284. uint8* memStart = &mMemory[0];
  5285. int memSize = mMemory.mSize;
  5286. uint8* instPtr = (ceFunction->mCode.IsEmpty()) ? NULL : &ceFunction->mCode[0];
  5287. uint8* stackPtr = startStackPtr;
  5288. uint8* framePtr = startFramePtr;
  5289. bool needsFunctionIds = ceModule->mSystem->mPtrSize != 8;
  5290. int32 ptrSize = ceModule->mSystem->mPtrSize;
  5291. bool isDebugging = mCeMachine->mDebugger != NULL;
  5292. volatile bool* specialCheckPtr = &mCeMachine->mSpecialCheck;
  5293. volatile bool* fastFinishPtr = &mCeMachine->mCompiler->mFastFinish;
  5294. volatile bool* cancelingPtr = &mCeMachine->mCompiler->mCanceling;
  5295. auto _GetCurFrame = [&]()
  5296. {
  5297. CeFrame ceFrame;
  5298. ceFrame.mFunction = ceFunction;
  5299. ceFrame.mReturnType = returnType;
  5300. ceFrame.mFrameAddr = framePtr - memStart;
  5301. ceFrame.mStackAddr = stackPtr - memStart;
  5302. ceFrame.mInstPtr = instPtr;
  5303. return ceFrame;
  5304. };
  5305. auto _FixVariables = [&]()
  5306. {
  5307. memSize = mMemory.mSize;
  5308. intptr memOffset = &mMemory[0] - memStart;
  5309. if (memOffset == 0)
  5310. return;
  5311. memStart += memOffset;
  5312. stackPtr += memOffset;
  5313. framePtr += memOffset;
  5314. };
  5315. auto _DbgPause = [&]()
  5316. {
  5317. int itr = 0;
  5318. while (mCeMachine->mDebugger != NULL)
  5319. {
  5320. if (mCeMachine->mDbgPaused)
  5321. {
  5322. // This indicates a missed breakpoint, we should try to avoid this
  5323. // Re-entrancy can cause this, from populating a type during cedebugger autocomplete
  5324. OutputDebugStrF("CeMachine DbgPause reentry\n");
  5325. return;
  5326. }
  5327. CePendingExpr* prevPendingExpr = NULL;
  5328. ///
  5329. {
  5330. AutoCrit autoCrit(mCeMachine->mCritSect);
  5331. if ((mCeMachine->mDebugger->mDebugPendingExpr != NULL) && (itr == 0))
  5332. {
  5333. // Abandon evaluating expression
  5334. prevPendingExpr = mCeMachine->mDebugger->mDebugPendingExpr;
  5335. mCeMachine->mDebugger->mDebugPendingExpr = NULL;
  5336. }
  5337. if (itr == 0)
  5338. mCallStack.Add(_GetCurFrame());
  5339. mCeMachine->mDbgPaused = true;
  5340. }
  5341. mCeMachine->mDebugEvent.WaitFor();
  5342. CePendingExpr* pendingExpr = NULL;
  5343. ///
  5344. {
  5345. AutoCrit autoCrit(mCeMachine->mCritSect);
  5346. mCeMachine->mDbgPaused = false;
  5347. if (mCeMachine->mStepState.mKind != CeStepState::Kind_Evaluate)
  5348. {
  5349. mCallStack.pop_back();
  5350. _FixVariables();
  5351. break;
  5352. }
  5353. mCeMachine->mStepState.mKind = CeStepState::Kind_None;
  5354. String result;
  5355. if (mCeMachine->mDebugger->mDebugPendingExpr != NULL)
  5356. pendingExpr = mCeMachine->mDebugger->mDebugPendingExpr;
  5357. }
  5358. if (pendingExpr == NULL)
  5359. continue;;
  5360. pendingExpr->mResult = mCeMachine->mDebugger->DoEvaluate(pendingExpr, true);
  5361. ///
  5362. {
  5363. AutoCrit autoCrit(mCeMachine->mCritSect);
  5364. pendingExpr->mDone = true;
  5365. if (pendingExpr != mCeMachine->mDebugger->mDebugPendingExpr)
  5366. delete pendingExpr;
  5367. }
  5368. itr++;
  5369. }
  5370. };
  5371. auto _Fail = [&](const StringImpl& error)
  5372. {
  5373. auto bfError = Fail(_GetCurFrame(), error);
  5374. if ((bfError != NULL) && (mCeMachine->mDebugger != NULL))
  5375. {
  5376. mCeMachine->mDebugger->OutputRawMessage(StrFormat("error %s", error.c_str()));
  5377. _DbgPause();
  5378. }
  5379. };
  5380. auto _CheckFastFinish = [&]()
  5381. {
  5382. if (*fastFinishPtr)
  5383. return true;
  5384. if (mCeMachine->mDbgWantBreak)
  5385. {
  5386. mCeMachine->mDbgWantBreak = false;
  5387. _DbgPause();
  5388. }
  5389. return false;
  5390. };
  5391. std::function<bool(CeFunction* checkFunction, bool& handled)> _CheckFunction = [&](CeFunction* checkFunction, bool& handled)
  5392. {
  5393. if (checkFunction == NULL)
  5394. {
  5395. Fail(_GetCurFrame(), "Const method not available");
  5396. return false;
  5397. }
  5398. if (mCeMachine->mDebugger != NULL)
  5399. {
  5400. if (checkFunction->mBreakpointVersion != mCeMachine->mDebugger->mBreakpointVersion)
  5401. mCeMachine->mDebugger->UpdateBreakpoints(checkFunction);
  5402. }
  5403. else if (checkFunction->mBreakpointVersion != 0)
  5404. {
  5405. checkFunction->UnbindBreakpoints();
  5406. checkFunction->mBreakpointVersion = 0;
  5407. }
  5408. if (checkFunction->mFunctionKind != CeFunctionKind_Normal)
  5409. {
  5410. if (checkFunction->mFunctionKind == CeFunctionKind_OOB)
  5411. {
  5412. Fail(_GetCurFrame(), "Array out of bounds");
  5413. return false;
  5414. }
  5415. else if (checkFunction->mFunctionKind == CeFunctionKind_OOB)
  5416. {
  5417. Fail(_GetCurFrame(), "Object not initialized");
  5418. return false;
  5419. }
  5420. else if (checkFunction->mFunctionKind == CeFunctionKind_Malloc)
  5421. {
  5422. int64 size;
  5423. if (ptrSize == 4)
  5424. size = *(int32*)((uint8*)stackPtr + 4);
  5425. else
  5426. size = *(int64*)((uint8*)stackPtr + 8);
  5427. CE_CHECKALLOC(size);
  5428. uint8* ptr = CeMalloc(size);
  5429. CeSetAddrVal(stackPtr + 0, ptr - memStart, ptrSize);
  5430. }
  5431. else if (checkFunction->mFunctionKind == CeFunctionKind_Free)
  5432. {
  5433. addr_ce freeAddr = *(addr_ce*)((uint8*)stackPtr + 4);
  5434. bool success = CeFree(freeAddr);
  5435. if (!success)
  5436. _Fail("Invalid heap address");
  5437. }
  5438. else if (checkFunction->mFunctionKind == CeFunctionKind_FatalError)
  5439. {
  5440. int32 strInstAddr = *(int32*)((uint8*)stackPtr + 0);
  5441. int32 stackOffset = *(int32*)(stackPtr + ceModule->mSystem->mPtrSize);
  5442. if (mCeMachine->mDebugger != NULL)
  5443. mCeMachine->mDebugger->mPendingActiveFrameOffset = stackOffset;
  5444. String error = "Fatal Error: ";
  5445. GetStringFromAddr(strInstAddr, error);
  5446. _Fail(error);
  5447. return false;
  5448. }
  5449. else if (checkFunction->mFunctionKind == CeFunctionKind_DynCheckFailed)
  5450. {
  5451. _Fail("Dynamic cast check failed");
  5452. return false;
  5453. }
  5454. else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite)
  5455. {
  5456. int32 ptrVal = *(int32*)((uint8*)stackPtr + 0);
  5457. auto size = *(int32*)(stackPtr + ceModule->mSystem->mPtrSize);
  5458. CE_CHECKADDR(ptrVal, size);
  5459. char* strPtr = (char*)(ptrVal + memStart);
  5460. String str;
  5461. str.Insert(0, strPtr, size);
  5462. if (mCeMachine->mDebugger != NULL)
  5463. mCeMachine->mDebugger->OutputMessage(str);
  5464. else
  5465. OutputDebugStr(str);
  5466. }
  5467. else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite_Int)
  5468. {
  5469. if (ceModule->mSystem->mPtrSize == 4)
  5470. {
  5471. int32 intVal = *(int32*)((uint8*)stackPtr + 0);
  5472. OutputDebugStrF("Debug Val: %d %X\n", intVal, intVal);
  5473. }
  5474. else
  5475. {
  5476. int64 intVal = *(int64*)((uint8*)stackPtr + 0);
  5477. OutputDebugStrF("Debug Val: %lld %llX\n", intVal, intVal);
  5478. }
  5479. }
  5480. else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectTypeDeclById)
  5481. {
  5482. int32 typeId = *(int32*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize);
  5483. auto reflectType = GetReflectTypeDecl(typeId);
  5484. _FixVariables();
  5485. CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
  5486. }
  5487. else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectTypeDeclByName)
  5488. {
  5489. addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  5490. String typeName;
  5491. if (!GetStringFromStringView(strViewPtr, typeName))
  5492. {
  5493. _Fail("Invalid StringView");
  5494. return false;
  5495. }
  5496. auto reflectType = GetReflectType(typeName, true);
  5497. _FixVariables();
  5498. CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
  5499. }
  5500. else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectNextTypeDecl)
  5501. {
  5502. int32 typeId = *(int32*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize);
  5503. addr_ce reflectType = 0;
  5504. auto context = mCeMachine->mCeModule->mContext;
  5505. if (mTypeDeclState == NULL)
  5506. mTypeDeclState = new CeTypeDeclState();
  5507. while (true)
  5508. {
  5509. typeId++;
  5510. if (typeId >= mCeMachine->mCeModule->mContext->mTypes.mSize)
  5511. {
  5512. int foundTypeCount = 0;
  5513. if (!mTypeDeclState->mCheckedAllTypeDefs)
  5514. {
  5515. mTypeDeclState->mCheckedAllTypeDefs = true;
  5516. for (auto typeDef : ceModule->mSystem->mTypeDefs)
  5517. {
  5518. if ((typeDef->mIsPartial) && (!typeDef->mIsCombinedPartial))
  5519. continue;
  5520. if (typeDef->mTypeCode == BfTypeCode_TypeAlias)
  5521. continue;
  5522. if (typeDef->mTypeDeclaration == NULL)
  5523. continue;
  5524. if (mTypeDeclState->mIteratedTypeDefs.Contains(typeDef))
  5525. continue;
  5526. int lastTypeId = mCeMachine->mCompiler->mCurTypeId;
  5527. auto resolvedType = mCeMachine->mCeModule->ResolveTypeDef(typeDef, BfPopulateType_Identity);
  5528. if ((resolvedType != NULL) && (resolvedType->IsTypeInstance()))
  5529. {
  5530. if (resolvedType->mDefineState == BfTypeDefineState_Undefined)
  5531. foundTypeCount++;
  5532. }
  5533. }
  5534. }
  5535. if (foundTypeCount > 0)
  5536. typeId = 0;
  5537. else
  5538. break;
  5539. }
  5540. auto bfType = mCeMachine->mCeModule->mContext->mTypes[typeId];
  5541. if (bfType != NULL)
  5542. {
  5543. if (bfType->IsOnDemand())
  5544. continue;
  5545. if (bfType->IsBoxed())
  5546. continue;
  5547. auto bfTypeInst = bfType->ToTypeInstance();
  5548. if (bfTypeInst == NULL)
  5549. continue;
  5550. auto useTypeDef = bfTypeInst->mTypeDef;
  5551. useTypeDef = useTypeDef->GetLatest();
  5552. if (!mTypeDeclState->mCheckedAllTypeDefs)
  5553. {
  5554. mTypeDeclState->mIteratedTypeDefs.Add(useTypeDef);
  5555. }
  5556. else
  5557. {
  5558. if (mTypeDeclState->mIteratedTypeDefs.Contains(useTypeDef))
  5559. continue;
  5560. }
  5561. if (bfTypeInst->IsGenericTypeInstance())
  5562. {
  5563. if (!bfTypeInst->IsUnspecializedType())
  5564. continue;
  5565. if (bfTypeInst->IsUnspecializedTypeVariation())
  5566. continue;
  5567. }
  5568. reflectType = GetReflectTypeDecl(typeId);
  5569. if (reflectType != 0)
  5570. break;
  5571. }
  5572. }
  5573. _FixVariables();
  5574. CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
  5575. }
  5576. else if (checkFunction->mFunctionKind == CeFunctionKind_GetBaseType)
  5577. {
  5578. int32 typeId = *(int32*)((uint8*)stackPtr + 4);
  5579. int baseTypeId = 0;
  5580. BfType* type = GetBfType(typeId);
  5581. if (type != NULL)
  5582. {
  5583. AddTypeSigRebuild(type);
  5584. if (auto typeInst = type->ToTypeInstance())
  5585. {
  5586. if (type->mDefineState < BfTypeDefineState_HasCustomAttributes)
  5587. ceModule->PopulateType(type, BfPopulateType_CustomAttributes);
  5588. if (typeInst->mBaseType != NULL)
  5589. baseTypeId = typeInst->mBaseType->mTypeId;
  5590. }
  5591. }
  5592. *(addr_ce*)(stackPtr + 0) = baseTypeId;
  5593. }
  5594. else if (checkFunction->mFunctionKind == CeFunctionKind_HasDeclaredMember)
  5595. {
  5596. int32 typeId = *(int32*)((uint8*)stackPtr + 1);
  5597. int32 memberKind = *(int32*)((uint8*)stackPtr + 1 + 4);
  5598. addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 4 + 4);
  5599. bool hasMember;
  5600. String typeName;
  5601. if (!GetStringFromStringView(strViewPtr, typeName))
  5602. {
  5603. _Fail("Invalid StringView");
  5604. return false;
  5605. }
  5606. BfType* type = GetBfType(typeId);
  5607. if ((type != NULL) && (type->IsTypeInstance()))
  5608. {
  5609. AddTypeSigRebuild(type);
  5610. auto typeInst = type->ToTypeInstance();
  5611. typeInst->mTypeDef->PopulateMemberSets();
  5612. if (memberKind == 0) // Field
  5613. hasMember = typeInst->mTypeDef->mFieldSet.ContainsWith((StringImpl&)typeName);
  5614. else if (memberKind == 1) // Method
  5615. hasMember = typeInst->mTypeDef->mMethodSet.ContainsWith((StringImpl&)typeName);
  5616. else if (memberKind == 2) // Property
  5617. hasMember = typeInst->mTypeDef->mPropertySet.ContainsWith((StringImpl&)typeName);
  5618. }
  5619. *(addr_ce*)(stackPtr + 0) = hasMember;
  5620. }
  5621. else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectType)
  5622. {
  5623. addr_ce objAddr = *(addr_ce*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize);
  5624. CE_CHECKADDR(objAddr, 4);
  5625. int32 typeId = *(int32*)(objAddr + memStart);
  5626. auto reflectType = GetReflectType(typeId);
  5627. _FixVariables();
  5628. CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
  5629. }
  5630. else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectTypeById)
  5631. {
  5632. int32 typeId = *(int32*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize);
  5633. auto reflectType = GetReflectType(typeId);
  5634. _FixVariables();
  5635. CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
  5636. }
  5637. else if (checkFunction->mFunctionKind == CeFunctionKind_GetWrappedType)
  5638. {
  5639. int32 typeId = *(int32*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize);
  5640. BfType* type = GetBfType(typeId);
  5641. bool success = false;
  5642. if (type == NULL)
  5643. {
  5644. _Fail("Invalid type");
  5645. return false;
  5646. }
  5647. addr_ce reflectType = NULL;
  5648. type = ceModule->GetWrappedStructType(type);
  5649. if (type != NULL)
  5650. reflectType = GetReflectType(type->mTypeId);
  5651. _FixVariables();
  5652. CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
  5653. }
  5654. else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectTypeByName)
  5655. {
  5656. addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  5657. String typeName;
  5658. if (!GetStringFromStringView(strViewPtr, typeName))
  5659. {
  5660. _Fail("Invalid StringView");
  5661. return false;
  5662. }
  5663. auto reflectType = GetReflectType(typeName, false);
  5664. _FixVariables();
  5665. CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
  5666. }
  5667. else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectSpecializedType)
  5668. {
  5669. addr_ce typeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  5670. addr_ce typeSpan = *(addr_ce*)((uint8*)stackPtr + ptrSize * 2);
  5671. auto reflectType = GetReflectSpecializedType(typeAddr, typeSpan);
  5672. _FixVariables();
  5673. CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
  5674. }
  5675. else if (checkFunction->mFunctionKind == CeFunctionKind_Type_ToString)
  5676. {
  5677. int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize);
  5678. BfType* type = GetBfType(typeId);
  5679. bool success = false;
  5680. if (type == NULL)
  5681. {
  5682. _Fail("Invalid type");
  5683. return false;
  5684. }
  5685. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, mCallerMethodInstance);
  5686. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCeMachine->mCeModule->mCurTypeInstance, mCallerTypeInstance);
  5687. bool simpleName = false;
  5688. if ((type->IsUnspecializedType()) && (!type->IsUnspecializedTypeVariation()) && (!type->IsGenericParam()))
  5689. simpleName = true;
  5690. String typeName;
  5691. if (simpleName)
  5692. mCeMachine->mCeModule->DoTypeToString(typeName, type, BfTypeNameFlags_None);
  5693. else
  5694. typeName = mCeMachine->mCeModule->TypeToString(type);
  5695. CeSetAddrVal(stackPtr + 0, GetString(typeName), ptrSize);
  5696. _FixVariables();
  5697. }
  5698. else if (checkFunction->mFunctionKind == CeFunctionKind_TypeName_ToString)
  5699. {
  5700. int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize);
  5701. BfType* type = GetBfType(typeId);
  5702. bool success = false;
  5703. if (type == NULL)
  5704. {
  5705. _Fail("Invalid type");
  5706. return false;
  5707. }
  5708. String str;
  5709. if (auto typeInst = type->ToTypeInstance())
  5710. str = typeInst->mTypeDef->mName->ToString();
  5711. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, mCallerMethodInstance);
  5712. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCeMachine->mCeModule->mCurTypeInstance, mCallerTypeInstance);
  5713. CeSetAddrVal(stackPtr + 0, GetString(str), ptrSize);
  5714. _FixVariables();
  5715. }
  5716. else if (checkFunction->mFunctionKind == CeFunctionKind_TypeDocumentation_ToString)
  5717. {
  5718. int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize);
  5719. BfType* type = GetBfType(typeId);
  5720. if (type == NULL)
  5721. {
  5722. _Fail("Invalid type");
  5723. return false;
  5724. }
  5725. String str;
  5726. if (auto typeInst = type->ToTypeInstance())
  5727. if(typeInst->mTypeDef->mTypeDeclaration->mDocumentation != NULL)
  5728. typeInst->mTypeDef->mTypeDeclaration->mDocumentation->GetDocString(str);
  5729. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, mCallerMethodInstance);
  5730. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCeMachine->mCeModule->mCurTypeInstance, mCallerTypeInstance);
  5731. CeSetAddrVal(stackPtr + 0, GetString(str), ptrSize);
  5732. _FixVariables();
  5733. }
  5734. else if (checkFunction->mFunctionKind == CeFunctionKind_Namespace_ToString)
  5735. {
  5736. int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize);
  5737. BfType* type = GetBfType(typeId);
  5738. bool success = false;
  5739. if (type == NULL)
  5740. {
  5741. _Fail("Invalid type");
  5742. return false;
  5743. }
  5744. String str;
  5745. if (auto typeInst = type->ToTypeInstance())
  5746. typeInst->mTypeDef->mNamespace.ToString(str);
  5747. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, mCallerMethodInstance);
  5748. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCeMachine->mCeModule->mCurTypeInstance, mCallerTypeInstance);
  5749. CeSetAddrVal(stackPtr + 0, GetString(str), ptrSize);
  5750. _FixVariables();
  5751. }
  5752. else if (checkFunction->mFunctionKind == CeFunctionKind_Type_GetCustomAttribute)
  5753. {
  5754. int32 typeId = *(int32*)((uint8*)stackPtr + 1);
  5755. int32 attributeIdx = *(int32*)((uint8*)stackPtr + 1 + 4);
  5756. addr_ce resultPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 4 + 4);
  5757. BfType* type = GetBfType(typeId);
  5758. bool success = false;
  5759. if (type != NULL)
  5760. {
  5761. AddTypeSigRebuild(type);
  5762. auto typeInst = type->ToTypeInstance();
  5763. if (typeInst != NULL)
  5764. success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, typeInst->mCustomAttributes, attributeIdx, resultPtr);
  5765. _FixVariables();
  5766. }
  5767. *(addr_ce*)(stackPtr + 0) = success;
  5768. }
  5769. else if (checkFunction->mFunctionKind == CeFunctionKind_Field_GetCustomAttribute)
  5770. {
  5771. int32 typeId = *(int32*)((uint8*)stackPtr + 1);
  5772. int32 fieldIdx = *(int32*)((uint8*)stackPtr + 1 + 4);
  5773. int32 attributeIdx = *(int32*)((uint8*)stackPtr + 1 + 4 + 4);
  5774. addr_ce resultPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 4 + 4 + 4);
  5775. BfType* type = GetBfType(typeId);
  5776. bool success = false;
  5777. if (type != NULL)
  5778. {
  5779. AddTypeSigRebuild(type);
  5780. auto typeInst = type->ToTypeInstance();
  5781. if (typeInst != NULL)
  5782. {
  5783. if (typeInst->mDefineState < BfTypeDefineState_CETypeInit)
  5784. mCurModule->PopulateType(typeInst);
  5785. if ((fieldIdx >= 0) && (fieldIdx < typeInst->mFieldInstances.mSize))
  5786. {
  5787. auto& fieldInstance = typeInst->mFieldInstances[fieldIdx];
  5788. success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, fieldInstance.mCustomAttributes, attributeIdx, resultPtr);
  5789. _FixVariables();
  5790. }
  5791. else if (fieldIdx != -1)
  5792. {
  5793. _Fail("Invalid field");
  5794. return false;
  5795. }
  5796. }
  5797. }
  5798. *(addr_ce*)(stackPtr + 0) = success;
  5799. }
  5800. else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetCustomAttribute)
  5801. {
  5802. int64 methodHandle = *(int64*)((uint8*)stackPtr + 1);
  5803. int32 attributeIdx = *(int32*)((uint8*)stackPtr + 1 + 8);
  5804. addr_ce resultPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 8 + 4);
  5805. auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
  5806. if (methodInstance == NULL)
  5807. {
  5808. _Fail("Invalid method instance");
  5809. return false;
  5810. }
  5811. AddTypeSigRebuild(methodInstance->GetOwner());
  5812. bool success = GetCustomAttribute(mCurModule, methodInstance->GetOwner()->mConstHolder, methodInstance->GetCustomAttributes(), attributeIdx, resultPtr);
  5813. _FixVariables();
  5814. *(addr_ce*)(stackPtr + 0) = success;
  5815. }
  5816. else if (checkFunction->mFunctionKind == CeFunctionKind_Type_GetCustomAttributeType)
  5817. {
  5818. int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize);
  5819. int32 attributeIdx = *(int32*)((uint8*)stackPtr + ptrSize + 4);
  5820. BfType* type = GetBfType(typeId);
  5821. addr_ce reflectType = 0;
  5822. if (type != NULL)
  5823. {
  5824. AddTypeSigRebuild(type);
  5825. auto typeInst = type->ToTypeInstance();
  5826. if (typeInst != NULL)
  5827. {
  5828. auto attrType = GetCustomAttributeType(typeInst->mCustomAttributes, attributeIdx);
  5829. if (attrType != NULL)
  5830. reflectType = GetReflectType(attrType->mTypeId);
  5831. }
  5832. _FixVariables();
  5833. }
  5834. CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
  5835. }
  5836. else if (checkFunction->mFunctionKind == CeFunctionKind_Field_GetCustomAttributeType)
  5837. {
  5838. int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize);
  5839. int32 fieldIdx = *(int32*)((uint8*)stackPtr + ptrSize + 4);
  5840. int32 attributeIdx = *(int32*)((uint8*)stackPtr + ptrSize + 4 + 4);
  5841. BfType* type = GetBfType(typeId);
  5842. addr_ce reflectType = 0;
  5843. if (type != NULL)
  5844. {
  5845. AddTypeSigRebuild(type);
  5846. auto typeInst = type->ToTypeInstance();
  5847. if (typeInst != NULL)
  5848. {
  5849. if (typeInst->mDefineState < BfTypeDefineState_CETypeInit)
  5850. mCurModule->PopulateType(typeInst);
  5851. if ((fieldIdx >= 0) && (fieldIdx < typeInst->mFieldInstances.mSize))
  5852. {
  5853. auto& fieldInstance = typeInst->mFieldInstances[fieldIdx];
  5854. auto attrType = GetCustomAttributeType(fieldInstance.mCustomAttributes, attributeIdx);
  5855. if (attrType != NULL)
  5856. reflectType = GetReflectType(attrType->mTypeId);
  5857. _FixVariables();
  5858. }
  5859. else if (fieldIdx != -1)
  5860. {
  5861. _Fail("Invalid field");
  5862. return false;
  5863. }
  5864. }
  5865. }
  5866. CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
  5867. }
  5868. else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetCustomAttributeType)
  5869. {
  5870. int64 methodHandle = *(int64*)((uint8*)stackPtr + ptrSize);
  5871. int32 attributeIdx = *(int32*)((uint8*)stackPtr + ptrSize + 8);
  5872. auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
  5873. if (methodInstance == NULL)
  5874. {
  5875. _Fail("Invalid method instance");
  5876. return false;
  5877. }
  5878. AddTypeSigRebuild(methodInstance->GetOwner());
  5879. auto attrType = GetCustomAttributeType(methodInstance->GetCustomAttributes(), attributeIdx);
  5880. if (attrType != NULL)
  5881. CeSetAddrVal(stackPtr + 0, GetReflectType(attrType->mTypeId), ptrSize);
  5882. else
  5883. CeSetAddrVal(stackPtr + 0, 0, ptrSize);
  5884. _FixVariables();
  5885. }
  5886. else if (checkFunction->mFunctionKind == CeFunctionKind_GetMethodCount)
  5887. {
  5888. int32 typeId = *(int32*)((uint8*)stackPtr + 4);
  5889. CeTypeInfo* typeInfo = mCeMachine->GetTypeInfo(GetBfType(typeId));
  5890. if (typeInfo == NULL)
  5891. {
  5892. _Fail("Invalid type");
  5893. return false;
  5894. }
  5895. *(int32*)(stackPtr + 0) = (int)typeInfo->mMethodInstances.size();
  5896. }
  5897. else if (checkFunction->mFunctionKind == CeFunctionKind_GetMethod)
  5898. {
  5899. int32 typeId = *(int32*)((uint8*)stackPtr + 8);
  5900. int32 methodIdx = *(int32*)((uint8*)stackPtr + 8+4);
  5901. CeTypeInfo* typeInfo = mCeMachine->GetTypeInfo(GetBfType(typeId));
  5902. if (typeInfo == NULL)
  5903. {
  5904. _Fail("Invalid type");
  5905. return false;
  5906. }
  5907. if ((methodIdx < 0) || (methodIdx >= typeInfo->mMethodInstances.mSize))
  5908. {
  5909. *(int64*)(stackPtr + 0) = 0;
  5910. }
  5911. else
  5912. *(int64*)(stackPtr + 0) = (int64)(intptr)typeInfo->mMethodInstances[methodIdx];
  5913. }
  5914. else if (checkFunction->mFunctionKind == CeFunctionKind_Method_ToString)
  5915. {
  5916. int64 methodHandle = *(int64*)((uint8*)stackPtr + ptrSize);
  5917. auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
  5918. if (methodInstance == NULL)
  5919. {
  5920. _Fail("Invalid method instance");
  5921. return false;
  5922. }
  5923. CeSetAddrVal(stackPtr + 0, GetString(mCeMachine->mCeModule->MethodToString(methodInstance)), ptrSize);
  5924. _FixVariables();
  5925. }
  5926. else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetName)
  5927. {
  5928. int64 methodHandle = *(int64*)((uint8*)stackPtr + ptrSize);
  5929. auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
  5930. if (methodInstance == NULL)
  5931. {
  5932. _Fail("Invalid method instance");
  5933. return false;
  5934. }
  5935. CeSetAddrVal(stackPtr + 0, GetString(methodInstance->mMethodDef->GetReflectName()), ptrSize);
  5936. _FixVariables();
  5937. }
  5938. else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetDocumentation)
  5939. {
  5940. int64 methodHandle = *(int64*)((uint8*)stackPtr + ptrSize);
  5941. auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
  5942. if (methodInstance == NULL)
  5943. {
  5944. _Fail("Invalid method instance");
  5945. return false;
  5946. }
  5947. String docs;
  5948. if (auto decl = BfNodeDynCast<BfMethodDeclaration>(methodInstance->mMethodDef->mMethodDeclaration))
  5949. if(decl->mDocumentation != NULL)
  5950. decl->mDocumentation->GetDocString(docs);
  5951. CeSetAddrVal(stackPtr + 0, GetString(docs), ptrSize);
  5952. _FixVariables();
  5953. }
  5954. else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetInfo)
  5955. {
  5956. // int32 mReturnType
  5957. // int32 mParamCount
  5958. // int32 mGenericArgCount
  5959. // int32 mFlags
  5960. // int8 ComptimeMethodFlags
  5961. // int32 mMethodIdx
  5962. int64 methodHandle = *(int64*)((uint8*)stackPtr + 4+4+4+4+1+4);
  5963. auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
  5964. if (methodInstance == NULL)
  5965. {
  5966. _Fail("Invalid method instance");
  5967. return false;
  5968. }
  5969. AddTypeSigRebuild(methodInstance->GetOwner());
  5970. int genericArgCount = 0;
  5971. if (methodInstance->mMethodInfoEx != NULL)
  5972. genericArgCount = methodInstance->mMethodInfoEx->mMethodGenericArguments.mSize;
  5973. *(int32*)(stackPtr + 0) = methodInstance->mReturnType->mTypeId;
  5974. *(int32*)(stackPtr + 4) = methodInstance->GetParamCount();
  5975. *(int32*)(stackPtr + 4+4) = genericArgCount;
  5976. *(int32*)(stackPtr + 4+4+4) = methodInstance->GetMethodFlags();
  5977. *(int32*)(stackPtr + 4+4+4+4) = methodInstance->GetComptimeMethodFlags();
  5978. *(int32*)(stackPtr + 4+4+4+4+1) = methodInstance->mMethodDef->mIdx;
  5979. }
  5980. else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetParamInfo)
  5981. {
  5982. // int32 mParamType
  5983. // int16 mFlags
  5984. // str mName
  5985. int64 methodHandle = *(int64*)((uint8*)stackPtr + 4+2+ptrSize);
  5986. int32 paramIdx = *(int32*)((uint8*)stackPtr + 4+2+ptrSize+8);
  5987. auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
  5988. if (methodInstance == NULL)
  5989. {
  5990. _Fail("Invalid method instance");
  5991. return false;
  5992. }
  5993. if (paramIdx < 0 || paramIdx >= methodInstance->mParams.mSize)
  5994. {
  5995. _Fail("paramIdx is out of range");
  5996. return false;
  5997. }
  5998. enum ParamFlags
  5999. {
  6000. ParamFlag_None = 0,
  6001. ParamFlag_Splat = 1,
  6002. ParamFlag_Implicit = 2,
  6003. ParamFlag_AppendIdx = 4,
  6004. ParamFlag_Params = 8
  6005. };
  6006. ParamFlags paramFlags = ParamFlag_None;
  6007. if (methodInstance->GetParamIsSplat(paramIdx))
  6008. paramFlags = (ParamFlags)(paramFlags | ParamFlag_Splat);
  6009. if (methodInstance->GetParamKind(paramIdx) == BfParamKind_AppendIdx)
  6010. paramFlags = (ParamFlags)(paramFlags | ParamFlag_Implicit | ParamFlag_AppendIdx);
  6011. if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params)
  6012. paramFlags = (ParamFlags)(paramFlags | ParamFlag_Params);
  6013. addr_ce stringAddr = GetString(methodInstance->GetParamName(paramIdx));
  6014. _FixVariables();
  6015. *(int32*)(stackPtr + 0) = methodInstance->GetParamType(paramIdx)->mTypeId;
  6016. *(int16*)(stackPtr + 4) = (int16)paramFlags;
  6017. CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize);
  6018. }
  6019. else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetGenericArg)
  6020. {
  6021. int64 methodHandle = *(int64*)((uint8*)stackPtr + ptrSize);
  6022. int32 genericArgIdx = *(int32*)((uint8*)stackPtr + ptrSize + 8);
  6023. auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
  6024. if (methodInstance == NULL)
  6025. {
  6026. _Fail("Invalid method instance");
  6027. return false;
  6028. }
  6029. if ((methodInstance->mMethodInfoEx == NULL) || (genericArgIdx < 0) || (genericArgIdx >= methodInstance->mMethodInfoEx->mMethodGenericArguments.mSize))
  6030. {
  6031. _Fail("genericArgIdx is out of range");
  6032. return false;
  6033. }
  6034. auto reflectType = GetReflectType(methodInstance->mMethodInfoEx->mMethodGenericArguments[genericArgIdx]->mTypeId);
  6035. _FixVariables();
  6036. CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
  6037. }
  6038. else if (checkFunction->mFunctionKind == CeFunctionKind_Field_GetDocumentation)
  6039. {
  6040. int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize);
  6041. int32 fieldIdx = *(int32*)((uint8*)stackPtr + ptrSize + 4);
  6042. BfType* type = GetBfType(typeId);
  6043. if (type == NULL)
  6044. {
  6045. _Fail("Invalid type");
  6046. return false;
  6047. }
  6048. String docs;
  6049. if (type != NULL)
  6050. {
  6051. if (auto typeInst = type->ToTypeInstance())
  6052. {
  6053. if (fieldIdx < 0 || fieldIdx >= typeInst->mFieldInstances.size())
  6054. {
  6055. _Fail("Invalid field");
  6056. return false;
  6057. }
  6058. auto fieldInstance = typeInst->mFieldInstances[fieldIdx];
  6059. if (auto decl = BfNodeDynCast<BfFieldDeclaration>(fieldInstance.GetFieldDef()->mFieldDeclaration))
  6060. if(decl->mDocumentation != NULL)
  6061. decl->mDocumentation->GetDocString(docs);
  6062. }
  6063. }
  6064. CeSetAddrVal(stackPtr + 0, GetString(docs), ptrSize);
  6065. _FixVariables();
  6066. }
  6067. else if (checkFunction->mFunctionKind == CeFunctionKind_Field_GetStatic)
  6068. {
  6069. int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize);
  6070. int32 fieldIdx = *(int32*)((uint8*)stackPtr + ptrSize + 4);
  6071. CeFunction* ctorCallFunction = NULL;
  6072. BfType* bfType = GetBfType(typeId);
  6073. bool success = false;
  6074. if (bfType != NULL)
  6075. {
  6076. auto typeInst = bfType->ToTypeInstance();
  6077. if (typeInst != NULL)
  6078. {
  6079. if (typeInst->mDefineState < BfTypeDefineState_CETypeInit)
  6080. mCurModule->PopulateType(typeInst);
  6081. if ((fieldIdx >= 0) && (fieldIdx < typeInst->mFieldInstances.mSize))
  6082. {
  6083. auto& fieldInstance = typeInst->mFieldInstances[fieldIdx];
  6084. auto fieldType = fieldInstance.mResolvedType;
  6085. ceModule->PopulateType(fieldType, BfPopulateType_Full_Force);
  6086. int64 fieldId = ((int64)typeId << 32) | fieldIdx;
  6087. CeStaticFieldInfo* staticFieldInfo = NULL;
  6088. if (mStaticFieldIdMap.TryAdd(fieldId, NULL, &staticFieldInfo))
  6089. {
  6090. if (mStaticCtorExecSet.TryAdd(typeId, NULL))
  6091. {
  6092. BfTypeInstance* bfTypeInstance = NULL;
  6093. if (bfType != NULL)
  6094. bfTypeInstance = bfType->ToTypeInstance();
  6095. if (bfTypeInstance == NULL)
  6096. {
  6097. _Fail("Invalid type");
  6098. return false;
  6099. }
  6100. auto methodDef = bfTypeInstance->mTypeDef->GetMethodByName("__BfStaticCtor");
  6101. if (methodDef == NULL)
  6102. {
  6103. _Fail("No static ctor found");
  6104. return false;
  6105. }
  6106. auto moduleMethodInstance = ceModule->GetMethodInstance(bfTypeInstance, methodDef, BfTypeVector());
  6107. if (!moduleMethodInstance)
  6108. {
  6109. _Fail("No static ctor instance found");
  6110. return false;
  6111. }
  6112. bool added = false;
  6113. ctorCallFunction = mCeMachine->GetFunction(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, added);
  6114. if (ctorCallFunction->mInitializeState < CeFunction::InitializeState_Initialized)
  6115. mCeMachine->PrepareFunction(ctorCallFunction, NULL);
  6116. }
  6117. _FixVariables();
  6118. StringT<4096> staticVarName;
  6119. BfMangler::Mangle(staticVarName, ceModule->mCompiler->GetMangleKind(), &fieldInstance);
  6120. CeStaticFieldInfo* nameStaticFieldInfo = NULL;
  6121. mStaticFieldMap.TryAdd(staticVarName, NULL, &nameStaticFieldInfo);
  6122. if (nameStaticFieldInfo->mAddr == 0)
  6123. {
  6124. int fieldSize = fieldInstance.mResolvedType->mSize;
  6125. CE_CHECKALLOC(fieldSize);
  6126. uint8* ptr = CeMalloc(fieldSize);
  6127. _FixVariables();
  6128. if (fieldSize > 0)
  6129. memset(ptr, 0, fieldSize);
  6130. nameStaticFieldInfo->mAddr = (addr_ce)(ptr - memStart);
  6131. }
  6132. staticFieldInfo->mAddr = nameStaticFieldInfo->mAddr;
  6133. }
  6134. CeSetAddrVal(stackPtr + 0, staticFieldInfo->mAddr, ptrSize);
  6135. }
  6136. else if (fieldIdx != -1)
  6137. {
  6138. _Fail("Invalid field");
  6139. return false;
  6140. }
  6141. }
  6142. }
  6143. if (ctorCallFunction != NULL)
  6144. {
  6145. bool handled = false;
  6146. if (!_CheckFunction(ctorCallFunction, handled))
  6147. return false;
  6148. if (!handled)
  6149. CE_CALL(ctorCallFunction);
  6150. }
  6151. }
  6152. else if (checkFunction->mFunctionKind == CeFunctionKind_SetReturnType)
  6153. {
  6154. int32 typeId = *(int32*)((uint8*)stackPtr);
  6155. if (returnType->IsVar())
  6156. castReturnType = GetBfType(typeId);
  6157. else
  6158. _Fail("Comptime return types can only be set on methods declared with a 'var' return type");
  6159. }
  6160. else if (checkFunction->mFunctionKind == CeFunctionKind_Align)
  6161. {
  6162. int32 typeId = *(int32*)((uint8*)stackPtr);
  6163. int32 align = *(int32*)((uint8*)stackPtr + sizeof(int32));
  6164. if ((mCurEmitContext == NULL) || (mCurEmitContext->mType == NULL) || (mCurEmitContext->mType->mTypeId != typeId))
  6165. {
  6166. _Fail("This type cannot be modified in this context");
  6167. return false;
  6168. }
  6169. mCurEmitContext->mAlign = BF_MAX(mCurEmitContext->mAlign, align);
  6170. }
  6171. else if (checkFunction->mFunctionKind == CeFunctionKind_EmitTypeBody)
  6172. {
  6173. int32 typeId = *(int32*)((uint8*)stackPtr);
  6174. addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr + sizeof(int32));
  6175. if ((mCurEmitContext == NULL) || (mCurEmitContext->mType == NULL) || (mCurEmitContext->mType->mTypeId != typeId))
  6176. {
  6177. _Fail("Code cannot be emitted for this type in this context");
  6178. return false;
  6179. }
  6180. if (!GetStringFromStringView(strViewPtr, mCurEmitContext->mEmitData))
  6181. {
  6182. _Fail("Invalid StringView");
  6183. return false;
  6184. }
  6185. }
  6186. else if (checkFunction->mFunctionKind == CeFunctionKind_EmitAddInterface)
  6187. {
  6188. int32 typeId = *(int32*)((uint8*)stackPtr);
  6189. int32 ifaceTypeId = *(int32*)((uint8*)stackPtr + sizeof(int32));
  6190. if ((mCurEmitContext == NULL) || (mCurEmitContext->mType->mTypeId != typeId))
  6191. {
  6192. _Fail("Code cannot be emitted for this type in this context");
  6193. return false;
  6194. }
  6195. mCurEmitContext->mInterfaces.Add(ifaceTypeId);
  6196. }
  6197. else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMethodEntry)
  6198. {
  6199. int64 methodHandle = *(int64*)((uint8*)stackPtr);
  6200. addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr + sizeof(int64));
  6201. if ((mCurEmitContext == NULL) || (mCurEmitContext->mMethodInstance == NULL) ||
  6202. (methodHandle != (int64)mCurEmitContext->mMethodInstance))
  6203. {
  6204. _Fail("Code cannot be emitted for this method in this context");
  6205. return false;
  6206. }
  6207. if (!GetStringFromStringView(strViewPtr, mCurEmitContext->mEmitData))
  6208. {
  6209. _Fail("Invalid StringView");
  6210. return false;
  6211. }
  6212. }
  6213. else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMethodExit)
  6214. {
  6215. int64 methodHandle = *(int64*)((uint8*)stackPtr);
  6216. addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr + sizeof(int64));
  6217. if ((mCurEmitContext == NULL) || (mCurEmitContext->mMethodInstance == NULL) ||
  6218. (methodHandle != (int64)mCurEmitContext->mMethodInstance))
  6219. {
  6220. _Fail("Code cannot be emitted for this method in this context");
  6221. return false;
  6222. }
  6223. if (!GetStringFromStringView(strViewPtr, mCurEmitContext->mExitEmitData))
  6224. {
  6225. _Fail("Invalid StringView");
  6226. return false;
  6227. }
  6228. }
  6229. else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMixin)
  6230. {
  6231. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurModule->mCurMethodInstance, mCallerMethodInstance);
  6232. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurModule->mCurTypeInstance, mCallerTypeInstance);
  6233. SetAndRestoreValue<bool> emitIgnoreWrites(ceModule->mBfIRBuilder->mIgnoreWrites, ignoreWrites.mPrevVal);
  6234. addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr);
  6235. String emitStr;
  6236. if (!GetStringFromStringView(strViewPtr, emitStr))
  6237. {
  6238. _Fail("Invalid StringView");
  6239. return false;
  6240. }
  6241. mCurModule->CEMixin(mCurCallSource->mRefNode, emitStr);
  6242. }
  6243. else if (checkFunction->mFunctionKind == CeFunctionKind_GetStringById)
  6244. {
  6245. int32 stringId = *(int32*)((uint8*)stackPtr + ptrSize);
  6246. String string = "";
  6247. BfStringPoolEntry* valuePtr = NULL;
  6248. mCurModule->mContext->mStringObjectIdMap.TryGetValue(stringId, &valuePtr);
  6249. if (valuePtr != NULL)
  6250. string = valuePtr->mString;
  6251. CeSetAddrVal(stackPtr + 0, GetString(string), ptrSize);
  6252. _FixVariables();
  6253. }
  6254. else if (checkFunction->mFunctionKind == CeFunctionKind_Sleep)
  6255. {
  6256. int32 sleepMS = *(int32*)((uint8*)stackPtr);
  6257. while (sleepMS > 0)
  6258. {
  6259. if (_CheckFastFinish())
  6260. break;
  6261. if (sleepMS > 20)
  6262. {
  6263. BfpThread_Sleep(20);
  6264. sleepMS -= 20;
  6265. continue;
  6266. }
  6267. BfpThread_Sleep(sleepMS);
  6268. break;
  6269. }
  6270. }
  6271. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSystem_GetTimeStamp)
  6272. {
  6273. int64& result = *(int64*)((uint8*)stackPtr + 0);
  6274. result = BfpSystem_GetTimeStamp();
  6275. }
  6276. else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_ToLower)
  6277. {
  6278. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6279. int32 val = *(int32*)((uint8*)stackPtr + 4);
  6280. result = utf8proc_tolower(val);
  6281. }
  6282. else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_ToUpper)
  6283. {
  6284. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6285. int32 val = *(int32*)((uint8*)stackPtr + 4);
  6286. result = utf8proc_toupper(val);
  6287. }
  6288. else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLower)
  6289. {
  6290. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6291. int32 val = *(int32*)((uint8*)stackPtr + 1);
  6292. result = utf8proc_category(val) == UTF8PROC_CATEGORY_LL;
  6293. }
  6294. else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsUpper)
  6295. {
  6296. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6297. int32 val = *(int32*)((uint8*)stackPtr + 1);
  6298. result = utf8proc_category(val) == UTF8PROC_CATEGORY_LU;
  6299. }
  6300. else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsWhiteSpace_EX)
  6301. {
  6302. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6303. int32 val = *(int32*)((uint8*)stackPtr + 1);
  6304. auto cat = utf8proc_category(val);
  6305. result = (cat == UTF8PROC_CATEGORY_ZS) || (cat == UTF8PROC_CATEGORY_ZL) || (cat == UTF8PROC_CATEGORY_ZP);
  6306. }
  6307. else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLetterOrDigit)
  6308. {
  6309. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6310. int32 val = *(int32*)((uint8*)stackPtr + 1);
  6311. auto cat = utf8proc_category(val);
  6312. switch (cat)
  6313. {
  6314. case UTF8PROC_CATEGORY_LU:
  6315. case UTF8PROC_CATEGORY_LL:
  6316. case UTF8PROC_CATEGORY_LT:
  6317. case UTF8PROC_CATEGORY_LM:
  6318. case UTF8PROC_CATEGORY_LO:
  6319. case UTF8PROC_CATEGORY_ND:
  6320. case UTF8PROC_CATEGORY_NL:
  6321. case UTF8PROC_CATEGORY_NO:
  6322. result = true;
  6323. break;
  6324. default:
  6325. result = false;
  6326. }
  6327. }
  6328. else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLetter)
  6329. {
  6330. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6331. int32 val = *(int32*)((uint8*)stackPtr + 1);
  6332. auto cat = utf8proc_category(val);
  6333. switch (cat)
  6334. {
  6335. case UTF8PROC_CATEGORY_LU:
  6336. case UTF8PROC_CATEGORY_LL:
  6337. case UTF8PROC_CATEGORY_LT:
  6338. case UTF8PROC_CATEGORY_LM:
  6339. case UTF8PROC_CATEGORY_LO:
  6340. result = true;
  6341. break;
  6342. default:
  6343. result = false;
  6344. }
  6345. }
  6346. else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsNumber)
  6347. {
  6348. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6349. int32 val = *(int32*)((uint8*)stackPtr + 1);
  6350. auto cat = utf8proc_category(val);
  6351. switch (cat)
  6352. {
  6353. case UTF8PROC_CATEGORY_ND:
  6354. case UTF8PROC_CATEGORY_NL:
  6355. case UTF8PROC_CATEGORY_NO:
  6356. result = true;
  6357. break;
  6358. default:
  6359. result = false;
  6360. }
  6361. }
  6362. else if (checkFunction->mFunctionKind == CeFunctionKind_Double_Strtod)
  6363. {
  6364. double& result = *(double*)((uint8*)stackPtr + 0);
  6365. addr_ce strAddr = *(addr_ce*)((uint8*)stackPtr + 8);
  6366. addr_ce endAddr = *(addr_ce*)((uint8*)stackPtr + 8 + ptrSize);
  6367. addr_ce checkAddr = strAddr;
  6368. while (true)
  6369. {
  6370. if ((uintptr)checkAddr >= (uintptr)memSize)
  6371. {
  6372. checkAddr++;
  6373. break;
  6374. }
  6375. if (memStart[checkAddr] == 0)
  6376. break;
  6377. checkAddr++;
  6378. }
  6379. CE_CHECKADDR(strAddr, checkAddr - strAddr + 1);
  6380. char* strPtr = (char*)(memStart + strAddr);
  6381. char** endPtr = NULL;
  6382. if (endAddr != 0)
  6383. endPtr = (char**)(memStart + endAddr);
  6384. result = strtod(strPtr, endPtr);
  6385. if (endAddr != 0)
  6386. {
  6387. CE_CHECKADDR(endAddr, ptrSize);
  6388. CeSetAddrVal(endPtr, (uint8*)endPtr - memStart, ptrSize);
  6389. }
  6390. }
  6391. else if (checkFunction->mFunctionKind == CeFunctionKind_Double_Ftoa)
  6392. {
  6393. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6394. float val = *(float*)((uint8*)stackPtr + 4);
  6395. addr_ce strAddr = *(addr_ce*)((uint8*)stackPtr + 4 + 4);
  6396. char str[256];
  6397. int count = sprintf(str, "%1.9f", val);
  6398. CE_CHECKADDR(strAddr, count + 1);
  6399. memcpy(memStart + strAddr, str, count + 1);
  6400. result = count;
  6401. }
  6402. else if (checkFunction->mFunctionKind == CeFunctionKind_Double_ToString)
  6403. {
  6404. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6405. double val = *(double*)((uint8*)stackPtr + 4);
  6406. addr_ce strAddr = *(addr_ce*)((uint8*)stackPtr + 4 + 8);
  6407. char str[256];
  6408. int count = DoubleToString(val, str);
  6409. CE_CHECKADDR(strAddr, count + 1);
  6410. memcpy(memStart + strAddr, str, count + 1);
  6411. result = count;
  6412. }
  6413. else if (checkFunction->mFunctionKind == CeFunctionKind_Float_ToString)
  6414. {
  6415. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6416. float val = *(float*)((uint8*)stackPtr + 4);
  6417. addr_ce strAddr = *(addr_ce*)((uint8*)stackPtr + 4 + 4);
  6418. char str[256];
  6419. int count = FloatToString(val, str);
  6420. CE_CHECKADDR(strAddr, count + 1);
  6421. memcpy(memStart + strAddr, str, count + 1);
  6422. result = count;
  6423. }
  6424. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_Create)
  6425. {
  6426. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6427. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6428. if (outResultAddr != 0)
  6429. CE_CHECKADDR(outResultAddr, 4);
  6430. String path;
  6431. CE_CHECKADDR_STR(path, nameAddr);
  6432. FixRelativePath(path);
  6433. BfpDirectory_Create(path.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6434. }
  6435. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_Rename)
  6436. {
  6437. addr_ce srcAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6438. addr_ce destAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6439. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6440. if (outResultAddr != 0)
  6441. CE_CHECKADDR(outResultAddr, 4);
  6442. String srcPath;
  6443. CE_CHECKADDR_STR(srcPath, srcAddr);
  6444. String destPath;
  6445. CE_CHECKADDR_STR(destPath, destAddr);
  6446. FixRelativePath(srcPath);
  6447. FixRelativePath(destPath);
  6448. BfpDirectory_Rename(srcPath.c_str(), destPath.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6449. }
  6450. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_Delete)
  6451. {
  6452. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6453. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6454. if (outResultAddr != 0)
  6455. CE_CHECKADDR(outResultAddr, 4);
  6456. String path;
  6457. CE_CHECKADDR_STR(path, nameAddr);
  6458. FixRelativePath(path);
  6459. BfpDirectory_Delete(path.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6460. }
  6461. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_GetCurrent)
  6462. {
  6463. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6464. addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6465. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6466. CE_CHECKADDR(sizeAddr, 4);
  6467. int& nameSize = *(int*)(memStart + sizeAddr);
  6468. CE_CHECKADDR(nameAddr, nameSize);
  6469. char* namePtr = (char*)(memStart + nameAddr);
  6470. if (outResultAddr != 0)
  6471. CE_CHECKADDR(outResultAddr, 4);
  6472. CalcWorkingDir();
  6473. TryStringOut(mWorkingDir, namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpResult*)(memStart + outResultAddr));
  6474. }
  6475. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_SetCurrent)
  6476. {
  6477. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6478. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6479. if (outResultAddr != 0)
  6480. CE_CHECKADDR(outResultAddr, 4);
  6481. String path;
  6482. CE_CHECKADDR_STR(path, nameAddr);
  6483. FixRelativePath(path);
  6484. if (::BfpDirectory_Exists(path.c_str()))
  6485. {
  6486. mWorkingDir = path;
  6487. if (outResultAddr != 0)
  6488. *(BfpFileResult*)(memStart + outResultAddr) = BfpFileResult_Ok;
  6489. }
  6490. else
  6491. {
  6492. if (outResultAddr != 0)
  6493. *(BfpFileResult*)(memStart + outResultAddr) = BfpFileResult_NotFound;
  6494. }
  6495. }
  6496. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_Exists)
  6497. {
  6498. bool& result = *(bool*)((uint8*)stackPtr + 0);
  6499. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 1);
  6500. String path;
  6501. CE_CHECKADDR_STR(path, nameAddr);
  6502. FixRelativePath(path);
  6503. result = BfpDirectory_Exists(path.c_str());
  6504. }
  6505. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_GetSysDirectory)
  6506. {
  6507. BfpSysDirectoryKind sysDirKind = *(BfpSysDirectoryKind*)((uint8*)stackPtr + 0);
  6508. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 4);
  6509. addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + 4 + ptrSize);
  6510. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + 4 + ptrSize + ptrSize);
  6511. CE_CHECKADDR(sizeAddr, 4);
  6512. int& nameSize = *(int*)(memStart + sizeAddr);
  6513. CE_CHECKADDR(nameAddr, nameSize);
  6514. char* namePtr = (char*)(memStart + nameAddr);
  6515. if (outResultAddr != 0)
  6516. CE_CHECKADDR(outResultAddr, 4);
  6517. BfpDirectory_GetSysDirectory(sysDirKind, namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6518. }
  6519. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Close)
  6520. {
  6521. addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0);
  6522. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6523. CE_CHECKADDR(outResultAddr, 4);
  6524. CeInternalData* internalData = NULL;
  6525. CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
  6526. BfpFile_Close(internalData->mFile, (BfpFileResult*)(memStart + outResultAddr));
  6527. }
  6528. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Create)
  6529. {
  6530. void* resultPtr = ((uint8*)stackPtr + 0);
  6531. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6532. int createKind = *(int*)((uint8*)stackPtr + ptrSize + ptrSize);
  6533. int createFlags = *(int*)((uint8*)stackPtr + ptrSize + ptrSize + 4);
  6534. int createFileAttrs = *(int*)((uint8*)stackPtr + ptrSize + ptrSize + 4 + 4);
  6535. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + 4 + 4 + 4);
  6536. String path;
  6537. CE_CHECKADDR_STR(path, nameAddr);
  6538. CE_CHECKADDR(outResultAddr, 4);
  6539. FixRelativePath(path);
  6540. auto bfpFile = BfpFile_Create(path.c_str(), (BfpFileCreateKind)createKind, (BfpFileCreateFlags)createFlags, (BfpFileAttributes)createFileAttrs, (BfpFileResult*)(memStart + outResultAddr));
  6541. if (bfpFile != NULL)
  6542. {
  6543. if ((createKind == BfpFileCreateKind_OpenExisting) || (createKind == BfpFileCreateKind_OpenAlways))
  6544. AddFileRebuild(path);
  6545. CeInternalData* internalData = new CeInternalData();
  6546. internalData->mKind = CeInternalData::Kind_File;
  6547. internalData->mFile = bfpFile;
  6548. mInternalDataMap[++mCurHandleId] = internalData;
  6549. CeSetAddrVal(resultPtr, mCurHandleId, ptrSize);
  6550. }
  6551. else
  6552. CeSetAddrVal(resultPtr, 0, ptrSize);
  6553. }
  6554. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Flush)
  6555. {
  6556. addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0);
  6557. CeInternalData* internalData = NULL;
  6558. CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
  6559. BfpFile_Flush(internalData->mFile);
  6560. }
  6561. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetFileSize)
  6562. {
  6563. int64& result = *(int64*)((uint8*)stackPtr + 0);
  6564. addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 8);
  6565. CeInternalData* internalData = NULL;
  6566. CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
  6567. result = BfpFile_GetFileSize(internalData->mFile);
  6568. }
  6569. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Read)
  6570. {
  6571. void* resultPtr = ((uint8*)stackPtr + 0);
  6572. addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6573. addr_ce bufferPtr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6574. intptr bufferSize = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
  6575. int timeoutMS = *(int32*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize);
  6576. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize);
  6577. CE_CHECKADDR(bufferPtr, bufferSize);
  6578. CE_CHECKADDR(outResultAddr, 4);
  6579. BfpFileResult fileResult = BfpFileResult_UnknownError;
  6580. CeInternalData* internalData = NULL;
  6581. CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
  6582. int timeoutLeft = timeoutMS;
  6583. int64 result = 0;
  6584. CeAsyncOperation* asyncOperation = NULL;
  6585. BfpThread* asyncThread = NULL;
  6586. while (true)
  6587. {
  6588. if (*cancelingPtr)
  6589. break;
  6590. int useTimeout = timeoutLeft;
  6591. if (useTimeout < 0)
  6592. {
  6593. useTimeout = 20;
  6594. }
  6595. else if (useTimeout > 20)
  6596. {
  6597. useTimeout = 20;
  6598. timeoutLeft -= useTimeout;
  6599. }
  6600. else
  6601. timeoutLeft = 0;
  6602. if (asyncOperation != NULL)
  6603. {
  6604. if (BfpThread_WaitFor(asyncThread, useTimeout))
  6605. {
  6606. if (asyncOperation->mReadSize > 0)
  6607. memcpy(memStart + bufferPtr, asyncOperation->mData, asyncOperation->mReadSize);
  6608. result = asyncOperation->mReadSize;
  6609. fileResult = asyncOperation->mResult;
  6610. break;
  6611. }
  6612. continue;
  6613. }
  6614. result = BfpFile_Read(internalData->mFile, memStart + bufferPtr, bufferSize, useTimeout, &fileResult);
  6615. if (fileResult == BfpFileResult_Timeout)
  6616. {
  6617. if (timeoutLeft > 0)
  6618. continue;
  6619. }
  6620. if (fileResult != BfpFileResult_InvalidParameter)
  6621. break;
  6622. BF_ASSERT(asyncOperation == NULL);
  6623. asyncOperation = new CeAsyncOperation();
  6624. asyncOperation->mInternalData = internalData;
  6625. asyncOperation->mInternalData->AddRef();
  6626. asyncOperation->mData = new uint8[bufferSize];
  6627. asyncOperation->mDataSize = bufferSize;
  6628. asyncOperation->AddRef();
  6629. asyncThread = BfpThread_Create(CeAsyncOperation::RunProc, asyncOperation);
  6630. }
  6631. if (asyncOperation != NULL)
  6632. asyncOperation->Release();
  6633. if (asyncThread != NULL)
  6634. BfpThread_Release(asyncThread);
  6635. if (outResultAddr != 0)
  6636. *(BfpFileResult*)(memStart + outResultAddr) = fileResult;
  6637. CeSetAddrVal(resultPtr, result, ptrSize);
  6638. }
  6639. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Release)
  6640. {
  6641. addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0);
  6642. CeInternalData* internalData = NULL;
  6643. CE_REMOVE_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
  6644. internalData->Release();
  6645. }
  6646. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Seek)
  6647. {
  6648. int64& result = *(int64*)((uint8*)stackPtr + 0);
  6649. addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 8);
  6650. int64 offset = *(int64*)((uint8*)stackPtr + 8 + ptrSize);
  6651. int seekKind = *(int*)((uint8*)stackPtr + 8 + ptrSize + 8);
  6652. CeInternalData* internalData = NULL;
  6653. CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
  6654. result = BfpFile_Seek(internalData->mFile, offset, (BfpFileSeekKind)seekKind);
  6655. }
  6656. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Truncate)
  6657. {
  6658. addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0);
  6659. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6660. CE_CHECKADDR(outResultAddr, 4);
  6661. CeInternalData* internalData = NULL;
  6662. CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
  6663. BfpFile_Truncate(internalData->mFile, (BfpFileResult*)(memStart + outResultAddr));
  6664. }
  6665. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Write)
  6666. {
  6667. void* resultPtr = ((uint8*)stackPtr + 0);
  6668. addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6669. addr_ce bufferPtr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6670. intptr bufferSize = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
  6671. int timeoutMS = *(int32*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize);
  6672. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize);
  6673. CE_CHECKADDR(bufferPtr, bufferSize);
  6674. CE_CHECKADDR(outResultAddr, 4);
  6675. CeInternalData* internalData = NULL;
  6676. CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
  6677. int64 result = BfpFile_Write(internalData->mFile, memStart + bufferPtr, bufferSize, timeoutMS, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6678. CeSetAddrVal(resultPtr, result, ptrSize);
  6679. }
  6680. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetTime_LastWrite)
  6681. {
  6682. BfpTimeStamp& result = *(BfpTimeStamp*)((uint8*)stackPtr + 0);
  6683. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 8);
  6684. String path;
  6685. CE_CHECKADDR_STR(path, nameAddr);
  6686. FixRelativePath(path);
  6687. AddFileRebuild(path);
  6688. result = BfpFile_GetTime_LastWrite(path.c_str());
  6689. }
  6690. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetAttributes)
  6691. {
  6692. BfpFileAttributes& result = *(BfpFileAttributes*)((uint8*)stackPtr + 0);
  6693. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 4);
  6694. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + 4);
  6695. if (outResultAddr != 0)
  6696. CE_CHECKADDR(outResultAddr, 4);
  6697. String path;
  6698. CE_CHECKADDR_STR(path, nameAddr);
  6699. FixRelativePath(path);
  6700. result = BfpFile_GetAttributes(path.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6701. }
  6702. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_SetAttributes)
  6703. {
  6704. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6705. BfpFileAttributes attribs = *(BfpFileAttributes*)((uint8*)stackPtr + ptrSize);
  6706. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6707. if (outResultAddr != 0)
  6708. CE_CHECKADDR(outResultAddr, 4);
  6709. String path;
  6710. CE_CHECKADDR_STR(path, nameAddr);
  6711. FixRelativePath(path);
  6712. BfpFile_SetAttributes(path.c_str(), attribs, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6713. }
  6714. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Copy)
  6715. {
  6716. addr_ce srcAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6717. addr_ce destAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6718. BfpFileCopyKind fileCopyKind = *(BfpFileCopyKind*)((uint8*)stackPtr + ptrSize + ptrSize);
  6719. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + 4);
  6720. if (outResultAddr != 0)
  6721. CE_CHECKADDR(outResultAddr, 4);
  6722. String srcPath;
  6723. CE_CHECKADDR_STR(srcPath, srcAddr);
  6724. String destPath;
  6725. CE_CHECKADDR_STR(destPath, destAddr);
  6726. FixRelativePath(srcPath);
  6727. FixRelativePath(destPath);
  6728. BfpFile_Copy(srcPath.c_str(), destPath.c_str(), fileCopyKind, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6729. }
  6730. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Rename)
  6731. {
  6732. addr_ce srcAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6733. addr_ce destAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6734. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6735. if (outResultAddr != 0)
  6736. CE_CHECKADDR(outResultAddr, 4);
  6737. String srcPath;
  6738. CE_CHECKADDR_STR(srcPath, srcAddr);
  6739. String destPath;
  6740. CE_CHECKADDR_STR(destPath, destAddr);
  6741. FixRelativePath(srcPath);
  6742. FixRelativePath(destPath);
  6743. BfpFile_Rename(srcPath.c_str(), destPath.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6744. }
  6745. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Delete)
  6746. {
  6747. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6748. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6749. if (outResultAddr != 0)
  6750. CE_CHECKADDR(outResultAddr, 4);
  6751. String path;
  6752. CE_CHECKADDR_STR(path, nameAddr);
  6753. FixRelativePath(path);
  6754. BfpFile_Delete(path.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6755. }
  6756. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Exists)
  6757. {
  6758. bool& result = *(bool*)((uint8*)stackPtr + 0);
  6759. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 1);
  6760. String path;
  6761. CE_CHECKADDR_STR(path, nameAddr);
  6762. FixRelativePath(path);
  6763. AddFileRebuild(path);
  6764. result = BfpFile_Exists(path.c_str());
  6765. }
  6766. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetTempPath)
  6767. {
  6768. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6769. addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6770. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6771. CE_CHECKADDR(sizeAddr, 4);
  6772. int& nameSize = *(int*)(memStart + sizeAddr);
  6773. CE_CHECKADDR(nameAddr, nameSize);
  6774. char* namePtr = (char*)(memStart + nameAddr);
  6775. if (outResultAddr != 0)
  6776. CE_CHECKADDR(outResultAddr, 4);
  6777. BfpFile_GetTempPath(namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6778. }
  6779. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetTempFileName)
  6780. {
  6781. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6782. addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6783. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6784. CE_CHECKADDR(sizeAddr, 4);
  6785. int& nameSize = *(int*)(memStart + sizeAddr);
  6786. CE_CHECKADDR(nameAddr, nameSize);
  6787. char* namePtr = (char*)(memStart + nameAddr);
  6788. if (outResultAddr != 0)
  6789. CE_CHECKADDR(outResultAddr, 4);
  6790. BfpFile_GetTempFileName(namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6791. }
  6792. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetFullPath)
  6793. {
  6794. addr_ce srcAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6795. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6796. addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6797. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
  6798. String srcPath;
  6799. CE_CHECKADDR_STR(srcPath, srcAddr);
  6800. CE_CHECKADDR(sizeAddr, 4);
  6801. int& nameSize = *(int*)(memStart + sizeAddr);
  6802. CE_CHECKADDR(nameAddr, nameSize);
  6803. char* namePtr = (char*)(memStart + nameAddr);
  6804. if (outResultAddr != 0)
  6805. CE_CHECKADDR(outResultAddr, 4);
  6806. FixRelativePath(srcPath);
  6807. BfpFile_GetFullPath(srcPath.c_str(), namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6808. }
  6809. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetActualPath)
  6810. {
  6811. addr_ce srcAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6812. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6813. addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6814. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
  6815. String srcPath;
  6816. CE_CHECKADDR_STR(srcPath, srcAddr);
  6817. CE_CHECKADDR(sizeAddr, 4);
  6818. int& nameSize = *(int*)(memStart + sizeAddr);
  6819. CE_CHECKADDR(nameAddr, nameSize);
  6820. char* namePtr = (char*)(memStart + nameAddr);
  6821. if (outResultAddr != 0)
  6822. CE_CHECKADDR(outResultAddr, 4);
  6823. FixRelativePath(srcPath);
  6824. BfpFile_GetActualPath(srcPath.c_str(), namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6825. }
  6826. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_Create)
  6827. {
  6828. void* resultPtr = ((uint8*)stackPtr + 0);
  6829. addr_ce targetPathAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6830. addr_ce argsAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6831. addr_ce workingDirAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
  6832. addr_ce envAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize);
  6833. int flags = *(int*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize);
  6834. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize + 4);
  6835. String targetPath;
  6836. CE_CHECKADDR_STR(targetPath, targetPathAddr);
  6837. String args;
  6838. if (argsAddr != 0)
  6839. CE_CHECKADDR_STR(args, argsAddr);
  6840. String workingDir;
  6841. if (workingDirAddr != 0)
  6842. CE_CHECKADDR_STR(workingDir, workingDirAddr);
  6843. String env;
  6844. if (envAddr != 0)
  6845. CE_CHECKADDR_STR(env, envAddr);
  6846. if (outResultAddr != 0)
  6847. CE_CHECKADDR(outResultAddr, 4);
  6848. if ((targetPath.Contains('/')) || (targetPath.Contains('\\')))
  6849. {
  6850. FixRelativePath(targetPath);
  6851. }
  6852. auto bfpSpawn = BfpSpawn_Create(targetPath.c_str(),
  6853. (argsAddr == 0) ? NULL : args.c_str(),
  6854. (workingDirAddr == 0) ? NULL : workingDir.c_str(),
  6855. (envAddr == 0) ? NULL : env.c_str(), (BfpSpawnFlags)flags, (outResultAddr == 0) ? NULL : (BfpSpawnResult*)(memStart + outResultAddr));
  6856. if (bfpSpawn != NULL)
  6857. {
  6858. CeInternalData* internalData = new CeInternalData();
  6859. internalData->mKind = CeInternalData::Kind_Spawn;
  6860. internalData->mSpawn = bfpSpawn;
  6861. mInternalDataMap[++mCurHandleId] = internalData;
  6862. CeSetAddrVal(resultPtr, mCurHandleId, ptrSize);
  6863. }
  6864. else
  6865. CeSetAddrVal(resultPtr, 0, ptrSize);
  6866. }
  6867. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_GetStdHandles)
  6868. {
  6869. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 0);
  6870. addr_ce outStdInAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6871. addr_ce outStdOutAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6872. addr_ce outStdErrAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
  6873. if (outStdInAddr != 0)
  6874. CE_CHECKADDR(outStdInAddr, ptrSize);
  6875. if (outStdOutAddr != 0)
  6876. CE_CHECKADDR(outStdOutAddr, ptrSize);
  6877. if (outStdErrAddr != 0)
  6878. CE_CHECKADDR(outStdErrAddr, ptrSize);
  6879. BfpFile* outStdIn = NULL;
  6880. BfpFile* outStdOut = NULL;
  6881. BfpFile* outStdErr = NULL;
  6882. CeInternalData* internalData = NULL;
  6883. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn);
  6884. BfpSpawn_GetStdHandles(internalData->mSpawn,
  6885. (outStdInAddr != 0) ? &outStdIn : NULL,
  6886. (outStdOutAddr != 0) ? &outStdOut : NULL,
  6887. (outStdErrAddr != 0) ? &outStdErr : NULL);
  6888. auto _SetHandle = [&](addr_ce addr, BfpFile* file)
  6889. {
  6890. if (addr == 0)
  6891. return;
  6892. if (file != NULL)
  6893. {
  6894. CeInternalData* internalData = new CeInternalData();
  6895. internalData->mKind = CeInternalData::Kind_File;
  6896. internalData->mFile = file;
  6897. mInternalDataMap[++mCurHandleId] = internalData;
  6898. CeSetAddrVal(memStart + addr, mCurHandleId, ptrSize);
  6899. }
  6900. };
  6901. if (outStdInAddr != 0)
  6902. _SetHandle(outStdInAddr, outStdIn);
  6903. if (outStdOutAddr != 0)
  6904. _SetHandle(outStdOutAddr, outStdOut);
  6905. if (outStdErrAddr != 0)
  6906. _SetHandle(outStdErrAddr, outStdErr);
  6907. }
  6908. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_Kill)
  6909. {
  6910. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 0);
  6911. int exitCode = *(int*)((uint8*)stackPtr + ptrSize);
  6912. int killFlags = *(int*)((uint8*)stackPtr + ptrSize + ptrSize);
  6913. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
  6914. CE_CHECKADDR(outResultAddr, 4);
  6915. CeInternalData* internalData = NULL;
  6916. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn);
  6917. BfpSpawn_Kill(internalData->mSpawn, exitCode, (BfpKillFlags)killFlags, (BfpSpawnResult*)(memStart + outResultAddr));
  6918. }
  6919. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_Release)
  6920. {
  6921. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 0);
  6922. CeInternalData* internalData = NULL;
  6923. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn);
  6924. internalData->mReleased = true;
  6925. }
  6926. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_WaitFor)
  6927. {
  6928. bool& result = *(bool*)((uint8*)stackPtr + 0);
  6929. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 1);
  6930. int waitMS = *(int*)((uint8*)stackPtr + 1 + ptrSize);
  6931. addr_ce outExitCodeAddr = *(addr_ce*)((uint8*)stackPtr + 1 + ptrSize + ptrSize);
  6932. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + 1 + ptrSize + ptrSize + ptrSize);
  6933. CE_CHECKADDR(outExitCodeAddr, ptrSize);
  6934. if (outResultAddr != 0)
  6935. CE_CHECKADDR(outResultAddr, 4);
  6936. CeInternalData* internalData = NULL;
  6937. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn);
  6938. int outExitCode = 0;
  6939. int timeLeft = waitMS;
  6940. do
  6941. {
  6942. if (_CheckFastFinish())
  6943. {
  6944. result = false;
  6945. break;
  6946. }
  6947. int waitTime = 20;
  6948. if (timeLeft >= 0)
  6949. {
  6950. waitTime = BF_MIN(timeLeft, 20);
  6951. timeLeft -= waitTime;
  6952. }
  6953. result = BfpSpawn_WaitFor(internalData->mSpawn, waitTime, &outExitCode, (outResultAddr == 0) ? NULL : (BfpSpawnResult*)(memStart + outResultAddr));
  6954. if (result)
  6955. break;
  6956. if (waitTime == 0)
  6957. break;
  6958. } while (true);
  6959. *(int*)(memStart + outExitCodeAddr) = outExitCode;
  6960. }
  6961. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_FindFirstFile)
  6962. {
  6963. void* resultPtr = ((uint8*)stackPtr + 0);
  6964. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6965. int flags = *(int*)((uint8*)stackPtr + ptrSize + ptrSize);
  6966. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + 4);
  6967. String path;
  6968. CE_CHECKADDR_STR(path, nameAddr);
  6969. if (outResultAddr != 0)
  6970. CE_CHECKADDR(outResultAddr, 4);
  6971. FixRelativePath(path);
  6972. auto bfpFindFileData = BfpFindFileData_FindFirstFile(path.c_str(), (BfpFindFileFlags)flags, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6973. if (bfpFindFileData != NULL)
  6974. {
  6975. String dir = GetFileDir(path);
  6976. dir = FixPathAndCase(dir);
  6977. dir.Append(DIR_SEP_CHAR);
  6978. CeRebuildKey rebuildKey;
  6979. rebuildKey.mKind = CeRebuildKey::Kind_Directory;
  6980. rebuildKey.mString = dir;
  6981. CeRebuildValue rebuildValue;
  6982. if (AddRebuild(rebuildKey, rebuildValue))
  6983. mCurModule->mCompiler->mRebuildFileSet.Add(dir);
  6984. CeInternalData* internalData = new CeInternalData();
  6985. internalData->mKind = CeInternalData::Kind_FindFileData;
  6986. internalData->mFindFileData = bfpFindFileData;
  6987. mInternalDataMap[++mCurHandleId] = internalData;
  6988. CeSetAddrVal(resultPtr, mCurHandleId, ptrSize);
  6989. }
  6990. else
  6991. CeSetAddrVal(resultPtr, 0, ptrSize);
  6992. }
  6993. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_FindNextFile)
  6994. {
  6995. bool& result = *(bool*)((uint8*)stackPtr + 0);
  6996. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 1);
  6997. CeInternalData* internalData = NULL;
  6998. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData);
  6999. result = BfpFindFileData_FindNextFile(internalData->mFindFileData);
  7000. }
  7001. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_GetFileName)
  7002. {
  7003. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 0);
  7004. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  7005. addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  7006. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
  7007. CeInternalData* internalData = NULL;
  7008. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData);
  7009. CE_CHECKADDR(sizeAddr, 4);
  7010. int& nameSize = *(int*)(memStart + sizeAddr);
  7011. CE_CHECKADDR(nameAddr, nameSize);
  7012. char* namePtr = (char*)(memStart + nameAddr);
  7013. if (outResultAddr != 0)
  7014. CE_CHECKADDR(outResultAddr, 4);
  7015. BfpFindFileData_GetFileName(internalData->mFindFileData, namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  7016. }
  7017. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_GetTime_LastWrite)
  7018. {
  7019. BfpTimeStamp& result = *(BfpTimeStamp*)((uint8*)stackPtr + 0);
  7020. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 8);
  7021. CeInternalData* internalData = NULL;
  7022. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData);
  7023. result = BfpFindFileData_GetTime_LastWrite(internalData->mFindFileData);
  7024. }
  7025. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_GetTime_Created)
  7026. {
  7027. BfpTimeStamp& result = *(BfpTimeStamp*)((uint8*)stackPtr + 0);
  7028. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 8);
  7029. CeInternalData* internalData = NULL;
  7030. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData);
  7031. result = BfpFindFileData_GetTime_Created(internalData->mFindFileData);
  7032. }
  7033. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_GetTime_Access)
  7034. {
  7035. BfpTimeStamp& result = *(BfpTimeStamp*)((uint8*)stackPtr + 0);
  7036. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 8);
  7037. CeInternalData* internalData = NULL;
  7038. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData);
  7039. result = BfpFindFileData_GetTime_Access(internalData->mFindFileData);
  7040. }
  7041. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_GetFileAttributes)
  7042. {
  7043. BfpFileAttributes& result = *(BfpFileAttributes*)((uint8*)stackPtr + 0);
  7044. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 4);
  7045. CeInternalData* internalData = NULL;
  7046. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData);
  7047. result = BfpFindFileData_GetFileAttributes(internalData->mFindFileData);
  7048. }
  7049. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_GetFileSize)
  7050. {
  7051. int64& result = *(int64*)((uint8*)stackPtr + 0);
  7052. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 8);
  7053. CeInternalData* internalData = NULL;
  7054. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData);
  7055. result = BfpFindFileData_GetFileSize(internalData->mFindFileData);
  7056. }
  7057. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_Release)
  7058. {
  7059. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 0);
  7060. CeInternalData* internalData = NULL;
  7061. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData);
  7062. internalData->mReleased = true;
  7063. }
  7064. else
  7065. {
  7066. Fail(_GetCurFrame(), StrFormat("Unable to invoke extern method '%s'", ceModule->MethodToString(checkFunction->mMethodInstance).c_str()));
  7067. return false;
  7068. }
  7069. handled = true;
  7070. return true;
  7071. }
  7072. if (!checkFunction->mFailed)
  7073. return true;
  7074. if ((mCeMachine->mDebugger != NULL) && (!mCallStack.IsEmpty()))
  7075. _Fail(StrFormat("Attempting to call failed method '%s'", ceModule->MethodToString(checkFunction->mMethodInstance).c_str()));
  7076. auto error = Fail(_GetCurFrame(), StrFormat("Method call preparation '%s' failed", ceModule->MethodToString(checkFunction->mMethodInstance).c_str()));
  7077. if ((error != NULL) && (!checkFunction->mGenError.IsEmpty()))
  7078. mCeMachine->mCompiler->mPassInstance->MoreInfo("Comptime method generation error: " + checkFunction->mGenError);
  7079. return false;
  7080. };
  7081. //
  7082. {
  7083. bool handled = false;
  7084. if (!_CheckFunction(ceFunction, handled))
  7085. return false;
  7086. if (handled)
  7087. return true;
  7088. }
  7089. int callCount = 0;
  7090. int instCount = 0;
  7091. CE_CHECKSTACK();
  7092. while (true)
  7093. {
  7094. ++instCount;
  7095. CeOp op = CE_GETINST(CeOp);
  7096. if (*specialCheckPtr)
  7097. {
  7098. SpecialCheck:
  7099. if (*fastFinishPtr)
  7100. {
  7101. BfTypeInstance* rebuildType = NULL;
  7102. if ((mCurModule != NULL) && (mCurModule->mCurTypeInstance != NULL))
  7103. rebuildType = mCurModule->mCurTypeInstance;
  7104. if ((mCurEmitContext != NULL) && (mCurEmitContext->mType != NULL))
  7105. rebuildType = mCurEmitContext->mType->ToTypeInstance();
  7106. if (rebuildType != NULL)
  7107. {
  7108. rebuildType->mRebuildFlags = (BfTypeRebuildFlags)(rebuildType->mRebuildFlags | BfTypeRebuildFlag_ConstEvalCancelled);
  7109. mCurModule->DeferRebuildType(rebuildType);
  7110. }
  7111. if (*cancelingPtr)
  7112. {
  7113. if ((mCurModule == NULL) || (mCurModule->mCurTypeInstance == NULL))
  7114. _Fail("Comptime evaluation canceled");
  7115. }
  7116. return false;
  7117. }
  7118. bool wantsStop = false;
  7119. if (mCeMachine->mStepState.mKind != CeStepState::Kind_None)
  7120. {
  7121. int curDepth = mCallStack.mSize + 1;
  7122. int instIdx = instPtr - ceFunction->mCode.mVals - 1;
  7123. switch (mCeMachine->mStepState.mKind)
  7124. {
  7125. case CeStepState::Kind_StepInfo:
  7126. if (curDepth != mCeMachine->mStepState.mStartDepth)
  7127. wantsStop = true;
  7128. else if (instIdx >= mCeMachine->mStepState.mNextInstIdx)
  7129. wantsStop = true;
  7130. break;
  7131. case CeStepState::Kind_StepInfo_Asm:
  7132. wantsStop = true;
  7133. break;
  7134. case CeStepState::Kind_StepOver:
  7135. if (curDepth < mCeMachine->mStepState.mStartDepth)
  7136. wantsStop = true;
  7137. else if ((mCeMachine->mStepState.mStartDepth == curDepth) && (instIdx >= mCeMachine->mStepState.mNextInstIdx))
  7138. wantsStop = true;
  7139. break;
  7140. case CeStepState::Kind_StepOver_Asm:
  7141. if (curDepth < mCeMachine->mStepState.mStartDepth)
  7142. wantsStop = true;
  7143. else if (curDepth == mCeMachine->mStepState.mStartDepth)
  7144. wantsStop = true;
  7145. break;
  7146. case CeStepState::Kind_StepOut:
  7147. if (curDepth < mCeMachine->mStepState.mStartDepth)
  7148. wantsStop = true;
  7149. else if ((curDepth == mCeMachine->mStepState.mStartDepth) && (instIdx >= mCeMachine->mStepState.mNextInstIdx))
  7150. wantsStop = true;
  7151. break;
  7152. case CeStepState::Kind_StepOut_Asm:
  7153. if (curDepth <= mCeMachine->mStepState.mStartDepth)
  7154. wantsStop = true;
  7155. break;
  7156. case CeStepState::Kind_Jmp:
  7157. instPtr = &ceFunction->mCode[mCeMachine->mStepState.mNextInstIdx];
  7158. op = CE_GETINST(CeOp);
  7159. wantsStop = true;
  7160. break;
  7161. }
  7162. }
  7163. else if (mCeMachine->mDbgWantBreak)
  7164. {
  7165. wantsStop = true;
  7166. }
  7167. else if ((mCeMachine->mDebugger != NULL) && (mCeMachine->mDebugger->mBreakpointFramesDirty))
  7168. {
  7169. AutoCrit autoCrit(mCeMachine->mCritSect);
  7170. mCallStack.Add(_GetCurFrame());
  7171. mCeMachine->mDebugger->UpdateBreakpointFrames();
  7172. mCallStack.pop_back();
  7173. }
  7174. else
  7175. *specialCheckPtr = false;
  7176. if (wantsStop)
  7177. {
  7178. mCeMachine->mDbgWantBreak = false;
  7179. mCeMachine->mStepState.mKind = CeStepState::Kind_None;
  7180. _DbgPause();
  7181. if (mCeMachine->mStepState.mKind == CeStepState::Kind_Jmp)
  7182. goto SpecialCheck;
  7183. // We may have changed breakpoints so we need to re-read
  7184. instPtr -= sizeof(CeOp);
  7185. op = CE_GETINST(CeOp);
  7186. }
  7187. }
  7188. OpSwitch:
  7189. switch (op)
  7190. {
  7191. case CeOp_Nop:
  7192. break;
  7193. case CeOp_DbgBreak:
  7194. {
  7195. bool foundBreakpoint = false;
  7196. bool skipInst = false;
  7197. if (mCeMachine->mDebugger != NULL)
  7198. {
  7199. AutoCrit autoCrit(mCeMachine->mCritSect);
  7200. int instIdx = instPtr - ceFunction->mCode.mVals - 2;
  7201. CeBreakpointBind* breakpointEntry = NULL;
  7202. if (ceFunction->mBreakpoints.TryGetValue(instIdx, &breakpointEntry))
  7203. {
  7204. bool doBreak = false;
  7205. mCallStack.Add(_GetCurFrame());
  7206. if (mCeMachine->mDebugger->CheckConditionalBreakpoint(breakpointEntry->mBreakpoint))
  7207. doBreak = true;
  7208. mCallStack.pop_back();
  7209. op = breakpointEntry->mPrevOpCode;
  7210. // Keep us from an infinite loop if we set a breakpoint on a manual Break
  7211. skipInst = op == CeOp_DbgBreak;
  7212. foundBreakpoint = true;
  7213. if (!doBreak)
  7214. {
  7215. _FixVariables();
  7216. if (skipInst)
  7217. break;
  7218. goto OpSwitch;
  7219. }
  7220. mCeMachine->mDebugger->mActiveBreakpoint = breakpointEntry->mBreakpoint;
  7221. }
  7222. }
  7223. _DbgPause();
  7224. if (mCeMachine->mStepState.mKind == CeStepState::Kind_Jmp)
  7225. goto SpecialCheck;
  7226. if (skipInst)
  7227. break;
  7228. if (foundBreakpoint)
  7229. goto OpSwitch;
  7230. }
  7231. break;
  7232. case CeOp_Ret:
  7233. {
  7234. if (mCallStack.mSize == 0)
  7235. return true;
  7236. auto& ceFrame = mCallStack.back();
  7237. ceFunction = ceFrame.mFunction;
  7238. instPtr = ceFrame.mInstPtr;
  7239. stackPtr = memStart + ceFrame.mStackAddr;
  7240. framePtr = memStart + ceFrame.mFrameAddr;
  7241. returnType = ceFrame.mReturnType;
  7242. mCallStack.pop_back();
  7243. }
  7244. break;
  7245. case CeOp_SetRetType:
  7246. {
  7247. int typeId = CE_GETINST(int32);
  7248. returnType = GetBfType(typeId);
  7249. BF_ASSERT(returnType != NULL);
  7250. }
  7251. break;
  7252. case CeOp_Jmp:
  7253. {
  7254. auto relOfs = CE_GETINST(int32);
  7255. instPtr += relOfs;
  7256. }
  7257. break;
  7258. case CeOp_JmpIf:
  7259. {
  7260. auto relOfs = CE_GETINST(int32);
  7261. bool cond = CE_GETFRAME(bool);
  7262. if (cond)
  7263. instPtr += relOfs - 4;
  7264. }
  7265. break;
  7266. case CeOp_JmpIfNot:
  7267. {
  7268. auto relOfs = CE_GETINST(int32);
  7269. bool cond = CE_GETFRAME(bool);
  7270. if (!cond)
  7271. instPtr += relOfs - 4;
  7272. }
  7273. break;
  7274. case CeOp_Error:
  7275. {
  7276. auto errorKind = (CeErrorKind)CE_GETINST(int32);
  7277. switch (errorKind)
  7278. {
  7279. case CeErrorKind_GlobalVariable:
  7280. _Fail("Global variable access not allowed");
  7281. break;
  7282. case CeErrorKind_FunctionPointer:
  7283. _Fail("Function pointer calls not allowed");
  7284. break;
  7285. case CeErrorKind_Intrinsic:
  7286. _Fail("Intrinsic not allowed");
  7287. break;
  7288. case CeErrorKind_ObjectDynCheckFailed:
  7289. _Fail("Dynamic cast check failed");
  7290. break;
  7291. default:
  7292. _Fail("Operation not allowed");
  7293. break;
  7294. }
  7295. }
  7296. break;
  7297. case CeOp_DynamicCastCheck:
  7298. {
  7299. auto& result = CE_GETFRAME(uint32);
  7300. auto valueAddr = CE_GETFRAME(addr_ce);
  7301. int32 ifaceId = CE_GETINST(int32);
  7302. if (valueAddr == 0)
  7303. {
  7304. CeSetAddrVal(&result, 0, ptrSize);
  7305. }
  7306. else
  7307. {
  7308. CE_CHECKADDR(valueAddr, sizeof(int32));
  7309. auto wantType = GetBfType(ifaceId);
  7310. int32 objTypeId = *(int32*)(memStart + valueAddr);
  7311. auto valueType = GetBfType(objTypeId);
  7312. if ((wantType == NULL) || (valueType == NULL))
  7313. {
  7314. _Fail("Invalid type in CeOp_DynamicCastCheck");
  7315. return false;
  7316. }
  7317. bool matches = false;
  7318. if (ceModule->TypeIsSubTypeOf(valueType->ToTypeInstance(), wantType->ToTypeInstance(), false))
  7319. {
  7320. matches = true;
  7321. }
  7322. else if ((valueType->IsDelegate()) && (wantType->IsDelegate()))
  7323. {
  7324. int valueSignatureId = ceModule->GetDelegateSignatureId(valueType->ToTypeInstance());
  7325. int checkSignatureId = ceModule->GetDelegateSignatureId(wantType->ToTypeInstance());
  7326. matches = valueSignatureId == checkSignatureId;
  7327. }
  7328. if (matches)
  7329. CeSetAddrVal(&result, valueAddr, ptrSize);
  7330. else
  7331. CeSetAddrVal(&result, 0, ptrSize);
  7332. }
  7333. }
  7334. break;
  7335. case CeOp_GetReflectType:
  7336. {
  7337. auto frameOfs = CE_GETINST(int32);
  7338. int32 typeId = CE_GETINST(int32);
  7339. auto reflectType = GetReflectType(typeId);
  7340. _FixVariables();
  7341. CeSetAddrVal(framePtr + frameOfs, reflectType, ptrSize);
  7342. }
  7343. break;
  7344. case CeOp_GetString:
  7345. {
  7346. auto frameOfs = CE_GETINST(int32);
  7347. auto stringTableIdx = CE_GETINST(int32);
  7348. auto& ceStringEntry = ceFunction->mStringTable[stringTableIdx];
  7349. if (ceStringEntry.mBindExecuteId != mExecuteId)
  7350. {
  7351. ceStringEntry.mStringAddr = GetString(ceStringEntry.mStringId);
  7352. _FixVariables();
  7353. ceStringEntry.mBindExecuteId = mExecuteId;
  7354. }
  7355. CeSetAddrVal(framePtr + frameOfs, ceStringEntry.mStringAddr, ptrSize);
  7356. }
  7357. break;
  7358. case CeOp_Malloc:
  7359. {
  7360. auto frameOfs = CE_GETINST(int32);
  7361. int64 size;
  7362. if (ptrSize == 4)
  7363. size = CE_GETFRAME(int32);
  7364. else
  7365. size = CE_GETFRAME(int64);
  7366. CE_CHECKALLOC(size);
  7367. uint8* mem = CeMalloc(size);
  7368. _FixVariables();
  7369. CeSetAddrVal(framePtr + frameOfs, mem - memStart, ptrSize);
  7370. }
  7371. break;
  7372. case CeOp_Free:
  7373. {
  7374. auto freeAddr = CE_GETFRAME(addr_ce);
  7375. bool success = CeFree(freeAddr);
  7376. if (!success)
  7377. _Fail("Invalid heap address");
  7378. }
  7379. break;
  7380. case CeOp_MemSet:
  7381. {
  7382. auto destAddr = CE_GETFRAME(addr_ce);
  7383. uint8 setValue = CE_GETFRAME(uint8);
  7384. int32 setSize = CE_GETFRAME(int32);
  7385. CE_CHECKSIZE(setSize);
  7386. CE_CHECKADDR(destAddr, setSize);
  7387. memset(memStart + destAddr, setValue, setSize);
  7388. }
  7389. break;
  7390. case CeOp_MemSet_Const:
  7391. {
  7392. auto destAddr = CE_GETFRAME(addr_ce);
  7393. uint8 setValue = CE_GETINST(uint8);
  7394. int32 setSize = CE_GETINST(int32);
  7395. CE_CHECKSIZE(setSize);
  7396. CE_CHECKADDR(destAddr, setSize);
  7397. memset(memStart + destAddr, setValue, setSize);
  7398. }
  7399. break;
  7400. case CeOp_MemCpy:
  7401. {
  7402. auto destAddr = CE_GETFRAME(addr_ce);
  7403. auto srcAddr = CE_GETFRAME(addr_ce);
  7404. int32 size = CE_GETFRAME(int32);
  7405. CE_CHECKSIZE(size);
  7406. CE_CHECKADDR(srcAddr, size);
  7407. CE_CHECKADDR(destAddr, size);
  7408. memmove(memStart + destAddr, memStart + srcAddr, size);
  7409. }
  7410. break;
  7411. case CeOp_FrameAddr_32:
  7412. {
  7413. auto& result = CE_GETFRAME(int32);
  7414. auto addr = &CE_GETFRAME(uint8);
  7415. result = addr - memStart;
  7416. }
  7417. break;
  7418. case CeOp_FrameAddr_64:
  7419. {
  7420. //if (instPtr - ceFunction->mCode.mVals == 0x9c1)
  7421. auto& result = CE_GETFRAME(int64);
  7422. auto addr = &CE_GETFRAME(uint8);
  7423. result = addr - memStart;
  7424. }
  7425. break;
  7426. case CeOp_FrameAddrOfs_32:
  7427. {
  7428. auto& result = CE_GETFRAME(int32);
  7429. auto addr = &CE_GETFRAME(uint8);
  7430. int32 ofs = CE_GETINST(int32);
  7431. result = (int32)(addr - memStart + ofs);
  7432. }
  7433. break;
  7434. case CeOp_ConstData:
  7435. {
  7436. auto frameOfs = CE_GETINST(int32);
  7437. int32 constIdx = CE_GETINST(int32);
  7438. auto& constEntry = ceFunction->mConstStructTable[constIdx];
  7439. if (constEntry.mBindExecuteId != mExecuteId)
  7440. {
  7441. PrepareConstStructEntry(constEntry);
  7442. _FixVariables();
  7443. }
  7444. auto& buff = (constEntry.mFixedData.mSize > 0) ? constEntry.mFixedData : constEntry.mData;
  7445. memcpy(framePtr + frameOfs, buff.mVals, buff.mSize);
  7446. }
  7447. break;
  7448. case CeOp_ConstDataRef:
  7449. {
  7450. auto frameOfs = CE_GETINST(int32);
  7451. int32 constIdx = CE_GETINST(int32);
  7452. auto& constEntry = ceFunction->mConstStructTable[constIdx];
  7453. if (constEntry.mBindExecuteId != mExecuteId)
  7454. {
  7455. PrepareConstStructEntry(constEntry);
  7456. _FixVariables();
  7457. auto& buff = (constEntry.mFixedData.mSize > 0) ? constEntry.mFixedData : constEntry.mData;
  7458. addr_ce* constAddrPtr = NULL;
  7459. if (mConstDataMap.TryAdd(constEntry.mHash, NULL, &constAddrPtr))
  7460. {
  7461. uint8* data = CeMalloc(buff.mSize);
  7462. _FixVariables();
  7463. memcpy(data, &buff[0], buff.mSize);
  7464. *constAddrPtr = (addr_ce)(data - memStart);
  7465. }
  7466. constEntry.mAddr = *constAddrPtr;
  7467. constEntry.mBindExecuteId = mExecuteId;
  7468. }
  7469. *(addr_ce*)(framePtr + frameOfs) = constEntry.mAddr;
  7470. }
  7471. break;
  7472. case CeOp_Zero:
  7473. {
  7474. auto resultPtr = &CE_GETFRAME(uint8);
  7475. int32 constSize = CE_GETINST(int32);
  7476. memset(resultPtr, 0, constSize);
  7477. }
  7478. break;
  7479. case CeOp_Const_8:
  7480. {
  7481. auto& result = CE_GETFRAME(int8);
  7482. result = CE_GETINST(int8);
  7483. }
  7484. break;
  7485. case CeOp_Const_16:
  7486. {
  7487. auto& result = CE_GETFRAME(int16);
  7488. result = CE_GETINST(int16);
  7489. }
  7490. break;
  7491. case CeOp_Const_32:
  7492. {
  7493. auto& result = CE_GETFRAME(int32);
  7494. result = CE_GETINST(int32);
  7495. }
  7496. break;
  7497. case CeOp_Const_64:
  7498. {
  7499. auto& result = CE_GETFRAME(int64);
  7500. result = CE_GETINST(int64);
  7501. }
  7502. break;
  7503. case CeOp_Const_X:
  7504. {
  7505. int32 constSize = CE_GETINST(int32);
  7506. auto resultPtr = &CE_GETFRAME(uint8);
  7507. memcpy(resultPtr, instPtr, constSize);
  7508. instPtr += constSize;
  7509. }
  7510. break;
  7511. case CeOp_Load_8:
  7512. CE_LOAD(uint8);
  7513. break;
  7514. case CeOp_Load_16:
  7515. CE_LOAD(uint16);
  7516. break;
  7517. case CeOp_Load_32:
  7518. CE_LOAD(uint32);
  7519. break;
  7520. case CeOp_Load_64:
  7521. CE_LOAD(uint64);
  7522. break;
  7523. case CeOp_Load_X:
  7524. {
  7525. int32 size = CE_GETINST(int32);
  7526. auto resultPtr = &CE_GETFRAME(uint8);
  7527. auto ceAddr = CE_GETFRAME(addr_ce);
  7528. CE_CHECKADDR(ceAddr, size);
  7529. memcpy(resultPtr, memStart + ceAddr, size);
  7530. }
  7531. break;
  7532. case CeOp_Store_8:
  7533. CE_STORE(uint8);
  7534. break;
  7535. case CeOp_Store_16:
  7536. CE_STORE(uint16);
  7537. break;
  7538. case CeOp_Store_32:
  7539. CE_STORE(uint32);
  7540. break;
  7541. case CeOp_Store_64:
  7542. CE_STORE(uint64);
  7543. break;
  7544. case CeOp_Store_X:
  7545. {
  7546. auto size = CE_GETINST(int32);
  7547. auto srcPtr = &CE_GETFRAME(uint8);
  7548. auto ceAddr = CE_GETFRAME(addr_ce);
  7549. CE_CHECKADDR(ceAddr, size);
  7550. memcpy(memStart + ceAddr, srcPtr, size);
  7551. }
  7552. break;
  7553. case CeOp_Move_8:
  7554. CEOP_MOVE(int8);
  7555. break;
  7556. case CeOp_Move_16:
  7557. CEOP_MOVE(int16);
  7558. break;
  7559. case CeOp_Move_32:
  7560. CEOP_MOVE(int32);
  7561. break;
  7562. case CeOp_Move_64:
  7563. CEOP_MOVE(int64);
  7564. break;
  7565. case CeOp_Move_X:
  7566. {
  7567. int32 size = CE_GETINST(int32);
  7568. auto valPtr = &CE_GETFRAME(uint8);
  7569. auto destPtr = &CE_GETFRAME(uint8);
  7570. memcpy(destPtr, valPtr, size);
  7571. }
  7572. break;
  7573. case CeOp_Push_8:
  7574. CEOP_PUSH(int8);
  7575. break;
  7576. case CeOp_Push_16:
  7577. CEOP_PUSH(int16);
  7578. break;
  7579. case CeOp_Push_32:
  7580. CEOP_PUSH(int32);
  7581. break;
  7582. case CeOp_Push_64:
  7583. CEOP_PUSH(int64);
  7584. break;
  7585. case CeOp_Pop_8:
  7586. CEOP_POP(int8);
  7587. break;
  7588. case CeOp_Pop_16:
  7589. CEOP_POP(int16);
  7590. break;
  7591. case CeOp_Pop_32:
  7592. CEOP_POP(int32);
  7593. break;
  7594. case CeOp_Pop_64:
  7595. CEOP_POP(int64);
  7596. break;
  7597. case CeOp_Pop_X:
  7598. {
  7599. int32 size = CE_GETINST(int32);
  7600. auto resultPtr = &CE_GETFRAME(uint8);
  7601. memcpy(resultPtr, stackPtr, size);
  7602. stackPtr += size;
  7603. }
  7604. break;
  7605. case CeOp_AdjustSP:
  7606. {
  7607. int32 adjust = CE_GETFRAME(int32);
  7608. stackPtr += adjust;
  7609. }
  7610. break;
  7611. case CeOp_AdjustSPNeg:
  7612. {
  7613. int32 adjust = CE_GETFRAME(int32);
  7614. stackPtr -= adjust;
  7615. }
  7616. break;
  7617. case CeOp_AdjustSPConst:
  7618. {
  7619. int32 adjust = CE_GETINST(int32);
  7620. stackPtr += adjust;
  7621. }
  7622. break;
  7623. case CeOp_GetSP:
  7624. {
  7625. auto& result = CE_GETFRAME(int32);
  7626. result = stackPtr - memStart;
  7627. }
  7628. break;
  7629. case CeOp_SetSP:
  7630. {
  7631. auto addr = CE_GETFRAME(int32);
  7632. stackPtr = memStart + addr;
  7633. }
  7634. break;
  7635. case CeOp_GetStaticField:
  7636. case CeOp_GetStaticField_Initializer:
  7637. {
  7638. auto frameOfs = CE_GETINST(int32);
  7639. int32 tableIdx = CE_GETINST(int32);
  7640. int32 initializerFrameOfs = 0;
  7641. if (op == CeOp_GetStaticField_Initializer)
  7642. {
  7643. initializerFrameOfs = CE_GETINST(int32);;
  7644. }
  7645. CeFunction* ctorCallFunction = NULL;
  7646. auto& ceStaticFieldEntry = ceFunction->mStaticFieldTable[tableIdx];
  7647. if (ceStaticFieldEntry.mBindExecuteId != mExecuteId)
  7648. {
  7649. if ((ceStaticFieldEntry.mTypeId > 0) && (mStaticCtorExecSet.TryAdd(ceStaticFieldEntry.mTypeId, NULL)) && (!ceStaticFieldEntry.mName.StartsWith("#")))
  7650. {
  7651. auto bfType = GetBfType(ceStaticFieldEntry.mTypeId);
  7652. BfTypeInstance* bfTypeInstance = NULL;
  7653. if (bfType != NULL)
  7654. bfTypeInstance = bfType->ToTypeInstance();
  7655. if (bfTypeInstance == NULL)
  7656. {
  7657. _Fail("Invalid type");
  7658. return false;
  7659. }
  7660. if (bfType->mDefineState == BfTypeDefineState_CETypeInit)
  7661. {
  7662. // Don't create circular references
  7663. }
  7664. else
  7665. {
  7666. auto methodDef = bfTypeInstance->mTypeDef->GetMethodByName("__BfStaticCtor");
  7667. if (methodDef != NULL)
  7668. {
  7669. auto moduleMethodInstance = ceModule->GetMethodInstance(bfTypeInstance, methodDef, BfTypeVector());
  7670. if (!moduleMethodInstance)
  7671. {
  7672. _Fail("No static ctor instance found");
  7673. return false;
  7674. }
  7675. ceModule->PopulateType(bfTypeInstance, BfPopulateType_DataAndMethods);
  7676. bool added = false;
  7677. ctorCallFunction = mCeMachine->GetFunction(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, added);
  7678. if (ctorCallFunction->mInitializeState < CeFunction::InitializeState_Initialized)
  7679. mCeMachine->PrepareFunction(ctorCallFunction, NULL);
  7680. }
  7681. }
  7682. }
  7683. CeStaticFieldInfo* staticFieldInfo = NULL;
  7684. mStaticFieldMap.TryAdd(ceStaticFieldEntry.mName, NULL, &staticFieldInfo);
  7685. if (staticFieldInfo->mAddr == 0)
  7686. {
  7687. if (ceStaticFieldEntry.mSize < 0)
  7688. _Fail(StrFormat("Reference to unsized global variable '%s'", ceStaticFieldEntry.mName.c_str()));
  7689. CE_CHECKALLOC(ceStaticFieldEntry.mSize);
  7690. uint8* ptr = CeMalloc(ceStaticFieldEntry.mSize);
  7691. _FixVariables();
  7692. if (ceStaticFieldEntry.mSize > 0)
  7693. memset(ptr, 0, ceStaticFieldEntry.mSize);
  7694. staticFieldInfo->mAddr = (addr_ce)(ptr - memStart);
  7695. if (op == CeOp_GetStaticField_Initializer)
  7696. {
  7697. void* initDataPtr = framePtr + initializerFrameOfs;
  7698. memcpy(ptr, initDataPtr, ceStaticFieldEntry.mSize);
  7699. }
  7700. if (ceStaticFieldEntry.mName.StartsWith("#"))
  7701. {
  7702. addr_ce resultAddr = 0;
  7703. if (ceStaticFieldEntry.mName == "#CallerLineNum")
  7704. {
  7705. *(int*)ptr = mCurModule->mCurFilePosition.mCurLine;
  7706. }
  7707. else if (ceStaticFieldEntry.mName == "#CallerFilePath")
  7708. {
  7709. String filePath;
  7710. if (mCurModule->mCurFilePosition.mFileInstance != NULL)
  7711. filePath = mCurModule->mCurFilePosition.mFileInstance->mParser->mFileName;
  7712. resultAddr = GetString(filePath);
  7713. }
  7714. else if (ceStaticFieldEntry.mName == "#CallerFileName")
  7715. {
  7716. String filePath;
  7717. if (mCurModule->mCurFilePosition.mFileInstance != NULL)
  7718. filePath = mCurModule->mCurFilePosition.mFileInstance->mParser->mFileName;
  7719. resultAddr = GetString(GetFileName(filePath));
  7720. }
  7721. else if (ceStaticFieldEntry.mName == "#CallerFileDir")
  7722. {
  7723. String filePath;
  7724. if (mCurModule->mCurFilePosition.mFileInstance != NULL)
  7725. filePath = mCurModule->mCurFilePosition.mFileInstance->mParser->mFileName;
  7726. resultAddr = GetString(GetFileDir(filePath));
  7727. }
  7728. else if (ceStaticFieldEntry.mName == "#CallerTypeName")
  7729. {
  7730. String typeName = "";
  7731. typeName = mCeMachine->mCeModule->TypeToString(mCallerTypeInstance);
  7732. resultAddr = GetString(typeName);
  7733. }
  7734. else if (ceStaticFieldEntry.mName == "#CallerType")
  7735. {
  7736. addr_ce typeAddr = GetReflectType(mCallerTypeInstance->mTypeId);
  7737. resultAddr = typeAddr;
  7738. }
  7739. else if (ceStaticFieldEntry.mName == "#CallerMemberName")
  7740. {
  7741. String memberName = mCeMachine->mCeModule->MethodToString(mCallerMethodInstance);
  7742. resultAddr = GetString(memberName);
  7743. }
  7744. else if (ceStaticFieldEntry.mName == "#CallerProject")
  7745. {
  7746. BfProject* project = NULL;
  7747. project = mCallerTypeInstance->mTypeDef->mProject;
  7748. if (project != NULL)
  7749. resultAddr = GetString(project->mName);
  7750. }
  7751. else if (ceStaticFieldEntry.mName == "#OrigCalleeType")
  7752. {
  7753. if (mCurCallSource->mOrigCalleeType != NULL)
  7754. {
  7755. addr_ce typeAddr = GetReflectType(mCurCallSource->mOrigCalleeType->mTypeId);
  7756. resultAddr = typeAddr;
  7757. }
  7758. }
  7759. if (resultAddr != 0)
  7760. {
  7761. _FixVariables();
  7762. CeSetAddrVal(memStart + staticFieldInfo->mAddr, resultAddr, ptrSize);
  7763. }
  7764. }
  7765. }
  7766. ceStaticFieldEntry.mAddr = staticFieldInfo->mAddr;
  7767. ceStaticFieldEntry.mBindExecuteId = mExecuteId;
  7768. }
  7769. *(addr_ce*)(framePtr + frameOfs) = ceStaticFieldEntry.mAddr;
  7770. if (ctorCallFunction != NULL)
  7771. {
  7772. bool handled = false;
  7773. if (!_CheckFunction(ctorCallFunction, handled))
  7774. return false;
  7775. if (handled)
  7776. break;
  7777. CE_CALL(ctorCallFunction);
  7778. }
  7779. }
  7780. break;
  7781. case CeOp_GetMethod:
  7782. {
  7783. BF_ASSERT(memStart == mMemory.mVals);
  7784. auto resultFrameIdx = CE_GETINST(int32);
  7785. int32 callIdx = CE_GETINST(int32);
  7786. auto& callEntry = ceFunction->mCallTable[callIdx];
  7787. if (callEntry.mBindRevision != mCeMachine->mMethodBindRevision)
  7788. {
  7789. callEntry.mFunction = NULL;
  7790. //mNamedFunctionMap.TryGetValue(callEntry.mFunctionName, &callEntry.mFunction);
  7791. if (callEntry.mFunctionInfo == NULL)
  7792. {
  7793. _Fail("Unable to locate function entry");
  7794. return false;
  7795. }
  7796. if ((callEntry.mFunctionInfo->mCeFunction == NULL) && (!callEntry.mFunctionInfo->mMethodRef.IsNull()))
  7797. {
  7798. auto methodRef = callEntry.mFunctionInfo->mMethodRef;
  7799. if (methodRef.mMethodNum >= methodRef.mTypeInstance->mTypeDef->mMethods.mSize)
  7800. {
  7801. // Must be a comptime-generated method
  7802. ceModule->PopulateType(methodRef.mTypeInstance);
  7803. }
  7804. if (methodRef.mMethodNum >= methodRef.mTypeInstance->mTypeDef->mMethods.mSize)
  7805. {
  7806. _Fail("OOB method reference");
  7807. return false;
  7808. }
  7809. auto methodDef = methodRef.mTypeInstance->mTypeDef->mMethods[methodRef.mMethodNum];
  7810. auto moduleMethodInstance = ceModule->GetMethodInstance(methodRef.mTypeInstance, methodDef,
  7811. methodRef.mMethodGenericArguments);
  7812. if (moduleMethodInstance)
  7813. {
  7814. auto ceFunction = mCeMachine->QueueMethod(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc);
  7815. if (ceFunction == NULL)
  7816. {
  7817. _Fail("Method generation failed");
  7818. return false;
  7819. }
  7820. ceFunction->mCeFunctionInfo->mRefCount++;
  7821. mCeMachine->DerefMethodInfo(callEntry.mFunctionInfo);
  7822. callEntry.mFunctionInfo = ceFunction->mCeFunctionInfo;
  7823. }
  7824. }
  7825. if (callEntry.mFunctionInfo->mCeFunction == NULL)
  7826. {
  7827. _Fail("Method not generated");
  7828. return false;
  7829. }
  7830. callEntry.mFunction = callEntry.mFunctionInfo->mCeFunction;
  7831. if (callEntry.mFunction->mInitializeState < CeFunction::InitializeState_Initialized)
  7832. {
  7833. auto curFrame = _GetCurFrame();
  7834. SetAndRestoreValue<CeFrame*> prevFrame(mCurFrame, &curFrame);
  7835. BF_ASSERT(callEntry.mFunction->mInitializeState < CeFunction::InitializeState_Initialized);
  7836. mCeMachine->PrepareFunction(callEntry.mFunction, NULL);
  7837. }
  7838. if (callEntry.mFunction->mMethodInstance != NULL)
  7839. {
  7840. if (callEntry.mFunction->mMethodInstance->GetOwner()->IsDeleting())
  7841. {
  7842. _Fail("Calling method on deleted type");
  7843. return false;
  7844. }
  7845. }
  7846. callEntry.mBindRevision = mCeMachine->mMethodBindRevision;
  7847. }
  7848. BF_ASSERT(memStart == mMemory.mVals);
  7849. auto callFunction = callEntry.mFunction;
  7850. if (needsFunctionIds)
  7851. *(int32*)(framePtr + resultFrameIdx) = callFunction->mId;
  7852. else
  7853. *(CeFunction**)(framePtr + resultFrameIdx) = callFunction;
  7854. }
  7855. break;
  7856. case CeOp_GetMethod_Inner:
  7857. {
  7858. auto resultFrameIdx = CE_GETINST(int32);
  7859. int32 innerIdx = CE_GETINST(int32);
  7860. auto outerFunction = ceFunction;
  7861. if (outerFunction->mCeInnerFunctionInfo != NULL)
  7862. outerFunction = outerFunction->mCeInnerFunctionInfo->mOwner;
  7863. auto callFunction = outerFunction->mInnerFunctions[innerIdx];
  7864. if (needsFunctionIds)
  7865. *(int32*)(framePtr + resultFrameIdx) = callFunction->mId;
  7866. else
  7867. *(CeFunction**)(framePtr + resultFrameIdx) = callFunction;
  7868. }
  7869. break;
  7870. case CeOp_GetMethod_Virt:
  7871. {
  7872. auto resultFrameIdx = CE_GETINST(int32);
  7873. auto valueAddr = CE_GETFRAME(addr_ce);
  7874. int32 virtualIdx = CE_GETINST(int32);
  7875. CE_CHECKADDR(valueAddr, sizeof(int32));
  7876. int32 objTypeId = *(int32*)(memStart + valueAddr);
  7877. BfType* bfType = GetBfType(objTypeId);
  7878. if ((bfType == NULL) || (!bfType->IsObject()))
  7879. {
  7880. _Fail("Invalid virtual method target");
  7881. return false;
  7882. }
  7883. auto valueType = bfType->ToTypeInstance();
  7884. if (valueType->mVirtualMethodTable.IsEmpty())
  7885. ceModule->PopulateType(valueType, BfPopulateType_Full_Force);
  7886. if (valueType->mVirtualMethodTable.IsEmpty())
  7887. {
  7888. _Fail("Empty virtual table");
  7889. return false;
  7890. }
  7891. auto& methodRef = valueType->mVirtualMethodTable[virtualIdx].mImplementingMethod;
  7892. if (methodRef.mTypeInstance->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted)
  7893. ceModule->PopulateType(methodRef.mTypeInstance, BfPopulateType_DataAndMethods);
  7894. auto methodInstance = (BfMethodInstance*)methodRef;
  7895. auto callFunction = mCeMachine->GetPreparedFunction(methodInstance);
  7896. if (needsFunctionIds)
  7897. *(int32*)(framePtr + resultFrameIdx) = callFunction->mId;
  7898. else
  7899. *(CeFunction**)(framePtr + resultFrameIdx) = callFunction;
  7900. }
  7901. break;
  7902. case CeOp_GetMethod_IFace:
  7903. {
  7904. auto resultFrameIdx = CE_GETINST(int32);
  7905. auto valueAddr = CE_GETFRAME(addr_ce);
  7906. int32 ifaceId = CE_GETINST(int32);
  7907. int32 methodIdx = CE_GETINST(int32);
  7908. auto ifaceType = ceModule->mContext->mTypes[ifaceId]->ToTypeInstance();
  7909. CE_CHECKADDR(valueAddr, sizeof(int32));
  7910. int32 objTypeId = *(int32*)(memStart + valueAddr);
  7911. auto bfObjectType = GetBfType(objTypeId);
  7912. if ((bfObjectType == NULL) || (!bfObjectType->IsTypeInstance()))
  7913. {
  7914. _Fail("Invalid object");
  7915. return false;
  7916. }
  7917. auto valueType = bfObjectType->ToTypeInstance();
  7918. BfMethodInstance* methodInstance = NULL;
  7919. if (valueType != NULL)
  7920. {
  7921. if (valueType->mVirtualMethodTable.IsEmpty())
  7922. ceModule->PopulateType(valueType, BfPopulateType_DataAndMethods);
  7923. auto checkType = valueType;
  7924. while (checkType != NULL)
  7925. {
  7926. for (auto& iface : checkType->mInterfaces)
  7927. {
  7928. if (iface.mInterfaceType == ifaceType)
  7929. {
  7930. if (valueType->mInterfaceMethodTable.IsEmpty())
  7931. ceModule->PopulateType(valueType, BfPopulateType_Full_Force);
  7932. if (valueType->mInterfaceMethodTable.IsEmpty())
  7933. {
  7934. _Fail("Empty interface table");
  7935. return false;
  7936. }
  7937. methodInstance = valueType->mInterfaceMethodTable[iface.mStartInterfaceTableIdx + methodIdx].mMethodRef;
  7938. break;
  7939. }
  7940. }
  7941. checkType = checkType->mBaseType;
  7942. }
  7943. }
  7944. if (methodInstance == NULL)
  7945. {
  7946. _Fail("Failed to invoke interface method");
  7947. return false;
  7948. }
  7949. auto callFunction = mCeMachine->GetPreparedFunction(methodInstance);
  7950. if (needsFunctionIds)
  7951. *(int32*)(framePtr + resultFrameIdx) = callFunction->mId;
  7952. else
  7953. *(CeFunction**)(framePtr + resultFrameIdx) = callFunction;
  7954. }
  7955. break;
  7956. case CeOp_Call:
  7957. {
  7958. callCount++;
  7959. CeFunction* callFunction;
  7960. if (needsFunctionIds)
  7961. {
  7962. int32 functionId = CE_GETFRAME(int32);
  7963. callFunction = mCeMachine->mFunctionIdMap[functionId];
  7964. }
  7965. else
  7966. callFunction = CE_GETFRAME(CeFunction*);
  7967. bool handled = false;
  7968. if (!_CheckFunction(callFunction, handled))
  7969. return false;
  7970. if (callFunction->mIsVarReturn)
  7971. _Fail("Illegal call to method with 'var' return.");
  7972. if (handled)
  7973. break;
  7974. CE_CALL(callFunction);
  7975. }
  7976. break;
  7977. case CeOp_Conv_I8_I16:
  7978. CE_CAST(int8, int16);
  7979. break;
  7980. case CeOp_Conv_I8_I32:
  7981. CE_CAST(int8, int32);
  7982. break;
  7983. case CeOp_Conv_I8_I64:
  7984. CE_CAST(int8, int64);
  7985. break;
  7986. case CeOp_Conv_I8_F32:
  7987. CE_CAST(int8, float);
  7988. break;
  7989. case CeOp_Conv_I8_F64:
  7990. CE_CAST(int8, double);
  7991. break;
  7992. case CeOp_Conv_I16_I32:
  7993. CE_CAST(int16, int32);
  7994. break;
  7995. case CeOp_Conv_I16_I64:
  7996. CE_CAST(int16, int64);
  7997. break;
  7998. case CeOp_Conv_I16_F32:
  7999. CE_CAST(int16, float);
  8000. break;
  8001. case CeOp_Conv_I16_F64:
  8002. CE_CAST(int16, double);
  8003. break;
  8004. case CeOp_Conv_I32_I64:
  8005. CE_CAST(int32, int64);
  8006. break;
  8007. case CeOp_Conv_I32_F32:
  8008. CE_CAST(int32, float);
  8009. break;
  8010. case CeOp_Conv_I32_F64:
  8011. CE_CAST(int32, double);
  8012. break;
  8013. case CeOp_Conv_I64_F32:
  8014. CE_CAST(int64, float);
  8015. break;
  8016. case CeOp_Conv_I64_F64:
  8017. CE_CAST(int64, double);
  8018. break;
  8019. case CeOp_Conv_U8_U16:
  8020. CE_CAST(uint8, uint16);
  8021. break;
  8022. case CeOp_Conv_U8_U32:
  8023. CE_CAST(uint8, uint32);
  8024. break;
  8025. case CeOp_Conv_U8_U64:
  8026. CE_CAST(uint8, uint64);
  8027. break;
  8028. case CeOp_Conv_U8_F32:
  8029. CE_CAST(uint8, float);
  8030. break;
  8031. case CeOp_Conv_U8_F64:
  8032. CE_CAST(uint8, double);
  8033. break;
  8034. case CeOp_Conv_U16_U32:
  8035. CE_CAST(uint16, uint32);
  8036. break;
  8037. case CeOp_Conv_U16_U64:
  8038. CE_CAST(uint16, uint64);
  8039. break;
  8040. case CeOp_Conv_U16_F32:
  8041. CE_CAST(uint16, float);
  8042. break;
  8043. case CeOp_Conv_U16_F64:
  8044. CE_CAST(uint16, double);
  8045. break;
  8046. case CeOp_Conv_U32_U64:
  8047. CE_CAST(uint32, uint64);
  8048. break;
  8049. case CeOp_Conv_U32_F32:
  8050. CE_CAST(uint32, float);
  8051. break;
  8052. case CeOp_Conv_U32_F64:
  8053. CE_CAST(uint32, double);
  8054. break;
  8055. case CeOp_Conv_U64_F32:
  8056. CE_CAST(uint64, float);
  8057. break;
  8058. case CeOp_Conv_U64_F64:
  8059. CE_CAST(uint64, double);
  8060. break;
  8061. case CeOp_Conv_F32_I8:
  8062. CE_CAST(float, int8);
  8063. break;
  8064. case CeOp_Conv_F32_I16:
  8065. CE_CAST(float, int16);
  8066. break;
  8067. case CeOp_Conv_F32_I32:
  8068. CE_CAST(float, int32);
  8069. break;
  8070. case CeOp_Conv_F32_I64:
  8071. CE_CAST(float, int64);
  8072. break;
  8073. case CeOp_Conv_F32_F64:
  8074. CE_CAST(float, double);
  8075. break;
  8076. case CeOp_Conv_F64_I8:
  8077. CE_CAST(double, int8);
  8078. break;
  8079. case CeOp_Conv_F64_I16:
  8080. CE_CAST(double, int16);
  8081. break;
  8082. case CeOp_Conv_F64_I32:
  8083. CE_CAST(double, int32);
  8084. break;
  8085. case CeOp_Conv_F64_I64:
  8086. CE_CAST(double, int64);
  8087. break;
  8088. case CeOp_Conv_F64_F32:
  8089. CE_CAST(double, float);
  8090. break;
  8091. case CeOp_Conv_F32_U8:
  8092. CE_CAST(float, uint8);
  8093. break;
  8094. case CeOp_Conv_F32_U16:
  8095. CE_CAST(float, uint16);
  8096. break;
  8097. case CeOp_Conv_F32_U32:
  8098. CE_CAST(float, uint32);
  8099. break;
  8100. case CeOp_Conv_F32_U64:
  8101. CE_CAST(float, uint64);
  8102. break;
  8103. case CeOp_Conv_F64_U8:
  8104. CE_CAST(float, uint8);
  8105. break;
  8106. case CeOp_Conv_F64_U16:
  8107. CE_CAST(float, uint16);
  8108. break;
  8109. case CeOp_Conv_F64_U32:
  8110. CE_CAST(float, uint32);
  8111. break;
  8112. case CeOp_Conv_F64_U64:
  8113. CE_CAST(float, uint64);
  8114. break;
  8115. case CeOp_Abs_I8:
  8116. {
  8117. auto& result = CE_GETFRAME(int8);
  8118. auto val = CE_GETFRAME(int8);
  8119. result = (val < 0) ? -val : val;
  8120. }
  8121. break;
  8122. case CeOp_Abs_I16:
  8123. {
  8124. auto& result = CE_GETFRAME(int16);
  8125. auto val = CE_GETFRAME(int16);
  8126. result = (val < 0) ? -val : val;
  8127. }
  8128. break;
  8129. case CeOp_Abs_I32:
  8130. {
  8131. auto& result = CE_GETFRAME(int32);
  8132. auto val = CE_GETFRAME(int32);
  8133. result = (val < 0) ? -val : val;
  8134. }
  8135. break;
  8136. case CeOp_Abs_I64:
  8137. {
  8138. auto& result = CE_GETFRAME(int64);
  8139. auto val = CE_GETFRAME(int64);
  8140. result = (val < 0) ? -val : val;
  8141. }
  8142. break;
  8143. case CeOp_Abs_F32:
  8144. CEOP_UNARY_FUNC(fabs, float);
  8145. break;
  8146. case CeOp_Abs_F64:
  8147. CEOP_UNARY_FUNC(fabs, double);
  8148. break;
  8149. case CeOp_AddConst_I8:
  8150. CEOP_BIN_CONST(+, int8);
  8151. break;
  8152. case CeOp_AddConst_I16:
  8153. CEOP_BIN_CONST(+, int16);
  8154. break;
  8155. case CeOp_AddConst_I32:
  8156. CEOP_BIN_CONST(+, int32);
  8157. break;
  8158. case CeOp_AddConst_I64:
  8159. CEOP_BIN_CONST(+, int64);
  8160. break;
  8161. case CeOp_Add_I8:
  8162. CEOP_BIN(+, int8);
  8163. break;
  8164. case CeOp_Add_I16:
  8165. CEOP_BIN(+, int16);
  8166. break;
  8167. case CeOp_Add_I32:
  8168. CEOP_BIN(+, int32);
  8169. break;
  8170. case CeOp_Add_I64:
  8171. CEOP_BIN(+, int64);
  8172. break;
  8173. case CeOp_Add_F32:
  8174. CEOP_BIN(+, float);
  8175. break;
  8176. case CeOp_Add_F64:
  8177. CEOP_BIN(+, double);
  8178. break;
  8179. case CeOp_Sub_I8:
  8180. CEOP_BIN(-, int8);
  8181. break;
  8182. case CeOp_Sub_I16:
  8183. CEOP_BIN(-, int16);
  8184. break;
  8185. case CeOp_Sub_I32:
  8186. CEOP_BIN(-, int32);
  8187. break;
  8188. case CeOp_Sub_I64:
  8189. CEOP_BIN(-, int64);
  8190. break;
  8191. case CeOp_Sub_F32:
  8192. CEOP_BIN(-, float);
  8193. break;
  8194. case CeOp_Sub_F64:
  8195. CEOP_BIN(-, double);
  8196. break;
  8197. case CeOp_Mul_I8:
  8198. CEOP_BIN(*, int8);
  8199. break;
  8200. case CeOp_Mul_I16:
  8201. CEOP_BIN(*, int16);
  8202. break;
  8203. case CeOp_Mul_I32:
  8204. CEOP_BIN(*, int32);
  8205. break;
  8206. case CeOp_Mul_I64:
  8207. CEOP_BIN(*, int64);
  8208. break;
  8209. case CeOp_Mul_F32:
  8210. CEOP_BIN(*, float);
  8211. break;
  8212. case CeOp_Mul_F64:
  8213. CEOP_BIN(*, double);
  8214. break;
  8215. case CeOp_Div_I8:
  8216. CEOP_BIN_DIV(/ , int8);
  8217. break;
  8218. case CeOp_Div_I16:
  8219. CEOP_BIN_DIV(/ , int16);
  8220. break;
  8221. case CeOp_Div_I32:
  8222. CEOP_BIN_DIV(/ , int32);
  8223. break;
  8224. case CeOp_Div_I64:
  8225. CEOP_BIN_DIV(/ , int64);
  8226. break;
  8227. case CeOp_Div_F32:
  8228. CEOP_BIN_DIV(/ , float);
  8229. break;
  8230. case CeOp_Div_F64:
  8231. CEOP_BIN_DIV(/ , double);
  8232. break;
  8233. case CeOp_Div_U8:
  8234. CEOP_BIN_DIV(/ , uint8);
  8235. break;
  8236. case CeOp_Div_U16:
  8237. CEOP_BIN_DIV(/ , uint16);
  8238. break;
  8239. case CeOp_Div_U32:
  8240. CEOP_BIN_DIV(/ , uint32);
  8241. break;
  8242. case CeOp_Div_U64:
  8243. CEOP_BIN_DIV(/ , uint64);
  8244. break;
  8245. case CeOp_Mod_I8:
  8246. CEOP_BIN_DIV(%, int8);
  8247. break;
  8248. case CeOp_Mod_I16:
  8249. CEOP_BIN_DIV(%, int16);
  8250. break;
  8251. case CeOp_Mod_I32:
  8252. CEOP_BIN_DIV(%, int32);
  8253. break;
  8254. case CeOp_Mod_I64:
  8255. CEOP_BIN_DIV(%, int64);
  8256. break;
  8257. case CeOp_Mod_F32:
  8258. {
  8259. auto& result = CE_GETFRAME(float);
  8260. auto lhs = CE_GETFRAME(float);
  8261. auto rhs = CE_GETFRAME(float);
  8262. if (rhs == 0)
  8263. {
  8264. _Fail("Division by zero");
  8265. return false;
  8266. }
  8267. result = fmodf(lhs, rhs);
  8268. }
  8269. break;
  8270. case CeOp_Mod_F64:
  8271. {
  8272. auto& result = CE_GETFRAME(double);
  8273. auto lhs = CE_GETFRAME(double);
  8274. auto rhs = CE_GETFRAME(double);
  8275. if (rhs == 0)
  8276. {
  8277. _Fail("Division by zero");
  8278. return false;
  8279. }
  8280. result = fmod(lhs, rhs);
  8281. }
  8282. break;
  8283. case CeOp_Mod_U8:
  8284. CEOP_BIN_DIV(%, uint8);
  8285. break;
  8286. case CeOp_Mod_U16:
  8287. CEOP_BIN_DIV(%, uint16);
  8288. break;
  8289. case CeOp_Mod_U32:
  8290. CEOP_BIN_DIV(%, uint32);
  8291. break;
  8292. case CeOp_Mod_U64:
  8293. CEOP_BIN_DIV(%, uint64);
  8294. break;
  8295. case CeOp_And_I8:
  8296. CEOP_BIN(&, uint8);
  8297. break;
  8298. case CeOp_And_I16:
  8299. CEOP_BIN(&, uint16);
  8300. break;
  8301. case CeOp_And_I32:
  8302. CEOP_BIN(&, uint32);
  8303. break;
  8304. case CeOp_And_I64:
  8305. CEOP_BIN(&, uint64);
  8306. break;
  8307. case CeOp_Or_I8:
  8308. CEOP_BIN(| , uint8);
  8309. break;
  8310. case CeOp_Or_I16:
  8311. CEOP_BIN(| , uint16);
  8312. break;
  8313. case CeOp_Or_I32:
  8314. CEOP_BIN(| , uint32);
  8315. break;
  8316. case CeOp_Or_I64:
  8317. CEOP_BIN(| , uint64);
  8318. break;
  8319. case CeOp_Xor_I8:
  8320. CEOP_BIN(^, uint8);
  8321. break;
  8322. case CeOp_Xor_I16:
  8323. CEOP_BIN(^, uint16);
  8324. break;
  8325. case CeOp_Xor_I32:
  8326. CEOP_BIN(^, uint32);
  8327. break;
  8328. case CeOp_Xor_I64:
  8329. CEOP_BIN(^, uint64);
  8330. break;
  8331. case CeOp_Shl_I8:
  8332. CEOP_BIN2(<< , int8, uint8);
  8333. break;
  8334. case CeOp_Shl_I16:
  8335. CEOP_BIN2(<< , int16, uint8);
  8336. break;
  8337. case CeOp_Shl_I32:
  8338. CEOP_BIN2(<< , int32, uint8);
  8339. break;
  8340. case CeOp_Shl_I64:
  8341. CEOP_BIN2(<< , int64, uint8);
  8342. break;
  8343. case CeOp_Shr_I8:
  8344. CEOP_BIN2(>> , int8, uint8);
  8345. break;
  8346. case CeOp_Shr_I16:
  8347. CEOP_BIN2(>> , int16, uint8);
  8348. break;
  8349. case CeOp_Shr_I32:
  8350. CEOP_BIN2(>> , int32, uint8);
  8351. break;
  8352. case CeOp_Shr_I64:
  8353. CEOP_BIN2(>> , int64, uint8);
  8354. break;
  8355. case CeOp_Shr_U8:
  8356. CEOP_BIN2(>> , uint8, uint8);
  8357. break;
  8358. case CeOp_Shr_U16:
  8359. CEOP_BIN2(>> , uint16, uint8);
  8360. break;
  8361. case CeOp_Shr_U32:
  8362. CEOP_BIN2(>> , uint32, uint8);
  8363. break;
  8364. case CeOp_Shr_U64:
  8365. CEOP_BIN2(>> , uint64, uint8);
  8366. break;
  8367. case CeOp_Acos_F32:
  8368. CEOP_UNARY_FUNC(acosf, float);
  8369. break;
  8370. case CeOp_Acos_F64:
  8371. CEOP_UNARY_FUNC(acos, double);
  8372. break;
  8373. case CeOp_Asin_F32:
  8374. CEOP_UNARY_FUNC(asinf, float);
  8375. break;
  8376. case CeOp_Asin_F64:
  8377. CEOP_UNARY_FUNC(asin, double);
  8378. break;
  8379. case CeOp_Atan_F32:
  8380. CEOP_UNARY_FUNC(atanf, float);
  8381. break;
  8382. case CeOp_Atan_F64:
  8383. CEOP_UNARY_FUNC(atan, double);
  8384. break;
  8385. case CeOp_Atan2_F32:
  8386. CEOP_BIN_FUNC(atan2f, float);
  8387. break;
  8388. case CeOp_Atan2_F64:
  8389. CEOP_BIN_FUNC(atan2, double);
  8390. break;
  8391. case CeOp_Ceiling_F32:
  8392. CEOP_UNARY_FUNC(ceilf, float);
  8393. break;
  8394. case CeOp_Ceiling_F64:
  8395. CEOP_UNARY_FUNC(ceil, double);
  8396. break;
  8397. case CeOp_Cos_F32:
  8398. CEOP_UNARY_FUNC(cosf, float);
  8399. break;
  8400. case CeOp_Cos_F64:
  8401. CEOP_UNARY_FUNC(cos, double);
  8402. break;
  8403. case CeOp_Cosh_F32:
  8404. CEOP_UNARY_FUNC(coshf, float);
  8405. break;
  8406. case CeOp_Cosh_F64:
  8407. CEOP_UNARY_FUNC(cosh, double);
  8408. break;
  8409. case CeOp_Exp_F32:
  8410. CEOP_UNARY_FUNC(expf, float);
  8411. break;
  8412. case CeOp_Exp_F64:
  8413. CEOP_UNARY_FUNC(exp, double);
  8414. break;
  8415. case CeOp_Floor_F32:
  8416. CEOP_UNARY_FUNC(floorf, float);
  8417. break;
  8418. case CeOp_Floor_F64:
  8419. CEOP_UNARY_FUNC(floor, double);
  8420. break;
  8421. case CeOp_Log_F32:
  8422. CEOP_UNARY_FUNC(logf, float);
  8423. break;
  8424. case CeOp_Log_F64:
  8425. CEOP_UNARY_FUNC(log, double);
  8426. break;
  8427. case CeOp_Log10_F32:
  8428. CEOP_UNARY_FUNC(log10f, float);
  8429. break;
  8430. case CeOp_Log10_F64:
  8431. CEOP_UNARY_FUNC(log10, double);
  8432. break;
  8433. case CeOp_Pow_F32:
  8434. CEOP_BIN_FUNC(powf, float);
  8435. break;
  8436. case CeOp_Pow_F64:
  8437. CEOP_BIN_FUNC(pow, double);
  8438. break;
  8439. case CeOp_Round_F32:
  8440. CEOP_UNARY_FUNC(roundf, float);
  8441. break;
  8442. case CeOp_Round_F64:
  8443. CEOP_UNARY_FUNC(round, double);
  8444. break;
  8445. case CeOp_Sin_F32:
  8446. CEOP_UNARY_FUNC(sinf, float);
  8447. break;
  8448. case CeOp_Sin_F64:
  8449. CEOP_UNARY_FUNC(sin, double);
  8450. break;
  8451. case CeOp_Sinh_F32:
  8452. CEOP_UNARY_FUNC(sinhf, float);
  8453. break;
  8454. case CeOp_Sinh_F64:
  8455. CEOP_UNARY_FUNC(sinh, double);
  8456. break;
  8457. case CeOp_Sqrt_F32:
  8458. CEOP_UNARY_FUNC(sqrtf, float);
  8459. break;
  8460. case CeOp_Sqrt_F64:
  8461. CEOP_UNARY_FUNC(sqrt, double);
  8462. break;
  8463. case CeOp_Tan_F32:
  8464. CEOP_UNARY_FUNC(tanf, float);
  8465. break;
  8466. case CeOp_Tan_F64:
  8467. CEOP_UNARY_FUNC(tan, double);
  8468. break;
  8469. case CeOp_Tanh_F32:
  8470. CEOP_UNARY_FUNC(tanhf, float);
  8471. break;
  8472. case CeOp_Tanh_F64:
  8473. CEOP_UNARY_FUNC(tanh, double);
  8474. break;
  8475. case CeOp_Cmp_NE_I8:
  8476. CEOP_CMP(!= , int8);
  8477. break;
  8478. case CeOp_Cmp_NE_I16:
  8479. CEOP_CMP(!= , int16);
  8480. break;
  8481. case CeOp_Cmp_NE_I32:
  8482. CEOP_CMP(!= , int32);
  8483. break;
  8484. case CeOp_Cmp_NE_I64:
  8485. CEOP_CMP(!= , int64);
  8486. break;
  8487. case CeOp_Cmp_NE_F32:
  8488. CEOP_CMP(!= , float);
  8489. break;
  8490. case CeOp_Cmp_NE_F64:
  8491. CEOP_CMP(!= , double);
  8492. break;
  8493. case CeOp_Cmp_EQ_I8:
  8494. CEOP_CMP(== , int8);
  8495. break;
  8496. case CeOp_Cmp_EQ_I16:
  8497. CEOP_CMP(== , int16);
  8498. break;
  8499. case CeOp_Cmp_EQ_I32:
  8500. CEOP_CMP(== , int32);
  8501. break;
  8502. case CeOp_Cmp_EQ_I64:
  8503. CEOP_CMP(== , int64);
  8504. break;
  8505. case CeOp_Cmp_EQ_F32:
  8506. CEOP_CMP(== , float);
  8507. break;
  8508. case CeOp_Cmp_EQ_F64:
  8509. CEOP_CMP(== , double);
  8510. break;
  8511. case CeOp_Cmp_SLT_I8:
  8512. CEOP_CMP(< , int8);
  8513. break;
  8514. case CeOp_Cmp_SLT_I16:
  8515. CEOP_CMP(< , int16);
  8516. break;
  8517. case CeOp_Cmp_SLT_I32:
  8518. CEOP_CMP(< , int32);
  8519. break;
  8520. case CeOp_Cmp_SLT_I64:
  8521. CEOP_CMP(< , int64);
  8522. break;
  8523. case CeOp_Cmp_SLT_F32:
  8524. CEOP_CMP(< , float);
  8525. break;
  8526. case CeOp_Cmp_SLT_F64:
  8527. CEOP_CMP(< , double);
  8528. break;
  8529. case CeOp_Cmp_ULT_I8:
  8530. CEOP_CMP(< , uint8);
  8531. break;
  8532. case CeOp_Cmp_ULT_I16:
  8533. CEOP_CMP(< , uint16);
  8534. break;
  8535. case CeOp_Cmp_ULT_I32:
  8536. CEOP_CMP(< , uint32);
  8537. break;
  8538. case CeOp_Cmp_ULT_I64:
  8539. CEOP_CMP(< , uint64);
  8540. break;
  8541. case CeOp_Cmp_SLE_I8:
  8542. CEOP_CMP(<= , int8);
  8543. break;
  8544. case CeOp_Cmp_SLE_I16:
  8545. CEOP_CMP(<= , int16);
  8546. break;
  8547. case CeOp_Cmp_SLE_I32:
  8548. CEOP_CMP(<= , int32);
  8549. break;
  8550. case CeOp_Cmp_SLE_I64:
  8551. CEOP_CMP(<= , int64);
  8552. break;
  8553. case CeOp_Cmp_SLE_F32:
  8554. CEOP_CMP(<= , float);
  8555. break;
  8556. case CeOp_Cmp_SLE_F64:
  8557. CEOP_CMP(<= , double);
  8558. break;
  8559. case CeOp_Cmp_ULE_I8:
  8560. CEOP_CMP(<= , uint8);
  8561. break;
  8562. case CeOp_Cmp_ULE_I16:
  8563. CEOP_CMP(<= , uint16);
  8564. break;
  8565. case CeOp_Cmp_ULE_I32:
  8566. CEOP_CMP(<= , uint32);
  8567. break;
  8568. case CeOp_Cmp_ULE_I64:
  8569. CEOP_CMP(<= , uint64);
  8570. break;
  8571. case CeOp_Cmp_SGT_I8:
  8572. CEOP_CMP(> , int8);
  8573. break;
  8574. case CeOp_Cmp_SGT_I16:
  8575. CEOP_CMP(> , int16);
  8576. break;
  8577. case CeOp_Cmp_SGT_I32:
  8578. CEOP_CMP(> , int32);
  8579. break;
  8580. case CeOp_Cmp_SGT_I64:
  8581. CEOP_CMP(> , int64);
  8582. break;
  8583. case CeOp_Cmp_SGT_F32:
  8584. CEOP_CMP(> , float);
  8585. break;
  8586. case CeOp_Cmp_SGT_F64:
  8587. CEOP_CMP(> , double);
  8588. break;
  8589. case CeOp_Cmp_UGT_I8:
  8590. CEOP_CMP(> , uint8);
  8591. break;
  8592. case CeOp_Cmp_UGT_I16:
  8593. CEOP_CMP(> , uint16);
  8594. break;
  8595. case CeOp_Cmp_UGT_I32:
  8596. CEOP_CMP(> , uint32);
  8597. break;
  8598. case CeOp_Cmp_UGT_I64:
  8599. CEOP_CMP(> , uint64);
  8600. break;
  8601. case CeOp_Cmp_SGE_I8:
  8602. CEOP_CMP(>= , int8);
  8603. break;
  8604. case CeOp_Cmp_SGE_I16:
  8605. CEOP_CMP(>= , int16);
  8606. break;
  8607. case CeOp_Cmp_SGE_I32:
  8608. CEOP_CMP(>= , int32);
  8609. break;
  8610. case CeOp_Cmp_SGE_I64:
  8611. CEOP_CMP(>= , int64);
  8612. break;
  8613. case CeOp_Cmp_SGE_F32:
  8614. CEOP_CMP(>= , float);
  8615. break;
  8616. case CeOp_Cmp_SGE_F64:
  8617. CEOP_CMP(>= , double);
  8618. break;
  8619. case CeOp_Cmp_UGE_I8:
  8620. CEOP_CMP(>= , uint8);
  8621. break;
  8622. case CeOp_Cmp_UGE_I16:
  8623. CEOP_CMP(>= , uint16);
  8624. break;
  8625. case CeOp_Cmp_UGE_I32:
  8626. CEOP_CMP(>= , uint32);
  8627. break;
  8628. case CeOp_Cmp_UGE_I64:
  8629. CEOP_CMP(>= , uint64);
  8630. break;
  8631. case CeOp_Neg_I8:
  8632. CEOP_UNARY(-, int8);
  8633. break;
  8634. case CeOp_Neg_I16:
  8635. CEOP_UNARY(-, int16);
  8636. break;
  8637. case CeOp_Neg_I32:
  8638. CEOP_UNARY(-, int32);
  8639. break;
  8640. case CeOp_Neg_I64:
  8641. CEOP_UNARY(-, int64);
  8642. break;
  8643. case CeOp_Neg_F32:
  8644. CEOP_UNARY(-, float);
  8645. break;
  8646. case CeOp_Neg_F64:
  8647. CEOP_UNARY(-, double);
  8648. break;
  8649. case CeOp_Not_I1:
  8650. CEOP_UNARY(!, bool);
  8651. break;
  8652. case CeOp_Not_I8:
  8653. CEOP_UNARY(~, int8);
  8654. break;
  8655. case CeOp_Not_I16:
  8656. CEOP_UNARY(~, int16);
  8657. break;
  8658. case CeOp_Not_I32:
  8659. CEOP_UNARY(~, int32);
  8660. break;
  8661. case CeOp_Not_I64:
  8662. CEOP_UNARY(~, int64);
  8663. break;
  8664. default:
  8665. _Fail("Unhandled op");
  8666. return false;
  8667. }
  8668. //BF_ASSERT(_CrtCheckMemory() != 0);
  8669. }
  8670. return true;
  8671. }
  8672. //////////////////////////////////////////////////////////////////////////
  8673. CeMachine::CeMachine(BfCompiler* compiler)
  8674. {
  8675. mCompiler = compiler;
  8676. mCeModule = NULL;
  8677. mRevision = 0;
  8678. mMethodBindRevision = 0;
  8679. mCurContext = NULL;
  8680. mCurCallSource = NULL;
  8681. mExecuteId = -1;
  8682. mCurRecursiveDepth = 0;
  8683. mCurFunctionId = 0;
  8684. mRevisionExecuteTime = 0;
  8685. mCurBuilder = NULL;
  8686. mPreparingFunction = NULL;
  8687. mCurEmitContext = NULL;
  8688. mAppendAllocInfo = NULL;
  8689. mTempParser = NULL;
  8690. mTempReducer = NULL;
  8691. mTempPassInstance = NULL;
  8692. mDebugger = NULL;
  8693. mDbgPaused = false;
  8694. mDbgWantBreak = false;
  8695. mSpecialCheck = false;
  8696. BfLogSys(mCompiler->mSystem, "CeMachine::CeMachine %p\n", this);
  8697. }
  8698. CeMachine::~CeMachine()
  8699. {
  8700. BF_ASSERT(mDebugger == NULL);
  8701. for (auto context : mContextList)
  8702. delete context;
  8703. delete mTempPassInstance;
  8704. delete mTempParser;
  8705. delete mTempReducer;
  8706. delete mAppendAllocInfo;
  8707. delete mCeModule;
  8708. auto _RemoveFunctionInfo = [&](CeFunctionInfo* functionInfo)
  8709. {
  8710. if (functionInfo->mMethodInstance != NULL)
  8711. functionInfo->mMethodInstance->mInCEMachine = false;
  8712. if (functionInfo->mCeFunction != NULL)
  8713. {
  8714. // We don't need to actually unmap it at this point
  8715. functionInfo->mCeFunction->mId = -1;
  8716. for (auto innerFunction : functionInfo->mCeFunction->mInnerFunctions)
  8717. innerFunction->mId = -1;
  8718. }
  8719. delete functionInfo;
  8720. };
  8721. for (auto kv : mNamedFunctionMap)
  8722. {
  8723. if (kv.mValue->mMethodInstance == NULL)
  8724. _RemoveFunctionInfo(kv.mValue);
  8725. }
  8726. for (auto kv : mFunctions)
  8727. {
  8728. BF_ASSERT(kv.mValue != NULL);
  8729. _RemoveFunctionInfo(kv.mValue);
  8730. }
  8731. }
  8732. void CeMachine::Fail(const StringImpl& error)
  8733. {
  8734. if (mFailString.IsEmpty())
  8735. mFailString = error;
  8736. }
  8737. bool CeMachine::HasFailed()
  8738. {
  8739. return !mFailString.IsEmpty();
  8740. }
  8741. void CeMachine::Init()
  8742. {
  8743. BF_ASSERT(mCeModule == NULL);
  8744. mCeModule = new BfModule(mCompiler->mContext, "__constEval");
  8745. mCeModule->mIsSpecialModule = true;
  8746. //mCeModule->mIsScratchModule = true;
  8747. mCeModule->mIsComptimeModule = true;
  8748. //mCeModule->mIsReified = true;
  8749. if (mCompiler->mIsResolveOnly)
  8750. mCeModule->mIsReified = true;
  8751. else
  8752. mCeModule->mIsReified = false;
  8753. mCeModule->Init();
  8754. BF_ASSERT(mCeModule->mBfIRBuilder == NULL);
  8755. mCeModule->mBfIRBuilder = new BfIRBuilder(mCeModule);
  8756. mCeModule->mBfIRBuilder->mDbgVerifyCodeGen = true;
  8757. mCeModule->FinishInit();
  8758. mCeModule->mBfIRBuilder->mHasDebugInfo = true;
  8759. mCeModule->mHasFullDebugInfo = mDebugger != NULL;
  8760. mCeModule->mBfIRBuilder->mIgnoreWrites = false;
  8761. mCeModule->mWantsIRIgnoreWrites = false;
  8762. }
  8763. BeContext* CeMachine::GetBeContext()
  8764. {
  8765. if (mCeModule == NULL)
  8766. return NULL;
  8767. return mCeModule->mBfIRBuilder->mBeIRCodeGen->mBeContext;
  8768. }
  8769. BeModule* CeMachine::GetBeModule()
  8770. {
  8771. if (mCeModule == NULL)
  8772. return NULL;
  8773. return mCeModule->mBfIRBuilder->mBeIRCodeGen->mBeModule;
  8774. }
  8775. void CeMachine::CompileStarted()
  8776. {
  8777. mRevisionExecuteTime = 0;
  8778. mSpecialCheck = false;
  8779. mRevision++;
  8780. mMethodBindRevision++;
  8781. mDbgWantBreak = false;
  8782. mFailString.Clear();
  8783. if (mCeModule != NULL)
  8784. {
  8785. delete mCeModule;
  8786. mCeModule = NULL;
  8787. }
  8788. }
  8789. void CeMachine::CompileDone()
  8790. {
  8791. // So things like deleted local methods get rechecked
  8792. mRevision++;
  8793. mMethodBindRevision++;
  8794. mTypeInfoMap.Clear();
  8795. mMethodInstanceSet.Clear();
  8796. }
  8797. #define CE_SIZE_GET(T) *((T*)(ptr += sizeof(T)) - 1)
  8798. int CeMachine::GetInstSize(CeFunction* ceFunction, int instIdx)
  8799. {
  8800. auto ptr = &ceFunction->mCode[instIdx];
  8801. auto startPtr = ptr;
  8802. auto _HandleOperand = [&](CeOperandInfoKind kind)
  8803. {
  8804. switch (kind)
  8805. {
  8806. case CEOI_FrameRef:
  8807. case CEOI_FrameRef8:
  8808. case CEOI_FrameRef16:
  8809. case CEOI_FrameRef32:
  8810. case CEOI_FrameRef64:
  8811. case CEOI_FrameRefF32:
  8812. case CEOI_FrameRefF64:
  8813. ptr += 4;
  8814. break;
  8815. case CEOI_IMM8:
  8816. ptr += 1;
  8817. break;
  8818. case CEOI_IMM16:
  8819. ptr += 2;
  8820. break;
  8821. case CEOI_IMM32:
  8822. ptr += 4;
  8823. break;
  8824. case CEOI_IMM64:
  8825. ptr += 8;
  8826. break;
  8827. case CEOI_IMM_VAR:
  8828. {
  8829. int32 size = CE_SIZE_GET(int32);
  8830. ptr += size;
  8831. }
  8832. break;
  8833. case CEOI_JMPREL:
  8834. ptr += 4;
  8835. break;
  8836. default:
  8837. BF_ASSERT("Unhandled");
  8838. }
  8839. };
  8840. auto op = CE_SIZE_GET(CeOp);
  8841. if (op == CeOp_DbgBreak)
  8842. {
  8843. CeBreakpointBind* breakpointEntry = NULL;
  8844. if (ceFunction->mBreakpoints.TryGetValue(instIdx, &breakpointEntry))
  8845. op = breakpointEntry->mPrevOpCode;
  8846. }
  8847. CeOpInfo& opInfo = gOpInfo[op];
  8848. _HandleOperand(opInfo.mResultKind);
  8849. if ((opInfo.mFlags & CeOpInfoFlag_SizeX) != 0)
  8850. ptr += 4;
  8851. _HandleOperand(opInfo.mOperandA);
  8852. _HandleOperand(opInfo.mOperandB);
  8853. _HandleOperand(opInfo.mOperandC);
  8854. return (int)(ptr - startPtr);
  8855. }
  8856. void CeMachine::DerefMethodInfo(CeFunctionInfo* ceFunctionInfo)
  8857. {
  8858. ceFunctionInfo->mRefCount--;
  8859. if (ceFunctionInfo->mRefCount > 0)
  8860. return;
  8861. BF_ASSERT(ceFunctionInfo->mMethodInstance == NULL);
  8862. if (!ceFunctionInfo->mName.IsEmpty())
  8863. {
  8864. auto itr = mNamedFunctionMap.Find(ceFunctionInfo->mName);
  8865. if (itr->mValue == ceFunctionInfo)
  8866. mNamedFunctionMap.Remove(itr);
  8867. }
  8868. delete ceFunctionInfo;
  8869. }
  8870. void CeMachine::RemoveFunc(CeFunction* ceFunction)
  8871. {
  8872. mFunctionIdMap.Remove(ceFunction->mId);
  8873. ceFunction->mId = -1;
  8874. }
  8875. void CeMachine::RemoveMethod(BfMethodInstance* methodInstance)
  8876. {
  8877. BfLogSys(methodInstance->GetOwner()->mModule->mSystem, "CeMachine::RemoveMethod %p\n", methodInstance);
  8878. mMethodBindRevision++;
  8879. auto itr = mFunctions.Find(methodInstance);
  8880. auto ceFunctionInfo = itr->mValue;
  8881. BF_ASSERT(itr != mFunctions.end());
  8882. if (itr != mFunctions.end())
  8883. {
  8884. if (ceFunctionInfo->mMethodInstance == methodInstance)
  8885. {
  8886. auto ceFunction = ceFunctionInfo->mCeFunction;
  8887. for (auto& callEntry : ceFunction->mCallTable)
  8888. {
  8889. if (callEntry.mFunctionInfo != NULL)
  8890. DerefMethodInfo(callEntry.mFunctionInfo);
  8891. }
  8892. if (ceFunction->mId != -1)
  8893. {
  8894. RemoveFunc(ceFunction);
  8895. for (auto innerFunction : ceFunction->mInnerFunctions)
  8896. RemoveFunc(innerFunction);
  8897. }
  8898. delete ceFunction;
  8899. ceFunctionInfo->mCeFunction = NULL;
  8900. ceFunctionInfo->mMethodInstance = NULL;
  8901. if (methodInstance->mMethodDef->mIsLocalMethod)
  8902. {
  8903. // We can't rebuild these anyway
  8904. }
  8905. else if (ceFunctionInfo->mRefCount > 1)
  8906. {
  8907. // Generate a methodref
  8908. ceFunctionInfo->mMethodRef = methodInstance;
  8909. }
  8910. DerefMethodInfo(ceFunctionInfo);
  8911. }
  8912. mFunctions.Remove(itr);
  8913. }
  8914. methodInstance->mInCEMachine = false;
  8915. }
  8916. CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constVal, CeContext* ceContext, CeBuilder* ceBuilder)
  8917. {
  8918. auto ceModule = mCeModule;
  8919. auto beType = constVal->GetType();
  8920. if (auto globalVar = BeValueDynCast<BeGlobalVariable>(constVal))
  8921. {
  8922. if (globalVar->mName.StartsWith("__bfStrObj"))
  8923. {
  8924. int stringId = atoi(globalVar->mName.c_str() + 10);
  8925. addr_ce stringAddr;
  8926. if (data.mQueueFixups)
  8927. {
  8928. stringAddr = 0;
  8929. CeConstStructFixup fixup;
  8930. fixup.mKind = CeConstStructFixup::Kind_StringPtr;
  8931. fixup.mValue = stringId;
  8932. fixup.mOffset = (int)data.mData.mSize;
  8933. data.mFixups.Add(fixup);
  8934. }
  8935. else
  8936. {
  8937. stringAddr = ceContext->GetString(stringId);
  8938. }
  8939. auto ptr = data.mData.GrowUninitialized(ceModule->mSystem->mPtrSize);
  8940. int64 addr64 = stringAddr;
  8941. memcpy(ptr, &addr64, ceModule->mSystem->mPtrSize);
  8942. return CeErrorKind_None;
  8943. }
  8944. if (globalVar->mInitializer == NULL)
  8945. {
  8946. auto ptr = data.mData.GrowUninitialized(ceModule->mSystem->mPtrSize);
  8947. int64 addr64 = (addr_ce)0;
  8948. memcpy(ptr, &addr64, ceModule->mSystem->mPtrSize);
  8949. return CeErrorKind_None;
  8950. //TODO: Add this global variable in there and fixup
  8951. // CeStaticFieldInfo* staticFieldInfoPtr = NULL;
  8952. // if (mCeMachine->mStaticFieldMap.TryGetValue(globalVar->mName, &staticFieldInfoPtr))
  8953. // {
  8954. // CeStaticFieldInfo* staticFieldInfo = staticFieldInfoPtr;
  8955. //
  8956. // int* staticFieldTableIdxPtr = NULL;
  8957. // if (mStaticFieldMap.TryAdd(globalVar, NULL, &staticFieldTableIdxPtr))
  8958. // {
  8959. // CeStaticFieldEntry staticFieldEntry;
  8960. // staticFieldEntry.mTypeId = staticFieldInfo->mFieldInstance->mOwner->mTypeId;
  8961. // staticFieldEntry.mName = globalVar->mName;
  8962. // staticFieldEntry.mSize = globalVar->mType->mSize;
  8963. // *staticFieldTableIdxPtr = (int)mCeFunction->mStaticFieldTable.size();
  8964. // mCeFunction->mStaticFieldTable.Add(staticFieldEntry);
  8965. // }
  8966. //
  8967. // auto result = FrameAlloc(mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType));
  8968. //
  8969. // Emit(CeOp_GetStaticField);
  8970. // EmitFrameOffset(result);
  8971. // Emit((int32)*staticFieldTableIdxPtr);
  8972. //
  8973. // return result;
  8974. // }
  8975. // return CeErrorKind_GlobalVariable;
  8976. }
  8977. BF_ASSERT(!data.mQueueFixups);
  8978. CeConstStructData gvData;
  8979. auto result = WriteConstant(gvData, globalVar->mInitializer, ceContext, NULL);
  8980. if (result != CeErrorKind_None)
  8981. return result;
  8982. uint8* gvPtr = ceContext->CeMalloc(gvData.mData.mSize);
  8983. memcpy(gvPtr, gvData.mData.mVals, gvData.mData.mSize);
  8984. auto ptr = data.mData.GrowUninitialized(ceModule->mSystem->mPtrSize);
  8985. int64 addr64 = (addr_ce)(gvPtr - ceContext->mMemory.mVals);
  8986. memcpy(ptr, &addr64, mCeModule->mSystem->mPtrSize);
  8987. return CeErrorKind_None;
  8988. }
  8989. else if (auto beTypeOfConst = BeValueDynCast<BeTypeOfConstant>(constVal))
  8990. {
  8991. if (ceBuilder != NULL)
  8992. {
  8993. // Fake it to not break debugging
  8994. auto ptr = data.mData.GrowUninitialized(ceModule->mSystem->mPtrSize);
  8995. int64 addr64 = beTypeOfConst->mBfTypeId;
  8996. memcpy(ptr, &addr64, ceModule->mSystem->mPtrSize);
  8997. }
  8998. return CeErrorKind_None;
  8999. return CeErrorKind_Error;
  9000. }
  9001. else if (auto beFunc = BeValueDynCast<BeFunction>(constVal))
  9002. {
  9003. return CeErrorKind_FunctionPointer;
  9004. }
  9005. else if (auto constStruct = BeValueDynCast<BeStructConstant>(constVal))
  9006. {
  9007. int startOfs = data.mData.mSize;
  9008. if (constStruct->mType->mTypeCode == BeTypeCode_Struct)
  9009. {
  9010. BeStructType* structType = (BeStructType*)constStruct->mType;
  9011. BF_ASSERT(structType->mMembers.size() == constStruct->mMemberValues.size());
  9012. for (int memberIdx = 0; memberIdx < (int)constStruct->mMemberValues.size(); memberIdx++)
  9013. {
  9014. auto& member = structType->mMembers[memberIdx];
  9015. // Do any per-member alignment
  9016. int wantZeroes = member.mByteOffset - (data.mData.mSize - startOfs);
  9017. if (wantZeroes > 0)
  9018. data.mData.Insert(data.mData.size(), (uint8)0, wantZeroes);
  9019. auto result = WriteConstant(data, constStruct->mMemberValues[memberIdx], ceContext, ceBuilder);
  9020. if (result != CeErrorKind_None)
  9021. return result;
  9022. }
  9023. // Do end padding
  9024. data.mData.Insert(data.mData.size(), (uint8)0, structType->mSize - (data.mData.mSize - startOfs));
  9025. }
  9026. else if (constStruct->mType->mTypeCode == BeTypeCode_SizedArray)
  9027. {
  9028. for (auto& memberVal : constStruct->mMemberValues)
  9029. {
  9030. auto result = WriteConstant(data, memberVal, ceContext, ceBuilder);
  9031. if (result != CeErrorKind_None)
  9032. return result;
  9033. }
  9034. }
  9035. else
  9036. BF_FATAL("Invalid StructConst type");
  9037. }
  9038. else if (auto constStr = BeValueDynCast<BeStringConstant>(constVal))
  9039. {
  9040. data.mData.Insert(data.mData.mSize, (uint8*)constStr->mString.c_str(), (int)constStr->mString.length() + 1);
  9041. }
  9042. else if (auto constCast = BeValueDynCast<BeCastConstant>(constVal))
  9043. {
  9044. auto result = WriteConstant(data, constCast->mTarget, ceContext, ceBuilder);
  9045. if (result != CeErrorKind_None)
  9046. return result;
  9047. }
  9048. else if (auto constGep = BeValueDynCast<BeGEP2Constant>(constVal))
  9049. {
  9050. if (auto globalVar = BeValueDynCast<BeGlobalVariable>(constGep->mTarget))
  9051. {
  9052. BF_ASSERT(constGep->mIdx0 == 0);
  9053. int64 dataOfs = 0;
  9054. if (globalVar->mType->mTypeCode == BeTypeCode_Struct)
  9055. {
  9056. auto structType = (BeStructType*)globalVar->mType;
  9057. dataOfs = structType->mMembers[constGep->mIdx1].mByteOffset;
  9058. }
  9059. else if (globalVar->mType->mTypeCode == BeTypeCode_SizedArray)
  9060. {
  9061. auto arrayType = (BeSizedArrayType*)globalVar->mType;
  9062. dataOfs = arrayType->mElementType->GetStride() * constGep->mIdx1;
  9063. }
  9064. else
  9065. {
  9066. BF_FATAL("Invalid GEP");
  9067. }
  9068. addr_ce addr = -1;
  9069. if (globalVar->mName.StartsWith("__bfStrData"))
  9070. {
  9071. int stringId = atoi(globalVar->mName.c_str() + 11);
  9072. if (data.mQueueFixups)
  9073. {
  9074. addr = 0;
  9075. CeConstStructFixup fixup;
  9076. fixup.mKind = CeConstStructFixup::Kind_StringCharPtr;
  9077. fixup.mValue = stringId;
  9078. fixup.mOffset = (int)data.mData.mSize;
  9079. data.mFixups.Add(fixup);
  9080. }
  9081. else
  9082. {
  9083. addr_ce stringAddr = ceContext->GetString(stringId);
  9084. BfTypeInstance* stringTypeInst = (BfTypeInstance*)ceModule->ResolveTypeDef(ceModule->mCompiler->mStringTypeDef, BfPopulateType_Data);
  9085. addr = stringAddr + stringTypeInst->mInstSize;
  9086. }
  9087. }
  9088. if (addr != -1)
  9089. {
  9090. auto ptr = data.mData.GrowUninitialized(ceModule->mSystem->mPtrSize);
  9091. int64 addr64 = addr + dataOfs;
  9092. memcpy(ptr, &addr64, ceModule->mSystem->mPtrSize);
  9093. return CeErrorKind_None;
  9094. }
  9095. return CeErrorKind_GlobalVariable;
  9096. // auto sym = GetSymbol(globalVar);
  9097. //
  9098. // BeMCRelocation reloc;
  9099. // reloc.mKind = BeMCRelocationKind_ADDR64;
  9100. // reloc.mOffset = sect.mData.GetPos();
  9101. // reloc.mSymTableIdx = sym->mIdx;
  9102. // sect.mRelocs.push_back(reloc);
  9103. // sect.mData.Write((int64)dataOfs);
  9104. }
  9105. else
  9106. {
  9107. BF_FATAL("Invalid GEPConstant");
  9108. }
  9109. }
  9110. /*else if ((beType->IsPointer()) && (constVal->mTarget != NULL))
  9111. {
  9112. auto result = WriteConstant(arr, constVal->mTarget);
  9113. if (result != CeErrorKind_None)
  9114. return result;
  9115. }
  9116. else if (beType->IsComposite())
  9117. {
  9118. BF_ASSERT(constVal->mInt64 == 0);
  9119. int64 zero = 0;
  9120. int sizeLeft = beType->mSize;
  9121. while (sizeLeft > 0)
  9122. {
  9123. int writeSize = BF_MIN(sizeLeft, 8);
  9124. auto ptr = arr.GrowUninitialized(writeSize);
  9125. memset(ptr, 0, writeSize);
  9126. sizeLeft -= writeSize;
  9127. }
  9128. }*/
  9129. else if (BeValueDynCastExact<BeConstant>(constVal) != NULL)
  9130. {
  9131. if (constVal->mType->IsStruct())
  9132. {
  9133. if (constVal->mType->mSize > 0)
  9134. {
  9135. auto ptr = data.mData.GrowUninitialized(constVal->mType->mSize);
  9136. memset(ptr, 0, constVal->mType->mSize);
  9137. }
  9138. }
  9139. else
  9140. {
  9141. auto ptr = data.mData.GrowUninitialized(beType->mSize);
  9142. memcpy(ptr, &constVal->mInt64, beType->mSize);
  9143. }
  9144. }
  9145. else
  9146. return CeErrorKind_Error;
  9147. return CeErrorKind_None;
  9148. }
  9149. void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
  9150. {
  9151. ceFunction->mFunctionKind = CeFunctionKind_Normal;
  9152. if (ceFunction->mMethodInstance != NULL)
  9153. {
  9154. auto methodDef = ceFunction->mMethodInstance->mMethodDef;
  9155. if (methodDef->mIsExtern)
  9156. {
  9157. ceFunction->mFunctionKind = CeFunctionKind_Extern;
  9158. auto owner = ceFunction->mMethodInstance->GetOwner();
  9159. if (owner == mCeModule->mContext->mBfObjectType)
  9160. {
  9161. if (methodDef->mName == "Comptime_GetType")
  9162. {
  9163. ceFunction->mFunctionKind = CeFunctionKind_GetReflectType;
  9164. }
  9165. }
  9166. else if (owner->IsInstanceOf(mCeModule->mCompiler->mTypeTypeDef))
  9167. {
  9168. if (methodDef->mName == "Comptime_GetTypeDeclarationById")
  9169. {
  9170. ceFunction->mFunctionKind = CeFunctionKind_GetReflectTypeDeclById;
  9171. }
  9172. if (methodDef->mName == "Comptime_GetTypeDeclarationByName")
  9173. {
  9174. ceFunction->mFunctionKind = CeFunctionKind_GetReflectTypeDeclByName;
  9175. }
  9176. else if (methodDef->mName == "Comptime_GetNextTypeDeclaration")
  9177. {
  9178. ceFunction->mFunctionKind = CeFunctionKind_GetReflectNextTypeDecl;
  9179. }
  9180. else if (methodDef->mName == "Comptime_Type_GetBaseType")
  9181. {
  9182. ceFunction->mFunctionKind = CeFunctionKind_GetBaseType;
  9183. }
  9184. else if (methodDef->mName == "Comptime_Type_HasDeclaredMember")
  9185. {
  9186. ceFunction->mFunctionKind = CeFunctionKind_HasDeclaredMember;
  9187. }
  9188. else if (methodDef->mName == "Comptime_GetTypeById")
  9189. {
  9190. ceFunction->mFunctionKind = CeFunctionKind_GetReflectTypeById;
  9191. }
  9192. else if (methodDef->mName == "Comptime_GetWrappedType")
  9193. {
  9194. ceFunction->mFunctionKind = CeFunctionKind_GetWrappedType;
  9195. }
  9196. else if (methodDef->mName == "Comptime_GetTypeByName")
  9197. {
  9198. ceFunction->mFunctionKind = CeFunctionKind_GetReflectTypeByName;
  9199. }
  9200. else if (methodDef->mName == "Comptime_GetSpecializedType")
  9201. {
  9202. ceFunction->mFunctionKind = CeFunctionKind_GetReflectSpecializedType;
  9203. }
  9204. else if (methodDef->mName == "Comptime_Type_ToString")
  9205. {
  9206. ceFunction->mFunctionKind = CeFunctionKind_Type_ToString;
  9207. }
  9208. else if (methodDef->mName == "Comptime_TypeName_ToString")
  9209. {
  9210. ceFunction->mFunctionKind = CeFunctionKind_TypeName_ToString;
  9211. }
  9212. else if (methodDef->mName == "Comptime_TypeDocumentation_ToString")
  9213. {
  9214. ceFunction->mFunctionKind = CeFunctionKind_TypeDocumentation_ToString;
  9215. }
  9216. else if (methodDef->mName == "Comptime_Namespace_ToString")
  9217. {
  9218. ceFunction->mFunctionKind = CeFunctionKind_Namespace_ToString;
  9219. }
  9220. else if (methodDef->mName == "Comptime_Type_GetCustomAttribute")
  9221. {
  9222. ceFunction->mFunctionKind = CeFunctionKind_Type_GetCustomAttribute;
  9223. }
  9224. else if (methodDef->mName == "Comptime_Field_GetCustomAttribute")
  9225. {
  9226. ceFunction->mFunctionKind = CeFunctionKind_Field_GetCustomAttribute;
  9227. }
  9228. else if (methodDef->mName == "Comptime_Method_GetCustomAttribute")
  9229. {
  9230. ceFunction->mFunctionKind = CeFunctionKind_Method_GetCustomAttribute;
  9231. }
  9232. else if (methodDef->mName == "Comptime_Type_GetCustomAttributeType")
  9233. {
  9234. ceFunction->mFunctionKind = CeFunctionKind_Type_GetCustomAttributeType;
  9235. }
  9236. else if (methodDef->mName == "Comptime_Field_GetCustomAttributeType")
  9237. {
  9238. ceFunction->mFunctionKind = CeFunctionKind_Field_GetCustomAttributeType;
  9239. }
  9240. else if (methodDef->mName == "Comptime_Method_GetCustomAttributeType")
  9241. {
  9242. ceFunction->mFunctionKind = CeFunctionKind_Method_GetCustomAttributeType;
  9243. }
  9244. else if (methodDef->mName == "Comptime_GetMethod")
  9245. {
  9246. ceFunction->mFunctionKind = CeFunctionKind_GetMethod;
  9247. }
  9248. else if (methodDef->mName == "Comptime_GetMethodCount")
  9249. {
  9250. ceFunction->mFunctionKind = CeFunctionKind_GetMethodCount;
  9251. }
  9252. else if (methodDef->mName == "Comptime_Method_ToString")
  9253. {
  9254. ceFunction->mFunctionKind = CeFunctionKind_Method_ToString;
  9255. }
  9256. else if (methodDef->mName == "Comptime_Method_GetName")
  9257. {
  9258. ceFunction->mFunctionKind = CeFunctionKind_Method_GetName;
  9259. }
  9260. else if (methodDef->mName == "Comptime_Method_GetDocumentation")
  9261. {
  9262. ceFunction->mFunctionKind = CeFunctionKind_Method_GetDocumentation;
  9263. }
  9264. else if (methodDef->mName == "Comptime_Method_GetInfo")
  9265. {
  9266. ceFunction->mFunctionKind = CeFunctionKind_Method_GetInfo;
  9267. }
  9268. else if (methodDef->mName == "Comptime_Method_GetParamInfo")
  9269. {
  9270. ceFunction->mFunctionKind = CeFunctionKind_Method_GetParamInfo;
  9271. }
  9272. else if (methodDef->mName == "Comptime_Method_GetGenericArg")
  9273. {
  9274. ceFunction->mFunctionKind = CeFunctionKind_Method_GetGenericArg;
  9275. }
  9276. else if (methodDef->mName == "Comptime_Field_GetDocumentation")
  9277. {
  9278. ceFunction->mFunctionKind = CeFunctionKind_Field_GetDocumentation;
  9279. }
  9280. else if (methodDef->mName == "Comptime_Field_GetStatic")
  9281. {
  9282. ceFunction->mFunctionKind = CeFunctionKind_Field_GetStatic;
  9283. }
  9284. }
  9285. else if (owner->IsInstanceOf(mCeModule->mCompiler->mCompilerTypeDef))
  9286. {
  9287. if (methodDef->mName == "Comptime_SetReturnType")
  9288. {
  9289. ceFunction->mFunctionKind = CeFunctionKind_SetReturnType;
  9290. }
  9291. else if (methodDef->mName == "Comptime_Align")
  9292. {
  9293. ceFunction->mFunctionKind = CeFunctionKind_Align;
  9294. }
  9295. else if (methodDef->mName == "Comptime_EmitTypeBody")
  9296. {
  9297. ceFunction->mFunctionKind = CeFunctionKind_EmitTypeBody;
  9298. }
  9299. else if (methodDef->mName == "Comptime_EmitAddInterface")
  9300. {
  9301. ceFunction->mFunctionKind = CeFunctionKind_EmitAddInterface;
  9302. }
  9303. else if (methodDef->mName == "Comptime_EmitMethodEntry")
  9304. {
  9305. ceFunction->mFunctionKind = CeFunctionKind_EmitMethodEntry;
  9306. }
  9307. else if (methodDef->mName == "Comptime_EmitMethodExit")
  9308. {
  9309. ceFunction->mFunctionKind = CeFunctionKind_EmitMethodExit;
  9310. }
  9311. else if (methodDef->mName == "Comptime_EmitMixin")
  9312. {
  9313. ceFunction->mFunctionKind = CeFunctionKind_EmitMixin;
  9314. }
  9315. else if (methodDef->mName == "Comptime_GetStringById")
  9316. {
  9317. ceFunction->mFunctionKind = CeFunctionKind_GetStringById;
  9318. }
  9319. }
  9320. else if (owner->IsInstanceOf(mCeModule->mCompiler->mDiagnosticsDebugTypeDef))
  9321. {
  9322. if (methodDef->mName == "Write")
  9323. {
  9324. if (ceFunction->mMethodInstance->GetParamCount() == 1)
  9325. ceFunction->mFunctionKind = CeFunctionKind_DebugWrite_Int;
  9326. else
  9327. ceFunction->mFunctionKind = CeFunctionKind_DebugWrite;
  9328. }
  9329. }
  9330. else if (owner->IsInstanceOf(mCeModule->mCompiler->mThreadTypeDef))
  9331. {
  9332. if (methodDef->mName == "SleepInternal")
  9333. ceFunction->mFunctionKind = CeFunctionKind_Sleep;
  9334. }
  9335. else if (owner->IsInstanceOf(mCeModule->mCompiler->mInternalTypeDef))
  9336. {
  9337. if (methodDef->mName == "ThrowIndexOutOfRange")
  9338. ceFunction->mFunctionKind = CeFunctionKind_OOB;
  9339. else if (methodDef->mName == "ThrowObjectNotInitialized")
  9340. ceFunction->mFunctionKind = CeFunctionKind_ObjectNotInitialized;
  9341. else if (methodDef->mName == "FatalError")
  9342. ceFunction->mFunctionKind = CeFunctionKind_FatalError;
  9343. else if (methodDef->mName == "Dbg_RawAlloc")
  9344. ceFunction->mFunctionKind = CeFunctionKind_Malloc;
  9345. else if (methodDef->mName == "Dbg_RawFree")
  9346. ceFunction->mFunctionKind = CeFunctionKind_Free;
  9347. else if (methodDef->mName == "ObjectDynCheckFailed")
  9348. ceFunction->mFunctionKind = CeFunctionKind_DynCheckFailed;
  9349. }
  9350. else if (owner->IsInstanceOf(mCeModule->mCompiler->mPlatformTypeDef))
  9351. {
  9352. if (methodDef->mName == "BfpDirectory_Create")
  9353. ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_Create;
  9354. else if (methodDef->mName == "BfpDirectory_Rename")
  9355. ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_Rename;
  9356. else if (methodDef->mName == "BfpDirectory_Delete")
  9357. ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_Delete;
  9358. else if (methodDef->mName == "BfpDirectory_GetCurrent")
  9359. ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_GetCurrent;
  9360. else if (methodDef->mName == "BfpDirectory_SetCurrent")
  9361. ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_SetCurrent;
  9362. else if (methodDef->mName == "BfpDirectory_Exists")
  9363. ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_Exists;
  9364. else if (methodDef->mName == "BfpDirectory_GetSysDirectory")
  9365. ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_GetSysDirectory;
  9366. else if (methodDef->mName == "BfpFile_Close")
  9367. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Close;
  9368. else if (methodDef->mName == "BfpFile_Create")
  9369. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Create;
  9370. else if (methodDef->mName == "BfpFile_Flush")
  9371. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Flush;
  9372. else if (methodDef->mName == "BfpFile_GetFileSize")
  9373. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_GetFileSize;
  9374. else if (methodDef->mName == "BfpFile_Read")
  9375. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Read;
  9376. else if (methodDef->mName == "BfpFile_Release")
  9377. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Release;
  9378. else if (methodDef->mName == "BfpFile_Seek")
  9379. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Seek;
  9380. else if (methodDef->mName == "BfpFile_Truncate")
  9381. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Truncate;
  9382. else if (methodDef->mName == "BfpFile_Write")
  9383. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Write;
  9384. else if (methodDef->mName == "BfpFile_GetTime_LastWrite")
  9385. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_GetTime_LastWrite;
  9386. else if (methodDef->mName == "BfpFile_GetAttributes")
  9387. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_GetAttributes;
  9388. else if (methodDef->mName == "BfpFile_SetAttributes")
  9389. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_SetAttributes;
  9390. else if (methodDef->mName == "BfpFile_Copy")
  9391. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Copy;
  9392. else if (methodDef->mName == "BfpFile_Rename")
  9393. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Rename;
  9394. else if (methodDef->mName == "BfpFile_Delete")
  9395. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Delete;
  9396. else if (methodDef->mName == "BfpFile_Exists")
  9397. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Exists;
  9398. else if (methodDef->mName == "BfpFile_GetTempPath")
  9399. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_GetTempPath;
  9400. else if (methodDef->mName == "BfpFile_GetTempFileName")
  9401. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_GetTempFileName;
  9402. else if (methodDef->mName == "BfpFile_GetFullPath")
  9403. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_GetFullPath;
  9404. else if (methodDef->mName == "BfpFile_GetActualPath")
  9405. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_GetActualPath;
  9406. else if (methodDef->mName == "BfpSpawn_Create")
  9407. ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_Create;
  9408. else if (methodDef->mName == "BfpSpawn_GetStdHandles")
  9409. ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_GetStdHandles;
  9410. else if (methodDef->mName == "BfpSpawn_Kill")
  9411. ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_Kill;
  9412. else if (methodDef->mName == "BfpSpawn_Release")
  9413. ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_Release;
  9414. else if (methodDef->mName == "BfpSpawn_WaitFor")
  9415. ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_WaitFor;
  9416. else if (methodDef->mName == "BfpFindFileData_FindFirstFile")
  9417. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_FindFirstFile;
  9418. else if (methodDef->mName == "BfpFindFileData_FindNextFile")
  9419. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_FindNextFile;
  9420. else if (methodDef->mName == "BfpFindFileData_GetFileName")
  9421. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_GetFileName;
  9422. else if (methodDef->mName == "BfpFindFileData_GetTime_LastWrite")
  9423. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_GetTime_LastWrite;
  9424. else if (methodDef->mName == "BfpFindFileData_GetTime_Created")
  9425. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_GetTime_Created;
  9426. else if (methodDef->mName == "BfpFindFileData_GetTime_Access")
  9427. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_GetTime_Access;
  9428. else if (methodDef->mName == "BfpFindFileData_GetFileAttributes")
  9429. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_GetFileAttributes;
  9430. else if (methodDef->mName == "BfpFindFileData_GetFileSize")
  9431. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_GetFileSize;
  9432. else if (methodDef->mName == "BfpFindFileData_Release")
  9433. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_Release;
  9434. else if (methodDef->mName == "BfpSystem_GetTimeStamp")
  9435. ceFunction->mFunctionKind = CeFunctionKind_BfpSystem_GetTimeStamp;
  9436. }
  9437. else if (owner->IsInstanceOf(mCeModule->mCompiler->mChar32TypeDef))
  9438. {
  9439. if (methodDef->mName == "get__ToLower")
  9440. ceFunction->mFunctionKind = CeFunctionKind_Char32_ToLower;
  9441. else if (methodDef->mName == "get__ToUpper")
  9442. ceFunction->mFunctionKind = CeFunctionKind_Char32_ToUpper;
  9443. else if (methodDef->mName == "get__IsLower")
  9444. ceFunction->mFunctionKind = CeFunctionKind_Char32_IsLower;
  9445. else if (methodDef->mName == "get__IsUpper")
  9446. ceFunction->mFunctionKind = CeFunctionKind_Char32_IsUpper;
  9447. else if (methodDef->mName == "get__IsWhiteSpace_EX")
  9448. ceFunction->mFunctionKind = CeFunctionKind_Char32_IsWhiteSpace_EX;
  9449. else if (methodDef->mName == "get__IsLetter")
  9450. ceFunction->mFunctionKind = CeFunctionKind_Char32_IsLetter;
  9451. else if (methodDef->mName == "get__IsLetterOrDigit")
  9452. ceFunction->mFunctionKind = CeFunctionKind_Char32_IsLetterOrDigit;
  9453. else if (methodDef->mName == "get__IsNumer")
  9454. ceFunction->mFunctionKind = CeFunctionKind_Char32_IsNumber;
  9455. }
  9456. else if (owner->IsInstanceOf(mCeModule->mCompiler->mDoubleTypeDef))
  9457. {
  9458. if (methodDef->mName == "strtod")
  9459. ceFunction->mFunctionKind = CeFunctionKind_Double_Strtod;
  9460. else if (methodDef->mName == "ftoa")
  9461. ceFunction->mFunctionKind = CeFunctionKind_Double_Ftoa;
  9462. if (methodDef->mName == "ToString")
  9463. ceFunction->mFunctionKind = CeFunctionKind_Double_ToString;
  9464. }
  9465. else if (owner->IsInstanceOf(mCeModule->mCompiler->mFloatTypeDef))
  9466. {
  9467. if (methodDef->mName == "ftoa")
  9468. ceFunction->mFunctionKind = CeFunctionKind_Double_Ftoa;
  9469. if (methodDef->mName == "ToString")
  9470. ceFunction->mFunctionKind = CeFunctionKind_Float_ToString;
  9471. }
  9472. else if (owner->IsInstanceOf(mCeModule->mCompiler->mMathTypeDef))
  9473. {
  9474. if (methodDef->mName == "Abs")
  9475. ceFunction->mFunctionKind = CeFunctionKind_Math_Abs;
  9476. else if (methodDef->mName == "Acos")
  9477. ceFunction->mFunctionKind = CeFunctionKind_Math_Acos;
  9478. else if (methodDef->mName == "Asin")
  9479. ceFunction->mFunctionKind = CeFunctionKind_Math_Asin;
  9480. else if (methodDef->mName == "Atan")
  9481. ceFunction->mFunctionKind = CeFunctionKind_Math_Atan;
  9482. else if (methodDef->mName == "Atan2")
  9483. ceFunction->mFunctionKind = CeFunctionKind_Math_Atan2;
  9484. else if (methodDef->mName == "Ceiling")
  9485. ceFunction->mFunctionKind = CeFunctionKind_Math_Ceiling;
  9486. else if (methodDef->mName == "Cos")
  9487. ceFunction->mFunctionKind = CeFunctionKind_Math_Cos;
  9488. else if (methodDef->mName == "Cosh")
  9489. ceFunction->mFunctionKind = CeFunctionKind_Math_Cosh;
  9490. else if (methodDef->mName == "Exp")
  9491. ceFunction->mFunctionKind = CeFunctionKind_Math_Exp;
  9492. else if (methodDef->mName == "Floor")
  9493. ceFunction->mFunctionKind = CeFunctionKind_Math_Floor;
  9494. else if (methodDef->mName == "Log")
  9495. ceFunction->mFunctionKind = CeFunctionKind_Math_Log;
  9496. else if (methodDef->mName == "Log10")
  9497. ceFunction->mFunctionKind = CeFunctionKind_Math_Log10;
  9498. else if (methodDef->mName == "Mod")
  9499. ceFunction->mFunctionKind = CeFunctionKind_Math_Mod;
  9500. else if (methodDef->mName == "Pow")
  9501. ceFunction->mFunctionKind = CeFunctionKind_Math_Pow;
  9502. else if (methodDef->mName == "Round")
  9503. ceFunction->mFunctionKind = CeFunctionKind_Math_Round;
  9504. else if (methodDef->mName == "Sin")
  9505. ceFunction->mFunctionKind = CeFunctionKind_Math_Sin;
  9506. else if (methodDef->mName == "Sinh")
  9507. ceFunction->mFunctionKind = CeFunctionKind_Math_Sinh;
  9508. else if (methodDef->mName == "Sqrt")
  9509. ceFunction->mFunctionKind = CeFunctionKind_Math_Sqrt;
  9510. else if (methodDef->mName == "Tan")
  9511. ceFunction->mFunctionKind = CeFunctionKind_Math_Tan;
  9512. else if (methodDef->mName == "Tanh")
  9513. ceFunction->mFunctionKind = CeFunctionKind_Math_Tanh;
  9514. }
  9515. ceFunction->mInitializeState = CeFunction::InitializeState_Initialized;
  9516. return;
  9517. }
  9518. }
  9519. }
  9520. void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder)
  9521. {
  9522. AutoTimer autoTimer(mRevisionExecuteTime);
  9523. SetAndRestoreValue<CeFunction*> prevCEFunction(mPreparingFunction, ceFunction);
  9524. BF_ASSERT(ceFunction->mInitializeState <= CeFunction::InitializeState_Initialized);
  9525. if (ceFunction->mFunctionKind == CeFunctionKind_NotSet)
  9526. {
  9527. CheckFunctionKind(ceFunction);
  9528. if (ceFunction->mInitializeState == CeFunction::InitializeState_Initialized)
  9529. return;
  9530. }
  9531. BF_ASSERT(ceFunction->mInitializeState <= CeFunction::InitializeState_Initialized);
  9532. if (ceFunction->mInitializeState == CeFunction::InitializeState_Initializing_ReEntry)
  9533. {
  9534. //Fail("Function generation re-entry");
  9535. return;
  9536. }
  9537. if (ceFunction->mInitializeState == CeFunction::InitializeState_Initializing)
  9538. ceFunction->mInitializeState = CeFunction::InitializeState_Initializing_ReEntry;
  9539. else
  9540. ceFunction->mInitializeState = CeFunction::InitializeState_Initializing;
  9541. CeBuilder ceBuilder;
  9542. SetAndRestoreValue<CeBuilder*> prevBuilder(mCurBuilder, &ceBuilder);
  9543. ceBuilder.mParentBuilder = parentBuilder;
  9544. ceBuilder.mPtrSize = mCeModule->mCompiler->mSystem->mPtrSize;
  9545. ceBuilder.mCeMachine = this;
  9546. ceBuilder.mCeFunction = ceFunction;
  9547. SetAndRestoreValue<int> prevRecursiveDepth(mCurRecursiveDepth, mCurRecursiveDepth + 1);
  9548. ceBuilder.mRecursiveDepth = mCurRecursiveDepth;
  9549. ceBuilder.Build();
  9550. ceFunction->mInitializeState = CeFunction::InitializeState_Initialized;
  9551. /*if (!ceFunction->mCode.IsEmpty())
  9552. {
  9553. CeDumpContext dumpCtx;
  9554. dumpCtx.mCeFunction = ceFunction;
  9555. dumpCtx.mStart = &ceFunction->mCode[0];
  9556. dumpCtx.mPtr = dumpCtx.mStart;
  9557. dumpCtx.mEnd = dumpCtx.mPtr + ceFunction->mCode.mSize;
  9558. dumpCtx.Dump();
  9559. OutputDebugStrF("Code for %s:\n%s\n", ceBuilder.mBeFunction->mName.c_str(), dumpCtx.mStr.c_str());
  9560. }*/
  9561. }
  9562. void CeMachine::MapFunctionId(CeFunction* ceFunction)
  9563. {
  9564. if ((mCeModule->mSystem->mPtrSize == 8) && (mDebugger == NULL))
  9565. return;
  9566. ceFunction->mId = ++mCurFunctionId;
  9567. mFunctionIdMap[ceFunction->mId] = ceFunction;
  9568. }
  9569. CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue func, bool& added)
  9570. {
  9571. if (func)
  9572. {
  9573. if ((func.IsConst()) || (func.IsFake()))
  9574. return NULL;
  9575. auto funcVal = mCeModule->mBfIRBuilder->mBeIRCodeGen->TryGetBeValue(func.mId);
  9576. if (funcVal == NULL)
  9577. return NULL;
  9578. }
  9579. CeFunctionInfo** functionInfoPtr = NULL;
  9580. CeFunctionInfo* ceFunctionInfo = NULL;
  9581. CeFunction* ceFunction = NULL;
  9582. if (!mFunctions.TryAdd(methodInstance, NULL, &functionInfoPtr))
  9583. {
  9584. ceFunctionInfo = *functionInfoPtr;
  9585. BF_ASSERT(ceFunctionInfo->mCeFunction != NULL);
  9586. return ceFunctionInfo->mCeFunction;
  9587. }
  9588. BF_ASSERT(!methodInstance->mInCEMachine);
  9589. methodInstance->mInCEMachine = true;
  9590. BfLogSys(mCeModule->mSystem, "CeMachine::GetFunction %p\n", methodInstance);
  9591. if (!func)
  9592. {
  9593. ceFunctionInfo = new CeFunctionInfo();
  9594. }
  9595. else
  9596. {
  9597. auto funcVal = mCeModule->mBfIRBuilder->mBeIRCodeGen->GetBeValue(func.mId);
  9598. if (auto function = BeValueDynCast<BeFunction>(funcVal))
  9599. {
  9600. String funcName = function->mName;
  9601. if (funcName.EndsWith("__INLINE"))
  9602. funcName.RemoveFromEnd(8);
  9603. CeFunctionInfo** namedFunctionInfoPtr = NULL;
  9604. if (mNamedFunctionMap.TryAdd(funcName, NULL, &namedFunctionInfoPtr))
  9605. {
  9606. ceFunctionInfo = new CeFunctionInfo();
  9607. ceFunctionInfo->mName = funcName;
  9608. *namedFunctionInfoPtr = ceFunctionInfo;
  9609. }
  9610. else
  9611. {
  9612. ceFunctionInfo = *namedFunctionInfoPtr;
  9613. if ((ceFunctionInfo->mMethodInstance != NULL) && (ceFunctionInfo->mMethodInstance != methodInstance))
  9614. {
  9615. // This ceFunctionInfo is already taken - probably from a name mangling conflict
  9616. ceFunctionInfo = new CeFunctionInfo();
  9617. }
  9618. }
  9619. }
  9620. else
  9621. {
  9622. ceFunctionInfo = new CeFunctionInfo();
  9623. }
  9624. }
  9625. ceFunctionInfo->mRefCount++;
  9626. *functionInfoPtr = ceFunctionInfo;
  9627. if (ceFunctionInfo->mMethodInstance == NULL)
  9628. {
  9629. added = true;
  9630. auto module = methodInstance->GetOwner()->mModule;
  9631. BF_ASSERT(ceFunctionInfo->mCeFunction == NULL);
  9632. ceFunction = new CeFunction();
  9633. ceFunction->mCeMachine = this;
  9634. ceFunction->mIsVarReturn = methodInstance->mReturnType->IsVar();
  9635. ceFunction->mCeFunctionInfo = ceFunctionInfo;
  9636. ceFunction->mMethodInstance = methodInstance;
  9637. if (mDebugger != NULL)
  9638. ceFunction->mDbgInfo = new CeDbgFunctionInfo();
  9639. ceFunctionInfo->mMethodInstance = methodInstance;
  9640. ceFunctionInfo->mCeFunction = ceFunction;
  9641. MapFunctionId(ceFunction);
  9642. }
  9643. return ceFunction;
  9644. }
  9645. CeFunction* CeMachine::GetPreparedFunction(BfMethodInstance* methodInstance)
  9646. {
  9647. bool added = false;
  9648. auto ceFunction = GetFunction(methodInstance, BfIRValue(), added);
  9649. if (ceFunction == NULL)
  9650. return NULL;
  9651. if (ceFunction->mInitializeState < CeFunction::InitializeState_Initialized)
  9652. PrepareFunction(ceFunction, NULL);
  9653. return ceFunction;
  9654. }
  9655. CeTypeInfo* CeMachine::GetTypeInfo(BfType* type)
  9656. {
  9657. if (type == NULL)
  9658. return NULL;
  9659. auto typeInstance = type->ToTypeInstance();
  9660. if (typeInstance == NULL)
  9661. return NULL;
  9662. CeTypeInfo* ceTypeInfo = NULL;
  9663. if (!mTypeInfoMap.TryAdd(type, NULL, &ceTypeInfo))
  9664. {
  9665. if (ceTypeInfo->mRevision == typeInstance->mRevision)
  9666. return ceTypeInfo;
  9667. ceTypeInfo->mMethodInstances.Clear();
  9668. }
  9669. mCeModule->PopulateType(typeInstance, BfPopulateType_DataAndMethods);
  9670. ceTypeInfo->mRevision = typeInstance->mRevision;
  9671. for (auto& methodGroup : typeInstance->mMethodInstanceGroups)
  9672. {
  9673. if (methodGroup.mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference)
  9674. {
  9675. auto methodDef = typeInstance->mTypeDef->mMethods[methodGroup.mMethodIdx];
  9676. auto flags = ((methodDef->mGenericParams.size() != 0) || (typeInstance->IsUnspecializedType())) ? BfGetMethodInstanceFlag_UnspecializedPass : BfGetMethodInstanceFlag_None;
  9677. flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_MethodInstanceOnly);
  9678. mCeModule->GetMethodInstance(typeInstance, methodDef, BfTypeVector(), flags);
  9679. }
  9680. if (methodGroup.mDefault != NULL)
  9681. {
  9682. mMethodInstanceSet.Add(methodGroup.mDefault);
  9683. ceTypeInfo->mMethodInstances.Add(methodGroup.mDefault);
  9684. }
  9685. if (methodGroup.mMethodSpecializationMap != NULL)
  9686. {
  9687. for (auto& kv : *methodGroup.mMethodSpecializationMap)
  9688. {
  9689. mMethodInstanceSet.Add(kv.mValue);
  9690. ceTypeInfo->mMethodInstances.Add(kv.mValue);
  9691. }
  9692. }
  9693. }
  9694. return ceTypeInfo;
  9695. }
  9696. BfMethodInstance* CeMachine::GetMethodInstance(int64 methodHandle)
  9697. {
  9698. BfMethodInstance* methodInstance = (BfMethodInstance*)(intptr)methodHandle;
  9699. if (!mMethodInstanceSet.Contains(methodInstance))
  9700. return NULL;
  9701. return methodInstance;
  9702. }
  9703. BfFieldInstance* CeMachine::GetFieldInstance(int64 fieldHandle)
  9704. {
  9705. BfFieldInstance* fieldInstance = (BfFieldInstance*)(intptr)fieldHandle;
  9706. if (!mFieldInstanceSet.Contains(fieldInstance))
  9707. return NULL;
  9708. return fieldInstance;
  9709. }
  9710. CeFunction* CeMachine::QueueMethod(BfMethodInstance* methodInstance, BfIRValue func)
  9711. {
  9712. if (mPreparingFunction != NULL)
  9713. {
  9714. auto curOwner = mPreparingFunction->mMethodInstance->GetOwner();
  9715. curOwner->mModule->AddDependency(methodInstance->GetOwner(), curOwner, BfDependencyMap::DependencyFlag_ConstEval);
  9716. }
  9717. bool added = false;
  9718. return GetFunction(methodInstance, func, added);
  9719. }
  9720. void CeMachine::QueueMethod(BfModuleMethodInstance moduleMethodInstance)
  9721. {
  9722. QueueMethod(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc);
  9723. }
  9724. void CeMachine::QueueStaticField(BfFieldInstance* fieldInstance, const StringImpl& mangledFieldName)
  9725. {
  9726. if (mCurBuilder != NULL)
  9727. mCurBuilder->mStaticFieldInstanceMap[mangledFieldName] = fieldInstance;
  9728. }
  9729. void CeMachine::ClearTypeData(BfTypeInstance* typeInstance)
  9730. {
  9731. if (mTypeInfoMap.Remove(typeInstance))
  9732. {
  9733. for (auto& methodGroup : typeInstance->mMethodInstanceGroups)
  9734. {
  9735. if (methodGroup.mDefault != NULL)
  9736. mMethodInstanceSet.Remove(methodGroup.mDefault);
  9737. if (methodGroup.mMethodSpecializationMap != NULL)
  9738. {
  9739. for (auto& kv : *methodGroup.mMethodSpecializationMap)
  9740. mMethodInstanceSet.Remove(kv.mValue);
  9741. }
  9742. }
  9743. }
  9744. }
  9745. void CeMachine::SetAppendAllocInfo(BfModule* module, BfIRValue allocValue, BfIRValue appendSizeValue)
  9746. {
  9747. delete mAppendAllocInfo;
  9748. mAppendAllocInfo = new CeAppendAllocInfo();
  9749. mAppendAllocInfo->mModule = module;
  9750. mAppendAllocInfo->mAllocValue = allocValue;
  9751. mAppendAllocInfo->mAppendSizeValue = appendSizeValue;
  9752. }
  9753. void CeMachine::ClearAppendAllocInfo()
  9754. {
  9755. delete mAppendAllocInfo;
  9756. mAppendAllocInfo = NULL;
  9757. }
  9758. CeContext* CeMachine::AllocContext()
  9759. {
  9760. CeContext* ceContext = NULL;
  9761. if (!mContextList.IsEmpty())
  9762. {
  9763. ceContext = mContextList.back();
  9764. mContextList.pop_back();
  9765. }
  9766. else
  9767. {
  9768. ceContext = new CeContext();
  9769. ceContext->mCeMachine = this;
  9770. ceContext->mMemory.Reserve(BF_CE_INITIAL_MEMORY);
  9771. memset(ceContext->mMemory.mVals, 0, BF_CE_INITIAL_MEMORY);
  9772. }
  9773. ceContext->mCurEmitContext = mCurEmitContext;
  9774. mCurEmitContext = NULL;
  9775. mExecuteId++;
  9776. ceContext->mStackSize = BF_CE_DEFAULT_STACK_SIZE;
  9777. ceContext->mMemory.ResizeRaw(ceContext->mStackSize);
  9778. ceContext->mExecuteId = mExecuteId;
  9779. ceContext->mCurHandleId = 0;
  9780. return ceContext;
  9781. }
  9782. void CeMachine::ReleaseContext(CeContext* ceContext)
  9783. {
  9784. ceContext->mStringMap.Clear();
  9785. delete ceContext->mTypeDeclState;
  9786. ceContext->mTypeDeclState = NULL;
  9787. ceContext->mReflectMap.Clear();
  9788. ceContext->mConstDataMap.Clear();
  9789. ceContext->mMemory.Clear();
  9790. if (ceContext->mMemory.mAllocSize > BF_CE_MAX_CARRYOVER_MEMORY)
  9791. ceContext->mMemory.Dispose();
  9792. ceContext->mStaticCtorExecSet.Clear();
  9793. ceContext->mStaticFieldMap.Clear();
  9794. ceContext->mStaticFieldIdMap.Clear();
  9795. ceContext->mHeap->Clear(BF_CE_MAX_CARRYOVER_HEAP);
  9796. ceContext->mReflectTypeIdOffset = -1;
  9797. mCurEmitContext = ceContext->mCurEmitContext;
  9798. ceContext->mCurEmitContext = NULL;
  9799. mContextList.Add(ceContext);
  9800. for (auto kv : ceContext->mInternalDataMap)
  9801. kv.mValue->Release();
  9802. ceContext->mInternalDataMap.Clear();
  9803. ceContext->mWorkingDir.Clear();
  9804. }
  9805. BfTypedValue CeMachine::Call(CeCallSource callSource, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags, BfType* expectingType)
  9806. {
  9807. auto ceContext = AllocContext();
  9808. SetAndRestoreValue<int> prevRecursiveDepth(mCurRecursiveDepth, mCurRecursiveDepth + 1);
  9809. ceContext->mRecursiveDepth = mCurRecursiveDepth;
  9810. auto result = ceContext->Call(callSource, module, methodInstance, args, flags, expectingType);
  9811. ReleaseContext(ceContext);
  9812. return result;
  9813. }
  9814. BfError* CeMachine::FailCurrent(BfModule* srcModule, const StringImpl& error, BfAstNode* refNode)
  9815. {
  9816. BfError* bfError = NULL;
  9817. if ((mCurBuilder != NULL) &&
  9818. ((mCurContext != NULL) || (mCurBuilder->mRecursiveDepth > mCurContext->mRecursiveDepth)))
  9819. {
  9820. String useError = error;
  9821. useError += StrFormat(" during const-eval generation of '%s'", srcModule->MethodToString(mCurBuilder->mCeFunction->mMethodInstance).c_str());
  9822. bfError = srcModule->Fail(error, refNode);
  9823. if (bfError != NULL)
  9824. {
  9825. auto filePos = mCurBuilder->mCeMachine->mCeModule->mCurFilePosition;
  9826. auto parser = filePos.mFileInstance->mParser;
  9827. if (parser != NULL)
  9828. {
  9829. srcModule->mCompiler->mPassInstance->MoreInfoAt(
  9830. StrFormat("See comptime method '%s' processing location", srcModule->MethodToString(mCurBuilder->mCeFunction->mMethodInstance).c_str()),
  9831. parser, filePos.mCurSrcPos, 1, BfFailFlag_None);
  9832. }
  9833. }
  9834. }
  9835. else
  9836. {
  9837. bfError = srcModule->Fail(error, refNode);
  9838. }
  9839. return bfError;
  9840. }
  9841. void CeMachine::FailCurrentMoreInfo(const StringImpl& error, BfAstNode* refNode)
  9842. {
  9843. }