From 43e8f80e10600d8913ef473ef1796432e2c1f2ee Mon Sep 17 00:00:00 2001 From: TeamworkGuy2 Date: Sat, 22 Oct 2022 02:06:03 +0000 Subject: [PATCH] 0.6.0 - Decompiler improvements for loops, if-statements, try-catch, and synchronized blocks. --- CHANGELOG.md | 23 +- README.md | 2 +- bin/class_loading.jar | Bin 286096 -> 316988 bytes package-lib.json | 2 +- res/build.txt | 2 +- src/twg2/jbcm/CodeFlow.java | 257 +++++++++++- .../IterateCode.java => CodeIterator.java} | 39 +- src/twg2/jbcm/CodeUtility.java | 162 ++++---- src/twg2/jbcm/DataCountingInputStream.java | 61 +++ src/twg2/jbcm/Op.java | 8 +- src/twg2/jbcm/OpcodeOperations.java | 14 +- src/twg2/jbcm/Opcodes.java | 10 +- src/twg2/jbcm/classFormat/ClassFile.java | 125 +++--- .../classFormat/ConstantPoolExtensions.java | 9 + .../jbcm/classFormat/ConstantPoolTag.java | 27 +- src/twg2/jbcm/classFormat/CpIndex.java | 11 +- src/twg2/jbcm/classFormat/Field_Info.java | 13 +- src/twg2/jbcm/classFormat/Method_Info.java | 13 +- src/twg2/jbcm/classFormat/ReadWritable.java | 4 +- src/twg2/jbcm/classFormat/Settings.java | 30 +- .../classFormat/attributes/Annotation.java | 11 +- .../attributes/AnnotationDefault.java | 8 +- .../attributes/Attribute_Type.java | 3 +- .../attributes/BootstrapMethods.java | 17 +- .../jbcm/classFormat/attributes/Code.java | 100 +++-- .../attributes/Code_Attribute.java | 4 +- .../classFormat/attributes/ConstantValue.java | 8 +- .../classFormat/attributes/Deprecated.java | 6 +- .../classFormat/attributes/Element_Value.java | 19 +- .../attributes/Element_Value_Pair.java | 11 +- .../attributes/EnclosingMethod.java | 10 +- .../classFormat/attributes/Exceptions.java | 8 +- .../classFormat/attributes/InnerClasses.java | 19 +- .../attributes/LineNumberTable.java | 13 +- .../attributes/LocalVariableTable.java | 14 +- .../attributes/LocalVariableTypeTable.java | 17 +- .../attributes/MethodParameters.java | 15 +- .../jbcm/classFormat/attributes/Module.java | 53 +-- .../attributes/ModuleMainClass.java | 6 +- .../attributes/ModulePackages.java | 6 +- .../attributes/Parameter_Annotations.java | 9 +- .../RuntimeInvisibleAnnotations.java | 8 +- .../RuntimeInvisibleParameterAnnotations.java | 8 +- .../RuntimeInvisibleTypeAnnotations.java | 8 +- .../attributes/RuntimeVisibleAnnotations.java | 8 +- .../RuntimeVisibleParameterAnnotations.java | 8 +- .../RuntimeVisibleTypeAnnotations.java | 8 +- .../classFormat/attributes/Signature.java | 8 +- .../attributes/SourceDebugExtension.java | 6 +- .../classFormat/attributes/SourceFile.java | 8 +- .../classFormat/attributes/StackMapTable.java | 15 +- .../classFormat/attributes/Synthetic.java | 6 +- .../classFormat/attributes/Target_Info.java | 3 +- .../attributes/Target_Info_Union.java | 26 +- .../attributes/TypeAnnotation.java | 25 +- .../attributes/UnknownAttributeType.java | 6 +- .../attributes/VerificationTypeInfo.java | 9 +- .../constantPool/CONSTANT_CP_Info.java | 3 +- .../constantPool/CONSTANT_Class.java | 6 +- .../constantPool/CONSTANT_Double.java | 3 +- .../constantPool/CONSTANT_Fieldref.java | 14 +- .../constantPool/CONSTANT_Float.java | 3 +- .../constantPool/CONSTANT_Integer.java | 3 +- .../CONSTANT_InterfaceMethodref.java | 14 +- .../constantPool/CONSTANT_InvokeDynamic.java | 11 +- .../constantPool/CONSTANT_Long.java | 3 +- .../constantPool/CONSTANT_MethodHandle.java | 6 +- .../constantPool/CONSTANT_MethodType.java | 6 +- .../constantPool/CONSTANT_Methodref.java | 14 +- .../constantPool/CONSTANT_Module.java | 6 +- .../constantPool/CONSTANT_NameAndType.java | 8 +- .../constantPool/CONSTANT_Package.java | 10 +- .../constantPool/CONSTANT_String.java | 8 +- .../constantPool/CONSTANT_Utf8.java | 3 +- src/twg2/jbcm/ir/JumpConditionInfo.java | 169 +++++--- src/twg2/jbcm/main/RuntimeReloadMain.java | 331 ++-------------- src/twg2/jbcm/main/UsageCliMain.java | 190 ++++++--- src/twg2/jbcm/modify/ChangeCpIndex.java | 90 ----- src/twg2/jbcm/modify/ChangeIndex.java | 93 +++++ src/twg2/jbcm/modify/CodeCpIndexChanger.java | 24 ++ src/twg2/jbcm/modify/CpIndexChangeable.java | 11 + src/twg2/jbcm/modify/CpIndexChanger.java | 51 ++- src/twg2/jbcm/modify/FindCpIndexUsage.java | 52 +++ src/twg2/jbcm/modify/IndexChanger.java | 11 - src/twg2/jbcm/modify/IndexUtility.java | 58 --- src/twg2/jbcm/modify/TypeUtility.java | 92 +++-- src/twg2/jbcm/runtime/ClassLoaders.java | 262 ++++++++++++ .../CompileSource.java | 145 ++++--- src/twg2/jbcm/runtime/FileUtility.java | 99 +++++ .../MemoryClassLoader.java | 23 +- .../ResourceClassLoader.java | 2 +- src/twg2/jbcm/runtime/ResourceToClass.java | 83 ++++ .../jbcm/runtimeLoading/ResourceToClass.java | 67 ---- src/twg2/jbcm/toSource/ClassFileToSource.java | 3 +- src/twg2/jbcm/toSource/CodeToSource.java | 292 ++++++-------- src/twg2/jbcm/toSource/Indent.java | 136 ++++--- src/twg2/jbcm/toSource/SourceWriter.java | 6 +- .../jbcm/toSource/StringBuilderIndent.java | 375 ++++++++++++++++++ src/twg2/jbcm/toSource/SwitchFlow.java | 6 +- .../jbcm/toSource/structures/CodeEmitter.java | 39 ++ .../toSource/structures/CodeStructureIf.java | 72 ++++ .../structures/CodeStructureLoop.java | 64 +++ .../structures/CodeStructureSwitch.java | 79 ++++ .../structures/CodeStructureSynchronized.java | 45 +++ .../CodeStructureTryCatchFinally.java | 120 ++++++ .../toSource/structures/EmitterResponse.java | 14 + test/twg2/jbcm/test/BasicMathTest.java | 6 +- test/twg2/jbcm/test/BcRenameTest.java | 75 ++++ .../jbcm/test/BeforeAllCompileTestData.java | 60 +++ .../test/DataCountingInputStreamTest.java | 34 ++ .../jbcm/test/LoopsDecompileInspection.java | 24 ++ test/twg2/jbcm/test/MethodCallTest.java | 6 +- test/twg2/jbcm/test/RuntimeReloadTest.java | 45 +++ test/twg2/jbcm/testParser/CompileJava.java | 106 +++++ test/twg2/jbcm/testParser/CompileTest.java | 77 ---- 115 files changed, 3379 insertions(+), 1608 deletions(-) rename src/twg2/jbcm/{toSource/IterateCode.java => CodeIterator.java} (69%) create mode 100644 src/twg2/jbcm/DataCountingInputStream.java delete mode 100644 src/twg2/jbcm/modify/ChangeCpIndex.java create mode 100644 src/twg2/jbcm/modify/ChangeIndex.java create mode 100644 src/twg2/jbcm/modify/CodeCpIndexChanger.java create mode 100644 src/twg2/jbcm/modify/CpIndexChangeable.java create mode 100644 src/twg2/jbcm/modify/FindCpIndexUsage.java delete mode 100644 src/twg2/jbcm/modify/IndexChanger.java delete mode 100644 src/twg2/jbcm/modify/IndexUtility.java create mode 100644 src/twg2/jbcm/runtime/ClassLoaders.java rename src/twg2/jbcm/{runtimeLoading => runtime}/CompileSource.java (60%) create mode 100644 src/twg2/jbcm/runtime/FileUtility.java rename src/twg2/jbcm/{runtimeLoading => runtime}/MemoryClassLoader.java (80%) rename src/twg2/jbcm/{runtimeLoading => runtime}/ResourceClassLoader.java (87%) create mode 100644 src/twg2/jbcm/runtime/ResourceToClass.java delete mode 100644 src/twg2/jbcm/runtimeLoading/ResourceToClass.java create mode 100644 src/twg2/jbcm/toSource/StringBuilderIndent.java create mode 100644 src/twg2/jbcm/toSource/structures/CodeEmitter.java create mode 100644 src/twg2/jbcm/toSource/structures/CodeStructureIf.java create mode 100644 src/twg2/jbcm/toSource/structures/CodeStructureLoop.java create mode 100644 src/twg2/jbcm/toSource/structures/CodeStructureSwitch.java create mode 100644 src/twg2/jbcm/toSource/structures/CodeStructureSynchronized.java create mode 100644 src/twg2/jbcm/toSource/structures/CodeStructureTryCatchFinally.java create mode 100644 src/twg2/jbcm/toSource/structures/EmitterResponse.java create mode 100644 test/twg2/jbcm/test/BcRenameTest.java create mode 100644 test/twg2/jbcm/test/BeforeAllCompileTestData.java create mode 100644 test/twg2/jbcm/test/DataCountingInputStreamTest.java create mode 100644 test/twg2/jbcm/test/LoopsDecompileInspection.java create mode 100644 test/twg2/jbcm/test/RuntimeReloadTest.java create mode 100644 test/twg2/jbcm/testParser/CompileJava.java delete mode 100644 test/twg2/jbcm/testParser/CompileTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index b63271e..7df4a1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,30 @@ All notable changes to this project will be documented in this file. This project does its best to adhere to [Semantic Versioning](http://semver.org/). +-------- +### [0.6.0](N/A) - 2022-10-22 +__Add loop and if-statements detection to decompilation, also handle basic try-catch and synchronized blocks.__ +#### Added +* `StringBuilderIndent` provides the same API as `StringBuilder` (unfortunately we can't extend StringBuilder because it is final) and implements `Indent` so that this class can be used to easily build source code strings +* `src/twg2/jbcm/toSource/structures` with state handlers for inserting more complex structures such as loops and try-catch statements into source code during opcode iteration + +#### Changed +* `twg2.jbcm.classFormat.attributes.Code` `toClassString()` renamed `toClassCodeString()` +* `CpIndexChanger` is now stateful and contains the old and new index and uses a proper visitor pattern to handle changing indexes +* `Indent` changed from a class to an interface with a public static `Impl` subclass +* `IterateCode` renamed `CodeIterator` +* `RuntimeReloadMain` refactored, more complex threaded loading and invocation of methods from updated class files, some code moved to new classes `twg2.jbcm.runtime.ClassLoaders` and `FileUtility` +* `twg2.jbcm.runtimeLoading` package renamed `twg2.jbcm.runtime` +* `CodeFlow` contains algorithms for detecting loops and if-statements in byte code +* `DataCountingInputStream` added and used in `ClassFile` when parsing a class to improve debug and error message with exact byte index locations +* Several new unit/integration tests added, `CompileTest` renamed `CompileJava` +* Fixed compiling code during runtime to support class names with arbitrary package paths, required extensive changes to `CompileSource` +* `JumpConditionInfo` rewritten to support representing loop and nested if-statement conditions +* `TypeUtility.classNameFieldDescriptor()` renamed `toBinaryClassName()` + -------- -### [0.5.1](N/A) - 2020-12-05 +### [0.5.1](https://github.com/TeamworkGuy2/ClassLoading/commit/3653372d7564f749135a7db119a70f77df8b1696) - 2020-12-05 __Fix `switch` statements to decompile much more accurately based on code flow analysis. Start work on `if` statements.__ #### Added * new `Indent` class to handle `SourceWriter` indentation diff --git a/README.md b/README.md index 7c1f455..32ee8f3 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Also see [extract-opcodes.js](extract-opcodes.js) file for how the enum literals ### twg2.jbcm.dynamicModification & twg2.jbcm.parserExamples Classes used by the example and test packages. -### twg2.jbcm.runtimeLoading +### twg2.jbcm.runtime Runtime class loading. ### twg2.jbcm.main diff --git a/bin/class_loading.jar b/bin/class_loading.jar index 38e171c26d702dc11c3e87faa73abb78fc731fb5..3c777a01bade7a8cc081a500a5918ec7b0d26833 100644 GIT binary patch delta 248604 zcmZ^~b8ukMvo#vqwryjgiEZ1qos)?twlT@Xwr$%sCz){K*r%uKMMA}Ij~>1KUhz19e~07WjgA?8eEDvf zpEfKSR+tC6F2SfY)vozmtOi9h!M^;skK{}lO_;75&OM%3zp~eU=O}qcSMA|&hL6O5 z44?M4(<@Y~Uo2XP2FfaHlZanMm>JyI2U3i=H0O3R&yPHtG!N!$Fq=%{COj*3B@o77 z(31`qO?N>=+fexf@zY*BO7~b2uP10&E(5Z(d3L=Qq># z!ir!kaQ!hej3ok##K{$dA&o`!5G2g*xhRC+?YToW`xDHX(o0UJW;^JIKKcxCmEovu zaGV$^ov=R=iZYaP7Tc4)MTb`Y3md2-mlxDIxc}23QqffbblUz9tr*_$u5kXu|Bu5H zs0I?bKtVv3!TxuLGk)#Xe|!7OK>3^`fxPf18S++65msw_dkfvLa`205aZ*wS=1-FHAmz zn$@7b$>cB`{L5eD8)@3%%8<8bZT~>oYyZ?S&yVsmP}>`_gQva~8gtr0HJgsr8SAjX z!w@z`5zInITd6jW2lwIL&!&Nh$_Nq_{h>uvrB7zRjWlv#^6QZo^7Yms&ig!BD4ZRx z_xJ9>vI>;ZA=RyC14iE8DkvpjW^9P;!!=Ncm%5p2_e+P5Ns!X~1+NpABI5+(^TpV? z#;s#)7*V{ru=eV<_ya)y<0eLRy&~wjaO;qI zFzE4lx5=gKhT{zcpp@pZvgyM^`Wi$jqS9+xoum?n7;ouoduPxwAp{2#vr+Z_e2|-( z2yof@Dw|>ZRXy@b^0WwpJpUj_a_kn?KAh5K>W|T?SDH}a`Y0{hrBAHIJcI8GwXd^e z(W?v8I+SuH?pt6`MG0aUD|0t~VMo&{I4t|n1DVgWE9XE3J?cUtEnOM zJIZz=E8NHR`hq6I6P3K*HFV?{svwV4(xk$St2wD3U*=e6-|L{F7534S@ULkakH2!U?wV%h?zL?w31@&n`Bg3`uS`t zABOmAWo1eNq%B{^8mTwy<2CQIUG}OAiYK^0M#Pgy!bss}%Z|3e-M&^rIsb4+v?;`> zqk4&~=UpQ6@Qi8S5Cm`S!C1~zqBO+Oz!wv$^74%H@DD=0Pw&s3!m%K217FaLQ;npenRyn5ae2+zc&FRWt~<9N0hp>zwM9;`a8&uCSeakc-V?^g z9HX3Bo_qXle{DQMnF6xHQ_42naeve@dM%ZVtQLrkY?p8av1&qWT1P-p5^=p;NrGOC-%tTGmA(vd`T^x5r zG$^x_=~3ai(a)$;6GQ`(-#fpxIr12jNqhJ5Qep9JsfRH5aPiH(T*gI5;M>r#AS01W zq<5NvsZcK0cDB!S_Of9%8%Bw`Qb0`;&U+{1M)~bZ`L1Y-gHcOh+)rw&P@X;ryHrLj zKu)T{V%$v!+Z`}mUo3RQMUxY8BdNJ}gDG=iFR(0R1%QP4O_ zWNYl+JMXZy__uq@)JBlZepL&`3P%gArD}uArXB*4r9zsLZQ;K3yNEeGM-O$W)Zuid zu{aVB_U$wo4?kQc*VJ+?->Suc_i36d02(@|uUYY(NiIBbW(h9E_`yI0br*h_)l72_ zJ!;wTdQ*D9b*F37mAZr9^Y-(IH(Rj}NQ5`vSj;%P32HBvaUY%J=c50UrG#_}@-652 zwCNyZh#%DIPX-wQ7+pJ9?+eAOqXKXW_AVvfDD+yQrh}IgXpsEZgxq5KQ_s+*plP$9b*}Q^eKY)ke zj3Dn$XW=NY@+@lwE(Wa`(mi@O0qp07dbx@|#MLiYziQ#p8;gAqBC9F~j8-Mzoq_u@ z;74|^)h+aI%?u4^4l1{Gtxs)q^j(h6e1SS`6ZjQkxa zJ7M(?<4%MVUR%Y${dC%1O4)r(!w{#{a%I85u4t-4?pCW#WXYJ7ycyylreRCQp0lIyTRkZsuZl8P{*c0Jq)oCv_f=lG(RFZadB}b0)_gfJuH|}D+ zMR?^SzE-P&&{Ac0I{sS>o%gX!Q(K9G$u_UR~W_wayeGmM#($!0Lg9)Ccb)V;xBQRu=drdOq$Gi}#rhB{UBX6$!04637s z5~+v6$LEC7XA`3SbZq4C zsqQbQ(agUE(tHN9)&35Ig|e7W(IU{MDJ69)xD7s^FjS3om!o!zJWVW^rHg3&>Fhe& zy;8t1+LDS*{YSTb3e?nW+KLKBxN~g0A`E_!}vZHyNC$UNysT2^1#)i=c*@sJS*i!;}O=g|A zRc}}T`a{A{A@54Upmsx`#v`$7p`+sK=abURPft0q^)Hnk-G_ zwoPPaUSw2$s|%+-ezvsb)iR5cZx@UnL#eIzrzqk6qJ{akm%hT~AG0-H5xx3l0MORb z{9(;ydkE|)XO?kwtW}&XEm6F6_}uJ6zA|Q37tj4=7MgT0sDqU)pvV}UqmZt?`s)~C zRJ6=_fO$_x6?3GKn2Cr!FG9X4ng*Y7AzCG)0KXEQ7GuGp)q5SyJv)|pKykvg!zVpe zH~t7k_W|qLpmKsdb^npu=-ua3grO-^e;>ukvIm@Kq=;m;r1VzN^6o3c-X0j#hY?eB zJm06@9NYPh8#Jru$Jo=;=n<``i62#DrL8-1!boXl@^h>O=W1 zD1?TQjaJ1e8{8I?&S8i~pd2E?COKP5%-3~s@;a=5!FA~3*H^PXPYPZpt`Tboq-(zq z*#lX|l35$eqg0R_e{y-_pbha(ixIEqq)bU82pdVq3J)z*PP$wA^p` zz8+O1<7$&y6?}@kzSK}WH&Y1#cb=rN*MM_TUgxs7?l)5xeQhLW9u%vmbS(O3h+wD1 z_fVx?ry$vwC&6+FZLjLEuz8+AD7W@TimWZ=Gm!)}WtS_f7EBk2(U*ylc9{F21%3E;2{WYax zyMWUk&HQi$m%FoXIQ@^2#jT9)AC)y4DdR*7s$L=lQ4ReK@W)A{`@2ZF(l}_c$ z^5#jGJ2$PtEs6cmAYOhffsZP}!T}tagjL+JX5GiBJ2vfw>s?jn%V3^~#71DO3gLK? zJ!K6El_FSI=8#RoWrus9kiVduP+cS}syw?mpdty)7UDyZaBlHMPL{4$8AP36&dEGj>L=A_LX_ae~@^jcxv$r$LYSO2)W#@<3Gd{TwqDBIRi4#CyD#= zx+_M*MzB9^z#`>~EBB69C1IcIp(Uc<6e|LS6mw&I_-QS3@N)a~o&xNVAF8TD$W*t3 zBBal##gIov=y0@ytId{1Sj}7x#&>BlA;6iZC>OTsuC9+^Pr)m_ew)!6Oi*!`OSEU# zP0f(FyLMi3p>OCd_Z@NkqXZg+r#Abj?YTmQEIoV2lDLq28b{2Q4~S)Et{(zNr!*&? z{c<86T$*T>qwM(&Z<|KkOhyl7=cS=`dEU(5REFeu71%=VSH0KMNA7-jx=U zvHzUbKfmL5jH$6It*AwiayDj)XK*57j*GD=rg0>=qD--tERU?ajsjFHknvL>Z+sH<-4;?^ob`R9X9D358n8-erU z_ln6KtQ`?RaTCFSlhd=KG@C|rF_dL{4E^xJ2}uxAdU=ruP5z#;C)G8NnRRzuYx)=` zJ}31W)d;GtFL24nbdC_WdU1`~9@Mb@{V_?V`yVJX5LDktDF}d8A!)gANF1rO@X;-I z(}^svY-4YCU%S?T7~#M@Lv#HTq&r`It;SxPc-vbPE2K&-6^mEjB^J;1R=Yi`PareB z61h9c%uyCo&d%X}GtVD^uu$e?P>0lfs_qEEzkU5iA?X?8{30WEPH zgic<*=}j3)27L;+T75nF?U)^Zp1jT@@Eoo?H4?>hvrU`a?HLvXeizD?z$28;be$!weh?a~D;PL>ODmG42QA91FD7Ax8ZiA!Q#rnzm)Xn+{tQ}Q6H z>-+X}-MJ!ySsu4R7*jn1tW;6f#N41Mt%RxzsS~O~YyzoBtZDWijcXPC?U-~M;P?=u z1&`xfZot2g{NgITtbb{}HaJc6ah()UB?O)u!Bj$|g${tv*844~2axyvl0G;4uJ^n4 zX`2lt$}DSS!;HvYGwRu*E%w<5m-&DP+c`ljt4K>Si(%uRIf;&Z;^mszre_Jb>-{!P zs#M%q>vs~i9|98OfzxSZ^no&u*+9SvxmbvGvXEHN~ z(?#%{@ao5G5Jy>916yGNLnSyX9tBe45$Y<*lohvglnq68g^gsio!jw%`F4b#;h2%z zvt5SJBX02A?;)8UX`ylu>CNx>9v1_#!qUOPk>_S$fNkRWHn(h-v~VQkk@I#q-a* z97qGW1(lVg=Vt67eN7xR0=GGdGnugLaLP!L9%T6Ln=ny$ZUHW1D#GfgAH^l4TcQ9` zu0@=$7)~t2qnl!;zWbjoVf!><^D#t2YrSs96yTC%##iP{hTPqov)WU%Aik*(mO^v> zkz{LQB%iU$Wh&8g@WJW$HpzDLSNDx;iLcn1?2>ph)eavfQ<`ksmR%&-c#@Xb1dmK} zg&vkk*3@q)28~dyF$SIcH9UK&n|**^7u5}c8A9hXaNuKiSoyJ`Jb=2cvH)_2V#9mT z8+FV~d2p;beS|GxV<_^iA^8St^6s%bmSj#NW%7&`f^i~n|GIt^5i_lf%}zk6!Z|y3 z9YSQH)%K~wGyO_28w%JIE%lIZml`n!JSTQS~-0IYs6_-(zr_5s-LdSJX{ z!}YxTRC}56>OTMP+pCy78n#Y4ZyQ*$V$Dy;|C9#>B*yH`zY5ckU#08+;jG873^HFd z^}h!I{bkBYi;63#itDRP#jdlUbidL{WP21@ZCn+pIBpLHE}=-qYLBy0gta2FM#`f) z?qu{{HK)YSMxVT9{XAo+Ec~&_=>da9RO@BN@KADbiliSBevFzc1U$nHFONhK1B}xv zmcuf9MEWq($h%-}9*rIJ1j9ZN&GJSsk@~o+B?PVfT?N-kmlN*)Rkwf=k$uZk_Z@tUwJx$0Pm@CrVo23`7wAt3oHY71@3vzxt(!N)veLZ0h=1KzlQ!rK8v z(8-PH#Sg9Z(l;gcWbRgee_yu^X><<4mz4{yV_1U~AErN>RZ};dp^4|tr@#nz@12)k zRZq{m!*jZr5!{`-9t@o&5|L4n{{rVk3IW;oA92qiFS4L1nOTS{U}lg-8Z~U_xRYL? z4-7wIIAoi+0?{+EE#PgCI#>HWwas87h>Nh)A!XRx=v--QsiQayE$g*<;rHP}cj^X_ zain9w&^lG6l~LDZPThV|0tsy#8zECgv=Oe=98NTCTx|L$dZKO1Mdc9VmVlJ*s7bZ5 zc%_(et`ep%i9ubU&DdRbA&%j1-!ImrexxxmG~cUol+k+}_1*G~5}TVAA>~-F8g29` zl6f#hWwZb{W^1$0g0@uLhX5!`DF201Mi)KI)|b5ADau`s2J6H~uQRGwq26zm6QP6- zyAS7Vny)?}gx!Z)zLMfa4TQ*D6SUERsSdUncODb}2e|Y<=WhePs{cF?|2uHAQBkG; z8?|4?7qUT^EUn$FEgc+P%oh~LCl^lUWoH;b6NkzuDKos!hQ3<}D+g%UxWH;ru?sNw z(4@fsS1woAfK5RC^)da|RFVb$Z#@X2<5lfz<-f;Qwg;jjE-WT5{*}p9sc+cev!eK~ zXd>W5BL2jZ$xQrC9BEBjluv5^Vgi=h)L_8d&XBnL@55hG$B@hUC2^T~*_IR@U`q8s2Tug6_zruFI0c3Qh{5s@;jfgZB;m}gPUi)AJ+(u=q(roC39~)Y~7IqnOtTDD#Xr>*=q=boRy9j6^IFVf7 zo|X6>7r6%1WbI~Ct%~}cprTScc_ND$who|d7HKtzb@`Pk;+tw^Z?U)7AI)m9bW+rC zaEE|($jz+c+psnYM~Oi-%Ox8+)eH&Kax_^bEDPrbzZp$rM}1Os^=mUYMkvb;ey^|H!Edlyg<+jQkVQaJp4X9aL`VT{4*zH6Rp zQ@eh5n8nNsiahN{yXa)lekAsd!rm}2ZnDq+PfC?kaw5Dbfw|ccy@%xG! z{}WYUU^Uc}PC;paE^T8%FEuYW>36K#+d6vKZfrGQ6?r&rEvYX& z`hCh#?ZwVCyq0D-c5k$God}%Z_dNHp&w!SuwPGU)OIuh1GjHveIr?4hF=JA0=KO67 z@M%VG|E^=5^!c+-%WTg!i7v-sBCBnz9oOcu))y(_{=JMYULVN0q2aVr@CZF1+*6b5Iib?e zu&--0GPxTA&N*Q!bFC!8FZwg=H{G?Dj*s$fd~G$^h)SAS%QaTgA|Hm?>ImnCQIqn; zEVSt`x3>snE%7>GV2<-Xg@ve0qKSiOv1F9!vM{Ol3Y#!vA)9c&Jzg-))OI9PKJ7Xt#svPWixq@f0PZE^TkI>LTRzLkQF)9LC6j&x5(`BY6CtNJm1t$s|4y}~-ECi% zYh)@k&%ftfz(Ef;n)mB-SHeDKAlwv0Yq*U7XsA=*R3;P_O20tWDKxmV-Y#bb_uZjT zlDDxg^2^?7!7k@j9dy`49<|C9AdzEqg>-=yQ5p!4MQHWxnE7sSa6I|*A zpy>>9lrI+eOf#zOQ_i=>?eBH@Q%}G2Irfyg?QX9|?#xj!@&LC2N$GG}j8YpWz3o(K zXJ1kGaGQp$e#G*arOkPlhZpzeZ-V!5K{sZ%VISSD=qZE5UUQPdzt3z0^f4y>G{=LH zn+_%IjYddmhPrrNK=XQr|2m(%%4-t@2(NxtM^dt3c^Gr6`kKpLV10BLtCzM}!!sJ? zLe8KK^ixiDW;r!r6Qj!s+~L9l5xO)A55xvao3QN)3BM6Z@jR|<)bbGB;i}?n1$R6| zC@%ZOxRkK3>aIu5F(j?bQ4wE5LKXLss+bt@Gj&=*maDDWEo60NZGBbgUCkhXYy6}x z|2;LHBst~T66X@^y!`ZpivbMVy@uAPQ3Yz%$(i$Vbk{$NEp&HoyF~DhbQ$gQb@;!( zIrq$8gWD(zB1^6pQu$5y=ka!hk4evf5VDR&F9C-=5F{7Z-0xEseUs%4p%jIJ#JzdmH=)W^ zA{$q3RO_~TGdJQzEdlMcM)=sW%T=b^=IQ=(PR!nivO#0iR7bZTTKs78&)4RCc63eT znI=B!Z0N6a>|^5)Yng_k^tKtv8zw(>8c?RyURWcD-dzX#4R>kraEmViST^9<>TfLC z!menlS6StJ(#ZYcLeRRZ@{qNo(g;z@Y_z)1h~XLGOpcQzQK9ARKIHQ1`M4g6l@WvT z*?{IxOimrMhMr(*1#QPq2^65S_!N>Rr=g&}mfG)L_x z-Oh26GSRHFsbaCgKqGU24f7mp5@(Arn@ga_e(&!!VHkgvz|fF-K0BWg#AuJ@p1b@; z!3RI-Q^urF?X~DzgmZL}I{m@CD|NEG&ka6SK!F$WPTFLAk?EdSDPI~@P@aw#y3lX` z;-F!bGr3aVr*?PgZ4u9A>a&NJSDBWS0U8+rn|+WPm?{v6k`4|D@PYeHS`q}5a=7L0!cnm zU?rlR*h)}bec3=8KXTcMzw*7{rt~Eiag+*-!694MyBVcH#}bZTbbrnj(r3?n1JWT! zPd@y@a<7xCAxQ#gd9vGcvHvJgrS(U$kNEX5n4UdAD^aBt_}WF*XngN{!YC>#+U|o4 zPVXSg?~P}#a5cFmeHby5NVdmE#WI<(HGzf-M%hJL%xcX~@0n}gmH7h~aCtpGP^C{{ zy}IAHUvbElB5F>xNImkVhOHl(eU%Btcp&Dr>|uBF`FI9iW059wD<>|cZOk%9?DC!_b^ZRW*Ge~RXjN2F@4#oA~%P<;>VlnHvm(^P){jMR=FMk%lv1v0cPTM=f zk{qR~jj9#hGucBxUPwrMFlffuF!>}UXgyxFA9b)RtE(8+ymu)xzDk!h9+G7!q-12v z?=eBK@$3WQp2G)~f7QH-Q(ei1<)O`=yqvR~5>VxFZ->wD(Tmnj^8Kc3Vg{rpo|nvY z)<@ZP7`KX8n|ttdYG1*IZuMl3k2*q?_im2R)wT0Ch@LRy|K0AFy8>Qx5jwyBIH2Eb zA!eFKImKx*VKTfaXm(VQ)zg+bF(i;jB*04^S_X_*?u3<~B)X_Lk zJq5Ao&Y8l1cBUYFW<6u&G|-ika6Q=;gn5$0Qet)TkYd8JU9KKbS0K)+0P?bt_+D0h zI-U-=Jg2`QbGWMEZME`eOgb61I?8i2FyczT9^tJWro;rDL3Ww`BpkypaG#RUbwKb8 z?^xyh+icdLH_^VJn~v7WR$n)s)5vUCq}X8PW6|K<$eI1;Zh`Pi#r7)|*FDUb(a7su z$B7-;Fv+kQ;EB6t)b}ZePQH2aYBPXWSWN`5v`40NdHeK`DbeQC$e$?)<$Xi9#wuN1 zerk?dtIl+$Bs6iOJC+M})bCZpVb|Hu?>v>VZC+n5OgJJvv7{c5S?Q`zW_$~%kM1Yr zhr6gvJIif)VI(a>Oa#p=@x&S5hGhbx z1D-LQzQwBd2)Q}dSCx%3dm_o87HSS=FEmwPs@^I`$?GnM;^Q~2D|_`mk03};;8(J- z#_J}EWzJ(gySTkmZDr!VdMf98a}0Rr{-8U8 z(X@VuP<}^EpxBr-%y1Y>9rwfZUI&0^I%go%d-J9r{j%`_I*w)qG&b*rJ~$0>EBLnm z^*89=zGa_Bq85nFqt|dQXuaSU`U>ZMD!Kg~8$8@XaErSQf?+GBqyC zmjL4^$_SeO~GoMf2bxqfBT<(qqvrybLp z4?&x*(&R^}x4#7ig+@o4G3GV)xX}1f` zXU=XY!Yh@G6`m<6j!P^(cnCnNL@4jBJAY&>`D!V=wq6IedGy(-{+0d1Hs~Z@5aU4B zFoERBaN?-4n-Bm|hhBW}jqnt%w_FA}mVBO$w*8%VSruv|cWqHuVL&GX@YfcDp zm*RJ*{LTcy__DeDk)jsgq6R2|j3MRsTRE(mRQ?)6{%==Pfs zz1=^Qmsmvr^AJIV2|=-%l+K~&PPpvX6GY!lQBcR;2OfT3JyCBU;98}sK6-*;RaTDT zn)G-;;&y?mA7Fnz{#HEt@Z~4Dk}A1;mc4ChB~NG0AesfLP=Lq}VZ)g(u{CRl$fO;S zZL2#v#|x_C8qQ%5zw<7wHG{cR_XbIjiOEld!B2&17pV;;F9Ekz^?0|zh4v~DYLh(6 zDUZK*W%oeu6^$qryH?R)_~b~}OKf}a_bnEYr(B=#2nYXOdMv0UXZLPtUsbG6aRZfW z>e+DiC^fre4^Wqs@w-Ky?UlgwM)wULy%k4@i}nwhP>+JmtQpe?e4APBj}q50KR*Av zzf>82kJo`+p^Uhml$5rHo+SFqhW$jkH|&6sx7_cBZ!Nh+F^_w|eWlvIf={5>ci-0= zrpIS%ZHP}>v(B^%tY(kDs(eLJpmI+j=$)r1D#Ip}p@4MK_K07COBU-J@9=3Yt|)>f zg7p#|14xl5!cl1z_nF3c_T*m2sk71mDbzZ*4>Ey4=bxcnDTi@p-b+g6?7zSCWT&&9 z)>wr7jbs$VX~nXrgcaxdkelgW z%1ixzISXL@t!7cv6$Lxxg~L@p&e%o1>~Ff)qe*2(xhEt)10fNt7ufc@=nT|m@W5>K z2+oIp<_rG-39%%|j0s$>C}u7-HW0eBSD_V#4f|4qzRQfdJcBy9!=lu_yqufQ#N|#Z zzUw2WeVM?DkQdDDF|IYu>;2cAZMxSOj%&;dya<3xY!(>|)~>{T%w%C6)N2d0^dA6i zp+sq<+FjTqDsT~G)`jPj^Y~Sq{(Z`66(o}c-Sx;nuwH#a6!I20{ET^npBhLOAyg9C z(Yc}7tnOP#eAckcZ*Qsp0cudhS>t?fUwrAQwbe6$_bD(xe^Gg`V|n=js<9u=@I#1< zu?r9$e}-if+hiQvBz)rae}&(SGu#9D>y73Z6S1AYR~|s42tm-5Q*jP;eHVcMBqhZgNc!-?M^(#O#{f^`b#)_A2+h$e}W(r6pP8-7~ zlq_85_sAnIZ&q5~<%QV#=%lbw0cWT=U|wUKtUVVG3pD`zS1p^tn+J~&*?pTmIx4N|t4 z6phvdhH@cTi{+_nZP8_^c)wGFah=>1s>+6Yrcs|(-o4+j`)A8^hlcq7Neq!53X)_xAa$jShB z;)9mt=n8m` zJ=&kWIJ#eBOqj0=C>kcPUB(L}s?{U(Tc_u1NWHF@xA9X*xc<*K}e%3?Y{pc%>>cmZxe zYd1iB`_v)#)z6WP$!k-!59KO0hS`jH73fPGB%Pq85i&(dni@;a@gM}JuOMdnWuXML)}4LY_a zeoJ!g{g&+}TS~H~!>J>ZVLaD+)13W3sT_?01^C+AiVdt;>ji>?_ZNp5NPl%EQGve5 zO25WyIxa5@%L9uO_1=b&&C0RE1TLF%7S|&#+Nd!Hf4cn9bi;7Sgeq~0yO#4Om4js*1)Kl#h$FrMyhpHj= ziVKN8tZRJ^#)Vuoz$u)30*navARIr3uJam}Kq@0O!9hbK#>c>r5g)9p%tn}*`NCaQ zuqB45!;A~!MYX0{ux}l+t2yekl>Ht4srG-un8_T1f%%uWdz++V2-RTO^?dVPijb+fL!*Q zh0UN1Ci+sbIiHJF&OMHbGZ?kDi+D#i2G4z_SczI^=mHp1Sx|_lK2*56n3v)ea=(+yb$^{X&xVwWl# zn@T*kFbZnxeywEpsW|;8V>pNvSgBlOdni<2tSoR22VC)&dHC(-)UDtw9;f^}SW9j_ zZNnmYCmZ%R=ll0Ro;NR!?wy3i@o>TD&SG$X7w)iCP`FUMwd1TER6Hq(YkaZFq~{_# z9k?9LI*QPL@+X!J8JK9CQ6YY#cD2OqZ5s6rVOy2DYsF2Xhwa2*E9!a@Ds=Nym18VG z^?D^X5KUj)X$k$fU5-l2`dX%)s;rp&ATbcXK;7qTrHyrau=i6lqoTir$Fpw>-#;RD z$J?oIX6Xc{;|X#x75vfRD#r^PTBomIG+A)H8;H)eox2SGQ}4^xF5pgVC?Wbg4yAP$ z_u6i6w3U0;{XKd}o}k1Z-ti;wqeg!pGVe74aNM7a6@4@nt9i)vk4O;WzL^fV=$OZY zw>Rd;xc-0`@+Yoza!uqFl?1&1$^YRFa^Vv@o}Fk)I~mXe$1xL9_(g2_B!P3Zz!Pf( zM@r#+W9f|GO)ye&uQejQ$`jK8bD%pM5S~sxtQN(xJpy?Z@WK5fDp_<$GySlKDbf`g zAih4d_y@41cZ#|XJB$G#P7;qblRi{JvbS24;OKaR9L#rw z(YW!z4KD?f(KnX9$cwsBvlnQIuGt*_f-3B-=N7AfoBoQqJsYff-gN16tyhzDy8CU| zU2og&KH&_fEtk53LJ|J3xk40bg1?U!kQR@?y|X9mTx=*3MLy8^c5iGJhh(|y8-zsL zuRWIL2qp=hsMuNB3nyqp?-W-iuqhf`C)vt{yRYZHg{;F?7_OV_c?O{kHw)ttTYJLW z2XAMwo{wUG?=fcbynxAHL8%gx=}dfX*Ng_ z7t<`XvDzWDz;u~+WR&N{(1ikt$9Yb^i~VT+^VPRM_Ga;6InCP>0DQvkqRddX;%MX` zH-R@9aAlS+bNz`dYnqC^((vg%C z2=hP4e;YS3oKObyWzeyDd1-*i!bodbMC{NRNZ(X8rl@e%U4 z22VIxE*cY)hFlXCC8cTjRD=%GT=x>vf3-HT`$#rd_sUOrGZRVsW~%gYK_S|js7;aB z2qRpL-El=Y&$*r3(8d<+R-zVyV{)!3q6YX@`jW7tuZ4$Dy8wUJ3seF>Q$r7gyObeG zR9t}L^{t9j0pDW*{$cj#Jj$5M&CiIGV^WPws49cV?LPh^=J>~CzmHHLFz2CmRkSdC ziJt!{GKM*5y`U$qUf4}U?7M-S+aV?%#?3X{IA(LomSCbxJF@uN1-U>u3Z}nEGA@+> z>Nzo`qqv$Hlo9{GPzML+BRMU-4p}X|uB-w&B1FE5##@G(Tg0&$Q`;`yxB&oy?dVQbT}b&?Qr0~gv^Xcv)S)oI;k||{~1ZsV!6Ta05M}XV^K$U z2RCa6OKArucQ;ix7jt8KivN$b{}oho5|tGflrTm9L=FHEN`C6`bhkDd9^~YE-1MCmH~~CA zE@upP01&PI0$BN7hbND}9_BsUJf)R<`3+cZZ?j*06d%Uan+Uqqu1cq_7X2tVJD%G- zn9QYvU|`ZreCLsYrEpfc%<@0l#AZpnBcAz!2m#=r0FyA#Ckw@qD8qoIe z^h-&+!Yn*Nhyr8788dRT>cE2Wkl;v=xS3KU=cEK8ben=R(+}Itqx_t42y_v*%QAxR z_U_gldTp+H#HSM)s)@EA5YORolc`4kh*@44v_fSz3y7lN7*?ugRZSviqS1I`z)(3u zd8kpTF=BpRu#Rs_Be?w|IK_T}t%iiOu~cMfF{4>-6khFfQygw|#?tY`#kx}d{R;P} z(4v6cg0d%5Q|MHrSzL0rU5MAGL_RrzYDYn~+qziSV1*EKc8lNsBTG;9d_wD&&DhR= zm}0q1$V=E4zK{POeE|QF8q@HV!2f^o{lBmr8ZRq5po9`S(^zLczbNV7gQ~9v2_NKu z!L3e;qNjzbx80cLBby~f6!|$8LjnW0zfMf~b&ImS)C+qcCnL_);`re12(edCL;euP zc1+*5W%(wnYrRfNOh7JJ4AP#vRT@b8YUrM0H%77G+t*lBE6x8wmG4vvmO_AfT)vIW z0YYGBfEMkunn=aazun`3FKWXTNyCdH+$TXq*`Hnl=AHV_4_6704TX(u>3*HQaJz%rzbEgP_Bj;W{xQf(PVSx8~0w zTwp!O<$f3QtFN)h0$P8~Vj)Hl!El#4$YLpH_<2JH@m2}fCT`+p`sNP*KtO2*-Y(Ne zYHrNb=I!y@R8GzHUdEmi>|0lVRzBCe0{A)f3zR zBnn?|Bx#ZYyH|N2{;%)dcJ7IP&*SUUt|9j}s8Sp- zN)xYSL3FmG#=VM9RBj7!k*y1=#+@IRB7{Ty{q?PKS$s(g(D(iO3yZ6aFc#Vr)xOX> zP=#@>AWWW|m2R(FLzY|oqP<&l$+e*}YPkM77OVU#UQm6iGJgt` z@uxGS;M32T$V+F&{9&>w2|5cMIjE>o5oIi)TNrXUP&%x1Lv*RO2-T4HE3zr>hi&16pf-_G)V!UX%QcH6IJwf2^QkrTHQ zmex8|w;@4_2hzvvzo@brLEW{u(a`9wlx`biK1q;k0j6T)k(}H{YE)1agY;Rk;yvq( z9qjD63s*%JZi}u;uDfxxT8@hvt5cNk5il{Rj z_IA^ULj z+E9RXmc^rMPywr)J{A$SJSd zM$34+tDc>7gE!*b%pp9`t%%`AcydOXUzRW%nD7fatyTSvl-uCsj-1wvJ;E0g8$)l9 zJ7WMfRivTH%y2ZbZIXl|r!UnG%8?Fdprwoo4AL}%MVPyLLSk_t+)U$F3x*%D5Q(@3 zKr%6&%Z_jmTQ1s#>OKXI_V4NVQ6hcEIE{6hYjmZtyP0E%=P4nGIBH^cYO!Nz?s1on zY6#LP23?9E!@(K!m^xu9o7?E(Gxd4$ZX_}!T8*r->2%+IZ_1m?4uy%-$=1CJ&`4ENd!1M0gzOpYAQ%$WP6$DEMO{s`KIs^I z7;4+J(YHf<&Jjq<=N$d4U|t~o>u@pi*{mHSA^N8_Oq^-+@c!YN^szgLcpnb(uebA1 z>bpW8qMY)-d~8*_TO)>I%FN$3Y-N<@Z`%FucLgHDhLn}99dt92IvJ1kQdyd$05eOs z3j9;|VQ>=P+Im|X^Z1&tlAJaxh76X{Es4-jPa?h+OlQnIz7~VvM77Sj?DNKe;;&>2 z*}BQZAc+Zfrt>G-Y#v)G%0|XB) z!QI^n z+QngXw5fpMx}=NjGBP6)rsmA zE;C8$YCZOI;N+zM7I*6(K1AUPrQ`|if-Tij;w_U$IgUr4Sp#;|@LqqOy)RFF#t{o> z7TX}xP1y!}!wOrHTP2e)%j!ofdLD-vW>Xkv!h`8;B%C;V<9JlPHSH~pBA_MaX}!p4 z->hkny4dD`;h6EW^E)D)5dE~{3QPT9b9dCim7rxH*^tJc(=LF-@87yQGtI#!3kLym zImO^Z;m@ku%VCVd!Qby708yiZ?7l;wVqrmF*4WUFKU)Ox63){JKy@9rOY1(-TgN)F zj!AC%Ofo{jIKrK`$Kti2fS&qOK?mvqZV_vmEs1ICw0NFQDzu|_Zj19Co}1owX<$Df^B;$$|Qp86{leCsnh&GNCngt zSx6_SYSRXZg?b+1-e3NoqvdzNqq4ebQoE?Ly3lh$!ip`mH2h=(~C3_$lMmyQ;xI}c6q&l#2XexE~eT_p+( zS3W&5VSmB+%Uqy(eB0AykUW6eb(sGMp7x(wI;aN%fpFh3l!$|n6PF(e)XFmtk(n#w zc`XQ(WCEqatHjMdUl0K+Q#DML6Q)`7;EW`$BpZ!?BH%skuBRc-D=mVFqA0wvU@_;_ z>nS?}9V-lZnSExMF!Y#oX(ObNJ5gjioK_kwI~+)?yX=;2;!{mnAjq`Eh6(<-1Bkl~ zp$m9CBh9ZJs4-8`%|lK8&d%0THG2sisg>Uu9r5C4OEegf*Li_e51NgN>1R+m=nNHI zW{j&gi%jfHzjunckCh+4e45%!{Msi{{8JX!I{lv~auByY{(zx=MQ%+@ss?82r<^9% z3){V5I1Bp;Rs%fysSX=jxqq?t6GGQt-7V;w=$xn6tgmO?-5uh`O)Y^8CO7y5Yzz>=uR%MJigNxZh4ajM5R#`I- z64^N4%2E-M85hsyo~z$BKF@Vb+QP~At+)Q?%R26e%qE@OSKgKGXq(#9sgCRH;3t&F z5#^>J^>S{vg2-l-ZEsj@BVgMs&5WG5AQ{UuUhUZGDIUWN{AJf}n77aSAk3>>Nl3DQ zD0?k%YS^I5H%uTMEgfb%YY}f@JlN75`9~&x3&oh;Vut7u-H7&LkNOwQFD6_?-3%d4 zkP)#b@{4*kik z)+D7Qshx_xzym)9Taw5wtKq6OTr@J`3Bv;}uaHX1b>CKo{N_a_I8VrNMw>W&1h;DA zNJs~#_Z7$$$~(bOtQL6_4Mc$W7IvkrwFgIRI=3T5Qz+pdK&TQVOR7fNuK}8i$0xAP z3t`%v6DcqW_}3;TJo)HV)ok*jAcv|RFJzf)If2CsjMb1s)tD#KARwpGD;w7!4V2#J zOPZ03N0okdqD}e?4);lPL6|DSA()9|VbzLJ80O5m+E@t z$i3)1p^~e87JXk(GEb&~FVRR+D#@Zd9(VEr5|40B%$BUIVTsNOcMqVc?F!cIF!$J| z^qchLec85#=2DSYC>d>`o^|J&L}01BQtYrlnek>g!f z!A~@=rq#H9%K(p(A3kC#_)BY&r|=&RP;q@E1XW@oonx>3b?5um4D<|iGZJ3I$KdM+ z3f#I+iEBp+OGh-PL)Kp)_?kxiT?t`_ujT}gHQpkDS2@Ox@91X;S}*(bF#0a>+tv)# z@mO~|*}&hM<)Tu7&ACDMIK-)=dSM3M!6Y;*HZ7j5YUc{EX*S*=C@Yl`o6|zB-z3B+ zj-GK0r}15W!kaEZZ0@a(f+&w&(Vp^v3(m?v;lFYFq@4-y|N43x6O{SO3XV#jKSD=! za_O$=nbFWnW(QLRB9Hk(wioa3w{Hlchszq6=D)#7 z4lVJq)szrS$7~AaV*6IL1jUwq)+BM&?v4Eo<_mxDU@~h`tfA^;9q_ZFYJ%Rd_$zAc zKCs7S>4`q-{P<~hEATkJxP9VF|NVg}u?Q95YI z_;@wkU+Q>OaMu~r<@af*NXZwTEl+;HVss~k)vS&LK(s|bR z$>y31e0N zFJid$N}}YocpT-X{6}^WS~>J8+hsWKe_>L~1LZKGu2FxY#5|^@7?%*1k)h#l>jD|L z8MtCm0w_}IvGLO=-3bR-4O^f-xv!P|lI9M%7Lr6@pt~QSO^r0ufBkCReTCzgwfvj? z3&~g3M9f;G9eM0OOy`TVo*wGw+;IhV851cPEL209bCB63P^p4b8iWgyTtG$lHyiU$ z`U6s<6jRm}vs1y52=-Bm8^*Ed+oFAB+z+)X>3w;Cm<&K-h2~{Uo=ME>ysuY&5BaPF zqucm*@3zxPE}q>qtVh{q>l zU`U52+Q1jlz|3fb9ofYPz|i`^(6+PWH*CBy!X<{|ROI zYr=zoLBq|6y?=dR+rc0)S9?4=0o3$b78Q(3Ot>21dgBCtj$XRFeF--0oj!f+coS{g zJbZXv3n?7G^n4Cx>z&?zw0;gY2rcz?h`0+EgezuzX+vo(Wsh}N3KDutc zBA6aDriGjTP74=zkZ1?maz~+gIG0;y6qHqv@ocL2q?U=|nzpaw#@vo8EJHiTpweHv zrFpfN>BsoLUb}E9FuiO`*NxE++0*0yRPOC7m-E22eO2n$;u#bzgsze-MLu3((YRyU z;oYxvq~=fyp%Phq_8BuKF@;N_XU{{;F@0Tf{-=rWS~l|T{ioLp;!NTGN3|^&Vol+` zB4;dk$@8k0VIX}tI>q|E5qf(eU)3sVk*$<9NyxSpm;fdv*{~#;%gC)u=Zlure5A&( zp$=3MW|5`rhVSoh zRgj1G8bn4KSnEgEhzoC&@zJ{maH^mg3~?jh&XDDa(9j3si^Rc0{N3P3$Hu2dM}($5 zZ*PU~^k<(r0^{;ee;DzN><%CUwu&`?XGnqyJR2?|BAvH4x7xzFE}Zh6Ohl4;HeJp14`ep{r`E<9#_uf5G_8AE>q7#@vTY^9O z21aw{;?q9Oz#g#-kAuC8y$ANmo6Nnfxnv%(JwqxRO&J|)73j))qI-*@w;2##2or1IT`UckQhF8#Znp0w) zPxw8954k03!lJcrk%7YBFjtI#CIgVWS$&oZcG4nBL3q+eH}dzXZHgS{>~Fhkv&^X26Hac#(9x@uP?67I zFr}z7VRtc=s1v1mqWQ6}0hR)gv@HPth%tj;^3ks!Fd$fL5Gl627hndMBPECZRay`I zYebqf2D&OX2%yOiNIjA+!iZJ{q{`nNCQBD_gThD!)8y$=`l)iH39zO3y{KmJ^2Q0L z60qitIalD~gqP0`hlywsX3${>VhUhtmDkH*|CBbli|`E-T3y>$R@~0B+}CnbicIb* zV06+fv?wuW)wVT%VO9e^AUj!^y+Qb`z??G{%6+n^Jz;CvUyPkX4Z0>mXY2{IH3LpX zrSy0srSv+hTmWV6N3umiAX4;og}d*k1^sAA!QG_>kv@l%BP{45zh=^;$)mpk0#dRk ze-MChv4==Cvxhg5PO{ej@}&$ zq=-(CLMUDoJNOA3Mq%EAP@XzLS|pkW`xubRUy}BVvN2H#9wY%^+vkXZm}BP&pwe+h zK=w(ak_i=e6w##=P-)zGqb&eYY0Fa<{2(kq-66+UX*!SzDVIV#z#S(#1t6<2zA<1y z^;f*{PrG~98xV1Iu&FoWa*HE&typ1g$btvN3Aotih=S;2Ke`htS(1XJNQYAh)pn@R zcNLT=uMwk>0B3ps2%|v&x|!p`k34Td5!OA~-(kCJ{1OP3$KU=qii~-t4g$tJIYIOS z#>$plAX|QAI?hOlCuv!7w&IQqx|YJ16u%rPe2_f=Xu8jlApIG{$Nwd*f&JAPoeldz zVRJWGYCvU23f%>JP9bQ(LJ&j*5Iy7wkBEl2^83k80Ir45xfLd;uX&>l0ARrTuYM)! zEJz!vhr(V;Uq4Thv?vm(@~r}H@)LbDG`1_Sk`xu_KIx~KdE?F?wp7~2|< zDv+L%EmuSm?GHFeI~uhR1;GIVJoUwQu(5*$j3q6pKyejHMf%dbO1mG@a>`rOG=Ymn zYc;}a-vXLr&ri^H8e;O}6j1jYvZVz;Sfs!)1r{pK*gIEsKA$rulWd^Xl#7PGFI-x*DSz7Gw6Zsfy3sP4sGo`855hAHZ+Y zFrW-lVtJm_ii6+sMIdRiXgX|1c^)@?DN9xmFX>{czMQ2@Z;iUj>Y1EJ;8gwI5$yP&jEFojV!`LBLpQ#}GSOz*xyr z2t-5Ln%17^(z$nl<2C2+ZXhv5Z5*3^fV-+T&56F0;)npUK^KxYR@>o;K2=x~-?2yM zOI}vkF+dkmIHSIXjy3_f0Isp4NfgfL+!F^~u=!H_3IFsZt_QO?Jt>$(a71~HR!cSmH|9_)gRHa zqPLHv52@Ga*qd(c;Sf>mcJVd29aZd2&-OHk3E+Krn+@AnYg^3iw(vne!TI0@H}K~6 z=%}~-*)=db#~{@x6v&Kw+q?Ex?3R8FdY;W_am#U{G()nqek1hfRdq_xAL5^coWSAI z=;t`7;(;1L!$Z5?BXfTI4HcaaVceaDLWl@}l=OniJrou_1VMgH2^yg{P+?8(!@SC` zsr_dZNC9Etn-bX3@>^TJF%TGl+f`sFB>X><43PriIb{q4+Jy)xcj% zr?|WfijVJ&y~O@_jsL5t>|uy-rit?5un6S4k3n}!OLgvvWI=vx_Sm*NlcZ%K(1L&X z+xPpJem5wF<0~A1jho+Bhz551m5|~NA(HVE8I5~BEZg72G=7Pq>{!VeWoUwsNq}l< zU*x6&cDel4z$Gqd4&b)!n+r+P&O)Bb)cohY!_!d#sQ=C}vOn6o37w3m_f;+Ro)Nnp zJ17?N(UQ)Mjyu9f2aT!ht~Vbp6r(b zTL)_faL@cO)2V)-|4P)?Tu8=9J<2Au`zfAVaf((*wMB2q}zg(g`Varju zS|_mAR|bIUH!iY&?$*^Z)HAWx*8^%XhVgaS>KR>~sz#oc6$Efro!;s24wdtT-91)= zzQhE7SN#0li0a~sxjMKs11&?}NmoV1*=l^aTj?sKEhq3c3Y+*?%G_1~8E2 z3mluQs%JOb>@(mN0tFu2z`N3lFcY+_rXR2y99P>p>5w&9gq5#op+5k8%6;(m&+H#i zGxar$+C(WHwZdn=de|=M>R5pE*OLQH*1kSp3Fe=F9)|ZDXw(102YceT{JCVTw{Iox zE|V&EgG-&&KnAa%eSI7rCe>(DX>ITH6_`W%0)|&sLAg)0&}`R(Py5py5(6`Ax_iYM zNH&dqLJMzz`aoyv+SrD6)KCVl^04J#0+`Z4w@U~8tnf$p=BNua*h&pIeKc8h1*Yjt>>08D)Q z%*4pr{f0NxSii!D{t%r>PMkixLc!=8WL4YdQ(G_E1rEb+N2R|_+Qwn}Cp6VlE-203 zXlA3aVwO4d&V2jzes2Dc>wBOdf$hJrX|$NJ zQC5aBXXwG&G21HvodaP0oAM(79e5a7CKxPLGmMuJQz1($6nXYs(~3TaZTJWW6ZIE( z4*=uHB<$l=dyJoYv6GSSe12DiT5evpXO1#z)Xj(D%t-K>Y`LE&`%1x(Br3|ev7`HS z@FdjA^i|u%`zP$W-)84CSgSl+3y0p3HPVF zwWhjEZ7;v~WvoEWL8oN8y_uJl?_pdUCypkNTBt>FVfW|RQteAj`fqZz*;BQsj+id9 zy6Jp-D`>;Bvxge5sN0L`jzImb8@W|qn!7-~xEDfv$%f4{pNFUlQQ~navch?r?-(;0 zcI};*IQKH(PZ$sKPKAHJFOAcQpy=k(2a}5~_%+T2F^?^2Yf_x1;MZA|?ZW>B^QIW3 zZ3Rz&YpQ|-rn*?+Ud^IWgi{mf?OE#WSy<~GZiWoBDg&*Fe$yL2IsmWvDsm4p`RW)9 z&ALlknWj86Hb`LtTBb=FW?-BPTRYJYW1?1bGuOBo_)LMl4;_DU8{;pi#;)dTt{3>8 zDw_Q}GL#Bf;hi5cwqc@Ya#R+)+03M@tP|Edmx<;M)NV@xcb1bDom}t?WmsDr4K7t5 zc|Xsx?HBztTQ6oH5hdTCT_laxS*>~-$nM}>8XK`jU&njp*kHKd9>^C%OB0bM0vb06 zcp;QV|C$S7`yTzPruOw81-}T78{2+n68S@R>}u}t%~);}|5@vJN6P?lB!;!~n&QwV3KeHY2;QA#@Cfsy>T!cF=Ktp4GnJ zXIW^gLyvo4RdKFSsjaS6ayB-~tLiQ0E!k0H3Kmov$}k_FL8_FBMkmWR1gg?5yk?@Q z)|Tk~tCXTs(?;?^(-<~ztWEGb&s&W@3ouACCAKoL>2uO4h0n(hwmAJ+v~ef~lsZC& zRVB4DaS>M?FXH(-6xCVxISb3md5E^Ux5BLU%PSqS_7M{d{#-@&$-nfc>eBhPPL%%A zgzS2noGjR?SPayQL#vuj zzvT*^Lrk-eJ|BP0sS&%@5+Bb?RY%L*YGiR?@VMQj6^8A3XB$0)3PS`F{T1~m9uZ*` zO(bEtTbB9yL@i0J$b(#Ut5BAD7HRnArQSHKQt`>-~rT%H7%`hW-r0+`hJUb5QfYzci5$`KV-3^TPO~6XsE z=X_t$(6STc#o-mQrvuviEGjRa6|Lwr=h^s9lIM!>2HKa|JuE6OoE5L=H5b|dC*yb! z?9k_x=aiQwev_66=zGQ-s83qt4)V&`**GN5la>k?dd45&gYl-Hy(VM zWX#p#ZRRPrw{h&`@#I<0o#VB&3*fPJn3}zFIB+Qeme-7gv-scW1BZF>CkUB_5|5P9%!l*9&ky z*BaEXd|#PYbu#so) zfk-X_&*cJG?KWgGJU5z$;&+hxE!AW+FNULN(R0NC*5n8e#Zr2%njQIqaGAgHZG=tp zfx@I#ZaHt^e30U;{iH3=w4G@6bN<0?F1uY%g}?4CEpRf6*K9_({JHADF}L2a=f`u| zfl;ojV^8rj8t9hL-qNrrX7Na(N7t-vbw|&>urfnWCEP_PHLGrEmj^OWYm%y7c@XK^B(!fXjlhz&1j*D7l*py$u-42tusU z!1|jFb}ktkz@@}~uy{N!4UIpA_D1v&11D4JW5bOolWg2f3Ro`v(VbH^-kvBJh-$wX zX$7U%>`{PiHMD$HH#c^lPDno-=_^ueYzy(@6a}9e><5@CW8w^SnX1<{TNY*i8t63D ztkZ)4I2pmG`5xVLZ1@DxzTI`kuCb$*9)3$kWA};K)MXLA-POjIag~-I7Z73WKIIp- z!L|tn^HRBGZZ`hLeU3*kRg(GSLbaz!J#=PWf8I_H-ao_FnrsEeu4?cAryT{=>R@{YH)@7fn zZQ{sZ*3TluaA_>2x}c+$*jC*2TYk$XU@yig^V8M=)ELGDyP8+gp3n)DcuF+>x9M%-PZ8{?zO6U-AZtqlfNSGTX6(MDKj4ydpB0B0 z5-Y#qKh`C#9Xlq!p_J~MqR*%+d&8!?L2H?zk2h-c11zdRTSe`k#dwLV!CFP*&z#|# zQGvyq0@fKbqH&OM2DsMV)Zu#I` zZ(Ohwie@e|est$$_{P~`tE7Olm@jo3Wotlt-J1SwpcYGKz~#bNV68s=qD*J&`B;}! z4Z$gmf4$yDfo1qI=4h9azi*t%`IwYF{gqF( zok;4}w|{>^U%?*0^9YfT4*$Nd0lfxT|MN=LHU+nJKc?Gc1U{POyODg1>ScP|EN~Nw zs?c?|d>{1rC-1^swenZ3`B`iXGVc?fqq-co4b9D&!8nHGYu?_cJj0|FkMm&h;W-oz z?i9GuN1;rVw2H9wBl-SMB>^N~wVgytySf!UPr*4>KNaV}>c7rOkWPLm`p7^wjeFjH8AMtz)Y6@{KM%==3<`?78+y*3239{|K zkELJ0=0Bjf1f?TdXp``LUPi(&w|hgQiZD6fUFM({j_F69@KrwF(l5htJNd{SYZ*y* z`l1BoKr>7yxNU*z?3`xkq?OJ(jug%L6BvTgSN2?JQ`Te8(T3xO90CBlcHa2sUok{o ziQeCb`xm&uO8FJOy!YP}gyQ_Q+73QJL1gwC*d;Xd`PPsA(IbOj!V>Wri~i^qQ>##7 z*_d89jH>D$CH2AQUL<1DcR&MGgUTipGiUw~tMxb12*=ZOBmIQHyf3!y1*~xokkqxY znbzX$L<`aAA_9kydUb&ht92G>@;`3`OZObsn5@7{x~aMzP&0*8&LRD?dYZPTAE}&E z8fJxP4vGTTbaayy7Z&nGKfvvWF7%O>U8jsGs2@Hi5Ydt zncbWtJc{yOB63?0SudMiRt}*T6~&15J~(na^^heBB_IB=Lb+YgA88QIrc=dw01uYU z-puDGc^a9-uuwYI;f)>#zhuH_|3g_t%tv%_ZpYZ!lb9|&mDcI=2K|}iy^U%MvfG*hKx1mYz!k4jvoVg z*a$YJ-|vr%Az5r{Rbms&>)E5kt=Xf90I5RDz0DpCsjJ$hOmm&83TY=x78L zXi!oBXaq&gJT}y+rNET9BkBZbX+3*fs!oMs+!+&M>lpG`{m>)E1eqAq*}f6u68XXC zBi01G7;XC+$-5L;w4!<*U78n#Vyqc6Vn-|j1uGcKP@d0J@QPL_)GEYASjV%=QNNOh zTVf<;m%|8I5(;9dW|tEPnG(8VEN0trIE{&4v1m%%*{QXN5r9}UrPq{}={)E(vP!#% zmhn8fSXQO(#GI=OmG8ZbBXSC$P+k$5gCr%^5$R^+U*G_FE3caeUs2^Q__Sr|ix4YFk-&nxAD zVzXG0axPJf|19a(Z1&0R7`RzdP`h-l6(&ll0C}T)ZW?A>sQ{V=+axIj+x~--BJYWB zS;=#YDQZ6@%aUfpY1zSZNU1CDNnWIxn?rmVEt1XEi7~Wa zq&_JzNYZDWq?7LES)w8?@n6M#Cd*@%6mL=8yLbxeP3b3_A!M^bk$&AgW;7d=lYAhd(r0w{ES^pJ z4Tj02n6A=i#%ntJ5DBnB?jb0!M3VZ&I#|HBna@8h$o~FD5>u8$Jv2MutD^8!2<0X5s!70)EaoNuKF+TgO!RHAoF0Wmqv@1jU@j2ny z2$Z&v-C>;Y%C{7+d5!m#Bb=v3-C8_pjd#Itb>5-~e+o7Sy+P|1AFri=b!s)yB-oc< z3qXhFdOJyOR^>enU0UR8^Y$=nYsZvl$9Lpwsb24Q|&>p=@7F37G>AwcOMWUAM$NxYqK{zP_fOZolunxp6$B@u&aA5&lgJLw?3Z zKz`DMMtUQ7=hUx*E)i3AL4iQH@*lQVDSkPB@qC+%K2C9!XHe4Dunn*MPm zIj!l}cxc1_$5RYEf2-oxaX5XYSfAonw}kE2vXpRTSkHYGP~Y1JBw=K{vQcCMXEb4L zsCHm%C_EExoICdgcE9$&b{`HPbk|2?1X6@01@xj(Jic=WrRE|RmSy(YR{q((ou}W5 zo3Gy*pa0kI`r;M2`9OqZcAo>MaE2(N@U-dkLa_~Hm9(O^xZ9o$9RnXO680DQ-#9GH zKe(7tI~%#YmC6xA;5TuP?aL(}1!MnZq6ZeP#P_zaBh8J&Gmj=O0S*1B+w{J#$j_eY zR2pY2fkgiVeSip?G~Dd{vTdJ8H(<1hT&Hzy6_$$vi6@Sq28K zLp9p*_lFd5jx;gnf$*Sr;bK0UM)>WrAnwx2e>NSS*~gRTp6Zw1)ye(>hKCzIRd)hI z-Nv__p^(67Xv;jry&=SL+Wecbv>7?VATYvhKKcjc{K_(CiAgs9DcwdQU8ZvPQ(O)b zIszg3LyN`MCD0xr(F30R2`;a~A8QbFU3P5#f9JPrhBd-$`r{dF5hw_y#Z z>mqTb(%&kaq7bDQM57}sQctn|#b-pLL(gBFJq<>*gCB&vwqBhz9~46VZ;wq;gBX6S z!Tt6L4P1@N4sl<)dOOcsIlNZoakc-6&NGp+yc(*74-SyKq} z2LFBtlfG)@kvj)1RB>0WZqL~yAg4SR3_5fDqtdo<fYfHT6=Nldbi3dUR8Sfqqp2W)$k`SEG2ZtebLY4&WR^Y1S#%) z{Cn|Y#N-`L=Tl*LtlAAh;g?Mw;5CS_oBvB*_fpy9#Bws)yTz}G!k?38s5#HY$vM4F zc^yW-;0v9Q3IuTKXULaxYZ-~2D1UZX*c9r9n<)X`?cYN_8y+UPwl*>TBYN=uLp>WF z8}mr8{XpQ}$X2A)%qt=#5_cltWHul3y-4smF8BFVW)j(8{wY~z-{85kLdGxd`1o9U z{i$7tqvBAZI=g@GTQ@$!Dt}@?i~x~fuGUxbC)IcIxlyL(gGw#^+eXLS-&hofa1Xx; z9Zf8Otali?ajT1)D^>5ho2~bSSjNCED`@-`7(JJ&_qhAC^mr>h-+*MUZhmM%_?5wb zQenpmCX!T;92toMQGU8;zhzvbLFDEs3dlqGUfqHDk{jnH zV}vd>Nz1Wz2WJ8-6RCq&tH^mEME0pI?%%n-zSiGlUtRF+sdJT#is)^b=c`~t;)%|w zZeY{V&szQNN%vF8R`R!iyWf`Iz~!HUt4|M@Cp1J(no+s&o$z$UmO)9kmnI$@=Y8!|%hz$`T~-s% zUx?wPu?r~vNe5gd?xN{l@LBzwsfkl03QQ_E)O{VkyZ0?df3Z1_jF?+oZBku)!C5Sw zHlL1dP3t-lJy6@INliFr9j*0rof#c5Og;a0s@5Y(AUdQKkOwRuSgnoahS_z!^apHPhxN z5k5IvREJgrl4nr~Q@d?-c(rK zGZ6r)b|DXlW9HxEZ8Cg)&|UR2x3H>~6h~yR>lVOJhyeiz?*Fj-{UoLcW{72D8K0P% zntF5ZhRXhKPbGJBdKfs%CCU05oFG)8|(XLdF~8;Ofu~E%`=30%Z;6MNlz1p z$(BZ)dr|oaEt5Tr02J@08LWKo)lQ{-NKk2!xEePAk&OKPeB^Z4MU`%Kd*!_F*48vw zKlkxuREcl;9r1iKqWJ8)H0553&J-+L(U%5m_5O(_i>it@uCmh{`~>>{&XV`^tzz&) z7zpS8v*GFguv-&+KB%l>W@JE=Ank>jLV>PPmrN9BDsg#g6ov>DNx%(iEPzTL7dkbX z4%a=+X}~fyp^F5djfCM~W zT9+@y3g&1%@B72YMt1oE+@1&S7yFS(6u{J&gUVnwP35#=0^jru7od~RuW zLg7Y#StTbYd3Z%yc%guQI=0Q{BW?lx-jSKM0nSo!zOh|{;rcjg;{ZB>glo6 znl|?|RrYiyf*iADhk;KHcfJqsr0nK{%HLwEKGJMSnDpkgp{k~!usF0bnRVM3$msCG<5_4B)l}3}n`vq2ByrLkgnFyA+>ckEI#zM; z6NeY`m^+_Wy~Muc>a-BvTh6l$pWl`PL7gt@OSh-lw&iPI@yr7i%YswMzSu@-6%z4s7 z6x9G4<6LfCyN8Xp#WMkk;E&LR{W%1G&b8@!oe(J z{h`i-jrJO-JG?C5ZO4_tC{M{FO4?q*M~I#e7jA-HkB_MLVBgwKR1_N#Fj&j)V}*m- ziN4n<6q@UA*dRn`f=V1Y33F)snMw z9Sx>RJiJbsYM)^O$GqL|(H#@5{+~z#GX#qhq_e4cQLw~yR@mrE#5@Hy@!!3FZpa)C zy3-3$gtJkKJ;1zE!EOWU@^n~9wukXM5Z^nuvQdEp^$3%P4475F-)(c+DYm~4ezzn> z`v<&ZK#xIGMAY}wLXO5)-&N-r6gnL+%95bvK{b7t3pp6Q*T zxkxzeS{XJI49?-QRmqLBkU}Jr*+1KnPx8SPl{+;Vq2^Z8e72b=9^nag>jb?^{buL2 zqsjp0<#HT4jb)Mi6lWkQDp{7W&E@95?(dHM-8J@o?#N3^_~B>wsx6u!pxWB%^FkKK zB$;;Qh=+va<1IXE8TW+AvZ6&U-xFJ+HG<@IK={~^Hb%?u1o(AnJ{n_C&OXvlQN*TuH&a+4@(G2EG#NbYZSsWl z!?%j!gR!vP!6}MKx4=HiLLyFbz9YzG#}eamrtzc8r3RLk_y))kw` zlmA4@w#^6RWvT)!i<+s&N#jh?9hBaH8bB3awR*x6_5NY2LXP}FTM1#=5}OQ>L9cC& z7!1DHr0Obphh#GGHP6C96c7Kq0=Nq=M}{DOby(~R;0TI}Ed zfWRQyHY9_xONgcc1p-Mh)Of~mrEd8TzT z9sP0y3Mn%$p5r=J)`tEGPSc8)7@xB;h!{8*Xtt{|pRtNPR-9$1hkpI`CJf4+u}O+8+alj+=lvfTKT_?q$qb;n{cQ z%(dR#mN%D(PmZl_N=KI*W>M`&ZRl->GYt~s&Bkg|Z$5LA9zA^Ml6s-&5gL!`l<_WD zDr48}D!~yKouioRF9emvWpNgGfZO5Ov*yigf3K<_*EXYy8X@P_$On1R)_b@+H~qd# z@2`F)B_v#oc?q{90{Vlv!mSXO;Mh*kyxImzc~E``hM#sob)h2!2)4|ykl|XXD<0R4 zG~Inuk+2zU$-pB(=qeY=6bS29x6M-+hw56oZdLteJyK8E;OS0Cu5`ogH?jvNXjG%` zNuYUxc5&yV97fOQYtOI{c2Oyp)l{J`%AY4*bNS6f%(_g13iLA*_vcBUvWDA|3|EEz zbZ(vfBq&NTlhh@=HfX}u6Ei9_ZxZ)3Qinx~_hec&y9+)@E@>t}O;T!ec2c-;(c;>j z(}hi7d-qCp%oGTgf^KmnJfhvYluVp9LhDICX>ooYVjX>GBjU+G2o+riu`n;z7gyh z^=!9k)Gf;nW7gLXrv0(UEYh-mBuotf&Hvd3K@oeZICtg()nT^4@M#I z`j$|{t5fr^fiwPW*yovw=*u1Ut|ynRkw|Sk$toLJgz(;h$G#)1&|*Uuj$?fXQs6Wo zXpKJTXUB6jj922+qP}np4hf+oq6|vf9LG;?r+soPgVccU0vN>tEzk5ef8BQX7@h? z7q1r1rL=)JPjEh=K*C&1K`uGXH$CZFOzx+eq{uci&_9U+nqt0XW#Lwl=liaR9ru5r^E!^`?n|8DWX1HUOf8yyAQV7pWQ~xf(d`Uxn|r7 zTodG4aPdEypP%cbU!KE`u2W1DM1K`+3<9z5(O)p#4s3mJRwT9U7d9&NdaHi zQFFhlcI*NymziH-qQDk>SG66$S}P}x&x1gWSbz*|WwT{NUMmytve;CDOH|{6EkU_UtT`Qcez4>lTfW5D#fiphoeKVj?(QuDroP~*jGc@pVir{8N?VHoOOK( zL^7a3ur7TUq))FsKrtZWZlAm6yZ@~%3)-DDIj#ZxYj{nXUAMfbdnx)u0%3&4l8(3N zD7b7F5U%`j2fSm61g-LUcI!Wzml1wJr8eWJ;60BH>WhmYH>G7;e9l8E6G?2Fuh2-! zVznw!p1008z3e$OKh;iHPXFaXO-mo>0#3xXq;NM6Nbz$iwHE7fRxDX5ROph!yLK!m zUY`N3p&dsJRsTVq>S@{MjC`>tfIV_9BCh9e8Z(JWs`k;c2U+dUrMH`iPWg%7`1|s@ zgt>7*0j=-w_*X&Skj4-2W+Ae4e`^xl&?3TiRkpbbRv4n`Q1Bl8bOK(oy^xG))_KR! zwJNwziAwa+ad5wJ+*}Oix$l@JJ(iq(jvGus7xQsrtv3NyxnwQxjD_bg1-D@7O0Frl z%yC3OK7Al-%eniXq#)0O#B@vEDRtYVImgnwC?~s zBDw@GBzt82-__BYZ60FSL5WtdA3i&GUodU`4@x1fJ;wLa^p5%#x%YrLXx1DZI`Uswv z2|YvFoBl@BJ`b5cTZMkn4lhEmQ;8U4k`i`QI5aSh|Yn#~T(SVxqd8xn=7Ax19c7HAPAnJd%Krg9YRyOP102;%9 zb;|C-<5%ojTfTarTq1w_0mVGUgQR6NtzW=p1Ohsqj?db?~8X$4P4| zflyQ=aCl5iR6nesulm%VGl2m7%nLd9?57cOU*eqXwJ~tca|M?v734TvO ze(!X{L6w^w?BgTU4f274@)|$$M1IW@nBk}>bvyXV+B14bdgf90kRitcqF=IOmUkt6 zjFGEv-JAG_)~f^cLs{vyp00(NdjUV&|5L{bfIqo3{ap=6lz4VTTn@y}tjZ2QfsJer zpuVq)(ryc!3-UEeK>S|I2TQ~Mo--yjLP5eYt^b7E$q7SHi$Umm|q4| z*#^5_{{C@Upn6-_9V%abf=j%i<^Q13Y%Kb6+8uRT`5<+Z&jf;iEfidWoM!f8|RH6gEm{#F9I5rVbxhP(hcxk+g`N5lBtx@e3w zUc~l~6+!#XtV$QY-1fN59a=#oyFLc|vW^)wPjumi&J$B;fKn)~jP!n9!!BI0?cQj^ zh~jBu42Gtm3#f;(p62Q5mRwBnc+%hJ=&(WOzR>X|vq1-tMlabvxag|`07BB!OOFpW zsnF}mjSr$Zn*g!tn-KPQi-qlPQX6#6B@T8U8gz7Iv!(q3veXE6MWUZzx>iK`(TZGY zFuwu1dYS?oHFeJxZ6+L zr;)>T=;u%TR}$PCZF}jzx{+6y^ACoa$17i9FUVrC86e5)z%>&0f~XhM9h@iQ6feCrox^qmH8TUr=mi$&Vo$thWX6w|q z`+g_sUEnTj=SeVQax|iDR8RaT#LS`56Ge;sj^D-r?8^-2(+200f&JY|>+$N3J{?WlP~FXo$5gw8NY?qG?HG^9 zRodf++p?RUz(;n|=~K28G{)e^eRWHyIm(eW_UPWRF~0nryO3Y$L~}Fi7JK50r&CcV z4^T2Pyfs#38-;9cN*|* zrr895LU_=+;Az{OwFE*t^-fzLH}JB52!=gLF)NY<+v$Fy!aMFkt$NGK9WI~824H5p zyAO!0Y~*N4Vp;iqNTH0+YOR6e6w3{!1Y8-&7{s@-yE5puvXM8_~2iRyXdBTiM8gkB9WzwMmQgJ$kU2@>PCCK!PB| zqM4J7eEAunwB9&j(_hK)?qCD4p%W&g@**&KJ33j$lH0;R{YflY-B{(PrWT7FpW^Ry zqC8T)%nhn|DC#SCNjUPe@3Qi-URS1-$LbyHZ*QG4Al$jJzrP%^3~T-#dX$+Oop9Lj zzHe-kbaE(x<2!(D20uR87H(Eum5>S z9K8ji4{z_J$U7z@8OEH_LX&+vhB^q;88Y8)W0Fw|v!Q=koeC=0p#riM}BdA``xxl;5L8w(ldwE3m(b14Jo;gc< zdW20sZ6C%}5$6;epK8yT1w1^}Wp(ShHmG8cG%XE)!%anNKMq)jWfioAqqHQM(Yrhr zc3?@R5QXNLfwT?M*MsSPr{a!XnnC3!Ag|9tzx%E-?UQkXZn>v++WSnl9{Y=3+Xl(z zK#cUFWS?^4=+5MhJ~vAdr91s#fYpSk7HT_sIP2Eii0lf)Hb3XplzN zIsAR>YXR|Gyg_He3{OoR%0UJEwGC}VfD)VMl(1U7bKfiC8$@frwM|50iC}Zab^1%` zRM9b^8}(`x=N9T8JMb>u{_r%yUfY}A+l17bEQjB-=C#f5%&9ds{cZ#w2CTs@)yK)&X^w{GY3DZPr zQy9H+{VKjk&{4a%PqQx_p{p;3luj%Ujs&_vM@P?d&Mf*u?d~+*-=~A0nYnw`j-k46 zEk@ZrQ>zP>Ja{@s)n|CzKhxbvF?%7JkN`dDKQ%3<<12n4iUAdvw3}Behc6bZw|RC2 z_rPy)LEBN}nTE!ic7 zkWwoEzK*z*bf9EYw%vTsclK*J7HQj>qrqEJZ|wG^+HAK}ths!^8vR&!b&I~z>^DF$ z*O^X7u#}Pc_qUf#@B#-gi=EW|H9VbPtJetNH^`IIu<6-++r>Yfd;~ay>tE6)H5GlY zKmB{R(3Iio^grj0_ZQh)Ho@5iQEYL}KxzIa%9$e@F9H!mYQ@-}_ze*9yP8Hq zq`E%I7x?w;AGt_j?k#UW&A&=&P7y{!#W}zy+x77t&b@(Bd_x0+6?L%0e#+Lhllml=+ zlCBDxpXpy?t`3<16i0V_yn$B-^)LKYdwc+VU?Ruu$NC_GeL(jR57U>44`zP!b+bDI zkn`n-yGO*B_B22@##{Y z7Y`Q!pg7;qmMX-{_Xpyv>f5LJ>X)}u8z0G!NMH{CAp!ULdmKr+zANf=G+y9)SbhL- zS7V@>yKF{pQoxDz&MFGzYrQrWxbxSUqT5+#u-kEc#EvuTkOPmw;GOL=({)5Y042~Y zg3GvJf|;@Z2IUjy3$N?`iB-Q{2jceQLajV1DNjp?8pfkp!{{nM;|1c2fNOy^0DH~MGj7_IO_{8E}X#Ew`qE`R%iul3Jn=QP%=1kt@lOt^~p+)Utipe(;o zxK76biDe4!8>Bmx%FqM}>vyjCU{+-`x3=fh6X=C2q+5F|>>(trvAv?dM>oXh%_YLF z89v=CTXF^$BV~#Z4nGAu*#8XjeL;~w90f?H%J3wa5GQ$4Cd0iWDRISHl4ng{1Aol& zrAa;M{`t`MY`YHwL8MU|n}AvH25w_mz+TbJ4vTX|VVTnAM9g0kuS^PA%?6IXlj^6X z+~TTe$~c%=6!TA`KhQ*r_A-u2r%?~9MKYf>5Gdr^$iO&vKw&crR+e%Wh8{XEo2nqE zofEToA>*=9WeId<{?_qL2w&x>9nj0z{s7hi(d#3qaoLAAO++>wi+T{D7fad~1jl=+S(O!9R>X{*E~( z&6q22J$%njAWHqf#Dh9UTIgQqcr7_LT7SbUYjTTxuzQz~z9guNb91gr(jt!q@W&o) zE>i?BWJQ+ZU{xZS(vBoUJ1Yj1qaD zNT9P7D1k;Gw_tyLICkb?GyS&gii{fKt-=w?go_!`(a_6Rdb@zhKXrs9sMXqGhF zgSo>Hbr&)=SodPIejS>Y@v7~Y&P`BO!I^h!y(geDpGIu3^5EH%0e?$7TUk(JtLY6j zyd9g6#ZB`XV*EC_#TGmGeFK$HPOjuTMpm6BGN;0iRt~0BNv<4!I}1Otl>>0Dr=C^P zwYHt+@8Nl1OG5?lsKSMzJA7*{so#dfOOW0;wQk68X5rn1-tZjj+5s!l!s=IPWIr^( zxwD5wQQMo>;tbCa2PzhsNSTPx(Q6$knd~c(iHK8CcxZe@hwkQ=oX-;eicCHkUQ``8 z*p}cdz2>V_yC@oU>K9i1z)<%sOf2bDy`Kf26=-6C;7V;zMOypM+AeW91h6ymaE z56}{$DCdHDszrO9iZy)Fo5PgSDCcLpwp6Kz@=R0zLB z=uLHbsoE2v1UN~>adMgwKt^67UoL%(+Nb>k(dWAj(shRLfb3M>hvk`672klivG2HL zxHKZJ;%*-duQ)yKu}$k#vEk&d_|L%{uy-XX(*eJ~E3?V6g8RZ$4KroIk>kgX#dh-{ck-UYGJ ztQT~iB7gYcsCK46Iy>JTYvxP8Elhp0DiMGyE#x<~Hgn3!uXy7Gy z1OB65(2zID(j)`{0m}bdrICCy14WhBE{~O);A^jT(2jcx3Wd~#Z8$E>*{~KvU{4dlRMfvY2!r1?Xg5z=iM^t@J zBHMo#|LI8bFKlp}dhQgk{}J-HH-z<`Y5!^zVf{=7$-kqRv;Wm7!uq&e%zsB6=Og|b zu@|BJ8-;VO+5t0?i9A(-`aBWh7eSyqX(mB zNUcrihMAccr4KuP*r*BTgUtQWG|HBW91A;irau9ujAP?xS7ghqPNCzHoMqHrOxPQq z-aA{qJD)1;P81qHhRH&Ja?k!TmgI&_okzr$HUl4Kl7kvl>WEIKG~W&ix~Uck9g0?Kdnk4D2)La^UP6GMKetqRUQuMZtlBn4d}HHn z;P+}v8O^AztS~x^-jYb?8m_A+;>|NC88BcKN6troVlB%N!P|`}inLyI&2utkl}4ys z4n{KA|A|&&L1AZtA@=tesgPM9ZUN(xsOS!G;gFE3L6%4C^^}Sv*-;c2;H7F(ytCg^ z#HyCvkOk`4Kx9|R8DYeo)f4a69i#F&XR6v}OBFq2>hB(=+QuI{VLb7jge6O#l0IE? zxR^Tx3U00Z#k0)Z<=%qEx5+kI+h{y0?^Q|_Gb>NeQo7^ERjLngYWjqbI zp^l(G3GaaIYTc#L2df? zSVVed7-2GBhSk)Ul1g*s)-VeiQ>H$k-hctL>VU!`$x7}rSvz~lPpY4X3)=axV;fB4 zh}zg~e2^YaoqBnC5axqu5h3I(+)1$q9)@T`FyBv(Xp>Pqyjp!sCWB(;>{~oJtSqp? z=rLf*x*~5o(O2)dxeMHa=E6;1Er}_-rTdL-hWyjZ*-b+M~G)IDdEn3n^H}@soT@^Wtf^EuFMJPN~3e_*_TgbREaCq4s3o z2}7FQCzd>CZiMX#v{V~TM0u_xA~Ep3996L5*Ak98Cju8Vp=eTF6a#OR-)TddJ-*6P z7jK;2{YFFMl^Q?|N_q|X?8^6|kuW0r@^pMk20JtJd6JYlDDQUW3s>k*BtMTG zJ_CMBq>m=9LO6-}{u8{98_Ky{-UVRnVn9e#3hlCZzdkpj& zdnd&68i@hKS6~y*G6xElUVpyZ9?$oIZEAcJ#7JlnidHb!8ygNF=mXOpU%+hjZxLN_ z{uumd9uH&*IOsT-=HXycHEna3km>i26x(lt=7PA3yd(Mi`%JzSHWWW{4J8Q?khW&f z?zeiMC-6v37wt1hDAXL79X-*^f}U%_PS|u>aIRvVIj>W+oM3jIw{3I)5MGzR)G8x+ zn}aZnMfZ`D;ggbp*ltUA(JUm4(PI23q)q}?^$^eAkp1q+(c7FZ53u62yj7f`?GoN{ zNsPt!B=UW7{+`ILU}1R4{bbpAwOfa4;hzB%TEK~%$gpDiVn;N04FjjanSFzB)rf%w+iT=YCp+rqF9UwRmy8x*Cz)j{Gm558|Llg;1>m>s zt(%KUrjDDDoS3!J_==0835H$-ho_dC#pa|VSX3=*_OISZWpF64j2=neNGjwEp*oqj zBY@|$M_jn-#NbD3+@CbWAqcZfXNH6Xh8x&++6JAyOxg5-N<))Eu@f)9qA| zomjBNwTQiOzj(V8#5=tga2SF5rwjXl+fkp&p$p*PQ`x%K)5)U?U{u&c5s&bv7eK+j zt2Kkaa2DxST z)1`(OSe^JC=B>By8OcWniS`_#JuorSe-J{TPo8yt^xWjLt4^>+e^(s`{H?Kjd^$O* zgAS-Y+;s2CAf=W(+_v=8t_yXn>eDTTtY7W4{{8rq0|(bF?LGN8y9$(TsoHY4*;e+x zayN5?Kog~+)2)#Iv(Ic%tdV(>QdtZb$^6=B59coL-F+o_>Hqa#R`akqN%BgNARy=e zKdbqF1h#)wxBvA?CQ0{3uDoSDmO?B#G3RwYK@TqBTnf!)k*ahiIPOl*?p_kU(#7BDU(h1w7~a zfbldxc`_Bt7fjNGK8gTbwO_SwbzW`0nbLne-M51z?GZ3bkxnqX!m)xkJq-qd0c#7= zMjMV#h!!BN|3nD#ZKB9MoH6qvmo=61Ec{fGg#+h)ZL(q#7E28{DPqrsNOQx{;w~gd zK`8Z>loe|YSQ+%?VPos!%4DSFxngq__T-)Era;7oFWz0f{6pAj(I@A}feHO!y*@vW z4lfzghfE%HuQH^dES8)$VOa<(0gO|y&~gcC_nR@zHFQUzQx$LELbcJONx;XULxvOU zC(0#SfzGvnYKB+~$P2qkBiCLPKI7(D?boiX^zpJ%HgmTrKQV~BXrNifI=7C5T-a+; z*Q}kL?Vx6K*1}o0UbHf7?6x6kCZ4B}6*yg1=`JUH zxD{HkC?Ri2TV%q__aW&*D7=KkEmbP4B`>tE(l>F#SW$qIOB{zOQ7Xnh*&$wK*XfvX zkmAjWC(WmbTN}9EB56bS$>jBU1ef;GEkFS?9@=E(l0^rS{Iab5_+dtOoR>YV`2Uz@z=yX8;3=Q1A z+J1vvfkUFC^rVZ6P^~2Vr=TJRg1R4X4%P*&A(XV0rCsM?N64@Eh?0QzD(xxgwwhF| zyyibOY=@*3Euzu6k&B~a%fvgI+6QBvIZuspKt|n!%rSH*$mroC&q~JL%lc8G`3tpxq9UsVkU8}>-u_23*_98BW>w`E2+tO z3}TDuCv;HEZiKy4^OylO)V^I2ek>5zk76_&bq}t9}vf4X? ziyG~!Lvm10>ngvP2V^FV0^%iYe#(l$F8oPz8*VTl$t@nci2(+Xl>tYr0YFoQY4W|# z1lwnbh0HXdguIoH|KO$mc{I}8)$_F>20nWIaV%JwYr)~4uvBrTFLDGwbs;}dF~3?o zoOuH;L)G)$#EME)IMu$3CKA0fp_y2=p!%Sbu``i`*jo9%gbdx5e$CPWWp}ZmIowDi zMO5DKY2@L1bRgDWuO=7-m^NwWW1sKYLuMk0=Vr2}npLuNLjxVi3oW9quZ_n2RN+=+ zdOgz2dd9ucnrikS5Lk5}wOlpdi1j)ms>hzk*!&xgb#u4T0FlYQ=Kg|oP5oFK(w2Qy zEX)@;!&Wit-e-eE9rSx_>~nDI+=bbS*FWG{J|uM`d4Q|y9jp4ZBpe-|wsoGL*)z&< zzpmt{gu+bB(Stv0ebL6NrU&hXBlz3tam@%P{9tMg@@copJCujbvd*+ zq4(sFVC;rb0Z96WTWF$&NZ4%)fqze`SwMT$Q>9A`H8x<7XsAWSPy9Yxt*+IZRSR7R z?&S1$Vg^nfS}vrKPzkeKox3??am3|T&$(*%7$OIR%XK0F|#d_=`#oP%zTpJkAgKv4G7ks`?dtfQ+DIM?=WcU|gz)w0mRW2XXvRjv3jOT8|=k5f? zd<_vUPJ`zzKeryPSF5Bs>gp7vt8l6>?eE?FSHMw^;%DgN<7CFGqLjE@g3yK@?I?lz zx6U=omkG=coATkp-dePo`jZs$*Fg2~Gfs?9zLdc{s)H}67)4NmGDRrSj)iarB$+%w zx^z_@?+O{r8x_3=^??Pw2lv66?k!$Ix$bQ+<;F>znL^h%*_NzFk@TZ-))CcAfYcuR7%unHH!-V~;BUBp5PWJw=nAtPi_PVFx zFtPq*z)v9v;B>hwKi->IX9on#I*(&VYFHS0%ChfjTcWA0rD$7EoW8aptqX+ZJliw^ z`}3d8Hv^-$e-a4P8_IZRoXqLimf>+M0L{gNPfSVpP1`k1$9@(b6yAa1yRU)Lvm_&v zrx>QL{6cO*4>YHPkEMp5nM}|?jC8H33%QsI>bt;F=d44Cny{uWx{}Ws{sFzLLylPT zR0)={L644ti|##j_(Lna(a|>Qr9m9#Nnm$X|ML85_;=@5yJzsa+dDDCkEAoKJwio)_D^MD6WtJWBXSx2*y~N z7IJ|h$ya1L9$<^XZ+a|o`SXyp^}uDr;%j3l5%2lvU8mic!D@{YHg%B-ewvb3W%noz zInpogLvZGFs&83lmEApl-m$(N1N^)_T|6U%@GjG*Er^`=agPTsvK0sUpq-|D~ zpGf!6C!~6j`$q3awSN7cXuF+9^c_QzH{3>^{`#@OwfJ^*#R&C$(QUi)8JuiY1O_0L z>zas1o)*j)QM+eGyE-;cvYL3&`#3M5+iZEm%xS$Eu_;y7R(h#uzZ_`U4*Sr6i%|RGg7(eUB4>` zz%q$Bs=)2X0J65tO>xpPPgr*JE_2|dkmvVJ&#meJQn`|$fk~Hj2xPfkj{BXrZ*b?b zf9Pasw`mfG1Qy76GDOG#{blSBMJvYu0tHel!^hjHiT6S zj~^w0l`$Qf2nTO#F{rI{t(MZV5!7zu$b(bS`YviyxwyDtiP8R!VtWsG>ghjpxqsRiU!Tx$6k`^v)ZTAu#oSL$i7v;nTN|7%OdwB_&ihA=V zu?jOeN%P{{9CJi!F!v!5tYe#A!fqg!g#;OHpr!M;VH+s>H?t#$r?_D2434j|ww&$h zihO}OdpC~qMt_e zTTUkzBGa1Kl&H}5&`mPj#IAz+{mW%SL=NP8%8_txP#;SeFwclTEGQD;NZRB^L@5ia z1ObLkhdGg=nytC|#-KLng+vECUooEt)h4$`Oc=N<5i;dNyHI1fETQP978V!gtSI7+ zI=E}92=Iz+r7%E^WG3h#MwQNEKv@{FYO0|7{avFfAJs&L3Yw|n=6shGxt?8!{O=70 zGWlHdM$0c{K&Hgb9g%#C`yiqmqiC7@#5Y5qDIwCq+~2l9r4&kX0}5$a_WR<%mHq} zGtv!O!4)l1!>~Frkq^t;{l%;k(pMFOjIu)%rTIweK+8Y!d{Yw^<(&~ID+%Xi*r^hj6x9K-KdAE<)qg|Bg6Eb2emIZPZ>P1$C z@k2gtKpQI;7t>zZxjb#{!Y#QtDa%;!H*!28sC`mCC!VUfKV?m?0a7}IM{OLtN!f5NR8eJ#1i&KS6w2qU zu7o&UMxmHtgiY_>@dKiu*oUg47`D}BvTu+C42&kGEHgu$>+g}5t*+|Mx_5CF-N51q2%EKQ3;QUluS=9EgQf<$p_X225Br1I3NuC5BQtbO?u~2>MQ8*V#Zkoxb1*D)gSQoNah>G8(fCe z%P$mA&steWGwae+jMo2|n|MDdMXI%)1^OdDA>!Zc7{Fo3?duF9+>qG*nz$~9)xy|O zZLI-_XU13BV)aDdC=>Yf-4cK86iF}S=-$zkyuqTuYlDdLG=W5ySX=XQ@t1bLA_u}lq63gq|g@jhQ$0kdXU zl-Pd{JE#mZy$8KTpU>Ww)D-uYb{Vde;SXN{o-2c-i{EQP?h7&?iw-po+7Y>O_eirA z8T-{dbSuX5lvqT=sSxI_sfg}rx42kXiO{o_ZoGEbb;*t-3Oe~*CG}Vx1`c$sIbT|e zHRUz*>oV7OOk-7sVcAh_u@bS+foVaHcdEVXH$#v4ih^wiUkhqV`Bpak)o1SC?aa+3 z>XnV__SRkL&jH9v6G8SuKD}jQ%aB_d(-d7DwXMJ0PSH+0PmMjVaGw-xM)%D|VB69Q zY3)=q13idGdm#0{&-O0-&5DCSXzhA;8W?$t_-K#Hf8m(7f;ck#qH7`i0y?@M`6jCq zbgNz~?-dvCQ@%&vlEZ-Nbz0h!7u}R;!#s20-Qrxq>g4d7Q7gBerfR-Vxyc^A;ciY2 z1~$cupRD#z@5a3ofu~Ca$871iBE$S({NO~lnbdVe#Sl<+1%nAvP`ZF`gJ@l>wAT?K z1w<{G3@8bmjlUqP1(8vz1DDk_UFob(t8^4^4T}Pxmf}r(d?AQr{HDMf|m)1!Z_ff^_8vmkMg7fBcsy?59W zCPX^Bu{l|z9OkBi1Dk$PZ7rY9Q*$IIU&2+D=s} zHs}(JA*_DC5=N=x8H%+j=0N%*uT(`OA~xGsR`7@#`vFhh?LTT~gpIy}jYPU@le|Y) z*5NH;L3Xu9Wz$M`p+r`xGL7i@BL`wb<>|100>fp=4R5^69ta{`T;v+swkaXAmJ-iF zL_kFQlL8$@m+D3pQ5TKaoMb50)7lNQi3fJgCdiSZ^eV3ttgxF$^vgB9k!@*`YX-=@ zPGDH8a`-l)CFRsUb0twHF6r1qpLjcaa8570%=3G2*dbl?7CvtOx@-M|RFdiOuLj!F z@&!_{+!KY=0mu?crrf7`8ACOk45hB@MzT})dt9fP4#)$!FUMZw4Y^C-wDe)!;}*Yn z0sF=WZJc?q2&(B1>iRR%p87`jhrZS|@j`@dgL24KEmph5V4>fY18c+IU*>w6SB#St zss(zsI8Bn0JLHy|`PWZ#tEVyw-w$J#YfN~Kn>&oj@o0mZ)eF4~B+K&7;2F)hquAT) z@7{T#0>EQ|&|!pM!he8Z(duRp^}&p+0Td;2rAoy@Vp-UIEVxw4B!Q13PPnnydkTcd zE*!stcM9G?E`6}t_H(9;w_nP;#M~f39AC0YJ!NL zQLZ}fSIdO9^RLL!zyvy%c1+$=b1$3yk?j2pDy#QBtu7fd;(tx}pRrmz1O5Ow_xrsU zvxhQ1K$fIK^dzBX%Bfj|8wfi&#f9cbb1mqp3QMXZNjp`&#UWpqM$R@RzD+xf94+r3 z5CU)WhzW9Dl2JVz-h%cXWfQS5?&RuPHgt>Ydb}}lq@c;5Ql8?#H*=myUQDeT9j zBF!>hA;*@EG6EpM`Qq68-*mJLvfj2&jHq&(qKGLxywf1F3<@(0;{izvx42{g{IgI1 zNiBziEY3ILa=V(ELe?=1)rFA_q(S;{B47+-8)lg)nixmrQVFByu~8y)ezIQDHeHA8 z6wU?XYbK-C8BObE+8fPLMSj#7iOgIBLXDi^BmAbzz*{GF z2r92F)$>3=9G`$(ojTMxTNa7_k>(BD;bOWquicIF6Z_j9&$-K$BL^_@?M*J!;%$^sp{dJ8m*xA<5VT^@yP1G(TEpv?7SXbxZkZNlBa6 zYN6Zu#vS_^lSOs08u8(?()n%r>+eNy5Rk!f!)J{!ARxR%|7-DoLGyQW|DVh%-x2cP z%qosL+Go~A)N-b*>MJ$^Tw#i9c zfYPy0TTQ}Gm_iFFZFAp-dB@pVC0BTXn{Qv>N7oqkj*wgFSah)_?X}aXsa{*&TN_ti zuft#b&zL5%uKq3}_YRz6E;pu|nycH~E!SJ8MNEa#S z6Xq)`+t>FR(k4F_x5Af1I$<8mSp2Ho_ojzVOe)h}s=Y6GQgJ4|+96 zQdD^nlA8kKEQi$4{+s>JkZ((%pwY%+yZI0jTMQ>1dWZzwL=b2Yg=Ms1UZg$ ziL)?)rKu6@+Bw}&X&DQL4^+ayA<^xm1ICOVq+B|K2~)Q66ti<=8tE%NQ?7#_&p8&R zemgsyduZ}jhvTL$=1GYhMd3+$DN?C}6{7X!w7#FACMv3d zez~_tD!0aRLwPREv1}E5VA>z$VpVQ3Ib_yFE(~c%Do8zYzNWydzfyAGpXyz7XPAm; zEKNSWjO@ib$>J6O6HB4VP(ufiMe>T_BvwPK8CK!KV@{-%vTJD@XeCRdqT&$*Zu+J2 z4VU$UA;%*nrm>;=O3`k39pYLfwfwI)%hdwms=iL@CZqEA)#5x1Z>5JA5$~TpSJ}_b zKWYD9e>=5ot8E7xtFRpeYW9PSCnC08&SH zs+VkZqiTxnsdf}?16n&S7R(oCFZvI_^p1`jCO%$6>jKmFE408!(K>T?WjhAHX^kJ; z(-!yJM6%Kw09$=v-LIwbp?TU4I)~Wb@j{=2i@X_BaUJY!2VN;s- zdphUhQF~Y&sA8T;R9ENnNZ6I+dKdhCal~z^2)o5~)dp?Kw3P>a!j`669@7=rRpknd zQ!xCB0rG~Nb1(?#e06koMNVJ1G;AgA$p*@YqV>S@+mWz|q>^`adWW}kGSvLmy;^;{ z+;+kP?qBfwqLX5UDy~bG&BYGsz8`#hlh*1V*|S~WGsJggY6tVa+S^3_vCp&L)lVi; zMhyUm7~1It7k)wPXVT0sD$gr|c|&Sk;0ypVeTL3I0Qs(~y@+W3p2?k} z6NzR;t;VaevMz7Ydbo2axiw$<`Z1XHku~O{hfB#u2b_wPT9L4eC7HvI8%^tg?Sx|P z@{V7h~y273tOzkVKK@-iq6J0w5 zl&=+%ug9PMlQ8#g^VDLa*PP#iT!^^w$qlzQgy(_172t>0UPN<@cGlAK%`o)i%NRf! zu_+!N1x5R-E*ky9k#b7{Dw=+Kv#>%z)JKOt3K(z>);HTL+vGocqPvTXFR$YL?zS*& zbB?$z`TC6d_F!>7z|w-SB?xY&SvSoLR5Xhnx?}S>MH6tj^hkr}?a6fU;iqJ`-@yV~ zcxxT5Y+vLr+P7}Z?_hs|i0BJvD_qi2TpY{cw@O}hVjUK=Ip7JzNZR$O#(yH)?dpKN zRGz1H;Cjp~Lj~o)2q)NG-w}Q1M2{ipN=Co=yP2JQU61T@`SzW_7AE<+>1qich~+pM z4$r06=S4;v!%14Iz76+`PDaME-|Udd-4QVkmV6EB^30$6yS+4{A?g05{L2xMeQj^V zfP1arSI?99+n_hbS=}4;*)wnTdbNXw?ytL!skY7@!Y^Vhe3Rt=`R;p*=YARt=E|6Vo3GrhAX zcN6_pj+I|6|M#_?nZp0IkoYHyh*;lsbMk+~yLWs4!u8h=kN-mdRFKR-^0#uz=k5Q? zclE-rr~kqAOz+tL(X;*2p!&ei-T&}^N{zXohyP!xxfcv{<9`&F!9oAK>i_CWB^fwG z^UDv=)&CI!2lanKns1;%|BvFYN)zlK#Uuid-pJa($*ED@!ug-gXnZYGR{S;p9)%jv z+V5*Am^h5#5#iS3Im8UL#__&NEJ+YVF=Ry1nzL~Yva1aiZ5*U0V&?IG0-FfQ&_l7~ zY$em1PU0@#q?(;SmYf`=uF_L6zq#heJH489aa?U&b-i7FY^HNee;(b0gJ@kdfYt*s z)v(3)CL;a$e<+egju@hz4<4n5~;c8=On~fWfc|dyN z%2kr0Xo*>ko0)xyGMQ_MzaVRaJ7M}l6wCZ2m4_z0AybX3Bf&Y=u^tm9Bmy`Ulc5!D zssvdCJ9B9zPC*X$EJ@pM(S-UqK(#sYPMpHG?1(}Qv2mNmkI8B{eJb&R5ptlC1F)pi z_RqH!?=?(QFl^S&3kk# ze7P+ZW^aE;$v(00O={uY`=+=PI^r=>>&D{?<}uFBdgE6yq`Cn3@Gjw?iIZxo)GkSp z)_@q%t60UU6K}FPj_{Jd^E_}SpP8C7GeAu{uVXQ+B!ThQjoWz1{`*qW6oof6@}tJP zH#6!K0ez-?Upk#&{qvj2#Nqq5!aGS1Jt&9p?1Y_zca;-B+$JtmKDq#n5&U|G$%s2z z8L1^+tOM$>`5xX(+}u`x!Zw+Fme{IA`HLsz0t?-7{5G$(t zJbXta0fwDf3daVO0Uq*I3=_g#>)tmg$MYx?m&u$^+p0_p7gL_t`41NsjlUCqcWr(% z1v1>dNHF(nkWlG|1vijfHp*BybOeQGmt|KfxjqGzF7mp75}^Rk+%hz`E>*_`W{P_}2Ev7ywC7WR$JM zWmp+ewlQULt%!9s(9Y`)LV#kQW^i*4D(2jugB>~g%!yy%ZU}_9U(SuNSSMIhHq{M`ilZZ<8*Lsp*h7iY z?qiwuslVbulY;;8^55WPxB*2kAW8;uije-gG)82paH|(WgjP=&y(dzw*in%kR^qq8 za}lXh?Y7d6Q0|NNU`CrS@?33CZUA2STb~~mUE$W47Y1fMKBzaOy8K}|uhZAU4J_hZ zwgbpJARE>3u%;s_@^qsFUJrRVr7ci<+9?Wy)_D1gNMXqTbgjr8q1`v_Q6_S!(Cvjf zuF-dKk3lJ@)Xh*VT~4h}g3uk-b}sX$p#a66K2}I1s$!=}vBn){?8rgA+#Oij<*1Ik zfYYfgvaALNi@1U-6b?~ktRG)t7zY?pB_B|81-i5>i`j?=CxL#nUD7!Z31i-W41My$y}UjZJ#bJ+gB`=ab-c-7_?hrou6&$Gd!^ zJ=SpIa0q2YJ28F`O4c&0%lKo!qaqcgb>4|@8CJPo@;y;AN<>{~R+YM6_BC%I^&0Ri zWuC^4<9Y~sOR84@;SgL}A2mmmW;39<3Qoovd!;_JF6U|hyd`!6%Gy-pb^XfR#0_~T zkhLq`R09Eh{bnGuO*f3ikL}Qv{y;S$W$SUaJ5t#h;;B9SqW=9B&2T34f)VBc=2Gjd z$q2MBO9KWKs|3I&<+vsw<%l%#R0*(xZfo?NFKoN$qEPOcgLdi!9W&vw34&+J^I#Tz zZrem*wR4c*It|USC3&2=we1>x#v{^N?D#_5Qu+L)J<}M|m}udgh&sm?xcYK$k^$r3 zcUKsA-QBV&Dk$sX&}v3r*!=H`^>aMM|7teyW&hLo3CNPm;t20L1e2LoaTZ{)qV$b% zU5t%EySpJc!L4v?U2*^@`U`8jDTu}6!e<%b9`*qqf=+XHoMvj` zPV@zr6^s1Ha7(b?x6FA7hvL?l#?~tmP0noXnbHEbD&qY9>IKE-+_OFtQLeE*+ij5HeSsLGHw0@t1_P!i4Wzfv%6iLM z?uiRF6?}ktE!f>;Ow!wfG)#Hu_7PfQJ`1I-+vCbcKo3bY#BeM zr)GSaKCW)~b^*Zd!8#C5u(%H{j|=z^21lXD@g-v6F+q27MGTa9#qblb(e zzBcu#g$C*Qk^ueILw&pqO9N;8Q9Du$#(VqeuzdJkUdRZ?9D!Ov&NFq2prL=24&ny; zhm{$bZCrOTssqyFM~MoK8pv9-+AZm_%GA?WVT-SyDTLk#Fek9eGK}z&r?mF%9qp0} zGrZh5EZf~;2dBFsaA4Y7XZjTk)Xyu`@n#G7&;23E)&csTBq)hW`6_7W4m02$ip89P^B4j*m!hLrLImBu2Ez{M}D#2Euonf^9 z#A#&}b^t_{!p*`95Q5e<>2wMddV~|JL|j9wWL$Iat#&V);jeHl!HNECy3#7F%o7x# zUD;3@4XT=+Y&V_G_h}@)&!Dmb^e>Da?oe~SI`*BfqR|{`Ha@s(N8oc18M#}N>Aryf z^G;Eo1{c`<31@u({=eTTsbUyFx_~n$WD^|UohIkay0t*)2xXW8G72mdI@r+P!bII9 z^$}|8WSg!Q9oTHx@HZblcRe>BeVFBeGi7>9n4=Gof6+h1aB^R^Nugx4B8<2aKd(N% zV*a|_w0?WPbNDsh^@POrk=d<|Vcy{it>3w`+Mz^d;<#ExDNmKtUFgexcoN!*O4HAqxV_=%m@aq=`mIuVEybQ?*LR^DIPWhd*Sln){7@npR)ooE5_adZK98u;-TA#}R*uh^o~9 zpf^F_f`T)Hu3}$cgaa6n&a61V8(u;j-1;D???`cz$YJC3dn* zr~Qn@5vZ{ku5Ba00iGmkUg$Sbbm*u$qMsQBhr3um2sK!V9}*o|t;lki!kGz~>b1n^ zmW=74;h<&>u}3e>ZJ)n|^$$ku6{RMpMR=Fg%|D_T-iL8Dn+60#2`CJr`M*KDDf%2^ zW8UN8I_1xb;M1SZLWHJ%LUnV#aU! zw;FCZ|AJc2dYzL;p1kEA zGV{7b#=(yCi5Twlbsp(>HaZiNv`k-6pWQ`x{eZ6a5s&_`N0LK(ZD7YN{X=pU#t*JX z5CKrv-`9SUO{$NbXYp6+9h!j3YOby76xjBydOYJb%afCLrKG7WS$5Qyq=Bk}ZyExj zaVjfzYPdyL8E~2yu&QJIeGMhJym9Q+P%}B&P=i!jm`1lp#e85j@|{_M(VSwm6aiBw zvA=h4s1srKjDGaCMw`E>7rmbWHOMDn-6HK zu6~4a9dDD_+i1Ziw{MKfDzba9(C|fWE4;G(c2T+Yq|+m}|L&3a!2{{MVqd&gEr~2Z zEFvWglKS0px0`s86dfPxjxe0JyK`xgwnQ6`K6f)(2O(*jQl?_Mq{lOqE0v(vJ^HDw zJJjZb*wORY9dLJ55)64W9lMj<(ktO9)FHViDT^z3Ni6R(B#+3C8ZN|AjsEP)`D4@F zUW&NhS2huPaRsef9NXYbcDmi-Wqg7Cr?AD|N7N}@IQquHyel{mF5p92B2Ea z!s|zZ@~x%zviA6;g#m29M2jLp7M2ET4%;;1FC2{?5k>KvXk=jxFV0Na!dP&FOy{)c zhR`N)A)3}gO3)gZ*`lM>V#E1kqxP!x%a2#$%xScRj@RGg zZ(Se6KG%ObLj3xfUY=D{zK$e3hyXdWXhDPC#9aEVw*3wdtD@74VE5ca)`mgR9Y)cH zlQ?g4Na&_4X0mAamAcV`Kw|RgrpkN)0^Zv89PGiRxpW*E7U-tbWU{O%7Edx>c1}(D z?S!(vgPi>Q!0_(Skmq7>&-WLoppS{KM3lzS4luMQPS<`GYqzyAv}sZ51c0N;Eg05= zY5%xvhKK)?Pc!06MSU`hMGK+Xk<2FQ8gt|=tY^2ZXhlTbQhXDH?`?~wh56Pv>O#hF|81D9ZcPO6b#9TuO&q)kS zSWsU@6|A!5Lag$H%4~vg0wBv$0+J+V8bA4*#JbJmhbO>Ynal`r2g0(ZXL&_ zZ+scnCQP}Bg$l6;7-7ZiG^toZ|J<{qn8uadqbq#52zJO+05%GX{UCl4M{5JgOG2hB zl`P3-D2CV4hZL(FtG19n8^qd@pNdQl9%);1N;#PCgHSr11*z8q>%U!as;NRS=Kqj+l;)Cwo zg>Zvzo{UE2+Qg1E0C7hMXSSa5*J6-V1?wL@ub{RH_-6rLC7AnHV0A_F)apv+9fP;v z;OKbuL~e|nVX7Y)1LMBpje4;euIK#lVojz-mqUCQcN8OT=Al1R0v)fT_mJJv-7g zXG&$qo@zdEcf$(Db{+T>>|mwr>KE_?*~DTQEBsXMz>e25$Vg)>G9UbJS{ zc{E#^Fi3At4a;{NMm#;yM2@p`%01UmP{3#jAl@na6&0g*$aXo2d`#i5W(vN#`WUrq zw}wd;n?1y#GPS&h*+?;Qlfc$;+McDwrrEt=W!xz7Jbg_H_v!&d8|-e|Q+24Jty!@D zLc<8+InXlQwegn>`>hff8(mmyP;YJH1kFT~XMduWblJ5&$Nc;^KhJA@NV0jr(CQQn z!2TC!ZWp-V*Bw&XP8We=w@fwNVd7|S#$R0NZVv%PtFE5=ZRz!9^-(jfZ?B}B0B^S; zS|cB7S5$023Sq-+s}jV_ffe@5GrS_{#6Cc7!K>SldF*E?HM209t&hEISGnd@uOUT-tUk`NYj+i*4jv8JI3q zyNBdX3K}>oCHWX-&+FQ9?x?{Y$6oxf71`K6uH#NKEQDm_wlseTKmv6Q zA=-RCX1)bYa0x27C<^?JVwg8mCw zllb4t&OeIm*uN`}H{LG3Q{>N4lA5Q0?33hU>SOSYadFLXd4_7M4z>C6^P0VCB8G5>V7jB&n5N8GDF&pMPifHz2y$)ZS&f!>QrXEnn(M0F*5=SM9II zOuUmniNQ0uRQLasCa8{ z_G&>P*}~VOUaC8}=IB zA6CCrWQEjO3L)8~lPJP&SIg}?tqoK{>s@-vQ_sVwU zME6`y1)CHOM4CH&LsI`uziG{U!UOuKUJC^g`*Ls1$Sg?@NpIN*nLiQ!)2q1DSz9>% zEODa$?|wmF{7{|(Kc+?AJ6zwD406UTpt00l4*fLLae6e1$VlcF&CffEZr z1dv#Ir*jYRGa{Sm@;9kiC977q*p@Y6HCt{)!T=RZZrks=Re$s-U#M0VJomnIr%Rhk zVDV<%cs*S6xN&@Q{pI_c^Kl#NwgtBLE8a*brjK{zeB~2Bsm2VkNfl_LNzF=!WV0G2 zIZa=Xe{nL(}-dr~j5NybCP(985N>a`5rcsv7c z4_Tokr~m_mKoIYz%{NH~*g%ilfQ^`J_AgC7f%(f@sWWjFD(mciUt(&6BxQ%4DJ zP=30=07shAsV^PrttlhxqNVdDN`_!saXyyRt>pYdTT8D%!=8j!_S7zcNO~xZWD%F>?Q#@P^BMNGLF(KBZOB&+Nd}xg)%8D?I;?V_&F`^;#w_5rlogx?gT85RLZ}&j68){Zqh36O(MN*@XxgFR_fO15l|Q##^V0E&aBorj zeXz;*-A)4#@n@L-$)&q@rx7N-%$TGpOu|1vMlp!=hJv)o6a0p~KeCJZAEiS_p0))d zhi=UKM(`lEJdsc^rQY^7yEKLijcXT)mxfNi^6`vL_rLFjY)~T$%F8#(R9YEDA0b#i zsBp1~Od4oXsi}LyT9AcC3RYJE9o? zWA&ReLxyRIFzJz}6{!AS2xGtWPKL}c2lmx-_qpx(ZIymsqoUdex_c$GT0_XD1*qS^ ze|SN3`vW&+6i4xjF){nk?`Wz(1`{PK%CA~DJ7Za<7+pIEbPM@l&PBY;%{3WX3_ zA*1qb7Ra=)eweag9^l7cjNje>XP3O*U78-MRUxShOnJb2}zXPI{YLcMas@ybp8 zo%hMfn`N5(Ymo#!n+i>*@1F#vs5D zQE}Hq%-`_(7lQHx*X}t$Oe(0gCUZq~xn)vGcbp!Mm8t4@h1gzIZg4Y~X3F|4Ck1O- zGmC+c*|7CsX4Nr7qrGgA(st+WNwzip#YwXWbI5LIAZ+i3c-wNwi^g*aE>dG*b#}r^ zxYIxk!dcVIrC7fgBk_qyhMICFUGH0lQO`+wE!G3et~c0}THqVtfB~>LtD^DEy}5CR z&$-qR?4jy$V8wmzc?>no4GS4-nr+tbm~|4ry7$d_N7G|u8jBu3#p)A-#T3opUiEqG zu-GN2e-H29yk9Diu%0{-FxqJtxB3p^ALB zhsQ~jf%S3U@b^AI!iVi!tmsj!1-}MQ-eJ`n&#e`fv-U2lqI$PRnCh zG^$sldN=!9L>K}mnwuGMlVL5e+t7*id5CT)2R=B11J0}8>Z*Nyqp|)UYm$wSL9q7= ze-D}FcDSiq!g98;E4kM8xT#yja<-vsspfV$Pa3Vj31u9hbKc!=W>$B^mFjuKaf%-@ zR38khjuFb)2-um}^dJ?KE7FGRJ`{Bv|D#dC#z(ODokSn<>CH}DokS0c*ixyKqkltL zpVr2LHpjvT;OlWF`s#IcCa)N1#hIvoOs;=SHQSicFTkE=R6=gG@GIFy9H@y5ByT@W z4tt2LTqP4g-Ry^|YCV!KRn$7^31{K?A#7`p6rYn7R7dY$_dAp#1~*5ZoRl`0BQD58 z0qaDfJWXyo%)ft1E37>Gm6k1Xihct_f*DODx@wGW0ENn zn@v&H0rCLti9F!Ac`_o1#Mu*U{ zs}Q?lMi@6#oc3qfYL^+moBT-`=btbxN;e`etIy*AG*DQnG-#AqL!0zoi}H_S(FwH& zRqe(kI>l)%!=*Bxr+u=YwU(ZQF*sh{=kfxsMy|E&&lhOaJC{B`WY~phulqHwojmPz z5msyl-mAO2_%cR`?Ac^I>5#8|U^_n~3T?QR@bb>^hAg>KVK=XI+lLI(+4i$9uS{QpZq}q)KmN+D zl>Q3T>qJB zPahUw+l}I$QKcGI^u#PrNAtX5FFJLY8?xEPbheWCxI41VM0fBlcMR=<>*usdc(FW^O+U#R7V#I>5P(2%Z0T^VZ&FldFX#{AIJc$@f z`V3=)Xa}hO5@E4KCFlZ0^Yyt5S*vhe^v`TJ85EM08?x7twQ2_}7J^#X? z_}^no%++;8_Je3$W+f2_X_S&5N8zz8lvEN(Rf?l$U+N_ALkxz{*?g!13c+D%{zk*n z7zJ45k?ZUtuMQdPkblEG*yV7dTnf7f4-n<4>v8C#? zO3H{lo_Jch4au=o>+exC*ojuOiK>WpqMK{)S=GQLjoRM*DS>CS=z0w*WtM%!9Hy4` zq|9wdSlUo^`A#s1#KNTf#aQ^&JaM~c8F+@fTKQDi%fFr*Nu z9B@67?tF+NqHIO;38NEwd4&yH%V8*Qa6L|9>$3)>ydzc1pw(b3^~e#1W6Xg=fXQel$cFS&u7NKpNf<58CBdI7Dz8a?H+U z%5AxMD9&WK)L`^{Oy#~0_Gbk`kW`Yiya1R^`A(tlDyN=$-BEjGP}*(w%IVtidYSK= z_YI`a!@Hbti2hH?$xIQtX_esyW!mw5+y$ykJZtdnWqQQk@gpQU;K9~+>v4(*eTxde zoTjvvec;EEY`WI0Pn&TTa5hyuYKqoI%G|_=V++sQKmCto7VSjZ-^$#oj;h1M%atRW z!X%r!H#MDHnDz=|gIm`XCUVQ@6w?+yOTntM&kNHzG%Krx6k2Fi6x|z(G4|+^V-y87 zHqCLi^?Gx!@tD&DV8Cg(Ec{K~5P{7s-7=yg<`h%Yh$Cc`d$nfhw=eF!_>ZInV*rzF z)}={5*Wb0PZw^ULTBOguj~|qCaK>PBzcBd#_J!;dYbZnqFi9<)oG)F^GsXL`DK0bAVx@9}_vn-FgjPY{rf~3twxg zv;IQHs*pNmF~E-!qFoGoDH?@B4u+K{`e_OOHoRp^vA)WVeZF2Lz+F)qv&de#4=eQ7 zshhzbzE++MpkNHdoy=2t2&}toUr)#+Qx4k&UZJ$4%VWgek{+r^A?Yl--OZA{#my)w zCY!dhjo65CO4A_R7^ue@JYGk4tv2Yoc&}eYB#D|I_DJXpHfPnMGY@_A|g$aL{) zD|$!kh((6sTKi$GkEBMS3567=SnQ}cxLU+r%amnBG?JNF9#3e@l@v<`A3r%Ttved6=yR+%I2|Bf z*sw1N_|k(M41N{uXTG_cdUak&ckyy@9%QZa+f3pUd@SFP*Y|rIW!NhaMqZ>&Zc8jZ z+nlO*5fe!3wjnqcjdA;ssU$){svocqGrr66l434LUhrM-quE-yRT$L!D|!BurFBP5 z3xP;#bG5`xK_^dcf*a~pahgT)#W8qBgP>0dSj|9;!oyOafi%Eo_7wU;=KnJHoIi8b z46Xy=I@^{^>0DyVFzfHZ^*U`&brmv3FKEs24vH~8Cw$&jb3<5g3Kjf9Gw>FB-97w$ z#p!M3d>|5BPGwp`-w7-oYa4XtlNXXMjT_;j=I}~*Fg_D1UgPL2584-N{EbZbDee0S z2>5(eaUk_c!dmtBld6ePq9$zS6sSbwE9;r z+lAT_(6PT_8E}2f&*g_$qCqPpg(GCdDhi~(qNV7m_v}$dO(oU3X9y8g&zu@HA4ERz z>HylM7gc5yLp3L!rjbl;x{*Zs_qAjMh+4$BgjZuAT|B?RcDzvHEzJ6o00k^7xGw+c zv{w_km;t_0`za?yctA{>9_O37{)Ahi603`$zt8O|WtKfXeYGyF&XLa`9>5+d&YB_Sn6V~|OGmg0<@0N11qigNR^8OX~%m`KO#XB0VhioX}h z)bnxD2=EI$aAUPVT4GoSsm z3`yK@ax)dcVrhn{Vy(x%k*N)>Y7e@ zA-^IFpx6^MDe*eKe_P8_ePSkj@Z=Ru{!2Q?x`sPF2UUd)jG)pJ>!_35%vM`W*xu+-cWKedWnN3U$b_FxFv~rZvJLVdJ?H6S8i3&CCTD=Z-!(sk_nMPu@HCbH_MoMfi zy(=rBt{u$;slgPDnETP{7n^*LkoT)mNQMc_`(noXP zf_-n9$_W5{hF&8TCDUnW$X29p%ul9hd2bgZdk@HpLyvrKWtLv=HA+*n$07vEl)ZQ& z-73ap%DEeiQCou>-gzo|QWuuubU=-EY|r0Q=^A0EB}2+UL^O9wjTnQr%eLvoJ*N+r&#_jGUCBdhW34v8|*<__*?^;dDF;x`qQ$D32F z@MWGJ-XJw4*5eU_A#^ACyTL@%OSjDnoBHrx8%j3XCOe^1A6#W!l0`Tz%as^cHC%w@ z4D3{wQc-md-{7xyQK0bYe(NS8`(k}G4g?;xIMhBUc9jI~EG zdL5+pN226s+BuyIM+f>5Cp&!?DBqli81G3b6vaZD_H~9L7sNk!VAlxb$gc^-L(F1wmn}*f5x&<#oY{G_E5+m zi^Icx((79psu|~7Ak5JKjP%wsCSd@Bx}uD^R`v(5b8e&)+SCWHtY+vvJVRg@^VHIZ zd*=b-`meBhFlPy|3>vX(BWrEw9TCpB2W#4!bvut)Zq@qpsSQ{uM$x9mBJ8zLc6dkL zHwQeR962Z2<8IjFF4%n}TI4U^os(|oyn=n8-l>+m6Umwt-{L}mqUSwtP0a3aGf?eh zd)NhecTJ{a;wzgMlRNqy__&?aJ<{dGSaoRc z*YHYvM0H?&SYdwTfl%8hUDwQI`;Wa1<3$Dt@#}AV4WIVLzUJn#R~W6UHcG6oqA)mo zEwB$L-s5YM4~%c3-2C_dHq_t^lN+yKzkV_NG}ZrCvA`Atk^*3ClM9dq2@n!kf^{jA zptFEcsemX8S6Q^530DD+5MmDKr%5D+2XwbS``YEcFEo2w;=kwVkgm8c1++A?OW@Rk%0EahQy zs#2I1SDUB@bMo)m!H3l4tdtwdAt`Ok9yGPt5;lMbYXH%TObU4X;Vcn3jLKBGq>mGY zgQ(Xr0Sq+9W z{=HrWL|-tdf?wF?VgUcn4ly?8%GmsEy}MsYee6QZe(6hH_Jt}V@J$SDpZ*SXu12*% zJkDsS5r8pwoDYna66Q+t%AfF!vg%>oUZk=-Q8JwK zY^BmgEVklw`Ncy^)xWvfaZu*^uf2j||!E63RVzcjfc387}^p{jNjN9aXQv5@8p zx&Q)|{}i<588BtmCK_kQ<=vCigee+LQx3LFb8=*k&E-=sl>e0O63ASjL{c+Xnc{#f zM3<7;AZDmV{${a;v!oB7L@L49m}pdDo+OexHXd>a&i7Z-J``{rkF+2mCBXnj0V%T_W0RO4<{Wfvles~f2?B>^Bn#9p}~KcwWuB#DWKj|!ccq}NaAf8Dyj zdj*LILN9Cl8XX?9V?r7f%(+Ij-1OI=acEvk4E>x(O#+>bh{DkB5HO`J#Mc;Lv@syr z%3D#VS{?7ok+syILz|z#r<-&Kt6i9`Hf79+H)cPjBfkSTA;RmDRek2#6=;Xrkp|dJ zw1u~xa_$*3J==kFDE-5pr>x!SQ|GpvN<)Od$A!P&W?8!&h#h+7rEt-2g}`6%qU@vc zp*8|C;GEAAL7$F+a|%x~JZXfA&WtJ2^#R}?SgZ;8T$Oywl$G4jLg8Vp&ec+)cRd!} zAl~x5o94fHGVJopb)*k->p&dHpaX0ie7IBymEEIqxGYQ~&O6VxF}fmC^vjC`IDe`zbx&&oJ|70v|bq<>D@cDSbEzSS?ZF(lBs~rgfNkgX$WW1w0>ET4%jF z)jKq$c?c)QpBt27=B-N;v0N3|zanNXB$)z%$xoqf-I+li-tGI1yd3kl?8Gj1-ER>gTWlKE}KGNu=j8s*M#T5_|ZFq z8t7Zy-m4!zdWAU%njP+YGU!$o-A}i(Tmf`q3!;C4D{k^Pc(Vjyz~=>IZ;D?5M={@FL4Iy{K(h^Z)U8cD&LVaQs-3jE0iYp3f#YwC~+z{A%G-|YxEi1d?9R7 zvmDZ;zhjEf@W_$82l;be0duKovS{hD2Us=8*Tl-hrdWgz$!RNn+knSkKqGDQ=n*j= z(G&KeWWECj!=3I9e~uo|ZWn^%Zdkq?Uy$D8d?>-X6#6!s?(y{YPdQdAj(#e~L%*6i zn*Xyg#XE>XjbE%Sx(B$3oovFp(o(A0m=dLbdPy@VhbC#MMUXdmYP{yWFjQz|DDx|5 zE|UM1xm%lKh>Ja6AFV7@r1hrWV`S1klfl94{}au}73hTm{bTbp``?-oCk`YJz*fQV zl@*t0pbi#?e=4eOXfzTNa3pWs`t z@!wZ=+6(Gry?@W*57nT(G>6LoCZd^hrDp8;#L6Siz?OvC@EoLv`&-fn5I>cM-iHIS z8<;qQ)|{&@06_=S6x@&g1sXsJEI-C*lJ>ssNLaXep^~mcK~;Io#=IH#p*eSPiFw53 z#kyTWL-g=m<(1s*#Y334UcBj~QW8kH;h@|9yXKvq+Wt6dR#|%xl5WF%2vjitifKY3 z`#QN?jF)@<{Dc_{IM#v;;3MJ0?7t&F(Oh6KY^>jWi82`jQ?=!rupG%UDGJu1cTB2w zL9Te~f@&kb`FoIyw`)2iYeb2`UxKK^Wzj3;s!k-|*j=cfdFRPMl;E8&s`!8==oGF} zIxBMeb+HQ^ka%gdG2ft9V?O-!UODHea@K#ikZ7vnfsN)c8QRtd2v!=UL{dKhlZ?xN z=VYcap_UqTomhsTJQ0}nf=z5)DFWAESIroh(z!&UbG)((^|+4VYffgrm9Xa+ zq1mM$f?cPi-|SZj!_T9J>3q=PR!WzQf0;^na3*tpra;TgmZ=0H; zH0=t(3={Po;s;a1ii_~Fhx3iX@rPO32gVrAq{X=!Z=^Q@=w1`i-mXT8OBN!zUviAJ zXMf{mH%NaAHwBd2aTn<2@c6uyQg0lf!6`C97XK~*Q9z5V`{$C{Cy!butB=y?9t)exJ42P~5j3&;9OMal~kaH-rqNgu~wjRJvN+T~FaEP>`Xg)%-#X)psAd?Z`QsXw(oe5_t zZY4I!2l-w{AFTo=W;&brN2@UTapL^{+t2?uN&UYc{#1ifAd=Kw zW>EOlN=i^fK(gwl60+Kldclu2P_ZRk9cEY!CmdF+QYMc=Y);80!ymj*M*>4lmdR}0 z_2@glbK`a;ZRUM0g>PLtq*3#)OeNib|$}s9AORv^I0#f+{m2)Fd>aPD=MaQmnD&z3_CX(31GmT z_mW{UwMao^LPtr0R-U#pW04bPGUFLseDEAolqcJxuxxg-z=qWhy8yoM1o21i5i0cW z*^|G~&*h))YcSz6nO>*$Z`OTpW?sZvB$DXHNe0e@IY9m+cM4NKrolrv#~g>Bu)2ed zn7wiVXm|}ML0b+C!CaYzv8F1*dXWI4RDF%sP-;woLb}`4>FDfp`6Faaf)?rCH7NAO zek zwnwNopZAtI3M$!MUw17Gg{5pgpz4pL_VBYIvpH9!&vmFa6c&N&F0VgWWouGt7cJZgT>X)zorVM_u+>petA`q;)ry0&465!%3=X_nmVmlye(&FgZX5 z;2{>k>qNFvte@ML^HD8I{#>9md}wa8jx3e|^!8T~cP#18MISlSeNY6}QiG3>lX11# z8sy~^O`SQl^^~@H!Fe+&vQ9&s=e~;lX^h|mRn-AKI|pU-F_Wqg1AYVasptWBK>;3i zu~2T)Q<2{!i-X-cuw~39DhN3r3;3-zV4&`CFrygC+PU~*Ak5>a-+m#2oMyAG@y1&` z)=c!;!GD94W7qy!R5ea-m>`6bAtDjFOs#PvCqjvRy50QaDZMI3F_muGM^FTpRs2c< zRZfbcl;$`$l9ZafWKWGh?fN5)l-f@{f%p8L;joNR9nn_`CL43w6Xl39G;J37k z`8zi~Mhpx#OM#wlE)73Iua!FGC?Eo|0C;)fAc73#PJFqNXo(1HkB*G!|f$nB4X@POw)xRiNZY^!ot zwA<^-{DH$ZEKF0!eQ=RqdW~b37;_Dj#W{$@`5-FVg3)~q8gEJP_U7ar#p<}J#hDW- z`f-pGwe$l_VIHN|5WWAF$qG0FM1nrZ(CU z{;nZ+ZNqHk+tE?e?0WX|1k`Y;V7g2b(d{pQ%z`b{>PE`N+QNaYc)kN7m)2I~+Ecd8 zmK953t&@(K)44$y0(}yMP2iJ7G4-q^&Y)j(pi!dRAUD-|Nqs^3)@w>f)Fm>gy>jG@ zSh^F<)-Sp@%(lIg!0nI*>0&lbQ@EF8!5FzcynIpdj#Ky6EWNvH>T=e^l*V;ChTdva zBipwC?$$dApTcMgurJ}rJ-o=!BQxTp4&F!|=#E;8_@%o;+ej@Yu}$Oq+xB>R*n0g_ zpg_^co6HT%4*KTdmDr;Tw3FHU=~>V5fyL6M{Lw)4 z5qVP{I#)+afJU5N$yzMBnJJn^dYl&6=Gd2y$v%sNJ-8i*-!c)?@)&ji{dK{19+zWj zrQk@Rf6}#I_wB#hhIs8bAKFi!n)JVYYPk}SIzSd#0Y#^j=8+W=g`yzO z@&B;(j_q~!@3wGbTQhEK+qUgANy7$>lSVU~X>8j@V;ha_q;X^0&%E#Tti9Jd{`(tT zFRpR^#)&b8+L|*yOs_&KJWRu?tQp3x21gdjD%qJLhY-#y?iZhFIA7LuT4<%$Pa>l& zQw^d;RG>#^=9jvAVcVLUlZS_#PnK5$NO=AE%OfgfYkHl9$5K`5diAIA)S620YrnN& zYDx*yvku4;IGZcSUFK@XfiuC>x8lW?4}Ja9ja8kq^ZAy47w%5Emqu16S=R}k@t2%g z>?EvL$RGNKS^bi60bWnllVgDdBfJ3o{&BFKW3r`n4u_%yBWnxAj1sI$-{{q+^+Qec z;J)cJcE$Gw{ZVIciNEZ@>dDnOJX~wB4{b9Ph|(dZbay#>1Ni*6K**UstbOyUu^Cw? z>yc4>gPMglj%~?Rr?w?#j1WjsTmZ zgjjlq|K2`TsAtOo{0SK91bjVoaArvDq3qNSoR65TwYg{RFFa`IDG2YApZh&7c!wQU z9KE1lKh)Wxl$piJq7!8ny(T=)9(g#a8^W>=@{~YP-OAELqBJjmI> z@1oPBDgoL~a{=4O+xW$TW@KW*OVKLKh_=fmUfzsRjRC@z%yt-h2lK zI<7PF!xTHD#C@2ix`>7BS|c$?k>W5MayFHTJO;AAgCWTi|A`pGVOR)&yV0{7L`*We ztkM(tCxHTVa1KONwMxCaKRnK7vn#LWH7Q-iD)gI9Y7bS$v;(G&*OI6hCt|@%?AJ&k zKlx%RcWk9|Fs@a{8Nn(eH;@ZOHjpt_l6snz+RVm`H+~-(MsI`ak z#Z~+jrM1`nufo)?{y+Bk?ip7Cd3luen-N`0xCR z^23U*6vH0)%a9T;l@5ny*}cSJ4y>M-meFuq(j|ePu|boG4wofKW*~!;_)ikF7M6{D zAj_j`V=k|OWMfO&qW3Srf*oYy6{c?(Dv9x^+i|ieelz1o8Q$L((rPKHT6}`@m;Sr1 z=E2@bDOn@?#w7}oY-kplHiAzMOrhYC-RnCjf4Z(jK!CCfTK0~A4Woe~5MSY;o$&jO zk=4csuCNVzf2(bT2$6XMd66<+`Bzn^|HvQ6PLhE&IC|DJGiiR04xq292o$^ zlHkl`ISm?&7S|w>Ip}D!kXGq>j%!IeOr@;D#b4mEDn(qu!=iaB9&I2z&RU9cjdkxs zF=4@n*Mog7d$(b67{#d_>G1n!OQ7C(oL{4Q7$F}B;@DWiF-c}U^o8=FRMCeP>u6$k zBG&-&H*j1EhKEg#UYCPGJDKG~{c#&sNJSPI({z@#B`G$?KS4hpIici(aDElH8%m;( zgU8T1C`CCou%Iz&^7gyUS#E}W`)%VOs^ecKV#CAy#tm*iF`lY$EPr$_>k_hp=5#^( z;e;yTtBNdud**`V55$70Y7f-6JpmPNv<>EE6Cgs}@5e3cQ({;&r;!k>W&g8h>6ZtB z!!0&fbRDM&P*=39?cwqvSw8Xwn=aa0(0vY5uGV^Oo=w9-C{1b2b=Dgx+Z{cpum4*7 zjqrKM--jy`(l8!3lqapZk$3tAB!&C7NEvPvy&X2~t^e|zo8+wqCO z8%ZU~0QYR#gf4Xn9%8}|Zw(K#w%ujRwnIP&aJj>w27gk%Pk*9j{nvQMLfp93?Yi%V z@s%V*BEmQB+ZQj!5(C>`E4QFHvSx9|d&d(OP_|Knl8nkh2AfivcQiHUF%Umi+tk(Z*;}nW*Z{Y zfIF6}wFg4jrb}Ca4jJFRm?iU_Sc|8uRatqZI*qaN)q^94ONVq& zzK>03j^xz1G&omI0;d68e;QY`V(S)Tm@~7_Ml7jy3`>$+L8e864XxbO#v64tkVB>q zTT|G?1+d#zfJ8tp*W5VnqsV3%F{wS{1Vjm?Cb5iU3O%BOc2rh<&}U(5r%;2C;nXD8 z3?aFNMYnK5U7ec_y=gdnR;oI%58V%^Y{L^j92WgViexElXJEq{5wooJL~fMD%P4u@ zI06hTQs(pedt&2TF)u5YakFbt@;-4&$;iT|1&|co;FkGyaNENq7=Yg?r zU3zj_f0ewCb~8LuvQ6z}q*2{mWv{HvWpSQf6Z=G^5;QtsZ(*i9J?h-0#rE@u^upRX zq^|lf?)MkZS@$7&AY485q5S#gB9A=Ktc9K}0} zWV0z(Um~?GzZv~hLT{=E5-R4OF?rE&+j=9^G&1_$RGPa_tQ5gPL?hxu3rC99MV`q} zO3H%mH%7M~^7}iN2b;RudbU;RQy3Cy->Wul@oiqT?Sw`TLMEj}gEcKN2{5ne*`}MmN@DC7{0NTbm=O$2e3j&K)e_ z24O?;6oi))8Li($HBc>nTR{D^um{PU-SREEHZSb(FEbz5QHW+4NLMh=7sCB_^QeE~ zj5>hlJ3>;x*pmT)zy$ViOMHox$QyFP{VLX0I1e8<52CLCnp{}%)zEgmbXpU_l+hcw zndG?QFDBuRm?PGYL)`I*L);D_8ip*-yWb3wiTwhfOW`~SJ^FGO(tv&I;E(?zzw15U zYNldv#31FggRZSK)+co&G&!D zYH^)It9IZgS{ecUKi+9$7ckYMH-n%DVmBp9<&ytV6;(43)xLCq2mvR}=LQ0HB{=Lu z>k3b~*XXu_Qt&=vs1e1mfc_$*o|bL%@?vIYr0$cMdpd<|5FozR zIMPOKjukEjgRP?3%9AQ58z(v;0gdE*b0%jN7IXe1#`dFw=rjH|I-W74lXV5)i%Nu` z2Ko`cj8_c`H2$j26Mr+}`iQ|znpRvAY&u}_Eaq16avfzziAVq$|%0s>GDS!cp2knQQ#FkJQ< zBQIU)kTJlfstEiebu-?s!CtAw+|kXmFhxX$~+PvpLtbK)DQzpG&}!7~7DdV<5iQZJ?i zu>-%bnM|P_d8&tM5f>HyqBjz4-p@E12>j8t8Mbd4WNoL-r zo9L$ofxa@e7ibp#oys2^h{@JFJf}DlQd};3gbv-21I=vJ-!}R>f8XL-YBkC$YwxAT zlg4#~43j=^K1xiOOZ)u(^!M%oA$t}d?1xkP^Y52`=Gb_Cj`i|TpFZ9F|Gm}!XsxO( zz@r8u6)ZJ$p=KsK5!?WBDQr!2Hv?g9vC9H~S%@lb?q5Hz!tB=8>IygPn+$q^MPcI8 z1CKjFf?!%a%@-m6E29yuCV~?&rVp~v+A5(ElZ~{Rl2!AM z=xJrp%>6n`OES>ns41Dr3BeB(R)5hGBFEw8}q$SHnz}Je!Jk^K{je-B7j!WjF-;7UVl%2L5WA zT48pg^|5XaGeL@DsO2Iu%hIiSwt?R`+ig4hT0>SReRU)H0P;D4{YD9VQ4&uZ8Tk(T z-(RA~^Yl0ld-x!0S*G5*Z%!g4@u>ymS8=l7A%mTaFMYso!#F3xxrU5LJz%}Fj}l&8 zbVI3|ykqQgJgB!SIF^@2ixR(hs@f<18R6_}u;yL}9C7R+EEx^Iz@hR7d6toR*)2|2 z^s?||XGsK{kgGdltgjTyh6T?j)7zO8+@J4W*Ogc*x-L6BG;BNkCt*9dz5W^(kgy{j zajc|zDMWS9WaPq}BrpEkP(Z`0tyFGW!&8C4)7k)jS4rYNw{^$T@8Wz}{M>%v8G{Tm zkH*L6dygkv4*ZXHlFfY`P~dFbly_?geW0cd7zx-yHB5>rV!5&y zFgTL-W9*253J@uf`u3E+{AbX(=k8}vZLHFd2m}5L38Y&w?0VbN~Dg zYt~!tXgYvp*acfHk;Fs3DS=s9FR6+h8#FlHGIU#}CLCUKbd-P^cs7r?{wFpGKVPq+ zRHxZ>E!JZSfR0npTburdRwc)Fi_I{Pon38}4pgMsDeJ&*{_8| z7EI9+?F936zQSD)hlf?{r^ANfU>%GbOLm;rYqCU2M3yWow0$}-!RqvTHh#SvM<8V} zHc*lMwz*YH@hixfL98R6(=ok!iuH((__8#=)|r#LUNLhg>@-X}V=*z%d%j-#hGV!i zxrKND5@k!$xsTYsLn=tYbbLD?aa97;>**aekQ^ynraOQcrd6}ls%Hks12w{UCuxWY zQrpv*?`WhwMw+%^-KKqFcaa)28lTN{1}1;SdrBwMBC*A~h#dI5ZK0U3W>e;=j5xwN zp8X+_`yqBx;?IVeL@MkmmWNf?W_^~=;hWWPKdn??^xPI7+H#qODttS$dPcxAqf)Vo zEQ$@)Fek`%NHx`dWp1nFb3r|nuFRsAZ3b{YG3sM|VoqQZZDwHBO=n~mW>0$!1kO+x z-fTm2pSB54XN$lP^MRtbs2y6Tn=wQP`T2eXL-*@MHi_feuw+40ZAT+1aomw)7k7<% zpaO^2+YevK&J`x%Jh6?0dlH}uMH)E^oy!yYNgB{9&f7o-%;3Hd#+dw;@Sg`^fH{JC z3k(GI{|6AjFM>o$vK<7@{~4DkvIL37ks~7hTumOMg*Qh0i9P*|B1|e$Wuif-L1Hz{ z(u@95=f8%}-NSgKl;<48xvD?Ox-!SQDmy3toV*IY-b3{;8Z%t7GKQb+BsL|D=`{H0 z)huW;wdW%#;q`GlyYl|+XGHG*P&9+L(~xdX{k!&nB@y|P;Wo~poMeyG)4*wKLhHNU?%gR-bqcUh8iJ7m#qfuuk zRuxffj#HymGPZCd%lc?f01UF)k zCiy%y)pYUG)AT5nXLO$>%Ta8_dnJxn^lsEQXz^Okh8g>(<90Gzr44R*NC!Ac6w-uD z52Korf7<{4863_xo}ha7Ehz&AJSfpos5Ri-9_E;JQ=}G72~$AEIuQE;|Cu92ORxtU z7)AGW;Y{!gS79FoQ(smhps+pB##w-FVN&ih9jI&!2&w*7_TAqUGZBxZ;U7HIS=$$I z_$ufN92U{^8{aysSX{Wcmw^{^#S7hQo;&r#&3o5)Jo^RAG{L#RG^gsrw%l=rkJX2VA`pJ+bT@9VBeY~YM2PX6?CHo= zB6W6t#1C&Z2*=835GfSIc!gPm{)qGsB78ojsO^IhLH~ad0r%g!gwpR|+eA!Gb$LSqg zt#deNl^vdNW9T#^NL~RpcNpy)g}QgC?-k3o-+y{Vw$FH0Fk(2gG*++&lg(&DR4cZ3Mh2-_>e_?Uy?NLY05??I5STaxLdk<#>ZxN7mOQf~& zU)dOjgGwd9nFS5(neqVYFQwQV>&D4Ntge)mmBzXY_7Yv*^4-8?)=}iE0bsgLVjfky zSi;UP_4TSI6`}YJ>;1?(`w5OAA{7C80o6zf0#J50EE}i&Oy*N07#$8=+w1YBHtKPe zKh>pp!-DE->N+S(cbq@r*%ZI{UF`)FAt0yVaFQ)Y8sEY=hWypaQV|oWR+on3X*6AN zRr2E^(M!524+L7$viqs_#@@P|WcV{z_UZv|Fm0)gUX?qvXmgENJcHk-w#CBu9%b2E*j1Z{2@r5eo}!|@^F`bw4~2^i@tEYB_VVuA@fCWhjA~aMaD`<&*tMu zQ0hB@P#SO^^*sL!1wq(#dgXJ{DF?rtwjo?FdNB=Ghy#n~`W4N_NDqs$Ns8?)WRWX@ z6;Ve$uT0ZT;mzC{49yC;O(D?J`jUzHEN>W&4&{_=r=Luep%L~TN9-Pj?EVd2_3;yJ zq-i9tXu8)QHhC8SbVZZW28w#a5P&7@;7K3wuv9*5w*M`rA z!Dmzy+>FfpU!?sv(7?^VB~VY}ACF<`&j=%<7^rBf7!X+1TAG48Y48M5{(-8(McgC) z3RLZ76OvmqG^F!zcVa-0HeIs*KH8;>-u*Z;8#P7*{SE8f+T6w$(k}=9jsO(D_M(yY zXD;hz%r0@P1ZGbVf=2*n*vNT=;=Go{jGl5|*fY79XXR`cltq9IifaV=tMu2mf!hEW z=9Yx$H4BCm_lZ|)%R^nBY=GCF+Qr+aasH|JrV!Iwwpl2LJ#8WlK$_qKMGtFNN+h5y zWV~2+WT?T}Cm~=EUmQOvt;D9)PQSQibQ(L1nS+z&ln5;!ftY~v)XG{V4L64Yk9}P) zeuOnx!+r5L3n4I?u3N~W-qS7_fUEw|?8F9oTN$2b&!(l`2o5FJ0>B7ZRXZI0`6{l* z&!+d&QriX){V^Ao=N3dT`JJH8gcn_|%qgvj8Ry1AjS&flm$yD`UrH=2<(0Q@y76mD zW=%&!;C3oV8(M-l8p{t^eeHPH2GDnj>fodBTUa`N#sYZcr!E06Mi60y%Q-2%!U|24 zAC}>Gk%K_P#IuP`o%_NzGOhPexs9#tEoSJt^9f_XN?%hu$kCkPR4To&QJPLFziczo zy^&31Qsd&=!c|?`loO4A1agV(&!c#?QX3h9xO@57CU)u-&$K)m^%#7kWLzCC!+y7& zdNoF8hGF2eN>(MuJ$o38s9RGMnr2mCUn^a~IIALO-wM?#lYUhxa_qb#?!iy02=|qd zYdsBSneW60G#0evHnVjt39%7Hj;AP5UZt}TYO2^fqh+-kjG`8 z?mh>WLJ|xvZw5#YcbQ~vV?}Eh#_8wkK;NeKbv+?XV^7k4&i7wR#JNro0=$EcWVVrV zoaB@i>!TR93D;zQhZhPeTyr~g*93S+pmr2MbX6U{*1{e16TAJ93O~;c>G6mL#N=6h0e%$PQf)AP z%V_n@rm>~zw|*hGXfb{?ArzlVYJn8#f7EJWHN=aT+0P6G6F4#`1It50Rz(Rxt4ryx z0?1v7T3ceCGgai!NqGWaQ(u*;GI#Hr7^l!Db$@g=6s&Pvwu{`$$_e0 zNg6{-=xtKYbsHc$?QkMDfD~2dihObI>cV1N1dPZO|1dZrRhOr5@Ea9iJ%k_i4};Ug zN=gSaxQfsp#u$>V(w5V1lJG<|Tkys2GK45YaY* z+6p&Join+0y3$sO-cy{|mYZcMQaxbJZ=9Vny^tpJNO}#yneC^|xWa~z#bHd7cEs85 zpM~KtjPcHQ@*!aMMs{qd;Fu*b8-quAo2qCSA9njE%zZiq^7l9nP7IqA;&RH5XLR{th)!EZX5}XKX)2I{ab_kblN*Zm67Y5 zbxK$CBSN)rUJ#s6gFF9_-0f_68w7koj5`6#^T`N@vfxTOR!P>t&yz};Q4MG)(H^DB3pq{t1k$X+Br@hpV0dzn_Qu(^ms@X2_eY z>&Ts=FFRDz1SEXZoXgMs8uL0&lf9&=?|^K+-poCpNUQCGVb33t^9RKsMlM(9TGX@N z^7`uSBngRR-CpziZBnHM<8j8=8x;q4EP#AArShi6 zY+O_tTStwUDiIU137(77u48a4{n=C&dT~hM*$Gzc3WiiRaQ)khvMz=r#yngKsaL(- zQZ?4*je}f##`1@HT?A7JQp~pie);ebw}@?PXC1g5>EvO+tAzqvRY?43kGgqY&s}Dc z75t%m9E&w%!1fmRUqeLmVjxG+zUyFl>Hv9T{rxicQh6R0-bOlCWFS#ansO0~atU6w zUc`af0YY9$M?h_F`G%3e5T{Z7B!{Fp+M&B=b}xfFM8mck!kcGg9us!<1$6%|CO^jK zp2FgrBYC#|i3Y4cTZ^as;x$Q2qsaB`5+a%-vBMBafXO!eGwn0Mb|9NMpzNVhODdIZ zI12+ICYQ#a2IG30cHcQ=i82_&^l+BjLQ|zZ58<47t2Fqt7odABoNWOpx*Fb-h)2Ah;{?L>r;Jk^#Cj^#VoMTaP+$onk z?W$vy5X_MYwr?lHO+^NT$|OqQ;)Y={8e~yOOYIfSE*1TK)xB`9jCN4^N>Yl!y!9xQ z9@B8Mo6I{i8qN{Ra6Cy0)R|{lzx^XGE+yAA3^rAr-brYzHb=fjZUrXdNi8=q29*zM z6*L_J5wxufWcW#p+}XQDNQ{Z)XPD@r7Z?(*0e=;L<7CF$Zco;r?BwH4md8TCCT1sv zZeaiUFW^tyat7z2bZA{iWxD?y~D~k}^A*Y-Ni9S@E_cC5s_18-e17Np(O;mPHPlO7>4F^%~oPR+S zjpOtXvdPbPI{$&|THBj)+j<^?C#ZfcA`IKaMd`UOJuxg{TRLvV-nPZwPRPUdbDZ~w z=XCKufJd&guzF5n=BBT=zL{5|r$eV%Jybn6kUEt+mVI3-g{;=Y*S2OKD1*BO@xGxL zJ}R*y^D}X_uI7e)78#S2+28YT_|8J!H7UJFSy(G~UF~^r$sT*@i;2ZpjRs%&K?d># zjm^{qW$&_@K=N`Cioh?95Zyb7eia4$S_S+eK%J{}rKHgnCHWBYN$V)Eg+EVVn)mPU z7Ogm>Kjrzfq>S$#1a^Z4R> z3)iChI;ohR$W3)vXKV3yFVpw_y{ogkUgh~_a}(SNLsio|B5>+k!7jq8+z*2Se+4Ix zoXQu60y!B<^|V(Hr}Vw3m$M^n!bq6xt=|xYoVkl+_C&>6Mfc^-8gLb@|BBYue-x6` zV=LmoC%di)@<+-8Avw}1;)3#$&t(l73Vr}H{F^(s_!JFXa^+0CY-h)H({1jo!z#~* zI0KG%wxHK-gc1}p7v~@&RwH(88i%FDOHRt@fJ{{x$vtlgfEb9)^vE%$`Wp>34Z_(1 z5dIP=t}d@$gQhHj<5#I=04o^>u)eW z2Q~wWP3^I)ACfBPg|unbrzupKLrD_zlm`VFv1xC(Zar(^6|fmC^W+EAe_@Y7|3yC3 zHm)XSbp2g+WA>#bPqK_bRH&>}GKq+*RF%yr8j{}9q_}6?y?uin!FEA0bpT-VZ_ zy`a3KzSkw<;JMoBaGGb!a?^bdUHG`C^{mA=(6a02&*s~41jK&mmY?x$YY>v@W#Hn} zvxRn2bIUGzMMw3_{#qrHABw`Vk|}FiO+KQgt2SCLFnJ)}q5oD%9^9!Iqn28r4U`|O ztyr0+aB8Y(LE~aK3B6sQ+q${iSaXMPQ(SgJspI9MzEoVTz0Cq2yN}=TwXw#F@y(<) zs_TuppW1ly7MCyvajErO)JvaJ}C!6Ps;K(>d`mRS4#+ug((+_Y12zdxJL&c!1Vn!{Yp79-Fy_=p#91A1(x%rI4Jw~4 zsfQ@YMhNg#ba7ab&B^J(C>CNVBcQqjlG4JqxB|1MS>?G#Y&@Z3=sXkGsRuN!c-`S?F)64%1C??#uduU= zN%k|19A8dB7ArYPzVDg-z&da9S1vM@%IE{FOmXoZi&RZJj77%6B-cY)&#-4wl{zY0 z${nxOAf(cS7#*z+(9(~3o3ccQAsFrFa4Jho9wmp45sqWRPJfP!lcKriqB##}+)Kc^ z#fdki`X&vJVIm=O6w-MEaHk#iBbG#azTGM9q5x%fj)s16j9EYVS7~p$+{5)}P{N9< zVv0U`>X%oas`xcIR`YbP)#PaKZ=^6O?AB3@pOQnTs@fluv5WZb=hoX#^Ih||$e)t? z3=gKI&iiLZ;gzwoANNQv6WJpr;u$|urw$}hBseiszg);fPv4Zj1O?2?VB0^ z=)-nx4RLJ@TiCb3!NgEx7y8fxM%#Ju;<1Mw+9i&X+cZWSD{G9TDzDSL9{0p~hUc28 z%JQ*$@ESw#5{o;=WUSF=yzKs%Kmc^C`xiXB9gfaSF_|30_Of~Zw*GgBEu&lJCs2#h6UGF=!^< z!?Y@lk;bQB4U}M)y+OHc`z$j;7;UEMjJSn zCPb=@nDo$~^wtgEcrCH4L8;*|6_Ys=*kG~M79u514MH)2-1(Bq zctrh-0%Fb|Wifs3$i9gEweJLF1p}I4lu`MuHqY|w{gW@?g)&ZxJ1%3|n=iL18{r^L zNXO*fARuis*_EbZQEHona+P%uH&3&TE`h}OCX{zB>gyqKKYO|r{veWP+~tx+HcYZZ z;zU;nRemx9@ZhHIB}sDM;fg4muPxm=01ojk>o-{p=mHJ_v*sgeH>VU&sX8Br-@BSH=T; zv%{)$F7xZJOpY))n9pX_*riG`D_?Yrw*oKUM_}-Tnd)I)_`0^%BwVs`Sk$imeZ5?Y zM`?n7~)LO z@?XVS+VPwdEK->3E1qtl%Z6c%^D41UG)v)}aWyA@iWYBC7#NA$Y zdYEPx3-qCSxo87{Cp^*7mwMkQXs>#E)g}&Otkop;i%sh)R(-ex>?qoOgd zXNQu7bXv`owY?gGg-b)VBw~i!p7NWPO)_hkC;Fnp74J?!+~ctddyyB*)x)j@VYO|4 z)6vw|Bx)N6DAJL%88sY<>ERdCS4n8#$8dPJ$+4SG*z8k)9Sv)W$?Zmh(lP1NgMy9L z9QP+g(sPZZr%Iy}Q_Y-=WAWuP9mBen{$a2jf3y(gRZsiwbZv(T`bKSuG*pB1#k;bN zDCXx+TZi1pt>9MHH_wv*dj^O;9?E4QgQb224tTI(gV zfA01y%|$(tL{>sf&KDhUObE;vG-Cdtv-IxShmOjG7_Q1#X@HHLFRFW?z9k(%T$z!i zXVWZIuo_EXAq>#}%Xj9&cPWS%UBo+WfkVgM-`MH+_d50L_ zWwacoEOu_7CsbBB1!0SRv>djE?V6WyR}dX({R_UgKTLlsv#nJu^H6O%Vy)E!;N+6v zXf)ABaoP@*RaxbG+=zwQL2Ng1X^V+omNGmcBm*%P>;@e^Ri!%1ORh-x`8BJPt~3p zuMZsJSxW(Eju~qP2U&Bf`0u>m&-YPHiMe!vn>aclrjs6n!#*F_Q~hMn#_LHa z+75jQ!nbP>1*nK(NX$g#6im#v*g)dUwtPT`OCm2m_h2_sml;;#?lwAUBK{o0U#BIT zMfF^8_4I{IDs~INsH>KHT{rCF&2IMrt{Qf62G|$7?L#~KZWSjA=hV-LXV3pj|6@By zyZl;lyeod7vv};3*I|kTOS__>GOEmlLRBhu?}$srh1|H%9ve6fvV z?2EHWvjsCcj8=**QYioWQ~L%m5K~4XQiLi@2AB;NRJ-DoSZ;&zPQ~D$9rjLp#LYBg zzpxk!2YyX!VARZRs*OQok`dbnBGxpYvO`La64rhRj7enQhcrw=9-MF#UZ^CdUSMPf zn!r|CGEev>ESt>Qr^z*A(cU7R>?T+%&MMd(a}|{}k9=pA3J%)5SF+0pR;fF~Zo2!W z#ut@Wjr?{?DU`N-AnnA`P4?$_L>AQIhQIUt*W{MXAT_{@g?z_GX%@r?OsbETD<4<= z@dY%x;SxKmnH-xf0F%5)L1Bk`TAh5FjaMw^Atd$SBByA1_&&ooZBwB|SK@HhJp{NdC`wB0FBNT6xJ8_t)3O+Cf~J@gNgLLmES_wtR1 z;0udEjT*_HTyn!)L_>2u!+d_jVw4u~iPR$ZruMMXl*+>RC=tr!X~6yrlzGYSUam@P z!qAFe__a+uwpVoW?2V>qcdj`9@cm|K>ZC^4;7H$??0Edqk=-C05OSxTP%&)AtCEdM zdRR3hez|!rIZ+n}@fB~Tt}$C`QBspiswuj>yh5FP_k#N7PV_}rcW2O9n$nBFqY-XB zj1Ev{*N&FqUQip8?p{%QVcD*uSy{YR9o z6QHlt{=A;@9w>a*+1+E@#esm3B6>`3>-2Y=&+6jM*BfZ1;`jD4oC87Bg93vZKz*WK zxFW!Zn|=+-U%hqJVPq@PGoGl!9MYYgE$M^+Dj*ph&g{Ic>T2q!(y9uV8O?X7O+TSo-e-5H3i*`L9S_YM7`_- zAqbM8BY&3ZjX-~eT@>DE8g-{t`YXwZd-we81@%VU`PK_z`)YDRCQUmf9&v0rkdBV- z7l6pY$5l)d`0Fay;o4t#;?Cbc{)d2IoqW#%y^K5i9{L z45IHp(rk!tns!6l0gxX3xnS{RiHQJkE^Rn0oVZ2BWDNunk4yqVXmvIkZ9mcQ!u=EX%$)8WgwfGx>A>$6_^=HYFL#;mMgG zF|FOSC_8I8!V=~Mx~W=Dc@WA|H8;`0_iCOA%i5_XIexwFIt%`J;!3w75Xv0r)g0(* zCW2b-39qCn>{JNuQ_adZY?A8k{q#cIahNr)!$H))^;POIO206cm+3A8y6Z$2ta20^ z$mCXkh5^CZAr|1=PhL zaD)z-20tk?)o9(OZ;GXmi=@<<)V=0?)t~3oH zHOgco8EXZ-qz17(boCVC2tI@^X@AV4Z6^~Mk4VdC&-WYrcgDQ z(Se27h1Dr@0`Z*rrb58&0pxFcm*L?$R|Fzl`hwLNrU63dhID#^O15l&K680IXDl%b zbx{d*F{w(}*O)#q>z%se?)o0*Nv`_Ro(b#2eqOL#g1$r`=9Gn7(lShnnqd>7uC>rY zGOiM3OoKmSujwdJa8OKWFypz(D9)~}XX)NMNm-|uzv{!i1QG+oYhe(>`M{~Vyl|OB zPlG|PyF9Tc`}bZjGWRClSr6-ebxTf~o|YV)@az4}F1H3fRu;R0=k~Yr<9Y75cTw4T zr_YP-dribR&bQ9%W2!HYe**w&1x`$DMZkact zj&73=B7FzTd~D!KJ5!StmmB+;-j-=Yai`~;@#2ia8qZkd8XkVl7=W~IyTJ)fMc}dW zvXE7fJjckzlX0wZ{O{h^@EG=_tfv0sL^Y5VOmxB8P%rFwr*JjS^;t0S9=}du3@&~@ zN2mt7>>AUpz-O!eX2)c>)o$rlWaGJUieCKC(l~FP_a~r+I9+Yte4Ta=n>gQOqDKK} z`xr3Ye*ghHmYhokRR!}E9z&kVmdFyHh_=!8yd{XA46A>w1M=#-BG_*86*bPb)H;#X zqcu~+WOT8QNj0wCI-!2dnR}h~*L(1co~s<4GTDdT*D!a-nA#)#L!D z+bC9kgAANOb@ELW@sOrXsK3-mftZ}4X!&Wu3KoVPTtRMM95^IfupyS8UmomfpBqm6 zb`Y+*OlW4~;EYLW6JkCfGIsBr6obs@m`6=6zSKXK|z(WiOk^NC#@aenOIeb%jx zU1`i1L&Tx}l%+cS3k!qZJ@c4Nw`oKQTe+AHJ3)M>BR#BhK2}eS`vu=D~us$ zt^5`8%c?-&neG-t;_JURL9F0fLk?~>yZ%$59nAyDmg1fY&P3L>)gjcv-bjI_4z>xn ztiu`Y7f%q)kf$nwR+Ej0Rze^UHK=roM>hSOCYOMK_T|p#4dES5q*Ot@f;lDUO^tb~ z6H7cDx^7%QZN2p&vvca}Ce+94%gdKffse-GNd1wGIoYVEl<_N~>;<@pW0t}d`Vb3s z*IxP7HX%K2ziff2FGD+5ldGo630vlet7;GPqS9Qm0oG@dqeSB$(sLp<~Dys%`iSICAFF8G?YC^g*f73_KrOZB*-@k;4OHdZ*|Auk6H{HF` z4a?2Z>Xw^UrCU;?M^_Il;_58!oGdQdSqA{xl*PxarB{KgmL`Zn97X!{5@UZcCDu9| z4i_Q&TbgaE**0PMLMIacf}nia+h(S=E}yyAJt6R@409VY{C|651R?v{Oq9?2hKv?3 zYZ2ZI`6wYSp@J0HSGWIGVBljKB4=T2Olya)1Sfydz{005qcNji7zd>Q&6!h^_==C@88upvbIN9DGt?`E zzC)i}@%ruj$L?||Vk1Zxi%Jri3#odvXP#gl8KpnQyH|3h0wJj;*q?s`0^S9_oz#>3D1Se>3 z!%!WFO%m467_acXKy)xtL&KfHk1wH)~;AnUQL#M;RIz8T#m-mqD>; z`02hU3N0>Hl(UOEC~rsJU#^h0n!l$mevuGn-PMzekb!u)uL(Nd!-KdDnV3V*&pTN>#P-= zDz0V|{Q8I-k8=FY!n>D(98@^ULDWr6{Mhma_5<`uZ24-*mNW0E17PMHJtvUqr={8g z=6+|$yhVdl`f-Ui;k$a0tA%9lHCv1E;z}BfbB9Labw9l(aqThvJ?4YX>n$OO3Yp0C zx5$s+?HrgMS|K6GcTAyB1iRorGHlWU6ip1qeHLQV6yhdkT+s;EmK`k?<$BNiRtIn0 zW~I=ZoA8O3*D5&4+)n&tu@-A}k>i($K+93u0CstXJZNC0Q+BztLly7Tj`qrrxJm=h z5b86)Uu9?4h#;Hr574KhW)z0j#$7k(gLTft!&B}vzN53~Ps-EjYcWpiBba}-pnI)U z^?P*GLf@X7uo|_psD=z0vI{y@ac*=&ejuMLql42lI{E+7Sp3~$Y59QSf6H`u1o8|> z;pGI}x&-Iu%zYg3i#PD66AKW8{`^axgr4}7(Bdc$87|B!kk_)-5J&6(qw5@lEA6^& z-LY+V(y?vZwr$%x>5gruW81cE+crDtBxgU*`&Avhb!z|JKkr&=tU1RRS1qaG}@`Ra#f($>TFJ(^Me%q z=N(`Fit7R}KGQ?s{s{g*`y;sjv%ndMQI!LrNul!*fPxK_g6nGPVe~PzHoIRo(`&u} zZ=k#M`Z$t|lcOz7Rz4N`i*_Ri(ZkNj%WaKqNqIU}(sQ+`yh>Qzo0=#3Dz=r*9ISvi zQ|#4!p3Uc0g9e#ox;;rSKKO&HJ$+dH4;ojp8qa>g8{!^sMK^<PoxLgc`uj3>~t_ON=zZfNJPLc7mLQ&#~T4G8{a|LW%kJ zhUvITC^e&eH~~#bqqIDlY^@uxfmqBpLuOsd_HIq9Wf~IQ$a-E)c>L?Chgr3Y)wHBc z`(H-SQ7ATEimNC1dc&M{68R1qw~q9%5ADJJn&iVy3%v-`J5(dIoBehn{vLpxVMZt1 z%ytvmv}Q*TF!*JVpda2gL<}$|bX3~B#|bP^g^}$AOQ-Aup$;my z1rv`Zgm93bhLQvu&9~o>s3-uig`GG-$}%;!yC`R$m3k)oOeqMo1mysoIUUcRC57i1 zaew6YI<2Ve$@M6&d-58;bdQrf0>>{|mNs*d;F7Ur zbM<0rvF*yhkyR!jjtjB42Ek?=I(OQTFIh#!lXk=ja=_!}d1IbS$O!>>PApS;y}T35 z&(`GFBT{~gG-?-jfk&G^gVCG2bYTC{csIyD@rq^-A$3zHvfpK{3i;viH;5)=Xu|1TDO@7uBojY3Jl(O^^fJzf@NEE^F(`r>GisJImq-UYzVY`RRiC-|5w!kh+68uguseCpo8D$9~a9OM*v!X7^)($ zk*;Z(ck$JqSQCD=_^2pcu`va43>h*sJxx~e-M?pN=dBEot5qy+&(%aS0RPsA#CoY$m4$TTpts4P|fHuTmh%U>_NN=HBi&lQyem%V6X=pv* zD95y@$ck@W+a;GVW|0o7o}l6cvUfdsEv}5dcBoV*GH#ZX=3fSX|{SaPILD z!Q$E1K>($>Mw!Kp=428ktWfYIVk3XjEBMwF47QG9KMp%bUb~@L#$;Bb7~4iF;0(Pw&e0{#8FpB*Kns8rkpb{5!4PobJV9qc30Q4px$=d7@{Qo zDiM}7K!vknA3x@nG%hq11PB;k+N-x-`zpK?1=K_!f_quBxJ+s@SPURmVJ!d5W-}+M zEX;7EgX>ZjOl8X5ZF2)Hx2fERMWv0cYo~B*MG3j&HzJ)O#>lqBQd|)&#ie-Cs>ghR z4Jkmfjv=q5xoldkJ#aRuJUo<&Jy7$Kea7@Q4$PKmV+Ps7CzVlX-a@F=je=IbHr-i(RuloRMK2s^b*u7!Rf}kqFWA z_opGD%3Z6by2m++=o$a+(nY@ znDPZbw}!zYi%lVNdSyB;0T2#k!D=JLr)Ex2Lf+6F2*F`Zcs>ws|KXt)iM!~K!A^3` z)NOyKA~H-nBFsw~e&v;KUy-B`^FCu+q@Y=(xFhB#S&G#g@2+Oi?a@;ja?@B9TqS!9 zmk6W#L;Few<8@JRe`mv=pwpyZyxhpEYxSq4ddcHI)f*Wg!7G>!5Wp!U{Qq-8tECd= zgOUTSi14X~l^|HD)hytUfGRaT6&*EnJqj4opbgNxBN<9XA$!zy#lMxrYLbEC3(9am z>C`)=?DvdY$2K=t_Y;vm5l8r+nxtt9{fUwu#(i#S)OzYGdkV5?mmaQStHV;DDG zrnlcKyPo+k@VnPv|H^!0FdRaP?X`M;ySKDuOVo=rd(bXpRjXZQ1@IKFHJh1^H|s}C zRbf3jEzquJ*r88?wCT2&u5DhUS?VusuNZqx>BdZ%sy|g;Np$tzeF!m}Y1{WP+tMYj zd_Z4@>ChZT*<93_GMODe;*DXDoHNS{I_;<4x3}5WK!?Eua&Ne0>&OZ)eH3v)xz9IN zJ+%scq#5BpGY)dV-#6gIyc+18N@KvQ-}B)PhY1%~E3_#y3h>7JzF$?p|lh)7v+Or`1J? zr*eOQ6Sy4eRFwT?KO2DWM*Cax$8l@t~?`PD0A<*(9S|Zxp*T%d@%mjL^jtf zR;LfAQyIbu4p10EVd_VB&yu%GmIX9pkmI!>aks1oYheP3SZ%oS4qH|$xGx9z3N|fX z`L>5H?HGfs+Mu4KCZohKD{2aH*~`2q9vwE94#@ zsy+9F2wqPgo=%Da|L)oJIS_RD9=_V`Qx7Xi+8okn2pkRmLhgBrxwC1!uV@9~{8@lc zrQN8(0f=Q;mqL#A4T*tmZ~pc(=0FGhHXCeS-E9Bos8-H^%4nqM&Nn;$YDj`zB&$1T z{G?uy7vy7RC%7qQxfjdEpQ{ptb98e`T=c0Qlj}UxAnaQ@M5Hq42;fD1PR8m zB6s}a^gBZp4Q$;9I=($?`#w>B0t`l9H0s|F^j-->UcpK@i3V~uJSnU@(Ioe2VVV-> z>9_Ur6A>ety?J*Mt6~qD-qXmlRk?A!tA0NITv&vqrxz7zaK4h0{KepLjJcjqe+0V? z-vuD^OYoSPnu229H)-Uy=g=NT-i!F9*|*VRVxw(+-{TaR$IM-@E#aO$tIu8H&&s%OSdys$SWI?+=GZ{At_Ewi{I z?0wnq5}lCUpnEd=ToSGzg@}@q(TS7BiOxLy1~+DJ?xHN%^U8s5@fax}XhAD`73KdT!PR{;hMGIJ z=rsIMd-B;i^WK@-^ZEIK^sS{9M_ABM>B>QY!s8*>xn8lpe2Hv@Mu*yp>S*mxM#9qJ zx{(+?Cm^PR)~sV1n!zQOwkc7k;hrpA$2G|VTR5{fSnr}OnO1As-I=V1297!iG0>(8 zfj3_LuFQgF7@FAkT7QjhT_<$RmFxihNXR=BnQRB`RNc0#fBD6>gz~#GXqWfGeY1_( zS!vc(EI9YE-H5se#Lv4rx4`B`og^i2r@nwddO+as%B#`PCTC#q+U-_znNG9FZKA>J z%AvW8po6+L>%+h`1I;qFMA_s51-jGh`%lW5ZT8vl(ty6-x0&zjZIPY2w;$t+Tj$i4 zT)uYT;`?hHa3@oB?;(EX61(R;{HS4%P+*70x+bL$3ej$e3H#j=T5*PYu~8|Ol|v)gVlA+_PnVMf4QM7njbc$tR$XlkA#dKlyJaSkl_A^1=yFZ%%a)P0RLxV1sj_Fm9Eb#3P1u_5 zKb4QQS*F;inH?9kIjD?t7O%$_k7#FPasbFD(-{iVhU}*KNOo>mmetj%er4H_;13f7 z{&^VXwnaE~C_Kq{PO+ll-p4D}V}toP4m$HbeoPYVb*F@+d(53A7J&6Zs*K24Gdfz9 zOB}wdGZ!Y_Ea>g&&Msdo%75(FM8)Q=64x8y8sj3gV7nHLAGZ56gZB-2SB+IKA^~t! zFetfZR{p7VG2+b)kWZtN))uK|T>lX`rViT;@&wZq!33$vQv1yscTTP47~?QuO8N13 z%@);gUd9+_%;UW7RYHP~$oD@)ncu|P&G35FsNcSWT0*fIoewWU^%|5A@|-4lqknW* zv56Gq*6}$-{Wh>d?G<~I_><=;9_;}@W75WZk~tM4iiV%P0kfT*`X0>(ABXK77&usj zh0Plrkr%D+E2hXLI=FI*nG(W!G2<)wyGz78_&0(TD7swdMP~YvC%7x@WQ?G#Rc+v# z5t!^QbG7A)Y{HKKo5mIK3L}K)H1}8kFVB4r_|8GgZ@hSm4Ju$;lZuy0H?(;Gg`^qm za|i765l-^PJSkZ=oHwNr5a7nAM^rgri7OqU{)%XJOk`x{)H`@BdKGHq^;Dtj0qreq z{^hfemx!?`x7a;h7;X=xiCU?`NRxM@kh8awvvB>-GyKvKVW2cRV=TOUjvlD8Q-TXecmkSZ%xYF5RTs};^`mo+zH=-5e7iYlJM-32!3 zeXJ1aReZIpcc_24Em`-tTu+&zk`KySEKhp8cwIIaSlswA_`06M2Q0nzhLQxp5M9$nkHtdLISH9hb*F2^~=xi{IfnAtVe=jRAmto|sHFxD6lEe^nJog=ik zKjArzgwjA%Pt2UVi`-n-%1PWvWAndKRN+awXYvi~Nm5(8;fciaJF^~ggY?)HCWZ?Q zV3yjC&2Z-bo(fW8P&__$ui10uMpqXEu*yfJsVgWO4zcn&Ke?_*wDE@;NqfA3p9}Oo zOPOm^k4@Wc%IbqqVL;?XfXWmv3^#$KrVdZ)%Xl!evxV#VKdoC8A4t($ou)LcD_kDao>RZ77O`NVp~N{5A(mg8amRGn@Im_4+! z)xc|U`hnEpTxFF$%^g_OheM#XK(B}@<&Fn}UZ6Z+>?@wjskxvJ8%T{%1P!gbWUM{B zJPE8gZ)xjO-cE?R2zTFNC%ZyO;q)Uv(&y4yQ99&u!U+EzUn2RN!TicwV=y;_D-BN& zdcv=?sKH{jcn`ADur?jd1a!h2z%6%vLh$N^pkegeSG#D>I%%SW!Lk)HCqcL}<*!4& zW}jY8R8c_6kMX3AR0F5s3&L%ClY;Bhs7k}gaRhT_S}1K6dFlho;lSd&*7yWS`S)JS zG=XmV^^ENJ`JMbccx@cqy17tjKOZUq1UXAWfflFL_-RCOoAn8xE!j5=085)QWw&xG zwg@##^0H0t=+dXb7oa|7k|}s(=1`^j;En)SCt1E$Y!s?Wk-HfFL}o`3fH-z41L_8` z$+ewkI*g(jH-pi+PY!6D%StO4@z^OYS+B>@xN+}lwXDY~NVynfJ`H=HC3ActTfl8+ znjUn6sj(|S>H^KQIEb1C5U9t<+4=Q4!gnm_Aqyf=`<-Hiq4zSUNZ~Y(4<2mFj@bzs zUVJeanlPKVS>RBR0(IpZC^iQ|Vb&gPN#WrjZFA8#d22b6SPZ){*Eo$T=?MD zc$eEz?Rf|IF9pix8WvT`uQjkwns%0;r{iMd|K&L;{#;9i7xAFRCYBs`ma~ z<8}5IzUd|(o@A++wqkgHU)us=O{%S{Jmm%$Ze^a4=RK$ZsU^K~eP^9X0=gs{o5L%y zD8*k#YF^sCdj46t45=D_oDw`GqE&5W2Rv@^$5<=+_pR8B0_8J38Ysby$D#;0OedL0 z$$jjCH>VIut+hg`gr^KEZf%;`8+yD=6EjgHkB`+t7FoxX+*1=5P~naWqk3C%%94X* z$cw~=ox3vuH^FDDY9fY4+xa7=adwQpo(8#PyPt(BYH!oz6Lp~!F`2wE*6b8Rl>HdD zcW`UYBL1sMRHlH6IJ**I_Uuij90f7WUVuBBbrv1vSIsUy8pu}-+0rDN*r4DkIJI!o z56%0Gb&aX7HeQTYG&0#=MW_94g_vy>cUrV+ykOD*+-8PX{OT7^T*8_2^;sucJhAA( z+E5z4O1zb?PlapyVx47Mnz7lX3Gs7E;wM*orzM5#=b?wS-M$)`Q=mmdQ`GK0?25c>8vy~i2J zjPq}F4+J6oqvHK*DlFmIByr$40z>7q5^VBFYbc)cPq?*|NneluN6UiYN z8&_mz8toLXufAYaVw|)|M~O-qMmZ(FU6M>{tEiM+nVm{PX{wO9@R?Hj9-qXmC11Gk zIiX!b38U~izFk4dMe2&;$xT^blD9VwTLcb@2w!M5GR7h3wKk{$=}zrrPKlTQXEJdr z0Kdq?zy`PFaD@?U9!@KR0=!dzc(%+T+H#EXaE zr=XL6kfvvFzQFkpD|E@gf-#1>E|V&P40gwu@QVq0R+M!<|5ED5IdMm%a$8Ttwxd7v zDo7Hzl-0_7Octe~>AOM2xa1bJ3Tamr`fMrDmb*=jt=%heQP^pF9Uk;dV9c0w12Wt- zYMi}GUDRgD9{h>~#*fDl)>vaTV!uAZ*dEm_7F!3_v6Wlzo9h1=d=HlN|eiq82 zJ7YY^9+v#lAF(Rm>epHkWy;uv&xuH`OJfia?ud;+J^DJ9McGz_xt7Z!b61M!;*@wu zy(iem_m^o5@A-j<0#MkL;8kD^=W#$`8H5}B7;FiL+2qQyXL?1%nTf!X?-D?y2R;AK2kAwGwhJAbZe@Z@jKK07xDqt4upJ=6N5t! zjyoSuruzYtQNSMskS266^Nnyg6;>CN;5m2<^Xt*mbeJgotf7JL?l1~q|L(RSpK(C7 zk@kdCM7xp26f&jd!fPHxPZlLV5wX#3H(aF!Q3R^C@aDBev`{7W)%)6rQiqWQ^BPIw zG0iZ5s%EHXLCK1K$>3_~P;G2DkV~|J|msiF^Zm8S->xna)QuwkXP371madO+4_v zkO?m~nRPM?YL!G=pul5P^#YacyvBNkWO>Su4y!LANDOCMB-3 z)$SL(5>MOK=gE7F1pjE0H~p#j8pP*RTJ?*t98)+FXStA%?E6p9i>gIg&6yHf*1&Nw z9=abit&eUW0I#h{g+bB&?i~N8Y`TSvUH~(IP+8} zWmTS{u?QDZD*P54GFMcIW!%cVDizc*;T3am;Cf9-@J+{7`t;5mh`C~YV5-mM=xV%S zp_&%`kf`a)XqHca%A~aZby)b2U(2GMa(x4!P@gr_TbyAc)P#Nh<2g>I*l_^?*ox8-@iRusy5GpRp5oV6tpOP)?qjtuO>D`v@T9A69UTnfQKIgD39(AETi_56wcpnQ#2H%4Kws^*IBBa)QxMR=z;IAtkRpP+csSs zbwd}KA_Xfeal_4Am!HcZ_nd-7o!5IyA}v$C&-bvl6Zl7oGfs*ZK_ppA`rK|#T}bZ@ z)rfcWJ5>+5O*3DA4EWE^F7e%xQobC!&)_U5$d+~iOm}U-F(t%bq#oWbU-`$u8*e1=< zLhivKt_P`j#p9lgi6pmGPjDQZv)dcy^z82KN@>D0p0*`w_a!RA{nk?lU`$auOA!~K zMUxwu2cC9cU@6FvJUj5c{m;c;O??<`m%Jupe3X#+QCtZvNG$l0<7ysDRAwgIK{J%E zVN^HBeXa!l+0~-XdG+7}ePosYA0L@Z zF9;a`W¨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�rZnIz7F*6`VTUoc)-9d8-ml!NR0nf z=Ijvj(`@qA$$ONx@=tp#bQFGToX_Xp~ zJ5iEI)3P_f9hf0D_{vPu{ZTse%DrOqWMa(e&R)QDkxMVnF1A`rYMkExMf-T|Yq42( zn#rv+)9_?%0Jz?pZBp*l+Vb}@(~doo>=G<>=NSCej((+0Va(K@+BVsAS0BJ->L*tj zO7fJPnfs&(Z+c9x?GbM;-=NP_HSC_&jp;IzZHFcxaE?tf5F}TU*aP*w>ZmB ze>GOiI}e1rBJU-hf!h>?gn3>5CiVu3SC50!uOUYT-%gMxZDfH&^@MJ)<>yq3L|!tCC&o;(d;T zKjQF40kO1SEAA`(6}wA2H@pEQtvB`{i&pwr=(jz#cDpVNH3ZZGU~VeqT`H1e64f7_ ztjn&yg5k>wuS*{~ zeKQ%Hiw9EU50A~7+f~ZlZ2Owt8f^<#SLp@j^l+Kz8odb;qi*b~y5XBgIRhEMq+Jb*2L{Y4 zTatiFiHDJZ5EJm2x;gMvjC|3y9cUAQ7W<|#Xq0{rl5M7-HFg#LCJ#EQ=qzLx^Swp` zVC81wIN^leTT!|^zbNkuS-v6(@B!P0ZMw_JdY}p349|vK4A%<8^%~cmbB^Sz$sLxl zc$JBl5CCb}1cZaeJfn}2_fWcIx+(gL%AJ1*&98}k-?jQ7l9% zKieGT`w?)zA8mp1@su_dlcxf%0&Uor?t#Ff#l1+}AfJpbBmNOPyyZ{Z-;}|BdEgVb_gf%#oku_PpxAg*W~?_Xa`Dq%TIj*NMd%f2}Gid z>}J7*!s(O1<%sA7O^yx@LW=+MQ85iEyB8Nz=l2K1V#JKMw4(c3#M}ktCh68*dhY!b z_6(@qF=+7%^3^@cpGVRi-$;jh`phFh<%Rt1hM4LSsrdYqF`XlK70dE52xJY2Y)Ut# zcSqqbjiKWRnz0IXB3YUzfDa*^ON9iYHuEh~%F>g^$2$ahk1>WX zmmMGa&=b_`#94mHi3Uciww?>C!0=0DyI%rxCnE>!-&BQVYk6Ls1@sO8 zKM&mXyMb(6zCQ9pBZ6;4maBZfdl=oZpyoeUKAne_%D*a%`~W}%yH1BMuFBF)KtT9c zW?x+vcPgO0DQ)Pce{1S`_k~#ZY0!H+wZ{Xwrm3EsRk+cjlfoFO5gayW@A~=ip85_? zC>SXU)cvU&vgbKSy9?)@1*_XdDb*TIL@|rLmeafSCO$NX8 z*vmEGk*AD~9RoFHM+Wpt$ow3vnT>jIozvyL3;$f!%C!EicKY+P25-tT z!q^={q$SYPGOQe9zHc1?jmqKYxTP0sqxWE0X#14iZ=n&VIsYBU_`|Z7y!HdjdBylo zY77ekiuw!k|F+?-I|Ro5U${xYeGNhpAs$kRC-$v?SAN+=C?nS9y$J!$&#Jv>d+8G z_BjE`aJuF>=Gu9^a(jK>;rj-@L6f8ugk`!qUytyu)#F&)@&uG^J5p-TY^d0F+`kTl z6bTxz1N1u?ohNFo-k!dIYFa4?VKI2s#}L^}pBNoQkHE~t zJt=5b8Xw+cj6RgEk+6svDa@1mjC+_% zmU3Ehz1C-53T`3;9Nzu(iu5+!OPrg>(=l~+4tW|~hUy(5MiEUtWvz6RqyyG_2X4t| zsEXM0qw+EfA88Zeca+JPq+V#N)@iCqT=}9a_IPaMZGd4N0j``gvg-XvrjQ%{ef7Q+ z?6foVz_;;QP49P(fhK{#XFUPjNOiRF91I230qm>!Dy(Sm7K!d6ftKZ#qgaAIR_4tC zpAhmgA_S~q3~**rfJ)G}q+-4k$x3M_H8z~yrFfDTendQOo2OI|12h-DnjTm2gxeV` z+dG!)3BWs*d~DO1@*#?s5n4!KfC!KXfyZgf<8Hcr#K#D>V_@f|(aT`&vGGrKnlW8Q zHd`Tx!9ERf;DJq8PeeWA3yHkHy^&4Y0TR1vEFKjGFrPH*mZ*xZ5_ICm>k}Z%=@e!B zhDSO<)@mPB_JCB3oYTZ`PmRYry!jj1BD-5D3^3~!PM-oLH^TmE1VL8_+`rBY=G0^8@`f=;A^jEd>ZVQ|d0
oBlEJ*E#HaUBVgo> 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 T!r=rA{;l>Qk&bPEbWHjmD2^D% delta 217843 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 C#sGBy diff --git a/package-lib.json b/package-lib.json index fb23920..196c1fd 100644 --- a/package-lib.json +++ b/package-lib.json @@ -1,5 +1,5 @@ { - "version" : "0.5.1", + "version" : "0.6.0", "name" : "class-loading", "description" : "Java class file parsing, manipulation, and to human readable representation", "homepage" : "https://github.com/TeamworkGuy2/ClassLoading", diff --git a/res/build.txt b/res/build.txt index 071669c..2c05246 100644 --- a/res/build.txt +++ b/res/build.txt @@ -2,4 +2,4 @@ Run the following command to compile java files in the source\classLoading folde This folder is for various java files used to test dynamic reloading that cannot be part of the eclipse project's source/build path. Navigate to the classpath folder, then run the following command: -"C:\Program Files\Java\jdk1.8.0_112\bin\javac" -sourcepath source -classpath C:\Users\TeamworkGuy2\Documents\Java\Projects\ClassLoading\res source\classLoading\*.java source\classLoading\base\*.java source\classLoading\load\*.java -d destination +"C:\Program Files\Java\jdk1.8.0_25\bin\javac" -sourcepath source -classpath C:\Users\TeamworkGuy2\Documents\Java\Projects\ClassLoading\res source\classLoading\*.java source\classLoading\base\*.java source\classLoading\load\*.java -d destination diff --git a/src/twg2/jbcm/CodeFlow.java b/src/twg2/jbcm/CodeFlow.java index 189d2e2..6b54428 100644 --- a/src/twg2/jbcm/CodeFlow.java +++ b/src/twg2/jbcm/CodeFlow.java @@ -1,8 +1,15 @@ package twg2.jbcm; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + import twg2.collections.primitiveCollections.IntArrayList; import twg2.collections.primitiveCollections.IntListReadOnly; import twg2.jbcm.Opcodes.Type; +import twg2.jbcm.ir.JumpConditionInfo; +import twg2.jbcm.ir.JumpConditionInfo.UsageHint; /** Trace all possible paths through the code in a method. A code flow follows jump, branch/condition, return, and throw instructions. * Circular paths end at the first jump/branch destination which already exists in the code flow. @@ -10,6 +17,9 @@ * @since 2020-12-03 */ public class CodeFlow { + /** The size of a GOTO instruction, 1 byte opcode + 2 byte operand */ + public static final int GOTO_SIZE = 3; + /** Starting at a given point in a bytecode array, follow code jumps and branches to all termination (return/throw) points potentially reachable from the starting point * @param idx the starting point @@ -20,22 +30,32 @@ public class CodeFlow { * and can easily be converted back by negating them again. This differentiates non-terminal indexes from all * valid terminal indexes because valid code indexes cannot be less than 0. */ - public static IntArrayList getFlowPaths(int idx, byte[] instr, IntArrayList dstPath) { - for(int i = idx, size = instr.length; i < size; i++) { - Opcodes opc = Opcodes.get(instr[i] & 0xFF); + public static IntArrayList getFlowPaths(byte[] code, int idx) { + var dstPath = new IntArrayList(); + getFlowPaths(code, idx, code.length, dstPath, 0); + return dstPath; + } + + + public static int getFlowPaths(byte[] code, int idx, int max, IntArrayList dstPath, int pathJumps) { + for(int i = idx; i < max; i++) { + Opcodes opc = Opcodes.get(code[i]); int numOperands = opc.getOperandCount(); // Type.JUMP instruction set includes all Type.CONDITION instructions if(opc.hasBehavior(Type.JUMP)) { - // follow the jump path if it has not already been followed (to avoid loops) - if(!dstPath.contains(~i)) { - dstPath.add(~i); + // skip the jump path if it has already been followed and this is the beginning (to avoid loops) + if(dstPath.contains(~i) && pathJumps == 0) { + break; } - int jumpDst = opc.getJumpDestination(instr, i); + dstPath.add(~i); + pathJumps++; + int jumpDst = opc.getJumpDestination(code, i); if(jumpDst < 0) { - jumpDst = opc.getJumpDestination(instr, i); + jumpDst = opc.getJumpDestination(code, i); } - getFlowPaths(jumpDst, instr, dstPath); + int subPathJumps = getFlowPaths(code, jumpDst, max, dstPath, pathJumps); + pathJumps = subPathJumps; // end this code path if the jump path is unconditional (i.e. GOTO or JSR) if(!opc.hasBehavior(Type.CONDITION)) { @@ -45,13 +65,224 @@ public static IntArrayList getFlowPaths(int idx, byte[] instr, IntArrayList dstP // end this code flow path once a terminal instruction is reached else if(opc.hasBehavior(Type.RETURN) || opc == Opcodes.ATHROW) { dstPath.add(i); + pathJumps = 0; break; } i += (numOperands < 0 ? 0 : numOperands); } - return dstPath; + return pathJumps; + } + + + /** + * @param code the code array + * @param offset the offset into the code array at which to start finding instructions + * @param length the number of bytes of the code array to check through + * @return + */ + public static List findFlowConditions(byte[] code, int offset, int length) { + var conditions = new ArrayList(); // track GOTO/IF_* loops detected in the code + + // BYTECODE LOOP: + for(int i = offset, size = offset + length; i < size; i++) { + Opcodes opc = Opcodes.get(code[i]); + int numOperands = opc.getOperandCount(); + // Special handling for instructions with unpredictable byte code lengths + if(numOperands == Opcodes.Const.UNPREDICTABLE) { + if(Opcodes.WIDE.is(code[i])) { + i++; // WIDE opcodes are nested around other operations + opc = Opcodes.get(code[i]); + numOperands = opc.getOperandCount() * 2; // WIDE opcodes double the operands of the widened opcode + } + else if(Opcodes.TABLESWITCH.is(code[i])) { + throw new IllegalStateException("tableswitch code handling not implemented"); + } + else if(Opcodes.LOOKUPSWITCH.is(code[i])) { + throw new IllegalStateException("lookupswitch code handling not implemented"); + } + } + int jumpRelative = CodeUtility.loadOperands(numOperands, code, i); + + // form 1: [..., GOTO , instructions[], setup_if[], IF_* , ...] - for()/while() forward GOTO, condition after loop with backward jump + // form 2: [..., setup_if[], IF_* , instructions[], GOTO , after[], ...] - for()/while() condition before loop with forward jump, backward GOTO + // form 3: [..., instructions[], setup_if[], IF_* , after[], ...] - do{}while() condition after loop with backward jump + var isJump = opc.hasBehavior(Opcodes.Type.JUMP); + // backward jump, required for a loop (thought experiment: create a loop, using Java bytecodes, that does not jump backward) + // although a code obfuscator could re-arrange code and include backward jumps so not all backward jumps are loops + if(isJump && jumpRelative < 0) { + conditions.add(JumpConditionInfo.loadConditionFlow(opc, i, jumpRelative, code, UsageHint.FOR_OR_WHILE_LOOP)); + // 'for' or 'while' loop has to evaluate the condition first so it needs an IF or GOTO at the beginning + // 'do-while' loop evaluates condition after loop runs once, only compiled form seen so far is: no GOTO and one backward jump at the end + } + else if(opc.hasBehavior(Opcodes.Type.CONDITION)) { + conditions.add(JumpConditionInfo.loadConditionFlow(opc, i, jumpRelative, code, UsageHint.IF)); + } + i += (numOperands < 0) ? 0 : numOperands; + } + + Collections.sort(conditions, JumpConditionInfo.LOWER_INDEX_SORTER); + + // post processing - convert special cases + for(int i = 0, size = conditions.size(); i < size; i++) { + var loop = conditions.get(i); + // find and convert if-conditions that may have been miss-identified as loops + // case: an if-statement inside a loop where there are no instructions after the if-statement and before the + // end of the loop may be compiled as a condition with a backward jump and thus look like a loop, we can tell + // in the case when it shares the same jump destination as the closest parent loop that contains it + // form: [..., loop_start, instructions[], setup_if[], IF_* , instructions_in_if[], loop_end, ...] + if(loop.targetOffset < 0) { + var targetIndex = loop.getTargetIndex(); + var loopUpperIndex = loop.getUpperIndex(); + // look at conditions beyond the current one since they are later in the code or contained within the + // current loop and a nested if-statement is contained within the nearest parent loop + for(int j = i + 1; j < size; j++) { + var loopJ = conditions.get(j); + if(loopJ.opcIdx > loopUpperIndex) { + break; // skip remaining conditions once we're past beyond the bounds of the current one + } + if(loopJ.targetOffset < 0 && targetIndex == loopJ.getTargetIndex() && containsIndex(loop, loopJ.opcIdx)) { + // TODO debugging + System.out.println("converted loop to nested IF-within-loop at " + loopJ.opcIdx + " (" + loopJ.opc + ") contained in " + loop + " to " + targetIndex); + + conditions.set(j, loopJ.withLoopEndIndexForIf(loopUpperIndex)); + } + } + } + + // set the potential-if-index of loops + if(UsageHint.isLoop(loop.usageHint) && loop.potentialIfIndex < 0) { + var loopConditionIdx = findFirstIfConditionPointingToEndOf(conditions, i); + + if(loopConditionIdx >= 0) { + loop = loop.withPotentialIfIndex(conditions.get(loopConditionIdx).opcIdx); + conditions.set(i, loop); + + // TODO debugging + System.out.println("converted if index for loop: " + loop + " found IF " + (loopConditionIdx >= 0 ? conditions.get(loopConditionIdx) : "-1")); + + conditions.remove(loopConditionIdx); + size--; + if(loopConditionIdx <= i) { + i--; + } + } + } + } + + return conditions; + } + + + /** Find the first IF* condition that is contained within the condition located at {@code startIdx} in the {@code conditions} list. + * @param conditions list of conditions, should include all IF* and GOTO instructions in the code, + * sorted based on {@link JumpConditionInfo#getLowerIndex()} + * @param startIdx the index into the {@code conditions} list of the condition to find an IF* condition within + * @return the {@code conditions} index of the first matching IF* condition, else -1 if none is found + */ + public static int findFirstIfConditionPointingToEndOf(List conditions, int startIdx) { + var withinThis = conditions.get(startIdx); + int maxIdx = withinThis.getUpperIndex(); + int lowestOpcIdxFound = Integer.MAX_VALUE; + int lowestOpcIdxI = -1; + + for(int i = startIdx + 1, size = conditions.size(); i < size; i++) { + var cond = conditions.get(i); + // stop once the condition isn't contained within the target condition, we can safely break because the loops are sorted by lower bound index + if(cond.getLowerIndex() > maxIdx) { + break; + } + if(cond != withinThis && cond.opcIdx < lowestOpcIdxFound && containsIfAndEndsWith(withinThis, cond)) { + lowestOpcIdxFound = cond.opcIdx; + lowestOpcIdxI = i; + } + } + return lowestOpcIdxI; + } + + + public static boolean containsJumpTo(byte[] code, int offset, int length, int targetIndex) { + // BYTECODE LOOP: + for(int i = offset, size = offset + length; i < size; i++) { + Opcodes opc = Opcodes.get(code[i]); + int numOperands = opc.getOperandCount(); + // Special handling for instructions with unpredictable byte code lengths + if(numOperands == Opcodes.Const.UNPREDICTABLE) { + if(Opcodes.WIDE.is(code[i])) { + i++; // WIDE opcodes are nested around other operations + opc = Opcodes.get(code[i]); + numOperands = opc.getOperandCount() * 2; // WIDE opcodes double the operands of the widened opcode + } + else if(Opcodes.TABLESWITCH.is(code[i])) { + throw new IllegalStateException("tableswitch code handling not implemented"); + } + else if(Opcodes.LOOKUPSWITCH.is(code[i])) { + throw new IllegalStateException("lookupswitch code handling not implemented"); + } + } + if(opc.hasBehavior(Opcodes.Type.JUMP)) { + int jumpRelative = CodeUtility.loadOperands(numOperands, code, i); + if(i + jumpRelative == targetIndex) { + return true; + } + } + + i += (numOperands < 0) ? 0 : numOperands; + } + return false; + } + + + public static int findLastOpcodeIndex(byte[] instr, int start, int end) { + AtomicInteger lastIdx = new AtomicInteger(-1); + CodeUtility.forEach(instr, start, end - start, (opc, instrs, idx) -> { + lastIdx.set(idx); + }); + return lastIdx.get(); + } + + + public static int findContainsIfIndex(List loops, int index) { + for(int i = 0, size = loops.size(); i < size; i++) { + if(loops.get(i).potentialIfIndex == index) { + return i; + } + } + return -1; + } + + + public static int findOpcIndex(List loops, int index) { + for(int i = 0, size = loops.size(); i < size; i++) { + if(loops.get(i).opcIdx == index) { + return i; + } + } + return -1; + } + + + public static boolean containsIndex(JumpConditionInfo cond, int index) { + var condTarget = cond.opcIdx + cond.targetOffset; + // avoid branch logic (ternary statements such as Math.min/max) + return (index >= cond.opcIdx && index <= condTarget) || (index >= condTarget && index <= cond.opcIdx); + } + + + /** + * Check that an {@code ifCond}'s lower bound (generally its opcode index) is within a loop condition's + * bounds and that the {@code ifCond}'s upper bound (generally its target index) is the instruction immediately after + * the loop end instruction. + * ASSUMPTION: the {@code loopCond}'s opcode index is its upper bound (i.e. the loop ends with a backward jump instruction) + * @param loopCond the loop condition + * @param ifCond the other condition, could be a loop or if + * @return true if the conditions described above hold, false if not + */ + public static boolean containsIfAndEndsWith(JumpConditionInfo loopCond, JumpConditionInfo ifCond) { + return loopCond.getTargetIndex() <= ifCond.getLowerIndex() && + // require the match to be a condition that jumps to the instruction after the loop + loopCond.getOpcodeIndex() + loopCond.opc.getOperandCount() + 1 == ifCond.getUpperIndex(); } @@ -66,18 +297,18 @@ public static int maxIndex(IntListReadOnly codeFlow) { } - public static String flowPathToString(byte[] instr, IntListReadOnly codeFlow) { + public static String flowPathToString(byte[] code, IntListReadOnly codeFlow) { var sb = new StringBuilder(); for(int i = 0, size = codeFlow.size(); i < size; i++) { var idx = codeFlow.get(i); // a conditional/jump point if(idx < 0) { - var opc = Opcodes.get(instr[~idx] & 0xFF); + var opc = Opcodes.get(code[~idx]); sb.append(~idx).append(' ').append(opc).append(" -> "); } // a terminal point else { - var opc = Opcodes.get(instr[idx] & 0xFF); + var opc = Opcodes.get(code[idx]); sb.append(idx).append(' ').append(opc).append("], "); } } diff --git a/src/twg2/jbcm/toSource/IterateCode.java b/src/twg2/jbcm/CodeIterator.java similarity index 69% rename from src/twg2/jbcm/toSource/IterateCode.java rename to src/twg2/jbcm/CodeIterator.java index 4ef129a..90f6da5 100644 --- a/src/twg2/jbcm/toSource/IterateCode.java +++ b/src/twg2/jbcm/CodeIterator.java @@ -1,37 +1,36 @@ -package twg2.jbcm.toSource; +package twg2.jbcm; import java.util.BitSet; -import twg2.jbcm.Opcodes; import twg2.jbcm.Opcodes.Type; /** * @author TeamworkGuy2 * @since 2020-08-15 */ -public class IterateCode { +public class CodeIterator { /** Create a bit set of the same size as {@code instr} with each index corresponding to the {@code instr} array and the bit set to true for instructions and false for operands. - * @param instr the code array to process + * @param code the code array to process * @return a bit set matching the size of {@code instr} where instruction indices are set to true */ - public static BitSet markInstructions(byte[] instr) { - var isInstr = new BitSet(instr.length); + public static BitSet markInstructions(byte[] code) { + var isInstr = new BitSet(code.length); - for(int i = 0, size = instr.length; i < size; i++) { - Opcodes opc = Opcodes.get(instr[i] & 0xFF); + for(int i = 0, size = code.length; i < size; i++) { + Opcodes opc = Opcodes.get(code[i]); int numOperands = opc.getOperandCount(); // Special handling for instructions with unpredictable byte code lengths if(numOperands == Opcodes.Const.UNPREDICTABLE) { - if(Opcodes.WIDE.is(instr[i])) { + if(Opcodes.WIDE.is(code[i])) { i++; // because wide instructions are wrapped around other instructions - opc = Opcodes.get(instr[i] & 0xFF); + opc = Opcodes.get(code[i]); numOperands = opc.getOperandCount(); } - else if(Opcodes.TABLESWITCH.is(instr[i])) { + else if(Opcodes.TABLESWITCH.is(code[i])) { throw new IllegalStateException("tableswitch code handling not implemented"); } - else if(Opcodes.LOOKUPSWITCH.is(instr[i])) { + else if(Opcodes.LOOKUPSWITCH.is(code[i])) { throw new IllegalStateException("lookupswitch code handling not implemented"); } } @@ -47,12 +46,12 @@ else if(Opcodes.LOOKUPSWITCH.is(instr[i])) { /** Read the sequence of instructions starting from 'idx' and return the index of the next conditional, jump, or return instruction. * @param idx the {@code instr} code array start index - * @param instr the code + * @param code the byte code * @return an index in the range {@code [idx, instr.length)} of the next conditional, jump, or return instruction found or -1 if no conditional, jump, or return instruction is found */ - public static int nextJumpOrEndIndex(int idx, byte[] instr) { - for(int i = idx, size = instr.length; i < size; i++) { - Opcodes opc = Opcodes.get(instr[i] & 0xFF); + public static int nextJumpOrEndIndex(int idx, byte[] code) { + for(int i = idx, size = code.length; i < size; i++) { + Opcodes opc = Opcodes.get(code[i]); int numOperands = opc.getOperandCount(); if(opc.hasBehavior(Type.JUMP) || opc.hasBehavior(Type.RETURN) || opc == Opcodes.ATHROW) { @@ -67,15 +66,15 @@ public static int nextJumpOrEndIndex(int idx, byte[] instr) { /** Check if the sequence of instructions starting from the current code index is terminated by a return instruction and contains no conditional or jump instructions. * @param idx the {@code instr} code array start index - * @param instr the code + * @param code the byte code * @return true if the code from the 'idx' to the next return instruction contains no conditional or jump instructions */ - public static boolean isStraightReturnRun(int idx, byte[] instr) { - int nextJumpIdx = nextJumpOrEndIndex(idx, instr); + public static boolean isStraightReturnRun(int idx, byte[] code) { + int nextJumpIdx = nextJumpOrEndIndex(idx, code); if(nextJumpIdx == -1) { return false; } - Opcodes opc = Opcodes.get(instr[nextJumpIdx] & 0xFF); + Opcodes opc = Opcodes.get(code[nextJumpIdx]); return opc.hasBehavior(Type.RETURN); } } diff --git a/src/twg2/jbcm/CodeUtility.java b/src/twg2/jbcm/CodeUtility.java index a35b4a1..2c9f241 100644 --- a/src/twg2/jbcm/CodeUtility.java +++ b/src/twg2/jbcm/CodeUtility.java @@ -1,28 +1,101 @@ package twg2.jbcm; +import java.util.function.BiFunction; + import twg2.jbcm.modify.BytecodeConsumer; -import twg2.jbcm.modify.ChangeCpIndex; +import twg2.jbcm.modify.ChangeIndex; import twg2.jbcm.modify.CodeOffsetChanger; -import twg2.jbcm.modify.CpIndexChanger; +import twg2.jbcm.modify.CodeCpIndexChanger; /** Utilities for dealing with byte code arrays * @author TeamworkGuy2 * @since 2020-12-3 */ public class CodeUtility { + /** The factory for {@link CodeCpIndexChanger}'s used by Opcodes, + * can be replaced but must be done before Opcodes are loaded to take effect + */ + public static BiFunction cpIndexChangerFactory = (offset, cpIndexStorageSize) -> new ChangeIndex(offset, cpIndexStorageSize); + + /** The factory for {@link CodeOffsetChanger}'s used by Opcodes, + * can be replaced but must be done before Opcodes are loaded to take effect + */ + public static BiFunction codeOffsetChangerFactory = (offset, offsetStorageSize) -> new ChangeIndex(offset, offsetStorageSize); + + + /** Call the specified {@code BytecodeConsumer} for each instruction in a byte-code array + * @param code the code array + * @param offset the offset into the code array at which to start finding instructions + * @param length the number of bytes of the code array to check through + * @param cbFunc the function to call for each instruction found in specified code array range + */ + public static void forEach(byte[] code, int offset, int length, BytecodeConsumer cbFunc) { + // BYTECODE LOOP: + for(int i = offset, size = offset + length; i < size; i++) { + Opcodes opc = Opcodes.get(code[i]); + int numOperands = opc.getOperandCount(); + // Special handling for instructions with unpredictable byte code lengths + if(numOperands == Opcodes.Const.UNPREDICTABLE) { + if(Opcodes.WIDE.is(code[i])) { + cbFunc.accept(opc, code, i); + i++; // WIDE opcodes are nested around other operations + opc = Opcodes.get(code[i]); + numOperands = opc.getOperandCount() * 2; // WIDE opcodes double the operands of the widened opcode + } + else if(Opcodes.TABLESWITCH.is(code[i])) { + throw new IllegalStateException("tableswitch code handling not implemented"); + } + else if(Opcodes.LOOKUPSWITCH.is(code[i])) { + throw new IllegalStateException("lookupswitch code handling not implemented"); + } + } + cbFunc.accept(opc, code, i); + i += (numOperands < 0) ? 0 : numOperands; + } + } + + + /** Extract from [0, 4] operands following a specified index in little-endian style order: + *
{@code
+     * (((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) <<  8) | (d & 0xFF))
+     * }
+ * @param numOperands the number of bytes to read as operand(s) + * @param code the byte code array + * @param index the index of the instruction immediately preceding the operand(s) + * @return The binary OR'ed value of the operand bytes with the first operand in the most significant position or -1 if {@code numOperations = 0} + */ + public static int loadOperands(int numOperands, byte[] code, int index) { + boolean isCpIndex = Opcodes.get(code[index]).hasBehavior(Opcodes.Type.CP_INDEX); + int res = (numOperands > 3 ? (((code[index+1] & 0xFF) << 24) | ((code[index+2] & 0xFF) << 16) | ((code[index+3] & 0xFF) << 8) | (code[index+4] & 0xFF)) : + (numOperands > 2 ? (((code[index+1] & 0xFF) << 16) | ((code[index+2] & 0xFF) << 8) | (code[index+3] & 0xFF)) : + (numOperands > 1 ? (((code[index+1] & 0xFF) << 8) | (code[index+2] & 0xFF)) : + (numOperands > 0 ? ((code[index+1] & 0xFF)) : -1)))); + return numOperands == 2 && !isCpIndex ? (short)res : res; + } + + + public static CodeCpIndexChanger cpIndex(int offset, int cpIndexStorageSize) { + return cpIndexChangerFactory.apply(offset, cpIndexStorageSize); + } + + + public static CodeOffsetChanger offsetModifier(int offset, int offsetStorageSize) { + return codeOffsetChangerFactory.apply(offset, offsetStorageSize); + } + /** Shift the offset values associated with a specific instruction in a chunk of code. - * For example, shifting a goto offsets at position 55 by 12 might look like:
- * {@code shiftOffset(0xA7, 12, 1, 2, code, 55);}
- * Or shifting a goto_w offsets at position 25 by 160:
- * {@code shiftOffset(0xC8, 160, 1, 4, code, 25);} + * Assumes that the offset is stored as a byte. + * As of Java 16 there are no opcodes which store an offset in 1 byte. + * For example, shifting a theoretical_opcode offset at position 55 by 12 might look like:
+ * shift1Offset(12, 1, code, 55);
* @param offset the instruction code offset to adjust * @param offsetOffset the number of bytes ahead of the opcode at which the offset to adjust starts (1 for an offset that immediately follows an opcode) * @param code the array of code to search through for the opcode * @param codeOffset the offset into the code array at which to update the opcode's offset value * @return the location after the opcode's offset value, calculated as {@code codeOffset + offsetOffset + 1} */ - public static int shift1Offset(int offset, final int offsetOffset, byte[] code, int codeOffset) { + public static int shift1Offset(int offset, int offsetOffset, byte[] code, int codeOffset) { codeOffset += offsetOffset; byte curOffset = code[codeOffset]; if(curOffset + offset < 0) { @@ -35,10 +108,9 @@ public static int shift1Offset(int offset, final int offsetOffset, byte[] code, /** Shift the offset values associated with a specific instruction in a chunk of code. - * For example, shifting a goto offsets at position 55 by 12 might look like:
- * {@code shiftOffset(12, 1, 2, code, 55);}
- * Or shifting a goto_w offsets at position 25 by 160:
- * {@code shiftOffset(160, 1, 4, code, 25);} + * Assumes that the offset is stored as a 2 byte 'short'. + * For example, shifting a goto offset at position 55 by 12 might look like:
+ * shiftOffset(12, 1, code, 55);
* @param offset the instruction code offset to adjust * @param offsetOffset the number of bytes ahead of the opcode at which the offset to adjust starts (1 for an offset that immediately follows an opcode) * @param code the array of code to search through for the opcode @@ -58,10 +130,9 @@ public static int shift2Offset(int offset, int offsetOffset, byte[] code, int co /** Shift the offset values associated with a specific instruction in a chunk of code. - * For example, shifting a goto offsets at position 55 by 12 might look like:
- * {@code shiftOffset(12, 1, 2, code, 55);}
- * Or shifting a goto_w offsets at position 25 by 160:
- * {@code shiftOffset(160, 1, 4, code, 25);} + * Assumes that the offset is stored as a 4 byte 'int'. + * For example, shifting a goto_w offset at position 25 by 160 might look like:
+ * shiftOffset(160, 1, code, 25);
* @param offset the instruction code offset to adjust * @param offsetOffset the number of bytes ahead of the opcode at which the offset to adjust starts (1 for an offset that immediately follows an opcode) * @param code the array of code to search through for the opcode @@ -79,65 +150,4 @@ public static int shift4Offset(int offset, int offsetOffset, byte[] code, int co return codeOffset + 4; } - - /** Call the specified {@code BytecodeConsumer} for each instruction in the specified code array - * @param code the code array - * @param offset the offset into the code array at which to start finding instructions - * @param length the number of bytes of the code array to check through - * @param cbFunc the function to call for each instruction found in specified code array range - */ - public static void forEach(byte[] code, int offset, int length, BytecodeConsumer cbFunc) { - int numOperands = 0; - @SuppressWarnings("unused") - int operand = 0; - - for(int i = offset, size = offset + length; i < size; i++) { - numOperands = Opcodes.get((code[i] & 0xFF)).getOperandCount(); - // Read following bytes of code and convert them to an operand depending on the number of operands specified for the current command - operand = CodeUtility.loadOperands(numOperands, code, i); - // Special handling for instructions with unpredictable byte code lengths - if(numOperands == Opcodes.Const.UNPREDICTABLE) { - if(Opcodes.WIDE.is(code[i])) { - cbFunc.accept(Opcodes.get((code[i] & 0xFF)), code, i); - i++; // because wide operations are nested around other operations - numOperands = Opcodes.get((code[i] & 0xFF)).getOperandCount(); - } - else if(Opcodes.TABLESWITCH.is(code[i])) { - throw new IllegalStateException("tableswitch code handling not implemented"); - } - else if(Opcodes.LOOKUPSWITCH.is(code[i])) { - throw new IllegalStateException("lookupswitch code handling not implemented"); - } - } - cbFunc.accept(Opcodes.get((code[i] & 0xFF)), code, i); - i+= (numOperands < 0) ? 0 : numOperands; - } - } - - /** Extract from [0, 4] operands following a specified index in little-endian style order: - *
{@code
-     * (((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) <<  8) | (d & 0xFF))
-     * }
- * @param numOperands the number of bytes to read as operand(s) - * @param code the byte code array - * @param index the index of the instruction immediately preceding the operand(s) - * @return The binary OR'ed value of the operand bytes with the first operand in the most significant position or -1 if {@code numOperations = 0} - */ - public static int loadOperands(int numOperands, byte[] code, int index) { - return (numOperands > 3 ? (((code[index+1] & 0xFF) << 24) | ((code[index+2] & 0xFF) << 16) | ((code[index+3] & 0xFF) << 8) | (code[index+4] & 0xFF)) : - (numOperands > 2 ? (((code[index+1] & 0xFF) << 16) | ((code[index+2] & 0xFF) << 8) | (code[index+3] & 0xFF)) : - (numOperands > 1 ? (((code[index+1] & 0xFF) << 8) | (code[index+2] & 0xFF)) : - (numOperands > 0 ? ((code[index+1] & 0xFF)) : -1)))); - } - - - public static CpIndexChanger cpIndex(int offset, int len) { - return new ChangeCpIndex(offset, len); - } - - - public static CodeOffsetChanger offsetModifier(int offset, int len) { - return new ChangeCpIndex(offset, len); - } - } diff --git a/src/twg2/jbcm/DataCountingInputStream.java b/src/twg2/jbcm/DataCountingInputStream.java new file mode 100644 index 0000000..d7b3ec2 --- /dev/null +++ b/src/twg2/jbcm/DataCountingInputStream.java @@ -0,0 +1,61 @@ +package twg2.jbcm; + +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** A {@link DataInputStream} that counts the number of bytes that have been read. + * @author TeamworkGuy2 + * @since 2022-07-28 + */ +public class DataCountingInputStream extends DataInputStream { + + public DataCountingInputStream(InputStream in) { + super(new CountingInputStream(in)); + } + + + public int bytesRead() { + return ((CountingInputStream)super.in).readCount; + } + + + /** + * @author TeamworkGuy2 + * @since 2022-07-28 + */ + public static class CountingInputStream extends InputStream { + int readCount = 0; + InputStream in; + + public CountingInputStream(InputStream in) { + super(); + this.in = in; + } + + + @Override + public int read() throws IOException { + int b = in.read(); + readCount += (b > -1 ? 1 : 0); + return b; + } + + + @Override + public int read(byte[] b) throws IOException { + int res = in.read(b); + readCount += (res > -1 ? res : 0); + return res; + } + + + @Override + public int read(byte[] b, int off, int len) throws IOException { + int res = in.read(b, off, len); + readCount += (res > -1 ? res : 0); + return res; + } + } + +} diff --git a/src/twg2/jbcm/Op.java b/src/twg2/jbcm/Op.java index aa36ecf..32fbb7f 100644 --- a/src/twg2/jbcm/Op.java +++ b/src/twg2/jbcm/Op.java @@ -1,6 +1,6 @@ package twg2.jbcm; -import twg2.jbcm.modify.CpIndexChanger; +import twg2.jbcm.modify.CodeCpIndexChanger; import twg2.jbcm.modify.CodeOffsetChanger; import twg2.jbcm.modify.CodeOffsetGetter; @@ -10,13 +10,13 @@ */ public class Op { private CodeOffsetGetter offsetGetter; - private CpIndexChanger cpIndex; + private CodeCpIndexChanger cpIndex; private CodeOffsetChanger codeOffset; private Op() {} - public Op add(CpIndexChanger cpIndex) { + public Op add(CodeCpIndexChanger cpIndex) { this.cpIndex = cpIndex; // detect if index change implementation is also an offset getter and save it for that purpose if(cpIndex instanceof CodeOffsetGetter) { @@ -42,7 +42,7 @@ public OpcodeOperations create() { } - public static Op of(CpIndexChanger cpIndex) { + public static Op of(CodeCpIndexChanger cpIndex) { Op op = new Op(); return op.add(cpIndex); } diff --git a/src/twg2/jbcm/OpcodeOperations.java b/src/twg2/jbcm/OpcodeOperations.java index d5dc4f9..bb95bed 100644 --- a/src/twg2/jbcm/OpcodeOperations.java +++ b/src/twg2/jbcm/OpcodeOperations.java @@ -1,6 +1,6 @@ package twg2.jbcm; -import twg2.jbcm.modify.CpIndexChanger; +import twg2.jbcm.modify.CodeCpIndexChanger; import twg2.jbcm.modify.CodeOffsetChanger; import twg2.jbcm.modify.CodeOffsetGetter; @@ -9,16 +9,16 @@ * @since 2014-4-20 */ public class OpcodeOperations { - public static final OpcodeOperations EMPTY = new OpcodeOperations(CodeOffsetGetter.RETURN_ZERO, CpIndexChanger.NO_OP, CodeOffsetChanger.NO_OP); + public static final OpcodeOperations EMPTY = new OpcodeOperations(CodeOffsetGetter.RETURN_ZERO, CodeCpIndexChanger.NO_OP, CodeOffsetChanger.NO_OP); private CodeOffsetGetter codeOffsetGetter; - private CpIndexChanger cpIndexChanger; + private CodeCpIndexChanger codeCpIndexChanger; private CodeOffsetChanger codeOffsetChanger; - public OpcodeOperations(CodeOffsetGetter codeOffsetGetter, CpIndexChanger cpIndexChanger, CodeOffsetChanger codeOffsetChanger) { + public OpcodeOperations(CodeOffsetGetter codeOffsetGetter, CodeCpIndexChanger codeCpIndexChanger, CodeOffsetChanger codeOffsetChanger) { this.codeOffsetGetter = codeOffsetGetter; - this.cpIndexChanger = cpIndexChanger; + this.codeCpIndexChanger = codeCpIndexChanger; this.codeOffsetChanger = codeOffsetChanger; } @@ -28,8 +28,8 @@ public CodeOffsetGetter getCodeOffsetGetter() { } - public CpIndexChanger getCpIndexModifier() { - return cpIndexChanger; + public CodeCpIndexChanger getCpIndexModifier() { + return codeCpIndexChanger; } diff --git a/src/twg2/jbcm/Opcodes.java b/src/twg2/jbcm/Opcodes.java index 8a5363c..bb1c48d 100644 --- a/src/twg2/jbcm/Opcodes.java +++ b/src/twg2/jbcm/Opcodes.java @@ -497,11 +497,12 @@ public OpcodeOperations getOperations() { /** - * @param opcode the opcode to compare to this opcode + * @param opcode the opcode to compare to this opcode, + * can be a signed byte value between [-128, 127] or an int value [0, 255] * @return true if this opcode equals the specified opcode value */ public boolean is(int opcode) { - return this.opcode == opcode; + return this.opcode == (opcode & 0xFF); } @@ -585,11 +586,12 @@ public static List getOpcodeSet(Type type) { /** Return the opcode with the specified opcode value - * @param opcode the opcode value to lookup + * @param opcode the opcode value to lookup, + * can be a signed byte value between [-128, 127] or an int value [0, 255] * @return the instruction corresponding to the specified opcode */ public static Opcodes get(int opcode) { - Opcodes op = OpcodeMap.opcodes[opcode]; + Opcodes op = OpcodeMap.opcodes[(opcode & 0xFF)]; return op != null ? op : Opcodes.UNDEFINED; } diff --git a/src/twg2/jbcm/classFormat/ClassFile.java b/src/twg2/jbcm/classFormat/ClassFile.java index 5c5bcd7..9172592 100644 --- a/src/twg2/jbcm/classFormat/ClassFile.java +++ b/src/twg2/jbcm/classFormat/ClassFile.java @@ -16,6 +16,7 @@ import java.util.Collections; import java.util.List; +import twg2.jbcm.DataCountingInputStream; import twg2.jbcm.classFormat.attributes.Attribute_Type; import twg2.jbcm.classFormat.attributes.BootstrapMethods; import twg2.jbcm.classFormat.constantPool.CONSTANT_CP_Info; @@ -28,14 +29,15 @@ import twg2.jbcm.classFormat.constantPool.CONSTANT_MethodType; import twg2.jbcm.classFormat.constantPool.CONSTANT_String; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; import twg2.jbcm.modify.TypeUtility; /** Java class file format parent class * @author TeamworkGuy2 * @since 2013-7-7 */ -public class ClassFile extends ConstantPoolExtensions implements Externalizable, ReadWritable { +public class ClassFile extends ConstantPoolExtensions implements Externalizable, ReadWritable, CpIndexChangeable { public static final int HEADER_BYTES = 0xCAFEBABE; /** Declared public; may be accessed from outside its package. */ public static final short ACC_PUBLIC = 0x0001; @@ -56,19 +58,19 @@ public class ClassFile extends ConstantPoolExtensions implements Externalizable, /** Is a module, not a class or interface. */ public static final int ACC_MODULE = 0x8000; - int magic; // Must be: 0xCAFEBABE - short minor_version; // Minor 'm' version value of M.m - short major_version; // Major 'M' version value of M.m + protected int magic; // Must be: 0xCAFEBABE + protected short minor_version; // Minor 'm' version value of M.m + protected short major_version; // Major 'M' version value of M.m // The value of the constant_pool_count item equals the number of entries in the constant_pool // table plus one. A constant_pool index is considered valid if it is greater than zero and less // than constant_pool_count, with the exception for constants of type long and double noted in §4.4.5 - short constant_pool_count; + protected short constant_pool_count; // The constant_pool is a table of structures (§4.4) representing various string constants, class and interface names, // field names, and other constants that are referred to within the ClassFile structure and its substructures. // The format of each constant_pool table entry is indicated by its first "tag" byte. // constant_pool table is indexed from 1 to constant_pool_count-1, size [constant_pool_count-1], indexed from 1. - List> constant_pool; - List>> constantPoolExpectations; + protected List> constant_pool; + protected List>> constantPoolExpectations; // The value of the access_flags item is a mask of flags used to denote access permissions to and properties of // this class or interface. The interpretation of each flag, when set, is as shown in Table 4.1. /* Flag Name Value Interpretation @@ -82,44 +84,44 @@ public class ClassFile extends ConstantPoolExtensions implements Externalizable, * ACC_ENUM 0x4000 Declared as an enum type. * ACC_MODULE 0x8000 Is a module, not a class or interface. */ - short access_flags; + protected short access_flags; /* Value of the this_class must be a valid index into the constant_pool table. * The constant_pool entry at that index must be a CONSTANT_Class_info (§4.4.1) structure * representing the class or interface defined by this class file. */ - CpIndex this_class; + protected CpIndex this_class; /* For a class, the value of the super_class item either must be zero or must be a * valid index into the constant_pool table. If the value of the super_class item is nonzero, * the constant_pool entry at that index must be a CONSTANT_Class_info (§4.4.1) structure * representing the direct superclass of the class defined by this class file. * Neither the direct superclass nor any of its superclasses may be a final class. */ - CpIndex super_class; + protected CpIndex super_class; // The value of the interfaces_count item gives the number of direct superinterfaces of this class or interface type. - short interfaces_count; + protected short interfaces_count; + // CONSTANT_Class.class /* Each value in the interfaces array must be a valid index into the constant_pool table. * The constant_pool entry at each value of interfaces[i], where -1 < i < interfaces_count, * must be a CONSTANT_Class_info (§4.4.1) structure representing an interface that is a * direct superinterface of this class or interface type, in the left-to-right order given * in the source for the type, size [interfaces_count], indexed from 0. */ - // CONSTANT_Class.class - CpIndex[] interfaces; + protected CpIndex[] interfaces; /* The value of the fields_count item gives the number of field_info structures in the fields table. * The field_info (§4.5) structures represent all fields, both class variables and instance * variables, declared by this class or interface type. */ - short fields_count; + protected short fields_count; /* Each value in the fields table must be a field_info (§4.5) structure giving a complete * description of a field in this class or interface. The fields table includes only * those fields that are declared by this class or interface. It does not include items * representing fields that are inherited from superclasses or superinterfaces, * size [fields_count], indexed from 0. */ - Field_Info[] fields; + protected Field_Info[] fields; /** The value of the methods_count item gives the number of method_info structures in the methods table. */ - short methods_count; + protected short methods_count; /** Each value in the methods table must be a method_info (§4.6) structure giving a complete description of a method * in this class or interface. If the method is not native or abstract, the Java virtual machine instructions * implementing the method are also supplied. @@ -128,10 +130,10 @@ public class ClassFile extends ConstantPoolExtensions implements Externalizable, * method (§3.9). The methods table does not include items representing methods that are inherited from superclasses * or superinterfaces, size [methods_count], indexed from 0. */ - Method_Info[] methods; + protected Method_Info[] methods; /** The value of the attributes_count item gives the number of attributes (§4.7) in the attributes table of this class. */ - short attributes_count; + protected short attributes_count; /** Each value of the attributes table must be an attribute structure (§4.7). * The only attributes defined by this specification as appearing in the attributes table of a ClassFile structure * are the SourceFile attribute (§4.7.7) and the Deprecated (§4.7.10) attribute. @@ -140,23 +142,20 @@ public class ClassFile extends ConstantPoolExtensions implements Externalizable, * allowed to affect the semantics of the class file, but only to provide additional descriptive * information (§4.7.1), size [attributes_count], indexed from 0. */ - Attribute_Type[] attributes; + protected Attribute_Type[] attributes; /** Optional bootstrap methods reference if it exists */ - BootstrapMethods bootstrapMethods; + protected BootstrapMethods bootstrapMethods; // non class fields private boolean requireJavaHeaderBytes = true; + private String source; - public ClassFile() { - super(); - } - - - public ClassFile(boolean requireJavaMagicBytes) { + public ClassFile(boolean requireJavaMagicBytes, String source) { super(); this.requireJavaHeaderBytes = requireJavaMagicBytes; + this.source = source; } @@ -236,6 +235,11 @@ public CONSTANT_Class getInterface(int index) { } + public String getSource() { + return source; + } + + @Override public void addConstantPoolExpectation(int index, Class clazz) { constantPoolExpectations.get(index).add(clazz); @@ -276,17 +280,17 @@ public void setConstantPool(int index, CONSTANT_CP_Info cpObj) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(this_class, oldIndex, newIndex); - IndexUtility.indexChange(super_class, oldIndex, newIndex); - IndexUtility.indexChange(interfaces, oldIndex, newIndex); - for(int i = constant_pool_count-1; i > 0; i--) { - IndexUtility.indexChange(constant_pool.get(i), oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(this_class); + indexChanger.indexChange(super_class); + indexChanger.indexChange(interfaces); + for(int i = constant_pool_count - 1; i > 0; i--) { + indexChanger.indexChange(constant_pool.get(i)); } - IndexUtility.indexChange(fields, oldIndex, newIndex); - IndexUtility.indexChange(methods, oldIndex, newIndex); - IndexUtility.indexChange(attributes, oldIndex, newIndex); - IndexUtility.indexChange(bootstrapMethods, oldIndex, newIndex); + indexChanger.indexChange(fields); + indexChanger.indexChange(methods); + indexChanger.indexChange(attributes); + indexChanger.indexChange(bootstrapMethods); } @@ -298,9 +302,10 @@ public void swapConstantPoolIndices(int index1, int index2) { setConstantPool(index2, item1); // Swap the indices of all objects that refer to these two constant pool objects short tempIndex = (short)(constant_pool_count + 1); - changeCpIndex((short)index1, tempIndex); - changeCpIndex((short)index2, (short)index1); - changeCpIndex(tempIndex, (short)index2); + CpIndexChanger index1ToTemp = new CpIndexChanger((short)index1, tempIndex); + CpIndexChanger tempToIndex2 = new CpIndexChanger(tempIndex, (short)index2); + changeCpIndex(index1ToTemp); + changeCpIndex(tempToIndex2); } @@ -389,6 +394,7 @@ public void writeData(DataOutput out) throws IOException { @SuppressWarnings("unchecked") @Override public void readData(DataInput in) throws IOException { + var incs = (DataCountingInputStream)in; magic = in.readInt(); if(magic != HEADER_BYTES && requireJavaHeaderBytes) { throw new IllegalStateException("Header bytes do not match " + HEADER_BYTES + ": " + magic); @@ -412,7 +418,25 @@ public void readData(DataInput in) throws IOException { } // Constant pool starts at 1 for(int i = 1; i < constant_pool_count; i++) { - constant_pool.get(i).setCpObject( ConstantPoolTag.loadConstantPoolObject(in, this) ); + if(Settings.debug) { System.out.println("Constant pool item #" + i + " at stream index " + incs.bytesRead()); } + CONSTANT_CP_Info cpItem = ConstantPoolTag.loadConstantPoolObject(in, i, this); + if(cpItem != null) { + constant_pool.get(i).setCpObject(cpItem); + } + else if(Settings.debug) { + System.out.println("Failed to parse constant pool item #" + i + ", now at stream index " + incs.bytesRead()); + } + } + // if debug mode: print constant pool entries + if(Settings.debug) { + System.out.println("Constant pool finished reading, stream index @ " + incs.bytesRead()); + for(int i = 1; i < constant_pool_count; i++) { + try { + System.out.println("CP item " + i + ": " + constant_pool.get(i)); + } catch(Exception ex) { + System.err.println("Error with constant pool item " + i + ": " + ex.getMessage()); + } + } } // validate constant pool expected types if(Settings.checkCPExpectedType) { @@ -427,7 +451,7 @@ public void readData(DataInput in) throws IOException { } access_flags = in.readShort(); this_class = this.getCheckCpIndex(in.readShort(), CONSTANT_Class.class); - super_class = this.getCheckCpIndex(in.readShort(), CONSTANT_Class.class); + super_class = this.getCheckCpIndex(in.readShort(), CONSTANT_Class.class, true); interfaces_count = in.readShort(); interfaces = new CpIndex[interfaces_count]; for(int i = 0; i < interfaces_count; i++) { @@ -451,6 +475,9 @@ public void readData(DataInput in) throws IOException { attributes[i] = ClassFileAttributes.loadAttributeObject(in, this, null); // Loop bootstrap methods attribute if(attributes[i].getClass() == BootstrapMethods.class) { + if(Settings.debug && this.bootstrapMethods != null) { + System.out.println("duplicate bootstramp methods attributes found, overwriting prevous '" + this.bootstrapMethods + "' with '" + attributes[i] + "'"); + } this.bootstrapMethods = (BootstrapMethods)attributes[i]; } } @@ -562,8 +589,8 @@ public static final CONSTANT_CP_Info checkBootstrapArgumentType(CONSTANT_CP_Info * @return the class file loaded from the specified file * @throws IOException if the file cannot be opened or if it is not a recognized class file format */ - public static final ClassFile load(File file) throws IOException { - return load(new BufferedInputStream(new FileInputStream(file))); + public static ClassFile load(File file) throws IOException { + return load(new BufferedInputStream(new FileInputStream(file)), file.toString()); } @@ -572,11 +599,11 @@ public static final ClassFile load(File file) throws IOException { * @return the class file loaded from the specified input stream * @throws IOException if the file cannot be opened or if it is not a recognized class file format */ - public static final ClassFile load(InputStream input) throws IOException { - ClassFile classFile = new ClassFile(); + public static ClassFile load(InputStream input, String source) throws IOException { + ClassFile classFile = new ClassFile(true, source); DataInputStream in = null; try { - in = new DataInputStream(input); + in = new DataCountingInputStream(input); classFile.readData(in); } finally { if(in != null) { @@ -606,9 +633,9 @@ public static final ClassFile load(Class clazz) throws IOException { * @throws IOException if the class' class file could not be found or opened or if the class file found * is not a recognized class file format */ - public static final ClassFile load(Class clazz, boolean requireJavaMagicBytes) throws IOException { - ClassFile classFile = new ClassFile(requireJavaMagicBytes); + public static ClassFile load(Class clazz, boolean requireJavaMagicBytes) throws IOException { String filesystemClassName = clazz.getCanonicalName().replace('.', '/') + ".class"; + ClassFile classFile = new ClassFile(requireJavaMagicBytes, filesystemClassName); InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(filesystemClassName); DataInputStream in = null; try { diff --git a/src/twg2/jbcm/classFormat/ConstantPoolExtensions.java b/src/twg2/jbcm/classFormat/ConstantPoolExtensions.java index 296c6c0..d964edf 100644 --- a/src/twg2/jbcm/classFormat/ConstantPoolExtensions.java +++ b/src/twg2/jbcm/classFormat/ConstantPoolExtensions.java @@ -47,6 +47,15 @@ public String getCpString(int attributeNameIndex) { } + // TODO debugging + public CpIndex getCpIndex(int index, boolean allowZero) { + if(index == 0) { + return null; + } + return getCpIndex(index); + } + + public CpIndex getCpIndex(int index) { if(index > 0 && index < getConstantPoolCount()) { CpIndex result = getConstantPoolIndex(index); diff --git a/src/twg2/jbcm/classFormat/ConstantPoolTag.java b/src/twg2/jbcm/classFormat/ConstantPoolTag.java index 3851358..9e8e270 100644 --- a/src/twg2/jbcm/classFormat/ConstantPoolTag.java +++ b/src/twg2/jbcm/classFormat/ConstantPoolTag.java @@ -39,7 +39,7 @@ public enum ConstantPoolTag { METHOD_TYPE ((byte)16) { @Override public CONSTANT_MethodType create(ClassFile clazz) { return new CONSTANT_MethodType(clazz); } }, INVOKE_DYNAMIC ((byte)18) { @Override public CONSTANT_InvokeDynamic create(ClassFile clazz) { return new CONSTANT_InvokeDynamic(clazz); } }; - private static ConstantPoolTag[] tagArray; + private static final ConstantPoolTag[] tagArray; private byte tag; @@ -91,21 +91,32 @@ public int getTag() { } - /** Java class file format ConstantPool info type loading method - * @author TeamworkGuy2 - * @since 2013-7-7 + /** Java class file format ConstantPool item parser/loader. + * Uses this enum's tag values and {@link #create(ClassFile)} methods to parse constant pool + * entries from a {@link DataInput} stream. */ - public static final CONSTANT_CP_Info loadConstantPoolObject(DataInput in, ClassFile resolver) throws IOException { + public static CONSTANT_CP_Info loadConstantPoolObject(DataInput in, int cpIndex, ClassFile resolver) throws IOException { CONSTANT_CP_Info cpObj = null; - int tag = in.readByte(); + int tag = in.readByte() & 0xFF; try { cpObj = tagArray[tag].create(resolver); - } catch(ArrayIndexOutOfBoundsException e) { - throw new IllegalArgumentException("Unkown constant pool tag: " + tag); + } catch(RuntimeException e) { + if(Settings.checkCPTag) { + throw new IllegalArgumentException("Unknown constant pool tag: " + tag); + } + else { + // all constant pool entries will have a tag followed by at least 2 bytes of data, so even if invalid, read 2 bytes + // https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4 + int unknownData1 = cpObj == null ? in.readByte() : 0; + int unknownData2 = cpObj == null ? in.readByte() : 0; + System.err.println("Unknown constant pool tag: " + tag + " at index " + cpIndex + ", attempting to read required 2 byte info: [" + unknownData1 + ", " + unknownData2 + "]"); + return null; + } } cpObj.readData(in); + return cpObj; } diff --git a/src/twg2/jbcm/classFormat/CpIndex.java b/src/twg2/jbcm/classFormat/CpIndex.java index faac6a1..3e2fd76 100644 --- a/src/twg2/jbcm/classFormat/CpIndex.java +++ b/src/twg2/jbcm/classFormat/CpIndex.java @@ -5,7 +5,8 @@ import java.io.IOException; import twg2.jbcm.classFormat.constantPool.CONSTANT_CP_Info; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** A constant pool index and type.
* The data type of the index this object points to can be lazily initialized by using the @@ -13,7 +14,7 @@ * @author TeamworkGuy2 * @since 2014-4-20 */ -public final class CpIndex implements ReadWritable { +public final class CpIndex implements ReadWritable, CpIndexChangeable { private static final Class VALID_TYPE = CONSTANT_CP_Info.class; private boolean initialized; private Class clas; @@ -58,7 +59,7 @@ boolean isInitialized() { final void initialize(Class clas) { - if(initialized == true) { + if(initialized) { throw new IllegalStateException("cannot reinitialize CpIndex"); } if(clas == null) { throw new NullPointerException("constant pool item class type cannot be null"); } @@ -106,8 +107,8 @@ public T getCpObject() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - this.index = IndexUtility.indexChange((short)this.index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + this.index = indexChanger.indexChange((short)this.index); } diff --git a/src/twg2/jbcm/classFormat/Field_Info.java b/src/twg2/jbcm/classFormat/Field_Info.java index 53a6306..7215fef 100644 --- a/src/twg2/jbcm/classFormat/Field_Info.java +++ b/src/twg2/jbcm/classFormat/Field_Info.java @@ -9,13 +9,14 @@ import twg2.jbcm.classFormat.attributes.Attribute_Type; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** Java class file format Field info type * @author TeamworkGuy2 * @since 2013-7-7 */ -public class Field_Info implements Externalizable, ReadWritable { +public class Field_Info implements Externalizable, ReadWritable, CpIndexChangeable { /** Declared public; may be accessed from outside its package. */ public static final int ACC_PUBLIC = 0x0001; /** Declared private; usable only within the defining class. */ @@ -85,10 +86,10 @@ public Field_Info(ClassFile resolver) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(name_index, oldIndex, newIndex); - IndexUtility.indexChange(descriptor_index, oldIndex, newIndex); - IndexUtility.indexChange(attributes, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(name_index); + indexChanger.indexChange(descriptor_index); + indexChanger.indexChange(attributes); } diff --git a/src/twg2/jbcm/classFormat/Method_Info.java b/src/twg2/jbcm/classFormat/Method_Info.java index 90a6048..12a82fb 100644 --- a/src/twg2/jbcm/classFormat/Method_Info.java +++ b/src/twg2/jbcm/classFormat/Method_Info.java @@ -10,13 +10,14 @@ import twg2.jbcm.classFormat.attributes.Attribute_Type; import twg2.jbcm.classFormat.attributes.Code; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** Java class file format Method info type * @author TeamworkGuy2 * @since 2013-7-7 */ -public class Method_Info implements Externalizable, ReadWritable { +public class Method_Info implements Externalizable, ReadWritable, CpIndexChangeable { /** Declared public; may be accessed from outside its package. */ public static final int ACC_PUBLIC = 0x0001; /** Declared private; accessible only within the defining class. */ @@ -93,10 +94,10 @@ public Method_Info(ClassFile resolver) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(name_index, oldIndex, newIndex); - IndexUtility.indexChange(descriptor_index, oldIndex, newIndex); - IndexUtility.indexChange(attributes, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(name_index); + indexChanger.indexChange(descriptor_index); + indexChanger.indexChange(attributes); } diff --git a/src/twg2/jbcm/classFormat/ReadWritable.java b/src/twg2/jbcm/classFormat/ReadWritable.java index ef463c5..3ad1364 100644 --- a/src/twg2/jbcm/classFormat/ReadWritable.java +++ b/src/twg2/jbcm/classFormat/ReadWritable.java @@ -4,14 +4,12 @@ import java.io.DataOutput; import java.io.IOException; -import twg2.jbcm.modify.IndexChanger; - /** An interface for objects that can save themselves to a binary stream, similar * to {@link java.io.Externalizable Externalizable}. * @author TeamworkGuy2 * @since 2013-7-7 */ -public interface ReadWritable extends IndexChanger { +public interface ReadWritable { public void writeData(DataOutput out) throws IOException; diff --git a/src/twg2/jbcm/classFormat/Settings.java b/src/twg2/jbcm/classFormat/Settings.java index 0a4347e..9cecd25 100644 --- a/src/twg2/jbcm/classFormat/Settings.java +++ b/src/twg2/jbcm/classFormat/Settings.java @@ -5,9 +5,13 @@ * @since 2013-7-7 */ public class Settings { - public static boolean debug = true; + public static boolean debug = false; public static boolean cpTagRead = true; public static boolean checkCPIndex = true; + /** Whether to validate the tag type of each constant pool entry read, without a valid tag constant pool entries + * cannot be loaded and two bytes of data assumed to contain the constant pool entry info are skipped + */ + public static boolean checkCPTag = true; public static boolean checkCPExpectedType = true; public static boolean checkAttributeName = true; public static boolean readAttributeName = false; @@ -17,28 +21,4 @@ private Settings() { throw new AssertionError("may not instantiate Settings"); } - public static boolean debug() { - return debug; - } - - public static boolean cpTagRead() { - return cpTagRead; - } - - public static boolean checkCPIndex() { - return checkCPIndex; - } - - public static boolean checkCPExpectedType() { - return checkCPExpectedType; - } - - public static boolean checkAttributeName() { - return checkAttributeName; - } - - public static boolean readAttributeName() { - return readAttributeName; - } - } diff --git a/src/twg2/jbcm/classFormat/attributes/Annotation.java b/src/twg2/jbcm/classFormat/attributes/Annotation.java index b36c059..4837e84 100644 --- a/src/twg2/jbcm/classFormat/attributes/Annotation.java +++ b/src/twg2/jbcm/classFormat/attributes/Annotation.java @@ -8,13 +8,14 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.ReadWritable; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Annotation subtype of type Annotation * @author TeamworkGuy2 * @since 2013-12-3 */ -public class Annotation implements ReadWritable { +public class Annotation implements ReadWritable, CpIndexChangeable { ClassFile resolver; /** The value of the type_index item must be a valid index into the constant_pool table. * The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure @@ -42,9 +43,9 @@ public Annotation(ClassFile resolver) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(type_index, oldIndex, newIndex); - IndexUtility.indexChange(element_value_pairs, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(type_index); + indexChanger.indexChange(element_value_pairs); } diff --git a/src/twg2/jbcm/classFormat/attributes/AnnotationDefault.java b/src/twg2/jbcm/classFormat/attributes/AnnotationDefault.java index ca450dc..243a1a2 100644 --- a/src/twg2/jbcm/classFormat/attributes/AnnotationDefault.java +++ b/src/twg2/jbcm/classFormat/attributes/AnnotationDefault.java @@ -9,7 +9,7 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type AnnotationDefault * @author TeamworkGuy2 @@ -49,9 +49,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(default_value, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(default_value); } diff --git a/src/twg2/jbcm/classFormat/attributes/Attribute_Type.java b/src/twg2/jbcm/classFormat/attributes/Attribute_Type.java index c081412..86287ff 100644 --- a/src/twg2/jbcm/classFormat/attributes/Attribute_Type.java +++ b/src/twg2/jbcm/classFormat/attributes/Attribute_Type.java @@ -2,13 +2,14 @@ import twg2.jbcm.classFormat.ClassFileAttributes; import twg2.jbcm.classFormat.ReadWritable; +import twg2.jbcm.modify.CpIndexChangeable; /** Interface for all Attribute types in a Java class file format.
* Remember to add new attribute types to the {@link ClassFileAttributes} enum. * @author TeamworkGuy2 * @since 2013-7-7 */ -public interface Attribute_Type extends ReadWritable { +public interface Attribute_Type extends ReadWritable, CpIndexChangeable { public String getAttributeName(); diff --git a/src/twg2/jbcm/classFormat/attributes/BootstrapMethods.java b/src/twg2/jbcm/classFormat/attributes/BootstrapMethods.java index a33d77d..270e09e 100644 --- a/src/twg2/jbcm/classFormat/attributes/BootstrapMethods.java +++ b/src/twg2/jbcm/classFormat/attributes/BootstrapMethods.java @@ -12,7 +12,8 @@ import twg2.jbcm.classFormat.constantPool.CONSTANT_CP_Info; import twg2.jbcm.classFormat.constantPool.CONSTANT_MethodHandle; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type BootstrapMethods * @author TeamworkGuy2 @@ -65,9 +66,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(bootstrap_methods, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(bootstrap_methods); } @@ -124,7 +125,7 @@ public String toString() { * @author TeamworkGuy2 * @since 2013-10-6 */ - public static class BootstrapMethod implements ReadWritable { + public static class BootstrapMethod implements ReadWritable, CpIndexChangeable { ClassFile resolver; /** The value of the bootstrap_method_ref item must be a valid index into the constant_pool table. * The constant_pool entry at that index must be a CONSTANT_MethodHandle_info structure (§4.4.8). @@ -167,9 +168,9 @@ public CONSTANT_CP_Info getBootstrapArgument(int index) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(bootstrap_method_ref, oldIndex, newIndex); - IndexUtility.indexChange(bootstrap_arguments, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(bootstrap_method_ref); + indexChanger.indexChange(bootstrap_arguments); } diff --git a/src/twg2/jbcm/classFormat/attributes/Code.java b/src/twg2/jbcm/classFormat/attributes/Code.java index 7e3e3fd..a5edd68 100644 --- a/src/twg2/jbcm/classFormat/attributes/Code.java +++ b/src/twg2/jbcm/classFormat/attributes/Code.java @@ -4,6 +4,7 @@ import java.io.DataOutput; import java.io.IOException; +import twg2.jbcm.CodeUtility; import twg2.jbcm.Opcodes; import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.ClassFileAttributes; @@ -12,7 +13,8 @@ import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Class; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type Code * @author TeamworkGuy2 @@ -89,10 +91,10 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(exception_table, oldIndex, newIndex); - IndexUtility.indexChange(attributes, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(exception_table); + indexChanger.indexChange(attributes); } @@ -126,6 +128,8 @@ public int getMaxLocals() { } + // TODO these modify operations should clone this Code attribute + public void setCode(byte[] instructions) { byte[] oldCode = this.code; this.code = instructions; @@ -172,24 +176,6 @@ private void updateOffsets(int offset, int length, int shift) { } - /** Set this code block's max stack size - * @param maxStackSize the size of this code's stack - */ - public void setStackSize(short maxStackSize) { - this.max_stack = maxStackSize; - } - - - /** Ensure that this code block's max stack size is atleast the specified size - * @param maxStackSize the minimum size of this code's stack - */ - public void ensureStackSize(short maxStackSize) { - if(maxStackSize > this.max_stack) { - this.max_stack = maxStackSize; - } - } - - @Override public void writeData(DataOutput out) throws IOException { attribute_name_index.writeData(out); @@ -237,30 +223,30 @@ public void readData(DataInput in) throws IOException { @Override public String toString() { StringBuilder dst = new StringBuilder(); - toClassString("\t", dst); + toClassCodeString("\t", dst); return dst.toString(); } // approximately black-boxed based on Eclipse class file view - public void toClassString(String tab, StringBuilder str) { + public void toClassCodeString(String tab, StringBuilder str) { str.append(ATTRIBUTE_NAME).append("(stack: ").append(max_stack) .append(", locals: ").append(max_locals).append(",\n").append(tab) .append("code: ").append(code_length).append(" [\n"); for(int i = 0; i < code_length; i++) { - Opcodes opc = Opcodes.get(code[i] & 0xFF); + Opcodes opc = Opcodes.get(code[i]); boolean isWide = false; int numOperands = opc.getOperandCount(); // Read following bytes of code and convert them to an operand depending on the current instruction - int operand = loadOperands(numOperands, code, i); + int operand = CodeUtility.loadOperands(numOperands, code, i); // Special handling for instructions with unpredictable byte code lengths if(numOperands == Opcodes.Const.UNPREDICTABLE) { if(Opcodes.WIDE.is(code[i])) { // TODO doesn't properly read extra wide operand bytes isWide = true; i++; // because wide instructions are wrapped around other instructions - opc = Opcodes.get(code[i] & 0xFF); + opc = Opcodes.get(code[i]); numOperands = opc.getOperandCount(); } else if(Opcodes.TABLESWITCH.is(code[i])) { @@ -311,14 +297,6 @@ else if(opc.hasBehavior(Opcodes.Type.JUMP)) { } - private static int loadOperands(int numOperands, byte[] code, int index) { - return (numOperands > 3 ? (((code[index+1] & 0xFF) << 24) | ((code[index+2] & 0xFF) << 16) | ((code[index+3] & 0xFF) << 8) | (code[index+4] & 0xFF)) : - (numOperands > 2 ? (((code[index+1] & 0xFF) << 16) | ((code[index+2] & 0xFF) << 8) | (code[index+3] & 0xFF)) : - (numOperands > 1 ? (((code[index+1] & 0xFF) << 8) | (code[index+2] & 0xFF)) : - (numOperands > 0 ? ((code[index+1] & 0xFF)) : -1)))); - } - - private static String instructionIndex(int instPtr) { if(instPtr < 10) { return " " + instPtr + " "; @@ -337,9 +315,9 @@ else if(instPtr < 100) { * @author TeamworkGuy2 * @since 2013-7-7 */ - public static class ExceptionPoint implements ReadWritable { + public static class ExceptionPoint implements ReadWritable, CpIndexChangeable { Code parent; - /* Each entry in the exception_table array describes one exception handler in the code array. The order of the + /** Each entry in the exception_table array describes one exception handler in the code array. The order of the * handlers in the exception_table array is significant. See Section 3.10 for more details. * Each exception_table entry contains the following four items: * start_pc, end_pc @@ -372,9 +350,49 @@ public ExceptionPoint(Code codeParent) { } + /** + * @see #parent + */ + public Code getParent() { + return parent; + } + + + /** + * @see #start_pc + */ + public short getStartPc() { + return start_pc; + } + + + /** + * @see #end_pc + */ + public short getEndPc() { + return end_pc; + } + + + /** + * @see #handler_pc + */ + public short getHandlerPc() { + return handler_pc; + } + + + /** + * @see #catch_type + */ + public CpIndex getCatchType() { + return catch_type; + } + + @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(catch_type, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(catch_type); } @@ -398,7 +416,7 @@ public void readData(DataInput in) throws IOException { @Override public String toString() { - return "Exception(start=" + start_pc + ", end=" + end_pc + ", handler=" + handler_pc + ", catch_type=" + (catch_type.getIndex() > 0 ? catch_type.getCpObject() : "finally") + ")"; + return "Exception(start=" + start_pc + ", end=" + end_pc + ", handler=" + handler_pc + ", catch_type=" + (catch_type != null && catch_type.getIndex() > 0 ? catch_type.getCpObject() : "finally") + ")"; } } diff --git a/src/twg2/jbcm/classFormat/attributes/Code_Attribute.java b/src/twg2/jbcm/classFormat/attributes/Code_Attribute.java index bcae3bc..f70ad63 100644 --- a/src/twg2/jbcm/classFormat/attributes/Code_Attribute.java +++ b/src/twg2/jbcm/classFormat/attributes/Code_Attribute.java @@ -1,9 +1,11 @@ package twg2.jbcm.classFormat.attributes; +import twg2.jbcm.modify.CpIndexChangeable; + /** Interface implemented by Java Class File attributes as defined in the JVM specification Attributes section (§4.7) * @author TeamworkGuy2 * @since 2014-4-28 */ -public interface Code_Attribute { +public interface Code_Attribute extends CpIndexChangeable { } diff --git a/src/twg2/jbcm/classFormat/attributes/ConstantValue.java b/src/twg2/jbcm/classFormat/attributes/ConstantValue.java index d56a109..132daea 100644 --- a/src/twg2/jbcm/classFormat/attributes/ConstantValue.java +++ b/src/twg2/jbcm/classFormat/attributes/ConstantValue.java @@ -10,7 +10,7 @@ import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_CP_Info; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type ConstantValue * @author TeamworkGuy2 @@ -57,9 +57,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(constantvalue_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(constantvalue_index); } diff --git a/src/twg2/jbcm/classFormat/attributes/Deprecated.java b/src/twg2/jbcm/classFormat/attributes/Deprecated.java index 9c34bd2..ba3d5f8 100644 --- a/src/twg2/jbcm/classFormat/attributes/Deprecated.java +++ b/src/twg2/jbcm/classFormat/attributes/Deprecated.java @@ -9,7 +9,7 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type Deprecated * @author TeamworkGuy2 @@ -45,8 +45,8 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); } diff --git a/src/twg2/jbcm/classFormat/attributes/Element_Value.java b/src/twg2/jbcm/classFormat/attributes/Element_Value.java index bcaa574..713d124 100644 --- a/src/twg2/jbcm/classFormat/attributes/Element_Value.java +++ b/src/twg2/jbcm/classFormat/attributes/Element_Value.java @@ -13,14 +13,15 @@ import twg2.jbcm.classFormat.constantPool.CONSTANT_Integer; import twg2.jbcm.classFormat.constantPool.CONSTANT_Long; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Annotation subtype of type element_value * TODO class needs cleaning up, is currently using multiple fields for a union type (I think, 2014-3-19) * @author TeamworkGuy2 * @since 2013-12-3 */ -public class Element_Value implements ReadWritable { +public class Element_Value implements ReadWritable, CpIndexChangeable { ClassFile resolver; /** The tag item indicates the type of this annotation element-value pair. * The letters B, C, D, F, I, J, S, and Z indicate a primitive type. These letters are @@ -96,13 +97,13 @@ public Element_Value(ClassFile resolver) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - if(const_value_index != null) IndexUtility.indexChange(const_value_index, oldIndex, newIndex); - if(const_name_index != null) IndexUtility.indexChange(const_name_index, oldIndex, newIndex); - if(type_name_index != null) IndexUtility.indexChange(type_name_index, oldIndex, newIndex); - if(class_info_index != null) IndexUtility.indexChange(class_info_index, oldIndex, newIndex); - if(annotation_value != null) IndexUtility.indexChange(annotation_value, oldIndex, newIndex); - if(values != null) IndexUtility.indexChange(values, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + if(const_value_index != null) indexChanger.indexChange(const_value_index); + if(const_name_index != null) indexChanger.indexChange(const_name_index); + if(type_name_index != null) indexChanger.indexChange(type_name_index); + if(class_info_index != null) indexChanger.indexChange(class_info_index); + if(annotation_value != null) indexChanger.indexChange(annotation_value); + if(values != null) indexChanger.indexChange(values); } diff --git a/src/twg2/jbcm/classFormat/attributes/Element_Value_Pair.java b/src/twg2/jbcm/classFormat/attributes/Element_Value_Pair.java index f5ab8f2..f15f5ba 100644 --- a/src/twg2/jbcm/classFormat/attributes/Element_Value_Pair.java +++ b/src/twg2/jbcm/classFormat/attributes/Element_Value_Pair.java @@ -8,14 +8,15 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.ReadWritable; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Annotation subtype of type Element_Value_Pair. * Represents a single element-value pair in an annotation structure. * @author TeamworkGuy2 * @since 2013-12-3 */ -public class Element_Value_Pair implements ReadWritable { +public class Element_Value_Pair implements ReadWritable, CpIndexChangeable { ClassFile resolver; /** The value of the element_name_index item must be a valid index into the constant_pool table. * The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (§4.4.7) @@ -35,9 +36,9 @@ public Element_Value_Pair(ClassFile resolver) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(element_name_index, oldIndex, newIndex); - IndexUtility.indexChange(value, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(element_name_index); + indexChanger.indexChange(value); } diff --git a/src/twg2/jbcm/classFormat/attributes/EnclosingMethod.java b/src/twg2/jbcm/classFormat/attributes/EnclosingMethod.java index ad4cdc0..23878bd 100644 --- a/src/twg2/jbcm/classFormat/attributes/EnclosingMethod.java +++ b/src/twg2/jbcm/classFormat/attributes/EnclosingMethod.java @@ -11,7 +11,7 @@ import twg2.jbcm.classFormat.constantPool.CONSTANT_Class; import twg2.jbcm.classFormat.constantPool.CONSTANT_NameAndType; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type EnclosingMethod * @author TeamworkGuy2 @@ -62,10 +62,10 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(class_index, oldIndex, newIndex); - IndexUtility.indexChange(method_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(class_index); + indexChanger.indexChange(method_index); } diff --git a/src/twg2/jbcm/classFormat/attributes/Exceptions.java b/src/twg2/jbcm/classFormat/attributes/Exceptions.java index c728375..3d936c5 100644 --- a/src/twg2/jbcm/classFormat/attributes/Exceptions.java +++ b/src/twg2/jbcm/classFormat/attributes/Exceptions.java @@ -10,7 +10,7 @@ import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Class; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type Exceptions * @author TeamworkGuy2 @@ -53,9 +53,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(exception_index_table, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(exception_index_table); } diff --git a/src/twg2/jbcm/classFormat/attributes/InnerClasses.java b/src/twg2/jbcm/classFormat/attributes/InnerClasses.java index 385e194..30820ab 100644 --- a/src/twg2/jbcm/classFormat/attributes/InnerClasses.java +++ b/src/twg2/jbcm/classFormat/attributes/InnerClasses.java @@ -11,7 +11,8 @@ import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Class; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type InnerClasses * @author TeamworkGuy2 @@ -57,9 +58,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(classes, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(classes); } @@ -109,7 +110,7 @@ public String toString() { * @author TeamworkGuy2 * @since 2013-7-7 */ - public static class InnerClassPoint implements ReadWritable { + public static class InnerClassPoint implements ReadWritable, CpIndexChangeable { ClassFile resolver; /** Every CONSTANT_Class_info entry in the constant_pool table which represents a class or interface C that is not * a package member must have exactly one corresponding entry in the classes array. @@ -163,10 +164,10 @@ public InnerClassPoint(ClassFile resolver) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(inner_class_info_index, oldIndex, newIndex); - IndexUtility.indexChange(outer_class_info_index, oldIndex, newIndex); - IndexUtility.indexChange(inner_name_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(inner_class_info_index); + indexChanger.indexChange(outer_class_info_index); + indexChanger.indexChange(inner_name_index); } diff --git a/src/twg2/jbcm/classFormat/attributes/LineNumberTable.java b/src/twg2/jbcm/classFormat/attributes/LineNumberTable.java index e953da4..0745905 100644 --- a/src/twg2/jbcm/classFormat/attributes/LineNumberTable.java +++ b/src/twg2/jbcm/classFormat/attributes/LineNumberTable.java @@ -10,7 +10,8 @@ import twg2.jbcm.classFormat.ReadWritable; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type LineNumberTable * @author TeamworkGuy2 @@ -54,9 +55,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(line_number_table, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(line_number_table); } @@ -104,7 +105,7 @@ public String toString() { * @author TeamworkGuy2 * @since 2013-7-7 */ - public static class LineNumberPoint implements ReadWritable { + public static class LineNumberPoint implements ReadWritable, CpIndexChangeable { Code parent; /** Each entry in the line_number_table array indicates that the line number in the original source file changes at * a given point in the code array. Each line_number_table entry must contain the following two items: @@ -126,7 +127,7 @@ public LineNumberPoint(Code codeParent) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } diff --git a/src/twg2/jbcm/classFormat/attributes/LocalVariableTable.java b/src/twg2/jbcm/classFormat/attributes/LocalVariableTable.java index 1c712ef..9b28c90 100644 --- a/src/twg2/jbcm/classFormat/attributes/LocalVariableTable.java +++ b/src/twg2/jbcm/classFormat/attributes/LocalVariableTable.java @@ -11,7 +11,7 @@ import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; import twg2.jbcm.modify.AttributeOffsetFunction; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; import twg2.jbcm.modify.OffsetAttribute; /** A Java class file format Attribute of type {@code LocalVariableTable} @@ -79,9 +79,9 @@ public AttributeOffsetFunction getAttributeOffsetModifier() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(local_variable_table, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(local_variable_table); } @@ -193,9 +193,9 @@ public AttributeOffsetFunction getAttributeOffsetModifier() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(name_index, oldIndex, newIndex); - IndexUtility.indexChange(descriptor_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(name_index); + indexChanger.indexChange(descriptor_index); } diff --git a/src/twg2/jbcm/classFormat/attributes/LocalVariableTypeTable.java b/src/twg2/jbcm/classFormat/attributes/LocalVariableTypeTable.java index 5f68a81..35dc0f7 100644 --- a/src/twg2/jbcm/classFormat/attributes/LocalVariableTypeTable.java +++ b/src/twg2/jbcm/classFormat/attributes/LocalVariableTypeTable.java @@ -10,7 +10,8 @@ import twg2.jbcm.classFormat.ReadWritable; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type {@code LocalVariableTable} * @author TeamworkGuy2 @@ -56,9 +57,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(local_variable_type_table, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(local_variable_type_table); } @@ -106,7 +107,7 @@ public String toString() { * @author TeamworkGuy2 * @since 2013-12-3 */ - public static class LocalVariableTypePoint implements ReadWritable { + public static class LocalVariableTypePoint implements ReadWritable, CpIndexChangeable { Code parent; /** Each entry in the local_variable_type_table array indicates a range of code array offsets within which a local * variable has a value. It also indicates the index into the local variable array of the current frame at which @@ -143,9 +144,9 @@ public LocalVariableTypePoint(Code codeParent) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(name_index, oldIndex, newIndex); - IndexUtility.indexChange(signature_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(name_index); + indexChanger.indexChange(signature_index); } diff --git a/src/twg2/jbcm/classFormat/attributes/MethodParameters.java b/src/twg2/jbcm/classFormat/attributes/MethodParameters.java index 937dfa8..18b2408 100644 --- a/src/twg2/jbcm/classFormat/attributes/MethodParameters.java +++ b/src/twg2/jbcm/classFormat/attributes/MethodParameters.java @@ -11,7 +11,8 @@ import twg2.jbcm.classFormat.ReadWritable; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type MethodParameters * @author TeamworkGuy2 @@ -82,9 +83,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(parameters, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(parameters); } @@ -134,7 +135,7 @@ public String toString() { * @author TeamworkGuy2 * @since 2014-3-19 */ - public static class Parameter_Entry implements ReadWritable { + public static class Parameter_Entry implements ReadWritable, CpIndexChangeable { ClassFile resolver; /** The value of the name_index item must either be zero or a valid index into the constant_pool table.
* If the value of the name_index item is zero, then this parameters element indicates a formal @@ -172,9 +173,9 @@ public Parameter_Entry(ClassFile resolver, short nameIndex, short accessFlags) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { if(name_index.getIndex() != 0) { - IndexUtility.indexChange(name_index, oldIndex, newIndex); + indexChanger.indexChange(name_index); } } diff --git a/src/twg2/jbcm/classFormat/attributes/Module.java b/src/twg2/jbcm/classFormat/attributes/Module.java index 2a800b6..9d5574d 100644 --- a/src/twg2/jbcm/classFormat/attributes/Module.java +++ b/src/twg2/jbcm/classFormat/attributes/Module.java @@ -14,7 +14,8 @@ import twg2.jbcm.classFormat.constantPool.CONSTANT_Module; import twg2.jbcm.classFormat.constantPool.CONSTANT_Package; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type Module * @author TeamworkGuy2 @@ -114,15 +115,15 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(module_name_index, oldIndex, newIndex); - IndexUtility.indexChange(module_version_index, oldIndex, newIndex); - IndexUtility.indexChange(requires, oldIndex, newIndex); - IndexUtility.indexChange(exports, oldIndex, newIndex); - IndexUtility.indexChange(opens, oldIndex, newIndex); - IndexUtility.indexChange(uses_index, oldIndex, newIndex); - IndexUtility.indexChange(provides, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(module_name_index); + indexChanger.indexChange(module_version_index); + indexChanger.indexChange(requires); + indexChanger.indexChange(exports); + indexChanger.indexChange(opens); + indexChanger.indexChange(uses_index); + indexChanger.indexChange(provides); } @@ -273,7 +274,7 @@ public String toString() { * @author TeamworkGuy2 * @since 2017-12-22 */ - public static class ModuleRequire implements ReadWritable { + public static class ModuleRequire implements ReadWritable, CpIndexChangeable { ClassFile resolver; /** The value of the requires_index item must be a valid index into the constant_pool table. The constant_pool entry * at that index must be a CONSTANT_Module_info structure denoting a module on which the current module depends. @@ -302,9 +303,9 @@ public ModuleRequire(ClassFile resolver) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(requires_index, oldIndex, newIndex); - IndexUtility.indexChange(requires_version_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(requires_index); + indexChanger.indexChange(requires_version_index); } @@ -343,7 +344,7 @@ public String toString() { * @author TeamworkGuy2 * @since 2017-12-22 */ - public static class ModuleExport implements ReadWritable { + public static class ModuleExport implements ReadWritable, CpIndexChangeable { ClassFile resolver; /** The value of the exports_index item must be a valid index into the constant_pool table. The constant_pool entry * at that index must be a CONSTANT_Package_info structure representing a package exported by the current module. @@ -376,9 +377,9 @@ public ModuleExport(ClassFile resolver) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(exports_index, oldIndex, newIndex); - IndexUtility.indexChange(exports_to_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(exports_index); + indexChanger.indexChange(exports_to_index); } @@ -428,7 +429,7 @@ public String toString() { * @author TeamworkGuy2 * @since 2017-12-22 */ - public static class ModuleOpen implements ReadWritable { + public static class ModuleOpen implements ReadWritable, CpIndexChangeable { ClassFile resolver; /** The value of the opens_index item must be a valid index into the constant_pool table. The constant_pool entry * at that index must be a CONSTANT_Package_info structure representing a package opened by the current module. @@ -461,9 +462,9 @@ public ModuleOpen(ClassFile resolver) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(opens_index, oldIndex, newIndex); - IndexUtility.indexChange(opens_to_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(opens_index); + indexChanger.indexChange(opens_to_index); } @@ -513,7 +514,7 @@ public String toString() { * @author TeamworkGuy2 * @since 2017-12-22 */ - public static class ModuleProvide implements ReadWritable { + public static class ModuleProvide implements ReadWritable, CpIndexChangeable { ClassFile resolver; /** The value of the provides_index item must be a valid index into the constant_pool table. The constant_pool entry * at that index must be a CONSTANT_Class_info structure representing a service interface for which the current module provides a service implementation. @@ -538,9 +539,9 @@ public ModuleProvide(ClassFile resolver) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(provides_index, oldIndex, newIndex); - IndexUtility.indexChange(provides_to_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(provides_index); + indexChanger.indexChange(provides_to_index); } diff --git a/src/twg2/jbcm/classFormat/attributes/ModuleMainClass.java b/src/twg2/jbcm/classFormat/attributes/ModuleMainClass.java index 9dec98c..87b65d5 100644 --- a/src/twg2/jbcm/classFormat/attributes/ModuleMainClass.java +++ b/src/twg2/jbcm/classFormat/attributes/ModuleMainClass.java @@ -10,7 +10,7 @@ import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Class; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type Module * @author TeamworkGuy2 @@ -57,8 +57,8 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(main_class_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(main_class_index); } diff --git a/src/twg2/jbcm/classFormat/attributes/ModulePackages.java b/src/twg2/jbcm/classFormat/attributes/ModulePackages.java index 0974db0..6836f6e 100644 --- a/src/twg2/jbcm/classFormat/attributes/ModulePackages.java +++ b/src/twg2/jbcm/classFormat/attributes/ModulePackages.java @@ -10,7 +10,7 @@ import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Package; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type ModulePackages * @author TeamworkGuy2 @@ -56,8 +56,8 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(package_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(package_index); } diff --git a/src/twg2/jbcm/classFormat/attributes/Parameter_Annotations.java b/src/twg2/jbcm/classFormat/attributes/Parameter_Annotations.java index 33da31f..a79f1ae 100644 --- a/src/twg2/jbcm/classFormat/attributes/Parameter_Annotations.java +++ b/src/twg2/jbcm/classFormat/attributes/Parameter_Annotations.java @@ -6,13 +6,14 @@ import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.ReadWritable; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Annotation subtype of type Parameter_Annotation * @author TeamworkGuy2 * @since 2013-12-3 */ -public class Parameter_Annotations implements ReadWritable { +public class Parameter_Annotations implements ReadWritable, CpIndexChangeable { ClassFile resolver; /** The value of the num_annotations item indicates the number of run-time-invisible annotations * on the parameter corresponding to the sequence number of this parameter_annotations element. @@ -30,8 +31,8 @@ public Parameter_Annotations(ClassFile resolver) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(annotations, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(annotations); } diff --git a/src/twg2/jbcm/classFormat/attributes/RuntimeInvisibleAnnotations.java b/src/twg2/jbcm/classFormat/attributes/RuntimeInvisibleAnnotations.java index a240174..c8965d9 100644 --- a/src/twg2/jbcm/classFormat/attributes/RuntimeInvisibleAnnotations.java +++ b/src/twg2/jbcm/classFormat/attributes/RuntimeInvisibleAnnotations.java @@ -9,7 +9,7 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type RuntimeInvisibleAnnotations * @author TeamworkGuy2 @@ -58,9 +58,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(annotations, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(annotations); } diff --git a/src/twg2/jbcm/classFormat/attributes/RuntimeInvisibleParameterAnnotations.java b/src/twg2/jbcm/classFormat/attributes/RuntimeInvisibleParameterAnnotations.java index b17794f..7396e4b 100644 --- a/src/twg2/jbcm/classFormat/attributes/RuntimeInvisibleParameterAnnotations.java +++ b/src/twg2/jbcm/classFormat/attributes/RuntimeInvisibleParameterAnnotations.java @@ -9,7 +9,7 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type RuntimeInvisibleParameterAnnotations * @author TeamworkGuy2 @@ -61,9 +61,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(parameter_annotations, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(parameter_annotations); } diff --git a/src/twg2/jbcm/classFormat/attributes/RuntimeInvisibleTypeAnnotations.java b/src/twg2/jbcm/classFormat/attributes/RuntimeInvisibleTypeAnnotations.java index fc79a96..90589d7 100644 --- a/src/twg2/jbcm/classFormat/attributes/RuntimeInvisibleTypeAnnotations.java +++ b/src/twg2/jbcm/classFormat/attributes/RuntimeInvisibleTypeAnnotations.java @@ -9,7 +9,7 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type RuntimeInvisibleTypeAnnotations * @author TeamworkGuy2 @@ -56,9 +56,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(annotations, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(annotations); } diff --git a/src/twg2/jbcm/classFormat/attributes/RuntimeVisibleAnnotations.java b/src/twg2/jbcm/classFormat/attributes/RuntimeVisibleAnnotations.java index 2b01d77..931a9d3 100644 --- a/src/twg2/jbcm/classFormat/attributes/RuntimeVisibleAnnotations.java +++ b/src/twg2/jbcm/classFormat/attributes/RuntimeVisibleAnnotations.java @@ -9,7 +9,7 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type RuntimeVisibleAnnotations * @author TeamworkGuy2 @@ -58,9 +58,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(annotations, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(annotations); } diff --git a/src/twg2/jbcm/classFormat/attributes/RuntimeVisibleParameterAnnotations.java b/src/twg2/jbcm/classFormat/attributes/RuntimeVisibleParameterAnnotations.java index 5e52116..63ae4db 100644 --- a/src/twg2/jbcm/classFormat/attributes/RuntimeVisibleParameterAnnotations.java +++ b/src/twg2/jbcm/classFormat/attributes/RuntimeVisibleParameterAnnotations.java @@ -9,7 +9,7 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type RuntimeInvisibleParameterAnnotations * @author TeamworkGuy2 @@ -61,9 +61,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(parameter_annotations, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(parameter_annotations); } diff --git a/src/twg2/jbcm/classFormat/attributes/RuntimeVisibleTypeAnnotations.java b/src/twg2/jbcm/classFormat/attributes/RuntimeVisibleTypeAnnotations.java index a3130bd..916d69a 100644 --- a/src/twg2/jbcm/classFormat/attributes/RuntimeVisibleTypeAnnotations.java +++ b/src/twg2/jbcm/classFormat/attributes/RuntimeVisibleTypeAnnotations.java @@ -9,7 +9,7 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type RuntimeVisibleTypeAnnotations * @author TeamworkGuy2 @@ -55,9 +55,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(annotations, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(annotations); } diff --git a/src/twg2/jbcm/classFormat/attributes/Signature.java b/src/twg2/jbcm/classFormat/attributes/Signature.java index 4440915..2e9edf4 100644 --- a/src/twg2/jbcm/classFormat/attributes/Signature.java +++ b/src/twg2/jbcm/classFormat/attributes/Signature.java @@ -9,7 +9,7 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type Signature * @author TeamworkGuy2 @@ -53,9 +53,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(signature_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(signature_index); } diff --git a/src/twg2/jbcm/classFormat/attributes/SourceDebugExtension.java b/src/twg2/jbcm/classFormat/attributes/SourceDebugExtension.java index bd0e535..352cf4c 100644 --- a/src/twg2/jbcm/classFormat/attributes/SourceDebugExtension.java +++ b/src/twg2/jbcm/classFormat/attributes/SourceDebugExtension.java @@ -10,7 +10,7 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type SourceDebugExtension * @author TeamworkGuy2 @@ -56,8 +56,8 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); } diff --git a/src/twg2/jbcm/classFormat/attributes/SourceFile.java b/src/twg2/jbcm/classFormat/attributes/SourceFile.java index 3894d1b..2544257 100644 --- a/src/twg2/jbcm/classFormat/attributes/SourceFile.java +++ b/src/twg2/jbcm/classFormat/attributes/SourceFile.java @@ -9,7 +9,7 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type SourceFile * @author TeamworkGuy2 @@ -53,9 +53,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(sourcefile_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(sourcefile_index); } diff --git a/src/twg2/jbcm/classFormat/attributes/StackMapTable.java b/src/twg2/jbcm/classFormat/attributes/StackMapTable.java index 8f89a0a..3251c0e 100644 --- a/src/twg2/jbcm/classFormat/attributes/StackMapTable.java +++ b/src/twg2/jbcm/classFormat/attributes/StackMapTable.java @@ -10,7 +10,8 @@ import twg2.jbcm.classFormat.ReadWritable; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type StackMapTable * @author TeamworkGuy2 @@ -62,9 +63,9 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); - IndexUtility.indexChange(entries, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); + indexChanger.indexChange(entries); } @@ -111,7 +112,7 @@ public String toString() { * @author TeamworkGuy2 * @since 2013-10-6 */ - public static class StackMapFrame implements ReadWritable { + public static class StackMapFrame implements ReadWritable, CpIndexChangeable { ClassFile resolver; /** * 0-63 = same_frame @@ -154,8 +155,8 @@ public StackMapFrame(ClassFile resolver) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(stack, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(stack); } diff --git a/src/twg2/jbcm/classFormat/attributes/Synthetic.java b/src/twg2/jbcm/classFormat/attributes/Synthetic.java index a295353..0ed68ad 100644 --- a/src/twg2/jbcm/classFormat/attributes/Synthetic.java +++ b/src/twg2/jbcm/classFormat/attributes/Synthetic.java @@ -9,7 +9,7 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type Synthetic * @author TeamworkGuy2 @@ -45,8 +45,8 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); } diff --git a/src/twg2/jbcm/classFormat/attributes/Target_Info.java b/src/twg2/jbcm/classFormat/attributes/Target_Info.java index 38d0df5..f1731ae 100644 --- a/src/twg2/jbcm/classFormat/attributes/Target_Info.java +++ b/src/twg2/jbcm/classFormat/attributes/Target_Info.java @@ -1,12 +1,13 @@ package twg2.jbcm.classFormat.attributes; import twg2.jbcm.classFormat.ReadWritable; +import twg2.jbcm.modify.CpIndexChangeable; /** A marker interface for {@link Target_Info} types. * @author TeamworkGuy2 * @since 2014-3-19 */ -public interface Target_Info extends ReadWritable { +public interface Target_Info extends ReadWritable, CpIndexChangeable { } diff --git a/src/twg2/jbcm/classFormat/attributes/Target_Info_Union.java b/src/twg2/jbcm/classFormat/attributes/Target_Info_Union.java index 4fec740..e376422 100644 --- a/src/twg2/jbcm/classFormat/attributes/Target_Info_Union.java +++ b/src/twg2/jbcm/classFormat/attributes/Target_Info_Union.java @@ -5,7 +5,7 @@ import java.io.IOException; import twg2.jbcm.classFormat.ReadWritable; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A container class for all {@link Target_Info} classes * which are a member type in {@link TypeAnnotation}.
@@ -47,7 +47,7 @@ public static class Type_Parameter_Target implements ReadWritable, Target_Info { byte type_parameter_index; @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } @Override @@ -86,7 +86,7 @@ public static class Supertype_Target implements ReadWritable, Target_Info { short supertype_index; @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } @Override @@ -131,7 +131,7 @@ public static class Type_Parameter_Bound_Target implements ReadWritable, Target_ byte bound_index; @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } @Override @@ -170,7 +170,7 @@ public static class Empty_Target implements ReadWritable, Target_Info { ; @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } @Override @@ -209,7 +209,7 @@ public static class Formal_Parameter_Target implements ReadWritable, Target_Info byte formal_parameter_index; @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } @Override @@ -245,7 +245,7 @@ public static class Throws_Target implements ReadWritable, Target_Info { short throws_type_index; @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } @Override @@ -303,8 +303,8 @@ public static class Localvar_Target implements ReadWritable, Target_Info { Localvar_Target_Table_Entry[] table; @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(table, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(table); } @Override @@ -364,7 +364,7 @@ public static class Localvar_Target_Table_Entry implements ReadWritable, Code_At @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } @@ -412,7 +412,7 @@ public static class Catch_Target implements ReadWritable, Target_Info { short exception_table_index; @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } @Override @@ -449,7 +449,7 @@ public static class Offset_Target implements ReadWritable, Target_Info { short offset; @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } @Override @@ -497,7 +497,7 @@ public static class Type_Argument_Target implements ReadWritable, Target_Info { byte type_argument_index; @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } @Override diff --git a/src/twg2/jbcm/classFormat/attributes/TypeAnnotation.java b/src/twg2/jbcm/classFormat/attributes/TypeAnnotation.java index 2e82e14..c394c2e 100644 --- a/src/twg2/jbcm/classFormat/attributes/TypeAnnotation.java +++ b/src/twg2/jbcm/classFormat/attributes/TypeAnnotation.java @@ -8,13 +8,14 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.ReadWritable; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** * @author TeamworkGuy2 * @since 2014-3-19 */ -public class TypeAnnotation implements ReadWritable { +public class TypeAnnotation implements ReadWritable, CpIndexChangeable { ClassFile resolver; /** The value of the target_type item denotes the kind of target on which the annotation appears. * The various kinds of target correspond to the type contexts of the Java programming language @@ -98,11 +99,11 @@ public TypeAnnotation(ClassFile resolver) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(target_info, oldIndex, newIndex); - IndexUtility.indexChange(target_path, oldIndex, newIndex); - IndexUtility.indexChange(type_index, oldIndex, newIndex); - IndexUtility.indexChange(element_value_pairs, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(target_info); + indexChanger.indexChange(target_path); + indexChanger.indexChange(type_index); + indexChanger.indexChange(element_value_pairs); } @@ -217,14 +218,14 @@ public String toString() { * @author TeamworkGuy2 * @since 2014-3-19 */ - public static class Type_Path implements ReadWritable { + public static class Type_Path implements ReadWritable, CpIndexChangeable { byte table_length; Type_Path_Table_Entry[] table; @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(table, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(table); } @Override @@ -337,7 +338,7 @@ public String toString() { * @author TeamworkGuy2 * @since 2014-3-19 */ - public static class Type_Path_Table_Entry implements ReadWritable { + public static class Type_Path_Table_Entry implements ReadWritable, CpIndexChangeable { byte type_path_kind; byte type_argument_index; @@ -353,7 +354,7 @@ public Type_Path_Table_Entry(byte typePathKind, byte typeArgumentIndex) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } diff --git a/src/twg2/jbcm/classFormat/attributes/UnknownAttributeType.java b/src/twg2/jbcm/classFormat/attributes/UnknownAttributeType.java index c0b86af..69ec257 100644 --- a/src/twg2/jbcm/classFormat/attributes/UnknownAttributeType.java +++ b/src/twg2/jbcm/classFormat/attributes/UnknownAttributeType.java @@ -9,7 +9,7 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute for an unrecognized or unknown attribute type * @author TeamworkGuy2 @@ -46,8 +46,8 @@ public int getAttributeLength() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(attribute_name_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(attribute_name_index); } diff --git a/src/twg2/jbcm/classFormat/attributes/VerificationTypeInfo.java b/src/twg2/jbcm/classFormat/attributes/VerificationTypeInfo.java index 69f038d..1687346 100644 --- a/src/twg2/jbcm/classFormat/attributes/VerificationTypeInfo.java +++ b/src/twg2/jbcm/classFormat/attributes/VerificationTypeInfo.java @@ -8,13 +8,14 @@ import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.ReadWritable; import twg2.jbcm.classFormat.constantPool.CONSTANT_Class; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChangeable; +import twg2.jbcm.modify.CpIndexChanger; /** A Java class file format Attribute of type VerificationTypeInfo for a {@link StackMapTable.StackMapFrame} * @author TeamworkGuy2 * @since 2013-10-6 */ -public class VerificationTypeInfo implements ReadWritable { +public class VerificationTypeInfo implements ReadWritable, CpIndexChangeable { ClassFile resolver; /** The verification type info: * 0 = TOP @@ -67,9 +68,9 @@ public VerificationTypeInfo(ClassFile resolver, byte tag, short value) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { if(tag == 7) { - IndexUtility.indexChange(cpool_index, oldIndex, newIndex); + indexChanger.indexChange(cpool_index); } } diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_CP_Info.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_CP_Info.java index 9b51195..6add768 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_CP_Info.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_CP_Info.java @@ -1,12 +1,13 @@ package twg2.jbcm.classFormat.constantPool; import twg2.jbcm.classFormat.ReadWritable; +import twg2.jbcm.modify.CpIndexChangeable; /** Interface for all Constant Pool info types in a Java class file format * @author TeamworkGuy2 * @since 2013-7-7 */ -public interface CONSTANT_CP_Info extends ReadWritable { +public interface CONSTANT_CP_Info extends ReadWritable, CpIndexChangeable { public int getTag(); diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Class.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Class.java index 9641cc2..cf7e014 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Class.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Class.java @@ -7,7 +7,7 @@ import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** Java class file format constant pool Class info type.
* Constant value = 7, class version = 45.3, Java SE = 1.0.2 @@ -37,8 +37,8 @@ public int getTag() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(name_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(name_index); } diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Double.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Double.java index 4f40c23..71cd238 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Double.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Double.java @@ -6,6 +6,7 @@ import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.Settings; +import twg2.jbcm.modify.CpIndexChanger; /** Java class file format constant pool Double info type.
* Constant value = 6, class version = 45.3, Java SE = 1.0.2 @@ -47,7 +48,7 @@ public int getTag() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Fieldref.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Fieldref.java index df5e7b9..4f64a1d 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Fieldref.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Fieldref.java @@ -7,7 +7,7 @@ import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; import twg2.jbcm.modify.TypeUtility; /** Java class file format constant pool Field reference info type.
@@ -45,9 +45,9 @@ public int getTag() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(class_index, oldIndex, newIndex); - IndexUtility.indexChange(name_and_type_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(class_index); + indexChanger.indexChange(name_and_type_index); } @@ -106,7 +106,11 @@ public String toShortString() { public String toString() { CONSTANT_Class clazz = class_index.getCpObject(); CONSTANT_NameAndType field = name_and_type_index.getCpObject(); - return "Fieldref(9, class=" + clazz.getName() + ", name=" + field.getName() + ", type=" + field.getDescriptor() + ")"; + // null checks for malformed classes, for example, when a constant pool item references another item ahead of + // it in the constant pool that hasn't been parsed yet + return "Fieldref(9, class=" + (clazz != null ? clazz.getName() : class_index) + + ", name=" + (field != null ? field.getName() : name_and_type_index) + + ", type=" + (field != null ? field.getDescriptor() : null) + ")"; } } diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Float.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Float.java index 861bc44..c6e7a9e 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Float.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Float.java @@ -6,6 +6,7 @@ import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.Settings; +import twg2.jbcm.modify.CpIndexChanger; /** Java class file format constant pool Float info type.
* Constant value = 4, class version = 45.3, Java SE = 1.0.2 @@ -45,7 +46,7 @@ public int getTag() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Integer.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Integer.java index b6c4279..c98b45b 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Integer.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Integer.java @@ -6,6 +6,7 @@ import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.Settings; +import twg2.jbcm.modify.CpIndexChanger; /** Java class file format constant pool Integer info type.
* Constant value = 3, class version = 45.3, Java SE = 1.0.2 @@ -34,7 +35,7 @@ public int getTag() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_InterfaceMethodref.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_InterfaceMethodref.java index 9578f43..bc63536 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_InterfaceMethodref.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_InterfaceMethodref.java @@ -7,7 +7,7 @@ import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; import twg2.jbcm.modify.TypeUtility; /** Java class file format constant pool Interface method reference info type.
@@ -46,9 +46,9 @@ public int getTag() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(class_index, oldIndex, newIndex); - IndexUtility.indexChange(name_and_type_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(class_index); + indexChanger.indexChange(name_and_type_index); } @@ -105,7 +105,11 @@ public String toShortString() { public String toString() { CONSTANT_Class clazz = class_index.getCpObject(); CONSTANT_NameAndType method = name_and_type_index.getCpObject(); - return "InterfaceMethodref(11, class=" + clazz.getName() + ", name=" + method.getName() + ", type=" + method.getDescriptor() + ")"; + // null checks for malformed classes, for example, when a constant pool item references another item ahead of + // it in the constant pool that hasn't been parsed yet + return "InterfaceMethodref(11, class=" + (clazz != null ? clazz.getName() : class_index) + + ", name=" + (method != null ? method.getName() : name_and_type_index) + + ", type=" + (method != null ? method.getDescriptor() : null) + ")"; } } diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_InvokeDynamic.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_InvokeDynamic.java index 34aedea..95258c0 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_InvokeDynamic.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_InvokeDynamic.java @@ -9,7 +9,7 @@ import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.attributes.BootstrapMethods; import twg2.jbcm.classFormat.attributes.BootstrapMethods.BootstrapMethod; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** Java class file format constant pool InvokeDynamic reference info type.
* Constant value = 18, class version = 51.0, Java SE = 7 @@ -43,8 +43,8 @@ public int getTag() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(name_and_type_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(name_and_type_index); } @@ -97,8 +97,11 @@ public String toShortString() { public String toString() { BootstrapMethods bootstrapMethod = ((BootstrapMethods)resolver.getBootstrapMethods()); CONSTANT_NameAndType method = name_and_type_index.getCpObject(); + // null checks for malformed classes, for example, when a constant pool item references another item ahead of + // it in the constant pool that hasn't been parsed yet return "InvokeDynamic(18, invoke_dynamic=" + bootstrapMethod.getBootstrapMethod(bootstrap_method_attr_index) + - ", name=" + method.getName() + ", type=" + method.getDescriptor() + ")"; + ", name=" + (method != null ? method.getName() : name_and_type_index) + + ", type=" + (method != null ? method.getDescriptor() : null) + ")"; } } diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Long.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Long.java index ac1d06a..927d5f2 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Long.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Long.java @@ -6,6 +6,7 @@ import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.Settings; +import twg2.jbcm.modify.CpIndexChanger; /** Java class file format constant pool Long info type.
* Constant value = 5, class version = 45.3, Java SE = 1.0.2 @@ -36,7 +37,7 @@ public int getTag() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_MethodHandle.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_MethodHandle.java index a23f9e4..b154a3e 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_MethodHandle.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_MethodHandle.java @@ -7,7 +7,7 @@ import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** Java class file format constant pool MethodHandle info type.
* Constant value = 15, class version = 51.0, Java SE = 7 @@ -68,8 +68,8 @@ public int getTag() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(reference_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(reference_index); } diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_MethodType.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_MethodType.java index d542bef..f56d209 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_MethodType.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_MethodType.java @@ -7,7 +7,7 @@ import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** Java class file format constant pool MethodType reference info type.
* Constant value = 16, class version = 51.0, Java SE = 7 @@ -37,8 +37,8 @@ public int getTag() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(descriptor_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(descriptor_index); } diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Methodref.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Methodref.java index 71afce9..50e0574 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Methodref.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Methodref.java @@ -7,7 +7,7 @@ import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; import twg2.jbcm.modify.TypeUtility; /** Java class file format constant pool Method reference info type.
@@ -49,9 +49,9 @@ public int getTag() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(class_index, oldIndex, newIndex); - IndexUtility.indexChange(name_and_type_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(class_index); + indexChanger.indexChange(name_and_type_index); } @@ -108,7 +108,11 @@ public String toShortString() { public String toString() { CONSTANT_Class clazz = class_index.getCpObject(); CONSTANT_NameAndType method = name_and_type_index.getCpObject(); - return "Methodref(10, class=" + clazz.getName() + ", name=" + method.getName() + ", type=" + method.getDescriptor() + ")"; + // null checks for malformed classes, for example, when a constant pool item references another item ahead of + // it in the constant pool that hasn't been parsed yet + return "Methodref(10, class=" + (clazz != null ? clazz.getName() : class_index) + + ", name=" + (method != null ? method.getName() : name_and_type_index) + + ", type=" + (method != null ? method.getDescriptor() : null) + ")"; } } diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Module.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Module.java index 4c981b0..10b664c 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Module.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Module.java @@ -7,7 +7,7 @@ import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** Java class file format constant pool Module info type.
* Constant value = 19, class version = 53.0, Java SE = 9
@@ -40,8 +40,8 @@ public int getTag() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(name_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(name_index); } diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_NameAndType.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_NameAndType.java index cab44f1..47250bc 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_NameAndType.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_NameAndType.java @@ -7,7 +7,7 @@ import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; import twg2.jbcm.modify.TypeUtility; /** Java class file format constant pool NameAndType info type.
@@ -44,9 +44,9 @@ public int getTag() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(name_index, oldIndex, newIndex); - IndexUtility.indexChange(descriptor_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(name_index); + indexChanger.indexChange(descriptor_index); } diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Package.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Package.java index f3c48d9..c8c8944 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Package.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Package.java @@ -7,7 +7,7 @@ import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** Java class file format constant pool Package info type.
* Constant value = 20, class version = 53.0, Java SE = 9
@@ -40,8 +40,8 @@ public int getTag() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(name_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(name_index); } @@ -81,7 +81,9 @@ public String toShortString() { @Override public String toString() { CONSTANT_Utf8 name = name_index.getCpObject(); - return "Package(19, name=" + name.getString() + ")"; + // null checks for malformed classes, for example, when a constant pool item references another item ahead of + // it in the constant pool that hasn't been parsed yet + return "Package(19, name=" + (name != null ? name.getString() : name_index) + ")"; } } diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_String.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_String.java index 4716a5d..45e5680 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_String.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_String.java @@ -7,7 +7,7 @@ import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.CpIndex; import twg2.jbcm.classFormat.Settings; -import twg2.jbcm.modify.IndexUtility; +import twg2.jbcm.modify.CpIndexChanger; /** Java class file format constant pool String info type.
* Constant value = 8, class version = 45.3, Java SE = 1.0.2 @@ -37,8 +37,8 @@ public int getTag() { @Override - public void changeCpIndex(short oldIndex, short newIndex) { - IndexUtility.indexChange(string_index, oldIndex, newIndex); + public void changeCpIndex(CpIndexChanger indexChanger) { + indexChanger.indexChange(string_index); } @@ -77,7 +77,7 @@ public String toShortString() { @Override public String toString() { - return "String(8, index=" + string_index + ", string=" + string_index.getCpObject() + ")"; + return "String(8, string=" + string_index.getCpObject() + ")"; } } diff --git a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Utf8.java b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Utf8.java index 2bc1820..b0607cc 100644 --- a/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Utf8.java +++ b/src/twg2/jbcm/classFormat/constantPool/CONSTANT_Utf8.java @@ -6,6 +6,7 @@ import twg2.jbcm.classFormat.ClassFile; import twg2.jbcm.classFormat.Settings; +import twg2.jbcm.modify.CpIndexChanger; /** Java class file format constant pool UTF-8 string info type.
* Constant value = 1, class version = 45.3, Java SE = 1.0.2 @@ -49,7 +50,7 @@ public CONSTANT_Utf8(ClassFile resolver) { @Override - public void changeCpIndex(short oldIndex, short newIndex) { + public void changeCpIndex(CpIndexChanger indexChanger) { } diff --git a/src/twg2/jbcm/ir/JumpConditionInfo.java b/src/twg2/jbcm/ir/JumpConditionInfo.java index 0910c8f..6ecb288 100644 --- a/src/twg2/jbcm/ir/JumpConditionInfo.java +++ b/src/twg2/jbcm/ir/JumpConditionInfo.java @@ -1,10 +1,9 @@ package twg2.jbcm.ir; +import java.util.Comparator; import java.util.List; import java.util.concurrent.atomic.AtomicReference; -import twg2.collections.primitiveCollections.IntArrayList; -import twg2.jbcm.CodeFlow; import twg2.jbcm.Opcodes; /** Contains the beginning and end opcodes and targets for a goto/if condition pair @@ -12,100 +11,154 @@ * @since 2020-08-15 */ public class JumpConditionInfo { - private final Opcodes opc; - private final int opcIdx; - private final int targetOffset; - private final IntArrayList codeFlow; - public final int codeFlowMaxIndex; - private boolean finished; + /** + * @author TeamworkGuy2 + * @since 2022-09-30 + */ + public enum UsageHint { + FOR_OR_WHILE_LOOP(16), + DO_WHILE_LOOP(16), + IF(1), + IF_WITHIN_LOOP_AND_WITH_LOOP_ENDS(1); + + /** Usage hint type/category: + * 1 = IF/ELSE
+ * 16 = LOOP
+ */ + private final byte type; + + UsageHint(int type) { + this.type = (byte)type; + } + + public static boolean isLoop(UsageHint hint) { + return hint != null && hint.type == 16; + } + } - public JumpConditionInfo(Opcodes opc, int opcIdx, int targetOffset, int codeFlowMaxIndex, IntArrayList codeFlow) { + + /** Sort jump conditions based on lower index and greatest range between lower and upper.
+ * 1. the lower of the {@link JumpConditionInfo#getLowerIndex()}
+ * 2. the greater of the {@link JumpConditionInfo#getUpperIndex()}
+ */ + public static final Comparator LOWER_INDEX_SORTER = (JumpConditionInfo o1, JumpConditionInfo o2) -> { + int lowerIdxDiff = o1.getLowerIndex() - o2.getLowerIndex(); + return lowerIdxDiff == 0 ? o2.getUpperIndex() - o1.getUpperIndex() : lowerIdxDiff; + }; + + public final Opcodes opc; + public final int opcIdx; + public final int targetOffset; + /** It is not always clear which IF_* instruction belongs to a loop (since loops are commonly detected via backward jumps (GOTOs). + * This value is a best guess of the code index of an IF_* instruction that belongs to the setup code for this loop. + * This index will be between the {@link #getTargetIndex()} and {@code opcIdx} + */ + public final int potentialIfIndex; + /** If {@code usageHint ==}{@link UsageHint#IF_WITHIN_LOOP_AND_WITH_LOOP_ENDS} then this index should be set with the + * end index of the loop that this condition resides within. This condition and the loop end at the same index. + */ + public final int loopEndIndexForIf; + /** A {@link UsageHint} best guess as to the structural usage of this condition within the code, i.e. whether it is a + * {@code for} loop or do { } while() loop or {@code if} statement. + */ + public final UsageHint usageHint; + + + public JumpConditionInfo(Opcodes opc, int opcIdx, int targetOffset, + int potentialIfIndex, int loopEndIndexForIf, UsageHint usageHint) { this.opc = opc; this.opcIdx = opcIdx; this.targetOffset = targetOffset; - this.codeFlowMaxIndex = codeFlowMaxIndex; - this.codeFlow = codeFlow; + this.potentialIfIndex = potentialIfIndex; + this.loopEndIndexForIf = loopEndIndexForIf; + this.usageHint = usageHint; } + /** The jump cause opcode, i.e. GOTO or IF* + */ public Opcodes getOpcode() { return opc; } + /** + * @return the index of the opcode within it's method code array + */ public int getOpcodeIndex() { return opcIdx; } - public IntArrayList getCodeFlow() { - return codeFlow; - } - - + /** The jump target index in the method's code array + */ public int getTargetIndex() { return opcIdx + targetOffset; } - public void finish() { - this.finished = true; + /** Get the lower index of {@link #getOpcodeIndex()} and {@link #getTargetIndex()}.
+ * For most if-statements the opcode index is lower.
+ * For most loops the target index is lower. + */ + public int getLowerIndex() { + return opcIdx + (targetOffset < 0 ? targetOffset : 0); } - public boolean isFinished() { - return finished; + /** Get the higher index of {@link #getOpcodeIndex()} and {@link #getTargetIndex()}.
+ * For most if-statements the jump/target index index is higher.
+ * For most loops the opcode index is higher. + */ + public int getUpperIndex() { + return opcIdx + (targetOffset >= 0 ? targetOffset : 0); } - /** Analyze a switch case and return helpful information about it's bytecode layout. - * Used by {@link #loadTableSwitch(int, byte[], List, AtomicReference) and {@link #loadLookupSwitch(int, byte[], List, AtomicReference)} - * @param caseMatch the value to match for this case in the switch - * @param targetIdx the target {@code instr} index at which the case's code begins - * @param instr the method bytecode array - * @return the analyzed switch information + /** Create a clone of this object with a new {@link #potentialIfIndex} + * @param potentialIfIndex potential index of the IF_* opcode at the beginning of this loop, if it is a loop, otherwise -1 */ - public static JumpConditionInfo loadConditionFlow(Opcodes opc, int idx, int targetOffset, byte[] instr) { - // analyze code flow path - var condFlowPath = new IntArrayList(); - condFlowPath.add(~idx); - CodeFlow.getFlowPaths(idx, instr, condFlowPath); + public JumpConditionInfo withPotentialIfIndex(int index) { + return new JumpConditionInfo(opc, opcIdx, targetOffset, index, loopEndIndexForIf, usageHint); + } - // potential end index (probably redundant once code flow is working) - var maxCodeFlowIndex = CodeFlow.maxIndex(condFlowPath); - return new JumpConditionInfo(opc, idx, targetOffset, maxCodeFlowIndex, condFlowPath); + public JumpConditionInfo withLoopEndIndexForIf(int loopEndTarget) { + return new JumpConditionInfo(opc, opcIdx, targetOffset, potentialIfIndex, loopEndTarget, UsageHint.IF_WITHIN_LOOP_AND_WITH_LOOP_ENDS); } - public static int findLoopStart(int curIdx, int jumpRelative, List loops) { - // Loops are generally compiled using a GOTO and an IF_* instruction - // form 1: [..., GOTO , instructions[], setup_if[], IF_* , ...] - if(jumpRelative < 0) { - var jumpToIdx = curIdx + jumpRelative - 3; // GOTO has a 2 byte operand so -3 is the GOTO instruction index right before the jump destination (which is the first instruction in a loop) - for(int i = loops.size() - 1; i >= 0; i--) { - var cond = loops.get(i); - if(cond.getOpcodeIndex() == jumpToIdx) { - return i; - } - } - } - return -1; + /** Create a clone of this object with a new {@link #usageHint} + */ + public JumpConditionInfo withUsageHint(UsageHint hint) { + return new JumpConditionInfo(opc, opcIdx, targetOffset, potentialIfIndex, loopEndIndexForIf, hint); } - public static int findLoopEnd(int curIdx, int numOperands, int jumpRelative, List loops) { - if(jumpRelative > 0) { - var instAfterJumpIdx = curIdx + numOperands + 1; - for(int i = loops.size() - 1; i >= 0; i--) { - var cond = loops.get(i); - if(cond.getTargetIndex() == instAfterJumpIdx) { - return i; - } - } - } - return -1; + @Override + public String toString() { + return "condition at " + this.opcIdx + " (" + this.opc + ")"; + } + + + /** Analyze the flow of a sub-section of code and return information about its bytecode layout.
+ * Used by {@link #loadTableSwitch(int, byte[], List, AtomicReference) and {@link #loadLookupSwitch(int, byte[], List, AtomicReference)} + * @param opc the instruction op-code + * @param idx the {@code instr} index at which the {@code opc} instruction is located + * @param targetOffset offset from {@code idx} into the {@code instr} array that this condition points to + * @param code the method bytecode array + * @param usageHint a best guess hint of the jump condition's usage + * @return the analyzed code flow information + */ + public static JumpConditionInfo loadConditionFlow(Opcodes opc, int idx, int targetOffset, byte[] code, UsageHint usageHint) { + // follow an array of jump points found in the code + //var condFlowPath = CodeFlow.getFlowPaths(code, idx); + + // potential end index (probably redundant once code flow is working) + //var maxCodeFlowIndex = CodeFlow.maxIndex(condFlowPath); + + return new JumpConditionInfo(opc, idx, targetOffset, -1, -1, usageHint); } } diff --git a/src/twg2/jbcm/main/RuntimeReloadMain.java b/src/twg2/jbcm/main/RuntimeReloadMain.java index 7d424ba..e929ebf 100644 --- a/src/twg2/jbcm/main/RuntimeReloadMain.java +++ b/src/twg2/jbcm/main/RuntimeReloadMain.java @@ -1,32 +1,19 @@ package twg2.jbcm.main; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.net.URL; -import java.net.URLClassLoader; -import java.nio.channels.FileChannel; import java.util.NoSuchElementException; import java.util.Scanner; +import twg2.jbcm.runtime.ClassLoaders; +import twg2.jbcm.runtime.ClassLoaders.ThreadMethodResultFuture; +import twg2.jbcm.runtime.FileUtility; + /** Test how and whether classes can be reloaded during runtime * @author TeamworkGuy2 * @since 2013-7-20 */ -public class RuntimeReloadMain implements Runnable { - private static final String classPostfix = ".class"; - private static final String defaultMainClassPath = "res/destination"; - private static final String classPath2 = "res/second_runtime"; - private static URL appPath; - private static String appPathStr; - private String className; - private String methodName; - private Object classInstance; - private Object[] arguments; +public class RuntimeReloadMain { private Class previousReload; private Class currentReload; @@ -34,17 +21,17 @@ public class RuntimeReloadMain implements Runnable { /** Load the specified classes over and over for testing purposes. * Trying to test if an application running an instance of this class can reload a newer version of this class * and continue running normally without needing to restart - * @param customClassPath the custom class path to load classes from + * @param customClasspath the custom class path to load classes from * @param customPath2 the second custom class path to copy overwrite files from * @param args the string array arguments to pass to the method being called */ - public void loadLoopUserInput(String customClassPath, String customPath2, String[] args) { - String applicationPath = getApplicationPathString(); + public void loadLoopUserInput(String customClasspath, String customPath2, String[] args) { + String applicationPath = ClassLoaders.getApplicationPathString(); - String path = new File(applicationPath).getParent() + File.separatorChar + customClassPath; + String path = new File(applicationPath).getParent() + File.separatorChar + customClasspath; String path2 = new File(applicationPath).getParent() + File.separatorChar + customPath2; System.out.println("Classpath=" + path + "\nCopyFromPath=" + path2); - byte choice = 0; + char choice = 0; boolean doLoop = true; @SuppressWarnings("resource") @@ -53,37 +40,37 @@ public void loadLoopUserInput(String customClassPath, String customPath2, String // Loop to process class loading choices while(doLoop) { System.out.print("Load next class (a=Reload.main(), b=Test.main(), c=overwrite-call-RuntimeReloadMain.main(), i=compare, z=exit): "); - Thread t = null; + ThreadMethodResultFuture t = null; try { - choice = (byte)input.nextLine().charAt(0); + choice = input.nextLine().charAt(0); } catch(NoSuchElementException e) { e.printStackTrace(); } if(choice == 'a') { System.out.println("Choice: " + choice); - t= callClassMethod(path, "classLoading.Reload", "main", null, (Object)args); + t = ClassLoaders.callClassMethod(path, "classLoading.Reload", "main", null, (Object)args); try { - t.join(); + t.thread.join(); } catch (InterruptedException e) { System.err.println("Error waiting for thread: " + e.getLocalizedMessage()); } } else if(choice == 'b') { System.out.println("Choice: " + choice); - t = callClassMethod(path, "classLoading.base.Test", "main", null, (Object)args); + t = ClassLoaders.callClassMethod(path, "classLoading.base.Test", "main", null, (Object)args); try { - t.join(); + t.thread.join(); } catch (InterruptedException e) { System.err.println("Error waiting for thread: " + e.getLocalizedMessage()); } } else if(choice == 'c') { System.out.println("Choice loader: " + choice); - overwriteClass(path, "classLoading.Settings", path2, "classLoading.Settings", "main", null, new Object[] {args}); - t = callClassMethod(path, "classLoading.Reload", "main", null, new Object[] {args}); + FileUtility.overwriteClass(path, "classLoading.Settings", path2, "classLoading.Settings"); + t = ClassLoaders.callClassMethod(path, "classLoading.Reload", "main", null, new Object[] {args}); try { - t.join(); + t.thread.join(); } catch (InterruptedException e) { System.err.println("Error waiting for thread: " + e.getLocalizedMessage()); } @@ -103,278 +90,16 @@ else if(choice == 'z') { } - /** Load the specified classes over and over for testing purposes. + /** Load the specified class and run the specified method on an instance of that class. * Trying to test if an application running an instance of this class can reload a newer version of this class * and continue running normally without needing to restart - * @param args - the string array arguments to pass to the method being called - */ - public void loadRun(String customClassPath, String className, String methodName, String[] args) { - String applicationPath = getApplicationPathString(); - - String mainClassPath = customClassPath; - String path = new File(applicationPath).getParent() + File.separatorChar + mainClassPath; - System.out.println("Classpath=" + applicationPath + "\nAlternate path=" + path); - - System.out.print("Load class: "); - callClassMethod(path, className, methodName, null, (Object)args); - } - - - /** Call the method name in the class name saved in this object's member variables + * @param args the arguments to pass to the method being called */ - @Override - public void run() { - callMethod(className, classInstance, methodName, arguments); - } - - - /** Call a method reflexively - * @param className the name of the class to containing the method - * @param instance the object instance to use, or null if the method is - * static or a new instance should be created - * @param methodName the name of the method to call - * @param args the parameters to pass to the method - */ - public void callMethod(String className, Object instance, String methodName, Object[] args) { - Class clazz = null; - // Create the list of parameter class types from the list of parameters - Class[] argumentTypes = null; - if(args != null && !(args.length == 1 && args[0] == null)) { - int argCount = args.length; - argumentTypes = new Class[argCount]; - for(int i = 0; i < argCount; i++) { - argumentTypes[i] = args[i].getClass(); - } - } - else { - args = null; - } - // Get this thread's class loader and load the class, then get the method in the class with the specified name - Method method = null; - int modifiers = -1; - try { - clazz = Thread.currentThread().getContextClassLoader().loadClass(className); - method = clazz.getMethod(methodName, argumentTypes); - modifiers = method.getModifiers(); - } catch (SecurityException e1) { - System.err.println("Security exception, class " + className + " is not public, caused by " + e1.getCause()); - } catch (NoSuchMethodException e1) { - System.err.println("No such method exception, method: " + methodName + ", caused by " + e1.getCause()); - } catch (ClassNotFoundException e1) { - System.err.println("Error, could not find class name=" + className + ", caused by " + e1.getCause()); - } - // Save the class instance for comparison to other loaded classes later - currentReload = clazz; - // If the method is not static and the instance is null, create an instance of the class to use to call the method - try { - if(instance == null && !Modifier.isStatic(modifiers)) { - @SuppressWarnings("deprecation") - Object obj = clazz.newInstance(); - instance = obj; - } - } catch(Exception e) { - System.err.println("Error creating new instance of class: " + className + ", " + e.getLocalizedMessage() + ", caused by " + e.getCause()); - } - // Call the method - try { - method.invoke(instance, args); - } catch (IllegalAccessException e) { - System.err.println("Illegal Access Exception: cannot invoke \'" + clazz.getSimpleName() + "." + - methodName + "\' method, caused by " + e.getCause()); - return; - } catch (InvocationTargetException e) { - System.err.println("Exception throw by " + className + "." + methodName + - "() while calling it, caused by " + e.getCause()); - } finally { - method = null; - } - return; - } - - - /** Dynamically load and call a specified class' method in a new thread. - * Designed to start or restart a particular dynamic program module that - * is well suited to run in its own thread. - * @param path the folder path or jar file path that the class is located in. - * This path should end with a '/' forward slash if it is a folder, otherwise - * it is assumed to be a jar file. - * @param className the fully qualifying Java class name separated by - * '.' periods - * @param methodName the name of the method to call without parentheses - * or arguments. - * @param instance an optional instance of the class to use when calling the method, - * if the method being called is not static and this instance parameter is null, - * than a new instance of the class is created using {@link Class#newInstance()}. - * @param args the list of parameters to pass to the method call - * @return true if the method was called, false if there was an error - */ - public Thread callClassMethod(String path, String className, String methodName, Object instance, Object... args) { - this.className = className; - this.methodName = methodName; - this.classInstance = instance; - this.arguments = args; - Thread t = new Thread(this, "Run " + className + "." + methodName); - URLClassLoader cl = createClassLoader(path); - - try { - t.setContextClassLoader(cl); - } catch(SecurityException se) { - System.err.println("Error, security error setting new thread class loader while trying to run class: " + className); - } - t.start(); - return t; - } - - - /** The new class file is copied and written over the original class file. Designed to start - * or restart a particular dynamic program module that is well suited to run in its own thread.
- *
- * Unfortunately, the trick to get this to work requires that both class files be located - * in the same named relative class path with unique base paths, for example, to load a - * new version of the class "myProject.Original" the new class must also be contained in - * a path ending with "myProject.Original" but must be located in a folder outside of the - * current application's classpath. The original class might be located in - * "/home/name/project/myProject/Original.class" and the new class might be - * located in "/home/name/projectAlt/myProject/Original.class".
- *
- * @param originalPath the folder path (jar file paths are not yet supported) that the original - * class to be overwritten is located in. - * @param originalClassName the fully qualifying Java name used of the original - * class to overwrite, the path separated by '.' periods. - * @param newPath the folder path (jar file paths are not yet supported) that the new class - * to load and overwrite the original class with is located in. - * @param newClassName the fully qualifying Java name used for the new class to - * overwrite the old class, the path separated by '.' periods. - * @param methodName the name of the method to call - * @param instance an optional instance of the class to use when calling the method, if the - * method being called is not static and this instance parameter is null, than a new instance - * of the class is created using {@link Class#newInstance()}. - * @param args the list of parameters to pass to the method call - * @return true if the method was called, false if there was an error - */ - public boolean overwriteClass(String originalPath, String originalClassName, String newPath, String newClassName, String methodName, Object instance, Object[] args) { - try { - // The sub path of the class file with the class' name - String originalClassNamePath = originalClassName.replace('.', File.separatorChar) + classPostfix; - String newClassNamePath = newClassName.replace('.', File.separatorChar) + classPostfix; - // Create the full original path using the original path and class name path - String fullOriginalPath = originalPath + ((originalPath.endsWith("\\") || originalPath.endsWith("/")) ? originalClassNamePath : File.separatorChar + originalClassNamePath); - // Create the full new path using the new path and class name path - String fullNewPath = newPath + ((newPath.endsWith("\\") || newPath.endsWith("/")) ? newClassNamePath : File.separatorChar + newClassNamePath); - // Overwrite the original file with the new file - overwriteFile(fullNewPath, fullOriginalPath); - } catch(IOException ioe) { - System.err.println("Error, could not overwrite the old file, caused by " + ioe.getCause()); - return false; - } - return true; - } - - - /** Create a class loader using the specified file path - * @param path the file path to set as the classloader's path - * @return the classloader with the specified classpath - */ - private static URLClassLoader createClassLoader(String path) { - URL url = null; - try { - url = toURL(path); - } catch (IOException e) { - System.err.println("Error creating class loader URL"); - e.printStackTrace(); - } - return new URLClassLoader(new URL[] {url}, Thread.currentThread().getContextClassLoader()); - } - - - /** Convert a local file path to a {@link URL} - * @param path the local file path to parse into a URL - * @return the URL corresponding to the specified file/folder path - * @throws IOException if there is an error creating the URL - */ - private static URL toURL(String path) throws IOException { - URL url = null; - // Convert the path to a URL - try { - url = new URL(path); - } catch(Exception e) { - // If the path is not a valid URL convert it to a file then to a URL - File file = new File(path).getCanonicalFile(); - url = file.toURI().toURL(); - } - return url; - } - - - /** Overwrite the destination file with the source file - * @param newFilePath the source file to use - * @param oldFilePath the destination file to overwrite with the contents of the source file - * @throws IOException if there is an error opening either of the files or copying the source file's - * contents into the destination file - */ - private static void overwriteFile(String newFilePath, String oldFilePath) throws IOException { - FileChannel src = null; - FileChannel dst = null; - try { - File oldFile = new File(oldFilePath).getCanonicalFile(); - File newFile = new File(newFilePath).getCanonicalFile(); - System.out.println("Overwriting: " + oldFile.getAbsolutePath() + ", with: " + newFile.getAbsolutePath()); - if(!oldFile.isFile() || !newFile.isFile()) { - throw new IOException("Error, one of these paths is not a valid file (" + oldFilePath + ", " + newFilePath + ")"); - } - - @SuppressWarnings("resource") - FileInputStream srcStream = new FileInputStream(newFile); - src = srcStream.getChannel(); - - @SuppressWarnings("resource") - FileOutputStream dstStream = new FileOutputStream(oldFile); - dst = dstStream.getChannel(); - - long transferCount = 0; - long size = src.size(); - do { - transferCount += dst.transferFrom(src, transferCount, size-transferCount); - } while(transferCount < size); - } catch (IOException e) { - throw e; - } - finally { - try { - if(src != null) { - src.close(); - } - if(dst != null) { - dst.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - - public static URL getApplicationPathURL() { - if(appPath == null) { - appPath = RuntimeReloadMain.class.getProtectionDomain().getCodeSource().getLocation(); - // more sure way - /* - java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() { - public URL run() { - return (appPath = RuntimeReloadMain.class.getProtectionDomain().getCodeSource().getLocation()); - } - }); - */ - } - return appPath; - } - + public static ThreadMethodResultFuture loadRun(String customClassPath, String className, String methodName, Object[] args) { + String applicationPath = ClassLoaders.getApplicationPathString(); + String path = new File(applicationPath).getParent() + File.separatorChar + customClassPath; - public static String getApplicationPathString() { - if(appPathStr == null) { - appPathStr = getApplicationPathURL().getPath(); - } - return appPathStr; + return ClassLoaders.callClassMethod(path, className, methodName, null, args); } @@ -382,10 +107,10 @@ public static void main(String[] args) throws IOException { // How to properly retrieve the based folder in which the current class is running // This folder is the base folder, for example: /home/me/project/code/MyClass where // MyClass' package declaration is "packet project.code;" would return a domain of "/home/me" - System.out.println("java.class.path" + ": " + System.getProperty("java.class.path")); - System.out.println("Domain: " + getApplicationPathURL()); + System.out.println("java.class.path: " + System.getProperty("java.class.path")); + System.out.println("Domain: " + ClassLoaders.getApplicationPathURL()); RuntimeReloadMain load = new RuntimeReloadMain(); - load.loadLoopUserInput(defaultMainClassPath, classPath2, args); + load.loadLoopUserInput("res/destination", "res/second_runtime", args); } } diff --git a/src/twg2/jbcm/main/UsageCliMain.java b/src/twg2/jbcm/main/UsageCliMain.java index d8c5f80..e44c24e 100644 --- a/src/twg2/jbcm/main/UsageCliMain.java +++ b/src/twg2/jbcm/main/UsageCliMain.java @@ -2,9 +2,12 @@ import java.io.BufferedInputStream; import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.PrintStream; import java.net.MalformedURLException; import java.nio.file.FileSystem; @@ -17,20 +20,23 @@ import java.util.Arrays; import java.util.List; import java.util.Scanner; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; import twg2.jbcm.classFormat.ClassFile; +import twg2.jbcm.classFormat.CpIndex; +import twg2.jbcm.classFormat.Settings; import twg2.jbcm.classFormat.constantPool.CONSTANT_CP_Info; import twg2.jbcm.classFormat.constantPool.CONSTANT_Class; +import twg2.jbcm.classFormat.constantPool.CONSTANT_Utf8; import twg2.jbcm.dynamicModification.SimpleInterface; -import twg2.jbcm.runtimeLoading.CompileSource; +import twg2.jbcm.modify.FindCpIndexUsage; +import twg2.jbcm.runtime.ClassLoaders; +import twg2.jbcm.runtime.CompileSource; import twg2.jbcm.toSource.ClassFileToSource; import twg2.jbcm.toSource.SourceWriter; - public class UsageCliMain { - static final String a = "twg2/jbcm/main/test/UnitTest"; - static final String b = "UnitTest-Other"; - /** Print the class file format data about the specified class * @param file the class file to print the internal data of @@ -61,34 +67,35 @@ public static void testPerformance(SimpleInterface test, SimpleInterface base) { int innerLoops = 100; long timeTest = 0; long timeBase = 0; - long temp = 0; + long start = 0; for(int i = 0; i < loops; i++) { - temp = System.nanoTime(); + start = System.nanoTime(); for(int a = 0; a < innerLoops; a++) { base.callTest(); } - timeBase += (System.nanoTime() - temp); + timeBase += (System.nanoTime() - start); - temp = System.nanoTime(); + start = System.nanoTime(); for(int a = 0; a < innerLoops; a++) { test.callTest(); } - timeTest += (System.nanoTime() - temp); + timeTest += (System.nanoTime() - start); } System.out.println("Time base: " + timeBase + ", base=" + base.getCount()); System.out.println("Time test: " + timeTest + ", test=" + test.getCount()); } - public static void interactiveClassLoad() { - Scanner in = new Scanner(System.in); + public static void interactiveClassLoad(String... args) { + var nextLineGetter = createLineGetter(args, System.in); List classFiles = new ArrayList<>(); int errorCount = 0; int errorMax = 10; String str = null; + System.out.println("Class file manipulator:"); do { try { - displayMenuGetUserInput(in, classFiles); + displayMenuGetUserInput(nextLineGetter, classFiles); } catch (IOException e) { errorCount++; if(errorCount > errorMax) { break; } @@ -98,29 +105,36 @@ public static void interactiveClassLoad() { } - private static void displayMenuGetUserInput(Scanner in, List classFiles) throws IOException { + private static void displayMenuGetUserInput(Supplier userInputNextLine, List classFiles) throws IOException { + var nextLine = userInputNextLine; FileSystem fs = FileSystems.getDefault(); + String appPath = ClassLoaders.getApplicationPathString(); + String path = new File(appPath).getParent() + "/res/destination"; String classpath = System.getProperty("user.dir"); if(!classpath.endsWith("\\") && !classpath.endsWith("/")) { classpath += "/"; } - System.out.print("Class file manipulator " + (classFiles.size() > 0 ? "(" + classFiles.size() + " loaded)" : "") + - ", options ('classpath', 'printInfo', 'printClass', 'decompile', 'dependencies', 'load', 'modify', 'clear'): "); - String input = in.nextLine(); + System.out.print((classFiles.size() > 0 ? "(" + classFiles.size() + " loaded), " : "") + + "options ('classpath', 'printInfo', 'printClass', 'decompile', 'dependencies', 'load', 'modify', 'run', 'clear', 'save'): "); + String input = nextLine.get(); ClassFile cls = null; SourceWriter writer = null; + Object[] args = new String[0]; switch(input) { + // classpath case "classpath": System.out.print("enter classpath to use for 'load' commands: "); - input = in.nextLine(); + input = nextLine.get(); classpath = input; + break; + // decompile case "decompile": String methodFilter = null; if(classFiles.size() < 1) { System.out.print("enter file name (relative to '" + classpath + "' or absolute) to print source: "); - input = in.nextLine(); + input = nextLine.get(); // allow file names like "\bin\twg2\jbcm\modify\TypeUtility.class isPrimitive() if(input.endsWith("()")) { int spaceIdx = input.lastIndexOf(' '); @@ -142,10 +156,11 @@ private static void displayMenuGetUserInput(Scanner in, List classFil } System.out.println(writer.toString()); break; + // printClass case "printClass": if(classFiles.size() < 1) { System.out.print("enter file name (relative to '" + classpath + "' or absolute) to print class: "); - input = in.nextLine(); + input = nextLine.get(); File file = getClassPath(fs, classpath, input).toFile(); cls = ClassFile.load(file); } @@ -156,10 +171,11 @@ private static void displayMenuGetUserInput(Scanner in, List classFil ClassFileToSource.toSource(cls, writer, false); System.out.println(writer.toString()); break; + // printInfo case "printInfo": if(classFiles.size() < 1) { System.out.print("enter file name (relative to '" + classpath + "' or absolute) to print: "); - input = in.nextLine(); + input = nextLine.get(); File file = getClassPath(fs, classpath, input).toFile(); cls = ClassFile.load(file); } @@ -168,9 +184,10 @@ private static void displayMenuGetUserInput(Scanner in, List classFil } cls.print(System.out); break; + // load case "load": System.out.print("enter file/path name (relative to '" + classpath + "' or absolute) to load: "); - input = in.nextLine(); + input = nextLine.get(); File file = getClassPath(fs, classpath, input).toFile(); List files; if(file.isDirectory()) { @@ -180,23 +197,78 @@ private static void displayMenuGetUserInput(Scanner in, List classFil files = Arrays.asList(file); } for(int i = 0, sz = files.size(); i < sz; i++) { - classFiles.add(ClassFile.load(files.get(i))); + cls = ClassFile.load(files.get(i)); + classFiles.add(cls); } System.out.println(files.size() + " class files loaded"); break; + // dependencies case "dependencies": System.out.print("enter dependency name to search for (optional) or nothing to print all dependencies: "); - input = in.nextLine(); + input = nextLine.get(); for(int i = 0, sz = classFiles.size(); i < sz; i++) { printDeps(classFiles.get(i), input, System.out); } break; + // modify case "modify": - System.out.print("enter modification (currently not implemented): "); - input = in.nextLine(); - // TODO modify(classFiles.get(0), input); - System.out.println("ERROR: 'modify' is not yet implemented"); + System.out.println("Modification Options: "); + System.out.println("1. 'removeUnusedCPs' - remove constant pool entries"); + System.out.println("2. 'replaceCP [# | \"string\"] \"replacement\"' - replace constant pool string"); + System.out.print("Choice: "); + input = nextLine.get(); + cls = classFiles.size() > 0 ? classFiles.get(0) : null; + if(input.equals("removeUnusedCPs")) { + var unusedIndexes = FindCpIndexUsage.findUnusedIndexes(cls); + System.out.println("unused indexes: " + unusedIndexes); + //var removedIndexes = cls.removeUnusedCpIndexes(); + //System.out.println("Removed unused constant pool entries: " + removedIndexes.toString()); + } + else if(input.startsWith("replaceCP")) { + var strs = input.split(" \""); + CpIndex strCp; + if(strs.length == 3) { + strCp = cls.findConstantPoolString(strs[1]); + } + else { + int idx = Integer.parseInt(strs[0].split(" ")[1]); + strCp = cls.getCheckCpIndex(idx, CONSTANT_Utf8.class); + } + if(strCp != null) { + var utfStr = new CONSTANT_Utf8(cls); + utfStr.setString(strs[1].endsWith("\"") ? strs[1].substring(0, strs[1].length() - 1) : strs[1]); + strCp.setCpObject(utfStr); + cls.setConstantPool(strCp.getIndex(), strCp.getCpObject()); + } + else { + System.err.println("Could not find constant pool string \"" + strs[1] + "\""); + } + } + else { + System.err.println("ERROR: unknown modification option '" + input + "'"); + } + break; + // run + case "run": + System.out.print("Load a class, example 'classLoading.base.Test.main()' or 'classLoading.Reload.main()': "); + input = nextLine.get(); + String[] classAndMethod = splitClassAndMethod(input); + System.out.println("running '" + classAndMethod[0] + "." + classAndMethod[1] + "()..."); + var t = ClassLoaders.callClassMethod(path, classAndMethod[0], classAndMethod[1], null, (Object)args); + try { + t.thread.join(); + } catch (InterruptedException e) { + System.err.println("Error waiting for thread: " + e.getLocalizedMessage()); + } + break; + // save + case "save": + cls = classFiles.get(0); + DataOutputStream out = new DataOutputStream(new FileOutputStream(cls.getSource().replace(".class", "-modified.class"))); + cls.writeData(out); + out.close(); break; + // clear case "clear": classFiles.clear(); break; @@ -206,6 +278,18 @@ private static void displayMenuGetUserInput(Scanner in, List classFil } + private static Supplier createLineGetter(String[] lines, InputStream in) { + if(lines != null && lines.length > 0) { + var idx = new AtomicInteger(0); + return () -> lines.length > idx.get() ? lines[idx.getAndIncrement()] : null; + } + else { + var inScanner = new Scanner(in); + return () -> inScanner.nextLine(); + } + } + + private static Path getClassPath(FileSystem fs, String dir, String file) { String fileNorm = file.endsWith(".class") ? file : file.replace('.', '/') + ".class"; Path tmp = null; @@ -243,17 +327,30 @@ private static void printDeps(ClassFile classFile, String dependency, PrintStrea } - private static byte[] compileSourceToBytecode(String javaSrc) throws MalformedURLException, ClassNotFoundException { + /** Splits a string in the format 'class.path.and.Name.methodName()' into + * two strings, the full class name and the method name, + * like ['class.path.and.Name', 'methodName'] + */ + private static String[] splitClassAndMethod(String input) { + int lastDot = input.lastIndexOf('.'); + String method = input.substring(lastDot + 1, input.length() - 2); + String fullClass = input.substring(0, lastDot); + return new String[] { fullClass, method }; + } + + + private static ClassFile compileAndLoad(String javaSrc) throws MalformedURLException, ClassNotFoundException { try { File tmpFile = new File("res/tmp/src/CompilerTemp.java"); Files.write(tmpFile.toPath(), javaSrc.getBytes("UTF-8"), StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE); - File sourceFilesPath = new File("res/tmp/src"); - String classPath = new File("res/tmp/src").getAbsolutePath(); - File destinationClassPath = new File("res/tmp/bin"); + File sourceDir = new File("res/tmp/src"); + String classPath = sourceDir.getAbsolutePath(); + File destinationDir = new File("res/tmp/bin"); - CompileSource.compile(true, tmpFile, sourceFilesPath, classPath, destinationClassPath); + //CompileSource.compile(CompileSource.JAVA_1_8_COMPILE, tmpFile, sourceDir, classPath, destinationDir); + CompileSource.compileUsingEclipseEcj(tmpFile, sourceDir, classPath, destinationDir); - var bytecode = Files.readAllBytes(new File("res/tmp/bin/CompilerTemp.class").toPath()); + var bytecode = ClassFile.load(new File("res/tmp/bin/CompilerTemp.class")); tmpFile.delete(); @@ -264,31 +361,12 @@ private static byte[] compileSourceToBytecode(String javaSrc) throws MalformedUR } - private static void compileSourceFileToClass(File srcJavaFile, File dstClassFile) throws ClassNotFoundException, IOException { - File entryFile = new File("res/tmp/src/twg2/compileTest/Hello.java"); - File sourceFilesPath = new File("res/tmp/src"); - String classPath = new File("res/tmp/src/twg2/compileTest").getAbsolutePath(); - File destinationClassPath = new File("res/tmp/bin"); - - CompileSource.compile(true, entryFile, sourceFilesPath, classPath, destinationClassPath); - - RuntimeReloadMain reload = new RuntimeReloadMain(); - reload.loadRun("res/tmp/bin", "twg2.compileTest.Hello", "run", (String[])null); - - //Runnable thing = (Runnable)classes[0].newInstance(); - //thing.run(); - } - - public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { - var codes = new int[] { 0, 1, 5, 122, Integer.MAX_VALUE - 1, Integer.MAX_VALUE }; - for(var code : codes) { - System.out.println(code + " (" + (~code) + ") = " + ~(~code)); - } + Settings.debug = true; - interactiveClassLoad(); + interactiveClassLoad(new String[] { "decompile", "res/destination/classLoading/RunnableThing.class" }); - // compileSourceToClass(); + // compileAndLoad(); //File file = new File("bin/twg2.jbcm.classFormat/test/UnitTest.class"); //File file = new File("C:/Users/TeamworkGuy2/Documents/Java/Projects/ClassLoading/bin/twg2.jbcm.classFormat/Field_Info.class"); diff --git a/src/twg2/jbcm/modify/ChangeCpIndex.java b/src/twg2/jbcm/modify/ChangeCpIndex.java deleted file mode 100644 index ae7d478..0000000 --- a/src/twg2/jbcm/modify/ChangeCpIndex.java +++ /dev/null @@ -1,90 +0,0 @@ -package twg2.jbcm.modify; - -import twg2.jbcm.CodeUtility; -import twg2.jbcm.IoUtility; - -/** A default implementation of {@link CpIndexChanger}. - * The {@link #shiftIndex(byte[], int, int)} method calls {@code IoUtility.shiftOffset(...)} - * using the parameters from this object's constructor and the {@code #changeCpIndexIf(byte[], int, int, int)} method calls - * {@code IoUtility.read*()} and then conditionally calls {@code IoUtility.write*()} if the index matches the current target index. - * @author TeamworkGuy2 - * @since 2014-4-20 - */ -public class ChangeCpIndex implements CpIndexChanger, CodeOffsetGetter, CodeOffsetChanger { - private final int offsetOffset; - private final int offsetLen; - - - public ChangeCpIndex(int offsetOffset, int offsetLen) { - if(offsetLen != 1 && offsetLen != 2 && offsetLen != 4) { - throw new IllegalArgumentException("cannot shift offsets values that are not 1, 2, or 4 bytes long: " + offsetLen); - } - this.offsetOffset = offsetOffset; - this.offsetLen = offsetLen; - } - - - @Override - public int getOffset(byte[] code, int location) { - location += offsetOffset; - if(offsetLen == 2) { - short offset = IoUtility.readShort(code, location); - return offset; - } - else if(offsetLen == 4) { - int offset = IoUtility.readInt(code, location); - return offset; - } - else if(offsetLen == 1) { - byte offset = code[location]; - return offset; - } - else { - throw new IllegalStateException("offset length must be 1, 2, or 4"); - } - } - - - @Override - public void shiftIndex(byte[] code, int location, int offset) { - if(offsetLen == 2) { - CodeUtility.shift2Offset(offset, offsetOffset, code, location); - } - else if(offsetLen == 4) { - CodeUtility.shift4Offset(offset, offsetOffset, code, location); - } - else if(offsetLen == 1) { - CodeUtility.shift1Offset(offset, offsetOffset, code, location); - } - else { - throw new IllegalStateException("offset length must be 1, 2, or 4"); - } - } - - - @Override - public void changeCpIndexIf(byte[] code, int location, int currentIndex, int newIndex) { - location += offsetOffset; - if(offsetLen == 2) { - short index = IoUtility.readShort(code, location); - if(index == currentIndex) { - IoUtility.writeShort((short)newIndex, code, location); - } - } - else if(offsetLen == 4) { - int index = IoUtility.readInt(code, location); - if(index == currentIndex) { - IoUtility.writeInt(newIndex, code, location); - } - } - else if(offsetLen == 1) { - byte index = code[location]; - if(index == currentIndex) { - code[location] = (byte)newIndex; - } - } - else { - throw new IllegalStateException("offset length must be 1, 2, or 4"); - } - } -} \ No newline at end of file diff --git a/src/twg2/jbcm/modify/ChangeIndex.java b/src/twg2/jbcm/modify/ChangeIndex.java new file mode 100644 index 0000000..86f1b11 --- /dev/null +++ b/src/twg2/jbcm/modify/ChangeIndex.java @@ -0,0 +1,93 @@ +package twg2.jbcm.modify; + +import twg2.jbcm.CodeUtility; +import twg2.jbcm.IoUtility; + +/** Implementation of {@link CodeCpIndexChanger} and {@link CodeOffsetChanger}.
+ * {@link #shiftIndex(byte[], int, int)} method calls {@code IoUtility.shiftOffset(...)} + * using the parameters from this object's constructor.
+ * {@link #changeCpIndexIf(byte[], int, int, int)} method calls {@code IoUtility.read*()} and then conditionally + * calls {@code IoUtility.write*()} if the index matches the current target index. + * @author TeamworkGuy2 + * @since 2014-4-20 + */ +public class ChangeIndex implements CodeCpIndexChanger, CodeOffsetGetter, CodeOffsetChanger { + /** The offset at which the offset is stored relative to the instructions (this is always 1 for all Java opcodes as of Java 16) */ + final int offsetFromInstruction; + /** The offset value storage size in bytes, must be 1, 2, or 4. Could represent a constant pool index or a code[] offset. */ + final int offsetStorageSize; + + + public ChangeIndex(int offsetFromInstruction, int storageSize) { + if(storageSize != 1 && storageSize != 2 && storageSize != 4) { + throw new IllegalArgumentException("cannot shift offsets values that are not 1, 2, or 4 bytes long: " + storageSize); + } + this.offsetFromInstruction = offsetFromInstruction; + this.offsetStorageSize = storageSize; + } + + + @Override + public int getOffset(byte[] code, int location) { + location += offsetFromInstruction; + if(offsetStorageSize == 2) { + short offset = IoUtility.readShort(code, location); + return offset; + } + else if(offsetStorageSize == 4) { + int offset = IoUtility.readInt(code, location); + return offset; + } + else if(offsetStorageSize == 1) { + byte offset = code[location]; + return offset; + } + else { + throw new IllegalStateException("offset length must be 1, 2, or 4"); + } + } + + + @Override + public void shiftIndex(byte[] code, int location, int offset) { + if(offsetStorageSize == 2) { + CodeUtility.shift2Offset(offset, offsetFromInstruction, code, location); + } + else if(offsetStorageSize == 4) { + CodeUtility.shift4Offset(offset, offsetFromInstruction, code, location); + } + else if(offsetStorageSize == 1) { + CodeUtility.shift1Offset(offset, offsetFromInstruction, code, location); + } + else { + throw new IllegalStateException("offset length must be 1, 2, or 4"); + } + } + + + @Override + public void changeCpIndexIf(byte[] code, int location, int currentIndex, int newIndex) { + location += offsetFromInstruction; + if(offsetStorageSize == 2) { + short index = IoUtility.readShort(code, location); + if(index == currentIndex) { + IoUtility.writeShort((short)newIndex, code, location); + } + } + else if(offsetStorageSize == 4) { + int index = IoUtility.readInt(code, location); + if(index == currentIndex) { + IoUtility.writeInt(newIndex, code, location); + } + } + else if(offsetStorageSize == 1) { + byte index = code[location]; + if(index == currentIndex) { + code[location] = (byte)newIndex; + } + } + else { + throw new IllegalStateException("offset length must be 1, 2, or 4"); + } + } +} \ No newline at end of file diff --git a/src/twg2/jbcm/modify/CodeCpIndexChanger.java b/src/twg2/jbcm/modify/CodeCpIndexChanger.java new file mode 100644 index 0000000..77a2111 --- /dev/null +++ b/src/twg2/jbcm/modify/CodeCpIndexChanger.java @@ -0,0 +1,24 @@ +package twg2.jbcm.modify; + +/** An operation that accepts a code block, location, and index offset as input. + * @author TeamworkGuy2 + * @since 2014-4-20 + */ +public interface CodeCpIndexChanger { + + public static final CodeCpIndexChanger NO_OP = new CodeCpIndexChanger() { + @Override public void changeCpIndexIf(byte[] code, int location, int currentIndex, int newIndex) { + } + }; + + + /** Change a constant_pool index if it matches the current target index of the instruction at {@code location}. + * If the constant_pool index equals {@code currentIndex}, then set it to {@code newIndex}. + * @param code the bytecode array + * @param location the location in the array at which the current instruction is located + * @param currentIndex the index to compare the current constant_pool index to + * @param newIndex if the current constant_pool index matches the {@code currentIndex}, set it to {@code newIndex}. + */ + void changeCpIndexIf(byte[] code, int location, int currentIndex, int newIndex); + +} diff --git a/src/twg2/jbcm/modify/CpIndexChangeable.java b/src/twg2/jbcm/modify/CpIndexChangeable.java new file mode 100644 index 0000000..377e8b5 --- /dev/null +++ b/src/twg2/jbcm/modify/CpIndexChangeable.java @@ -0,0 +1,11 @@ +package twg2.jbcm.modify; + +/** Represents an object that contains constant pool indexes that can be changed. + * @author TeamworkGuy2 + * @since 2014-4-20 + */ +public interface CpIndexChangeable { + + public void changeCpIndex(CpIndexChanger indexChanger); + +} diff --git a/src/twg2/jbcm/modify/CpIndexChanger.java b/src/twg2/jbcm/modify/CpIndexChanger.java index f575949..cc20452 100644 --- a/src/twg2/jbcm/modify/CpIndexChanger.java +++ b/src/twg2/jbcm/modify/CpIndexChanger.java @@ -1,24 +1,49 @@ package twg2.jbcm.modify; -/** An operation that accepts a code block, location, and index offset as input. +/** Default parameter implementation for {@link CpIndexChangeable} * @author TeamworkGuy2 - * @since 2014-4-20 + * @since 2014-4-21 */ -public interface CpIndexChanger { +public class CpIndexChanger { + /** the old index to replace when found*/ + protected short oldIndex; + /** the new index to replace matching old indices with */ + protected short newIndex; - public static final CpIndexChanger NO_OP = new CpIndexChanger() { - @Override public void changeCpIndexIf(byte[] code, int location, int currentIndex, int newIndex) { + + public CpIndexChanger(short oldIndex, short newIndex) { + this.oldIndex = oldIndex; + this.newIndex = newIndex; + } + + + /** Call {@link CpIndexChangeable#changeCpIndex(short, short)} on each object in the specified array + * @param objs the array of objects to call {@link CpIndexChangeable#changeCpIndex(short, short)} on + */ + public void indexChange(CpIndexChangeable[] objs) { + for(CpIndexChangeable obj : objs) { + obj.changeCpIndex(this); + } + } + + + /** Call {@link CpIndexChangeable#changeCpIndex(short, short)} on the specified object + * @param obj the object to call {@link CpIndexChangeable#changeCpIndex(short, short)} on + */ + public void indexChange(CpIndexChangeable obj) { + if(obj != null) { + obj.changeCpIndex(this); } - }; + } - /** Change a constant_pool index if it matches the current target index of the {@code location} instruction. - * If the constant_pool index equals {@code currentIndex}, then set it to {@code newIndex}. - * @param code the bytecode array - * @param location the location in the array at which the current instruction is located - * @param currentIndex the index to compare the current constant_pool index to - * @param newIndex if the current constant_pool index matches the {@code currentIndex}, set it to {@code newIndex}. + /** Check if the specified index matches the old index and if so, return the new index, else return the old index. + * An example of this might be: {@code myIndex = indexChange(myIndex, 30, 35)}
+ * If {@code (myIndex == 30)}, then {@code 35} would be returned, else {@code myIndex} would be returned. + * @param currentIndex the current index to compare and replace if necessary */ - void changeCpIndexIf(byte[] code, int location, int currentIndex, int newIndex); + public short indexChange(short currentIndex) { + return (currentIndex == oldIndex) ? newIndex : currentIndex; + } } diff --git a/src/twg2/jbcm/modify/FindCpIndexUsage.java b/src/twg2/jbcm/modify/FindCpIndexUsage.java new file mode 100644 index 0000000..dbacbea --- /dev/null +++ b/src/twg2/jbcm/modify/FindCpIndexUsage.java @@ -0,0 +1,52 @@ +package twg2.jbcm.modify; + +import twg2.collections.primitiveCollections.IntArrayList; +import twg2.collections.primitiveCollections.IntList; +import twg2.jbcm.classFormat.ClassFile; + +/** + * @author TeamworkGuy2 + * @since 2021-08-04 + */ +public class FindCpIndexUsage { + + public static IntList findUnusedIndexes(ClassFile classFile) { + int constantPoolSize = classFile.getConstantPoolCount(); + + CpIndexVisitor visitor = new CpIndexVisitor(constantPoolSize); + classFile.changeCpIndex(visitor); + + IntArrayList unusedIndexes = new IntArrayList(); + for(int i = 0; i < constantPoolSize; i++) { + if(visitor.indexVisitCounts[i] == 0) { + unusedIndexes.add(i); + } + } + + return unusedIndexes; + } + + + + /** Track all the constant pool indexes visited, without modifying them + * @author TeamworkGuy2 + * @since 2021-08-05 + */ + public static class CpIndexVisitor extends CpIndexChanger { + protected int[] indexVisitCounts; + + public CpIndexVisitor(int constantPoolSize) { + super((short)0, (short)0); + this.indexVisitCounts = new int[constantPoolSize]; + } + + + @Override + public short indexChange(short currentIndex) { + indexVisitCounts[currentIndex]++; + return currentIndex; + } + + } + +} diff --git a/src/twg2/jbcm/modify/IndexChanger.java b/src/twg2/jbcm/modify/IndexChanger.java deleted file mode 100644 index f9a1dde..0000000 --- a/src/twg2/jbcm/modify/IndexChanger.java +++ /dev/null @@ -1,11 +0,0 @@ -package twg2.jbcm.modify; - -/** - * @author TeamworkGuy2 - * @since 2014-4-20 - */ -public interface IndexChanger { - - public void changeCpIndex(short oldIndex, short newIndex); - -} diff --git a/src/twg2/jbcm/modify/IndexUtility.java b/src/twg2/jbcm/modify/IndexUtility.java deleted file mode 100644 index 997c3a0..0000000 --- a/src/twg2/jbcm/modify/IndexUtility.java +++ /dev/null @@ -1,58 +0,0 @@ -package twg2.jbcm.modify; - -/** Helper methods for {@link IndexChanger} - * @author TeamworkGuy2 - * @since 2014-4-21 - */ -public class IndexUtility { - - /** Call {@link IndexChanger#changeCpIndex(short, short)} on each object in the specified array - * @param objs the array of objects to call {@link IndexChanger#changeCpIndex(short, short)} on - * @param oldIndex the old index to look for - * @param newIndex the new index to replace matching old indices with - */ - public static final void indexChange(IndexChanger[] objs, short oldIndex, short newIndex) { - for(IndexChanger obj : objs) { - obj.changeCpIndex(oldIndex, newIndex); - } - } - - - /** Check if each index in the specified array matches the old index and if so, replace it with the new index - * @param indices an array of short indices to check - * @param oldIndex the old index to look for - * @param newIndex the new index to replace matching old indices with - */ - public static final void indexChange(short[] indices, short oldIndex, short newIndex) { - for(int i = indices.length-1; i > -1; i--) { - if(indices[i] == oldIndex) { - indices[i] = newIndex; - } - } - } - - - /** Call {@link IndexChanger#changeCpIndex(short, short)} on the specified object - * @param obj the object to call {@link IndexChanger#changeCpIndex(short, short)} on - * @param oldIndex the old index to look for - * @param newIndex the new index to replace matching old indices with - */ - public static final void indexChange(IndexChanger obj, short oldIndex, short newIndex) { - if(obj != null) { - obj.changeCpIndex(oldIndex, newIndex); - } - } - - - /** Check if the specified index matches the old index and if so, return the new index, else return the old index. - * An example of this might be: {@code myIndex = indexChange(myIndex, 30, 35)}
- * If {@code (myIndex == 30)}, then {@code 35} would be returned, else {@code myIndex} would be returned. - * @param index the index to compare to the old index - * @param oldIndex the old index to compare to - * @param newIndex the new index to return if the specified index matches the old index - */ - public static final short indexChange(short index, short oldIndex, short newIndex) { - return (index == oldIndex) ? newIndex : index; - } - -} diff --git a/src/twg2/jbcm/modify/TypeUtility.java b/src/twg2/jbcm/modify/TypeUtility.java index e1850c0..b32b767 100644 --- a/src/twg2/jbcm/modify/TypeUtility.java +++ b/src/twg2/jbcm/modify/TypeUtility.java @@ -137,20 +137,6 @@ public static String methodDescriptor(Method method) { } - /** Return the internal binary class name of the specified class. - * For example, the normal binary name of class Thread is {@code java.lang.Thread}. - * In the internal form used in descriptors in the class file format, a - * reference to the name of class Thread is implemented using a CONSTANT_Utf8_info - * structure representing the string {@code java/lang/Thread} (§4.2.1). - * @param clas the class to get the internal formatted name of - * @return the internal binary name of the specified class - * @see #classToFieldDescriptor(Class) - */ - public static String classNameInternal(Class clas) { - return classNameFieldDescriptor(clas.getName()); - } - - public static String methodDescriptor(CONSTANT_NameAndType method) { StringBuilder dst = new StringBuilder(); methodDescriptor(method, dst); @@ -198,6 +184,52 @@ public static String getArrayType(int atype) { } + /** Converts a class name separated by periods (i.e. {@code java.lang.String}) + * to an internal binary class name (i.e. {@code java/lang/String}). + * @param className the standard class name to convert + * @return the internal binary class name of the specified class name + */ + private static String toBinaryClassName(String className) { + return className.replace('.', '/'); + } + + + /** Exactly the same as {@link #toBinaryClassName(String)} + * except that the resulting string is appended to the specified string builder + * @param className the standard class name to convert + * @param dst the string builder to append the resulting internal binary class name to + * @see #toBinaryClassName(String) + */ + private static void toBinaryClassName(String className, StringBuilder dst) { + int pos = dst.length(); + dst.append(className); + int index = dst.indexOf(".", pos); + while(index > -1) { + dst.setCharAt(index, '/'); + index = dst.indexOf(".", index + 1); + } + } + + + /** Return the internal binary class name of the specified class. + * For example, the normal binary name of class Thread is {@code java.lang.Thread}. + * In the internal form used in descriptors in the class file format, a + * reference to the name of class Thread is implemented using a CONSTANT_Utf8_info + * structure representing the string {@code java/lang/Thread} (§4.2.1). + * @param clas the class to get the internal formatted name of + * @return the internal binary name of the specified class + * @see #classToFieldDescriptor(Class) + */ + public static String classNameInternal(Class clas) { + return toBinaryClassName(clas.getName()); + } + + + public static String decodeBinaryClassName(CONSTANT_Class classRef) { + return classRef.getName().getString().replace('/', '.'); + } + + /** Convert a class to a field descriptor. For example a byte is 'B', * an int is 'I', a String is 'Ljava/lang/String;' (§4.3). * @param clas the class name to convert to a field descriptor @@ -216,22 +248,11 @@ public static String classToFieldDescriptor(Class clas) { else if(clas == Void.TYPE) { return "V"; } else if(clas.isArray()) { return '[' + classToFieldDescriptor(clas.getComponentType()); } else { - return 'L' + classNameFieldDescriptor(clas.getName()) + ';'; + return 'L' + toBinaryClassName(clas.getName()) + ';'; } } - /** Converts a class name retrieved by calling {@code class.getName()} - * to an internal binary class name, for example the internal binary name - * of {@code java.lang.String} is {@code java/lang/String}. - * @param className the standard class name to convert - * @return the internal binary class name of the specified class name - */ - private static String classNameFieldDescriptor(String className) { - return className.replace('.', '/'); - } - - /** Exactly the same as {@link #classToFieldDescriptor(Class)} * except that the resulting string is appended to the specified string builder * @param clas the class to convert to a field descriptor @@ -254,30 +275,13 @@ else if(clas.isArray()) { } else { dst.append('L'); - classNameFieldDescriptor(clas.getName(), dst); + toBinaryClassName(clas.getName(), dst); dst.append(';'); } return dst; } - /** Exactly the same as {@link #classNameToFieldDescriptor(String)} - * except that the resulting string is appended to the specified string builder - * @param className the standard class name to convert - * @param dst the string builder to append the resulting internal binary class name to - * @see #classNameToFieldDescriptor(String) - */ - private static void classNameFieldDescriptor(String className, StringBuilder dst) { - int pos = dst.length(); - dst.append(className); - int index = dst.indexOf(".", pos); - while(index > -1) { - dst.setCharAt(index, '/'); - index = dst.indexOf(".", index + 1); - } - } - - /** Convert a field descriptor string to source * same as {@link #fieldDescriptorToSource(String, StringBuilder) * @param fd the field descriptor diff --git a/src/twg2/jbcm/runtime/ClassLoaders.java b/src/twg2/jbcm/runtime/ClassLoaders.java new file mode 100644 index 0000000..1706c47 --- /dev/null +++ b/src/twg2/jbcm/runtime/ClassLoaders.java @@ -0,0 +1,262 @@ +package twg2.jbcm.runtime; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.AbstractMap; +import java.util.Map.Entry; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; + +/** Dynamically reloading a class a runtime has proven tricky. + * This class tries to provide patterns to work around that. + * If a class has already been loaded then it CANNOT be reloaded without + * some form of class loading trickery that I have not yet discovered. + * Instead, spin up a new thread with a new class loader that can reload the + * class. + *
+ * I've also been unable to load a class from byte-code in-memory + * so we have to write the file to disk before reloading it. + *
+ * See {@link MemoryClassLoader} for my in-memory class loading attempt. + * @author TeamworkGuy2 + * @since 2022-09-05 + */ +public class ClassLoaders { + private static URL appPath; + private static String appPathStr; + + + public static class ThreadMethodResultFuture { + public final Thread thread; + public final Future method; + public final Future result; + + public ThreadMethodResultFuture(Thread thread, Future method, Future result) { + this.thread = thread; + this.method = method; + this.result = result; + } + } + + + public static class ThreadMethodResult { + public final Thread thread; + public final Method method; + public final T result; + + public ThreadMethodResult(Thread thread, Method method, T result) { + this.thread = thread; + this.method = method; + this.result = result; + } + } + + + /** Dynamically load and call a specified class' method in a new thread. + * Designed to start or restart a particular dynamic program module that + * is well suited to run in its own thread. + * @param path the folder path or jar file path that the class is located in. + * This path should end with a '/' forward slash if it is a folder, otherwise + * it is assumed to be a jar file + * @param className the fully qualifying Java class name separated by '.' periods + * @param methodName the name of the method to call without parentheses or arguments + * @param classInst an optional instance of the class to use when calling the method, + * if the method being called is not static and this instance parameter is null, + * than a new instance of the class is created using {@link Class#newInstance()} + * @param args the list of parameters to pass to the method call + * @return true if the method was called, false if there was an error + */ + public static ThreadMethodResultFuture callClassMethod(String path, String className, String methodName, Object classInst, Object... args) { + return callClassMethod(toURLClean(path), className, methodName, classInst, args); + } + + + /** Dynamically load and call a specified class' method in a new thread. + * Designed to start or restart a particular dynamic program module that + * is well suited to run in its own thread. + * @param path the folder path or jar file path that the class is located in. + * @param className the fully qualifying Java class name separated by '.' periods + * @param methodName the name of the method to call without parentheses or arguments + * @param classInst an optional instance of the class to use when calling the method, + * if the method being called is not static and this instance parameter is null, + * than a new instance of the class is created using {@link Class#newInstance()} + * @param args the list of parameters to pass to the method call + * @return true if the method was called, false if there was an error + */ + public static ThreadMethodResultFuture callClassMethod(URL path, String className, String methodName, Object classInst, Object... args) { + final CompletableFuture resultFuture = new CompletableFuture<>(); + FutureTask task = new FutureTask<>(() -> { + @SuppressWarnings("unchecked") + var res = (Entry)callMethod(className, classInst, methodName, args); + resultFuture.complete(res.getValue()); + return res.getKey(); + }); + + Thread t = new Thread(task, "Run " + className + "." + methodName); + + URLClassLoader cl = createClassLoader(path); + + try { + t.setContextClassLoader(cl); + } catch(SecurityException se) { + System.err.println("Error, security error setting new thread classloader: " + className); + } + t.start(); + return new ThreadMethodResultFuture(t, task, resultFuture); + } + + + /** Loads a class and calls a method on it via reflection using the current thread's + * context class loader. Catches exceptions and prints appropriate error messages. + * @param className the name of the class to containing the method + * @param instance the object instance to use, or null if the method is + * static or a new instance should be created + * @param methodName the name of the method to call + * @param args the parameters to pass to the method + */ + public static Entry callMethod(String className, Object instance, String methodName, Object[] args) { + Method method = loadClassAndFindMethod(className, methodName, args); + Class clazz = method.getDeclaringClass(); + + // If the method is not static and the instance is null, create an instance of the class to use to call the method + int modifiers = method.getModifiers(); + try { + if(instance == null && !Modifier.isStatic(modifiers)) { + @SuppressWarnings("deprecation") + Object obj = clazz.newInstance(); + instance = obj; + } + } catch(Exception e) { + System.err.println("Error creating new instance of class: " + className + ", " + e.getLocalizedMessage() + ", caused by " + e); + } + + // Call the method + Object result = null; + try { + result = method.invoke(instance, args); + } catch (IllegalAccessException e) { + System.err.println("Illegal Access Exception: cannot invoke \'" + clazz.getSimpleName() + "." + + methodName + "\' method, caused by " + e.getCause()); + } catch (InvocationTargetException e) { + System.err.println("Exception throw by " + className + "." + methodName + + "() while calling it, caused by " + e.getCause()); + } + return new AbstractMap.SimpleImmutableEntry<>(method, result); + } + + + /** Loads a class and find a method by name and arguments via reflection using the + * current thread's context class loader. + * Catches exceptions and prints appropriate error messages. + * @param className the name of the class to containing the method + * @param methodName the name of the method to find + * @param args the parameters to pass to the method + */ + public static Method loadClassAndFindMethod(String className, String methodName, Object[] args) { + // Infer the list of parameter types from the arguments, we may not find the + // method if the argument types don't exactly match the method's parameter types + Class[] argumentTypes = inferArgumentTypes(args); + + // Get this thread's class loader and load the class, then get the method in the class with the specified name + Class clazz = null; + Method method = null; + try { + clazz = Thread.currentThread().getContextClassLoader().loadClass(className); + method = clazz.getMethod(methodName, argumentTypes); + } catch (SecurityException e1) { + System.err.println("Security exception, ensure that class " + className + " is public, caused by " + e1); + } catch (NoSuchMethodException e1) { + System.err.println("No such method exception, method: " + methodName + ", caused by " + e1); + } catch (ClassNotFoundException e1) { + System.err.println("Error, could not find class name=" + className + ", caused by " + e1); + } + return method; + } + + + /** Create the list of parameter class types from the list of parameters + * @param args the list of arguments to infer types from + * @return list of argument types + */ + public static Class[] inferArgumentTypes(Object[] args) { + Class[] argumentTypes = null; + if(args != null && args.length > 0 && !(args.length == 1 && args[0] == null)) { + int argCount = args.length; + argumentTypes = new Class[argCount]; + for(int i = 0; i < argCount; i++) { + argumentTypes[i] = args[i].getClass(); + } + } + return argumentTypes; + } + + + /** Create a class loader using the specified URL + * @param path the URL to set as the classloader's path + * @return the classloader with the specified classpath + */ + public static URLClassLoader createClassLoader(URL path) { + return new URLClassLoader(new URL[] {path}, Thread.currentThread().getContextClassLoader()); + } + + + public static URL toURLClean(String path) { + try { + return toURL(path); + } catch (IOException e) { + System.err.println("Error creating class loader URL"); + e.printStackTrace(); + } + return null; + } + + + /** Convert a local file path to a {@link URL} + * @param path the local file path to parse into a URL + * @return the URL corresponding to the specified file/folder path + * @throws IOException if there is an error creating the URL + */ + private static URL toURL(String path) throws IOException { + URL url = null; + // Convert the path to a URL + try { + url = new URL(path); + } catch(Exception e) { + // If the path is not a valid URL convert it to a file then to a URL + File file = new File(path).getCanonicalFile(); + url = file.toURI().toURL(); + } + return url; + } + + + public static URL getApplicationPathURL() { + if(appPath == null) { + appPath = ClassLoaders.class.getProtectionDomain().getCodeSource().getLocation(); + // more sure way + /* + java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() { + public URL run() { + return (appPath = RuntimeReloadMain.class.getProtectionDomain().getCodeSource().getLocation()); + } + }); + */ + } + return appPath; + } + + + public static String getApplicationPathString() { + if(appPathStr == null) { + appPathStr = getApplicationPathURL().getPath(); + } + return appPathStr; + } + +} diff --git a/src/twg2/jbcm/runtimeLoading/CompileSource.java b/src/twg2/jbcm/runtime/CompileSource.java similarity index 60% rename from src/twg2/jbcm/runtimeLoading/CompileSource.java rename to src/twg2/jbcm/runtime/CompileSource.java index 2641aed..b8c8db0 100644 --- a/src/twg2/jbcm/runtimeLoading/CompileSource.java +++ b/src/twg2/jbcm/runtime/CompileSource.java @@ -1,4 +1,4 @@ -package twg2.jbcm.runtimeLoading; +package twg2.jbcm.runtime; import java.io.ByteArrayOutputStream; import java.io.File; @@ -8,7 +8,6 @@ import java.io.OutputStreamWriter; import java.io.PrintStream; import java.io.PrintWriter; -import java.net.MalformedURLException; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.StandardOpenOption; @@ -17,14 +16,34 @@ import org.eclipse.jdt.core.compiler.CompilationProgress; import twg2.jbcm.classFormat.ClassFile; -import twg2.jbcm.main.RuntimeReloadMain; /** Compile a Java source file * @author TeamworkGuy2 * @since 2013-10-7 */ public class CompileSource { + /** Default class name for dynamically compiled snippets of code */ public static String defaultCompileClassName = "CompilerTemp"; + /** Compiler configuration for Java 1.8 source and target */ + public static CompilerConfig JAVA_1_8_COMPILE = new CompilerConfig("\"C:/Program Files/Java/jdk1.8.0_25/bin/javac\"", "1.8", "1.8"); + /** Whether to print code by default when calling {@code compileCode()} without the last boolean parameter */ + public static boolean printCode = false; + /** Whether to print additional debug diagnostic information */ + public static boolean debug = false; + + + public static class CompilerConfig { + public final String compilerPath; + public final String sourceVersion; + public final String targetCompileVersion; + + public CompilerConfig(String compilerPath, String sourceVersion, String targetCompileVersion) { + this.compilerPath = compilerPath; + this.sourceVersion = sourceVersion; + this.targetCompileVersion = targetCompileVersion; + } + } + private CompileSource() { } @@ -34,68 +53,88 @@ private CompileSource() { * TODO: make JDK path/version a variable in future. * @param useEclipse whether to compile using {@link org.eclipse.jdt.core.compiler.batch.BatchCompiler} * @param entrySourceFile the source file to compile - * @param sourceFilesPath the directory containing all source files required for compiling {@code entrySourceFile} - * @param classPaths 'classpath' semicolon separated list of for JDK/JRE and dependency libraries - * @param destinationPath the directory to write compiled {@code .class} files to + * @param sourceDir the directory containing all source files required for compiling {@code entrySourceFile} + * @param classPaths 'classpath' semicolon separated list of JDK/JRE and dependency libraries + * @param destinationDir the directory to write compiled {@code .class} files to * @throws ClassNotFoundException * @throws IOException */ - public static boolean compile(boolean useEclipse, File entrySourceFile, File sourceFilesPath, String classPaths, File destinationPath) throws ClassNotFoundException, IOException { - Charset charset = Charset.forName("UTF-8"); - String sourceFilesPathStr = sourceFilesPath.getAbsoluteFile().getPath(); - String dstPathStr = destinationPath.getAbsoluteFile().getPath(); - String clArg = (useEclipse ? "-1.6" : "-source 1.8 -target 1.8") + + public static boolean compile(CompilerConfig config, File entrySourceFile, File sourceDir, String classPaths, File destinationDir) throws ClassNotFoundException, IOException { + String sourceFilesPathStr = sourceDir.getAbsoluteFile().getPath(); + String dstPathStr = destinationDir.getAbsoluteFile().getPath(); + String clArg = "-source " + config.sourceVersion + " -target " + config.targetCompileVersion + " -classpath rt.jar;" + classPaths + " -sourcepath " + sourceFilesPathStr + " -d " + dstPathStr + - " " + entrySourceFile.getAbsolutePath(); + " " + (entrySourceFile != null ? entrySourceFile.getAbsolutePath() : ""); - System.out.println("Compiler args: " + clArg); + if(debug) { + System.out.println("Compiler args: " + clArg); + } - if(useEclipse) { - // http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftask-using_batch_compiler.htm - CompilationProgress compileProgress = new CompilationProgressImpl(); - ByteArrayOutputStream out = new ByteArrayOutputStream(4096); - PrintWriter outWriter = new PrintWriter(new OutputStreamWriter(out, charset)); - PrintWriter errWriter = new PrintWriter(System.err); - boolean res = org.eclipse.jdt.core.compiler.batch.BatchCompiler.compile(clArg, outWriter, errWriter, compileProgress); + int res = runCommand(Runtime.getRuntime(), config.compilerPath + " " + clArg, System.out, System.err); + return res == 0; + } - System.out.println(out.toString(charset)); - return res; - } - else { - int res = runCommand(Runtime.getRuntime(), "\"C:/Program Files/Java/jdk1.8.0_25/bin/javac\" " + clArg, System.out, System.err); - return res == 0; + + public static boolean compileUsingEclipseEcj(File entrySourceFile, File sourceDir, String classPaths, File destinationDir) throws ClassNotFoundException, IOException { + String sourceFilesPathStr = sourceDir.getAbsoluteFile().getPath(); + String dstPathStr = destinationDir.getAbsoluteFile().getPath(); + String clArg = "-1.6" + + " -classpath rt.jar;" + classPaths + + " -sourcepath " + sourceFilesPathStr + + " -d " + dstPathStr + + " " + (entrySourceFile != null ? entrySourceFile.getAbsolutePath() : ""); + + if(debug) { + System.out.println("Compiler args: " + clArg); } - } + // http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftask-using_batch_compiler.htm + Charset charset = Charset.forName("UTF-8"); + CompilationProgress compileProgress = new CompilationProgressImpl(); + ByteArrayOutputStream out = new ByteArrayOutputStream(4096); + PrintWriter outWriter = new PrintWriter(new OutputStreamWriter(out, charset)); + PrintWriter errWriter = new PrintWriter(System.err); + boolean res = org.eclipse.jdt.core.compiler.batch.BatchCompiler.compile(clArg, outWriter, errWriter, compileProgress); + + System.out.println(out.toString(charset)); + return res; + } /** Compile a Java source string to bytecode + * @param sourceRootDir the root folder containing the source files + * @param destinationRootDir the root folder to write compiled class files into + * @param packageDir the relative package directory within the source directory the find the file and + * within the destination directory to write the compiled class file. Expected format for. + * Example: when compiling {@code com.app.utils.MathUtils}, the {@code packageDir} should be {@code com/app/utils} + * @param className the simple class name of the {@code javaSrc}, does not include the package name nor file extension. + * Example: when compiling {@code com.app.utils.MathUtils}, the {@code className} should be {@code MathUtils} * @param javaSrc the Java source code string * @return the compiled byte code loaded as a byte[] (which can be loaded to {@link ClassFile} via {@link ClassFile#readData(java.io.DataInput)} - * @throws MalformedURLException - * @throws ClassNotFoundException + * @throws RuntimeException wrapping possible {@link IOException} or {@link ClassNotFoundException} */ - public static byte[] compileSourceToBytecode(String javaSrc) { + public static byte[] compileSourceToBytecode(String sourceRootDir, String destinationRootDir, String packageDir, String className, String javaSrc) { File tmpSrcFile = null; File tmpDstFile = null; try { - new File("res/tmp/src").mkdir(); - new File("res/tmp/bin").mkdir(); + File srcDir = new File(sourceRootDir); + File dstDir = new File(destinationRootDir); - tmpSrcFile = new File("res/tmp/src/" + defaultCompileClassName + ".java"); - Files.write(tmpSrcFile.toPath(), javaSrc.getBytes("UTF-8"), StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE); - File sourceFilesPath = new File("res/tmp/src"); - String classPath = new File("res/tmp/src").getAbsolutePath(); - File destinationPath = new File("res/tmp/bin"); + new File(srcDir, packageDir).mkdir(); + dstDir.mkdir(); - boolean success = CompileSource.compile(false, tmpSrcFile, sourceFilesPath, classPath, destinationPath); + tmpSrcFile = new File(sourceRootDir + "/" + (packageDir != null && packageDir.length() > 0 ? packageDir + "/" : "") + className + ".java"); + Files.write(tmpSrcFile.toPath(), javaSrc.getBytes("UTF-8"), StandardOpenOption.CREATE, StandardOpenOption.WRITE); + String classPath = srcDir.getAbsolutePath(); + + boolean success = compile(JAVA_1_8_COMPILE, tmpSrcFile, srcDir, classPath, dstDir); if(!success) { throw new RuntimeException("Error compiling source"); } - tmpDstFile = new File("res/tmp/bin/" + defaultCompileClassName + ".class"); + tmpDstFile = new File(destinationRootDir + "/" + (packageDir != null && packageDir.length() > 0 ? packageDir + "/" : "") + className + ".class"); var bytecode = Files.readAllBytes(tmpDstFile.toPath()); tmpSrcFile.delete(); @@ -122,29 +161,7 @@ public static byte[] compileSourceToBytecode(String javaSrc) { } - /** Compile a Java source file and load it - * @param srcJavaFile - * @param dstClassFile - * @throws ClassNotFoundException - * @throws IOException - */ - public static void compileSourceFileToClass(File srcJavaFile, File dstClassFile) throws ClassNotFoundException, IOException { - File entryFile = new File("res/tmp/src/twg2/compileTest/Hello.java"); - File sourceFilesPath = new File("res/tmp/src"); - String classPath = new File("res/tmp/src/twg2/compileTest").getAbsolutePath(); - File destinationClassPath = new File("res/tmp/bin"); - - CompileSource.compile(false, entryFile, sourceFilesPath, classPath, destinationClassPath); - - RuntimeReloadMain reload = new RuntimeReloadMain(); - reload.loadRun("res/tmp/bin", "twg2.compileTest.Hello", "run", (String[])null); - - //Runnable thing = (Runnable)classes[0].newInstance(); - //thing.run(); - } - - - private static int runCommand(Runtime runtime, String command, OutputStream outStream, OutputStream errStream) throws IOException { + protected static int runCommand(Runtime runtime, String command, OutputStream outStream, OutputStream errStream) throws IOException { Level level = Level.INFO; PrintStream log = System.err; @@ -165,7 +182,7 @@ private static int runCommand(Runtime runtime, String command, OutputStream outS * @param exeCmd the command to execute * @return 0 normally indicates success, other values normally indicate failure */ - private static int finishSync(Process process, ReadInputStream inputReader, ReadInputStream errorReader) { + protected static int finishSync(Process process, ReadInputStream inputReader, ReadInputStream errorReader) { int res = -1; try { res = process.waitFor(); @@ -183,7 +200,7 @@ private static int finishSync(Process process, ReadInputStream inputReader, Read - private static class CompilationProgressImpl extends CompilationProgress { + protected static class CompilationProgressImpl extends CompilationProgress { //private boolean done; @Override diff --git a/src/twg2/jbcm/runtime/FileUtility.java b/src/twg2/jbcm/runtime/FileUtility.java new file mode 100644 index 0000000..774e154 --- /dev/null +++ b/src/twg2/jbcm/runtime/FileUtility.java @@ -0,0 +1,99 @@ +package twg2.jbcm.runtime; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.channels.FileChannel; + +/** File utilities related to class loading and bytecode manipulation + * @author TeamworkGuy2 + * @since 2022-08-21 + */ +public class FileUtility { + + /** The source class file is copied and written over the target class file. + *
+ * Unfortunately, the trick to get this to work requires that both class files be located + * in the same named relative class path with unique base paths, for example, to load a + * new version of the class "myProject.Original" the new class must also be contained in + * a path ending with "myProject.Original" but must be located in a folder outside of the + * current application's classpath. The original class might be located in + * "/home/name/project/myProject/Original.class" and the new class might be + * located in "/home/name/projectAlt/myProject/Original.class".
+ *
+ * @param sourcePath the directory location of the new class to copy (jar file paths are not supported). + * @param sourceClassName the fully qualifying Java name of the source class to copy, + * the path separated by '.' periods. + * @param targetPath the directory location of the class to overwrite (jar file paths are not supported). + * @param targetClassName the fully qualifying Java name of the class to overwrite, + * the path separated by '.' periods. + * @return true if the class was successfully overwritten, false if there was an IO error + */ + public static boolean overwriteClass(String sourcePath, String sourceClassName, String targetPath, String targetClassName) { + try { + String sourceClass = sourceClassName.replace('.', File.separatorChar) + ".class"; + String targetClass = targetClassName.replace('.', File.separatorChar) + ".class"; + String fullSourcePath = sourcePath + ((sourcePath.endsWith("\\") || sourcePath.endsWith("/")) ? sourceClass : File.separatorChar + sourceClass); + String fullTargetPath = targetPath + ((targetPath.endsWith("\\") || targetPath.endsWith("/")) ? targetClass : File.separatorChar + targetClass); + // Faster when the destination file exists + overwriteFile(fullSourcePath, fullTargetPath); + // Faster when the destination files does not exist + //Files.copy(Paths.get(fullSourcePath), Paths.get(fullTargetPath), StandardCopyOption.REPLACE_EXISTING); + } catch(IOException ioe) { + System.err.println("Error, could not overwrite the old file, caused by " + ioe.getMessage() + "\nCause:" + ioe.getCause()); + return false; + } + return true; + } + + + /** Overwrite the destination file with the source file + * @param sourceFilePath the source file to copy + * @param targetFilePath the destination file to overwrite with the contents of the source file + * @throws IOException if there is an error opening either of the files or copying the source file's + * contents into the target file + */ + private static void overwriteFile(String sourceFilePath, String targetFilePath) throws IOException { + FileChannel src = null; + FileChannel dst = null; + try { + File sourceFile = new File(sourceFilePath).getCanonicalFile(); + File targetFile = new File(targetFilePath).getCanonicalFile(); + //System.out.println("Overwriting: " + sourceFile.getAbsolutePath() + ", with: " + targetFile.getAbsolutePath()); + + @SuppressWarnings("resource") + FileInputStream srcStream = new FileInputStream(sourceFile); + src = srcStream.getChannel(); + + @SuppressWarnings("resource") + FileOutputStream dstStream = new FileOutputStream(targetFile); + dst = dstStream.getChannel(); + + long transferCount = 0; + long size = src.size(); + do { + transferCount += dst.transferFrom(src, transferCount, size - transferCount); + } while(transferCount < size); + } catch (IOException e) { + throw e; + } + finally { + try { + if(src != null) { + src.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + try { + if(dst != null) { + dst.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + +} diff --git a/src/twg2/jbcm/runtimeLoading/MemoryClassLoader.java b/src/twg2/jbcm/runtime/MemoryClassLoader.java similarity index 80% rename from src/twg2/jbcm/runtimeLoading/MemoryClassLoader.java rename to src/twg2/jbcm/runtime/MemoryClassLoader.java index 8ec1ef9..b709754 100644 --- a/src/twg2/jbcm/runtimeLoading/MemoryClassLoader.java +++ b/src/twg2/jbcm/runtime/MemoryClassLoader.java @@ -1,8 +1,11 @@ -package twg2.jbcm.runtimeLoading; +package twg2.jbcm.runtime; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; +import java.security.CodeSource; +import java.security.Principal; +import java.security.ProtectionDomain; import java.util.HashMap; import twg2.jbcm.IoUtility; @@ -14,18 +17,22 @@ public class MemoryClassLoader extends ClassLoader implements ResourceClassLoader { private File customPath; + private class CustomClass { private final String className; private final byte[] data; + private final ProtectionDomain protectionDomain; private boolean isDefined; private Class definedClass; - CustomClass(String className, byte[] b) { + CustomClass(String className, byte[] b, ProtectionDomain protectionDomain) { this.className = className; this.data = b; + this.protectionDomain = protectionDomain; } } + /** {@link sun.misc.Launcher$AppClassLoader} * {@link java.lang.ClassLoader#loadClass()} * {@link java.net.URLClassLoader$1} */ @@ -72,7 +79,7 @@ public Class findClass(String name) { if(customPath != null) { try { byte[] classBytes = IoUtility.loadBytes(new File(customPath, name.replace('.', '/') + ".class")); - CustomClass customClass = new CustomClass(name, classBytes); + CustomClass customClass = new CustomClass(name, classBytes, newProtectionDomain()); memoryClasses.put(name, customClass); return setupCustomClass(customClass); } catch (MalformedURLException e) { @@ -94,7 +101,7 @@ public Class findClass(String name) { private final Class setupCustomClass(CustomClass classData) { if(classData.isDefined == false) { System.out.println("Define class: " + classData.className); - Class clas = super.defineClass(classData.className, classData.data, 0, classData.data.length); + Class clas = super.defineClass(classData.className, classData.data, 0, classData.data.length, classData.protectionDomain); classData.isDefined = true; classData.definedClass = clas; return clas; @@ -108,7 +115,13 @@ private final Class setupCustomClass(CustomClass classData) { @Override public void addClassByteCode(String name, byte[] b) { - memoryClasses.put(name, new CustomClass(name, b)); + memoryClasses.put(name, new CustomClass(name, b, newProtectionDomain())); + } + + + private ProtectionDomain newProtectionDomain() { + CodeSource codeSource = this.getClass().getProtectionDomain().getCodeSource(); + return new ProtectionDomain(codeSource, null, this, new Principal[0]); } } diff --git a/src/twg2/jbcm/runtimeLoading/ResourceClassLoader.java b/src/twg2/jbcm/runtime/ResourceClassLoader.java similarity index 87% rename from src/twg2/jbcm/runtimeLoading/ResourceClassLoader.java rename to src/twg2/jbcm/runtime/ResourceClassLoader.java index bc8fdfe..02404b5 100644 --- a/src/twg2/jbcm/runtimeLoading/ResourceClassLoader.java +++ b/src/twg2/jbcm/runtime/ResourceClassLoader.java @@ -1,4 +1,4 @@ -package twg2.jbcm.runtimeLoading; +package twg2.jbcm.runtime; /** An interface representing a custom resource classloader * @author TeamworkGuy2 diff --git a/src/twg2/jbcm/runtime/ResourceToClass.java b/src/twg2/jbcm/runtime/ResourceToClass.java new file mode 100644 index 0000000..33e3e7c --- /dev/null +++ b/src/twg2/jbcm/runtime/ResourceToClass.java @@ -0,0 +1,83 @@ +package twg2.jbcm.runtime; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** A class for converting URL resources to classes. + * @author TeamworkGuy2 + * @since 2013-9-24 + */ +public class ResourceToClass { + + public static Class[] loadClasses(URL[] urls, MemoryClassLoader cl) throws IOException { + int size = 8192; + byte[] buf = new byte[size]; + int urlCount = urls.length; + // Open each URL and load its contents into a byte buffer + for(int i = 0; i < urlCount; i++) { + InputStream is = urls[i].openStream(); + int bufPos = 0; + int read = 0; + // Read each input stream into our byte array buffer + while(read > -1) { + int newSize = bufPos + size; + if(newSize > buf.length) { + buf = Arrays.copyOf(buf, (buf.length << 1)); + } + bufPos = newSize; + read = is.read(buf, bufPos - size, size); + } + // Create a copy of the buffers exact length and add it to the classloader + byte[] bufN = new byte[bufPos]; + System.arraycopy(buf, 0, bufN, 0, bufPos); + cl.addClassByteCode(urls[i].getFile(), bufN); + } + + // For each URL class, convert the byte array into a class in the classloader + Class[] classes = new Class[urlCount]; + for(int i = 0; i < urlCount; i++) { + classes[i] = cl.findClass(urls[i].getFile()); + } + return classes; + } + + + public static List> loadClasses(InputStream[] dataStreams, String[] fileNames, MemoryClassLoader cl) throws IOException { + ArrayList> classes = new ArrayList>(); + int size = 8192; + byte[] buf = new byte[size]; + int bufPos = 0; + int newSize = 0; + int read = 0; + // Open each URL and load its contents into a byte buffer + for(int i = 0, sz = dataStreams.length; i < sz; i++) { + InputStream stream = dataStreams[i]; + bufPos = 0; + read = 0; + // Read each input stream into our byte array buffer + while(read > -1) { + newSize = bufPos + size; + if(newSize > buf.length) { + buf = Arrays.copyOf(buf, (buf.length << 1)); + } + bufPos = newSize; + read = stream.read(buf, bufPos-size, size); + } + // Create a copy of the buffers exact length and add it to the classloader + byte[] bufN = new byte[bufPos]; + System.arraycopy(buf, 0, bufN, 0, bufPos); + cl.addClassByteCode(fileNames[i], bufN); + } + + // For each URL class, convert the byte array into a class in the classloader + for(int i = 0, sz = dataStreams.length; i < sz; i++) { + classes.add(cl.findClass(fileNames[i])); + } + return classes; + } + +} diff --git a/src/twg2/jbcm/runtimeLoading/ResourceToClass.java b/src/twg2/jbcm/runtimeLoading/ResourceToClass.java deleted file mode 100644 index 0bcb2a1..0000000 --- a/src/twg2/jbcm/runtimeLoading/ResourceToClass.java +++ /dev/null @@ -1,67 +0,0 @@ -package twg2.jbcm.runtimeLoading; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.Arrays; - -/** A class for converting URL resources to classes. - * @author TeamworkGuy2 - * @since 2013-9-24 - */ -public class ResourceToClass { - - /** Load a list of URLs as class files and create an instance of the - * runI index class and cast it to {@link Runnable} and - * call the {@link Runnable#run() run()} method on it. - * @param urls the list of class file locations to load - * @param runI the index in the url array of corresponding to the class to run - * once the classes are loaded - * @param cl the classloader to handle loading the classes - * @throws IOException if there is any other error loading the urls - * @throws ReflectiveOperationException if there is an error calling the runI class' default constructor - */ - public ResourceToClass(URL[] urls, int runI, MemoryClassLoader cl) throws IOException, ReflectiveOperationException { - Class[] classes = loadClasses(urls, cl); - Runnable r = (Runnable)classes[runI].getDeclaredConstructor().newInstance(); - r.run(); - } - - - private Class[] loadClasses(URL[] urls, MemoryClassLoader cl) throws IOException { - Class[] classes = new Class[urls.length]; - int size = 8192; - byte[] buf = new byte[size]; - int bufP = 0; - int newSize = 0; - int urlCount = urls.length; - int read = 0; - InputStream is = null; - // Open each URL and load its contents into a byte buffer - for(int i = 0; i < urlCount; i++) { - is = urls[i].openStream(); - bufP = 0; - read = 0; - // Read each input stream into our byte array buffer - while(read > -1) { - newSize = bufP + size; - if(newSize > buf.length) { - buf = Arrays.copyOf(buf, (buf.length+2 << 1)); - } - bufP = newSize; - read = is.read(buf, bufP-size, size); - } - // Create a copy of the buffers exact length and add it to the classloader - byte[] bufN = new byte[bufP]; - System.arraycopy(buf, 0, bufN, 0, bufP); - cl.addClassByteCode(urls[i].getFile(), bufN); - } - // For each URL class, convert the byte array into a class in the classloader - for(int i = 0; i < urlCount; i++) { - System.out.println("[ResourceToClass.loadClasses()] find class: " + urls[i].getFile() + " (" + urls[i] + ")"); - classes[i] = cl.findClass(urls[i].getFile()); - } - return classes; - } - -} diff --git a/src/twg2/jbcm/toSource/ClassFileToSource.java b/src/twg2/jbcm/toSource/ClassFileToSource.java index 12add86..2c5757f 100644 --- a/src/twg2/jbcm/toSource/ClassFileToSource.java +++ b/src/twg2/jbcm/toSource/ClassFileToSource.java @@ -4,6 +4,7 @@ import twg2.jbcm.classFormat.Field_Info; import twg2.jbcm.classFormat.Method_Info; import twg2.jbcm.ir.MethodStack; +import twg2.jbcm.modify.TypeUtility; /** * @author TeamworkGuy2 @@ -29,7 +30,7 @@ public static void toSource(ClassFile cls, SourceWriter dst, boolean decompile) dst.accessModifierClass(cls.getAccessFlags()).space().keyword("class").space(); dst.identifier(className); // extends - String superClassName = cls.getSuperClassIndex().getCpObject().getName().getString().replace('/', '.'); + String superClassName = TypeUtility.decodeBinaryClassName(cls.getSuperClassIndex().getCpObject()); if(!superClassName.equals("java.lang.Object")) { dst.space().keyword("extends").space().identifier(superClassName); } diff --git a/src/twg2/jbcm/toSource/CodeToSource.java b/src/twg2/jbcm/toSource/CodeToSource.java index 5177a25..9368a02 100644 --- a/src/twg2/jbcm/toSource/CodeToSource.java +++ b/src/twg2/jbcm/toSource/CodeToSource.java @@ -1,10 +1,10 @@ package twg2.jbcm.toSource; import java.util.ArrayList; -import java.util.BitSet; import java.util.List; import twg2.collections.primitiveCollections.IntArrayList; +import twg2.jbcm.CodeFlow; import twg2.jbcm.Opcodes; import twg2.jbcm.Opcodes.Type; import twg2.jbcm.classFormat.ClassFile; @@ -21,14 +21,20 @@ import twg2.jbcm.classFormat.constantPool.CONSTANT_MethodType; import twg2.jbcm.classFormat.constantPool.CONSTANT_Methodref; import twg2.jbcm.classFormat.constantPool.CONSTANT_String; -import twg2.jbcm.ir.JumpConditionInfo; import twg2.jbcm.ir.MethodStack; import twg2.jbcm.ir.OperandInfo; -import twg2.jbcm.ir.Switch; import twg2.jbcm.ir.VariableInfo; import twg2.jbcm.modify.TypeUtility; +import twg2.jbcm.toSource.structures.CodeStructureIf; +import twg2.jbcm.toSource.structures.CodeStructureLoop; +import twg2.jbcm.toSource.structures.CodeEmitter; +import twg2.jbcm.toSource.structures.CodeStructureSwitch; +import twg2.jbcm.toSource.structures.CodeStructureSynchronized; +import twg2.jbcm.toSource.structures.CodeStructureTryCatchFinally; import static twg2.jbcm.CodeUtility.loadOperands; +import static twg2.jbcm.modify.TypeUtility.decodeBinaryClassName; +import static twg2.jbcm.toSource.structures.CodeEmitter.runEmits; /** * @author TeamworkGuy2 @@ -47,114 +53,47 @@ public static void toSource(ClassFile cls, Method_Info method, MethodStack metho Code code = method.getCode(); byte[] instr = code.getCode(); int instrCount = instr.length; - //BitSet instrUsed = new BitSet(instr.length); // track which instructions have already run through the loop + int i = 0; + int endIdx = instrCount - 1; + + var possibleLoops = CodeFlow.findFlowConditions(instr, i, endIdx); // track GOTO/IF_* loops detected in the code + var structuresInProgress = new ArrayList(); + + var exception_table = code.getExceptionTable(); + for(int j = 0; j < exception_table.length; j++) { + var tryCatchStructure = CodeStructureTryCatchFinally.create(instr, exception_table[j], "ex" + (j + 1), methodStack); + if(tryCatchStructure != null) { + structuresInProgress.add(tryCatchStructure); + } + } - var loops = new ArrayList(); // track GOTO/IF_* loops detected in the code - // pairs of values, the first is the case match value the second is the target index - Switch curSwitch = null; - int conditionUnfinishedIdx = -1; - Indent indent = dst.getIndent(); StringBuilder tmp = new StringBuilder(); var tmpList = new ArrayList(); var tmpList2 = new ArrayList(); - StringBuilder str = dst.src; + var src = new StringBuilderIndent(dst.src, dst.getIndent()); - str.append(" // stack: ").append(code.getMaxStack()) - .append(", locals: ").append(code.getMaxLocals()).append("\n"); + src.append("// stack: ").append(code.getMaxStack()) + .append(", locals: ").append(code.getMaxLocals()).append('\n'); - var instrFlows = new ArrayList(); // pairs of index start (inclusive) and end (inclusive) indexes to control which portions of the code are processed by the main loop + var instrFlows = new ArrayList(); // pairs of start (inclusive) and end (inclusive) indexes to control which portions of the code are processed by the main loop instrFlows.add(new IntArrayList()); - int i = 0; - int endIdx = instrCount - 1; for( ; i <= endIdx; i++) { Opcodes opc = Opcodes.get(instr[i] & 0xFF); int numOperands = opc.getOperandCount(); - boolean isWide = false; // read following bytes of code and convert them to an operand int operand = loadOperands(numOperands, instr, i); - // skip instructions that have already been processed (since code flow can be non-linear with branches, loops, and switches - //if(instrUsed.get(i)) { - // i += (numOperands < 0 ? 0 : numOperands); - // continue; - //} - - //instrUsed.set(i); - - // end if-else blocks and loops based on ending instruction index tracked when if_* and goto instructions are first encountered - var curCond = conditionUnfinishedIdx > -1 ? loops.get(conditionUnfinishedIdx) : null; - while(curCond != null && curCond.getTargetIndex() <= i) { - // if-statement (loops start with GOTO, handled elsewhere) - if(curCond.getOpcode() != Opcodes.GOTO && !curCond.isFinished()) { - curCond.finish(); - indent.dedent(); - str.append(indent).append('}').append('\n'); - } - conditionUnfinishedIdx--; - curCond = conditionUnfinishedIdx > -1 ? loops.get(conditionUnfinishedIdx) : null; - } - - // switch cases - if(curSwitch != null) { - if(curSwitch.switchDefault.caseTarget == i) { - curSwitch.finish(curSwitch.switchDefault); - str.append("default: ").append("// offset ").append(curSwitch.switchDefault.caseTarget); - } - var switchCaseIdx = SwitchFlow.findSwitchCase(i, curSwitch.switchCases, 0); - while(switchCaseIdx > -1) { - var caseObj = curSwitch.switchCases.get(switchCaseIdx); - caseObj.finish(); - str.append(indent.toDedent()).append("case ").append(caseObj.caseMatch).append(": ").append("// offset ").append(caseObj.caseTarget).append('\n'); - switchCaseIdx = SwitchFlow.findSwitchCase(i, curSwitch.switchCases, switchCaseIdx + 1); - } - } - - str.append(indent).append(isWide ? "WIDE " : ""); - // unpredictable operand length instructions if(opc == Opcodes.WIDE) { // TODO need to read extra wide operand bytes in all possible cases - isWide = true; i++; // because wide instructions are wrapped around other instructions opc = Opcodes.get(instr[i] & 0xFF); numOperands = opc.getOperandCount(); - //instrUsed.set(i); } // switch else if(numOperands == Opcodes.Const.UNPREDICTABLE) { - if(opc == Opcodes.TABLESWITCH) { - curSwitch = Switch.loadTableSwitch(i, instr); - } - else if(opc == Opcodes.LOOKUPSWITCH) { - curSwitch = Switch.loadLookupSwitch(i, instr); - } - int origI = i; - i += curSwitch.switchInstSize; - //instrUsed.set(origI, i); - var switchKey = methodStack.popOperand(); - indent.indent(); - str.append("switch(" + switchKey.getExpression() + ") {"); - - //var instrFlow = last(instrFlows); - //instrFlow.add(curSwitch.switchEndIdx > -1 ? ~curSwitch.switchEndIdx : ~i); // TODO technically we wouldn't want to restart at the current index - // need some unit tests to check different types of switches - // can a switch with fall through cases still have a common end index, 'break' instructions should lead to a common end index, what if the default throws, etc? - //instrFlow.add(endIdx); - - //SwitchFlow.loadCasesToFlow(curSwitch.switchCases, curSwitch.switchDefault, instrFlows); - - // TODO debugging - //str.append(" // common end: " + commonEndIdx); - //for(var caseObj : switchCases) { - // str.append('\n').append(indentation).append(indentMark).append("// case " + caseObj.caseMatch + ": [" + caseObj.caseTarget + ", " + caseObj.caseEndIdx + "]" + (caseObj.caseEndTarget > 0 ? " jump to " + caseObj.caseEndTarget : "")); - // System.out.println("case " + caseObj.caseMatch + ": " + CodeFlow.flowPathToString(instr, caseObj.getCodeFlow())); - //} - //str.append('\n').append(indentation).append(indentMark).append("// default: [" + switchDefault.get().caseTarget + ", " + switchDefault.get().caseEndIdx + "]" + (switchDefault.get().caseEndTarget > 0 ? " jump to " + switchDefault.get().caseEndTarget : "")); - - //if(curSwitch.switchEndIdx == -1) { - // throw new IllegalStateException(opc + " switch statement common end index could not be found, cannot decompile"); - //} + structuresInProgress.add(CodeStructureSwitch.create(opc, instr, i, methodStack.popOperand(), src)); } if(opc.hasBehavior(Type.CONST_LOAD)) { @@ -194,6 +133,7 @@ else if(opc == Opcodes.LDC || opc == Opcodes.LDC_W || opc == Opcodes.LDC2_W) { } methodStack.addOperand(new OperandInfo(expr, exprType, opc)); } + // includes: ILOAD*, LLOAD*, FLOAD*, DLOAD*, ALOAD* else if(opc.hasBehavior(Type.VAR_LOAD)) { int localVarIdx = numOperands > 0 ? loadOperands(numOperands, instr, i) : ((Number)opc.getConstantValue()).intValue(); var value = methodStack.getVariable(localVarIdx); @@ -205,15 +145,20 @@ else if(opc.hasBehavior(Type.ARRAY_LOAD)) { String componentType = TypeUtility.arrayComponentType(arrayref.getExpressionFullType()); methodStack.addOperand(new OperandInfo(arrayref.getExpression() + '[' + index.getExpression() + ']', componentType, opc)); } + // includes: ISTORE*, LSTORE*, FSTORE*, DSTORE*, ASTORE* else if(opc.hasBehavior(Type.VAR_STORE)) { int localVarIdx = numOperands > 0 ? loadOperands(numOperands, instr, i) : ((Number)opc.getConstantValue()).intValue(); - setVariable(methodStack, localVarIdx, methodStack.popOperand(), method, str); + try { + setVariable(methodStack, localVarIdx, methodStack.popOperand(), method, src); + } catch(Exception ex) { + throw ex; + } } else if(opc.hasBehavior(Type.ARRAY_STORE)) { var value = methodStack.popOperand(); var index = methodStack.popOperand(); var arrayref = methodStack.popOperand(); - str.append(arrayref.getExpression()).append('[').append(index.getExpression()).append(']').append(" = ").append(value.getExpression()).append(';'); + src.appendIndent().append(arrayref.getExpression()).append('[').append(index.getExpression()).append(']').append(" = ").append(value.getExpression()).append(';').append('\n'); } else if(opc == Opcodes.POP) { methodStack.popOperand(); @@ -225,7 +170,6 @@ else if(opc == Opcodes.POP2) { else if(opc.hasBehavior(Type.STACK_MANIPULATE)) { // TODO DUP instructions are referenced multiple times, so if the current expression is compound it needs to become a new temp variable if(opc == Opcodes.DUP) { - // TODO Correct ??? DUP (89, 0, enums(Type.STACK_MANIPULATE), null), // Duplicate the top operand stack value var op = methodStack.popOperand(); var opCopy = op.copy(); methodStack.addOperand(op); @@ -254,7 +198,7 @@ else if(opc == Opcodes.IINC) { int index = (operand >> 8) & 0xFF; var varref = methodStack.getVariable(index); int increment = operand & 0xFF; - str.append(varref.getName()).append(increment == 1 ? "++" : " += " + increment); + src.appendIndent().append(varref.getName()).append(increment == 1 ? "++" : " += " + increment).append('\n'); } else if(opc.hasBehavior(Type.TYPE_CONVERT)) { // TODO @@ -262,10 +206,11 @@ else if(opc.hasBehavior(Type.TYPE_CONVERT)) { else if(opc.hasBehavior(Type.COMPARE_NUMERIC)) { // TODO } - if(opc.hasBehavior(Type.CONDITION)) { + else if(opc.hasBehavior(Type.CONDITION)) { OperandInfo lhs = null; String rhs = null; + // extract the operands for the 'if' condition if(opc.hasBehavior(Type.POP1)) { lhs = methodStack.popOperand(); @@ -278,6 +223,7 @@ else if(opc.hasBehavior(Type.COMPARE_NUMERIC)) { rhs = "0"; } } + // all condition opcodes involve either one or two operands (as of Java 8) else { var val2 = methodStack.popOperand(); var val1 = methodStack.popOperand(); @@ -290,59 +236,27 @@ else if(opc.hasBehavior(Type.COMPARE_NUMERIC)) { } } - var condInfo = JumpConditionInfo.loadConditionFlow(opc, i, (short)operand, instr); + int loopIdx = CodeFlow.findContainsIfIndex(possibleLoops, i); - // standard if-statement - if((short)operand > 0) { - loops.add(condInfo); - conditionUnfinishedIdx = loops.size() - 1; - indent.indent(); - tmp.setLength(0); - tmp.append(lhs.getExpression()).append(' ').append(opc.getComparisonSymbolInverse()).append(' ').append(rhs); - str.append("if(").append(tmp).append(") {"); + // loop found + if(loopIdx >= 0) { + structuresInProgress.add(CodeStructureLoop.create(possibleLoops.get(loopIdx), lhs, rhs)); } - // loop with if_* at the end and jump backward + // if-statement else { - int loopIdx = JumpConditionInfo.findLoopStart(i, (short)operand, loops); - - if(loopIdx == -1) { - throw new IllegalStateException("if_* jumps backward but no loop start point found at " + i); + int condIdx = CodeFlow.findOpcIndex(possibleLoops, i); + if(condIdx >= 0) { + structuresInProgress.add(CodeStructureIf.create(possibleLoops.get(condIdx), lhs, rhs)); } - - if(conditionUnfinishedIdx == loopIdx) { - conditionUnfinishedIdx--; + else { + throw new IllegalArgumentException("could not find condition at index " + i); } - loops.get(loopIdx).finish(); - indent.dedent(); - tmp.setLength(0); - tmp.append(lhs.getExpression()).append(' ').append(opc.getComparisonSymbol()).append(' ').append(rhs); - str.append("} while(").append(tmp).append(");"); } } else if(opc == Opcodes.GOTO) { - int loopIdx = JumpConditionInfo.findLoopStart(i, (short)operand, loops); - int loopEndIdx = JumpConditionInfo.findLoopEnd(i, numOperands, (short)operand, loops); - - // standard if-else statement - if(loopIdx > -1) { - if(conditionUnfinishedIdx == loopIdx) { - conditionUnfinishedIdx--; - } - loops.get(loopIdx).finish(); - indent.dedent(); - str.append('}'); - } - else if(loopEndIdx > -1) { - loops.get(loopEndIdx).finish(); - indent.dedent(); - str.append('}').append('\n').append(indent).append("else "); - } - else { - loops.add(JumpConditionInfo.loadConditionFlow(opc, i, (short)operand, instr)); - conditionUnfinishedIdx = loops.size() - 1; - indent.indent(); - str.append("do {"); - } + // handled by Type.CONDITION loop and if structures above + // TODO what other actions is GOTO used for: + // labeled block breaks? } else if(opc == Opcodes.JSR || opc == Opcodes.GOTO_W || opc == Opcodes.JSR_W) { // TODO: JSR, GOTO_W, & JSR_W @@ -351,12 +265,12 @@ else if(opc == Opcodes.RET) { // TODO } else if(opc.hasBehavior(Type.RETURN)) { - str.append("return"); + src.appendIndent().append("return"); if(opc != Opcodes.RETURN) { var retVal = methodStack.popOperand(); - str.append(' ').append(retVal.getExpression()); + src.append(' ').append(retVal.getExpression()); } - str.append(';'); + src.append(';').append('\n'); } else if(opc == Opcodes.GETSTATIC) { var fieldRef = (CONSTANT_Fieldref)cls.getConstantPoolIndex(operand).getCpObject(); @@ -366,7 +280,7 @@ else if(opc == Opcodes.GETSTATIC) { var fieldClass = fieldRef.getClassType(); var fieldNameAndType = fieldRef.getNameAndType(); - var fieldStr = fieldClass.getName().getString() + "." + fieldNameAndType.getName().getString(); + var fieldStr = decodeBinaryClassName(fieldClass) + "." + fieldNameAndType.getName().getString(); methodStack.addOperand(new OperandInfo(fieldStr, fieldType, opc)); } @@ -376,7 +290,7 @@ else if(opc == Opcodes.PUTSTATIC) { var fieldClass = fieldRef.getClassType(); var fieldNt = fieldRef.getNameAndType(); - str.append(fieldClass.getName().getString()).append('.').append(fieldNt.getName().getString()).append(" = ").append(val.getExpression()); + src.appendIndent().append(decodeBinaryClassName(fieldClass)).append('.').append(fieldNt.getName().getString()).append(" = ").append(val.getExpression()).append('\n'); } else if(opc == Opcodes.GETFIELD) { var objRef = methodStack.popOperand(); @@ -395,22 +309,23 @@ else if(opc == Opcodes.PUTFIELD) { var fieldRef = (CONSTANT_Fieldref)cls.getConstantPoolIndex(operand).getCpObject(); var fieldNt = fieldRef.getNameAndType(); - str.append(objRef.getExpression()).append('.').append(fieldNt.getName().getString()).append(" = ").append(val.getExpression()); + src.appendIndent().append(objRef.getExpression()).append('.').append(fieldNt.getName().getString()).append(" = ").append(val.getExpression()).append('\n'); } else if(opc.hasBehavior(Type.CP_INDEX) && opc.hasBehavior(Type.POP_UNPREDICTABLE)) { + StringBuilder callExpr = null; if(opc == Opcodes.INVOKEVIRTUAL) { var methodRef = (CONSTANT_Methodref)cls.getConstantPoolIndex(operand).getCpObject(); extractMethodTypesAndExpressions(methodRef, tmpList, tmpList2, tmp, methodStack); String returnType = tmp.toString(); var objRef = methodStack.popOperand(); - methodCallExpression(methodRef, objRef.getExpression(), tmpList, tmpList2, returnType, methodStack, opc, tmp, str); + callExpr = methodCallExpression(methodRef, objRef.getExpression(), tmpList, tmpList2, returnType, methodStack, opc, tmp); } else if(opc == Opcodes.INVOKESTATIC) { var methodRef = (CONSTANT_Methodref)cls.getConstantPoolIndex(operand).getCpObject(); - var staticClass = methodRef.getClassType().getName().getString(); + var staticClass = methodRef.getClassType(); extractMethodTypesAndExpressions(methodRef, tmpList, tmpList2, tmp, methodStack); String returnType = tmp.toString(); - methodCallExpression(methodRef, staticClass, tmpList, tmpList2, returnType, methodStack, opc, tmp, str); + callExpr = methodCallExpression(methodRef, decodeBinaryClassName(staticClass), tmpList, tmpList2, returnType, methodStack, opc, tmp); } else if(opc == Opcodes.INVOKEDYNAMIC) { Opcodes nextOpc = i + (numOperands < 0 ? 0 : numOperands) + 1 < instrCount ? Opcodes.get(instr[i + (numOperands < 0 ? 0 : numOperands) + 1] & 0xFF) : null; @@ -424,11 +339,10 @@ else if(opc == Opcodes.INVOKEDYNAMIC) { var dynamicMethodName = dynamicRef.getNameAndType().getName().getString(); extractMethodTypesAndExpressions(dynamicRef, tmpList, tmpList2, tmp, methodStack); String returnType = tmp.toString(); - methodCallExpression(dynamicRef, dynamicMethodName, tmpList, tmpList2, returnType, methodStack, opc, tmp, str); + callExpr = methodCallExpression(dynamicRef, dynamicMethodName, tmpList, tmpList2, returnType, methodStack, opc, tmp); // TODO handle lambda decompiling or at least print out what the call looks like i += (numOperands < 0 ? 0 : numOperands); // skip next instruction which invokes the lambda numOperands = opc.getOperandCount(); - //instrUsed.set(i); // java.lang.invoke.CallSite res = java.lang.invoke.LambdaMetafactory.metafactory(MethodHandles.lookup(), "String", java.lang.invoke.MethodType, java.lang.invoke.MethodType, java.lang.invoke.MethodHandle, java.lang.invoke.MethodType); } else if(opc == Opcodes.INVOKESPECIAL) { @@ -436,7 +350,7 @@ else if(opc == Opcodes.INVOKESPECIAL) { extractMethodTypesAndExpressions(methodRef, tmpList, tmpList2, tmp, methodStack); String returnType = tmp.toString(); var objRef = methodStack.popOperand(); - methodCallExpression(methodRef, objRef.getExpression(), tmpList, tmpList2, returnType, methodStack, opc, tmp, str); + callExpr = methodCallExpression(methodRef, objRef.getExpression(), tmpList, tmpList2, returnType, methodStack, opc, tmp); } else if(opc == Opcodes.INVOKEINTERFACE) { // TODO @@ -444,10 +358,13 @@ else if(opc == Opcodes.INVOKEINTERFACE) { else { throw new IllegalArgumentException("unknown Type.POP_UNPREDICTABLE instruction " + opc); } + if(callExpr != null) { + src.appendIndent().append(callExpr).append('\n'); + } } else if(opc == Opcodes.NEW) { var cpNewType = (CONSTANT_Class)cls.getConstantPoolIndex(operand).getCpObject(); - methodStack.addOperand(new OperandInfo("new " + cpNewType.getName().getString().replace('/', '.'), cpNewType.getName().getString().replace('/', '.'), opc)); + methodStack.addOperand(new OperandInfo("new " + decodeBinaryClassName(cpNewType), decodeBinaryClassName(cpNewType), opc)); } else if(opc == Opcodes.NEWARRAY) { var countRef = methodStack.popOperand(); @@ -457,41 +374,46 @@ else if(opc == Opcodes.NEWARRAY) { else if(opc == Opcodes.ANEWARRAY) { var countRef = methodStack.popOperand(); var arrayType = (CONSTANT_Class)cls.getConstantPoolIndex(operand).getCpObject(); - var arrayTypeName = arrayType.getName().getString().replace('/', '.'); + var arrayTypeName = decodeBinaryClassName(arrayType); methodStack.addOperand(new OperandInfo("new " + arrayTypeName + '[' + countRef.getExpression() + ']', arrayTypeName + "[]", opc)); } else if(opc == Opcodes.ARRAYLENGTH) { var arrayref = methodStack.popOperand(); methodStack.addOperand(new OperandInfo(arrayref.getExpression() + ".length", "int", opc)); + } + else if(opc == Opcodes.ALOAD) { + } else if(opc == Opcodes.ATHROW) { var objectref = methodStack.popOperand(); - str.append("throw").append(' ').append(objectref.getExpression()).append(';'); + src.appendIndent().append("throw").append(' ').append(objectref.getExpression()).append(';').append('\n'); + } + else if(opc == Opcodes.MONITORENTER) { + var objectref = methodStack.popOperand(); + structuresInProgress.add(CodeStructureSynchronized.create(i, objectref)); + } + else if(opc == Opcodes.MONITOREXIT) { + // MONITOREXIT is handled by the above if-statement } /* TODO: CHECKCAST INSTANCEOF - MONITORENTER - MONITOREXIT MULTIANEWARRAY */ else if(opc.hasBehavior(Opcodes.Type.CP_INDEX) && operand < cls.getConstantPoolCount()) { - str.append(" // ").append(opc.displayName()).append(' ').append(cls.getCpIndex((short)operand).getCpObject().toShortString()).append(" [").append(operand).append(']'); + src.appendIndent().append(" // ").append(opc.displayName()).append(' ').append(cls.getCpIndex((short)operand).getCpObject().toShortString()).append(" [").append(operand).append(']').append('\n'); } else { - str.append(" // ").append(opc.displayName()).append(' ').append(operand).append(" 0x").append(Integer.toHexString(operand)); - } - str.append('\n'); - - if(curSwitch != null) { - if(i == curSwitch.switchEndIdx) { - indent.dedent(); - str.append(indent).append('}').append('\n'); - curSwitch = null; + src.appendIndent().append(" // ").append(opc.displayName()).append(' '); + if(numOperands > 0) { + src.append(operand).append(" 0x").append(Integer.toHexString(operand)); } + src.append('\n'); } + runEmits(structuresInProgress, opc, instr, i, operand, src); + i += (numOperands < 0 ? 0 : numOperands); // next code flow if current one is finished @@ -514,24 +436,24 @@ else if(opc.hasBehavior(Opcodes.Type.CP_INDEX) && operand < cls.getConstantPoolC } } - var tab = indent; - str.append("\n").append(tab); + src.append("\n"); - var exception_table = code.getExceptionTable(); - str.append("// exceptions: ").append(exception_table.length).append(" ["); - if(exception_table.length > 0) { str.append("\n").append(tab); } + // TODO should finish processing any unfinished structures + + src.appendIndent().append("// exceptions: ").append(exception_table.length).append(" ["); + if(exception_table.length > 0) { src.append("\n").appendIndent(); } for(int j = 0; j < exception_table.length - 1; j++) { - str.append("// ").append(exception_table[j]).append(",\n").append(tab); + src.append("// ").append(exception_table[j]).append(",\n").appendIndent(); } - if(exception_table.length > 0) { str.append("// ").append(exception_table[exception_table.length - 1]); } + if(exception_table.length > 0) { src.append("// ").append(exception_table[exception_table.length - 1]); src.append('\n'); } var attributes = code.getAttributes(); - str.append("// attributes: ").append(attributes.length).append(" ["); - if(attributes.length > 0) { str.append("\n").append(tab); } + src.appendIndent().append("// attributes: ").append(attributes.length).append(" ["); + if(attributes.length > 0) { src.append("\n").appendIndent(); } for(int j = 0; j < attributes.length - 1; j++) { - str.append("// ").append(attributes[j]).append(",\n").append(tab); + src.append("// ").append(attributes[j]).append(",\n").appendIndent(); } - if(attributes.length > 0) { str.append("// ").append(attributes[attributes.length - 1]); } + if(attributes.length > 0) { src.append("// ").append(attributes[attributes.length - 1]); } } @@ -552,7 +474,16 @@ private static int extractMethodTypesAndExpressions(CONSTANT_Methodref methodRef } - private static void methodCallExpression(CONSTANT_Methodref methodRef, String callObjName, List parameterTypes, List parameterExpressions, String returnType, MethodStack methodStack, Opcodes opc, StringBuilder tmp, StringBuilder dst) { + private static StringBuilder methodCallExpression( + CONSTANT_Methodref methodRef, + String callObjName, + List parameterTypes, + List parameterExpressions, + String returnType, + MethodStack methodStack, + Opcodes opc, + StringBuilder tmp + ) { int parameterCount = parameterExpressions.size(); tmp.setLength(0); var methodName = methodRef.getNameAndType().getName().getString(); @@ -572,16 +503,17 @@ private static void methodCallExpression(CONSTANT_Methodref methodRef, String ca if(!"void".equals(returnType)) { methodStack.addOperand(new OperandInfo(tmp.toString(), returnType, opc)); + return null; } else { - dst.append(tmp); + return tmp; } } - private static void setVariable(MethodStack methodStack, int variableIdx, OperandInfo operand, Method_Info method, StringBuilder dst) { + private static void setVariable(MethodStack methodStack, int variableIdx, OperandInfo operand, Method_Info method, StringBuilderIndent dst) { VariableInfo varInfo = methodStack.getVariableCount() > variableIdx ? methodStack.getVariable(variableIdx) : methodStack.setVariable(variableIdx, operand.getExpressionFullType(), method); - dst.append(varInfo.getName()).append(" = ").append(operand.getExpression()).append(';'); + dst.appendIndent().append(varInfo.getName()).append(" = ").append(operand.getExpression()).append(';').append('\n'); } diff --git a/src/twg2/jbcm/toSource/Indent.java b/src/twg2/jbcm/toSource/Indent.java index 9ec1ac8..ec7ca9d 100644 --- a/src/twg2/jbcm/toSource/Indent.java +++ b/src/twg2/jbcm/toSource/Indent.java @@ -6,71 +6,113 @@ * @author TeamworkGuy2 * @since 2020-12-05 */ -public class Indent { - protected String indentMark; - protected ArrayList indentCache; - protected int indent; +public interface Indent { + public void indent(); - public Indent(String indentMark) { - this.indentMark = indentMark; - this.indentCache = new ArrayList<>(); - this.indentCache.add(""); // for indent = 0 - this.indent = 0; - } + public void dedent(); + + public int getCount(); + + public String getIndent(); + + public StringBuilder writeTo(StringBuilder src); + + /** + * @return the indent if {@code dedent()} was called + */ + public String toDedent(); + + /** + * @return the indent if {@code indent()} was called + */ + public String toIndent(); + @Override + public String toString(); + + + /** + * @author TeamworkGuy2 + * @since 2022-10-01 + */ + public static class Impl implements Indent { + protected String indentMark; + protected ArrayList indentCache; + protected int indent; - public void indent() { - this.indent++; - int cacheSize = this.indentCache.size(); - if(cacheSize <= this.indent) { - var indent = cacheSize == 0 ? indentMark : this.indentCache.get(cacheSize - 1) + indentMark; - this.indentCache.add(indent); + + public Impl(String indentMark) { + this.indentMark = indentMark; + this.indentCache = new ArrayList<>(); + this.indentCache.add(""); // for indent = 0 + this.indent = 0; } - } - public void dedent() { - this.indent--; - } + @Override + public void indent() { + this.indent++; + int cacheSize = this.indentCache.size(); + if(cacheSize <= this.indent) { + var indent = cacheSize == 0 ? indentMark : this.indentCache.get(cacheSize - 1) + indentMark; + this.indentCache.add(indent); + } + } - public String getIndent() { - return this.indentCache.get(this.indent); - } + @Override + public void dedent() { + this.indent--; + } - public StringBuilder writeTo(StringBuilder src) { - src.append(this.indentCache.get(this.indent)); + @Override + public int getCount() { + return this.indent; + } - return src; - } + @Override + public String getIndent() { + return this.indentCache.get(this.indent); + } - @Override - public String toString() { - return getIndent(); - } + @Override + public StringBuilder writeTo(StringBuilder src) { + src.append(this.indentCache.get(this.indent)); - /** - * @return the indent if {@code #dedent()} was called - */ - public String toDedent() { - return this.indentCache.get(this.indent - 1); - } + return src; + } - /** - * @return the indent if {@code #indent()} was called - */ - public String toIndent() { - int cacheSize = this.indentCache.size(); - if(cacheSize <= this.indent + 1) { - var indent = cacheSize == 0 ? indentMark : this.indentCache.get(cacheSize - 1) + indentMark; - this.indentCache.add(indent); + @Override + public String toString() { + return getIndent(); } - return this.indentCache.get(this.indent + 1); - } + + /** + * @return the indent if {@code dedent()} was called + */ + @Override + public String toDedent() { + return this.indentCache.get(this.indent - 1); + } + + + /** + * @return the indent if {@code indent()} was called + */ + @Override + public String toIndent() { + int cacheSize = this.indentCache.size(); + if(cacheSize <= this.indent + 1) { + var indent = cacheSize == 0 ? indentMark : this.indentCache.get(cacheSize - 1) + indentMark; + this.indentCache.add(indent); + } + return this.indentCache.get(this.indent + 1); + } + } } diff --git a/src/twg2/jbcm/toSource/SourceWriter.java b/src/twg2/jbcm/toSource/SourceWriter.java index e832865..6ff4b09 100644 --- a/src/twg2/jbcm/toSource/SourceWriter.java +++ b/src/twg2/jbcm/toSource/SourceWriter.java @@ -17,7 +17,7 @@ public class SourceWriter { public SourceWriter(String indentMark, String newln) { - this.indent = new Indent(indentMark); + this.indent = new Indent.Impl(indentMark); this.newln = newln; this.src = new StringBuilder(); } @@ -137,7 +137,7 @@ public SourceWriter closeParenthesis() { public SourceWriter writeClassCode(ClassFile cls, Method_Info method, MethodStack methodStack) { - method.getCode().toClassString(this.getIndent().getIndent(), this.src); + method.getCode().toClassCodeString(this.getIndent().getIndent(), this.src); return this; } @@ -227,7 +227,7 @@ public String accessModifiersField(int access) { sb.append("transient "); } - return sb.substring(0, sb.length() - 1); + return sb.substring(0, sb.length() > 0 ? sb.length() - 1 : 0); } diff --git a/src/twg2/jbcm/toSource/StringBuilderIndent.java b/src/twg2/jbcm/toSource/StringBuilderIndent.java new file mode 100644 index 0000000..3c24e93 --- /dev/null +++ b/src/twg2/jbcm/toSource/StringBuilderIndent.java @@ -0,0 +1,375 @@ +package twg2.jbcm.toSource; + +public class StringBuilderIndent implements CharSequence, Indent { + public final StringBuilder sb; + public final Indent indent; + + public StringBuilderIndent(StringBuilder strBuilder, Indent indent) { + sb = strBuilder; + this.indent = indent; + } + + /** + * @see StringBuilder#StringBuilder(int) + */ + public StringBuilderIndent(int capacity, Indent indent) { + sb = new StringBuilder(capacity); + this.indent = indent; + } + + /** + * @see StringBuilder#StringBuilder(String) + */ + public StringBuilderIndent(String str, Indent indent) { + this(str.length() + 16, indent); + append(str); + } + + /** + * @see StringBuilder#StringBuilder(CharSequence) + */ + public StringBuilderIndent(CharSequence seq, Indent indent) { + this(seq.length() + 16, indent); + append(seq); + } + + /** + * @see StringBuilder#append(Object) + */ + public StringBuilderIndent append(Object obj) { + return append(String.valueOf(obj)); + } + + /** + * @see StringBuilder#append(String) + */ + public StringBuilderIndent append(String str) { + sb.append(str); + return this; + } + + /** + * @see StringBuilder#append(StringBuffer) + */ + public StringBuilderIndent append(StringBuffer sb) { + sb.append(sb); + return this; + } + + /** + * @see StringBuilder#append(CharSequence) + */ + public StringBuilderIndent append(CharSequence s) { + sb.append(s); + return this; + } + + /** + * @see StringBuilder#append(CharSequence, int, int) + */ + public StringBuilderIndent append(CharSequence s, int start, int end) { + sb.append(s, start, end); + return this; + } + + /** + * @see StringBuilder#append(char[]) + */ + public StringBuilderIndent append(char[] str) { + sb.append(str); + return this; + } + + /** + * @see StringBuilder#append(char[], int, int) + */ + public StringBuilderIndent append(char[] str, int offset, int len) { + sb.append(str, offset, len); + return this; + } + + /** + * @see StringBuilder#append(boolean) + */ + public StringBuilderIndent append(boolean b) { + sb.append(b); + return this; + } + + /** + * @see StringBuilder#append(char) + */ + public StringBuilderIndent append(char c) { + sb.append(c); + return this; + } + + /** + * @see StringBuilder#append(int) + */ + public StringBuilderIndent append(int i) { + sb.append(i); + return this; + } + + /** + * @see StringBuilder#append(long) + */ + public StringBuilderIndent append(long lng) { + sb.append(lng); + return this; + } + + /** + * @see StringBuilder#append(float) + */ + public StringBuilderIndent append(float f) { + sb.append(f); + return this; + } + + /** + * @see StringBuilder#append(double) + */ + public StringBuilderIndent append(double d) { + sb.append(d); + return this; + } + + /** + * @see StringBuilder#appendCodePoint(int) + */ + public StringBuilderIndent appendCodePoint(int codePoint) { + sb.appendCodePoint(codePoint); + return this; + } + + /** + * @see StringBuilder#delete(int, int) + */ + public StringBuilderIndent delete(int start, int end) { + sb.delete(start, end); + return this; + } + + /** + * @see StringBuilder#deleteCharAt(int) + */ + public StringBuilderIndent deleteCharAt(int index) { + sb.deleteCharAt(index); + return this; + } + + /** + * @see StringBuilder#replace(int, int, String) + */ + public StringBuilderIndent replace(int start, int end, String str) { + sb.replace(start, end, str); + return this; + } + + /** + * @see StringBuilder#insert(int, char[], int, int) + */ + public StringBuilderIndent insert(int index, char[] str, int offset, int len) { + sb.insert(index, str, offset, len); + return this; + } + + /** + * @see StringBuilder#insert(int, Object) + */ + public StringBuilderIndent insert(int offset, Object obj) { + sb.insert(offset, obj); + return this; + } + + /** + * @see StringBuilder#insert(int, String) + */ + public StringBuilderIndent insert(int offset, String str) { + sb.insert(offset, str); + return this; + } + + /** + * @see StringBuilder#insert(int, char[]) + */ + public StringBuilderIndent insert(int offset, char[] str) { + sb.insert(offset, str); + return this; + } + + /** + * @see StringBuilder#insert(int, CharSequence) + */ + public StringBuilderIndent insert(int dstOffset, CharSequence s) { + sb.insert(dstOffset, s); + return this; + } + + /** + * @see StringBuilder#insert(int, CharSequence, int, int) + */ + public StringBuilderIndent insert(int dstOffset, CharSequence s, int start, int end) + { + sb.insert(dstOffset, s, start, end); + return this; + } + + /** + * @see StringBuilder#insert(int, boolean) + */ + public StringBuilderIndent insert(int offset, boolean b) { + sb.insert(offset, b); + return this; + } + + /** + * @see StringBuilder#insert(int, char) + */ + public StringBuilderIndent insert(int offset, char c) { + sb.insert(offset, c); + return this; + } + + /** + * @see StringBuilder#insert(int, int) + */ + public StringBuilderIndent insert(int offset, int i) { + sb.insert(offset, i); + return this; + } + + /** + * @see StringBuilder#insert(int, long) + */ + public StringBuilderIndent insert(int offset, long l) { + sb.insert(offset, l); + return this; + } + + /** + * @see StringBuilder#insert(int, float) + */ + public StringBuilderIndent insert(int offset, float f) { + sb.insert(offset, f); + return this; + } + + /** + * @see StringBuilder#insert(int, double) + */ + public StringBuilderIndent insert(int offset, double d) { + sb.insert(offset, d); + return this; + } + + /** + * @see StringBuilder#indexOf(String) + */ + public int indexOf(String str) { + return sb.indexOf(str); + } + + /** + * @see StringBuilder#indexOf(String, int) + */ + public int indexOf(String str, int fromIndex) { + return sb.indexOf(str, fromIndex); + } + + /** + * @see StringBuilder#lastIndexOf(String) + */ + public int lastIndexOf(String str) { + return sb.lastIndexOf(str); + } + + /** + * @see StringBuilder#lastIndexOf(String, int) + */ + public int lastIndexOf(String str, int fromIndex) { + return sb.lastIndexOf(str, fromIndex); + } + + /** + * @see StringBuilder#reverse() + */ + public StringBuilderIndent reverse() { + sb.reverse(); + return this; + } + + /** + * @see StringBuilder#length() + */ + @Override + public int length() { + return sb.length(); + } + + /** + * @see StringBuilder#charAt(int) + */ + @Override + public char charAt(int index) { + return sb.charAt(index); + } + + /** + * @see StringBuilder#subSequence(int, int) + */ + @Override + public CharSequence subSequence(int start, int end) { + return sb.subSequence(start, end); + } + + @Override + public String toString() { + return sb.toString(); + } + + + // implement Indent + + @Override + public void indent() { + indent.indent(); + } + + @Override + public void dedent() { + indent.dedent(); + } + + @Override + public int getCount() { + return indent.getCount(); + } + + @Override + public String getIndent() { + return indent.getIndent(); + } + + @Override + public StringBuilder writeTo(StringBuilder src) { + return indent.writeTo(src); + } + + @Override + public String toDedent() { + return indent.toDedent(); + } + + @Override + public String toIndent() { + return indent.toIndent(); + } + + public StringBuilderIndent appendIndent() { + this.append(this.indent); + return this; + } +} \ No newline at end of file diff --git a/src/twg2/jbcm/toSource/SwitchFlow.java b/src/twg2/jbcm/toSource/SwitchFlow.java index f235a9c..649de9a 100644 --- a/src/twg2/jbcm/toSource/SwitchFlow.java +++ b/src/twg2/jbcm/toSource/SwitchFlow.java @@ -90,9 +90,7 @@ public static int loadLookupSwitch(int i, byte[] instr, List dstCase */ public static SwitchCase loadSwitchCase(int caseMatch, int targetIdx, byte[] instr) { // analyze code flow path - var caseFlowPath = new IntArrayList(); - caseFlowPath.add(~targetIdx); - CodeFlow.getFlowPaths(targetIdx, instr, caseFlowPath); + var caseFlowPath = CodeFlow.getFlowPaths(instr, targetIdx); // potential end index (probably redundant once code flow is working) var maxCodeFlowIndex = CodeFlow.maxIndex(caseFlowPath); @@ -175,7 +173,7 @@ public static boolean isSwitchSimplePacked(List switchCases, SwitchC return false; } prevEnd = caseObj.codeFlowMaxIndex; - var endOpc = Opcodes.get(instr[prevEnd] & 0xFF); + var endOpc = Opcodes.get(instr[prevEnd]); var operands = endOpc.getOperandCount(); prevOperands = operands; } diff --git a/src/twg2/jbcm/toSource/structures/CodeEmitter.java b/src/twg2/jbcm/toSource/structures/CodeEmitter.java new file mode 100644 index 0000000..7296c82 --- /dev/null +++ b/src/twg2/jbcm/toSource/structures/CodeEmitter.java @@ -0,0 +1,39 @@ +package twg2.jbcm.toSource.structures; + +import java.util.ArrayList; + +import twg2.jbcm.Opcodes; +import twg2.jbcm.toSource.StringBuilderIndent; + +/** + * @author TeamworkGuy2 + * @since 2022-10-01 + */ +public interface CodeEmitter { + + /** Accepts an instruction, processes it, potentially outputs source code, + * and returns whether this emitter will accept more code. + * @param opc the op-code of the current instruction + * @param instr code method/block that the {@code opc} comes from + * @param index index into {@code instr} where {@code opc} is located + * @param operand the operand data of the current {@code opc} instruction + * @param toSourceDst destination to write generated source code to + * @return the emitter response type + */ + public EmitterResponse emitOpcode(Opcodes opc, byte[] instr, int index, int operand, StringBuilderIndent toSourceDst); + + + public static void runEmits(ArrayList codeStructures, Opcodes opc, byte[] instr, int idx, int operand, StringBuilderIndent sourceCodeDst) { + // loop backward so that nested code structures can process first + for(int i = codeStructures.size() - 1; i >= 0; i--) { + var res = codeStructures.get(i).emitOpcode(opc, instr, idx, operand, sourceCodeDst); + if(res == EmitterResponse.DEREGISTER) { + codeStructures.remove(i); + } + else if(res == EmitterResponse.CONSUMED) { + break; + } + } + } + +} diff --git a/src/twg2/jbcm/toSource/structures/CodeStructureIf.java b/src/twg2/jbcm/toSource/structures/CodeStructureIf.java new file mode 100644 index 0000000..5ad4536 --- /dev/null +++ b/src/twg2/jbcm/toSource/structures/CodeStructureIf.java @@ -0,0 +1,72 @@ +package twg2.jbcm.toSource.structures; + +import twg2.jbcm.Opcodes; +import twg2.jbcm.ir.JumpConditionInfo; +import twg2.jbcm.ir.JumpConditionInfo.UsageHint; +import twg2.jbcm.toSource.StringBuilderIndent; +import twg2.jbcm.ir.OperandInfo; + +/** + * @author TeamworkGuy2 + * @since 2022-10-01 + */ +public class CodeStructureIf implements CodeEmitter { + final JumpConditionInfo condition; + final int endTargetIndex; + final OperandInfo lhs; + final String rhs; + + + public CodeStructureIf(JumpConditionInfo condition, int endTargetIndex, OperandInfo lhs, String rhs) { + this.condition = condition; + this.endTargetIndex = endTargetIndex; + this.lhs = lhs; + this.rhs = rhs; + } + + + @Override + public EmitterResponse emitOpcode(Opcodes opc, byte[] instr, int idx, int operand, StringBuilderIndent src) { + // end if-else blocks based on ending instruction index tracked when jump instructions (IF_* and GOTO) are first encountered + if(idx >= endTargetIndex) { + // if-statement (loops start with GOTO, handled elsewhere) + if(condition.getOpcode() != Opcodes.GOTO) { + src.dedent(); + try { + src.appendIndent().append('}').append(" // end IF-" + condition).append('\n'); + } catch(Exception ex) { + throw ex; + } + } + return EmitterResponse.DEREGISTER; + } + + if(idx == condition.opcIdx) { + String comparisonSymbol = opc.getComparisonSymbol(); + if(condition.usageHint == UsageHint.IF_WITHIN_LOOP_AND_WITH_LOOP_ENDS && condition.targetOffset < 0) { + comparisonSymbol = opc.getComparisonSymbolInverse(); + } + src.appendIndent().append("if(") + .append(lhs.getExpression()).append(' ').append(comparisonSymbol).append(' ').append(rhs) + .append(") {") + .append('\n'); + src.indent(); + } + return EmitterResponse.CONTINUE; + } + + + public static CodeStructureIf create(JumpConditionInfo condition, OperandInfo lhs, String rhs) { + int endTargetIndex = condition.getTargetIndex(); + if(condition.usageHint == UsageHint.IF_WITHIN_LOOP_AND_WITH_LOOP_ENDS && condition.targetOffset < 0) { + endTargetIndex = condition.loopEndIndexForIf; + } + + return new CodeStructureIf( + condition, + endTargetIndex, + lhs, + rhs + ); + } +} diff --git a/src/twg2/jbcm/toSource/structures/CodeStructureLoop.java b/src/twg2/jbcm/toSource/structures/CodeStructureLoop.java new file mode 100644 index 0000000..be5f7f9 --- /dev/null +++ b/src/twg2/jbcm/toSource/structures/CodeStructureLoop.java @@ -0,0 +1,64 @@ +package twg2.jbcm.toSource.structures; + +import twg2.jbcm.Opcodes; +import twg2.jbcm.ir.JumpConditionInfo; +import twg2.jbcm.ir.OperandInfo; +import twg2.jbcm.toSource.StringBuilderIndent; + +/** + * @author TeamworkGuy2 + * @since 2022-10-01 + */ +public class CodeStructureLoop implements CodeEmitter { + final JumpConditionInfo condition; + final int startIndex; + final OperandInfo lhs; + final String rhs; + + + public CodeStructureLoop(JumpConditionInfo condition, int startIndex, OperandInfo lhs, String rhs) { + this.condition = condition; + this.startIndex = startIndex; + this.lhs = lhs; + this.rhs = rhs; + } + + + @Override + public EmitterResponse emitOpcode(Opcodes opc, byte[] instr, int idx, int operand, StringBuilderIndent src) { + // end loops based on ending instruction index tracked when jump instructions (IF_* and GOTO) are first encountered + if(idx >= condition.getUpperIndex()) { + src.dedent(); + try { + src.appendIndent().append('}').append(" // end loop-" + condition).append('\n'); + } catch(Exception ex) { + throw ex; + } + // done - deregister this emitter + return EmitterResponse.DEREGISTER; + } + + if(idx == startIndex) { + // if-statement (loops start with GOTO, handled elsewhere) + try { + src.appendIndent().append("while(") + .append(lhs.getExpression()).append(' ').append(opc.getComparisonSymbolInverse()).append(' ').append(rhs) + .append(") {") + .append('\n'); + src.indent(); + } catch(Exception ex) { + throw ex; + } + } + return EmitterResponse.CONTINUE; + } + + + public static CodeStructureLoop create(JumpConditionInfo condition, OperandInfo lhs, String rhs) { + int startIndex = condition.getTargetIndex(); + if(condition.potentialIfIndex >= 0) { + startIndex = condition.potentialIfIndex; + } + return new CodeStructureLoop(condition, startIndex, lhs, rhs); + } +} diff --git a/src/twg2/jbcm/toSource/structures/CodeStructureSwitch.java b/src/twg2/jbcm/toSource/structures/CodeStructureSwitch.java new file mode 100644 index 0000000..d0485d7 --- /dev/null +++ b/src/twg2/jbcm/toSource/structures/CodeStructureSwitch.java @@ -0,0 +1,79 @@ +package twg2.jbcm.toSource.structures; + +import twg2.jbcm.Opcodes; +import twg2.jbcm.ir.OperandInfo; +import twg2.jbcm.ir.Switch; +import twg2.jbcm.toSource.StringBuilderIndent; +import twg2.jbcm.toSource.SwitchFlow; + +/** + * @author TeamworkGuy2 + * @since 2022-10-01 + */ +public class CodeStructureSwitch implements CodeEmitter { + Switch curSwitch = null; + + + @Override + public EmitterResponse emitOpcode(Opcodes opc, byte[] instr, int idx, int operand, StringBuilderIndent src) { + // end switch + if(idx == curSwitch.switchEndIdx) { + src.dedent(); + src.appendIndent().append('}').append('\n'); + return EmitterResponse.DEREGISTER; + } + + // switch cases + if(curSwitch.switchDefault.caseTarget == idx) { + curSwitch.finish(curSwitch.switchDefault); + src.append("default: ").append("// offset ").append(curSwitch.switchDefault.caseTarget); + } + + var switchCaseIdx = SwitchFlow.findSwitchCase(idx, curSwitch.switchCases, 0); + while(switchCaseIdx > -1) { + var caseObj = curSwitch.switchCases.get(switchCaseIdx); + caseObj.finish(); + src.append(src.indent.toDedent()).append("case ").append(caseObj.caseMatch).append(": ").append("// offset ").append(caseObj.caseTarget).append('\n'); + switchCaseIdx = SwitchFlow.findSwitchCase(idx, curSwitch.switchCases, switchCaseIdx + 1); + } + + return EmitterResponse.CONTINUE; + } + + + public static CodeStructureSwitch create(Opcodes opc, byte[] instr, int idx, OperandInfo switchKey, StringBuilderIndent src) { + var inst = new CodeStructureSwitch(); + + if(opc == Opcodes.TABLESWITCH) { + inst.curSwitch = Switch.loadTableSwitch(idx, instr); + } + else if(opc == Opcodes.LOOKUPSWITCH) { + inst.curSwitch = Switch.loadLookupSwitch(idx, instr); + } + //int origI = idx; + idx += inst.curSwitch.switchInstSize; + src.indent(); + src.append("switch(" + switchKey.getExpression() + ") {"); + + //var instrFlow = last(instrFlows); + //instrFlow.add(curSwitch.switchEndIdx > -1 ? ~curSwitch.switchEndIdx : ~i); // TODO technically we wouldn't want to restart at the current index + // need some unit tests to check different types of switches + // can a switch with fall through cases still have a common end index, 'break' instructions should lead to a common end index, what if the default throws, etc? + //instrFlow.add(endIdx); + + //SwitchFlow.loadCasesToFlow(curSwitch.switchCases, curSwitch.switchDefault, instrFlows); + + // TODO debugging + //str.append(" // common end: " + commonEndIdx); + //for(var caseObj : switchCases) { + // str.append('\n').append(indentation).append(indentMark).append("// case " + caseObj.caseMatch + ": [" + caseObj.caseTarget + ", " + caseObj.caseEndIdx + "]" + (caseObj.caseEndTarget > 0 ? " jump to " + caseObj.caseEndTarget : "")); + // System.out.println("case " + caseObj.caseMatch + ": " + CodeFlow.flowPathToString(instr, caseObj.getCodeFlow())); + //} + //str.append('\n').append(indentation).append(indentMark).append("// default: [" + switchDefault.get().caseTarget + ", " + switchDefault.get().caseEndIdx + "]" + (switchDefault.get().caseEndTarget > 0 ? " jump to " + switchDefault.get().caseEndTarget : "")); + + //if(curSwitch.switchEndIdx == -1) { + // throw new IllegalStateException(opc + " switch statement common end index could not be found, cannot decompile"); + //} + return inst; + } +} diff --git a/src/twg2/jbcm/toSource/structures/CodeStructureSynchronized.java b/src/twg2/jbcm/toSource/structures/CodeStructureSynchronized.java new file mode 100644 index 0000000..f81dd0a --- /dev/null +++ b/src/twg2/jbcm/toSource/structures/CodeStructureSynchronized.java @@ -0,0 +1,45 @@ +package twg2.jbcm.toSource.structures; + +import twg2.jbcm.Opcodes; +import twg2.jbcm.ir.OperandInfo; +import twg2.jbcm.toSource.StringBuilderIndent; + +/** A synchronized(...) { ... } block source code emitter. + * @author TeamworkGuy2 + * @since 2022-10-09 + */ +public class CodeStructureSynchronized implements CodeEmitter { + final int monitorEnterIndex; + final OperandInfo synchronizeObj; + + + public CodeStructureSynchronized(int monitorEnterIndex, OperandInfo operand) { + this.monitorEnterIndex = monitorEnterIndex; + this.synchronizeObj = operand; + } + + + @Override + public EmitterResponse emitOpcode(Opcodes opc, byte[] instr, int idx, int operand, StringBuilderIndent src) { + // end synchronized block + if(opc == Opcodes.MONITOREXIT) { + src.dedent(); + src.appendIndent().append('}').append(" // end synchronized of (" + synchronizeObj.getExpression() + ")").append('\n'); + return EmitterResponse.DEREGISTER; + } + + if(idx == monitorEnterIndex) { + src.appendIndent().append("synchronized(") + .append(synchronizeObj.getExpression()) + .append(") {") + .append('\n'); + src.indent(); + } + return EmitterResponse.CONTINUE; + } + + + public static CodeStructureSynchronized create(int monitorEnterIndex, OperandInfo operand) { + return new CodeStructureSynchronized(monitorEnterIndex, operand); + } +} diff --git a/src/twg2/jbcm/toSource/structures/CodeStructureTryCatchFinally.java b/src/twg2/jbcm/toSource/structures/CodeStructureTryCatchFinally.java new file mode 100644 index 0000000..54dcee6 --- /dev/null +++ b/src/twg2/jbcm/toSource/structures/CodeStructureTryCatchFinally.java @@ -0,0 +1,120 @@ +package twg2.jbcm.toSource.structures; + +import static twg2.jbcm.CodeUtility.loadOperands; + +import twg2.jbcm.CodeFlow; +import twg2.jbcm.Opcodes; +import twg2.jbcm.classFormat.attributes.Code.ExceptionPoint; +import twg2.jbcm.ir.MethodStack; +import twg2.jbcm.ir.OperandInfo; +import twg2.jbcm.modify.TypeUtility; +import twg2.jbcm.toSource.StringBuilderIndent; + +/** + * @author TeamworkGuy2 + * @since 2022-10-09 + */ +public class CodeStructureTryCatchFinally implements CodeEmitter { + final ExceptionPoint exceptionAttr; + final String exceptionVariableName; + final MethodStack stack; + /** 'catch' blocks are generally preceded by an unconditional 'GOTO' jump to skip the catch code in the case of no exception */ + final int jumpIdxAroundHandler; + /** whether the exception point 'handler' is an ALOAD* instruction */ + final boolean startsWithAload; + /** the instruction immediately before 'start' is MONITORENTER */ + final boolean monitorEnterBeforeStart; + /** the last instruction before 'end' is MONITOREXIT */ + final boolean monitorExitAtEnd; + /** whether the exception point has a null 'catch_type' (i.e. is a 'finally { }' block) */ + final boolean isFinally; + + + public CodeStructureTryCatchFinally( + ExceptionPoint exceptionAttr, + String exceptionVariableName, + int jumpIdxAroundHandler, + boolean startsWithAload, + boolean monitorEnterBeforeStart, + boolean monitorExitAtEnd, + boolean isFinally, + MethodStack stack) { + this.exceptionAttr = exceptionAttr; + this.exceptionVariableName = exceptionVariableName; + this.stack = stack; + this.jumpIdxAroundHandler = jumpIdxAroundHandler; + this.startsWithAload = startsWithAload; + this.monitorEnterBeforeStart = monitorEnterBeforeStart; + this.monitorExitAtEnd = monitorExitAtEnd; + this.isFinally = isFinally; + } + + + @Override + public EmitterResponse emitOpcode(Opcodes opc, byte[] instr, int idx, int operand, StringBuilderIndent src) { + // end loops based on ending instruction index tracked when jump instructions (IF_* and GOTO) are first encountered + if(idx == exceptionAttr.getEndPc()) { + // TODO need to push exception onto the stack for handler + var catchType = exceptionAttr.getCatchType(); + String exceptionType = (catchType != null && catchType.getIndex() > 0) + ? TypeUtility.decodeBinaryClassName(catchType.getCpObject()) + : "Throwable"; + + src.append(src.indent.toDedent()).append('}').append(" catch(") + .append(exceptionType).append(' ').append(exceptionVariableName) + .append(") {").append('\n'); + + // push the exception onto the stack like the JVM will during runtime (I think... https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.3) + stack.addOperand(new OperandInfo(exceptionVariableName, exceptionType, opc)); + + if(jumpIdxAroundHandler < 0) { + // done - deregister this emitter + return EmitterResponse.DEREGISTER; + } + } + + if(idx == jumpIdxAroundHandler) { + src.dedent(); + src.appendIndent().append('}').append(" // end try-catch of (" + exceptionVariableName + ")").append('\n'); + // done - deregister this emitter + return EmitterResponse.DEREGISTER; + } + + if(idx == exceptionAttr.getStartPc()) { + // if-statement (loops start with GOTO, handled elsewhere) + try { + src.appendIndent().append("try {").append('\n'); + src.indent(); + } catch(Exception ex) { + throw ex; + } + } + return EmitterResponse.CONTINUE; + } + + + public static CodeStructureTryCatchFinally create(byte[] instr, ExceptionPoint exceptionAttr, String exceptionVariableName, MethodStack stack) { + int firstOpcodeIdxBeforeExBlock = CodeFlow.findLastOpcodeIndex(instr, 0, exceptionAttr.getStartPc()); + boolean monitorEnterBeforeStart = firstOpcodeIdxBeforeExBlock >= 0 && Opcodes.get(instr[firstOpcodeIdxBeforeExBlock]) == Opcodes.MONITORENTER; + + int firstOpcodeIdxBeforeHandler = CodeFlow.findLastOpcodeIndex(instr, 0, exceptionAttr.getHandlerPc()); + int gotoIdxBeforeStart = -1; + if(firstOpcodeIdxBeforeHandler >= 0 && Opcodes.get(instr[firstOpcodeIdxBeforeHandler]) == Opcodes.GOTO) { + int numOperands = Opcodes.GOTO.getOperandCount(); + gotoIdxBeforeStart = firstOpcodeIdxBeforeHandler + loadOperands(numOperands, instr, firstOpcodeIdxBeforeHandler); + } + boolean startsWithAload = Opcodes.get(instr[exceptionAttr.getHandlerPc()]).hasBehavior(Opcodes.Type.VAR_LOAD); + int lastExBlockOpcodeIdx = CodeFlow.findLastOpcodeIndex(instr, exceptionAttr.getStartPc(), exceptionAttr.getEndPc()); + boolean monitorExitAtEnd = lastExBlockOpcodeIdx >= 0 && Opcodes.get(instr[lastExBlockOpcodeIdx]) == Opcodes.MONITOREXIT; + boolean isFinally = exceptionAttr.getCatchType() == null || exceptionAttr.getCatchType().getIndex() == 0; + + // skip generating a try-catch for a 'synchronized (...) { }' block since this is synthetic, automatically generated when the source code is compiled + if(monitorEnterBeforeStart && monitorExitAtEnd) { + return null; + } + else { + return new CodeStructureTryCatchFinally(exceptionAttr, exceptionVariableName, gotoIdxBeforeStart, startsWithAload, monitorEnterBeforeStart, monitorExitAtEnd, isFinally, stack); + } + } + +} diff --git a/src/twg2/jbcm/toSource/structures/EmitterResponse.java b/src/twg2/jbcm/toSource/structures/EmitterResponse.java new file mode 100644 index 0000000..8aef7b7 --- /dev/null +++ b/src/twg2/jbcm/toSource/structures/EmitterResponse.java @@ -0,0 +1,14 @@ +package twg2.jbcm.toSource.structures; + +/** + * @author TeamworkGuy2 + * @since 2022-10-09 + */ +public enum EmitterResponse { + /** The emitter processed the input and does not wish to signal any change */ + CONTINUE, + /** The emitter consumed the input and no other emitter should be given the same input to process */ + CONSUMED, + /** The emitter is done and should be deregistered, it should not be given any further inputs */ + DEREGISTER, +} diff --git a/test/twg2/jbcm/test/BasicMathTest.java b/test/twg2/jbcm/test/BasicMathTest.java index 1e075fe..8a32ffe 100644 --- a/test/twg2/jbcm/test/BasicMathTest.java +++ b/test/twg2/jbcm/test/BasicMathTest.java @@ -4,7 +4,7 @@ import org.junit.Test; import twg2.jbcm.testParser.BytecodePseudoParser; -import twg2.jbcm.testParser.CompileTest; +import twg2.jbcm.testParser.CompileJava; /** * @author TeamworkGuy2 @@ -14,7 +14,7 @@ public class BasicMathTest { @Test public void arrayTest() { - var java = CompileTest.compileCode("int[] ary = new int[3]; int i = 2; ary[i] = (int)(i * Math.random()) % 2;"); + var java = CompileJava.compileCode("int[] ary = new int[3]; int i = 2; ary[i] = (int)(i * Math.random()) % 2;"); var res = BytecodePseudoParser.parse( "ICONST_3 NEWARRAY 10 ASTORE_1 ICONST_2 ISTORE_2 ALOAD_1 ILOAD_2 ILOAD_2 I2D INVOKESTATIC 0 2 DMUL D2I ICONST_2 IREM IASTORE RETURN" @@ -26,7 +26,7 @@ public void arrayTest() { @Test public void mathTest() { - var java = CompileTest.compileCode("int x = 2; int y = 6; int r = x * y; r++;"); + var java = CompileJava.compileCode("int x = 2; int y = 6; int r = x * y; r++;"); var res = BytecodePseudoParser.parse( "ICONST_2 ISTORE_1 BIPUSH 6 ISTORE_2 ILOAD_1 ILOAD_2 IMUL ISTORE_3 IINC 3 1 RETURN" diff --git a/test/twg2/jbcm/test/BcRenameTest.java b/test/twg2/jbcm/test/BcRenameTest.java new file mode 100644 index 0000000..1852d02 --- /dev/null +++ b/test/twg2/jbcm/test/BcRenameTest.java @@ -0,0 +1,75 @@ +package twg2.jbcm.test; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.Collections; +import java.util.concurrent.ExecutionException; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import twg2.jbcm.classFormat.ClassFile; +import twg2.jbcm.runtime.ClassLoaders; +import twg2.jbcm.runtime.CompileSource; +import twg2.jbcm.runtime.ClassLoaders.ThreadMethodResult; +import twg2.jbcm.runtime.ClassLoaders.ThreadMethodResultFuture; +import twg2.jbcm.testParser.CompileJava; + +/** Bytecode class and method renaming tests + * @author TeamworkGuy2 + * @since 2022-07-31 + */ +public class BcRenameTest { + + @ExtendWith({BeforeAllCompileTestData.class}) + @Test + public void renameClassTest() throws Exception { + String className = "examples.ClassRename1"; + ThreadMethodResult res = compileAndRunClass(className, "System.out.println(\" >> examples.ClassRename1 run!\");"); + Assert.assertEquals(className, res.method.getDeclaringClass().getName()); + } + + + public static ThreadMethodResult compileAndRunClass(String className, String code) throws IOException, URISyntaxException, InterruptedException, ExecutionException, ClassNotFoundException { + ClassFile classFile = CompileJava.compileToClass(className, Collections.emptyList(), code); + ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(1024); + classFile.writeData(new DataOutputStream(byteArrayOut)); + byte[] bc = byteArrayOut.toByteArray(); + + if(CompileSource.debug) { + classFile.print(System.out); + } + + URI rootLocation = BcRenameTest.class.getProtectionDomain().getCodeSource().getLocation().toURI(); + Path workingRoot = Paths.get(rootLocation).getParent().resolve("res/tmp/"); + Path other = Paths.get(className.replace('.', '/') + ".class"); + Path classBinaryDir = workingRoot.resolve("bin"); + Path classBinaryPath = classBinaryDir.resolve(other); + Files.createDirectories(classBinaryPath.getParent()); + Files.write(classBinaryPath, bc, StandardOpenOption.CREATE, StandardOpenOption.WRITE); + URL classpathRoot = classBinaryDir.toUri().toURL(); + + //MemoryClassLoader cl = new MemoryClassLoader(); + //List> classes = ResourceToClass.loadClasses(new InputStream[] { new ByteArrayInputStream(bc) }, new String[] { className }, cl); + + // load the class and call the method + ThreadMethodResultFuture res = ClassLoaders.callClassMethod(classpathRoot, className, "run", null, new Object[0]); + + // wait for the result + try { + res.thread.join(); + } catch (InterruptedException e) { + System.err.println("Error waiting for thread: " + e.getLocalizedMessage()); + } + return new ThreadMethodResult(res.thread, res.method.get(), (T)res.result.get()); + } +} diff --git a/test/twg2/jbcm/test/BeforeAllCompileTestData.java b/test/twg2/jbcm/test/BeforeAllCompileTestData.java new file mode 100644 index 0000000..2318f65 --- /dev/null +++ b/test/twg2/jbcm/test/BeforeAllCompileTestData.java @@ -0,0 +1,60 @@ +package twg2.jbcm.test; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.Extension; +import org.junit.jupiter.api.extension.ExtensionContext; + +import twg2.jbcm.runtime.CompileSource; + +/** + * @author TeamworkGuy2 + * @since 2022-09-05 + */ +public class BeforeAllCompileTestData implements Extension, BeforeAllCallback, ExtensionContext.Store.CloseableResource { + /** Gate keeper to prevent multiple Threads within the same routine */ + private static final Lock lock = new ReentrantLock(); + /** volatile boolean to tell other threads, when unblocked, whether they should try attempt start-up. Alternatively, could use AtomicBoolean. */ + private static volatile boolean started = false; + + @Override + public void beforeAll(final ExtensionContext context) throws Exception { + // for parallel JUnit tests, lock the access + lock.lock(); + try { + if (!started) { + started = true; + // Register a callback hook when the root test context is shut down + context.getRoot().getStore(ExtensionContext.Namespace.GLOBAL).put(this.getClass().getCanonicalName(), this); + + compileJava("res/source", "res/destination"); + } + } + finally { + lock.unlock(); + } + } + + @Override + public void close() { + // "after all tests" logic goes here + } + + + private void compileJava(String sourceDir, String destinationDir) throws ClassNotFoundException, IOException { + File tmpFile = new File("res/tmp/src/CompilerTemp.java"); + File sourceDirFile = new File(sourceDir); + String classPath = sourceDirFile.getAbsolutePath(); + File destinationDirFile = new File(destinationDir); + + try { + CompileSource.compile(CompileSource.JAVA_1_8_COMPILE, tmpFile, sourceDirFile, classPath, destinationDirFile); + } catch(Exception ex) { + throw ex; + } + } +} \ No newline at end of file diff --git a/test/twg2/jbcm/test/DataCountingInputStreamTest.java b/test/twg2/jbcm/test/DataCountingInputStreamTest.java new file mode 100644 index 0000000..f37a32b --- /dev/null +++ b/test/twg2/jbcm/test/DataCountingInputStreamTest.java @@ -0,0 +1,34 @@ +package twg2.jbcm.test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import org.junit.Assert; +import org.junit.Test; + +import twg2.jbcm.DataCountingInputStream; + +/** + * @author TeamworkGuy2 + * @since 2022-07-28 + */ +public class DataCountingInputStreamTest { + + @Test + public void readBytes() throws IOException { + @SuppressWarnings("resource") + DataCountingInputStream ds = new DataCountingInputStream(new ByteArrayInputStream(new byte[] {2, 4, 6, 10})); + + int d = ds.read(); + Assert.assertEquals(2, d); + Assert.assertEquals(1, ds.bytesRead()); + d = ds.readShort(); + Assert.assertEquals((4 << 8) | 6, d); + Assert.assertEquals(3, ds.bytesRead()); + byte[] b = new byte[1]; + ds.read(b); + Assert.assertArrayEquals(new byte[] {10}, b); + Assert.assertEquals(4, ds.bytesRead()); + } + +} diff --git a/test/twg2/jbcm/test/LoopsDecompileInspection.java b/test/twg2/jbcm/test/LoopsDecompileInspection.java new file mode 100644 index 0000000..771f795 --- /dev/null +++ b/test/twg2/jbcm/test/LoopsDecompileInspection.java @@ -0,0 +1,24 @@ +package twg2.jbcm.test; + +import java.io.IOException; + +/** + * @author TeamworkGuy2 + * @since 2022-09-15 + */ +public class LoopsDecompileInspection { + + public static void loopConditionWithNestedIfOrGoto() throws IOException { + int i = 0; + while(Math.random() > 0 ? LoopsDecompileInspection.class.getResourceAsStream(LoopsDecompileInspection.class.getName()).read() > 0 : true) { + System.out.println("iteration " + i); + if(i < 10) { + i++; + } + else { + break; + } + } + } + +} diff --git a/test/twg2/jbcm/test/MethodCallTest.java b/test/twg2/jbcm/test/MethodCallTest.java index 8986e49..9e84ebf 100644 --- a/test/twg2/jbcm/test/MethodCallTest.java +++ b/test/twg2/jbcm/test/MethodCallTest.java @@ -6,7 +6,7 @@ import org.junit.Test; import twg2.jbcm.testParser.BytecodePseudoParser; -import twg2.jbcm.testParser.CompileTest; +import twg2.jbcm.testParser.CompileJava; /** * @author TeamworkGuy2 @@ -16,7 +16,7 @@ public class MethodCallTest { @Test public void invokeVirtualTest() { - var java = CompileTest.compileCode("byte[] res = \"\".getBytes();"); + var java = CompileJava.compileCode("byte[] res = \"\".getBytes();"); var res = BytecodePseudoParser.parse( "LDC 2 INVOKEVIRTUAL 0 3 ASTORE_1 RETURN" @@ -28,7 +28,7 @@ public void invokeVirtualTest() { @Test public void invokeStaticAndVirtualTest() { - var java = CompileTest.compileCode(Arrays.asList("java.nio.charset.Charset"), "Charset charset = Charset.forName(\"ASCII\"); byte[] res = \"\".getBytes(charset);"); + var java = CompileJava.compileCode(Arrays.asList("java.nio.charset.Charset"), "Charset charset = Charset.forName(\"ASCII\"); byte[] res = \"\".getBytes(charset);", false); var res = BytecodePseudoParser.parse( "LDC 2 INVOKESTATIC 0 3 ASTORE_1 LDC 4 ALOAD_1 INVOKEVIRTUAL 0 5 ASTORE_2 RETURN" diff --git a/test/twg2/jbcm/test/RuntimeReloadTest.java b/test/twg2/jbcm/test/RuntimeReloadTest.java new file mode 100644 index 0000000..307ab34 --- /dev/null +++ b/test/twg2/jbcm/test/RuntimeReloadTest.java @@ -0,0 +1,45 @@ +package twg2.jbcm.test; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +import org.junit.Assert; +import org.junit.Test; + +import twg2.jbcm.main.RuntimeReloadMain; +import twg2.jbcm.runtime.CompileSource; + +/** + * @author TeamworkGuy2 + * @since 2022-07-31 + */ +public class RuntimeReloadTest { + + + /** Compile a Java source file and load it + * @throws ClassNotFoundException + * @throws IOException + * @throws InterruptedException + * @throws ExecutionException + */ + @Test + public void compileSourceFileToClass() throws ClassNotFoundException, IOException, InterruptedException, ExecutionException { + File entryFile = new File("examples/ExampleMain.java"); + File projectRoot = new File("examples"); + String classPath = new File("examples").getAbsolutePath(); + File destinationDir = new File("res/tmp/bin"); + + CompileSource.compile(CompileSource.JAVA_1_8_COMPILE, entryFile, projectRoot, classPath, destinationDir); + + var res = RuntimeReloadMain.loadRun("res/tmp/bin", "examples.ExampleMain", "run", (String[])null); + + //Runnable thing = (Runnable)classes[0].newInstance(); + //thing.run(); + + res.thread.join(1000); + + Assert.assertNotNull(res.method.get()); // success! + } + +} diff --git a/test/twg2/jbcm/testParser/CompileJava.java b/test/twg2/jbcm/testParser/CompileJava.java new file mode 100644 index 0000000..a5f56de --- /dev/null +++ b/test/twg2/jbcm/testParser/CompileJava.java @@ -0,0 +1,106 @@ +package twg2.jbcm.testParser; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.Collections; + +import twg2.jbcm.classFormat.ClassFile; +import twg2.jbcm.runtime.CompileSource; +import twg2.jbcm.toSource.ClassFileToSource; +import twg2.jbcm.toSource.SourceWriter; + +/** Compile Java source code to byte code + * @author TeamworkGuy2 + * @since 2020-07-19 + */ +public class CompileJava { + + /** Compile Java source code and return the byte code result + * @param srcCode the source code to compile + * @param printCode whether to print the source and compiled byte-code + * @return the byte code result + */ + public static byte[] compileCode(String srcCode) { + return compileCode(CompileSource.defaultCompileClassName, Collections.emptyList(), srcCode, CompileSource.printCode); + } + + + /** Compile Java source code and return the byte code result + * @param imports the imports required to compile the source code, full class names or package names ends with wildcard, + * not prefixed by {@code "import "} + * @param srcCode the source code to compile + * @param printCode whether to print the source and compiled byte-code + * @return the byte code result + */ + public static byte[] compileCode(Iterable imports, String srcCode, boolean printCode) { + return compileCode(CompileSource.defaultCompileClassName, imports, srcCode, printCode); + } + + + /** Compile Java source code and return the byte code result + * @param className the simple name of the class (i.e. {@code MathUtils}) + * @param imports the imports required to compile the source code, full class names or package names ends with wildcard, + * not prefixed by {@code "import "} + * @param srcCode the source code to compile + * @param printCode whether to print the source and compiled byte-code + * @return the byte code result + */ + public static byte[] compileCode(String className, Iterable imports, String srcCode, boolean printCode) { + ClassFile javaClass = compileToClass(className, imports, srcCode); + String binaryClassName = javaClass.getClassIndex().getCpObject().getName().getString(); + String fullClassName = binaryClassName.replace('/', '.'); + String simpleClassName = fullClassName.substring(fullClassName.lastIndexOf('.') + 1); + + var runMethod = javaClass.getMethod(1); // skip constructor and get 'run()' method + + if(printCode) { + SourceWriter writer = new SourceWriter("\t", "\n"); + ClassFileToSource.methodToSource(javaClass, fullClassName, simpleClassName, runMethod, writer, false); + System.out.println("Source:\n" + srcCode + + "\nCompiled:\n" + writer.toString()); + } + + return runMethod.getCode().getCode(); + } + + + /** Compile Java source code into a {@code run()} method in a class named {@link CompileSource#defaultCompileClassName} + * @param className the simple name of the class (i.e. {@code com.app.utils.MathUtils}) + * @param imports the imports required to compile the source code, full class names or package names ends with wildcard, + * not prefixed by {@code "import "} + * @param srcCode the source {@code run()} method source code + * @return the compiled class file + */ + public static ClassFile compileToClass(String fullClassName, Iterable imports, String srcCode) { + String simpleClassName = fullClassName.substring(fullClassName.lastIndexOf('.') + 1); + String packageName = simpleClassName.length() < fullClassName.length() ? fullClassName.substring(0, fullClassName.length() - simpleClassName.length() - 1) : ""; + String packagePath = packageName.length() > 0 ? '/' + packageName.replace('.', '/') : ""; + String importsSrc = String.join(";\nimport ", imports); + var javaRes = CompileSource.compileSourceToBytecode( + "res/tmp/src", + "res/tmp/bin", + packagePath, + simpleClassName, + (packageName.length() > 0 ? "package " + packageName + ";\n\n" : "") + + (importsSrc.length() > 0 ? "import " + importsSrc + ";\n\n" : "") + + wrapInClass(srcCode, simpleClassName) + ); + + try { + return ClassFile.load(new ByteArrayInputStream(javaRes), fullClassName); + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } + + + private static String wrapInClass(String srcCode, String className) { + return + "public class " + className + " {\n" + + " public void run() {\n" + + " " + srcCode + "\n" + + " }\n" + + "}\n"; + } + +} diff --git a/test/twg2/jbcm/testParser/CompileTest.java b/test/twg2/jbcm/testParser/CompileTest.java deleted file mode 100644 index c1ae5d6..0000000 --- a/test/twg2/jbcm/testParser/CompileTest.java +++ /dev/null @@ -1,77 +0,0 @@ -package twg2.jbcm.testParser; - -import java.io.ByteArrayInputStream; -import java.io.IOException; - -import twg2.jbcm.classFormat.ClassFile; -import twg2.jbcm.runtimeLoading.CompileSource; -import twg2.jbcm.toSource.ClassFileToSource; -import twg2.jbcm.toSource.SourceWriter; - -/** Compile Java source code to byte code - * @author TeamworkGuy2 - * @since 2020-07-19 - */ -public class CompileTest { - - /** Compile Java source code and return the byte code result - * @param srcCode the source code to compile - * @return the byte code result - */ - public static byte[] compileCode(String srcCode) { - return compileCode(java.util.Collections.emptyList(), srcCode); - } - - - /** Compile Java source code and return the byte code result - * @param imports the imports required to compile the source code - * @param srcCode the source code to compile - * @return the byte code result - */ - public static byte[] compileCode(Iterable imports, String srcCode) { - ClassFile javaClass = compileToClass(imports, srcCode); - String binaryClassName = javaClass.getClassIndex().getCpObject().getName().getString(); - String fullClassName = binaryClassName.replace('/', '.'); - String className = fullClassName.substring(fullClassName.lastIndexOf('.') + 1); - - var runMethod = javaClass.getMethod(1); // skip constructor and get 'run()' method - - SourceWriter writer = new SourceWriter("\t", "\n"); - ClassFileToSource.methodToSource(javaClass, fullClassName, className, runMethod, writer, false); - System.out.println("Source:\n" + srcCode + - "\nCompiled:\n" + writer.toString()); - - return runMethod.getCode().getCode(); - } - - - /** Compile Java source code into a {@code run()} method in a class named {@link CompileSource#defaultCompileClassName} - * @param imports the imports required to compile the source code - * @param srcCode the source {@code run()} method source code - * @return the compiled class file - */ - public static ClassFile compileToClass(Iterable imports, String srcCode) { - var importsSrc = String.join(";\nimport ", imports); - var javaRes = CompileSource.compileSourceToBytecode( - (importsSrc.length() > 0 ? "import " + importsSrc + ";\n\n" : "") + - wrapInClass(srcCode, CompileSource.defaultCompileClassName) - ); - - try { - return ClassFile.load(new ByteArrayInputStream(javaRes)); - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } - } - - - private static String wrapInClass(String srcCode, String className) { - return - "public class " + className + " {\n" + - " public void run() {\n" + - " " + srcCode + "\n" + - " }\n" + - "}\n"; - } - -}