CeMachine.cpp 314 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826
  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_Namespace_ToString)
  5717. {
  5718. int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize);
  5719. BfType* type = GetBfType(typeId);
  5720. bool success = false;
  5721. if (type == NULL)
  5722. {
  5723. _Fail("Invalid type");
  5724. return false;
  5725. }
  5726. String str;
  5727. if (auto typeInst = type->ToTypeInstance())
  5728. typeInst->mTypeDef->mNamespace.ToString(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_Type_GetCustomAttribute)
  5735. {
  5736. int32 typeId = *(int32*)((uint8*)stackPtr + 1);
  5737. int32 attributeIdx = *(int32*)((uint8*)stackPtr + 1 + 4);
  5738. addr_ce resultPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 4 + 4);
  5739. BfType* type = GetBfType(typeId);
  5740. bool success = false;
  5741. if (type != NULL)
  5742. {
  5743. AddTypeSigRebuild(type);
  5744. auto typeInst = type->ToTypeInstance();
  5745. if (typeInst != NULL)
  5746. success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, typeInst->mCustomAttributes, attributeIdx, resultPtr);
  5747. _FixVariables();
  5748. }
  5749. *(addr_ce*)(stackPtr + 0) = success;
  5750. }
  5751. else if (checkFunction->mFunctionKind == CeFunctionKind_Field_GetCustomAttribute)
  5752. {
  5753. int32 typeId = *(int32*)((uint8*)stackPtr + 1);
  5754. int32 fieldIdx = *(int32*)((uint8*)stackPtr + 1 + 4);
  5755. int32 attributeIdx = *(int32*)((uint8*)stackPtr + 1 + 4 + 4);
  5756. addr_ce resultPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 4 + 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. {
  5765. if (typeInst->mDefineState < BfTypeDefineState_CETypeInit)
  5766. mCurModule->PopulateType(typeInst);
  5767. if ((fieldIdx >= 0) && (fieldIdx < typeInst->mFieldInstances.mSize))
  5768. {
  5769. auto& fieldInstance = typeInst->mFieldInstances[fieldIdx];
  5770. success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, fieldInstance.mCustomAttributes, attributeIdx, resultPtr);
  5771. _FixVariables();
  5772. }
  5773. else if (fieldIdx != -1)
  5774. {
  5775. _Fail("Invalid field");
  5776. return false;
  5777. }
  5778. }
  5779. }
  5780. *(addr_ce*)(stackPtr + 0) = success;
  5781. }
  5782. else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetCustomAttribute)
  5783. {
  5784. int64 methodHandle = *(int64*)((uint8*)stackPtr + 1);
  5785. int32 attributeIdx = *(int32*)((uint8*)stackPtr + 1 + 8);
  5786. addr_ce resultPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 8 + 4);
  5787. auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
  5788. if (methodInstance == NULL)
  5789. {
  5790. _Fail("Invalid method instance");
  5791. return false;
  5792. }
  5793. AddTypeSigRebuild(methodInstance->GetOwner());
  5794. bool success = GetCustomAttribute(mCurModule, methodInstance->GetOwner()->mConstHolder, methodInstance->GetCustomAttributes(), attributeIdx, resultPtr);
  5795. _FixVariables();
  5796. *(addr_ce*)(stackPtr + 0) = success;
  5797. }
  5798. else if (checkFunction->mFunctionKind == CeFunctionKind_Type_GetCustomAttributeType)
  5799. {
  5800. int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize);
  5801. int32 attributeIdx = *(int32*)((uint8*)stackPtr + ptrSize + 4);
  5802. BfType* type = GetBfType(typeId);
  5803. addr_ce reflectType = 0;
  5804. if (type != NULL)
  5805. {
  5806. AddTypeSigRebuild(type);
  5807. auto typeInst = type->ToTypeInstance();
  5808. if (typeInst != NULL)
  5809. {
  5810. auto attrType = GetCustomAttributeType(typeInst->mCustomAttributes, attributeIdx);
  5811. if (attrType != NULL)
  5812. reflectType = GetReflectType(attrType->mTypeId);
  5813. }
  5814. _FixVariables();
  5815. }
  5816. CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
  5817. }
  5818. else if (checkFunction->mFunctionKind == CeFunctionKind_Field_GetCustomAttributeType)
  5819. {
  5820. int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize);
  5821. int32 fieldIdx = *(int32*)((uint8*)stackPtr + ptrSize + 4);
  5822. int32 attributeIdx = *(int32*)((uint8*)stackPtr + ptrSize + 4 + 4);
  5823. BfType* type = GetBfType(typeId);
  5824. addr_ce reflectType = 0;
  5825. if (type != NULL)
  5826. {
  5827. AddTypeSigRebuild(type);
  5828. auto typeInst = type->ToTypeInstance();
  5829. if (typeInst != NULL)
  5830. {
  5831. if (typeInst->mDefineState < BfTypeDefineState_CETypeInit)
  5832. mCurModule->PopulateType(typeInst);
  5833. if ((fieldIdx >= 0) && (fieldIdx < typeInst->mFieldInstances.mSize))
  5834. {
  5835. auto& fieldInstance = typeInst->mFieldInstances[fieldIdx];
  5836. auto attrType = GetCustomAttributeType(fieldInstance.mCustomAttributes, attributeIdx);
  5837. if (attrType != NULL)
  5838. reflectType = GetReflectType(attrType->mTypeId);
  5839. _FixVariables();
  5840. }
  5841. else if (fieldIdx != -1)
  5842. {
  5843. _Fail("Invalid field");
  5844. return false;
  5845. }
  5846. }
  5847. }
  5848. CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
  5849. }
  5850. else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetCustomAttributeType)
  5851. {
  5852. int64 methodHandle = *(int64*)((uint8*)stackPtr + ptrSize);
  5853. int32 attributeIdx = *(int32*)((uint8*)stackPtr + ptrSize + 8);
  5854. auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
  5855. if (methodInstance == NULL)
  5856. {
  5857. _Fail("Invalid method instance");
  5858. return false;
  5859. }
  5860. AddTypeSigRebuild(methodInstance->GetOwner());
  5861. auto attrType = GetCustomAttributeType(methodInstance->GetCustomAttributes(), attributeIdx);
  5862. if (attrType != NULL)
  5863. CeSetAddrVal(stackPtr + 0, GetReflectType(attrType->mTypeId), ptrSize);
  5864. else
  5865. CeSetAddrVal(stackPtr + 0, 0, ptrSize);
  5866. _FixVariables();
  5867. }
  5868. else if (checkFunction->mFunctionKind == CeFunctionKind_GetMethodCount)
  5869. {
  5870. int32 typeId = *(int32*)((uint8*)stackPtr + 4);
  5871. CeTypeInfo* typeInfo = mCeMachine->GetTypeInfo(GetBfType(typeId));
  5872. if (typeInfo == NULL)
  5873. {
  5874. _Fail("Invalid type");
  5875. return false;
  5876. }
  5877. *(int32*)(stackPtr + 0) = (int)typeInfo->mMethodInstances.size();
  5878. }
  5879. else if (checkFunction->mFunctionKind == CeFunctionKind_GetMethod)
  5880. {
  5881. int32 typeId = *(int32*)((uint8*)stackPtr + 8);
  5882. int32 methodIdx = *(int32*)((uint8*)stackPtr + 8+4);
  5883. CeTypeInfo* typeInfo = mCeMachine->GetTypeInfo(GetBfType(typeId));
  5884. if (typeInfo == NULL)
  5885. {
  5886. _Fail("Invalid type");
  5887. return false;
  5888. }
  5889. if ((methodIdx < 0) || (methodIdx >= typeInfo->mMethodInstances.mSize))
  5890. {
  5891. *(int64*)(stackPtr + 0) = 0;
  5892. }
  5893. else
  5894. *(int64*)(stackPtr + 0) = (int64)(intptr)typeInfo->mMethodInstances[methodIdx];
  5895. }
  5896. else if (checkFunction->mFunctionKind == CeFunctionKind_Method_ToString)
  5897. {
  5898. int64 methodHandle = *(int64*)((uint8*)stackPtr + ptrSize);
  5899. auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
  5900. if (methodInstance == NULL)
  5901. {
  5902. _Fail("Invalid method instance");
  5903. return false;
  5904. }
  5905. CeSetAddrVal(stackPtr + 0, GetString(mCeMachine->mCeModule->MethodToString(methodInstance)), ptrSize);
  5906. _FixVariables();
  5907. }
  5908. else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetName)
  5909. {
  5910. int64 methodHandle = *(int64*)((uint8*)stackPtr + ptrSize);
  5911. auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
  5912. if (methodInstance == NULL)
  5913. {
  5914. _Fail("Invalid method instance");
  5915. return false;
  5916. }
  5917. CeSetAddrVal(stackPtr + 0, GetString(methodInstance->mMethodDef->GetReflectName()), ptrSize);
  5918. _FixVariables();
  5919. }
  5920. else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetInfo)
  5921. {
  5922. // int32 mReturnType
  5923. // int32 mParamCount
  5924. // int32 mGenericArgCount
  5925. // int32 mFlags
  5926. // int8 ComptimeMethodFlags
  5927. // int32 mMethodIdx
  5928. int64 methodHandle = *(int64*)((uint8*)stackPtr + 4+4+4+4+1+4);
  5929. auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
  5930. if (methodInstance == NULL)
  5931. {
  5932. _Fail("Invalid method instance");
  5933. return false;
  5934. }
  5935. AddTypeSigRebuild(methodInstance->GetOwner());
  5936. int genericArgCount = 0;
  5937. if (methodInstance->mMethodInfoEx != NULL)
  5938. genericArgCount = methodInstance->mMethodInfoEx->mMethodGenericArguments.mSize;
  5939. *(int32*)(stackPtr + 0) = methodInstance->mReturnType->mTypeId;
  5940. *(int32*)(stackPtr + 4) = methodInstance->GetParamCount();
  5941. *(int32*)(stackPtr + 4+4) = genericArgCount;
  5942. *(int32*)(stackPtr + 4+4+4) = methodInstance->GetMethodFlags();
  5943. *(int32*)(stackPtr + 4+4+4+4) = methodInstance->GetComptimeMethodFlags();
  5944. *(int32*)(stackPtr + 4+4+4+4+1) = methodInstance->mMethodDef->mIdx;
  5945. }
  5946. else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetParamInfo)
  5947. {
  5948. // int32 mParamType
  5949. // int16 mFlags
  5950. // str mName
  5951. int64 methodHandle = *(int64*)((uint8*)stackPtr + 4+2+ptrSize);
  5952. int32 paramIdx = *(int32*)((uint8*)stackPtr + 4+2+ptrSize+8);
  5953. auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
  5954. if (methodInstance == NULL)
  5955. {
  5956. _Fail("Invalid method instance");
  5957. return false;
  5958. }
  5959. if (paramIdx < 0 || paramIdx >= methodInstance->mParams.mSize)
  5960. {
  5961. _Fail("paramIdx is out of range");
  5962. return false;
  5963. }
  5964. enum ParamFlags
  5965. {
  5966. ParamFlag_None = 0,
  5967. ParamFlag_Splat = 1,
  5968. ParamFlag_Implicit = 2,
  5969. ParamFlag_AppendIdx = 4,
  5970. ParamFlag_Params = 8
  5971. };
  5972. ParamFlags paramFlags = ParamFlag_None;
  5973. if (methodInstance->GetParamIsSplat(paramIdx))
  5974. paramFlags = (ParamFlags)(paramFlags | ParamFlag_Splat);
  5975. if (methodInstance->GetParamKind(paramIdx) == BfParamKind_AppendIdx)
  5976. paramFlags = (ParamFlags)(paramFlags | ParamFlag_Implicit | ParamFlag_AppendIdx);
  5977. if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params)
  5978. paramFlags = (ParamFlags)(paramFlags | ParamFlag_Params);
  5979. addr_ce stringAddr = GetString(methodInstance->GetParamName(paramIdx));
  5980. _FixVariables();
  5981. *(int32*)(stackPtr + 0) = methodInstance->GetParamType(paramIdx)->mTypeId;
  5982. *(int16*)(stackPtr + 4) = (int16)paramFlags;
  5983. CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize);
  5984. }
  5985. else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetGenericArg)
  5986. {
  5987. int64 methodHandle = *(int64*)((uint8*)stackPtr + ptrSize);
  5988. int32 genericArgIdx = *(int32*)((uint8*)stackPtr + ptrSize + 8);
  5989. auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
  5990. if (methodInstance == NULL)
  5991. {
  5992. _Fail("Invalid method instance");
  5993. return false;
  5994. }
  5995. if ((methodInstance->mMethodInfoEx == NULL) || (genericArgIdx < 0) || (genericArgIdx >= methodInstance->mMethodInfoEx->mMethodGenericArguments.mSize))
  5996. {
  5997. _Fail("genericArgIdx is out of range");
  5998. return false;
  5999. }
  6000. auto reflectType = GetReflectType(methodInstance->mMethodInfoEx->mMethodGenericArguments[genericArgIdx]->mTypeId);
  6001. _FixVariables();
  6002. CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
  6003. }
  6004. else if (checkFunction->mFunctionKind == CeFunctionKind_Field_GetStatic)
  6005. {
  6006. int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize);
  6007. int32 fieldIdx = *(int32*)((uint8*)stackPtr + ptrSize + 4);
  6008. CeFunction* ctorCallFunction = NULL;
  6009. BfType* bfType = GetBfType(typeId);
  6010. bool success = false;
  6011. if (bfType != NULL)
  6012. {
  6013. auto typeInst = bfType->ToTypeInstance();
  6014. if (typeInst != NULL)
  6015. {
  6016. if (typeInst->mDefineState < BfTypeDefineState_CETypeInit)
  6017. mCurModule->PopulateType(typeInst);
  6018. if ((fieldIdx >= 0) && (fieldIdx < typeInst->mFieldInstances.mSize))
  6019. {
  6020. auto& fieldInstance = typeInst->mFieldInstances[fieldIdx];
  6021. auto fieldType = fieldInstance.mResolvedType;
  6022. ceModule->PopulateType(fieldType, BfPopulateType_Full_Force);
  6023. int64 fieldId = ((int64)typeId << 32) | fieldIdx;
  6024. CeStaticFieldInfo* staticFieldInfo = NULL;
  6025. if (mStaticFieldIdMap.TryAdd(fieldId, NULL, &staticFieldInfo))
  6026. {
  6027. if (mStaticCtorExecSet.TryAdd(typeId, NULL))
  6028. {
  6029. BfTypeInstance* bfTypeInstance = NULL;
  6030. if (bfType != NULL)
  6031. bfTypeInstance = bfType->ToTypeInstance();
  6032. if (bfTypeInstance == NULL)
  6033. {
  6034. _Fail("Invalid type");
  6035. return false;
  6036. }
  6037. auto methodDef = bfTypeInstance->mTypeDef->GetMethodByName("__BfStaticCtor");
  6038. if (methodDef == NULL)
  6039. {
  6040. _Fail("No static ctor found");
  6041. return false;
  6042. }
  6043. auto moduleMethodInstance = ceModule->GetMethodInstance(bfTypeInstance, methodDef, BfTypeVector());
  6044. if (!moduleMethodInstance)
  6045. {
  6046. _Fail("No static ctor instance found");
  6047. return false;
  6048. }
  6049. bool added = false;
  6050. ctorCallFunction = mCeMachine->GetFunction(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, added);
  6051. if (ctorCallFunction->mInitializeState < CeFunction::InitializeState_Initialized)
  6052. mCeMachine->PrepareFunction(ctorCallFunction, NULL);
  6053. }
  6054. _FixVariables();
  6055. StringT<4096> staticVarName;
  6056. BfMangler::Mangle(staticVarName, ceModule->mCompiler->GetMangleKind(), &fieldInstance);
  6057. CeStaticFieldInfo* nameStaticFieldInfo = NULL;
  6058. mStaticFieldMap.TryAdd(staticVarName, NULL, &nameStaticFieldInfo);
  6059. if (nameStaticFieldInfo->mAddr == 0)
  6060. {
  6061. int fieldSize = fieldInstance.mResolvedType->mSize;
  6062. CE_CHECKALLOC(fieldSize);
  6063. uint8* ptr = CeMalloc(fieldSize);
  6064. _FixVariables();
  6065. if (fieldSize > 0)
  6066. memset(ptr, 0, fieldSize);
  6067. nameStaticFieldInfo->mAddr = (addr_ce)(ptr - memStart);
  6068. }
  6069. staticFieldInfo->mAddr = nameStaticFieldInfo->mAddr;
  6070. }
  6071. CeSetAddrVal(stackPtr + 0, staticFieldInfo->mAddr, ptrSize);
  6072. }
  6073. else if (fieldIdx != -1)
  6074. {
  6075. _Fail("Invalid field");
  6076. return false;
  6077. }
  6078. }
  6079. }
  6080. if (ctorCallFunction != NULL)
  6081. {
  6082. bool handled = false;
  6083. if (!_CheckFunction(ctorCallFunction, handled))
  6084. return false;
  6085. if (!handled)
  6086. CE_CALL(ctorCallFunction);
  6087. }
  6088. }
  6089. else if (checkFunction->mFunctionKind == CeFunctionKind_SetReturnType)
  6090. {
  6091. int32 typeId = *(int32*)((uint8*)stackPtr);
  6092. if (returnType->IsVar())
  6093. castReturnType = GetBfType(typeId);
  6094. else
  6095. _Fail("Comptime return types can only be set on methods declared with a 'var' return type");
  6096. }
  6097. else if (checkFunction->mFunctionKind == CeFunctionKind_Align)
  6098. {
  6099. int32 typeId = *(int32*)((uint8*)stackPtr);
  6100. int32 align = *(int32*)((uint8*)stackPtr + sizeof(int32));
  6101. if ((mCurEmitContext == NULL) || (mCurEmitContext->mType == NULL) || (mCurEmitContext->mType->mTypeId != typeId))
  6102. {
  6103. _Fail("This type cannot be modified in this context");
  6104. return false;
  6105. }
  6106. mCurEmitContext->mAlign = BF_MAX(mCurEmitContext->mAlign, align);
  6107. }
  6108. else if (checkFunction->mFunctionKind == CeFunctionKind_EmitTypeBody)
  6109. {
  6110. int32 typeId = *(int32*)((uint8*)stackPtr);
  6111. addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr + sizeof(int32));
  6112. if ((mCurEmitContext == NULL) || (mCurEmitContext->mType == NULL) || (mCurEmitContext->mType->mTypeId != typeId))
  6113. {
  6114. _Fail("Code cannot be emitted for this type in this context");
  6115. return false;
  6116. }
  6117. if (!GetStringFromStringView(strViewPtr, mCurEmitContext->mEmitData))
  6118. {
  6119. _Fail("Invalid StringView");
  6120. return false;
  6121. }
  6122. }
  6123. else if (checkFunction->mFunctionKind == CeFunctionKind_EmitAddInterface)
  6124. {
  6125. int32 typeId = *(int32*)((uint8*)stackPtr);
  6126. int32 ifaceTypeId = *(int32*)((uint8*)stackPtr + sizeof(int32));
  6127. if ((mCurEmitContext == NULL) || (mCurEmitContext->mType->mTypeId != typeId))
  6128. {
  6129. _Fail("Code cannot be emitted for this type in this context");
  6130. return false;
  6131. }
  6132. mCurEmitContext->mInterfaces.Add(ifaceTypeId);
  6133. }
  6134. else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMethodEntry)
  6135. {
  6136. int64 methodHandle = *(int64*)((uint8*)stackPtr);
  6137. addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr + sizeof(int64));
  6138. if ((mCurEmitContext == NULL) || (mCurEmitContext->mMethodInstance == NULL) ||
  6139. (methodHandle != (int64)mCurEmitContext->mMethodInstance))
  6140. {
  6141. _Fail("Code cannot be emitted for this method in this context");
  6142. return false;
  6143. }
  6144. if (!GetStringFromStringView(strViewPtr, mCurEmitContext->mEmitData))
  6145. {
  6146. _Fail("Invalid StringView");
  6147. return false;
  6148. }
  6149. }
  6150. else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMethodExit)
  6151. {
  6152. int64 methodHandle = *(int64*)((uint8*)stackPtr);
  6153. addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr + sizeof(int64));
  6154. if ((mCurEmitContext == NULL) || (mCurEmitContext->mMethodInstance == NULL) ||
  6155. (methodHandle != (int64)mCurEmitContext->mMethodInstance))
  6156. {
  6157. _Fail("Code cannot be emitted for this method in this context");
  6158. return false;
  6159. }
  6160. if (!GetStringFromStringView(strViewPtr, mCurEmitContext->mExitEmitData))
  6161. {
  6162. _Fail("Invalid StringView");
  6163. return false;
  6164. }
  6165. }
  6166. else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMixin)
  6167. {
  6168. SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurModule->mCurMethodInstance, mCallerMethodInstance);
  6169. SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurModule->mCurTypeInstance, mCallerTypeInstance);
  6170. SetAndRestoreValue<bool> emitIgnoreWrites(ceModule->mBfIRBuilder->mIgnoreWrites, ignoreWrites.mPrevVal);
  6171. addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr);
  6172. String emitStr;
  6173. if (!GetStringFromStringView(strViewPtr, emitStr))
  6174. {
  6175. _Fail("Invalid StringView");
  6176. return false;
  6177. }
  6178. mCurModule->CEMixin(mCurCallSource->mRefNode, emitStr);
  6179. }
  6180. else if (checkFunction->mFunctionKind == CeFunctionKind_GetStringById)
  6181. {
  6182. int32 stringId = *(int32*)((uint8*)stackPtr + ptrSize);
  6183. String string = "";
  6184. BfStringPoolEntry* valuePtr = NULL;
  6185. mCurModule->mContext->mStringObjectIdMap.TryGetValue(stringId, &valuePtr);
  6186. if (valuePtr != NULL)
  6187. string = valuePtr->mString;
  6188. CeSetAddrVal(stackPtr + 0, GetString(string), ptrSize);
  6189. _FixVariables();
  6190. }
  6191. else if (checkFunction->mFunctionKind == CeFunctionKind_Sleep)
  6192. {
  6193. int32 sleepMS = *(int32*)((uint8*)stackPtr);
  6194. while (sleepMS > 0)
  6195. {
  6196. if (_CheckFastFinish())
  6197. break;
  6198. if (sleepMS > 20)
  6199. {
  6200. BfpThread_Sleep(20);
  6201. sleepMS -= 20;
  6202. continue;
  6203. }
  6204. BfpThread_Sleep(sleepMS);
  6205. break;
  6206. }
  6207. }
  6208. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSystem_GetTimeStamp)
  6209. {
  6210. int64& result = *(int64*)((uint8*)stackPtr + 0);
  6211. result = BfpSystem_GetTimeStamp();
  6212. }
  6213. else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_ToLower)
  6214. {
  6215. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6216. int32 val = *(int32*)((uint8*)stackPtr + 4);
  6217. result = utf8proc_tolower(val);
  6218. }
  6219. else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_ToUpper)
  6220. {
  6221. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6222. int32 val = *(int32*)((uint8*)stackPtr + 4);
  6223. result = utf8proc_toupper(val);
  6224. }
  6225. else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLower)
  6226. {
  6227. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6228. int32 val = *(int32*)((uint8*)stackPtr + 1);
  6229. result = utf8proc_category(val) == UTF8PROC_CATEGORY_LL;
  6230. }
  6231. else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsUpper)
  6232. {
  6233. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6234. int32 val = *(int32*)((uint8*)stackPtr + 1);
  6235. result = utf8proc_category(val) == UTF8PROC_CATEGORY_LU;
  6236. }
  6237. else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsWhiteSpace_EX)
  6238. {
  6239. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6240. int32 val = *(int32*)((uint8*)stackPtr + 1);
  6241. auto cat = utf8proc_category(val);
  6242. result = (cat == UTF8PROC_CATEGORY_ZS) || (cat == UTF8PROC_CATEGORY_ZL) || (cat == UTF8PROC_CATEGORY_ZP);
  6243. }
  6244. else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLetterOrDigit)
  6245. {
  6246. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6247. int32 val = *(int32*)((uint8*)stackPtr + 1);
  6248. auto cat = utf8proc_category(val);
  6249. switch (cat)
  6250. {
  6251. case UTF8PROC_CATEGORY_LU:
  6252. case UTF8PROC_CATEGORY_LL:
  6253. case UTF8PROC_CATEGORY_LT:
  6254. case UTF8PROC_CATEGORY_LM:
  6255. case UTF8PROC_CATEGORY_LO:
  6256. case UTF8PROC_CATEGORY_ND:
  6257. case UTF8PROC_CATEGORY_NL:
  6258. case UTF8PROC_CATEGORY_NO:
  6259. result = true;
  6260. break;
  6261. default:
  6262. result = false;
  6263. }
  6264. }
  6265. else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLetter)
  6266. {
  6267. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6268. int32 val = *(int32*)((uint8*)stackPtr + 1);
  6269. auto cat = utf8proc_category(val);
  6270. switch (cat)
  6271. {
  6272. case UTF8PROC_CATEGORY_LU:
  6273. case UTF8PROC_CATEGORY_LL:
  6274. case UTF8PROC_CATEGORY_LT:
  6275. case UTF8PROC_CATEGORY_LM:
  6276. case UTF8PROC_CATEGORY_LO:
  6277. result = true;
  6278. break;
  6279. default:
  6280. result = false;
  6281. }
  6282. }
  6283. else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsNumber)
  6284. {
  6285. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6286. int32 val = *(int32*)((uint8*)stackPtr + 1);
  6287. auto cat = utf8proc_category(val);
  6288. switch (cat)
  6289. {
  6290. case UTF8PROC_CATEGORY_ND:
  6291. case UTF8PROC_CATEGORY_NL:
  6292. case UTF8PROC_CATEGORY_NO:
  6293. result = true;
  6294. break;
  6295. default:
  6296. result = false;
  6297. }
  6298. }
  6299. else if (checkFunction->mFunctionKind == CeFunctionKind_Double_Strtod)
  6300. {
  6301. double& result = *(double*)((uint8*)stackPtr + 0);
  6302. addr_ce strAddr = *(addr_ce*)((uint8*)stackPtr + 8);
  6303. addr_ce endAddr = *(addr_ce*)((uint8*)stackPtr + 8 + ptrSize);
  6304. addr_ce checkAddr = strAddr;
  6305. while (true)
  6306. {
  6307. if ((uintptr)checkAddr >= (uintptr)memSize)
  6308. {
  6309. checkAddr++;
  6310. break;
  6311. }
  6312. if (memStart[checkAddr] == 0)
  6313. break;
  6314. checkAddr++;
  6315. }
  6316. CE_CHECKADDR(strAddr, checkAddr - strAddr + 1);
  6317. char* strPtr = (char*)(memStart + strAddr);
  6318. char** endPtr = NULL;
  6319. if (endAddr != 0)
  6320. endPtr = (char**)(memStart + endAddr);
  6321. result = strtod(strPtr, endPtr);
  6322. if (endAddr != 0)
  6323. {
  6324. CE_CHECKADDR(endAddr, ptrSize);
  6325. CeSetAddrVal(endPtr, (uint8*)endPtr - memStart, ptrSize);
  6326. }
  6327. }
  6328. else if (checkFunction->mFunctionKind == CeFunctionKind_Double_Ftoa)
  6329. {
  6330. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6331. float val = *(float*)((uint8*)stackPtr + 4);
  6332. addr_ce strAddr = *(addr_ce*)((uint8*)stackPtr + 4 + 4);
  6333. char str[256];
  6334. int count = sprintf(str, "%1.9f", val);
  6335. CE_CHECKADDR(strAddr, count + 1);
  6336. memcpy(memStart + strAddr, str, count + 1);
  6337. result = count;
  6338. }
  6339. else if (checkFunction->mFunctionKind == CeFunctionKind_Double_ToString)
  6340. {
  6341. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6342. double val = *(double*)((uint8*)stackPtr + 4);
  6343. addr_ce strAddr = *(addr_ce*)((uint8*)stackPtr + 4 + 8);
  6344. char str[256];
  6345. int count = DoubleToString(val, str);
  6346. CE_CHECKADDR(strAddr, count + 1);
  6347. memcpy(memStart + strAddr, str, count + 1);
  6348. result = count;
  6349. }
  6350. else if (checkFunction->mFunctionKind == CeFunctionKind_Float_ToString)
  6351. {
  6352. int32& result = *(int32*)((uint8*)stackPtr + 0);
  6353. float val = *(float*)((uint8*)stackPtr + 4);
  6354. addr_ce strAddr = *(addr_ce*)((uint8*)stackPtr + 4 + 4);
  6355. char str[256];
  6356. int count = FloatToString(val, str);
  6357. CE_CHECKADDR(strAddr, count + 1);
  6358. memcpy(memStart + strAddr, str, count + 1);
  6359. result = count;
  6360. }
  6361. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_Create)
  6362. {
  6363. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6364. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6365. if (outResultAddr != 0)
  6366. CE_CHECKADDR(outResultAddr, 4);
  6367. String path;
  6368. CE_CHECKADDR_STR(path, nameAddr);
  6369. FixRelativePath(path);
  6370. BfpDirectory_Create(path.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6371. }
  6372. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_Rename)
  6373. {
  6374. addr_ce srcAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6375. addr_ce destAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6376. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6377. if (outResultAddr != 0)
  6378. CE_CHECKADDR(outResultAddr, 4);
  6379. String srcPath;
  6380. CE_CHECKADDR_STR(srcPath, srcAddr);
  6381. String destPath;
  6382. CE_CHECKADDR_STR(destPath, destAddr);
  6383. FixRelativePath(srcPath);
  6384. FixRelativePath(destPath);
  6385. BfpDirectory_Rename(srcPath.c_str(), destPath.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6386. }
  6387. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_Delete)
  6388. {
  6389. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6390. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6391. if (outResultAddr != 0)
  6392. CE_CHECKADDR(outResultAddr, 4);
  6393. String path;
  6394. CE_CHECKADDR_STR(path, nameAddr);
  6395. FixRelativePath(path);
  6396. BfpDirectory_Delete(path.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6397. }
  6398. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_GetCurrent)
  6399. {
  6400. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6401. addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6402. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6403. CE_CHECKADDR(sizeAddr, 4);
  6404. int& nameSize = *(int*)(memStart + sizeAddr);
  6405. CE_CHECKADDR(nameAddr, nameSize);
  6406. char* namePtr = (char*)(memStart + nameAddr);
  6407. if (outResultAddr != 0)
  6408. CE_CHECKADDR(outResultAddr, 4);
  6409. CalcWorkingDir();
  6410. TryStringOut(mWorkingDir, namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpResult*)(memStart + outResultAddr));
  6411. }
  6412. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_SetCurrent)
  6413. {
  6414. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6415. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6416. if (outResultAddr != 0)
  6417. CE_CHECKADDR(outResultAddr, 4);
  6418. String path;
  6419. CE_CHECKADDR_STR(path, nameAddr);
  6420. FixRelativePath(path);
  6421. if (::BfpDirectory_Exists(path.c_str()))
  6422. {
  6423. mWorkingDir = path;
  6424. if (outResultAddr != 0)
  6425. *(BfpFileResult*)(memStart + outResultAddr) = BfpFileResult_Ok;
  6426. }
  6427. else
  6428. {
  6429. if (outResultAddr != 0)
  6430. *(BfpFileResult*)(memStart + outResultAddr) = BfpFileResult_NotFound;
  6431. }
  6432. }
  6433. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_Exists)
  6434. {
  6435. bool& result = *(bool*)((uint8*)stackPtr + 0);
  6436. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 1);
  6437. String path;
  6438. CE_CHECKADDR_STR(path, nameAddr);
  6439. FixRelativePath(path);
  6440. result = BfpDirectory_Exists(path.c_str());
  6441. }
  6442. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_GetSysDirectory)
  6443. {
  6444. BfpSysDirectoryKind sysDirKind = *(BfpSysDirectoryKind*)((uint8*)stackPtr + 0);
  6445. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 4);
  6446. addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + 4 + ptrSize);
  6447. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + 4 + ptrSize + ptrSize);
  6448. CE_CHECKADDR(sizeAddr, 4);
  6449. int& nameSize = *(int*)(memStart + sizeAddr);
  6450. CE_CHECKADDR(nameAddr, nameSize);
  6451. char* namePtr = (char*)(memStart + nameAddr);
  6452. if (outResultAddr != 0)
  6453. CE_CHECKADDR(outResultAddr, 4);
  6454. BfpDirectory_GetSysDirectory(sysDirKind, namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6455. }
  6456. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Close)
  6457. {
  6458. addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0);
  6459. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6460. CE_CHECKADDR(outResultAddr, 4);
  6461. CeInternalData* internalData = NULL;
  6462. CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
  6463. BfpFile_Close(internalData->mFile, (BfpFileResult*)(memStart + outResultAddr));
  6464. }
  6465. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Create)
  6466. {
  6467. void* resultPtr = ((uint8*)stackPtr + 0);
  6468. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6469. int createKind = *(int*)((uint8*)stackPtr + ptrSize + ptrSize);
  6470. int createFlags = *(int*)((uint8*)stackPtr + ptrSize + ptrSize + 4);
  6471. int createFileAttrs = *(int*)((uint8*)stackPtr + ptrSize + ptrSize + 4 + 4);
  6472. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + 4 + 4 + 4);
  6473. String path;
  6474. CE_CHECKADDR_STR(path, nameAddr);
  6475. CE_CHECKADDR(outResultAddr, 4);
  6476. FixRelativePath(path);
  6477. auto bfpFile = BfpFile_Create(path.c_str(), (BfpFileCreateKind)createKind, (BfpFileCreateFlags)createFlags, (BfpFileAttributes)createFileAttrs, (BfpFileResult*)(memStart + outResultAddr));
  6478. if (bfpFile != NULL)
  6479. {
  6480. if ((createKind == BfpFileCreateKind_OpenExisting) || (createKind == BfpFileCreateKind_OpenAlways))
  6481. AddFileRebuild(path);
  6482. CeInternalData* internalData = new CeInternalData();
  6483. internalData->mKind = CeInternalData::Kind_File;
  6484. internalData->mFile = bfpFile;
  6485. mInternalDataMap[++mCurHandleId] = internalData;
  6486. CeSetAddrVal(resultPtr, mCurHandleId, ptrSize);
  6487. }
  6488. else
  6489. CeSetAddrVal(resultPtr, 0, ptrSize);
  6490. }
  6491. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Flush)
  6492. {
  6493. addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0);
  6494. CeInternalData* internalData = NULL;
  6495. CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
  6496. BfpFile_Flush(internalData->mFile);
  6497. }
  6498. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetFileSize)
  6499. {
  6500. int64& result = *(int64*)((uint8*)stackPtr + 0);
  6501. addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 8);
  6502. CeInternalData* internalData = NULL;
  6503. CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
  6504. result = BfpFile_GetFileSize(internalData->mFile);
  6505. }
  6506. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Read)
  6507. {
  6508. void* resultPtr = ((uint8*)stackPtr + 0);
  6509. addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6510. addr_ce bufferPtr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6511. intptr bufferSize = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
  6512. int timeoutMS = *(int32*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize);
  6513. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize);
  6514. CE_CHECKADDR(bufferPtr, bufferSize);
  6515. CE_CHECKADDR(outResultAddr, 4);
  6516. BfpFileResult fileResult = BfpFileResult_UnknownError;
  6517. CeInternalData* internalData = NULL;
  6518. CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
  6519. int timeoutLeft = timeoutMS;
  6520. int64 result = 0;
  6521. CeAsyncOperation* asyncOperation = NULL;
  6522. BfpThread* asyncThread = NULL;
  6523. while (true)
  6524. {
  6525. if (*cancelingPtr)
  6526. break;
  6527. int useTimeout = timeoutLeft;
  6528. if (useTimeout < 0)
  6529. {
  6530. useTimeout = 20;
  6531. }
  6532. else if (useTimeout > 20)
  6533. {
  6534. useTimeout = 20;
  6535. timeoutLeft -= useTimeout;
  6536. }
  6537. else
  6538. timeoutLeft = 0;
  6539. if (asyncOperation != NULL)
  6540. {
  6541. if (BfpThread_WaitFor(asyncThread, useTimeout))
  6542. {
  6543. if (asyncOperation->mReadSize > 0)
  6544. memcpy(memStart + bufferPtr, asyncOperation->mData, asyncOperation->mReadSize);
  6545. result = asyncOperation->mReadSize;
  6546. fileResult = asyncOperation->mResult;
  6547. break;
  6548. }
  6549. continue;
  6550. }
  6551. result = BfpFile_Read(internalData->mFile, memStart + bufferPtr, bufferSize, useTimeout, &fileResult);
  6552. if (fileResult == BfpFileResult_Timeout)
  6553. {
  6554. if (timeoutLeft > 0)
  6555. continue;
  6556. }
  6557. if (fileResult != BfpFileResult_InvalidParameter)
  6558. break;
  6559. BF_ASSERT(asyncOperation == NULL);
  6560. asyncOperation = new CeAsyncOperation();
  6561. asyncOperation->mInternalData = internalData;
  6562. asyncOperation->mInternalData->AddRef();
  6563. asyncOperation->mData = new uint8[bufferSize];
  6564. asyncOperation->mDataSize = bufferSize;
  6565. asyncOperation->AddRef();
  6566. asyncThread = BfpThread_Create(CeAsyncOperation::RunProc, asyncOperation);
  6567. }
  6568. if (asyncOperation != NULL)
  6569. asyncOperation->Release();
  6570. if (asyncThread != NULL)
  6571. BfpThread_Release(asyncThread);
  6572. if (outResultAddr != 0)
  6573. *(BfpFileResult*)(memStart + outResultAddr) = fileResult;
  6574. CeSetAddrVal(resultPtr, result, ptrSize);
  6575. }
  6576. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Release)
  6577. {
  6578. addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0);
  6579. CeInternalData* internalData = NULL;
  6580. CE_REMOVE_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
  6581. internalData->Release();
  6582. }
  6583. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Seek)
  6584. {
  6585. int64& result = *(int64*)((uint8*)stackPtr + 0);
  6586. addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 8);
  6587. int64 offset = *(int64*)((uint8*)stackPtr + 8 + ptrSize);
  6588. int seekKind = *(int*)((uint8*)stackPtr + 8 + ptrSize + 8);
  6589. CeInternalData* internalData = NULL;
  6590. CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
  6591. result = BfpFile_Seek(internalData->mFile, offset, (BfpFileSeekKind)seekKind);
  6592. }
  6593. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Truncate)
  6594. {
  6595. addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0);
  6596. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6597. CE_CHECKADDR(outResultAddr, 4);
  6598. CeInternalData* internalData = NULL;
  6599. CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
  6600. BfpFile_Truncate(internalData->mFile, (BfpFileResult*)(memStart + outResultAddr));
  6601. }
  6602. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Write)
  6603. {
  6604. void* resultPtr = ((uint8*)stackPtr + 0);
  6605. addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6606. addr_ce bufferPtr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6607. intptr bufferSize = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
  6608. int timeoutMS = *(int32*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize);
  6609. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize);
  6610. CE_CHECKADDR(bufferPtr, bufferSize);
  6611. CE_CHECKADDR(outResultAddr, 4);
  6612. CeInternalData* internalData = NULL;
  6613. CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
  6614. int64 result = BfpFile_Write(internalData->mFile, memStart + bufferPtr, bufferSize, timeoutMS, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6615. CeSetAddrVal(resultPtr, result, ptrSize);
  6616. }
  6617. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetTime_LastWrite)
  6618. {
  6619. BfpTimeStamp& result = *(BfpTimeStamp*)((uint8*)stackPtr + 0);
  6620. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 8);
  6621. String path;
  6622. CE_CHECKADDR_STR(path, nameAddr);
  6623. FixRelativePath(path);
  6624. AddFileRebuild(path);
  6625. result = BfpFile_GetTime_LastWrite(path.c_str());
  6626. }
  6627. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetAttributes)
  6628. {
  6629. BfpFileAttributes& result = *(BfpFileAttributes*)((uint8*)stackPtr + 0);
  6630. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 4);
  6631. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + 4);
  6632. if (outResultAddr != 0)
  6633. CE_CHECKADDR(outResultAddr, 4);
  6634. String path;
  6635. CE_CHECKADDR_STR(path, nameAddr);
  6636. FixRelativePath(path);
  6637. result = BfpFile_GetAttributes(path.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6638. }
  6639. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_SetAttributes)
  6640. {
  6641. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6642. BfpFileAttributes attribs = *(BfpFileAttributes*)((uint8*)stackPtr + ptrSize);
  6643. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6644. if (outResultAddr != 0)
  6645. CE_CHECKADDR(outResultAddr, 4);
  6646. String path;
  6647. CE_CHECKADDR_STR(path, nameAddr);
  6648. FixRelativePath(path);
  6649. BfpFile_SetAttributes(path.c_str(), attribs, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6650. }
  6651. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Copy)
  6652. {
  6653. addr_ce srcAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6654. addr_ce destAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6655. BfpFileCopyKind fileCopyKind = *(BfpFileCopyKind*)((uint8*)stackPtr + ptrSize + ptrSize);
  6656. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + 4);
  6657. if (outResultAddr != 0)
  6658. CE_CHECKADDR(outResultAddr, 4);
  6659. String srcPath;
  6660. CE_CHECKADDR_STR(srcPath, srcAddr);
  6661. String destPath;
  6662. CE_CHECKADDR_STR(destPath, destAddr);
  6663. FixRelativePath(srcPath);
  6664. FixRelativePath(destPath);
  6665. BfpFile_Copy(srcPath.c_str(), destPath.c_str(), fileCopyKind, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6666. }
  6667. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Rename)
  6668. {
  6669. addr_ce srcAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6670. addr_ce destAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6671. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6672. if (outResultAddr != 0)
  6673. CE_CHECKADDR(outResultAddr, 4);
  6674. String srcPath;
  6675. CE_CHECKADDR_STR(srcPath, srcAddr);
  6676. String destPath;
  6677. CE_CHECKADDR_STR(destPath, destAddr);
  6678. FixRelativePath(srcPath);
  6679. FixRelativePath(destPath);
  6680. BfpFile_Rename(srcPath.c_str(), destPath.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6681. }
  6682. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Delete)
  6683. {
  6684. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6685. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6686. if (outResultAddr != 0)
  6687. CE_CHECKADDR(outResultAddr, 4);
  6688. String path;
  6689. CE_CHECKADDR_STR(path, nameAddr);
  6690. FixRelativePath(path);
  6691. BfpFile_Delete(path.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6692. }
  6693. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Exists)
  6694. {
  6695. bool& result = *(bool*)((uint8*)stackPtr + 0);
  6696. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 1);
  6697. String path;
  6698. CE_CHECKADDR_STR(path, nameAddr);
  6699. FixRelativePath(path);
  6700. AddFileRebuild(path);
  6701. result = BfpFile_Exists(path.c_str());
  6702. }
  6703. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetTempPath)
  6704. {
  6705. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6706. addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6707. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6708. CE_CHECKADDR(sizeAddr, 4);
  6709. int& nameSize = *(int*)(memStart + sizeAddr);
  6710. CE_CHECKADDR(nameAddr, nameSize);
  6711. char* namePtr = (char*)(memStart + nameAddr);
  6712. if (outResultAddr != 0)
  6713. CE_CHECKADDR(outResultAddr, 4);
  6714. BfpFile_GetTempPath(namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6715. }
  6716. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetTempFileName)
  6717. {
  6718. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6719. addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6720. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6721. CE_CHECKADDR(sizeAddr, 4);
  6722. int& nameSize = *(int*)(memStart + sizeAddr);
  6723. CE_CHECKADDR(nameAddr, nameSize);
  6724. char* namePtr = (char*)(memStart + nameAddr);
  6725. if (outResultAddr != 0)
  6726. CE_CHECKADDR(outResultAddr, 4);
  6727. BfpFile_GetTempFileName(namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6728. }
  6729. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetFullPath)
  6730. {
  6731. addr_ce srcAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6732. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6733. addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6734. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
  6735. String srcPath;
  6736. CE_CHECKADDR_STR(srcPath, srcAddr);
  6737. CE_CHECKADDR(sizeAddr, 4);
  6738. int& nameSize = *(int*)(memStart + sizeAddr);
  6739. CE_CHECKADDR(nameAddr, nameSize);
  6740. char* namePtr = (char*)(memStart + nameAddr);
  6741. if (outResultAddr != 0)
  6742. CE_CHECKADDR(outResultAddr, 4);
  6743. FixRelativePath(srcPath);
  6744. BfpFile_GetFullPath(srcPath.c_str(), namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6745. }
  6746. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetActualPath)
  6747. {
  6748. addr_ce srcAddr = *(addr_ce*)((uint8*)stackPtr + 0);
  6749. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6750. addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6751. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
  6752. String srcPath;
  6753. CE_CHECKADDR_STR(srcPath, srcAddr);
  6754. CE_CHECKADDR(sizeAddr, 4);
  6755. int& nameSize = *(int*)(memStart + sizeAddr);
  6756. CE_CHECKADDR(nameAddr, nameSize);
  6757. char* namePtr = (char*)(memStart + nameAddr);
  6758. if (outResultAddr != 0)
  6759. CE_CHECKADDR(outResultAddr, 4);
  6760. FixRelativePath(srcPath);
  6761. BfpFile_GetActualPath(srcPath.c_str(), namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6762. }
  6763. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_Create)
  6764. {
  6765. void* resultPtr = ((uint8*)stackPtr + 0);
  6766. addr_ce targetPathAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6767. addr_ce argsAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6768. addr_ce workingDirAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
  6769. addr_ce envAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize);
  6770. int flags = *(int*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize);
  6771. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize + 4);
  6772. String targetPath;
  6773. CE_CHECKADDR_STR(targetPath, targetPathAddr);
  6774. String args;
  6775. if (argsAddr != 0)
  6776. CE_CHECKADDR_STR(args, argsAddr);
  6777. String workingDir;
  6778. if (workingDirAddr != 0)
  6779. CE_CHECKADDR_STR(workingDir, workingDirAddr);
  6780. String env;
  6781. if (envAddr != 0)
  6782. CE_CHECKADDR_STR(env, envAddr);
  6783. if (outResultAddr != 0)
  6784. CE_CHECKADDR(outResultAddr, 4);
  6785. if ((targetPath.Contains('/')) || (targetPath.Contains('\\')))
  6786. {
  6787. FixRelativePath(targetPath);
  6788. }
  6789. auto bfpSpawn = BfpSpawn_Create(targetPath.c_str(),
  6790. (argsAddr == 0) ? NULL : args.c_str(),
  6791. (workingDirAddr == 0) ? NULL : workingDir.c_str(),
  6792. (envAddr == 0) ? NULL : env.c_str(), (BfpSpawnFlags)flags, (outResultAddr == 0) ? NULL : (BfpSpawnResult*)(memStart + outResultAddr));
  6793. if (bfpSpawn != NULL)
  6794. {
  6795. CeInternalData* internalData = new CeInternalData();
  6796. internalData->mKind = CeInternalData::Kind_Spawn;
  6797. internalData->mSpawn = bfpSpawn;
  6798. mInternalDataMap[++mCurHandleId] = internalData;
  6799. CeSetAddrVal(resultPtr, mCurHandleId, ptrSize);
  6800. }
  6801. else
  6802. CeSetAddrVal(resultPtr, 0, ptrSize);
  6803. }
  6804. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_GetStdHandles)
  6805. {
  6806. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 0);
  6807. addr_ce outStdInAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6808. addr_ce outStdOutAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6809. addr_ce outStdErrAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
  6810. if (outStdInAddr != 0)
  6811. CE_CHECKADDR(outStdInAddr, ptrSize);
  6812. if (outStdOutAddr != 0)
  6813. CE_CHECKADDR(outStdOutAddr, ptrSize);
  6814. if (outStdErrAddr != 0)
  6815. CE_CHECKADDR(outStdErrAddr, ptrSize);
  6816. BfpFile* outStdIn = NULL;
  6817. BfpFile* outStdOut = NULL;
  6818. BfpFile* outStdErr = NULL;
  6819. CeInternalData* internalData = NULL;
  6820. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn);
  6821. BfpSpawn_GetStdHandles(internalData->mSpawn,
  6822. (outStdInAddr != 0) ? &outStdIn : NULL,
  6823. (outStdOutAddr != 0) ? &outStdOut : NULL,
  6824. (outStdErrAddr != 0) ? &outStdErr : NULL);
  6825. auto _SetHandle = [&](addr_ce addr, BfpFile* file)
  6826. {
  6827. if (addr == 0)
  6828. return;
  6829. if (file != NULL)
  6830. {
  6831. CeInternalData* internalData = new CeInternalData();
  6832. internalData->mKind = CeInternalData::Kind_File;
  6833. internalData->mFile = file;
  6834. mInternalDataMap[++mCurHandleId] = internalData;
  6835. CeSetAddrVal(memStart + addr, mCurHandleId, ptrSize);
  6836. }
  6837. };
  6838. if (outStdInAddr != 0)
  6839. _SetHandle(outStdInAddr, outStdIn);
  6840. if (outStdOutAddr != 0)
  6841. _SetHandle(outStdOutAddr, outStdOut);
  6842. if (outStdErrAddr != 0)
  6843. _SetHandle(outStdErrAddr, outStdErr);
  6844. }
  6845. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_Kill)
  6846. {
  6847. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 0);
  6848. int exitCode = *(int*)((uint8*)stackPtr + ptrSize);
  6849. int killFlags = *(int*)((uint8*)stackPtr + ptrSize + ptrSize);
  6850. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
  6851. CE_CHECKADDR(outResultAddr, 4);
  6852. CeInternalData* internalData = NULL;
  6853. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn);
  6854. BfpSpawn_Kill(internalData->mSpawn, exitCode, (BfpKillFlags)killFlags, (BfpSpawnResult*)(memStart + outResultAddr));
  6855. }
  6856. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_Release)
  6857. {
  6858. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 0);
  6859. CeInternalData* internalData = NULL;
  6860. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn);
  6861. internalData->mReleased = true;
  6862. }
  6863. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_WaitFor)
  6864. {
  6865. bool& result = *(bool*)((uint8*)stackPtr + 0);
  6866. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 1);
  6867. int waitMS = *(int*)((uint8*)stackPtr + 1 + ptrSize);
  6868. addr_ce outExitCodeAddr = *(addr_ce*)((uint8*)stackPtr + 1 + ptrSize + ptrSize);
  6869. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + 1 + ptrSize + ptrSize + ptrSize);
  6870. CE_CHECKADDR(outExitCodeAddr, ptrSize);
  6871. if (outResultAddr != 0)
  6872. CE_CHECKADDR(outResultAddr, 4);
  6873. CeInternalData* internalData = NULL;
  6874. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn);
  6875. int outExitCode = 0;
  6876. int timeLeft = waitMS;
  6877. do
  6878. {
  6879. if (_CheckFastFinish())
  6880. {
  6881. result = false;
  6882. break;
  6883. }
  6884. int waitTime = 20;
  6885. if (timeLeft >= 0)
  6886. {
  6887. waitTime = BF_MIN(timeLeft, 20);
  6888. timeLeft -= waitTime;
  6889. }
  6890. result = BfpSpawn_WaitFor(internalData->mSpawn, waitTime, &outExitCode, (outResultAddr == 0) ? NULL : (BfpSpawnResult*)(memStart + outResultAddr));
  6891. if (result)
  6892. break;
  6893. if (waitTime == 0)
  6894. break;
  6895. } while (true);
  6896. *(int*)(memStart + outExitCodeAddr) = outExitCode;
  6897. }
  6898. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_FindFirstFile)
  6899. {
  6900. void* resultPtr = ((uint8*)stackPtr + 0);
  6901. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6902. int flags = *(int*)((uint8*)stackPtr + ptrSize + ptrSize);
  6903. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + 4);
  6904. String path;
  6905. CE_CHECKADDR_STR(path, nameAddr);
  6906. if (outResultAddr != 0)
  6907. CE_CHECKADDR(outResultAddr, 4);
  6908. FixRelativePath(path);
  6909. auto bfpFindFileData = BfpFindFileData_FindFirstFile(path.c_str(), (BfpFindFileFlags)flags, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6910. if (bfpFindFileData != NULL)
  6911. {
  6912. String dir = GetFileDir(path);
  6913. dir = FixPathAndCase(dir);
  6914. dir.Append(DIR_SEP_CHAR);
  6915. CeRebuildKey rebuildKey;
  6916. rebuildKey.mKind = CeRebuildKey::Kind_Directory;
  6917. rebuildKey.mString = dir;
  6918. CeRebuildValue rebuildValue;
  6919. if (AddRebuild(rebuildKey, rebuildValue))
  6920. mCurModule->mCompiler->mRebuildFileSet.Add(dir);
  6921. CeInternalData* internalData = new CeInternalData();
  6922. internalData->mKind = CeInternalData::Kind_FindFileData;
  6923. internalData->mFindFileData = bfpFindFileData;
  6924. mInternalDataMap[++mCurHandleId] = internalData;
  6925. CeSetAddrVal(resultPtr, mCurHandleId, ptrSize);
  6926. }
  6927. else
  6928. CeSetAddrVal(resultPtr, 0, ptrSize);
  6929. }
  6930. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_FindNextFile)
  6931. {
  6932. bool& result = *(bool*)((uint8*)stackPtr + 0);
  6933. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 1);
  6934. CeInternalData* internalData = NULL;
  6935. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData);
  6936. result = BfpFindFileData_FindNextFile(internalData->mFindFileData);
  6937. }
  6938. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_GetFileName)
  6939. {
  6940. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 0);
  6941. addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
  6942. addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
  6943. addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
  6944. CeInternalData* internalData = NULL;
  6945. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData);
  6946. CE_CHECKADDR(sizeAddr, 4);
  6947. int& nameSize = *(int*)(memStart + sizeAddr);
  6948. CE_CHECKADDR(nameAddr, nameSize);
  6949. char* namePtr = (char*)(memStart + nameAddr);
  6950. if (outResultAddr != 0)
  6951. CE_CHECKADDR(outResultAddr, 4);
  6952. BfpFindFileData_GetFileName(internalData->mFindFileData, namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr));
  6953. }
  6954. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_GetTime_LastWrite)
  6955. {
  6956. BfpTimeStamp& result = *(BfpTimeStamp*)((uint8*)stackPtr + 0);
  6957. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 8);
  6958. CeInternalData* internalData = NULL;
  6959. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData);
  6960. result = BfpFindFileData_GetTime_LastWrite(internalData->mFindFileData);
  6961. }
  6962. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_GetTime_Created)
  6963. {
  6964. BfpTimeStamp& result = *(BfpTimeStamp*)((uint8*)stackPtr + 0);
  6965. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 8);
  6966. CeInternalData* internalData = NULL;
  6967. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData);
  6968. result = BfpFindFileData_GetTime_Created(internalData->mFindFileData);
  6969. }
  6970. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_GetTime_Access)
  6971. {
  6972. BfpTimeStamp& result = *(BfpTimeStamp*)((uint8*)stackPtr + 0);
  6973. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 8);
  6974. CeInternalData* internalData = NULL;
  6975. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData);
  6976. result = BfpFindFileData_GetTime_Access(internalData->mFindFileData);
  6977. }
  6978. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_GetFileAttributes)
  6979. {
  6980. BfpFileAttributes& result = *(BfpFileAttributes*)((uint8*)stackPtr + 0);
  6981. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 4);
  6982. CeInternalData* internalData = NULL;
  6983. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData);
  6984. result = BfpFindFileData_GetFileAttributes(internalData->mFindFileData);
  6985. }
  6986. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_GetFileSize)
  6987. {
  6988. int64& result = *(int64*)((uint8*)stackPtr + 0);
  6989. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 8);
  6990. CeInternalData* internalData = NULL;
  6991. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData);
  6992. result = BfpFindFileData_GetFileSize(internalData->mFindFileData);
  6993. }
  6994. else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFindFileData_Release)
  6995. {
  6996. addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 0);
  6997. CeInternalData* internalData = NULL;
  6998. CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData);
  6999. internalData->mReleased = true;
  7000. }
  7001. else
  7002. {
  7003. Fail(_GetCurFrame(), StrFormat("Unable to invoke extern method '%s'", ceModule->MethodToString(checkFunction->mMethodInstance).c_str()));
  7004. return false;
  7005. }
  7006. handled = true;
  7007. return true;
  7008. }
  7009. if (!checkFunction->mFailed)
  7010. return true;
  7011. if ((mCeMachine->mDebugger != NULL) && (!mCallStack.IsEmpty()))
  7012. _Fail(StrFormat("Attempting to call failed method '%s'", ceModule->MethodToString(checkFunction->mMethodInstance).c_str()));
  7013. auto error = Fail(_GetCurFrame(), StrFormat("Method call preparation '%s' failed", ceModule->MethodToString(checkFunction->mMethodInstance).c_str()));
  7014. if ((error != NULL) && (!checkFunction->mGenError.IsEmpty()))
  7015. mCeMachine->mCompiler->mPassInstance->MoreInfo("Comptime method generation error: " + checkFunction->mGenError);
  7016. return false;
  7017. };
  7018. //
  7019. {
  7020. bool handled = false;
  7021. if (!_CheckFunction(ceFunction, handled))
  7022. return false;
  7023. if (handled)
  7024. return true;
  7025. }
  7026. int callCount = 0;
  7027. int instCount = 0;
  7028. CE_CHECKSTACK();
  7029. while (true)
  7030. {
  7031. ++instCount;
  7032. CeOp op = CE_GETINST(CeOp);
  7033. if (*specialCheckPtr)
  7034. {
  7035. SpecialCheck:
  7036. if (*fastFinishPtr)
  7037. {
  7038. BfTypeInstance* rebuildType = NULL;
  7039. if ((mCurModule != NULL) && (mCurModule->mCurTypeInstance != NULL))
  7040. rebuildType = mCurModule->mCurTypeInstance;
  7041. if ((mCurEmitContext != NULL) && (mCurEmitContext->mType != NULL))
  7042. rebuildType = mCurEmitContext->mType->ToTypeInstance();
  7043. if (rebuildType != NULL)
  7044. {
  7045. rebuildType->mRebuildFlags = (BfTypeRebuildFlags)(rebuildType->mRebuildFlags | BfTypeRebuildFlag_ConstEvalCancelled);
  7046. mCurModule->DeferRebuildType(rebuildType);
  7047. }
  7048. if (*cancelingPtr)
  7049. {
  7050. if ((mCurModule == NULL) || (mCurModule->mCurTypeInstance == NULL))
  7051. _Fail("Comptime evaluation canceled");
  7052. }
  7053. return false;
  7054. }
  7055. bool wantsStop = false;
  7056. if (mCeMachine->mStepState.mKind != CeStepState::Kind_None)
  7057. {
  7058. int curDepth = mCallStack.mSize + 1;
  7059. int instIdx = instPtr - ceFunction->mCode.mVals - 1;
  7060. switch (mCeMachine->mStepState.mKind)
  7061. {
  7062. case CeStepState::Kind_StepInfo:
  7063. if (curDepth != mCeMachine->mStepState.mStartDepth)
  7064. wantsStop = true;
  7065. else if (instIdx >= mCeMachine->mStepState.mNextInstIdx)
  7066. wantsStop = true;
  7067. break;
  7068. case CeStepState::Kind_StepInfo_Asm:
  7069. wantsStop = true;
  7070. break;
  7071. case CeStepState::Kind_StepOver:
  7072. if (curDepth < mCeMachine->mStepState.mStartDepth)
  7073. wantsStop = true;
  7074. else if ((mCeMachine->mStepState.mStartDepth == curDepth) && (instIdx >= mCeMachine->mStepState.mNextInstIdx))
  7075. wantsStop = true;
  7076. break;
  7077. case CeStepState::Kind_StepOver_Asm:
  7078. if (curDepth < mCeMachine->mStepState.mStartDepth)
  7079. wantsStop = true;
  7080. else if (curDepth == mCeMachine->mStepState.mStartDepth)
  7081. wantsStop = true;
  7082. break;
  7083. case CeStepState::Kind_StepOut:
  7084. if (curDepth < mCeMachine->mStepState.mStartDepth)
  7085. wantsStop = true;
  7086. else if ((curDepth == mCeMachine->mStepState.mStartDepth) && (instIdx >= mCeMachine->mStepState.mNextInstIdx))
  7087. wantsStop = true;
  7088. break;
  7089. case CeStepState::Kind_StepOut_Asm:
  7090. if (curDepth <= mCeMachine->mStepState.mStartDepth)
  7091. wantsStop = true;
  7092. break;
  7093. case CeStepState::Kind_Jmp:
  7094. instPtr = &ceFunction->mCode[mCeMachine->mStepState.mNextInstIdx];
  7095. op = CE_GETINST(CeOp);
  7096. wantsStop = true;
  7097. break;
  7098. }
  7099. }
  7100. else if (mCeMachine->mDbgWantBreak)
  7101. {
  7102. wantsStop = true;
  7103. }
  7104. else if ((mCeMachine->mDebugger != NULL) && (mCeMachine->mDebugger->mBreakpointFramesDirty))
  7105. {
  7106. AutoCrit autoCrit(mCeMachine->mCritSect);
  7107. mCallStack.Add(_GetCurFrame());
  7108. mCeMachine->mDebugger->UpdateBreakpointFrames();
  7109. mCallStack.pop_back();
  7110. }
  7111. else
  7112. *specialCheckPtr = false;
  7113. if (wantsStop)
  7114. {
  7115. mCeMachine->mDbgWantBreak = false;
  7116. mCeMachine->mStepState.mKind = CeStepState::Kind_None;
  7117. _DbgPause();
  7118. if (mCeMachine->mStepState.mKind == CeStepState::Kind_Jmp)
  7119. goto SpecialCheck;
  7120. // We may have changed breakpoints so we need to re-read
  7121. instPtr -= sizeof(CeOp);
  7122. op = CE_GETINST(CeOp);
  7123. }
  7124. }
  7125. OpSwitch:
  7126. switch (op)
  7127. {
  7128. case CeOp_Nop:
  7129. break;
  7130. case CeOp_DbgBreak:
  7131. {
  7132. bool foundBreakpoint = false;
  7133. bool skipInst = false;
  7134. if (mCeMachine->mDebugger != NULL)
  7135. {
  7136. AutoCrit autoCrit(mCeMachine->mCritSect);
  7137. int instIdx = instPtr - ceFunction->mCode.mVals - 2;
  7138. CeBreakpointBind* breakpointEntry = NULL;
  7139. if (ceFunction->mBreakpoints.TryGetValue(instIdx, &breakpointEntry))
  7140. {
  7141. bool doBreak = false;
  7142. mCallStack.Add(_GetCurFrame());
  7143. if (mCeMachine->mDebugger->CheckConditionalBreakpoint(breakpointEntry->mBreakpoint))
  7144. doBreak = true;
  7145. mCallStack.pop_back();
  7146. op = breakpointEntry->mPrevOpCode;
  7147. // Keep us from an infinite loop if we set a breakpoint on a manual Break
  7148. skipInst = op == CeOp_DbgBreak;
  7149. foundBreakpoint = true;
  7150. if (!doBreak)
  7151. {
  7152. _FixVariables();
  7153. if (skipInst)
  7154. break;
  7155. goto OpSwitch;
  7156. }
  7157. mCeMachine->mDebugger->mActiveBreakpoint = breakpointEntry->mBreakpoint;
  7158. }
  7159. }
  7160. _DbgPause();
  7161. if (mCeMachine->mStepState.mKind == CeStepState::Kind_Jmp)
  7162. goto SpecialCheck;
  7163. if (skipInst)
  7164. break;
  7165. if (foundBreakpoint)
  7166. goto OpSwitch;
  7167. }
  7168. break;
  7169. case CeOp_Ret:
  7170. {
  7171. if (mCallStack.mSize == 0)
  7172. return true;
  7173. auto& ceFrame = mCallStack.back();
  7174. ceFunction = ceFrame.mFunction;
  7175. instPtr = ceFrame.mInstPtr;
  7176. stackPtr = memStart + ceFrame.mStackAddr;
  7177. framePtr = memStart + ceFrame.mFrameAddr;
  7178. returnType = ceFrame.mReturnType;
  7179. mCallStack.pop_back();
  7180. }
  7181. break;
  7182. case CeOp_SetRetType:
  7183. {
  7184. int typeId = CE_GETINST(int32);
  7185. returnType = GetBfType(typeId);
  7186. BF_ASSERT(returnType != NULL);
  7187. }
  7188. break;
  7189. case CeOp_Jmp:
  7190. {
  7191. auto relOfs = CE_GETINST(int32);
  7192. instPtr += relOfs;
  7193. }
  7194. break;
  7195. case CeOp_JmpIf:
  7196. {
  7197. auto relOfs = CE_GETINST(int32);
  7198. bool cond = CE_GETFRAME(bool);
  7199. if (cond)
  7200. instPtr += relOfs - 4;
  7201. }
  7202. break;
  7203. case CeOp_JmpIfNot:
  7204. {
  7205. auto relOfs = CE_GETINST(int32);
  7206. bool cond = CE_GETFRAME(bool);
  7207. if (!cond)
  7208. instPtr += relOfs - 4;
  7209. }
  7210. break;
  7211. case CeOp_Error:
  7212. {
  7213. auto errorKind = (CeErrorKind)CE_GETINST(int32);
  7214. switch (errorKind)
  7215. {
  7216. case CeErrorKind_GlobalVariable:
  7217. _Fail("Global variable access not allowed");
  7218. break;
  7219. case CeErrorKind_FunctionPointer:
  7220. _Fail("Function pointer calls not allowed");
  7221. break;
  7222. case CeErrorKind_Intrinsic:
  7223. _Fail("Intrinsic not allowed");
  7224. break;
  7225. case CeErrorKind_ObjectDynCheckFailed:
  7226. _Fail("Dynamic cast check failed");
  7227. break;
  7228. default:
  7229. _Fail("Operation not allowed");
  7230. break;
  7231. }
  7232. }
  7233. break;
  7234. case CeOp_DynamicCastCheck:
  7235. {
  7236. auto& result = CE_GETFRAME(uint32);
  7237. auto valueAddr = CE_GETFRAME(addr_ce);
  7238. int32 ifaceId = CE_GETINST(int32);
  7239. if (valueAddr == 0)
  7240. {
  7241. CeSetAddrVal(&result, 0, ptrSize);
  7242. }
  7243. else
  7244. {
  7245. CE_CHECKADDR(valueAddr, sizeof(int32));
  7246. auto wantType = GetBfType(ifaceId);
  7247. int32 objTypeId = *(int32*)(memStart + valueAddr);
  7248. auto valueType = GetBfType(objTypeId);
  7249. if ((wantType == NULL) || (valueType == NULL))
  7250. {
  7251. _Fail("Invalid type in CeOp_DynamicCastCheck");
  7252. return false;
  7253. }
  7254. bool matches = false;
  7255. if (ceModule->TypeIsSubTypeOf(valueType->ToTypeInstance(), wantType->ToTypeInstance(), false))
  7256. {
  7257. matches = true;
  7258. }
  7259. else if ((valueType->IsDelegate()) && (wantType->IsDelegate()))
  7260. {
  7261. int valueSignatureId = ceModule->GetDelegateSignatureId(valueType->ToTypeInstance());
  7262. int checkSignatureId = ceModule->GetDelegateSignatureId(wantType->ToTypeInstance());
  7263. matches = valueSignatureId == checkSignatureId;
  7264. }
  7265. if (matches)
  7266. CeSetAddrVal(&result, valueAddr, ptrSize);
  7267. else
  7268. CeSetAddrVal(&result, 0, ptrSize);
  7269. }
  7270. }
  7271. break;
  7272. case CeOp_GetReflectType:
  7273. {
  7274. auto frameOfs = CE_GETINST(int32);
  7275. int32 typeId = CE_GETINST(int32);
  7276. auto reflectType = GetReflectType(typeId);
  7277. _FixVariables();
  7278. CeSetAddrVal(framePtr + frameOfs, reflectType, ptrSize);
  7279. }
  7280. break;
  7281. case CeOp_GetString:
  7282. {
  7283. auto frameOfs = CE_GETINST(int32);
  7284. auto stringTableIdx = CE_GETINST(int32);
  7285. auto& ceStringEntry = ceFunction->mStringTable[stringTableIdx];
  7286. if (ceStringEntry.mBindExecuteId != mExecuteId)
  7287. {
  7288. ceStringEntry.mStringAddr = GetString(ceStringEntry.mStringId);
  7289. _FixVariables();
  7290. ceStringEntry.mBindExecuteId = mExecuteId;
  7291. }
  7292. CeSetAddrVal(framePtr + frameOfs, ceStringEntry.mStringAddr, ptrSize);
  7293. }
  7294. break;
  7295. case CeOp_Malloc:
  7296. {
  7297. auto frameOfs = CE_GETINST(int32);
  7298. int64 size;
  7299. if (ptrSize == 4)
  7300. size = CE_GETFRAME(int32);
  7301. else
  7302. size = CE_GETFRAME(int64);
  7303. CE_CHECKALLOC(size);
  7304. uint8* mem = CeMalloc(size);
  7305. _FixVariables();
  7306. CeSetAddrVal(framePtr + frameOfs, mem - memStart, ptrSize);
  7307. }
  7308. break;
  7309. case CeOp_Free:
  7310. {
  7311. auto freeAddr = CE_GETFRAME(addr_ce);
  7312. bool success = CeFree(freeAddr);
  7313. if (!success)
  7314. _Fail("Invalid heap address");
  7315. }
  7316. break;
  7317. case CeOp_MemSet:
  7318. {
  7319. auto destAddr = CE_GETFRAME(addr_ce);
  7320. uint8 setValue = CE_GETFRAME(uint8);
  7321. int32 setSize = CE_GETFRAME(int32);
  7322. CE_CHECKSIZE(setSize);
  7323. CE_CHECKADDR(destAddr, setSize);
  7324. memset(memStart + destAddr, setValue, setSize);
  7325. }
  7326. break;
  7327. case CeOp_MemSet_Const:
  7328. {
  7329. auto destAddr = CE_GETFRAME(addr_ce);
  7330. uint8 setValue = CE_GETINST(uint8);
  7331. int32 setSize = CE_GETINST(int32);
  7332. CE_CHECKSIZE(setSize);
  7333. CE_CHECKADDR(destAddr, setSize);
  7334. memset(memStart + destAddr, setValue, setSize);
  7335. }
  7336. break;
  7337. case CeOp_MemCpy:
  7338. {
  7339. auto destAddr = CE_GETFRAME(addr_ce);
  7340. auto srcAddr = CE_GETFRAME(addr_ce);
  7341. int32 size = CE_GETFRAME(int32);
  7342. CE_CHECKSIZE(size);
  7343. CE_CHECKADDR(srcAddr, size);
  7344. CE_CHECKADDR(destAddr, size);
  7345. memmove(memStart + destAddr, memStart + srcAddr, size);
  7346. }
  7347. break;
  7348. case CeOp_FrameAddr_32:
  7349. {
  7350. auto& result = CE_GETFRAME(int32);
  7351. auto addr = &CE_GETFRAME(uint8);
  7352. result = addr - memStart;
  7353. }
  7354. break;
  7355. case CeOp_FrameAddr_64:
  7356. {
  7357. //if (instPtr - ceFunction->mCode.mVals == 0x9c1)
  7358. auto& result = CE_GETFRAME(int64);
  7359. auto addr = &CE_GETFRAME(uint8);
  7360. result = addr - memStart;
  7361. }
  7362. break;
  7363. case CeOp_FrameAddrOfs_32:
  7364. {
  7365. auto& result = CE_GETFRAME(int32);
  7366. auto addr = &CE_GETFRAME(uint8);
  7367. int32 ofs = CE_GETINST(int32);
  7368. result = (int32)(addr - memStart + ofs);
  7369. }
  7370. break;
  7371. case CeOp_ConstData:
  7372. {
  7373. auto frameOfs = CE_GETINST(int32);
  7374. int32 constIdx = CE_GETINST(int32);
  7375. auto& constEntry = ceFunction->mConstStructTable[constIdx];
  7376. if (constEntry.mBindExecuteId != mExecuteId)
  7377. {
  7378. PrepareConstStructEntry(constEntry);
  7379. _FixVariables();
  7380. }
  7381. auto& buff = (constEntry.mFixedData.mSize > 0) ? constEntry.mFixedData : constEntry.mData;
  7382. memcpy(framePtr + frameOfs, buff.mVals, buff.mSize);
  7383. }
  7384. break;
  7385. case CeOp_ConstDataRef:
  7386. {
  7387. auto frameOfs = CE_GETINST(int32);
  7388. int32 constIdx = CE_GETINST(int32);
  7389. auto& constEntry = ceFunction->mConstStructTable[constIdx];
  7390. if (constEntry.mBindExecuteId != mExecuteId)
  7391. {
  7392. PrepareConstStructEntry(constEntry);
  7393. _FixVariables();
  7394. auto& buff = (constEntry.mFixedData.mSize > 0) ? constEntry.mFixedData : constEntry.mData;
  7395. addr_ce* constAddrPtr = NULL;
  7396. if (mConstDataMap.TryAdd(constEntry.mHash, NULL, &constAddrPtr))
  7397. {
  7398. uint8* data = CeMalloc(buff.mSize);
  7399. _FixVariables();
  7400. memcpy(data, &buff[0], buff.mSize);
  7401. *constAddrPtr = (addr_ce)(data - memStart);
  7402. }
  7403. constEntry.mAddr = *constAddrPtr;
  7404. constEntry.mBindExecuteId = mExecuteId;
  7405. }
  7406. *(addr_ce*)(framePtr + frameOfs) = constEntry.mAddr;
  7407. }
  7408. break;
  7409. case CeOp_Zero:
  7410. {
  7411. auto resultPtr = &CE_GETFRAME(uint8);
  7412. int32 constSize = CE_GETINST(int32);
  7413. memset(resultPtr, 0, constSize);
  7414. }
  7415. break;
  7416. case CeOp_Const_8:
  7417. {
  7418. auto& result = CE_GETFRAME(int8);
  7419. result = CE_GETINST(int8);
  7420. }
  7421. break;
  7422. case CeOp_Const_16:
  7423. {
  7424. auto& result = CE_GETFRAME(int16);
  7425. result = CE_GETINST(int16);
  7426. }
  7427. break;
  7428. case CeOp_Const_32:
  7429. {
  7430. auto& result = CE_GETFRAME(int32);
  7431. result = CE_GETINST(int32);
  7432. }
  7433. break;
  7434. case CeOp_Const_64:
  7435. {
  7436. auto& result = CE_GETFRAME(int64);
  7437. result = CE_GETINST(int64);
  7438. }
  7439. break;
  7440. case CeOp_Const_X:
  7441. {
  7442. int32 constSize = CE_GETINST(int32);
  7443. auto resultPtr = &CE_GETFRAME(uint8);
  7444. memcpy(resultPtr, instPtr, constSize);
  7445. instPtr += constSize;
  7446. }
  7447. break;
  7448. case CeOp_Load_8:
  7449. CE_LOAD(uint8);
  7450. break;
  7451. case CeOp_Load_16:
  7452. CE_LOAD(uint16);
  7453. break;
  7454. case CeOp_Load_32:
  7455. CE_LOAD(uint32);
  7456. break;
  7457. case CeOp_Load_64:
  7458. CE_LOAD(uint64);
  7459. break;
  7460. case CeOp_Load_X:
  7461. {
  7462. int32 size = CE_GETINST(int32);
  7463. auto resultPtr = &CE_GETFRAME(uint8);
  7464. auto ceAddr = CE_GETFRAME(addr_ce);
  7465. CE_CHECKADDR(ceAddr, size);
  7466. memcpy(resultPtr, memStart + ceAddr, size);
  7467. }
  7468. break;
  7469. case CeOp_Store_8:
  7470. CE_STORE(uint8);
  7471. break;
  7472. case CeOp_Store_16:
  7473. CE_STORE(uint16);
  7474. break;
  7475. case CeOp_Store_32:
  7476. CE_STORE(uint32);
  7477. break;
  7478. case CeOp_Store_64:
  7479. CE_STORE(uint64);
  7480. break;
  7481. case CeOp_Store_X:
  7482. {
  7483. auto size = CE_GETINST(int32);
  7484. auto srcPtr = &CE_GETFRAME(uint8);
  7485. auto ceAddr = CE_GETFRAME(addr_ce);
  7486. CE_CHECKADDR(ceAddr, size);
  7487. memcpy(memStart + ceAddr, srcPtr, size);
  7488. }
  7489. break;
  7490. case CeOp_Move_8:
  7491. CEOP_MOVE(int8);
  7492. break;
  7493. case CeOp_Move_16:
  7494. CEOP_MOVE(int16);
  7495. break;
  7496. case CeOp_Move_32:
  7497. CEOP_MOVE(int32);
  7498. break;
  7499. case CeOp_Move_64:
  7500. CEOP_MOVE(int64);
  7501. break;
  7502. case CeOp_Move_X:
  7503. {
  7504. int32 size = CE_GETINST(int32);
  7505. auto valPtr = &CE_GETFRAME(uint8);
  7506. auto destPtr = &CE_GETFRAME(uint8);
  7507. memcpy(destPtr, valPtr, size);
  7508. }
  7509. break;
  7510. case CeOp_Push_8:
  7511. CEOP_PUSH(int8);
  7512. break;
  7513. case CeOp_Push_16:
  7514. CEOP_PUSH(int16);
  7515. break;
  7516. case CeOp_Push_32:
  7517. CEOP_PUSH(int32);
  7518. break;
  7519. case CeOp_Push_64:
  7520. CEOP_PUSH(int64);
  7521. break;
  7522. case CeOp_Pop_8:
  7523. CEOP_POP(int8);
  7524. break;
  7525. case CeOp_Pop_16:
  7526. CEOP_POP(int16);
  7527. break;
  7528. case CeOp_Pop_32:
  7529. CEOP_POP(int32);
  7530. break;
  7531. case CeOp_Pop_64:
  7532. CEOP_POP(int64);
  7533. break;
  7534. case CeOp_Pop_X:
  7535. {
  7536. int32 size = CE_GETINST(int32);
  7537. auto resultPtr = &CE_GETFRAME(uint8);
  7538. memcpy(resultPtr, stackPtr, size);
  7539. stackPtr += size;
  7540. }
  7541. break;
  7542. case CeOp_AdjustSP:
  7543. {
  7544. int32 adjust = CE_GETFRAME(int32);
  7545. stackPtr += adjust;
  7546. }
  7547. break;
  7548. case CeOp_AdjustSPNeg:
  7549. {
  7550. int32 adjust = CE_GETFRAME(int32);
  7551. stackPtr -= adjust;
  7552. }
  7553. break;
  7554. case CeOp_AdjustSPConst:
  7555. {
  7556. int32 adjust = CE_GETINST(int32);
  7557. stackPtr += adjust;
  7558. }
  7559. break;
  7560. case CeOp_GetSP:
  7561. {
  7562. auto& result = CE_GETFRAME(int32);
  7563. result = stackPtr - memStart;
  7564. }
  7565. break;
  7566. case CeOp_SetSP:
  7567. {
  7568. auto addr = CE_GETFRAME(int32);
  7569. stackPtr = memStart + addr;
  7570. }
  7571. break;
  7572. case CeOp_GetStaticField:
  7573. case CeOp_GetStaticField_Initializer:
  7574. {
  7575. auto frameOfs = CE_GETINST(int32);
  7576. int32 tableIdx = CE_GETINST(int32);
  7577. int32 initializerFrameOfs = 0;
  7578. if (op == CeOp_GetStaticField_Initializer)
  7579. {
  7580. initializerFrameOfs = CE_GETINST(int32);;
  7581. }
  7582. CeFunction* ctorCallFunction = NULL;
  7583. auto& ceStaticFieldEntry = ceFunction->mStaticFieldTable[tableIdx];
  7584. if (ceStaticFieldEntry.mBindExecuteId != mExecuteId)
  7585. {
  7586. if ((ceStaticFieldEntry.mTypeId > 0) && (mStaticCtorExecSet.TryAdd(ceStaticFieldEntry.mTypeId, NULL)) && (!ceStaticFieldEntry.mName.StartsWith("#")))
  7587. {
  7588. auto bfType = GetBfType(ceStaticFieldEntry.mTypeId);
  7589. BfTypeInstance* bfTypeInstance = NULL;
  7590. if (bfType != NULL)
  7591. bfTypeInstance = bfType->ToTypeInstance();
  7592. if (bfTypeInstance == NULL)
  7593. {
  7594. _Fail("Invalid type");
  7595. return false;
  7596. }
  7597. if (bfType->mDefineState == BfTypeDefineState_CETypeInit)
  7598. {
  7599. // Don't create circular references
  7600. }
  7601. else
  7602. {
  7603. auto methodDef = bfTypeInstance->mTypeDef->GetMethodByName("__BfStaticCtor");
  7604. if (methodDef != NULL)
  7605. {
  7606. auto moduleMethodInstance = ceModule->GetMethodInstance(bfTypeInstance, methodDef, BfTypeVector());
  7607. if (!moduleMethodInstance)
  7608. {
  7609. _Fail("No static ctor instance found");
  7610. return false;
  7611. }
  7612. ceModule->PopulateType(bfTypeInstance, BfPopulateType_DataAndMethods);
  7613. bool added = false;
  7614. ctorCallFunction = mCeMachine->GetFunction(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, added);
  7615. if (ctorCallFunction->mInitializeState < CeFunction::InitializeState_Initialized)
  7616. mCeMachine->PrepareFunction(ctorCallFunction, NULL);
  7617. }
  7618. }
  7619. }
  7620. CeStaticFieldInfo* staticFieldInfo = NULL;
  7621. mStaticFieldMap.TryAdd(ceStaticFieldEntry.mName, NULL, &staticFieldInfo);
  7622. if (staticFieldInfo->mAddr == 0)
  7623. {
  7624. if (ceStaticFieldEntry.mSize < 0)
  7625. _Fail(StrFormat("Reference to unsized global variable '%s'", ceStaticFieldEntry.mName.c_str()));
  7626. CE_CHECKALLOC(ceStaticFieldEntry.mSize);
  7627. uint8* ptr = CeMalloc(ceStaticFieldEntry.mSize);
  7628. _FixVariables();
  7629. if (ceStaticFieldEntry.mSize > 0)
  7630. memset(ptr, 0, ceStaticFieldEntry.mSize);
  7631. staticFieldInfo->mAddr = (addr_ce)(ptr - memStart);
  7632. if (op == CeOp_GetStaticField_Initializer)
  7633. {
  7634. void* initDataPtr = framePtr + initializerFrameOfs;
  7635. memcpy(ptr, initDataPtr, ceStaticFieldEntry.mSize);
  7636. }
  7637. if (ceStaticFieldEntry.mName.StartsWith("#"))
  7638. {
  7639. addr_ce resultAddr = 0;
  7640. if (ceStaticFieldEntry.mName == "#CallerLineNum")
  7641. {
  7642. *(int*)ptr = mCurModule->mCurFilePosition.mCurLine;
  7643. }
  7644. else if (ceStaticFieldEntry.mName == "#CallerFilePath")
  7645. {
  7646. String filePath;
  7647. if (mCurModule->mCurFilePosition.mFileInstance != NULL)
  7648. filePath = mCurModule->mCurFilePosition.mFileInstance->mParser->mFileName;
  7649. resultAddr = GetString(filePath);
  7650. }
  7651. else if (ceStaticFieldEntry.mName == "#CallerFileName")
  7652. {
  7653. String filePath;
  7654. if (mCurModule->mCurFilePosition.mFileInstance != NULL)
  7655. filePath = mCurModule->mCurFilePosition.mFileInstance->mParser->mFileName;
  7656. resultAddr = GetString(GetFileName(filePath));
  7657. }
  7658. else if (ceStaticFieldEntry.mName == "#CallerFileDir")
  7659. {
  7660. String filePath;
  7661. if (mCurModule->mCurFilePosition.mFileInstance != NULL)
  7662. filePath = mCurModule->mCurFilePosition.mFileInstance->mParser->mFileName;
  7663. resultAddr = GetString(GetFileDir(filePath));
  7664. }
  7665. else if (ceStaticFieldEntry.mName == "#CallerTypeName")
  7666. {
  7667. String typeName = "";
  7668. typeName = mCeMachine->mCeModule->TypeToString(mCallerTypeInstance);
  7669. resultAddr = GetString(typeName);
  7670. }
  7671. else if (ceStaticFieldEntry.mName == "#CallerType")
  7672. {
  7673. addr_ce typeAddr = GetReflectType(mCallerTypeInstance->mTypeId);
  7674. resultAddr = typeAddr;
  7675. }
  7676. else if (ceStaticFieldEntry.mName == "#CallerMemberName")
  7677. {
  7678. String memberName = mCeMachine->mCeModule->MethodToString(mCallerMethodInstance);
  7679. resultAddr = GetString(memberName);
  7680. }
  7681. else if (ceStaticFieldEntry.mName == "#CallerProject")
  7682. {
  7683. BfProject* project = NULL;
  7684. project = mCallerTypeInstance->mTypeDef->mProject;
  7685. if (project != NULL)
  7686. resultAddr = GetString(project->mName);
  7687. }
  7688. else if (ceStaticFieldEntry.mName == "#OrigCalleeType")
  7689. {
  7690. if (mCurCallSource->mOrigCalleeType != NULL)
  7691. {
  7692. addr_ce typeAddr = GetReflectType(mCurCallSource->mOrigCalleeType->mTypeId);
  7693. resultAddr = typeAddr;
  7694. }
  7695. }
  7696. if (resultAddr != 0)
  7697. {
  7698. _FixVariables();
  7699. CeSetAddrVal(memStart + staticFieldInfo->mAddr, resultAddr, ptrSize);
  7700. }
  7701. }
  7702. }
  7703. ceStaticFieldEntry.mAddr = staticFieldInfo->mAddr;
  7704. ceStaticFieldEntry.mBindExecuteId = mExecuteId;
  7705. }
  7706. *(addr_ce*)(framePtr + frameOfs) = ceStaticFieldEntry.mAddr;
  7707. if (ctorCallFunction != NULL)
  7708. {
  7709. bool handled = false;
  7710. if (!_CheckFunction(ctorCallFunction, handled))
  7711. return false;
  7712. if (handled)
  7713. break;
  7714. CE_CALL(ctorCallFunction);
  7715. }
  7716. }
  7717. break;
  7718. case CeOp_GetMethod:
  7719. {
  7720. BF_ASSERT(memStart == mMemory.mVals);
  7721. auto resultFrameIdx = CE_GETINST(int32);
  7722. int32 callIdx = CE_GETINST(int32);
  7723. auto& callEntry = ceFunction->mCallTable[callIdx];
  7724. if (callEntry.mBindRevision != mCeMachine->mMethodBindRevision)
  7725. {
  7726. callEntry.mFunction = NULL;
  7727. //mNamedFunctionMap.TryGetValue(callEntry.mFunctionName, &callEntry.mFunction);
  7728. if (callEntry.mFunctionInfo == NULL)
  7729. {
  7730. _Fail("Unable to locate function entry");
  7731. return false;
  7732. }
  7733. if ((callEntry.mFunctionInfo->mCeFunction == NULL) && (!callEntry.mFunctionInfo->mMethodRef.IsNull()))
  7734. {
  7735. auto methodRef = callEntry.mFunctionInfo->mMethodRef;
  7736. if (methodRef.mMethodNum >= methodRef.mTypeInstance->mTypeDef->mMethods.mSize)
  7737. {
  7738. // Must be a comptime-generated method
  7739. ceModule->PopulateType(methodRef.mTypeInstance);
  7740. }
  7741. if (methodRef.mMethodNum >= methodRef.mTypeInstance->mTypeDef->mMethods.mSize)
  7742. {
  7743. _Fail("OOB method reference");
  7744. return false;
  7745. }
  7746. auto methodDef = methodRef.mTypeInstance->mTypeDef->mMethods[methodRef.mMethodNum];
  7747. auto moduleMethodInstance = ceModule->GetMethodInstance(methodRef.mTypeInstance, methodDef,
  7748. methodRef.mMethodGenericArguments);
  7749. if (moduleMethodInstance)
  7750. {
  7751. auto ceFunction = mCeMachine->QueueMethod(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc);
  7752. if (ceFunction == NULL)
  7753. {
  7754. _Fail("Method generation failed");
  7755. return false;
  7756. }
  7757. ceFunction->mCeFunctionInfo->mRefCount++;
  7758. mCeMachine->DerefMethodInfo(callEntry.mFunctionInfo);
  7759. callEntry.mFunctionInfo = ceFunction->mCeFunctionInfo;
  7760. }
  7761. }
  7762. if (callEntry.mFunctionInfo->mCeFunction == NULL)
  7763. {
  7764. _Fail("Method not generated");
  7765. return false;
  7766. }
  7767. callEntry.mFunction = callEntry.mFunctionInfo->mCeFunction;
  7768. if (callEntry.mFunction->mInitializeState < CeFunction::InitializeState_Initialized)
  7769. {
  7770. auto curFrame = _GetCurFrame();
  7771. SetAndRestoreValue<CeFrame*> prevFrame(mCurFrame, &curFrame);
  7772. BF_ASSERT(callEntry.mFunction->mInitializeState < CeFunction::InitializeState_Initialized);
  7773. mCeMachine->PrepareFunction(callEntry.mFunction, NULL);
  7774. }
  7775. if (callEntry.mFunction->mMethodInstance != NULL)
  7776. {
  7777. if (callEntry.mFunction->mMethodInstance->GetOwner()->IsDeleting())
  7778. {
  7779. _Fail("Calling method on deleted type");
  7780. return false;
  7781. }
  7782. }
  7783. callEntry.mBindRevision = mCeMachine->mMethodBindRevision;
  7784. }
  7785. BF_ASSERT(memStart == mMemory.mVals);
  7786. auto callFunction = callEntry.mFunction;
  7787. if (needsFunctionIds)
  7788. *(int32*)(framePtr + resultFrameIdx) = callFunction->mId;
  7789. else
  7790. *(CeFunction**)(framePtr + resultFrameIdx) = callFunction;
  7791. }
  7792. break;
  7793. case CeOp_GetMethod_Inner:
  7794. {
  7795. auto resultFrameIdx = CE_GETINST(int32);
  7796. int32 innerIdx = CE_GETINST(int32);
  7797. auto outerFunction = ceFunction;
  7798. if (outerFunction->mCeInnerFunctionInfo != NULL)
  7799. outerFunction = outerFunction->mCeInnerFunctionInfo->mOwner;
  7800. auto callFunction = outerFunction->mInnerFunctions[innerIdx];
  7801. if (needsFunctionIds)
  7802. *(int32*)(framePtr + resultFrameIdx) = callFunction->mId;
  7803. else
  7804. *(CeFunction**)(framePtr + resultFrameIdx) = callFunction;
  7805. }
  7806. break;
  7807. case CeOp_GetMethod_Virt:
  7808. {
  7809. auto resultFrameIdx = CE_GETINST(int32);
  7810. auto valueAddr = CE_GETFRAME(addr_ce);
  7811. int32 virtualIdx = CE_GETINST(int32);
  7812. CE_CHECKADDR(valueAddr, sizeof(int32));
  7813. int32 objTypeId = *(int32*)(memStart + valueAddr);
  7814. BfType* bfType = GetBfType(objTypeId);
  7815. if ((bfType == NULL) || (!bfType->IsObject()))
  7816. {
  7817. _Fail("Invalid virtual method target");
  7818. return false;
  7819. }
  7820. auto valueType = bfType->ToTypeInstance();
  7821. if (valueType->mVirtualMethodTable.IsEmpty())
  7822. ceModule->PopulateType(valueType, BfPopulateType_Full_Force);
  7823. if (valueType->mVirtualMethodTable.IsEmpty())
  7824. {
  7825. _Fail("Empty virtual table");
  7826. return false;
  7827. }
  7828. auto& methodRef = valueType->mVirtualMethodTable[virtualIdx].mImplementingMethod;
  7829. if (methodRef.mTypeInstance->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted)
  7830. ceModule->PopulateType(methodRef.mTypeInstance, BfPopulateType_DataAndMethods);
  7831. auto methodInstance = (BfMethodInstance*)methodRef;
  7832. auto callFunction = mCeMachine->GetPreparedFunction(methodInstance);
  7833. if (needsFunctionIds)
  7834. *(int32*)(framePtr + resultFrameIdx) = callFunction->mId;
  7835. else
  7836. *(CeFunction**)(framePtr + resultFrameIdx) = callFunction;
  7837. }
  7838. break;
  7839. case CeOp_GetMethod_IFace:
  7840. {
  7841. auto resultFrameIdx = CE_GETINST(int32);
  7842. auto valueAddr = CE_GETFRAME(addr_ce);
  7843. int32 ifaceId = CE_GETINST(int32);
  7844. int32 methodIdx = CE_GETINST(int32);
  7845. auto ifaceType = ceModule->mContext->mTypes[ifaceId]->ToTypeInstance();
  7846. CE_CHECKADDR(valueAddr, sizeof(int32));
  7847. int32 objTypeId = *(int32*)(memStart + valueAddr);
  7848. auto bfObjectType = GetBfType(objTypeId);
  7849. if ((bfObjectType == NULL) || (!bfObjectType->IsTypeInstance()))
  7850. {
  7851. _Fail("Invalid object");
  7852. return false;
  7853. }
  7854. auto valueType = bfObjectType->ToTypeInstance();
  7855. BfMethodInstance* methodInstance = NULL;
  7856. if (valueType != NULL)
  7857. {
  7858. if (valueType->mVirtualMethodTable.IsEmpty())
  7859. ceModule->PopulateType(valueType, BfPopulateType_DataAndMethods);
  7860. auto checkType = valueType;
  7861. while (checkType != NULL)
  7862. {
  7863. for (auto& iface : checkType->mInterfaces)
  7864. {
  7865. if (iface.mInterfaceType == ifaceType)
  7866. {
  7867. if (valueType->mInterfaceMethodTable.IsEmpty())
  7868. ceModule->PopulateType(valueType, BfPopulateType_Full_Force);
  7869. if (valueType->mInterfaceMethodTable.IsEmpty())
  7870. {
  7871. _Fail("Empty interface table");
  7872. return false;
  7873. }
  7874. methodInstance = valueType->mInterfaceMethodTable[iface.mStartInterfaceTableIdx + methodIdx].mMethodRef;
  7875. break;
  7876. }
  7877. }
  7878. checkType = checkType->mBaseType;
  7879. }
  7880. }
  7881. if (methodInstance == NULL)
  7882. {
  7883. _Fail("Failed to invoke interface method");
  7884. return false;
  7885. }
  7886. auto callFunction = mCeMachine->GetPreparedFunction(methodInstance);
  7887. if (needsFunctionIds)
  7888. *(int32*)(framePtr + resultFrameIdx) = callFunction->mId;
  7889. else
  7890. *(CeFunction**)(framePtr + resultFrameIdx) = callFunction;
  7891. }
  7892. break;
  7893. case CeOp_Call:
  7894. {
  7895. callCount++;
  7896. CeFunction* callFunction;
  7897. if (needsFunctionIds)
  7898. {
  7899. int32 functionId = CE_GETFRAME(int32);
  7900. callFunction = mCeMachine->mFunctionIdMap[functionId];
  7901. }
  7902. else
  7903. callFunction = CE_GETFRAME(CeFunction*);
  7904. bool handled = false;
  7905. if (!_CheckFunction(callFunction, handled))
  7906. return false;
  7907. if (callFunction->mIsVarReturn)
  7908. _Fail("Illegal call to method with 'var' return.");
  7909. if (handled)
  7910. break;
  7911. CE_CALL(callFunction);
  7912. }
  7913. break;
  7914. case CeOp_Conv_I8_I16:
  7915. CE_CAST(int8, int16);
  7916. break;
  7917. case CeOp_Conv_I8_I32:
  7918. CE_CAST(int8, int32);
  7919. break;
  7920. case CeOp_Conv_I8_I64:
  7921. CE_CAST(int8, int64);
  7922. break;
  7923. case CeOp_Conv_I8_F32:
  7924. CE_CAST(int8, float);
  7925. break;
  7926. case CeOp_Conv_I8_F64:
  7927. CE_CAST(int8, double);
  7928. break;
  7929. case CeOp_Conv_I16_I32:
  7930. CE_CAST(int16, int32);
  7931. break;
  7932. case CeOp_Conv_I16_I64:
  7933. CE_CAST(int16, int64);
  7934. break;
  7935. case CeOp_Conv_I16_F32:
  7936. CE_CAST(int16, float);
  7937. break;
  7938. case CeOp_Conv_I16_F64:
  7939. CE_CAST(int16, double);
  7940. break;
  7941. case CeOp_Conv_I32_I64:
  7942. CE_CAST(int32, int64);
  7943. break;
  7944. case CeOp_Conv_I32_F32:
  7945. CE_CAST(int32, float);
  7946. break;
  7947. case CeOp_Conv_I32_F64:
  7948. CE_CAST(int32, double);
  7949. break;
  7950. case CeOp_Conv_I64_F32:
  7951. CE_CAST(int64, float);
  7952. break;
  7953. case CeOp_Conv_I64_F64:
  7954. CE_CAST(int64, double);
  7955. break;
  7956. case CeOp_Conv_U8_U16:
  7957. CE_CAST(uint8, uint16);
  7958. break;
  7959. case CeOp_Conv_U8_U32:
  7960. CE_CAST(uint8, uint32);
  7961. break;
  7962. case CeOp_Conv_U8_U64:
  7963. CE_CAST(uint8, uint64);
  7964. break;
  7965. case CeOp_Conv_U8_F32:
  7966. CE_CAST(uint8, float);
  7967. break;
  7968. case CeOp_Conv_U8_F64:
  7969. CE_CAST(uint8, double);
  7970. break;
  7971. case CeOp_Conv_U16_U32:
  7972. CE_CAST(uint16, uint32);
  7973. break;
  7974. case CeOp_Conv_U16_U64:
  7975. CE_CAST(uint16, uint64);
  7976. break;
  7977. case CeOp_Conv_U16_F32:
  7978. CE_CAST(uint16, float);
  7979. break;
  7980. case CeOp_Conv_U16_F64:
  7981. CE_CAST(uint16, double);
  7982. break;
  7983. case CeOp_Conv_U32_U64:
  7984. CE_CAST(uint32, uint64);
  7985. break;
  7986. case CeOp_Conv_U32_F32:
  7987. CE_CAST(uint32, float);
  7988. break;
  7989. case CeOp_Conv_U32_F64:
  7990. CE_CAST(uint32, double);
  7991. break;
  7992. case CeOp_Conv_U64_F32:
  7993. CE_CAST(uint64, float);
  7994. break;
  7995. case CeOp_Conv_U64_F64:
  7996. CE_CAST(uint64, double);
  7997. break;
  7998. case CeOp_Conv_F32_I8:
  7999. CE_CAST(float, int8);
  8000. break;
  8001. case CeOp_Conv_F32_I16:
  8002. CE_CAST(float, int16);
  8003. break;
  8004. case CeOp_Conv_F32_I32:
  8005. CE_CAST(float, int32);
  8006. break;
  8007. case CeOp_Conv_F32_I64:
  8008. CE_CAST(float, int64);
  8009. break;
  8010. case CeOp_Conv_F32_F64:
  8011. CE_CAST(float, double);
  8012. break;
  8013. case CeOp_Conv_F64_I8:
  8014. CE_CAST(double, int8);
  8015. break;
  8016. case CeOp_Conv_F64_I16:
  8017. CE_CAST(double, int16);
  8018. break;
  8019. case CeOp_Conv_F64_I32:
  8020. CE_CAST(double, int32);
  8021. break;
  8022. case CeOp_Conv_F64_I64:
  8023. CE_CAST(double, int64);
  8024. break;
  8025. case CeOp_Conv_F64_F32:
  8026. CE_CAST(double, float);
  8027. break;
  8028. case CeOp_Conv_F32_U8:
  8029. CE_CAST(float, uint8);
  8030. break;
  8031. case CeOp_Conv_F32_U16:
  8032. CE_CAST(float, uint16);
  8033. break;
  8034. case CeOp_Conv_F32_U32:
  8035. CE_CAST(float, uint32);
  8036. break;
  8037. case CeOp_Conv_F32_U64:
  8038. CE_CAST(float, uint64);
  8039. break;
  8040. case CeOp_Conv_F64_U8:
  8041. CE_CAST(float, uint8);
  8042. break;
  8043. case CeOp_Conv_F64_U16:
  8044. CE_CAST(float, uint16);
  8045. break;
  8046. case CeOp_Conv_F64_U32:
  8047. CE_CAST(float, uint32);
  8048. break;
  8049. case CeOp_Conv_F64_U64:
  8050. CE_CAST(float, uint64);
  8051. break;
  8052. case CeOp_Abs_I8:
  8053. {
  8054. auto& result = CE_GETFRAME(int8);
  8055. auto val = CE_GETFRAME(int8);
  8056. result = (val < 0) ? -val : val;
  8057. }
  8058. break;
  8059. case CeOp_Abs_I16:
  8060. {
  8061. auto& result = CE_GETFRAME(int16);
  8062. auto val = CE_GETFRAME(int16);
  8063. result = (val < 0) ? -val : val;
  8064. }
  8065. break;
  8066. case CeOp_Abs_I32:
  8067. {
  8068. auto& result = CE_GETFRAME(int32);
  8069. auto val = CE_GETFRAME(int32);
  8070. result = (val < 0) ? -val : val;
  8071. }
  8072. break;
  8073. case CeOp_Abs_I64:
  8074. {
  8075. auto& result = CE_GETFRAME(int64);
  8076. auto val = CE_GETFRAME(int64);
  8077. result = (val < 0) ? -val : val;
  8078. }
  8079. break;
  8080. case CeOp_Abs_F32:
  8081. CEOP_UNARY_FUNC(fabs, float);
  8082. break;
  8083. case CeOp_Abs_F64:
  8084. CEOP_UNARY_FUNC(fabs, double);
  8085. break;
  8086. case CeOp_AddConst_I8:
  8087. CEOP_BIN_CONST(+, int8);
  8088. break;
  8089. case CeOp_AddConst_I16:
  8090. CEOP_BIN_CONST(+, int16);
  8091. break;
  8092. case CeOp_AddConst_I32:
  8093. CEOP_BIN_CONST(+, int32);
  8094. break;
  8095. case CeOp_AddConst_I64:
  8096. CEOP_BIN_CONST(+, int64);
  8097. break;
  8098. case CeOp_Add_I8:
  8099. CEOP_BIN(+, int8);
  8100. break;
  8101. case CeOp_Add_I16:
  8102. CEOP_BIN(+, int16);
  8103. break;
  8104. case CeOp_Add_I32:
  8105. CEOP_BIN(+, int32);
  8106. break;
  8107. case CeOp_Add_I64:
  8108. CEOP_BIN(+, int64);
  8109. break;
  8110. case CeOp_Add_F32:
  8111. CEOP_BIN(+, float);
  8112. break;
  8113. case CeOp_Add_F64:
  8114. CEOP_BIN(+, double);
  8115. break;
  8116. case CeOp_Sub_I8:
  8117. CEOP_BIN(-, int8);
  8118. break;
  8119. case CeOp_Sub_I16:
  8120. CEOP_BIN(-, int16);
  8121. break;
  8122. case CeOp_Sub_I32:
  8123. CEOP_BIN(-, int32);
  8124. break;
  8125. case CeOp_Sub_I64:
  8126. CEOP_BIN(-, int64);
  8127. break;
  8128. case CeOp_Sub_F32:
  8129. CEOP_BIN(-, float);
  8130. break;
  8131. case CeOp_Sub_F64:
  8132. CEOP_BIN(-, double);
  8133. break;
  8134. case CeOp_Mul_I8:
  8135. CEOP_BIN(*, int8);
  8136. break;
  8137. case CeOp_Mul_I16:
  8138. CEOP_BIN(*, int16);
  8139. break;
  8140. case CeOp_Mul_I32:
  8141. CEOP_BIN(*, int32);
  8142. break;
  8143. case CeOp_Mul_I64:
  8144. CEOP_BIN(*, int64);
  8145. break;
  8146. case CeOp_Mul_F32:
  8147. CEOP_BIN(*, float);
  8148. break;
  8149. case CeOp_Mul_F64:
  8150. CEOP_BIN(*, double);
  8151. break;
  8152. case CeOp_Div_I8:
  8153. CEOP_BIN_DIV(/ , int8);
  8154. break;
  8155. case CeOp_Div_I16:
  8156. CEOP_BIN_DIV(/ , int16);
  8157. break;
  8158. case CeOp_Div_I32:
  8159. CEOP_BIN_DIV(/ , int32);
  8160. break;
  8161. case CeOp_Div_I64:
  8162. CEOP_BIN_DIV(/ , int64);
  8163. break;
  8164. case CeOp_Div_F32:
  8165. CEOP_BIN_DIV(/ , float);
  8166. break;
  8167. case CeOp_Div_F64:
  8168. CEOP_BIN_DIV(/ , double);
  8169. break;
  8170. case CeOp_Div_U8:
  8171. CEOP_BIN_DIV(/ , uint8);
  8172. break;
  8173. case CeOp_Div_U16:
  8174. CEOP_BIN_DIV(/ , uint16);
  8175. break;
  8176. case CeOp_Div_U32:
  8177. CEOP_BIN_DIV(/ , uint32);
  8178. break;
  8179. case CeOp_Div_U64:
  8180. CEOP_BIN_DIV(/ , uint64);
  8181. break;
  8182. case CeOp_Mod_I8:
  8183. CEOP_BIN_DIV(%, int8);
  8184. break;
  8185. case CeOp_Mod_I16:
  8186. CEOP_BIN_DIV(%, int16);
  8187. break;
  8188. case CeOp_Mod_I32:
  8189. CEOP_BIN_DIV(%, int32);
  8190. break;
  8191. case CeOp_Mod_I64:
  8192. CEOP_BIN_DIV(%, int64);
  8193. break;
  8194. case CeOp_Mod_F32:
  8195. {
  8196. auto& result = CE_GETFRAME(float);
  8197. auto lhs = CE_GETFRAME(float);
  8198. auto rhs = CE_GETFRAME(float);
  8199. if (rhs == 0)
  8200. {
  8201. _Fail("Division by zero");
  8202. return false;
  8203. }
  8204. result = fmodf(lhs, rhs);
  8205. }
  8206. break;
  8207. case CeOp_Mod_F64:
  8208. {
  8209. auto& result = CE_GETFRAME(double);
  8210. auto lhs = CE_GETFRAME(double);
  8211. auto rhs = CE_GETFRAME(double);
  8212. if (rhs == 0)
  8213. {
  8214. _Fail("Division by zero");
  8215. return false;
  8216. }
  8217. result = fmod(lhs, rhs);
  8218. }
  8219. break;
  8220. case CeOp_Mod_U8:
  8221. CEOP_BIN_DIV(%, uint8);
  8222. break;
  8223. case CeOp_Mod_U16:
  8224. CEOP_BIN_DIV(%, uint16);
  8225. break;
  8226. case CeOp_Mod_U32:
  8227. CEOP_BIN_DIV(%, uint32);
  8228. break;
  8229. case CeOp_Mod_U64:
  8230. CEOP_BIN_DIV(%, uint64);
  8231. break;
  8232. case CeOp_And_I8:
  8233. CEOP_BIN(&, uint8);
  8234. break;
  8235. case CeOp_And_I16:
  8236. CEOP_BIN(&, uint16);
  8237. break;
  8238. case CeOp_And_I32:
  8239. CEOP_BIN(&, uint32);
  8240. break;
  8241. case CeOp_And_I64:
  8242. CEOP_BIN(&, uint64);
  8243. break;
  8244. case CeOp_Or_I8:
  8245. CEOP_BIN(| , uint8);
  8246. break;
  8247. case CeOp_Or_I16:
  8248. CEOP_BIN(| , uint16);
  8249. break;
  8250. case CeOp_Or_I32:
  8251. CEOP_BIN(| , uint32);
  8252. break;
  8253. case CeOp_Or_I64:
  8254. CEOP_BIN(| , uint64);
  8255. break;
  8256. case CeOp_Xor_I8:
  8257. CEOP_BIN(^, uint8);
  8258. break;
  8259. case CeOp_Xor_I16:
  8260. CEOP_BIN(^, uint16);
  8261. break;
  8262. case CeOp_Xor_I32:
  8263. CEOP_BIN(^, uint32);
  8264. break;
  8265. case CeOp_Xor_I64:
  8266. CEOP_BIN(^, uint64);
  8267. break;
  8268. case CeOp_Shl_I8:
  8269. CEOP_BIN2(<< , int8, uint8);
  8270. break;
  8271. case CeOp_Shl_I16:
  8272. CEOP_BIN2(<< , int16, uint8);
  8273. break;
  8274. case CeOp_Shl_I32:
  8275. CEOP_BIN2(<< , int32, uint8);
  8276. break;
  8277. case CeOp_Shl_I64:
  8278. CEOP_BIN2(<< , int64, uint8);
  8279. break;
  8280. case CeOp_Shr_I8:
  8281. CEOP_BIN2(>> , int8, uint8);
  8282. break;
  8283. case CeOp_Shr_I16:
  8284. CEOP_BIN2(>> , int16, uint8);
  8285. break;
  8286. case CeOp_Shr_I32:
  8287. CEOP_BIN2(>> , int32, uint8);
  8288. break;
  8289. case CeOp_Shr_I64:
  8290. CEOP_BIN2(>> , int64, uint8);
  8291. break;
  8292. case CeOp_Shr_U8:
  8293. CEOP_BIN2(>> , uint8, uint8);
  8294. break;
  8295. case CeOp_Shr_U16:
  8296. CEOP_BIN2(>> , uint16, uint8);
  8297. break;
  8298. case CeOp_Shr_U32:
  8299. CEOP_BIN2(>> , uint32, uint8);
  8300. break;
  8301. case CeOp_Shr_U64:
  8302. CEOP_BIN2(>> , uint64, uint8);
  8303. break;
  8304. case CeOp_Acos_F32:
  8305. CEOP_UNARY_FUNC(acosf, float);
  8306. break;
  8307. case CeOp_Acos_F64:
  8308. CEOP_UNARY_FUNC(acos, double);
  8309. break;
  8310. case CeOp_Asin_F32:
  8311. CEOP_UNARY_FUNC(asinf, float);
  8312. break;
  8313. case CeOp_Asin_F64:
  8314. CEOP_UNARY_FUNC(asin, double);
  8315. break;
  8316. case CeOp_Atan_F32:
  8317. CEOP_UNARY_FUNC(atanf, float);
  8318. break;
  8319. case CeOp_Atan_F64:
  8320. CEOP_UNARY_FUNC(atan, double);
  8321. break;
  8322. case CeOp_Atan2_F32:
  8323. CEOP_BIN_FUNC(atan2f, float);
  8324. break;
  8325. case CeOp_Atan2_F64:
  8326. CEOP_BIN_FUNC(atan2, double);
  8327. break;
  8328. case CeOp_Ceiling_F32:
  8329. CEOP_UNARY_FUNC(ceilf, float);
  8330. break;
  8331. case CeOp_Ceiling_F64:
  8332. CEOP_UNARY_FUNC(ceil, double);
  8333. break;
  8334. case CeOp_Cos_F32:
  8335. CEOP_UNARY_FUNC(cosf, float);
  8336. break;
  8337. case CeOp_Cos_F64:
  8338. CEOP_UNARY_FUNC(cos, double);
  8339. break;
  8340. case CeOp_Cosh_F32:
  8341. CEOP_UNARY_FUNC(coshf, float);
  8342. break;
  8343. case CeOp_Cosh_F64:
  8344. CEOP_UNARY_FUNC(cosh, double);
  8345. break;
  8346. case CeOp_Exp_F32:
  8347. CEOP_UNARY_FUNC(expf, float);
  8348. break;
  8349. case CeOp_Exp_F64:
  8350. CEOP_UNARY_FUNC(exp, double);
  8351. break;
  8352. case CeOp_Floor_F32:
  8353. CEOP_UNARY_FUNC(floorf, float);
  8354. break;
  8355. case CeOp_Floor_F64:
  8356. CEOP_UNARY_FUNC(floor, double);
  8357. break;
  8358. case CeOp_Log_F32:
  8359. CEOP_UNARY_FUNC(logf, float);
  8360. break;
  8361. case CeOp_Log_F64:
  8362. CEOP_UNARY_FUNC(log, double);
  8363. break;
  8364. case CeOp_Log10_F32:
  8365. CEOP_UNARY_FUNC(log10f, float);
  8366. break;
  8367. case CeOp_Log10_F64:
  8368. CEOP_UNARY_FUNC(log10, double);
  8369. break;
  8370. case CeOp_Pow_F32:
  8371. CEOP_BIN_FUNC(powf, float);
  8372. break;
  8373. case CeOp_Pow_F64:
  8374. CEOP_BIN_FUNC(pow, double);
  8375. break;
  8376. case CeOp_Round_F32:
  8377. CEOP_UNARY_FUNC(roundf, float);
  8378. break;
  8379. case CeOp_Round_F64:
  8380. CEOP_UNARY_FUNC(round, double);
  8381. break;
  8382. case CeOp_Sin_F32:
  8383. CEOP_UNARY_FUNC(sinf, float);
  8384. break;
  8385. case CeOp_Sin_F64:
  8386. CEOP_UNARY_FUNC(sin, double);
  8387. break;
  8388. case CeOp_Sinh_F32:
  8389. CEOP_UNARY_FUNC(sinhf, float);
  8390. break;
  8391. case CeOp_Sinh_F64:
  8392. CEOP_UNARY_FUNC(sinh, double);
  8393. break;
  8394. case CeOp_Sqrt_F32:
  8395. CEOP_UNARY_FUNC(sqrtf, float);
  8396. break;
  8397. case CeOp_Sqrt_F64:
  8398. CEOP_UNARY_FUNC(sqrt, double);
  8399. break;
  8400. case CeOp_Tan_F32:
  8401. CEOP_UNARY_FUNC(tanf, float);
  8402. break;
  8403. case CeOp_Tan_F64:
  8404. CEOP_UNARY_FUNC(tan, double);
  8405. break;
  8406. case CeOp_Tanh_F32:
  8407. CEOP_UNARY_FUNC(tanhf, float);
  8408. break;
  8409. case CeOp_Tanh_F64:
  8410. CEOP_UNARY_FUNC(tanh, double);
  8411. break;
  8412. case CeOp_Cmp_NE_I8:
  8413. CEOP_CMP(!= , int8);
  8414. break;
  8415. case CeOp_Cmp_NE_I16:
  8416. CEOP_CMP(!= , int16);
  8417. break;
  8418. case CeOp_Cmp_NE_I32:
  8419. CEOP_CMP(!= , int32);
  8420. break;
  8421. case CeOp_Cmp_NE_I64:
  8422. CEOP_CMP(!= , int64);
  8423. break;
  8424. case CeOp_Cmp_NE_F32:
  8425. CEOP_CMP(!= , float);
  8426. break;
  8427. case CeOp_Cmp_NE_F64:
  8428. CEOP_CMP(!= , double);
  8429. break;
  8430. case CeOp_Cmp_EQ_I8:
  8431. CEOP_CMP(== , int8);
  8432. break;
  8433. case CeOp_Cmp_EQ_I16:
  8434. CEOP_CMP(== , int16);
  8435. break;
  8436. case CeOp_Cmp_EQ_I32:
  8437. CEOP_CMP(== , int32);
  8438. break;
  8439. case CeOp_Cmp_EQ_I64:
  8440. CEOP_CMP(== , int64);
  8441. break;
  8442. case CeOp_Cmp_EQ_F32:
  8443. CEOP_CMP(== , float);
  8444. break;
  8445. case CeOp_Cmp_EQ_F64:
  8446. CEOP_CMP(== , double);
  8447. break;
  8448. case CeOp_Cmp_SLT_I8:
  8449. CEOP_CMP(< , int8);
  8450. break;
  8451. case CeOp_Cmp_SLT_I16:
  8452. CEOP_CMP(< , int16);
  8453. break;
  8454. case CeOp_Cmp_SLT_I32:
  8455. CEOP_CMP(< , int32);
  8456. break;
  8457. case CeOp_Cmp_SLT_I64:
  8458. CEOP_CMP(< , int64);
  8459. break;
  8460. case CeOp_Cmp_SLT_F32:
  8461. CEOP_CMP(< , float);
  8462. break;
  8463. case CeOp_Cmp_SLT_F64:
  8464. CEOP_CMP(< , double);
  8465. break;
  8466. case CeOp_Cmp_ULT_I8:
  8467. CEOP_CMP(< , uint8);
  8468. break;
  8469. case CeOp_Cmp_ULT_I16:
  8470. CEOP_CMP(< , uint16);
  8471. break;
  8472. case CeOp_Cmp_ULT_I32:
  8473. CEOP_CMP(< , uint32);
  8474. break;
  8475. case CeOp_Cmp_ULT_I64:
  8476. CEOP_CMP(< , uint64);
  8477. break;
  8478. case CeOp_Cmp_SLE_I8:
  8479. CEOP_CMP(<= , int8);
  8480. break;
  8481. case CeOp_Cmp_SLE_I16:
  8482. CEOP_CMP(<= , int16);
  8483. break;
  8484. case CeOp_Cmp_SLE_I32:
  8485. CEOP_CMP(<= , int32);
  8486. break;
  8487. case CeOp_Cmp_SLE_I64:
  8488. CEOP_CMP(<= , int64);
  8489. break;
  8490. case CeOp_Cmp_SLE_F32:
  8491. CEOP_CMP(<= , float);
  8492. break;
  8493. case CeOp_Cmp_SLE_F64:
  8494. CEOP_CMP(<= , double);
  8495. break;
  8496. case CeOp_Cmp_ULE_I8:
  8497. CEOP_CMP(<= , uint8);
  8498. break;
  8499. case CeOp_Cmp_ULE_I16:
  8500. CEOP_CMP(<= , uint16);
  8501. break;
  8502. case CeOp_Cmp_ULE_I32:
  8503. CEOP_CMP(<= , uint32);
  8504. break;
  8505. case CeOp_Cmp_ULE_I64:
  8506. CEOP_CMP(<= , uint64);
  8507. break;
  8508. case CeOp_Cmp_SGT_I8:
  8509. CEOP_CMP(> , int8);
  8510. break;
  8511. case CeOp_Cmp_SGT_I16:
  8512. CEOP_CMP(> , int16);
  8513. break;
  8514. case CeOp_Cmp_SGT_I32:
  8515. CEOP_CMP(> , int32);
  8516. break;
  8517. case CeOp_Cmp_SGT_I64:
  8518. CEOP_CMP(> , int64);
  8519. break;
  8520. case CeOp_Cmp_SGT_F32:
  8521. CEOP_CMP(> , float);
  8522. break;
  8523. case CeOp_Cmp_SGT_F64:
  8524. CEOP_CMP(> , double);
  8525. break;
  8526. case CeOp_Cmp_UGT_I8:
  8527. CEOP_CMP(> , uint8);
  8528. break;
  8529. case CeOp_Cmp_UGT_I16:
  8530. CEOP_CMP(> , uint16);
  8531. break;
  8532. case CeOp_Cmp_UGT_I32:
  8533. CEOP_CMP(> , uint32);
  8534. break;
  8535. case CeOp_Cmp_UGT_I64:
  8536. CEOP_CMP(> , uint64);
  8537. break;
  8538. case CeOp_Cmp_SGE_I8:
  8539. CEOP_CMP(>= , int8);
  8540. break;
  8541. case CeOp_Cmp_SGE_I16:
  8542. CEOP_CMP(>= , int16);
  8543. break;
  8544. case CeOp_Cmp_SGE_I32:
  8545. CEOP_CMP(>= , int32);
  8546. break;
  8547. case CeOp_Cmp_SGE_I64:
  8548. CEOP_CMP(>= , int64);
  8549. break;
  8550. case CeOp_Cmp_SGE_F32:
  8551. CEOP_CMP(>= , float);
  8552. break;
  8553. case CeOp_Cmp_SGE_F64:
  8554. CEOP_CMP(>= , double);
  8555. break;
  8556. case CeOp_Cmp_UGE_I8:
  8557. CEOP_CMP(>= , uint8);
  8558. break;
  8559. case CeOp_Cmp_UGE_I16:
  8560. CEOP_CMP(>= , uint16);
  8561. break;
  8562. case CeOp_Cmp_UGE_I32:
  8563. CEOP_CMP(>= , uint32);
  8564. break;
  8565. case CeOp_Cmp_UGE_I64:
  8566. CEOP_CMP(>= , uint64);
  8567. break;
  8568. case CeOp_Neg_I8:
  8569. CEOP_UNARY(-, int8);
  8570. break;
  8571. case CeOp_Neg_I16:
  8572. CEOP_UNARY(-, int16);
  8573. break;
  8574. case CeOp_Neg_I32:
  8575. CEOP_UNARY(-, int32);
  8576. break;
  8577. case CeOp_Neg_I64:
  8578. CEOP_UNARY(-, int64);
  8579. break;
  8580. case CeOp_Neg_F32:
  8581. CEOP_UNARY(-, float);
  8582. break;
  8583. case CeOp_Neg_F64:
  8584. CEOP_UNARY(-, double);
  8585. break;
  8586. case CeOp_Not_I1:
  8587. CEOP_UNARY(!, bool);
  8588. break;
  8589. case CeOp_Not_I8:
  8590. CEOP_UNARY(~, int8);
  8591. break;
  8592. case CeOp_Not_I16:
  8593. CEOP_UNARY(~, int16);
  8594. break;
  8595. case CeOp_Not_I32:
  8596. CEOP_UNARY(~, int32);
  8597. break;
  8598. case CeOp_Not_I64:
  8599. CEOP_UNARY(~, int64);
  8600. break;
  8601. default:
  8602. _Fail("Unhandled op");
  8603. return false;
  8604. }
  8605. //BF_ASSERT(_CrtCheckMemory() != 0);
  8606. }
  8607. return true;
  8608. }
  8609. //////////////////////////////////////////////////////////////////////////
  8610. CeMachine::CeMachine(BfCompiler* compiler)
  8611. {
  8612. mCompiler = compiler;
  8613. mCeModule = NULL;
  8614. mRevision = 0;
  8615. mMethodBindRevision = 0;
  8616. mCurContext = NULL;
  8617. mCurCallSource = NULL;
  8618. mExecuteId = -1;
  8619. mCurRecursiveDepth = 0;
  8620. mCurFunctionId = 0;
  8621. mRevisionExecuteTime = 0;
  8622. mCurBuilder = NULL;
  8623. mPreparingFunction = NULL;
  8624. mCurEmitContext = NULL;
  8625. mAppendAllocInfo = NULL;
  8626. mTempParser = NULL;
  8627. mTempReducer = NULL;
  8628. mTempPassInstance = NULL;
  8629. mDebugger = NULL;
  8630. mDbgPaused = false;
  8631. mDbgWantBreak = false;
  8632. mSpecialCheck = false;
  8633. BfLogSys(mCompiler->mSystem, "CeMachine::CeMachine %p\n", this);
  8634. }
  8635. CeMachine::~CeMachine()
  8636. {
  8637. BF_ASSERT(mDebugger == NULL);
  8638. for (auto context : mContextList)
  8639. delete context;
  8640. delete mTempPassInstance;
  8641. delete mTempParser;
  8642. delete mTempReducer;
  8643. delete mAppendAllocInfo;
  8644. delete mCeModule;
  8645. auto _RemoveFunctionInfo = [&](CeFunctionInfo* functionInfo)
  8646. {
  8647. if (functionInfo->mMethodInstance != NULL)
  8648. functionInfo->mMethodInstance->mInCEMachine = false;
  8649. if (functionInfo->mCeFunction != NULL)
  8650. {
  8651. // We don't need to actually unmap it at this point
  8652. functionInfo->mCeFunction->mId = -1;
  8653. for (auto innerFunction : functionInfo->mCeFunction->mInnerFunctions)
  8654. innerFunction->mId = -1;
  8655. }
  8656. delete functionInfo;
  8657. };
  8658. for (auto kv : mNamedFunctionMap)
  8659. {
  8660. if (kv.mValue->mMethodInstance == NULL)
  8661. _RemoveFunctionInfo(kv.mValue);
  8662. }
  8663. for (auto kv : mFunctions)
  8664. {
  8665. BF_ASSERT(kv.mValue != NULL);
  8666. _RemoveFunctionInfo(kv.mValue);
  8667. }
  8668. }
  8669. void CeMachine::Fail(const StringImpl& error)
  8670. {
  8671. if (mFailString.IsEmpty())
  8672. mFailString = error;
  8673. }
  8674. bool CeMachine::HasFailed()
  8675. {
  8676. return !mFailString.IsEmpty();
  8677. }
  8678. void CeMachine::Init()
  8679. {
  8680. BF_ASSERT(mCeModule == NULL);
  8681. mCeModule = new BfModule(mCompiler->mContext, "__constEval");
  8682. mCeModule->mIsSpecialModule = true;
  8683. //mCeModule->mIsScratchModule = true;
  8684. mCeModule->mIsComptimeModule = true;
  8685. //mCeModule->mIsReified = true;
  8686. if (mCompiler->mIsResolveOnly)
  8687. mCeModule->mIsReified = true;
  8688. else
  8689. mCeModule->mIsReified = false;
  8690. mCeModule->Init();
  8691. BF_ASSERT(mCeModule->mBfIRBuilder == NULL);
  8692. mCeModule->mBfIRBuilder = new BfIRBuilder(mCeModule);
  8693. mCeModule->mBfIRBuilder->mDbgVerifyCodeGen = true;
  8694. mCeModule->FinishInit();
  8695. mCeModule->mBfIRBuilder->mHasDebugInfo = true;
  8696. mCeModule->mHasFullDebugInfo = mDebugger != NULL;
  8697. mCeModule->mBfIRBuilder->mIgnoreWrites = false;
  8698. mCeModule->mWantsIRIgnoreWrites = false;
  8699. }
  8700. BeContext* CeMachine::GetBeContext()
  8701. {
  8702. if (mCeModule == NULL)
  8703. return NULL;
  8704. return mCeModule->mBfIRBuilder->mBeIRCodeGen->mBeContext;
  8705. }
  8706. BeModule* CeMachine::GetBeModule()
  8707. {
  8708. if (mCeModule == NULL)
  8709. return NULL;
  8710. return mCeModule->mBfIRBuilder->mBeIRCodeGen->mBeModule;
  8711. }
  8712. void CeMachine::CompileStarted()
  8713. {
  8714. mRevisionExecuteTime = 0;
  8715. mSpecialCheck = false;
  8716. mRevision++;
  8717. mMethodBindRevision++;
  8718. mDbgWantBreak = false;
  8719. mFailString.Clear();
  8720. if (mCeModule != NULL)
  8721. {
  8722. delete mCeModule;
  8723. mCeModule = NULL;
  8724. }
  8725. }
  8726. void CeMachine::CompileDone()
  8727. {
  8728. // So things like deleted local methods get rechecked
  8729. mRevision++;
  8730. mMethodBindRevision++;
  8731. mTypeInfoMap.Clear();
  8732. mMethodInstanceSet.Clear();
  8733. }
  8734. #define CE_SIZE_GET(T) *((T*)(ptr += sizeof(T)) - 1)
  8735. int CeMachine::GetInstSize(CeFunction* ceFunction, int instIdx)
  8736. {
  8737. auto ptr = &ceFunction->mCode[instIdx];
  8738. auto startPtr = ptr;
  8739. auto _HandleOperand = [&](CeOperandInfoKind kind)
  8740. {
  8741. switch (kind)
  8742. {
  8743. case CEOI_FrameRef:
  8744. case CEOI_FrameRef8:
  8745. case CEOI_FrameRef16:
  8746. case CEOI_FrameRef32:
  8747. case CEOI_FrameRef64:
  8748. case CEOI_FrameRefF32:
  8749. case CEOI_FrameRefF64:
  8750. ptr += 4;
  8751. break;
  8752. case CEOI_IMM8:
  8753. ptr += 1;
  8754. break;
  8755. case CEOI_IMM16:
  8756. ptr += 2;
  8757. break;
  8758. case CEOI_IMM32:
  8759. ptr += 4;
  8760. break;
  8761. case CEOI_IMM64:
  8762. ptr += 8;
  8763. break;
  8764. case CEOI_IMM_VAR:
  8765. {
  8766. int32 size = CE_SIZE_GET(int32);
  8767. ptr += size;
  8768. }
  8769. break;
  8770. case CEOI_JMPREL:
  8771. ptr += 4;
  8772. break;
  8773. default:
  8774. BF_ASSERT("Unhandled");
  8775. }
  8776. };
  8777. auto op = CE_SIZE_GET(CeOp);
  8778. if (op == CeOp_DbgBreak)
  8779. {
  8780. CeBreakpointBind* breakpointEntry = NULL;
  8781. if (ceFunction->mBreakpoints.TryGetValue(instIdx, &breakpointEntry))
  8782. op = breakpointEntry->mPrevOpCode;
  8783. }
  8784. CeOpInfo& opInfo = gOpInfo[op];
  8785. _HandleOperand(opInfo.mResultKind);
  8786. if ((opInfo.mFlags & CeOpInfoFlag_SizeX) != 0)
  8787. ptr += 4;
  8788. _HandleOperand(opInfo.mOperandA);
  8789. _HandleOperand(opInfo.mOperandB);
  8790. _HandleOperand(opInfo.mOperandC);
  8791. return (int)(ptr - startPtr);
  8792. }
  8793. void CeMachine::DerefMethodInfo(CeFunctionInfo* ceFunctionInfo)
  8794. {
  8795. ceFunctionInfo->mRefCount--;
  8796. if (ceFunctionInfo->mRefCount > 0)
  8797. return;
  8798. BF_ASSERT(ceFunctionInfo->mMethodInstance == NULL);
  8799. if (!ceFunctionInfo->mName.IsEmpty())
  8800. {
  8801. auto itr = mNamedFunctionMap.Find(ceFunctionInfo->mName);
  8802. if (itr->mValue == ceFunctionInfo)
  8803. mNamedFunctionMap.Remove(itr);
  8804. }
  8805. delete ceFunctionInfo;
  8806. }
  8807. void CeMachine::RemoveFunc(CeFunction* ceFunction)
  8808. {
  8809. mFunctionIdMap.Remove(ceFunction->mId);
  8810. ceFunction->mId = -1;
  8811. }
  8812. void CeMachine::RemoveMethod(BfMethodInstance* methodInstance)
  8813. {
  8814. BfLogSys(methodInstance->GetOwner()->mModule->mSystem, "CeMachine::RemoveMethod %p\n", methodInstance);
  8815. mMethodBindRevision++;
  8816. auto itr = mFunctions.Find(methodInstance);
  8817. auto ceFunctionInfo = itr->mValue;
  8818. BF_ASSERT(itr != mFunctions.end());
  8819. if (itr != mFunctions.end())
  8820. {
  8821. if (ceFunctionInfo->mMethodInstance == methodInstance)
  8822. {
  8823. auto ceFunction = ceFunctionInfo->mCeFunction;
  8824. for (auto& callEntry : ceFunction->mCallTable)
  8825. {
  8826. if (callEntry.mFunctionInfo != NULL)
  8827. DerefMethodInfo(callEntry.mFunctionInfo);
  8828. }
  8829. if (ceFunction->mId != -1)
  8830. {
  8831. RemoveFunc(ceFunction);
  8832. for (auto innerFunction : ceFunction->mInnerFunctions)
  8833. RemoveFunc(innerFunction);
  8834. }
  8835. delete ceFunction;
  8836. ceFunctionInfo->mCeFunction = NULL;
  8837. ceFunctionInfo->mMethodInstance = NULL;
  8838. if (methodInstance->mMethodDef->mIsLocalMethod)
  8839. {
  8840. // We can't rebuild these anyway
  8841. }
  8842. else if (ceFunctionInfo->mRefCount > 1)
  8843. {
  8844. // Generate a methodref
  8845. ceFunctionInfo->mMethodRef = methodInstance;
  8846. }
  8847. DerefMethodInfo(ceFunctionInfo);
  8848. }
  8849. mFunctions.Remove(itr);
  8850. }
  8851. methodInstance->mInCEMachine = false;
  8852. }
  8853. CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constVal, CeContext* ceContext, CeBuilder* ceBuilder)
  8854. {
  8855. auto ceModule = mCeModule;
  8856. auto beType = constVal->GetType();
  8857. if (auto globalVar = BeValueDynCast<BeGlobalVariable>(constVal))
  8858. {
  8859. if (globalVar->mName.StartsWith("__bfStrObj"))
  8860. {
  8861. int stringId = atoi(globalVar->mName.c_str() + 10);
  8862. addr_ce stringAddr;
  8863. if (data.mQueueFixups)
  8864. {
  8865. stringAddr = 0;
  8866. CeConstStructFixup fixup;
  8867. fixup.mKind = CeConstStructFixup::Kind_StringPtr;
  8868. fixup.mValue = stringId;
  8869. fixup.mOffset = (int)data.mData.mSize;
  8870. data.mFixups.Add(fixup);
  8871. }
  8872. else
  8873. {
  8874. stringAddr = ceContext->GetString(stringId);
  8875. }
  8876. auto ptr = data.mData.GrowUninitialized(ceModule->mSystem->mPtrSize);
  8877. int64 addr64 = stringAddr;
  8878. memcpy(ptr, &addr64, ceModule->mSystem->mPtrSize);
  8879. return CeErrorKind_None;
  8880. }
  8881. if (globalVar->mInitializer == NULL)
  8882. {
  8883. auto ptr = data.mData.GrowUninitialized(ceModule->mSystem->mPtrSize);
  8884. int64 addr64 = (addr_ce)0;
  8885. memcpy(ptr, &addr64, ceModule->mSystem->mPtrSize);
  8886. return CeErrorKind_None;
  8887. //TODO: Add this global variable in there and fixup
  8888. // CeStaticFieldInfo* staticFieldInfoPtr = NULL;
  8889. // if (mCeMachine->mStaticFieldMap.TryGetValue(globalVar->mName, &staticFieldInfoPtr))
  8890. // {
  8891. // CeStaticFieldInfo* staticFieldInfo = staticFieldInfoPtr;
  8892. //
  8893. // int* staticFieldTableIdxPtr = NULL;
  8894. // if (mStaticFieldMap.TryAdd(globalVar, NULL, &staticFieldTableIdxPtr))
  8895. // {
  8896. // CeStaticFieldEntry staticFieldEntry;
  8897. // staticFieldEntry.mTypeId = staticFieldInfo->mFieldInstance->mOwner->mTypeId;
  8898. // staticFieldEntry.mName = globalVar->mName;
  8899. // staticFieldEntry.mSize = globalVar->mType->mSize;
  8900. // *staticFieldTableIdxPtr = (int)mCeFunction->mStaticFieldTable.size();
  8901. // mCeFunction->mStaticFieldTable.Add(staticFieldEntry);
  8902. // }
  8903. //
  8904. // auto result = FrameAlloc(mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType));
  8905. //
  8906. // Emit(CeOp_GetStaticField);
  8907. // EmitFrameOffset(result);
  8908. // Emit((int32)*staticFieldTableIdxPtr);
  8909. //
  8910. // return result;
  8911. // }
  8912. // return CeErrorKind_GlobalVariable;
  8913. }
  8914. BF_ASSERT(!data.mQueueFixups);
  8915. CeConstStructData gvData;
  8916. auto result = WriteConstant(gvData, globalVar->mInitializer, ceContext, NULL);
  8917. if (result != CeErrorKind_None)
  8918. return result;
  8919. uint8* gvPtr = ceContext->CeMalloc(gvData.mData.mSize);
  8920. memcpy(gvPtr, gvData.mData.mVals, gvData.mData.mSize);
  8921. auto ptr = data.mData.GrowUninitialized(ceModule->mSystem->mPtrSize);
  8922. int64 addr64 = (addr_ce)(gvPtr - ceContext->mMemory.mVals);
  8923. memcpy(ptr, &addr64, mCeModule->mSystem->mPtrSize);
  8924. return CeErrorKind_None;
  8925. }
  8926. else if (auto beTypeOfConst = BeValueDynCast<BeTypeOfConstant>(constVal))
  8927. {
  8928. if (ceBuilder != NULL)
  8929. {
  8930. // Fake it to not break debugging
  8931. auto ptr = data.mData.GrowUninitialized(ceModule->mSystem->mPtrSize);
  8932. int64 addr64 = beTypeOfConst->mBfTypeId;
  8933. memcpy(ptr, &addr64, ceModule->mSystem->mPtrSize);
  8934. }
  8935. return CeErrorKind_None;
  8936. return CeErrorKind_Error;
  8937. }
  8938. else if (auto beFunc = BeValueDynCast<BeFunction>(constVal))
  8939. {
  8940. return CeErrorKind_FunctionPointer;
  8941. }
  8942. else if (auto constStruct = BeValueDynCast<BeStructConstant>(constVal))
  8943. {
  8944. int startOfs = data.mData.mSize;
  8945. if (constStruct->mType->mTypeCode == BeTypeCode_Struct)
  8946. {
  8947. BeStructType* structType = (BeStructType*)constStruct->mType;
  8948. BF_ASSERT(structType->mMembers.size() == constStruct->mMemberValues.size());
  8949. for (int memberIdx = 0; memberIdx < (int)constStruct->mMemberValues.size(); memberIdx++)
  8950. {
  8951. auto& member = structType->mMembers[memberIdx];
  8952. // Do any per-member alignment
  8953. int wantZeroes = member.mByteOffset - (data.mData.mSize - startOfs);
  8954. if (wantZeroes > 0)
  8955. data.mData.Insert(data.mData.size(), (uint8)0, wantZeroes);
  8956. auto result = WriteConstant(data, constStruct->mMemberValues[memberIdx], ceContext, ceBuilder);
  8957. if (result != CeErrorKind_None)
  8958. return result;
  8959. }
  8960. // Do end padding
  8961. data.mData.Insert(data.mData.size(), (uint8)0, structType->mSize - (data.mData.mSize - startOfs));
  8962. }
  8963. else if (constStruct->mType->mTypeCode == BeTypeCode_SizedArray)
  8964. {
  8965. for (auto& memberVal : constStruct->mMemberValues)
  8966. {
  8967. auto result = WriteConstant(data, memberVal, ceContext, ceBuilder);
  8968. if (result != CeErrorKind_None)
  8969. return result;
  8970. }
  8971. }
  8972. else
  8973. BF_FATAL("Invalid StructConst type");
  8974. }
  8975. else if (auto constStr = BeValueDynCast<BeStringConstant>(constVal))
  8976. {
  8977. data.mData.Insert(data.mData.mSize, (uint8*)constStr->mString.c_str(), (int)constStr->mString.length() + 1);
  8978. }
  8979. else if (auto constCast = BeValueDynCast<BeCastConstant>(constVal))
  8980. {
  8981. auto result = WriteConstant(data, constCast->mTarget, ceContext, ceBuilder);
  8982. if (result != CeErrorKind_None)
  8983. return result;
  8984. }
  8985. else if (auto constGep = BeValueDynCast<BeGEP2Constant>(constVal))
  8986. {
  8987. if (auto globalVar = BeValueDynCast<BeGlobalVariable>(constGep->mTarget))
  8988. {
  8989. BF_ASSERT(constGep->mIdx0 == 0);
  8990. int64 dataOfs = 0;
  8991. if (globalVar->mType->mTypeCode == BeTypeCode_Struct)
  8992. {
  8993. auto structType = (BeStructType*)globalVar->mType;
  8994. dataOfs = structType->mMembers[constGep->mIdx1].mByteOffset;
  8995. }
  8996. else if (globalVar->mType->mTypeCode == BeTypeCode_SizedArray)
  8997. {
  8998. auto arrayType = (BeSizedArrayType*)globalVar->mType;
  8999. dataOfs = arrayType->mElementType->GetStride() * constGep->mIdx1;
  9000. }
  9001. else
  9002. {
  9003. BF_FATAL("Invalid GEP");
  9004. }
  9005. addr_ce addr = -1;
  9006. if (globalVar->mName.StartsWith("__bfStrData"))
  9007. {
  9008. int stringId = atoi(globalVar->mName.c_str() + 11);
  9009. if (data.mQueueFixups)
  9010. {
  9011. addr = 0;
  9012. CeConstStructFixup fixup;
  9013. fixup.mKind = CeConstStructFixup::Kind_StringCharPtr;
  9014. fixup.mValue = stringId;
  9015. fixup.mOffset = (int)data.mData.mSize;
  9016. data.mFixups.Add(fixup);
  9017. }
  9018. else
  9019. {
  9020. addr_ce stringAddr = ceContext->GetString(stringId);
  9021. BfTypeInstance* stringTypeInst = (BfTypeInstance*)ceModule->ResolveTypeDef(ceModule->mCompiler->mStringTypeDef, BfPopulateType_Data);
  9022. addr = stringAddr + stringTypeInst->mInstSize;
  9023. }
  9024. }
  9025. if (addr != -1)
  9026. {
  9027. auto ptr = data.mData.GrowUninitialized(ceModule->mSystem->mPtrSize);
  9028. int64 addr64 = addr + dataOfs;
  9029. memcpy(ptr, &addr64, ceModule->mSystem->mPtrSize);
  9030. return CeErrorKind_None;
  9031. }
  9032. return CeErrorKind_GlobalVariable;
  9033. // auto sym = GetSymbol(globalVar);
  9034. //
  9035. // BeMCRelocation reloc;
  9036. // reloc.mKind = BeMCRelocationKind_ADDR64;
  9037. // reloc.mOffset = sect.mData.GetPos();
  9038. // reloc.mSymTableIdx = sym->mIdx;
  9039. // sect.mRelocs.push_back(reloc);
  9040. // sect.mData.Write((int64)dataOfs);
  9041. }
  9042. else
  9043. {
  9044. BF_FATAL("Invalid GEPConstant");
  9045. }
  9046. }
  9047. /*else if ((beType->IsPointer()) && (constVal->mTarget != NULL))
  9048. {
  9049. auto result = WriteConstant(arr, constVal->mTarget);
  9050. if (result != CeErrorKind_None)
  9051. return result;
  9052. }
  9053. else if (beType->IsComposite())
  9054. {
  9055. BF_ASSERT(constVal->mInt64 == 0);
  9056. int64 zero = 0;
  9057. int sizeLeft = beType->mSize;
  9058. while (sizeLeft > 0)
  9059. {
  9060. int writeSize = BF_MIN(sizeLeft, 8);
  9061. auto ptr = arr.GrowUninitialized(writeSize);
  9062. memset(ptr, 0, writeSize);
  9063. sizeLeft -= writeSize;
  9064. }
  9065. }*/
  9066. else if (BeValueDynCastExact<BeConstant>(constVal) != NULL)
  9067. {
  9068. if (constVal->mType->IsStruct())
  9069. {
  9070. if (constVal->mType->mSize > 0)
  9071. {
  9072. auto ptr = data.mData.GrowUninitialized(constVal->mType->mSize);
  9073. memset(ptr, 0, constVal->mType->mSize);
  9074. }
  9075. }
  9076. else
  9077. {
  9078. auto ptr = data.mData.GrowUninitialized(beType->mSize);
  9079. memcpy(ptr, &constVal->mInt64, beType->mSize);
  9080. }
  9081. }
  9082. else
  9083. return CeErrorKind_Error;
  9084. return CeErrorKind_None;
  9085. }
  9086. void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
  9087. {
  9088. ceFunction->mFunctionKind = CeFunctionKind_Normal;
  9089. if (ceFunction->mMethodInstance != NULL)
  9090. {
  9091. auto methodDef = ceFunction->mMethodInstance->mMethodDef;
  9092. if (methodDef->mIsExtern)
  9093. {
  9094. ceFunction->mFunctionKind = CeFunctionKind_Extern;
  9095. auto owner = ceFunction->mMethodInstance->GetOwner();
  9096. if (owner == mCeModule->mContext->mBfObjectType)
  9097. {
  9098. if (methodDef->mName == "Comptime_GetType")
  9099. {
  9100. ceFunction->mFunctionKind = CeFunctionKind_GetReflectType;
  9101. }
  9102. }
  9103. else if (owner->IsInstanceOf(mCeModule->mCompiler->mTypeTypeDef))
  9104. {
  9105. if (methodDef->mName == "Comptime_GetTypeDeclarationById")
  9106. {
  9107. ceFunction->mFunctionKind = CeFunctionKind_GetReflectTypeDeclById;
  9108. }
  9109. if (methodDef->mName == "Comptime_GetTypeDeclarationByName")
  9110. {
  9111. ceFunction->mFunctionKind = CeFunctionKind_GetReflectTypeDeclByName;
  9112. }
  9113. else if (methodDef->mName == "Comptime_GetNextTypeDeclaration")
  9114. {
  9115. ceFunction->mFunctionKind = CeFunctionKind_GetReflectNextTypeDecl;
  9116. }
  9117. else if (methodDef->mName == "Comptime_Type_GetBaseType")
  9118. {
  9119. ceFunction->mFunctionKind = CeFunctionKind_GetBaseType;
  9120. }
  9121. else if (methodDef->mName == "Comptime_Type_HasDeclaredMember")
  9122. {
  9123. ceFunction->mFunctionKind = CeFunctionKind_HasDeclaredMember;
  9124. }
  9125. else if (methodDef->mName == "Comptime_GetTypeById")
  9126. {
  9127. ceFunction->mFunctionKind = CeFunctionKind_GetReflectTypeById;
  9128. }
  9129. else if (methodDef->mName == "Comptime_GetWrappedType")
  9130. {
  9131. ceFunction->mFunctionKind = CeFunctionKind_GetWrappedType;
  9132. }
  9133. else if (methodDef->mName == "Comptime_GetTypeByName")
  9134. {
  9135. ceFunction->mFunctionKind = CeFunctionKind_GetReflectTypeByName;
  9136. }
  9137. else if (methodDef->mName == "Comptime_GetSpecializedType")
  9138. {
  9139. ceFunction->mFunctionKind = CeFunctionKind_GetReflectSpecializedType;
  9140. }
  9141. else if (methodDef->mName == "Comptime_Type_ToString")
  9142. {
  9143. ceFunction->mFunctionKind = CeFunctionKind_Type_ToString;
  9144. }
  9145. else if (methodDef->mName == "Comptime_TypeName_ToString")
  9146. {
  9147. ceFunction->mFunctionKind = CeFunctionKind_TypeName_ToString;
  9148. }
  9149. else if (methodDef->mName == "Comptime_Namespace_ToString")
  9150. {
  9151. ceFunction->mFunctionKind = CeFunctionKind_Namespace_ToString;
  9152. }
  9153. else if (methodDef->mName == "Comptime_Type_GetCustomAttribute")
  9154. {
  9155. ceFunction->mFunctionKind = CeFunctionKind_Type_GetCustomAttribute;
  9156. }
  9157. else if (methodDef->mName == "Comptime_Field_GetCustomAttribute")
  9158. {
  9159. ceFunction->mFunctionKind = CeFunctionKind_Field_GetCustomAttribute;
  9160. }
  9161. else if (methodDef->mName == "Comptime_Method_GetCustomAttribute")
  9162. {
  9163. ceFunction->mFunctionKind = CeFunctionKind_Method_GetCustomAttribute;
  9164. }
  9165. else if (methodDef->mName == "Comptime_Type_GetCustomAttributeType")
  9166. {
  9167. ceFunction->mFunctionKind = CeFunctionKind_Type_GetCustomAttributeType;
  9168. }
  9169. else if (methodDef->mName == "Comptime_Field_GetCustomAttributeType")
  9170. {
  9171. ceFunction->mFunctionKind = CeFunctionKind_Field_GetCustomAttributeType;
  9172. }
  9173. else if (methodDef->mName == "Comptime_Method_GetCustomAttributeType")
  9174. {
  9175. ceFunction->mFunctionKind = CeFunctionKind_Method_GetCustomAttributeType;
  9176. }
  9177. else if (methodDef->mName == "Comptime_GetMethod")
  9178. {
  9179. ceFunction->mFunctionKind = CeFunctionKind_GetMethod;
  9180. }
  9181. else if (methodDef->mName == "Comptime_GetMethodCount")
  9182. {
  9183. ceFunction->mFunctionKind = CeFunctionKind_GetMethodCount;
  9184. }
  9185. else if (methodDef->mName == "Comptime_Method_ToString")
  9186. {
  9187. ceFunction->mFunctionKind = CeFunctionKind_Method_ToString;
  9188. }
  9189. else if (methodDef->mName == "Comptime_Method_GetName")
  9190. {
  9191. ceFunction->mFunctionKind = CeFunctionKind_Method_GetName;
  9192. }
  9193. else if (methodDef->mName == "Comptime_Method_GetInfo")
  9194. {
  9195. ceFunction->mFunctionKind = CeFunctionKind_Method_GetInfo;
  9196. }
  9197. else if (methodDef->mName == "Comptime_Method_GetParamInfo")
  9198. {
  9199. ceFunction->mFunctionKind = CeFunctionKind_Method_GetParamInfo;
  9200. }
  9201. else if (methodDef->mName == "Comptime_Method_GetGenericArg")
  9202. {
  9203. ceFunction->mFunctionKind = CeFunctionKind_Method_GetGenericArg;
  9204. }
  9205. else if (methodDef->mName == "Comptime_Field_GetStatic")
  9206. {
  9207. ceFunction->mFunctionKind = CeFunctionKind_Field_GetStatic;
  9208. }
  9209. }
  9210. else if (owner->IsInstanceOf(mCeModule->mCompiler->mCompilerTypeDef))
  9211. {
  9212. if (methodDef->mName == "Comptime_SetReturnType")
  9213. {
  9214. ceFunction->mFunctionKind = CeFunctionKind_SetReturnType;
  9215. }
  9216. else if (methodDef->mName == "Comptime_Align")
  9217. {
  9218. ceFunction->mFunctionKind = CeFunctionKind_Align;
  9219. }
  9220. else if (methodDef->mName == "Comptime_EmitTypeBody")
  9221. {
  9222. ceFunction->mFunctionKind = CeFunctionKind_EmitTypeBody;
  9223. }
  9224. else if (methodDef->mName == "Comptime_EmitAddInterface")
  9225. {
  9226. ceFunction->mFunctionKind = CeFunctionKind_EmitAddInterface;
  9227. }
  9228. else if (methodDef->mName == "Comptime_EmitMethodEntry")
  9229. {
  9230. ceFunction->mFunctionKind = CeFunctionKind_EmitMethodEntry;
  9231. }
  9232. else if (methodDef->mName == "Comptime_EmitMethodExit")
  9233. {
  9234. ceFunction->mFunctionKind = CeFunctionKind_EmitMethodExit;
  9235. }
  9236. else if (methodDef->mName == "Comptime_EmitMixin")
  9237. {
  9238. ceFunction->mFunctionKind = CeFunctionKind_EmitMixin;
  9239. }
  9240. else if (methodDef->mName == "Comptime_GetStringById")
  9241. {
  9242. ceFunction->mFunctionKind = CeFunctionKind_GetStringById;
  9243. }
  9244. }
  9245. else if (owner->IsInstanceOf(mCeModule->mCompiler->mDiagnosticsDebugTypeDef))
  9246. {
  9247. if (methodDef->mName == "Write")
  9248. {
  9249. if (ceFunction->mMethodInstance->GetParamCount() == 1)
  9250. ceFunction->mFunctionKind = CeFunctionKind_DebugWrite_Int;
  9251. else
  9252. ceFunction->mFunctionKind = CeFunctionKind_DebugWrite;
  9253. }
  9254. }
  9255. else if (owner->IsInstanceOf(mCeModule->mCompiler->mThreadTypeDef))
  9256. {
  9257. if (methodDef->mName == "SleepInternal")
  9258. ceFunction->mFunctionKind = CeFunctionKind_Sleep;
  9259. }
  9260. else if (owner->IsInstanceOf(mCeModule->mCompiler->mInternalTypeDef))
  9261. {
  9262. if (methodDef->mName == "ThrowIndexOutOfRange")
  9263. ceFunction->mFunctionKind = CeFunctionKind_OOB;
  9264. else if (methodDef->mName == "ThrowObjectNotInitialized")
  9265. ceFunction->mFunctionKind = CeFunctionKind_ObjectNotInitialized;
  9266. else if (methodDef->mName == "FatalError")
  9267. ceFunction->mFunctionKind = CeFunctionKind_FatalError;
  9268. else if (methodDef->mName == "Dbg_RawAlloc")
  9269. ceFunction->mFunctionKind = CeFunctionKind_Malloc;
  9270. else if (methodDef->mName == "Dbg_RawFree")
  9271. ceFunction->mFunctionKind = CeFunctionKind_Free;
  9272. else if (methodDef->mName == "ObjectDynCheckFailed")
  9273. ceFunction->mFunctionKind = CeFunctionKind_DynCheckFailed;
  9274. }
  9275. else if (owner->IsInstanceOf(mCeModule->mCompiler->mPlatformTypeDef))
  9276. {
  9277. if (methodDef->mName == "BfpDirectory_Create")
  9278. ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_Create;
  9279. else if (methodDef->mName == "BfpDirectory_Rename")
  9280. ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_Rename;
  9281. else if (methodDef->mName == "BfpDirectory_Delete")
  9282. ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_Delete;
  9283. else if (methodDef->mName == "BfpDirectory_GetCurrent")
  9284. ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_GetCurrent;
  9285. else if (methodDef->mName == "BfpDirectory_SetCurrent")
  9286. ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_SetCurrent;
  9287. else if (methodDef->mName == "BfpDirectory_Exists")
  9288. ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_Exists;
  9289. else if (methodDef->mName == "BfpDirectory_GetSysDirectory")
  9290. ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_GetSysDirectory;
  9291. else if (methodDef->mName == "BfpFile_Close")
  9292. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Close;
  9293. else if (methodDef->mName == "BfpFile_Create")
  9294. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Create;
  9295. else if (methodDef->mName == "BfpFile_Flush")
  9296. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Flush;
  9297. else if (methodDef->mName == "BfpFile_GetFileSize")
  9298. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_GetFileSize;
  9299. else if (methodDef->mName == "BfpFile_Read")
  9300. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Read;
  9301. else if (methodDef->mName == "BfpFile_Release")
  9302. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Release;
  9303. else if (methodDef->mName == "BfpFile_Seek")
  9304. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Seek;
  9305. else if (methodDef->mName == "BfpFile_Truncate")
  9306. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Truncate;
  9307. else if (methodDef->mName == "BfpFile_Write")
  9308. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Write;
  9309. else if (methodDef->mName == "BfpFile_GetTime_LastWrite")
  9310. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_GetTime_LastWrite;
  9311. else if (methodDef->mName == "BfpFile_GetAttributes")
  9312. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_GetAttributes;
  9313. else if (methodDef->mName == "BfpFile_SetAttributes")
  9314. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_SetAttributes;
  9315. else if (methodDef->mName == "BfpFile_Copy")
  9316. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Copy;
  9317. else if (methodDef->mName == "BfpFile_Rename")
  9318. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Rename;
  9319. else if (methodDef->mName == "BfpFile_Delete")
  9320. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Delete;
  9321. else if (methodDef->mName == "BfpFile_Exists")
  9322. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Exists;
  9323. else if (methodDef->mName == "BfpFile_GetTempPath")
  9324. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_GetTempPath;
  9325. else if (methodDef->mName == "BfpFile_GetTempFileName")
  9326. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_GetTempFileName;
  9327. else if (methodDef->mName == "BfpFile_GetFullPath")
  9328. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_GetFullPath;
  9329. else if (methodDef->mName == "BfpFile_GetActualPath")
  9330. ceFunction->mFunctionKind = CeFunctionKind_BfpFile_GetActualPath;
  9331. else if (methodDef->mName == "BfpSpawn_Create")
  9332. ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_Create;
  9333. else if (methodDef->mName == "BfpSpawn_GetStdHandles")
  9334. ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_GetStdHandles;
  9335. else if (methodDef->mName == "BfpSpawn_Kill")
  9336. ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_Kill;
  9337. else if (methodDef->mName == "BfpSpawn_Release")
  9338. ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_Release;
  9339. else if (methodDef->mName == "BfpSpawn_WaitFor")
  9340. ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_WaitFor;
  9341. else if (methodDef->mName == "BfpFindFileData_FindFirstFile")
  9342. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_FindFirstFile;
  9343. else if (methodDef->mName == "BfpFindFileData_FindNextFile")
  9344. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_FindNextFile;
  9345. else if (methodDef->mName == "BfpFindFileData_GetFileName")
  9346. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_GetFileName;
  9347. else if (methodDef->mName == "BfpFindFileData_GetTime_LastWrite")
  9348. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_GetTime_LastWrite;
  9349. else if (methodDef->mName == "BfpFindFileData_GetTime_Created")
  9350. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_GetTime_Created;
  9351. else if (methodDef->mName == "BfpFindFileData_GetTime_Access")
  9352. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_GetTime_Access;
  9353. else if (methodDef->mName == "BfpFindFileData_GetFileAttributes")
  9354. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_GetFileAttributes;
  9355. else if (methodDef->mName == "BfpFindFileData_GetFileSize")
  9356. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_GetFileSize;
  9357. else if (methodDef->mName == "BfpFindFileData_Release")
  9358. ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_Release;
  9359. else if (methodDef->mName == "BfpSystem_GetTimeStamp")
  9360. ceFunction->mFunctionKind = CeFunctionKind_BfpSystem_GetTimeStamp;
  9361. }
  9362. else if (owner->IsInstanceOf(mCeModule->mCompiler->mChar32TypeDef))
  9363. {
  9364. if (methodDef->mName == "get__ToLower")
  9365. ceFunction->mFunctionKind = CeFunctionKind_Char32_ToLower;
  9366. else if (methodDef->mName == "get__ToUpper")
  9367. ceFunction->mFunctionKind = CeFunctionKind_Char32_ToUpper;
  9368. else if (methodDef->mName == "get__IsLower")
  9369. ceFunction->mFunctionKind = CeFunctionKind_Char32_IsLower;
  9370. else if (methodDef->mName == "get__IsUpper")
  9371. ceFunction->mFunctionKind = CeFunctionKind_Char32_IsUpper;
  9372. else if (methodDef->mName == "get__IsWhiteSpace_EX")
  9373. ceFunction->mFunctionKind = CeFunctionKind_Char32_IsWhiteSpace_EX;
  9374. else if (methodDef->mName == "get__IsLetter")
  9375. ceFunction->mFunctionKind = CeFunctionKind_Char32_IsLetter;
  9376. else if (methodDef->mName == "get__IsLetterOrDigit")
  9377. ceFunction->mFunctionKind = CeFunctionKind_Char32_IsLetterOrDigit;
  9378. else if (methodDef->mName == "get__IsNumer")
  9379. ceFunction->mFunctionKind = CeFunctionKind_Char32_IsNumber;
  9380. }
  9381. else if (owner->IsInstanceOf(mCeModule->mCompiler->mDoubleTypeDef))
  9382. {
  9383. if (methodDef->mName == "strtod")
  9384. ceFunction->mFunctionKind = CeFunctionKind_Double_Strtod;
  9385. else if (methodDef->mName == "ftoa")
  9386. ceFunction->mFunctionKind = CeFunctionKind_Double_Ftoa;
  9387. if (methodDef->mName == "ToString")
  9388. ceFunction->mFunctionKind = CeFunctionKind_Double_ToString;
  9389. }
  9390. else if (owner->IsInstanceOf(mCeModule->mCompiler->mFloatTypeDef))
  9391. {
  9392. if (methodDef->mName == "ftoa")
  9393. ceFunction->mFunctionKind = CeFunctionKind_Double_Ftoa;
  9394. if (methodDef->mName == "ToString")
  9395. ceFunction->mFunctionKind = CeFunctionKind_Float_ToString;
  9396. }
  9397. else if (owner->IsInstanceOf(mCeModule->mCompiler->mMathTypeDef))
  9398. {
  9399. if (methodDef->mName == "Abs")
  9400. ceFunction->mFunctionKind = CeFunctionKind_Math_Abs;
  9401. else if (methodDef->mName == "Acos")
  9402. ceFunction->mFunctionKind = CeFunctionKind_Math_Acos;
  9403. else if (methodDef->mName == "Asin")
  9404. ceFunction->mFunctionKind = CeFunctionKind_Math_Asin;
  9405. else if (methodDef->mName == "Atan")
  9406. ceFunction->mFunctionKind = CeFunctionKind_Math_Atan;
  9407. else if (methodDef->mName == "Atan2")
  9408. ceFunction->mFunctionKind = CeFunctionKind_Math_Atan2;
  9409. else if (methodDef->mName == "Ceiling")
  9410. ceFunction->mFunctionKind = CeFunctionKind_Math_Ceiling;
  9411. else if (methodDef->mName == "Cos")
  9412. ceFunction->mFunctionKind = CeFunctionKind_Math_Cos;
  9413. else if (methodDef->mName == "Cosh")
  9414. ceFunction->mFunctionKind = CeFunctionKind_Math_Cosh;
  9415. else if (methodDef->mName == "Exp")
  9416. ceFunction->mFunctionKind = CeFunctionKind_Math_Exp;
  9417. else if (methodDef->mName == "Floor")
  9418. ceFunction->mFunctionKind = CeFunctionKind_Math_Floor;
  9419. else if (methodDef->mName == "Log")
  9420. ceFunction->mFunctionKind = CeFunctionKind_Math_Log;
  9421. else if (methodDef->mName == "Log10")
  9422. ceFunction->mFunctionKind = CeFunctionKind_Math_Log10;
  9423. else if (methodDef->mName == "Mod")
  9424. ceFunction->mFunctionKind = CeFunctionKind_Math_Mod;
  9425. else if (methodDef->mName == "Pow")
  9426. ceFunction->mFunctionKind = CeFunctionKind_Math_Pow;
  9427. else if (methodDef->mName == "Round")
  9428. ceFunction->mFunctionKind = CeFunctionKind_Math_Round;
  9429. else if (methodDef->mName == "Sin")
  9430. ceFunction->mFunctionKind = CeFunctionKind_Math_Sin;
  9431. else if (methodDef->mName == "Sinh")
  9432. ceFunction->mFunctionKind = CeFunctionKind_Math_Sinh;
  9433. else if (methodDef->mName == "Sqrt")
  9434. ceFunction->mFunctionKind = CeFunctionKind_Math_Sqrt;
  9435. else if (methodDef->mName == "Tan")
  9436. ceFunction->mFunctionKind = CeFunctionKind_Math_Tan;
  9437. else if (methodDef->mName == "Tanh")
  9438. ceFunction->mFunctionKind = CeFunctionKind_Math_Tanh;
  9439. }
  9440. ceFunction->mInitializeState = CeFunction::InitializeState_Initialized;
  9441. return;
  9442. }
  9443. }
  9444. }
  9445. void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder)
  9446. {
  9447. AutoTimer autoTimer(mRevisionExecuteTime);
  9448. SetAndRestoreValue<CeFunction*> prevCEFunction(mPreparingFunction, ceFunction);
  9449. BF_ASSERT(ceFunction->mInitializeState <= CeFunction::InitializeState_Initialized);
  9450. if (ceFunction->mFunctionKind == CeFunctionKind_NotSet)
  9451. {
  9452. CheckFunctionKind(ceFunction);
  9453. if (ceFunction->mInitializeState == CeFunction::InitializeState_Initialized)
  9454. return;
  9455. }
  9456. BF_ASSERT(ceFunction->mInitializeState <= CeFunction::InitializeState_Initialized);
  9457. if (ceFunction->mInitializeState == CeFunction::InitializeState_Initializing_ReEntry)
  9458. {
  9459. //Fail("Function generation re-entry");
  9460. return;
  9461. }
  9462. if (ceFunction->mInitializeState == CeFunction::InitializeState_Initializing)
  9463. ceFunction->mInitializeState = CeFunction::InitializeState_Initializing_ReEntry;
  9464. else
  9465. ceFunction->mInitializeState = CeFunction::InitializeState_Initializing;
  9466. CeBuilder ceBuilder;
  9467. SetAndRestoreValue<CeBuilder*> prevBuilder(mCurBuilder, &ceBuilder);
  9468. ceBuilder.mParentBuilder = parentBuilder;
  9469. ceBuilder.mPtrSize = mCeModule->mCompiler->mSystem->mPtrSize;
  9470. ceBuilder.mCeMachine = this;
  9471. ceBuilder.mCeFunction = ceFunction;
  9472. SetAndRestoreValue<int> prevRecursiveDepth(mCurRecursiveDepth, mCurRecursiveDepth + 1);
  9473. ceBuilder.mRecursiveDepth = mCurRecursiveDepth;
  9474. ceBuilder.Build();
  9475. ceFunction->mInitializeState = CeFunction::InitializeState_Initialized;
  9476. /*if (!ceFunction->mCode.IsEmpty())
  9477. {
  9478. CeDumpContext dumpCtx;
  9479. dumpCtx.mCeFunction = ceFunction;
  9480. dumpCtx.mStart = &ceFunction->mCode[0];
  9481. dumpCtx.mPtr = dumpCtx.mStart;
  9482. dumpCtx.mEnd = dumpCtx.mPtr + ceFunction->mCode.mSize;
  9483. dumpCtx.Dump();
  9484. OutputDebugStrF("Code for %s:\n%s\n", ceBuilder.mBeFunction->mName.c_str(), dumpCtx.mStr.c_str());
  9485. }*/
  9486. }
  9487. void CeMachine::MapFunctionId(CeFunction* ceFunction)
  9488. {
  9489. if ((mCeModule->mSystem->mPtrSize == 8) && (mDebugger == NULL))
  9490. return;
  9491. ceFunction->mId = ++mCurFunctionId;
  9492. mFunctionIdMap[ceFunction->mId] = ceFunction;
  9493. }
  9494. CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue func, bool& added)
  9495. {
  9496. if (func)
  9497. {
  9498. if ((func.IsConst()) || (func.IsFake()))
  9499. return NULL;
  9500. auto funcVal = mCeModule->mBfIRBuilder->mBeIRCodeGen->TryGetBeValue(func.mId);
  9501. if (funcVal == NULL)
  9502. return NULL;
  9503. }
  9504. CeFunctionInfo** functionInfoPtr = NULL;
  9505. CeFunctionInfo* ceFunctionInfo = NULL;
  9506. CeFunction* ceFunction = NULL;
  9507. if (!mFunctions.TryAdd(methodInstance, NULL, &functionInfoPtr))
  9508. {
  9509. ceFunctionInfo = *functionInfoPtr;
  9510. BF_ASSERT(ceFunctionInfo->mCeFunction != NULL);
  9511. return ceFunctionInfo->mCeFunction;
  9512. }
  9513. BF_ASSERT(!methodInstance->mInCEMachine);
  9514. methodInstance->mInCEMachine = true;
  9515. BfLogSys(mCeModule->mSystem, "CeMachine::GetFunction %p\n", methodInstance);
  9516. if (!func)
  9517. {
  9518. ceFunctionInfo = new CeFunctionInfo();
  9519. }
  9520. else
  9521. {
  9522. auto funcVal = mCeModule->mBfIRBuilder->mBeIRCodeGen->GetBeValue(func.mId);
  9523. if (auto function = BeValueDynCast<BeFunction>(funcVal))
  9524. {
  9525. String funcName = function->mName;
  9526. if (funcName.EndsWith("__INLINE"))
  9527. funcName.RemoveFromEnd(8);
  9528. CeFunctionInfo** namedFunctionInfoPtr = NULL;
  9529. if (mNamedFunctionMap.TryAdd(funcName, NULL, &namedFunctionInfoPtr))
  9530. {
  9531. ceFunctionInfo = new CeFunctionInfo();
  9532. ceFunctionInfo->mName = funcName;
  9533. *namedFunctionInfoPtr = ceFunctionInfo;
  9534. }
  9535. else
  9536. {
  9537. ceFunctionInfo = *namedFunctionInfoPtr;
  9538. if ((ceFunctionInfo->mMethodInstance != NULL) && (ceFunctionInfo->mMethodInstance != methodInstance))
  9539. {
  9540. // This ceFunctionInfo is already taken - probably from a name mangling conflict
  9541. ceFunctionInfo = new CeFunctionInfo();
  9542. }
  9543. }
  9544. }
  9545. else
  9546. {
  9547. ceFunctionInfo = new CeFunctionInfo();
  9548. }
  9549. }
  9550. ceFunctionInfo->mRefCount++;
  9551. *functionInfoPtr = ceFunctionInfo;
  9552. if (ceFunctionInfo->mMethodInstance == NULL)
  9553. {
  9554. added = true;
  9555. auto module = methodInstance->GetOwner()->mModule;
  9556. BF_ASSERT(ceFunctionInfo->mCeFunction == NULL);
  9557. ceFunction = new CeFunction();
  9558. ceFunction->mCeMachine = this;
  9559. ceFunction->mIsVarReturn = methodInstance->mReturnType->IsVar();
  9560. ceFunction->mCeFunctionInfo = ceFunctionInfo;
  9561. ceFunction->mMethodInstance = methodInstance;
  9562. if (mDebugger != NULL)
  9563. ceFunction->mDbgInfo = new CeDbgFunctionInfo();
  9564. ceFunctionInfo->mMethodInstance = methodInstance;
  9565. ceFunctionInfo->mCeFunction = ceFunction;
  9566. MapFunctionId(ceFunction);
  9567. }
  9568. return ceFunction;
  9569. }
  9570. CeFunction* CeMachine::GetPreparedFunction(BfMethodInstance* methodInstance)
  9571. {
  9572. bool added = false;
  9573. auto ceFunction = GetFunction(methodInstance, BfIRValue(), added);
  9574. if (ceFunction == NULL)
  9575. return NULL;
  9576. if (ceFunction->mInitializeState < CeFunction::InitializeState_Initialized)
  9577. PrepareFunction(ceFunction, NULL);
  9578. return ceFunction;
  9579. }
  9580. CeTypeInfo* CeMachine::GetTypeInfo(BfType* type)
  9581. {
  9582. if (type == NULL)
  9583. return NULL;
  9584. auto typeInstance = type->ToTypeInstance();
  9585. if (typeInstance == NULL)
  9586. return NULL;
  9587. CeTypeInfo* ceTypeInfo = NULL;
  9588. if (!mTypeInfoMap.TryAdd(type, NULL, &ceTypeInfo))
  9589. {
  9590. if (ceTypeInfo->mRevision == typeInstance->mRevision)
  9591. return ceTypeInfo;
  9592. ceTypeInfo->mMethodInstances.Clear();
  9593. }
  9594. mCeModule->PopulateType(typeInstance, BfPopulateType_DataAndMethods);
  9595. ceTypeInfo->mRevision = typeInstance->mRevision;
  9596. for (auto& methodGroup : typeInstance->mMethodInstanceGroups)
  9597. {
  9598. if (methodGroup.mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference)
  9599. {
  9600. auto methodDef = typeInstance->mTypeDef->mMethods[methodGroup.mMethodIdx];
  9601. auto flags = ((methodDef->mGenericParams.size() != 0) || (typeInstance->IsUnspecializedType())) ? BfGetMethodInstanceFlag_UnspecializedPass : BfGetMethodInstanceFlag_None;
  9602. flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_MethodInstanceOnly);
  9603. mCeModule->GetMethodInstance(typeInstance, methodDef, BfTypeVector(), flags);
  9604. }
  9605. if (methodGroup.mDefault != NULL)
  9606. {
  9607. mMethodInstanceSet.Add(methodGroup.mDefault);
  9608. ceTypeInfo->mMethodInstances.Add(methodGroup.mDefault);
  9609. }
  9610. if (methodGroup.mMethodSpecializationMap != NULL)
  9611. {
  9612. for (auto& kv : *methodGroup.mMethodSpecializationMap)
  9613. {
  9614. mMethodInstanceSet.Add(kv.mValue);
  9615. ceTypeInfo->mMethodInstances.Add(kv.mValue);
  9616. }
  9617. }
  9618. }
  9619. return ceTypeInfo;
  9620. }
  9621. BfMethodInstance* CeMachine::GetMethodInstance(int64 methodHandle)
  9622. {
  9623. BfMethodInstance* methodInstance = (BfMethodInstance*)(intptr)methodHandle;
  9624. if (!mMethodInstanceSet.Contains(methodInstance))
  9625. return NULL;
  9626. return methodInstance;
  9627. }
  9628. BfFieldInstance* CeMachine::GetFieldInstance(int64 fieldHandle)
  9629. {
  9630. BfFieldInstance* fieldInstance = (BfFieldInstance*)(intptr)fieldHandle;
  9631. if (!mFieldInstanceSet.Contains(fieldInstance))
  9632. return NULL;
  9633. return fieldInstance;
  9634. }
  9635. CeFunction* CeMachine::QueueMethod(BfMethodInstance* methodInstance, BfIRValue func)
  9636. {
  9637. if (mPreparingFunction != NULL)
  9638. {
  9639. auto curOwner = mPreparingFunction->mMethodInstance->GetOwner();
  9640. curOwner->mModule->AddDependency(methodInstance->GetOwner(), curOwner, BfDependencyMap::DependencyFlag_ConstEval);
  9641. }
  9642. bool added = false;
  9643. return GetFunction(methodInstance, func, added);
  9644. }
  9645. void CeMachine::QueueMethod(BfModuleMethodInstance moduleMethodInstance)
  9646. {
  9647. QueueMethod(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc);
  9648. }
  9649. void CeMachine::QueueStaticField(BfFieldInstance* fieldInstance, const StringImpl& mangledFieldName)
  9650. {
  9651. if (mCurBuilder != NULL)
  9652. mCurBuilder->mStaticFieldInstanceMap[mangledFieldName] = fieldInstance;
  9653. }
  9654. void CeMachine::ClearTypeData(BfTypeInstance* typeInstance)
  9655. {
  9656. if (mTypeInfoMap.Remove(typeInstance))
  9657. {
  9658. for (auto& methodGroup : typeInstance->mMethodInstanceGroups)
  9659. {
  9660. if (methodGroup.mDefault != NULL)
  9661. mMethodInstanceSet.Remove(methodGroup.mDefault);
  9662. if (methodGroup.mMethodSpecializationMap != NULL)
  9663. {
  9664. for (auto& kv : *methodGroup.mMethodSpecializationMap)
  9665. mMethodInstanceSet.Remove(kv.mValue);
  9666. }
  9667. }
  9668. }
  9669. }
  9670. void CeMachine::SetAppendAllocInfo(BfModule* module, BfIRValue allocValue, BfIRValue appendSizeValue)
  9671. {
  9672. delete mAppendAllocInfo;
  9673. mAppendAllocInfo = new CeAppendAllocInfo();
  9674. mAppendAllocInfo->mModule = module;
  9675. mAppendAllocInfo->mAllocValue = allocValue;
  9676. mAppendAllocInfo->mAppendSizeValue = appendSizeValue;
  9677. }
  9678. void CeMachine::ClearAppendAllocInfo()
  9679. {
  9680. delete mAppendAllocInfo;
  9681. mAppendAllocInfo = NULL;
  9682. }
  9683. CeContext* CeMachine::AllocContext()
  9684. {
  9685. CeContext* ceContext = NULL;
  9686. if (!mContextList.IsEmpty())
  9687. {
  9688. ceContext = mContextList.back();
  9689. mContextList.pop_back();
  9690. }
  9691. else
  9692. {
  9693. ceContext = new CeContext();
  9694. ceContext->mCeMachine = this;
  9695. ceContext->mMemory.Reserve(BF_CE_INITIAL_MEMORY);
  9696. memset(ceContext->mMemory.mVals, 0, BF_CE_INITIAL_MEMORY);
  9697. }
  9698. ceContext->mCurEmitContext = mCurEmitContext;
  9699. mCurEmitContext = NULL;
  9700. mExecuteId++;
  9701. ceContext->mStackSize = BF_CE_DEFAULT_STACK_SIZE;
  9702. ceContext->mMemory.ResizeRaw(ceContext->mStackSize);
  9703. ceContext->mExecuteId = mExecuteId;
  9704. ceContext->mCurHandleId = 0;
  9705. return ceContext;
  9706. }
  9707. void CeMachine::ReleaseContext(CeContext* ceContext)
  9708. {
  9709. ceContext->mStringMap.Clear();
  9710. delete ceContext->mTypeDeclState;
  9711. ceContext->mTypeDeclState = NULL;
  9712. ceContext->mReflectMap.Clear();
  9713. ceContext->mConstDataMap.Clear();
  9714. ceContext->mMemory.Clear();
  9715. if (ceContext->mMemory.mAllocSize > BF_CE_MAX_CARRYOVER_MEMORY)
  9716. ceContext->mMemory.Dispose();
  9717. ceContext->mStaticCtorExecSet.Clear();
  9718. ceContext->mStaticFieldMap.Clear();
  9719. ceContext->mStaticFieldIdMap.Clear();
  9720. ceContext->mHeap->Clear(BF_CE_MAX_CARRYOVER_HEAP);
  9721. ceContext->mReflectTypeIdOffset = -1;
  9722. mCurEmitContext = ceContext->mCurEmitContext;
  9723. ceContext->mCurEmitContext = NULL;
  9724. mContextList.Add(ceContext);
  9725. for (auto kv : ceContext->mInternalDataMap)
  9726. kv.mValue->Release();
  9727. ceContext->mInternalDataMap.Clear();
  9728. ceContext->mWorkingDir.Clear();
  9729. }
  9730. BfTypedValue CeMachine::Call(CeCallSource callSource, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags, BfType* expectingType)
  9731. {
  9732. auto ceContext = AllocContext();
  9733. SetAndRestoreValue<int> prevRecursiveDepth(mCurRecursiveDepth, mCurRecursiveDepth + 1);
  9734. ceContext->mRecursiveDepth = mCurRecursiveDepth;
  9735. auto result = ceContext->Call(callSource, module, methodInstance, args, flags, expectingType);
  9736. ReleaseContext(ceContext);
  9737. return result;
  9738. }
  9739. BfError* CeMachine::FailCurrent(BfModule* srcModule, const StringImpl& error, BfAstNode* refNode)
  9740. {
  9741. BfError* bfError = NULL;
  9742. if ((mCurBuilder != NULL) &&
  9743. ((mCurContext != NULL) || (mCurBuilder->mRecursiveDepth > mCurContext->mRecursiveDepth)))
  9744. {
  9745. String useError = error;
  9746. useError += StrFormat(" during const-eval generation of '%s'", srcModule->MethodToString(mCurBuilder->mCeFunction->mMethodInstance).c_str());
  9747. bfError = srcModule->Fail(error, refNode);
  9748. if (bfError != NULL)
  9749. {
  9750. auto filePos = mCurBuilder->mCeMachine->mCeModule->mCurFilePosition;
  9751. auto parser = filePos.mFileInstance->mParser;
  9752. if (parser != NULL)
  9753. {
  9754. srcModule->mCompiler->mPassInstance->MoreInfoAt(
  9755. StrFormat("See comptime method '%s' processing location", srcModule->MethodToString(mCurBuilder->mCeFunction->mMethodInstance).c_str()),
  9756. parser, filePos.mCurSrcPos, 1, BfFailFlag_None);
  9757. }
  9758. }
  9759. }
  9760. else
  9761. {
  9762. bfError = srcModule->Fail(error, refNode);
  9763. }
  9764. return bfError;
  9765. }
  9766. void CeMachine::FailCurrentMoreInfo(const StringImpl& error, BfAstNode* refNode)
  9767. {
  9768. }