/* Ċ Ġ* ĠCopyright Ġ 2 0 1 0 - 2 0 1 9 ĠJetBrains Ġs . r . o . Ġand ĠKotlin ĠProgramming ĠLanguage Ġcontributors . Ċ Ġ* ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense Ġthat Ġcan Ġbe Ġfound Ġin Ġthe Ġlicense / LICENSE . txt Ġfile . Ċ Ġ*/ Ċ Ċ package Ġorg . jetbrains . kotlin . codegen . inline Ċ Ċ import Ġorg . jetbrains . kotlin . codegen . optimization . common . Fast Method Analyzer Ċ import Ġorg . jetbrains . kotlin . codegen . optimization . common . Insn Sequence Ċ import Ġorg . jetbrains . kotlin . codegen . optimization . common . is Mean ing ful Ċ import Ġorg . jetbrains . kotlin . codegen . optimization . null Check . is Check Parameter IsNotNull Ċ import Ġorg . jetbrains . kotlin . resolve . jvm . Asm Types Ċ import Ġorg . jetbrains . org . object web . asm . Op codes Ċ import Ġorg . jetbrains . org . object web . asm . tree . Abstract Insn Node Ċ import Ġorg . jetbrains . org . object web . asm . tree . Field Insn Node Ċ import Ġorg . jetbrains . org . object web . asm . tree . Method Node Ċ import Ġorg . jetbrains . org . object web . asm . tree . Var Insn Node Ċ import Ġorg . jetbrains . org . object web . asm . tree . analysis .* Ċ Ċ fun ĠMethod Node . remove ( instructions : ĠSequence < Abstract Insn Node >) Ġ= ĊĠĠĠ Ġinstructions . forEach Ġ{ ĊĠĠĠĠĠĠĠ Ġthis @ remove . instructions . remove ( it ) ĊĠĠĠ Ġ} Ċ Ċ fun ĠMethod Node . remove ( instructions : ĠCollection < Abstract Insn Node >) Ġ{ ĊĠĠĠ Ġinstructions . forEach Ġ{ ĊĠĠĠĠĠĠĠ Ġthis @ remove . instructions . remove ( it ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠMethod Node . find Capt ured Field Assignment Instructions (): ĠSequence < Field Insn Node > Ġ{ ĊĠĠĠ Ġreturn ĠIn sn Sequence ( instructions ). filter Is Instance < Field Insn Node >(). filter Ġ{ Ġfield Node Ġ-> ĊĠĠĠĠĠĠĠ Ġ// filter Ġcaptured Ġfield Ġassignment ĊĠĠĠĠĠĠĠ Ġ// Ġ Ġal o ad Ġ 0 ĊĠĠĠĠĠĠĠ Ġ// Ġ Ġal o ad Ġx ĊĠĠĠĠĠĠĠ Ġ// Ġ ĠPUT FIELD Ġ$ fieldName ĊĊĠĠĠĠĠĠĠ Ġval Ġprev Prev Ġ= Ġfield Node . previous ?. previous Ġas ? ĠVar Insn Node ĊĊĠĠĠĠĠĠĠ Ġfield Node . opcode Ġ== ĠOp codes . PUT FIELD Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Capt ured FieldName ( field Node . name ) Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield Node . previous Ġis ĠVar Insn Node Ġ&& Ġprev Prev Ġ!= Ġnull Ġ&& Ġprev Prev .` var ` Ġ== Ġ 0 ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠAbstract Insn Node . getNext Mean ing ful (): ĠAbstract Insn Node ? Ġ{ ĊĠĠĠ Ġvar Ġresult : ĠAbstract Insn Node ? Ġ= Ġnext ĊĠĠĠ Ġwhile Ġ( result Ġ!= Ġnull Ġ&& Ġ! result . is Mean ing ful ) Ġ{ ĊĠĠĠĠĠĠĠ Ġresult Ġ= Ġresult . next ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġresult Ċ } Ċ Ċ // ĠInterpreter , Ġthat Ġanaly zes Ġfunctional Ġarguments Ġonly , Ġto Ġreplace ĠSource Interpreter , Ġsince ĠSource Interpreter 's Ġmerge Ġhas ĠO ( N Â² ) Ġcomplexity Ċ Ċ internal Ġclass ĠFunctional Argument Value ( ĊĠĠĠ Ġval Ġfunctional Argument : ĠFunctional Argument , Ġbasic Value : ĠBasic Value ? Ċ ) Ġ: ĠBasic Value ( basic Value ?. type ) Ġ{ ĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ"$ functional Argument " Ċ } Ċ Ċ val ĠBasic Value ?. functional Argument ĊĠĠĠ Ġget () Ġ= Ġ( this Ġas ? ĠFunctional Argument Value )?. functional Argument Ċ Ċ internal Ġclass ĠFunctional Argument Interpreter ( private Ġval Ġin liner : ĠMethod In liner ) Ġ: ĠBasic Interpreter ( Op codes . API _ VERSION ) Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġunary Operation ( insn : ĠAbstract Insn Node , Ġvalue : ĠBasic Value ): ĠBasic Value ? Ġ= ĊĠĠĠĠĠĠĠ Ġwrap Argument In Value IfNeeded ( insn , Ġsuper . unary Operation ( insn , Ġvalue )) ĊĊĠĠĠ Ġoverride Ġfun Ġcopy Operation ( insn : ĠAbstract Insn Node , Ġvalue : ĠBasic Value ?): ĠBasic Value ? Ġ= ĊĠĠĠĠĠĠĠ Ġwrap Argument In Value IfNeeded ( insn , Ġsuper . copy Operation ( insn , Ġvalue )) ĊĊĠĠĠ Ġoverride Ġfun Ġnew Operation ( insn : ĠAbstract Insn Node ): ĠBasic Value ? Ġ= ĊĠĠĠĠĠĠĠ Ġwrap Argument In Value IfNeeded ( insn , Ġsuper . new Operation ( insn )) ĊĊĠĠĠ Ġprivate Ġfun Ġwrap Argument In Value IfNeeded ( ĊĠĠĠĠĠĠĠ Ġinsn : ĠAbstract Insn Node , ĊĠĠĠĠĠĠĠ Ġbasic Value : ĠBasic Value ? ĊĠĠĠ Ġ): ĠBasic Value ? Ġ= ĊĠĠĠĠĠĠĠ Ġin liner . get Functional Argument IfExists ( insn ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ ĠFunctional Argument Value ( it , Ġbasic Value ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġbasic Value ĊĊĠĠĠ Ġoverride Ġfun Ġmerge ( v : ĠBasic Value ?, Ġw : ĠBasic Value ?): ĠBasic Value ? Ġ= ĊĠĠĠĠĠĠĠ Ġif Ġ( v Ġis ĠFunctional Argument Value Ġ&& Ġw Ġis ĠFunctional Argument Value Ġ&& Ġv . functional Argument Ġ== Ġw . functional Argument ) Ġv ĊĠĠĠĠĠĠĠ Ġelse Ġsuper . merge ( v , Ġw ) Ċ } Ċ Ċ internal Ġfun ĠAbstract Insn Node . is A load Before Check Parameter IsNotNull (): ĠBoolean Ġ= ĊĠĠĠ Ġopcode Ġ== ĠOp codes . AL O AD Ġ&& Ġnext ?. opcode Ġ== ĠOp codes . L DC Ġ&& Ġnext ?. next ?. is Check Parameter IsNotNull () Ġ== Ġtrue Ċ Ċ // ĠInterpreter , Ġthat Ġanaly zes Ġonly ĠA LOAD _ 0 s , Ġwhich Ġare Ġused Ġas Ġcontinuation Ġarguments Ċ Ċ internal Ġclass ĠA load 0 Basic Value Ġprivate Ġconstructor ( val Ġindices : ĠSet < Int >) Ġ: ĠBasic Value ( Asm Types . OBJECT _ TYPE ) Ġ{ ĊĠĠĠ Ġconstructor ( i : ĠInt ) Ġ: Ġthis ( set Of ( i )) Ġ{} ĊĊĠĠĠ Ġoperator Ġfun Ġplus ( other : ĠA load 0 Basic Value ) Ġ= ĠA load 0 Basic Value ( indices Ġ+ Ġother . indices ) Ċ } Ċ Ċ internal Ġclass ĠA load 0 Interpreter ( private Ġval Ġnode : ĠMethod Node ) Ġ: ĠBasic Interpreter ( Op codes . API _ VERSION ) Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġcopy Operation ( insn : ĠAbstract Insn Node , Ġvalue : ĠBasic Value ?): ĠBasic Value ? Ġ= ĊĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinsn . is A load 0 () Ġ-> ĠA load 0 Basic Value ( node . instructions . indexOf ( insn )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinsn . opcode Ġ== ĠOp codes . AL O AD Ġ-> Ġif Ġ( value Ġ== Ġnull ) Ġnull Ġelse ĠBasic Value ( value . type ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġsuper . copy Operation ( insn , Ġvalue ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġmerge ( v : ĠBasic Value ?, Ġw : ĠBasic Value ?): ĠBasic Value Ġ= ĊĠĠĠĠĠĠĠ Ġif Ġ( v Ġis ĠA load 0 Basic Value Ġ&& Ġw Ġis ĠA load 0 Basic Value ) Ġv Ġ+ Ġw Ġelse Ġsuper . merge ( v , Ġw ) Ċ } Ċ Ċ internal Ġfun ĠAbstract Insn Node . is A load 0 () Ġ= Ġopcode Ġ== ĠOp codes . AL O AD Ġ&& Ġ( this Ġas ĠVar Insn Node ). ` var ` Ġ== Ġ 0 Ċ Ċ internal Ġfun Ġanalyze Method Node With Interpreter ( ĊĠĠĠ Ġnode : ĠMethod Node , ĊĠĠĠ Ġinterpreter : ĠBasic Interpreter Ċ ): ĠArray < out ĠFrame < Basic Value > ?> Ġ{ ĊĠĠĠ Ġval Ġanalyzer Ġ= Ġobject Ġ: ĠFast Method Analyzer < Basic Value >(" fake ", Ġnode , Ġinterpreter , Ġprune Exception Edges Ġ= Ġtrue ) Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġnew Frame ( n Local s : ĠInt , Ġn Stack : ĠInt ): ĠFrame < Basic Value > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġobject Ġ: ĠFrame < Basic Value >( n Local s , Ġn Stack ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Throws ( Analyzer Exception :: class ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġexecute ( insn : ĠAbstract Insn Node , Ġinterpreter : ĠInterpreter < Basic Value >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThis Ġcan Ġbe Ġa Ġvoid Ġnon - local Ġreturn Ġfrom Ġa Ġnon - void Ġmethod ; ĠFrame # execute Ġwould Ġthrow Ġand Ġdo Ġnothing Ġelse . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( insn . opcode Ġ== ĠOp codes . RETURN ) Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . execute ( insn , Ġinterpreter ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġanalyzer . analyze () ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠAnalyzer Exception ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠRuntimeException ( e ) ĊĠĠĠ Ġ} Ċ }