/* Ċ Ġ* ĠĠĠĠĠ ĠK ores - Byte code Writer Ġ- ĠTrans lates ĠK ores ĠStructure Ġto ĠJVM ĠByte code Ġ< https :// github . com / Jon athan xD / Code API - Byte code Writer > Ċ Ġ* Ċ Ġ* ĠĠĠĠĠĠĠĠ ĠThe ĠMIT ĠLicense Ġ( MIT ) Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ ĠCopyright Ġ( c ) Ġ 2 0 2 1 ĠThe Real Bug gy / Jon athan xD Ġ( https :// github . com / Jon athan xD /) Ġ< jon athan . script er @ program mer . net > Ċ Ġ* ĠĠĠĠĠ ĠCopyright Ġ( c ) Ġcontributors Ċ Ġ* Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ ĠPermission Ġis Ġhereby Ġgranted , Ġfree Ġof Ġcharge , Ġto Ġany Ġperson Ġobtaining Ġa Ġcopy Ċ Ġ* ĠĠĠĠĠ Ġof Ġthis Ġsoftware Ġand Ġassociated Ġdocumentation Ġfiles Ġ( the Ġ" Software "), Ġto Ġdeal Ċ Ġ* ĠĠĠĠĠ Ġin Ġthe ĠSoftware Ġwithout Ġrestriction , Ġincluding Ġwithout Ġlimitation Ġthe Ġrights Ċ Ġ* ĠĠĠĠĠ Ġto Ġuse , Ġcopy , Ġmodify , Ġmerge , Ġpublish , Ġdistribute , Ġsublicense , Ġand / or Ġsell Ċ Ġ* ĠĠĠĠĠ Ġcopies Ġof Ġthe ĠSoftware , Ġand Ġto Ġpermit Ġpersons Ġto Ġwhom Ġthe ĠSoftware Ġis Ċ Ġ* ĠĠĠĠĠ Ġfurnished Ġto Ġdo Ġso , Ġsubject Ġto Ġthe Ġfollowing Ġconditions : Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ ĠThe Ġabove Ġcopyright Ġnotice Ġand Ġthis Ġpermission Ġnotice Ġshall Ġbe Ġincluded Ġin Ċ Ġ* ĠĠĠĠĠ Ġall Ġcopies Ġor Ġsubstantial Ġportions Ġof Ġthe ĠSoftware . Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ ĠTHE ĠSOFTWARE ĠIS ĠPROVIDED Ġ" AS ĠIS ", ĠWITHOUT ĠWARRANTY ĠOF ĠANY ĠKIND , ĠEXPRESS ĠOR Ċ Ġ* ĠĠĠĠĠ ĠIMPLIED , ĠINCLUDING ĠBUT ĠNOT ĠLIMITED ĠTO ĠTHE ĠWARRANTIES ĠOF ĠMERCHANTABILITY , Ċ Ġ* ĠĠĠĠĠ ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE ĠAND ĠNONINFRINGEMENT . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE Ċ Ġ* ĠĠĠĠĠ ĠAUTHORS ĠOR ĠCOPYRIGHT ĠHOLDERS ĠBE ĠLIABLE ĠFOR ĠANY ĠCLAIM , ĠDAMAGES ĠOR ĠOTHER Ċ Ġ* ĠĠĠĠĠ ĠLIABILITY , ĠWHETHER ĠIN ĠAN ĠACTION ĠOF ĠCONTRACT , ĠTORT ĠOR ĠOTHERWISE , ĠARISING ĠFROM , Ċ Ġ* ĠĠĠĠĠ ĠOUT ĠOF ĠOR ĠIN ĠCONNECTION ĠWITH ĠTHE ĠSOFTWARE ĠOR ĠTHE ĠUSE ĠOR ĠOTHER ĠDEALINGS ĠIN Ċ Ġ* ĠĠĠĠĠ ĠTHE ĠSOFTWARE . Ċ Ġ*/ Ċ package Ġcom . k ores framework . k ores . byte code . processor . processors Ċ Ċ import Ġcom . github . jon athan xd . i utils . data . Typed Data Ċ import Ġcom . github . jon athan xd . i utils . kt . add Ċ import Ġcom . github . jon athan xd . i utils . kt . require Ċ import Ġcom . k ores framework . k ores . Instructions Ċ import Ġcom . k ores framework . k ores . base . Catch Statement Ċ import Ġcom . k ores framework . k ores . base . Throw Exception Ċ import Ġcom . k ores framework . k ores . base . Try Statement Ċ import Ġcom . k ores framework . k ores . byte code . processor . METHOD _ VIS ITOR Ċ import Ġcom . k ores framework . k ores . byte code . processor . TRY _ BLOCK _ DATA Ċ import Ġcom . k ores framework . k ores . byte code . processor . Try Block Data Ċ import Ġcom . k ores framework . k ores . common . K ores Nothing Ċ import Ġcom . k ores framework . k ores . factory . access Variable Ċ import Ġcom . k ores framework . k ores . factory . variable Ċ import Ġcom . k ores framework . k ores . processor . Processor Ċ import Ġcom . k ores framework . k ores . processor . Processor Manager Ċ import Ġcom . k ores framework . k ores . type . internal Name Ċ import Ġcom . k ores framework . k ores . type . k ores Type Ċ import Ġorg . object web . asm . Label Ċ import Ġorg . object web . asm . Op codes Ċ Ċ object ĠTry Statement Processor Ġ: ĠProcessor < Try Statement > Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġprocess ( ĊĠĠĠĠĠĠĠ Ġpart : ĠTry Statement , ĊĠĠĠĠĠĠĠ Ġdata : ĠTyped Data , ĊĠĠĠĠĠĠĠ Ġprocessor Manager : ĠProcessor Manager < *> ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmv Helper Ġ= ĠMETHOD _ VIS ITOR . require ( data ) ĊĠĠĠĠĠĠĠ Ġval Ġmv Ġ= Ġmv Helper . method Visitor ĊĊĠĠĠĠĠĠĠ Ġval Ġl 0 Ġ= ĠLabel () Ġ// ĠCode Ġto Ġsur round ĊĠĠĠĠĠĠĠ Ġval Ġl 1 Ġ= ĠLabel () Ġ// Ġif Ġno Ġexceptions . ĊĠĠĠĠĠĠĠ Ġval Ġend Tc Ġ= ĠLabel () Ġ// ĠEnd Ġof Ġtry Ġcatch ĊĠĠĠĠĠĠĠ Ġval Ġl Catch All Ġ= ĠLabel () ĊĊĠĠĠĠĠĠĠ Ġval Ġfinally Source Ġ= Ġpart . finally Statement ĊĠĠĠĠĠĠĠ Ġval Ġgen Finally Ġ= Ġfinally Source . isNotEmpty ĊĊĠĠĠĠĠĠĠ Ġval Ġcat ches Ġ= Ġmutable Map Of < Catch Statement , ĠTry Block Data >() ĊĊĠĠĠĠĠĠĠ Ġval Ġout Of If Ġ= ĠLabel () Ġ// ĠOut Ġof Ġif ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( catch Block Ġin Ġpart . catch Statements ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġl Catch Ġ= ĠLabel () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexception Types Ġ= Ġcatch Block . exception Types ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( exception Type Ġin Ġexception Types ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmv . visit Try Catch Block ( l 0 , Ġl 1 , Ġl Catch , Ġexception Type . internal Name ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcat ches . put ( catch Block , ĠTry Block Data ( l Catch , Ġpart )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun ĠTry Block Data . visit Blocks ( start : ĠLabel , Ġend : ĠLabel ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! gen Finally ) Ġreturn ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( this . labels . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmv . visit Try Catch Block ( start , Ġstart , Ġl Catch All , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġlast Ġ= Ġstart ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . labels . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( last . offset Ġ!= Ġit . start . offset ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmv . visit Try Catch Block ( last , Ġit . start , Ġl Catch All , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlast Ġ= Ġit . end ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( last . offset Ġ!= Ġend . offset ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmv . visit Try Catch Block ( last , Ġend , Ġl Catch All , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġgen Finally () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! gen Finally ) Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTR Y _ BLOCK _ DATA . get OrNull ( data )?. let Ġ{ Ġblocks Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( blocks . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTR Y _ BLOCK _ DATA . remove ( data ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblocks . forEach Ġ{ Ġit . visit ( processor Manager , Ġdata ) Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTR Y _ BLOCK _ DATA . set ( data , Ġblocks ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġmv . visit Label ( l 0 ) ĊĊĠĠĠĠĠĠĠ Ġval Ġtry Block Data Ġ= ĠTry Block Data ( l 0 , Ġpart ) ĊĠĠĠĠĠĠĠ ĠTR Y _ BLOCK _ DATA . add ( data , Ġtry Block Data ) ĊĊĠĠĠĠĠĠĠ Ġval Ġbody Ġ= Ġpart . body ĊĊĠĠĠĠĠĠĠ Ġmv Helper . enter New Frame () ĊĊĠĠĠĠĠĠĠ Ġprocessor Manager . process ( Instructions :: class . java , Ġbody , Ġdata ) ĊĠĠĠĠĠĠĠ Ġgen Finally () ĊĊĠĠĠĠĠĠĠ Ġmv Helper . exit Frame () ĊĊĠĠĠĠĠĠĠ ĠTR Y _ BLOCK _ DATA . require ( data ). remove ( try Block Data ) ĊĊĠĠĠĠĠĠĠ Ġmv . visit Label ( l 1 ) ĊĊĠĠĠĠĠĠĠ Ġtry Block Data . visit Blocks ( l 0 , Ġl 1 ) ĊĊĠĠĠĠĠĠĠ Ġmv . visit Jump Insn ( Op codes . GOTO , Ġout Of If ) ĊĊĠĠĠĠĠĠĠ Ġ// //////////////////////// ///// ĊĊĠĠĠĠĠĠĠ Ġval Ġi _ label Ġ= ĠLabel () ĊĊĠĠĠĠĠĠĠ Ġmv . visit Label ( i _ label ) ĊĊĠĠĠĠĠĠĠ Ġval Ġend Label Ġ= ĠLabel () ĊĊĠĠĠĠĠĠĠ Ġcat ches . forEach Ġ{ Ġ(_, Ġfield , Ġcode Source ), Ġt data Ġ-> ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠTR Y _ BLOCK _ DATA . add ( data , Ġt data ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlabel Ġ= Ġt data . start Label ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġend Ġ= ĠLabel () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġmv . visit Label ( label ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmv Helper . enter New Frame () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfield Value Ġ= Ġfield . value ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstack Pos Ġ= Ġmv Helper . store Var ( field . name , Ġfield . type . k ores Type , Ġi _ label , Ġend ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. orElse Throw ({ Ġmv Helper . fail Store ( field . name ) Ġ}) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġmv . visit Label ( Label ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġmv . visit Var Insn ( Op codes . AST ORE , Ġstack Pos ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( field Value Ġ!= ĠK ores Nothing ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocessor Manager . process ( field Value :: class . java , Ġfield Value , Ġdata ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmv . visit Var Insn ( Op codes . AST ORE , Ġstack Pos ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprocessor Manager . process ( Instructions :: class . java , Ġcode Source , Ġdata ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġgen Finally () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġmv Helper . exit Frame () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġmv . visit Label ( end ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠTR Y _ BLOCK _ DATA . require ( data ). remove ( tdata ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġt data . visit Blocks ( label , Ġend ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġmv . visit Jump Insn ( Op codes . GOTO , Ġout Of If ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġmv . visit Label ( end Tc ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( gen Finally ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmv . visit Label ( l Catch All ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġend Ġ= ĠLabel () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdummy Name Ġ= Ġmv Helper . get Unique Variable Name (" dummy \$ # ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġmv Helper . get Unique Variable Name (" finally Exception \$ # ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġmv Helper . enter New Frame () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvariable Ġ= Ġvariable ( Throwable :: class . java , Ġname , ĠK ores Nothing ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġmv Helper . store Var ( dummy Name , ĠException :: class . java . k ores Type , Ġl Catch All , Ġend ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. orElse Throw ({ Ġmv Helper . fail Store ( variable . name ) Ġ}) Ġ// Ġdummy ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstack Pos Ġ= Ġmv Helper . store Var ( variable . name , Ġvariable . type . k ores Type , Ġl Catch All , Ġend ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. orElse Throw ({ Ġmv Helper . fail Store ( variable . name ) Ġ}) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġmv . visit Label ( Label ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġmv . visit Var Insn ( Op codes . AST ORE , Ġstack Pos ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprocessor Manager . process ( Instructions :: class . java , Ġfinally Source , Ġdata ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprocessor Manager . process ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠThrow Exception :: class . java , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠThrow Exception ( access Variable ( variable )), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġmv . visit Label ( end ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġmv Helper . exit Frame () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġmv . visit Label ( end Label ) ĊĊĠĠĠĠĠĠĠ Ġmv . visit Label ( out Of If ) ĊĊĠĠĠĠĠĠĠ ĠTR Y _ BLOCK _ DATA . require ( data ). remove ( try Block Data ) ĊĠĠĠ Ġ} Ċ Ċ }