/* Ċ Ġ* Ġ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 Ċ Ċ import Ġorg . jetbrains . kotlin . codegen . coroutines . create Custom Copy Ċ import Ġorg . jetbrains . kotlin . codegen . optimization . common . Insn Sequence Ċ import Ġorg . jetbrains . kotlin . codegen . optimization . common . find Previous OrNull Ċ import Ġorg . jetbrains . kotlin . config . JV MA ssert ions Mode Ċ import Ġorg . jetbrains . kotlin . descriptors . Function Descriptor Ċ import Ġorg . jetbrains . kotlin . descriptors . is TopLevel In Package Ċ import Ġorg . jetbrains . kotlin . name . Name Ċ import Ġorg . jetbrains . kotlin . resolve . Binding Trace Context Ċ import Ġorg . jetbrains . kotlin . resolve . Delegating Binding Trace Ċ import Ġorg . jetbrains . kotlin . resolve . calls . model . Mutable Data Flow Info For Arguments Ċ import Ġorg . jetbrains . kotlin . resolve . calls . model . Resolved Call Ċ import Ġorg . jetbrains . kotlin . resolve . calls . model . Resolved Call Impl Ċ import Ġorg . jetbrains . kotlin . resolve . calls . smart casts . Data Flow Info Ċ import Ġorg . jetbrains . kotlin . resolve . calls . tasks . Tracing Strategy Ċ import Ġorg . jetbrains . kotlin . resolve . jvm . Asm Types Ċ import Ġorg . jetbrains . kotlin . resolve . jvm . diagnostics . Jvm Declaration Origin Ċ import Ġorg . jetbrains . kotlin . utils . addTo Std lib . safe As Ċ import Ġorg . jetbrains . org . object web . asm . Label Ċ import Ġorg . jetbrains . org . object web . asm . Method Visitor Ċ import Ġorg . jetbrains . org . object web . asm . Op codes Ċ import Ġorg . jetbrains . org . object web . asm . Type Ċ import Ġorg . jetbrains . org . object web . asm . commons . Instruction Adapter Ċ import Ġorg . jetbrains . org . object web . asm . tree . Field Insn Node Ċ import Ġorg . jetbrains . org . object web . asm . tree . L dc Insn Node Ċ import Ġorg . jetbrains . org . object web . asm . tree . Method Insn Node Ċ import Ġorg . jetbrains . org . object web . asm . tree . Method Node Ċ Ċ const Ġval ĠASSERT IONS _ DISABLED _ FIELD _ NAME Ġ= Ġ"\ $ assertions Disabled " Ċ private Ġconst Ġval ĠAL WAYS _ ENABLED _ ASSERT _ FUNCTION _ NAME Ġ= Ġ" always Enabled Assert " Ċ private Ġconst Ġval ĠL AMBDA _ INTERNAL _ NAME Ġ= Ġ" kotlin / jvm / functions / Function 0 " Ċ private Ġconst Ġval ĠASSERT ION _ ERROR _ INTERNAL _ NAME Ġ= Ġ" java / lang / AssertionError " Ċ private Ġconst Ġval ĠTHROW ABLE _ INTERNAL _ NAME Ġ= Ġ" java / lang / Throwable " Ċ Ċ fun Ġis Assert Call ( resolved Call : ĠResolved Call <* >) Ġ= Ġresolved Call . result ing Descriptor . is TopLevel In Package (" assert ", Ġ" kotlin ") Ċ Ċ private Ġfun ĠFunction Descriptor . is Builtin Always Enabled Assert With Lambda () Ġ= ĊĠĠĠ Ġthis . is TopLevel In Package ( ALWAYS _ ENABLED _ ASSERT _ FUNCTION _ NAME , Ġ" kotlin ") Ġ&& Ġthis . value Parameters . size Ġ== Ġ 2 Ċ Ċ private Ġfun ĠFunction Descriptor . is Builtin Always Enabled Assert Without Lambda () Ġ= ĊĠĠĠ Ġthis . is TopLevel In Package ( ALWAYS _ ENABLED _ ASSERT _ FUNCTION _ NAME , Ġ" kotlin ") Ġ&& Ġthis . value Parameters . size Ġ== Ġ 1 Ċ Ċ fun ĠFunction Descriptor . is Builtin Always Enabled Assert () Ġ= ĊĠĠĠ Ġthis . is Builtin Always Enabled Assert With Lambda () Ġ|| Ġthis . is Builtin Always Enabled Assert Without Lambda () Ċ Ċ fun ĠField Insn Node . is Check Assertions Status () Ġ= ĊĠĠĠ Ġopcode Ġ== ĠOp codes . GET STATIC Ġ&& Ġname Ġ== ĠASSERT IONS _ DISABLED _ FIELD _ NAME Ġ&& Ġdesc Ġ== ĠType . BOOLEAN _ TYPE . descriptor Ċ Ċ fun Ġcreate Method Node For Always Enabled Assert ( function Descriptor : ĠFunction Descriptor ): ĠMethod Node Ġ{ ĊĠĠĠ Ġval Ġsignature Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġfunction Descriptor . is Builtin Always Enabled Assert With Lambda () Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠType . getMethod Descriptor ( Type . VOID _ TYPE , ĠType . BOOLEAN _ TYPE , ĠA sm Types . FUNCTION 0 ) ĊĠĠĠĠĠĠĠ Ġfunction Descriptor . is Builtin Always Enabled Assert Without Lambda () Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠType . getMethod Descriptor ( Type . VOID _ TYPE , ĠType . BOOLEAN _ TYPE ) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror (" function Descriptor Ġmust Ġbe Ġkotlin . always Enabled Assert , Ġbut Ġgot Ġ$ function Descriptor ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġnode Ġ= ĠMethod Node ( Op codes . API _ VERSION , ĠOp codes . ACC _ STATIC , Ġ" fake ", Ġsignature , Ġnull , Ġnull ) ĊĠĠĠ Ġval Ġv Ġ= ĠInstruction Adapter ( node ) ĊĠĠĠ Ġval Ġreturn Label Ġ= ĠLabel () ĊĊĠĠĠ Ġ// Ġif Ġ(! condition ) ĊĠĠĠ Ġv . load ( 0 , ĠType . BOOLEAN _ TYPE ) ĊĠĠĠ Ġv . if ne ( return Label ) ĊĠĠĠ Ġif Ġ( function Descriptor . is Builtin Always Enabled Assert With Lambda ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġval Ġerr Ġ= ĠAssertionError ( lambda ()) ĊĠĠĠĠĠĠĠ Ġv . load ( 1 , ĠType . get ObjectType ( L AMBDA _ INTERNAL _ NAME )) ĊĠĠĠĠĠĠĠ Ġv . invoke interface ( L AMBDA _ INTERNAL _ NAME , Ġ" invoke ", Ġ" () Ljava / lang / Object ; ") ĊĠĠĠĠĠĠĠ Ġv . store ( 2 , ĠA sm Types . OBJECT _ TYPE ) ĊĠĠĠĠĠĠĠ Ġv . an ew ( Type . get ObjectType ( ASSERT ION _ ERROR _ INTERNAL _ NAME )) ĊĠĠĠĠĠĠĠ Ġv . dup () ĊĠĠĠĠĠĠĠ Ġv . load ( 2 , ĠA sm Types . OBJECT _ TYPE ) ĊĠĠĠĠĠĠĠ Ġv . inv okes pec ial ( ASSERT ION _ ERROR _ INTERNAL _ NAME , Ġ"< init >", Ġ"( Ljava / lang / Object ;) V ", Ġfalse ) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġval Ġerr Ġ= ĠAssertionError (" Assertion Ġfailed ") ĊĠĠĠĠĠĠĠ Ġv . an ew ( Type . get ObjectType ( ASSERT ION _ ERROR _ INTERNAL _ NAME )) ĊĠĠĠĠĠĠĠ Ġv . dup () ĊĠĠĠĠĠĠĠ Ġv . visit L dc Insn (" Assertion Ġfailed ") ĊĠĠĠĠĠĠĠ Ġv . inv okes pec ial ( ASSERT ION _ ERROR _ INTERNAL _ NAME , Ġ"< init >", Ġ"( Ljava / lang / Object ;) V ", Ġfalse ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġ// Ġthrow Ġerr ĊĠĠĠ Ġv . check cast ( Type . get ObjectType ( THROW ABLE _ INTERNAL _ NAME )) ĊĠĠĠ Ġv . ath row () ĊĠĠĠ Ġ// Ġelse Ġreturn ĊĠĠĠ Ġv . mark ( return Label ) ĊĠĠĠ Ġv . are turn ( Type . VOID _ TYPE ) ĊĠĠĠ Ġnode . visit Max s ( 3 , Ġ 3 ) ĊĊĠĠĠ Ġreturn Ġnode Ċ } Ċ Ċ fun Ġgenerate Assert ( ĊĠĠĠ Ġassertions Mode : ĠJ V MA ssert ions Mode , ĊĠĠĠ Ġresolved Call : ĠResolved Call <* >, ĊĠĠĠ Ġcodegen : ĠExpression Code gen , ĊĠĠĠ Ġparent Code gen : ĠMember Code gen < *> Ċ ) Ġ{ ĊĠĠĠ Ġassert ( is Assert Call ( resolved Call )) Ġ{ Ġ" generate Assert Ġexpects Ġcall Ġof Ġkotlin . assert Ġfunction " Ġ} ĊĠĠĠ Ġwhen Ġ( assertions Mode ) Ġ{ ĊĠĠĠĠĠĠĠ ĠJ V MA ssert ions Mode . ALWAYS _ ENABLE Ġ-> Ġinline Always Inline Assert ( resolved Call , Ġcodegen ) ĊĠĠĠĠĠĠĠ ĠJ V MA ssert ions Mode . ALWAYS _ DISABLE Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNothing Ġto Ġdo : Ġassertions Ġdisabled ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠJ V MA ssert ions Mode . JVM Ġ-> Ġgenerate Jvm Assert ( resolved Call , Ġcodegen , Ġparent Code gen ) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" legacy Ġassertions Ġmode Ġshall Ġbe Ġhandled Ġin ĠExpression Code gen ") ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġgenerate Jvm Assert ( resolved Call : ĠResolved Call <* >, Ġcodegen : ĠExpression Code gen , Ġparent Code gen : ĠMember Code gen <* >) Ġ{ ĊĠĠĠ Ġparent Code gen . generate Assert Field () ĊĊĠĠĠ Ġval Ġlabel Ġ= ĠLabel () ĊĠĠĠ Ġwith ( codegen . v ) Ġ{ ĊĠĠĠĠĠĠĠ Ġget static ( parent Code gen . v . this Name , Ġ"\ $ assertions Disabled ", Ġ" Z ") ĊĠĠĠĠĠĠĠ Ġif ne ( label ) ĊĠĠĠĠĠĠĠ Ġinline Always Inline Assert ( resolved Call , Ġcodegen ) ĊĠĠĠĠĠĠĠ Ġmark ( label ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ @ Suppress (" UN CHECK ED _ CAST ") Ċ private Ġfun Ġinline Always Inline Assert ( resolved Call : ĠResolved Call <* >, Ġcodegen : ĠExpression Code gen ) Ġ{ ĊĠĠĠ Ġval Ġreplaced Ġ= Ġ( resolved Call Ġas ĠResolved Call < Function Descriptor >). replace Assert With Assert Inner () ĊĠĠĠ Ġcodegen . invoke Method With Arguments ( ĊĠĠĠĠĠĠĠ Ġcodegen . type Mapper . map To Callable Method ( re placed . result ing Descriptor , Ġfalse ), ĊĠĠĠĠĠĠĠ Ġreplaced , ĊĠĠĠĠĠĠĠ ĠStack Value . none () ĊĠĠĠ Ġ) Ċ } Ċ Ċ fun Ġgenerate Assertions Disabled Field Initialization ( class Builder : ĠClass Builder , Ġcl Init Builder : ĠMethod Visitor , ĠclassName : ĠString ) Ġ{ ĊĠĠĠ Ġclass Builder . new Field ( ĊĠĠĠĠĠĠĠ ĠJ vm Declaration Origin . NO _ ORIGIN , ĠOp codes . ACC _ STATIC Ġor ĠOp codes . ACC _ FINAL Ġor ĠOp codes . ACC _ SYN TH ET IC , ĠASSERT IONS _ DISABLED _ FIELD _ NAME , ĊĠĠĠĠĠĠĠ Ġ" Z ", Ġnull , Ġnull ĊĠĠĠ Ġ) ĊĠĠĠ Ġval Ġthen Label Ġ= ĠLabel () ĊĠĠĠ Ġval Ġelse Label Ġ= ĠLabel () ĊĠĠĠ Ġwith ( Instruction Adapter ( cl Init Builder )) Ġ{ ĊĠĠĠĠĠĠĠ Ġmark ( Label ()) ĊĠĠĠĠĠĠĠ Ġa const ( Type . get ObjectType ( className )) ĊĠĠĠĠĠĠĠ Ġinvoke virtual (" java / lang / Class ", Ġ" desired Assertion Status ", Ġ" () Z ", Ġfalse ) ĊĠĠĠĠĠĠĠ Ġif ne ( then Label ) ĊĠĠĠĠĠĠĠ Ġicon st ( 1 ) ĊĠĠĠĠĠĠĠ Ġgo To ( else Label ) ĊĊĠĠĠĠĠĠĠ Ġmark ( then Label ) ĊĠĠĠĠĠĠĠ Ġicon st ( 0 ) ĊĊĠĠĠĠĠĠĠ Ġmark ( else Label ) ĊĠĠĠĠĠĠĠ Ġput static ( class Builder . this Name , ĠASSERT IONS _ DISABLED _ FIELD _ NAME , Ġ" Z ") ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġrewrite Assertions Disabled Field Initialization ( method Node : ĠMethod Node , ĠclassName : ĠString ) Ġ{ ĊĠĠĠ ĠIn sn Sequence ( method Node . instructions ). first OrNull Ġ{ ĊĠĠĠĠĠĠĠ Ġit Ġis ĠField Insn Node Ġ&& Ġit . opcode Ġ== ĠOp codes . PUT STATIC Ġ&& Ġit . name Ġ== ĠASSERT IONS _ DISABLED _ FIELD _ NAME ĊĠĠĠ Ġ} ?. find Previous OrNull Ġ{ ĊĠĠĠĠĠĠĠ Ġit Ġis ĠMethod Insn Node Ġ&& Ġit . opcode Ġ== ĠOp codes . IN VOKE VIRTUAL ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġit . owner Ġ== Ġ" java / lang / Class " Ġ&& Ġit . name Ġ== Ġ" desired Assertion Status " Ġ&& Ġit . desc Ġ== Ġ" () Z " ĊĠĠĠ Ġ} ?. previous ?. safe As < L dc Insn Node >() ?. cst Ġ= ĊĠĠĠĠĠĠĠ ĠType . get ObjectType ( className ) Ċ } Ċ Ċ private Ġfun Ġ< D Ġ: ĠFunction Descriptor > ĠResolved Call < D >. replace Assert With Assert Inner (): ĠResolved Call < D > Ġ{ ĊĠĠĠ Ġval Ġnew Candidate Descriptor Ġ= Ġresulting Descriptor . create Custom Copy Ġ{ ĊĠĠĠĠĠĠĠ ĠsetName ( Name . identifier ( ALWAYS _ ENABLED _ ASSERT _ FUNCTION _ NAME )) ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġnew Resolved Call Ġ= ĠResolved Call Impl ( ĊĠĠĠĠĠĠĠ Ġcall , ĊĠĠĠĠĠĠĠ Ġnew Candidate Descriptor , ĊĠĠĠĠĠĠĠ Ġdispatch Receiver , Ġextension Receiver , Ġexplicit Receiver Kind , Ġadditional Re ceiv ers , ĊĠĠĠĠĠĠĠ Ġnull , ĠDeleg ating Binding Trace ( Binding Trace Context (). binding Context , Ġ" Temporary Ġtrace Ġfor Ġassert Inner "), ĊĠĠĠĠĠĠĠ ĠTr acing Strategy . EMPTY , ĠMutable Data Flow Info For Arguments . Without Arguments Check ( Data Flow Info . EMPTY ) ĊĠĠĠ Ġ) ĊĠĠĠ Ġvalue Arguments . forEach Ġ{ ĊĠĠĠĠĠĠĠ Ġnew Resolved Call . record Value Argument ( new Candidate Descriptor . value Parameters [ it . key . index ], Ġit . value ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġnew Resolved Call Ċ } Ċ