1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710 |
- #include "TransformContext.h"
- #include "metadata/GenericMetadata.h"
- #include "vm/Class.h"
- #include "vm/Exception.h"
- #include "vm/String.h"
- #include "vm/Field.h"
- #include "../metadata/MethodBodyCache.h"
- #include "../interpreter/InterpreterUtil.h"
- namespace hybridclr
- {
- namespace transform
- {
- constexpr int32_t MAX_STACK_SIZE = (2 << 16) - 1;
- constexpr int32_t MAX_VALUE_TYPE_SIZE = (2 << 16) - 1;
- template<typename T>
- void AllocResolvedData(il2cpp::utils::dynamic_array<uint64_t>& resolvedDatas, int32_t size, int32_t& index, T*& buf)
- {
- if (size > 0)
- {
- int32_t oldSize = index = (int32_t)resolvedDatas.size();
- resolvedDatas.resize_initialized(oldSize + size);
- buf = (T*)&resolvedDatas[oldSize];
- }
- else
- {
- index = 0;
- buf = nullptr;
- }
- }
- IRCommon* CreateInitLocals(TemporaryMemoryArena& pool, uint32_t size, int32_t offset)
- {
- if (offset == 0)
- {
- CreateIR(ir, InitLocals_n_4);
- ir->size = size;
- return ir;
- }
- else
- {
- CreateIR(ir, InitInlineLocals_n_4);
- ir->size = size;
- ir->offset = offset;
- return ir;
- }
- }
- IRCommon* CreateLoadExpandDataToStackVarVar(TemporaryMemoryArena& pool, int32_t dstOffset, int32_t srcOffset, const Il2CppType* type, int32_t size);
- IRCommon* CreateAssignVarVar(TemporaryMemoryArena& pool, int32_t dstOffset, int32_t srcOffset, int32_t size);
- interpreter::IRCommon* CreateClassLdfld(TemporaryMemoryArena& pool, int32_t dstIdx, int32_t objIdx, const FieldInfo* fieldInfo);
- interpreter::IRCommon* CreateValueTypeLdfld(TemporaryMemoryArena& pool, int32_t dstIdx, int32_t objIdx, const FieldInfo* fieldInfo);
- interpreter::IRCommon* CreateStfld(TemporaryMemoryArena& pool, int32_t objIdx, const FieldInfo* fieldInfo, int32_t dataIdx);
- interpreter::IRCommon* CreateLdsfld(TemporaryMemoryArena& pool, int32_t dstIdx, const FieldInfo* fieldInfo, uint32_t parent);
- interpreter::IRCommon* CreateStsfld(TemporaryMemoryArena& pool, const FieldInfo* fieldInfo, uint32_t parent, int32_t dataIdx);
- interpreter::IRCommon* CreateLdthreadlocal(TemporaryMemoryArena& pool, int32_t dstIdx, const FieldInfo* fieldInfo, uint32_t parent);
- interpreter::IRCommon* CreateStthreadlocal(TemporaryMemoryArena& pool, const FieldInfo* fieldInfo, uint32_t parent, int32_t dataIdx);
- EvalStackReduceDataType GetEvalStackReduceDataType(const Il2CppType* type)
- {
- if (type->byref)
- {
- return NATIVE_INT_REDUCE_TYPE;
- }
- switch (type->type)
- {
- case IL2CPP_TYPE_BOOLEAN:
- case IL2CPP_TYPE_I1:
- case IL2CPP_TYPE_U1:
- case IL2CPP_TYPE_CHAR:
- case IL2CPP_TYPE_I2:
- case IL2CPP_TYPE_U2:
- case IL2CPP_TYPE_I4:
- case IL2CPP_TYPE_U4:
- return EvalStackReduceDataType::I4;
- case IL2CPP_TYPE_R4:
- return EvalStackReduceDataType::R4;
- case IL2CPP_TYPE_I8:
- case IL2CPP_TYPE_U8:
- return EvalStackReduceDataType::I8;
- case IL2CPP_TYPE_R8:
- return EvalStackReduceDataType::R8;
- case IL2CPP_TYPE_I:
- case IL2CPP_TYPE_U:
- case IL2CPP_TYPE_FNPTR:
- case IL2CPP_TYPE_PTR:
- case IL2CPP_TYPE_BYREF:
- case IL2CPP_TYPE_STRING:
- case IL2CPP_TYPE_CLASS:
- case IL2CPP_TYPE_ARRAY:
- case IL2CPP_TYPE_SZARRAY:
- case IL2CPP_TYPE_OBJECT:
- return NATIVE_INT_REDUCE_TYPE;
- case IL2CPP_TYPE_TYPEDBYREF:
- return EvalStackReduceDataType::Other;
- case IL2CPP_TYPE_VALUETYPE:
- {
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type);
- return klass->enumtype ? GetEvalStackReduceDataType(&klass->element_class->byval_arg) : EvalStackReduceDataType::Other;
- }
- case IL2CPP_TYPE_GENERICINST:
- {
- Il2CppGenericClass* genericClass = type->data.generic_class;
- if (genericClass->type->type == IL2CPP_TYPE_CLASS)
- {
- return NATIVE_INT_REDUCE_TYPE;
- }
- else
- {
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type);
- return klass->enumtype ? GetEvalStackReduceDataType(&klass->element_class->byval_arg) : EvalStackReduceDataType::Other;
- }
- }
- default:
- {
- RaiseExecutionEngineException("GetEvalStackReduceDataType invalid type");
- return EvalStackReduceDataType::Other;
- }
- }
- }
- int32_t GetSizeByReduceType(EvalStackReduceDataType type)
- {
- switch (type)
- {
- case hybridclr::transform::EvalStackReduceDataType::I4:
- case hybridclr::transform::EvalStackReduceDataType::R4:
- return 4;
- case hybridclr::transform::EvalStackReduceDataType::I8:
- case hybridclr::transform::EvalStackReduceDataType::R8:
- return 8;
- default:
- {
- RaiseExecutionEngineException("GetSizeByReduceType not support type");
- return PTR_SIZE;
- }
- }
- }
- LocationDescInfo ComputValueTypeDescInfo(int32_t size, bool hasReference)
- {
- #if HYBRIDCLR_ENABLE_WRITE_BARRIERS
- if (hasReference)
- {
- return { LocationDescType::StructContainsRef, size };
- }
- #endif
- switch (size)
- {
- case 1: return { LocationDescType::U1, 0 };
- case 2: return { LocationDescType::U2, 0 };
- case 4: return { LocationDescType::I4, 0 };
- case 8: return { LocationDescType::I8, 0 };
- default: return { LocationDescType::S, size };
- }
- }
- LocationDescInfo ComputLocationDescInfo(const Il2CppType* type)
- {
- if (type->byref)
- {
- return { NATIVE_INT_DESC_TYPE, 0 };
- }
- switch (type->type)
- {
- case IL2CPP_TYPE_BOOLEAN:
- case IL2CPP_TYPE_U1:
- return{ LocationDescType::U1, 0 };
- case IL2CPP_TYPE_I1:
- return{ LocationDescType::I1, 0 };
- case IL2CPP_TYPE_I2:
- return{ LocationDescType::I2, 0 };
- case IL2CPP_TYPE_CHAR:
- case IL2CPP_TYPE_U2:
- return{ LocationDescType::U2, 0 };
- case IL2CPP_TYPE_I4:
- case IL2CPP_TYPE_U4:
- case IL2CPP_TYPE_R4:
- return{ LocationDescType::I4, 0 };
- case IL2CPP_TYPE_I8:
- case IL2CPP_TYPE_U8:
- case IL2CPP_TYPE_R8:
- return{ LocationDescType::I8, 0 };
- case IL2CPP_TYPE_I:
- case IL2CPP_TYPE_U:
- case IL2CPP_TYPE_FNPTR:
- case IL2CPP_TYPE_PTR:
- case IL2CPP_TYPE_BYREF:
- return{ NATIVE_INT_DESC_TYPE, 0 };
- case IL2CPP_TYPE_STRING:
- case IL2CPP_TYPE_ARRAY:
- case IL2CPP_TYPE_SZARRAY:
- case IL2CPP_TYPE_OBJECT:
- case IL2CPP_TYPE_CLASS:
- return{ LocationDescType::Ref, 0 };
- case IL2CPP_TYPE_TYPEDBYREF:
- return { LocationDescType::S, sizeof(Il2CppTypedRef) };
- case IL2CPP_TYPE_VALUETYPE:
- {
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type);
- IL2CPP_ASSERT(IS_CLASS_VALUE_TYPE(klass));
- if (klass->enumtype)
- {
- return ComputLocationDescInfo(&klass->castClass->byval_arg);
- }
- return ComputValueTypeDescInfo(il2cpp::vm::Class::GetValueSize(klass, nullptr), klass->has_references);
- }
- case IL2CPP_TYPE_GENERICINST:
- {
- Il2CppGenericClass* genericClass = type->data.generic_class;
- if (genericClass->type->type == IL2CPP_TYPE_CLASS)
- {
- IL2CPP_ASSERT(!IS_CLASS_VALUE_TYPE(il2cpp::vm::Class::FromIl2CppType(type)));
- return{ LocationDescType::Ref, 0 };
- }
- else
- {
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type);
- IL2CPP_ASSERT(IS_CLASS_VALUE_TYPE(klass));
- if (klass->enumtype)
- {
- return ComputLocationDescInfo(&klass->castClass->byval_arg);
- }
- return ComputValueTypeDescInfo(il2cpp::vm::Class::GetValueSize(klass, nullptr), klass->has_references);
- }
- }
- default:
- {
- RaiseExecutionEngineException("not support arg type");
- return{ NATIVE_INT_DESC_TYPE, 0 };
- }
- }
- }
- IRCommon* CreateLoadExpandDataToStackVarVar(TemporaryMemoryArena& pool, int32_t dstOffset, int32_t srcOffset, const Il2CppType* type, int32_t size)
- {
- if (type->byref)
- {
- CreateIR(ir, LdlocVarVar);
- ir->dst = dstOffset;
- ir->src = srcOffset;
- return ir;
- }
- switch (type->type)
- {
- case Il2CppTypeEnum::IL2CPP_TYPE_I1:
- {
- CreateIR(ir, LdlocExpandVarVar_i1);
- ir->dst = dstOffset;
- ir->src = srcOffset;
- return ir;
- }
- case Il2CppTypeEnum::IL2CPP_TYPE_BOOLEAN:
- case Il2CppTypeEnum::IL2CPP_TYPE_U1:
- {
- CreateIR(ir, LdlocExpandVarVar_u1);
- ir->dst = dstOffset;
- ir->src = srcOffset;
- return ir;
- }
- case Il2CppTypeEnum::IL2CPP_TYPE_I2:
- {
- CreateIR(ir, LdlocExpandVarVar_i2);
- ir->dst = dstOffset;
- ir->src = srcOffset;
- return ir;
- }
- case IL2CPP_TYPE_CHAR:
- case IL2CPP_TYPE_U2:
- {
- CreateIR(ir, LdlocExpandVarVar_u2);
- ir->dst = dstOffset;
- ir->src = srcOffset;
- return ir;
- }
- case IL2CPP_TYPE_VALUETYPE:
- {
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type);
- if (klass->enumtype)
- {
- return CreateLoadExpandDataToStackVarVar(pool, dstOffset, srcOffset, &klass->element_class->byval_arg, size);
- }
- break;
- }
- default: break;
- }
- if (size <= 8)
- {
- CreateIR(ir, LdlocVarVar);
- ir->dst = dstOffset;
- ir->src = srcOffset;
- return ir;
- }
- else
- {
- IL2CPP_ASSERT(size <= MAX_VALUE_TYPE_SIZE);
- CreateIR(ir, LdlocVarVarSize);
- ir->dst = dstOffset;
- ir->src = srcOffset;
- ir->size = size;
- return ir;
- }
- }
- IRCommon* CreateAssignVarVar(TemporaryMemoryArena& pool, int32_t dstOffset, int32_t srcOffset, int32_t size)
- {
- IL2CPP_ASSERT(dstOffset >= 0 && dstOffset < 0x10000);
- IL2CPP_ASSERT(srcOffset >= 0 && srcOffset < 0x10000);
- if (size <= 8)
- {
- CreateIR(ir, LdlocVarVar);
- ir->dst = dstOffset;
- ir->src = srcOffset;
- return ir;
- }
- else
- {
- IL2CPP_ASSERT(size <= MAX_VALUE_TYPE_SIZE);
- CreateIR(ir, LdlocVarVarSize);
- ir->dst = dstOffset;
- ir->src = srcOffset;
- ir->size = size;
- return ir;
- }
- }
- interpreter::IRCommon* CreateClassLdfld(TemporaryMemoryArena& pool, int32_t dstIdx, int32_t objIdx, const FieldInfo* fieldInfo)
- {
- uint16_t offset = (uint16_t)GetFieldOffset(fieldInfo);
- const Il2CppType* type = fieldInfo->type;
- LocationDescInfo desc = ComputLocationDescInfo(type);
- CreateIR(ir, LdfldVarVar_i1);
- ir->dst = dstIdx;
- ir->obj = objIdx;
- ir->offset = offset;
- switch (desc.type)
- {
- case LocationDescType::I1:
- {
- ir->type = HiOpcodeEnum::LdfldVarVar_i1;
- return ir;
- }
- case LocationDescType::U1:
- {
- ir->type = HiOpcodeEnum::LdfldVarVar_u1;
- return ir;
- }
- case LocationDescType::I2:
- {
- ir->type = HiOpcodeEnum::LdfldVarVar_i2;
- return ir;
- }
- case LocationDescType::U2:
- {
- ir->type = HiOpcodeEnum::LdfldVarVar_u2;
- return ir;
- }
- case LocationDescType::I4:
- {
- ir->type = HiOpcodeEnum::LdfldVarVar_i4;
- return ir;
- }
- case LocationDescType::I8:
- {
- ir->type = HiOpcodeEnum::LdfldVarVar_i8;
- return ir;
- }
- case LocationDescType::Ref:
- {
- ir->type = ARCH_ARGUMENT(HiOpcodeEnum::LdfldVarVar_i4, HiOpcodeEnum::LdfldVarVar_i8);
- return ir;
- }
- case LocationDescType::S:
- case LocationDescType::StructContainsRef:
- {
- switch (desc.size)
- {
- case 12:
- {
- ir->type = HiOpcodeEnum::LdfldVarVar_size_12;
- return ir;
- }
- case 16:
- {
- ir->type = HiOpcodeEnum::LdfldVarVar_size_16;
- return ir;
- }
- case 20:
- {
- ir->type = HiOpcodeEnum::LdfldVarVar_size_20;
- return ir;
- }
- case 24:
- {
- ir->type = HiOpcodeEnum::LdfldVarVar_size_24;
- return ir;
- }
- case 28:
- {
- ir->type = HiOpcodeEnum::LdfldVarVar_size_28;
- return ir;
- }
- case 32:
- {
- ir->type = HiOpcodeEnum::LdfldVarVar_size_32;
- return ir;
- }
- default:
- {
- CreateIR(irn, LdfldVarVar_n_4);
- irn->dst = dstIdx;
- irn->obj = objIdx;
- irn->offset = offset;
- irn->size = desc.size;
- return irn;
- }
- }
- }
- default:
- {
- RaiseExecutionEngineException("field");
- return ir;
- }
- }
- }
- interpreter::IRCommon* CreateValueTypeLdfld(TemporaryMemoryArena& pool, int32_t dstIdx, int32_t objIdx, const FieldInfo* fieldInfo)
- {
- uint16_t offset = (uint16_t)GetFieldOffset(fieldInfo);
- const Il2CppType* type = fieldInfo->type;
- LocationDescInfo desc = ComputLocationDescInfo(type);
- CreateIR(ir, LdfldValueTypeVarVar_i1);
- ir->dst = dstIdx;
- ir->obj = objIdx;
- ir->offset = offset;
- switch (desc.type)
- {
- case LocationDescType::I1:
- {
- ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_i1;
- return ir;
- }
- case LocationDescType::U1:
- {
- ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_u1;
- return ir;
- }
- case LocationDescType::I2:
- {
- ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_i2;
- return ir;
- }
- case LocationDescType::U2:
- {
- ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_u2;
- return ir;
- }
- case LocationDescType::I4:
- {
- ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_i4;
- return ir;
- }
- case LocationDescType::I8:
- {
- ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_i8;
- return ir;
- }
- case LocationDescType::Ref:
- {
- ir->type = ARCH_ARGUMENT(HiOpcodeEnum::LdfldValueTypeVarVar_i4, HiOpcodeEnum::LdfldValueTypeVarVar_i8);
- return ir;
- }
- case LocationDescType::S:
- case LocationDescType::StructContainsRef:
- {
- switch (desc.size)
- {
- case 12:
- {
- ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_size_12;
- return ir;
- }
- case 16:
- {
- ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_size_16;
- return ir;
- }
- case 20:
- {
- ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_size_20;
- return ir;
- }
- case 24:
- {
- ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_size_24;
- return ir;
- }
- case 28:
- {
- ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_size_28;
- return ir;
- }
- case 32:
- {
- ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_size_32;
- return ir;
- }
- default:
- {
- CreateIR(irn, LdfldValueTypeVarVar_n_4);
- irn->dst = dstIdx;
- irn->obj = objIdx;
- irn->offset = offset;
- irn->size = desc.size;
- return irn;
- }
- }
- }
- default:
- {
- RaiseExecutionEngineException("field");
- return ir;
- }
- }
- }
- interpreter::IRCommon* CreateStfld(TemporaryMemoryArena& pool, int32_t objIdx, const FieldInfo* fieldInfo, int32_t dataIdx)
- {
- uint16_t offset = (uint16_t)GetFieldOffset(fieldInfo);
- const Il2CppType* type = fieldInfo->type;
- LocationDescInfo desc = ComputLocationDescInfo(type);
- CreateIR(ir, StfldVarVar_i1);
- ir->data = dataIdx;
- ir->obj = objIdx;
- ir->offset = offset;
- switch (desc.type)
- {
- case LocationDescType::I1:
- {
- ir->type = HiOpcodeEnum::StfldVarVar_i1;
- return ir;
- }
- case LocationDescType::U1:
- {
- ir->type = HiOpcodeEnum::StfldVarVar_u1;
- return ir;
- }
- case LocationDescType::I2:
- {
- ir->type = HiOpcodeEnum::StfldVarVar_i2;
- return ir;
- }
- case LocationDescType::U2:
- {
- ir->type = HiOpcodeEnum::StfldVarVar_u2;
- return ir;
- }
- case LocationDescType::I4:
- {
- ir->type = HiOpcodeEnum::StfldVarVar_i4;
- return ir;
- }
- case LocationDescType::I8:
- {
- ir->type = HiOpcodeEnum::StfldVarVar_i8;
- return ir;
- }
- case LocationDescType::Ref:
- {
- ir->type = HiOpcodeEnum::StfldVarVar_ref;
- return ir;
- }
- case LocationDescType::S:
- {
- switch (desc.size)
- {
- case 12:
- {
- ir->type = HiOpcodeEnum::StfldVarVar_size_12;
- return ir;
- }
- case 16:
- {
- ir->type = HiOpcodeEnum::StfldVarVar_size_16;
- return ir;
- }
- case 20:
- {
- ir->type = HiOpcodeEnum::StfldVarVar_size_20;
- return ir;
- }
- case 24:
- {
- ir->type = HiOpcodeEnum::StfldVarVar_size_24;
- return ir;
- }
- case 28:
- {
- ir->type = HiOpcodeEnum::StfldVarVar_size_28;
- return ir;
- }
- case 32:
- {
- ir->type = HiOpcodeEnum::StfldVarVar_size_32;
- return ir;
- }
- default:
- {
- CreateIR(irn, StfldVarVar_n_4);
- irn->data = dataIdx;
- irn->obj = objIdx;
- irn->offset = offset;
- irn->size = desc.size;
- return irn;
- }
- }
- }
- case LocationDescType::StructContainsRef:
- {
- CreateIR(irn, StfldVarVar_WriteBarrier_n_4);
- irn->data = dataIdx;
- irn->obj = objIdx;
- irn->offset = offset;
- irn->size = desc.size;
- return irn;
- }
- default:
- {
- RaiseExecutionEngineException("field");
- return ir;
- }
- }
- }
- interpreter::IRCommon* CreateLdsfld(TemporaryMemoryArena& pool, int32_t dstIdx, const FieldInfo* fieldInfo, uint32_t parent)
- {
- IL2CPP_ASSERT(fieldInfo->offset < (1 << 16));
- uint16_t offset = (uint16_t)fieldInfo->offset;
- const Il2CppType* type = fieldInfo->type;
- LocationDescInfo desc = ComputLocationDescInfo(type);
- CreateIR(ir, LdsfldVarVar_i1);
- ir->dst = dstIdx;
- ir->klass = parent;
- ir->offset = offset;
- switch (desc.type)
- {
- case LocationDescType::I1:
- {
- ir->type = HiOpcodeEnum::LdsfldVarVar_i1;
- return ir;
- }
- case LocationDescType::U1:
- {
- ir->type = HiOpcodeEnum::LdsfldVarVar_u1;
- return ir;
- }
- case LocationDescType::I2:
- {
- ir->type = HiOpcodeEnum::LdsfldVarVar_i2;
- return ir;
- }
- case LocationDescType::U2:
- {
- ir->type = HiOpcodeEnum::LdsfldVarVar_u2;
- return ir;
- }
- case LocationDescType::I4:
- {
- ir->type = HiOpcodeEnum::LdsfldVarVar_i4;
- return ir;
- }
- case LocationDescType::I8:
- {
- ir->type = HiOpcodeEnum::LdsfldVarVar_i8;
- return ir;
- }
- case LocationDescType::Ref:
- {
- ir->type = ARCH_ARGUMENT(HiOpcodeEnum::LdsfldVarVar_i4, HiOpcodeEnum::LdsfldVarVar_i8);
- return ir;
- }
- case LocationDescType::S:
- case LocationDescType::StructContainsRef:
- {
- switch (desc.size)
- {
- case 12:
- {
- ir->type = HiOpcodeEnum::LdsfldVarVar_size_12;
- return ir;
- }
- case 16:
- {
- ir->type = HiOpcodeEnum::LdsfldVarVar_size_16;
- return ir;
- }
- case 20:
- {
- ir->type = HiOpcodeEnum::LdsfldVarVar_size_20;
- return ir;
- }
- case 24:
- {
- ir->type = HiOpcodeEnum::LdsfldVarVar_size_24;
- return ir;
- }
- case 28:
- {
- ir->type = HiOpcodeEnum::LdsfldVarVar_size_28;
- return ir;
- }
- case 32:
- {
- ir->type = HiOpcodeEnum::LdsfldVarVar_size_32;
- return ir;
- }
- default:
- {
- CreateIR(irn, LdsfldVarVar_n_4);
- irn->dst = dstIdx;
- irn->klass = parent;
- irn->offset = offset;
- irn->size = desc.size;
- return irn;
- }
- }
- }
- default:
- {
- RaiseExecutionEngineException("field");
- return ir;
- }
- }
- }
- interpreter::IRCommon* CreateStsfld(TemporaryMemoryArena& pool, const FieldInfo* fieldInfo, uint32_t parent, int32_t dataIdx)
- {
- IL2CPP_ASSERT(fieldInfo->offset < (1 << 16));
- uint16_t offset = (uint16_t)fieldInfo->offset;
- const Il2CppType* type = fieldInfo->type;
- LocationDescInfo desc = ComputLocationDescInfo(type);
- CreateIR(ir, StsfldVarVar_i1);
- ir->klass = parent;
- ir->offset = offset;
- ir->data = dataIdx;
- switch (desc.type)
- {
- case LocationDescType::I1:
- {
- ir->type = HiOpcodeEnum::StsfldVarVar_i1;
- return ir;
- }
- case LocationDescType::U1:
- {
- ir->type = HiOpcodeEnum::StsfldVarVar_u1;
- return ir;
- }
- case LocationDescType::I2:
- {
- ir->type = HiOpcodeEnum::StsfldVarVar_i2;
- return ir;
- }
- case LocationDescType::U2:
- {
- ir->type = HiOpcodeEnum::StsfldVarVar_u2;
- return ir;
- }
- case LocationDescType::I4:
- {
- ir->type = HiOpcodeEnum::StsfldVarVar_i4;
- return ir;
- }
- case LocationDescType::I8:
- {
- ir->type = HiOpcodeEnum::StsfldVarVar_i8;
- return ir;
- }
- case LocationDescType::Ref:
- {
- ir->type = HiOpcodeEnum::StsfldVarVar_ref;
- return ir;
- }
- case LocationDescType::S:
- {
- switch (desc.size)
- {
- case 12:
- {
- ir->type = HiOpcodeEnum::StsfldVarVar_size_12;
- return ir;
- }
- case 16:
- {
- ir->type = HiOpcodeEnum::StsfldVarVar_size_16;
- return ir;
- }
- case 20:
- {
- ir->type = HiOpcodeEnum::StsfldVarVar_size_20;
- return ir;
- }
- case 24:
- {
- ir->type = HiOpcodeEnum::StsfldVarVar_size_24;
- return ir;
- }
- case 28:
- {
- ir->type = HiOpcodeEnum::StsfldVarVar_size_28;
- return ir;
- }
- case 32:
- {
- ir->type = HiOpcodeEnum::StsfldVarVar_size_32;
- return ir;
- }
- default:
- {
- CreateIR(irn, StsfldVarVar_n_4);
- irn->klass = parent;
- irn->offset = offset;
- irn->data = dataIdx;
- irn->size = desc.size;
- return irn;
- }
- }
- }
- case LocationDescType::StructContainsRef:
- {
- CreateIR(irn, StsfldVarVar_WriteBarrier_n_4);
- irn->klass = parent;
- irn->offset = offset;
- irn->data = dataIdx;
- irn->size = desc.size;
- return irn;
- }
- default:
- {
- RaiseExecutionEngineException("field");
- return ir;
- }
- }
- }
- interpreter::IRCommon* CreateLdthreadlocal(TemporaryMemoryArena& pool, int32_t dstIdx, const FieldInfo* fieldInfo, uint32_t parent)
- {
- IL2CPP_ASSERT(fieldInfo->offset == THREAD_STATIC_FIELD_OFFSET);
- int32_t offset = GetThreadStaticFieldOffset(fieldInfo);
- const Il2CppType* type = fieldInfo->type;
- LocationDescInfo desc = ComputLocationDescInfo(type);
- CreateIR(ir, LdthreadlocalVarVar_i1);
- ir->dst = dstIdx;
- ir->klass = parent;
- ir->offset = offset;
- switch (desc.type)
- {
- case LocationDescType::I1:
- {
- ir->type = HiOpcodeEnum::LdthreadlocalVarVar_i1;
- return ir;
- }
- case LocationDescType::U1:
- {
- ir->type = HiOpcodeEnum::LdthreadlocalVarVar_u1;
- return ir;
- }
- case LocationDescType::I2:
- {
- ir->type = HiOpcodeEnum::LdthreadlocalVarVar_i2;
- return ir;
- }
- case LocationDescType::U2:
- {
- ir->type = HiOpcodeEnum::LdthreadlocalVarVar_u2;
- return ir;
- }
- case LocationDescType::I4:
- {
- ir->type = HiOpcodeEnum::LdthreadlocalVarVar_i4;
- return ir;
- }
- case LocationDescType::I8:
- {
- ir->type = HiOpcodeEnum::LdthreadlocalVarVar_i8;
- return ir;
- }
- case LocationDescType::Ref:
- {
- ir->type = ARCH_ARGUMENT(HiOpcodeEnum::LdthreadlocalVarVar_i4, HiOpcodeEnum::LdthreadlocalVarVar_i8);
- return ir;
- }
- case LocationDescType::S:
- case LocationDescType::StructContainsRef:
- {
- switch (desc.size)
- {
- case 12:
- {
- ir->type = HiOpcodeEnum::LdthreadlocalVarVar_size_12;
- return ir;
- }
- case 16:
- {
- ir->type = HiOpcodeEnum::LdthreadlocalVarVar_size_16;
- return ir;
- }
- case 20:
- {
- ir->type = HiOpcodeEnum::LdthreadlocalVarVar_size_20;
- return ir;
- }
- case 24:
- {
- ir->type = HiOpcodeEnum::LdthreadlocalVarVar_size_24;
- return ir;
- }
- case 28:
- {
- ir->type = HiOpcodeEnum::LdthreadlocalVarVar_size_28;
- return ir;
- }
- case 32:
- {
- ir->type = HiOpcodeEnum::LdthreadlocalVarVar_size_32;
- return ir;
- }
- default:
- {
- CreateIR(irn, LdthreadlocalVarVar_n_4);
- irn->dst = dstIdx;
- irn->klass = parent;
- irn->offset = offset;
- irn->size = desc.size;
- return irn;
- }
- }
- }
- default:
- {
- RaiseExecutionEngineException("field");
- return ir;
- }
- }
- }
- interpreter::IRCommon* CreateStthreadlocal(TemporaryMemoryArena& pool, const FieldInfo* fieldInfo, uint32_t parent, int32_t dataIdx)
- {
- IL2CPP_ASSERT(fieldInfo->offset == THREAD_STATIC_FIELD_OFFSET);
- int32_t offset = GetThreadStaticFieldOffset(fieldInfo);
- const Il2CppType* type = fieldInfo->type;
- LocationDescInfo desc = ComputLocationDescInfo(type);
- CreateIR(ir, StthreadlocalVarVar_i1);
- ir->klass = parent;
- ir->offset = offset;
- ir->data = dataIdx;
- switch (desc.type)
- {
- case LocationDescType::I1:
- {
- ir->type = HiOpcodeEnum::StthreadlocalVarVar_i1;
- return ir;
- }
- case LocationDescType::U1:
- {
- ir->type = HiOpcodeEnum::StthreadlocalVarVar_u1;
- return ir;
- }
- case LocationDescType::I2:
- {
- ir->type = HiOpcodeEnum::StthreadlocalVarVar_i2;
- return ir;
- }
- case LocationDescType::U2:
- {
- ir->type = HiOpcodeEnum::StthreadlocalVarVar_u2;
- return ir;
- }
- case LocationDescType::I4:
- {
- ir->type = HiOpcodeEnum::StthreadlocalVarVar_i4;
- return ir;
- }
- case LocationDescType::I8:
- {
- ir->type = HiOpcodeEnum::StthreadlocalVarVar_i8;
- return ir;
- }
- case LocationDescType::Ref:
- {
- ir->type = HiOpcodeEnum::StthreadlocalVarVar_ref;
- return ir;
- }
- case LocationDescType::S:
- {
- switch (desc.size)
- {
- case 12:
- {
- ir->type = HiOpcodeEnum::StthreadlocalVarVar_size_12;
- return ir;
- }
- case 16:
- {
- ir->type = HiOpcodeEnum::StthreadlocalVarVar_size_16;
- return ir;
- }
- case 20:
- {
- ir->type = HiOpcodeEnum::StthreadlocalVarVar_size_20;
- return ir;
- }
- case 24:
- {
- ir->type = HiOpcodeEnum::StthreadlocalVarVar_size_24;
- return ir;
- }
- case 28:
- {
- ir->type = HiOpcodeEnum::StthreadlocalVarVar_size_28;
- return ir;
- }
- case 32:
- {
- ir->type = HiOpcodeEnum::StthreadlocalVarVar_size_32;
- return ir;
- }
- default:
- {
- CreateIR(irn, StthreadlocalVarVar_n_4);
- irn->klass = parent;
- irn->offset = offset;
- irn->data = dataIdx;
- irn->size = desc.size;
- return irn;
- }
- }
- }
- case LocationDescType::StructContainsRef:
- {
- CreateIR(irn, StthreadlocalVarVar_WriteBarrier_n_4);
- irn->klass = parent;
- irn->offset = offset;
- irn->data = dataIdx;
- irn->size = desc.size;
- return irn;
- }
- default:
- {
- RaiseExecutionEngineException("field");
- return ir;
- }
- }
- }
- // TransformContext implements
- HiOpcodeEnum TransformContext::CalcGetMdArrElementVarVarOpcode(const Il2CppType* type)
- {
- LocationDescInfo desc = ComputLocationDescInfo(type);
- switch (desc.type)
- {
- case LocationDescType::I1: return HiOpcodeEnum::GetMdArrElementVarVar_i1;
- case LocationDescType::U1: return HiOpcodeEnum::GetMdArrElementVarVar_u1;
- case LocationDescType::I2: return HiOpcodeEnum::GetMdArrElementVarVar_i2;
- case LocationDescType::U2: return HiOpcodeEnum::GetMdArrElementVarVar_u2;
- case LocationDescType::I4: return HiOpcodeEnum::GetMdArrElementVarVar_i4;
- case LocationDescType::I8: return HiOpcodeEnum::GetMdArrElementVarVar_i8;
- case LocationDescType::Ref: return ARCH_ARGUMENT(HiOpcodeEnum::GetMdArrElementVarVar_i4, HiOpcodeEnum::GetMdArrElementVarVar_i8);
- case LocationDescType::S:
- case LocationDescType::StructContainsRef: return HiOpcodeEnum::GetMdArrElementVarVar_n;
- default:
- {
- RaiseExecutionEngineException("CalcGetMdArrElementVarVarOpcode");
- return (HiOpcodeEnum)0;
- }
- }
- }
- TransformContext::TransformContext(hybridclr::metadata::Image* image, const MethodInfo* methodInfo, metadata::MethodBody& body, TemporaryMemoryArena& pool, il2cpp::utils::dynamic_array<uint64_t>& resolveDatas)
- : image(image), methodInfo(methodInfo), body(body), pool(pool), resolveDatas(resolveDatas)
- {
- }
- uint32_t TransformContext::GetOrAddResolveDataIndex(const void* ptr)
- {
- auto it = ptr2DataIdxs.find(ptr);
- if (it != ptr2DataIdxs.end())
- {
- return it->second;
- }
- else
- {
- uint32_t newIndex = (uint32_t)resolveDatas.size();
- resolveDatas.push_back((uint64_t)ptr);
- ptr2DataIdxs.insert({ ptr, newIndex });
- return newIndex;
- }
- }
- void TransformContext::PushStackByType(const Il2CppType* type)
- {
- int32_t byteSize = GetTypeValueSize(type);
- int32_t stackSize = GetStackSizeByByteSize(byteSize);
- evalStack[evalStackTop].reduceType = GetEvalStackReduceDataType(type);
- evalStack[evalStackTop].byteSize = byteSize;
- evalStack[evalStackTop].locOffset = GetEvalStackNewTopOffset();
- evalStackTop++;
- curStackSize += stackSize;
- maxStackSize = std::max(curStackSize, maxStackSize);
- IL2CPP_ASSERT(maxStackSize < MAX_STACK_SIZE);
- }
- void TransformContext::PushStackByReduceType(EvalStackReduceDataType t)
- {
- int32_t byteSize = GetSizeByReduceType(t);
- int32_t stackSize = GetStackSizeByByteSize(byteSize);
- evalStack[evalStackTop].reduceType = t;
- evalStack[evalStackTop].byteSize = byteSize;
- evalStack[evalStackTop].locOffset = GetEvalStackNewTopOffset();
- evalStackTop++; curStackSize += stackSize;
- maxStackSize = std::max(curStackSize, maxStackSize);
- IL2CPP_ASSERT(maxStackSize < MAX_STACK_SIZE);
- }
- void TransformContext::DuplicateStack()
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- EvalStackVarInfo& oldTop = evalStack[evalStackTop - 1];
- int32_t stackSize = GetStackSizeByByteSize(oldTop.byteSize);
- EvalStackVarInfo& newTop = evalStack[evalStackTop++];
- newTop.reduceType = oldTop.reduceType;
- newTop.byteSize = oldTop.byteSize;
- newTop.locOffset = curStackSize;
- curStackSize += stackSize;
- maxStackSize = std::max(curStackSize, maxStackSize);
- IL2CPP_ASSERT(maxStackSize < MAX_STACK_SIZE);
- }
- void TransformContext::PopStack()
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- --evalStackTop;
- curStackSize = evalStack[evalStackTop].locOffset;
- }
- void TransformContext::PopStackN(int32_t n)
- {
- IL2CPP_ASSERT(evalStackTop >= n && n >= 0);
- if (n > 0)
- {
- evalStackTop -= n;
- curStackSize = evalStack[evalStackTop].locOffset;
- }
- }
- void TransformContext::PopAllStack()
- {
- if (evalStackTop > 0)
- {
- evalStackTop = 0;
- curStackSize = evalStackBaseOffset;
- }
- else
- {
- IL2CPP_ASSERT(curStackSize == evalStackBaseOffset);
- }
- }
- void TransformContext::InsertMemoryBarrier()
- {
- if (prefixFlags & (int32_t)PrefixFlags::Volatile)
- {
- CreateAddIR(_mb, MemoryBarrier);
- }
- }
- void TransformContext::ResetPrefixFlags()
- {
- prefixFlags = 0;
- }
- void TransformContext::Add_ldind(HiOpcodeEnum opCode, EvalStackReduceDataType dataType)
- {
- CreateAddIR(ir, LdindVarVar_i1);
- ir->type = opCode;
- ir->dst = ir->src = GetEvalStackTopOffset();
- PopStack();
- PushStackByReduceType(dataType);
- InsertMemoryBarrier();
- ResetPrefixFlags();
- ip++;
- }
- void TransformContext::Add_stind(HiOpcodeEnum opCode)
- {
- IL2CPP_ASSERT(evalStackTop >= 2);
- InsertMemoryBarrier();
- ResetPrefixFlags();
- CreateAddIR(ir, StindVarVar_i1);
- ir->type = opCode;
- ir->dst = evalStack[evalStackTop - 2].locOffset;
- ir->src = evalStack[evalStackTop - 1].locOffset;
- PopStackN(2);
- ip++;
- }
- void TransformContext::PushOffset(int32_t* offsetPtr)
- {
- IL2CPP_ASSERT(splitOffsets.find(*(offsetPtr)) != splitOffsets.end());
- relocationOffsets.push_back(offsetPtr);
- }
- void TransformContext::PushBranch(int32_t targetOffset)
- {
- IL2CPP_ASSERT(splitOffsets.find(targetOffset) != splitOffsets.end());
- IRBasicBlock* targetBb = ip2bb[targetOffset];
- if (!targetBb->inPending)
- {
- targetBb->inPending = true;
- FlowInfo* fi = pool.NewAny<FlowInfo>();
- fi->offset = targetOffset;
- fi->curStackSize = curStackSize;
- if (evalStackTop > 0)
- {
- fi->evalStack.insert(fi->evalStack.end(), evalStack, evalStack + evalStackTop);
- }
- else
- {
- IL2CPP_ASSERT(curStackSize == evalStackBaseOffset);
- }
- pendingFlows.push_back(fi);
- }
- }
- bool TransformContext::FindNextFlow()
- {
- for (; nextFlowIdx < (int32_t)pendingFlows.size(); )
- {
- FlowInfo* fi = pendingFlows[nextFlowIdx++];
- IRBasicBlock* nextBb = ip2bb[fi->offset];
- if (!nextBb->visited)
- {
- ip = ipBase + fi->offset;
- if (!fi->evalStack.empty()) {
- std::memcpy(evalStack, &fi->evalStack[0], sizeof(EvalStackVarInfo) * fi->evalStack.size());
- }
- curStackSize = fi->curStackSize;
- IL2CPP_ASSERT(curStackSize >= evalStackBaseOffset);
- evalStackTop = (int32_t)fi->evalStack.size();
- return true;
- }
- }
- return false;
- }
- void TransformContext::AddInst(IRCommon* ir)
- {
- IL2CPP_ASSERT(ir->type != HiOpcodeEnum::None);
- curbb->insts.push_back(ir);
- if (ir2offsetMap)
- {
- ir2offsetMap->insert({ ir, ipOffset });
- }
- }
- void TransformContext::AddInst_ldarg(int32_t argIdx)
- {
- ArgVarInfo& __arg = args[argIdx];
- IRCommon* ir = CreateLoadExpandDataToStackVarVar(pool, GetEvalStackNewTopOffset(), __arg.argLocOffset, __arg.type, GetTypeValueSize(__arg.type));
- AddInst(ir);
- PushStackByType(__arg.type);
- }
- bool TransformContext::IsCreateNotNullObjectInstrument(IRCommon* ir)
- {
- switch (ir->type)
- {
- case HiOpcodeEnum::BoxVarVar:
- {
- IRBoxVarVar* irBox = (IRBoxVarVar*)ir;
- Il2CppClass* klass = ((Il2CppClass*)resolveDatas[irBox->klass]);
- return IS_CLASS_VALUE_TYPE(klass) && !il2cpp::vm::Class::IsNullable(klass);
- }
- case HiOpcodeEnum::NewSystemObjectVar:
- case HiOpcodeEnum::NewString:
- case HiOpcodeEnum::NewString_2:
- case HiOpcodeEnum::NewString_3:
- case HiOpcodeEnum::CtorDelegate:
- case HiOpcodeEnum::NewDelegate:
- //case HiOpcodeEnum::NewClassInterpVar_Ctor_0:
- //case HiOpcodeEnum::NewClassInterpVar:
- //case HiOpcodeEnum::NewClassVar:
- //case HiOpcodeEnum::NewClassVar_Ctor_0:
- //case HiOpcodeEnum::NewClassVar_NotCtor:
- case HiOpcodeEnum::NewMdArrVarVar_length:
- case HiOpcodeEnum::NewMdArrVarVar_length_bound:
- case HiOpcodeEnum::NewArrVarVar:
- case HiOpcodeEnum::LdsfldaFromFieldDataVarVar:
- case HiOpcodeEnum::LdsfldaVarVar:
- case HiOpcodeEnum::LdthreadlocalaVarVar:
- case HiOpcodeEnum::LdlocVarAddress:
- return true;
- default:
- return false;
- }
- }
- void TransformContext::RemoveLastInstrument()
- {
- IL2CPP_ASSERT(!curbb->insts.empty());
- curbb->insts.pop_back();
- }
- void TransformContext::AddInst_ldarga(int32_t argIdx)
- {
- IL2CPP_ASSERT(argIdx < actualParamCount);
- ArgVarInfo& argInfo = args[argIdx];
- CreateAddIR(ir, LdlocVarAddress);
- ir->dst = GetEvalStackNewTopOffset();
- ir->src = argInfo.argLocOffset;
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- }
- void TransformContext::AddInst_starg(int32_t argIdx)
- {
- IL2CPP_ASSERT(argIdx < actualParamCount);
- ArgVarInfo& __arg = args[argIdx];
- IRCommon* ir = CreateAssignVarVar(pool, __arg.argLocOffset, GetEvalStackTopOffset(), GetTypeValueSize(__arg.type));
- AddInst(ir);
- PopStack();
- }
- void TransformContext::CreateAddInst_ldloc(int32_t locIdx)
- {
- LocVarInfo& __loc = locals[locIdx];
- IRCommon* ir = CreateLoadExpandDataToStackVarVar(pool, GetEvalStackNewTopOffset(), __loc.locOffset, __loc.type, GetTypeValueSize(__loc.type));
- AddInst(ir);
- PushStackByType(__loc.type);
- }
- void TransformContext::CreateAddInst_stloc(int32_t locIdx)
- {
- LocVarInfo& __loc = locals[locIdx];
- IRCommon* ir = CreateAssignVarVar(pool, __loc.locOffset, GetEvalStackTopOffset(), GetTypeValueSize(__loc.type));
- AddInst(ir);
- PopStack();
- }
- void TransformContext::CreateAddInst_ldloca(int32_t locIdx)
- {
- CreateAddIR(ir, LdlocVarAddress);
- LocVarInfo& __loc = locals[locIdx];
- ir->dst = GetEvalStackNewTopOffset();
- ir->src = __loc.locOffset;
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- }
- void TransformContext::CreateAddInst_ldc4(int32_t c, EvalStackReduceDataType rtype)
- {
- CreateAddIR(ir, LdcVarConst_4);
- ir->dst = GetEvalStackNewTopOffset();
- ir->src = c;
- PushStackByReduceType(rtype);
- }
- void TransformContext::CreateAddInst_ldc8(int64_t c, EvalStackReduceDataType rtype)
- {
- CreateAddIR(ir, LdcVarConst_8);
- ir->dst = GetEvalStackNewTopOffset();
- ir->src = c;
- PushStackByReduceType(rtype);
- }
- void TransformContext::Add_brtruefalse(bool c, int32_t targetOffset)
- {
- EvalStackVarInfo& top = evalStack[evalStackTop - 1];
- IRCommon* lastIR = GetLastInstrument();
- if (lastIR == nullptr || !IsCreateNotNullObjectInstrument(lastIR))
- {
- if (top.byteSize <= 4)
- {
- CreateAddIR(ir, BranchTrueVar_i4);
- ir->type = c ? HiOpcodeEnum::BranchTrueVar_i4 : HiOpcodeEnum::BranchFalseVar_i4;
- ir->op = top.locOffset;
- ir->offset = targetOffset;
- PushOffset(&ir->offset);
- }
- else
- {
- CreateAddIR(ir, BranchTrueVar_i8);
- ir->type = c ? HiOpcodeEnum::BranchTrueVar_i8 : HiOpcodeEnum::BranchFalseVar_i8;
- ir->op = top.locOffset;
- ir->offset = targetOffset;
- PushOffset(&ir->offset);
- }
- }
- else
- {
- // optimize instrument sequence like` box T!; brtrue`
- // this optimization is not semanticly equals to origin instrument because may ommit `Class::InitRuntime`.
- // but it's ok in most occasions.
- RemoveLastInstrument();
- if (c)
- {
- // brtrue always true, replace with br
- CreateAddIR(ir, BranchUncondition_4);
- ir->offset = targetOffset;
- PushOffset(&ir->offset);
- }
- else
- {
- // brfalse always false, run throughtly.
- }
- }
- PopStack();
- PushBranch(targetOffset);
- }
- void TransformContext::Add_bc(int32_t ipOffset, int32_t brOffset, int32_t opSize, HiOpcodeEnum opI4, HiOpcodeEnum opI8, HiOpcodeEnum opR4, HiOpcodeEnum opR8)
- {
- int32_t targetOffset = ipOffset + brOffset + opSize;
- EvalStackVarInfo& op1 = evalStack[evalStackTop - 2];
- EvalStackVarInfo& op2 = evalStack[evalStackTop - 1];
- IRBranchVarVar_Ceq_i4* ir = pool.AllocIR<IRBranchVarVar_Ceq_i4>();
- ir->type = (HiOpcodeEnum)0;
- ir->op1 = op1.locOffset;
- ir->op2 = op2.locOffset;
- ir->offset = targetOffset;
- PushOffset(&ir->offset);
- switch (op1.reduceType)
- {
- case EvalStackReduceDataType::I4:
- {
- switch (op2.reduceType)
- {
- case EvalStackReduceDataType::I4:
- {
- ir->type = opI4;
- break;
- }
- case EvalStackReduceDataType::I8:
- {
- CreateAddIR(irConv, ConvertVarVar_i4_i8);
- irConv->dst = irConv->src = op1.locOffset;
- ir->type = opI8;
- break;
- }
- default:
- {
- IL2CPP_ASSERT(false && "I4 not match");
- break;
- }
- }
- break;
- }
- case EvalStackReduceDataType::I8:
- {
- IL2CPP_ASSERT(op2.reduceType == EvalStackReduceDataType::I8);
- ir->type = opI8;
- break;
- }
- case EvalStackReduceDataType::R4:
- {
- switch (op2.reduceType)
- {
- case EvalStackReduceDataType::R4:
- {
- ir->type = opR4;
- break;
- }
- default:
- {
- IL2CPP_ASSERT(false && "R4 not match");
- break;
- }
- }
- break;
- }
- case EvalStackReduceDataType::R8:
- {
- switch (op2.reduceType)
- {
- case EvalStackReduceDataType::R8:
- {
- ir->type = opR8;
- break;
- }
- default:
- {
- IL2CPP_ASSERT(false && "R8 not match");
- break;
- }
- }
- break;
- }
- default:
- {
- IL2CPP_ASSERT(false && "nothing match");
- }
- }
- AddInst(ir);
- PopStackN(2);
- PushBranch(targetOffset);
- }
- void TransformContext::Add_conv(int32_t dstTypeSize, EvalStackReduceDataType dstReduceType, HiOpcodeEnum opI4, HiOpcodeEnum opI8, HiOpcodeEnum opR4, HiOpcodeEnum opR8)
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- EvalStackVarInfo& top = evalStack[evalStackTop - 1];
- //if (top.reduceType != dstReduceType)
- {
- CreateIR(ir, ConvertVarVar_i4_u4);
- ir->type = (HiOpcodeEnum)0;
- ir->dst = ir->src = GetEvalStackTopOffset();
- switch (top.reduceType)
- {
- case EvalStackReduceDataType::I4:
- {
- ir->type = opI4;
- AddInst(ir);
- break;
- }
- case EvalStackReduceDataType::I8:
- {
- ir->type = opI8;
- AddInst(ir);
- break;
- }
- case EvalStackReduceDataType::R4:
- {
- ir->type = opR4;
- AddInst(ir);
- break;
- }
- case EvalStackReduceDataType::R8:
- {
- ir->type = opR8;
- AddInst(ir);
- break;
- }
- default:
- {
- RaiseExecutionEngineException("conv");
- break;
- }
- }
- }
- top.reduceType = dstReduceType;
- top.byteSize = dstTypeSize;
- ip++;
- }
- void TransformContext::Add_conv_ovf(int32_t dstTypeSize, EvalStackReduceDataType dstReduceType, HiOpcodeEnum opI4, HiOpcodeEnum opI8, HiOpcodeEnum opR4, HiOpcodeEnum opR8)
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- EvalStackVarInfo& top = evalStack[evalStackTop - 1];
- //if (top.reduceType != dstReduceType)
- {
- CreateIR(ir, ConvertOverflowVarVar_i4_u4);
- ir->type = (HiOpcodeEnum)0;
- ir->dst = ir->src = GetEvalStackTopOffset();
- switch (top.reduceType)
- {
- case EvalStackReduceDataType::I4:
- {
- ir->type = opI4;
- AddInst(ir);
- break;
- }
- case EvalStackReduceDataType::I8:
- {
- ir->type = opI8;
- AddInst(ir);
- break;
- }
- case EvalStackReduceDataType::R4:
- {
- ir->type = opR4;
- AddInst(ir);
- break;
- }
- case EvalStackReduceDataType::R8:
- {
- ir->type = opR8;
- AddInst(ir);
- break;
- }
- default:
- {
- RaiseExecutionEngineException("conv_ovf");
- break;
- }
- }
- }
- top.reduceType = dstReduceType;
- top.byteSize = dstTypeSize;
- ip++;
- }
- void TransformContext::Add_binop(HiOpcodeEnum opI4, HiOpcodeEnum opI8, HiOpcodeEnum opR4, HiOpcodeEnum opR8)
- {
- IL2CPP_ASSERT(evalStackTop >= 2);
- EvalStackVarInfo& op1 = evalStack[evalStackTop - 2];
- EvalStackVarInfo& op2 = evalStack[evalStackTop - 1];
- CreateIR(ir, BinOpVarVarVar_Add_i4);
- ir->op1 = op1.locOffset;
- ir->op2 = op2.locOffset;
- ir->ret = op1.locOffset;
- EvalStackReduceDataType resultType;
- switch (op1.reduceType)
- {
- case EvalStackReduceDataType::I4:
- {
- switch (op2.reduceType)
- {
- case EvalStackReduceDataType::I4:
- {
- resultType = EvalStackReduceDataType::I4;
- ir->type = opI4;
- break;
- }
- case EvalStackReduceDataType::I8:
- {
- CreateAddIR(irConv, ConvertVarVar_i4_i8);
- irConv->dst = irConv->src = op1.locOffset;
- ir->type = opI8;
- resultType = EvalStackReduceDataType::I8;
- break;
- }
- default:
- {
- RaiseExecutionEngineException("Add_bin_op I4 op unknown");
- resultType = (EvalStackReduceDataType)-1;
- }
- }
- break;
- }
- case EvalStackReduceDataType::I8:
- {
- switch (op2.reduceType)
- {
- case EvalStackReduceDataType::I4:
- {
- CreateAddIR(irConv, ConvertVarVar_i4_i8);
- irConv->dst = irConv->src = op2.locOffset;
- resultType = EvalStackReduceDataType::I8;
- ir->type = opI8;
- break;
- }
- case EvalStackReduceDataType::I8:
- {
- resultType = EvalStackReduceDataType::I8;
- ir->type = opI8;
- break;
- }
- default:
- {
- RaiseExecutionEngineException("Add_bin_op I8 op unknown");
- resultType = (EvalStackReduceDataType)-1;
- break;
- }
- }
- break;
- }
- case EvalStackReduceDataType::R4:
- {
- switch (op2.reduceType)
- {
- case EvalStackReduceDataType::R4:
- {
- resultType = EvalStackReduceDataType::R4;
- ir->type = opR4;
- break;
- }
- default:
- {
- RaiseExecutionEngineException("Add_bin_op R4 op unknown");
- resultType = (EvalStackReduceDataType)-1;
- break;
- }
- }
- break;
- }
- case EvalStackReduceDataType::R8:
- {
- switch (op2.reduceType)
- {
- case EvalStackReduceDataType::R8:
- {
- resultType = EvalStackReduceDataType::R8;
- ir->type = opR8;
- break;
- }
- default:
- {
- RaiseExecutionEngineException("Add_bin_op R8 op unknown");
- resultType = (EvalStackReduceDataType)-1;
- break;
- }
- }
- break;
- }
- default:
- {
- RaiseExecutionEngineException("Add_bin_op unknown");
- resultType = (EvalStackReduceDataType)-1;
- break;
- }
- }
- PopStack();
- op1.reduceType = resultType;
- op1.byteSize = GetSizeByReduceType(resultType);
- AddInst(ir);
- ip++;
- }
- void TransformContext::Add_shiftop(HiOpcodeEnum opI4I4, HiOpcodeEnum opI4I8, HiOpcodeEnum opI8I4, HiOpcodeEnum opI8I8)
- {
- IL2CPP_ASSERT(evalStackTop >= 2);
- EvalStackVarInfo& op1 = evalStack[evalStackTop - 2];
- EvalStackVarInfo& op2 = evalStack[evalStackTop - 1];
- CreateAddIR(ir, BitShiftBinOpVarVarVar_Shr_i4_i4);
- ir->ret = op1.locOffset;
- ir->value = op1.locOffset;
- ir->shiftAmount = op2.locOffset;
- switch (op1.reduceType)
- {
- case EvalStackReduceDataType::I4:
- {
- switch (op2.reduceType)
- {
- case EvalStackReduceDataType::I4:
- {
- ir->type = opI4I4;
- break;
- }
- case EvalStackReduceDataType::I8:
- {
- ir->type = opI4I8;
- break;
- }
- default:
- {
- RaiseExecutionEngineException("shitf i4");
- }
- }
- break;
- }
- case EvalStackReduceDataType::I8:
- {
- switch (op2.reduceType)
- {
- case EvalStackReduceDataType::I4:
- {
- ir->type = opI8I4;
- break;
- }
- case EvalStackReduceDataType::I8:
- {
- ir->type = opI8I8;
- break;
- }
- default:
- {
- RaiseExecutionEngineException("shitf i8");
- break;
- }
- }
- break;
- }
- default:
- {
- RaiseExecutionEngineException("shitf i");
- break;
- }
- }
- PopStack();
- ip++;
- }
- void TransformContext::Add_compare(HiOpcodeEnum opI4, HiOpcodeEnum opI8, HiOpcodeEnum opR4, HiOpcodeEnum opR8)
- {
- IL2CPP_ASSERT(evalStackTop >= 2);
- EvalStackVarInfo& op1 = evalStack[evalStackTop - 2];
- EvalStackVarInfo& op2 = evalStack[evalStackTop - 1];
- CreateIR(ir, CompOpVarVarVar_Ceq_i4);
- ir->c1 = op1.locOffset;
- ir->c2 = op2.locOffset;
- ir->ret = op1.locOffset;
- switch (op1.reduceType)
- {
- case EvalStackReduceDataType::I4:
- {
- switch (op2.reduceType)
- {
- case EvalStackReduceDataType::I4:
- {
- ir->type = opI4;
- break;
- }
- case EvalStackReduceDataType::I8:
- {
- CreateAddIR(irConv, ConvertVarVar_i4_i8);
- irConv->dst = irConv->src = op1.locOffset;
- ir->type = opI8;
- break;
- }
- default:
- {
- RaiseExecutionEngineException("compare i4");
- break;
- }
- }
- break;
- }
- case EvalStackReduceDataType::I8:
- {
- switch (op2.reduceType)
- {
- case EvalStackReduceDataType::I4:
- {
- CreateAddIR(irConv, ConvertVarVar_i4_i8);
- irConv->dst = irConv->src = op2.locOffset;
- ir->type = opI8;
- break;
- }
- case EvalStackReduceDataType::I8:
- {
- ir->type = opI8;
- break;
- }
- default:
- {
- RaiseExecutionEngineException("compare i8");
- break;
- }
- }
- break;
- }
- case EvalStackReduceDataType::R4:
- {
- if (op2.reduceType == EvalStackReduceDataType::R4)
- {
- ir->type = opR4;
- }
- else
- {
- RaiseExecutionEngineException("compare r4");
- }
- break;
- }
- case EvalStackReduceDataType::R8:
- {
- if (op2.reduceType == EvalStackReduceDataType::R8)
- {
- ir->type = opR8;
- }
- else
- {
- RaiseExecutionEngineException("compare r8");
- }
- break;
- }
- default:
- {
- RaiseExecutionEngineException("compare");
- break;
- }
- }
- PopStackN(2);
- AddInst(ir);
- PushStackByReduceType(EvalStackReduceDataType::I4);
- }
- void TransformContext::Add_ldelem(EvalStackReduceDataType resultType, HiOpcodeEnum opI4)
- {
- IL2CPP_ASSERT(evalStackTop >= 2);
- EvalStackVarInfo& arr = evalStack[evalStackTop - 2];
- EvalStackVarInfo& index = evalStack[evalStackTop - 1];
- CreateAddIR(ir, GetArrayElementVarVar_i1);
- ir->type = opI4;
- ir->arr = arr.locOffset;
- ir->index = index.locOffset;
- ir->dst = arr.locOffset;
- PopStackN(2);
- PushStackByReduceType(resultType);
- ip++;
- }
- void TransformContext::Add_stelem(HiOpcodeEnum opI4)
- {
- IL2CPP_ASSERT(evalStackTop >= 3);
- EvalStackVarInfo& arr = evalStack[evalStackTop - 3];
- EvalStackVarInfo& index = evalStack[evalStackTop - 2];
- EvalStackVarInfo& ele = evalStack[evalStackTop - 1];
- CreateAddIR(ir, SetArrayElementVarVar_i1);
- ir->type = opI4;
- ir->arr = arr.locOffset;
- ir->index = index.locOffset;
- ir->ele = ele.locOffset;
- PopStackN(3);
- ip++;
- }
- bool TransformContext::FindFirstLeaveHandlerIndex(const std::vector<ExceptionClause>& exceptionClauses, uint32_t leaveOffset, uint32_t targetOffset, uint16_t& index)
- {
- index = 0;
- for (const ExceptionClause& ec : exceptionClauses)
- {
- if (ec.flags == CorILExceptionClauseType::Finally)
- {
- if (ec.tryOffset <= leaveOffset && leaveOffset < ec.tryOffset + ec.tryLength)
- return !(ec.tryOffset <= targetOffset && targetOffset < ec.tryOffset + ec.tryLength);
- }
- ++index;
- }
- return false;
- }
- bool TransformContext::IsLeaveInTryBlock(const std::vector<ExceptionClause>& exceptionClauses, uint32_t leaveOffset)
- {
- for (const ExceptionClause& ec : exceptionClauses)
- {
- if (ec.tryOffset <= leaveOffset && leaveOffset < ec.tryOffset + ec.tryLength)
- {
- return true;
- }
- if (ec.handlerOffsets <= leaveOffset && leaveOffset < ec.handlerOffsets + ec.handlerLength)
- {
- return false;
- }
- }
- return false;
- }
- void TransformContext::Add_leave(uint32_t targetOffset)
- {
- uint32_t leaveOffset = (uint32_t)(ip - ipBase);
- uint16_t firstHandlerIndex;
- if (FindFirstLeaveHandlerIndex(body.exceptionClauses, leaveOffset, targetOffset, firstHandlerIndex))
- {
- CreateAddIR(ir, LeaveEx);
- ir->target = targetOffset;
- ir->firstHandlerIndex = firstHandlerIndex;
- PushOffset(&ir->target);
- }
- else if (!IsLeaveInTryBlock(body.exceptionClauses, leaveOffset))
- {
- CreateAddIR(ir, LeaveEx_Directly);
- ir->target = targetOffset;
- PushOffset(&ir->target);
- }
- else
- {
- CreateAddIR(ir, BranchUncondition_4);
- ir->offset = targetOffset;
- PushOffset(&ir->offset);
- }
- PopAllStack();
- PushBranch(targetOffset);
- }
- uint16_t TransformContext::FindFirstThrowHandlerIndex(const std::vector<ExceptionClause>& exceptionClauses, uint32_t throwOffset)
- {
- uint16_t index = 0;
- for (const ExceptionClause& ec : exceptionClauses)
- {
- if (ec.flags == CorILExceptionClauseType::Finally || ec.flags == CorILExceptionClauseType::Exception || ec.flags == CorILExceptionClauseType::Filter)
- {
- if (ec.tryOffset <= throwOffset && throwOffset < ec.tryOffset + ec.tryLength)
- return index;
- }
- ++index;
- }
- return index;
- }
- inline const Il2CppType* InflateIfNeeded(const Il2CppType* type, const Il2CppGenericContext* context, bool inflateMethodVars)
- {
- if (context == nullptr)
- {
- return type;
- }
- else
- {
- // FIXME memory leak
- return il2cpp::metadata::GenericMetadata::InflateIfNeeded(type, context, inflateMethodVars);
- }
- }
- #pragma region conv
- #define CI_conv(dstTypeName, dstReduceType, dstTypeSize) \
- Add_conv(dstTypeSize, EvalStackReduceDataType::dstReduceType, \
- HiOpcodeEnum::ConvertVarVar_i4_##dstTypeName,\
- HiOpcodeEnum::ConvertVarVar_i8_##dstTypeName,\
- HiOpcodeEnum::ConvertVarVar_f4_##dstTypeName,\
- HiOpcodeEnum::ConvertVarVar_f8_##dstTypeName);
- #define CI_conv_un(dstTypeName, dstReduceType, dstTypeSize) \
- Add_conv(dstTypeSize, EvalStackReduceDataType::dstReduceType, \
- HiOpcodeEnum::ConvertVarVar_u4_##dstTypeName,\
- HiOpcodeEnum::ConvertVarVar_u8_##dstTypeName,\
- HiOpcodeEnum::ConvertVarVar_f4_##dstTypeName,\
- HiOpcodeEnum::ConvertVarVar_f8_##dstTypeName);
- #define CI_conv_ovf(dstTypeName, dstReduceType, dstTypeSize) \
- Add_conv_ovf(dstTypeSize, EvalStackReduceDataType::dstReduceType, \
- HiOpcodeEnum::ConvertOverflowVarVar_i4_##dstTypeName,\
- HiOpcodeEnum::ConvertOverflowVarVar_i8_##dstTypeName,\
- HiOpcodeEnum::ConvertOverflowVarVar_f4_##dstTypeName,\
- HiOpcodeEnum::ConvertOverflowVarVar_f8_##dstTypeName);
- #define CI_conv_un_ovf(dstTypeName, dstReduceType, dstTypeSize) \
- Add_conv_ovf(dstTypeSize, EvalStackReduceDataType::dstReduceType, \
- HiOpcodeEnum::ConvertOverflowVarVar_u4_##dstTypeName,\
- HiOpcodeEnum::ConvertOverflowVarVar_u8_##dstTypeName,\
- HiOpcodeEnum::ConvertOverflowVarVar_f4_##dstTypeName,\
- HiOpcodeEnum::ConvertOverflowVarVar_f8_##dstTypeName);
- #pragma endregion
- #pragma region branch
- #define CI_branch1(opName) IL2CPP_ASSERT(evalStackTop >= 2); \
- brOffset = GetI1(ip+1); \
- if (brOffset != 0) \
- {\
- Add_bc(ipOffset, brOffset, 2, HiOpcodeEnum::BranchVarVar_##opName##_i4, HiOpcodeEnum::BranchVarVar_##opName##_i8, HiOpcodeEnum::BranchVarVar_##opName##_f4, HiOpcodeEnum::BranchVarVar_##opName##_f8); \
- }\
- else\
- {\
- PopStackN(2);\
- }\
- ip += 2;
- #define CI_branch4(opName) IL2CPP_ASSERT(evalStackTop >= 2); \
- brOffset = GetI4LittleEndian(ip + 1); \
- if (brOffset != 0) \
- { \
- Add_bc(ipOffset, brOffset, 5, HiOpcodeEnum::BranchVarVar_##opName##_i4, HiOpcodeEnum::BranchVarVar_##opName##_i8, HiOpcodeEnum::BranchVarVar_##opName##_f4, HiOpcodeEnum::BranchVarVar_##opName##_f8); \
- }\
- else \
- {\
- PopStackN(2);\
- }\
- ip += 5;
- #define PopBranch() { \
- if (FindNextFlow()) \
- { \
- continue; \
- } \
- else \
- { \
- goto finish_transform; \
- } \
- }
- #pragma endregion
- #pragma region binop
- #define CI_binOp(op) Add_binop(HiOpcodeEnum::BinOpVarVarVar_##op##_i4, HiOpcodeEnum::BinOpVarVarVar_##op##_i8, HiOpcodeEnum::BinOpVarVarVar_##op##_f4, HiOpcodeEnum::BinOpVarVarVar_##op##_f8);
- #define CI_binOpUn(op) Add_binop(HiOpcodeEnum::BinOpVarVarVar_##op##_i4, HiOpcodeEnum::BinOpVarVarVar_##op##_i8, (HiOpcodeEnum)0, (HiOpcodeEnum)0);
- #define CI_binOpOvf(op) Add_binop(HiOpcodeEnum::BinOpOverflowVarVarVar_##op##_i4, HiOpcodeEnum::BinOpOverflowVarVarVar_##op##_i8, (HiOpcodeEnum)0, (HiOpcodeEnum)0);
- #define CI_binOpUnOvf(op) Add_binop(HiOpcodeEnum::BinOpOverflowVarVarVar_##op##_u4, HiOpcodeEnum::BinOpOverflowVarVarVar_##op##_u8, (HiOpcodeEnum)0, (HiOpcodeEnum)0);
- #pragma endregion
- #pragma region shiftop
- #define CI_binOpShift(op) Add_shiftop(HiOpcodeEnum::BitShiftBinOpVarVarVar_##op##_i4_i4, HiOpcodeEnum::BitShiftBinOpVarVarVar_##op##_i4_i8, HiOpcodeEnum::BitShiftBinOpVarVarVar_##op##_i8_i4, HiOpcodeEnum::BitShiftBinOpVarVarVar_##op##_i8_i8);
- #pragma endregion
- #define CI_compare(op) Add_compare(HiOpcodeEnum::CompOpVarVarVar_##op##_i4, HiOpcodeEnum::CompOpVarVarVar_##op##_i8, HiOpcodeEnum::CompOpVarVarVar_##op##_f4, HiOpcodeEnum::CompOpVarVarVar_##op##_f8);
- #define CI_ldele(eleType, resultType) Add_ldelem(EvalStackReduceDataType::resultType, HiOpcodeEnum::GetArrayElementVarVar_##eleType);
- #define CI_stele(eleType) Add_stelem(HiOpcodeEnum::SetArrayElementVarVar_##eleType);
- static const MethodInfo* FindRedirectCreateString(const MethodInfo* shareMethod)
- {
- int32_t paramCount = shareMethod->parameters_count;
- void* iter = nullptr;
- for (const MethodInfo* searchMethod; (searchMethod = il2cpp::vm::Class::GetMethods(il2cpp_defaults.string_class, &iter)) != nullptr;)
- {
- if (searchMethod->parameters_count != paramCount || std::strcmp(searchMethod->name, "CreateString"))
- {
- continue;
- }
- bool sigMatch = true;
- for (uint8_t i = 0; i < paramCount; i++)
- {
- if (!IsTypeEqual(GET_METHOD_PARAMETER_TYPE(searchMethod->parameters[i]), GET_METHOD_PARAMETER_TYPE(shareMethod->parameters[i])))
- {
- sigMatch = false;
- break;
- }
- }
- if (sigMatch)
- {
- return searchMethod;
- }
- }
- return nullptr;
- }
- static bool ShouldBeInlined(const MethodInfo* method, int32_t depth)
- {
- if (depth >= RuntimeConfig::GetMaxMethodInlineDepth())
- {
- return false;
- }
- return metadata::MethodBodyCache::IsInlineable(method);
- }
- void TransformContext::TransformBody(int32_t depth, int32_t localVarOffset, interpreter::InterpMethodInfo& result)
- {
- TransformBodyImpl(depth, localVarOffset);
- BuildInterpMethodInfo(result);
- }
- void TransformContext::TransformBodyImpl(int32_t depth, int32_t localVarOffset)
- {
- #pragma region header
- const Il2CppGenericContext* genericContext = methodInfo->is_inflated ? &methodInfo->genericMethod->context : nullptr;
- const Il2CppGenericContainer* klassContainer = GetGenericContainerFromIl2CppType(&methodInfo->klass->byval_arg);
- const Il2CppGenericContainer* methodContainer = methodInfo->is_inflated ?
- (const Il2CppGenericContainer*)methodInfo->genericMethod->methodDefinition->genericContainerHandle :
- (const Il2CppGenericContainer*)methodInfo->genericContainerHandle;
- BasicBlockSpliter bbc(body);
- bbc.SplitBasicBlocks();
- splitOffsets = bbc.GetSplitOffsets();
- ip2bb = pool.NewNAny<IRBasicBlock*>(body.codeSize + 1);
- uint32_t lastSplitBegin = 0;
- for (uint32_t offset : splitOffsets)
- {
- IRBasicBlock* bb = pool.NewAny<IRBasicBlock>();
- bb->visited = false;
- bb->ilOffset = lastSplitBegin;
- irbbs.push_back(bb);
- for (uint32_t idx = lastSplitBegin; idx < offset; idx++)
- {
- ip2bb[idx] = bb;
- }
- lastSplitBegin = offset;
- }
- IRBasicBlock* endBb = pool.NewAny<IRBasicBlock>();
- *endBb = { true, false, body.codeSize, 0 };
- ip2bb[body.codeSize] = endBb;
- curbb = irbbs[0];
- IL2CPP_ASSERT(lastSplitBegin == body.codeSize);
- bool instanceCall = IsInstanceMethod(methodInfo);
- actualParamCount = methodInfo->parameters_count + instanceCall;
- args = pool.NewNAny<ArgVarInfo>(actualParamCount);
- locals = pool.NewNAny<LocVarInfo>((int)body.localVars.size());
- evalStack = pool.NewNAny<EvalStackVarInfo>(body.maxStack + 100);
- nextFlowIdx = 0;
- totalArgSize = 0;
- {
- int32_t idx = 0;
- if (instanceCall)
- {
- ArgVarInfo& self = args[0];
- self.klass = methodInfo->klass;
- self.type = IS_CLASS_VALUE_TYPE(self.klass) ? &self.klass->this_arg : &self.klass->byval_arg;
- self.argOffset = idx;
- self.argLocOffset = localVarOffset + totalArgSize;
- totalArgSize += GetTypeValueStackObjectCount(self.type);
- idx = 1;
- }
- for (uint32_t i = 0; i < methodInfo->parameters_count; i++)
- {
- ArgVarInfo& arg = args[idx + i];
- arg.type = InflateIfNeeded((Il2CppType*)(GET_METHOD_PARAMETER_TYPE(methodInfo->parameters[i])), genericContext, true);
- arg.klass = il2cpp::vm::Class::FromIl2CppType(arg.type);
- arg.argOffset = idx + i;
- arg.argLocOffset = localVarOffset + totalArgSize;
- il2cpp::vm::Class::SetupFields(arg.klass);
- totalArgSize += GetTypeValueStackObjectCount(arg.type);
- }
- }
- totalArgLocalSize = totalArgSize;
- for (size_t i = 0; i < body.localVars.size(); i++)
- {
- LocVarInfo& local = locals[i];
- // FIXME memory leak
- local.type = InflateIfNeeded(body.localVars[i], genericContext, true);
- local.klass = il2cpp::vm::Class::FromIl2CppType(local.type);
- il2cpp::vm::Class::SetupFields(local.klass);
- local.locOffset = localVarOffset + totalArgLocalSize;
- totalArgLocalSize += GetTypeValueStackObjectCount(local.type);
- }
- evalStackBaseOffset = localVarOffset + totalArgLocalSize;
- int32_t totalLocalSize = totalArgLocalSize - totalArgSize;
- maxStackSize = evalStackBaseOffset;
- curStackSize = evalStackBaseOffset;
- ipBase = body.ilcodes;
- ip = body.ilcodes;
- ipOffset = 0;
- evalStackTop = 0;
- prefixFlags = 0;
- int32_t argIdx = 0;
- int32_t varKst = 0;
- int64_t varKst8 = 0;
- int32_t brOffset = 0;
- shareMethod = nullptr;
- Token2RuntimeHandleMap tokenCache(64);
- bool inMethodInlining = depth > 0;
- hybridclr::metadata::PDBImage* pdbImage = image->GetPDBImage();
- ir2offsetMap = pdbImage && !inMethodInlining ? new IR2OffsetMap(body.codeSize) : nullptr;
- if (inMethodInlining)
- {
- if (instanceCall)
- {
- CreateAddIR(irCheckNull, CheckThrowIfNullVar);
- irCheckNull->obj = args[0].argLocOffset;
- }
- else
- {
- if (!IS_CCTOR_FINISH_OR_NO_CCTOR(methodInfo->klass))
- {
- CreateAddIR(irInitStaticCtor, InitClassStaticCtor);
- irInitStaticCtor->klass = (uint64_t)methodInfo->klass;
- }
- }
- }
- initLocals = (body.flags & (uint32_t)CorILMethodFormat::InitLocals) != 0;
- // init local vars
- if (initLocals && totalLocalSize > 0)
- {
- AddInst(CreateInitLocals(pool, totalLocalSize * sizeof(StackObject), locals[0].locOffset));
- }
- exClauses.resize_initialized(body.exceptionClauses.size());
- int clauseIdx = 0;
- for (ExceptionClause& ec : body.exceptionClauses)
- {
- InterpExceptionClause* iec = &exClauses[clauseIdx++];
- iec->flags = ec.flags;
- iec->tryBeginOffset = ec.tryOffset;
- iec->tryEndOffset = ec.tryOffset + ec.tryLength;
- iec->handlerBeginOffset = ec.handlerOffsets;
- iec->handlerEndOffset = ec.handlerOffsets + ec.handlerLength;
- PushOffset(&iec->tryBeginOffset);
- PushOffset(&iec->tryEndOffset);
- PushOffset(&iec->handlerBeginOffset);
- PushOffset(&iec->handlerEndOffset);
- if (ec.flags == CorILExceptionClauseType::Exception)
- {
- iec->filterBeginOffset = 0;
- iec->exKlass = image->GetClassFromToken(tokenCache, ec.classTokenOrFilterOffset, klassContainer, methodContainer, genericContext);
- }
- else if (ec.flags == CorILExceptionClauseType::Filter)
- {
- iec->filterBeginOffset = ec.classTokenOrFilterOffset;
- PushOffset(&iec->filterBeginOffset);
- iec->exKlass = nullptr;
- }
- else
- {
- IL2CPP_ASSERT(ec.classTokenOrFilterOffset == 0);
- iec->filterBeginOffset = 0;
- iec->exKlass = nullptr;
- }
- switch (ec.flags)
- {
- case CorILExceptionClauseType::Exception:
- {
- IRBasicBlock* bb = ip2bb[iec->handlerBeginOffset];
- IL2CPP_ASSERT(!bb->inPending);
- bb->inPending = true;
- FlowInfo* fi = pool.NewAny<FlowInfo>();
- fi->offset = ec.handlerOffsets;
- fi->curStackSize = evalStackBaseOffset + 1;
- fi->evalStack.push_back({ NATIVE_INT_REDUCE_TYPE, PTR_SIZE, evalStackBaseOffset });
- pendingFlows.push_back(fi);
- break;
- }
- case CorILExceptionClauseType::Filter:
- {
- IRBasicBlock* bb = ip2bb[iec->filterBeginOffset];
- IL2CPP_ASSERT(!bb->inPending);
- bb->inPending = true;
- {
- FlowInfo* fi = pool.NewAny<FlowInfo>();
- IL2CPP_ASSERT(ec.classTokenOrFilterOffset);
- fi->offset = ec.classTokenOrFilterOffset;
- fi->curStackSize = evalStackBaseOffset + 1;
- fi->evalStack.push_back({ NATIVE_INT_REDUCE_TYPE, PTR_SIZE, evalStackBaseOffset });
- pendingFlows.push_back(fi);
- }
- {
- FlowInfo* fi = pool.NewAny<FlowInfo>();
- IL2CPP_ASSERT(ec.handlerOffsets);
- fi->offset = ec.handlerOffsets;
- fi->curStackSize = evalStackBaseOffset + 1;
- fi->evalStack.push_back({ NATIVE_INT_REDUCE_TYPE, PTR_SIZE, evalStackBaseOffset });
- pendingFlows.push_back(fi);
- }
- break;
- }
- case CorILExceptionClauseType::Fault:
- case CorILExceptionClauseType::Finally:
- {
- IRBasicBlock* bb = ip2bb[iec->handlerBeginOffset];
- IL2CPP_ASSERT(!bb->inPending);
- bb->inPending = true;
- FlowInfo* fi = pool.NewAny<FlowInfo>();
- fi->offset = ec.handlerOffsets;
- fi->curStackSize = evalStackBaseOffset;
- pendingFlows.push_back(fi);
- break;
- }
- default:
- {
- RaiseExecutionEngineException("");
- }
- }
- }
- #pragma endregion
- IRBasicBlock* lastBb = nullptr;
- for (;;)
- {
- ipOffset = (uint32_t)(ip - ipBase);
- curbb = ip2bb[ipOffset];
- if (curbb != lastBb)
- {
- if (curbb && !curbb->visited)
- {
- curbb->visited = true;
- lastBb = curbb;
- }
- else
- {
- PopBranch();
- }
- }
- switch ((OpcodeValue)*ip)
- {
- case OpcodeValue::NOP:
- {
- ip++;
- continue;
- }
- case OpcodeValue::BREAK:
- {
- ip++;
- continue;
- }
- case OpcodeValue::LDARG_0:
- {
- AddInst_ldarg(0);
- ip++;
- continue;
- }
- case OpcodeValue::LDARG_1:
- {
- AddInst_ldarg(1);
- ip++;
- continue;
- }
- case OpcodeValue::LDARG_2:
- {
- AddInst_ldarg(2);
- ip++;
- continue;
- }
- case OpcodeValue::LDARG_3:
- {
- AddInst_ldarg(3);
- ip++;
- continue;
- }
- case OpcodeValue::LDLOC_0:
- {
- CreateAddInst_ldloc(0);
- ip++;
- continue;
- }
- case OpcodeValue::LDLOC_1:
- {
- CreateAddInst_ldloc(1);
- ip++;
- continue;
- }
- case OpcodeValue::LDLOC_2:
- {
- CreateAddInst_ldloc(2);
- ip++;
- continue;
- }
- case OpcodeValue::LDLOC_3:
- {
- CreateAddInst_ldloc(3);
- ip++;
- continue;
- }
- case OpcodeValue::STLOC_0:
- {
- CreateAddInst_stloc(0);
- ip++;
- continue;
- }
- case OpcodeValue::STLOC_1:
- {
- CreateAddInst_stloc(1);
- ip++;
- continue;
- }
- case OpcodeValue::STLOC_2:
- {
- CreateAddInst_stloc(2);
- ip++;
- continue;
- }
- case OpcodeValue::STLOC_3:
- {
- CreateAddInst_stloc(3);
- ip++;
- continue;
- }
- case OpcodeValue::LDARG_S:
- {
- argIdx = ip[1];
- AddInst_ldarg(argIdx);
- ip += 2;
- continue;
- }
- case OpcodeValue::LDARGA_S:
- {
- argIdx = ip[1];
- AddInst_ldarga(argIdx);
- ip += 2;
- continue;
- }
- case OpcodeValue::STARG_S:
- {
- argIdx = ip[1];
- AddInst_starg(argIdx);
- ip += 2;
- continue;
- }
- case OpcodeValue::LDLOC_S:
- {
- argIdx = ip[1];
- CreateAddInst_ldloc(argIdx);
- ip += 2;
- continue;
- }
- case OpcodeValue::LDLOCA_S:
- {
- argIdx = ip[1];
- CreateAddInst_ldloca(argIdx);
- ip += 2;
- continue;
- }
- case OpcodeValue::STLOC_S:
- {
- argIdx = ip[1];
- CreateAddInst_stloc(argIdx);
- ip += 2;
- continue;
- }
- case OpcodeValue::LDNULL:
- {
- CreateAddIR(ir, LdnullVar);
- ir->dst = curStackSize;
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- ip++;
- continue;
- }
- case OpcodeValue::LDC_I4_M1:
- {
- CreateAddInst_ldc4(-1, EvalStackReduceDataType::I4);
- ip++;
- continue;
- }
- case OpcodeValue::LDC_I4_0:
- {
- CreateAddInst_ldc4(0, EvalStackReduceDataType::I4);
- ip++;
- continue;
- }
- case OpcodeValue::LDC_I4_1:
- {
- CreateAddInst_ldc4(1, EvalStackReduceDataType::I4);
- ip++;
- continue;
- }
- case OpcodeValue::LDC_I4_2:
- {
- CreateAddInst_ldc4(2, EvalStackReduceDataType::I4);
- ip++;
- continue;
- }
- case OpcodeValue::LDC_I4_3:
- {
- CreateAddInst_ldc4(3, EvalStackReduceDataType::I4);
- ip++;
- continue;
- }
- case OpcodeValue::LDC_I4_4:
- {
- CreateAddInst_ldc4(4, EvalStackReduceDataType::I4);
- ip++;
- continue;
- }
- case OpcodeValue::LDC_I4_5:
- {
- CreateAddInst_ldc4(5, EvalStackReduceDataType::I4);
- ip++;
- continue;
- }
- case OpcodeValue::LDC_I4_6:
- {
- CreateAddInst_ldc4(6, EvalStackReduceDataType::I4);
- ip++;
- continue;
- }
- case OpcodeValue::LDC_I4_7:
- {
- CreateAddInst_ldc4(7, EvalStackReduceDataType::I4);
- ip++;
- continue;
- }
- case OpcodeValue::LDC_I4_8:
- {
- CreateAddInst_ldc4(8, EvalStackReduceDataType::I4);
- ip++;
- continue;
- }
- case OpcodeValue::LDC_I4_S:
- {
- varKst = GetI1(ip + 1);
- CreateAddInst_ldc4(varKst, EvalStackReduceDataType::I4);
- ip += 2;
- continue;
- }
- case OpcodeValue::LDC_I4:
- {
- varKst = GetI4LittleEndian(ip + 1);
- CreateAddInst_ldc4(varKst, EvalStackReduceDataType::I4);
- ip += 5;
- continue;
- }
- case OpcodeValue::LDC_I8:
- {
- varKst8 = GetI8LittleEndian(ip + 1);
- CreateAddInst_ldc8(varKst8, EvalStackReduceDataType::I8);
- ip += 9;
- continue;
- }
- case OpcodeValue::LDC_R4:
- {
- varKst = GetI4LittleEndian(ip + 1);
- CreateAddInst_ldc4(varKst, EvalStackReduceDataType::R4);
- ip += 5;
- continue;
- }
- case OpcodeValue::LDC_R8:
- {
- varKst8 = GetI8LittleEndian(ip + 1);
- CreateAddInst_ldc8(varKst8, EvalStackReduceDataType::R8);
- ip += 9;
- continue;
- }
- case OpcodeValue::DUP:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- EvalStackVarInfo& __eval = evalStack[evalStackTop - 1];
- IRCommon* ir = CreateAssignVarVar(pool, GetEvalStackNewTopOffset(), __eval.locOffset, __eval.byteSize);
- AddInst(ir);
- DuplicateStack();
- ip++;
- continue;
- }
- case OpcodeValue::POP:
- {
- PopStack();
- ip++;
- continue;
- }
- case OpcodeValue::JMP:
- {
- /* auto& x = ir.jump;
- x.type = IRType::Jmp;
- x.methodToken = GetI4LittleEndian(ip + 1);
- irs.push_back(ir);
- ip += 5;*/
- RaiseNotSupportedException("not support jmp");
- continue;
- }
- case OpcodeValue::CALL:
- {
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- ip += 5;
- shareMethod = const_cast<MethodInfo*>(image->GetMethodInfoFromToken(tokenCache, token, klassContainer, methodContainer, genericContext));
- IL2CPP_ASSERT(shareMethod);
- }
- LabelCall:
- {
- if (TryAddInstinctInstruments(shareMethod))
- {
- continue;
- }
- #if HYBRIDCLR_UNITY_2021_OR_NEW
- if (!shareMethod->has_full_generic_sharing_signature)
- #endif
- {
- if (!InitAndGetInterpreterDirectlyCallMethodPointer(shareMethod))
- {
- RaiseAOTGenericMethodNotInstantiatedException(shareMethod);
- }
- }
- bool resolvedIsInstanceMethod = IsInstanceMethod(shareMethod);
- int32_t resolvedTotalArgNum = shareMethod->parameters_count + resolvedIsInstanceMethod;
- int32_t needDataSlotNum = (resolvedTotalArgNum + 3) / 4;
- int32_t callArgEvalStackIdxBase = evalStackTop - resolvedTotalArgNum;
- uint32_t methodDataIndex = GetOrAddResolveDataIndex(shareMethod);
- if (hybridclr::metadata::IsInterpreterImplement(shareMethod))
- {
- uint16_t argBaseOffset = (uint16_t)GetEvalStackOffset(callArgEvalStackIdxBase);
- if (ShouldBeInlined(shareMethod, depth) && TransformSubMethodBody(*this, shareMethod, depth + 1, argBaseOffset))
- {
- }
- else
- {
- if (IsReturnVoidMethod(shareMethod))
- {
- CreateAddIR(ir, CallInterp_void);
- ir->methodInfo = methodDataIndex;
- ir->argBase = argBaseOffset;
- }
- else
- {
- CreateAddIR(ir, CallInterp_ret);
- ir->methodInfo = methodDataIndex;
- ir->argBase = argBaseOffset;
- ir->ret = argBaseOffset;
- }
- }
- PopStackN(resolvedTotalArgNum);
- if (!IsReturnVoidMethod(shareMethod))
- {
- PushStackByType(shareMethod->return_type);
- }
- continue;
- }
- #if HYBRIDCLR_UNITY_2021_OR_NEW
- if (!shareMethod->has_full_generic_sharing_signature)
- #endif
- {
- if (TryAddCallCommonInstruments(shareMethod, methodDataIndex))
- {
- continue;
- }
- }
- Managed2NativeCallMethod managed2NativeMethod = InterpreterModule::GetManaged2NativeMethodPointer(shareMethod, false);
- IL2CPP_ASSERT(managed2NativeMethod);
- uint32_t managed2NativeMethodDataIdx = GetOrAddResolveDataIndex((void*)managed2NativeMethod);
- int32_t argIdxDataIndex;
- uint16_t* __argIdxs;
- AllocResolvedData(resolveDatas, needDataSlotNum, argIdxDataIndex, __argIdxs);
- if (resolvedIsInstanceMethod)
- {
- __argIdxs[0] = GetEvalStackOffset(callArgEvalStackIdxBase);
- }
- for (uint8_t i = 0; i < shareMethod->parameters_count; i++)
- {
- int32_t curArgIdx = i + resolvedIsInstanceMethod;
- __argIdxs[curArgIdx] = evalStack[callArgEvalStackIdxBase + curArgIdx].locOffset;
- }
- PopStackN(resolvedTotalArgNum);
- if (!IsReturnVoidMethod(shareMethod))
- {
- PushStackByType(shareMethod->return_type);
- interpreter::LocationDataType locDataType = GetLocationDataTypeByType(shareMethod->return_type);
- if (interpreter::IsNeedExpandLocationType(locDataType))
- {
- CreateAddIR(ir, CallNativeInstance_ret_expand);
- ir->type = resolvedIsInstanceMethod ? HiOpcodeEnum::CallNativeInstance_ret_expand : HiOpcodeEnum::CallNativeStatic_ret_expand;
- ir->managed2NativeMethod = managed2NativeMethodDataIdx;
- ir->methodInfo = methodDataIndex;
- ir->argIdxs = argIdxDataIndex;
- ir->ret = GetEvalStackTopOffset();
- ir->retLocationType = (uint8_t)locDataType;
- }
- else
- {
- CreateAddIR(ir, CallNativeInstance_ret);
- ir->type = resolvedIsInstanceMethod ? HiOpcodeEnum::CallNativeInstance_ret : HiOpcodeEnum::CallNativeStatic_ret;
- ir->managed2NativeMethod = managed2NativeMethodDataIdx;
- ir->methodInfo = methodDataIndex;
- ir->argIdxs = argIdxDataIndex;
- ir->ret = GetEvalStackTopOffset();
- }
- }
- else
- {
- CreateAddIR(ir, CallNativeInstance_void);
- ir->type = resolvedIsInstanceMethod ? HiOpcodeEnum::CallNativeInstance_void : HiOpcodeEnum::CallNativeStatic_void;
- ir->managed2NativeMethod = managed2NativeMethodDataIdx;
- ir->methodInfo = methodDataIndex;
- ir->argIdxs = argIdxDataIndex;
- }
- continue;
- }
- case OpcodeValue::CALLVIRT:
- {
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- ip += 5;
- shareMethod = image->GetMethodInfoFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- }
- LabelCallVir:
- {
- IL2CPP_ASSERT(shareMethod);
- IL2CPP_ASSERT(hybridclr::metadata::IsInstanceMethod(shareMethod));
- if ((!metadata::IsVirtualMethod(shareMethod->flags)) || metadata::IsSealed(shareMethod->flags))
- {
- goto LabelCall;
- }
- int32_t resolvedTotalArgNum = shareMethod->parameters_count + 1;
- int32_t callArgEvalStackIdxBase = evalStackTop - resolvedTotalArgNum;
- uint32_t methodDataIndex = GetOrAddResolveDataIndex(shareMethod);
- bool isMultiDelegate = IsChildTypeOfMulticastDelegate(shareMethod->klass);
- if (!isMultiDelegate && IsInterpreterMethod(shareMethod) && !IsInterface(shareMethod->klass->flags))
- {
- PopStackN(resolvedTotalArgNum);
- uint16_t argBaseOffset = (uint16_t)GetEvalStackOffset(callArgEvalStackIdxBase);
- if (IsReturnVoidMethod(shareMethod))
- {
- CreateAddIR(ir, CallInterpVirtual_void);
- ir->method = methodDataIndex;
- ir->argBase = argBaseOffset;
- }
- else
- {
- CreateAddIR(ir, CallInterpVirtual_ret);
- ir->method = methodDataIndex;
- ir->argBase = argBaseOffset;
- ir->ret = argBaseOffset;
- PushStackByType(shareMethod->return_type);
- }
- continue;
- }
- Managed2NativeCallMethod managed2NativeMethod = InterpreterModule::GetManaged2NativeMethodPointer(shareMethod, false);
- IL2CPP_ASSERT(managed2NativeMethod);
- uint32_t managed2NativeMethodDataIdx = GetOrAddResolveDataIndex((void*)managed2NativeMethod);
- int32_t needDataSlotNum = (resolvedTotalArgNum + 3) / 4;
- int32_t argIdxDataIndex;
- uint16_t* __argIdxs;
- AllocResolvedData(resolveDatas, needDataSlotNum, argIdxDataIndex, __argIdxs);
- __argIdxs[0] = GetEvalStackOffset(callArgEvalStackIdxBase);
- for (uint8_t i = 0; i < shareMethod->parameters_count; i++)
- {
- int32_t curArgIdx = i + 1;
- __argIdxs[curArgIdx] = evalStack[callArgEvalStackIdxBase + curArgIdx].locOffset;
- }
- PopStackN(resolvedTotalArgNum);
- const Il2CppType* returnType = shareMethod->return_type;
- int32_t retIdx;
- if (returnType->type != IL2CPP_TYPE_VOID)
- {
- PushStackByType(returnType);
- retIdx = GetEvalStackTopOffset();
- }
- else
- {
- retIdx = -1;
- }
- if (isMultiDelegate)
- {
- if (std::strcmp(shareMethod->name, "Invoke") == 0)
- {
- Managed2NativeCallMethod staticManaged2NativeMethod = InterpreterModule::GetManaged2NativeMethodPointer(shareMethod, true);
- IL2CPP_ASSERT(staticManaged2NativeMethod);
- uint32_t staticManaged2NativeMethodDataIdx = GetOrAddResolveDataIndex((void*)staticManaged2NativeMethod);
- if (retIdx < 0)
- {
- CreateAddIR(ir, CallDelegateInvoke_void);
- ir->managed2NativeStaticMethod = staticManaged2NativeMethodDataIdx;
- ir->managed2NativeInstanceMethod = managed2NativeMethodDataIdx;
- ir->argIdxs = argIdxDataIndex;
- ir->invokeParamCount = shareMethod->parameters_count;
- }
- else
- {
- interpreter::TypeDesc retDesc = GetTypeArgDesc(returnType);
- if (IsNeedExpandLocationType(retDesc.type))
- {
- CreateAddIR(ir, CallDelegateInvoke_ret_expand);
- ir->managed2NativeStaticMethod = staticManaged2NativeMethodDataIdx;
- ir->managed2NativeInstanceMethod = managed2NativeMethodDataIdx;
- ir->argIdxs = argIdxDataIndex;
- ir->ret = retIdx;
- ir->invokeParamCount = shareMethod->parameters_count;
- ir->retLocationType = (uint8_t)retDesc.type;
- }
- else
- {
- CreateAddIR(ir, CallDelegateInvoke_ret);
- ir->managed2NativeStaticMethod = staticManaged2NativeMethodDataIdx;
- ir->managed2NativeInstanceMethod = managed2NativeMethodDataIdx;
- ir->argIdxs = argIdxDataIndex;
- ir->ret = retIdx;
- ir->retTypeStackObjectSize = retDesc.stackObjectSize;
- ir->invokeParamCount = shareMethod->parameters_count;
- }
- }
- continue;
- }
- Il2CppMethodPointer directlyCallMethodPointer = InitAndGetInterpreterDirectlyCallMethodPointer(shareMethod);
- if (std::strcmp(shareMethod->name, "BeginInvoke") == 0)
- {
- if (IsInterpreterMethod(shareMethod) || directlyCallMethodPointer == nullptr)
- {
- CreateAddIR(ir, CallDelegateBeginInvoke);
- ir->methodInfo = methodDataIndex;
- ir->result = retIdx;
- ir->argIdxs = argIdxDataIndex;
- continue;
- }
- }
- else if (std::strcmp(shareMethod->name, "EndInvoke") == 0)
- {
- if (IsInterpreterMethod(shareMethod) || directlyCallMethodPointer == nullptr)
- {
- if (retIdx < 0)
- {
- CreateAddIR(ir, CallDelegateEndInvoke_void);
- ir->methodInfo = methodDataIndex;
- ir->asyncResult = __argIdxs[1];
- }
- else
- {
- CreateAddIR(ir, CallDelegateEndInvoke_ret);
- ir->methodInfo = methodDataIndex;
- ir->asyncResult = __argIdxs[1];
- ir->ret = retIdx;
- }
- continue;
- }
- }
- }
- if (retIdx < 0)
- {
- CreateAddIR(ir, CallVirtual_void);
- ir->managed2NativeMethod = managed2NativeMethodDataIdx;
- ir->methodInfo = methodDataIndex;
- ir->argIdxs = argIdxDataIndex;
- }
- else
- {
- interpreter::LocationDataType locDataType = GetLocationDataTypeByType(returnType);
- if (IsNeedExpandLocationType(locDataType))
- {
- CreateAddIR(ir, CallVirtual_ret_expand);
- ir->managed2NativeMethod = managed2NativeMethodDataIdx;
- ir->methodInfo = methodDataIndex;
- ir->argIdxs = argIdxDataIndex;
- ir->ret = retIdx;
- ir->retLocationType = (uint8_t)locDataType;
- }
- else
- {
- CreateAddIR(ir, CallVirtual_ret);
- ir->managed2NativeMethod = managed2NativeMethodDataIdx;
- ir->methodInfo = methodDataIndex;
- ir->argIdxs = argIdxDataIndex;
- ir->ret = retIdx;
- }
- }
- continue;
- }
- case OpcodeValue::CALLI:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- ResolveStandAloneMethodSig methodSig;
- image->GetStandAloneMethodSigFromToken(token, klassContainer, methodContainer, genericContext, methodSig);
- if (IsPrologExplicitThis(methodSig.flags))
- {
- RaiseNotSupportedException("not support StandAloneMethodSig flags:EXPLICITTHIS");
- }
- int32_t methodIdx = GetEvalStackTopOffset();
- //uint32_t methodDataIndex = GetOrAddResolveDataIndex(shareMethod);
- Managed2NativeCallMethod managed2NativeMethod = InterpreterModule::GetManaged2NativeMethodPointer(methodSig);
- IL2CPP_ASSERT(managed2NativeMethod);
- uint32_t managed2NativeMethodDataIdx = GetOrAddResolveDataIndex((void*)managed2NativeMethod);
- bool hasThis = metadata::IsPrologHasThis(methodSig.flags);
- int32_t resolvedTotalArgNum = (int32_t)methodSig.params.size() + hasThis;
- int32_t needDataSlotNum = (resolvedTotalArgNum + 3) / 4;
- int32_t argIdxDataIndex;
- uint16_t* __argIdxs;
- // we need at least one slot for argBasePtr when resolvedTotalArgNum == 0
- AllocResolvedData(resolveDatas, std::max(needDataSlotNum, 1), argIdxDataIndex, __argIdxs);
- int32_t callArgEvalStackIdxBase = evalStackTop - resolvedTotalArgNum - 1 /*funtion ptr*/;
- // CallInd need know the argBasePtr when resolvedTotalArgNum == 0
- if (needDataSlotNum == 0)
- {
- __argIdxs[0] = evalStack[callArgEvalStackIdxBase].locOffset;
- }
- if (hasThis)
- {
- __argIdxs[0] = evalStack[callArgEvalStackIdxBase].locOffset;
- }
- for (size_t i = 0; i < methodSig.params.size(); i++)
- {
- size_t curArgIdx = i + hasThis;
- __argIdxs[curArgIdx] = evalStack[callArgEvalStackIdxBase + curArgIdx].locOffset;
- }
- PopStackN(resolvedTotalArgNum + 1);
- if (!IsVoidType(methodSig.returnType))
- {
- PushStackByType(methodSig.returnType);
- interpreter::LocationDataType locDataType = GetLocationDataTypeByType(methodSig.returnType);
- if (interpreter::IsNeedExpandLocationType(locDataType))
- {
- CreateAddIR(ir, CallInd_ret_expand);
- ir->managed2NativeMethod = managed2NativeMethodDataIdx;
- ir->methodInfo = methodIdx;
- ir->argIdxs = argIdxDataIndex;
- ir->ret = GetEvalStackTopOffset();
- ir->retLocationType = (uint8_t)locDataType;
- }
- else
- {
- CreateAddIR(ir, CallInd_ret);
- ir->managed2NativeMethod = managed2NativeMethodDataIdx;
- ir->methodInfo = methodIdx;
- ir->argIdxs = argIdxDataIndex;
- ir->ret = GetEvalStackTopOffset();
- }
- }
- else
- {
- CreateAddIR(ir, CallInd_void);
- ir->managed2NativeMethod = managed2NativeMethodDataIdx;
- ir->methodInfo = methodIdx;
- ir->argIdxs = argIdxDataIndex;
- }
- ip += 5;
- continue;
- }
- case OpcodeValue::RET:
- {
- bool isVoidReturnType = methodInfo->return_type->type == IL2CPP_TYPE_VOID;
- if (inMethodInlining)
- {
- if (!isVoidReturnType)
- {
- uint16_t retVarIdx = GetEvalStackTopOffset();
- if (retVarIdx != localVarOffset)
- {
- IRCommon* ir = CreateAssignVarVar(pool, localVarOffset, retVarIdx, GetTypeValueSize(methodInfo->return_type));
- AddInst(ir);
- }
- }
- }
- else if (isVoidReturnType)
- {
- CreateAddIR(ir, RetVar_void);
- }
- else
- {
- // ms.ret = nullptr;
- IL2CPP_ASSERT(evalStackTop == 1);
- int32_t size = GetTypeValueSize(methodInfo->return_type);
- switch (size)
- {
- case 1:
- {
- CreateAddIR(ir, RetVar_ret_1);
- ir->ret = GetEvalStackTopOffset();
- break;
- }
- case 2:
- {
- CreateAddIR(ir, RetVar_ret_2);
- ir->ret = GetEvalStackTopOffset();
- break;
- }
- case 4:
- {
- CreateAddIR(ir, RetVar_ret_4);
- ir->ret = GetEvalStackTopOffset();
- break;
- }
- case 8:
- {
- CreateAddIR(ir, RetVar_ret_8);
- ir->ret = GetEvalStackTopOffset();
- break;
- }
- case 12:
- {
- CreateAddIR(ir, RetVar_ret_12);
- ir->ret = GetEvalStackTopOffset();
- break;
- }
- case 16:
- {
- CreateAddIR(ir, RetVar_ret_16);
- ir->ret = GetEvalStackTopOffset();
- break;
- }
- case 20:
- {
- CreateAddIR(ir, RetVar_ret_20);
- ir->ret = GetEvalStackTopOffset();
- break;
- }
- case 24:
- {
- CreateAddIR(ir, RetVar_ret_24);
- ir->ret = GetEvalStackTopOffset();
- break;
- }
- case 28:
- {
- CreateAddIR(ir, RetVar_ret_28);
- ir->ret = GetEvalStackTopOffset();
- break;
- }
- case 32:
- {
- CreateAddIR(ir, RetVar_ret_32);
- ir->ret = GetEvalStackTopOffset();
- break;
- }
- default:
- {
- CreateAddIR(ir, RetVar_ret_n);
- ir->ret = GetEvalStackTopOffset();
- ir->size = size;
- break;
- }
- }
- }
- ip++;
- PopBranch();
- continue;
- }
- case OpcodeValue::BR_S:
- {
- brOffset = GetI1(ip + 1);
- if (brOffset != 0)
- {
- int32_t targetOffset = ipOffset + brOffset + 2;
- CreateAddIR(ir, BranchUncondition_4);
- ir->offset = targetOffset;
- PushOffset(&ir->offset);
- PushBranch(targetOffset);
- PopBranch();
- }
- else
- {
- ip += 2;
- }
- continue;
- }
- case OpcodeValue::LEAVE_S:
- {
- brOffset = GetI1(ip + 1);
- int32_t targetOffset = ipOffset + brOffset + 2;
- Add_leave((uint32_t)targetOffset);
- PopBranch();
- continue;
- }
- case OpcodeValue::BRFALSE_S:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- brOffset = GetI1(ip + 1);
- if (brOffset != 0)
- {
- int32_t targetOffset = ipOffset + brOffset + 2;
- Add_brtruefalse(false, targetOffset);
- }
- else
- {
- PopStack();
- }
- ip += 2;
- continue;
- }
- case OpcodeValue::BRTRUE_S:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- brOffset = GetI1(ip + 1);
- if (brOffset != 0)
- {
- int32_t targetOffset = ipOffset + brOffset + 2;
- Add_brtruefalse(true, targetOffset);
- }
- else
- {
- PopStack();
- }
- ip += 2;
- continue;
- }
- case OpcodeValue::BEQ_S:
- {
- CI_branch1(Ceq);
- continue;
- }
- case OpcodeValue::BGE_S:
- {
- CI_branch1(Cge);
- continue;
- }
- case OpcodeValue::BGT_S:
- {
- CI_branch1(Cgt);
- continue;
- }
- case OpcodeValue::BLE_S:
- {
- CI_branch1(Cle);
- continue;
- }
- case OpcodeValue::BLT_S:
- {
- CI_branch1(Clt);
- continue;
- }
- case OpcodeValue::BNE_UN_S:
- {
- CI_branch1(CneUn);
- continue;
- }
- case OpcodeValue::BGE_UN_S:
- {
- CI_branch1(CgeUn);
- continue;
- }
- case OpcodeValue::BGT_UN_S:
- {
- CI_branch1(CgtUn);
- continue;
- }
- case OpcodeValue::BLE_UN_S:
- {
- CI_branch1(CleUn);
- continue;
- }
- case OpcodeValue::BLT_UN_S:
- {
- CI_branch1(CltUn);
- continue;
- }
- case OpcodeValue::BR:
- {
- brOffset = GetI4LittleEndian(ip + 1);
- if (brOffset != 0)
- {
- int32_t targetOffset = ipOffset + brOffset + 5;
- CreateAddIR(ir, BranchUncondition_4);
- ir->offset = targetOffset;
- PushOffset(&ir->offset);
- PushBranch(targetOffset);
- PopBranch();
- }
- else
- {
- ip += 5;
- }
- continue;
- }
- case OpcodeValue::LEAVE:
- {
- brOffset = GetI4LittleEndian(ip + 1);
- int32_t targetOffset = ipOffset + brOffset + 5;
- Add_leave((uint32_t)targetOffset);
- PopBranch();
- continue;
- }
- case OpcodeValue::BRFALSE:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- brOffset = GetI4LittleEndian(ip + 1);
- if (brOffset != 0)
- {
- int32_t targetOffset = ipOffset + brOffset + 5;
- Add_brtruefalse(false, targetOffset);
- }
- else
- {
- PopStack();
- }
- ip += 5;
- continue;
- }
- case OpcodeValue::BRTRUE:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- brOffset = GetI4LittleEndian(ip + 1);
- if (brOffset != 0)
- {
- int32_t targetOffset = ipOffset + brOffset + 5;
- Add_brtruefalse(true, targetOffset);
- }
- else
- {
- PopStack();
- }
- ip += 5;
- continue;
- }
- case OpcodeValue::BEQ:
- {
- CI_branch4(Ceq);
- continue;
- }
- case OpcodeValue::BGE:
- {
- CI_branch4(Cge);
- continue;
- }
- case OpcodeValue::BGT:
- {
- CI_branch4(Cgt);
- continue;
- }
- case OpcodeValue::BLE:
- {
- CI_branch4(Cle);
- continue;
- }
- case OpcodeValue::BLT:
- {
- CI_branch4(Clt);
- continue;
- }
- case OpcodeValue::BNE_UN:
- {
- CI_branch4(CneUn);
- continue;
- }
- case OpcodeValue::BGE_UN:
- {
- CI_branch4(CgeUn);
- continue;
- }
- case OpcodeValue::BGT_UN:
- {
- CI_branch4(CgtUn);
- continue;
- }
- case OpcodeValue::BLE_UN:
- {
- CI_branch4(CleUn);
- continue;
- }
- case OpcodeValue::BLT_UN:
- {
- CI_branch4(CltUn);
- continue;
- }
- case OpcodeValue::SWITCH:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- CreateIR(ir, BranchSwitch);
- uint32_t switchValue = GetEvalStackTopOffset();
- uint32_t n = (uint32_t)GetI4LittleEndian(ip + 1);
- ir->value = GetEvalStackTopOffset();
- ir->caseNum = n;
- int32_t* caseOffsets;
- AllocResolvedData(resolveDatas, (n + 1) / 2, *(int32_t*)&ir->caseOffsets, caseOffsets);
- PopStack();
- uint32_t instrSize = 1 + (n + 1) * 4;
- const byte* caseOffsetIp = ip + 5;
- // remove this instrument if all target is same to default.
- uint32_t nextInstrumentOffset = ipOffset + instrSize;
- bool anyNotDefaultCase = false;
- for (uint32_t caseIdx = 0; caseIdx < n; caseIdx++)
- {
- int32_t targetOffset = (int32_t)(nextInstrumentOffset + GetI4LittleEndian(caseOffsetIp + caseIdx * 4));
- caseOffsets[caseIdx] = targetOffset;
- //PushOffset(caseOffsets + caseIdx);
- if (targetOffset != nextInstrumentOffset)
- {
- anyNotDefaultCase = true;
- PushBranch(targetOffset);
- }
- }
- if (anyNotDefaultCase)
- {
- switchOffsetsInResolveData.push_back({ ir->caseOffsets, n });
- AddInst(ir);
- }
- ip += instrSize;
- continue;
- }
- case OpcodeValue::LDIND_I1:
- {
- Add_ldind(HiOpcodeEnum::LdindVarVar_i1, EvalStackReduceDataType::I4);
- continue;
- }
- case OpcodeValue::LDIND_U1:
- {
- Add_ldind(HiOpcodeEnum::LdindVarVar_u1, EvalStackReduceDataType::I4);
- continue;
- }
- case OpcodeValue::LDIND_I2:
- {
- Add_ldind(HiOpcodeEnum::LdindVarVar_i2, EvalStackReduceDataType::I4);
- continue;
- }
- case OpcodeValue::LDIND_U2:
- {
- Add_ldind(HiOpcodeEnum::LdindVarVar_u2, EvalStackReduceDataType::I4);
- continue;
- }
- case OpcodeValue::LDIND_I4:
- {
- Add_ldind(HiOpcodeEnum::LdindVarVar_i4, EvalStackReduceDataType::I4);
- continue;
- }
- case OpcodeValue::LDIND_U4:
- {
- Add_ldind(HiOpcodeEnum::LdindVarVar_u4, EvalStackReduceDataType::I4);
- continue;
- }
- case OpcodeValue::LDIND_I8:
- {
- Add_ldind(HiOpcodeEnum::LdindVarVar_i8, EvalStackReduceDataType::I8);
- continue;
- }
- case OpcodeValue::LDIND_I:
- {
- Add_ldind(ARCH_ARGUMENT(HiOpcodeEnum::LdindVarVar_i4, HiOpcodeEnum::LdindVarVar_i8), NATIVE_INT_REDUCE_TYPE);
- continue;
- }
- case OpcodeValue::LDIND_R4:
- {
- Add_ldind(HiOpcodeEnum::LdindVarVar_f4, EvalStackReduceDataType::R4);
- continue;
- }
- case OpcodeValue::LDIND_R8:
- {
- Add_ldind(HiOpcodeEnum::LdindVarVar_f8, EvalStackReduceDataType::R8);
- continue;
- }
- case OpcodeValue::LDIND_REF:
- {
- Add_ldind(ARCH_ARGUMENT(HiOpcodeEnum::LdindVarVar_i4, HiOpcodeEnum::LdindVarVar_i8), NATIVE_INT_REDUCE_TYPE);
- continue;
- }
- case OpcodeValue::STIND_REF:
- {
- Add_stind(HiOpcodeEnum::StindVarVar_ref);
- continue;
- }
- case OpcodeValue::STIND_I1:
- {
- Add_stind(HiOpcodeEnum::StindVarVar_i1);
- continue;
- }
- case OpcodeValue::STIND_I2:
- {
- Add_stind(HiOpcodeEnum::StindVarVar_i2);
- continue;
- }
- case OpcodeValue::STIND_I4:
- {
- Add_stind(HiOpcodeEnum::StindVarVar_i4);
- continue;
- }
- case OpcodeValue::STIND_I8:
- {
- Add_stind(HiOpcodeEnum::StindVarVar_i8);
- continue;
- }
- case OpcodeValue::STIND_R4:
- {
- Add_stind(HiOpcodeEnum::StindVarVar_f4);
- continue;
- }
- case OpcodeValue::STIND_R8:
- {
- Add_stind(HiOpcodeEnum::StindVarVar_f8);
- continue;
- }
- case OpcodeValue::ADD:
- {
- CI_binOp(Add);
- continue;
- }
- case OpcodeValue::SUB:
- {
- CI_binOp(Sub);
- continue;
- }
- case OpcodeValue::MUL:
- {
- CI_binOp(Mul);
- continue;
- }
- case OpcodeValue::DIV:
- {
- CI_binOp(Div);
- continue;
- }
- case OpcodeValue::DIV_UN:
- {
- CI_binOpUn(DivUn);
- continue;
- }
- case OpcodeValue::REM:
- {
- CI_binOp(Rem);
- continue;
- }
- case OpcodeValue::REM_UN:
- {
- CI_binOpUn(RemUn);
- continue;
- }
- case OpcodeValue::AND:
- {
- CI_binOpUn(And);
- continue;
- }
- case OpcodeValue::OR:
- {
- CI_binOpUn(Or);
- continue;
- }
- case OpcodeValue::XOR:
- {
- CI_binOpUn(Xor);
- continue;
- }
- case OpcodeValue::SHL:
- {
- CI_binOpShift(Shl);
- continue;
- }
- case OpcodeValue::SHR:
- {
- CI_binOpShift(Shr);
- continue;
- }
- case OpcodeValue::SHR_UN:
- {
- CI_binOpShift(ShrUn);
- continue;
- }
- case OpcodeValue::NEG:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- EvalStackVarInfo& op = evalStack[evalStackTop - 1];
- CreateAddIR(ir, UnaryOpVarVar_Neg_i4);
- ir->dst = ir->src = op.locOffset;
- switch (op.reduceType)
- {
- case EvalStackReduceDataType::I4:
- {
- ir->type = HiOpcodeEnum::UnaryOpVarVar_Neg_i4;
- break;
- }
- case EvalStackReduceDataType::I8:
- {
- ir->type = HiOpcodeEnum::UnaryOpVarVar_Neg_i8;
- break;
- }
- case EvalStackReduceDataType::R4:
- {
- ir->type = HiOpcodeEnum::UnaryOpVarVar_Neg_f4;
- break;
- }
- case EvalStackReduceDataType::R8:
- {
- ir->type = HiOpcodeEnum::UnaryOpVarVar_Neg_f8;
- break;
- }
- default:
- {
- RaiseExecutionEngineException("NEG not suppport type");
- break;
- }
- }
- ip++;
- continue;
- }
- case OpcodeValue::NOT:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- EvalStackVarInfo& op = evalStack[evalStackTop - 1];
- CreateAddIR(ir, UnaryOpVarVar_Not_i4);
- ir->dst = ir->src = op.locOffset;
- switch (op.reduceType)
- {
- case EvalStackReduceDataType::I4:
- {
- ir->type = HiOpcodeEnum::UnaryOpVarVar_Not_i4;
- break;
- }
- case EvalStackReduceDataType::I8:
- {
- ir->type = HiOpcodeEnum::UnaryOpVarVar_Not_i8;
- break;
- }
- default:
- {
- RaiseExecutionEngineException("NOT not suppport type");
- break;
- }
- }
- ip++;
- continue;
- }
- case OpcodeValue::CONV_I1:
- {
- CI_conv(i1, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_I2:
- {
- CI_conv(i2, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_I4:
- {
- CI_conv(i4, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_I8:
- {
- CI_conv(i8, I8, 8);
- continue;
- }
- case OpcodeValue::CONV_R4:
- {
- CI_conv(f4, R4, 4);
- continue;
- }
- case OpcodeValue::CONV_R8:
- {
- CI_conv(f8, R8, 8);
- continue;
- }
- case OpcodeValue::CONV_U4:
- {
- CI_conv(u4, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_U8:
- {
- CI_conv(u8, I8, 8);
- continue;
- }
- case OpcodeValue::CPOBJ:
- {
- IL2CPP_ASSERT(evalStackTop >= 2);
- EvalStackVarInfo& dst = evalStack[evalStackTop - 2];
- EvalStackVarInfo& src = evalStack[evalStackTop - 1];
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- Il2CppClass* objKlass = image->GetClassFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- IL2CPP_ASSERT(objKlass);
- if (IS_CLASS_VALUE_TYPE(objKlass))
- {
- uint32_t size = GetTypeValueSize(objKlass);
- if (!HYBRIDCLR_ENABLE_WRITE_BARRIERS || !objKlass->has_references)
- {
- switch (size)
- {
- case 1:
- {
- CreateAddIR(ir, CpobjVarVar_1);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- break;
- }
- case 2:
- {
- CreateAddIR(ir, CpobjVarVar_2);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- break;
- }
- case 4:
- {
- CreateAddIR(ir, CpobjVarVar_4);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- break;
- }
- case 8:
- {
- CreateAddIR(ir, CpobjVarVar_8);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- break;
- }
- case 12:
- {
- CreateAddIR(ir, CpobjVarVar_12);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- break;
- }
- case 16:
- {
- CreateAddIR(ir, CpobjVarVar_16);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- break;
- }
- default:
- {
- CreateAddIR(ir, CpobjVarVar_n_4);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- ir->size = size;
- break;
- }
- }
- }
- else
- {
- CreateAddIR(ir, CpobjVarVar_WriteBarrier_n_4);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- ir->size = size;
- }
- }
- else
- {
- CreateAddIR(ir, CpobjVarVar_ref);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- }
- PopStackN(2);
- ip += 5;
- continue;
- }
- case OpcodeValue::LDOBJ:
- {
- IL2CPP_ASSERT(evalStackTop >= 1);
- EvalStackVarInfo& top = evalStack[evalStackTop - 1];
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- Il2CppClass* objKlass = image->GetClassFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- IL2CPP_ASSERT(objKlass);
- LocationDescInfo desc = ComputLocationDescInfo(&objKlass->byval_arg);
- switch (desc.type)
- {
- case LocationDescType::I1:
- {
- CreateAddIR(ir, LdindVarVar_i1);
- ir->dst = ir->src = top.locOffset;
- break;
- }
- case LocationDescType::U1:
- {
- CreateAddIR(ir, LdindVarVar_u1);
- ir->dst = ir->src = top.locOffset;
- break;
- }
- case LocationDescType::I2:
- {
- CreateAddIR(ir, LdindVarVar_i2);
- ir->dst = ir->src = top.locOffset;
- break;
- }
- case LocationDescType::U2:
- {
- CreateAddIR(ir, LdindVarVar_u2);
- ir->dst = ir->src = top.locOffset;
- break;
- }
- case LocationDescType::I4:
- {
- CreateAddIR(ir, LdindVarVar_i4);
- ir->dst = ir->src = top.locOffset;
- break;
- }
- case LocationDescType::I8:
- {
- CreateAddIR(ir, LdindVarVar_i8);
- ir->dst = ir->src = top.locOffset;
- break;
- }
- case LocationDescType::Ref:
- {
- CreateAddIR(ir, LdobjVarVar_ref);
- ir->dst = ir->src = top.locOffset;
- break;
- }
- case LocationDescType::S:
- case LocationDescType::StructContainsRef:
- {
- uint32_t size = GetTypeValueSize(objKlass);
- switch (size)
- {
- case 1:
- {
- CreateAddIR(ir, LdobjVarVar_1);
- ir->dst = ir->src = top.locOffset;
- break;
- }
- case 2:
- {
- CreateAddIR(ir, LdobjVarVar_2);
- ir->dst = ir->src = top.locOffset;
- break;
- }
- case 4:
- {
- CreateAddIR(ir, LdobjVarVar_4);
- ir->dst = ir->src = top.locOffset;
- break;
- }
- case 8:
- {
- CreateAddIR(ir, LdobjVarVar_8);
- ir->dst = ir->src = top.locOffset;
- break;
- }
- case 12:
- {
- CreateAddIR(ir, LdobjVarVar_12);
- ir->dst = ir->src = top.locOffset;
- break;
- }
- case 16:
- {
- CreateAddIR(ir, LdobjVarVar_16);
- ir->dst = ir->src = top.locOffset;
- break;
- }
- default:
- {
- CreateAddIR(ir, LdobjVarVar_n_4);
- ir->dst = ir->src = top.locOffset;
- ir->size = size;
- break;
- }
- }
- break;
- }
- default:
- {
- RaiseExecutionEngineException("field");
- }
- }
- PopStack();
- PushStackByType(&objKlass->byval_arg);
- InsertMemoryBarrier();
- ResetPrefixFlags();
- ip += 5;
- continue;
- }
- case OpcodeValue::LDSTR:
- {
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- Il2CppString* str = image->GetIl2CppUserStringFromRawIndex(DecodeTokenRowIndex(token));
- uint32_t dataIdx = GetOrAddResolveDataIndex(str);
- CreateAddIR(ir, LdstrVar);
- ir->dst = GetEvalStackNewTopOffset();
- ir->str = dataIdx;
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- ip += 5;
- continue;
- }
- case OpcodeValue::NEWOBJ:
- {
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- ip += 5;
- // TODO token cache optimistic
- shareMethod = const_cast<MethodInfo*>(image->GetMethodInfoFromToken(tokenCache, token, klassContainer, methodContainer, genericContext));
- IL2CPP_ASSERT(shareMethod);
- IL2CPP_ASSERT(!std::strcmp(shareMethod->name, ".ctor"));
- IL2CPP_ASSERT(hybridclr::metadata::IsInstanceMethod(shareMethod));
- if (TryAddInstinctCtorInstruments(shareMethod))
- {
- continue;
- }
- Il2CppClass* klass = shareMethod->klass;
- uint8_t paramCount = shareMethod->parameters_count;
- if (klass == il2cpp_defaults.string_class)
- {
- const MethodInfo* searchMethod = FindRedirectCreateString(shareMethod);
- if (searchMethod)
- {
- // insert nullptr to eval stack
- int32_t thisIdx = evalStackTop - paramCount;
- for (int32_t i = evalStackTop; i > thisIdx; i--)
- {
- evalStack[i] = evalStack[i - 1];
- }
- // locOffset of this is not important. You only need make sure the value is not equal to nullptr.
- evalStack[thisIdx] = { NATIVE_INT_REDUCE_TYPE, PTR_SIZE, GetEvalStackOffset(thisIdx) };
- ++evalStackTop;
- shareMethod = searchMethod;
- goto LabelCall;
- }
- }
- if (!InitAndGetInterpreterDirectlyCallMethodPointer(shareMethod))
- {
- RaiseAOTGenericMethodNotInstantiatedException(shareMethod);
- }
- int32_t callArgEvalStackIdxBase = evalStackTop - shareMethod->parameters_count;
- IL2CPP_ASSERT(callArgEvalStackIdxBase >= 0);
- uint16_t objIdx = GetEvalStackOffset(callArgEvalStackIdxBase);
- int32_t resolvedTotalArgNum = shareMethod->parameters_count + 1;
- uint32_t methodDataIndex = GetOrAddResolveDataIndex(shareMethod);
- if (IsInterpreterImplement(shareMethod))
- {
- if (IS_CLASS_VALUE_TYPE(klass))
- {
- CreateAddIR(ir, NewValueTypeInterpVar);
- ir->obj = GetEvalStackOffset(callArgEvalStackIdxBase);
- ir->method = methodDataIndex;
- ir->argBase = ir->obj;
- ir->argStackObjectNum = curStackSize - ir->argBase;
- // IL2CPP_ASSERT(ir->argStackObjectNum > 0); may 0
- PopStackN(shareMethod->parameters_count);
- PushStackByType(&klass->byval_arg);
- ir->ctorFrameBase = GetEvalStackNewTopOffset();
- maxStackSize = std::max(maxStackSize, curStackSize + ir->argStackObjectNum + 1);
- }
- else
- {
- if (shareMethod->parameters_count == 0)
- {
- CreateAddIR(ir, NewClassInterpVar_Ctor_0);
- ir->obj = GetEvalStackNewTopOffset();
- ir->method = methodDataIndex;
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- ir->ctorFrameBase = GetEvalStackNewTopOffset();
- maxStackSize = std::max(maxStackSize, curStackSize + 1); // 1 for __this
- }
- else
- {
- CreateAddIR(ir, NewClassInterpVar);
- ir->obj = GetEvalStackOffset(callArgEvalStackIdxBase);
- ir->method = methodDataIndex;
- ir->argBase = ir->obj;
- ir->argStackObjectNum = curStackSize - ir->argBase;
- IL2CPP_ASSERT(ir->argStackObjectNum > 0);
- PopStackN(shareMethod->parameters_count);
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- ir->ctorFrameBase = GetEvalStackNewTopOffset();
- maxStackSize = std::max(maxStackSize, curStackSize + ir->argStackObjectNum + 1); // 1 for __this
- }
- }
- IL2CPP_ASSERT(maxStackSize < MAX_STACK_SIZE);
- continue;
- }
- // optimize when argv == 0
- if (shareMethod->parameters_count == 0 && !IS_CLASS_VALUE_TYPE(klass))
- {
- CreateAddIR(ir, NewClassVar_Ctor_0);
- ir->method = methodDataIndex;
- ir->obj = GetEvalStackNewTopOffset();
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- continue;
- }
- int32_t needDataSlotNum = (resolvedTotalArgNum + 3) / 4;
- Managed2NativeCallMethod managed2NativeMethod = InterpreterModule::GetManaged2NativeMethodPointer(shareMethod, false);
- IL2CPP_ASSERT((void*)managed2NativeMethod);
- //uint32_t managed2NativeMethodDataIdx = GetOrAddResolveDataIndex(managed2NativeMethod);
- int32_t argIdxDataIndex;
- uint16_t* __argIdxs;
- AllocResolvedData(resolveDatas, needDataSlotNum, argIdxDataIndex, __argIdxs);
- //
- // arg1, arg2, arg3 ..., argN, obj or valuetype, __this(= obj or ref valuetype)
- // obj on new top
- PushStackByType(&klass->byval_arg);
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- __argIdxs[0] = GetEvalStackTopOffset(); // this
- for (uint8_t i = 0; i < shareMethod->parameters_count; i++)
- {
- int32_t curArgIdx = i + 1;
- __argIdxs[curArgIdx] = evalStack[callArgEvalStackIdxBase + i].locOffset;
- }
- PopStackN(resolvedTotalArgNum + 1); // args + obj + this
- PushStackByType(&klass->byval_arg);
- CreateAddIR(ir, NewClassVar);
- ir->type = IS_CLASS_VALUE_TYPE(shareMethod->klass) ? HiOpcodeEnum::NewValueTypeVar : HiOpcodeEnum::NewClassVar;
- ir->managed2NativeMethod = GetOrAddResolveDataIndex((void*)managed2NativeMethod);
- ir->method = methodDataIndex;
- ir->argIdxs = argIdxDataIndex;
- ir->obj = objIdx;
- continue;
- }
- case OpcodeValue::CASTCLASS:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- Il2CppClass* objKlass = image->GetClassFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- IL2CPP_ASSERT(objKlass);
- if (il2cpp::vm::Class::IsNullable(objKlass))
- {
- objKlass = il2cpp::vm::Class::GetNullableArgument(objKlass);
- }
- uint32_t klassDataIdx = GetOrAddResolveDataIndex(objKlass);
- CreateAddIR(ir, CastclassVar);
- ir->obj = GetEvalStackTopOffset();
- ir->klass = klassDataIdx;
- ip += 5;
- continue;
- }
- case OpcodeValue::ISINST:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- Il2CppClass* objKlass = image->GetClassFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- IL2CPP_ASSERT(objKlass);
- if (il2cpp::vm::Class::IsNullable(objKlass))
- {
- objKlass = il2cpp::vm::Class::GetNullableArgument(objKlass);
- }
- uint32_t klassDataIdx = GetOrAddResolveDataIndex(objKlass);
- CreateAddIR(ir, IsInstVar);
- ir->obj = GetEvalStackTopOffset();
- ir->klass = klassDataIdx;
- ip += 5;
- continue;
- }
- case OpcodeValue::CONV_R_UN:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- EvalStackVarInfo& top = evalStack[evalStackTop - 1];
- switch (top.reduceType)
- {
- case EvalStackReduceDataType::I4:
- {
- CreateAddIR(ir, ConvertVarVar_u4_f8);
- ir->dst = ir->src = GetEvalStackTopOffset();
- break;
- }
- case EvalStackReduceDataType::I8:
- {
- CreateAddIR(ir, ConvertVarVar_u8_f8);
- ir->dst = ir->src = GetEvalStackTopOffset();
- break;
- }
- default:
- {
- RaiseExecutionEngineException("");
- break;
- }
- }
- top.reduceType = EvalStackReduceDataType::R8;
- top.byteSize = 8;
- ip++;
- continue;
- }
- case OpcodeValue::UNBOX:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- Il2CppClass* objKlass = image->GetClassFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- //if (il2cpp::vm::Class::IsNullable(objKlass))
- //{
- // objKlass = il2cpp::vm::Class::GetNullableArgument(objKlass);
- //}
- CreateAddIR(ir, UnBoxVarVar);
- ir->addr = ir->obj = GetEvalStackTopOffset();
- ir->klass = GetOrAddResolveDataIndex(objKlass);
- PopStack();
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- ip += 5;
- continue;
- }
- case OpcodeValue::THROW:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- CreateAddIR(ir, ThrowEx);
- ir->exceptionObj = GetEvalStackTopOffset();
- ir->firstHandlerIndex = FindFirstThrowHandlerIndex(body.exceptionClauses, ipOffset);
- PopAllStack();
- PopBranch();
- continue;
- }
- case OpcodeValue::LDFLD:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- FieldInfo* fieldInfo = const_cast<FieldInfo*>(image->GetFieldInfoFromToken(tokenCache, token, klassContainer, methodContainer, genericContext));
- IL2CPP_ASSERT(fieldInfo);
- // ldfld obj may be obj or or valuetype or ref valuetype....
- EvalStackVarInfo& obj = evalStack[evalStackTop - 1];
- uint16_t topIdx = GetEvalStackTopOffset();
- IRCommon* ir = obj.reduceType != NATIVE_INT_REDUCE_TYPE && IS_CLASS_VALUE_TYPE(fieldInfo->parent) ? CreateValueTypeLdfld(pool, topIdx, topIdx, fieldInfo) : CreateClassLdfld(pool, topIdx, topIdx, fieldInfo);
- AddInst(ir);
- PopStack();
- PushStackByType(fieldInfo->type);
- InsertMemoryBarrier();
- ResetPrefixFlags();
- ip += 5;
- continue;
- }
- case OpcodeValue::LDFLDA:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- FieldInfo* fieldInfo = const_cast<FieldInfo*>(image->GetFieldInfoFromToken(tokenCache, token, klassContainer, methodContainer, genericContext));
- IL2CPP_ASSERT(fieldInfo);
- uint16_t topIdx = GetEvalStackTopOffset();
- CreateAddIR(ir, LdfldaVarVar);
- ir->dst = topIdx;
- ir->obj = topIdx;
- ir->offset = GetFieldOffset(fieldInfo);
- PopStack();
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- ip += 5;
- continue;
- }
- case OpcodeValue::STFLD:
- {
- InsertMemoryBarrier();
- ResetPrefixFlags();
- IL2CPP_ASSERT(evalStackTop >= 2);
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- FieldInfo* fieldInfo = const_cast<FieldInfo*>(image->GetFieldInfoFromToken(tokenCache, token, klassContainer, methodContainer, genericContext));
- IL2CPP_ASSERT(fieldInfo);
- IRCommon* ir = CreateStfld(pool, GetEvalStackOffset_2(), fieldInfo, GetEvalStackOffset_1());
- AddInst(ir);
- PopStackN(2);
- ip += 5;
- continue;
- }
- case OpcodeValue::LDSFLD:
- {
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- FieldInfo* fieldInfo = const_cast<FieldInfo*>(image->GetFieldInfoFromToken(tokenCache, token, klassContainer, methodContainer, genericContext));
- IL2CPP_ASSERT(fieldInfo);
- uint32_t parentIndex = GetOrAddResolveDataIndex(fieldInfo->parent);
- uint16_t dstIdx = GetEvalStackNewTopOffset();
- IRCommon* ir = fieldInfo->offset != THREAD_STATIC_FIELD_OFFSET ?
- CreateLdsfld(pool, dstIdx, fieldInfo, parentIndex)
- : CreateLdthreadlocal(pool, dstIdx, fieldInfo, parentIndex);
- AddInst(ir);
- PushStackByType(fieldInfo->type);
- InsertMemoryBarrier();
- ResetPrefixFlags();
- ip += 5;
- continue;
- }
- case OpcodeValue::LDSFLDA:
- {
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- FieldInfo* fieldInfo = const_cast<FieldInfo*>(image->GetFieldInfoFromToken(tokenCache, token, klassContainer, methodContainer, genericContext));
- IL2CPP_ASSERT(fieldInfo);
- uint16_t dstIdx = GetEvalStackNewTopOffset();
- if (fieldInfo->offset != THREAD_STATIC_FIELD_OFFSET)
- {
- bool ldfldFromFieldData = false;
- if (hybridclr::metadata::IsInterpreterType(fieldInfo->parent))
- {
- const FieldDetail& fieldDet = hybridclr::metadata::MetadataModule::GetImage(fieldInfo->parent)
- ->GetFieldDetailFromRawIndex(hybridclr::metadata::DecodeTokenRowIndex(fieldInfo->token - 1));
- if (fieldDet.defaultValueIndex != kDefaultValueIndexNull)
- {
- ldfldFromFieldData = true;
- CreateAddIR(ir, LdsfldaFromFieldDataVarVar);
- ir->dst = dstIdx;
- ir->src = GetOrAddResolveDataIndex(il2cpp::vm::Field::GetData(fieldInfo));
- }
- }
- if (!ldfldFromFieldData)
- {
- CreateAddIR(ir, LdsfldaVarVar);
- ir->dst = dstIdx;
- ir->klass = GetOrAddResolveDataIndex(fieldInfo->parent);
- ir->offset = fieldInfo->offset;
- }
- }
- else
- {
- CreateAddIR(ir, LdthreadlocalaVarVar);
- ir->dst = dstIdx;
- ir->klass = GetOrAddResolveDataIndex(fieldInfo->parent);
- ir->offset = GetThreadStaticFieldOffset(fieldInfo);
- }
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- ip += 5;
- continue;
- }
- case OpcodeValue::STSFLD:
- {
- InsertMemoryBarrier();
- ResetPrefixFlags();
- IL2CPP_ASSERT(evalStackTop >= 1);
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- FieldInfo* fieldInfo = const_cast<FieldInfo*>(image->GetFieldInfoFromToken(tokenCache, token, klassContainer, methodContainer, genericContext));
- IL2CPP_ASSERT(fieldInfo);
- uint32_t klassIndex = GetOrAddResolveDataIndex(fieldInfo->parent);
- uint16_t dataIdx = GetEvalStackTopOffset();
- IRCommon* ir = fieldInfo->offset != THREAD_STATIC_FIELD_OFFSET ?
- CreateStsfld(pool, fieldInfo, klassIndex, dataIdx)
- : CreateStthreadlocal(pool, fieldInfo, klassIndex, dataIdx);
- AddInst(ir);
- PopStack();
- ip += 5;
- continue;
- }
- case OpcodeValue::STOBJ:
- {
- InsertMemoryBarrier();
- ResetPrefixFlags();
- IL2CPP_ASSERT(evalStackTop >= 2);
- EvalStackVarInfo& dst = evalStack[evalStackTop - 2];
- EvalStackVarInfo& src = evalStack[evalStackTop - 1];
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- Il2CppClass* objKlass = image->GetClassFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- IL2CPP_ASSERT(objKlass);
- if (IS_CLASS_VALUE_TYPE(objKlass))
- {
- uint32_t size = GetTypeValueSize(objKlass);
- if (!HYBRIDCLR_ENABLE_WRITE_BARRIERS || !objKlass->has_references)
- {
- switch (size)
- {
- case 1:
- {
- CreateAddIR(ir, StobjVarVar_1);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- break;
- }
- case 2:
- {
- CreateAddIR(ir, StobjVarVar_2);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- break;
- }
- case 4:
- {
- CreateAddIR(ir, StobjVarVar_4);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- break;
- }
- case 8:
- {
- CreateAddIR(ir, StobjVarVar_8);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- break;
- }
- case 12:
- {
- CreateAddIR(ir, StobjVarVar_12);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- break;
- }
- case 16:
- {
- CreateAddIR(ir, StobjVarVar_16);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- break;
- }
- default:
- {
- CreateAddIR(ir, StobjVarVar_n_4);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- ir->size = size;
- break;
- }
- }
- }
- else
- {
- CreateAddIR(ir, StobjVarVar_WriteBarrier_n_4);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- ir->size = size;
- }
- }
- else
- {
- CreateAddIR(ir, StobjVarVar_ref);
- ir->dst = dst.locOffset;
- ir->src = src.locOffset;
- }
- PopStackN(2);
- ip += 5;
- continue;
- }
- case OpcodeValue::CONV_OVF_I1_UN:
- {
- CI_conv_un_ovf(i1, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_OVF_I2_UN:
- {
- CI_conv_un_ovf(i2, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_OVF_I4_UN:
- {
- CI_conv_un_ovf(i4, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_OVF_I8_UN:
- {
- CI_conv_un_ovf(i8, I8, 8);
- continue;
- }
- case OpcodeValue::CONV_OVF_U1_UN:
- {
- CI_conv_un_ovf(u1, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_OVF_U2_UN:
- {
- CI_conv_un_ovf(u2, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_OVF_U4_UN:
- {
- CI_conv_un_ovf(u4, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_OVF_U8_UN:
- {
- CI_conv_un_ovf(u8, I8, 8);
- continue;
- }
- case OpcodeValue::CONV_OVF_I_UN:
- {
- #if HYBRIDCLR_ARCH_64
- CI_conv_un_ovf(i8, I8, 8);
- #else
- CI_conv_un_ovf(i4, I4, 4);
- #endif
- continue;
- }
- case OpcodeValue::CONV_OVF_U_UN:
- {
- #if HYBRIDCLR_ARCH_64
- CI_conv_un_ovf(u8, I8, 8);
- #else
- CI_conv_un_ovf(u4, I4, 4);
- #endif
- continue;
- }
- case OpcodeValue::BOX:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- Il2CppClass* objKlass = image->GetClassFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- /* if (il2cpp::vm::Class::IsNullable(objKlass))
- {
- objKlass = il2cpp::vm::Class::GetNullableArgument(objKlass);
- }*/
- PopStack();
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- if (IS_CLASS_VALUE_TYPE(objKlass))
- {
- CreateAddIR(ir, BoxVarVar);
- ir->dst = ir->data = GetEvalStackTopOffset();
- ir->klass = GetOrAddResolveDataIndex(objKlass);
- }
- else
- {
- // ignore class
- }
- ip += 5;
- continue;
- }
- case OpcodeValue::NEWARR:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- EvalStackVarInfo& varSize = evalStack[evalStackTop - 1];
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- Il2CppClass* eleKlass = image->GetClassFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- IL2CPP_ASSERT(eleKlass);
- Il2CppClass* arrKlass = il2cpp::vm::Class::GetArrayClass(eleKlass, 1);
- uint32_t arrKlassIndex = GetOrAddResolveDataIndex(arrKlass);
- CreateAddIR(ir, NewArrVarVar);
- ir->arr = ir->size = varSize.locOffset;
- ir->klass = arrKlassIndex;
- PopStack();
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- ip += 5;
- continue;
- }
- case OpcodeValue::LDLEN:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- CreateAddIR(ir, GetArrayLengthVarVar);
- ir->arr = ir->len = GetEvalStackTopOffset();
- PopStack();
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- ip++;
- continue;
- }
- case OpcodeValue::LDELEMA:
- {
- IL2CPP_ASSERT(evalStackTop >= 2);
- EvalStackVarInfo& arr = evalStack[evalStackTop - 2];
- EvalStackVarInfo& index = evalStack[evalStackTop - 1];
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- Il2CppClass* eleKlass = image->GetClassFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- uint32_t eleKlassIndex = GetOrAddResolveDataIndex(eleKlass);
- if (prefixFlags & (int32_t)PrefixFlags::ReadOnly)
- {
- CreateAddIR(ir, GetArrayElementAddressAddrVarVar);
- ir->arr = ir->addr = arr.locOffset;
- ir->index = index.locOffset;
- }
- else
- {
- CreateAddIR(ir, GetArrayElementAddressCheckAddrVarVar);
- ir->arr = ir->addr = arr.locOffset;
- ir->index = index.locOffset;
- ir->eleKlass = eleKlassIndex;
- }
- ResetPrefixFlags();
- PopStackN(2);
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- ip += 5;
- continue;
- }
- case OpcodeValue::LDELEM_I1:
- {
- CI_ldele(i1, I4);
- continue;
- }
- case OpcodeValue::LDELEM_U1:
- {
- CI_ldele(u1, I4);
- continue;
- }
- case OpcodeValue::LDELEM_I2:
- {
- CI_ldele(i2, I4);
- continue;
- }
- case OpcodeValue::LDELEM_U2:
- {
- CI_ldele(u2, I4);
- continue;
- }
- case OpcodeValue::LDELEM_I4:
- {
- CI_ldele(i4, I4);
- continue;
- }
- case OpcodeValue::LDELEM_U4:
- {
- CI_ldele(u4, I4);
- continue;
- }
- case OpcodeValue::LDELEM_I8:
- {
- CI_ldele(i8, I8);
- continue;
- }
- case OpcodeValue::LDELEM_I:
- {
- #if HYBRIDCLR_ARCH_64
- CI_ldele(i8, I8);
- #else
- CI_ldele(i4, I4);
- #endif
- continue;
- }
- case OpcodeValue::LDELEM_R4:
- {
- CI_ldele(i4, R4);
- continue;
- }
- case OpcodeValue::LDELEM_R8:
- {
- CI_ldele(i8, R8);
- continue;
- }
- case OpcodeValue::LDELEM_REF:
- {
- #if HYBRIDCLR_ARCH_64
- CI_ldele(i8, I8);
- #else
- CI_ldele(i4, I4);
- #endif
- continue;
- }
- case OpcodeValue::STELEM_I:
- {
- #if HYBRIDCLR_ARCH_64
- CI_stele(i8)
- #else
- CI_stele(i4)
- #endif
- continue;
- }
- case OpcodeValue::STELEM_I1:
- {
- CI_stele(i1);
- continue;
- }
- case OpcodeValue::STELEM_I2:
- {
- CI_stele(i2);
- continue;
- }
- case OpcodeValue::STELEM_I4:
- {
- CI_stele(i4);
- continue;
- }
- case OpcodeValue::STELEM_I8:
- {
- CI_stele(i8);
- continue;
- }
- case OpcodeValue::STELEM_R4:
- {
- CI_stele(i4);
- continue;
- }
- case OpcodeValue::STELEM_R8:
- {
- CI_stele(i8);
- continue;
- }
- case OpcodeValue::STELEM_REF:
- {
- CI_stele(ref);
- continue;
- }
- #define CI_ldele0(eleType) \
- CreateAddIR(ir, GetArrayElementVarVar_##eleType); \
- ir->arr = arr.locOffset; \
- ir->index = index.locOffset; \
- ir->dst = arr.locOffset;
- case OpcodeValue::LDELEM:
- {
- IL2CPP_ASSERT(evalStackTop >= 2);
- EvalStackVarInfo& arr = evalStack[evalStackTop - 2];
- EvalStackVarInfo& index = evalStack[evalStackTop - 1];
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- Il2CppClass* objKlass = image->GetClassFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- const Il2CppType* eleType = &objKlass->byval_arg;
- IL2CPP_ASSERT(index.reduceType == EvalStackReduceDataType::I4 || index.reduceType == EvalStackReduceDataType::I8);
- bool isIndexInt32Type = index.reduceType == EvalStackReduceDataType::I4;
- LocationDescInfo desc = ComputLocationDescInfo(eleType);
- switch (desc.type)
- {
- case LocationDescType::I1: { CI_ldele0(i1); break; }
- case LocationDescType::U1: { CI_ldele0(u1); break; }
- case LocationDescType::I2: { CI_ldele0(i2); break; }
- case LocationDescType::U2: { CI_ldele0(u2); break; }
- case LocationDescType::I4: { CI_ldele0(i4); break; }
- case LocationDescType::I8: { CI_ldele0(i8); break; }
- case LocationDescType::Ref:
- {
- if (HYBRIDCLR_ARCH_64)
- {
- CI_ldele0(i8);
- }
- else
- {
- CI_ldele0(i4);
- }
- break;
- }
- case LocationDescType::S:
- case LocationDescType::StructContainsRef:
- {
- CreateAddIR(ir, GetArrayElementVarVar_size_1);
- ir->arr = arr.locOffset;
- ir->index = index.locOffset;
- ir->dst = arr.locOffset;
- uint32_t size = il2cpp::vm::Class::GetValueSize(objKlass, nullptr);
- switch (size)
- {
- case 1:
- {
- ir->type = HiOpcodeEnum::GetArrayElementVarVar_size_1;
- break;
- }
- case 2:
- {
- ir->type = HiOpcodeEnum::GetArrayElementVarVar_size_2;
- break;
- }
- case 4:
- {
- ir->type = HiOpcodeEnum::GetArrayElementVarVar_size_4;
- break;
- }
- case 8:
- {
- ir->type = HiOpcodeEnum::GetArrayElementVarVar_size_8;
- break;
- }
- case 12:
- {
- ir->type = HiOpcodeEnum::GetArrayElementVarVar_size_12;
- break;
- }
- case 16:
- {
- ir->type = HiOpcodeEnum::GetArrayElementVarVar_size_16;
- break;
- }
- case 20:
- {
- ir->type = HiOpcodeEnum::GetArrayElementVarVar_size_20;
- break;
- }
- case 24:
- {
- ir->type = HiOpcodeEnum::GetArrayElementVarVar_size_24;
- break;
- }
- case 28:
- {
- ir->type = HiOpcodeEnum::GetArrayElementVarVar_size_28;
- break;
- }
- case 32:
- {
- ir->type = HiOpcodeEnum::GetArrayElementVarVar_size_32;
- break;
- }
- default:
- {
- ir->type = HiOpcodeEnum::GetArrayElementVarVar_n;
- }
- }
- break;
- }
- default:
- {
- RaiseExecutionEngineException("ldelem not support type");
- }
- }
- PopStackN(2);
- PushStackByType(eleType);
- ip += 5;
- continue;
- }
- #define CI_stele0(eleType) \
- CreateAddIR(ir, SetArrayElementVarVar_##eleType); \
- ir->arr = arr.locOffset; \
- ir->index = index.locOffset; \
- ir->ele = ele.locOffset;
- case OpcodeValue::STELEM:
- {
- IL2CPP_ASSERT(evalStackTop >= 3);
- EvalStackVarInfo& arr = evalStack[evalStackTop - 3];
- EvalStackVarInfo& index = evalStack[evalStackTop - 2];
- EvalStackVarInfo& ele = evalStack[evalStackTop - 1];
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- Il2CppClass* objKlass = image->GetClassFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- const Il2CppType* eleType = &objKlass->byval_arg;
- IL2CPP_ASSERT(index.reduceType == EvalStackReduceDataType::I4 || index.reduceType == EvalStackReduceDataType::I8);
- bool isIndexInt32Type = index.reduceType == EvalStackReduceDataType::I4;
- LocationDescInfo desc = ComputLocationDescInfo(eleType);
- switch (desc.type)
- {
- case LocationDescType::I1: { CI_stele0(i1); break; }
- case LocationDescType::U1: { CI_stele0(u1); break; }
- case LocationDescType::I2: { CI_stele0(i2); break; }
- case LocationDescType::U2: { CI_stele0(u2); break; }
- case LocationDescType::I4: { CI_stele0(i4); break; }
- case LocationDescType::I8: { CI_stele0(i8); break; }
- case LocationDescType::Ref: { CI_stele0(ref); break; }
- case LocationDescType::S:
- {
- uint32_t size = il2cpp::vm::Class::GetValueSize(objKlass, nullptr);
- switch (size)
- {
- case 12:
- {
- CreateAddIR(ir, SetArrayElementVarVar_size_12);
- ir->arr = arr.locOffset;
- ir->index = index.locOffset;
- ir->ele = ele.locOffset;
- break;
- }
- case 16:
- {
- CreateAddIR(ir, SetArrayElementVarVar_size_16);
- ir->arr = arr.locOffset;
- ir->index = index.locOffset;
- ir->ele = ele.locOffset;
- break;
- }
- default:
- {
- CreateAddIR(ir, SetArrayElementVarVar_n);
- ir->arr = arr.locOffset;
- ir->index = index.locOffset;
- ir->ele = ele.locOffset;
- break;
- }
- }
- break;
- }
- case LocationDescType::StructContainsRef:
- {
- CreateAddIR(ir, SetArrayElementVarVar_WriteBarrier_n);
- ir->arr = arr.locOffset;
- ir->index = index.locOffset;
- ir->ele = ele.locOffset;
- break;
- }
- default:
- {
- RaiseExecutionEngineException("stelem not support type");
- }
- }
- PopStackN(3);
- ip += 5;
- continue;
- }
- case OpcodeValue::UNBOX_ANY:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- Il2CppClass* objKlass = image->GetClassFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- IL2CPP_ASSERT(objKlass);
- if (IS_CLASS_VALUE_TYPE(objKlass))
- {
- CreateAddIR(ir, UnBoxAnyVarVar);
- ir->dst = ir->obj = GetEvalStackTopOffset();
- ir->klass = GetOrAddResolveDataIndex(objKlass);
- PopStack();
- PushStackByType(&objKlass->byval_arg);
- }
- else
- {
- CreateAddIR(ir, CastclassVar);
- ir->obj = GetEvalStackTopOffset();
- ir->klass = GetOrAddResolveDataIndex(objKlass);
- }
- ip += 5;
- continue;
- }
- case OpcodeValue::CONV_OVF_I1:
- {
- CI_conv_ovf(i1, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_OVF_U1:
- {
- CI_conv_ovf(u1, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_OVF_I2:
- {
- CI_conv_ovf(i2, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_OVF_U2:
- {
- CI_conv_ovf(u2, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_OVF_I4:
- {
- CI_conv_ovf(i4, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_OVF_U4:
- {
- CI_conv_ovf(u4, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_OVF_I8:
- {
- CI_conv_ovf(i8, I8, 8);
- continue;
- }
- case OpcodeValue::CONV_OVF_U8:
- {
- CI_conv_ovf(u8, I8, 8);
- continue;
- }
- case OpcodeValue::REFANYVAL:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- Il2CppClass* objKlass = image->GetClassFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- CreateAddIR(ir, RefAnyValueVarVar);
- ir->addr = ir->typedRef = GetEvalStackTopOffset();
- ir->klass = GetOrAddResolveDataIndex(objKlass);
- PopStack();
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- ip += 5;
- continue;
- }
- case OpcodeValue::CKFINITE:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- EvalStackVarInfo& top = evalStack[evalStackTop - 1];
- switch (top.reduceType)
- {
- case EvalStackReduceDataType::R4:
- {
- CreateAddIR(ir, CheckFiniteVar_f4);
- ir->src = GetEvalStackTopOffset();
- break;
- }
- case EvalStackReduceDataType::R8:
- {
- CreateAddIR(ir, CheckFiniteVar_f8);
- ir->src = GetEvalStackTopOffset();
- break;
- }
- default:
- {
- RaiseExecutionEngineException("CKFINITE invalid reduceType");
- break;
- }
- }
- ip++;
- continue;
- }
- case OpcodeValue::MKREFANY:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- Il2CppClass* objKlass = image->GetClassFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- IL2CPP_ASSERT(objKlass);
- CreateAddIR(ir, MakeRefVarVar);
- ir->dst = ir->data = GetEvalStackTopOffset();
- ir->klass = GetOrAddResolveDataIndex(objKlass);
- PopStack();
- Il2CppType typedRef = {};
- typedRef.type = IL2CPP_TYPE_TYPEDBYREF;
- PushStackByType(&typedRef);
- ip += 5;
- continue;
- }
- case OpcodeValue::LDTOKEN:
- {
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 1);
- void* runtimeHandle = (void*)image->GetRuntimeHandleFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- CreateAddIR(ir, LdtokenVar);
- ir->runtimeHandle = GetEvalStackNewTopOffset();
- ir->token = GetOrAddResolveDataIndex(runtimeHandle);
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- ip += 5;
- continue;
- }
- case OpcodeValue::CONV_U2:
- {
- CI_conv(u2, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_U1:
- {
- CI_conv(u1, I4, 4);
- continue;
- }
- case OpcodeValue::CONV_I:
- {
- #if HYBRIDCLR_ARCH_64
- CI_conv(i8, I8, 8);
- #else
- CI_conv(i4, I4, 4);
- #endif
- continue;
- }
- case OpcodeValue::CONV_OVF_I:
- {
- #if HYBRIDCLR_ARCH_64
- CI_conv_ovf(i8, I8, 8);
- #else
- CI_conv_ovf(i4, I4, 4);
- #endif
- continue;
- }
- case OpcodeValue::CONV_OVF_U:
- {
- #if HYBRIDCLR_ARCH_64
- CI_conv_ovf(u8, I8, 8);
- #else
- CI_conv_ovf(u4, I4, 4);
- #endif
- continue;
- }
- case OpcodeValue::ADD_OVF:
- {
- CI_binOpOvf(Add);
- continue;
- }
- case OpcodeValue::ADD_OVF_UN:
- {
- CI_binOpUnOvf(Add);
- continue;
- }
- case OpcodeValue::MUL_OVF:
- {
- CI_binOpOvf(Mul);
- continue;
- }
- case OpcodeValue::MUL_OVF_UN:
- {
- CI_binOpUnOvf(Mul);
- continue;
- }
- case OpcodeValue::SUB_OVF:
- {
- CI_binOpOvf(Sub);
- continue;
- }
- case OpcodeValue::SUB_OVF_UN:
- {
- CI_binOpUnOvf(Sub);
- continue;
- }
- case OpcodeValue::ENDFINALLY:
- {
- CreateAddIR(ir, EndFinallyEx);
- PopBranch();
- continue;
- }
- case OpcodeValue::STIND_I:
- {
- Add_stind(ARCH_ARGUMENT(HiOpcodeEnum::StindVarVar_i4, HiOpcodeEnum::StindVarVar_i8));
- continue;
- }
- case OpcodeValue::CONV_U:
- {
- #if HYBRIDCLR_ARCH_64
- CI_conv(u8, I8, 8);
- #else
- CI_conv(u4, I4, 4);
- #endif
- continue;
- }
- case OpcodeValue::PREFIX7:
- case OpcodeValue::PREFIX6:
- case OpcodeValue::PREFIX5:
- case OpcodeValue::PREFIX4:
- case OpcodeValue::PREFIX3:
- case OpcodeValue::PREFIX2:
- {
- ip++;
- continue;
- }
- case OpcodeValue::PREFIX1:
- {
- // This is the prefix for all the 2-byte opcodes.
- // Figure out the second byte of the 2-byte opcode.
- byte ops = *(ip + 1);
- switch ((OpcodeValue)ops)
- {
- case OpcodeValue::ARGLIST:
- {
- RaiseExecutionEngineException("");
- ip += 2;
- continue;
- }
- case OpcodeValue::CEQ:
- {
- CI_compare(Ceq);
- ip += 2;
- continue;
- }
- case OpcodeValue::CGT:
- {
- CI_compare(Cgt);
- ip += 2;
- continue;
- }
- case OpcodeValue::CGT_UN:
- {
- CI_compare(CgtUn);
- ip += 2;
- continue;
- }
- case OpcodeValue::CLT:
- {
- CI_compare(Clt);
- ip += 2;
- continue;
- }
- case OpcodeValue::CLT_UN:
- {
- CI_compare(CltUn);
- ip += 2;
- continue;
- }
- case OpcodeValue::LDFTN:
- {
- uint32_t methodToken = (uint32_t)GetI4LittleEndian(ip + 2);
- MethodInfo* methodInfo = const_cast<MethodInfo*>(image->GetMethodInfoFromToken(tokenCache, methodToken, klassContainer, methodContainer, genericContext));
- IL2CPP_ASSERT(methodInfo);
- CreateAddIR(ir, LdcVarConst_8);
- ir->dst = GetEvalStackNewTopOffset();
- ir->src = (uint64_t)methodInfo;
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- ip += 6;
- continue;
- }
- case OpcodeValue::LDVIRTFTN:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- uint32_t methodToken = (uint32_t)GetI4LittleEndian(ip + 2);
- MethodInfo* methodInfo = const_cast<MethodInfo*>(image->GetMethodInfoFromToken(tokenCache, methodToken, klassContainer, methodContainer, genericContext));
- IL2CPP_ASSERT(methodInfo);
- CreateAddIR(ir, LdvirftnVarVar);
- ir->resultMethod = ir->obj = GetEvalStackTopOffset();
- ir->virtualMethod = GetOrAddResolveDataIndex(methodInfo);
- PopStack();
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- ip += 6;
- continue;
- }
- case OpcodeValue::UNUSED56:
- {
- ip += 2;
- continue;
- }
- case OpcodeValue::LDARG:
- {
- argIdx = GetU2LittleEndian(ip + 2);
- AddInst_ldarg(argIdx);
- ip += 4;
- continue;
- }
- case OpcodeValue::LDARGA:
- {
- argIdx = GetU2LittleEndian(ip + 2);
- AddInst_ldarga(argIdx);
- ip += 4;
- continue;
- }
- case OpcodeValue::STARG:
- {
- argIdx = GetU2LittleEndian(ip + 2);
- AddInst_starg(argIdx);
- ip += 4;
- continue;
- }
- case OpcodeValue::LDLOC:
- {
- argIdx = GetU2LittleEndian(ip + 2);
- CreateAddInst_ldloc(argIdx);
- ip += 4;
- continue;
- }
- case OpcodeValue::LDLOCA:
- {
- argIdx = GetU2LittleEndian(ip + 2);
- CreateAddInst_ldloca(argIdx);
- ip += 4;
- continue;
- }
- case OpcodeValue::STLOC:
- {
- argIdx = GetU2LittleEndian(ip + 2);
- CreateAddInst_stloc(argIdx);
- ip += 4;
- continue;
- }
- case OpcodeValue::LOCALLOC:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- EvalStackVarInfo& top = evalStack[evalStackTop - 1];
- switch (top.reduceType)
- {
- case EvalStackReduceDataType::I4:
- case EvalStackReduceDataType::I8: // FIXE ME
- {
- CreateAddIR(ir, LocalAllocVarVar_n_4);
- ir->dst = ir->size = GetEvalStackTopOffset();
- break;
- }
- default:
- {
- RaiseExecutionEngineException("LOCALLOC invalid reduceType");
- break;
- }
- }
- PopStack();
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- ip += 2;
- continue;
- }
- case OpcodeValue::UNUSED57:
- {
- ip += 2;
- continue;
- }
- case OpcodeValue::ENDFILTER:
- {
- CreateAddIR(ir, EndFilterEx);
- ir->value = GetEvalStackTopOffset();
- PopAllStack();
- PopBranch();
- continue;
- }
- case OpcodeValue::UNALIGNED_:
- {
- // Nothing to do here.
- prefixFlags |= (int32_t)PrefixFlags::Unaligned;
- uint8_t alignment = ip[2];
- IL2CPP_ASSERT(alignment == 1 || alignment == 2 || alignment == 4);
- ip += 3;
- continue;
- }
- case OpcodeValue::VOLATILE_:
- {
- // Set a flag that causes a memory barrier to be associated with the next load or store.
- //CI_volatileFlag = true;
- prefixFlags |= (int32_t)PrefixFlags::Volatile;
- ip += 2;
- continue;
- }
- case OpcodeValue::TAIL_:
- {
- prefixFlags |= (int32_t)PrefixFlags::Tail;
- ip += 2;
- continue;
- }
- case OpcodeValue::INITOBJ:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 2);
- Il2CppClass* objKlass = image->GetClassFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- if (IS_CLASS_VALUE_TYPE(objKlass))
- {
- uint32_t objSize = GetTypeValueSize(objKlass);
- if ((HYBRIDCLR_ENABLE_WRITE_BARRIERS && objKlass->has_references))
- {
- CreateAddIR(ir, InitobjVar_WriteBarrier_n_4);
- ir->obj = GetEvalStackTopOffset();
- ir->size = objSize;
- }
- else
- {
- bool convert = false;
- switch (objSize)
- {
- case 1:
- {
- CreateAddIR(ir, InitobjVar_1);
- ir->obj = GetEvalStackTopOffset();
- convert = true;
- break;
- }
- case 2:
- {
- if (SUPPORT_MEMORY_NOT_ALIGMENT_ACCESS || objKlass->minimumAlignment >= 2)
- {
- CreateAddIR(ir, InitobjVar_2);
- ir->obj = GetEvalStackTopOffset();
- convert = true;
- }
- break;
- }
- case 4:
- {
- if (SUPPORT_MEMORY_NOT_ALIGMENT_ACCESS || objKlass->minimumAlignment >= 4)
- {
- CreateAddIR(ir, InitobjVar_4);
- ir->obj = GetEvalStackTopOffset();
- convert = true;
- }
- break;
- }
- case 8:
- {
- if (SUPPORT_MEMORY_NOT_ALIGMENT_ACCESS || objKlass->minimumAlignment >= 8)
- {
- CreateAddIR(ir, InitobjVar_8);
- ir->obj = GetEvalStackTopOffset();
- convert = true;
- }
- break;
- }
- case 12:
- {
- if (SUPPORT_MEMORY_NOT_ALIGMENT_ACCESS || objKlass->minimumAlignment >= 4)
- {
- CreateAddIR(ir, InitobjVar_12);
- ir->obj = GetEvalStackTopOffset();
- convert = true;
- }
- break;
- }
- case 16:
- {
- if (SUPPORT_MEMORY_NOT_ALIGMENT_ACCESS || objKlass->minimumAlignment >= 8)
- {
- CreateAddIR(ir, InitobjVar_16);
- ir->obj = GetEvalStackTopOffset();
- convert = true;
- }
- break;
- }
- case 20:
- {
- if (SUPPORT_MEMORY_NOT_ALIGMENT_ACCESS || objKlass->minimumAlignment >= 4)
- {
- CreateAddIR(ir, InitobjVar_20);
- ir->obj = GetEvalStackTopOffset();
- convert = true;
- }
- break;
- }
- case 24:
- {
- if (SUPPORT_MEMORY_NOT_ALIGMENT_ACCESS || objKlass->minimumAlignment >= 8)
- {
- CreateAddIR(ir, InitobjVar_24);
- ir->obj = GetEvalStackTopOffset();
- convert = true;
- }
- break;
- }
- case 28:
- {
- if (SUPPORT_MEMORY_NOT_ALIGMENT_ACCESS || objKlass->minimumAlignment >= 4)
- {
- CreateAddIR(ir, InitobjVar_28);
- ir->obj = GetEvalStackTopOffset();
- convert = true;
- }
- break;
- }
- case 32:
- {
- if (SUPPORT_MEMORY_NOT_ALIGMENT_ACCESS || objKlass->minimumAlignment >= 8)
- {
- CreateAddIR(ir, InitobjVar_32);
- ir->obj = GetEvalStackTopOffset();
- convert = true;
- }
- break;
- }
- }
- if (!convert)
- {
- CreateAddIR(ir, InitobjVar_n_4);
- ir->obj = GetEvalStackTopOffset();
- ir->size = objSize;
- }
- }
- }
- else
- {
- CreateAddIR(ir, InitobjVar_ref);
- ir->obj = GetEvalStackTopOffset();
- }
- PopStack();
- ip += 6;
- break;
- }
- case OpcodeValue::CONSTRAINED_:
- {
- uint32_t typeToken = (uint32_t)GetI4LittleEndian(ip + 2);
- Il2CppClass* conKlass = image->GetClassFromToken(tokenCache, typeToken, klassContainer, methodContainer, genericContext);
- IL2CPP_ASSERT(conKlass);
- ip += 6;
- IL2CPP_ASSERT(*ip == (uint8_t)OpcodeValue::CALLVIRT);
- uint32_t methodToken = (uint32_t)GetI4LittleEndian(ip + 1);
- ip += 5;
- // TODO token cache optimistic
- shareMethod = const_cast<MethodInfo*>(image->GetMethodInfoFromToken(tokenCache, methodToken, klassContainer, methodContainer, genericContext));
- IL2CPP_ASSERT(shareMethod);
- int32_t resolvedTotalArgNum = shareMethod->parameters_count + 1;
- int32_t selfIdx = evalStackTop - resolvedTotalArgNum;
- EvalStackVarInfo& self = evalStack[selfIdx];
- if (IS_CLASS_VALUE_TYPE(conKlass))
- {
- // impl in self
- const MethodInfo* implMethod = image->FindImplMethod(conKlass, shareMethod);
- if (implMethod->klass == conKlass)
- {
- shareMethod = implMethod;
- goto LabelCall;
- }
- else if (conKlass->enumtype && !std::strcmp(shareMethod->name, "GetHashCode"))
- {
- Il2CppTypeEnum typeEnum = conKlass->element_class->byval_arg.type;
- self.reduceType = EvalStackReduceDataType::I4;
- if (typeEnum == IL2CPP_TYPE_I8 || typeEnum == IL2CPP_TYPE_U8)
- {
- CreateAddIR(ir, GetEnumHashCode);
- ir->dst = ir->src = self.locOffset;
- }
- else
- {
- CreateAddIR(ir, LdindVarVar_i1);
- ir->dst = ir->src = self.locOffset;
- switch (conKlass->element_class->byval_arg.type)
- {
- case IL2CPP_TYPE_U1: ir->type = HiOpcodeEnum::LdindVarVar_u1; break;
- case IL2CPP_TYPE_I1: ir->type = HiOpcodeEnum::LdindVarVar_i1; break;
- case IL2CPP_TYPE_U2: ir->type = HiOpcodeEnum::LdindVarVar_u2; break;
- case IL2CPP_TYPE_I2: ir->type = HiOpcodeEnum::LdindVarVar_u2; break;
- case IL2CPP_TYPE_U4: ir->type = HiOpcodeEnum::LdindVarVar_u4; break;
- case IL2CPP_TYPE_I4: ir->type = HiOpcodeEnum::LdindVarVar_i4; break;
- case IL2CPP_TYPE_CHAR: ir->type = HiOpcodeEnum::LdindVarVar_u2; break;
- case IL2CPP_TYPE_BOOLEAN: ir->type = HiOpcodeEnum::LdindVarVar_i1; break;
- default:
- IL2CPP_ASSERT(false && "GetHashCode");
- break;
- }
- }
- }
- else
- {
- CreateAddIR(ir, BoxRefVarVar);
- ir->dst = ir->src = self.locOffset;
- ir->klass = GetOrAddResolveDataIndex(conKlass);
- self.reduceType = NATIVE_INT_REDUCE_TYPE;
- self.byteSize = GetSizeByReduceType(self.reduceType);
- goto LabelCallVir;
- }
- }
- else
- {
- // deref object. FIXME gc memory barrier
- #if HYBRIDCLR_ARCH_64
- CreateAddIR(ir, LdindVarVar_i8);
- #else
- CreateAddIR(ir, LdindVarVar_i4);
- #endif
- ir->dst = ir->src = self.locOffset;
- self.reduceType = NATIVE_INT_REDUCE_TYPE;
- self.byteSize = GetSizeByReduceType(self.reduceType);
- goto LabelCallVir;
- }
- continue;
- }
- case OpcodeValue::CPBLK:
- {
- // we don't sure dst or src is volatile. so insert memory barrier ahead and end.
- IL2CPP_ASSERT(evalStackTop >= 3);
- InsertMemoryBarrier();
- ResetPrefixFlags();
- CreateAddIR(ir, CpblkVarVar);
- ir->dst = GetEvalStackOffset_3();
- ir->src = GetEvalStackOffset_2();
- ir->size = GetEvalStackOffset_1();
- PopStackN(3);
- InsertMemoryBarrier();
- ResetPrefixFlags();
- ip += 2;
- continue;
- }
- case OpcodeValue::INITBLK:
- {
- IL2CPP_ASSERT(evalStackTop >= 3);
- InsertMemoryBarrier();
- ResetPrefixFlags();
- CreateAddIR(ir, InitblkVarVarVar);
- ir->addr = GetEvalStackOffset_3();
- ir->value = GetEvalStackOffset_2();
- ir->size = GetEvalStackOffset_1();
- PopStackN(3);
- ip += 2;
- continue;
- }
- case OpcodeValue::NO_:
- {
- uint8_t checkType = ip[2];
- // {typecheck:0x1} | {rangecheck:0x2} | {nullcheck:0x4}
- IL2CPP_ASSERT(checkType < 8);
- ip += 3;
- continue;
- }
- case OpcodeValue::RETHROW:
- {
- CreateAddIR(ir, RethrowEx);
- AddInst(ir);
- PopAllStack();
- PopBranch();
- continue;
- }
- case OpcodeValue::UNUSED:
- {
- ip += 2;
- continue;
- }
- case OpcodeValue::SIZEOF:
- {
- uint32_t token = (uint32_t)GetI4LittleEndian(ip + 2);
- Il2CppClass* objKlass = image->GetClassFromToken(tokenCache, token, klassContainer, methodContainer, genericContext);
- IL2CPP_ASSERT(objKlass);
- int32_t typeSize = GetTypeValueSize(&objKlass->byval_arg);
- CreateAddInst_ldc4(typeSize, EvalStackReduceDataType::I4);
- ip += 6;
- continue;
- }
- case OpcodeValue::REFANYTYPE:
- {
- IL2CPP_ASSERT(evalStackTop > 0);
- CreateAddIR(ir, RefAnyTypeVarVar);
- ir->dst = ir->typedRef = GetEvalStackOffset_1();
- PopStack();
- PushStackByReduceType(NATIVE_INT_REDUCE_TYPE);
- ip += 2;
- continue;
- }
- case OpcodeValue::READONLY_:
- {
- prefixFlags |= (int32_t)PrefixFlags::ReadOnly;
- ip += 2;
- // generic md array also can follow readonly
- //IL2CPP_ASSERT(*ip == (byte)OpcodeValue::LDELEMA && "According to the ECMA spec, READONLY may only precede LDELEMA");
- continue;
- }
- case OpcodeValue::UNUSED53:
- case OpcodeValue::UNUSED54:
- case OpcodeValue::UNUSED55:
- case OpcodeValue::UNUSED70:
- {
- ip += 2;
- continue;
- }
- default:
- {
- //UNREACHABLE();
- RaiseExecutionEngineException("not support instruction");
- continue;
- }
- }
- continue;
- }
- case OpcodeValue::PREFIXREF:
- {
- ip++;
- continue;
- }
- default:
- {
- RaiseExecutionEngineException("not support instruction");
- continue;
- }
- }
- ip++;
- }
- finish_transform:
- totalIRSize = 0;
- for (IRBasicBlock* bb : irbbs)
- {
- bb->codeOffset = totalIRSize;
- for (IRCommon* ir : bb->insts)
- {
- totalIRSize += g_instructionSizes[(int)ir->type];
- }
- }
- endBb->codeOffset = totalIRSize;
- for (int32_t* relocOffsetPtr : relocationOffsets)
- {
- int32_t relocOffset = *relocOffsetPtr;
- IL2CPP_ASSERT(splitOffsets.find(relocOffset) != splitOffsets.end());
- *relocOffsetPtr = ip2bb[relocOffset]->codeOffset;
- }
- for (auto switchOffsetPair : switchOffsetsInResolveData)
- {
- int32_t* offsetStartPtr = (int32_t*)&resolveDatas[switchOffsetPair.first];
- for (int32_t i = 0; i < switchOffsetPair.second; i++)
- {
- int32_t relocOffset = offsetStartPtr[i];
- IL2CPP_ASSERT(splitOffsets.find(relocOffset) != splitOffsets.end());
- offsetStartPtr[i] = ip2bb[relocOffset]->codeOffset;
- }
- }
- }
- void TransformContext::BuildInterpMethodInfo(interpreter::InterpMethodInfo& result)
- {
- il2cpp::utils::dynamic_array<hybridclr::metadata::ILMapper>* ilMappers;
- if (ir2offsetMap)
- {
- ilMappers = new il2cpp::utils::dynamic_array<hybridclr::metadata::ILMapper>();
- ilMappers->reserve(ir2offsetMap->size());
- }
- else
- {
- ilMappers = nullptr;
- }
- byte* tranCodes = (byte*)HYBRIDCLR_METADATA_MALLOC(totalIRSize);
- uint32_t tranOffset = 0;
- for (IRBasicBlock* bb : irbbs)
- {
- //bb->codeOffset = tranOffset;
- for (IRCommon* ir : bb->insts)
- {
- if (ilMappers)
- {
- auto it = ir2offsetMap->find(ir);
- if (it != ir2offsetMap->end())
- {
- hybridclr::metadata::ILMapper ilMapper;
- ilMapper.irOffset = tranOffset;
- ilMapper.ilOffset = it->second;
- ilMappers->push_back(ilMapper);
- }
- }
- uint32_t irSize = g_instructionSizes[(int)ir->type];
- std::memcpy(tranCodes + tranOffset, &ir->type, irSize);
- tranOffset += irSize;
- }
- bb->~IRBasicBlock();
- }
- IL2CPP_ASSERT(tranOffset == totalIRSize);
- for (FlowInfo* fi : pendingFlows)
- {
- fi->~FlowInfo();
- }
- MethodArgDesc* argDescs;
- if (actualParamCount > 0)
- {
- argDescs = (MethodArgDesc*)HYBRIDCLR_METADATA_CALLOC(actualParamCount, sizeof(MethodArgDesc));
- for (int32_t i = 0; i < actualParamCount; i++)
- {
- const Il2CppType* argType = args[i].type;
- TypeDesc typeDesc = GetTypeArgDesc(argType);
- MethodArgDesc& argDesc = argDescs[i];
- argDesc.type = typeDesc.type;
- IL2CPP_ASSERT(typeDesc.stackObjectSize < 0x10000);
- argDesc.stackObjectSize = (uint16_t)typeDesc.stackObjectSize;
- argDesc.passbyValWhenInvoke = argType->byref || !IsValueType(argType);
- }
- }
- else
- {
- argDescs = nullptr;
- }
- result.args = argDescs;
- result.argCount = actualParamCount;
- result.argStackObjectSize = totalArgSize;
- result.retStackObjectSize = IsVoidType(methodInfo->return_type) ? 0 : GetTypeArgDesc(methodInfo->return_type).stackObjectSize;
- result.codes = tranCodes;
- result.codeLength = totalIRSize;
- result.evalStackBaseOffset = evalStackBaseOffset;
- result.localVarBaseOffset = totalArgSize;
- result.localStackSize = totalArgLocalSize;
- result.maxStackSize = maxStackSize;
- result.initLocals = initLocals;
- if (resolveDatas.empty())
- {
- result.resolveDatas = nullptr;
- }
- else
- {
- //result.resolveData = (uint8_t*)HYBRIDCLR_MALLOC(resolveDatas.size() * sizeof(uint8_t));
- size_t dataSize = resolveDatas.size() * sizeof(uint64_t);
- uint64_t* data = (uint64_t*)HYBRIDCLR_METADATA_MALLOC(dataSize);
- std::memcpy(data, resolveDatas.data(), dataSize);
- result.resolveDatas = data;
- }
- if (exClauses.empty())
- {
- result.exClauses = nullptr;
- result.exClauseCount = 0;
- }
- else
- {
- size_t dataSize = exClauses.size() * sizeof(InterpExceptionClause);
- InterpExceptionClause* data = (InterpExceptionClause*)HYBRIDCLR_METADATA_MALLOC(dataSize);
- std::memcpy(data, exClauses.data(), dataSize);
- result.exClauses = data;
- result.exClauseCount = (uint32_t)exClauses.size();
- }
- if (ilMappers)
- {
- image->GetPDBImage()->SetMethodDebugInfo(methodInfo, *ilMappers);
- }
- }
- bool TransformContext::TransformSubMethodBody(TransformContext& callingCtx, const MethodInfo* methodInfo, int32_t depth, int32_t localVarOffset)
- {
- metadata::Image* image = metadata::MetadataModule::GetUnderlyingInterpreterImage(methodInfo);
- IL2CPP_ASSERT(image);
- metadata::MethodBody* methodBody = metadata::MethodBodyCache::GetMethodBody(image, methodInfo->token);
- if (methodBody == nullptr || methodBody->ilcodes == nullptr)
- {
- TEMP_FORMAT(errMsg, "Method body is null. %s.%s::%s", methodInfo->klass->namespaze, methodInfo->klass->name, methodInfo->name);
- il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetExecutionEngineException(errMsg));
- }
- TransformContext ctx(image, methodInfo, *methodBody, callingCtx.pool, callingCtx.resolveDatas);
- try
- {
- ctx.TransformBodyImpl(depth, localVarOffset);
- callingCtx.maxStackSize = std::max(callingCtx.maxStackSize, ctx.maxStackSize);
- callingCtx.curbb->insts.insert(callingCtx.curbb->insts.end(), ctx.curbb->insts.begin(), ctx.curbb->insts.end());
- return true;
- }
- catch (Il2CppExceptionWrapper&)
- {
- //LOG_ERROR("TransformSubMethodBody failed: %s", ex.what());
- metadata::MethodBodyCache::DisableInline(methodInfo);
- return false;
- }
- return false;
- }
- }
- }
|