wasm_interp_classic.c 284 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "wasm_interp.h"
  6. #include "bh_log.h"
  7. #include "wasm_runtime.h"
  8. #include "wasm_opcode.h"
  9. #include "wasm_loader.h"
  10. #include "wasm_memory.h"
  11. #include "../common/wasm_exec_env.h"
  12. #if WASM_ENABLE_GC != 0
  13. #include "../common/gc/gc_object.h"
  14. #include "mem_alloc.h"
  15. #if WASM_ENABLE_STRINGREF != 0
  16. #include "string_object.h"
  17. #endif
  18. #endif
  19. #if WASM_ENABLE_SHARED_MEMORY != 0
  20. #include "../common/wasm_shared_memory.h"
  21. #endif
  22. #if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
  23. #include "../libraries/thread-mgr/thread_manager.h"
  24. #include "../libraries/debug-engine/debug_engine.h"
  25. #endif
  26. #if WASM_ENABLE_FAST_JIT != 0
  27. #include "../fast-jit/jit_compiler.h"
  28. #endif
  29. typedef int32 CellType_I32;
  30. typedef int64 CellType_I64;
  31. typedef float32 CellType_F32;
  32. typedef float64 CellType_F64;
  33. #define BR_TABLE_TMP_BUF_LEN 32
  34. #if WASM_ENABLE_THREAD_MGR == 0
  35. #define get_linear_mem_size() linear_mem_size
  36. #else
  37. /**
  38. * Load memory data size in each time boundary check in
  39. * multi-threading mode since it may be changed by other
  40. * threads in memory.grow
  41. */
  42. #define get_linear_mem_size() GET_LINEAR_MEMORY_SIZE(memory)
  43. #endif
  44. #if WASM_ENABLE_SHARED_HEAP != 0
  45. #if WASM_ENABLE_MULTI_MEMORY != 0
  46. /* Only enable shared heap for the default memory */
  47. #define is_default_memory (memidx == 0)
  48. #else
  49. #define is_default_memory true
  50. #endif
  51. #define app_addr_in_shared_heap(app_addr, bytes) \
  52. (shared_heap && is_default_memory && (app_addr) >= shared_heap_start_off \
  53. && (app_addr) <= shared_heap_end_off - bytes + 1)
  54. #define shared_heap_addr_app_to_native(app_addr, native_addr) \
  55. native_addr = shared_heap_base_addr + ((app_addr)-shared_heap_start_off)
  56. #define CHECK_SHARED_HEAP_OVERFLOW(app_addr, bytes, native_addr) \
  57. if (app_addr_in_shared_heap(app_addr, bytes)) \
  58. shared_heap_addr_app_to_native(app_addr, native_addr); \
  59. else
  60. #else
  61. #define CHECK_SHARED_HEAP_OVERFLOW(app_addr, bytes, native_addr)
  62. #endif
  63. #if WASM_ENABLE_MEMORY64 == 0
  64. #if (!defined(OS_ENABLE_HW_BOUND_CHECK) \
  65. || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0)
  66. #define CHECK_MEMORY_OVERFLOW(bytes) \
  67. do { \
  68. uint64 offset1 = (uint64)offset + (uint64)addr; \
  69. CHECK_SHARED_HEAP_OVERFLOW(offset1, bytes, maddr) \
  70. if (disable_bounds_checks || offset1 + bytes <= get_linear_mem_size()) \
  71. /* If offset1 is in valid range, maddr must also \
  72. be in valid range, no need to check it again. */ \
  73. maddr = memory->memory_data + offset1; \
  74. else \
  75. goto out_of_bounds; \
  76. } while (0)
  77. #define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \
  78. do { \
  79. uint64 offset1 = (uint32)(start); \
  80. CHECK_SHARED_HEAP_OVERFLOW(offset1, bytes, maddr) \
  81. if (disable_bounds_checks || offset1 + bytes <= get_linear_mem_size()) \
  82. /* App heap space is not valid space for \
  83. bulk memory operation */ \
  84. maddr = memory->memory_data + offset1; \
  85. else \
  86. goto out_of_bounds; \
  87. } while (0)
  88. #else /* else of !defined(OS_ENABLE_HW_BOUND_CHECK) || \
  89. WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 */
  90. #define CHECK_MEMORY_OVERFLOW(bytes) \
  91. do { \
  92. uint64 offset1 = (uint64)offset + (uint64)addr; \
  93. CHECK_SHARED_HEAP_OVERFLOW(offset1, bytes, maddr) \
  94. maddr = memory->memory_data + offset1; \
  95. } while (0)
  96. #define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \
  97. do { \
  98. uint64 offset1 = (uint32)(start); \
  99. CHECK_SHARED_HEAP_OVERFLOW(offset1, bytes, maddr) \
  100. maddr = memory->memory_data + offset1; \
  101. } while (0)
  102. #endif /* end of !defined(OS_ENABLE_HW_BOUND_CHECK) || \
  103. WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 */
  104. #else /* else of WASM_ENABLE_MEMORY64 == 0 */
  105. #define CHECK_MEMORY_OVERFLOW(bytes) \
  106. do { \
  107. uint64 offset1 = (uint64)offset + (uint64)addr; \
  108. CHECK_SHARED_HEAP_OVERFLOW(offset1, bytes, maddr) \
  109. /* If memory64 is enabled, offset1, offset1 + bytes can overflow */ \
  110. if (disable_bounds_checks \
  111. || (offset1 >= offset && offset1 + bytes >= offset1 \
  112. && offset1 + bytes <= get_linear_mem_size())) \
  113. maddr = memory->memory_data + offset1; \
  114. else \
  115. goto out_of_bounds; \
  116. } while (0)
  117. #define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \
  118. do { \
  119. uint64 offset1 = (uint64)(start); \
  120. CHECK_SHARED_HEAP_OVERFLOW(offset1, bytes, maddr) \
  121. /* If memory64 is enabled, offset1 + bytes can overflow */ \
  122. if (disable_bounds_checks \
  123. || (offset1 + bytes >= offset1 \
  124. && offset1 + bytes <= get_linear_mem_size())) \
  125. /* App heap space is not valid space for \
  126. bulk memory operation */ \
  127. maddr = memory->memory_data + offset1; \
  128. else \
  129. goto out_of_bounds; \
  130. } while (0)
  131. #endif /* end of WASM_ENABLE_MEMORY64 == 0 */
  132. #define CHECK_ATOMIC_MEMORY_ACCESS() \
  133. do { \
  134. if (((uintptr_t)maddr & (((uintptr_t)1 << align) - 1)) != 0) \
  135. goto unaligned_atomic; \
  136. } while (0)
  137. #if WASM_ENABLE_DEBUG_INTERP != 0
  138. #define TRIGGER_WATCHPOINT_SIGTRAP() \
  139. do { \
  140. wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TRAP); \
  141. CHECK_SUSPEND_FLAGS(); \
  142. } while (0)
  143. #define CHECK_WATCHPOINT(list, current_addr) \
  144. do { \
  145. WASMDebugWatchPoint *watchpoint = bh_list_first_elem(list); \
  146. while (watchpoint) { \
  147. WASMDebugWatchPoint *next = bh_list_elem_next(watchpoint); \
  148. if (watchpoint->addr <= current_addr \
  149. && watchpoint->addr + watchpoint->length > current_addr) { \
  150. TRIGGER_WATCHPOINT_SIGTRAP(); \
  151. } \
  152. watchpoint = next; \
  153. } \
  154. } while (0)
  155. #define CHECK_READ_WATCHPOINT(addr, offset) \
  156. CHECK_WATCHPOINT(watch_point_list_read, WASM_ADDR_OFFSET(addr + offset))
  157. #define CHECK_WRITE_WATCHPOINT(addr, offset) \
  158. CHECK_WATCHPOINT(watch_point_list_write, WASM_ADDR_OFFSET(addr + offset))
  159. #else
  160. #define CHECK_READ_WATCHPOINT(addr, offset) (void)0
  161. #define CHECK_WRITE_WATCHPOINT(addr, offset) (void)0
  162. #endif
  163. static inline uint32
  164. rotl32(uint32 n, uint32 c)
  165. {
  166. const uint32 mask = (31);
  167. c = c % 32;
  168. c &= mask;
  169. return (n << c) | (n >> ((0 - c) & mask));
  170. }
  171. static inline uint32
  172. rotr32(uint32 n, uint32 c)
  173. {
  174. const uint32 mask = (31);
  175. c = c % 32;
  176. c &= mask;
  177. return (n >> c) | (n << ((0 - c) & mask));
  178. }
  179. static inline uint64
  180. rotl64(uint64 n, uint64 c)
  181. {
  182. const uint64 mask = (63);
  183. c = c % 64;
  184. c &= mask;
  185. return (n << c) | (n >> ((0 - c) & mask));
  186. }
  187. static inline uint64
  188. rotr64(uint64 n, uint64 c)
  189. {
  190. const uint64 mask = (63);
  191. c = c % 64;
  192. c &= mask;
  193. return (n >> c) | (n << ((0 - c) & mask));
  194. }
  195. static inline float32
  196. f32_min(float32 a, float32 b)
  197. {
  198. if (isnan(a) || isnan(b))
  199. return NAN;
  200. else if (a == 0 && a == b)
  201. return signbit(a) ? a : b;
  202. else
  203. return a > b ? b : a;
  204. }
  205. static inline float32
  206. f32_max(float32 a, float32 b)
  207. {
  208. if (isnan(a) || isnan(b))
  209. return NAN;
  210. else if (a == 0 && a == b)
  211. return signbit(a) ? b : a;
  212. else
  213. return a > b ? a : b;
  214. }
  215. static inline float64
  216. f64_min(float64 a, float64 b)
  217. {
  218. if (isnan(a) || isnan(b))
  219. return NAN;
  220. else if (a == 0 && a == b)
  221. return signbit(a) ? a : b;
  222. else
  223. return a > b ? b : a;
  224. }
  225. static inline float64
  226. f64_max(float64 a, float64 b)
  227. {
  228. if (isnan(a) || isnan(b))
  229. return NAN;
  230. else if (a == 0 && a == b)
  231. return signbit(a) ? b : a;
  232. else
  233. return a > b ? a : b;
  234. }
  235. static inline uint32
  236. clz32(uint32 type)
  237. {
  238. uint32 num = 0;
  239. if (type == 0)
  240. return 32;
  241. while (!(type & 0x80000000)) {
  242. num++;
  243. type <<= 1;
  244. }
  245. return num;
  246. }
  247. static inline uint32
  248. clz64(uint64 type)
  249. {
  250. uint32 num = 0;
  251. if (type == 0)
  252. return 64;
  253. while (!(type & 0x8000000000000000LL)) {
  254. num++;
  255. type <<= 1;
  256. }
  257. return num;
  258. }
  259. static inline uint32
  260. ctz32(uint32 type)
  261. {
  262. uint32 num = 0;
  263. if (type == 0)
  264. return 32;
  265. while (!(type & 1)) {
  266. num++;
  267. type >>= 1;
  268. }
  269. return num;
  270. }
  271. static inline uint32
  272. ctz64(uint64 type)
  273. {
  274. uint32 num = 0;
  275. if (type == 0)
  276. return 64;
  277. while (!(type & 1)) {
  278. num++;
  279. type >>= 1;
  280. }
  281. return num;
  282. }
  283. static inline uint32
  284. popcount32(uint32 u)
  285. {
  286. uint32 ret = 0;
  287. while (u) {
  288. u = (u & (u - 1));
  289. ret++;
  290. }
  291. return ret;
  292. }
  293. static inline uint32
  294. popcount64(uint64 u)
  295. {
  296. uint32 ret = 0;
  297. while (u) {
  298. u = (u & (u - 1));
  299. ret++;
  300. }
  301. return ret;
  302. }
  303. static float
  304. local_copysignf(float x, float y)
  305. {
  306. union {
  307. float f;
  308. uint32 i;
  309. } ux = { x }, uy = { y };
  310. ux.i &= 0x7fffffff;
  311. ux.i |= uy.i & 0x80000000;
  312. return ux.f;
  313. }
  314. static double
  315. local_copysign(double x, double y)
  316. {
  317. union {
  318. double f;
  319. uint64 i;
  320. } ux = { x }, uy = { y };
  321. ux.i &= UINT64_MAX / 2;
  322. ux.i |= uy.i & 1ULL << 63;
  323. return ux.f;
  324. }
  325. static uint64
  326. read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
  327. {
  328. uint64 result = 0, byte;
  329. uint32 offset = *p_offset;
  330. uint32 shift = 0;
  331. while (true) {
  332. byte = buf[offset++];
  333. result |= ((byte & 0x7f) << shift);
  334. shift += 7;
  335. if ((byte & 0x80) == 0) {
  336. break;
  337. }
  338. }
  339. if (sign && (shift < maxbits) && (byte & 0x40)) {
  340. /* Sign extend */
  341. result |= (~((uint64)0)) << shift;
  342. }
  343. *p_offset = offset;
  344. return result;
  345. }
  346. #if WASM_ENABLE_GC != 0
  347. static uint8 *
  348. get_frame_ref(WASMInterpFrame *frame)
  349. {
  350. WASMFunctionInstance *cur_func = frame->function;
  351. uint32 all_cell_num;
  352. if (!cur_func) {
  353. /* it's a glue frame created in wasm_interp_call_wasm,
  354. no GC object will be traversed */
  355. return (uint8 *)frame->lp;
  356. }
  357. else if (!frame->ip) {
  358. /* it's a native method frame created in
  359. wasm_interp_call_func_native */
  360. all_cell_num =
  361. cur_func->param_cell_num > 2 ? cur_func->param_cell_num : 2;
  362. return (uint8 *)(frame->lp + all_cell_num);
  363. }
  364. else {
  365. #if WASM_ENABLE_JIT == 0
  366. /* it's a wasm bytecode function frame */
  367. return (uint8 *)frame->csp_boundary;
  368. #else
  369. return (uint8 *)(frame->lp + cur_func->param_cell_num
  370. + cur_func->local_cell_num
  371. + cur_func->u.func->max_stack_cell_num);
  372. #endif
  373. }
  374. }
  375. static void
  376. init_frame_refs(uint8 *frame_ref, uint32 cell_num, WASMFunctionInstance *func)
  377. {
  378. uint32 i, j;
  379. memset(frame_ref, 0, cell_num);
  380. for (i = 0, j = 0; i < func->param_count; i++) {
  381. if (wasm_is_type_reftype(func->param_types[i])
  382. && !wasm_is_reftype_i31ref(func->param_types[i])) {
  383. frame_ref[j++] = 1;
  384. #if UINTPTR_MAX == UINT64_MAX
  385. frame_ref[j++] = 1;
  386. #endif
  387. }
  388. else {
  389. j += wasm_value_type_cell_num(func->param_types[i]);
  390. }
  391. }
  392. for (i = 0; i < func->local_count; i++) {
  393. if (wasm_is_type_reftype(func->local_types[i])
  394. && !wasm_is_reftype_i31ref(func->local_types[i])) {
  395. frame_ref[j++] = 1;
  396. #if UINTPTR_MAX == UINT64_MAX
  397. frame_ref[j++] = 1;
  398. #endif
  399. }
  400. else {
  401. j += wasm_value_type_cell_num(func->local_types[i]);
  402. }
  403. }
  404. }
  405. uint8 *
  406. wasm_interp_get_frame_ref(WASMInterpFrame *frame)
  407. {
  408. return get_frame_ref(frame);
  409. }
  410. /* Return the corresponding ref slot of the given address of local
  411. variable or stack pointer. */
  412. #define COMPUTE_FRAME_REF(ref, lp, p) (ref + (unsigned)((uint32 *)p - lp))
  413. #define FRAME_REF(p) COMPUTE_FRAME_REF(frame_ref, frame_lp, p)
  414. #define FRAME_REF_FOR(frame, p) \
  415. COMPUTE_FRAME_REF(get_frame_ref(frame), frame->lp, p)
  416. #define CLEAR_FRAME_REF(p, n) \
  417. do { \
  418. int32 ref_i, ref_n = (int32)(n); \
  419. uint8 *ref = FRAME_REF(p); \
  420. for (ref_i = 0; ref_i < ref_n; ref_i++) \
  421. ref[ref_i] = 0; \
  422. } while (0)
  423. #else
  424. #define CLEAR_FRAME_REF(p, n) (void)0
  425. #endif /* end of WASM_ENABLE_GC != 0 */
  426. #define skip_leb(p) while (*p++ & 0x80)
  427. #define PUSH_I32(value) \
  428. do { \
  429. *(int32 *)frame_sp++ = (int32)(value); \
  430. } while (0)
  431. #define PUSH_F32(value) \
  432. do { \
  433. *(float32 *)frame_sp++ = (float32)(value); \
  434. } while (0)
  435. #define PUSH_I64(value) \
  436. do { \
  437. PUT_I64_TO_ADDR(frame_sp, value); \
  438. frame_sp += 2; \
  439. } while (0)
  440. #define PUSH_F64(value) \
  441. do { \
  442. PUT_F64_TO_ADDR(frame_sp, value); \
  443. frame_sp += 2; \
  444. } while (0)
  445. #if UINTPTR_MAX == UINT64_MAX
  446. #define PUSH_REF(value) \
  447. do { \
  448. PUT_REF_TO_ADDR(frame_sp, value); \
  449. frame_ref_tmp = FRAME_REF(frame_sp); \
  450. *frame_ref_tmp = *(frame_ref_tmp + 1) = 1; \
  451. frame_sp += 2; \
  452. } while (0)
  453. #define PUSH_I31REF(value) \
  454. do { \
  455. PUT_REF_TO_ADDR(frame_sp, value); \
  456. frame_sp += 2; \
  457. } while (0)
  458. #else
  459. #define PUSH_REF(value) \
  460. do { \
  461. PUT_REF_TO_ADDR(frame_sp, value); \
  462. frame_ref_tmp = FRAME_REF(frame_sp); \
  463. *frame_ref_tmp = 1; \
  464. frame_sp++; \
  465. } while (0)
  466. #define PUSH_I31REF(value) \
  467. do { \
  468. PUT_REF_TO_ADDR(frame_sp, value); \
  469. frame_sp++; \
  470. } while (0)
  471. #endif
  472. #if UINTPTR_MAX == UINT64_MAX
  473. #define PUSH_PTR(value) PUSH_I64(value)
  474. #else
  475. #define PUSH_PTR(value) PUSH_I32(value)
  476. #endif
  477. /* in exception handling, label_type needs to be stored to lookup exception
  478. * handlers */
  479. #if WASM_ENABLE_EXCE_HANDLING != 0
  480. #define SET_LABEL_TYPE(_label_type) frame_csp->label_type = _label_type
  481. #else
  482. #define SET_LABEL_TYPE(_label_type) (void)0
  483. #endif
  484. #if WASM_ENABLE_MEMORY64 != 0
  485. #define COND_PUSH_TEMPLATE(cond, value) \
  486. do { \
  487. if (cond) { \
  488. PUT_I64_TO_ADDR(frame_sp, value); \
  489. frame_sp += 2; \
  490. } \
  491. else { \
  492. *(int32 *)frame_sp++ = (int32)(value); \
  493. } \
  494. } while (0)
  495. #define PUSH_MEM_OFFSET(value) COND_PUSH_TEMPLATE(is_memory64, value)
  496. #define PUSH_TBL_ELEM_IDX(value) COND_PUSH_TEMPLATE(is_table64, value)
  497. #else
  498. #define PUSH_MEM_OFFSET(value) PUSH_I32(value)
  499. #define PUSH_TBL_ELEM_IDX(value) PUSH_I32(value)
  500. #endif
  501. #define PUSH_PAGE_COUNT(value) PUSH_MEM_OFFSET(value)
  502. #define PUSH_CSP(_label_type, param_cell_num, cell_num, _target_addr) \
  503. do { \
  504. bh_assert(frame_csp < frame->csp_boundary); \
  505. SET_LABEL_TYPE(_label_type); \
  506. frame_csp->cell_num = cell_num; \
  507. frame_csp->begin_addr = frame_ip; \
  508. frame_csp->target_addr = _target_addr; \
  509. frame_csp->frame_sp = frame_sp - param_cell_num; \
  510. frame_csp++; \
  511. } while (0)
  512. #define POP_I32() (--frame_sp, *(int32 *)frame_sp)
  513. #define POP_F32() (--frame_sp, *(float32 *)frame_sp)
  514. #define POP_I64() (frame_sp -= 2, GET_I64_FROM_ADDR(frame_sp))
  515. #define POP_F64() (frame_sp -= 2, GET_F64_FROM_ADDR(frame_sp))
  516. #if UINTPTR_MAX == UINT64_MAX
  517. #define POP_REF() \
  518. (frame_sp -= 2, frame_ref_tmp = FRAME_REF(frame_sp), \
  519. *frame_ref_tmp = *(frame_ref_tmp + 1) = 0, GET_REF_FROM_ADDR(frame_sp))
  520. #else
  521. #define POP_REF() \
  522. (frame_sp--, frame_ref_tmp = FRAME_REF(frame_sp), *frame_ref_tmp = 0, \
  523. GET_REF_FROM_ADDR(frame_sp))
  524. #endif
  525. #if WASM_ENABLE_MEMORY64 != 0
  526. #define POP_MEM_OFFSET() (is_memory64 ? POP_I64() : (uint32)POP_I32())
  527. #define POP_TBL_ELEM_IDX() (is_table64 ? POP_I64() : (uint32)POP_I32())
  528. #else
  529. #define POP_MEM_OFFSET() POP_I32()
  530. #define POP_TBL_ELEM_IDX() POP_I32()
  531. #endif
  532. #define POP_PAGE_COUNT() POP_MEM_OFFSET()
  533. #define POP_CSP_CHECK_OVERFLOW(n) \
  534. do { \
  535. bh_assert(frame_csp - n >= frame->csp_bottom); \
  536. } while (0)
  537. #define POP_CSP() \
  538. do { \
  539. POP_CSP_CHECK_OVERFLOW(1); \
  540. --frame_csp; \
  541. } while (0)
  542. #define POP_CSP_N(n) \
  543. do { \
  544. uint32 *frame_sp_old = frame_sp; \
  545. uint32 cell_num_to_copy; \
  546. POP_CSP_CHECK_OVERFLOW(n + 1); \
  547. frame_csp -= n; \
  548. frame_ip = (frame_csp - 1)->target_addr; \
  549. /* copy arity values of block */ \
  550. frame_sp = (frame_csp - 1)->frame_sp; \
  551. cell_num_to_copy = (frame_csp - 1)->cell_num; \
  552. if (cell_num_to_copy > 0) { \
  553. word_copy(frame_sp, frame_sp_old - cell_num_to_copy, \
  554. cell_num_to_copy); \
  555. frame_ref_copy(FRAME_REF(frame_sp), \
  556. FRAME_REF(frame_sp_old - cell_num_to_copy), \
  557. cell_num_to_copy); \
  558. } \
  559. frame_sp += cell_num_to_copy; \
  560. CLEAR_FRAME_REF(frame_sp, frame_sp_old - frame_sp); \
  561. } while (0)
  562. /* Pop the given number of elements from the given frame's stack. */
  563. #define POP(N) \
  564. do { \
  565. int n = (N); \
  566. frame_sp -= n; \
  567. CLEAR_FRAME_REF(frame_sp, n); \
  568. } while (0)
  569. #if WASM_ENABLE_EXCE_HANDLING != 0
  570. /* unwind the CSP to a given label and optionally modify the labeltype */
  571. #define UNWIND_CSP(N, T) \
  572. do { \
  573. /* unwind to function frame */ \
  574. frame_csp -= N; \
  575. /* drop handlers and values pushd in try block */ \
  576. frame_sp = (frame_csp - 1)->frame_sp; \
  577. (frame_csp - 1)->label_type = T ? T : (frame_csp - 1)->label_type; \
  578. } while (0)
  579. #endif
  580. #define SYNC_ALL_TO_FRAME() \
  581. do { \
  582. frame->sp = frame_sp; \
  583. frame->ip = frame_ip; \
  584. frame->csp = frame_csp; \
  585. } while (0)
  586. #define UPDATE_ALL_FROM_FRAME() \
  587. do { \
  588. frame_sp = frame->sp; \
  589. frame_ip = frame->ip; \
  590. frame_csp = frame->csp; \
  591. } while (0)
  592. #define read_leb_int64(p, p_end, res) \
  593. do { \
  594. uint8 _val = *p; \
  595. if (!(_val & 0x80)) { \
  596. res = (int64)_val; \
  597. if (_val & 0x40) \
  598. /* sign extend */ \
  599. res |= 0xFFFFFFFFFFFFFF80LL; \
  600. p++; \
  601. } \
  602. else { \
  603. uint32 _off = 0; \
  604. res = (int64)read_leb(p, &_off, 64, true); \
  605. p += _off; \
  606. } \
  607. } while (0)
  608. #define read_leb_uint32(p, p_end, res) \
  609. do { \
  610. uint8 _val = *p; \
  611. if (!(_val & 0x80)) { \
  612. res = _val; \
  613. p++; \
  614. } \
  615. else { \
  616. uint32 _off = 0; \
  617. res = (uint32)read_leb(p, &_off, 32, false); \
  618. p += _off; \
  619. } \
  620. } while (0)
  621. #define read_leb_int32(p, p_end, res) \
  622. do { \
  623. uint8 _val = *p; \
  624. if (!(_val & 0x80)) { \
  625. res = (int32)_val; \
  626. if (_val & 0x40) \
  627. /* sign extend */ \
  628. res |= 0xFFFFFF80; \
  629. p++; \
  630. } \
  631. else { \
  632. uint32 _off = 0; \
  633. res = (int32)read_leb(p, &_off, 32, true); \
  634. p += _off; \
  635. } \
  636. } while (0)
  637. #if WASM_ENABLE_MEMORY64 != 0
  638. #define read_leb_mem_offset(p, p_end, res) \
  639. do { \
  640. uint8 _val = *p; \
  641. if (!(_val & 0x80)) { \
  642. res = (mem_offset_t)_val; \
  643. p++; \
  644. } \
  645. else { \
  646. uint32 _off = 0; \
  647. res = (mem_offset_t)read_leb(p, &_off, is_memory64 ? 64 : 32, \
  648. false); \
  649. p += _off; \
  650. } \
  651. } while (0)
  652. #else
  653. #define read_leb_mem_offset(p, p_end, res) read_leb_uint32(p, p_end, res)
  654. #endif
  655. #if WASM_ENABLE_MULTI_MEMORY != 0
  656. /* If the current memidx differs than the last cached one,
  657. * update memory related information */
  658. #define read_leb_memidx(p, p_end, res) \
  659. do { \
  660. read_leb_uint32(p, p_end, res); \
  661. if (res != memidx_cached) { \
  662. memory = wasm_get_memory_with_idx(module, res); \
  663. linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory); \
  664. memidx_cached = res; \
  665. } \
  666. } while (0)
  667. /* First read the alignment, then if it has flag indicating following memidx,
  668. * read and update memory related information, if it differs than the
  669. * last(cached) one. If it doesn't have flag reset the
  670. * memory instance to the default memories[0] */
  671. #define read_leb_memarg(p, p_end, res) \
  672. do { \
  673. read_leb_uint32(p, p_end, res); \
  674. if (!(res & OPT_MEMIDX_FLAG)) \
  675. memidx = 0; \
  676. else \
  677. read_leb_uint32(p, p_end, memidx); \
  678. if (memidx != memidx_cached) { \
  679. memory = wasm_get_memory_with_idx(module, memidx); \
  680. linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory); \
  681. memidx_cached = memidx; \
  682. } \
  683. } while (0)
  684. #else
  685. #define read_leb_memarg(p, p_end, res) \
  686. do { \
  687. read_leb_uint32(p, p_end, res); \
  688. (void)res; \
  689. } while (0)
  690. #define read_leb_memidx(p, p_end, res) read_leb_memarg(p, p_end, res)
  691. #endif
  692. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  693. #define RECOVER_FRAME_IP_END() frame_ip_end = wasm_get_func_code_end(cur_func)
  694. #else
  695. #define RECOVER_FRAME_IP_END() (void)0
  696. #endif
  697. #if WASM_ENABLE_GC != 0
  698. #define RECOVER_FRAME_REF() frame_ref = (uint8 *)frame->csp_boundary
  699. #else
  700. #define RECOVER_FRAME_REF() (void)0
  701. #endif
  702. #define RECOVER_CONTEXT(new_frame) \
  703. do { \
  704. frame = (new_frame); \
  705. cur_func = frame->function; \
  706. prev_frame = frame->prev_frame; \
  707. frame_ip = frame->ip; \
  708. RECOVER_FRAME_IP_END(); \
  709. frame_lp = frame->lp; \
  710. frame_sp = frame->sp; \
  711. frame_csp = frame->csp; \
  712. RECOVER_FRAME_REF(); \
  713. } while (0)
  714. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  715. #define GET_OPCODE() opcode = *(frame_ip - 1);
  716. #else
  717. #define GET_OPCODE() (void)0
  718. #endif
  719. #define DEF_OP_I_CONST(ctype, src_op_type) \
  720. do { \
  721. ctype cval; \
  722. read_leb_##ctype(frame_ip, frame_ip_end, cval); \
  723. PUSH_##src_op_type(cval); \
  724. } while (0)
  725. #define DEF_OP_EQZ(src_op_type) \
  726. do { \
  727. int32 pop_val; \
  728. pop_val = POP_##src_op_type() == 0; \
  729. PUSH_I32(pop_val); \
  730. } while (0)
  731. #define DEF_OP_CMP(src_type, src_op_type, cond) \
  732. do { \
  733. uint32 res; \
  734. src_type val1, val2; \
  735. val2 = (src_type)POP_##src_op_type(); \
  736. val1 = (src_type)POP_##src_op_type(); \
  737. res = val1 cond val2; \
  738. PUSH_I32(res); \
  739. } while (0)
  740. #define DEF_OP_BIT_COUNT(src_type, src_op_type, operation) \
  741. do { \
  742. src_type val1, val2; \
  743. val1 = (src_type)POP_##src_op_type(); \
  744. val2 = (src_type)operation(val1); \
  745. PUSH_##src_op_type(val2); \
  746. } while (0)
  747. #define DEF_OP_NUMERIC(src_type1, src_type2, src_op_type, operation) \
  748. do { \
  749. frame_sp -= sizeof(src_type2) / sizeof(uint32); \
  750. *(src_type1 *)(frame_sp - sizeof(src_type1) / sizeof(uint32)) \
  751. operation## = *(src_type2 *)(frame_sp); \
  752. } while (0)
  753. #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
  754. #define DEF_OP_NUMERIC_64 DEF_OP_NUMERIC
  755. #else
  756. #define DEF_OP_NUMERIC_64(src_type1, src_type2, src_op_type, operation) \
  757. do { \
  758. src_type1 val1; \
  759. src_type2 val2; \
  760. frame_sp -= 2; \
  761. val1 = (src_type1)GET_##src_op_type##_FROM_ADDR(frame_sp - 2); \
  762. val2 = (src_type2)GET_##src_op_type##_FROM_ADDR(frame_sp); \
  763. val1 operation## = val2; \
  764. PUT_##src_op_type##_TO_ADDR(frame_sp - 2, val1); \
  765. } while (0)
  766. #endif
  767. #define DEF_OP_NUMERIC2(src_type1, src_type2, src_op_type, operation) \
  768. do { \
  769. frame_sp -= sizeof(src_type2) / sizeof(uint32); \
  770. *(src_type1 *)(frame_sp - sizeof(src_type1) / sizeof(uint32)) \
  771. operation## = (*(src_type2 *)(frame_sp) % 32); \
  772. } while (0)
  773. #define DEF_OP_NUMERIC2_64(src_type1, src_type2, src_op_type, operation) \
  774. do { \
  775. src_type1 val1; \
  776. src_type2 val2; \
  777. frame_sp -= 2; \
  778. val1 = (src_type1)GET_##src_op_type##_FROM_ADDR(frame_sp - 2); \
  779. val2 = (src_type2)GET_##src_op_type##_FROM_ADDR(frame_sp); \
  780. val1 operation## = (val2 % 64); \
  781. PUT_##src_op_type##_TO_ADDR(frame_sp - 2, val1); \
  782. } while (0)
  783. #define DEF_OP_MATH(src_type, src_op_type, method) \
  784. do { \
  785. src_type src_val; \
  786. src_val = POP_##src_op_type(); \
  787. PUSH_##src_op_type(method(src_val)); \
  788. } while (0)
  789. #define TRUNC_FUNCTION(func_name, src_type, dst_type, signed_type) \
  790. static dst_type func_name(src_type src_value, src_type src_min, \
  791. src_type src_max, dst_type dst_min, \
  792. dst_type dst_max, bool is_sign) \
  793. { \
  794. dst_type dst_value = 0; \
  795. if (!isnan(src_value)) { \
  796. if (src_value <= src_min) \
  797. dst_value = dst_min; \
  798. else if (src_value >= src_max) \
  799. dst_value = dst_max; \
  800. else { \
  801. if (is_sign) \
  802. dst_value = (dst_type)(signed_type)src_value; \
  803. else \
  804. dst_value = (dst_type)src_value; \
  805. } \
  806. } \
  807. return dst_value; \
  808. }
  809. TRUNC_FUNCTION(trunc_f32_to_i32, float32, uint32, int32)
  810. TRUNC_FUNCTION(trunc_f32_to_i64, float32, uint64, int64)
  811. TRUNC_FUNCTION(trunc_f64_to_i32, float64, uint32, int32)
  812. TRUNC_FUNCTION(trunc_f64_to_i64, float64, uint64, int64)
  813. static bool
  814. trunc_f32_to_int(WASMModuleInstance *module, uint32 *frame_sp, float32 src_min,
  815. float32 src_max, bool saturating, bool is_i32, bool is_sign)
  816. {
  817. float32 src_value = POP_F32();
  818. uint64 dst_value_i64;
  819. uint32 dst_value_i32;
  820. if (!saturating) {
  821. if (isnan(src_value)) {
  822. wasm_set_exception(module, "invalid conversion to integer");
  823. return false;
  824. }
  825. else if (src_value <= src_min || src_value >= src_max) {
  826. wasm_set_exception(module, "integer overflow");
  827. return false;
  828. }
  829. }
  830. if (is_i32) {
  831. uint32 dst_min = is_sign ? INT32_MIN : 0;
  832. uint32 dst_max = is_sign ? INT32_MAX : UINT32_MAX;
  833. dst_value_i32 = trunc_f32_to_i32(src_value, src_min, src_max, dst_min,
  834. dst_max, is_sign);
  835. PUSH_I32(dst_value_i32);
  836. }
  837. else {
  838. uint64 dst_min = is_sign ? INT64_MIN : 0;
  839. uint64 dst_max = is_sign ? INT64_MAX : UINT64_MAX;
  840. dst_value_i64 = trunc_f32_to_i64(src_value, src_min, src_max, dst_min,
  841. dst_max, is_sign);
  842. PUSH_I64(dst_value_i64);
  843. }
  844. return true;
  845. }
  846. static bool
  847. trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min,
  848. float64 src_max, bool saturating, bool is_i32, bool is_sign)
  849. {
  850. float64 src_value = POP_F64();
  851. uint64 dst_value_i64;
  852. uint32 dst_value_i32;
  853. if (!saturating) {
  854. if (isnan(src_value)) {
  855. wasm_set_exception(module, "invalid conversion to integer");
  856. return false;
  857. }
  858. else if (src_value <= src_min || src_value >= src_max) {
  859. wasm_set_exception(module, "integer overflow");
  860. return false;
  861. }
  862. }
  863. if (is_i32) {
  864. uint32 dst_min = is_sign ? INT32_MIN : 0;
  865. uint32 dst_max = is_sign ? INT32_MAX : UINT32_MAX;
  866. dst_value_i32 = trunc_f64_to_i32(src_value, src_min, src_max, dst_min,
  867. dst_max, is_sign);
  868. PUSH_I32(dst_value_i32);
  869. }
  870. else {
  871. uint64 dst_min = is_sign ? INT64_MIN : 0;
  872. uint64 dst_max = is_sign ? INT64_MAX : UINT64_MAX;
  873. dst_value_i64 = trunc_f64_to_i64(src_value, src_min, src_max, dst_min,
  874. dst_max, is_sign);
  875. PUSH_I64(dst_value_i64);
  876. }
  877. return true;
  878. }
  879. #define DEF_OP_TRUNC_F32(min, max, is_i32, is_sign) \
  880. do { \
  881. if (!trunc_f32_to_int(module, frame_sp, min, max, false, is_i32, \
  882. is_sign)) \
  883. goto got_exception; \
  884. } while (0)
  885. #define DEF_OP_TRUNC_F64(min, max, is_i32, is_sign) \
  886. do { \
  887. if (!trunc_f64_to_int(module, frame_sp, min, max, false, is_i32, \
  888. is_sign)) \
  889. goto got_exception; \
  890. } while (0)
  891. #define DEF_OP_TRUNC_SAT_F32(min, max, is_i32, is_sign) \
  892. do { \
  893. (void)trunc_f32_to_int(module, frame_sp, min, max, true, is_i32, \
  894. is_sign); \
  895. } while (0)
  896. #define DEF_OP_TRUNC_SAT_F64(min, max, is_i32, is_sign) \
  897. do { \
  898. (void)trunc_f64_to_int(module, frame_sp, min, max, true, is_i32, \
  899. is_sign); \
  900. } while (0)
  901. #define DEF_OP_CONVERT(dst_type, dst_op_type, src_type, src_op_type) \
  902. do { \
  903. dst_type value = (dst_type)(src_type)POP_##src_op_type(); \
  904. PUSH_##dst_op_type(value); \
  905. } while (0)
  906. #define GET_LOCAL_INDEX_TYPE_AND_OFFSET() \
  907. do { \
  908. uint32 param_count = cur_func->param_count; \
  909. read_leb_uint32(frame_ip, frame_ip_end, local_idx); \
  910. bh_assert(local_idx < param_count + cur_func->local_count); \
  911. local_offset = cur_func->local_offsets[local_idx]; \
  912. if (local_idx < param_count) \
  913. local_type = cur_func->param_types[local_idx]; \
  914. else \
  915. local_type = cur_func->local_types[local_idx - param_count]; \
  916. } while (0)
  917. #define DEF_ATOMIC_RMW_OPCODE(OP_NAME, op) \
  918. case WASM_OP_ATOMIC_RMW_I32_##OP_NAME: \
  919. case WASM_OP_ATOMIC_RMW_I32_##OP_NAME##8_U: \
  920. case WASM_OP_ATOMIC_RMW_I32_##OP_NAME##16_U: \
  921. { \
  922. uint32 readv, sval; \
  923. \
  924. sval = POP_I32(); \
  925. addr = POP_MEM_OFFSET(); \
  926. \
  927. if (opcode == WASM_OP_ATOMIC_RMW_I32_##OP_NAME##8_U) { \
  928. CHECK_MEMORY_OVERFLOW(1); \
  929. CHECK_ATOMIC_MEMORY_ACCESS(); \
  930. \
  931. shared_memory_lock(memory); \
  932. readv = (uint32)(*(uint8 *)maddr); \
  933. *(uint8 *)maddr = (uint8)(readv op sval); \
  934. shared_memory_unlock(memory); \
  935. } \
  936. else if (opcode == WASM_OP_ATOMIC_RMW_I32_##OP_NAME##16_U) { \
  937. CHECK_MEMORY_OVERFLOW(2); \
  938. CHECK_ATOMIC_MEMORY_ACCESS(); \
  939. \
  940. shared_memory_lock(memory); \
  941. readv = (uint32)LOAD_U16(maddr); \
  942. STORE_U16(maddr, (uint16)(readv op sval)); \
  943. shared_memory_unlock(memory); \
  944. } \
  945. else { \
  946. CHECK_MEMORY_OVERFLOW(4); \
  947. CHECK_ATOMIC_MEMORY_ACCESS(); \
  948. \
  949. shared_memory_lock(memory); \
  950. readv = LOAD_I32(maddr); \
  951. STORE_U32(maddr, readv op sval); \
  952. shared_memory_unlock(memory); \
  953. } \
  954. PUSH_I32(readv); \
  955. break; \
  956. } \
  957. case WASM_OP_ATOMIC_RMW_I64_##OP_NAME: \
  958. case WASM_OP_ATOMIC_RMW_I64_##OP_NAME##8_U: \
  959. case WASM_OP_ATOMIC_RMW_I64_##OP_NAME##16_U: \
  960. case WASM_OP_ATOMIC_RMW_I64_##OP_NAME##32_U: \
  961. { \
  962. uint64 readv, sval; \
  963. \
  964. sval = (uint64)POP_I64(); \
  965. addr = POP_MEM_OFFSET(); \
  966. \
  967. if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##8_U) { \
  968. CHECK_MEMORY_OVERFLOW(1); \
  969. CHECK_ATOMIC_MEMORY_ACCESS(); \
  970. \
  971. shared_memory_lock(memory); \
  972. readv = (uint64)(*(uint8 *)maddr); \
  973. *(uint8 *)maddr = (uint8)(readv op sval); \
  974. shared_memory_unlock(memory); \
  975. } \
  976. else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##16_U) { \
  977. CHECK_MEMORY_OVERFLOW(2); \
  978. CHECK_ATOMIC_MEMORY_ACCESS(); \
  979. \
  980. shared_memory_lock(memory); \
  981. readv = (uint64)LOAD_U16(maddr); \
  982. STORE_U16(maddr, (uint16)(readv op sval)); \
  983. shared_memory_unlock(memory); \
  984. } \
  985. else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##32_U) { \
  986. CHECK_MEMORY_OVERFLOW(4); \
  987. CHECK_ATOMIC_MEMORY_ACCESS(); \
  988. \
  989. shared_memory_lock(memory); \
  990. readv = (uint64)LOAD_U32(maddr); \
  991. STORE_U32(maddr, (uint32)(readv op sval)); \
  992. shared_memory_unlock(memory); \
  993. } \
  994. else { \
  995. uint64 op_result; \
  996. CHECK_MEMORY_OVERFLOW(8); \
  997. CHECK_ATOMIC_MEMORY_ACCESS(); \
  998. \
  999. shared_memory_lock(memory); \
  1000. readv = (uint64)LOAD_I64(maddr); \
  1001. op_result = readv op sval; \
  1002. STORE_I64(maddr, op_result); \
  1003. shared_memory_unlock(memory); \
  1004. } \
  1005. PUSH_I64(readv); \
  1006. break; \
  1007. }
  1008. static inline int32
  1009. sign_ext_8_32(int8 val)
  1010. {
  1011. if (val & 0x80)
  1012. return (int32)val | (int32)0xffffff00;
  1013. return val;
  1014. }
  1015. static inline int32
  1016. sign_ext_16_32(int16 val)
  1017. {
  1018. if (val & 0x8000)
  1019. return (int32)val | (int32)0xffff0000;
  1020. return val;
  1021. }
  1022. static inline int64
  1023. sign_ext_8_64(int8 val)
  1024. {
  1025. if (val & 0x80)
  1026. return (int64)val | (int64)0xffffffffffffff00LL;
  1027. return val;
  1028. }
  1029. static inline int64
  1030. sign_ext_16_64(int16 val)
  1031. {
  1032. if (val & 0x8000)
  1033. return (int64)val | (int64)0xffffffffffff0000LL;
  1034. return val;
  1035. }
  1036. static inline int64
  1037. sign_ext_32_64(int32 val)
  1038. {
  1039. if (val & (int32)0x80000000)
  1040. return (int64)val | (int64)0xffffffff00000000LL;
  1041. return val;
  1042. }
  1043. static inline void
  1044. word_copy(uint32 *dest, uint32 *src, unsigned num)
  1045. {
  1046. bh_assert(dest != NULL);
  1047. bh_assert(src != NULL);
  1048. bh_assert(num > 0);
  1049. if (dest != src) {
  1050. /* No overlap buffer */
  1051. bh_assert(!((src < dest) && (dest < src + num)));
  1052. for (; num > 0; num--)
  1053. *dest++ = *src++;
  1054. }
  1055. }
  1056. #if WASM_ENABLE_GC != 0
  1057. static inline void
  1058. frame_ref_copy(uint8 *frame_ref_dest, uint8 *frame_ref_src, unsigned num)
  1059. {
  1060. if (frame_ref_dest != frame_ref_src)
  1061. for (; num > 0; num--)
  1062. *frame_ref_dest++ = *frame_ref_src++;
  1063. }
  1064. #else
  1065. #define frame_ref_copy(frame_ref_dst, frame_ref_src, num) (void)0
  1066. #endif
  1067. static inline WASMInterpFrame *
  1068. ALLOC_FRAME(WASMExecEnv *exec_env, uint32 size, WASMInterpFrame *prev_frame)
  1069. {
  1070. WASMInterpFrame *frame = wasm_exec_env_alloc_wasm_frame(exec_env, size);
  1071. if (frame) {
  1072. frame->prev_frame = prev_frame;
  1073. #if WASM_ENABLE_PERF_PROFILING != 0
  1074. frame->time_started = os_time_thread_cputime_us();
  1075. #endif
  1076. }
  1077. else {
  1078. wasm_set_exception((WASMModuleInstance *)exec_env->module_inst,
  1079. "wasm operand stack overflow");
  1080. }
  1081. return frame;
  1082. }
  1083. static inline void
  1084. FREE_FRAME(WASMExecEnv *exec_env, WASMInterpFrame *frame)
  1085. {
  1086. #if WASM_ENABLE_PERF_PROFILING != 0
  1087. if (frame->function) {
  1088. WASMInterpFrame *prev_frame = frame->prev_frame;
  1089. uint64 time_elapsed = os_time_thread_cputime_us() - frame->time_started;
  1090. frame->function->total_exec_time += time_elapsed;
  1091. frame->function->total_exec_cnt++;
  1092. if (prev_frame && prev_frame->function)
  1093. prev_frame->function->children_exec_time += time_elapsed;
  1094. }
  1095. #endif
  1096. wasm_exec_env_free_wasm_frame(exec_env, frame);
  1097. }
  1098. static void
  1099. wasm_interp_call_func_native(WASMModuleInstance *module_inst,
  1100. WASMExecEnv *exec_env,
  1101. WASMFunctionInstance *cur_func,
  1102. WASMInterpFrame *prev_frame)
  1103. {
  1104. WASMFunctionImport *func_import = cur_func->u.func_import;
  1105. CApiFuncImport *c_api_func_import = NULL;
  1106. unsigned local_cell_num =
  1107. cur_func->param_cell_num > 2 ? cur_func->param_cell_num : 2;
  1108. unsigned all_cell_num;
  1109. WASMInterpFrame *frame;
  1110. uint32 argv_ret[2], cur_func_index;
  1111. void *native_func_pointer = NULL;
  1112. char buf[128];
  1113. bool ret;
  1114. #if WASM_ENABLE_GC != 0
  1115. WASMFuncType *func_type;
  1116. uint8 *frame_ref;
  1117. #endif
  1118. if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
  1119. return;
  1120. }
  1121. all_cell_num = local_cell_num;
  1122. #if WASM_ENABLE_GC != 0
  1123. all_cell_num += (local_cell_num + 3) / 4;
  1124. #endif
  1125. if (!(frame =
  1126. ALLOC_FRAME(exec_env, wasm_interp_interp_frame_size(all_cell_num),
  1127. prev_frame)))
  1128. return;
  1129. frame->function = cur_func;
  1130. frame->ip = NULL;
  1131. frame->sp = frame->lp + local_cell_num;
  1132. #if WASM_ENABLE_GC != 0
  1133. /* native function doesn't have operand stack and label stack */
  1134. frame_ref = (uint8 *)frame->sp;
  1135. init_frame_refs(frame_ref, local_cell_num, cur_func);
  1136. #endif
  1137. wasm_exec_env_set_cur_frame(exec_env, frame);
  1138. cur_func_index = (uint32)(cur_func - module_inst->e->functions);
  1139. bh_assert(cur_func_index < module_inst->module->import_function_count);
  1140. if (!func_import->call_conv_wasm_c_api) {
  1141. native_func_pointer = module_inst->import_func_ptrs[cur_func_index];
  1142. }
  1143. else if (module_inst->c_api_func_imports) {
  1144. c_api_func_import = module_inst->c_api_func_imports + cur_func_index;
  1145. native_func_pointer = c_api_func_import->func_ptr_linked;
  1146. }
  1147. if (!native_func_pointer) {
  1148. snprintf(buf, sizeof(buf),
  1149. "failed to call unlinked import function (%s, %s)",
  1150. func_import->module_name, func_import->field_name);
  1151. wasm_set_exception(module_inst, buf);
  1152. return;
  1153. }
  1154. if (func_import->call_conv_wasm_c_api) {
  1155. ret = wasm_runtime_invoke_c_api_native(
  1156. (WASMModuleInstanceCommon *)module_inst, native_func_pointer,
  1157. func_import->func_type, cur_func->param_cell_num, frame->lp,
  1158. c_api_func_import->with_env_arg, c_api_func_import->env_arg);
  1159. if (ret) {
  1160. argv_ret[0] = frame->lp[0];
  1161. argv_ret[1] = frame->lp[1];
  1162. }
  1163. }
  1164. else if (!func_import->call_conv_raw) {
  1165. ret = wasm_runtime_invoke_native(
  1166. exec_env, native_func_pointer, func_import->func_type,
  1167. func_import->signature, func_import->attachment, frame->lp,
  1168. cur_func->param_cell_num, argv_ret);
  1169. }
  1170. else {
  1171. ret = wasm_runtime_invoke_native_raw(
  1172. exec_env, native_func_pointer, func_import->func_type,
  1173. func_import->signature, func_import->attachment, frame->lp,
  1174. cur_func->param_cell_num, argv_ret);
  1175. }
  1176. if (!ret)
  1177. return;
  1178. #if WASM_ENABLE_GC != 0
  1179. func_type = cur_func->u.func_import->func_type;
  1180. if (func_type->result_count
  1181. && wasm_is_type_reftype(func_type->types[cur_func->param_count])) {
  1182. frame_ref = (uint8 *)prev_frame->csp_boundary
  1183. + (unsigned)(uintptr_t)(prev_frame->sp - prev_frame->lp);
  1184. if (!wasm_is_reftype_i31ref(func_type->types[cur_func->param_count])) {
  1185. #if UINTPTR_MAX == UINT64_MAX
  1186. *frame_ref = *(frame_ref + 1) = 1;
  1187. #else
  1188. *frame_ref = 1;
  1189. #endif
  1190. }
  1191. }
  1192. #endif
  1193. if (cur_func->ret_cell_num == 1) {
  1194. prev_frame->sp[0] = argv_ret[0];
  1195. prev_frame->sp++;
  1196. }
  1197. else if (cur_func->ret_cell_num == 2) {
  1198. prev_frame->sp[0] = argv_ret[0];
  1199. prev_frame->sp[1] = argv_ret[1];
  1200. prev_frame->sp += 2;
  1201. }
  1202. FREE_FRAME(exec_env, frame);
  1203. wasm_exec_env_set_cur_frame(exec_env, prev_frame);
  1204. }
  1205. #if WASM_ENABLE_FAST_JIT != 0
  1206. bool
  1207. fast_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
  1208. WASMInterpFrame *prev_frame)
  1209. {
  1210. WASMModuleInstance *module_inst =
  1211. (WASMModuleInstance *)exec_env->module_inst;
  1212. WASMFunctionInstance *cur_func = module_inst->e->functions + func_idx;
  1213. wasm_interp_call_func_native(module_inst, exec_env, cur_func, prev_frame);
  1214. return wasm_copy_exception(module_inst, NULL) ? false : true;
  1215. }
  1216. #endif
  1217. #if WASM_ENABLE_MULTI_MODULE != 0
  1218. static void
  1219. wasm_interp_call_func_bytecode(WASMModuleInstance *module,
  1220. WASMExecEnv *exec_env,
  1221. WASMFunctionInstance *cur_func,
  1222. WASMInterpFrame *prev_frame);
  1223. static void
  1224. wasm_interp_call_func_import(WASMModuleInstance *module_inst,
  1225. WASMExecEnv *exec_env,
  1226. WASMFunctionInstance *cur_func,
  1227. WASMInterpFrame *prev_frame)
  1228. {
  1229. WASMModuleInstance *sub_module_inst = cur_func->import_module_inst;
  1230. WASMFunctionInstance *sub_func_inst = cur_func->import_func_inst;
  1231. WASMFunctionImport *func_import = cur_func->u.func_import;
  1232. uint8 *ip = prev_frame->ip;
  1233. char buf[128];
  1234. WASMExecEnv *sub_module_exec_env = NULL;
  1235. uintptr_t aux_stack_origin_boundary = 0;
  1236. uintptr_t aux_stack_origin_bottom = 0;
  1237. /*
  1238. * perform stack overflow check before calling
  1239. * wasm_interp_call_func_bytecode recursively.
  1240. */
  1241. if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
  1242. return;
  1243. }
  1244. if (!sub_func_inst) {
  1245. snprintf(buf, sizeof(buf),
  1246. "failed to call unlinked import function (%s, %s)",
  1247. func_import->module_name, func_import->field_name);
  1248. wasm_set_exception(module_inst, buf);
  1249. return;
  1250. }
  1251. /* Switch exec_env but keep using the same one by replacing necessary
  1252. * variables */
  1253. sub_module_exec_env = wasm_runtime_get_exec_env_singleton(
  1254. (WASMModuleInstanceCommon *)sub_module_inst);
  1255. if (!sub_module_exec_env) {
  1256. wasm_set_exception(module_inst, "create singleton exec_env failed");
  1257. return;
  1258. }
  1259. /* - module_inst */
  1260. wasm_exec_env_set_module_inst(exec_env,
  1261. (WASMModuleInstanceCommon *)sub_module_inst);
  1262. /* - aux_stack_boundary */
  1263. aux_stack_origin_boundary = exec_env->aux_stack_boundary;
  1264. exec_env->aux_stack_boundary = sub_module_exec_env->aux_stack_boundary;
  1265. /* - aux_stack_bottom */
  1266. aux_stack_origin_bottom = exec_env->aux_stack_bottom;
  1267. exec_env->aux_stack_bottom = sub_module_exec_env->aux_stack_bottom;
  1268. /* set ip NULL to make call_func_bytecode return after executing
  1269. this function */
  1270. prev_frame->ip = NULL;
  1271. /* call function of sub-module*/
  1272. wasm_interp_call_func_bytecode(sub_module_inst, exec_env, sub_func_inst,
  1273. prev_frame);
  1274. /* restore ip and other replaced */
  1275. prev_frame->ip = ip;
  1276. exec_env->aux_stack_boundary = aux_stack_origin_boundary;
  1277. exec_env->aux_stack_bottom = aux_stack_origin_bottom;
  1278. wasm_exec_env_restore_module_inst(exec_env,
  1279. (WASMModuleInstanceCommon *)module_inst);
  1280. }
  1281. #endif
  1282. #if WASM_ENABLE_THREAD_MGR != 0
  1283. #if WASM_ENABLE_DEBUG_INTERP != 0
  1284. #define CHECK_SUSPEND_FLAGS() \
  1285. do { \
  1286. os_mutex_lock(&exec_env->wait_lock); \
  1287. if (IS_WAMR_TERM_SIG(exec_env->current_status->signal_flag)) { \
  1288. os_mutex_unlock(&exec_env->wait_lock); \
  1289. return; \
  1290. } \
  1291. if (IS_WAMR_STOP_SIG(exec_env->current_status->signal_flag)) { \
  1292. SYNC_ALL_TO_FRAME(); \
  1293. wasm_cluster_thread_waiting_run(exec_env); \
  1294. } \
  1295. os_mutex_unlock(&exec_env->wait_lock); \
  1296. } while (0)
  1297. #else
  1298. #if WASM_SUSPEND_FLAGS_IS_ATOMIC != 0
  1299. /* The lock is only needed when the suspend_flags is atomic; otherwise
  1300. the lock is already taken at the time when SUSPENSION_LOCK() is called. */
  1301. #define SUSPENSION_LOCK() os_mutex_lock(&exec_env->wait_lock);
  1302. #define SUSPENSION_UNLOCK() os_mutex_unlock(&exec_env->wait_lock);
  1303. #else
  1304. #define SUSPENSION_LOCK()
  1305. #define SUSPENSION_UNLOCK()
  1306. #endif
  1307. #define CHECK_SUSPEND_FLAGS() \
  1308. do { \
  1309. WASM_SUSPEND_FLAGS_LOCK(exec_env->wait_lock); \
  1310. if (WASM_SUSPEND_FLAGS_GET(exec_env->suspend_flags) \
  1311. & WASM_SUSPEND_FLAG_TERMINATE) { \
  1312. /* terminate current thread */ \
  1313. WASM_SUSPEND_FLAGS_UNLOCK(exec_env->wait_lock); \
  1314. return; \
  1315. } \
  1316. while (WASM_SUSPEND_FLAGS_GET(exec_env->suspend_flags) \
  1317. & WASM_SUSPEND_FLAG_SUSPEND) { \
  1318. /* suspend current thread */ \
  1319. SUSPENSION_LOCK() \
  1320. os_cond_wait(&exec_env->wait_cond, &exec_env->wait_lock); \
  1321. SUSPENSION_UNLOCK() \
  1322. } \
  1323. WASM_SUSPEND_FLAGS_UNLOCK(exec_env->wait_lock); \
  1324. } while (0)
  1325. #endif /* WASM_ENABLE_DEBUG_INTERP */
  1326. #endif /* WASM_ENABLE_THREAD_MGR */
  1327. #if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
  1328. #if BH_ATOMIC_32_IS_ATOMIC != 0
  1329. #define GET_SIGNAL_FLAG() \
  1330. do { \
  1331. signal_flag = \
  1332. BH_ATOMIC_32_LOAD(exec_env->current_status->signal_flag); \
  1333. } while (0)
  1334. #else
  1335. #define GET_SIGNAL_FLAG() \
  1336. do { \
  1337. os_mutex_lock(&exec_env->wait_lock); \
  1338. signal_flag = exec_env->current_status->signal_flag; \
  1339. os_mutex_unlock(&exec_env->wait_lock); \
  1340. } while (0)
  1341. #endif
  1342. #endif
  1343. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  1344. #define HANDLE_OP(opcode) HANDLE_##opcode:
  1345. #define FETCH_OPCODE_AND_DISPATCH() goto *handle_table[*frame_ip++]
  1346. #if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
  1347. #define HANDLE_OP_END() \
  1348. do { \
  1349. /* Record the current frame_ip, so when exception occurs, \
  1350. debugger can know the exact opcode who caused the exception */ \
  1351. frame_ip_orig = frame_ip; \
  1352. /* Atomic load the exec_env's signal_flag first, and then handle \
  1353. more with lock if it is WAMR_SIG_SINGSTEP */ \
  1354. GET_SIGNAL_FLAG(); \
  1355. if (signal_flag == WAMR_SIG_SINGSTEP) { \
  1356. os_mutex_lock(&exec_env->wait_lock); \
  1357. while (exec_env->current_status->signal_flag == WAMR_SIG_SINGSTEP \
  1358. && exec_env->current_status->step_count++ == 1) { \
  1359. exec_env->current_status->step_count = 0; \
  1360. SYNC_ALL_TO_FRAME(); \
  1361. wasm_cluster_thread_waiting_run(exec_env); \
  1362. } \
  1363. os_mutex_unlock(&exec_env->wait_lock); \
  1364. } \
  1365. goto *handle_table[*frame_ip++]; \
  1366. } while (0)
  1367. #else
  1368. #define HANDLE_OP_END() FETCH_OPCODE_AND_DISPATCH()
  1369. #endif
  1370. #else /* else of WASM_ENABLE_LABELS_AS_VALUES */
  1371. #define HANDLE_OP(opcode) case opcode:
  1372. #if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
  1373. #define HANDLE_OP_END() \
  1374. /* Record the current frame_ip, so when exception occurs, \
  1375. debugger can know the exact opcode who caused the exception */ \
  1376. frame_ip_orig = frame_ip; \
  1377. /* Atomic load the exec_env's signal_flag first, and then handle \
  1378. more with lock if it is WAMR_SIG_SINGSTEP */ \
  1379. GET_SIGNAL_FLAG(); \
  1380. if (signal_flag == WAMR_SIG_SINGSTEP) { \
  1381. os_mutex_lock(&exec_env->wait_lock); \
  1382. while (exec_env->current_status->signal_flag == WAMR_SIG_SINGSTEP \
  1383. && exec_env->current_status->step_count++ == 1) { \
  1384. exec_env->current_status->step_count = 0; \
  1385. SYNC_ALL_TO_FRAME(); \
  1386. wasm_cluster_thread_waiting_run(exec_env); \
  1387. } \
  1388. os_mutex_unlock(&exec_env->wait_lock); \
  1389. } \
  1390. continue;
  1391. #else
  1392. #define HANDLE_OP_END() continue
  1393. #endif
  1394. #endif /* end of WASM_ENABLE_LABELS_AS_VALUES */
  1395. static inline uint8 *
  1396. get_global_addr(uint8 *global_data, WASMGlobalInstance *global)
  1397. {
  1398. #if WASM_ENABLE_MULTI_MODULE == 0
  1399. return global_data + global->data_offset;
  1400. #else
  1401. return global->import_global_inst
  1402. ? global->import_module_inst->global_data
  1403. + global->import_global_inst->data_offset
  1404. : global_data + global->data_offset;
  1405. #endif
  1406. }
  1407. static void
  1408. wasm_interp_call_func_bytecode(WASMModuleInstance *module,
  1409. WASMExecEnv *exec_env,
  1410. WASMFunctionInstance *cur_func,
  1411. WASMInterpFrame *prev_frame)
  1412. {
  1413. WASMMemoryInstance *memory = wasm_get_default_memory(module);
  1414. #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
  1415. || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
  1416. || WASM_ENABLE_BULK_MEMORY != 0
  1417. uint64 linear_mem_size = 0;
  1418. if (memory)
  1419. #if WASM_ENABLE_THREAD_MGR == 0
  1420. linear_mem_size = memory->memory_data_size;
  1421. #else
  1422. linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory);
  1423. #endif
  1424. #endif
  1425. WASMFuncType **wasm_types = (WASMFuncType **)module->module->types;
  1426. WASMGlobalInstance *globals = module->e->globals, *global;
  1427. uint8 *global_data = module->global_data;
  1428. uint8 opcode_IMPDEP = WASM_OP_IMPDEP;
  1429. WASMInterpFrame *frame = NULL;
  1430. /* Points to this special opcode so as to jump to the
  1431. * call_method_from_entry. */
  1432. register uint8 *frame_ip = &opcode_IMPDEP; /* cache of frame->ip */
  1433. register uint32 *frame_lp = NULL; /* cache of frame->lp */
  1434. register uint32 *frame_sp = NULL; /* cache of frame->sp */
  1435. #if WASM_ENABLE_GC != 0
  1436. register uint8 *frame_ref = NULL; /* cache of frame->ref */
  1437. uint8 *frame_ref_tmp;
  1438. #endif
  1439. WASMBranchBlock *frame_csp = NULL;
  1440. BlockAddr *cache_items;
  1441. uint8 *frame_ip_end = frame_ip + 1;
  1442. uint8 opcode;
  1443. uint32 i, depth, cond, count, fidx, tidx, lidx, frame_size = 0;
  1444. uint32 all_cell_num = 0;
  1445. tbl_elem_idx_t val;
  1446. uint8 *else_addr, *end_addr, *maddr = NULL;
  1447. uint32 local_idx, local_offset, global_idx;
  1448. uint8 local_type, *global_addr;
  1449. uint32 cache_index, type_index, param_cell_num, cell_num;
  1450. #if WASM_ENABLE_EXCE_HANDLING != 0
  1451. int32_t exception_tag_index;
  1452. #endif
  1453. uint8 value_type;
  1454. #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
  1455. || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
  1456. #if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
  1457. bool disable_bounds_checks = !wasm_runtime_is_bounds_checks_enabled(
  1458. (WASMModuleInstanceCommon *)module);
  1459. #else
  1460. bool disable_bounds_checks = false;
  1461. #endif
  1462. #endif
  1463. #if WASM_ENABLE_GC != 0
  1464. WASMObjectRef gc_obj;
  1465. WASMStructObjectRef struct_obj;
  1466. WASMArrayObjectRef array_obj;
  1467. WASMFuncObjectRef func_obj;
  1468. WASMI31ObjectRef i31_obj;
  1469. WASMExternrefObjectRef externref_obj;
  1470. #if WASM_ENABLE_STRINGREF != 0
  1471. WASMString str_obj = NULL;
  1472. WASMStringrefObjectRef stringref_obj;
  1473. WASMStringviewWTF8ObjectRef stringview_wtf8_obj;
  1474. WASMStringviewWTF16ObjectRef stringview_wtf16_obj;
  1475. WASMStringviewIterObjectRef stringview_iter_obj;
  1476. #endif
  1477. #endif
  1478. #if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
  1479. bool is_return_call = false;
  1480. #endif
  1481. #if WASM_ENABLE_MEMORY64 != 0
  1482. /* TODO: multi-memories for now assuming the memory idx type is consistent
  1483. * across multi-memories */
  1484. bool is_memory64 = false;
  1485. bool is_table64 = false;
  1486. if (memory)
  1487. is_memory64 = memory->is_memory64;
  1488. #endif
  1489. #if WASM_ENABLE_SHARED_HEAP != 0
  1490. WASMSharedHeap *shared_heap = module->e->shared_heap;
  1491. uint8 *shared_heap_base_addr = shared_heap ? shared_heap->base_addr : NULL;
  1492. #if WASM_ENABLE_MEMORY64 != 0
  1493. uint64 shared_heap_start_off =
  1494. shared_heap ? (is_memory64 ? shared_heap->start_off_mem64
  1495. : shared_heap->start_off_mem32)
  1496. : 0;
  1497. uint64 shared_heap_end_off =
  1498. shared_heap ? (is_memory64 ? UINT64_MAX : UINT32_MAX) : 0;
  1499. #else
  1500. uint64 shared_heap_start_off =
  1501. shared_heap ? shared_heap->start_off_mem32 : 0;
  1502. uint64 shared_heap_end_off = shared_heap ? UINT32_MAX : 0;
  1503. #endif
  1504. #endif /* end of WASM_ENABLE_SHARED_HEAP != 0 */
  1505. #if WASM_ENABLE_MULTI_MEMORY != 0
  1506. uint32 memidx = 0;
  1507. uint32 memidx_cached = (uint32)-1;
  1508. #endif
  1509. #if WASM_ENABLE_DEBUG_INTERP != 0
  1510. uint8 *frame_ip_orig = NULL;
  1511. WASMDebugInstance *debug_instance = wasm_exec_env_get_instance(exec_env);
  1512. bh_list *watch_point_list_read =
  1513. debug_instance ? &debug_instance->watch_point_list_read : NULL;
  1514. bh_list *watch_point_list_write =
  1515. debug_instance ? &debug_instance->watch_point_list_write : NULL;
  1516. #if WASM_ENABLE_THREAD_MGR != 0
  1517. uint32 signal_flag;
  1518. #endif
  1519. #endif
  1520. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  1521. #define HANDLE_OPCODE(op) &&HANDLE_##op
  1522. DEFINE_GOTO_TABLE(const void *, handle_table);
  1523. #undef HANDLE_OPCODE
  1524. #endif
  1525. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  1526. while (frame_ip < frame_ip_end) {
  1527. opcode = *frame_ip++;
  1528. switch (opcode) {
  1529. #else
  1530. FETCH_OPCODE_AND_DISPATCH();
  1531. #endif
  1532. /* control instructions */
  1533. HANDLE_OP(WASM_OP_UNREACHABLE)
  1534. {
  1535. wasm_set_exception(module, "unreachable");
  1536. goto got_exception;
  1537. }
  1538. HANDLE_OP(WASM_OP_NOP) { HANDLE_OP_END(); }
  1539. #if WASM_ENABLE_EXCE_HANDLING != 0
  1540. HANDLE_OP(WASM_OP_RETHROW)
  1541. {
  1542. int32_t relative_depth;
  1543. read_leb_int32(frame_ip, frame_ip_end, relative_depth);
  1544. /* No frame found with exception handler; validation should
  1545. * catch it */
  1546. bh_assert(frame_csp >= frame->csp_bottom + relative_depth);
  1547. /* go up the frame stack */
  1548. WASMBranchBlock *tgtframe = (frame_csp - 1) - relative_depth;
  1549. bh_assert(tgtframe->label_type == LABEL_TYPE_CATCH
  1550. || tgtframe->label_type == LABEL_TYPE_CATCH_ALL);
  1551. /* tgtframe points to the frame containing a thrown
  1552. * exception */
  1553. uint32 *tgtframe_sp = tgtframe->frame_sp;
  1554. /* frame sp of tgtframe points to caught exception */
  1555. exception_tag_index = *((uint32 *)tgtframe_sp);
  1556. tgtframe_sp++;
  1557. /* get tag type */
  1558. uint8 tag_type_index =
  1559. module->module->tags[exception_tag_index]->type;
  1560. uint32 cell_num_to_copy =
  1561. wasm_types[tag_type_index]->param_cell_num;
  1562. /* move exception parameters (if there are any) onto top
  1563. * of stack */
  1564. if (cell_num_to_copy > 0) {
  1565. word_copy(frame_sp, tgtframe_sp - cell_num_to_copy,
  1566. cell_num_to_copy);
  1567. }
  1568. frame_sp += cell_num_to_copy;
  1569. goto find_a_catch_handler;
  1570. }
  1571. HANDLE_OP(WASM_OP_THROW)
  1572. {
  1573. read_leb_int32(frame_ip, frame_ip_end, exception_tag_index);
  1574. /* landing pad for the rethrow ? */
  1575. find_a_catch_handler:
  1576. {
  1577. WASMFuncType *tag_type = NULL;
  1578. uint32 cell_num_to_copy = 0;
  1579. if (IS_INVALID_TAGINDEX(exception_tag_index)) {
  1580. /*
  1581. * invalid exception index,
  1582. * generated if a submodule throws an exception
  1583. * that has not been imported here
  1584. *
  1585. * This should result in a branch to the CATCH_ALL block,
  1586. * if there is one
  1587. */
  1588. tag_type = NULL;
  1589. cell_num_to_copy = 0;
  1590. }
  1591. else {
  1592. if (module->e->tags[exception_tag_index].is_import_tag) {
  1593. tag_type = module->e->tags[exception_tag_index]
  1594. .u.tag_import->tag_type;
  1595. }
  1596. else {
  1597. tag_type = module->e->tags[exception_tag_index]
  1598. .u.tag->tag_type;
  1599. }
  1600. cell_num_to_copy = tag_type->param_cell_num;
  1601. }
  1602. /* browse through frame stack */
  1603. uint32 relative_depth = 0;
  1604. do {
  1605. POP_CSP_CHECK_OVERFLOW(relative_depth - 1);
  1606. WASMBranchBlock *tgtframe = frame_csp - relative_depth - 1;
  1607. switch (tgtframe->label_type) {
  1608. case LABEL_TYPE_BLOCK:
  1609. case LABEL_TYPE_IF:
  1610. case LABEL_TYPE_LOOP:
  1611. case LABEL_TYPE_CATCH:
  1612. case LABEL_TYPE_CATCH_ALL:
  1613. /*
  1614. * skip that blocks in search
  1615. * BLOCK, IF and LOOP do not contain handlers and
  1616. * cannot catch exceptions.
  1617. * blocks marked as CATCH or
  1618. * CATCH_ALL did already caught an exception and can
  1619. * only be a target for RETHROW, but cannot catch an
  1620. * exception again
  1621. */
  1622. break;
  1623. case LABEL_TYPE_TRY:
  1624. {
  1625. uint32 handler_number = 0;
  1626. uint8 **handlers = (uint8 **)tgtframe->frame_sp;
  1627. uint8 *handler = NULL;
  1628. while ((handler = handlers[handler_number]) != 0) {
  1629. uint8 handler_opcode = *handler;
  1630. uint8 *target_addr =
  1631. handler
  1632. + 1; /* first instruction or leb-immediate
  1633. behind the handler opcode */
  1634. switch (handler_opcode) {
  1635. case WASM_OP_CATCH:
  1636. {
  1637. int32 lookup_index = 0;
  1638. /* read the tag_index and advance
  1639. * target_addr to the first instruction
  1640. * in the block */
  1641. read_leb_int32(target_addr, 0,
  1642. lookup_index);
  1643. if (exception_tag_index
  1644. == lookup_index) {
  1645. /* set ip */
  1646. frame_ip = target_addr;
  1647. /* save frame_sp (points to
  1648. * exception values) */
  1649. uint32 *frame_sp_old = frame_sp;
  1650. UNWIND_CSP(relative_depth,
  1651. LABEL_TYPE_CATCH);
  1652. /* push exception_tag_index and
  1653. * exception values for rethrow */
  1654. PUSH_I32(exception_tag_index);
  1655. if (cell_num_to_copy > 0) {
  1656. word_copy(
  1657. frame_sp,
  1658. frame_sp_old
  1659. - cell_num_to_copy,
  1660. cell_num_to_copy);
  1661. frame_sp += cell_num_to_copy;
  1662. /* push exception values for
  1663. * catch
  1664. */
  1665. word_copy(
  1666. frame_sp,
  1667. frame_sp_old
  1668. - cell_num_to_copy,
  1669. cell_num_to_copy);
  1670. frame_sp += cell_num_to_copy;
  1671. }
  1672. /* advance to handler */
  1673. HANDLE_OP_END();
  1674. }
  1675. break;
  1676. }
  1677. case WASM_OP_DELEGATE:
  1678. {
  1679. int32 lookup_depth = 0;
  1680. /* read the depth */
  1681. read_leb_int32(target_addr, 0,
  1682. lookup_depth);
  1683. /* save frame_sp (points to exception
  1684. * values) */
  1685. uint32 *frame_sp_old = frame_sp;
  1686. UNWIND_CSP(relative_depth,
  1687. LABEL_TYPE_CATCH);
  1688. /* leave the block (the delegate is
  1689. * technically not inside the frame) */
  1690. frame_csp--;
  1691. /* unwind to delegated frame */
  1692. frame_csp -= lookup_depth;
  1693. /* push exception values for catch */
  1694. if (cell_num_to_copy > 0) {
  1695. word_copy(frame_sp,
  1696. frame_sp_old
  1697. - cell_num_to_copy,
  1698. cell_num_to_copy);
  1699. frame_sp += cell_num_to_copy;
  1700. }
  1701. /* tag_index is already stored in
  1702. * exception_tag_index */
  1703. goto find_a_catch_handler;
  1704. }
  1705. case WASM_OP_CATCH_ALL:
  1706. {
  1707. /* no immediate */
  1708. /* save frame_sp (points to exception
  1709. * values) */
  1710. uint32 *frame_sp_old = frame_sp;
  1711. /* set ip */
  1712. frame_ip = target_addr;
  1713. UNWIND_CSP(relative_depth,
  1714. LABEL_TYPE_CATCH_ALL);
  1715. /* push exception_tag_index and
  1716. * exception values for rethrow */
  1717. PUSH_I32(exception_tag_index);
  1718. if (cell_num_to_copy > 0) {
  1719. word_copy(frame_sp,
  1720. frame_sp_old
  1721. - cell_num_to_copy,
  1722. cell_num_to_copy);
  1723. frame_sp += cell_num_to_copy;
  1724. }
  1725. /* catch_all has no exception values */
  1726. /* advance to handler */
  1727. HANDLE_OP_END();
  1728. }
  1729. default:
  1730. wasm_set_exception(
  1731. module, "WASM_OP_THROW found "
  1732. "unexpected handler type");
  1733. goto got_exception;
  1734. }
  1735. handler_number++;
  1736. }
  1737. /* exception not caught in this frame */
  1738. break;
  1739. }
  1740. case LABEL_TYPE_FUNCTION:
  1741. {
  1742. /* save frame_sp (points to exception values) */
  1743. uint32 *frame_sp_old = frame_sp;
  1744. UNWIND_CSP(relative_depth, LABEL_TYPE_FUNCTION);
  1745. /* push exception values for catch
  1746. * The values are copied to the CALLER FRAME
  1747. * (prev_frame->sp) same behvior ad WASM_OP_RETURN
  1748. */
  1749. if (cell_num_to_copy > 0) {
  1750. word_copy(prev_frame->sp,
  1751. frame_sp_old - cell_num_to_copy,
  1752. cell_num_to_copy);
  1753. prev_frame->sp += cell_num_to_copy;
  1754. }
  1755. *((int32 *)(prev_frame->sp)) = exception_tag_index;
  1756. prev_frame->sp++;
  1757. /* mark frame as raised exception */
  1758. wasm_set_exception(module,
  1759. "uncaught wasm exception");
  1760. /* end of function, treat as WASM_OP_RETURN */
  1761. goto return_func;
  1762. }
  1763. default:
  1764. wasm_set_exception(
  1765. module,
  1766. "unexpected or invalid label in THROW or "
  1767. "RETHROW when searching a catch handler");
  1768. goto got_exception;
  1769. }
  1770. relative_depth++;
  1771. } while (1);
  1772. }
  1773. /* something went wrong. normally, we should always find the
  1774. * func label. if not, stop the interpreter */
  1775. wasm_set_exception(
  1776. module, "WASM_OP_THROW hit the bottom of the frame stack");
  1777. goto got_exception;
  1778. }
  1779. HANDLE_OP(EXT_OP_TRY)
  1780. {
  1781. /* read the blocktype */
  1782. read_leb_uint32(frame_ip, frame_ip_end, type_index);
  1783. param_cell_num = wasm_types[type_index]->param_cell_num;
  1784. cell_num = wasm_types[type_index]->ret_cell_num;
  1785. goto handle_op_try;
  1786. }
  1787. HANDLE_OP(WASM_OP_TRY)
  1788. {
  1789. value_type = *frame_ip++;
  1790. param_cell_num = 0;
  1791. cell_num = wasm_value_type_cell_num(value_type);
  1792. handle_op_try:
  1793. cache_index = ((uintptr_t)frame_ip)
  1794. & (uintptr_t)(BLOCK_ADDR_CACHE_SIZE - 1);
  1795. cache_items = exec_env->block_addr_cache[cache_index];
  1796. if (cache_items[0].start_addr == frame_ip) {
  1797. cache_items[0].start_addr = 0;
  1798. }
  1799. if (cache_items[1].start_addr == frame_ip) {
  1800. cache_items[1].start_addr = 0;
  1801. }
  1802. /* start at the first opcode following the try and its blocktype
  1803. */
  1804. uint8 *lookup_cursor = frame_ip;
  1805. uint8 handler_opcode = WASM_OP_UNREACHABLE;
  1806. /* target_addr filled in when END or DELEGATE is found */
  1807. PUSH_CSP(LABEL_TYPE_TRY, param_cell_num, cell_num, 0);
  1808. /* reset to begin of block */
  1809. lookup_cursor = frame_ip;
  1810. do {
  1811. /* lookup the next CATCH, CATCH_ALL or END for this TRY */
  1812. if (!wasm_loader_find_block_addr(
  1813. exec_env, (BlockAddr *)exec_env->block_addr_cache,
  1814. lookup_cursor, (uint8 *)-1, LABEL_TYPE_TRY,
  1815. &else_addr, &end_addr)) {
  1816. /* something went wrong */
  1817. wasm_set_exception(module, "find block address failed");
  1818. goto got_exception;
  1819. }
  1820. /* place cursor for continuation past opcode */
  1821. lookup_cursor = end_addr + 1;
  1822. /* end_addr points to CATCH, CATCH_ALL, DELEGATE or END */
  1823. handler_opcode = *end_addr;
  1824. switch (handler_opcode) {
  1825. case WASM_OP_CATCH:
  1826. skip_leb(lookup_cursor); /* skip tag_index */
  1827. PUSH_PTR(end_addr);
  1828. break;
  1829. case WASM_OP_CATCH_ALL:
  1830. PUSH_PTR(end_addr);
  1831. break;
  1832. case WASM_OP_DELEGATE:
  1833. skip_leb(lookup_cursor); /* skip depth */
  1834. PUSH_PTR(end_addr);
  1835. /* patch target_addr */
  1836. (frame_csp - 1)->target_addr = lookup_cursor;
  1837. break;
  1838. case WASM_OP_END:
  1839. PUSH_PTR(0);
  1840. /* patch target_addr */
  1841. (frame_csp - 1)->target_addr = end_addr;
  1842. break;
  1843. default:
  1844. /* something went wrong */
  1845. wasm_set_exception(module,
  1846. "find block address returned an "
  1847. "unexpected opcode");
  1848. goto got_exception;
  1849. }
  1850. /* ... search until the returned address is the END of the
  1851. * TRY block */
  1852. } while (handler_opcode != WASM_OP_END
  1853. && handler_opcode != WASM_OP_DELEGATE);
  1854. /* handler setup on stack complete */
  1855. HANDLE_OP_END();
  1856. }
  1857. HANDLE_OP(WASM_OP_CATCH)
  1858. {
  1859. /* skip the tag_index */
  1860. skip_leb(frame_ip);
  1861. /* leave the frame */
  1862. POP_CSP_N(0);
  1863. HANDLE_OP_END();
  1864. }
  1865. HANDLE_OP(WASM_OP_CATCH_ALL)
  1866. {
  1867. /* leave the frame */
  1868. POP_CSP_N(0);
  1869. HANDLE_OP_END();
  1870. }
  1871. HANDLE_OP(WASM_OP_DELEGATE)
  1872. {
  1873. /* skip the delegate depth */
  1874. skip_leb(frame_ip);
  1875. /* leave the frame like WASM_OP_END */
  1876. POP_CSP();
  1877. HANDLE_OP_END();
  1878. }
  1879. #endif /* end of WASM_ENABLE_EXCE_HANDLING != 0 */
  1880. HANDLE_OP(EXT_OP_BLOCK)
  1881. {
  1882. read_leb_uint32(frame_ip, frame_ip_end, type_index);
  1883. param_cell_num =
  1884. ((WASMFuncType *)wasm_types[type_index])->param_cell_num;
  1885. cell_num =
  1886. ((WASMFuncType *)wasm_types[type_index])->ret_cell_num;
  1887. goto handle_op_block;
  1888. }
  1889. HANDLE_OP(WASM_OP_BLOCK)
  1890. {
  1891. value_type = *frame_ip++;
  1892. param_cell_num = 0;
  1893. cell_num = wasm_value_type_cell_num(value_type);
  1894. handle_op_block:
  1895. cache_index = ((uintptr_t)frame_ip)
  1896. & (uintptr_t)(BLOCK_ADDR_CACHE_SIZE - 1);
  1897. cache_items = exec_env->block_addr_cache[cache_index];
  1898. if (cache_items[0].start_addr == frame_ip) {
  1899. end_addr = cache_items[0].end_addr;
  1900. }
  1901. else if (cache_items[1].start_addr == frame_ip) {
  1902. end_addr = cache_items[1].end_addr;
  1903. }
  1904. #if WASM_ENABLE_DEBUG_INTERP != 0
  1905. else if (!wasm_loader_find_block_addr(
  1906. exec_env, (BlockAddr *)exec_env->block_addr_cache,
  1907. frame_ip, (uint8 *)-1, LABEL_TYPE_BLOCK,
  1908. &else_addr, &end_addr)) {
  1909. wasm_set_exception(module, "find block address failed");
  1910. goto got_exception;
  1911. }
  1912. #endif
  1913. else {
  1914. end_addr = NULL;
  1915. }
  1916. PUSH_CSP(LABEL_TYPE_BLOCK, param_cell_num, cell_num, end_addr);
  1917. HANDLE_OP_END();
  1918. }
  1919. HANDLE_OP(EXT_OP_LOOP)
  1920. {
  1921. read_leb_uint32(frame_ip, frame_ip_end, type_index);
  1922. param_cell_num =
  1923. ((WASMFuncType *)wasm_types[type_index])->param_cell_num;
  1924. cell_num =
  1925. ((WASMFuncType *)wasm_types[type_index])->param_cell_num;
  1926. goto handle_op_loop;
  1927. }
  1928. HANDLE_OP(WASM_OP_LOOP)
  1929. {
  1930. value_type = *frame_ip++;
  1931. param_cell_num = 0;
  1932. cell_num = 0;
  1933. handle_op_loop:
  1934. PUSH_CSP(LABEL_TYPE_LOOP, param_cell_num, cell_num, frame_ip);
  1935. HANDLE_OP_END();
  1936. }
  1937. HANDLE_OP(EXT_OP_IF)
  1938. {
  1939. read_leb_uint32(frame_ip, frame_ip_end, type_index);
  1940. param_cell_num =
  1941. ((WASMFuncType *)wasm_types[type_index])->param_cell_num;
  1942. cell_num =
  1943. ((WASMFuncType *)wasm_types[type_index])->ret_cell_num;
  1944. goto handle_op_if;
  1945. }
  1946. HANDLE_OP(WASM_OP_IF)
  1947. {
  1948. value_type = *frame_ip++;
  1949. param_cell_num = 0;
  1950. cell_num = wasm_value_type_cell_num(value_type);
  1951. handle_op_if:
  1952. cache_index = ((uintptr_t)frame_ip)
  1953. & (uintptr_t)(BLOCK_ADDR_CACHE_SIZE - 1);
  1954. cache_items = exec_env->block_addr_cache[cache_index];
  1955. if (cache_items[0].start_addr == frame_ip) {
  1956. else_addr = cache_items[0].else_addr;
  1957. end_addr = cache_items[0].end_addr;
  1958. }
  1959. else if (cache_items[1].start_addr == frame_ip) {
  1960. else_addr = cache_items[1].else_addr;
  1961. end_addr = cache_items[1].end_addr;
  1962. }
  1963. else if (!wasm_loader_find_block_addr(
  1964. exec_env, (BlockAddr *)exec_env->block_addr_cache,
  1965. frame_ip, (uint8 *)-1, LABEL_TYPE_IF, &else_addr,
  1966. &end_addr)) {
  1967. wasm_set_exception(module, "find block address failed");
  1968. goto got_exception;
  1969. }
  1970. cond = (uint32)POP_I32();
  1971. if (cond) { /* if branch is met */
  1972. PUSH_CSP(LABEL_TYPE_IF, param_cell_num, cell_num, end_addr);
  1973. }
  1974. else { /* if branch is not met */
  1975. /* if there is no else branch, go to the end addr */
  1976. if (else_addr == NULL) {
  1977. frame_ip = end_addr + 1;
  1978. }
  1979. /* if there is an else branch, go to the else addr */
  1980. else {
  1981. PUSH_CSP(LABEL_TYPE_IF, param_cell_num, cell_num,
  1982. end_addr);
  1983. frame_ip = else_addr + 1;
  1984. }
  1985. }
  1986. HANDLE_OP_END();
  1987. }
  1988. HANDLE_OP(WASM_OP_ELSE)
  1989. {
  1990. /* comes from the if branch in WASM_OP_IF */
  1991. frame_ip = (frame_csp - 1)->target_addr;
  1992. HANDLE_OP_END();
  1993. }
  1994. HANDLE_OP(WASM_OP_END)
  1995. {
  1996. if (frame_csp > frame->csp_bottom + 1) {
  1997. POP_CSP();
  1998. }
  1999. else { /* end of function, treat as WASM_OP_RETURN */
  2000. frame_sp -= cur_func->ret_cell_num;
  2001. for (i = 0; i < cur_func->ret_cell_num; i++) {
  2002. #if WASM_ENABLE_GC != 0
  2003. if (prev_frame->ip) {
  2004. /* prev frame is not a glue frame and has
  2005. the frame ref area */
  2006. *FRAME_REF_FOR(prev_frame, prev_frame->sp) =
  2007. *FRAME_REF(frame_sp + i);
  2008. }
  2009. #endif
  2010. *prev_frame->sp++ = frame_sp[i];
  2011. }
  2012. goto return_func;
  2013. }
  2014. HANDLE_OP_END();
  2015. }
  2016. HANDLE_OP(WASM_OP_BR)
  2017. {
  2018. #if WASM_ENABLE_THREAD_MGR != 0
  2019. CHECK_SUSPEND_FLAGS();
  2020. #endif
  2021. read_leb_uint32(frame_ip, frame_ip_end, depth);
  2022. label_pop_csp_n:
  2023. POP_CSP_N(depth);
  2024. if (!frame_ip) { /* must be label pushed by WASM_OP_BLOCK */
  2025. if (!wasm_loader_find_block_addr(
  2026. exec_env, (BlockAddr *)exec_env->block_addr_cache,
  2027. (frame_csp - 1)->begin_addr, (uint8 *)-1,
  2028. LABEL_TYPE_BLOCK, &else_addr, &end_addr)) {
  2029. wasm_set_exception(module, "find block address failed");
  2030. goto got_exception;
  2031. }
  2032. frame_ip = end_addr;
  2033. }
  2034. HANDLE_OP_END();
  2035. }
  2036. HANDLE_OP(WASM_OP_BR_IF)
  2037. {
  2038. #if WASM_ENABLE_THREAD_MGR != 0
  2039. CHECK_SUSPEND_FLAGS();
  2040. #endif
  2041. read_leb_uint32(frame_ip, frame_ip_end, depth);
  2042. cond = (uint32)POP_I32();
  2043. if (cond)
  2044. goto label_pop_csp_n;
  2045. HANDLE_OP_END();
  2046. }
  2047. HANDLE_OP(WASM_OP_BR_TABLE)
  2048. {
  2049. #if WASM_ENABLE_THREAD_MGR != 0
  2050. CHECK_SUSPEND_FLAGS();
  2051. #endif
  2052. read_leb_uint32(frame_ip, frame_ip_end, count);
  2053. lidx = POP_I32();
  2054. if (lidx > count)
  2055. lidx = count;
  2056. depth = frame_ip[lidx];
  2057. goto label_pop_csp_n;
  2058. }
  2059. HANDLE_OP(EXT_OP_BR_TABLE_CACHE)
  2060. {
  2061. BrTableCache *node_cache =
  2062. bh_list_first_elem(module->module->br_table_cache_list);
  2063. BrTableCache *node_next;
  2064. #if WASM_ENABLE_THREAD_MGR != 0
  2065. CHECK_SUSPEND_FLAGS();
  2066. #endif
  2067. lidx = POP_I32();
  2068. while (node_cache) {
  2069. node_next = bh_list_elem_next(node_cache);
  2070. if (node_cache->br_table_op_addr == frame_ip - 1) {
  2071. if (lidx > node_cache->br_count)
  2072. lidx = node_cache->br_count;
  2073. depth = node_cache->br_depths[lidx];
  2074. goto label_pop_csp_n;
  2075. }
  2076. node_cache = node_next;
  2077. }
  2078. bh_assert(0);
  2079. HANDLE_OP_END();
  2080. }
  2081. HANDLE_OP(WASM_OP_RETURN)
  2082. {
  2083. frame_sp -= cur_func->ret_cell_num;
  2084. for (i = 0; i < cur_func->ret_cell_num; i++) {
  2085. #if WASM_ENABLE_GC != 0
  2086. if (prev_frame->ip) {
  2087. /* prev frame is not a glue frame and has
  2088. the frame ref area */
  2089. *FRAME_REF_FOR(prev_frame, prev_frame->sp) =
  2090. *FRAME_REF(frame_sp + i);
  2091. }
  2092. #endif
  2093. *prev_frame->sp++ = frame_sp[i];
  2094. }
  2095. goto return_func;
  2096. }
  2097. HANDLE_OP(WASM_OP_CALL)
  2098. {
  2099. #if WASM_ENABLE_THREAD_MGR != 0
  2100. CHECK_SUSPEND_FLAGS();
  2101. #endif
  2102. read_leb_uint32(frame_ip, frame_ip_end, fidx);
  2103. #if WASM_ENABLE_MULTI_MODULE != 0
  2104. if (fidx >= module->e->function_count) {
  2105. wasm_set_exception(module, "unknown function");
  2106. goto got_exception;
  2107. }
  2108. #endif
  2109. cur_func = module->e->functions + fidx;
  2110. goto call_func_from_interp;
  2111. }
  2112. #if WASM_ENABLE_TAIL_CALL != 0
  2113. HANDLE_OP(WASM_OP_RETURN_CALL)
  2114. {
  2115. #if WASM_ENABLE_THREAD_MGR != 0
  2116. CHECK_SUSPEND_FLAGS();
  2117. #endif
  2118. read_leb_uint32(frame_ip, frame_ip_end, fidx);
  2119. #if WASM_ENABLE_MULTI_MODULE != 0
  2120. if (fidx >= module->e->function_count) {
  2121. wasm_set_exception(module, "unknown function");
  2122. goto got_exception;
  2123. }
  2124. #endif
  2125. cur_func = module->e->functions + fidx;
  2126. goto call_func_from_return_call;
  2127. }
  2128. #endif /* WASM_ENABLE_TAIL_CALL */
  2129. HANDLE_OP(WASM_OP_CALL_INDIRECT)
  2130. #if WASM_ENABLE_TAIL_CALL != 0
  2131. HANDLE_OP(WASM_OP_RETURN_CALL_INDIRECT)
  2132. #endif
  2133. {
  2134. WASMFuncType *cur_type, *cur_func_type;
  2135. WASMTableInstance *tbl_inst;
  2136. uint32 tbl_idx;
  2137. #if WASM_ENABLE_TAIL_CALL != 0
  2138. opcode = *(frame_ip - 1);
  2139. #endif
  2140. #if WASM_ENABLE_THREAD_MGR != 0
  2141. CHECK_SUSPEND_FLAGS();
  2142. #endif
  2143. /**
  2144. * type check. compiler will make sure all like
  2145. * (call_indirect (type $x) (it.const 1))
  2146. * the function type has to be defined in the module also
  2147. * no matter it is used or not
  2148. */
  2149. read_leb_uint32(frame_ip, frame_ip_end, tidx);
  2150. bh_assert(tidx < module->module->type_count);
  2151. cur_type = wasm_types[tidx];
  2152. /* clang-format off */
  2153. #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0
  2154. read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
  2155. #else
  2156. frame_ip++;
  2157. tbl_idx = 0;
  2158. #endif
  2159. bh_assert(tbl_idx < module->table_count);
  2160. /* clang-format on */
  2161. tbl_inst = wasm_get_table_inst(module, tbl_idx);
  2162. #if WASM_ENABLE_MEMORY64 != 0
  2163. is_table64 = tbl_inst->is_table64;
  2164. #endif
  2165. val = POP_TBL_ELEM_IDX();
  2166. if (val >= tbl_inst->cur_size) {
  2167. wasm_set_exception(module, "undefined element");
  2168. goto got_exception;
  2169. }
  2170. /* clang-format off */
  2171. #if WASM_ENABLE_GC == 0
  2172. fidx = tbl_inst->elems[val];
  2173. if (fidx == (uint32)-1) {
  2174. wasm_set_exception(module, "uninitialized element");
  2175. goto got_exception;
  2176. }
  2177. #else
  2178. func_obj = (WASMFuncObjectRef)tbl_inst->elems[val];
  2179. if (!func_obj) {
  2180. wasm_set_exception(module, "uninitialized element");
  2181. goto got_exception;
  2182. }
  2183. fidx = wasm_func_obj_get_func_idx_bound(func_obj);
  2184. #endif
  2185. /* clang-format on */
  2186. /*
  2187. * we might be using a table injected by host or
  2188. * another module. In that case, we don't validate
  2189. * the elem value while loading
  2190. */
  2191. if (fidx >= module->e->function_count) {
  2192. wasm_set_exception(module, "unknown function");
  2193. goto got_exception;
  2194. }
  2195. /* always call module own functions */
  2196. cur_func = module->e->functions + fidx;
  2197. if (cur_func->is_import_func)
  2198. cur_func_type = cur_func->u.func_import->func_type;
  2199. else
  2200. cur_func_type = cur_func->u.func->func_type;
  2201. /* clang-format off */
  2202. #if WASM_ENABLE_GC == 0
  2203. if (cur_type != cur_func_type) {
  2204. wasm_set_exception(module, "indirect call type mismatch");
  2205. goto got_exception;
  2206. }
  2207. #else
  2208. if (!wasm_func_type_is_super_of(cur_type, cur_func_type)) {
  2209. wasm_set_exception(module, "indirect call type mismatch");
  2210. goto got_exception;
  2211. }
  2212. #endif
  2213. /* clang-format on */
  2214. #if WASM_ENABLE_TAIL_CALL != 0
  2215. if (opcode == WASM_OP_RETURN_CALL_INDIRECT)
  2216. goto call_func_from_return_call;
  2217. #endif
  2218. goto call_func_from_interp;
  2219. }
  2220. /* parametric instructions */
  2221. HANDLE_OP(WASM_OP_DROP)
  2222. {
  2223. frame_sp--;
  2224. #if WASM_ENABLE_GC != 0
  2225. frame_ref_tmp = FRAME_REF(frame_sp);
  2226. *frame_ref_tmp = 0;
  2227. #endif
  2228. HANDLE_OP_END();
  2229. }
  2230. HANDLE_OP(WASM_OP_DROP_64)
  2231. {
  2232. frame_sp -= 2;
  2233. #if WASM_ENABLE_GC != 0
  2234. frame_ref_tmp = FRAME_REF(frame_sp);
  2235. *frame_ref_tmp = 0;
  2236. *(frame_ref_tmp + 1) = 0;
  2237. #endif
  2238. HANDLE_OP_END();
  2239. }
  2240. HANDLE_OP(WASM_OP_SELECT)
  2241. {
  2242. cond = (uint32)POP_I32();
  2243. frame_sp--;
  2244. if (!cond)
  2245. *(frame_sp - 1) = *frame_sp;
  2246. HANDLE_OP_END();
  2247. }
  2248. HANDLE_OP(WASM_OP_SELECT_64)
  2249. {
  2250. cond = (uint32)POP_I32();
  2251. frame_sp -= 2;
  2252. if (!cond) {
  2253. *(frame_sp - 2) = *frame_sp;
  2254. *(frame_sp - 1) = *(frame_sp + 1);
  2255. }
  2256. HANDLE_OP_END();
  2257. }
  2258. #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0
  2259. HANDLE_OP(WASM_OP_SELECT_T)
  2260. {
  2261. uint32 vec_len;
  2262. uint8 type;
  2263. read_leb_uint32(frame_ip, frame_ip_end, vec_len);
  2264. type = *frame_ip++;
  2265. cond = (uint32)POP_I32();
  2266. if (type == VALUE_TYPE_I64 || type == VALUE_TYPE_F64
  2267. #if WASM_ENABLE_GC != 0 && UINTPTR_MAX == UINT64_MAX
  2268. || wasm_is_type_reftype(type)
  2269. #endif
  2270. ) {
  2271. frame_sp -= 2;
  2272. if (!cond) {
  2273. *(frame_sp - 2) = *frame_sp;
  2274. *(frame_sp - 1) = *(frame_sp + 1);
  2275. }
  2276. }
  2277. else {
  2278. frame_sp--;
  2279. if (!cond)
  2280. *(frame_sp - 1) = *frame_sp;
  2281. }
  2282. #if WASM_ENABLE_GC != 0
  2283. frame_ref_tmp = FRAME_REF(frame_sp);
  2284. *frame_ref_tmp = 0;
  2285. #if UINTPTR_MAX == UINT64_MAX
  2286. *(frame_ref_tmp + 1) = 0;
  2287. #endif
  2288. #endif
  2289. (void)vec_len;
  2290. HANDLE_OP_END();
  2291. }
  2292. HANDLE_OP(WASM_OP_TABLE_GET)
  2293. {
  2294. uint32 tbl_idx;
  2295. tbl_elem_idx_t elem_idx;
  2296. WASMTableInstance *tbl_inst;
  2297. read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
  2298. bh_assert(tbl_idx < module->table_count);
  2299. tbl_inst = wasm_get_table_inst(module, tbl_idx);
  2300. #if WASM_ENABLE_MEMORY64 != 0
  2301. is_table64 = tbl_inst->is_table64;
  2302. #endif
  2303. elem_idx = POP_TBL_ELEM_IDX();
  2304. if (elem_idx >= tbl_inst->cur_size) {
  2305. wasm_set_exception(module, "out of bounds table access");
  2306. goto got_exception;
  2307. }
  2308. #if WASM_ENABLE_GC == 0
  2309. PUSH_I32(tbl_inst->elems[elem_idx]);
  2310. #else
  2311. PUSH_REF(tbl_inst->elems[elem_idx]);
  2312. #endif
  2313. HANDLE_OP_END();
  2314. }
  2315. HANDLE_OP(WASM_OP_TABLE_SET)
  2316. {
  2317. WASMTableInstance *tbl_inst;
  2318. uint32 tbl_idx;
  2319. tbl_elem_idx_t elem_idx;
  2320. table_elem_type_t elem_val;
  2321. read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
  2322. bh_assert(tbl_idx < module->table_count);
  2323. tbl_inst = wasm_get_table_inst(module, tbl_idx);
  2324. #if WASM_ENABLE_MEMORY64 != 0
  2325. is_table64 = tbl_inst->is_table64;
  2326. #endif
  2327. #if WASM_ENABLE_GC == 0
  2328. elem_val = POP_I32();
  2329. #else
  2330. elem_val = POP_REF();
  2331. #endif
  2332. elem_idx = POP_TBL_ELEM_IDX();
  2333. if (elem_idx >= tbl_inst->cur_size) {
  2334. wasm_set_exception(module, "out of bounds table access");
  2335. goto got_exception;
  2336. }
  2337. tbl_inst->elems[elem_idx] = elem_val;
  2338. HANDLE_OP_END();
  2339. }
  2340. HANDLE_OP(WASM_OP_REF_NULL)
  2341. {
  2342. uint32 ref_type;
  2343. read_leb_uint32(frame_ip, frame_ip_end, ref_type);
  2344. #if WASM_ENABLE_GC == 0
  2345. PUSH_I32(NULL_REF);
  2346. #else
  2347. PUSH_REF(NULL_REF);
  2348. #endif
  2349. (void)ref_type;
  2350. HANDLE_OP_END();
  2351. }
  2352. HANDLE_OP(WASM_OP_REF_IS_NULL)
  2353. {
  2354. #if WASM_ENABLE_GC == 0
  2355. uint32 ref_val;
  2356. ref_val = POP_I32();
  2357. #else
  2358. void *ref_val;
  2359. ref_val = POP_REF();
  2360. #endif
  2361. PUSH_I32(ref_val == NULL_REF ? 1 : 0);
  2362. HANDLE_OP_END();
  2363. }
  2364. HANDLE_OP(WASM_OP_REF_FUNC)
  2365. {
  2366. uint32 func_idx;
  2367. read_leb_uint32(frame_ip, frame_ip_end, func_idx);
  2368. #if WASM_ENABLE_GC == 0
  2369. PUSH_I32(func_idx);
  2370. #else
  2371. SYNC_ALL_TO_FRAME();
  2372. if (!(gc_obj = wasm_create_func_obj(module, func_idx, true,
  2373. NULL, 0))) {
  2374. goto got_exception;
  2375. }
  2376. PUSH_REF(gc_obj);
  2377. #endif
  2378. HANDLE_OP_END();
  2379. }
  2380. #endif /* end of WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */
  2381. #if WASM_ENABLE_GC != 0
  2382. HANDLE_OP(WASM_OP_CALL_REF)
  2383. {
  2384. #if WASM_ENABLE_THREAD_MGR != 0
  2385. CHECK_SUSPEND_FLAGS();
  2386. #endif
  2387. read_leb_uint32(frame_ip, frame_ip_end, type_index);
  2388. func_obj = POP_REF();
  2389. if (!func_obj) {
  2390. wasm_set_exception(module, "null function reference");
  2391. goto got_exception;
  2392. }
  2393. fidx = wasm_func_obj_get_func_idx_bound(func_obj);
  2394. cur_func = module->e->functions + fidx;
  2395. goto call_func_from_interp;
  2396. }
  2397. HANDLE_OP(WASM_OP_RETURN_CALL_REF)
  2398. {
  2399. #if WASM_ENABLE_THREAD_MGR != 0
  2400. CHECK_SUSPEND_FLAGS();
  2401. #endif
  2402. read_leb_uint32(frame_ip, frame_ip_end, type_index);
  2403. func_obj = POP_REF();
  2404. if (!func_obj) {
  2405. wasm_set_exception(module, "null function reference");
  2406. goto got_exception;
  2407. }
  2408. fidx = wasm_func_obj_get_func_idx_bound(func_obj);
  2409. cur_func = module->e->functions + fidx;
  2410. goto call_func_from_return_call;
  2411. }
  2412. HANDLE_OP(WASM_OP_REF_EQ)
  2413. {
  2414. WASMObjectRef gc_obj1, gc_obj2;
  2415. gc_obj2 = POP_REF();
  2416. gc_obj1 = POP_REF();
  2417. val = wasm_obj_equal(gc_obj1, gc_obj2);
  2418. PUSH_I32(val);
  2419. HANDLE_OP_END();
  2420. }
  2421. HANDLE_OP(WASM_OP_REF_AS_NON_NULL)
  2422. {
  2423. gc_obj = POP_REF();
  2424. if (gc_obj == NULL_REF) {
  2425. wasm_set_exception(module, "null reference");
  2426. goto got_exception;
  2427. }
  2428. PUSH_REF(gc_obj);
  2429. HANDLE_OP_END();
  2430. }
  2431. HANDLE_OP(WASM_OP_BR_ON_NULL)
  2432. {
  2433. #if WASM_ENABLE_THREAD_MGR != 0
  2434. CHECK_SUSPEND_FLAGS();
  2435. #endif
  2436. read_leb_uint32(frame_ip, frame_ip_end, depth);
  2437. gc_obj = GET_REF_FROM_ADDR(frame_sp - REF_CELL_NUM);
  2438. if (gc_obj == NULL_REF) {
  2439. frame_sp -= REF_CELL_NUM;
  2440. CLEAR_FRAME_REF(frame_sp, REF_CELL_NUM);
  2441. goto label_pop_csp_n;
  2442. }
  2443. HANDLE_OP_END();
  2444. }
  2445. HANDLE_OP(WASM_OP_BR_ON_NON_NULL)
  2446. {
  2447. #if WASM_ENABLE_THREAD_MGR != 0
  2448. CHECK_SUSPEND_FLAGS();
  2449. #endif
  2450. read_leb_uint32(frame_ip, frame_ip_end, depth);
  2451. gc_obj = GET_REF_FROM_ADDR(frame_sp - REF_CELL_NUM);
  2452. if (gc_obj != NULL_REF) {
  2453. goto label_pop_csp_n;
  2454. }
  2455. else {
  2456. frame_sp -= REF_CELL_NUM;
  2457. CLEAR_FRAME_REF(frame_sp, REF_CELL_NUM);
  2458. }
  2459. HANDLE_OP_END();
  2460. }
  2461. HANDLE_OP(WASM_OP_GC_PREFIX)
  2462. {
  2463. uint32 opcode1;
  2464. read_leb_uint32(frame_ip, frame_ip_end, opcode1);
  2465. /* opcode1 was checked in loader and is no larger than
  2466. UINT8_MAX */
  2467. opcode = (uint8)opcode1;
  2468. switch (opcode) {
  2469. case WASM_OP_STRUCT_NEW:
  2470. case WASM_OP_STRUCT_NEW_DEFAULT:
  2471. {
  2472. WASMModule *wasm_module = module->module;
  2473. WASMStructType *struct_type;
  2474. WASMRttType *rtt_type;
  2475. WASMValue field_value = { 0 };
  2476. read_leb_uint32(frame_ip, frame_ip_end, type_index);
  2477. struct_type =
  2478. (WASMStructType *)module->module->types[type_index];
  2479. if (!(rtt_type = wasm_rtt_type_new(
  2480. (WASMType *)struct_type, type_index,
  2481. wasm_module->rtt_types,
  2482. wasm_module->type_count,
  2483. &wasm_module->rtt_type_lock))) {
  2484. wasm_set_exception(module,
  2485. "create rtt type failed");
  2486. goto got_exception;
  2487. }
  2488. SYNC_ALL_TO_FRAME();
  2489. struct_obj = wasm_struct_obj_new(exec_env, rtt_type);
  2490. if (!struct_obj) {
  2491. wasm_set_exception(module,
  2492. "create struct object failed");
  2493. goto got_exception;
  2494. }
  2495. if (opcode == WASM_OP_STRUCT_NEW) {
  2496. WASMStructFieldType *fields = struct_type->fields;
  2497. int32 field_count = (int32)struct_type->field_count;
  2498. int32 field_idx;
  2499. uint8 field_type;
  2500. for (field_idx = field_count - 1; field_idx >= 0;
  2501. field_idx--) {
  2502. field_type = fields[field_idx].field_type;
  2503. if (wasm_is_type_reftype(field_type)) {
  2504. field_value.gc_obj = POP_REF();
  2505. }
  2506. else if (field_type == VALUE_TYPE_I32
  2507. || field_type == VALUE_TYPE_F32
  2508. || field_type == PACKED_TYPE_I8
  2509. || field_type == PACKED_TYPE_I16) {
  2510. field_value.i32 = POP_I32();
  2511. }
  2512. else {
  2513. field_value.i64 = POP_I64();
  2514. }
  2515. wasm_struct_obj_set_field(struct_obj, field_idx,
  2516. &field_value);
  2517. }
  2518. }
  2519. PUSH_REF(struct_obj);
  2520. HANDLE_OP_END();
  2521. }
  2522. case WASM_OP_STRUCT_GET:
  2523. case WASM_OP_STRUCT_GET_S:
  2524. case WASM_OP_STRUCT_GET_U:
  2525. {
  2526. WASMStructType *struct_type;
  2527. WASMValue field_value = { 0 };
  2528. uint32 field_idx;
  2529. uint8 field_type;
  2530. read_leb_uint32(frame_ip, frame_ip_end, type_index);
  2531. read_leb_uint32(frame_ip, frame_ip_end, field_idx);
  2532. struct_type =
  2533. (WASMStructType *)module->module->types[type_index];
  2534. struct_obj = POP_REF();
  2535. if (!struct_obj) {
  2536. wasm_set_exception(module,
  2537. "null structure reference");
  2538. goto got_exception;
  2539. }
  2540. wasm_struct_obj_get_field(
  2541. struct_obj, field_idx,
  2542. opcode == WASM_OP_STRUCT_GET_S ? true : false,
  2543. &field_value);
  2544. field_type = struct_type->fields[field_idx].field_type;
  2545. if (wasm_is_reftype_i31ref(field_type)) {
  2546. PUSH_I31REF(field_value.gc_obj);
  2547. }
  2548. else if (wasm_is_type_reftype(field_type)) {
  2549. PUSH_REF(field_value.gc_obj);
  2550. }
  2551. else if (field_type == VALUE_TYPE_I32
  2552. || field_type == VALUE_TYPE_F32
  2553. || field_type == PACKED_TYPE_I8
  2554. || field_type == PACKED_TYPE_I16) {
  2555. PUSH_I32(field_value.i32);
  2556. }
  2557. else {
  2558. PUSH_I64(field_value.i64);
  2559. }
  2560. HANDLE_OP_END();
  2561. }
  2562. case WASM_OP_STRUCT_SET:
  2563. {
  2564. WASMStructType *struct_type;
  2565. WASMValue field_value = { 0 };
  2566. uint32 field_idx;
  2567. uint8 field_type;
  2568. read_leb_uint32(frame_ip, frame_ip_end, type_index);
  2569. read_leb_uint32(frame_ip, frame_ip_end, field_idx);
  2570. struct_type =
  2571. (WASMStructType *)module->module->types[type_index];
  2572. field_type = struct_type->fields[field_idx].field_type;
  2573. if (wasm_is_type_reftype(field_type)) {
  2574. field_value.gc_obj = POP_REF();
  2575. }
  2576. else if (field_type == VALUE_TYPE_I32
  2577. || field_type == VALUE_TYPE_F32
  2578. || field_type == PACKED_TYPE_I8
  2579. || field_type == PACKED_TYPE_I16) {
  2580. field_value.i32 = POP_I32();
  2581. }
  2582. else {
  2583. field_value.i64 = POP_I64();
  2584. }
  2585. struct_obj = POP_REF();
  2586. if (!struct_obj) {
  2587. wasm_set_exception(module,
  2588. "null structure reference");
  2589. goto got_exception;
  2590. }
  2591. wasm_struct_obj_set_field(struct_obj, field_idx,
  2592. &field_value);
  2593. HANDLE_OP_END();
  2594. }
  2595. case WASM_OP_ARRAY_NEW:
  2596. case WASM_OP_ARRAY_NEW_DEFAULT:
  2597. case WASM_OP_ARRAY_NEW_FIXED:
  2598. {
  2599. WASMModule *wasm_module = module->module;
  2600. WASMArrayType *array_type;
  2601. WASMRttType *rtt_type;
  2602. WASMValue array_elem = { 0 };
  2603. uint32 array_len;
  2604. read_leb_uint32(frame_ip, frame_ip_end, type_index);
  2605. array_type =
  2606. (WASMArrayType *)wasm_module->types[type_index];
  2607. if (!(rtt_type = wasm_rtt_type_new(
  2608. (WASMType *)array_type, type_index,
  2609. wasm_module->rtt_types,
  2610. wasm_module->type_count,
  2611. &wasm_module->rtt_type_lock))) {
  2612. wasm_set_exception(module,
  2613. "create rtt type failed");
  2614. goto got_exception;
  2615. }
  2616. if (opcode != WASM_OP_ARRAY_NEW_FIXED)
  2617. array_len = POP_I32();
  2618. else
  2619. read_leb_uint32(frame_ip, frame_ip_end, array_len);
  2620. if (opcode == WASM_OP_ARRAY_NEW) {
  2621. if (wasm_is_type_reftype(array_type->elem_type)) {
  2622. array_elem.gc_obj = POP_REF();
  2623. }
  2624. else if (array_type->elem_type == VALUE_TYPE_I32
  2625. || array_type->elem_type == VALUE_TYPE_F32
  2626. || array_type->elem_type == PACKED_TYPE_I8
  2627. || array_type->elem_type
  2628. == PACKED_TYPE_I16) {
  2629. array_elem.i32 = POP_I32();
  2630. }
  2631. else {
  2632. array_elem.i64 = POP_I64();
  2633. }
  2634. }
  2635. SYNC_ALL_TO_FRAME();
  2636. array_obj = wasm_array_obj_new(exec_env, rtt_type,
  2637. array_len, &array_elem);
  2638. if (!array_obj) {
  2639. wasm_set_exception(module,
  2640. "create array object failed");
  2641. goto got_exception;
  2642. }
  2643. if (opcode == WASM_OP_ARRAY_NEW_FIXED) {
  2644. for (i = 0; i < array_len; i++) {
  2645. if (wasm_is_type_reftype(
  2646. array_type->elem_type)) {
  2647. array_elem.gc_obj = POP_REF();
  2648. }
  2649. else if (array_type->elem_type == VALUE_TYPE_I32
  2650. || array_type->elem_type
  2651. == VALUE_TYPE_F32
  2652. || array_type->elem_type
  2653. == PACKED_TYPE_I8
  2654. || array_type->elem_type
  2655. == PACKED_TYPE_I16) {
  2656. array_elem.i32 = POP_I32();
  2657. }
  2658. else {
  2659. array_elem.i64 = POP_I64();
  2660. }
  2661. wasm_array_obj_set_elem(
  2662. array_obj, array_len - 1 - i, &array_elem);
  2663. }
  2664. }
  2665. PUSH_REF(array_obj);
  2666. HANDLE_OP_END();
  2667. }
  2668. case WASM_OP_ARRAY_NEW_DATA:
  2669. {
  2670. WASMModule *wasm_module = module->module;
  2671. WASMArrayType *array_type;
  2672. WASMRttType *rtt_type;
  2673. WASMValue array_elem = { 0 };
  2674. WASMDataSeg *data_seg;
  2675. uint8 *array_elem_base;
  2676. uint32 array_len, data_seg_idx, data_seg_offset;
  2677. uint32 elem_size = 0;
  2678. uint64 total_size;
  2679. read_leb_uint32(frame_ip, frame_ip_end, type_index);
  2680. read_leb_uint32(frame_ip, frame_ip_end, data_seg_idx);
  2681. data_seg = wasm_module->data_segments[data_seg_idx];
  2682. array_type =
  2683. (WASMArrayType *)wasm_module->types[type_index];
  2684. if (!(rtt_type = wasm_rtt_type_new(
  2685. (WASMType *)array_type, type_index,
  2686. wasm_module->rtt_types,
  2687. wasm_module->type_count,
  2688. &wasm_module->rtt_type_lock))) {
  2689. wasm_set_exception(module,
  2690. "create rtt type failed");
  2691. goto got_exception;
  2692. }
  2693. array_len = POP_I32();
  2694. data_seg_offset = POP_I32();
  2695. switch (array_type->elem_type) {
  2696. case PACKED_TYPE_I8:
  2697. elem_size = 1;
  2698. break;
  2699. case PACKED_TYPE_I16:
  2700. elem_size = 2;
  2701. break;
  2702. case VALUE_TYPE_I32:
  2703. case VALUE_TYPE_F32:
  2704. elem_size = 4;
  2705. break;
  2706. case VALUE_TYPE_I64:
  2707. case VALUE_TYPE_F64:
  2708. elem_size = 8;
  2709. break;
  2710. default:
  2711. bh_assert(0);
  2712. }
  2713. total_size = (uint64)elem_size * array_len;
  2714. if (data_seg_offset >= data_seg->data_length
  2715. || total_size
  2716. > data_seg->data_length - data_seg_offset) {
  2717. wasm_set_exception(module,
  2718. "data segment out of bounds");
  2719. goto got_exception;
  2720. }
  2721. SYNC_ALL_TO_FRAME();
  2722. array_obj = wasm_array_obj_new(exec_env, rtt_type,
  2723. array_len, &array_elem);
  2724. if (!array_obj) {
  2725. wasm_set_exception(module,
  2726. "create array object failed");
  2727. goto got_exception;
  2728. }
  2729. array_elem_base =
  2730. (uint8 *)wasm_array_obj_first_elem_addr(array_obj);
  2731. bh_memcpy_s(array_elem_base, (uint32)total_size,
  2732. data_seg->data + data_seg_offset,
  2733. (uint32)total_size);
  2734. PUSH_REF(array_obj);
  2735. HANDLE_OP_END();
  2736. }
  2737. case WASM_OP_ARRAY_NEW_ELEM:
  2738. {
  2739. /* TODO */
  2740. wasm_set_exception(module, "unsupported opcode");
  2741. goto got_exception;
  2742. }
  2743. case WASM_OP_ARRAY_GET:
  2744. case WASM_OP_ARRAY_GET_S:
  2745. case WASM_OP_ARRAY_GET_U:
  2746. {
  2747. WASMArrayType *array_type;
  2748. WASMValue array_elem = { 0 };
  2749. uint32 elem_idx, elem_size_log;
  2750. read_leb_uint32(frame_ip, frame_ip_end, type_index);
  2751. array_type =
  2752. (WASMArrayType *)module->module->types[type_index];
  2753. elem_idx = POP_I32();
  2754. array_obj = POP_REF();
  2755. if (!array_obj) {
  2756. wasm_set_exception(module, "null array reference");
  2757. goto got_exception;
  2758. }
  2759. if (elem_idx >= wasm_array_obj_length(array_obj)) {
  2760. wasm_set_exception(module,
  2761. "out of bounds array access");
  2762. goto got_exception;
  2763. }
  2764. wasm_array_obj_get_elem(
  2765. array_obj, elem_idx,
  2766. opcode == WASM_OP_ARRAY_GET_S ? true : false,
  2767. &array_elem);
  2768. elem_size_log = wasm_array_obj_elem_size_log(array_obj);
  2769. if (wasm_is_reftype_i31ref(array_type->elem_type)) {
  2770. PUSH_I31REF(array_elem.gc_obj);
  2771. }
  2772. else if (wasm_is_type_reftype(array_type->elem_type)) {
  2773. PUSH_REF(array_elem.gc_obj);
  2774. }
  2775. else if (elem_size_log < 3) {
  2776. PUSH_I32(array_elem.i32);
  2777. }
  2778. else {
  2779. PUSH_I64(array_elem.i64);
  2780. }
  2781. HANDLE_OP_END();
  2782. }
  2783. case WASM_OP_ARRAY_SET:
  2784. {
  2785. WASMArrayType *array_type;
  2786. WASMValue array_elem = { 0 };
  2787. uint32 elem_idx;
  2788. read_leb_uint32(frame_ip, frame_ip_end, type_index);
  2789. array_type =
  2790. (WASMArrayType *)module->module->types[type_index];
  2791. if (wasm_is_type_reftype(array_type->elem_type)) {
  2792. array_elem.gc_obj = POP_REF();
  2793. }
  2794. else if (array_type->elem_type == VALUE_TYPE_I32
  2795. || array_type->elem_type == VALUE_TYPE_F32
  2796. || array_type->elem_type == PACKED_TYPE_I8
  2797. || array_type->elem_type == PACKED_TYPE_I16) {
  2798. array_elem.i32 = POP_I32();
  2799. }
  2800. else {
  2801. array_elem.i64 = POP_I64();
  2802. }
  2803. elem_idx = POP_I32();
  2804. array_obj = POP_REF();
  2805. if (!array_obj) {
  2806. wasm_set_exception(module, "null array reference");
  2807. goto got_exception;
  2808. }
  2809. if (elem_idx >= wasm_array_obj_length(array_obj)) {
  2810. wasm_set_exception(module,
  2811. "out of bounds array access");
  2812. goto got_exception;
  2813. }
  2814. wasm_array_obj_set_elem(array_obj, elem_idx,
  2815. &array_elem);
  2816. HANDLE_OP_END();
  2817. }
  2818. case WASM_OP_ARRAY_LEN:
  2819. {
  2820. uint32 array_len;
  2821. array_obj = POP_REF();
  2822. if (!array_obj) {
  2823. wasm_set_exception(module, "null array reference");
  2824. goto got_exception;
  2825. }
  2826. array_len = wasm_array_obj_length(array_obj);
  2827. PUSH_I32(array_len);
  2828. HANDLE_OP_END();
  2829. }
  2830. case WASM_OP_ARRAY_FILL:
  2831. {
  2832. WASMArrayType *array_type;
  2833. WASMValue fill_value = { 0 };
  2834. uint32 start_offset, len;
  2835. read_leb_uint32(frame_ip, frame_ip_end, type_index);
  2836. array_type =
  2837. (WASMArrayType *)module->module->types[type_index];
  2838. len = POP_I32();
  2839. if (wasm_is_type_reftype(array_type->elem_type)) {
  2840. fill_value.gc_obj = POP_REF();
  2841. }
  2842. else if (array_type->elem_type == VALUE_TYPE_I32
  2843. || array_type->elem_type == VALUE_TYPE_F32
  2844. || array_type->elem_type == PACKED_TYPE_I8
  2845. || array_type->elem_type == PACKED_TYPE_I16) {
  2846. fill_value.i32 = POP_I32();
  2847. }
  2848. else {
  2849. fill_value.i64 = POP_I64();
  2850. }
  2851. start_offset = POP_I32();
  2852. array_obj = POP_REF();
  2853. if (!array_obj) {
  2854. wasm_set_exception(module, "null array reference");
  2855. goto got_exception;
  2856. }
  2857. if (len > 0) {
  2858. if ((uint64)start_offset + len
  2859. >= wasm_array_obj_length(array_obj)) {
  2860. wasm_set_exception(
  2861. module, "out of bounds array access");
  2862. goto got_exception;
  2863. }
  2864. wasm_array_obj_fill(array_obj, start_offset, len,
  2865. &fill_value);
  2866. }
  2867. HANDLE_OP_END();
  2868. }
  2869. case WASM_OP_ARRAY_COPY:
  2870. {
  2871. uint32 dst_offset, src_offset, len, src_type_index;
  2872. WASMArrayObjectRef src_obj, dst_obj;
  2873. read_leb_uint32(frame_ip, frame_ip_end, type_index);
  2874. read_leb_uint32(frame_ip, frame_ip_end, src_type_index);
  2875. len = POP_I32();
  2876. src_offset = POP_I32();
  2877. src_obj = POP_REF();
  2878. dst_offset = POP_I32();
  2879. dst_obj = POP_REF();
  2880. if (!src_obj || !dst_obj) {
  2881. wasm_set_exception(module, "null array reference");
  2882. goto got_exception;
  2883. }
  2884. if (len > 0) {
  2885. if ((dst_offset > UINT32_MAX - len)
  2886. || (dst_offset + len
  2887. > wasm_array_obj_length(dst_obj))
  2888. || (src_offset > UINT32_MAX - len)
  2889. || (src_offset + len
  2890. > wasm_array_obj_length(src_obj))) {
  2891. wasm_set_exception(
  2892. module, "out of bounds array access");
  2893. goto got_exception;
  2894. }
  2895. wasm_array_obj_copy(dst_obj, dst_offset, src_obj,
  2896. src_offset, len);
  2897. }
  2898. (void)src_type_index;
  2899. HANDLE_OP_END();
  2900. }
  2901. case WASM_OP_REF_I31:
  2902. {
  2903. uint32 i31_val;
  2904. i31_val = POP_I32();
  2905. i31_obj = wasm_i31_obj_new(i31_val);
  2906. PUSH_I31REF(i31_obj);
  2907. HANDLE_OP_END();
  2908. }
  2909. case WASM_OP_I31_GET_S:
  2910. case WASM_OP_I31_GET_U:
  2911. {
  2912. uint32 i31_val;
  2913. i31_obj = (WASMI31ObjectRef)POP_REF();
  2914. if (!i31_obj) {
  2915. wasm_set_exception(module, "null i31 reference");
  2916. goto got_exception;
  2917. }
  2918. i31_val = (uint32)(((uintptr_t)i31_obj) >> 1);
  2919. if (opcode == WASM_OP_I31_GET_S
  2920. && (i31_val & 0x40000000) /* bit 30 is 1 */)
  2921. /* set bit 31 to 1 */
  2922. i31_val |= 0x80000000;
  2923. PUSH_I32(i31_val);
  2924. HANDLE_OP_END();
  2925. }
  2926. case WASM_OP_REF_TEST:
  2927. case WASM_OP_REF_CAST:
  2928. case WASM_OP_REF_TEST_NULLABLE:
  2929. case WASM_OP_REF_CAST_NULLABLE:
  2930. {
  2931. int32 heap_type;
  2932. read_leb_int32(frame_ip, frame_ip_end, heap_type);
  2933. gc_obj = GET_REF_FROM_ADDR(frame_sp - REF_CELL_NUM);
  2934. if (!gc_obj) {
  2935. if (opcode == WASM_OP_REF_TEST
  2936. || opcode == WASM_OP_REF_TEST_NULLABLE) {
  2937. (void)POP_REF();
  2938. if (opcode == WASM_OP_REF_TEST)
  2939. PUSH_I32(0);
  2940. else
  2941. PUSH_I32(1);
  2942. }
  2943. else if (opcode == WASM_OP_REF_CAST) {
  2944. wasm_set_exception(module, "cast failure");
  2945. goto got_exception;
  2946. }
  2947. else {
  2948. /* Do nothing for WASM_OP_REF_CAST_NULLABLE */
  2949. }
  2950. }
  2951. else {
  2952. bool castable = false;
  2953. if (heap_type >= 0) {
  2954. WASMModule *wasm_module = module->module;
  2955. castable = wasm_obj_is_instance_of(
  2956. gc_obj, (uint32)heap_type,
  2957. wasm_module->types,
  2958. wasm_module->type_count);
  2959. }
  2960. else {
  2961. castable =
  2962. wasm_obj_is_type_of(gc_obj, heap_type);
  2963. }
  2964. if (opcode == WASM_OP_REF_TEST
  2965. || opcode == WASM_OP_REF_TEST_NULLABLE) {
  2966. (void)POP_REF();
  2967. if (castable)
  2968. PUSH_I32(1);
  2969. else
  2970. PUSH_I32(0);
  2971. }
  2972. else if (!castable) {
  2973. wasm_set_exception(module, "cast failure");
  2974. goto got_exception;
  2975. }
  2976. }
  2977. HANDLE_OP_END();
  2978. }
  2979. case WASM_OP_BR_ON_CAST:
  2980. case WASM_OP_BR_ON_CAST_FAIL:
  2981. {
  2982. int32 heap_type, heap_type_dst;
  2983. uint8 castflags;
  2984. #if WASM_ENABLE_THREAD_MGR != 0
  2985. CHECK_SUSPEND_FLAGS();
  2986. #endif
  2987. castflags = *frame_ip++;
  2988. read_leb_uint32(frame_ip, frame_ip_end, depth);
  2989. read_leb_int32(frame_ip, frame_ip_end, heap_type);
  2990. read_leb_int32(frame_ip, frame_ip_end, heap_type_dst);
  2991. gc_obj = GET_REF_FROM_ADDR(frame_sp - REF_CELL_NUM);
  2992. if (!gc_obj) {
  2993. /*
  2994. * castflags should be 0~3:
  2995. * 0: (non-null, non-null)
  2996. * 1: (null, non-null)
  2997. * 2: (non-null, null)
  2998. * 3: (null, null)
  2999. */
  3000. if (
  3001. /* op is BR_ON_CAST and dst reftype is nullable
  3002. */
  3003. ((opcode1 == WASM_OP_BR_ON_CAST)
  3004. && ((castflags == 2) || (castflags == 3)))
  3005. /* op is BR_ON_CAST_FAIL and dst reftype is
  3006. non-nullable */
  3007. || ((opcode1 == WASM_OP_BR_ON_CAST_FAIL)
  3008. && ((castflags == 0) || (castflags == 1))))
  3009. goto label_pop_csp_n;
  3010. }
  3011. else {
  3012. bool castable = false;
  3013. if (heap_type_dst >= 0) {
  3014. WASMModule *wasm_module = module->module;
  3015. castable = wasm_obj_is_instance_of(
  3016. gc_obj, (uint32)heap_type_dst,
  3017. wasm_module->types,
  3018. wasm_module->type_count);
  3019. }
  3020. else {
  3021. castable =
  3022. wasm_obj_is_type_of(gc_obj, heap_type_dst);
  3023. }
  3024. if ((castable && (opcode == WASM_OP_BR_ON_CAST))
  3025. || (!castable
  3026. && (opcode == WASM_OP_BR_ON_CAST_FAIL))) {
  3027. goto label_pop_csp_n;
  3028. }
  3029. }
  3030. (void)heap_type;
  3031. HANDLE_OP_END();
  3032. }
  3033. case WASM_OP_ANY_CONVERT_EXTERN:
  3034. {
  3035. externref_obj = POP_REF();
  3036. if (externref_obj == NULL_REF)
  3037. PUSH_REF(NULL_REF);
  3038. else {
  3039. gc_obj = wasm_externref_obj_to_internal_obj(
  3040. externref_obj);
  3041. PUSH_REF(gc_obj);
  3042. }
  3043. HANDLE_OP_END();
  3044. }
  3045. case WASM_OP_EXTERN_CONVERT_ANY:
  3046. {
  3047. gc_obj = POP_REF();
  3048. if (gc_obj == NULL_REF)
  3049. PUSH_REF(NULL_REF);
  3050. else {
  3051. if (!(externref_obj =
  3052. wasm_internal_obj_to_externref_obj(
  3053. exec_env, gc_obj))) {
  3054. wasm_set_exception(
  3055. module, "create externref object failed");
  3056. goto got_exception;
  3057. }
  3058. PUSH_REF(externref_obj);
  3059. }
  3060. HANDLE_OP_END();
  3061. }
  3062. #if WASM_ENABLE_STRINGREF != 0
  3063. case WASM_OP_STRING_NEW_UTF8:
  3064. case WASM_OP_STRING_NEW_WTF16:
  3065. case WASM_OP_STRING_NEW_LOSSY_UTF8:
  3066. case WASM_OP_STRING_NEW_WTF8:
  3067. {
  3068. uint32 mem_idx, addr, bytes_length, offset = 0;
  3069. EncodingFlag flag = WTF8;
  3070. read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
  3071. bytes_length = POP_I32();
  3072. addr = POP_I32();
  3073. CHECK_MEMORY_OVERFLOW(bytes_length);
  3074. if (opcode == WASM_OP_STRING_NEW_WTF16) {
  3075. flag = WTF16;
  3076. }
  3077. else if (opcode == WASM_OP_STRING_NEW_UTF8) {
  3078. flag = UTF8;
  3079. }
  3080. else if (opcode == WASM_OP_STRING_NEW_LOSSY_UTF8) {
  3081. flag = LOSSY_UTF8;
  3082. }
  3083. else if (opcode == WASM_OP_STRING_NEW_WTF8) {
  3084. flag = WTF8;
  3085. }
  3086. str_obj = wasm_string_new_with_encoding(
  3087. maddr, bytes_length, flag);
  3088. if (!str_obj) {
  3089. wasm_set_exception(module,
  3090. "create string object failed");
  3091. goto got_exception;
  3092. }
  3093. SYNC_ALL_TO_FRAME();
  3094. stringref_obj =
  3095. wasm_stringref_obj_new(exec_env, str_obj);
  3096. if (!stringref_obj) {
  3097. wasm_set_exception(module,
  3098. "create stringref failed");
  3099. goto got_exception;
  3100. }
  3101. PUSH_REF(stringref_obj);
  3102. (void)mem_idx;
  3103. HANDLE_OP_END();
  3104. }
  3105. case WASM_OP_STRING_CONST:
  3106. {
  3107. WASMModule *wasm_module = module->module;
  3108. uint32 contents;
  3109. read_leb_uint32(frame_ip, frame_ip_end, contents);
  3110. str_obj = wasm_string_new_const(
  3111. (const char *)
  3112. wasm_module->string_literal_ptrs[contents],
  3113. wasm_module->string_literal_lengths[contents]);
  3114. if (!str_obj) {
  3115. wasm_set_exception(module,
  3116. "create string object failed");
  3117. goto got_exception;
  3118. }
  3119. SYNC_ALL_TO_FRAME();
  3120. stringref_obj =
  3121. wasm_stringref_obj_new(exec_env, str_obj);
  3122. if (!stringref_obj) {
  3123. wasm_set_exception(module,
  3124. "create stringref failed");
  3125. goto got_exception;
  3126. }
  3127. PUSH_REF(stringref_obj);
  3128. HANDLE_OP_END();
  3129. }
  3130. case WASM_OP_STRING_MEASURE_UTF8:
  3131. case WASM_OP_STRING_MEASURE_WTF8:
  3132. case WASM_OP_STRING_MEASURE_WTF16:
  3133. {
  3134. int32 target_bytes_length;
  3135. EncodingFlag flag = WTF8;
  3136. stringref_obj = POP_REF();
  3137. if (opcode == WASM_OP_STRING_MEASURE_WTF16) {
  3138. flag = WTF16;
  3139. }
  3140. else if (opcode == WASM_OP_STRING_MEASURE_UTF8) {
  3141. flag = UTF8;
  3142. }
  3143. else if (opcode == WASM_OP_STRING_MEASURE_WTF8) {
  3144. flag = LOSSY_UTF8;
  3145. }
  3146. target_bytes_length = wasm_string_measure(
  3147. (WASMString)wasm_stringref_obj_get_value(
  3148. stringref_obj),
  3149. flag);
  3150. PUSH_I32(target_bytes_length);
  3151. HANDLE_OP_END();
  3152. }
  3153. case WASM_OP_STRING_ENCODE_UTF8:
  3154. case WASM_OP_STRING_ENCODE_WTF16:
  3155. case WASM_OP_STRING_ENCODE_LOSSY_UTF8:
  3156. case WASM_OP_STRING_ENCODE_WTF8:
  3157. {
  3158. uint32 mem_idx, addr;
  3159. int32 target_bytes_length;
  3160. WASMMemoryInstance *memory_inst;
  3161. EncodingFlag flag = WTF8;
  3162. read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
  3163. addr = POP_I32();
  3164. stringref_obj = POP_REF();
  3165. str_obj = (WASMString)wasm_stringref_obj_get_value(
  3166. stringref_obj);
  3167. #if WASM_ENABLE_SHARED_HEAP != 0
  3168. if (app_addr_in_shared_heap((uint64)addr, 1))
  3169. shared_heap_addr_app_to_native((uint64)addr, maddr);
  3170. else
  3171. #endif
  3172. {
  3173. memory_inst = module->memories[mem_idx];
  3174. maddr = memory_inst->memory_data + addr;
  3175. }
  3176. if (opcode == WASM_OP_STRING_ENCODE_WTF16) {
  3177. flag = WTF16;
  3178. count = wasm_string_measure(str_obj, flag);
  3179. target_bytes_length = wasm_string_encode(
  3180. str_obj, 0, count, maddr, NULL, flag);
  3181. }
  3182. else {
  3183. if (opcode == WASM_OP_STRING_ENCODE_UTF8) {
  3184. flag = UTF8;
  3185. }
  3186. else if (opcode
  3187. == WASM_OP_STRING_ENCODE_LOSSY_UTF8) {
  3188. flag = LOSSY_UTF8;
  3189. }
  3190. else if (opcode == WASM_OP_STRING_ENCODE_WTF8) {
  3191. flag = WTF8;
  3192. }
  3193. count = wasm_string_measure(str_obj, flag);
  3194. target_bytes_length = wasm_string_encode(
  3195. str_obj, 0, count, maddr, NULL, flag);
  3196. if (target_bytes_length == -1) {
  3197. wasm_set_exception(
  3198. module, "isolated surrogate is seen");
  3199. goto got_exception;
  3200. }
  3201. }
  3202. if (target_bytes_length < 0) {
  3203. wasm_set_exception(module,
  3204. "stringref encode failed");
  3205. goto got_exception;
  3206. }
  3207. PUSH_I32(target_bytes_length);
  3208. HANDLE_OP_END();
  3209. }
  3210. case WASM_OP_STRING_CONCAT:
  3211. {
  3212. WASMStringrefObjectRef stringref_obj1, stringref_obj2;
  3213. stringref_obj2 = POP_REF();
  3214. stringref_obj1 = POP_REF();
  3215. str_obj = wasm_string_concat(
  3216. (WASMString)wasm_stringref_obj_get_value(
  3217. stringref_obj1),
  3218. (WASMString)wasm_stringref_obj_get_value(
  3219. stringref_obj2));
  3220. if (!str_obj) {
  3221. wasm_set_exception(module,
  3222. "create string object failed");
  3223. goto got_exception;
  3224. }
  3225. SYNC_ALL_TO_FRAME();
  3226. stringref_obj =
  3227. wasm_stringref_obj_new(exec_env, str_obj);
  3228. if (!stringref_obj) {
  3229. wasm_set_exception(module,
  3230. "create stringref failed");
  3231. goto got_exception;
  3232. }
  3233. PUSH_REF(stringref_obj);
  3234. HANDLE_OP_END();
  3235. }
  3236. case WASM_OP_STRING_EQ:
  3237. {
  3238. WASMStringrefObjectRef stringref_obj1, stringref_obj2;
  3239. int32 is_eq;
  3240. stringref_obj2 = POP_REF();
  3241. stringref_obj1 = POP_REF();
  3242. is_eq = wasm_string_eq(
  3243. (WASMString)wasm_stringref_obj_get_value(
  3244. stringref_obj1),
  3245. (WASMString)wasm_stringref_obj_get_value(
  3246. stringref_obj2));
  3247. PUSH_I32(is_eq);
  3248. HANDLE_OP_END();
  3249. }
  3250. case WASM_OP_STRING_IS_USV_SEQUENCE:
  3251. {
  3252. int32 is_usv_sequence;
  3253. stringref_obj = POP_REF();
  3254. is_usv_sequence = wasm_string_is_usv_sequence(
  3255. (WASMString)wasm_stringref_obj_get_value(
  3256. stringref_obj));
  3257. PUSH_I32(is_usv_sequence);
  3258. HANDLE_OP_END();
  3259. }
  3260. case WASM_OP_STRING_AS_WTF8:
  3261. {
  3262. stringref_obj = POP_REF();
  3263. str_obj = wasm_string_create_view(
  3264. (WASMString)wasm_stringref_obj_get_value(
  3265. stringref_obj),
  3266. STRING_VIEW_WTF8);
  3267. if (!str_obj) {
  3268. wasm_set_exception(module,
  3269. "create string object failed");
  3270. goto got_exception;
  3271. }
  3272. SYNC_ALL_TO_FRAME();
  3273. stringview_wtf8_obj =
  3274. wasm_stringview_wtf8_obj_new(exec_env, str_obj);
  3275. if (!stringview_wtf8_obj) {
  3276. wasm_set_exception(module,
  3277. "create stringview wtf8 failed");
  3278. goto got_exception;
  3279. }
  3280. PUSH_REF(stringview_wtf8_obj);
  3281. HANDLE_OP_END();
  3282. }
  3283. case WASM_OP_STRINGVIEW_WTF8_ADVANCE:
  3284. {
  3285. uint32 next_pos, bytes, pos;
  3286. bytes = POP_I32();
  3287. pos = POP_I32();
  3288. stringview_wtf8_obj = POP_REF();
  3289. next_pos = wasm_string_advance(
  3290. (WASMString)wasm_stringview_wtf8_obj_get_value(
  3291. stringview_wtf8_obj),
  3292. pos, bytes, NULL);
  3293. PUSH_I32(next_pos);
  3294. HANDLE_OP_END();
  3295. }
  3296. case WASM_OP_STRINGVIEW_WTF8_ENCODE_UTF8:
  3297. case WASM_OP_STRINGVIEW_WTF8_ENCODE_LOSSY_UTF8:
  3298. case WASM_OP_STRINGVIEW_WTF8_ENCODE_WTF8:
  3299. {
  3300. uint32 mem_idx, addr, pos, bytes, next_pos;
  3301. int32 bytes_written;
  3302. WASMMemoryInstance *memory_inst;
  3303. EncodingFlag flag = WTF8;
  3304. if (opcode == WASM_OP_STRINGVIEW_WTF8_ENCODE_UTF8) {
  3305. flag = UTF8;
  3306. }
  3307. else if (opcode
  3308. == WASM_OP_STRINGVIEW_WTF8_ENCODE_LOSSY_UTF8) {
  3309. flag = LOSSY_UTF8;
  3310. }
  3311. else if (opcode
  3312. == WASM_OP_STRINGVIEW_WTF8_ENCODE_WTF8) {
  3313. flag = WTF8;
  3314. }
  3315. read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
  3316. bytes = POP_I32();
  3317. pos = POP_I32();
  3318. addr = POP_I32();
  3319. stringview_wtf8_obj = POP_REF();
  3320. #if WASM_ENABLE_SHARED_HEAP != 0
  3321. if (app_addr_in_shared_heap((uint64)addr, 1))
  3322. shared_heap_addr_app_to_native((uint64)addr, maddr);
  3323. else
  3324. #endif
  3325. {
  3326. memory_inst = module->memories[mem_idx];
  3327. maddr = memory_inst->memory_data + addr;
  3328. }
  3329. bytes_written = wasm_string_encode(
  3330. (WASMString)wasm_stringview_wtf8_obj_get_value(
  3331. stringview_wtf8_obj),
  3332. pos, bytes, maddr, &next_pos, flag);
  3333. if (bytes_written < 0) {
  3334. if (bytes_written == Isolated_Surrogate) {
  3335. wasm_set_exception(
  3336. module, "isolated surrogate is seen");
  3337. }
  3338. else {
  3339. wasm_set_exception(module, "encode failed");
  3340. }
  3341. goto got_exception;
  3342. }
  3343. PUSH_I32(next_pos);
  3344. PUSH_I32(bytes_written);
  3345. HANDLE_OP_END();
  3346. }
  3347. case WASM_OP_STRINGVIEW_WTF8_SLICE:
  3348. {
  3349. uint32 start, end;
  3350. end = POP_I32();
  3351. start = POP_I32();
  3352. stringview_wtf8_obj = POP_REF();
  3353. str_obj = wasm_string_slice(
  3354. (WASMString)wasm_stringview_wtf8_obj_get_value(
  3355. stringview_wtf8_obj),
  3356. start, end, STRING_VIEW_WTF8);
  3357. if (!str_obj) {
  3358. wasm_set_exception(module,
  3359. "create string object failed");
  3360. goto got_exception;
  3361. }
  3362. SYNC_ALL_TO_FRAME();
  3363. stringref_obj =
  3364. wasm_stringref_obj_new(exec_env, str_obj);
  3365. if (!stringref_obj) {
  3366. wasm_set_exception(module,
  3367. "create stringref failed");
  3368. goto got_exception;
  3369. }
  3370. PUSH_REF(stringref_obj);
  3371. HANDLE_OP_END();
  3372. }
  3373. case WASM_OP_STRING_AS_WTF16:
  3374. {
  3375. stringref_obj = POP_REF();
  3376. str_obj = wasm_string_create_view(
  3377. (WASMString)wasm_stringref_obj_get_value(
  3378. stringref_obj),
  3379. STRING_VIEW_WTF16);
  3380. if (!str_obj) {
  3381. wasm_set_exception(module,
  3382. "create string object failed");
  3383. goto got_exception;
  3384. }
  3385. SYNC_ALL_TO_FRAME();
  3386. stringview_wtf16_obj =
  3387. wasm_stringview_wtf16_obj_new(exec_env, str_obj);
  3388. if (!stringview_wtf16_obj) {
  3389. wasm_set_exception(
  3390. module, "create stringview wtf16 failed");
  3391. goto got_exception;
  3392. }
  3393. PUSH_REF(stringview_wtf16_obj);
  3394. HANDLE_OP_END();
  3395. }
  3396. case WASM_OP_STRINGVIEW_WTF16_LENGTH:
  3397. {
  3398. int32 code_units_length;
  3399. stringview_wtf16_obj = POP_REF();
  3400. code_units_length = wasm_string_wtf16_get_length(
  3401. (WASMString)wasm_stringview_wtf16_obj_get_value(
  3402. stringview_wtf16_obj));
  3403. PUSH_I32(code_units_length);
  3404. HANDLE_OP_END();
  3405. }
  3406. case WASM_OP_STRINGVIEW_WTF16_GET_CODEUNIT:
  3407. {
  3408. int32 pos;
  3409. uint32 code_unit;
  3410. pos = POP_I32();
  3411. stringview_wtf16_obj = POP_REF();
  3412. code_unit = (uint32)wasm_string_get_wtf16_codeunit(
  3413. (WASMString)wasm_stringview_wtf16_obj_get_value(
  3414. stringview_wtf16_obj),
  3415. pos);
  3416. PUSH_I32(code_unit);
  3417. HANDLE_OP_END();
  3418. }
  3419. case WASM_OP_STRINGVIEW_WTF16_ENCODE:
  3420. {
  3421. uint32 mem_idx, addr, pos, len, offset = 0;
  3422. int32 written_code_units = 0;
  3423. read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
  3424. len = POP_I32();
  3425. pos = POP_I32();
  3426. addr = POP_I32();
  3427. stringview_wtf16_obj = POP_REF();
  3428. CHECK_MEMORY_OVERFLOW(len * sizeof(uint16));
  3429. /* check 2-byte alignment */
  3430. if (((uintptr_t)maddr & (((uintptr_t)1 << 2) - 1))
  3431. != 0) {
  3432. wasm_set_exception(module,
  3433. "unaligned memory access");
  3434. goto got_exception;
  3435. }
  3436. written_code_units = wasm_string_encode(
  3437. (WASMString)wasm_stringview_wtf16_obj_get_value(
  3438. stringview_wtf16_obj),
  3439. pos, len, maddr, NULL, WTF16);
  3440. if (written_code_units < 0) {
  3441. wasm_set_exception(module, "encode failed");
  3442. goto got_exception;
  3443. }
  3444. PUSH_I32(written_code_units);
  3445. (void)mem_idx;
  3446. HANDLE_OP_END();
  3447. }
  3448. case WASM_OP_STRINGVIEW_WTF16_SLICE:
  3449. {
  3450. uint32 start, end;
  3451. end = POP_I32();
  3452. start = POP_I32();
  3453. stringview_wtf16_obj = POP_REF();
  3454. str_obj = wasm_string_slice(
  3455. (WASMString)wasm_stringview_wtf16_obj_get_value(
  3456. stringview_wtf16_obj),
  3457. start, end, STRING_VIEW_WTF16);
  3458. if (!str_obj) {
  3459. wasm_set_exception(module,
  3460. "create string object failed");
  3461. goto got_exception;
  3462. }
  3463. SYNC_ALL_TO_FRAME();
  3464. stringref_obj =
  3465. wasm_stringref_obj_new(exec_env, str_obj);
  3466. if (!stringref_obj) {
  3467. wasm_set_exception(module,
  3468. "create stringref failed");
  3469. goto got_exception;
  3470. }
  3471. PUSH_REF(stringref_obj);
  3472. HANDLE_OP_END();
  3473. }
  3474. case WASM_OP_STRING_AS_ITER:
  3475. {
  3476. stringref_obj = POP_REF();
  3477. str_obj = wasm_string_create_view(
  3478. (WASMString)wasm_stringref_obj_get_value(
  3479. stringref_obj),
  3480. STRING_VIEW_ITER);
  3481. if (!str_obj) {
  3482. wasm_set_exception(module,
  3483. "create string object failed");
  3484. goto got_exception;
  3485. }
  3486. SYNC_ALL_TO_FRAME();
  3487. stringview_iter_obj =
  3488. wasm_stringview_iter_obj_new(exec_env, str_obj, 0);
  3489. if (!stringview_iter_obj) {
  3490. wasm_set_exception(module,
  3491. "create stringview iter failed");
  3492. goto got_exception;
  3493. }
  3494. PUSH_REF(stringview_iter_obj);
  3495. HANDLE_OP_END();
  3496. }
  3497. case WASM_OP_STRINGVIEW_ITER_NEXT:
  3498. {
  3499. uint32 code_point;
  3500. stringview_iter_obj = POP_REF();
  3501. code_point = wasm_string_next_codepoint(
  3502. (WASMString)wasm_stringview_iter_obj_get_value(
  3503. stringview_iter_obj),
  3504. wasm_stringview_iter_obj_get_pos(
  3505. stringview_iter_obj));
  3506. PUSH_I32(code_point);
  3507. HANDLE_OP_END();
  3508. }
  3509. case WASM_OP_STRINGVIEW_ITER_ADVANCE:
  3510. case WASM_OP_STRINGVIEW_ITER_REWIND:
  3511. {
  3512. uint32 code_points_count, code_points_consumed = 0,
  3513. cur_pos, next_pos = 0;
  3514. code_points_count = POP_I32();
  3515. stringview_iter_obj = POP_REF();
  3516. str_obj =
  3517. (WASMString)wasm_stringview_iter_obj_get_value(
  3518. stringview_iter_obj);
  3519. cur_pos = wasm_stringview_iter_obj_get_pos(
  3520. stringview_iter_obj);
  3521. if (opcode == WASM_OP_STRINGVIEW_ITER_ADVANCE) {
  3522. next_pos = wasm_string_advance(
  3523. str_obj, cur_pos, code_points_count,
  3524. &code_points_consumed);
  3525. }
  3526. else if (opcode == WASM_OP_STRINGVIEW_ITER_REWIND) {
  3527. next_pos = wasm_string_rewind(
  3528. str_obj, cur_pos, code_points_count,
  3529. &code_points_consumed);
  3530. }
  3531. wasm_stringview_iter_obj_update_pos(stringview_iter_obj,
  3532. next_pos);
  3533. PUSH_I32(code_points_consumed);
  3534. HANDLE_OP_END();
  3535. }
  3536. case WASM_OP_STRINGVIEW_ITER_SLICE:
  3537. {
  3538. uint32 code_points_count, cur_pos;
  3539. code_points_count = POP_I32();
  3540. stringview_iter_obj = POP_REF();
  3541. cur_pos = wasm_stringview_iter_obj_get_pos(
  3542. stringview_iter_obj);
  3543. str_obj = wasm_string_slice(
  3544. (WASMString)wasm_stringview_iter_obj_get_value(
  3545. stringview_iter_obj),
  3546. cur_pos, cur_pos + code_points_count,
  3547. STRING_VIEW_ITER);
  3548. if (!str_obj) {
  3549. wasm_set_exception(module,
  3550. "create string object failed");
  3551. goto got_exception;
  3552. }
  3553. SYNC_ALL_TO_FRAME();
  3554. stringref_obj =
  3555. wasm_stringref_obj_new(exec_env, str_obj);
  3556. if (!stringref_obj) {
  3557. wasm_set_exception(module,
  3558. "create stringref failed");
  3559. goto got_exception;
  3560. }
  3561. PUSH_REF(stringref_obj);
  3562. HANDLE_OP_END();
  3563. }
  3564. case WASM_OP_STRING_NEW_UTF8_ARRAY:
  3565. case WASM_OP_STRING_NEW_WTF16_ARRAY:
  3566. case WASM_OP_STRING_NEW_LOSSY_UTF8_ARRAY:
  3567. case WASM_OP_STRING_NEW_WTF8_ARRAY:
  3568. {
  3569. uint32 start, end, array_len;
  3570. EncodingFlag flag = WTF8;
  3571. WASMArrayType *array_type;
  3572. void *arr_start_addr;
  3573. end = POP_I32();
  3574. start = POP_I32();
  3575. array_obj = POP_REF();
  3576. array_type = (WASMArrayType *)wasm_obj_get_defined_type(
  3577. (WASMObjectRef)array_obj);
  3578. arr_start_addr =
  3579. wasm_array_obj_elem_addr(array_obj, start);
  3580. array_len = wasm_array_obj_length(array_obj);
  3581. if (start > end || end > array_len) {
  3582. wasm_set_exception(module,
  3583. "out of bounds array access");
  3584. goto got_exception;
  3585. }
  3586. if (opcode == WASM_OP_STRING_NEW_WTF16_ARRAY) {
  3587. if (array_type->elem_type != VALUE_TYPE_I16) {
  3588. wasm_set_exception(module,
  3589. "array type mismatch");
  3590. goto got_exception;
  3591. }
  3592. flag = WTF16;
  3593. }
  3594. else {
  3595. if (array_type->elem_type != VALUE_TYPE_I8) {
  3596. wasm_set_exception(module,
  3597. "array type mismatch");
  3598. goto got_exception;
  3599. }
  3600. if (opcode == WASM_OP_STRING_NEW_UTF8_ARRAY) {
  3601. flag = UTF8;
  3602. }
  3603. else if (opcode == WASM_OP_STRING_NEW_WTF8_ARRAY) {
  3604. flag = WTF8;
  3605. }
  3606. else if (opcode
  3607. == WASM_OP_STRING_NEW_LOSSY_UTF8_ARRAY) {
  3608. flag = LOSSY_UTF8;
  3609. }
  3610. }
  3611. str_obj = wasm_string_new_with_encoding(
  3612. arr_start_addr, (end - start), flag);
  3613. if (!str_obj) {
  3614. wasm_set_exception(module,
  3615. "create string object failed");
  3616. goto got_exception;
  3617. }
  3618. SYNC_ALL_TO_FRAME();
  3619. stringref_obj =
  3620. wasm_stringref_obj_new(exec_env, str_obj);
  3621. if (!stringref_obj) {
  3622. wasm_set_exception(module,
  3623. "create stringref failed");
  3624. goto got_exception;
  3625. }
  3626. PUSH_REF(stringref_obj);
  3627. HANDLE_OP_END();
  3628. }
  3629. case WASM_OP_STRING_ENCODE_UTF8_ARRAY:
  3630. case WASM_OP_STRING_ENCODE_WTF16_ARRAY:
  3631. case WASM_OP_STRING_ENCODE_LOSSY_UTF8_ARRAY:
  3632. case WASM_OP_STRING_ENCODE_WTF8_ARRAY:
  3633. {
  3634. uint32 start, array_len, count;
  3635. int32 bytes_written;
  3636. EncodingFlag flag = WTF8;
  3637. WASMArrayType *array_type;
  3638. void *arr_start_addr;
  3639. start = POP_I32();
  3640. array_obj = POP_REF();
  3641. stringref_obj = POP_REF();
  3642. str_obj = (WASMString)wasm_stringref_obj_get_value(
  3643. stringref_obj);
  3644. array_type = (WASMArrayType *)wasm_obj_get_defined_type(
  3645. (WASMObjectRef)array_obj);
  3646. arr_start_addr =
  3647. wasm_array_obj_elem_addr(array_obj, start);
  3648. array_len = wasm_array_obj_length(array_obj);
  3649. if (start > array_len) {
  3650. wasm_set_exception(module,
  3651. "out of bounds array access");
  3652. goto got_exception;
  3653. }
  3654. if (opcode == WASM_OP_STRING_ENCODE_WTF16_ARRAY) {
  3655. if (array_type->elem_type != VALUE_TYPE_I16) {
  3656. wasm_set_exception(module,
  3657. "array type mismatch");
  3658. goto got_exception;
  3659. }
  3660. flag = WTF16;
  3661. }
  3662. else {
  3663. if (array_type->elem_type != VALUE_TYPE_I8) {
  3664. wasm_set_exception(module,
  3665. "array type mismatch");
  3666. goto got_exception;
  3667. }
  3668. if (opcode == WASM_OP_STRING_ENCODE_UTF8_ARRAY) {
  3669. flag = UTF8;
  3670. }
  3671. else if (opcode
  3672. == WASM_OP_STRING_ENCODE_WTF8_ARRAY) {
  3673. flag = WTF8;
  3674. }
  3675. else if (
  3676. opcode
  3677. == WASM_OP_STRING_ENCODE_LOSSY_UTF8_ARRAY) {
  3678. flag = LOSSY_UTF8;
  3679. }
  3680. }
  3681. count = wasm_string_measure(str_obj, flag);
  3682. bytes_written = wasm_string_encode(
  3683. str_obj, 0, count, arr_start_addr, NULL, flag);
  3684. if (bytes_written < 0) {
  3685. if (bytes_written == Isolated_Surrogate) {
  3686. wasm_set_exception(
  3687. module, "isolated surrogate is seen");
  3688. }
  3689. else if (bytes_written == Insufficient_Space) {
  3690. wasm_set_exception(
  3691. module, "array space is insufficient");
  3692. }
  3693. else {
  3694. wasm_set_exception(module, "encode failed");
  3695. }
  3696. goto got_exception;
  3697. }
  3698. PUSH_I32(bytes_written);
  3699. HANDLE_OP_END();
  3700. }
  3701. #endif /* end of WASM_ENABLE_STRINGREF != 0 */
  3702. default:
  3703. {
  3704. wasm_set_exception(module, "unsupported opcode");
  3705. goto got_exception;
  3706. }
  3707. }
  3708. }
  3709. #endif /* end of WASM_ENABLE_GC != 0 */
  3710. /* variable instructions */
  3711. HANDLE_OP(WASM_OP_GET_LOCAL)
  3712. {
  3713. GET_LOCAL_INDEX_TYPE_AND_OFFSET();
  3714. switch (local_type) {
  3715. case VALUE_TYPE_I32:
  3716. case VALUE_TYPE_F32:
  3717. #if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0
  3718. case VALUE_TYPE_FUNCREF:
  3719. case VALUE_TYPE_EXTERNREF:
  3720. #endif
  3721. PUSH_I32(*(int32 *)(frame_lp + local_offset));
  3722. break;
  3723. case VALUE_TYPE_I64:
  3724. case VALUE_TYPE_F64:
  3725. PUSH_I64(GET_I64_FROM_ADDR(frame_lp + local_offset));
  3726. break;
  3727. default:
  3728. #if WASM_ENABLE_GC != 0
  3729. if (wasm_is_type_reftype(local_type)) {
  3730. if (wasm_is_reftype_i31ref(local_type)) {
  3731. PUSH_I31REF(
  3732. GET_REF_FROM_ADDR(frame_lp + local_offset));
  3733. }
  3734. else {
  3735. PUSH_REF(
  3736. GET_REF_FROM_ADDR(frame_lp + local_offset));
  3737. }
  3738. }
  3739. else
  3740. #endif
  3741. {
  3742. wasm_set_exception(module, "invalid local type");
  3743. goto got_exception;
  3744. }
  3745. }
  3746. HANDLE_OP_END();
  3747. }
  3748. HANDLE_OP(EXT_OP_GET_LOCAL_FAST)
  3749. {
  3750. local_offset = *frame_ip++;
  3751. if (local_offset & 0x80)
  3752. PUSH_I64(
  3753. GET_I64_FROM_ADDR(frame_lp + (local_offset & 0x7F)));
  3754. else
  3755. PUSH_I32(*(int32 *)(frame_lp + local_offset));
  3756. HANDLE_OP_END();
  3757. }
  3758. HANDLE_OP(WASM_OP_SET_LOCAL)
  3759. {
  3760. GET_LOCAL_INDEX_TYPE_AND_OFFSET();
  3761. switch (local_type) {
  3762. case VALUE_TYPE_I32:
  3763. case VALUE_TYPE_F32:
  3764. #if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0
  3765. case VALUE_TYPE_FUNCREF:
  3766. case VALUE_TYPE_EXTERNREF:
  3767. #endif
  3768. *(int32 *)(frame_lp + local_offset) = POP_I32();
  3769. break;
  3770. case VALUE_TYPE_I64:
  3771. case VALUE_TYPE_F64:
  3772. PUT_I64_TO_ADDR((uint32 *)(frame_lp + local_offset),
  3773. POP_I64());
  3774. break;
  3775. default:
  3776. #if WASM_ENABLE_GC != 0
  3777. if (wasm_is_type_reftype(local_type)) {
  3778. PUT_REF_TO_ADDR(frame_lp + local_offset, POP_REF());
  3779. }
  3780. else
  3781. #endif
  3782. {
  3783. wasm_set_exception(module, "invalid local type");
  3784. goto got_exception;
  3785. }
  3786. }
  3787. HANDLE_OP_END();
  3788. }
  3789. HANDLE_OP(EXT_OP_SET_LOCAL_FAST)
  3790. {
  3791. local_offset = *frame_ip++;
  3792. if (local_offset & 0x80)
  3793. PUT_I64_TO_ADDR(
  3794. (uint32 *)(frame_lp + (local_offset & 0x7F)),
  3795. POP_I64());
  3796. else
  3797. *(int32 *)(frame_lp + local_offset) = POP_I32();
  3798. HANDLE_OP_END();
  3799. }
  3800. HANDLE_OP(WASM_OP_TEE_LOCAL)
  3801. {
  3802. GET_LOCAL_INDEX_TYPE_AND_OFFSET();
  3803. switch (local_type) {
  3804. case VALUE_TYPE_I32:
  3805. case VALUE_TYPE_F32:
  3806. #if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0
  3807. case VALUE_TYPE_FUNCREF:
  3808. case VALUE_TYPE_EXTERNREF:
  3809. #endif
  3810. *(int32 *)(frame_lp + local_offset) =
  3811. *(int32 *)(frame_sp - 1);
  3812. break;
  3813. case VALUE_TYPE_I64:
  3814. case VALUE_TYPE_F64:
  3815. PUT_I64_TO_ADDR((uint32 *)(frame_lp + local_offset),
  3816. GET_I64_FROM_ADDR(frame_sp - 2));
  3817. break;
  3818. default:
  3819. #if WASM_ENABLE_GC != 0
  3820. if (wasm_is_type_reftype(local_type)) {
  3821. PUT_REF_TO_ADDR(
  3822. frame_lp + local_offset,
  3823. GET_REF_FROM_ADDR(frame_sp - REF_CELL_NUM));
  3824. }
  3825. else
  3826. #endif
  3827. {
  3828. wasm_set_exception(module, "invalid local type");
  3829. goto got_exception;
  3830. }
  3831. }
  3832. HANDLE_OP_END();
  3833. }
  3834. HANDLE_OP(EXT_OP_TEE_LOCAL_FAST)
  3835. {
  3836. local_offset = *frame_ip++;
  3837. if (local_offset & 0x80)
  3838. PUT_I64_TO_ADDR(
  3839. (uint32 *)(frame_lp + (local_offset & 0x7F)),
  3840. GET_I64_FROM_ADDR(frame_sp - 2));
  3841. else
  3842. *(int32 *)(frame_lp + local_offset) =
  3843. *(int32 *)(frame_sp - 1);
  3844. HANDLE_OP_END();
  3845. }
  3846. HANDLE_OP(WASM_OP_GET_GLOBAL)
  3847. {
  3848. read_leb_uint32(frame_ip, frame_ip_end, global_idx);
  3849. bh_assert(global_idx < module->e->global_count);
  3850. global = globals + global_idx;
  3851. global_addr = get_global_addr(global_data, global);
  3852. /* clang-format off */
  3853. #if WASM_ENABLE_GC == 0
  3854. PUSH_I32(*(uint32 *)global_addr);
  3855. #else
  3856. if (!wasm_is_type_reftype(global->type)) {
  3857. PUSH_I32(*(uint32 *)global_addr);
  3858. }
  3859. else if (wasm_is_reftype_i31ref(global->type)) {
  3860. PUSH_I31REF(GET_REF_FROM_ADDR((uint32 *)global_addr));
  3861. }
  3862. else {
  3863. PUSH_REF(GET_REF_FROM_ADDR((uint32 *)global_addr));
  3864. }
  3865. #endif
  3866. /* clang-format on */
  3867. HANDLE_OP_END();
  3868. }
  3869. HANDLE_OP(WASM_OP_GET_GLOBAL_64)
  3870. {
  3871. read_leb_uint32(frame_ip, frame_ip_end, global_idx);
  3872. bh_assert(global_idx < module->e->global_count);
  3873. global = globals + global_idx;
  3874. global_addr = get_global_addr(global_data, global);
  3875. PUSH_I64(GET_I64_FROM_ADDR((uint32 *)global_addr));
  3876. HANDLE_OP_END();
  3877. }
  3878. HANDLE_OP(WASM_OP_SET_GLOBAL)
  3879. {
  3880. read_leb_uint32(frame_ip, frame_ip_end, global_idx);
  3881. bh_assert(global_idx < module->e->global_count);
  3882. global = globals + global_idx;
  3883. global_addr = get_global_addr(global_data, global);
  3884. /* clang-format off */
  3885. #if WASM_ENABLE_GC == 0
  3886. *(int32 *)global_addr = POP_I32();
  3887. #else
  3888. if (!wasm_is_type_reftype(global->type))
  3889. *(int32 *)global_addr = POP_I32();
  3890. else
  3891. PUT_REF_TO_ADDR((uint32 *)global_addr, POP_REF());
  3892. #endif
  3893. /* clang-format on */
  3894. HANDLE_OP_END();
  3895. }
  3896. HANDLE_OP(WASM_OP_SET_GLOBAL_AUX_STACK)
  3897. {
  3898. uint64 aux_stack_top;
  3899. read_leb_uint32(frame_ip, frame_ip_end, global_idx);
  3900. bh_assert(global_idx < module->e->global_count);
  3901. global = globals + global_idx;
  3902. global_addr = get_global_addr(global_data, global);
  3903. #if WASM_ENABLE_MEMORY64 != 0
  3904. if (is_memory64) {
  3905. aux_stack_top = *(uint64 *)(frame_sp - 2);
  3906. }
  3907. else
  3908. #endif
  3909. {
  3910. aux_stack_top = (uint64)(*(uint32 *)(frame_sp - 1));
  3911. }
  3912. if (aux_stack_top <= (uint64)exec_env->aux_stack_boundary) {
  3913. wasm_set_exception(module, "wasm auxiliary stack overflow");
  3914. goto got_exception;
  3915. }
  3916. if (aux_stack_top > (uint64)exec_env->aux_stack_bottom) {
  3917. wasm_set_exception(module,
  3918. "wasm auxiliary stack underflow");
  3919. goto got_exception;
  3920. }
  3921. #if WASM_ENABLE_MEMORY64 != 0
  3922. if (is_memory64) {
  3923. *(uint64 *)global_addr = aux_stack_top;
  3924. frame_sp -= 2;
  3925. }
  3926. else
  3927. #endif
  3928. {
  3929. *(uint32 *)global_addr = (uint32)aux_stack_top;
  3930. frame_sp--;
  3931. }
  3932. #if WASM_ENABLE_MEMORY_PROFILING != 0
  3933. if (module->module->aux_stack_top_global_index != (uint32)-1) {
  3934. uint32 aux_stack_used =
  3935. (uint32)(module->module->aux_stack_bottom
  3936. - *(uint32 *)global_addr);
  3937. if (aux_stack_used > module->e->max_aux_stack_used)
  3938. module->e->max_aux_stack_used = aux_stack_used;
  3939. }
  3940. #endif
  3941. HANDLE_OP_END();
  3942. }
  3943. HANDLE_OP(WASM_OP_SET_GLOBAL_64)
  3944. {
  3945. read_leb_uint32(frame_ip, frame_ip_end, global_idx);
  3946. bh_assert(global_idx < module->e->global_count);
  3947. global = globals + global_idx;
  3948. global_addr = get_global_addr(global_data, global);
  3949. PUT_I64_TO_ADDR((uint32 *)global_addr, POP_I64());
  3950. HANDLE_OP_END();
  3951. }
  3952. /* memory load instructions */
  3953. HANDLE_OP(WASM_OP_I32_LOAD)
  3954. HANDLE_OP(WASM_OP_F32_LOAD)
  3955. {
  3956. uint32 flags;
  3957. mem_offset_t offset, addr;
  3958. read_leb_memarg(frame_ip, frame_ip_end, flags);
  3959. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  3960. addr = POP_MEM_OFFSET();
  3961. CHECK_MEMORY_OVERFLOW(4);
  3962. PUSH_I32(LOAD_I32(maddr));
  3963. CHECK_READ_WATCHPOINT(addr, offset);
  3964. HANDLE_OP_END();
  3965. }
  3966. HANDLE_OP(WASM_OP_I64_LOAD)
  3967. HANDLE_OP(WASM_OP_F64_LOAD)
  3968. {
  3969. uint32 flags;
  3970. mem_offset_t offset, addr;
  3971. read_leb_memarg(frame_ip, frame_ip_end, flags);
  3972. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  3973. addr = POP_MEM_OFFSET();
  3974. CHECK_MEMORY_OVERFLOW(8);
  3975. PUSH_I64(LOAD_I64(maddr));
  3976. CHECK_READ_WATCHPOINT(addr, offset);
  3977. HANDLE_OP_END();
  3978. }
  3979. HANDLE_OP(WASM_OP_I32_LOAD8_S)
  3980. {
  3981. uint32 flags;
  3982. mem_offset_t offset, addr;
  3983. read_leb_memarg(frame_ip, frame_ip_end, flags);
  3984. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  3985. addr = POP_MEM_OFFSET();
  3986. CHECK_MEMORY_OVERFLOW(1);
  3987. PUSH_I32(sign_ext_8_32(*(int8 *)maddr));
  3988. CHECK_READ_WATCHPOINT(addr, offset);
  3989. HANDLE_OP_END();
  3990. }
  3991. HANDLE_OP(WASM_OP_I32_LOAD8_U)
  3992. {
  3993. uint32 flags;
  3994. mem_offset_t offset, addr;
  3995. read_leb_memarg(frame_ip, frame_ip_end, flags);
  3996. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  3997. addr = POP_MEM_OFFSET();
  3998. CHECK_MEMORY_OVERFLOW(1);
  3999. PUSH_I32((uint32)(*(uint8 *)maddr));
  4000. CHECK_READ_WATCHPOINT(addr, offset);
  4001. HANDLE_OP_END();
  4002. }
  4003. HANDLE_OP(WASM_OP_I32_LOAD16_S)
  4004. {
  4005. uint32 flags;
  4006. mem_offset_t offset, addr;
  4007. read_leb_memarg(frame_ip, frame_ip_end, flags);
  4008. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  4009. addr = POP_MEM_OFFSET();
  4010. CHECK_MEMORY_OVERFLOW(2);
  4011. PUSH_I32(sign_ext_16_32(LOAD_I16(maddr)));
  4012. CHECK_READ_WATCHPOINT(addr, offset);
  4013. HANDLE_OP_END();
  4014. }
  4015. HANDLE_OP(WASM_OP_I32_LOAD16_U)
  4016. {
  4017. uint32 flags;
  4018. mem_offset_t offset, addr;
  4019. read_leb_memarg(frame_ip, frame_ip_end, flags);
  4020. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  4021. addr = POP_MEM_OFFSET();
  4022. CHECK_MEMORY_OVERFLOW(2);
  4023. PUSH_I32((uint32)(LOAD_U16(maddr)));
  4024. CHECK_READ_WATCHPOINT(addr, offset);
  4025. HANDLE_OP_END();
  4026. }
  4027. HANDLE_OP(WASM_OP_I64_LOAD8_S)
  4028. {
  4029. uint32 flags;
  4030. mem_offset_t offset, addr;
  4031. read_leb_memarg(frame_ip, frame_ip_end, flags);
  4032. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  4033. addr = POP_MEM_OFFSET();
  4034. CHECK_MEMORY_OVERFLOW(1);
  4035. PUSH_I64(sign_ext_8_64(*(int8 *)maddr));
  4036. CHECK_READ_WATCHPOINT(addr, offset);
  4037. HANDLE_OP_END();
  4038. }
  4039. HANDLE_OP(WASM_OP_I64_LOAD8_U)
  4040. {
  4041. uint32 flags;
  4042. mem_offset_t offset, addr;
  4043. read_leb_memarg(frame_ip, frame_ip_end, flags);
  4044. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  4045. addr = POP_MEM_OFFSET();
  4046. CHECK_MEMORY_OVERFLOW(1);
  4047. PUSH_I64((uint64)(*(uint8 *)maddr));
  4048. CHECK_READ_WATCHPOINT(addr, offset);
  4049. HANDLE_OP_END();
  4050. }
  4051. HANDLE_OP(WASM_OP_I64_LOAD16_S)
  4052. {
  4053. uint32 flags;
  4054. mem_offset_t offset, addr;
  4055. read_leb_memarg(frame_ip, frame_ip_end, flags);
  4056. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  4057. addr = POP_MEM_OFFSET();
  4058. CHECK_MEMORY_OVERFLOW(2);
  4059. PUSH_I64(sign_ext_16_64(LOAD_I16(maddr)));
  4060. CHECK_READ_WATCHPOINT(addr, offset);
  4061. HANDLE_OP_END();
  4062. }
  4063. HANDLE_OP(WASM_OP_I64_LOAD16_U)
  4064. {
  4065. uint32 flags;
  4066. mem_offset_t offset, addr;
  4067. read_leb_memarg(frame_ip, frame_ip_end, flags);
  4068. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  4069. addr = POP_MEM_OFFSET();
  4070. CHECK_MEMORY_OVERFLOW(2);
  4071. PUSH_I64((uint64)(LOAD_U16(maddr)));
  4072. CHECK_READ_WATCHPOINT(addr, offset);
  4073. HANDLE_OP_END();
  4074. }
  4075. HANDLE_OP(WASM_OP_I64_LOAD32_S)
  4076. {
  4077. uint32 flags;
  4078. mem_offset_t offset, addr;
  4079. read_leb_memarg(frame_ip, frame_ip_end, flags);
  4080. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  4081. addr = POP_MEM_OFFSET();
  4082. CHECK_MEMORY_OVERFLOW(4);
  4083. PUSH_I64(sign_ext_32_64(LOAD_I32(maddr)));
  4084. CHECK_READ_WATCHPOINT(addr, offset);
  4085. HANDLE_OP_END();
  4086. }
  4087. HANDLE_OP(WASM_OP_I64_LOAD32_U)
  4088. {
  4089. uint32 flags;
  4090. mem_offset_t offset, addr;
  4091. read_leb_memarg(frame_ip, frame_ip_end, flags);
  4092. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  4093. addr = POP_MEM_OFFSET();
  4094. CHECK_MEMORY_OVERFLOW(4);
  4095. PUSH_I64((uint64)(LOAD_U32(maddr)));
  4096. CHECK_READ_WATCHPOINT(addr, offset);
  4097. HANDLE_OP_END();
  4098. }
  4099. /* memory store instructions */
  4100. HANDLE_OP(WASM_OP_I32_STORE)
  4101. HANDLE_OP(WASM_OP_F32_STORE)
  4102. {
  4103. uint32 flags;
  4104. mem_offset_t offset, addr;
  4105. read_leb_memarg(frame_ip, frame_ip_end, flags);
  4106. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  4107. frame_sp--;
  4108. addr = POP_MEM_OFFSET();
  4109. CHECK_MEMORY_OVERFLOW(4);
  4110. #if WASM_ENABLE_MEMORY64 != 0
  4111. if (is_memory64) {
  4112. STORE_U32(maddr, frame_sp[2]);
  4113. }
  4114. else
  4115. #endif
  4116. {
  4117. STORE_U32(maddr, frame_sp[1]);
  4118. }
  4119. CHECK_WRITE_WATCHPOINT(addr, offset);
  4120. HANDLE_OP_END();
  4121. }
  4122. HANDLE_OP(WASM_OP_I64_STORE)
  4123. HANDLE_OP(WASM_OP_F64_STORE)
  4124. {
  4125. uint32 flags;
  4126. mem_offset_t offset, addr;
  4127. read_leb_memarg(frame_ip, frame_ip_end, flags);
  4128. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  4129. frame_sp -= 2;
  4130. addr = POP_MEM_OFFSET();
  4131. CHECK_MEMORY_OVERFLOW(8);
  4132. #if WASM_ENABLE_MEMORY64 != 0
  4133. if (is_memory64) {
  4134. PUT_I64_TO_ADDR((mem_offset_t *)maddr,
  4135. GET_I64_FROM_ADDR(frame_sp + 2));
  4136. }
  4137. else
  4138. #endif
  4139. {
  4140. PUT_I64_TO_ADDR((uint32 *)maddr,
  4141. GET_I64_FROM_ADDR(frame_sp + 1));
  4142. }
  4143. CHECK_WRITE_WATCHPOINT(addr, offset);
  4144. HANDLE_OP_END();
  4145. }
  4146. HANDLE_OP(WASM_OP_I32_STORE8)
  4147. HANDLE_OP(WASM_OP_I32_STORE16)
  4148. {
  4149. uint32 flags;
  4150. mem_offset_t offset, addr;
  4151. uint32 sval;
  4152. opcode = *(frame_ip - 1);
  4153. read_leb_memarg(frame_ip, frame_ip_end, flags);
  4154. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  4155. sval = (uint32)POP_I32();
  4156. addr = POP_MEM_OFFSET();
  4157. if (opcode == WASM_OP_I32_STORE8) {
  4158. CHECK_MEMORY_OVERFLOW(1);
  4159. *(uint8 *)maddr = (uint8)sval;
  4160. }
  4161. else {
  4162. CHECK_MEMORY_OVERFLOW(2);
  4163. STORE_U16(maddr, (uint16)sval);
  4164. }
  4165. CHECK_WRITE_WATCHPOINT(addr, offset);
  4166. HANDLE_OP_END();
  4167. }
  4168. HANDLE_OP(WASM_OP_I64_STORE8)
  4169. HANDLE_OP(WASM_OP_I64_STORE16)
  4170. HANDLE_OP(WASM_OP_I64_STORE32)
  4171. {
  4172. uint32 flags;
  4173. mem_offset_t offset, addr;
  4174. uint64 sval;
  4175. opcode = *(frame_ip - 1);
  4176. read_leb_memarg(frame_ip, frame_ip_end, flags);
  4177. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  4178. sval = (uint64)POP_I64();
  4179. addr = POP_MEM_OFFSET();
  4180. if (opcode == WASM_OP_I64_STORE8) {
  4181. CHECK_MEMORY_OVERFLOW(1);
  4182. *(uint8 *)maddr = (uint8)sval;
  4183. }
  4184. else if (opcode == WASM_OP_I64_STORE16) {
  4185. CHECK_MEMORY_OVERFLOW(2);
  4186. STORE_U16(maddr, (uint16)sval);
  4187. }
  4188. else {
  4189. CHECK_MEMORY_OVERFLOW(4);
  4190. STORE_U32(maddr, (uint32)sval);
  4191. }
  4192. CHECK_WRITE_WATCHPOINT(addr, offset);
  4193. HANDLE_OP_END();
  4194. }
  4195. /* memory size and memory grow instructions */
  4196. HANDLE_OP(WASM_OP_MEMORY_SIZE)
  4197. {
  4198. uint32 mem_idx;
  4199. read_leb_memidx(frame_ip, frame_ip_end, mem_idx);
  4200. PUSH_PAGE_COUNT(memory->cur_page_count);
  4201. HANDLE_OP_END();
  4202. }
  4203. HANDLE_OP(WASM_OP_MEMORY_GROW)
  4204. {
  4205. uint32 mem_idx, prev_page_count;
  4206. mem_offset_t delta;
  4207. read_leb_memidx(frame_ip, frame_ip_end, mem_idx);
  4208. prev_page_count = memory->cur_page_count;
  4209. delta = POP_PAGE_COUNT();
  4210. if (
  4211. #if WASM_ENABLE_MEMORY64 != 0
  4212. delta > UINT32_MAX ||
  4213. #endif
  4214. !wasm_enlarge_memory_with_idx(module, (uint32)delta,
  4215. mem_idx)) {
  4216. /* failed to memory.grow, return -1 */
  4217. PUSH_PAGE_COUNT(-1);
  4218. }
  4219. else {
  4220. /* success, return previous page count */
  4221. PUSH_PAGE_COUNT(prev_page_count);
  4222. /* update memory size, no need to update memory ptr as
  4223. it isn't changed in wasm_enlarge_memory */
  4224. #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
  4225. || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
  4226. || WASM_ENABLE_BULK_MEMORY != 0
  4227. linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory);
  4228. #endif
  4229. }
  4230. HANDLE_OP_END();
  4231. }
  4232. /* constant instructions */
  4233. HANDLE_OP(WASM_OP_I32_CONST)
  4234. DEF_OP_I_CONST(int32, I32);
  4235. HANDLE_OP_END();
  4236. HANDLE_OP(WASM_OP_I64_CONST)
  4237. DEF_OP_I_CONST(int64, I64);
  4238. HANDLE_OP_END();
  4239. HANDLE_OP(WASM_OP_F32_CONST)
  4240. {
  4241. uint8 *p_float = (uint8 *)frame_sp++;
  4242. for (i = 0; i < sizeof(float32); i++)
  4243. *p_float++ = *frame_ip++;
  4244. HANDLE_OP_END();
  4245. }
  4246. HANDLE_OP(WASM_OP_F64_CONST)
  4247. {
  4248. uint8 *p_float = (uint8 *)frame_sp++;
  4249. frame_sp++;
  4250. for (i = 0; i < sizeof(float64); i++)
  4251. *p_float++ = *frame_ip++;
  4252. HANDLE_OP_END();
  4253. }
  4254. /* comparison instructions of i32 */
  4255. HANDLE_OP(WASM_OP_I32_EQZ)
  4256. {
  4257. DEF_OP_EQZ(I32);
  4258. HANDLE_OP_END();
  4259. }
  4260. HANDLE_OP(WASM_OP_I32_EQ)
  4261. {
  4262. DEF_OP_CMP(uint32, I32, ==);
  4263. HANDLE_OP_END();
  4264. }
  4265. HANDLE_OP(WASM_OP_I32_NE)
  4266. {
  4267. DEF_OP_CMP(uint32, I32, !=);
  4268. HANDLE_OP_END();
  4269. }
  4270. HANDLE_OP(WASM_OP_I32_LT_S)
  4271. {
  4272. DEF_OP_CMP(int32, I32, <);
  4273. HANDLE_OP_END();
  4274. }
  4275. HANDLE_OP(WASM_OP_I32_LT_U)
  4276. {
  4277. DEF_OP_CMP(uint32, I32, <);
  4278. HANDLE_OP_END();
  4279. }
  4280. HANDLE_OP(WASM_OP_I32_GT_S)
  4281. {
  4282. DEF_OP_CMP(int32, I32, >);
  4283. HANDLE_OP_END();
  4284. }
  4285. HANDLE_OP(WASM_OP_I32_GT_U)
  4286. {
  4287. DEF_OP_CMP(uint32, I32, >);
  4288. HANDLE_OP_END();
  4289. }
  4290. HANDLE_OP(WASM_OP_I32_LE_S)
  4291. {
  4292. DEF_OP_CMP(int32, I32, <=);
  4293. HANDLE_OP_END();
  4294. }
  4295. HANDLE_OP(WASM_OP_I32_LE_U)
  4296. {
  4297. DEF_OP_CMP(uint32, I32, <=);
  4298. HANDLE_OP_END();
  4299. }
  4300. HANDLE_OP(WASM_OP_I32_GE_S)
  4301. {
  4302. DEF_OP_CMP(int32, I32, >=);
  4303. HANDLE_OP_END();
  4304. }
  4305. HANDLE_OP(WASM_OP_I32_GE_U)
  4306. {
  4307. DEF_OP_CMP(uint32, I32, >=);
  4308. HANDLE_OP_END();
  4309. }
  4310. /* comparison instructions of i64 */
  4311. HANDLE_OP(WASM_OP_I64_EQZ)
  4312. {
  4313. DEF_OP_EQZ(I64);
  4314. HANDLE_OP_END();
  4315. }
  4316. HANDLE_OP(WASM_OP_I64_EQ)
  4317. {
  4318. DEF_OP_CMP(uint64, I64, ==);
  4319. HANDLE_OP_END();
  4320. }
  4321. HANDLE_OP(WASM_OP_I64_NE)
  4322. {
  4323. DEF_OP_CMP(uint64, I64, !=);
  4324. HANDLE_OP_END();
  4325. }
  4326. HANDLE_OP(WASM_OP_I64_LT_S)
  4327. {
  4328. DEF_OP_CMP(int64, I64, <);
  4329. HANDLE_OP_END();
  4330. }
  4331. HANDLE_OP(WASM_OP_I64_LT_U)
  4332. {
  4333. DEF_OP_CMP(uint64, I64, <);
  4334. HANDLE_OP_END();
  4335. }
  4336. HANDLE_OP(WASM_OP_I64_GT_S)
  4337. {
  4338. DEF_OP_CMP(int64, I64, >);
  4339. HANDLE_OP_END();
  4340. }
  4341. HANDLE_OP(WASM_OP_I64_GT_U)
  4342. {
  4343. DEF_OP_CMP(uint64, I64, >);
  4344. HANDLE_OP_END();
  4345. }
  4346. HANDLE_OP(WASM_OP_I64_LE_S)
  4347. {
  4348. DEF_OP_CMP(int64, I64, <=);
  4349. HANDLE_OP_END();
  4350. }
  4351. HANDLE_OP(WASM_OP_I64_LE_U)
  4352. {
  4353. DEF_OP_CMP(uint64, I64, <=);
  4354. HANDLE_OP_END();
  4355. }
  4356. HANDLE_OP(WASM_OP_I64_GE_S)
  4357. {
  4358. DEF_OP_CMP(int64, I64, >=);
  4359. HANDLE_OP_END();
  4360. }
  4361. HANDLE_OP(WASM_OP_I64_GE_U)
  4362. {
  4363. DEF_OP_CMP(uint64, I64, >=);
  4364. HANDLE_OP_END();
  4365. }
  4366. /* comparison instructions of f32 */
  4367. HANDLE_OP(WASM_OP_F32_EQ)
  4368. {
  4369. DEF_OP_CMP(float32, F32, ==);
  4370. HANDLE_OP_END();
  4371. }
  4372. HANDLE_OP(WASM_OP_F32_NE)
  4373. {
  4374. DEF_OP_CMP(float32, F32, !=);
  4375. HANDLE_OP_END();
  4376. }
  4377. HANDLE_OP(WASM_OP_F32_LT)
  4378. {
  4379. DEF_OP_CMP(float32, F32, <);
  4380. HANDLE_OP_END();
  4381. }
  4382. HANDLE_OP(WASM_OP_F32_GT)
  4383. {
  4384. DEF_OP_CMP(float32, F32, >);
  4385. HANDLE_OP_END();
  4386. }
  4387. HANDLE_OP(WASM_OP_F32_LE)
  4388. {
  4389. DEF_OP_CMP(float32, F32, <=);
  4390. HANDLE_OP_END();
  4391. }
  4392. HANDLE_OP(WASM_OP_F32_GE)
  4393. {
  4394. DEF_OP_CMP(float32, F32, >=);
  4395. HANDLE_OP_END();
  4396. }
  4397. /* comparison instructions of f64 */
  4398. HANDLE_OP(WASM_OP_F64_EQ)
  4399. {
  4400. DEF_OP_CMP(float64, F64, ==);
  4401. HANDLE_OP_END();
  4402. }
  4403. HANDLE_OP(WASM_OP_F64_NE)
  4404. {
  4405. DEF_OP_CMP(float64, F64, !=);
  4406. HANDLE_OP_END();
  4407. }
  4408. HANDLE_OP(WASM_OP_F64_LT)
  4409. {
  4410. DEF_OP_CMP(float64, F64, <);
  4411. HANDLE_OP_END();
  4412. }
  4413. HANDLE_OP(WASM_OP_F64_GT)
  4414. {
  4415. DEF_OP_CMP(float64, F64, >);
  4416. HANDLE_OP_END();
  4417. }
  4418. HANDLE_OP(WASM_OP_F64_LE)
  4419. {
  4420. DEF_OP_CMP(float64, F64, <=);
  4421. HANDLE_OP_END();
  4422. }
  4423. HANDLE_OP(WASM_OP_F64_GE)
  4424. {
  4425. DEF_OP_CMP(float64, F64, >=);
  4426. HANDLE_OP_END();
  4427. }
  4428. /* numberic instructions of i32 */
  4429. HANDLE_OP(WASM_OP_I32_CLZ)
  4430. {
  4431. DEF_OP_BIT_COUNT(uint32, I32, clz32);
  4432. HANDLE_OP_END();
  4433. }
  4434. HANDLE_OP(WASM_OP_I32_CTZ)
  4435. {
  4436. DEF_OP_BIT_COUNT(uint32, I32, ctz32);
  4437. HANDLE_OP_END();
  4438. }
  4439. HANDLE_OP(WASM_OP_I32_POPCNT)
  4440. {
  4441. DEF_OP_BIT_COUNT(uint32, I32, popcount32);
  4442. HANDLE_OP_END();
  4443. }
  4444. HANDLE_OP(WASM_OP_I32_ADD)
  4445. {
  4446. DEF_OP_NUMERIC(uint32, uint32, I32, +);
  4447. HANDLE_OP_END();
  4448. }
  4449. HANDLE_OP(WASM_OP_I32_SUB)
  4450. {
  4451. DEF_OP_NUMERIC(uint32, uint32, I32, -);
  4452. HANDLE_OP_END();
  4453. }
  4454. HANDLE_OP(WASM_OP_I32_MUL)
  4455. {
  4456. DEF_OP_NUMERIC(uint32, uint32, I32, *);
  4457. HANDLE_OP_END();
  4458. }
  4459. HANDLE_OP(WASM_OP_I32_DIV_S)
  4460. {
  4461. int32 a, b;
  4462. b = POP_I32();
  4463. a = POP_I32();
  4464. if (a == (int32)0x80000000 && b == -1) {
  4465. wasm_set_exception(module, "integer overflow");
  4466. goto got_exception;
  4467. }
  4468. if (b == 0) {
  4469. wasm_set_exception(module, "integer divide by zero");
  4470. goto got_exception;
  4471. }
  4472. PUSH_I32(a / b);
  4473. HANDLE_OP_END();
  4474. }
  4475. HANDLE_OP(WASM_OP_I32_DIV_U)
  4476. {
  4477. uint32 a, b;
  4478. b = (uint32)POP_I32();
  4479. a = (uint32)POP_I32();
  4480. if (b == 0) {
  4481. wasm_set_exception(module, "integer divide by zero");
  4482. goto got_exception;
  4483. }
  4484. PUSH_I32(a / b);
  4485. HANDLE_OP_END();
  4486. }
  4487. HANDLE_OP(WASM_OP_I32_REM_S)
  4488. {
  4489. int32 a, b;
  4490. b = POP_I32();
  4491. a = POP_I32();
  4492. if (a == (int32)0x80000000 && b == -1) {
  4493. PUSH_I32(0);
  4494. HANDLE_OP_END();
  4495. }
  4496. if (b == 0) {
  4497. wasm_set_exception(module, "integer divide by zero");
  4498. goto got_exception;
  4499. }
  4500. PUSH_I32(a % b);
  4501. HANDLE_OP_END();
  4502. }
  4503. HANDLE_OP(WASM_OP_I32_REM_U)
  4504. {
  4505. uint32 a, b;
  4506. b = (uint32)POP_I32();
  4507. a = (uint32)POP_I32();
  4508. if (b == 0) {
  4509. wasm_set_exception(module, "integer divide by zero");
  4510. goto got_exception;
  4511. }
  4512. PUSH_I32(a % b);
  4513. HANDLE_OP_END();
  4514. }
  4515. HANDLE_OP(WASM_OP_I32_AND)
  4516. {
  4517. DEF_OP_NUMERIC(uint32, uint32, I32, &);
  4518. HANDLE_OP_END();
  4519. }
  4520. HANDLE_OP(WASM_OP_I32_OR)
  4521. {
  4522. DEF_OP_NUMERIC(uint32, uint32, I32, |);
  4523. HANDLE_OP_END();
  4524. }
  4525. HANDLE_OP(WASM_OP_I32_XOR)
  4526. {
  4527. DEF_OP_NUMERIC(uint32, uint32, I32, ^);
  4528. HANDLE_OP_END();
  4529. }
  4530. HANDLE_OP(WASM_OP_I32_SHL)
  4531. {
  4532. DEF_OP_NUMERIC2(uint32, uint32, I32, <<);
  4533. HANDLE_OP_END();
  4534. }
  4535. HANDLE_OP(WASM_OP_I32_SHR_S)
  4536. {
  4537. DEF_OP_NUMERIC2(int32, uint32, I32, >>);
  4538. HANDLE_OP_END();
  4539. }
  4540. HANDLE_OP(WASM_OP_I32_SHR_U)
  4541. {
  4542. DEF_OP_NUMERIC2(uint32, uint32, I32, >>);
  4543. HANDLE_OP_END();
  4544. }
  4545. HANDLE_OP(WASM_OP_I32_ROTL)
  4546. {
  4547. uint32 a, b;
  4548. b = (uint32)POP_I32();
  4549. a = (uint32)POP_I32();
  4550. PUSH_I32(rotl32(a, b));
  4551. HANDLE_OP_END();
  4552. }
  4553. HANDLE_OP(WASM_OP_I32_ROTR)
  4554. {
  4555. uint32 a, b;
  4556. b = (uint32)POP_I32();
  4557. a = (uint32)POP_I32();
  4558. PUSH_I32(rotr32(a, b));
  4559. HANDLE_OP_END();
  4560. }
  4561. /* numberic instructions of i64 */
  4562. HANDLE_OP(WASM_OP_I64_CLZ)
  4563. {
  4564. DEF_OP_BIT_COUNT(uint64, I64, clz64);
  4565. HANDLE_OP_END();
  4566. }
  4567. HANDLE_OP(WASM_OP_I64_CTZ)
  4568. {
  4569. DEF_OP_BIT_COUNT(uint64, I64, ctz64);
  4570. HANDLE_OP_END();
  4571. }
  4572. HANDLE_OP(WASM_OP_I64_POPCNT)
  4573. {
  4574. DEF_OP_BIT_COUNT(uint64, I64, popcount64);
  4575. HANDLE_OP_END();
  4576. }
  4577. HANDLE_OP(WASM_OP_I64_ADD)
  4578. {
  4579. DEF_OP_NUMERIC_64(uint64, uint64, I64, +);
  4580. HANDLE_OP_END();
  4581. }
  4582. HANDLE_OP(WASM_OP_I64_SUB)
  4583. {
  4584. DEF_OP_NUMERIC_64(uint64, uint64, I64, -);
  4585. HANDLE_OP_END();
  4586. }
  4587. HANDLE_OP(WASM_OP_I64_MUL)
  4588. {
  4589. DEF_OP_NUMERIC_64(uint64, uint64, I64, *);
  4590. HANDLE_OP_END();
  4591. }
  4592. HANDLE_OP(WASM_OP_I64_DIV_S)
  4593. {
  4594. int64 a, b;
  4595. b = POP_I64();
  4596. a = POP_I64();
  4597. if (a == (int64)0x8000000000000000LL && b == -1) {
  4598. wasm_set_exception(module, "integer overflow");
  4599. goto got_exception;
  4600. }
  4601. if (b == 0) {
  4602. wasm_set_exception(module, "integer divide by zero");
  4603. goto got_exception;
  4604. }
  4605. PUSH_I64(a / b);
  4606. HANDLE_OP_END();
  4607. }
  4608. HANDLE_OP(WASM_OP_I64_DIV_U)
  4609. {
  4610. uint64 a, b;
  4611. b = (uint64)POP_I64();
  4612. a = (uint64)POP_I64();
  4613. if (b == 0) {
  4614. wasm_set_exception(module, "integer divide by zero");
  4615. goto got_exception;
  4616. }
  4617. PUSH_I64(a / b);
  4618. HANDLE_OP_END();
  4619. }
  4620. HANDLE_OP(WASM_OP_I64_REM_S)
  4621. {
  4622. int64 a, b;
  4623. b = POP_I64();
  4624. a = POP_I64();
  4625. if (a == (int64)0x8000000000000000LL && b == -1) {
  4626. PUSH_I64(0);
  4627. HANDLE_OP_END();
  4628. }
  4629. if (b == 0) {
  4630. wasm_set_exception(module, "integer divide by zero");
  4631. goto got_exception;
  4632. }
  4633. PUSH_I64(a % b);
  4634. HANDLE_OP_END();
  4635. }
  4636. HANDLE_OP(WASM_OP_I64_REM_U)
  4637. {
  4638. uint64 a, b;
  4639. b = (uint64)POP_I64();
  4640. a = (uint64)POP_I64();
  4641. if (b == 0) {
  4642. wasm_set_exception(module, "integer divide by zero");
  4643. goto got_exception;
  4644. }
  4645. PUSH_I64(a % b);
  4646. HANDLE_OP_END();
  4647. }
  4648. HANDLE_OP(WASM_OP_I64_AND)
  4649. {
  4650. DEF_OP_NUMERIC_64(uint64, uint64, I64, &);
  4651. HANDLE_OP_END();
  4652. }
  4653. HANDLE_OP(WASM_OP_I64_OR)
  4654. {
  4655. DEF_OP_NUMERIC_64(uint64, uint64, I64, |);
  4656. HANDLE_OP_END();
  4657. }
  4658. HANDLE_OP(WASM_OP_I64_XOR)
  4659. {
  4660. DEF_OP_NUMERIC_64(uint64, uint64, I64, ^);
  4661. HANDLE_OP_END();
  4662. }
  4663. HANDLE_OP(WASM_OP_I64_SHL)
  4664. {
  4665. DEF_OP_NUMERIC2_64(uint64, uint64, I64, <<);
  4666. HANDLE_OP_END();
  4667. }
  4668. HANDLE_OP(WASM_OP_I64_SHR_S)
  4669. {
  4670. DEF_OP_NUMERIC2_64(int64, uint64, I64, >>);
  4671. HANDLE_OP_END();
  4672. }
  4673. HANDLE_OP(WASM_OP_I64_SHR_U)
  4674. {
  4675. DEF_OP_NUMERIC2_64(uint64, uint64, I64, >>);
  4676. HANDLE_OP_END();
  4677. }
  4678. HANDLE_OP(WASM_OP_I64_ROTL)
  4679. {
  4680. uint64 a, b;
  4681. b = (uint64)POP_I64();
  4682. a = (uint64)POP_I64();
  4683. PUSH_I64(rotl64(a, b));
  4684. HANDLE_OP_END();
  4685. }
  4686. HANDLE_OP(WASM_OP_I64_ROTR)
  4687. {
  4688. uint64 a, b;
  4689. b = (uint64)POP_I64();
  4690. a = (uint64)POP_I64();
  4691. PUSH_I64(rotr64(a, b));
  4692. HANDLE_OP_END();
  4693. }
  4694. /* numberic instructions of f32 */
  4695. HANDLE_OP(WASM_OP_F32_ABS)
  4696. {
  4697. DEF_OP_MATH(float32, F32, fabsf);
  4698. HANDLE_OP_END();
  4699. }
  4700. HANDLE_OP(WASM_OP_F32_NEG)
  4701. {
  4702. uint32 u32 = frame_sp[-1];
  4703. uint32 sign_bit = u32 & ((uint32)1 << 31);
  4704. if (sign_bit)
  4705. frame_sp[-1] = u32 & ~((uint32)1 << 31);
  4706. else
  4707. frame_sp[-1] = u32 | ((uint32)1 << 31);
  4708. HANDLE_OP_END();
  4709. }
  4710. HANDLE_OP(WASM_OP_F32_CEIL)
  4711. {
  4712. DEF_OP_MATH(float32, F32, ceilf);
  4713. HANDLE_OP_END();
  4714. }
  4715. HANDLE_OP(WASM_OP_F32_FLOOR)
  4716. {
  4717. DEF_OP_MATH(float32, F32, floorf);
  4718. HANDLE_OP_END();
  4719. }
  4720. HANDLE_OP(WASM_OP_F32_TRUNC)
  4721. {
  4722. DEF_OP_MATH(float32, F32, truncf);
  4723. HANDLE_OP_END();
  4724. }
  4725. HANDLE_OP(WASM_OP_F32_NEAREST)
  4726. {
  4727. DEF_OP_MATH(float32, F32, rintf);
  4728. HANDLE_OP_END();
  4729. }
  4730. HANDLE_OP(WASM_OP_F32_SQRT)
  4731. {
  4732. DEF_OP_MATH(float32, F32, sqrtf);
  4733. HANDLE_OP_END();
  4734. }
  4735. HANDLE_OP(WASM_OP_F32_ADD)
  4736. {
  4737. DEF_OP_NUMERIC(float32, float32, F32, +);
  4738. HANDLE_OP_END();
  4739. }
  4740. HANDLE_OP(WASM_OP_F32_SUB)
  4741. {
  4742. DEF_OP_NUMERIC(float32, float32, F32, -);
  4743. HANDLE_OP_END();
  4744. }
  4745. HANDLE_OP(WASM_OP_F32_MUL)
  4746. {
  4747. DEF_OP_NUMERIC(float32, float32, F32, *);
  4748. HANDLE_OP_END();
  4749. }
  4750. HANDLE_OP(WASM_OP_F32_DIV)
  4751. {
  4752. DEF_OP_NUMERIC(float32, float32, F32, /);
  4753. HANDLE_OP_END();
  4754. }
  4755. HANDLE_OP(WASM_OP_F32_MIN)
  4756. {
  4757. float32 a, b;
  4758. b = POP_F32();
  4759. a = POP_F32();
  4760. PUSH_F32(f32_min(a, b));
  4761. HANDLE_OP_END();
  4762. }
  4763. HANDLE_OP(WASM_OP_F32_MAX)
  4764. {
  4765. float32 a, b;
  4766. b = POP_F32();
  4767. a = POP_F32();
  4768. PUSH_F32(f32_max(a, b));
  4769. HANDLE_OP_END();
  4770. }
  4771. HANDLE_OP(WASM_OP_F32_COPYSIGN)
  4772. {
  4773. float32 a, b;
  4774. b = POP_F32();
  4775. a = POP_F32();
  4776. PUSH_F32(local_copysignf(a, b));
  4777. HANDLE_OP_END();
  4778. }
  4779. /* numberic instructions of f64 */
  4780. HANDLE_OP(WASM_OP_F64_ABS)
  4781. {
  4782. DEF_OP_MATH(float64, F64, fabs);
  4783. HANDLE_OP_END();
  4784. }
  4785. HANDLE_OP(WASM_OP_F64_NEG)
  4786. {
  4787. uint64 u64 = GET_I64_FROM_ADDR(frame_sp - 2);
  4788. uint64 sign_bit = u64 & (((uint64)1) << 63);
  4789. if (sign_bit)
  4790. PUT_I64_TO_ADDR(frame_sp - 2, (u64 & ~(((uint64)1) << 63)));
  4791. else
  4792. PUT_I64_TO_ADDR(frame_sp - 2, (u64 | (((uint64)1) << 63)));
  4793. HANDLE_OP_END();
  4794. }
  4795. HANDLE_OP(WASM_OP_F64_CEIL)
  4796. {
  4797. DEF_OP_MATH(float64, F64, ceil);
  4798. HANDLE_OP_END();
  4799. }
  4800. HANDLE_OP(WASM_OP_F64_FLOOR)
  4801. {
  4802. DEF_OP_MATH(float64, F64, floor);
  4803. HANDLE_OP_END();
  4804. }
  4805. HANDLE_OP(WASM_OP_F64_TRUNC)
  4806. {
  4807. DEF_OP_MATH(float64, F64, trunc);
  4808. HANDLE_OP_END();
  4809. }
  4810. HANDLE_OP(WASM_OP_F64_NEAREST)
  4811. {
  4812. DEF_OP_MATH(float64, F64, rint);
  4813. HANDLE_OP_END();
  4814. }
  4815. HANDLE_OP(WASM_OP_F64_SQRT)
  4816. {
  4817. DEF_OP_MATH(float64, F64, sqrt);
  4818. HANDLE_OP_END();
  4819. }
  4820. HANDLE_OP(WASM_OP_F64_ADD)
  4821. {
  4822. DEF_OP_NUMERIC_64(float64, float64, F64, +);
  4823. HANDLE_OP_END();
  4824. }
  4825. HANDLE_OP(WASM_OP_F64_SUB)
  4826. {
  4827. DEF_OP_NUMERIC_64(float64, float64, F64, -);
  4828. HANDLE_OP_END();
  4829. }
  4830. HANDLE_OP(WASM_OP_F64_MUL)
  4831. {
  4832. DEF_OP_NUMERIC_64(float64, float64, F64, *);
  4833. HANDLE_OP_END();
  4834. }
  4835. HANDLE_OP(WASM_OP_F64_DIV)
  4836. {
  4837. DEF_OP_NUMERIC_64(float64, float64, F64, /);
  4838. HANDLE_OP_END();
  4839. }
  4840. HANDLE_OP(WASM_OP_F64_MIN)
  4841. {
  4842. float64 a, b;
  4843. b = POP_F64();
  4844. a = POP_F64();
  4845. PUSH_F64(f64_min(a, b));
  4846. HANDLE_OP_END();
  4847. }
  4848. HANDLE_OP(WASM_OP_F64_MAX)
  4849. {
  4850. float64 a, b;
  4851. b = POP_F64();
  4852. a = POP_F64();
  4853. PUSH_F64(f64_max(a, b));
  4854. HANDLE_OP_END();
  4855. }
  4856. HANDLE_OP(WASM_OP_F64_COPYSIGN)
  4857. {
  4858. float64 a, b;
  4859. b = POP_F64();
  4860. a = POP_F64();
  4861. PUSH_F64(local_copysign(a, b));
  4862. HANDLE_OP_END();
  4863. }
  4864. /* conversions of i32 */
  4865. HANDLE_OP(WASM_OP_I32_WRAP_I64)
  4866. {
  4867. int32 value = (int32)(POP_I64() & 0xFFFFFFFFLL);
  4868. PUSH_I32(value);
  4869. HANDLE_OP_END();
  4870. }
  4871. HANDLE_OP(WASM_OP_I32_TRUNC_S_F32)
  4872. {
  4873. /* We don't use INT32_MIN/INT32_MAX/UINT32_MIN/UINT32_MAX,
  4874. since float/double values of ieee754 cannot precisely
  4875. represent all int32/uint32/int64/uint64 values, e.g.
  4876. UINT32_MAX is 4294967295, but (float32)4294967295 is
  4877. 4294967296.0f, but not 4294967295.0f. */
  4878. DEF_OP_TRUNC_F32(-2147483904.0f, 2147483648.0f, true, true);
  4879. HANDLE_OP_END();
  4880. }
  4881. HANDLE_OP(WASM_OP_I32_TRUNC_U_F32)
  4882. {
  4883. DEF_OP_TRUNC_F32(-1.0f, 4294967296.0f, true, false);
  4884. HANDLE_OP_END();
  4885. }
  4886. HANDLE_OP(WASM_OP_I32_TRUNC_S_F64)
  4887. {
  4888. DEF_OP_TRUNC_F64(-2147483649.0, 2147483648.0, true, true);
  4889. /* frame_sp can't be moved in trunc function, we need to
  4890. manually adjust it if src and dst op's cell num is
  4891. different */
  4892. frame_sp--;
  4893. HANDLE_OP_END();
  4894. }
  4895. HANDLE_OP(WASM_OP_I32_TRUNC_U_F64)
  4896. {
  4897. DEF_OP_TRUNC_F64(-1.0, 4294967296.0, true, false);
  4898. frame_sp--;
  4899. HANDLE_OP_END();
  4900. }
  4901. /* conversions of i64 */
  4902. HANDLE_OP(WASM_OP_I64_EXTEND_S_I32)
  4903. {
  4904. DEF_OP_CONVERT(int64, I64, int32, I32);
  4905. HANDLE_OP_END();
  4906. }
  4907. HANDLE_OP(WASM_OP_I64_EXTEND_U_I32)
  4908. {
  4909. DEF_OP_CONVERT(int64, I64, uint32, I32);
  4910. HANDLE_OP_END();
  4911. }
  4912. HANDLE_OP(WASM_OP_I64_TRUNC_S_F32)
  4913. {
  4914. DEF_OP_TRUNC_F32(-9223373136366403584.0f,
  4915. 9223372036854775808.0f, false, true);
  4916. frame_sp++;
  4917. HANDLE_OP_END();
  4918. }
  4919. HANDLE_OP(WASM_OP_I64_TRUNC_U_F32)
  4920. {
  4921. DEF_OP_TRUNC_F32(-1.0f, 18446744073709551616.0f, false, false);
  4922. frame_sp++;
  4923. HANDLE_OP_END();
  4924. }
  4925. HANDLE_OP(WASM_OP_I64_TRUNC_S_F64)
  4926. {
  4927. DEF_OP_TRUNC_F64(-9223372036854777856.0, 9223372036854775808.0,
  4928. false, true);
  4929. HANDLE_OP_END();
  4930. }
  4931. HANDLE_OP(WASM_OP_I64_TRUNC_U_F64)
  4932. {
  4933. DEF_OP_TRUNC_F64(-1.0, 18446744073709551616.0, false, false);
  4934. HANDLE_OP_END();
  4935. }
  4936. /* conversions of f32 */
  4937. HANDLE_OP(WASM_OP_F32_CONVERT_S_I32)
  4938. {
  4939. DEF_OP_CONVERT(float32, F32, int32, I32);
  4940. HANDLE_OP_END();
  4941. }
  4942. HANDLE_OP(WASM_OP_F32_CONVERT_U_I32)
  4943. {
  4944. DEF_OP_CONVERT(float32, F32, uint32, I32);
  4945. HANDLE_OP_END();
  4946. }
  4947. HANDLE_OP(WASM_OP_F32_CONVERT_S_I64)
  4948. {
  4949. DEF_OP_CONVERT(float32, F32, int64, I64);
  4950. HANDLE_OP_END();
  4951. }
  4952. HANDLE_OP(WASM_OP_F32_CONVERT_U_I64)
  4953. {
  4954. DEF_OP_CONVERT(float32, F32, uint64, I64);
  4955. HANDLE_OP_END();
  4956. }
  4957. HANDLE_OP(WASM_OP_F32_DEMOTE_F64)
  4958. {
  4959. DEF_OP_CONVERT(float32, F32, float64, F64);
  4960. HANDLE_OP_END();
  4961. }
  4962. /* conversions of f64 */
  4963. HANDLE_OP(WASM_OP_F64_CONVERT_S_I32)
  4964. {
  4965. DEF_OP_CONVERT(float64, F64, int32, I32);
  4966. HANDLE_OP_END();
  4967. }
  4968. HANDLE_OP(WASM_OP_F64_CONVERT_U_I32)
  4969. {
  4970. DEF_OP_CONVERT(float64, F64, uint32, I32);
  4971. HANDLE_OP_END();
  4972. }
  4973. HANDLE_OP(WASM_OP_F64_CONVERT_S_I64)
  4974. {
  4975. DEF_OP_CONVERT(float64, F64, int64, I64);
  4976. HANDLE_OP_END();
  4977. }
  4978. HANDLE_OP(WASM_OP_F64_CONVERT_U_I64)
  4979. {
  4980. DEF_OP_CONVERT(float64, F64, uint64, I64);
  4981. HANDLE_OP_END();
  4982. }
  4983. HANDLE_OP(WASM_OP_F64_PROMOTE_F32)
  4984. {
  4985. DEF_OP_CONVERT(float64, F64, float32, F32);
  4986. HANDLE_OP_END();
  4987. }
  4988. /* reinterpretations */
  4989. HANDLE_OP(WASM_OP_I32_REINTERPRET_F32)
  4990. HANDLE_OP(WASM_OP_I64_REINTERPRET_F64)
  4991. HANDLE_OP(WASM_OP_F32_REINTERPRET_I32)
  4992. HANDLE_OP(WASM_OP_F64_REINTERPRET_I64) { HANDLE_OP_END(); }
  4993. HANDLE_OP(WASM_OP_I32_EXTEND8_S)
  4994. {
  4995. DEF_OP_CONVERT(int32, I32, int8, I32);
  4996. HANDLE_OP_END();
  4997. }
  4998. HANDLE_OP(WASM_OP_I32_EXTEND16_S)
  4999. {
  5000. DEF_OP_CONVERT(int32, I32, int16, I32);
  5001. HANDLE_OP_END();
  5002. }
  5003. HANDLE_OP(WASM_OP_I64_EXTEND8_S)
  5004. {
  5005. DEF_OP_CONVERT(int64, I64, int8, I64);
  5006. HANDLE_OP_END();
  5007. }
  5008. HANDLE_OP(WASM_OP_I64_EXTEND16_S)
  5009. {
  5010. DEF_OP_CONVERT(int64, I64, int16, I64);
  5011. HANDLE_OP_END();
  5012. }
  5013. HANDLE_OP(WASM_OP_I64_EXTEND32_S)
  5014. {
  5015. DEF_OP_CONVERT(int64, I64, int32, I64);
  5016. HANDLE_OP_END();
  5017. }
  5018. HANDLE_OP(WASM_OP_MISC_PREFIX)
  5019. {
  5020. uint32 opcode1;
  5021. read_leb_uint32(frame_ip, frame_ip_end, opcode1);
  5022. /* opcode1 was checked in loader and is no larger than
  5023. UINT8_MAX */
  5024. opcode = (uint8)opcode1;
  5025. switch (opcode) {
  5026. case WASM_OP_I32_TRUNC_SAT_S_F32:
  5027. DEF_OP_TRUNC_SAT_F32(-2147483904.0f, 2147483648.0f,
  5028. true, true);
  5029. break;
  5030. case WASM_OP_I32_TRUNC_SAT_U_F32:
  5031. DEF_OP_TRUNC_SAT_F32(-1.0f, 4294967296.0f, true, false);
  5032. break;
  5033. case WASM_OP_I32_TRUNC_SAT_S_F64:
  5034. DEF_OP_TRUNC_SAT_F64(-2147483649.0, 2147483648.0, true,
  5035. true);
  5036. frame_sp--;
  5037. break;
  5038. case WASM_OP_I32_TRUNC_SAT_U_F64:
  5039. DEF_OP_TRUNC_SAT_F64(-1.0, 4294967296.0, true, false);
  5040. frame_sp--;
  5041. break;
  5042. case WASM_OP_I64_TRUNC_SAT_S_F32:
  5043. DEF_OP_TRUNC_SAT_F32(-9223373136366403584.0f,
  5044. 9223372036854775808.0f, false,
  5045. true);
  5046. frame_sp++;
  5047. break;
  5048. case WASM_OP_I64_TRUNC_SAT_U_F32:
  5049. DEF_OP_TRUNC_SAT_F32(-1.0f, 18446744073709551616.0f,
  5050. false, false);
  5051. frame_sp++;
  5052. break;
  5053. case WASM_OP_I64_TRUNC_SAT_S_F64:
  5054. DEF_OP_TRUNC_SAT_F64(-9223372036854777856.0,
  5055. 9223372036854775808.0, false,
  5056. true);
  5057. break;
  5058. case WASM_OP_I64_TRUNC_SAT_U_F64:
  5059. DEF_OP_TRUNC_SAT_F64(-1.0f, 18446744073709551616.0,
  5060. false, false);
  5061. break;
  5062. #if WASM_ENABLE_BULK_MEMORY != 0
  5063. case WASM_OP_MEMORY_INIT:
  5064. {
  5065. uint32 segment;
  5066. mem_offset_t addr;
  5067. uint64 bytes, offset, seg_len;
  5068. uint8 *data;
  5069. read_leb_uint32(frame_ip, frame_ip_end, segment);
  5070. #if WASM_ENABLE_MULTI_MEMORY != 0
  5071. read_leb_memidx(frame_ip, frame_ip_end, memidx);
  5072. #else
  5073. /* skip memory index */
  5074. frame_ip++;
  5075. #endif
  5076. bytes = (uint64)(uint32)POP_I32();
  5077. offset = (uint64)(uint32)POP_I32();
  5078. addr = (mem_offset_t)POP_MEM_OFFSET();
  5079. #if WASM_ENABLE_THREAD_MGR != 0
  5080. linear_mem_size = get_linear_mem_size();
  5081. #endif
  5082. #ifndef OS_ENABLE_HW_BOUND_CHECK
  5083. CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr);
  5084. #else
  5085. #if WASM_ENABLE_SHARED_HEAP != 0
  5086. if (app_addr_in_shared_heap((uint64)(uint32)addr,
  5087. bytes))
  5088. shared_heap_addr_app_to_native((uint64)(uint32)addr,
  5089. maddr);
  5090. else
  5091. #endif
  5092. {
  5093. if ((uint64)(uint32)addr + bytes > linear_mem_size)
  5094. goto out_of_bounds;
  5095. maddr = memory->memory_data + (uint32)addr;
  5096. }
  5097. #endif
  5098. if (bh_bitmap_get_bit(module->e->common.data_dropped,
  5099. segment)) {
  5100. seg_len = 0;
  5101. data = NULL;
  5102. }
  5103. else {
  5104. seg_len =
  5105. (uint64)module->module->data_segments[segment]
  5106. ->data_length;
  5107. data = module->module->data_segments[segment]->data;
  5108. }
  5109. if (offset + bytes > seg_len)
  5110. goto out_of_bounds;
  5111. bh_memcpy_s(maddr, (uint32)(linear_mem_size - addr),
  5112. data + offset, (uint32)bytes);
  5113. break;
  5114. }
  5115. case WASM_OP_DATA_DROP:
  5116. {
  5117. uint32 segment;
  5118. read_leb_uint32(frame_ip, frame_ip_end, segment);
  5119. bh_bitmap_set_bit(module->e->common.data_dropped,
  5120. segment);
  5121. break;
  5122. }
  5123. case WASM_OP_MEMORY_COPY:
  5124. {
  5125. mem_offset_t dst, src, len;
  5126. uint8 *mdst, *msrc;
  5127. uint64 dlen;
  5128. len = POP_MEM_OFFSET();
  5129. src = POP_MEM_OFFSET();
  5130. dst = POP_MEM_OFFSET();
  5131. #if WASM_ENABLE_MULTI_MEMORY != 0
  5132. /* dst memidx */
  5133. read_leb_memidx(frame_ip, frame_ip_end, memidx);
  5134. #else
  5135. /* skip dst memidx */
  5136. frame_ip += 1;
  5137. #endif
  5138. #if WASM_ENABLE_THREAD_MGR != 0
  5139. linear_mem_size = get_linear_mem_size();
  5140. #endif
  5141. dlen = linear_mem_size - dst;
  5142. /* dst boundary check */
  5143. #ifndef OS_ENABLE_HW_BOUND_CHECK
  5144. CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst);
  5145. #if WASM_ENABLE_SHARED_HEAP != 0
  5146. if (app_addr_in_shared_heap((uint64)dst, len))
  5147. dlen = shared_heap_end_off - dst + 1;
  5148. #endif
  5149. #else /* else of OS_ENABLE_HW_BOUND_CHECK */
  5150. #if WASM_ENABLE_SHARED_HEAP != 0
  5151. if (app_addr_in_shared_heap((uint64)dst, len)) {
  5152. shared_heap_addr_app_to_native((uint64)dst, mdst);
  5153. dlen = shared_heap_end_off - dst + 1;
  5154. }
  5155. else
  5156. #endif
  5157. {
  5158. if ((uint64)dst + len > linear_mem_size)
  5159. goto out_of_bounds;
  5160. mdst = memory->memory_data + dst;
  5161. }
  5162. #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
  5163. #if WASM_ENABLE_MULTI_MEMORY != 0
  5164. /* src memidx */
  5165. read_leb_memidx(frame_ip, frame_ip_end, memidx);
  5166. #else
  5167. /* skip src memidx */
  5168. frame_ip += 1;
  5169. #endif
  5170. #if WASM_ENABLE_THREAD_MGR != 0
  5171. linear_mem_size = get_linear_mem_size();
  5172. #endif
  5173. /* src boundary check */
  5174. #ifndef OS_ENABLE_HW_BOUND_CHECK
  5175. CHECK_BULK_MEMORY_OVERFLOW(src, len, msrc);
  5176. #else
  5177. #if WASM_ENABLE_SHARED_HEAP != 0
  5178. if (app_addr_in_shared_heap((uint64)src, len))
  5179. shared_heap_addr_app_to_native((uint64)src, msrc);
  5180. else
  5181. #endif
  5182. {
  5183. if ((uint64)src + len > linear_mem_size)
  5184. goto out_of_bounds;
  5185. msrc = memory->memory_data + src;
  5186. }
  5187. #endif
  5188. #if WASM_ENABLE_MEMORY64 == 0
  5189. /* allowing the destination and source to overlap */
  5190. bh_memmove_s(mdst, (uint32)dlen, msrc, (uint32)len);
  5191. #else
  5192. /* use memmove when memory64 is enabled since len
  5193. may be larger than UINT32_MAX */
  5194. memmove(mdst, msrc, len);
  5195. (void)dlen;
  5196. #endif
  5197. break;
  5198. }
  5199. case WASM_OP_MEMORY_FILL:
  5200. {
  5201. mem_offset_t dst, len;
  5202. uint8 fill_val, *mdst;
  5203. #if WASM_ENABLE_MULTI_MEMORY != 0
  5204. read_leb_memidx(frame_ip, frame_ip_end, memidx);
  5205. #else
  5206. /* skip memory index */
  5207. frame_ip++;
  5208. #endif
  5209. len = POP_MEM_OFFSET();
  5210. fill_val = POP_I32();
  5211. dst = POP_MEM_OFFSET();
  5212. #if WASM_ENABLE_THREAD_MGR != 0
  5213. linear_mem_size = get_linear_mem_size();
  5214. #endif
  5215. #ifndef OS_ENABLE_HW_BOUND_CHECK
  5216. CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst);
  5217. #else
  5218. #if WASM_ENABLE_SHARED_HEAP != 0
  5219. if (app_addr_in_shared_heap((uint64)(uint32)dst, len))
  5220. shared_heap_addr_app_to_native((uint64)(uint32)dst,
  5221. mdst);
  5222. else
  5223. #endif
  5224. {
  5225. if ((uint64)(uint32)dst + len > linear_mem_size)
  5226. goto out_of_bounds;
  5227. mdst = memory->memory_data + (uint32)dst;
  5228. }
  5229. #endif
  5230. memset(mdst, fill_val, len);
  5231. break;
  5232. }
  5233. #endif /* WASM_ENABLE_BULK_MEMORY */
  5234. #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0
  5235. case WASM_OP_TABLE_INIT:
  5236. {
  5237. uint32 tbl_idx;
  5238. tbl_elem_idx_t elem_idx, d;
  5239. uint32 n, s;
  5240. WASMTableInstance *tbl_inst;
  5241. table_elem_type_t *table_elems;
  5242. InitializerExpression *tbl_seg_init_values = NULL,
  5243. *init_values;
  5244. uint32 tbl_seg_len = 0;
  5245. read_leb_uint32(frame_ip, frame_ip_end, elem_idx);
  5246. bh_assert(elem_idx < module->module->table_seg_count);
  5247. read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
  5248. bh_assert(tbl_idx < module->module->table_count);
  5249. tbl_inst = wasm_get_table_inst(module, tbl_idx);
  5250. #if WASM_ENABLE_MEMORY64 != 0
  5251. is_table64 = tbl_inst->is_table64;
  5252. #endif
  5253. n = (uint32)POP_I32();
  5254. s = (uint32)POP_I32();
  5255. d = (tbl_elem_idx_t)POP_TBL_ELEM_IDX();
  5256. if (!bh_bitmap_get_bit(module->e->common.elem_dropped,
  5257. elem_idx)) {
  5258. /* table segment isn't dropped */
  5259. tbl_seg_init_values =
  5260. module->module->table_segments[elem_idx]
  5261. .init_values;
  5262. tbl_seg_len =
  5263. module->module->table_segments[elem_idx]
  5264. .value_count;
  5265. }
  5266. /* TODO: memory64 current implementation of table64
  5267. * still assumes the max table size UINT32_MAX
  5268. */
  5269. if (
  5270. #if WASM_ENABLE_MEMORY64 != 0
  5271. d > UINT32_MAX ||
  5272. #endif
  5273. offset_len_out_of_bounds(s, n, tbl_seg_len)
  5274. || offset_len_out_of_bounds((uint32)d, n,
  5275. tbl_inst->cur_size)) {
  5276. wasm_set_exception(module,
  5277. "out of bounds table access");
  5278. goto got_exception;
  5279. }
  5280. if (!n) {
  5281. break;
  5282. }
  5283. table_elems = tbl_inst->elems + d;
  5284. init_values = tbl_seg_init_values + s;
  5285. #if WASM_ENABLE_GC != 0
  5286. SYNC_ALL_TO_FRAME();
  5287. #endif
  5288. for (i = 0; i < n; i++) {
  5289. /* UINT32_MAX indicates that it is a null ref */
  5290. bh_assert(init_values[i].init_expr_type
  5291. == INIT_EXPR_TYPE_REFNULL_CONST
  5292. || init_values[i].init_expr_type
  5293. == INIT_EXPR_TYPE_FUNCREF_CONST);
  5294. #if WASM_ENABLE_GC == 0
  5295. table_elems[i] =
  5296. (table_elem_type_t)init_values[i].u.ref_index;
  5297. #else
  5298. if (init_values[i].u.ref_index != UINT32_MAX) {
  5299. if (!(func_obj = wasm_create_func_obj(
  5300. module, init_values[i].u.ref_index,
  5301. true, NULL, 0))) {
  5302. goto got_exception;
  5303. }
  5304. table_elems[i] = func_obj;
  5305. }
  5306. else {
  5307. table_elems[i] = NULL_REF;
  5308. }
  5309. #endif
  5310. }
  5311. break;
  5312. }
  5313. case WASM_OP_ELEM_DROP:
  5314. {
  5315. uint32 elem_idx;
  5316. read_leb_uint32(frame_ip, frame_ip_end, elem_idx);
  5317. bh_assert(elem_idx < module->module->table_seg_count);
  5318. bh_bitmap_set_bit(module->e->common.elem_dropped,
  5319. elem_idx);
  5320. break;
  5321. }
  5322. case WASM_OP_TABLE_COPY:
  5323. {
  5324. uint32 src_tbl_idx, dst_tbl_idx;
  5325. tbl_elem_idx_t n, s, d;
  5326. WASMTableInstance *src_tbl_inst, *dst_tbl_inst;
  5327. read_leb_uint32(frame_ip, frame_ip_end, dst_tbl_idx);
  5328. bh_assert(dst_tbl_idx < module->table_count);
  5329. dst_tbl_inst = wasm_get_table_inst(module, dst_tbl_idx);
  5330. read_leb_uint32(frame_ip, frame_ip_end, src_tbl_idx);
  5331. bh_assert(src_tbl_idx < module->table_count);
  5332. src_tbl_inst = wasm_get_table_inst(module, src_tbl_idx);
  5333. #if WASM_ENABLE_MEMORY64 != 0
  5334. is_table64 = src_tbl_inst->is_table64
  5335. && dst_tbl_inst->is_table64;
  5336. #endif
  5337. n = (tbl_elem_idx_t)POP_TBL_ELEM_IDX();
  5338. #if WASM_ENABLE_MEMORY64 != 0
  5339. is_table64 = src_tbl_inst->is_table64;
  5340. #endif
  5341. s = (tbl_elem_idx_t)POP_TBL_ELEM_IDX();
  5342. #if WASM_ENABLE_MEMORY64 != 0
  5343. is_table64 = dst_tbl_inst->is_table64;
  5344. #endif
  5345. d = (tbl_elem_idx_t)POP_TBL_ELEM_IDX();
  5346. if (
  5347. #if WASM_ENABLE_MEMORY64 != 0
  5348. n > UINT32_MAX || s > UINT32_MAX || d > UINT32_MAX
  5349. ||
  5350. #endif
  5351. offset_len_out_of_bounds((uint32)d, (uint32)n,
  5352. dst_tbl_inst->cur_size)
  5353. || offset_len_out_of_bounds(
  5354. (uint32)s, (uint32)n, src_tbl_inst->cur_size)) {
  5355. wasm_set_exception(module,
  5356. "out of bounds table access");
  5357. goto got_exception;
  5358. }
  5359. /* if s >= d, copy from front to back */
  5360. /* if s < d, copy from back to front */
  5361. /* merge all together */
  5362. bh_memmove_s((uint8 *)dst_tbl_inst
  5363. + offsetof(WASMTableInstance, elems)
  5364. + d * sizeof(table_elem_type_t),
  5365. (uint32)((dst_tbl_inst->cur_size - d)
  5366. * sizeof(table_elem_type_t)),
  5367. (uint8 *)src_tbl_inst
  5368. + offsetof(WASMTableInstance, elems)
  5369. + s * sizeof(table_elem_type_t),
  5370. (uint32)(n * sizeof(table_elem_type_t)));
  5371. break;
  5372. }
  5373. case WASM_OP_TABLE_GROW:
  5374. {
  5375. WASMTableInstance *tbl_inst;
  5376. uint32 tbl_idx, orig_tbl_sz;
  5377. tbl_elem_idx_t n;
  5378. table_elem_type_t init_val;
  5379. read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
  5380. bh_assert(tbl_idx < module->table_count);
  5381. tbl_inst = wasm_get_table_inst(module, tbl_idx);
  5382. #if WASM_ENABLE_MEMORY64 != 0
  5383. is_table64 = tbl_inst->is_table64;
  5384. #endif
  5385. orig_tbl_sz = tbl_inst->cur_size;
  5386. n = POP_TBL_ELEM_IDX();
  5387. #if WASM_ENABLE_GC == 0
  5388. init_val = POP_I32();
  5389. #else
  5390. init_val = POP_REF();
  5391. #endif
  5392. if (
  5393. #if WASM_ENABLE_MEMORY64 != 0
  5394. n > UINT32_MAX ||
  5395. #endif
  5396. !wasm_enlarge_table(module, tbl_idx, (uint32)n,
  5397. init_val)) {
  5398. PUSH_TBL_ELEM_IDX(-1);
  5399. }
  5400. else {
  5401. PUSH_TBL_ELEM_IDX(orig_tbl_sz);
  5402. }
  5403. break;
  5404. }
  5405. case WASM_OP_TABLE_SIZE:
  5406. {
  5407. uint32 tbl_idx;
  5408. WASMTableInstance *tbl_inst;
  5409. read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
  5410. bh_assert(tbl_idx < module->table_count);
  5411. tbl_inst = wasm_get_table_inst(module, tbl_idx);
  5412. #if WASM_ENABLE_MEMORY64 != 0
  5413. is_table64 = tbl_inst->is_table64;
  5414. #endif
  5415. PUSH_TBL_ELEM_IDX(tbl_inst->cur_size);
  5416. break;
  5417. }
  5418. case WASM_OP_TABLE_FILL:
  5419. {
  5420. uint32 tbl_idx;
  5421. tbl_elem_idx_t n, elem_idx;
  5422. WASMTableInstance *tbl_inst;
  5423. table_elem_type_t fill_val;
  5424. read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
  5425. bh_assert(tbl_idx < module->table_count);
  5426. tbl_inst = wasm_get_table_inst(module, tbl_idx);
  5427. #if WASM_ENABLE_MEMORY64 != 0
  5428. is_table64 = tbl_inst->is_table64;
  5429. #endif
  5430. n = POP_TBL_ELEM_IDX();
  5431. #if WASM_ENABLE_GC == 0
  5432. fill_val = POP_I32();
  5433. #else
  5434. fill_val = POP_REF();
  5435. #endif
  5436. elem_idx = POP_TBL_ELEM_IDX();
  5437. if (
  5438. #if WASM_ENABLE_MEMORY64 != 0
  5439. n > UINT32_MAX || elem_idx > UINT32_MAX ||
  5440. #endif
  5441. offset_len_out_of_bounds((uint32)elem_idx,
  5442. (uint32)n,
  5443. tbl_inst->cur_size)) {
  5444. wasm_set_exception(module,
  5445. "out of bounds table access");
  5446. goto got_exception;
  5447. }
  5448. for (; n != 0; elem_idx++, n--) {
  5449. tbl_inst->elems[elem_idx] = fill_val;
  5450. }
  5451. break;
  5452. }
  5453. #endif /* end of WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */
  5454. default:
  5455. wasm_set_exception(module, "unsupported opcode");
  5456. goto got_exception;
  5457. }
  5458. HANDLE_OP_END();
  5459. }
  5460. #if WASM_ENABLE_SHARED_MEMORY != 0
  5461. HANDLE_OP(WASM_OP_ATOMIC_PREFIX)
  5462. {
  5463. mem_offset_t offset = 0, addr;
  5464. uint32 align = 0;
  5465. uint32 opcode1;
  5466. read_leb_uint32(frame_ip, frame_ip_end, opcode1);
  5467. /* opcode1 was checked in loader and is no larger than
  5468. UINT8_MAX */
  5469. opcode = (uint8)opcode1;
  5470. if (opcode != WASM_OP_ATOMIC_FENCE) {
  5471. read_leb_uint32(frame_ip, frame_ip_end, align);
  5472. read_leb_mem_offset(frame_ip, frame_ip_end, offset);
  5473. }
  5474. switch (opcode) {
  5475. case WASM_OP_ATOMIC_NOTIFY:
  5476. {
  5477. uint32 notify_count, ret;
  5478. notify_count = POP_I32();
  5479. addr = POP_MEM_OFFSET();
  5480. CHECK_MEMORY_OVERFLOW(4);
  5481. CHECK_ATOMIC_MEMORY_ACCESS();
  5482. ret = wasm_runtime_atomic_notify(
  5483. (WASMModuleInstanceCommon *)module, maddr,
  5484. notify_count);
  5485. if (ret == (uint32)-1)
  5486. goto got_exception;
  5487. PUSH_I32(ret);
  5488. break;
  5489. }
  5490. case WASM_OP_ATOMIC_WAIT32:
  5491. {
  5492. uint64 timeout;
  5493. uint32 expect, ret;
  5494. timeout = POP_I64();
  5495. expect = POP_I32();
  5496. addr = POP_MEM_OFFSET();
  5497. CHECK_MEMORY_OVERFLOW(4);
  5498. CHECK_ATOMIC_MEMORY_ACCESS();
  5499. ret = wasm_runtime_atomic_wait(
  5500. (WASMModuleInstanceCommon *)module, maddr,
  5501. (uint64)expect, timeout, false);
  5502. if (ret == (uint32)-1)
  5503. goto got_exception;
  5504. #if WASM_ENABLE_THREAD_MGR != 0
  5505. CHECK_SUSPEND_FLAGS();
  5506. #endif
  5507. PUSH_I32(ret);
  5508. break;
  5509. }
  5510. case WASM_OP_ATOMIC_WAIT64:
  5511. {
  5512. uint64 timeout, expect;
  5513. uint32 ret;
  5514. timeout = POP_I64();
  5515. expect = POP_I64();
  5516. addr = POP_MEM_OFFSET();
  5517. CHECK_MEMORY_OVERFLOW(8);
  5518. CHECK_ATOMIC_MEMORY_ACCESS();
  5519. ret = wasm_runtime_atomic_wait(
  5520. (WASMModuleInstanceCommon *)module, maddr, expect,
  5521. timeout, true);
  5522. if (ret == (uint32)-1)
  5523. goto got_exception;
  5524. #if WASM_ENABLE_THREAD_MGR != 0
  5525. CHECK_SUSPEND_FLAGS();
  5526. #endif
  5527. PUSH_I32(ret);
  5528. break;
  5529. }
  5530. case WASM_OP_ATOMIC_FENCE:
  5531. {
  5532. /* Skip the memory index */
  5533. frame_ip++;
  5534. os_atomic_thread_fence(os_memory_order_seq_cst);
  5535. break;
  5536. }
  5537. case WASM_OP_ATOMIC_I32_LOAD:
  5538. case WASM_OP_ATOMIC_I32_LOAD8_U:
  5539. case WASM_OP_ATOMIC_I32_LOAD16_U:
  5540. {
  5541. uint32 readv;
  5542. addr = POP_MEM_OFFSET();
  5543. if (opcode == WASM_OP_ATOMIC_I32_LOAD8_U) {
  5544. CHECK_MEMORY_OVERFLOW(1);
  5545. CHECK_ATOMIC_MEMORY_ACCESS();
  5546. shared_memory_lock(memory);
  5547. readv = (uint32)(*(uint8 *)maddr);
  5548. shared_memory_unlock(memory);
  5549. }
  5550. else if (opcode == WASM_OP_ATOMIC_I32_LOAD16_U) {
  5551. CHECK_MEMORY_OVERFLOW(2);
  5552. CHECK_ATOMIC_MEMORY_ACCESS();
  5553. shared_memory_lock(memory);
  5554. readv = (uint32)LOAD_U16(maddr);
  5555. shared_memory_unlock(memory);
  5556. }
  5557. else {
  5558. CHECK_MEMORY_OVERFLOW(4);
  5559. CHECK_ATOMIC_MEMORY_ACCESS();
  5560. shared_memory_lock(memory);
  5561. readv = LOAD_I32(maddr);
  5562. shared_memory_unlock(memory);
  5563. }
  5564. PUSH_I32(readv);
  5565. break;
  5566. }
  5567. case WASM_OP_ATOMIC_I64_LOAD:
  5568. case WASM_OP_ATOMIC_I64_LOAD8_U:
  5569. case WASM_OP_ATOMIC_I64_LOAD16_U:
  5570. case WASM_OP_ATOMIC_I64_LOAD32_U:
  5571. {
  5572. uint64 readv;
  5573. addr = POP_MEM_OFFSET();
  5574. if (opcode == WASM_OP_ATOMIC_I64_LOAD8_U) {
  5575. CHECK_MEMORY_OVERFLOW(1);
  5576. CHECK_ATOMIC_MEMORY_ACCESS();
  5577. shared_memory_lock(memory);
  5578. readv = (uint64)(*(uint8 *)maddr);
  5579. shared_memory_unlock(memory);
  5580. }
  5581. else if (opcode == WASM_OP_ATOMIC_I64_LOAD16_U) {
  5582. CHECK_MEMORY_OVERFLOW(2);
  5583. CHECK_ATOMIC_MEMORY_ACCESS();
  5584. shared_memory_lock(memory);
  5585. readv = (uint64)LOAD_U16(maddr);
  5586. shared_memory_unlock(memory);
  5587. }
  5588. else if (opcode == WASM_OP_ATOMIC_I64_LOAD32_U) {
  5589. CHECK_MEMORY_OVERFLOW(4);
  5590. CHECK_ATOMIC_MEMORY_ACCESS();
  5591. shared_memory_lock(memory);
  5592. readv = (uint64)LOAD_U32(maddr);
  5593. shared_memory_unlock(memory);
  5594. }
  5595. else {
  5596. CHECK_MEMORY_OVERFLOW(8);
  5597. CHECK_ATOMIC_MEMORY_ACCESS();
  5598. shared_memory_lock(memory);
  5599. readv = LOAD_I64(maddr);
  5600. shared_memory_unlock(memory);
  5601. }
  5602. PUSH_I64(readv);
  5603. break;
  5604. }
  5605. case WASM_OP_ATOMIC_I32_STORE:
  5606. case WASM_OP_ATOMIC_I32_STORE8:
  5607. case WASM_OP_ATOMIC_I32_STORE16:
  5608. {
  5609. uint32 sval;
  5610. sval = (uint32)POP_I32();
  5611. addr = POP_MEM_OFFSET();
  5612. if (opcode == WASM_OP_ATOMIC_I32_STORE8) {
  5613. CHECK_MEMORY_OVERFLOW(1);
  5614. CHECK_ATOMIC_MEMORY_ACCESS();
  5615. shared_memory_lock(memory);
  5616. *(uint8 *)maddr = (uint8)sval;
  5617. shared_memory_unlock(memory);
  5618. }
  5619. else if (opcode == WASM_OP_ATOMIC_I32_STORE16) {
  5620. CHECK_MEMORY_OVERFLOW(2);
  5621. CHECK_ATOMIC_MEMORY_ACCESS();
  5622. shared_memory_lock(memory);
  5623. STORE_U16(maddr, (uint16)sval);
  5624. shared_memory_unlock(memory);
  5625. }
  5626. else {
  5627. CHECK_MEMORY_OVERFLOW(4);
  5628. CHECK_ATOMIC_MEMORY_ACCESS();
  5629. shared_memory_lock(memory);
  5630. STORE_U32(maddr, sval);
  5631. shared_memory_unlock(memory);
  5632. }
  5633. break;
  5634. }
  5635. case WASM_OP_ATOMIC_I64_STORE:
  5636. case WASM_OP_ATOMIC_I64_STORE8:
  5637. case WASM_OP_ATOMIC_I64_STORE16:
  5638. case WASM_OP_ATOMIC_I64_STORE32:
  5639. {
  5640. uint64 sval;
  5641. sval = (uint64)POP_I64();
  5642. addr = POP_MEM_OFFSET();
  5643. if (opcode == WASM_OP_ATOMIC_I64_STORE8) {
  5644. CHECK_MEMORY_OVERFLOW(1);
  5645. CHECK_ATOMIC_MEMORY_ACCESS();
  5646. shared_memory_lock(memory);
  5647. *(uint8 *)maddr = (uint8)sval;
  5648. shared_memory_unlock(memory);
  5649. }
  5650. else if (opcode == WASM_OP_ATOMIC_I64_STORE16) {
  5651. CHECK_MEMORY_OVERFLOW(2);
  5652. CHECK_ATOMIC_MEMORY_ACCESS();
  5653. shared_memory_lock(memory);
  5654. STORE_U16(maddr, (uint16)sval);
  5655. shared_memory_unlock(memory);
  5656. }
  5657. else if (opcode == WASM_OP_ATOMIC_I64_STORE32) {
  5658. CHECK_MEMORY_OVERFLOW(4);
  5659. CHECK_ATOMIC_MEMORY_ACCESS();
  5660. shared_memory_lock(memory);
  5661. STORE_U32(maddr, (uint32)sval);
  5662. shared_memory_unlock(memory);
  5663. }
  5664. else {
  5665. CHECK_MEMORY_OVERFLOW(8);
  5666. CHECK_ATOMIC_MEMORY_ACCESS();
  5667. shared_memory_lock(memory);
  5668. STORE_I64(maddr, sval);
  5669. shared_memory_unlock(memory);
  5670. }
  5671. break;
  5672. }
  5673. case WASM_OP_ATOMIC_RMW_I32_CMPXCHG:
  5674. case WASM_OP_ATOMIC_RMW_I32_CMPXCHG8_U:
  5675. case WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U:
  5676. {
  5677. uint32 readv, sval, expect;
  5678. sval = POP_I32();
  5679. expect = POP_I32();
  5680. addr = POP_MEM_OFFSET();
  5681. if (opcode == WASM_OP_ATOMIC_RMW_I32_CMPXCHG8_U) {
  5682. CHECK_MEMORY_OVERFLOW(1);
  5683. CHECK_ATOMIC_MEMORY_ACCESS();
  5684. expect = (uint8)expect;
  5685. shared_memory_lock(memory);
  5686. readv = (uint32)(*(uint8 *)maddr);
  5687. if (readv == expect)
  5688. *(uint8 *)maddr = (uint8)(sval);
  5689. shared_memory_unlock(memory);
  5690. }
  5691. else if (opcode == WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U) {
  5692. CHECK_MEMORY_OVERFLOW(2);
  5693. CHECK_ATOMIC_MEMORY_ACCESS();
  5694. expect = (uint16)expect;
  5695. shared_memory_lock(memory);
  5696. readv = (uint32)LOAD_U16(maddr);
  5697. if (readv == expect)
  5698. STORE_U16(maddr, (uint16)(sval));
  5699. shared_memory_unlock(memory);
  5700. }
  5701. else {
  5702. CHECK_MEMORY_OVERFLOW(4);
  5703. CHECK_ATOMIC_MEMORY_ACCESS();
  5704. shared_memory_lock(memory);
  5705. readv = LOAD_I32(maddr);
  5706. if (readv == expect)
  5707. STORE_U32(maddr, sval);
  5708. shared_memory_unlock(memory);
  5709. }
  5710. PUSH_I32(readv);
  5711. break;
  5712. }
  5713. case WASM_OP_ATOMIC_RMW_I64_CMPXCHG:
  5714. case WASM_OP_ATOMIC_RMW_I64_CMPXCHG8_U:
  5715. case WASM_OP_ATOMIC_RMW_I64_CMPXCHG16_U:
  5716. case WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U:
  5717. {
  5718. uint64 readv, sval, expect;
  5719. sval = (uint64)POP_I64();
  5720. expect = (uint64)POP_I64();
  5721. addr = POP_MEM_OFFSET();
  5722. if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG8_U) {
  5723. CHECK_MEMORY_OVERFLOW(1);
  5724. CHECK_ATOMIC_MEMORY_ACCESS();
  5725. expect = (uint8)expect;
  5726. shared_memory_lock(memory);
  5727. readv = (uint64)(*(uint8 *)maddr);
  5728. if (readv == expect)
  5729. *(uint8 *)maddr = (uint8)(sval);
  5730. shared_memory_unlock(memory);
  5731. }
  5732. else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG16_U) {
  5733. CHECK_MEMORY_OVERFLOW(2);
  5734. CHECK_ATOMIC_MEMORY_ACCESS();
  5735. expect = (uint16)expect;
  5736. shared_memory_lock(memory);
  5737. readv = (uint64)LOAD_U16(maddr);
  5738. if (readv == expect)
  5739. STORE_U16(maddr, (uint16)(sval));
  5740. shared_memory_unlock(memory);
  5741. }
  5742. else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U) {
  5743. CHECK_MEMORY_OVERFLOW(4);
  5744. CHECK_ATOMIC_MEMORY_ACCESS();
  5745. expect = (uint32)expect;
  5746. shared_memory_lock(memory);
  5747. readv = (uint64)LOAD_U32(maddr);
  5748. if (readv == expect)
  5749. STORE_U32(maddr, (uint32)(sval));
  5750. shared_memory_unlock(memory);
  5751. }
  5752. else {
  5753. CHECK_MEMORY_OVERFLOW(8);
  5754. CHECK_ATOMIC_MEMORY_ACCESS();
  5755. shared_memory_lock(memory);
  5756. readv = (uint64)LOAD_I64(maddr);
  5757. if (readv == expect)
  5758. STORE_I64(maddr, sval);
  5759. shared_memory_unlock(memory);
  5760. }
  5761. PUSH_I64(readv);
  5762. break;
  5763. }
  5764. DEF_ATOMIC_RMW_OPCODE(ADD, +);
  5765. DEF_ATOMIC_RMW_OPCODE(SUB, -);
  5766. DEF_ATOMIC_RMW_OPCODE(AND, &);
  5767. DEF_ATOMIC_RMW_OPCODE(OR, |);
  5768. DEF_ATOMIC_RMW_OPCODE(XOR, ^);
  5769. /* xchg, ignore the read value, and store the given
  5770. value: readv * 0 + sval */
  5771. DEF_ATOMIC_RMW_OPCODE(XCHG, *0 +);
  5772. }
  5773. HANDLE_OP_END();
  5774. }
  5775. #endif
  5776. HANDLE_OP(WASM_OP_IMPDEP)
  5777. {
  5778. frame = prev_frame;
  5779. frame_ip = frame->ip;
  5780. frame_sp = frame->sp;
  5781. frame_csp = frame->csp;
  5782. #if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
  5783. is_return_call = false;
  5784. #endif
  5785. goto call_func_from_entry;
  5786. }
  5787. #if WASM_ENABLE_DEBUG_INTERP != 0
  5788. HANDLE_OP(DEBUG_OP_BREAK)
  5789. {
  5790. wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TRAP);
  5791. WASM_SUSPEND_FLAGS_FETCH_OR(exec_env->suspend_flags,
  5792. WASM_SUSPEND_FLAG_SUSPEND);
  5793. frame_ip--;
  5794. SYNC_ALL_TO_FRAME();
  5795. CHECK_SUSPEND_FLAGS();
  5796. HANDLE_OP_END();
  5797. }
  5798. #endif
  5799. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  5800. default:
  5801. wasm_set_exception(module, "unsupported opcode");
  5802. goto got_exception;
  5803. }
  5804. #endif
  5805. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  5806. HANDLE_OP(WASM_OP_UNUSED_0x0a)
  5807. #if WASM_ENABLE_TAIL_CALL == 0
  5808. HANDLE_OP(WASM_OP_RETURN_CALL)
  5809. HANDLE_OP(WASM_OP_RETURN_CALL_INDIRECT)
  5810. #endif
  5811. #if WASM_ENABLE_SHARED_MEMORY == 0
  5812. HANDLE_OP(WASM_OP_ATOMIC_PREFIX)
  5813. #endif
  5814. #if WASM_ENABLE_REF_TYPES == 0 && WASM_ENABLE_GC == 0
  5815. HANDLE_OP(WASM_OP_SELECT_T)
  5816. HANDLE_OP(WASM_OP_TABLE_GET)
  5817. HANDLE_OP(WASM_OP_TABLE_SET)
  5818. HANDLE_OP(WASM_OP_REF_NULL)
  5819. HANDLE_OP(WASM_OP_REF_IS_NULL)
  5820. HANDLE_OP(WASM_OP_REF_FUNC)
  5821. #endif
  5822. #if WASM_ENABLE_GC == 0
  5823. HANDLE_OP(WASM_OP_CALL_REF)
  5824. HANDLE_OP(WASM_OP_RETURN_CALL_REF)
  5825. HANDLE_OP(WASM_OP_REF_EQ)
  5826. HANDLE_OP(WASM_OP_REF_AS_NON_NULL)
  5827. HANDLE_OP(WASM_OP_BR_ON_NULL)
  5828. HANDLE_OP(WASM_OP_BR_ON_NON_NULL)
  5829. HANDLE_OP(WASM_OP_GC_PREFIX)
  5830. #endif
  5831. #if WASM_ENABLE_EXCE_HANDLING == 0
  5832. HANDLE_OP(WASM_OP_TRY)
  5833. HANDLE_OP(WASM_OP_CATCH)
  5834. HANDLE_OP(WASM_OP_THROW)
  5835. HANDLE_OP(WASM_OP_RETHROW)
  5836. HANDLE_OP(WASM_OP_DELEGATE)
  5837. HANDLE_OP(WASM_OP_CATCH_ALL)
  5838. HANDLE_OP(EXT_OP_TRY)
  5839. #endif
  5840. #if WASM_ENABLE_JIT != 0 && WASM_ENABLE_SIMD != 0
  5841. /* SIMD isn't supported by interpreter, but when JIT is
  5842. enabled, `iwasm --interp <wasm_file>` may be run to
  5843. trigger the SIMD opcode in interpreter */
  5844. HANDLE_OP(WASM_OP_SIMD_PREFIX)
  5845. #endif
  5846. HANDLE_OP(WASM_OP_UNUSED_0x16)
  5847. HANDLE_OP(WASM_OP_UNUSED_0x17)
  5848. HANDLE_OP(WASM_OP_UNUSED_0x27)
  5849. /* Used by fast interpreter */
  5850. HANDLE_OP(EXT_OP_SET_LOCAL_FAST_I64)
  5851. HANDLE_OP(EXT_OP_TEE_LOCAL_FAST_I64)
  5852. HANDLE_OP(EXT_OP_COPY_STACK_TOP)
  5853. HANDLE_OP(EXT_OP_COPY_STACK_TOP_I64)
  5854. HANDLE_OP(EXT_OP_COPY_STACK_VALUES)
  5855. {
  5856. wasm_set_exception(module, "unsupported opcode");
  5857. goto got_exception;
  5858. }
  5859. #endif /* end of WASM_ENABLE_LABELS_AS_VALUES != 0 */
  5860. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  5861. continue;
  5862. #else
  5863. FETCH_OPCODE_AND_DISPATCH();
  5864. #endif
  5865. #if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
  5866. call_func_from_return_call:
  5867. {
  5868. POP(cur_func->param_cell_num);
  5869. if (cur_func->param_cell_num > 0) {
  5870. word_copy(frame->lp, frame_sp, cur_func->param_cell_num);
  5871. }
  5872. FREE_FRAME(exec_env, frame);
  5873. wasm_exec_env_set_cur_frame(exec_env, prev_frame);
  5874. is_return_call = true;
  5875. goto call_func_from_entry;
  5876. }
  5877. #endif
  5878. call_func_from_interp:
  5879. {
  5880. /* Only do the copy when it's called from interpreter. */
  5881. WASMInterpFrame *outs_area = wasm_exec_env_wasm_stack_top(exec_env);
  5882. if (cur_func->param_cell_num > 0) {
  5883. POP(cur_func->param_cell_num);
  5884. word_copy(outs_area->lp, frame_sp, cur_func->param_cell_num);
  5885. }
  5886. SYNC_ALL_TO_FRAME();
  5887. prev_frame = frame;
  5888. #if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
  5889. is_return_call = false;
  5890. #endif
  5891. }
  5892. call_func_from_entry:
  5893. {
  5894. if (cur_func->is_import_func) {
  5895. #if WASM_ENABLE_MULTI_MODULE != 0
  5896. if (cur_func->import_func_inst) {
  5897. wasm_interp_call_func_import(module, exec_env, cur_func,
  5898. prev_frame);
  5899. #if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
  5900. if (is_return_call) {
  5901. /* the frame was freed before tail calling and
  5902. the prev_frame was set as exec_env's cur_frame,
  5903. so here we recover context from prev_frame */
  5904. RECOVER_CONTEXT(prev_frame);
  5905. }
  5906. else
  5907. #endif
  5908. {
  5909. prev_frame = frame->prev_frame;
  5910. cur_func = frame->function;
  5911. UPDATE_ALL_FROM_FRAME();
  5912. }
  5913. #if WASM_ENABLE_EXCE_HANDLING != 0
  5914. char uncaught_exception[128] = { 0 };
  5915. bool has_exception =
  5916. wasm_copy_exception(module, uncaught_exception);
  5917. if (has_exception
  5918. && strstr(uncaught_exception, "uncaught wasm exception")) {
  5919. uint32 import_exception;
  5920. /* initialize imported exception index to be invalid */
  5921. SET_INVALID_TAGINDEX(import_exception);
  5922. /* pull external exception */
  5923. uint32 ext_exception = POP_I32();
  5924. /* external function came back with an exception or trap */
  5925. /* lookup exception in import tags */
  5926. WASMTagInstance *tag = module->e->tags;
  5927. for (uint32 t = 0; t < module->module->import_tag_count;
  5928. tag++, t++) {
  5929. /* compare the module and the external index with the
  5930. * imort tag data */
  5931. if ((cur_func->u.func_import->import_module
  5932. == tag->u.tag_import->import_module)
  5933. && (ext_exception
  5934. == tag->u.tag_import
  5935. ->import_tag_index_linked)) {
  5936. /* set the import_exception to the import tag */
  5937. import_exception = t;
  5938. break;
  5939. }
  5940. }
  5941. /*
  5942. * exchange the thrown exception (index valid in submodule)
  5943. * with the imported exception index (valid in this module)
  5944. * if the module did not import the exception,
  5945. * that results in a "INVALID_TAGINDEX", that triggers
  5946. * an CATCH_ALL block, if there is one.
  5947. */
  5948. PUSH_I32(import_exception);
  5949. }
  5950. #endif /* end of WASM_ENABLE_EXCE_HANDLING != 0 */
  5951. }
  5952. else
  5953. #endif /* end of WASM_ENABLE_MULTI_MODULE != 0 */
  5954. {
  5955. wasm_interp_call_func_native(module, exec_env, cur_func,
  5956. prev_frame);
  5957. #if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
  5958. if (is_return_call) {
  5959. /* the frame was freed before tail calling and
  5960. the prev_frame was set as exec_env's cur_frame,
  5961. so here we recover context from prev_frame */
  5962. RECOVER_CONTEXT(prev_frame);
  5963. }
  5964. else
  5965. #endif
  5966. {
  5967. prev_frame = frame->prev_frame;
  5968. cur_func = frame->function;
  5969. UPDATE_ALL_FROM_FRAME();
  5970. }
  5971. }
  5972. /* update memory size, no need to update memory ptr as
  5973. it isn't changed in wasm_enlarge_memory */
  5974. #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
  5975. || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
  5976. || WASM_ENABLE_BULK_MEMORY != 0
  5977. if (memory)
  5978. linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory);
  5979. #endif
  5980. if (wasm_copy_exception(module, NULL)) {
  5981. #if WASM_ENABLE_EXCE_HANDLING != 0
  5982. /* the caller raised an exception */
  5983. char uncaught_exception[128] = { 0 };
  5984. bool has_exception =
  5985. wasm_copy_exception(module, uncaught_exception);
  5986. /* libc_builtin signaled a "exception thrown by stdc++" trap */
  5987. if (has_exception
  5988. && strstr(uncaught_exception,
  5989. "exception thrown by stdc++")) {
  5990. wasm_set_exception(module, NULL);
  5991. /* setup internal c++ rethrow */
  5992. exception_tag_index = 0;
  5993. goto find_a_catch_handler;
  5994. }
  5995. /* when throw hits the end of a function it signals with a
  5996. * "uncaught wasm exception" trap */
  5997. if (has_exception
  5998. && strstr(uncaught_exception, "uncaught wasm exception")) {
  5999. wasm_set_exception(module, NULL);
  6000. exception_tag_index = POP_I32();
  6001. /* rethrow the exception into that frame */
  6002. goto find_a_catch_handler;
  6003. }
  6004. #endif /* WASM_ENABLE_EXCE_HANDLING != 0 */
  6005. goto got_exception;
  6006. }
  6007. }
  6008. else {
  6009. WASMFunction *cur_wasm_func = cur_func->u.func;
  6010. WASMFuncType *func_type = cur_wasm_func->func_type;
  6011. uint32 max_stack_cell_num = cur_wasm_func->max_stack_cell_num;
  6012. uint32 cell_num_of_local_stack;
  6013. #if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0
  6014. uint32 local_cell_idx;
  6015. #endif
  6016. #if WASM_ENABLE_EXCE_HANDLING != 0
  6017. /* account for exception handlers, bundle them here */
  6018. uint32 eh_size =
  6019. cur_wasm_func->exception_handler_count * sizeof(uint8 *);
  6020. max_stack_cell_num += eh_size;
  6021. #endif
  6022. cell_num_of_local_stack = cur_func->param_cell_num
  6023. + cur_func->local_cell_num
  6024. + max_stack_cell_num;
  6025. all_cell_num = cell_num_of_local_stack
  6026. + cur_wasm_func->max_block_num
  6027. * (uint32)sizeof(WASMBranchBlock) / 4;
  6028. #if WASM_ENABLE_GC != 0
  6029. /* area of frame_ref */
  6030. all_cell_num += (cell_num_of_local_stack + 3) / 4;
  6031. #endif
  6032. /* param_cell_num, local_cell_num, max_stack_cell_num and
  6033. max_block_num are all no larger than UINT16_MAX (checked
  6034. in loader), all_cell_num must be smaller than 1MB */
  6035. bh_assert(all_cell_num < 1 * BH_MB);
  6036. frame_size = wasm_interp_interp_frame_size(all_cell_num);
  6037. if (!(frame = ALLOC_FRAME(exec_env, frame_size, prev_frame))) {
  6038. frame = prev_frame;
  6039. goto got_exception;
  6040. }
  6041. /* Initialize the interpreter context. */
  6042. frame->function = cur_func;
  6043. frame_ip = wasm_get_func_code(cur_func);
  6044. frame_ip_end = wasm_get_func_code_end(cur_func);
  6045. frame_lp = frame->lp;
  6046. frame_sp = frame->sp_bottom =
  6047. frame_lp + cur_func->param_cell_num + cur_func->local_cell_num;
  6048. frame->sp_boundary = frame->sp_bottom + max_stack_cell_num;
  6049. frame_csp = frame->csp_bottom =
  6050. (WASMBranchBlock *)frame->sp_boundary;
  6051. frame->csp_boundary =
  6052. frame->csp_bottom + cur_wasm_func->max_block_num;
  6053. #if WASM_ENABLE_GC != 0
  6054. /* frame->sp and frame->ip are used during GC root set enumeration,
  6055. * so we must initialized these fields here */
  6056. frame->sp = frame_sp;
  6057. frame->ip = frame_ip;
  6058. frame_ref = (uint8 *)frame->csp_boundary;
  6059. init_frame_refs(frame_ref, (uint32)cell_num_of_local_stack,
  6060. cur_func);
  6061. #endif
  6062. /* Initialize the local variables */
  6063. memset(frame_lp + cur_func->param_cell_num, 0,
  6064. (uint32)(cur_func->local_cell_num * 4));
  6065. #if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0
  6066. /* externref/funcref should be NULL_REF rather than 0 */
  6067. local_cell_idx = cur_func->param_cell_num;
  6068. for (i = 0; i < cur_wasm_func->local_count; i++) {
  6069. if (cur_wasm_func->local_types[i] == VALUE_TYPE_EXTERNREF
  6070. || cur_wasm_func->local_types[i] == VALUE_TYPE_FUNCREF) {
  6071. *(frame_lp + local_cell_idx) = NULL_REF;
  6072. }
  6073. local_cell_idx +=
  6074. wasm_value_type_cell_num(cur_wasm_func->local_types[i]);
  6075. }
  6076. #endif
  6077. /* Push function block as first block */
  6078. cell_num = func_type->ret_cell_num;
  6079. PUSH_CSP(LABEL_TYPE_FUNCTION, 0, cell_num, frame_ip_end - 1);
  6080. wasm_exec_env_set_cur_frame(exec_env, frame);
  6081. }
  6082. #if WASM_ENABLE_THREAD_MGR != 0
  6083. CHECK_SUSPEND_FLAGS();
  6084. #endif
  6085. HANDLE_OP_END();
  6086. }
  6087. return_func:
  6088. {
  6089. FREE_FRAME(exec_env, frame);
  6090. wasm_exec_env_set_cur_frame(exec_env, prev_frame);
  6091. if (!prev_frame->ip) {
  6092. /* Called from native. */
  6093. return;
  6094. }
  6095. RECOVER_CONTEXT(prev_frame);
  6096. #if WASM_ENABLE_EXCE_HANDLING != 0
  6097. if (wasm_get_exception(module)) {
  6098. wasm_set_exception(module, NULL);
  6099. exception_tag_index = POP_I32();
  6100. goto find_a_catch_handler;
  6101. }
  6102. #endif
  6103. HANDLE_OP_END();
  6104. }
  6105. #if WASM_ENABLE_SHARED_MEMORY != 0
  6106. unaligned_atomic:
  6107. wasm_set_exception(module, "unaligned atomic");
  6108. goto got_exception;
  6109. #endif
  6110. #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
  6111. || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
  6112. || WASM_ENABLE_BULK_MEMORY != 0
  6113. out_of_bounds:
  6114. wasm_set_exception(module, "out of bounds memory access");
  6115. #endif
  6116. got_exception:
  6117. #if WASM_ENABLE_DEBUG_INTERP != 0
  6118. if (wasm_exec_env_get_instance(exec_env) != NULL) {
  6119. uint8 *frame_ip_temp = frame_ip;
  6120. frame_ip = frame_ip_orig;
  6121. wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TRAP);
  6122. CHECK_SUSPEND_FLAGS();
  6123. frame_ip = frame_ip_temp;
  6124. }
  6125. #endif
  6126. SYNC_ALL_TO_FRAME();
  6127. return;
  6128. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  6129. }
  6130. #else
  6131. FETCH_OPCODE_AND_DISPATCH();
  6132. #endif
  6133. }
  6134. #if WASM_ENABLE_GC != 0
  6135. bool
  6136. wasm_interp_traverse_gc_rootset(WASMExecEnv *exec_env, void *heap)
  6137. {
  6138. WASMInterpFrame *frame;
  6139. WASMObjectRef gc_obj;
  6140. int i;
  6141. frame = wasm_exec_env_get_cur_frame(exec_env);
  6142. for (; frame; frame = frame->prev_frame) {
  6143. uint8 *frame_ref = get_frame_ref(frame);
  6144. for (i = 0; i < frame->sp - frame->lp; i++) {
  6145. if (frame_ref[i]) {
  6146. gc_obj = GET_REF_FROM_ADDR(frame->lp + i);
  6147. if (wasm_obj_is_created_from_heap(gc_obj)) {
  6148. if (mem_allocator_add_root((mem_allocator_t)heap, gc_obj)) {
  6149. return false;
  6150. }
  6151. }
  6152. #if UINTPTR_MAX == UINT64_MAX
  6153. bh_assert(frame_ref[i + 1]);
  6154. i++;
  6155. #endif
  6156. }
  6157. }
  6158. }
  6159. return true;
  6160. }
  6161. #endif
  6162. #if WASM_ENABLE_FAST_JIT != 0
  6163. /*
  6164. * ASAN is not designed to work with custom stack unwind or other low-level
  6165. * things. Ignore a function that does some low-level magic. (e.g. walking
  6166. * through the thread's stack bypassing the frame boundaries)
  6167. */
  6168. #if defined(__GNUC__) || defined(__clang__)
  6169. __attribute__((no_sanitize_address))
  6170. #endif
  6171. static void
  6172. fast_jit_call_func_bytecode(WASMModuleInstance *module_inst,
  6173. WASMExecEnv *exec_env,
  6174. WASMFunctionInstance *function,
  6175. WASMInterpFrame *frame)
  6176. {
  6177. JitGlobals *jit_globals = jit_compiler_get_jit_globals();
  6178. JitInterpSwitchInfo info;
  6179. WASMModule *module = module_inst->module;
  6180. WASMFuncType *func_type = function->u.func->func_type;
  6181. uint8 type = func_type->result_count
  6182. ? func_type->types[func_type->param_count]
  6183. : VALUE_TYPE_VOID;
  6184. uint32 func_idx = (uint32)(function - module_inst->e->functions);
  6185. uint32 func_idx_non_import = func_idx - module->import_function_count;
  6186. int32 action;
  6187. #if WASM_ENABLE_REF_TYPES != 0
  6188. if (type == VALUE_TYPE_EXTERNREF || type == VALUE_TYPE_FUNCREF)
  6189. type = VALUE_TYPE_I32;
  6190. #endif
  6191. #if WASM_ENABLE_LAZY_JIT != 0
  6192. if (!jit_compiler_compile(module, func_idx)) {
  6193. wasm_set_exception(module_inst, "failed to compile fast jit function");
  6194. return;
  6195. }
  6196. #endif
  6197. bh_assert(jit_compiler_is_compiled(module, func_idx));
  6198. /* Switch to jitted code to call the jit function */
  6199. info.out.ret.last_return_type = type;
  6200. info.frame = frame;
  6201. frame->jitted_return_addr =
  6202. (uint8 *)jit_globals->return_to_interp_from_jitted;
  6203. action = jit_interp_switch_to_jitted(
  6204. exec_env, &info, func_idx,
  6205. module_inst->fast_jit_func_ptrs[func_idx_non_import]);
  6206. bh_assert(action == JIT_INTERP_ACTION_NORMAL
  6207. || (action == JIT_INTERP_ACTION_THROWN
  6208. && wasm_copy_exception(
  6209. (WASMModuleInstance *)exec_env->module_inst, NULL)));
  6210. /* Get the return values form info.out.ret */
  6211. if (func_type->result_count) {
  6212. switch (type) {
  6213. case VALUE_TYPE_I32:
  6214. *(frame->sp - function->ret_cell_num) = info.out.ret.ival[0];
  6215. break;
  6216. case VALUE_TYPE_I64:
  6217. *(frame->sp - function->ret_cell_num) = info.out.ret.ival[0];
  6218. *(frame->sp - function->ret_cell_num + 1) =
  6219. info.out.ret.ival[1];
  6220. break;
  6221. case VALUE_TYPE_F32:
  6222. *(frame->sp - function->ret_cell_num) = info.out.ret.fval[0];
  6223. break;
  6224. case VALUE_TYPE_F64:
  6225. *(frame->sp - function->ret_cell_num) = info.out.ret.fval[0];
  6226. *(frame->sp - function->ret_cell_num + 1) =
  6227. info.out.ret.fval[1];
  6228. break;
  6229. default:
  6230. bh_assert(0);
  6231. break;
  6232. }
  6233. }
  6234. (void)action;
  6235. (void)func_idx;
  6236. }
  6237. #endif /* end of WASM_ENABLE_FAST_JIT != 0 */
  6238. #if WASM_ENABLE_JIT != 0
  6239. #if WASM_ENABLE_DUMP_CALL_STACK != 0 || WASM_ENABLE_PERF_PROFILING != 0 \
  6240. || WASM_ENABLE_AOT_STACK_FRAME != 0
  6241. #if WASM_ENABLE_GC == 0
  6242. bool
  6243. llvm_jit_alloc_frame(WASMExecEnv *exec_env, uint32 func_index)
  6244. {
  6245. WASMModuleInstance *module_inst =
  6246. (WASMModuleInstance *)exec_env->module_inst;
  6247. WASMInterpFrame *cur_frame, *frame;
  6248. uint32 size = (uint32)offsetof(WASMInterpFrame, lp);
  6249. bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
  6250. cur_frame = exec_env->cur_frame;
  6251. if (!cur_frame)
  6252. frame = (WASMInterpFrame *)exec_env->wasm_stack.bottom;
  6253. else
  6254. frame = (WASMInterpFrame *)((uint8 *)cur_frame + size);
  6255. if ((uint8 *)frame + size > exec_env->wasm_stack.top_boundary) {
  6256. wasm_set_exception(module_inst, "wasm operand stack overflow");
  6257. return false;
  6258. }
  6259. frame->function = module_inst->e->functions + func_index;
  6260. /* No need to initialize ip, it will be committed in jitted code
  6261. when needed */
  6262. /* frame->ip = NULL; */
  6263. frame->prev_frame = cur_frame;
  6264. #if WASM_ENABLE_PERF_PROFILING != 0
  6265. frame->time_started = os_time_thread_cputime_us();
  6266. #endif
  6267. #if WASM_ENABLE_MEMORY_PROFILING != 0
  6268. {
  6269. uint32 wasm_stack_used =
  6270. (uint8 *)frame + size - exec_env->wasm_stack.bottom;
  6271. if (wasm_stack_used > exec_env->max_wasm_stack_used)
  6272. exec_env->max_wasm_stack_used = wasm_stack_used;
  6273. }
  6274. #endif
  6275. exec_env->cur_frame = frame;
  6276. return true;
  6277. }
  6278. static inline void
  6279. llvm_jit_free_frame_internal(WASMExecEnv *exec_env)
  6280. {
  6281. WASMInterpFrame *frame = exec_env->cur_frame;
  6282. WASMInterpFrame *prev_frame = frame->prev_frame;
  6283. bh_assert(exec_env->module_inst->module_type == Wasm_Module_Bytecode);
  6284. #if WASM_ENABLE_PERF_PROFILING != 0
  6285. if (frame->function) {
  6286. uint64 time_elapsed = os_time_thread_cputime_us() - frame->time_started;
  6287. frame->function->total_exec_time += time_elapsed;
  6288. frame->function->total_exec_cnt++;
  6289. /* parent function */
  6290. if (prev_frame)
  6291. prev_frame->function->children_exec_time += time_elapsed;
  6292. }
  6293. #endif
  6294. exec_env->cur_frame = prev_frame;
  6295. }
  6296. void
  6297. llvm_jit_free_frame(WASMExecEnv *exec_env)
  6298. {
  6299. llvm_jit_free_frame_internal(exec_env);
  6300. }
  6301. #else /* else of WASM_ENABLE_GC == 0 */
  6302. bool
  6303. llvm_jit_alloc_frame(WASMExecEnv *exec_env, uint32 func_index)
  6304. {
  6305. WASMModuleInstance *module_inst;
  6306. WASMModule *module;
  6307. WASMInterpFrame *frame;
  6308. uint32 size, max_local_cell_num, max_stack_cell_num;
  6309. bh_assert(exec_env->module_inst->module_type == Wasm_Module_Bytecode);
  6310. module_inst = (WASMModuleInstance *)exec_env->module_inst;
  6311. module = module_inst->module;
  6312. if (func_index >= func_index - module->import_function_count) {
  6313. WASMFunction *func =
  6314. module->functions[func_index - module->import_function_count];
  6315. max_local_cell_num = func->param_cell_num + func->local_cell_num;
  6316. max_stack_cell_num = func->max_stack_cell_num;
  6317. }
  6318. else {
  6319. WASMFunctionImport *func =
  6320. &((module->import_functions + func_index)->u.function);
  6321. max_local_cell_num = func->func_type->param_cell_num > 2
  6322. ? func->func_type->param_cell_num
  6323. : 2;
  6324. max_stack_cell_num = 0;
  6325. }
  6326. size =
  6327. wasm_interp_interp_frame_size(max_local_cell_num + max_stack_cell_num);
  6328. frame = wasm_exec_env_alloc_wasm_frame(exec_env, size);
  6329. if (!frame) {
  6330. wasm_set_exception(module_inst, "wasm operand stack overflow");
  6331. return false;
  6332. }
  6333. frame->function = module_inst->e->functions + func_index;
  6334. #if WASM_ENABLE_PERF_PROFILING != 0
  6335. frame->time_started = os_time_thread_cputime_us();
  6336. #endif
  6337. frame->prev_frame = wasm_exec_env_get_cur_frame(exec_env);
  6338. /* No need to initialize ip, it will be committed in jitted code
  6339. when needed */
  6340. /* frame->ip = NULL; */
  6341. #if WASM_ENABLE_GC != 0
  6342. frame->sp = frame->lp + max_local_cell_num;
  6343. /* Initialize frame ref flags for import function */
  6344. if (func_index < module->import_function_count) {
  6345. WASMFunctionImport *func =
  6346. &((module->import_functions + func_index)->u.function);
  6347. WASMFuncType *func_type = func->func_type;
  6348. /* native function doesn't have operand stack and label stack */
  6349. uint8 *frame_ref = (uint8 *)frame->sp;
  6350. uint32 i, j, k, value_type_cell_num;
  6351. for (i = 0, j = 0; i < func_type->param_count; i++) {
  6352. if (wasm_is_type_reftype(func_type->types[i])
  6353. && !wasm_is_reftype_i31ref(func_type->types[i])) {
  6354. frame_ref[j++] = 1;
  6355. #if UINTPTR_MAX == UINT64_MAX
  6356. frame_ref[j++] = 1;
  6357. #endif
  6358. }
  6359. else {
  6360. value_type_cell_num =
  6361. wasm_value_type_cell_num(func_type->types[i]);
  6362. for (k = 0; k < value_type_cell_num; k++)
  6363. frame_ref[j++] = 0;
  6364. }
  6365. }
  6366. }
  6367. #endif
  6368. wasm_exec_env_set_cur_frame(exec_env, frame);
  6369. return true;
  6370. }
  6371. static inline void
  6372. llvm_jit_free_frame_internal(WASMExecEnv *exec_env)
  6373. {
  6374. WASMInterpFrame *frame;
  6375. WASMInterpFrame *prev_frame;
  6376. bh_assert(exec_env->module_inst->module_type == Wasm_Module_Bytecode);
  6377. frame = wasm_exec_env_get_cur_frame(exec_env);
  6378. prev_frame = frame->prev_frame;
  6379. #if WASM_ENABLE_PERF_PROFILING != 0
  6380. if (frame->function) {
  6381. uint64 time_elapsed = os_time_thread_cputime_us() - frame->time_started;
  6382. frame->function->total_exec_time += time_elapsed;
  6383. frame->function->total_exec_cnt++;
  6384. /* parent function */
  6385. if (prev_frame)
  6386. prev_frame->function->children_exec_time += time_elapsed;
  6387. }
  6388. #endif
  6389. wasm_exec_env_free_wasm_frame(exec_env, frame);
  6390. wasm_exec_env_set_cur_frame(exec_env, prev_frame);
  6391. }
  6392. void
  6393. llvm_jit_free_frame(WASMExecEnv *exec_env)
  6394. {
  6395. llvm_jit_free_frame_internal(exec_env);
  6396. }
  6397. #endif /* end of WASM_ENABLE_GC == 0 */
  6398. void
  6399. llvm_jit_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame)
  6400. {
  6401. #if WASM_ENABLE_PERF_PROFILING != 0
  6402. WASMInterpFrame *cur_frame = exec_env->cur_frame;
  6403. if (alloc_frame) {
  6404. cur_frame->time_started = os_time_thread_cputime_us();
  6405. }
  6406. else {
  6407. if (cur_frame->function) {
  6408. WASMInterpFrame *prev_frame = cur_frame->prev_frame;
  6409. uint64 time_elapsed =
  6410. os_time_thread_cputime_us() - cur_frame->time_started;
  6411. cur_frame->function->total_exec_time += time_elapsed;
  6412. cur_frame->function->total_exec_cnt++;
  6413. /* parent function */
  6414. if (prev_frame)
  6415. prev_frame->function->children_exec_time += time_elapsed;
  6416. }
  6417. }
  6418. #endif
  6419. #if WASM_ENABLE_MEMORY_PROFILING != 0
  6420. if (alloc_frame) {
  6421. #if WASM_ENABLE_GC == 0
  6422. uint32 wasm_stack_used = (uint8 *)exec_env->cur_frame
  6423. + (uint32)offsetof(WASMInterpFrame, lp)
  6424. - exec_env->wasm_stack.bottom;
  6425. #else
  6426. uint32 wasm_stack_used =
  6427. exec_env->wasm_stack.top - exec_env->wasm_stack.bottom;
  6428. #endif
  6429. if (wasm_stack_used > exec_env->max_wasm_stack_used)
  6430. exec_env->max_wasm_stack_used = wasm_stack_used;
  6431. }
  6432. #endif
  6433. }
  6434. #endif /* end of WASM_ENABLE_DUMP_CALL_STACK != 0 \
  6435. || WASM_ENABLE_PERF_PROFILING != 0 \
  6436. || WASM_ENABLE_AOT_STACK_FRAME != 0 */
  6437. static bool
  6438. llvm_jit_call_func_bytecode(WASMModuleInstance *module_inst,
  6439. WASMExecEnv *exec_env,
  6440. WASMFunctionInstance *function, uint32 argc,
  6441. uint32 argv[])
  6442. {
  6443. WASMFuncType *func_type = function->u.func->func_type;
  6444. uint32 result_count = func_type->result_count;
  6445. uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
  6446. uint32 func_idx = (uint32)(function - module_inst->e->functions);
  6447. bool ret = false;
  6448. #if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0) \
  6449. || (WASM_ENABLE_AOT_STACK_FRAME != 0)
  6450. if (!llvm_jit_alloc_frame(exec_env, function - module_inst->e->functions)) {
  6451. /* wasm operand stack overflow has been thrown,
  6452. no need to throw again */
  6453. return false;
  6454. }
  6455. #endif
  6456. if (ext_ret_count > 0) {
  6457. uint32 cell_num = 0, i;
  6458. uint8 *ext_ret_types = func_type->types + func_type->param_count + 1;
  6459. uint32 argv1_buf[32], *argv1 = argv1_buf, *ext_rets = NULL;
  6460. uint32 *argv_ret = argv;
  6461. uint32 ext_ret_cell = wasm_get_cell_num(ext_ret_types, ext_ret_count);
  6462. uint64 size;
  6463. /* Allocate memory all arguments */
  6464. size =
  6465. sizeof(uint32) * (uint64)argc /* original arguments */
  6466. + sizeof(void *)
  6467. * (uint64)ext_ret_count /* extra result values' addr */
  6468. + sizeof(uint32) * (uint64)ext_ret_cell; /* extra result values */
  6469. if (size > sizeof(argv1_buf)) {
  6470. if (size > UINT32_MAX
  6471. || !(argv1 = wasm_runtime_malloc((uint32)size))) {
  6472. wasm_set_exception(module_inst, "allocate memory failed");
  6473. ret = false;
  6474. goto fail;
  6475. }
  6476. }
  6477. /* Copy original arguments */
  6478. bh_memcpy_s(argv1, (uint32)size, argv, sizeof(uint32) * argc);
  6479. /* Get the extra result value's address */
  6480. ext_rets =
  6481. argv1 + argc + sizeof(void *) / sizeof(uint32) * ext_ret_count;
  6482. /* Append each extra result value's address to original arguments */
  6483. for (i = 0; i < ext_ret_count; i++) {
  6484. *(uintptr_t *)(argv1 + argc + sizeof(void *) / sizeof(uint32) * i) =
  6485. (uintptr_t)(ext_rets + cell_num);
  6486. cell_num += wasm_value_type_cell_num(ext_ret_types[i]);
  6487. }
  6488. ret = wasm_runtime_invoke_native(
  6489. exec_env, module_inst->func_ptrs[func_idx], func_type, NULL, NULL,
  6490. argv1, argc, argv);
  6491. if (!ret) {
  6492. if (argv1 != argv1_buf)
  6493. wasm_runtime_free(argv1);
  6494. goto fail;
  6495. }
  6496. /* Get extra result values */
  6497. switch (func_type->types[func_type->param_count]) {
  6498. case VALUE_TYPE_I32:
  6499. case VALUE_TYPE_F32:
  6500. #if WASM_ENABLE_REF_TYPES != 0
  6501. case VALUE_TYPE_FUNCREF:
  6502. case VALUE_TYPE_EXTERNREF:
  6503. #endif
  6504. argv_ret++;
  6505. break;
  6506. case VALUE_TYPE_I64:
  6507. case VALUE_TYPE_F64:
  6508. argv_ret += 2;
  6509. break;
  6510. #if WASM_ENABLE_SIMD != 0
  6511. case VALUE_TYPE_V128:
  6512. argv_ret += 4;
  6513. break;
  6514. #endif
  6515. default:
  6516. bh_assert(0);
  6517. break;
  6518. }
  6519. ext_rets =
  6520. argv1 + argc + sizeof(void *) / sizeof(uint32) * ext_ret_count;
  6521. bh_memcpy_s(argv_ret, sizeof(uint32) * cell_num, ext_rets,
  6522. sizeof(uint32) * cell_num);
  6523. if (argv1 != argv1_buf)
  6524. wasm_runtime_free(argv1);
  6525. ret = true;
  6526. }
  6527. else {
  6528. #if WASM_ENABLE_QUICK_AOT_ENTRY != 0
  6529. /* Quick call if the quick jit entry is registered */
  6530. if (func_type->quick_aot_entry) {
  6531. void (*invoke_native)(void *func_ptr, void *exec_env, uint32 *argv,
  6532. uint32 *argv_ret) =
  6533. func_type->quick_aot_entry;
  6534. invoke_native(module_inst->func_ptrs[func_idx], exec_env, argv,
  6535. argv);
  6536. ret = !wasm_copy_exception(module_inst, NULL);
  6537. }
  6538. else
  6539. #endif
  6540. {
  6541. ret = wasm_runtime_invoke_native(
  6542. exec_env, module_inst->func_ptrs[func_idx], func_type, NULL,
  6543. NULL, argv, argc, argv);
  6544. if (ret)
  6545. ret = !wasm_copy_exception(module_inst, NULL);
  6546. }
  6547. }
  6548. fail:
  6549. #if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0) \
  6550. || (WASM_ENABLE_AOT_STACK_FRAME != 0)
  6551. llvm_jit_free_frame_internal(exec_env);
  6552. #endif
  6553. return ret;
  6554. }
  6555. #endif /* end of WASM_ENABLE_JIT != 0 */
  6556. void
  6557. wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
  6558. WASMFunctionInstance *function, uint32 argc,
  6559. uint32 argv[])
  6560. {
  6561. WASMRuntimeFrame *frame = NULL, *prev_frame, *outs_area;
  6562. RunningMode running_mode =
  6563. wasm_runtime_get_running_mode((WASMModuleInstanceCommon *)module_inst);
  6564. /* Allocate sufficient cells for all kinds of return values. */
  6565. bool alloc_frame = true;
  6566. if (argc < function->param_cell_num) {
  6567. char buf[128];
  6568. snprintf(buf, sizeof(buf),
  6569. "invalid argument count %" PRIu32
  6570. ", must be no smaller than %u",
  6571. argc, function->param_cell_num);
  6572. wasm_set_exception(module_inst, buf);
  6573. return;
  6574. }
  6575. argc = function->param_cell_num;
  6576. #if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
  6577. /*
  6578. * wasm_runtime_detect_native_stack_overflow is done by
  6579. * call_wasm_with_hw_bound_check.
  6580. */
  6581. #else
  6582. if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
  6583. return;
  6584. }
  6585. #endif
  6586. if (!function->is_import_func) {
  6587. /* No need to alloc frame when calling LLVM JIT function */
  6588. #if WASM_ENABLE_JIT != 0
  6589. if (running_mode == Mode_LLVM_JIT) {
  6590. alloc_frame = false;
  6591. }
  6592. #if WASM_ENABLE_LAZY_JIT != 0 && WASM_ENABLE_FAST_JIT != 0
  6593. else if (running_mode == Mode_Multi_Tier_JIT) {
  6594. /* Tier-up from Fast JIT to LLVM JIT, call llvm jit function
  6595. if it is compiled, else call fast jit function */
  6596. uint32 func_idx = (uint32)(function - module_inst->e->functions);
  6597. if (module_inst->module->func_ptrs_compiled
  6598. [func_idx - module_inst->module->import_function_count]) {
  6599. alloc_frame = false;
  6600. }
  6601. }
  6602. #endif
  6603. #endif
  6604. }
  6605. if (alloc_frame) {
  6606. unsigned all_cell_num =
  6607. function->ret_cell_num > 2 ? function->ret_cell_num : 2;
  6608. unsigned frame_size;
  6609. prev_frame = wasm_exec_env_get_cur_frame(exec_env);
  6610. /* This frame won't be used by JITed code, so only allocate interp
  6611. frame here. */
  6612. frame_size = wasm_interp_interp_frame_size(all_cell_num);
  6613. if (!(frame = ALLOC_FRAME(exec_env, frame_size, prev_frame)))
  6614. return;
  6615. outs_area = wasm_exec_env_wasm_stack_top(exec_env);
  6616. frame->function = NULL;
  6617. frame->ip = NULL;
  6618. /* There is no local variable. */
  6619. frame->sp = frame->lp + 0;
  6620. if ((uint8 *)(outs_area->lp + function->param_cell_num)
  6621. > exec_env->wasm_stack.top_boundary) {
  6622. wasm_set_exception(module_inst, "wasm operand stack overflow");
  6623. return;
  6624. }
  6625. if (argc > 0)
  6626. word_copy(outs_area->lp, argv, argc);
  6627. wasm_exec_env_set_cur_frame(exec_env, frame);
  6628. }
  6629. #if defined(os_writegsbase)
  6630. {
  6631. WASMMemoryInstance *memory_inst = wasm_get_default_memory(module_inst);
  6632. if (memory_inst)
  6633. /* write base addr of linear memory to GS segment register */
  6634. os_writegsbase(memory_inst->memory_data);
  6635. }
  6636. #endif
  6637. if (function->is_import_func) {
  6638. #if WASM_ENABLE_MULTI_MODULE != 0
  6639. if (function->import_module_inst) {
  6640. wasm_interp_call_func_import(module_inst, exec_env, function,
  6641. frame);
  6642. }
  6643. else
  6644. #endif
  6645. {
  6646. /* it is a native function */
  6647. wasm_interp_call_func_native(module_inst, exec_env, function,
  6648. frame);
  6649. }
  6650. }
  6651. else {
  6652. if (running_mode == Mode_Interp) {
  6653. wasm_interp_call_func_bytecode(module_inst, exec_env, function,
  6654. frame);
  6655. }
  6656. #if WASM_ENABLE_FAST_JIT != 0
  6657. else if (running_mode == Mode_Fast_JIT) {
  6658. fast_jit_call_func_bytecode(module_inst, exec_env, function, frame);
  6659. }
  6660. #endif
  6661. #if WASM_ENABLE_JIT != 0
  6662. else if (running_mode == Mode_LLVM_JIT) {
  6663. llvm_jit_call_func_bytecode(module_inst, exec_env, function, argc,
  6664. argv);
  6665. }
  6666. #endif
  6667. #if WASM_ENABLE_LAZY_JIT != 0 && WASM_ENABLE_FAST_JIT != 0 \
  6668. && WASM_ENABLE_JIT != 0
  6669. else if (running_mode == Mode_Multi_Tier_JIT) {
  6670. /* Tier-up from Fast JIT to LLVM JIT, call llvm jit function
  6671. if it is compiled, else call fast jit function */
  6672. uint32 func_idx = (uint32)(function - module_inst->e->functions);
  6673. if (module_inst->module->func_ptrs_compiled
  6674. [func_idx - module_inst->module->import_function_count]) {
  6675. llvm_jit_call_func_bytecode(module_inst, exec_env, function,
  6676. argc, argv);
  6677. }
  6678. else {
  6679. fast_jit_call_func_bytecode(module_inst, exec_env, function,
  6680. frame);
  6681. }
  6682. }
  6683. #endif
  6684. else {
  6685. /* There should always be a supported running mode selected */
  6686. bh_assert(0);
  6687. }
  6688. (void)wasm_interp_call_func_bytecode;
  6689. #if WASM_ENABLE_FAST_JIT != 0
  6690. (void)fast_jit_call_func_bytecode;
  6691. #endif
  6692. }
  6693. /* Output the return value to the caller */
  6694. if (!wasm_copy_exception(module_inst, NULL)) {
  6695. if (alloc_frame) {
  6696. uint32 i;
  6697. for (i = 0; i < function->ret_cell_num; i++) {
  6698. argv[i] = *(frame->sp + i - function->ret_cell_num);
  6699. }
  6700. }
  6701. }
  6702. else {
  6703. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  6704. if (wasm_interp_create_call_stack(exec_env)) {
  6705. wasm_interp_dump_call_stack(exec_env, true, NULL, 0);
  6706. }
  6707. #endif
  6708. }
  6709. if (alloc_frame) {
  6710. wasm_exec_env_set_cur_frame(exec_env, prev_frame);
  6711. FREE_FRAME(exec_env, frame);
  6712. }
  6713. }