From bc138133edbfadda9db261a387d70ca11b009e09 Mon Sep 17 00:00:00 2001 From: Michael Zhou Date: Tue, 5 Jun 2012 13:46:30 -0600 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=9A=82=E6=97=B6=E6=B2=A1?= =?UTF-8?q?=E7=94=A8=E7=9A=84asm/codegen=E5=AD=90=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=EF=BC=8C=E5=B0=86=E5=B0=91=E9=87=8F=E4=BE=9D=E8=B5=96=E5=88=B0?= =?UTF-8?q?=E7=9A=84=E7=B1=BB=E7=A7=BB=E5=88=B0generictype=E5=AD=90?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E4=B8=AD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/asm/docs/.cvsignore | 2 - common/asm/docs/readme.txt | 32 - common/asm/pom.xml | 34 - .../alibaba/citrus/asm/AnnotationVisitor.java | 115 - .../alibaba/citrus/asm/AnnotationWriter.java | 317 --- .../com/alibaba/citrus/asm/Attribute.java | 247 -- .../com/alibaba/citrus/asm/ByteVector.java | 309 -- .../com/alibaba/citrus/asm/ClassAdapter.java | 110 - .../com/alibaba/citrus/asm/ClassReader.java | 1849 ------------ .../com/alibaba/citrus/asm/ClassVisitor.java | 193 -- .../com/alibaba/citrus/asm/ClassWriter.java | 1310 --------- .../java/com/alibaba/citrus/asm/Edge.java | 92 - .../com/alibaba/citrus/asm/FieldVisitor.java | 81 - .../com/alibaba/citrus/asm/FieldWriter.java | 271 -- .../java/com/alibaba/citrus/asm/Frame.java | 1355 --------- .../java/com/alibaba/citrus/asm/Handler.java | 87 - .../java/com/alibaba/citrus/asm/Item.java | 262 -- .../java/com/alibaba/citrus/asm/Label.java | 522 ---- .../com/alibaba/citrus/asm/MethodAdapter.java | 170 -- .../com/alibaba/citrus/asm/MethodVisitor.java | 408 --- .../com/alibaba/citrus/asm/MethodWriter.java | 2489 ----------------- .../citrus/asm/commons/AdviceAdapter.java | 613 ---- .../citrus/asm/commons/AnalyzerAdapter.java | 851 ------ .../citrus/asm/commons/CodeSizeEvaluator.java | 216 -- .../citrus/asm/commons/EmptyVisitor.java | 176 -- .../citrus/asm/commons/GeneratorAdapter.java | 1425 ---------- .../citrus/asm/commons/JSRInlinerAdapter.java | 706 ----- .../asm/commons/LocalVariablesSorter.java | 327 --- .../alibaba/citrus/asm/commons/Remapper.java | 196 -- .../commons/RemappingAnnotationAdapter.java | 89 - .../asm/commons/RemappingClassAdapter.java | 125 - .../asm/commons/RemappingFieldAdapter.java | 82 - .../asm/commons/RemappingMethodAdapter.java | 147 - .../commons/RemappingSignatureAdapter.java | 143 - .../asm/commons/SerialVersionUIDAdder.java | 467 ---- .../citrus/asm/commons/SimpleRemapper.java | 82 - .../citrus/asm/commons/StaticInitMerger.java | 108 - .../asm/commons/TableSwitchGenerator.java | 72 - .../AnnotationConstantsCollector.java | 156 -- .../optimizer/ClassConstantsCollector.java | 195 -- .../citrus/asm/optimizer/ClassOptimizer.java | 161 -- .../citrus/asm/optimizer/Constant.java | 274 -- .../citrus/asm/optimizer/ConstantPool.java | 206 -- .../optimizer/FieldConstantsCollector.java | 88 - .../citrus/asm/optimizer/JarOptimizer.java | 217 -- .../optimizer/MethodConstantsCollector.java | 162 -- .../citrus/asm/optimizer/MethodOptimizer.java | 105 - .../citrus/asm/optimizer/NameMapping.java | 119 - .../citrus/asm/optimizer/Shrinker.java | 212 -- .../citrus/asm/signature/SignatureReader.java | 237 -- .../asm/signature/SignatureVisitor.java | 202 -- .../citrus/asm/signature/SignatureWriter.java | 225 -- .../citrus/asm/tree/AbstractInsnNode.java | 250 -- .../citrus/asm/tree/AnnotationNode.java | 197 -- .../alibaba/citrus/asm/tree/ClassNode.java | 265 -- .../citrus/asm/tree/FieldInsnNode.java | 120 - .../alibaba/citrus/asm/tree/FieldNode.java | 138 - .../alibaba/citrus/asm/tree/FrameNode.java | 219 -- .../alibaba/citrus/asm/tree/IincInsnNode.java | 97 - .../citrus/asm/tree/InnerClassNode.java | 114 - .../com/alibaba/citrus/asm/tree/InsnList.java | 655 ----- .../com/alibaba/citrus/asm/tree/InsnNode.java | 102 - .../alibaba/citrus/asm/tree/IntInsnNode.java | 101 - .../alibaba/citrus/asm/tree/JumpInsnNode.java | 109 - .../alibaba/citrus/asm/tree/LabelNode.java | 95 - .../alibaba/citrus/asm/tree/LdcInsnNode.java | 94 - .../citrus/asm/tree/LineNumberNode.java | 99 - .../citrus/asm/tree/LocalVariableNode.java | 121 - .../citrus/asm/tree/LookupSwitchInsnNode.java | 128 - .../alibaba/citrus/asm/tree/MemberNode.java | 134 - .../citrus/asm/tree/MethodInsnNode.java | 121 - .../alibaba/citrus/asm/tree/MethodNode.java | 440 --- .../asm/tree/MultiANewArrayInsnNode.java | 99 - .../citrus/asm/tree/TableSwitchInsnNode.java | 124 - .../citrus/asm/tree/TryCatchBlockNode.java | 104 - .../alibaba/citrus/asm/tree/TypeInsnNode.java | 105 - .../alibaba/citrus/asm/tree/VarInsnNode.java | 107 - .../citrus/asm/tree/analysis/Analyzer.java | 494 ---- .../asm/tree/analysis/AnalyzerException.java | 70 - .../asm/tree/analysis/BasicInterpreter.java | 325 --- .../citrus/asm/tree/analysis/BasicValue.java | 124 - .../asm/tree/analysis/BasicVerifier.java | 409 --- .../citrus/asm/tree/analysis/Frame.java | 677 ----- .../citrus/asm/tree/analysis/Interpreter.java | 178 -- .../asm/tree/analysis/SimpleVerifier.java | 288 -- .../citrus/asm/tree/analysis/SmallSet.java | 145 - .../asm/tree/analysis/SourceInterpreter.java | 182 -- .../citrus/asm/tree/analysis/SourceValue.java | 114 - .../citrus/asm/tree/analysis/Subroutine.java | 106 - .../citrus/asm/tree/analysis/Value.java | 62 - .../alibaba/citrus/asm/util/ASMifiable.java | 69 - .../asm/util/ASMifierAbstractVisitor.java | 231 -- .../asm/util/ASMifierAnnotationVisitor.java | 135 - .../citrus/asm/util/ASMifierClassVisitor.java | 528 ---- .../citrus/asm/util/ASMifierFieldVisitor.java | 65 - .../asm/util/ASMifierMethodVisitor.java | 391 --- .../citrus/asm/util/AbstractVisitor.java | 219 -- .../asm/util/CheckAnnotationAdapter.java | 134 - .../citrus/asm/util/CheckClassAdapter.java | 450 --- .../citrus/asm/util/CheckFieldAdapter.java | 91 - .../citrus/asm/util/CheckMethodAdapter.java | 1235 -------- .../asm/util/CheckSignatureAdapter.java | 303 -- .../citrus/asm/util/TraceAbstractVisitor.java | 191 -- .../asm/util/TraceAnnotationVisitor.java | 275 -- .../citrus/asm/util/TraceClassVisitor.java | 488 ---- .../citrus/asm/util/TraceFieldVisitor.java | 93 - .../citrus/asm/util/TraceMethodVisitor.java | 526 ---- .../asm/util/TraceSignatureVisitor.java | 315 --- .../alibaba/citrus/asm/util/Traceable.java | 68 - .../citrus/asm/xml/ASMContentHandler.java | 1217 -------- .../com/alibaba/citrus/asm/xml/Processor.java | 998 ------- .../alibaba/citrus/asm/xml/SAXAdapter.java | 112 - .../citrus/asm/xml/SAXAnnotationAdapter.java | 185 -- .../citrus/asm/xml/SAXClassAdapter.java | 319 --- .../citrus/asm/xml/SAXCodeAdapter.java | 313 --- .../citrus/asm/xml/SAXFieldAdapter.java | 74 - .../com/alibaba/citrus/ASM_LICENSE.txt | 28 - .../com/alibaba/citrus/asm/attrs/package.html | 48 - .../alibaba/citrus/asm/commons/package.html | 48 - .../citrus/asm/optimizer/jdk1.2.2_017.txt.gz | Bin 113814 -> 0 bytes .../citrus/asm/optimizer/jdk1.3.1_19.txt.gz | Bin 128067 -> 0 bytes .../optimizer/shrink-annotations.properties | 23 - .../asm/optimizer/shrink-frames.properties | 32 - .../asm/optimizer/shrink-resize.properties | 7 - .../optimizer/shrink-signatures.properties | 13 - .../asm/optimizer/shrink-writer.properties | 38 - .../citrus/asm/optimizer/shrink.properties | 282 -- .../com/alibaba/citrus/asm/package.html | 87 - .../alibaba/citrus/asm/signature/package.html | 36 - .../citrus/asm/tree/analysis/package.html | 67 - .../com/alibaba/citrus/asm/tree/package.html | 192 -- .../com/alibaba/citrus/asm/util/package.html | 40 - .../com/alibaba/citrus/asm/xml/asm-xml.dtd | 340 --- .../com/alibaba/citrus/asm/xml/package.html | 96 - .../com/alibaba/citrus/asm/AbstractTest.java | 189 -- .../alibaba/citrus/asm/AnnotationsTest.java | 141 - .../com/alibaba/citrus/asm/AsmTestParams.java | 123 - .../alibaba/citrus/asm/AttributeUnitTest.java | 61 - .../alibaba/citrus/asm/ClassAdapterTest.java | 86 - .../alibaba/citrus/asm/ClassReaderTest.java | 68 - .../citrus/asm/ClassReaderUnitTest.java | 106 - .../asm/ClassWriterComputeFramesTest.java | 294 -- .../asm/ClassWriterComputeMaxsTest.java | 70 - .../asm/ClassWriterComputeMaxsUnitTest.java | 952 ------- .../citrus/asm/ClassWriterCopyPoolTest.java | 87 - .../asm/ClassWriterResizeInsnsTest.java | 173 -- .../alibaba/citrus/asm/ClassWriterTest.java | 69 - .../citrus/asm/ClassWriterUnitTest.java | 85 - .../com/alibaba/citrus/asm/LabelUnitTest.java | 78 - .../com/alibaba/citrus/asm/TypeUnitTest.java | 130 - .../alibaba/citrus/asm/attrs/CodeComment.java | 105 - .../com/alibaba/citrus/asm/attrs/Comment.java | 94 - .../citrus/asm/commons/AdviceAdapterTest.java | 137 - .../asm/commons/AdviceAdapterUnitTest.java | 232 -- .../asm/commons/AnalyzerAdapterTest.java | 103 - .../asm/commons/CodeSizeEvaluatorTest.java | 86 - .../asm/commons/GASMifierClassVisitor.java | 157 -- .../asm/commons/GASMifierMethodVisitor.java | 1072 ------- .../citrus/asm/commons/GASMifierTest.java | 190 -- .../asm/commons/JSRInlinerAdapterTest.java | 99 - .../commons/JSRInlinerAdapterUnitTest.java | 1878 ------------- .../asm/commons/LocalVariablesSorterTest.java | 99 - .../commons/LocalVariablesSorterTest2.java | 141 - .../commons/RemappingClassAdapterTest.java | 257 -- .../commons/RemappingClassAdapterTest2.java | 80 - .../commons/SerialVersionUIDAdderTest.java | 70 - .../SerialVersionUIDAdderUnitTest.java | 92 - .../asm/commons/StaticInitMergerTest.java | 98 - .../asm/signature/SignatureUnitTest.java | 99 - .../asm/signature/SignatureWriterTest.java | 107 - .../citrus/asm/test/cases/Annotation.java | 327 --- .../citrus/asm/test/cases/Attribute.java | 112 - .../alibaba/citrus/asm/test/cases/Debug.java | 105 - .../alibaba/citrus/asm/test/cases/Enum.java | 161 -- .../alibaba/citrus/asm/test/cases/Frames.java | 684 ----- .../citrus/asm/test/cases/Generator.java | 81 - .../alibaba/citrus/asm/test/cases/Insns.java | 746 ----- .../citrus/asm/test/cases/Interface.java | 81 - .../alibaba/citrus/asm/test/cases/JSR.java | 186 -- .../alibaba/citrus/asm/test/cases/Outer.java | 193 -- .../alibaba/citrus/asm/test/cases/Wide.java | 129 - .../citrus/asm/tree/ClassNodeTest.java | 112 - .../citrus/asm/tree/ClassNodeUnitTest.java | 143 - .../citrus/asm/tree/InsnListUnitTest.java | 697 ----- .../asm/tree/analysis/AnalyzerUnitTest.java | 118 - .../tree/analysis/BasicInterpreterTest.java | 81 - .../asm/tree/analysis/BasicVerifierTest.java | 81 - .../asm/tree/analysis/SimpleVerifierTest.java | 87 - .../tree/analysis/SimpleVerifierUnitTest.java | 458 --- .../asm/tree/analysis/SmallSetUnitTest.java | 81 - .../tree/analysis/SourceInterpreterTest.java | 81 - .../asm/tree/analysis/ValueUnitTest.java | 70 - .../alibaba/citrus/asm/util/ASMifierTest.java | 140 - .../citrus/asm/util/ASMifierUnitTest.java | 68 - .../asm/util/CheckClassAdapterTest.java | 73 - .../asm/util/CheckClassAdapterUnitTest.java | 807 ------ .../asm/util/CheckSignatureAdapterTest.java | 109 - .../util/CheckSignatureAdapterUnitTest.java | 281 -- .../asm/util/TraceClassAdapterTest.java | 81 - .../asm/util/TraceClassAdapterUnitTest.java | 68 - .../util/TraceSignatureVisitorUnitTest.java | 197 -- .../asm/xml/ASMContentHandlerUnitTest.java | 137 - .../citrus/asm/xml/SAXAdapterTest.java | 104 - .../citrus/asm/xml/SAXAdapterUnitTest.java | 123 - common/codegen/.cvsignore | 13 - common/codegen/pom.xml | 28 - .../alibaba/citrus/codegen/ClassBuilder.java | 292 -- .../com/alibaba/citrus/codegen/ClassPool.java | 282 -- .../alibaba/citrus/codegen/CodeBuilder.java | 53 - .../alibaba/citrus/codegen/FieldBuilder.java | 140 - .../alibaba/citrus/codegen/MethodBuilder.java | 171 -- .../citrus/codegen/util/CodegenUtil.java | 129 - .../citrus/codegen/ClassGenerationTests.java | 125 - .../com/alibaba/citrus/codegen/MyClass.java | 35 - .../citrus/codegen/util/CodegenUtilTests.java | 146 - .../citrus/codegen/util/TypeUtilTests.java | 177 -- common/generictype/pom.xml | 4 - .../citrus/generictype/MethodInfo.java | 2 +- .../generictype/codegen}/CodegenConstant.java | 15 +- .../generictype/codegen}/MethodSignature.java | 12 +- .../citrus/generictype/codegen}/TypeUtil.java | 6 +- .../generictype/codegen/asm}/Method.java | 5 +- .../generictype/codegen}/asm/Opcodes.java | 2 +- .../citrus/generictype/codegen}/asm/Type.java | 3 +- .../citrus/generictype/impl/MethodImpl.java | 4 +- dist/test/pom.xml | 2 +- dist/webx/pom.xml | 10 +- pom.xml | 1542 +++++----- 228 files changed, 787 insertions(+), 53674 deletions(-) delete mode 100644 common/asm/docs/.cvsignore delete mode 100644 common/asm/docs/readme.txt delete mode 100644 common/asm/pom.xml delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/AnnotationVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/AnnotationWriter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/Attribute.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/ByteVector.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/ClassAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/ClassReader.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/ClassVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/ClassWriter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/Edge.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/FieldVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/FieldWriter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/Frame.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/Handler.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/Item.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/Label.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/MethodAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/MethodVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/MethodWriter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/AdviceAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/AnalyzerAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/CodeSizeEvaluator.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/EmptyVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/GeneratorAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/JSRInlinerAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/LocalVariablesSorter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/Remapper.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingAnnotationAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingClassAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingFieldAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingMethodAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingSignatureAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/SerialVersionUIDAdder.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/SimpleRemapper.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/StaticInitMerger.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/commons/TableSwitchGenerator.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/AnnotationConstantsCollector.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/ClassConstantsCollector.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/ClassOptimizer.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/Constant.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/ConstantPool.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/FieldConstantsCollector.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/JarOptimizer.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/MethodConstantsCollector.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/MethodOptimizer.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/NameMapping.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/Shrinker.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/signature/SignatureReader.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/signature/SignatureVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/signature/SignatureWriter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/AbstractInsnNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/AnnotationNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/ClassNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/FieldInsnNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/FieldNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/FrameNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/IincInsnNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/InnerClassNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/InsnList.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/InsnNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/IntInsnNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/JumpInsnNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/LabelNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/LdcInsnNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/LineNumberNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/LocalVariableNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/LookupSwitchInsnNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/MemberNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/MethodInsnNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/MethodNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/MultiANewArrayInsnNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/TableSwitchInsnNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/TryCatchBlockNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/TypeInsnNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/VarInsnNode.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Analyzer.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/AnalyzerException.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/BasicInterpreter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/BasicValue.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/BasicVerifier.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Frame.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Interpreter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/SimpleVerifier.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/SmallSet.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/SourceInterpreter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/SourceValue.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Subroutine.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Value.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifiable.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierAbstractVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierAnnotationVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierClassVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierFieldVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierMethodVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/AbstractVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckAnnotationAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckClassAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckFieldAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckMethodAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckSignatureAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceAbstractVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceAnnotationVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceClassVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceFieldVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceMethodVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceSignatureVisitor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/util/Traceable.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/xml/ASMContentHandler.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/xml/Processor.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXAnnotationAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXClassAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXCodeAdapter.java delete mode 100644 common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXFieldAdapter.java delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/ASM_LICENSE.txt delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/attrs/package.html delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/commons/package.html delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/jdk1.2.2_017.txt.gz delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/jdk1.3.1_19.txt.gz delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-annotations.properties delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-frames.properties delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-resize.properties delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-signatures.properties delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-writer.properties delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink.properties delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/package.html delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/signature/package.html delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/tree/analysis/package.html delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/tree/package.html delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/util/package.html delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/xml/asm-xml.dtd delete mode 100644 common/asm/src/main/resources/com/alibaba/citrus/asm/xml/package.html delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/AbstractTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/AnnotationsTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/AsmTestParams.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/AttributeUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/ClassAdapterTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/ClassReaderTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/ClassReaderUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterComputeFramesTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterComputeMaxsTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterComputeMaxsUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterCopyPoolTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterResizeInsnsTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/LabelUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/TypeUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/attrs/CodeComment.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/attrs/Comment.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/commons/AdviceAdapterTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/commons/AdviceAdapterUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/commons/AnalyzerAdapterTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/commons/CodeSizeEvaluatorTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/commons/GASMifierClassVisitor.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/commons/GASMifierMethodVisitor.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/commons/GASMifierTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/commons/JSRInlinerAdapterTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/commons/JSRInlinerAdapterUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/commons/LocalVariablesSorterTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/commons/LocalVariablesSorterTest2.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/commons/RemappingClassAdapterTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/commons/RemappingClassAdapterTest2.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/commons/SerialVersionUIDAdderTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/commons/SerialVersionUIDAdderUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/commons/StaticInitMergerTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/signature/SignatureUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/signature/SignatureWriterTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Annotation.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Attribute.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Debug.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Enum.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Frames.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Generator.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Insns.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Interface.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/JSR.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Outer.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Wide.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/tree/ClassNodeTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/tree/ClassNodeUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/tree/InsnListUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/AnalyzerUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/BasicInterpreterTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/BasicVerifierTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/SimpleVerifierTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/SimpleVerifierUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/SmallSetUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/SourceInterpreterTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/ValueUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/util/ASMifierTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/util/ASMifierUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/util/CheckClassAdapterTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/util/CheckClassAdapterUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/util/CheckSignatureAdapterTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/util/CheckSignatureAdapterUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/util/TraceClassAdapterTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/util/TraceClassAdapterUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/util/TraceSignatureVisitorUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/xml/ASMContentHandlerUnitTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/xml/SAXAdapterTest.java delete mode 100644 common/asm/src/test/java/com/alibaba/citrus/asm/xml/SAXAdapterUnitTest.java delete mode 100644 common/codegen/.cvsignore delete mode 100644 common/codegen/pom.xml delete mode 100644 common/codegen/src/main/java/com/alibaba/citrus/codegen/ClassBuilder.java delete mode 100644 common/codegen/src/main/java/com/alibaba/citrus/codegen/ClassPool.java delete mode 100644 common/codegen/src/main/java/com/alibaba/citrus/codegen/CodeBuilder.java delete mode 100644 common/codegen/src/main/java/com/alibaba/citrus/codegen/FieldBuilder.java delete mode 100644 common/codegen/src/main/java/com/alibaba/citrus/codegen/MethodBuilder.java delete mode 100644 common/codegen/src/main/java/com/alibaba/citrus/codegen/util/CodegenUtil.java delete mode 100644 common/codegen/src/test/java/com/alibaba/citrus/codegen/ClassGenerationTests.java delete mode 100644 common/codegen/src/test/java/com/alibaba/citrus/codegen/MyClass.java delete mode 100644 common/codegen/src/test/java/com/alibaba/citrus/codegen/util/CodegenUtilTests.java delete mode 100644 common/codegen/src/test/java/com/alibaba/citrus/codegen/util/TypeUtilTests.java rename common/{codegen/src/main/java/com/alibaba/citrus/codegen/util => generictype/src/main/java/com/alibaba/citrus/generictype/codegen}/CodegenConstant.java (74%) rename common/{codegen/src/main/java/com/alibaba/citrus/codegen/util => generictype/src/main/java/com/alibaba/citrus/generictype/codegen}/MethodSignature.java (75%) rename common/{codegen/src/main/java/com/alibaba/citrus/codegen/util => generictype/src/main/java/com/alibaba/citrus/generictype/codegen}/TypeUtil.java (94%) rename common/{asm/src/main/java/com/alibaba/citrus/asm/commons => generictype/src/main/java/com/alibaba/citrus/generictype/codegen/asm}/Method.java (96%) rename common/{asm/src/main/java/com/alibaba/citrus => generictype/src/main/java/com/alibaba/citrus/generictype/codegen}/asm/Opcodes.java (96%) rename common/{asm/src/main/java/com/alibaba/citrus => generictype/src/main/java/com/alibaba/citrus/generictype/codegen}/asm/Type.java (96%) diff --git a/common/asm/docs/.cvsignore b/common/asm/docs/.cvsignore deleted file mode 100644 index 687e77d20..000000000 --- a/common/asm/docs/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -api -api.test diff --git a/common/asm/docs/readme.txt b/common/asm/docs/readme.txt deleted file mode 100644 index 841131d54..000000000 --- a/common/asm/docs/readme.txt +++ /dev/null @@ -1,32 +0,0 @@ -说明: -====== - -本项目是从ObjectWeb ASM v3.1(http://asm.objectweb.org/license.html)中移植,并做了如下修改: - -* 修改package - org.objectweb.asm -> com.alibaba.citrus.asm - org/objectweb/asm -> com/alibaba/citrus/asm - -* 修改单元测试: - 1. 只保留了conform测试。 - 2. 增加AsmTestParams辅助类。 - 3. 修改AbstractTest类,使之: - # 使用AsmTestParams而不是System properties。 - # 改进suite的名称,加上“-part” - # 将stream改成URL,避免内存溢出 - # 添加exclude参数,排除多余的文件 - # 关闭zip流 - # 设置一个suite中test的最大数量 - 4. 修改了ASMifierUnitTest、CheckClassAdapterUnitTest、TraceClassAdapterUnitTest中传给main函数的参数。 - 5. 修改了ASMifierTest、GASMifierTest中的参数:clazz=java.lang - 6. 修改了ClassWriterComputeFramesTest、LocalVariablesSorterTest2、SimpleVerifierTest中的参数:parts=2 - 7. 修改所有对AbstractTest.is的引用,改成openStream()调用。 - 8. 修改了SerialVersionUIDAdderUnitTest中的UID,以便通过测试。 - 9. ClassNodeTest中,设置InsnList.check = false,以便通过测试。 - -* 将StringBuffer改成StringBuilder - -* Cleanup - -* 测试要点:内存需求非常大,最好分配1G-2G的空间:-Xms1536M -Xmx1536M -XX:MaxPermSize=512M - diff --git a/common/asm/pom.xml b/common/asm/pom.xml deleted file mode 100644 index 53ec0a9af..000000000 --- a/common/asm/pom.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - citrus-parent - com.alibaba.citrus - 3.0.8 - ../../pom.xml - - 4.0.0 - citrus-common-asm - Bytecode Engineering Tools - - - - maven-surefire-plugin - - true - - - - - - - ${project.groupId} - citrus-test-util - - - janino - janino - - - diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/AnnotationVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/AnnotationVisitor.java deleted file mode 100644 index e6d3e03a0..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/AnnotationVisitor.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * A visitor to visit a Java annotation. The methods of this interface must be - * called in the following order: (visit | visitEnum | - * visitAnnotation | visitArray)* visitEnd. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public interface AnnotationVisitor { - - /** - * Visits a primitive value of the annotation. - * - * @param name the value name. - * @param value the actual value, whose type must be {@link Byte}, - * {@link Boolean}, {@link Character}, {@link Short}, - * {@link Integer}, {@link Long}, {@link Float}, {@link Double}, - * {@link String} or {@link Type}. This value can also be an - * array of byte, boolean, short, char, int, long, float or - * double values (this is equivalent to using {@link #visitArray - * visitArray} and visiting each array element in turn, but is - * more convenient). - */ - void visit(String name, Object value); - - /** - * Visits an enumeration value of the annotation. - * - * @param name the value name. - * @param desc the class descriptor of the enumeration class. - * @param value the actual enumeration value. - */ - void visitEnum(String name, String desc, String value); - - /** - * Visits a nested annotation value of the annotation. - * - * @param name the value name. - * @param desc the class descriptor of the nested annotation class. - * @return a visitor to visit the actual nested annotation value, or - * null if this visitor is not interested in visiting this - * nested annotation. The nested annotation value must be fully - * visited before calling other methods on this annotation - * visitor. - */ - AnnotationVisitor visitAnnotation(String name, String desc); - - /** - * Visits an array value of the annotation. Note that arrays of primitive - * types (such as byte, boolean, short, char, int, long, float or double) - * can be passed as value to {@link #visit visit}. This is what - * {@link ClassReader} does. - * - * @param name the value name. - * @return a visitor to visit the actual array value elements, or - * null if this visitor is not interested in visiting these - * values. The 'name' parameters passed to the methods of this - * visitor are ignored. All the array values must be visited - * before calling other methods on this annotation visitor. - */ - AnnotationVisitor visitArray(String name); - - /** - * Visits the end of the annotation. - */ - void visitEnd(); -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/AnnotationWriter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/AnnotationWriter.java deleted file mode 100644 index cad59059e..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/AnnotationWriter.java +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * An {@link AnnotationVisitor} that generates annotations in bytecode form. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -final class AnnotationWriter implements AnnotationVisitor { - - /** - * The class writer to which this annotation must be added. - */ - private final ClassWriter cw; - - /** - * The number of values in this annotation. - */ - private int size; - - /** - * true if values are named, false otherwise. Annotation - * writers used for annotation default and annotation arrays use unnamed - * values. - */ - private final boolean named; - - /** - * The annotation values in bytecode form. This byte vector only contains - * the values themselves, i.e. the number of values must be stored as a - * unsigned short just before these bytes. - */ - private final ByteVector bv; - - /** - * The byte vector to be used to store the number of values of this - * annotation. See {@link #bv}. - */ - private final ByteVector parent; - - /** - * Where the number of values of this annotation must be stored in - * {@link #parent}. - */ - private final int offset; - - /** - * Next annotation writer. This field is used to store annotation lists. - */ - AnnotationWriter next; - - /** - * Previous annotation writer. This field is used to store annotation lists. - */ - AnnotationWriter prev; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructs a new {@link AnnotationWriter}. - * - * @param cw the class writer to which this annotation must be added. - * @param named true if values are named, false otherwise. - * @param bv where the annotation values must be stored. - * @param parent where the number of annotation values must be stored. - * @param offset where in parent the number of annotation values - * must be stored. - */ - AnnotationWriter(final ClassWriter cw, final boolean named, final ByteVector bv, final ByteVector parent, - final int offset) { - this.cw = cw; - this.named = named; - this.bv = bv; - this.parent = parent; - this.offset = offset; - } - - // ------------------------------------------------------------------------ - // Implementation of the AnnotationVisitor interface - // ------------------------------------------------------------------------ - - public void visit(final String name, final Object value) { - ++size; - if (named) { - bv.putShort(cw.newUTF8(name)); - } - if (value instanceof String) { - bv.put12('s', cw.newUTF8((String) value)); - } else if (value instanceof Byte) { - bv.put12('B', cw.newInteger(((Byte) value).byteValue()).index); - } else if (value instanceof Boolean) { - int v = ((Boolean) value).booleanValue() ? 1 : 0; - bv.put12('Z', cw.newInteger(v).index); - } else if (value instanceof Character) { - bv.put12('C', cw.newInteger(((Character) value).charValue()).index); - } else if (value instanceof Short) { - bv.put12('S', cw.newInteger(((Short) value).shortValue()).index); - } else if (value instanceof Type) { - bv.put12('c', cw.newUTF8(((Type) value).getDescriptor())); - } else if (value instanceof byte[]) { - byte[] v = (byte[]) value; - bv.put12('[', v.length); - for (byte element : v) { - bv.put12('B', cw.newInteger(element).index); - } - } else if (value instanceof boolean[]) { - boolean[] v = (boolean[]) value; - bv.put12('[', v.length); - for (boolean element : v) { - bv.put12('Z', cw.newInteger(element ? 1 : 0).index); - } - } else if (value instanceof short[]) { - short[] v = (short[]) value; - bv.put12('[', v.length); - for (short element : v) { - bv.put12('S', cw.newInteger(element).index); - } - } else if (value instanceof char[]) { - char[] v = (char[]) value; - bv.put12('[', v.length); - for (char element : v) { - bv.put12('C', cw.newInteger(element).index); - } - } else if (value instanceof int[]) { - int[] v = (int[]) value; - bv.put12('[', v.length); - for (int element : v) { - bv.put12('I', cw.newInteger(element).index); - } - } else if (value instanceof long[]) { - long[] v = (long[]) value; - bv.put12('[', v.length); - for (long element : v) { - bv.put12('J', cw.newLong(element).index); - } - } else if (value instanceof float[]) { - float[] v = (float[]) value; - bv.put12('[', v.length); - for (float element : v) { - bv.put12('F', cw.newFloat(element).index); - } - } else if (value instanceof double[]) { - double[] v = (double[]) value; - bv.put12('[', v.length); - for (double element : v) { - bv.put12('D', cw.newDouble(element).index); - } - } else { - Item i = cw.newConstItem(value); - bv.put12(".s.IFJDCS".charAt(i.type), i.index); - } - } - - public void visitEnum(final String name, final String desc, final String value) { - ++size; - if (named) { - bv.putShort(cw.newUTF8(name)); - } - bv.put12('e', cw.newUTF8(desc)).putShort(cw.newUTF8(value)); - } - - public AnnotationVisitor visitAnnotation(final String name, final String desc) { - ++size; - if (named) { - bv.putShort(cw.newUTF8(name)); - } - // write tag and type, and reserve space for values count - bv.put12('@', cw.newUTF8(desc)).putShort(0); - return new AnnotationWriter(cw, true, bv, bv, bv.length - 2); - } - - public AnnotationVisitor visitArray(final String name) { - ++size; - if (named) { - bv.putShort(cw.newUTF8(name)); - } - // write tag, and reserve space for array size - bv.put12('[', 0); - return new AnnotationWriter(cw, false, bv, bv, bv.length - 2); - } - - public void visitEnd() { - if (parent != null) { - byte[] data = parent.data; - data[offset] = (byte) (size >>> 8); - data[offset + 1] = (byte) size; - } - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - /** - * Returns the size of this annotation writer list. - * - * @return the size of this annotation writer list. - */ - int getSize() { - int size = 0; - AnnotationWriter aw = this; - while (aw != null) { - size += aw.bv.length; - aw = aw.next; - } - return size; - } - - /** - * Puts the annotations of this annotation writer list into the given byte - * vector. - * - * @param out where the annotations must be put. - */ - void put(final ByteVector out) { - int n = 0; - int size = 2; - AnnotationWriter aw = this; - AnnotationWriter last = null; - while (aw != null) { - ++n; - size += aw.bv.length; - aw.visitEnd(); // in case user forgot to call visitEnd - aw.prev = last; - last = aw; - aw = aw.next; - } - out.putInt(size); - out.putShort(n); - aw = last; - while (aw != null) { - out.putByteArray(aw.bv.data, 0, aw.bv.length); - aw = aw.prev; - } - } - - /** - * Puts the given annotation lists into the given byte vector. - * - * @param panns an array of annotation writer lists. - * @param off index of the first annotation to be written. - * @param out where the annotations must be put. - */ - static void put(final AnnotationWriter[] panns, final int off, final ByteVector out) { - int size = 1 + 2 * (panns.length - off); - for (int i = off; i < panns.length; ++i) { - size += panns[i] == null ? 0 : panns[i].getSize(); - } - out.putInt(size).putByte(panns.length - off); - for (int i = off; i < panns.length; ++i) { - AnnotationWriter aw = panns[i]; - AnnotationWriter last = null; - int n = 0; - while (aw != null) { - ++n; - aw.visitEnd(); // in case user forgot to call visitEnd - aw.prev = last; - last = aw; - aw = aw.next; - } - out.putShort(n); - aw = last; - while (aw != null) { - out.putByteArray(aw.bv.data, 0, aw.bv.length); - aw = aw.prev; - } - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/Attribute.java b/common/asm/src/main/java/com/alibaba/citrus/asm/Attribute.java deleted file mode 100644 index 6e9af2af3..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/Attribute.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * A non standard class, field, method or code attribute. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public class Attribute { - - /** - * The type of this attribute. - */ - public final String type; - - /** - * The raw value of this attribute, used only for unknown attributes. - */ - byte[] value; - - /** - * The next attribute in this attribute list. May be null. - */ - Attribute next; - - /** - * Constructs a new empty attribute. - * - * @param type the type of the attribute. - */ - protected Attribute(final String type) { - this.type = type; - } - - /** - * Returns true if this type of attribute is unknown. The default - * implementation of this method always returns true. - * - * @return true if this type of attribute is unknown. - */ - public boolean isUnknown() { - return true; - } - - /** - * Returns true if this type of attribute is a code attribute. - * - * @return true if this type of attribute is a code attribute. - */ - public boolean isCodeAttribute() { - return false; - } - - /** - * Returns the labels corresponding to this attribute. - * - * @return the labels corresponding to this attribute, or null if - * this attribute is not a code attribute that contains labels. - */ - protected Label[] getLabels() { - return null; - } - - /** - * Reads a {@link #type type} attribute. This method must return a - * new {@link Attribute} object, of type {@link #type type}, - * corresponding to the len bytes starting at the given offset, in - * the given class reader. - * - * @param cr the class that contains the attribute to be read. - * @param off index of the first byte of the attribute's content in - * {@link ClassReader#b cr.b}. The 6 attribute header bytes, - * containing the type and the length of the attribute, are not - * taken into account here. - * @param len the length of the attribute's content. - * @param buf buffer to be used to call {@link ClassReader#readUTF8 - * readUTF8}, {@link ClassReader#readClass(int,char[]) readClass} - * or {@link ClassReader#readConst readConst}. - * @param codeOff index of the first byte of code's attribute content in - * {@link ClassReader#b cr.b}, or -1 if the attribute to be read - * is not a code attribute. The 6 attribute header bytes, - * containing the type and the length of the attribute, are not - * taken into account here. - * @param labels the labels of the method's code, or null if the - * attribute to be read is not a code attribute. - * @return a new {@link Attribute} object corresponding to the given - * bytes. - */ - protected Attribute read(final ClassReader cr, final int off, final int len, final char[] buf, final int codeOff, - final Label[] labels) { - Attribute attr = new Attribute(type); - attr.value = new byte[len]; - System.arraycopy(cr.b, off, attr.value, 0, len); - return attr; - } - - /** - * Returns the byte array form of this attribute. - * - * @param cw the class to which this attribute must be added. This parameter - * can be used to add to the constant pool of this class the - * items that corresponds to this attribute. - * @param code the bytecode of the method corresponding to this code - * attribute, or null if this attribute is not a code - * attributes. - * @param len the length of the bytecode of the method corresponding to this - * code attribute, or null if this attribute is not a - * code attribute. - * @param maxStack the maximum stack size of the method corresponding to - * this code attribute, or -1 if this attribute is not a code - * attribute. - * @param maxLocals the maximum number of local variables of the method - * corresponding to this code attribute, or -1 if this attribute - * is not a code attribute. - * @return the byte array form of this attribute. - */ - protected ByteVector write(final ClassWriter cw, final byte[] code, final int len, final int maxStack, - final int maxLocals) { - ByteVector v = new ByteVector(); - v.data = value; - v.length = value.length; - return v; - } - - /** - * Returns the length of the attribute list that begins with this attribute. - * - * @return the length of the attribute list that begins with this attribute. - */ - final int getCount() { - int count = 0; - Attribute attr = this; - while (attr != null) { - count += 1; - attr = attr.next; - } - return count; - } - - /** - * Returns the size of all the attributes in this attribute list. - * - * @param cw the class writer to be used to convert the attributes into byte - * arrays, with the {@link #write write} method. - * @param code the bytecode of the method corresponding to these code - * attributes, or null if these attributes are not code - * attributes. - * @param len the length of the bytecode of the method corresponding to - * these code attributes, or null if these attributes - * are not code attributes. - * @param maxStack the maximum stack size of the method corresponding to - * these code attributes, or -1 if these attributes are not code - * attributes. - * @param maxLocals the maximum number of local variables of the method - * corresponding to these code attributes, or -1 if these - * attributes are not code attributes. - * @return the size of all the attributes in this attribute list. This size - * includes the size of the attribute headers. - */ - final int getSize(final ClassWriter cw, final byte[] code, final int len, final int maxStack, final int maxLocals) { - Attribute attr = this; - int size = 0; - while (attr != null) { - cw.newUTF8(attr.type); - size += attr.write(cw, code, len, maxStack, maxLocals).length + 6; - attr = attr.next; - } - return size; - } - - /** - * Writes all the attributes of this attribute list in the given byte - * vector. - * - * @param cw the class writer to be used to convert the attributes into byte - * arrays, with the {@link #write write} method. - * @param code the bytecode of the method corresponding to these code - * attributes, or null if these attributes are not code - * attributes. - * @param len the length of the bytecode of the method corresponding to - * these code attributes, or null if these attributes - * are not code attributes. - * @param maxStack the maximum stack size of the method corresponding to - * these code attributes, or -1 if these attributes are not code - * attributes. - * @param maxLocals the maximum number of local variables of the method - * corresponding to these code attributes, or -1 if these - * attributes are not code attributes. - * @param out where the attributes must be written. - */ - final void put(final ClassWriter cw, final byte[] code, final int len, final int maxStack, final int maxLocals, - final ByteVector out) { - Attribute attr = this; - while (attr != null) { - ByteVector b = attr.write(cw, code, len, maxStack, maxLocals); - out.putShort(cw.newUTF8(attr.type)).putInt(b.length); - out.putByteArray(b.data, 0, b.length); - attr = attr.next; - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/ByteVector.java b/common/asm/src/main/java/com/alibaba/citrus/asm/ByteVector.java deleted file mode 100644 index c4350b0a5..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/ByteVector.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * A dynamically extensible vector of bytes. This class is roughly equivalent to - * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient. - * - * @author Eric Bruneton - */ -public class ByteVector { - - /** - * The content of this vector. - */ - byte[] data; - - /** - * Actual number of bytes in this vector. - */ - int length; - - /** - * Constructs a new {@link ByteVector ByteVector} with a default initial - * size. - */ - public ByteVector() { - data = new byte[64]; - } - - /** - * Constructs a new {@link ByteVector ByteVector} with the given initial - * size. - * - * @param initialSize the initial size of the byte vector to be constructed. - */ - public ByteVector(final int initialSize) { - data = new byte[initialSize]; - } - - /** - * Puts a byte into this byte vector. The byte vector is automatically - * enlarged if necessary. - * - * @param b a byte. - * @return this byte vector. - */ - public ByteVector putByte(final int b) { - int length = this.length; - if (length + 1 > data.length) { - enlarge(1); - } - data[length++] = (byte) b; - this.length = length; - return this; - } - - /** - * Puts two bytes into this byte vector. The byte vector is automatically - * enlarged if necessary. - * - * @param b1 a byte. - * @param b2 another byte. - * @return this byte vector. - */ - ByteVector put11(final int b1, final int b2) { - int length = this.length; - if (length + 2 > data.length) { - enlarge(2); - } - byte[] data = this.data; - data[length++] = (byte) b1; - data[length++] = (byte) b2; - this.length = length; - return this; - } - - /** - * Puts a short into this byte vector. The byte vector is automatically - * enlarged if necessary. - * - * @param s a short. - * @return this byte vector. - */ - public ByteVector putShort(final int s) { - int length = this.length; - if (length + 2 > data.length) { - enlarge(2); - } - byte[] data = this.data; - data[length++] = (byte) (s >>> 8); - data[length++] = (byte) s; - this.length = length; - return this; - } - - /** - * Puts a byte and a short into this byte vector. The byte vector is - * automatically enlarged if necessary. - * - * @param b a byte. - * @param s a short. - * @return this byte vector. - */ - ByteVector put12(final int b, final int s) { - int length = this.length; - if (length + 3 > data.length) { - enlarge(3); - } - byte[] data = this.data; - data[length++] = (byte) b; - data[length++] = (byte) (s >>> 8); - data[length++] = (byte) s; - this.length = length; - return this; - } - - /** - * Puts an int into this byte vector. The byte vector is automatically - * enlarged if necessary. - * - * @param i an int. - * @return this byte vector. - */ - public ByteVector putInt(final int i) { - int length = this.length; - if (length + 4 > data.length) { - enlarge(4); - } - byte[] data = this.data; - data[length++] = (byte) (i >>> 24); - data[length++] = (byte) (i >>> 16); - data[length++] = (byte) (i >>> 8); - data[length++] = (byte) i; - this.length = length; - return this; - } - - /** - * Puts a long into this byte vector. The byte vector is automatically - * enlarged if necessary. - * - * @param l a long. - * @return this byte vector. - */ - public ByteVector putLong(final long l) { - int length = this.length; - if (length + 8 > data.length) { - enlarge(8); - } - byte[] data = this.data; - int i = (int) (l >>> 32); - data[length++] = (byte) (i >>> 24); - data[length++] = (byte) (i >>> 16); - data[length++] = (byte) (i >>> 8); - data[length++] = (byte) i; - i = (int) l; - data[length++] = (byte) (i >>> 24); - data[length++] = (byte) (i >>> 16); - data[length++] = (byte) (i >>> 8); - data[length++] = (byte) i; - this.length = length; - return this; - } - - /** - * Puts an UTF8 string into this byte vector. The byte vector is - * automatically enlarged if necessary. - * - * @param s a String. - * @return this byte vector. - */ - public ByteVector putUTF8(final String s) { - int charLength = s.length(); - if (length + 2 + charLength > data.length) { - enlarge(2 + charLength); - } - int len = length; - byte[] data = this.data; - // optimistic algorithm: instead of computing the byte length and then - // serializing the string (which requires two loops), we assume the byte - // length is equal to char length (which is the most frequent case), and - // we start serializing the string right away. During the serialization, - // if we find that this assumption is wrong, we continue with the - // general method. - data[len++] = (byte) (charLength >>> 8); - data[len++] = (byte) charLength; - for (int i = 0; i < charLength; ++i) { - char c = s.charAt(i); - if (c >= '\001' && c <= '\177') { - data[len++] = (byte) c; - } else { - int byteLength = i; - for (int j = i; j < charLength; ++j) { - c = s.charAt(j); - if (c >= '\001' && c <= '\177') { - byteLength++; - } else if (c > '\u07FF') { - byteLength += 3; - } else { - byteLength += 2; - } - } - data[length] = (byte) (byteLength >>> 8); - data[length + 1] = (byte) byteLength; - if (length + 2 + byteLength > data.length) { - length = len; - enlarge(2 + byteLength); - data = this.data; - } - for (int j = i; j < charLength; ++j) { - c = s.charAt(j); - if (c >= '\001' && c <= '\177') { - data[len++] = (byte) c; - } else if (c > '\u07FF') { - data[len++] = (byte) (0xE0 | c >> 12 & 0xF); - data[len++] = (byte) (0x80 | c >> 6 & 0x3F); - data[len++] = (byte) (0x80 | c & 0x3F); - } else { - data[len++] = (byte) (0xC0 | c >> 6 & 0x1F); - data[len++] = (byte) (0x80 | c & 0x3F); - } - } - break; - } - } - length = len; - return this; - } - - /** - * Puts an array of bytes into this byte vector. The byte vector is - * automatically enlarged if necessary. - * - * @param b an array of bytes. May be null to put len null - * bytes into this byte vector. - * @param off index of the fist byte of b that must be copied. - * @param len number of bytes of b that must be copied. - * @return this byte vector. - */ - public ByteVector putByteArray(final byte[] b, final int off, final int len) { - if (length + len > data.length) { - enlarge(len); - } - if (b != null) { - System.arraycopy(b, off, data, length, len); - } - length += len; - return this; - } - - /** - * Enlarge this byte vector so that it can receive n more bytes. - * - * @param size number of additional bytes that this byte vector should be - * able to receive. - */ - private void enlarge(final int size) { - int length1 = 2 * data.length; - int length2 = length + size; - byte[] newData = new byte[length1 > length2 ? length1 : length2]; - System.arraycopy(data, 0, newData, 0, length); - data = newData; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/ClassAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/ClassAdapter.java deleted file mode 100644 index 0c3ba0930..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/ClassAdapter.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * An empty {@link ClassVisitor} that delegates to another {@link ClassVisitor}. - * This class can be used as a super class to quickly implement usefull class - * adapter classes, just by overriding the necessary methods. - * - * @author Eric Bruneton - */ -public class ClassAdapter implements ClassVisitor { - - /** - * The {@link ClassVisitor} to which this adapter delegates calls. - */ - protected ClassVisitor cv; - - /** - * Constructs a new {@link ClassAdapter} object. - * - * @param cv the class visitor to which this adapter must delegate calls. - */ - public ClassAdapter(final ClassVisitor cv) { - this.cv = cv; - } - - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - cv.visit(version, access, name, signature, superName, interfaces); - } - - public void visitSource(final String source, final String debug) { - cv.visitSource(source, debug); - } - - public void visitOuterClass(final String owner, final String name, final String desc) { - cv.visitOuterClass(owner, name, desc); - } - - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - return cv.visitAnnotation(desc, visible); - } - - public void visitAttribute(final Attribute attr) { - cv.visitAttribute(attr); - } - - public void visitInnerClass(final String name, final String outerName, final String innerName, final int access) { - cv.visitInnerClass(name, outerName, innerName, access); - } - - public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, - final Object value) { - return cv.visitField(access, name, desc, signature, value); - } - - public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, - final String[] exceptions) { - return cv.visitMethod(access, name, desc, signature, exceptions); - } - - public void visitEnd() { - cv.visitEnd(); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/ClassReader.java b/common/asm/src/main/java/com/alibaba/citrus/asm/ClassReader.java deleted file mode 100644 index 315ba7168..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/ClassReader.java +++ /dev/null @@ -1,1849 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -import java.io.IOException; -import java.io.InputStream; - -/** - * A Java class parser to make a {@link ClassVisitor} visit an existing class. - * This class parses a byte array conforming to the Java class file format and - * calls the appropriate visit methods of a given class visitor for each field, - * method and bytecode instruction encountered. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public class ClassReader { - - /** - * True to enable signatures support. - */ - static final boolean SIGNATURES = true; - - /** - * True to enable annotations support. - */ - static final boolean ANNOTATIONS = true; - - /** - * True to enable stack map frames support. - */ - static final boolean FRAMES = true; - - /** - * True to enable bytecode writing support. - */ - static final boolean WRITER = true; - - /** - * True to enable JSR_W and GOTO_W support. - */ - static final boolean RESIZE = true; - - /** - * Flag to skip method code. If this class is set CODE - * attribute won't be visited. This can be used, for example, to retrieve - * annotations for methods and method parameters. - */ - public static final int SKIP_CODE = 1; - - /** - * Flag to skip the debug information in the class. If this flag is set the - * debug information of the class is not visited, i.e. the - * {@link MethodVisitor#visitLocalVariable visitLocalVariable} and - * {@link MethodVisitor#visitLineNumber visitLineNumber} methods will not be - * called. - */ - public static final int SKIP_DEBUG = 2; - - /** - * Flag to skip the stack map frames in the class. If this flag is set the - * stack map frames of the class is not visited, i.e. the - * {@link MethodVisitor#visitFrame visitFrame} method will not be called. - * This flag is useful when the {@link ClassWriter#COMPUTE_FRAMES} option is - * used: it avoids visiting frames that will be ignored and recomputed from - * scratch in the class writer. - */ - public static final int SKIP_FRAMES = 4; - - /** - * Flag to expand the stack map frames. By default stack map frames are - * visited in their original format (i.e. "expanded" for classes whose - * version is less than V1_6, and "compressed" for the other classes). If - * this flag is set, stack map frames are always visited in expanded format - * (this option adds a decompression/recompression step in ClassReader and - * ClassWriter which degrades performances quite a lot). - */ - public static final int EXPAND_FRAMES = 8; - - /** - * The class to be parsed. The content of this array must not be - * modified. This field is intended for {@link Attribute} sub classes, and - * is normally not needed by class generators or adapters. - */ - public final byte[] b; - - /** - * The start index of each constant pool item in {@link #b b}, plus one. The - * one byte offset skips the constant pool item tag that indicates its type. - */ - private final int[] items; - - /** - * The String objects corresponding to the CONSTANT_Utf8 items. This cache - * avoids multiple parsing of a given CONSTANT_Utf8 constant pool item, - * which GREATLY improves performances (by a factor 2 to 3). This caching - * strategy could be extended to all constant pool items, but its benefit - * would not be so great for these items (because they are much less - * expensive to parse than CONSTANT_Utf8 items). - */ - private final String[] strings; - - /** - * Maximum length of the strings contained in the constant pool of the - * class. - */ - private final int maxStringLength; - - /** - * Start index of the class header information (access, name...) in - * {@link #b b}. - */ - public final int header; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructs a new {@link ClassReader} object. - * - * @param b the bytecode of the class to be read. - */ - public ClassReader(final byte[] b) { - this(b, 0, b.length); - } - - /** - * Constructs a new {@link ClassReader} object. - * - * @param b the bytecode of the class to be read. - * @param off the start offset of the class data. - * @param len the length of the class data. - */ - public ClassReader(final byte[] b, final int off, final int len) { - this.b = b; - // parses the constant pool - items = new int[readUnsignedShort(off + 8)]; - int n = items.length; - strings = new String[n]; - int max = 0; - int index = off + 10; - for (int i = 1; i < n; ++i) { - items[i] = index + 1; - int size; - switch (b[index]) { - case ClassWriter.FIELD: - case ClassWriter.METH: - case ClassWriter.IMETH: - case ClassWriter.INT: - case ClassWriter.FLOAT: - case ClassWriter.NAME_TYPE: - size = 5; - break; - case ClassWriter.LONG: - case ClassWriter.DOUBLE: - size = 9; - ++i; - break; - case ClassWriter.UTF8: - size = 3 + readUnsignedShort(index + 1); - if (size > max) { - max = size; - } - break; - // case ClassWriter.CLASS: - // case ClassWriter.STR: - default: - size = 3; - break; - } - index += size; - } - maxStringLength = max; - // the class header information starts just after the constant pool - header = index; - } - - /** - * Returns the class's access flags (see {@link Opcodes}). This value may - * not reflect Deprecated and Synthetic flags when bytecode is before 1.5 - * and those flags are represented by attributes. - * - * @return the class access flags - * @see ClassVisitor#visit(int, int, String, String, String, String[]) - */ - public int getAccess() { - return readUnsignedShort(header); - } - - /** - * Returns the internal name of the class (see - * {@link Type#getInternalName() getInternalName}). - * - * @return the internal class name - * @see ClassVisitor#visit(int, int, String, String, String, String[]) - */ - public String getClassName() { - return readClass(header + 2, new char[maxStringLength]); - } - - /** - * Returns the internal of name of the super class (see - * {@link Type#getInternalName() getInternalName}). For interfaces, the - * super class is {@link Object}. - * - * @return the internal name of super class, or null for - * {@link Object} class. - * @see ClassVisitor#visit(int, int, String, String, String, String[]) - */ - public String getSuperName() { - int n = items[readUnsignedShort(header + 4)]; - return n == 0 ? null : readUTF8(n, new char[maxStringLength]); - } - - /** - * Returns the internal names of the class's interfaces (see - * {@link Type#getInternalName() getInternalName}). - * - * @return the array of internal names for all implemented interfaces or - * null. - * @see ClassVisitor#visit(int, int, String, String, String, String[]) - */ - public String[] getInterfaces() { - int index = header + 6; - int n = readUnsignedShort(index); - String[] interfaces = new String[n]; - if (n > 0) { - char[] buf = new char[maxStringLength]; - for (int i = 0; i < n; ++i) { - index += 2; - interfaces[i] = readClass(index, buf); - } - } - return interfaces; - } - - /** - * Copies the constant pool data into the given {@link ClassWriter}. Should - * be called before the {@link #accept(ClassVisitor,int)} method. - * - * @param classWriter the {@link ClassWriter} to copy constant pool into. - */ - void copyPool(final ClassWriter classWriter) { - char[] buf = new char[maxStringLength]; - int ll = items.length; - Item[] items2 = new Item[ll]; - for (int i = 1; i < ll; i++) { - int index = items[i]; - int tag = b[index - 1]; - Item item = new Item(i); - int nameType; - switch (tag) { - case ClassWriter.FIELD: - case ClassWriter.METH: - case ClassWriter.IMETH: - nameType = items[readUnsignedShort(index + 2)]; - item.set(tag, readClass(index, buf), readUTF8(nameType, buf), readUTF8(nameType + 2, buf)); - break; - - case ClassWriter.INT: - item.set(readInt(index)); - break; - - case ClassWriter.FLOAT: - item.set(Float.intBitsToFloat(readInt(index))); - break; - - case ClassWriter.NAME_TYPE: - item.set(tag, readUTF8(index, buf), readUTF8(index + 2, buf), null); - break; - - case ClassWriter.LONG: - item.set(readLong(index)); - ++i; - break; - - case ClassWriter.DOUBLE: - item.set(Double.longBitsToDouble(readLong(index))); - ++i; - break; - - case ClassWriter.UTF8: { - String s = strings[i]; - if (s == null) { - index = items[i]; - s = strings[i] = readUTF(index + 2, readUnsignedShort(index), buf); - } - item.set(tag, s, null, null); - } - break; - - // case ClassWriter.STR: - // case ClassWriter.CLASS: - default: - item.set(tag, readUTF8(index, buf), null, null); - break; - } - - int index2 = item.hashCode % items2.length; - item.next = items2[index2]; - items2[index2] = item; - } - - int off = items[1] - 1; - classWriter.pool.putByteArray(b, off, header - off); - classWriter.items = items2; - classWriter.threshold = (int) (0.75d * ll); - classWriter.index = ll; - } - - /** - * Constructs a new {@link ClassReader} object. - * - * @param is an input stream from which to read the class. - * @throws IOException if a problem occurs during reading. - */ - public ClassReader(final InputStream is) throws IOException { - this(readClass(is)); - } - - /** - * Constructs a new {@link ClassReader} object. - * - * @param name the fully qualified name of the class to be read. - * @throws IOException if an exception occurs during reading. - */ - public ClassReader(final String name) throws IOException { - this(ClassLoader.getSystemResourceAsStream(name.replace('.', '/') + ".class")); - } - - /** - * Reads the bytecode of a class. - * - * @param is an input stream from which to read the class. - * @return the bytecode read from the given input stream. - * @throws IOException if a problem occurs during reading. - */ - private static byte[] readClass(final InputStream is) throws IOException { - if (is == null) { - throw new IOException("Class not found"); - } - byte[] b = new byte[is.available()]; - int len = 0; - while (true) { - int n = is.read(b, len, b.length - len); - if (n == -1) { - if (len < b.length) { - byte[] c = new byte[len]; - System.arraycopy(b, 0, c, 0, len); - b = c; - } - return b; - } - len += n; - if (len == b.length) { - byte[] c = new byte[b.length + 1000]; - System.arraycopy(b, 0, c, 0, len); - b = c; - } - } - } - - // ------------------------------------------------------------------------ - // Public methods - // ------------------------------------------------------------------------ - - /** - * Makes the given visitor visit the Java class of this {@link ClassReader}. - * This class is the one specified in the constructor (see - * {@link #ClassReader(byte[]) ClassReader}). - * - * @param classVisitor the visitor that must visit this class. - * @param flags option flags that can be used to modify the default behavior - * of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES} - * , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}. - */ - public void accept(final ClassVisitor classVisitor, final int flags) { - accept(classVisitor, new Attribute[0], flags); - } - - /** - * Makes the given visitor visit the Java class of this {@link ClassReader}. - * This class is the one specified in the constructor (see - * {@link #ClassReader(byte[]) ClassReader}). - * - * @param classVisitor the visitor that must visit this class. - * @param attrs prototypes of the attributes that must be parsed during the - * visit of the class. Any attribute whose type is not equal to - * the type of one the prototypes will not be parsed: its byte - * array value will be passed unchanged to the ClassWriter. - * This may corrupt it if this value contains references to - * the constant pool, or has syntactic or semantic links with a - * class element that has been transformed by a class adapter - * between the reader and the writer. - * @param flags option flags that can be used to modify the default behavior - * of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES} - * , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}. - */ - public void accept(final ClassVisitor classVisitor, final Attribute[] attrs, final int flags) { - byte[] b = this.b; // the bytecode array - char[] c = new char[maxStringLength]; // buffer used to read strings - int i, j, k; // loop variables - int u, v, w; // indexes in b - Attribute attr; - - int access; - String name; - String desc; - String attrName; - String signature; - int anns = 0; - int ianns = 0; - Attribute cattrs = null; - - // visits the header - u = header; - access = readUnsignedShort(u); - name = readClass(u + 2, c); - v = items[readUnsignedShort(u + 4)]; - String superClassName = v == 0 ? null : readUTF8(v, c); - String[] implementedItfs = new String[readUnsignedShort(u + 6)]; - w = 0; - u += 8; - for (i = 0; i < implementedItfs.length; ++i) { - implementedItfs[i] = readClass(u, c); - u += 2; - } - - boolean skipCode = (flags & SKIP_CODE) != 0; - boolean skipDebug = (flags & SKIP_DEBUG) != 0; - boolean unzip = (flags & EXPAND_FRAMES) != 0; - - // skips fields and methods - v = u; - i = readUnsignedShort(v); - v += 2; - for (; i > 0; --i) { - j = readUnsignedShort(v + 6); - v += 8; - for (; j > 0; --j) { - v += 6 + readInt(v + 2); - } - } - i = readUnsignedShort(v); - v += 2; - for (; i > 0; --i) { - j = readUnsignedShort(v + 6); - v += 8; - for (; j > 0; --j) { - v += 6 + readInt(v + 2); - } - } - // reads the class's attributes - signature = null; - String sourceFile = null; - String sourceDebug = null; - String enclosingOwner = null; - String enclosingName = null; - String enclosingDesc = null; - - i = readUnsignedShort(v); - v += 2; - for (; i > 0; --i) { - attrName = readUTF8(v, c); - // tests are sorted in decreasing frequency order - // (based on frequencies observed on typical classes) - if ("SourceFile".equals(attrName)) { - sourceFile = readUTF8(v + 6, c); - } else if ("InnerClasses".equals(attrName)) { - w = v + 6; - } else if ("EnclosingMethod".equals(attrName)) { - enclosingOwner = readClass(v + 6, c); - int item = readUnsignedShort(v + 8); - if (item != 0) { - enclosingName = readUTF8(items[item], c); - enclosingDesc = readUTF8(items[item] + 2, c); - } - } else if (SIGNATURES && "Signature".equals(attrName)) { - signature = readUTF8(v + 6, c); - } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) { - anns = v + 6; - } else if ("Deprecated".equals(attrName)) { - access |= Opcodes.ACC_DEPRECATED; - } else if ("Synthetic".equals(attrName)) { - access |= Opcodes.ACC_SYNTHETIC; - } else if ("SourceDebugExtension".equals(attrName)) { - int len = readInt(v + 2); - sourceDebug = readUTF(v + 6, len, new char[len]); - } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) { - ianns = v + 6; - } else { - attr = readAttribute(attrs, attrName, v + 6, readInt(v + 2), c, -1, null); - if (attr != null) { - attr.next = cattrs; - cattrs = attr; - } - } - v += 6 + readInt(v + 2); - } - // calls the visit method - classVisitor.visit(readInt(4), access, name, signature, superClassName, implementedItfs); - - // calls the visitSource method - if (!skipDebug && (sourceFile != null || sourceDebug != null)) { - classVisitor.visitSource(sourceFile, sourceDebug); - } - - // calls the visitOuterClass method - if (enclosingOwner != null) { - classVisitor.visitOuterClass(enclosingOwner, enclosingName, enclosingDesc); - } - - // visits the class annotations - if (ANNOTATIONS) { - for (i = 1; i >= 0; --i) { - v = i == 0 ? ianns : anns; - if (v != 0) { - j = readUnsignedShort(v); - v += 2; - for (; j > 0; --j) { - v = readAnnotationValues(v + 2, c, true, classVisitor.visitAnnotation(readUTF8(v, c), i != 0)); - } - } - } - } - - // visits the class attributes - while (cattrs != null) { - attr = cattrs.next; - cattrs.next = null; - classVisitor.visitAttribute(cattrs); - cattrs = attr; - } - - // calls the visitInnerClass method - if (w != 0) { - i = readUnsignedShort(w); - w += 2; - for (; i > 0; --i) { - classVisitor.visitInnerClass(readUnsignedShort(w) == 0 ? null : readClass(w, c), - readUnsignedShort(w + 2) == 0 ? null : readClass(w + 2, c), - readUnsignedShort(w + 4) == 0 ? null : readUTF8(w + 4, c), readUnsignedShort(w + 6)); - w += 8; - } - } - - // visits the fields - i = readUnsignedShort(u); - u += 2; - for (; i > 0; --i) { - access = readUnsignedShort(u); - name = readUTF8(u + 2, c); - desc = readUTF8(u + 4, c); - // visits the field's attributes and looks for a ConstantValue - // attribute - int fieldValueItem = 0; - signature = null; - anns = 0; - ianns = 0; - cattrs = null; - - j = readUnsignedShort(u + 6); - u += 8; - for (; j > 0; --j) { - attrName = readUTF8(u, c); - // tests are sorted in decreasing frequency order - // (based on frequencies observed on typical classes) - if ("ConstantValue".equals(attrName)) { - fieldValueItem = readUnsignedShort(u + 6); - } else if (SIGNATURES && "Signature".equals(attrName)) { - signature = readUTF8(u + 6, c); - } else if ("Deprecated".equals(attrName)) { - access |= Opcodes.ACC_DEPRECATED; - } else if ("Synthetic".equals(attrName)) { - access |= Opcodes.ACC_SYNTHETIC; - } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) { - anns = u + 6; - } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) { - ianns = u + 6; - } else { - attr = readAttribute(attrs, attrName, u + 6, readInt(u + 2), c, -1, null); - if (attr != null) { - attr.next = cattrs; - cattrs = attr; - } - } - u += 6 + readInt(u + 2); - } - // visits the field - FieldVisitor fv = classVisitor.visitField(access, name, desc, signature, fieldValueItem == 0 ? null - : readConst(fieldValueItem, c)); - // visits the field annotations and attributes - if (fv != null) { - if (ANNOTATIONS) { - for (j = 1; j >= 0; --j) { - v = j == 0 ? ianns : anns; - if (v != 0) { - k = readUnsignedShort(v); - v += 2; - for (; k > 0; --k) { - v = readAnnotationValues(v + 2, c, true, fv.visitAnnotation(readUTF8(v, c), j != 0)); - } - } - } - } - while (cattrs != null) { - attr = cattrs.next; - cattrs.next = null; - fv.visitAttribute(cattrs); - cattrs = attr; - } - fv.visitEnd(); - } - } - - // visits the methods - i = readUnsignedShort(u); - u += 2; - for (; i > 0; --i) { - int u0 = u + 6; - access = readUnsignedShort(u); - name = readUTF8(u + 2, c); - desc = readUTF8(u + 4, c); - signature = null; - anns = 0; - ianns = 0; - int dann = 0; - int mpanns = 0; - int impanns = 0; - cattrs = null; - v = 0; - w = 0; - - // looks for Code and Exceptions attributes - j = readUnsignedShort(u + 6); - u += 8; - for (; j > 0; --j) { - attrName = readUTF8(u, c); - int attrSize = readInt(u + 2); - u += 6; - // tests are sorted in decreasing frequency order - // (based on frequencies observed on typical classes) - if ("Code".equals(attrName)) { - if (!skipCode) { - v = u; - } - } else if ("Exceptions".equals(attrName)) { - w = u; - } else if (SIGNATURES && "Signature".equals(attrName)) { - signature = readUTF8(u, c); - } else if ("Deprecated".equals(attrName)) { - access |= Opcodes.ACC_DEPRECATED; - } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) { - anns = u; - } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) { - dann = u; - } else if ("Synthetic".equals(attrName)) { - access |= Opcodes.ACC_SYNTHETIC; - } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) { - ianns = u; - } else if (ANNOTATIONS && "RuntimeVisibleParameterAnnotations".equals(attrName)) { - mpanns = u; - } else if (ANNOTATIONS && "RuntimeInvisibleParameterAnnotations".equals(attrName)) { - impanns = u; - } else { - attr = readAttribute(attrs, attrName, u, attrSize, c, -1, null); - if (attr != null) { - attr.next = cattrs; - cattrs = attr; - } - } - u += attrSize; - } - // reads declared exceptions - String[] exceptions; - if (w == 0) { - exceptions = null; - } else { - exceptions = new String[readUnsignedShort(w)]; - w += 2; - for (j = 0; j < exceptions.length; ++j) { - exceptions[j] = readClass(w, c); - w += 2; - } - } - - // visits the method's code, if any - MethodVisitor mv = classVisitor.visitMethod(access, name, desc, signature, exceptions); - - if (mv != null) { - /* - * if the returned MethodVisitor is in fact a MethodWriter, it - * means there is no method adapter between the reader and the - * writer. If, in addition, the writer's constant pool was - * copied from this reader (mw.cw.cr == this), and the signature - * and exceptions of the method have not been changed, then it - * is possible to skip all visit events and just copy the - * original code of the method to the writer (the access, name - * and descriptor can have been changed, this is not important - * since they are not copied as is from the reader). - */ - if (WRITER && mv instanceof MethodWriter) { - MethodWriter mw = (MethodWriter) mv; - if (mw.cw.cr == this) { - if (signature == mw.signature) { - boolean sameExceptions = false; - if (exceptions == null) { - sameExceptions = mw.exceptionCount == 0; - } else { - if (exceptions.length == mw.exceptionCount) { - sameExceptions = true; - for (j = exceptions.length - 1; j >= 0; --j) { - w -= 2; - if (mw.exceptions[j] != readUnsignedShort(w)) { - sameExceptions = false; - break; - } - } - } - } - if (sameExceptions) { - /* - * we do not copy directly the code into - * MethodWriter to save a byte array copy - * operation. The real copy will be done in - * ClassWriter.toByteArray(). - */ - mw.classReaderOffset = u0; - mw.classReaderLength = u - u0; - continue; - } - } - } - } - - if (ANNOTATIONS && dann != 0) { - AnnotationVisitor dv = mv.visitAnnotationDefault(); - readAnnotationValue(dann, c, null, dv); - if (dv != null) { - dv.visitEnd(); - } - } - if (ANNOTATIONS) { - for (j = 1; j >= 0; --j) { - w = j == 0 ? ianns : anns; - if (w != 0) { - k = readUnsignedShort(w); - w += 2; - for (; k > 0; --k) { - w = readAnnotationValues(w + 2, c, true, mv.visitAnnotation(readUTF8(w, c), j != 0)); - } - } - } - } - if (ANNOTATIONS && mpanns != 0) { - readParameterAnnotations(mpanns, desc, c, true, mv); - } - if (ANNOTATIONS && impanns != 0) { - readParameterAnnotations(impanns, desc, c, false, mv); - } - while (cattrs != null) { - attr = cattrs.next; - cattrs.next = null; - mv.visitAttribute(cattrs); - cattrs = attr; - } - } - - if (mv != null && v != 0) { - int maxStack = readUnsignedShort(v); - int maxLocals = readUnsignedShort(v + 2); - int codeLength = readInt(v + 4); - v += 8; - - int codeStart = v; - int codeEnd = v + codeLength; - - mv.visitCode(); - - // 1st phase: finds the labels - int label; - Label[] labels = new Label[codeLength + 2]; - readLabel(codeLength + 1, labels); - while (v < codeEnd) { - w = v - codeStart; - int opcode = b[v] & 0xFF; - switch (ClassWriter.TYPE[opcode]) { - case ClassWriter.NOARG_INSN: - case ClassWriter.IMPLVAR_INSN: - v += 1; - break; - case ClassWriter.LABEL_INSN: - readLabel(w + readShort(v + 1), labels); - v += 3; - break; - case ClassWriter.LABELW_INSN: - readLabel(w + readInt(v + 1), labels); - v += 5; - break; - case ClassWriter.WIDE_INSN: - opcode = b[v + 1] & 0xFF; - if (opcode == Opcodes.IINC) { - v += 6; - } else { - v += 4; - } - break; - case ClassWriter.TABL_INSN: - // skips 0 to 3 padding bytes* - v = v + 4 - (w & 3); - // reads instruction - readLabel(w + readInt(v), labels); - j = readInt(v + 8) - readInt(v + 4) + 1; - v += 12; - for (; j > 0; --j) { - readLabel(w + readInt(v), labels); - v += 4; - } - break; - case ClassWriter.LOOK_INSN: - // skips 0 to 3 padding bytes* - v = v + 4 - (w & 3); - // reads instruction - readLabel(w + readInt(v), labels); - j = readInt(v + 4); - v += 8; - for (; j > 0; --j) { - readLabel(w + readInt(v + 4), labels); - v += 8; - } - break; - case ClassWriter.VAR_INSN: - case ClassWriter.SBYTE_INSN: - case ClassWriter.LDC_INSN: - v += 2; - break; - case ClassWriter.SHORT_INSN: - case ClassWriter.LDCW_INSN: - case ClassWriter.FIELDORMETH_INSN: - case ClassWriter.TYPE_INSN: - case ClassWriter.IINC_INSN: - v += 3; - break; - case ClassWriter.ITFMETH_INSN: - v += 5; - break; - // case MANA_INSN: - default: - v += 4; - break; - } - } - // parses the try catch entries - j = readUnsignedShort(v); - v += 2; - for (; j > 0; --j) { - Label start = readLabel(readUnsignedShort(v), labels); - Label end = readLabel(readUnsignedShort(v + 2), labels); - Label handler = readLabel(readUnsignedShort(v + 4), labels); - int type = readUnsignedShort(v + 6); - if (type == 0) { - mv.visitTryCatchBlock(start, end, handler, null); - } else { - mv.visitTryCatchBlock(start, end, handler, readUTF8(items[type], c)); - } - v += 8; - } - // parses the local variable, line number tables, and code - // attributes - int varTable = 0; - int varTypeTable = 0; - int stackMap = 0; - int frameCount = 0; - int frameMode = 0; - int frameOffset = 0; - int frameLocalCount = 0; - int frameLocalDiff = 0; - int frameStackCount = 0; - Object[] frameLocal = null; - Object[] frameStack = null; - boolean zip = true; - cattrs = null; - j = readUnsignedShort(v); - v += 2; - for (; j > 0; --j) { - attrName = readUTF8(v, c); - if ("LocalVariableTable".equals(attrName)) { - if (!skipDebug) { - varTable = v + 6; - k = readUnsignedShort(v + 6); - w = v + 8; - for (; k > 0; --k) { - label = readUnsignedShort(w); - if (labels[label] == null) { - readLabel(label, labels).status |= Label.DEBUG; - } - label += readUnsignedShort(w + 2); - if (labels[label] == null) { - readLabel(label, labels).status |= Label.DEBUG; - } - w += 10; - } - } - } else if ("LocalVariableTypeTable".equals(attrName)) { - varTypeTable = v + 6; - } else if ("LineNumberTable".equals(attrName)) { - if (!skipDebug) { - k = readUnsignedShort(v + 6); - w = v + 8; - for (; k > 0; --k) { - label = readUnsignedShort(w); - if (labels[label] == null) { - readLabel(label, labels).status |= Label.DEBUG; - } - labels[label].line = readUnsignedShort(w + 2); - w += 4; - } - } - } else if (FRAMES && "StackMapTable".equals(attrName)) { - if ((flags & SKIP_FRAMES) == 0) { - stackMap = v + 8; - frameCount = readUnsignedShort(v + 6); - } - /* - * here we do not extract the labels corresponding to - * the attribute content. This would require a full - * parsing of the attribute, which would need to be - * repeated in the second phase (see below). Instead the - * content of the attribute is read one frame at a time - * (i.e. after a frame has been visited, the next frame - * is read), and the labels it contains are also - * extracted one frame at a time. Thanks to the ordering - * of frames, having only a "one frame lookahead" is not - * a problem, i.e. it is not possible to see an offset - * smaller than the offset of the current insn and for - * which no Label exist. - */ - // TODO true for frame offsets, - // but for UNINITIALIZED type offsets? - } else if (FRAMES && "StackMap".equals(attrName)) { - if ((flags & SKIP_FRAMES) == 0) { - stackMap = v + 8; - frameCount = readUnsignedShort(v + 6); - zip = false; - } - /* - * IMPORTANT! here we assume that the frames are - * ordered, as in the StackMapTable attribute, although - * this is not guaranteed by the attribute format. - */ - } else { - for (k = 0; k < attrs.length; ++k) { - if (attrs[k].type.equals(attrName)) { - attr = attrs[k].read(this, v + 6, readInt(v + 2), c, codeStart - 8, labels); - if (attr != null) { - attr.next = cattrs; - cattrs = attr; - } - } - } - } - v += 6 + readInt(v + 2); - } - - // 2nd phase: visits each instruction - if (FRAMES && stackMap != 0) { - // creates the very first (implicit) frame from the method - // descriptor - frameLocal = new Object[maxLocals]; - frameStack = new Object[maxStack]; - if (unzip) { - int local = 0; - if ((access & Opcodes.ACC_STATIC) == 0) { - if ("".equals(name)) { - frameLocal[local++] = Opcodes.UNINITIALIZED_THIS; - } else { - frameLocal[local++] = readClass(header + 2, c); - } - } - j = 1; - loop: while (true) { - k = j; - switch (desc.charAt(j++)) { - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - frameLocal[local++] = Opcodes.INTEGER; - break; - case 'F': - frameLocal[local++] = Opcodes.FLOAT; - break; - case 'J': - frameLocal[local++] = Opcodes.LONG; - break; - case 'D': - frameLocal[local++] = Opcodes.DOUBLE; - break; - case '[': - while (desc.charAt(j) == '[') { - ++j; - } - if (desc.charAt(j) == 'L') { - ++j; - while (desc.charAt(j) != ';') { - ++j; - } - } - frameLocal[local++] = desc.substring(k, ++j); - break; - case 'L': - while (desc.charAt(j) != ';') { - ++j; - } - frameLocal[local++] = desc.substring(k + 1, j++); - break; - default: - break loop; - } - } - frameLocalCount = local; - } - /* - * for the first explicit frame the offset is not - * offset_delta + 1 but only offset_delta; setting the - * implicit frame offset to -1 allow the use of the - * "offset_delta + 1" rule in all cases - */ - frameOffset = -1; - } - v = codeStart; - Label l; - while (v < codeEnd) { - w = v - codeStart; - - l = labels[w]; - if (l != null) { - mv.visitLabel(l); - if (!skipDebug && l.line > 0) { - mv.visitLineNumber(l.line, l); - } - } - - while (FRAMES && frameLocal != null && (frameOffset == w || frameOffset == -1)) { - // if there is a frame for this offset, - // makes the visitor visit it, - // and reads the next frame if there is one. - if (!zip || unzip) { - mv.visitFrame(Opcodes.F_NEW, frameLocalCount, frameLocal, frameStackCount, frameStack); - } else if (frameOffset != -1) { - mv.visitFrame(frameMode, frameLocalDiff, frameLocal, frameStackCount, frameStack); - } - - if (frameCount > 0) { - int tag, delta, n; - if (zip) { - tag = b[stackMap++] & 0xFF; - } else { - tag = MethodWriter.FULL_FRAME; - frameOffset = -1; - } - frameLocalDiff = 0; - if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME) { - delta = tag; - frameMode = Opcodes.F_SAME; - frameStackCount = 0; - } else if (tag < MethodWriter.RESERVED) { - delta = tag - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME; - stackMap = readFrameType(frameStack, 0, stackMap, c, labels); - frameMode = Opcodes.F_SAME1; - frameStackCount = 1; - } else { - delta = readUnsignedShort(stackMap); - stackMap += 2; - if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { - stackMap = readFrameType(frameStack, 0, stackMap, c, labels); - frameMode = Opcodes.F_SAME1; - frameStackCount = 1; - } else if (tag >= MethodWriter.CHOP_FRAME && tag < MethodWriter.SAME_FRAME_EXTENDED) { - frameMode = Opcodes.F_CHOP; - frameLocalDiff = MethodWriter.SAME_FRAME_EXTENDED - tag; - frameLocalCount -= frameLocalDiff; - frameStackCount = 0; - } else if (tag == MethodWriter.SAME_FRAME_EXTENDED) { - frameMode = Opcodes.F_SAME; - frameStackCount = 0; - } else if (tag < MethodWriter.FULL_FRAME) { - j = unzip ? frameLocalCount : 0; - for (k = tag - MethodWriter.SAME_FRAME_EXTENDED; k > 0; k--) { - stackMap = readFrameType(frameLocal, j++, stackMap, c, labels); - } - frameMode = Opcodes.F_APPEND; - frameLocalDiff = tag - MethodWriter.SAME_FRAME_EXTENDED; - frameLocalCount += frameLocalDiff; - frameStackCount = 0; - } else { // if (tag == FULL_FRAME) { - frameMode = Opcodes.F_FULL; - n = frameLocalDiff = frameLocalCount = readUnsignedShort(stackMap); - stackMap += 2; - for (j = 0; n > 0; n--) { - stackMap = readFrameType(frameLocal, j++, stackMap, c, labels); - } - n = frameStackCount = readUnsignedShort(stackMap); - stackMap += 2; - for (j = 0; n > 0; n--) { - stackMap = readFrameType(frameStack, j++, stackMap, c, labels); - } - } - } - frameOffset += delta + 1; - readLabel(frameOffset, labels); - - --frameCount; - } else { - frameLocal = null; - } - } - - int opcode = b[v] & 0xFF; - switch (ClassWriter.TYPE[opcode]) { - case ClassWriter.NOARG_INSN: - mv.visitInsn(opcode); - v += 1; - break; - case ClassWriter.IMPLVAR_INSN: - if (opcode > Opcodes.ISTORE) { - opcode -= 59; // ISTORE_0 - mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2), opcode & 0x3); - } else { - opcode -= 26; // ILOAD_0 - mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), opcode & 0x3); - } - v += 1; - break; - case ClassWriter.LABEL_INSN: - mv.visitJumpInsn(opcode, labels[w + readShort(v + 1)]); - v += 3; - break; - case ClassWriter.LABELW_INSN: - mv.visitJumpInsn(opcode - 33, labels[w + readInt(v + 1)]); - v += 5; - break; - case ClassWriter.WIDE_INSN: - opcode = b[v + 1] & 0xFF; - if (opcode == Opcodes.IINC) { - mv.visitIincInsn(readUnsignedShort(v + 2), readShort(v + 4)); - v += 6; - } else { - mv.visitVarInsn(opcode, readUnsignedShort(v + 2)); - v += 4; - } - break; - case ClassWriter.TABL_INSN: - // skips 0 to 3 padding bytes - v = v + 4 - (w & 3); - // reads instruction - label = w + readInt(v); - int min = readInt(v + 4); - int max = readInt(v + 8); - v += 12; - Label[] table = new Label[max - min + 1]; - for (j = 0; j < table.length; ++j) { - table[j] = labels[w + readInt(v)]; - v += 4; - } - mv.visitTableSwitchInsn(min, max, labels[label], table); - break; - case ClassWriter.LOOK_INSN: - // skips 0 to 3 padding bytes - v = v + 4 - (w & 3); - // reads instruction - label = w + readInt(v); - j = readInt(v + 4); - v += 8; - int[] keys = new int[j]; - Label[] values = new Label[j]; - for (j = 0; j < keys.length; ++j) { - keys[j] = readInt(v); - values[j] = labels[w + readInt(v + 4)]; - v += 8; - } - mv.visitLookupSwitchInsn(labels[label], keys, values); - break; - case ClassWriter.VAR_INSN: - mv.visitVarInsn(opcode, b[v + 1] & 0xFF); - v += 2; - break; - case ClassWriter.SBYTE_INSN: - mv.visitIntInsn(opcode, b[v + 1]); - v += 2; - break; - case ClassWriter.SHORT_INSN: - mv.visitIntInsn(opcode, readShort(v + 1)); - v += 3; - break; - case ClassWriter.LDC_INSN: - mv.visitLdcInsn(readConst(b[v + 1] & 0xFF, c)); - v += 2; - break; - case ClassWriter.LDCW_INSN: - mv.visitLdcInsn(readConst(readUnsignedShort(v + 1), c)); - v += 3; - break; - case ClassWriter.FIELDORMETH_INSN: - case ClassWriter.ITFMETH_INSN: - int cpIndex = items[readUnsignedShort(v + 1)]; - String iowner = readClass(cpIndex, c); - cpIndex = items[readUnsignedShort(cpIndex + 2)]; - String iname = readUTF8(cpIndex, c); - String idesc = readUTF8(cpIndex + 2, c); - if (opcode < Opcodes.INVOKEVIRTUAL) { - mv.visitFieldInsn(opcode, iowner, iname, idesc); - } else { - mv.visitMethodInsn(opcode, iowner, iname, idesc); - } - if (opcode == Opcodes.INVOKEINTERFACE) { - v += 5; - } else { - v += 3; - } - break; - case ClassWriter.TYPE_INSN: - mv.visitTypeInsn(opcode, readClass(v + 1, c)); - v += 3; - break; - case ClassWriter.IINC_INSN: - mv.visitIincInsn(b[v + 1] & 0xFF, b[v + 2]); - v += 3; - break; - // case MANA_INSN: - default: - mv.visitMultiANewArrayInsn(readClass(v + 1, c), b[v + 3] & 0xFF); - v += 4; - break; - } - } - l = labels[codeEnd - codeStart]; - if (l != null) { - mv.visitLabel(l); - } - // visits the local variable tables - if (!skipDebug && varTable != 0) { - int[] typeTable = null; - if (varTypeTable != 0) { - k = readUnsignedShort(varTypeTable) * 3; - w = varTypeTable + 2; - typeTable = new int[k]; - while (k > 0) { - typeTable[--k] = w + 6; // signature - typeTable[--k] = readUnsignedShort(w + 8); // index - typeTable[--k] = readUnsignedShort(w); // start - w += 10; - } - } - k = readUnsignedShort(varTable); - w = varTable + 2; - for (; k > 0; --k) { - int start = readUnsignedShort(w); - int length = readUnsignedShort(w + 2); - int index = readUnsignedShort(w + 8); - String vsignature = null; - if (typeTable != null) { - for (int a = 0; a < typeTable.length; a += 3) { - if (typeTable[a] == start && typeTable[a + 1] == index) { - vsignature = readUTF8(typeTable[a + 2], c); - break; - } - } - } - mv.visitLocalVariable(readUTF8(w + 4, c), readUTF8(w + 6, c), vsignature, labels[start], - labels[start + length], index); - w += 10; - } - } - // visits the other attributes - while (cattrs != null) { - attr = cattrs.next; - cattrs.next = null; - mv.visitAttribute(cattrs); - cattrs = attr; - } - // visits the max stack and max locals values - mv.visitMaxs(maxStack, maxLocals); - } - - if (mv != null) { - mv.visitEnd(); - } - } - - // visits the end of the class - classVisitor.visitEnd(); - } - - /** - * Reads parameter annotations and makes the given visitor visit them. - * - * @param v start offset in {@link #b b} of the annotations to be read. - * @param desc the method descriptor. - * @param buf buffer to be used to call {@link #readUTF8 readUTF8}, - * {@link #readClass(int,char[]) readClass} or {@link #readConst - * readConst}. - * @param visible true if the annotations to be read are visible at - * runtime. - * @param mv the visitor that must visit the annotations. - */ - private void readParameterAnnotations(int v, final String desc, final char[] buf, final boolean visible, - final MethodVisitor mv) { - int i; - int n = b[v++] & 0xFF; - // workaround for a bug in javac (javac compiler generates a parameter - // annotation array whose size is equal to the number of parameters in - // the Java source file, while it should generate an array whose size is - // equal to the number of parameters in the method descriptor - which - // includes the synthetic parameters added by the compiler). This work- - // around supposes that the synthetic parameters are the first ones. - int synthetics = Type.getArgumentTypes(desc).length - n; - AnnotationVisitor av; - for (i = 0; i < synthetics; ++i) { - // virtual annotation to detect synthetic parameters in MethodWriter - av = mv.visitParameterAnnotation(i, "Ljava/lang/Synthetic;", false); - if (av != null) { - av.visitEnd(); - } - } - for (; i < n + synthetics; ++i) { - int j = readUnsignedShort(v); - v += 2; - for (; j > 0; --j) { - av = mv.visitParameterAnnotation(i, readUTF8(v, buf), visible); - v = readAnnotationValues(v + 2, buf, true, av); - } - } - } - - /** - * Reads the values of an annotation and makes the given visitor visit them. - * - * @param v the start offset in {@link #b b} of the values to be read - * (including the unsigned short that gives the number of - * values). - * @param buf buffer to be used to call {@link #readUTF8 readUTF8}, - * {@link #readClass(int,char[]) readClass} or {@link #readConst - * readConst}. - * @param named if the annotation values are named or not. - * @param av the visitor that must visit the values. - * @return the end offset of the annotation values. - */ - private int readAnnotationValues(int v, final char[] buf, final boolean named, final AnnotationVisitor av) { - int i = readUnsignedShort(v); - v += 2; - if (named) { - for (; i > 0; --i) { - v = readAnnotationValue(v + 2, buf, readUTF8(v, buf), av); - } - } else { - for (; i > 0; --i) { - v = readAnnotationValue(v, buf, null, av); - } - } - if (av != null) { - av.visitEnd(); - } - return v; - } - - /** - * Reads a value of an annotation and makes the given visitor visit it. - * - * @param v the start offset in {@link #b b} of the value to be read (not - * including the value name constant pool index). - * @param buf buffer to be used to call {@link #readUTF8 readUTF8}, - * {@link #readClass(int,char[]) readClass} or {@link #readConst - * readConst}. - * @param name the name of the value to be read. - * @param av the visitor that must visit the value. - * @return the end offset of the annotation value. - */ - private int readAnnotationValue(int v, final char[] buf, final String name, final AnnotationVisitor av) { - int i; - if (av == null) { - switch (b[v] & 0xFF) { - case 'e': // enum_const_value - return v + 5; - case '@': // annotation_value - return readAnnotationValues(v + 3, buf, true, null); - case '[': // array_value - return readAnnotationValues(v + 1, buf, false, null); - default: - return v + 3; - } - } - switch (b[v++] & 0xFF) { - case 'I': // pointer to CONSTANT_Integer - case 'J': // pointer to CONSTANT_Long - case 'F': // pointer to CONSTANT_Float - case 'D': // pointer to CONSTANT_Double - av.visit(name, readConst(readUnsignedShort(v), buf)); - v += 2; - break; - case 'B': // pointer to CONSTANT_Byte - av.visit(name, new Byte((byte) readInt(items[readUnsignedShort(v)]))); - v += 2; - break; - case 'Z': // pointer to CONSTANT_Boolean - av.visit(name, readInt(items[readUnsignedShort(v)]) == 0 ? Boolean.FALSE : Boolean.TRUE); - v += 2; - break; - case 'S': // pointer to CONSTANT_Short - av.visit(name, new Short((short) readInt(items[readUnsignedShort(v)]))); - v += 2; - break; - case 'C': // pointer to CONSTANT_Char - av.visit(name, new Character((char) readInt(items[readUnsignedShort(v)]))); - v += 2; - break; - case 's': // pointer to CONSTANT_Utf8 - av.visit(name, readUTF8(v, buf)); - v += 2; - break; - case 'e': // enum_const_value - av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf)); - v += 4; - break; - case 'c': // class_info - av.visit(name, Type.getType(readUTF8(v, buf))); - v += 2; - break; - case '@': // annotation_value - v = readAnnotationValues(v + 2, buf, true, av.visitAnnotation(name, readUTF8(v, buf))); - break; - case '[': // array_value - int size = readUnsignedShort(v); - v += 2; - if (size == 0) { - return readAnnotationValues(v - 2, buf, false, av.visitArray(name)); - } - switch (this.b[v++] & 0xFF) { - case 'B': - byte[] bv = new byte[size]; - for (i = 0; i < size; i++) { - bv[i] = (byte) readInt(items[readUnsignedShort(v)]); - v += 3; - } - av.visit(name, bv); - --v; - break; - case 'Z': - boolean[] zv = new boolean[size]; - for (i = 0; i < size; i++) { - zv[i] = readInt(items[readUnsignedShort(v)]) != 0; - v += 3; - } - av.visit(name, zv); - --v; - break; - case 'S': - short[] sv = new short[size]; - for (i = 0; i < size; i++) { - sv[i] = (short) readInt(items[readUnsignedShort(v)]); - v += 3; - } - av.visit(name, sv); - --v; - break; - case 'C': - char[] cv = new char[size]; - for (i = 0; i < size; i++) { - cv[i] = (char) readInt(items[readUnsignedShort(v)]); - v += 3; - } - av.visit(name, cv); - --v; - break; - case 'I': - int[] iv = new int[size]; - for (i = 0; i < size; i++) { - iv[i] = readInt(items[readUnsignedShort(v)]); - v += 3; - } - av.visit(name, iv); - --v; - break; - case 'J': - long[] lv = new long[size]; - for (i = 0; i < size; i++) { - lv[i] = readLong(items[readUnsignedShort(v)]); - v += 3; - } - av.visit(name, lv); - --v; - break; - case 'F': - float[] fv = new float[size]; - for (i = 0; i < size; i++) { - fv[i] = Float.intBitsToFloat(readInt(items[readUnsignedShort(v)])); - v += 3; - } - av.visit(name, fv); - --v; - break; - case 'D': - double[] dv = new double[size]; - for (i = 0; i < size; i++) { - dv[i] = Double.longBitsToDouble(readLong(items[readUnsignedShort(v)])); - v += 3; - } - av.visit(name, dv); - --v; - break; - default: - v = readAnnotationValues(v - 3, buf, false, av.visitArray(name)); - } - } - return v; - } - - private int readFrameType(final Object[] frame, final int index, int v, final char[] buf, final Label[] labels) { - int type = b[v++] & 0xFF; - switch (type) { - case 0: - frame[index] = Opcodes.TOP; - break; - case 1: - frame[index] = Opcodes.INTEGER; - break; - case 2: - frame[index] = Opcodes.FLOAT; - break; - case 3: - frame[index] = Opcodes.DOUBLE; - break; - case 4: - frame[index] = Opcodes.LONG; - break; - case 5: - frame[index] = Opcodes.NULL; - break; - case 6: - frame[index] = Opcodes.UNINITIALIZED_THIS; - break; - case 7: // Object - frame[index] = readClass(v, buf); - v += 2; - break; - default: // Uninitialized - frame[index] = readLabel(readUnsignedShort(v), labels); - v += 2; - } - return v; - } - - /** - * Returns the label corresponding to the given offset. The default - * implementation of this method creates a label for the given offset if it - * has not been already created. - * - * @param offset a bytecode offset in a method. - * @param labels the already created labels, indexed by their offset. If a - * label already exists for offset this method must not create a - * new one. Otherwise it must store the new label in this array. - * @return a non null Label, which must be equal to labels[offset]. - */ - protected Label readLabel(int offset, Label[] labels) { - if (labels[offset] == null) { - labels[offset] = new Label(); - } - return labels[offset]; - } - - /** - * Reads an attribute in {@link #b b}. - * - * @param attrs prototypes of the attributes that must be parsed during the - * visit of the class. Any attribute whose type is not equal to - * the type of one the prototypes is ignored (i.e. an empty - * {@link Attribute} instance is returned). - * @param type the type of the attribute. - * @param off index of the first byte of the attribute's content in - * {@link #b b}. The 6 attribute header bytes, containing the - * type and the length of the attribute, are not taken into - * account here (they have already been read). - * @param len the length of the attribute's content. - * @param buf buffer to be used to call {@link #readUTF8 readUTF8}, - * {@link #readClass(int,char[]) readClass} or {@link #readConst - * readConst}. - * @param codeOff index of the first byte of code's attribute content in - * {@link #b b}, or -1 if the attribute to be read is not a code - * attribute. The 6 attribute header bytes, containing the type - * and the length of the attribute, are not taken into account - * here. - * @param labels the labels of the method's code, or null if the - * attribute to be read is not a code attribute. - * @return the attribute that has been read, or null to skip this - * attribute. - */ - private Attribute readAttribute(final Attribute[] attrs, final String type, final int off, final int len, - final char[] buf, final int codeOff, final Label[] labels) { - for (int i = 0; i < attrs.length; ++i) { - if (attrs[i].type.equals(type)) { - return attrs[i].read(this, off, len, buf, codeOff, labels); - } - } - return new Attribute(type).read(this, off, len, null, -1, null); - } - - // ------------------------------------------------------------------------ - // Utility methods: low level parsing - // ------------------------------------------------------------------------ - - /** - * Returns the start index of the constant pool item in {@link #b b}, plus - * one. This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @param item the index a constant pool item. - * @return the start index of the constant pool item in {@link #b b}, plus - * one. - */ - public int getItem(final int item) { - return items[item]; - } - - /** - * Reads a byte value in {@link #b b}. This method is intended for - * {@link Attribute} sub classes, and is normally not needed by class - * generators or adapters. - * - * @param index the start index of the value to be read in {@link #b b}. - * @return the read value. - */ - public int readByte(final int index) { - return b[index] & 0xFF; - } - - /** - * Reads an unsigned short value in {@link #b b}. This method is intended - * for {@link Attribute} sub classes, and is normally not needed by class - * generators or adapters. - * - * @param index the start index of the value to be read in {@link #b b}. - * @return the read value. - */ - public int readUnsignedShort(final int index) { - byte[] b = this.b; - return (b[index] & 0xFF) << 8 | b[index + 1] & 0xFF; - } - - /** - * Reads a signed short value in {@link #b b}. This method is intended - * for {@link Attribute} sub classes, and is normally not needed by class - * generators or adapters. - * - * @param index the start index of the value to be read in {@link #b b}. - * @return the read value. - */ - public short readShort(final int index) { - byte[] b = this.b; - return (short) ((b[index] & 0xFF) << 8 | b[index + 1] & 0xFF); - } - - /** - * Reads a signed int value in {@link #b b}. This method is intended for - * {@link Attribute} sub classes, and is normally not needed by class - * generators or adapters. - * - * @param index the start index of the value to be read in {@link #b b}. - * @return the read value. - */ - public int readInt(final int index) { - byte[] b = this.b; - return (b[index] & 0xFF) << 24 | (b[index + 1] & 0xFF) << 16 | (b[index + 2] & 0xFF) << 8 | b[index + 3] & 0xFF; - } - - /** - * Reads a signed long value in {@link #b b}. This method is intended for - * {@link Attribute} sub classes, and is normally not needed by class - * generators or adapters. - * - * @param index the start index of the value to be read in {@link #b b}. - * @return the read value. - */ - public long readLong(final int index) { - long l1 = readInt(index); - long l0 = readInt(index + 4) & 0xFFFFFFFFL; - return l1 << 32 | l0; - } - - /** - * Reads an UTF8 string constant pool item in {@link #b b}. This method - * is intended for {@link Attribute} sub classes, and is normally not needed - * by class generators or adapters. - * - * @param index the start index of an unsigned short value in {@link #b b}, - * whose value is the index of an UTF8 constant pool item. - * @param buf buffer to be used to read the item. This buffer must be - * sufficiently large. It is not automatically resized. - * @return the String corresponding to the specified UTF8 item. - */ - public String readUTF8(int index, final char[] buf) { - int item = readUnsignedShort(index); - String s = strings[item]; - if (s != null) { - return s; - } - index = items[item]; - return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf); - } - - /** - * Reads UTF8 string in {@link #b b}. - * - * @param index start offset of the UTF8 string to be read. - * @param utfLen length of the UTF8 string to be read. - * @param buf buffer to be used to read the string. This buffer must be - * sufficiently large. It is not automatically resized. - * @return the String corresponding to the specified UTF8 string. - */ - private String readUTF(int index, final int utfLen, final char[] buf) { - int endIndex = index + utfLen; - byte[] b = this.b; - int strLen = 0; - int c, d, e; - while (index < endIndex) { - c = b[index++] & 0xFF; - switch (c >> 4) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - // 0xxxxxxx - buf[strLen++] = (char) c; - break; - case 12: - case 13: - // 110x xxxx 10xx xxxx - d = b[index++]; - buf[strLen++] = (char) ((c & 0x1F) << 6 | d & 0x3F); - break; - default: - // 1110 xxxx 10xx xxxx 10xx xxxx - d = b[index++]; - e = b[index++]; - buf[strLen++] = (char) ((c & 0x0F) << 12 | (d & 0x3F) << 6 | e & 0x3F); - break; - } - } - return new String(buf, 0, strLen); - } - - /** - * Reads a class constant pool item in {@link #b b}. This method is - * intended for {@link Attribute} sub classes, and is normally not needed by - * class generators or adapters. - * - * @param index the start index of an unsigned short value in {@link #b b}, - * whose value is the index of a class constant pool item. - * @param buf buffer to be used to read the item. This buffer must be - * sufficiently large. It is not automatically resized. - * @return the String corresponding to the specified class item. - */ - public String readClass(final int index, final char[] buf) { - // computes the start index of the CONSTANT_Class item in b - // and reads the CONSTANT_Utf8 item designated by - // the first two bytes of this CONSTANT_Class item - return readUTF8(items[readUnsignedShort(index)], buf); - } - - /** - * Reads a numeric or string constant pool item in {@link #b b}. This - * method is intended for {@link Attribute} sub classes, and is normally not - * needed by class generators or adapters. - * - * @param item the index of a constant pool item. - * @param buf buffer to be used to read the item. This buffer must be - * sufficiently large. It is not automatically resized. - * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double}, - * {@link String} or {@link Type} corresponding to the given - * constant pool item. - */ - public Object readConst(final int item, final char[] buf) { - int index = items[item]; - switch (b[index - 1]) { - case ClassWriter.INT: - return new Integer(readInt(index)); - case ClassWriter.FLOAT: - return new Float(Float.intBitsToFloat(readInt(index))); - case ClassWriter.LONG: - return new Long(readLong(index)); - case ClassWriter.DOUBLE: - return new Double(Double.longBitsToDouble(readLong(index))); - case ClassWriter.CLASS: - return Type.getObjectType(readUTF8(index, buf)); - // case ClassWriter.STR: - default: - return readUTF8(index, buf); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/ClassVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/ClassVisitor.java deleted file mode 100644 index b0b68c1cb..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/ClassVisitor.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * A visitor to visit a Java class. The methods of this interface must be called - * in the following order: visit [ visitSource ] [ - * visitOuterClass ] ( visitAnnotation | - * visitAttribute )* (visitInnerClass | visitField | - * visitMethod )* visitEnd. - * - * @author Eric Bruneton - */ -public interface ClassVisitor { - - /** - * Visits the header of the class. - * - * @param version the class version. - * @param access the class's access flags (see {@link Opcodes}). This - * parameter also indicates if the class is deprecated. - * @param name the internal name of the class (see - * {@link Type#getInternalName() getInternalName}). - * @param signature the signature of this class. May be null if the - * class is not a generic one, and does not extend or implement - * generic classes or interfaces. - * @param superName the internal of name of the super class (see - * {@link Type#getInternalName() getInternalName}). For - * interfaces, the super class is {@link Object}. May be - * null, but only for the {@link Object} class. - * @param interfaces the internal names of the class's interfaces (see - * {@link Type#getInternalName() getInternalName}). May be - * null. - */ - void visit(int version, int access, String name, String signature, String superName, String[] interfaces); - - /** - * Visits the source of the class. - * - * @param source the name of the source file from which the class was - * compiled. May be null. - * @param debug additional debug information to compute the correspondance - * between source and compiled elements of the class. May be - * null. - */ - void visitSource(String source, String debug); - - /** - * Visits the enclosing class of the class. This method must be called only - * if the class has an enclosing class. - * - * @param owner internal name of the enclosing class of the class. - * @param name the name of the method that contains the class, or - * null if the class is not enclosed in a method of its - * enclosing class. - * @param desc the descriptor of the method that contains the class, or - * null if the class is not enclosed in a method of its - * enclosing class. - */ - void visitOuterClass(String owner, String name, String desc); - - /** - * Visits an annotation of the class. - * - * @param desc the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if - * this visitor is not interested in visiting this annotation. - */ - AnnotationVisitor visitAnnotation(String desc, boolean visible); - - /** - * Visits a non standard attribute of the class. - * - * @param attr an attribute. - */ - void visitAttribute(Attribute attr); - - /** - * Visits information about an inner class. This inner class is not - * necessarily a member of the class being visited. - * - * @param name the internal name of an inner class (see - * {@link Type#getInternalName() getInternalName}). - * @param outerName the internal name of the class to which the inner class - * belongs (see {@link Type#getInternalName() getInternalName}). - * May be null for not member classes. - * @param innerName the (simple) name of the inner class inside its - * enclosing class. May be null for anonymous inner - * classes. - * @param access the access flags of the inner class as originally declared - * in the enclosing class. - */ - void visitInnerClass(String name, String outerName, String innerName, int access); - - /** - * Visits a field of the class. - * - * @param access the field's access flags (see {@link Opcodes}). This - * parameter also indicates if the field is synthetic and/or - * deprecated. - * @param name the field's name. - * @param desc the field's descriptor (see {@link Type Type}). - * @param signature the field's signature. May be null if the - * field's type does not use generic types. - * @param value the field's initial value. This parameter, which may be - * null if the field does not have an initial value, - * must be an {@link Integer}, a {@link Float}, a {@link Long}, a - * {@link Double} or a {@link String} (for int, - * float, long or String fields - * respectively). This parameter is only used for static - * fields. Its value is ignored for non static fields, which - * must be initialized through bytecode instructions in - * constructors or methods. - * @return a visitor to visit field annotations and attributes, or - * null if this class visitor is not interested in visiting - * these annotations and attributes. - */ - FieldVisitor visitField(int access, String name, String desc, String signature, Object value); - - /** - * Visits a method of the class. This method must return a new - * {@link MethodVisitor} instance (or null) each time it is called, - * i.e., it should not return a previously returned visitor. - * - * @param access the method's access flags (see {@link Opcodes}). This - * parameter also indicates if the method is synthetic and/or - * deprecated. - * @param name the method's name. - * @param desc the method's descriptor (see {@link Type Type}). - * @param signature the method's signature. May be null if the - * method parameters, return type and exceptions do not use - * generic types. - * @param exceptions the internal names of the method's exception classes - * (see {@link Type#getInternalName() getInternalName}). May be - * null. - * @return an object to visit the byte code of the method, or null - * if this class visitor is not interested in visiting the code of - * this method. - */ - MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions); - - /** - * Visits the end of the class. This method, which is the last one to be - * called, is used to inform the visitor that all the fields and methods of - * the class have been visited. - */ - void visitEnd(); -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/ClassWriter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/ClassWriter.java deleted file mode 100644 index 69dc96dac..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/ClassWriter.java +++ /dev/null @@ -1,1310 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * A {@link ClassVisitor} that generates classes in bytecode form. More - * precisely this visitor generates a byte array conforming to the Java class - * file format. It can be used alone, to generate a Java class "from scratch", - * or with one or more {@link ClassReader ClassReader} and adapter class visitor - * to generate a modified class from one or more existing Java classes. - * - * @author Eric Bruneton - */ -public class ClassWriter implements ClassVisitor { - - /** - * Flag to automatically compute the maximum stack size and the maximum - * number of local variables of methods. If this flag is set, then the - * arguments of the {@link MethodVisitor#visitMaxs visitMaxs} method of the - * {@link MethodVisitor} returned by the {@link #visitMethod visitMethod} - * method will be ignored, and computed automatically from the signature and - * the bytecode of each method. - * - * @see #ClassWriter(int) - */ - public static final int COMPUTE_MAXS = 1; - - /** - * Flag to automatically compute the stack map frames of methods from - * scratch. If this flag is set, then the calls to the - * {@link MethodVisitor#visitFrame} method are ignored, and the stack map - * frames are recomputed from the methods bytecode. The arguments of the - * {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and - * recomputed from the bytecode. In other words, computeFrames implies - * computeMaxs. - * - * @see #ClassWriter(int) - */ - public static final int COMPUTE_FRAMES = 2; - - /** - * The type of instructions without any argument. - */ - static final int NOARG_INSN = 0; - - /** - * The type of instructions with an signed byte argument. - */ - static final int SBYTE_INSN = 1; - - /** - * The type of instructions with an signed short argument. - */ - static final int SHORT_INSN = 2; - - /** - * The type of instructions with a local variable index argument. - */ - static final int VAR_INSN = 3; - - /** - * The type of instructions with an implicit local variable index argument. - */ - static final int IMPLVAR_INSN = 4; - - /** - * The type of instructions with a type descriptor argument. - */ - static final int TYPE_INSN = 5; - - /** - * The type of field and method invocations instructions. - */ - static final int FIELDORMETH_INSN = 6; - - /** - * The type of the INVOKEINTERFACE instruction. - */ - static final int ITFMETH_INSN = 7; - - /** - * The type of instructions with a 2 bytes bytecode offset label. - */ - static final int LABEL_INSN = 8; - - /** - * The type of instructions with a 4 bytes bytecode offset label. - */ - static final int LABELW_INSN = 9; - - /** - * The type of the LDC instruction. - */ - static final int LDC_INSN = 10; - - /** - * The type of the LDC_W and LDC2_W instructions. - */ - static final int LDCW_INSN = 11; - - /** - * The type of the IINC instruction. - */ - static final int IINC_INSN = 12; - - /** - * The type of the TABLESWITCH instruction. - */ - static final int TABL_INSN = 13; - - /** - * The type of the LOOKUPSWITCH instruction. - */ - static final int LOOK_INSN = 14; - - /** - * The type of the MULTIANEWARRAY instruction. - */ - static final int MANA_INSN = 15; - - /** - * The type of the WIDE instruction. - */ - static final int WIDE_INSN = 16; - - /** - * The instruction types of all JVM opcodes. - */ - static final byte[] TYPE; - - /** - * The type of CONSTANT_Class constant pool items. - */ - static final int CLASS = 7; - - /** - * The type of CONSTANT_Fieldref constant pool items. - */ - static final int FIELD = 9; - - /** - * The type of CONSTANT_Methodref constant pool items. - */ - static final int METH = 10; - - /** - * The type of CONSTANT_InterfaceMethodref constant pool items. - */ - static final int IMETH = 11; - - /** - * The type of CONSTANT_String constant pool items. - */ - static final int STR = 8; - - /** - * The type of CONSTANT_Integer constant pool items. - */ - static final int INT = 3; - - /** - * The type of CONSTANT_Float constant pool items. - */ - static final int FLOAT = 4; - - /** - * The type of CONSTANT_Long constant pool items. - */ - static final int LONG = 5; - - /** - * The type of CONSTANT_Double constant pool items. - */ - static final int DOUBLE = 6; - - /** - * The type of CONSTANT_NameAndType constant pool items. - */ - static final int NAME_TYPE = 12; - - /** - * The type of CONSTANT_Utf8 constant pool items. - */ - static final int UTF8 = 1; - - /** - * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable}, - * instead of the constant pool, in order to avoid clashes with normal - * constant pool items in the ClassWriter constant pool's hash table. - */ - static final int TYPE_NORMAL = 13; - - /** - * Uninitialized type Item stored in the ClassWriter - * {@link ClassWriter#typeTable}, instead of the constant pool, in order to - * avoid clashes with normal constant pool items in the ClassWriter constant - * pool's hash table. - */ - static final int TYPE_UNINIT = 14; - - /** - * Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable}, - * instead of the constant pool, in order to avoid clashes with normal - * constant pool items in the ClassWriter constant pool's hash table. - */ - static final int TYPE_MERGED = 15; - - /** - * The class reader from which this class writer was constructed, if any. - */ - ClassReader cr; - - /** - * Minor and major version numbers of the class to be generated. - */ - int version; - - /** - * Index of the next item to be added in the constant pool. - */ - int index; - - /** - * The constant pool of this class. - */ - final ByteVector pool; - - /** - * The constant pool's hash table data. - */ - Item[] items; - - /** - * The threshold of the constant pool's hash table. - */ - int threshold; - - /** - * A reusable key used to look for items in the {@link #items} hash table. - */ - final Item key; - - /** - * A reusable key used to look for items in the {@link #items} hash table. - */ - final Item key2; - - /** - * A reusable key used to look for items in the {@link #items} hash table. - */ - final Item key3; - - /** - * A type table used to temporarily store internal names that will not - * necessarily be stored in the constant pool. This type table is used by - * the control flow and data flow analysis algorithm used to compute stack - * map frames from scratch. This array associates to each index i - * the Item whose index is i. All Item objects stored in this array - * are also stored in the {@link #items} hash table. These two arrays allow - * to retrieve an Item from its index or, conversely, to get the index of an - * Item from its value. Each Item stores an internal name in its - * {@link Item#strVal1} field. - */ - Item[] typeTable; - - /** - * Number of elements in the {@link #typeTable} array. - */ - private short typeCount; - - /** - * The access flags of this class. - */ - private int access; - - /** - * The constant pool item that contains the internal name of this class. - */ - private int name; - - /** - * The internal name of this class. - */ - String thisName; - - /** - * The constant pool item that contains the signature of this class. - */ - private int signature; - - /** - * The constant pool item that contains the internal name of the super class - * of this class. - */ - private int superName; - - /** - * Number of interfaces implemented or extended by this class or interface. - */ - private int interfaceCount; - - /** - * The interfaces implemented or extended by this class or interface. More - * precisely, this array contains the indexes of the constant pool items - * that contain the internal names of these interfaces. - */ - private int[] interfaces; - - /** - * The index of the constant pool item that contains the name of the source - * file from which this class was compiled. - */ - private int sourceFile; - - /** - * The SourceDebug attribute of this class. - */ - private ByteVector sourceDebug; - - /** - * The constant pool item that contains the name of the enclosing class of - * this class. - */ - private int enclosingMethodOwner; - - /** - * The constant pool item that contains the name and descriptor of the - * enclosing method of this class. - */ - private int enclosingMethod; - - /** - * The runtime visible annotations of this class. - */ - private AnnotationWriter anns; - - /** - * The runtime invisible annotations of this class. - */ - private AnnotationWriter ianns; - - /** - * The non standard attributes of this class. - */ - private Attribute attrs; - - /** - * The number of entries in the InnerClasses attribute. - */ - private int innerClassesCount; - - /** - * The InnerClasses attribute. - */ - private ByteVector innerClasses; - - /** - * The fields of this class. These fields are stored in a linked list of - * {@link FieldWriter} objects, linked to each other by their - * {@link FieldWriter#next} field. This field stores the first element of - * this list. - */ - FieldWriter firstField; - - /** - * The fields of this class. These fields are stored in a linked list of - * {@link FieldWriter} objects, linked to each other by their - * {@link FieldWriter#next} field. This field stores the last element of - * this list. - */ - FieldWriter lastField; - - /** - * The methods of this class. These methods are stored in a linked list of - * {@link MethodWriter} objects, linked to each other by their - * {@link MethodWriter#next} field. This field stores the first element of - * this list. - */ - MethodWriter firstMethod; - - /** - * The methods of this class. These methods are stored in a linked list of - * {@link MethodWriter} objects, linked to each other by their - * {@link MethodWriter#next} field. This field stores the last element of - * this list. - */ - MethodWriter lastMethod; - - /** - * true if the maximum stack size and number of local variables - * must be automatically computed. - */ - private final boolean computeMaxs; - - /** - * true if the stack map frames must be recomputed from scratch. - */ - private final boolean computeFrames; - - /** - * true if the stack map tables of this class are invalid. The - * {@link MethodWriter#resizeInstructions} method cannot transform existing - * stack map tables, and so produces potentially invalid classes when it is - * executed. In this case the class is reread and rewritten with the - * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize - * stack map tables when this option is used). - */ - boolean invalidFrames; - - // ------------------------------------------------------------------------ - // Static initializer - // ------------------------------------------------------------------------ - - /** - * Computes the instruction types of JVM opcodes. - */ - static { - int i; - byte[] b = new byte[220]; - String s = "AAAAAAAAAAAAAAAABCKLLDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD" - + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAIIIIIIIIIIIIIIIIDNOAA" - + "AAAAGGGGGGGHAFBFAAFFAAQPIIJJIIIIIIIIIIIIIIIIII"; - for (i = 0; i < b.length; ++i) { - b[i] = (byte) (s.charAt(i) - 'A'); - } - TYPE = b; - - // code to generate the above string - // - // // SBYTE_INSN instructions - // b[Constants.NEWARRAY] = SBYTE_INSN; - // b[Constants.BIPUSH] = SBYTE_INSN; - // - // // SHORT_INSN instructions - // b[Constants.SIPUSH] = SHORT_INSN; - // - // // (IMPL)VAR_INSN instructions - // b[Constants.RET] = VAR_INSN; - // for (i = Constants.ILOAD; i <= Constants.ALOAD; ++i) { - // b[i] = VAR_INSN; - // } - // for (i = Constants.ISTORE; i <= Constants.ASTORE; ++i) { - // b[i] = VAR_INSN; - // } - // for (i = 26; i <= 45; ++i) { // ILOAD_0 to ALOAD_3 - // b[i] = IMPLVAR_INSN; - // } - // for (i = 59; i <= 78; ++i) { // ISTORE_0 to ASTORE_3 - // b[i] = IMPLVAR_INSN; - // } - // - // // TYPE_INSN instructions - // b[Constants.NEW] = TYPE_INSN; - // b[Constants.ANEWARRAY] = TYPE_INSN; - // b[Constants.CHECKCAST] = TYPE_INSN; - // b[Constants.INSTANCEOF] = TYPE_INSN; - // - // // (Set)FIELDORMETH_INSN instructions - // for (i = Constants.GETSTATIC; i <= Constants.INVOKESTATIC; ++i) { - // b[i] = FIELDORMETH_INSN; - // } - // b[Constants.INVOKEINTERFACE] = ITFMETH_INSN; - // - // // LABEL(W)_INSN instructions - // for (i = Constants.IFEQ; i <= Constants.JSR; ++i) { - // b[i] = LABEL_INSN; - // } - // b[Constants.IFNULL] = LABEL_INSN; - // b[Constants.IFNONNULL] = LABEL_INSN; - // b[200] = LABELW_INSN; // GOTO_W - // b[201] = LABELW_INSN; // JSR_W - // // temporary opcodes used internally by ASM - see Label and - // MethodWriter - // for (i = 202; i < 220; ++i) { - // b[i] = LABEL_INSN; - // } - // - // // LDC(_W) instructions - // b[Constants.LDC] = LDC_INSN; - // b[19] = LDCW_INSN; // LDC_W - // b[20] = LDCW_INSN; // LDC2_W - // - // // special instructions - // b[Constants.IINC] = IINC_INSN; - // b[Constants.TABLESWITCH] = TABL_INSN; - // b[Constants.LOOKUPSWITCH] = LOOK_INSN; - // b[Constants.MULTIANEWARRAY] = MANA_INSN; - // b[196] = WIDE_INSN; // WIDE - // - // for (i = 0; i < b.length; ++i) { - // System.err.print((char)('A' + b[i])); - // } - // System.err.println(); - } - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructs a new {@link ClassWriter} object. - * - * @param flags option flags that can be used to modify the default behavior - * of this class. See {@link #COMPUTE_MAXS}, - * {@link #COMPUTE_FRAMES}. - */ - public ClassWriter(final int flags) { - index = 1; - pool = new ByteVector(); - items = new Item[256]; - threshold = (int) (0.75d * items.length); - key = new Item(); - key2 = new Item(); - key3 = new Item(); - this.computeMaxs = (flags & COMPUTE_MAXS) != 0; - this.computeFrames = (flags & COMPUTE_FRAMES) != 0; - } - - /** - * Constructs a new {@link ClassWriter} object and enables optimizations for - * "mostly add" bytecode transformations. These optimizations are the - * following: - *
    - *
  • The constant pool from the original class is copied as is in the new - * class, which saves time. New constant pool entries will be added at the - * end if necessary, but unused constant pool entries won't be - * removed.
  • - *
  • Methods that are not transformed are copied as is in the new class, - * directly from the original class bytecode (i.e. without emitting visit - * events for all the method instructions), which saves a lot of - * time. Untransformed methods are detected by the fact that the - * {@link ClassReader} receives {@link MethodVisitor} objects that come from - * a {@link ClassWriter} (and not from a custom {@link ClassAdapter} or any - * other {@link ClassVisitor} instance).
  • - *
- * - * @param classReader the {@link ClassReader} used to read the original - * class. It will be used to copy the entire constant pool from - * the original class and also to copy other fragments of - * original bytecode where applicable. - * @param flags option flags that can be used to modify the default behavior - * of this class. See {@link #COMPUTE_MAXS}, - * {@link #COMPUTE_FRAMES}. - */ - public ClassWriter(final ClassReader classReader, final int flags) { - this(flags); - classReader.copyPool(this); - this.cr = classReader; - } - - // ------------------------------------------------------------------------ - // Implementation of the ClassVisitor interface - // ------------------------------------------------------------------------ - - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - this.version = version; - this.access = access; - this.name = newClass(name); - thisName = name; - if (ClassReader.SIGNATURES && signature != null) { - this.signature = newUTF8(signature); - } - this.superName = superName == null ? 0 : newClass(superName); - if (interfaces != null && interfaces.length > 0) { - interfaceCount = interfaces.length; - this.interfaces = new int[interfaceCount]; - for (int i = 0; i < interfaceCount; ++i) { - this.interfaces[i] = newClass(interfaces[i]); - } - } - } - - public void visitSource(final String file, final String debug) { - if (file != null) { - sourceFile = newUTF8(file); - } - if (debug != null) { - sourceDebug = new ByteVector().putUTF8(debug); - } - } - - public void visitOuterClass(final String owner, final String name, final String desc) { - enclosingMethodOwner = newClass(owner); - if (name != null && desc != null) { - enclosingMethod = newNameType(name, desc); - } - } - - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write type, and reserve space for values count - bv.putShort(newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, 2); - if (visible) { - aw.next = anns; - anns = aw; - } else { - aw.next = ianns; - ianns = aw; - } - return aw; - } - - public void visitAttribute(final Attribute attr) { - attr.next = attrs; - attrs = attr; - } - - public void visitInnerClass(final String name, final String outerName, final String innerName, final int access) { - if (innerClasses == null) { - innerClasses = new ByteVector(); - } - ++innerClassesCount; - innerClasses.putShort(name == null ? 0 : newClass(name)); - innerClasses.putShort(outerName == null ? 0 : newClass(outerName)); - innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName)); - innerClasses.putShort(access); - } - - public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, - final Object value) { - return new FieldWriter(this, access, name, desc, signature, value); - } - - public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, - final String[] exceptions) { - return new MethodWriter(this, access, name, desc, signature, exceptions, computeMaxs, computeFrames); - } - - public void visitEnd() { - } - - // ------------------------------------------------------------------------ - // Other public methods - // ------------------------------------------------------------------------ - - /** - * Returns the bytecode of the class that was build with this class writer. - * - * @return the bytecode of the class that was build with this class writer. - */ - public byte[] toByteArray() { - // computes the real size of the bytecode of this class - int size = 24 + 2 * interfaceCount; - int nbFields = 0; - FieldWriter fb = firstField; - while (fb != null) { - ++nbFields; - size += fb.getSize(); - fb = fb.next; - } - int nbMethods = 0; - MethodWriter mb = firstMethod; - while (mb != null) { - ++nbMethods; - size += mb.getSize(); - mb = mb.next; - } - int attributeCount = 0; - if (ClassReader.SIGNATURES && signature != 0) { - ++attributeCount; - size += 8; - newUTF8("Signature"); - } - if (sourceFile != 0) { - ++attributeCount; - size += 8; - newUTF8("SourceFile"); - } - if (sourceDebug != null) { - ++attributeCount; - size += sourceDebug.length + 4; - newUTF8("SourceDebugExtension"); - } - if (enclosingMethodOwner != 0) { - ++attributeCount; - size += 10; - newUTF8("EnclosingMethod"); - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - ++attributeCount; - size += 6; - newUTF8("Deprecated"); - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0 && (version & 0xffff) < Opcodes.V1_5) { - ++attributeCount; - size += 6; - newUTF8("Synthetic"); - } - if (innerClasses != null) { - ++attributeCount; - size += 8 + innerClasses.length; - newUTF8("InnerClasses"); - } - if (ClassReader.ANNOTATIONS && anns != null) { - ++attributeCount; - size += 8 + anns.getSize(); - newUTF8("RuntimeVisibleAnnotations"); - } - if (ClassReader.ANNOTATIONS && ianns != null) { - ++attributeCount; - size += 8 + ianns.getSize(); - newUTF8("RuntimeInvisibleAnnotations"); - } - if (attrs != null) { - attributeCount += attrs.getCount(); - size += attrs.getSize(this, null, 0, -1, -1); - } - size += pool.length; - // allocates a byte vector of this size, in order to avoid unnecessary - // arraycopy operations in the ByteVector.enlarge() method - ByteVector out = new ByteVector(size); - out.putInt(0xCAFEBABE).putInt(version); - out.putShort(index).putByteArray(pool.data, 0, pool.length); - out.putShort(access).putShort(name).putShort(superName); - out.putShort(interfaceCount); - for (int i = 0; i < interfaceCount; ++i) { - out.putShort(interfaces[i]); - } - out.putShort(nbFields); - fb = firstField; - while (fb != null) { - fb.put(out); - fb = fb.next; - } - out.putShort(nbMethods); - mb = firstMethod; - while (mb != null) { - mb.put(out); - mb = mb.next; - } - out.putShort(attributeCount); - if (ClassReader.SIGNATURES && signature != 0) { - out.putShort(newUTF8("Signature")).putInt(2).putShort(signature); - } - if (sourceFile != 0) { - out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile); - } - if (sourceDebug != null) { - int len = sourceDebug.length - 2; - out.putShort(newUTF8("SourceDebugExtension")).putInt(len); - out.putByteArray(sourceDebug.data, 2, len); - } - if (enclosingMethodOwner != 0) { - out.putShort(newUTF8("EnclosingMethod")).putInt(4); - out.putShort(enclosingMethodOwner).putShort(enclosingMethod); - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - out.putShort(newUTF8("Deprecated")).putInt(0); - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0 && (version & 0xffff) < Opcodes.V1_5) { - out.putShort(newUTF8("Synthetic")).putInt(0); - } - if (innerClasses != null) { - out.putShort(newUTF8("InnerClasses")); - out.putInt(innerClasses.length + 2).putShort(innerClassesCount); - out.putByteArray(innerClasses.data, 0, innerClasses.length); - } - if (ClassReader.ANNOTATIONS && anns != null) { - out.putShort(newUTF8("RuntimeVisibleAnnotations")); - anns.put(out); - } - if (ClassReader.ANNOTATIONS && ianns != null) { - out.putShort(newUTF8("RuntimeInvisibleAnnotations")); - ianns.put(out); - } - if (attrs != null) { - attrs.put(this, null, 0, -1, -1, out); - } - if (invalidFrames) { - ClassWriter cw = new ClassWriter(COMPUTE_FRAMES); - new ClassReader(out.data).accept(cw, ClassReader.SKIP_FRAMES); - return cw.toByteArray(); - } - return out.data; - } - - // ------------------------------------------------------------------------ - // Utility methods: constant pool management - // ------------------------------------------------------------------------ - - /** - * Adds a number or string constant to the constant pool of the class being - * build. Does nothing if the constant pool already contains a similar item. - * - * @param cst the value of the constant to be added to the constant pool. - * This parameter must be an {@link Integer}, a {@link Float}, a - * {@link Long}, a {@link Double}, a {@link String} or a - * {@link Type}. - * @return a new or already existing constant item with the given value. - */ - Item newConstItem(final Object cst) { - if (cst instanceof Integer) { - int val = ((Integer) cst).intValue(); - return newInteger(val); - } else if (cst instanceof Byte) { - int val = ((Byte) cst).intValue(); - return newInteger(val); - } else if (cst instanceof Character) { - int val = ((Character) cst).charValue(); - return newInteger(val); - } else if (cst instanceof Short) { - int val = ((Short) cst).intValue(); - return newInteger(val); - } else if (cst instanceof Boolean) { - int val = ((Boolean) cst).booleanValue() ? 1 : 0; - return newInteger(val); - } else if (cst instanceof Float) { - float val = ((Float) cst).floatValue(); - return newFloat(val); - } else if (cst instanceof Long) { - long val = ((Long) cst).longValue(); - return newLong(val); - } else if (cst instanceof Double) { - double val = ((Double) cst).doubleValue(); - return newDouble(val); - } else if (cst instanceof String) { - return newString((String) cst); - } else if (cst instanceof Type) { - Type t = (Type) cst; - return newClassItem(t.getSort() == Type.OBJECT ? t.getInternalName() : t.getDescriptor()); - } else { - throw new IllegalArgumentException("value " + cst); - } - } - - /** - * Adds a number or string constant to the constant pool of the class being - * build. Does nothing if the constant pool already contains a similar item. - * This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @param cst the value of the constant to be added to the constant pool. - * This parameter must be an {@link Integer}, a {@link Float}, a - * {@link Long}, a {@link Double} or a {@link String}. - * @return the index of a new or already existing constant item with the - * given value. - */ - public int newConst(final Object cst) { - return newConstItem(cst).index; - } - - /** - * Adds an UTF8 string to the constant pool of the class being build. Does - * nothing if the constant pool already contains a similar item. This - * method is intended for {@link Attribute} sub classes, and is normally not - * needed by class generators or adapters. - * - * @param value the String value. - * @return the index of a new or already existing UTF8 item. - */ - public int newUTF8(final String value) { - key.set(UTF8, value, null, null); - Item result = get(key); - if (result == null) { - pool.putByte(UTF8).putUTF8(value); - result = new Item(index++, key); - put(result); - } - return result.index; - } - - /** - * Adds a class reference to the constant pool of the class being build. - * Does nothing if the constant pool already contains a similar item. - * This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @param value the internal name of the class. - * @return a new or already existing class reference item. - */ - Item newClassItem(final String value) { - key2.set(CLASS, value, null, null); - Item result = get(key2); - if (result == null) { - pool.put12(CLASS, newUTF8(value)); - result = new Item(index++, key2); - put(result); - } - return result; - } - - /** - * Adds a class reference to the constant pool of the class being build. - * Does nothing if the constant pool already contains a similar item. - * This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @param value the internal name of the class. - * @return the index of a new or already existing class reference item. - */ - public int newClass(final String value) { - return newClassItem(value).index; - } - - /** - * Adds a field reference to the constant pool of the class being build. - * Does nothing if the constant pool already contains a similar item. - * - * @param owner the internal name of the field's owner class. - * @param name the field's name. - * @param desc the field's descriptor. - * @return a new or already existing field reference item. - */ - Item newFieldItem(final String owner, final String name, final String desc) { - key3.set(FIELD, owner, name, desc); - Item result = get(key3); - if (result == null) { - put122(FIELD, newClass(owner), newNameType(name, desc)); - result = new Item(index++, key3); - put(result); - } - return result; - } - - /** - * Adds a field reference to the constant pool of the class being build. - * Does nothing if the constant pool already contains a similar item. - * This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @param owner the internal name of the field's owner class. - * @param name the field's name. - * @param desc the field's descriptor. - * @return the index of a new or already existing field reference item. - */ - public int newField(final String owner, final String name, final String desc) { - return newFieldItem(owner, name, desc).index; - } - - /** - * Adds a method reference to the constant pool of the class being build. - * Does nothing if the constant pool already contains a similar item. - * - * @param owner the internal name of the method's owner class. - * @param name the method's name. - * @param desc the method's descriptor. - * @param itf true if owner is an interface. - * @return a new or already existing method reference item. - */ - Item newMethodItem(final String owner, final String name, final String desc, final boolean itf) { - int type = itf ? IMETH : METH; - key3.set(type, owner, name, desc); - Item result = get(key3); - if (result == null) { - put122(type, newClass(owner), newNameType(name, desc)); - result = new Item(index++, key3); - put(result); - } - return result; - } - - /** - * Adds a method reference to the constant pool of the class being build. - * Does nothing if the constant pool already contains a similar item. - * This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @param owner the internal name of the method's owner class. - * @param name the method's name. - * @param desc the method's descriptor. - * @param itf true if owner is an interface. - * @return the index of a new or already existing method reference item. - */ - public int newMethod(final String owner, final String name, final String desc, final boolean itf) { - return newMethodItem(owner, name, desc, itf).index; - } - - /** - * Adds an integer to the constant pool of the class being build. Does - * nothing if the constant pool already contains a similar item. - * - * @param value the int value. - * @return a new or already existing int item. - */ - Item newInteger(final int value) { - key.set(value); - Item result = get(key); - if (result == null) { - pool.putByte(INT).putInt(value); - result = new Item(index++, key); - put(result); - } - return result; - } - - /** - * Adds a float to the constant pool of the class being build. Does nothing - * if the constant pool already contains a similar item. - * - * @param value the float value. - * @return a new or already existing float item. - */ - Item newFloat(final float value) { - key.set(value); - Item result = get(key); - if (result == null) { - pool.putByte(FLOAT).putInt(key.intVal); - result = new Item(index++, key); - put(result); - } - return result; - } - - /** - * Adds a long to the constant pool of the class being build. Does nothing - * if the constant pool already contains a similar item. - * - * @param value the long value. - * @return a new or already existing long item. - */ - Item newLong(final long value) { - key.set(value); - Item result = get(key); - if (result == null) { - pool.putByte(LONG).putLong(value); - result = new Item(index, key); - put(result); - index += 2; - } - return result; - } - - /** - * Adds a double to the constant pool of the class being build. Does nothing - * if the constant pool already contains a similar item. - * - * @param value the double value. - * @return a new or already existing double item. - */ - Item newDouble(final double value) { - key.set(value); - Item result = get(key); - if (result == null) { - pool.putByte(DOUBLE).putLong(key.longVal); - result = new Item(index, key); - put(result); - index += 2; - } - return result; - } - - /** - * Adds a string to the constant pool of the class being build. Does nothing - * if the constant pool already contains a similar item. - * - * @param value the String value. - * @return a new or already existing string item. - */ - private Item newString(final String value) { - key2.set(STR, value, null, null); - Item result = get(key2); - if (result == null) { - pool.put12(STR, newUTF8(value)); - result = new Item(index++, key2); - put(result); - } - return result; - } - - /** - * Adds a name and type to the constant pool of the class being build. Does - * nothing if the constant pool already contains a similar item. This - * method is intended for {@link Attribute} sub classes, and is normally not - * needed by class generators or adapters. - * - * @param name a name. - * @param desc a type descriptor. - * @return the index of a new or already existing name and type item. - */ - public int newNameType(final String name, final String desc) { - key2.set(NAME_TYPE, name, desc, null); - Item result = get(key2); - if (result == null) { - put122(NAME_TYPE, newUTF8(name), newUTF8(desc)); - result = new Item(index++, key2); - put(result); - } - return result.index; - } - - /** - * Adds the given internal name to {@link #typeTable} and returns its index. - * Does nothing if the type table already contains this internal name. - * - * @param type the internal name to be added to the type table. - * @return the index of this internal name in the type table. - */ - int addType(final String type) { - key.set(TYPE_NORMAL, type, null, null); - Item result = get(key); - if (result == null) { - result = addType(key); - } - return result.index; - } - - /** - * Adds the given "uninitialized" type to {@link #typeTable} and returns its - * index. This method is used for UNINITIALIZED types, made of an internal - * name and a bytecode offset. - * - * @param type the internal name to be added to the type table. - * @param offset the bytecode offset of the NEW instruction that created - * this UNINITIALIZED type value. - * @return the index of this internal name in the type table. - */ - int addUninitializedType(final String type, final int offset) { - key.type = TYPE_UNINIT; - key.intVal = offset; - key.strVal1 = type; - key.hashCode = 0x7FFFFFFF & TYPE_UNINIT + type.hashCode() + offset; - Item result = get(key); - if (result == null) { - result = addType(key); - } - return result.index; - } - - /** - * Adds the given Item to {@link #typeTable}. - * - * @param item the value to be added to the type table. - * @return the added Item, which a new Item instance with the same value as - * the given Item. - */ - private Item addType(final Item item) { - ++typeCount; - Item result = new Item(typeCount, key); - put(result); - if (typeTable == null) { - typeTable = new Item[16]; - } - if (typeCount == typeTable.length) { - Item[] newTable = new Item[2 * typeTable.length]; - System.arraycopy(typeTable, 0, newTable, 0, typeTable.length); - typeTable = newTable; - } - typeTable[typeCount] = result; - return result; - } - - /** - * Returns the index of the common super type of the two given types. This - * method calls {@link #getCommonSuperClass} and caches the result in the - * {@link #items} hash table to speedup future calls with the same - * parameters. - * - * @param type1 index of an internal name in {@link #typeTable}. - * @param type2 index of an internal name in {@link #typeTable}. - * @return the index of the common super type of the two given types. - */ - int getMergedType(final int type1, final int type2) { - key2.type = TYPE_MERGED; - key2.longVal = type1 | (long) type2 << 32; - key2.hashCode = 0x7FFFFFFF & TYPE_MERGED + type1 + type2; - Item result = get(key2); - if (result == null) { - String t = typeTable[type1].strVal1; - String u = typeTable[type2].strVal1; - key2.intVal = addType(getCommonSuperClass(t, u)); - result = new Item((short) 0, key2); - put(result); - } - return result.intVal; - } - - /** - * Returns the common super type of the two given types. The default - * implementation of this method loads the two given classes and uses - * the java.lang.Class methods to find the common super class. It can be - * overridden to compute this common super type in other ways, in particular - * without actually loading any class, or to take into account the class - * that is currently being generated by this ClassWriter, which can of - * course not be loaded since it is under construction. - * - * @param type1 the internal name of a class. - * @param type2 the internal name of another class. - * @return the internal name of the common super class of the two given - * classes. - */ - protected String getCommonSuperClass(final String type1, final String type2) { - Class c, d; - try { - c = Class.forName(type1.replace('/', '.')); - d = Class.forName(type2.replace('/', '.')); - } catch (Exception e) { - throw new RuntimeException(e.toString()); - } - if (c.isAssignableFrom(d)) { - return type1; - } - if (d.isAssignableFrom(c)) { - return type2; - } - if (c.isInterface() || d.isInterface()) { - return "java/lang/Object"; - } else { - do { - c = c.getSuperclass(); - } while (!c.isAssignableFrom(d)); - return c.getName().replace('.', '/'); - } - } - - /** - * Returns the constant pool's hash table item which is equal to the given - * item. - * - * @param key a constant pool item. - * @return the constant pool's hash table item which is equal to the given - * item, or null if there is no such item. - */ - private Item get(final Item key) { - Item i = items[key.hashCode % items.length]; - while (i != null && !key.isEqualTo(i)) { - i = i.next; - } - return i; - } - - /** - * Puts the given item in the constant pool's hash table. The hash table - * must not already contains this item. - * - * @param i the item to be added to the constant pool's hash table. - */ - private void put(final Item i) { - if (index > threshold) { - int ll = items.length; - int nl = ll * 2 + 1; - Item[] newItems = new Item[nl]; - for (int l = ll - 1; l >= 0; --l) { - Item j = items[l]; - while (j != null) { - int index = j.hashCode % newItems.length; - Item k = j.next; - j.next = newItems[index]; - newItems[index] = j; - j = k; - } - } - items = newItems; - threshold = (int) (nl * 0.75); - } - int index = i.hashCode % items.length; - i.next = items[index]; - items[index] = i; - } - - /** - * Puts one byte and two shorts into the constant pool. - * - * @param b a byte. - * @param s1 a short. - * @param s2 another short. - */ - private void put122(final int b, final int s1, final int s2) { - pool.put12(b, s1).putShort(s2); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/Edge.java b/common/asm/src/main/java/com/alibaba/citrus/asm/Edge.java deleted file mode 100644 index c5fd30d01..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/Edge.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * An edge in the control flow graph of a method body. See {@link Label Label}. - * - * @author Eric Bruneton - */ -class Edge { - - /** - * Denotes a normal control flow graph edge. - */ - static final int NORMAL = 0; - - /** - * Denotes a control flow graph edge corresponding to an exception handler. - * More precisely any {@link Edge} whose {@link #info} is strictly positive - * corresponds to an exception handler. The actual value of {@link #info} is - * the index, in the {@link ClassWriter} type table, of the exception that - * is catched. - */ - static final int EXCEPTION = 0x7FFFFFFF; - - /** - * Information about this control flow graph edge. If - * {@link ClassWriter#COMPUTE_MAXS} is used this field is the (relative) - * stack size in the basic block from which this edge originates. This size - * is equal to the stack size at the "jump" instruction to which this edge - * corresponds, relatively to the stack size at the beginning of the - * originating basic block. If {@link ClassWriter#COMPUTE_FRAMES} is used, - * this field is the kind of this control flow graph edge (i.e. NORMAL or - * EXCEPTION). - */ - int info; - - /** - * The successor block of the basic block from which this edge originates. - */ - Label successor; - - /** - * The next edge in the list of successors of the originating basic block. - * See {@link Label#successors successors}. - */ - Edge next; -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/FieldVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/FieldVisitor.java deleted file mode 100644 index f6d672dc9..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/FieldVisitor.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * A visitor to visit a Java field. The methods of this interface must be called - * in the following order: ( visitAnnotation | visitAttribute - * )* visitEnd. - * - * @author Eric Bruneton - */ -public interface FieldVisitor { - - /** - * Visits an annotation of the field. - * - * @param desc the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if - * this visitor is not interested in visiting this annotation. - */ - AnnotationVisitor visitAnnotation(String desc, boolean visible); - - /** - * Visits a non standard attribute of the field. - * - * @param attr an attribute. - */ - void visitAttribute(Attribute attr); - - /** - * Visits the end of the field. This method, which is the last one to be - * called, is used to inform the visitor that all the annotations and - * attributes of the field have been visited. - */ - void visitEnd(); -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/FieldWriter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/FieldWriter.java deleted file mode 100644 index 6daa1edbe..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/FieldWriter.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * An {@link FieldVisitor} that generates Java fields in bytecode form. - * - * @author Eric Bruneton - */ -final class FieldWriter implements FieldVisitor { - - /** - * Next field writer (see {@link ClassWriter#firstField firstField}). - */ - FieldWriter next; - - /** - * The class writer to which this field must be added. - */ - private final ClassWriter cw; - - /** - * Access flags of this field. - */ - private final int access; - - /** - * The index of the constant pool item that contains the name of this - * method. - */ - private final int name; - - /** - * The index of the constant pool item that contains the descriptor of this - * field. - */ - private final int desc; - - /** - * The index of the constant pool item that contains the signature of this - * field. - */ - private int signature; - - /** - * The index of the constant pool item that contains the constant value of - * this field. - */ - private int value; - - /** - * The runtime visible annotations of this field. May be null. - */ - private AnnotationWriter anns; - - /** - * The runtime invisible annotations of this field. May be null. - */ - private AnnotationWriter ianns; - - /** - * The non standard attributes of this field. May be null. - */ - private Attribute attrs; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructs a new {@link FieldWriter}. - * - * @param cw the class writer to which this field must be added. - * @param access the field's access flags (see {@link Opcodes}). - * @param name the field's name. - * @param desc the field's descriptor (see {@link Type}). - * @param signature the field's signature. May be null. - * @param value the field's constant value. May be null. - */ - FieldWriter(final ClassWriter cw, final int access, final String name, final String desc, final String signature, - final Object value) { - if (cw.firstField == null) { - cw.firstField = this; - } else { - cw.lastField.next = this; - } - cw.lastField = this; - this.cw = cw; - this.access = access; - this.name = cw.newUTF8(name); - this.desc = cw.newUTF8(desc); - if (ClassReader.SIGNATURES && signature != null) { - this.signature = cw.newUTF8(signature); - } - if (value != null) { - this.value = cw.newConstItem(value).index; - } - } - - // ------------------------------------------------------------------------ - // Implementation of the FieldVisitor interface - // ------------------------------------------------------------------------ - - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write type, and reserve space for values count - bv.putShort(cw.newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2); - if (visible) { - aw.next = anns; - anns = aw; - } else { - aw.next = ianns; - ianns = aw; - } - return aw; - } - - public void visitAttribute(final Attribute attr) { - attr.next = attrs; - attrs = attr; - } - - public void visitEnd() { - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - /** - * Returns the size of this field. - * - * @return the size of this field. - */ - int getSize() { - int size = 8; - if (value != 0) { - cw.newUTF8("ConstantValue"); - size += 8; - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0 && (cw.version & 0xffff) < Opcodes.V1_5) { - cw.newUTF8("Synthetic"); - size += 6; - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - cw.newUTF8("Deprecated"); - size += 6; - } - if (ClassReader.SIGNATURES && signature != 0) { - cw.newUTF8("Signature"); - size += 8; - } - if (ClassReader.ANNOTATIONS && anns != null) { - cw.newUTF8("RuntimeVisibleAnnotations"); - size += 8 + anns.getSize(); - } - if (ClassReader.ANNOTATIONS && ianns != null) { - cw.newUTF8("RuntimeInvisibleAnnotations"); - size += 8 + ianns.getSize(); - } - if (attrs != null) { - size += attrs.getSize(cw, null, 0, -1, -1); - } - return size; - } - - /** - * Puts the content of this field into the given byte vector. - * - * @param out where the content of this field must be put. - */ - void put(final ByteVector out) { - out.putShort(access).putShort(name).putShort(desc); - int attributeCount = 0; - if (value != 0) { - ++attributeCount; - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0 && (cw.version & 0xffff) < Opcodes.V1_5) { - ++attributeCount; - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - ++attributeCount; - } - if (ClassReader.SIGNATURES && signature != 0) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && anns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && ianns != null) { - ++attributeCount; - } - if (attrs != null) { - attributeCount += attrs.getCount(); - } - out.putShort(attributeCount); - if (value != 0) { - out.putShort(cw.newUTF8("ConstantValue")); - out.putInt(2).putShort(value); - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0 && (cw.version & 0xffff) < Opcodes.V1_5) { - out.putShort(cw.newUTF8("Synthetic")).putInt(0); - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - out.putShort(cw.newUTF8("Deprecated")).putInt(0); - } - if (ClassReader.SIGNATURES && signature != 0) { - out.putShort(cw.newUTF8("Signature")); - out.putInt(2).putShort(signature); - } - if (ClassReader.ANNOTATIONS && anns != null) { - out.putShort(cw.newUTF8("RuntimeVisibleAnnotations")); - anns.put(out); - } - if (ClassReader.ANNOTATIONS && ianns != null) { - out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations")); - ianns.put(out); - } - if (attrs != null) { - attrs.put(cw, null, 0, -1, -1, out); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/Frame.java b/common/asm/src/main/java/com/alibaba/citrus/asm/Frame.java deleted file mode 100644 index 3ee95a759..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/Frame.java +++ /dev/null @@ -1,1355 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * Information about the input and output stack map frames of a basic block. - * - * @author Eric Bruneton - */ -final class Frame { - - /* - * Frames are computed in a two steps process: during the visit of each instruction, the state of the frame at the - * end of current basic block is updated by simulating the action of the instruction on the previous state of this - * so called "output frame". In visitMaxs, a fix point algorithm is used to compute the "input frame" of each basic - * block, i.e. the stack map frame at the begining of the basic block, starting from the input frame of the first - * basic block (which is computed from the method descriptor), and by using the previously computed output frames to - * compute the input state of the other blocks. All output and input frames are stored as arrays of integers. - * Reference and array types are represented by an index into a type table (which is not the same as the constant - * pool of the class, in order to avoid adding unnecessary constants in the pool - not all computed frames will end - * up being stored in the stack map table). This allows very fast type comparisons. Output stack map frames are - * computed relatively to the input frame of the basic block, which is not yet known when output frames are - * computed. It is therefore necessary to be able to represent abstract types such as "the type at position x in the - * input frame locals" or "the type at position x from the top of the input frame stack" or even "the type at - * position x in the input frame, with y more (or less) array dimensions". This explains the rather complicated type - * format used in output frames. This format is the following: DIM KIND VALUE (4, 4 and 24 bits). DIM is a signed - * number of array dimensions (from -8 to 7). KIND is either BASE, LOCAL or STACK. BASE is used for types that are - * not relative to the input frame. LOCAL is used for types that are relative to the input local variable types. - * STACK is used for types that are relative to the input stack types. VALUE depends on KIND. For LOCAL types, it is - * an index in the input local variable types. For STACK types, it is a position relatively to the top of input - * frame stack. For BASE types, it is either one of the constants defined in FrameVisitor, or for OBJECT and - * UNINITIALIZED types, a tag and an index in the type table. Output frames can contain types of any kind and with a - * positive or negative dimension (and even unassigned types, represented by 0 - which does not correspond to any - * valid type value). Input frames can only contain BASE types of positive or null dimension. In all cases the type - * table contains only internal type names (array type descriptors are forbidden - dimensions must be represented - * through the DIM field). The LONG and DOUBLE types are always represented by using two slots (LONG + TOP or DOUBLE + - * TOP), for local variable types as well as in the operand stack. This is necessary to be able to simulate DUPx_y - * instructions, whose effect would be dependent on the actual type values if types were always represented by a - * single slot in the stack (and this is not possible, since actual type values are not always known - cf LOCAL and - * STACK type kinds). - */ - - /** - * Mask to get the dimension of a frame type. This dimension is a signed integer between -8 and 7. - */ - static final int DIM = 0xF0000000; - - /** - * Constant to be added to a type to get a type with one more dimension. - */ - static final int ARRAY_OF = 0x10000000; - - /** - * Constant to be added to a type to get a type with one less dimension. - */ - static final int ELEMENT_OF = 0xF0000000; - - /** - * Mask to get the kind of a frame type. - * - * @see #BASE - * @see #LOCAL - * @see #STACK - */ - static final int KIND = 0xF000000; - - /** - * Mask to get the value of a frame type. - */ - static final int VALUE = 0xFFFFFF; - - /** - * Mask to get the kind of base types. - */ - static final int BASE_KIND = 0xFF00000; - - /** - * Mask to get the value of base types. - */ - static final int BASE_VALUE = 0xFFFFF; - - /** - * Kind of the types that are not relative to an input stack map frame. - */ - static final int BASE = 0x1000000; - - /** - * Base kind of the base reference types. The BASE_VALUE of such types is an index into the type table. - */ - static final int OBJECT = BASE | 0x700000; - - /** - * Base kind of the uninitialized base types. The BASE_VALUE of such types in an index into the type table (the Item - * at that index contains both an instruction offset and an internal class name). - */ - static final int UNINITIALIZED = BASE | 0x800000; - - /** - * Kind of the types that are relative to the local variable types of an input stack map frame. The value of such - * types is a local variable index. - */ - private static final int LOCAL = 0x2000000; - - /** - * Kind of the the types that are relative to the stack of an input stack map frame. The value of such types is a - * position relatively to the top of this stack. - */ - private static final int STACK = 0x3000000; - - /** - * The TOP type. This is a BASE type. - */ - static final int TOP = BASE | 0; - - /** - * The BOOLEAN type. This is a BASE type mainly used for array types. - */ - static final int BOOLEAN = BASE | 9; - - /** - * The BYTE type. This is a BASE type mainly used for array types. - */ - static final int BYTE = BASE | 10; - - /** - * The CHAR type. This is a BASE type mainly used for array types. - */ - static final int CHAR = BASE | 11; - - /** - * The SHORT type. This is a BASE type mainly used for array types. - */ - static final int SHORT = BASE | 12; - - /** - * The INTEGER type. This is a BASE type. - */ - static final int INTEGER = BASE | 1; - - /** - * The FLOAT type. This is a BASE type. - */ - static final int FLOAT = BASE | 2; - - /** - * The DOUBLE type. This is a BASE type. - */ - static final int DOUBLE = BASE | 3; - - /** - * The LONG type. This is a BASE type. - */ - static final int LONG = BASE | 4; - - /** - * The NULL type. This is a BASE type. - */ - static final int NULL = BASE | 5; - - /** - * The UNINITIALIZED_THIS type. This is a BASE type. - */ - static final int UNINITIALIZED_THIS = BASE | 6; - - /** - * The stack size variation corresponding to each JVM instruction. This stack variation is equal to the size of the - * values produced by an instruction, minus the size of the values consumed by this instruction. - */ - static final int[] SIZE; - - /** - * Computes the stack size variation corresponding to each JVM instruction. - */ - static { - int i; - int[] b = new int[202]; - String s = "EFFFFFFFFGGFFFGGFFFEEFGFGFEEEEEEEEEEEEEEEEEEEEDEDEDDDDD" - + "CDCDEEEEEEEEEEEEEEEEEEEEBABABBBBDCFFFGGGEDCDCDCDCDCDCDCDCD" - + "CDCEEEEDDDDDDDCDCDCEFEFDDEEFFDEDEEEBDDBBDDDDDDCCCCCCCCEFED" + "DDCDCDEEEEEEEEEEFEEEEEEDDEEDDEE"; - for (i = 0; i < b.length; ++i) { - b[i] = s.charAt(i) - 'E'; - } - SIZE = b; - - // code to generate the above string - // - // int NA = 0; // not applicable (unused opcode or variable size opcode) - // - // b = new int[] { - // 0, //NOP, // visitInsn - // 1, //ACONST_NULL, // - - // 1, //ICONST_M1, // - - // 1, //ICONST_0, // - - // 1, //ICONST_1, // - - // 1, //ICONST_2, // - - // 1, //ICONST_3, // - - // 1, //ICONST_4, // - - // 1, //ICONST_5, // - - // 2, //LCONST_0, // - - // 2, //LCONST_1, // - - // 1, //FCONST_0, // - - // 1, //FCONST_1, // - - // 1, //FCONST_2, // - - // 2, //DCONST_0, // - - // 2, //DCONST_1, // - - // 1, //BIPUSH, // visitIntInsn - // 1, //SIPUSH, // - - // 1, //LDC, // visitLdcInsn - // NA, //LDC_W, // - - // NA, //LDC2_W, // - - // 1, //ILOAD, // visitVarInsn - // 2, //LLOAD, // - - // 1, //FLOAD, // - - // 2, //DLOAD, // - - // 1, //ALOAD, // - - // NA, //ILOAD_0, // - - // NA, //ILOAD_1, // - - // NA, //ILOAD_2, // - - // NA, //ILOAD_3, // - - // NA, //LLOAD_0, // - - // NA, //LLOAD_1, // - - // NA, //LLOAD_2, // - - // NA, //LLOAD_3, // - - // NA, //FLOAD_0, // - - // NA, //FLOAD_1, // - - // NA, //FLOAD_2, // - - // NA, //FLOAD_3, // - - // NA, //DLOAD_0, // - - // NA, //DLOAD_1, // - - // NA, //DLOAD_2, // - - // NA, //DLOAD_3, // - - // NA, //ALOAD_0, // - - // NA, //ALOAD_1, // - - // NA, //ALOAD_2, // - - // NA, //ALOAD_3, // - - // -1, //IALOAD, // visitInsn - // 0, //LALOAD, // - - // -1, //FALOAD, // - - // 0, //DALOAD, // - - // -1, //AALOAD, // - - // -1, //BALOAD, // - - // -1, //CALOAD, // - - // -1, //SALOAD, // - - // -1, //ISTORE, // visitVarInsn - // -2, //LSTORE, // - - // -1, //FSTORE, // - - // -2, //DSTORE, // - - // -1, //ASTORE, // - - // NA, //ISTORE_0, // - - // NA, //ISTORE_1, // - - // NA, //ISTORE_2, // - - // NA, //ISTORE_3, // - - // NA, //LSTORE_0, // - - // NA, //LSTORE_1, // - - // NA, //LSTORE_2, // - - // NA, //LSTORE_3, // - - // NA, //FSTORE_0, // - - // NA, //FSTORE_1, // - - // NA, //FSTORE_2, // - - // NA, //FSTORE_3, // - - // NA, //DSTORE_0, // - - // NA, //DSTORE_1, // - - // NA, //DSTORE_2, // - - // NA, //DSTORE_3, // - - // NA, //ASTORE_0, // - - // NA, //ASTORE_1, // - - // NA, //ASTORE_2, // - - // NA, //ASTORE_3, // - - // -3, //IASTORE, // visitInsn - // -4, //LASTORE, // - - // -3, //FASTORE, // - - // -4, //DASTORE, // - - // -3, //AASTORE, // - - // -3, //BASTORE, // - - // -3, //CASTORE, // - - // -3, //SASTORE, // - - // -1, //POP, // - - // -2, //POP2, // - - // 1, //DUP, // - - // 1, //DUP_X1, // - - // 1, //DUP_X2, // - - // 2, //DUP2, // - - // 2, //DUP2_X1, // - - // 2, //DUP2_X2, // - - // 0, //SWAP, // - - // -1, //IADD, // - - // -2, //LADD, // - - // -1, //FADD, // - - // -2, //DADD, // - - // -1, //ISUB, // - - // -2, //LSUB, // - - // -1, //FSUB, // - - // -2, //DSUB, // - - // -1, //IMUL, // - - // -2, //LMUL, // - - // -1, //FMUL, // - - // -2, //DMUL, // - - // -1, //IDIV, // - - // -2, //LDIV, // - - // -1, //FDIV, // - - // -2, //DDIV, // - - // -1, //IREM, // - - // -2, //LREM, // - - // -1, //FREM, // - - // -2, //DREM, // - - // 0, //INEG, // - - // 0, //LNEG, // - - // 0, //FNEG, // - - // 0, //DNEG, // - - // -1, //ISHL, // - - // -1, //LSHL, // - - // -1, //ISHR, // - - // -1, //LSHR, // - - // -1, //IUSHR, // - - // -1, //LUSHR, // - - // -1, //IAND, // - - // -2, //LAND, // - - // -1, //IOR, // - - // -2, //LOR, // - - // -1, //IXOR, // - - // -2, //LXOR, // - - // 0, //IINC, // visitIincInsn - // 1, //I2L, // visitInsn - // 0, //I2F, // - - // 1, //I2D, // - - // -1, //L2I, // - - // -1, //L2F, // - - // 0, //L2D, // - - // 0, //F2I, // - - // 1, //F2L, // - - // 1, //F2D, // - - // -1, //D2I, // - - // 0, //D2L, // - - // -1, //D2F, // - - // 0, //I2B, // - - // 0, //I2C, // - - // 0, //I2S, // - - // -3, //LCMP, // - - // -1, //FCMPL, // - - // -1, //FCMPG, // - - // -3, //DCMPL, // - - // -3, //DCMPG, // - - // -1, //IFEQ, // visitJumpInsn - // -1, //IFNE, // - - // -1, //IFLT, // - - // -1, //IFGE, // - - // -1, //IFGT, // - - // -1, //IFLE, // - - // -2, //IF_ICMPEQ, // - - // -2, //IF_ICMPNE, // - - // -2, //IF_ICMPLT, // - - // -2, //IF_ICMPGE, // - - // -2, //IF_ICMPGT, // - - // -2, //IF_ICMPLE, // - - // -2, //IF_ACMPEQ, // - - // -2, //IF_ACMPNE, // - - // 0, //GOTO, // - - // 1, //JSR, // - - // 0, //RET, // visitVarInsn - // -1, //TABLESWITCH, // visiTableSwitchInsn - // -1, //LOOKUPSWITCH, // visitLookupSwitch - // -1, //IRETURN, // visitInsn - // -2, //LRETURN, // - - // -1, //FRETURN, // - - // -2, //DRETURN, // - - // -1, //ARETURN, // - - // 0, //RETURN, // - - // NA, //GETSTATIC, // visitFieldInsn - // NA, //PUTSTATIC, // - - // NA, //GETFIELD, // - - // NA, //PUTFIELD, // - - // NA, //INVOKEVIRTUAL, // visitMethodInsn - // NA, //INVOKESPECIAL, // - - // NA, //INVOKESTATIC, // - - // NA, //INVOKEINTERFACE, // - - // NA, //UNUSED, // NOT VISITED - // 1, //NEW, // visitTypeInsn - // 0, //NEWARRAY, // visitIntInsn - // 0, //ANEWARRAY, // visitTypeInsn - // 0, //ARRAYLENGTH, // visitInsn - // NA, //ATHROW, // - - // 0, //CHECKCAST, // visitTypeInsn - // 0, //INSTANCEOF, // - - // -1, //MONITORENTER, // visitInsn - // -1, //MONITOREXIT, // - - // NA, //WIDE, // NOT VISITED - // NA, //MULTIANEWARRAY, // visitMultiANewArrayInsn - // -1, //IFNULL, // visitJumpInsn - // -1, //IFNONNULL, // - - // NA, //GOTO_W, // - - // NA, //JSR_W, // - - // }; - // for (i = 0; i < b.length; ++i) { - // System.err.print((char)('E' + b[i])); - // } - // System.err.println(); - } - - /** - * The label (i.e. basic block) to which these input and output stack map frames correspond. - */ - Label owner; - - /** - * The input stack map frame locals. - */ - int[] inputLocals; - - /** - * The input stack map frame stack. - */ - int[] inputStack; - - /** - * The output stack map frame locals. - */ - private int[] outputLocals; - - /** - * The output stack map frame stack. - */ - private int[] outputStack; - - /** - * Relative size of the output stack. The exact semantics of this field depends on the algorithm that is used. When - * only the maximum stack size is computed, this field is the size of the output stack relatively to the top of the - * input stack. When the stack map frames are completely computed, this field is the actual number of types in - * {@link #outputStack}. - */ - private int outputStackTop; - - /** - * Number of types that are initialized in the basic block. - * - * @see #initializations - */ - private int initializationCount; - - /** - * The types that are initialized in the basic block. A constructor invocation on an UNINITIALIZED or - * UNINITIALIZED_THIS type must replace every occurence of this type in the local variables and in the - * operand stack. This cannot be done during the first phase of the algorithm since, during this phase, the local - * variables and the operand stack are not completely computed. It is therefore necessary to store the types on - * which constructors are invoked in the basic block, in order to do this replacement during the second phase of the - * algorithm, where the frames are fully computed. Note that this array can contain types that are relative to input - * locals or to the input stack (see below for the description of the algorithm). - */ - private int[] initializations; - - /** - * Returns the output frame local variable type at the given index. - * - * @param local the index of the local that must be returned. - * @return the output frame local variable type at the given index. - */ - private int get(final int local) { - if (outputLocals == null || local >= outputLocals.length) { - // this local has never been assigned in this basic block, - // so it is still equal to its value in the input frame - return LOCAL | local; - } else { - int type = outputLocals[local]; - if (type == 0) { - // this local has never been assigned in this basic block, - // so it is still equal to its value in the input frame - type = outputLocals[local] = LOCAL | local; - } - return type; - } - } - - /** - * Sets the output frame local variable type at the given index. - * - * @param local the index of the local that must be set. - * @param type the value of the local that must be set. - */ - private void set(final int local, final int type) { - // creates and/or resizes the output local variables array if necessary - if (outputLocals == null) { - outputLocals = new int[10]; - } - int n = outputLocals.length; - if (local >= n) { - int[] t = new int[Math.max(local + 1, 2 * n)]; - System.arraycopy(outputLocals, 0, t, 0, n); - outputLocals = t; - } - // sets the local variable - outputLocals[local] = type; - } - - /** - * Pushes a new type onto the output frame stack. - * - * @param type the type that must be pushed. - */ - private void push(final int type) { - // creates and/or resizes the output stack array if necessary - if (outputStack == null) { - outputStack = new int[10]; - } - int n = outputStack.length; - if (outputStackTop >= n) { - int[] t = new int[Math.max(outputStackTop + 1, 2 * n)]; - System.arraycopy(outputStack, 0, t, 0, n); - outputStack = t; - } - // pushes the type on the output stack - outputStack[outputStackTop++] = type; - // updates the maximun height reached by the output stack, if needed - int top = owner.inputStackTop + outputStackTop; - if (top > owner.outputStackMax) { - owner.outputStackMax = top; - } - } - - /** - * Pushes a new type onto the output frame stack. - * - * @param cw the ClassWriter to which this label belongs. - * @param desc the descriptor of the type to be pushed. Can also be a method descriptor (in this case this method - * pushes its return type onto the output frame stack). - */ - private void push(final ClassWriter cw, final String desc) { - int type = type(cw, desc); - if (type != 0) { - push(type); - if (type == LONG || type == DOUBLE) { - push(TOP); - } - } - } - - /** - * Returns the int encoding of the given type. - * - * @param cw the ClassWriter to which this label belongs. - * @param desc a type descriptor. - * @return the int encoding of the given type. - */ - private static int type(final ClassWriter cw, final String desc) { - String t; - int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0; - switch (desc.charAt(index)) { - case 'V': - return 0; - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - return INTEGER; - case 'F': - return FLOAT; - case 'J': - return LONG; - case 'D': - return DOUBLE; - case 'L': - // stores the internal name, not the descriptor! - t = desc.substring(index + 1, desc.length() - 1); - return OBJECT | cw.addType(t); - // case '[': - default: - // extracts the dimensions and the element type - int data; - int dims = index + 1; - while (desc.charAt(dims) == '[') { - ++dims; - } - switch (desc.charAt(dims)) { - case 'Z': - data = BOOLEAN; - break; - case 'C': - data = CHAR; - break; - case 'B': - data = BYTE; - break; - case 'S': - data = SHORT; - break; - case 'I': - data = INTEGER; - break; - case 'F': - data = FLOAT; - break; - case 'J': - data = LONG; - break; - case 'D': - data = DOUBLE; - break; - // case 'L': - default: - // stores the internal name, not the descriptor - t = desc.substring(dims + 1, desc.length() - 1); - data = OBJECT | cw.addType(t); - } - return dims - index << 28 | data; - } - } - - /** - * Pops a type from the output frame stack and returns its value. - * - * @return the type that has been popped from the output frame stack. - */ - private int pop() { - if (outputStackTop > 0) { - return outputStack[--outputStackTop]; - } else { - // if the output frame stack is empty, pops from the input stack - return STACK | -(--owner.inputStackTop); - } - } - - /** - * Pops the given number of types from the output frame stack. - * - * @param elements the number of types that must be popped. - */ - private void pop(final int elements) { - if (outputStackTop >= elements) { - outputStackTop -= elements; - } else { - // if the number of elements to be popped is greater than the number - // of elements in the output stack, clear it, and pops the remaining - // elements from the input stack. - owner.inputStackTop -= elements - outputStackTop; - outputStackTop = 0; - } - } - - /** - * Pops a type from the output frame stack. - * - * @param desc the descriptor of the type to be popped. Can also be a method descriptor (in this case this method - * pops the types corresponding to the method arguments). - */ - private void pop(final String desc) { - char c = desc.charAt(0); - if (c == '(') { - pop((MethodWriter.getArgumentsAndReturnSizes(desc) >> 2) - 1); - } else if (c == 'J' || c == 'D') { - pop(2); - } else { - pop(1); - } - } - - /** - * Adds a new type to the list of types on which a constructor is invoked in the basic block. - * - * @param var a type on a which a constructor is invoked. - */ - private void init(final int var) { - // creates and/or resizes the initializations array if necessary - if (initializations == null) { - initializations = new int[2]; - } - int n = initializations.length; - if (initializationCount >= n) { - int[] t = new int[Math.max(initializationCount + 1, 2 * n)]; - System.arraycopy(initializations, 0, t, 0, n); - initializations = t; - } - // stores the type to be initialized - initializations[initializationCount++] = var; - } - - /** - * Replaces the given type with the appropriate type if it is one of the types on which a constructor is invoked in - * the basic block. - * - * @param cw the ClassWriter to which this label belongs. - * @param t a type - * @return t or, if t is one of the types on which a constructor is invoked in the basic block, the type - * corresponding to this constructor. - */ - private int init(final ClassWriter cw, final int t) { - int s; - if (t == UNINITIALIZED_THIS) { - s = OBJECT | cw.addType(cw.thisName); - } else if ((t & (DIM | BASE_KIND)) == UNINITIALIZED) { - String type = cw.typeTable[t & BASE_VALUE].strVal1; - s = OBJECT | cw.addType(type); - } else { - return t; - } - for (int j = 0; j < initializationCount; ++j) { - int u = initializations[j]; - int dim = u & DIM; - int kind = u & KIND; - if (kind == LOCAL) { - u = dim + inputLocals[u & VALUE]; - } else if (kind == STACK) { - u = dim + inputStack[inputStack.length - (u & VALUE)]; - } - if (t == u) { - return s; - } - } - return t; - } - - /** - * Initializes the input frame of the first basic block from the method descriptor. - * - * @param cw the ClassWriter to which this label belongs. - * @param access the access flags of the method to which this label belongs. - * @param args the formal parameter types of this method. - * @param maxLocals the maximum number of local variables of this method. - */ - void initInputFrame(final ClassWriter cw, final int access, final Type[] args, final int maxLocals) { - inputLocals = new int[maxLocals]; - inputStack = new int[0]; - int i = 0; - if ((access & Opcodes.ACC_STATIC) == 0) { - if ((access & MethodWriter.ACC_CONSTRUCTOR) == 0) { - inputLocals[i++] = OBJECT | cw.addType(cw.thisName); - } else { - inputLocals[i++] = UNINITIALIZED_THIS; - } - } - for (int j = 0; j < args.length; ++j) { - int t = type(cw, args[j].getDescriptor()); - inputLocals[i++] = t; - if (t == LONG || t == DOUBLE) { - inputLocals[i++] = TOP; - } - } - while (i < maxLocals) { - inputLocals[i++] = TOP; - } - } - - /** - * Simulates the action of the given instruction on the output stack frame. - * - * @param opcode the opcode of the instruction. - * @param arg the operand of the instruction, if any. - * @param cw the class writer to which this label belongs. - * @param item the operand of the instructions, if any. - */ - void execute(final int opcode, final int arg, final ClassWriter cw, final Item item) { - int t1, t2, t3, t4; - switch (opcode) { - case Opcodes.NOP: - case Opcodes.INEG: - case Opcodes.LNEG: - case Opcodes.FNEG: - case Opcodes.DNEG: - case Opcodes.I2B: - case Opcodes.I2C: - case Opcodes.I2S: - case Opcodes.GOTO: - case Opcodes.RETURN: - break; - case Opcodes.ACONST_NULL: - push(NULL); - break; - case Opcodes.ICONST_M1: - case Opcodes.ICONST_0: - case Opcodes.ICONST_1: - case Opcodes.ICONST_2: - case Opcodes.ICONST_3: - case Opcodes.ICONST_4: - case Opcodes.ICONST_5: - case Opcodes.BIPUSH: - case Opcodes.SIPUSH: - case Opcodes.ILOAD: - push(INTEGER); - break; - case Opcodes.LCONST_0: - case Opcodes.LCONST_1: - case Opcodes.LLOAD: - push(LONG); - push(TOP); - break; - case Opcodes.FCONST_0: - case Opcodes.FCONST_1: - case Opcodes.FCONST_2: - case Opcodes.FLOAD: - push(FLOAT); - break; - case Opcodes.DCONST_0: - case Opcodes.DCONST_1: - case Opcodes.DLOAD: - push(DOUBLE); - push(TOP); - break; - case Opcodes.LDC: - switch (item.type) { - case ClassWriter.INT: - push(INTEGER); - break; - case ClassWriter.LONG: - push(LONG); - push(TOP); - break; - case ClassWriter.FLOAT: - push(FLOAT); - break; - case ClassWriter.DOUBLE: - push(DOUBLE); - push(TOP); - break; - case ClassWriter.CLASS: - push(OBJECT | cw.addType("java/lang/Class")); - break; - // case ClassWriter.STR: - default: - push(OBJECT | cw.addType("java/lang/String")); - } - break; - case Opcodes.ALOAD: - push(get(arg)); - break; - case Opcodes.IALOAD: - case Opcodes.BALOAD: - case Opcodes.CALOAD: - case Opcodes.SALOAD: - pop(2); - push(INTEGER); - break; - case Opcodes.LALOAD: - case Opcodes.D2L: - pop(2); - push(LONG); - push(TOP); - break; - case Opcodes.FALOAD: - pop(2); - push(FLOAT); - break; - case Opcodes.DALOAD: - case Opcodes.L2D: - pop(2); - push(DOUBLE); - push(TOP); - break; - case Opcodes.AALOAD: - pop(1); - t1 = pop(); - push(ELEMENT_OF + t1); - break; - case Opcodes.ISTORE: - case Opcodes.FSTORE: - case Opcodes.ASTORE: - t1 = pop(); - set(arg, t1); - if (arg > 0) { - t2 = get(arg - 1); - // if t2 is of kind STACK or LOCAL we cannot know its size! - if (t2 == LONG || t2 == DOUBLE) { - set(arg - 1, TOP); - } - } - break; - case Opcodes.LSTORE: - case Opcodes.DSTORE: - pop(1); - t1 = pop(); - set(arg, t1); - set(arg + 1, TOP); - if (arg > 0) { - t2 = get(arg - 1); - // if t2 is of kind STACK or LOCAL we cannot know its size! - if (t2 == LONG || t2 == DOUBLE) { - set(arg - 1, TOP); - } - } - break; - case Opcodes.IASTORE: - case Opcodes.BASTORE: - case Opcodes.CASTORE: - case Opcodes.SASTORE: - case Opcodes.FASTORE: - case Opcodes.AASTORE: - pop(3); - break; - case Opcodes.LASTORE: - case Opcodes.DASTORE: - pop(4); - break; - case Opcodes.POP: - case Opcodes.IFEQ: - case Opcodes.IFNE: - case Opcodes.IFLT: - case Opcodes.IFGE: - case Opcodes.IFGT: - case Opcodes.IFLE: - case Opcodes.IRETURN: - case Opcodes.FRETURN: - case Opcodes.ARETURN: - case Opcodes.TABLESWITCH: - case Opcodes.LOOKUPSWITCH: - case Opcodes.ATHROW: - case Opcodes.MONITORENTER: - case Opcodes.MONITOREXIT: - case Opcodes.IFNULL: - case Opcodes.IFNONNULL: - pop(1); - break; - case Opcodes.POP2: - case Opcodes.IF_ICMPEQ: - case Opcodes.IF_ICMPNE: - case Opcodes.IF_ICMPLT: - case Opcodes.IF_ICMPGE: - case Opcodes.IF_ICMPGT: - case Opcodes.IF_ICMPLE: - case Opcodes.IF_ACMPEQ: - case Opcodes.IF_ACMPNE: - case Opcodes.LRETURN: - case Opcodes.DRETURN: - pop(2); - break; - case Opcodes.DUP: - t1 = pop(); - push(t1); - push(t1); - break; - case Opcodes.DUP_X1: - t1 = pop(); - t2 = pop(); - push(t1); - push(t2); - push(t1); - break; - case Opcodes.DUP_X2: - t1 = pop(); - t2 = pop(); - t3 = pop(); - push(t1); - push(t3); - push(t2); - push(t1); - break; - case Opcodes.DUP2: - t1 = pop(); - t2 = pop(); - push(t2); - push(t1); - push(t2); - push(t1); - break; - case Opcodes.DUP2_X1: - t1 = pop(); - t2 = pop(); - t3 = pop(); - push(t2); - push(t1); - push(t3); - push(t2); - push(t1); - break; - case Opcodes.DUP2_X2: - t1 = pop(); - t2 = pop(); - t3 = pop(); - t4 = pop(); - push(t2); - push(t1); - push(t4); - push(t3); - push(t2); - push(t1); - break; - case Opcodes.SWAP: - t1 = pop(); - t2 = pop(); - push(t1); - push(t2); - break; - case Opcodes.IADD: - case Opcodes.ISUB: - case Opcodes.IMUL: - case Opcodes.IDIV: - case Opcodes.IREM: - case Opcodes.IAND: - case Opcodes.IOR: - case Opcodes.IXOR: - case Opcodes.ISHL: - case Opcodes.ISHR: - case Opcodes.IUSHR: - case Opcodes.L2I: - case Opcodes.D2I: - case Opcodes.FCMPL: - case Opcodes.FCMPG: - pop(2); - push(INTEGER); - break; - case Opcodes.LADD: - case Opcodes.LSUB: - case Opcodes.LMUL: - case Opcodes.LDIV: - case Opcodes.LREM: - case Opcodes.LAND: - case Opcodes.LOR: - case Opcodes.LXOR: - pop(4); - push(LONG); - push(TOP); - break; - case Opcodes.FADD: - case Opcodes.FSUB: - case Opcodes.FMUL: - case Opcodes.FDIV: - case Opcodes.FREM: - case Opcodes.L2F: - case Opcodes.D2F: - pop(2); - push(FLOAT); - break; - case Opcodes.DADD: - case Opcodes.DSUB: - case Opcodes.DMUL: - case Opcodes.DDIV: - case Opcodes.DREM: - pop(4); - push(DOUBLE); - push(TOP); - break; - case Opcodes.LSHL: - case Opcodes.LSHR: - case Opcodes.LUSHR: - pop(3); - push(LONG); - push(TOP); - break; - case Opcodes.IINC: - set(arg, INTEGER); - break; - case Opcodes.I2L: - case Opcodes.F2L: - pop(1); - push(LONG); - push(TOP); - break; - case Opcodes.I2F: - pop(1); - push(FLOAT); - break; - case Opcodes.I2D: - case Opcodes.F2D: - pop(1); - push(DOUBLE); - push(TOP); - break; - case Opcodes.F2I: - case Opcodes.ARRAYLENGTH: - case Opcodes.INSTANCEOF: - pop(1); - push(INTEGER); - break; - case Opcodes.LCMP: - case Opcodes.DCMPL: - case Opcodes.DCMPG: - pop(4); - push(INTEGER); - break; - case Opcodes.JSR: - case Opcodes.RET: - throw new RuntimeException("JSR/RET are not supported with computeFrames option"); - case Opcodes.GETSTATIC: - push(cw, item.strVal3); - break; - case Opcodes.PUTSTATIC: - pop(item.strVal3); - break; - case Opcodes.GETFIELD: - pop(1); - push(cw, item.strVal3); - break; - case Opcodes.PUTFIELD: - pop(item.strVal3); - pop(); - break; - case Opcodes.INVOKEVIRTUAL: - case Opcodes.INVOKESPECIAL: - case Opcodes.INVOKESTATIC: - case Opcodes.INVOKEINTERFACE: - pop(item.strVal3); - if (opcode != Opcodes.INVOKESTATIC) { - t1 = pop(); - if (opcode == Opcodes.INVOKESPECIAL && item.strVal2.charAt(0) == '<') { - init(t1); - } - } - push(cw, item.strVal3); - break; - case Opcodes.NEW: - push(UNINITIALIZED | cw.addUninitializedType(item.strVal1, arg)); - break; - case Opcodes.NEWARRAY: - pop(); - switch (arg) { - case Opcodes.T_BOOLEAN: - push(ARRAY_OF | BOOLEAN); - break; - case Opcodes.T_CHAR: - push(ARRAY_OF | CHAR); - break; - case Opcodes.T_BYTE: - push(ARRAY_OF | BYTE); - break; - case Opcodes.T_SHORT: - push(ARRAY_OF | SHORT); - break; - case Opcodes.T_INT: - push(ARRAY_OF | INTEGER); - break; - case Opcodes.T_FLOAT: - push(ARRAY_OF | FLOAT); - break; - case Opcodes.T_DOUBLE: - push(ARRAY_OF | DOUBLE); - break; - // case Opcodes.T_LONG: - default: - push(ARRAY_OF | LONG); - break; - } - break; - case Opcodes.ANEWARRAY: - String s = item.strVal1; - pop(); - if (s.charAt(0) == '[') { - push(cw, '[' + s); - } else { - push(ARRAY_OF | OBJECT | cw.addType(s)); - } - break; - case Opcodes.CHECKCAST: - s = item.strVal1; - pop(); - if (s.charAt(0) == '[') { - push(cw, s); - } else { - push(OBJECT | cw.addType(s)); - } - break; - // case Opcodes.MULTIANEWARRAY: - default: - pop(arg); - push(cw, item.strVal1); - break; - } - } - - /** - * Merges the input frame of the given basic block with the input and output frames of this basic block. Returns - * true if the input frame of the given label has been changed by this operation. - * - * @param cw the ClassWriter to which this label belongs. - * @param frame the basic block whose input frame must be updated. - * @param edge the kind of the {@link Edge} between this label and 'label'. See {@link Edge#info}. - * @return true if the input frame of the given label has been changed by this operation. - */ - boolean merge(final ClassWriter cw, final Frame frame, final int edge) { - boolean changed = false; - int i, s, dim, kind, t; - - int nLocal = inputLocals.length; - int nStack = inputStack.length; - if (frame.inputLocals == null) { - frame.inputLocals = new int[nLocal]; - changed = true; - } - - for (i = 0; i < nLocal; ++i) { - if (outputLocals != null && i < outputLocals.length) { - s = outputLocals[i]; - if (s == 0) { - t = inputLocals[i]; - } else { - dim = s & DIM; - kind = s & KIND; - if (kind == LOCAL) { - t = dim + inputLocals[s & VALUE]; - } else if (kind == STACK) { - t = dim + inputStack[nStack - (s & VALUE)]; - } else { - t = s; - } - } - } else { - t = inputLocals[i]; - } - if (initializations != null) { - t = init(cw, t); - } - changed |= merge(cw, t, frame.inputLocals, i); - } - - if (edge > 0) { - for (i = 0; i < nLocal; ++i) { - t = inputLocals[i]; - changed |= merge(cw, t, frame.inputLocals, i); - } - if (frame.inputStack == null) { - frame.inputStack = new int[1]; - changed = true; - } - changed |= merge(cw, edge, frame.inputStack, 0); - return changed; - } - - int nInputStack = inputStack.length + owner.inputStackTop; - if (frame.inputStack == null) { - frame.inputStack = new int[nInputStack + outputStackTop]; - changed = true; - } - - for (i = 0; i < nInputStack; ++i) { - t = inputStack[i]; - if (initializations != null) { - t = init(cw, t); - } - changed |= merge(cw, t, frame.inputStack, i); - } - for (i = 0; i < outputStackTop; ++i) { - s = outputStack[i]; - dim = s & DIM; - kind = s & KIND; - if (kind == LOCAL) { - t = dim + inputLocals[s & VALUE]; - } else if (kind == STACK) { - t = dim + inputStack[nStack - (s & VALUE)]; - } else { - t = s; - } - if (initializations != null) { - t = init(cw, t); - } - changed |= merge(cw, t, frame.inputStack, nInputStack + i); - } - return changed; - } - - /** - * Merges the type at the given index in the given type array with the given type. Returns true if the - * type array has been modified by this operation. - * - * @param cw the ClassWriter to which this label belongs. - * @param t the type with which the type array element must be merged. - * @param types an array of types. - * @param index the index of the type that must be merged in 'types'. - * @return true if the type array has been modified by this operation. - */ - private static boolean merge(final ClassWriter cw, int t, final int[] types, final int index) { - int u = types[index]; - if (u == t) { - // if the types are equal, merge(u,t)=u, so there is no change - return false; - } - if ((t & ~DIM) == NULL) { - if (u == NULL) { - return false; - } - t = NULL; - } - if (u == 0) { - // if types[index] has never been assigned, merge(u,t)=t - types[index] = t; - return true; - } - int v; - if ((u & BASE_KIND) == OBJECT || (u & DIM) != 0) { - // if u is a reference type of any dimension - if (t == NULL) { - // if t is the NULL type, merge(u,t)=u, so there is no change - return false; - } else if ((t & (DIM | BASE_KIND)) == (u & (DIM | BASE_KIND))) { - if ((u & BASE_KIND) == OBJECT) { - // if t is also a reference type, and if u and t have the - // same dimension merge(u,t) = dim(t) | common parent of the - // element types of u and t - v = t & DIM | OBJECT | cw.getMergedType(t & BASE_VALUE, u & BASE_VALUE); - } else { - // if u and t are array types, but not with the same element - // type, merge(u,t)=java/lang/Object - v = OBJECT | cw.addType("java/lang/Object"); - } - } else if ((t & BASE_KIND) == OBJECT || (t & DIM) != 0) { - // if t is any other reference or array type, - // merge(u,t)=java/lang/Object - v = OBJECT | cw.addType("java/lang/Object"); - } else { - // if t is any other type, merge(u,t)=TOP - v = TOP; - } - } else if (u == NULL) { - // if u is the NULL type, merge(u,t)=t, - // or TOP if t is not a reference type - v = (t & BASE_KIND) == OBJECT || (t & DIM) != 0 ? t : TOP; - } else { - // if u is any other type, merge(u,t)=TOP whatever t - v = TOP; - } - if (u != v) { - types[index] = v; - return true; - } - return false; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/Handler.java b/common/asm/src/main/java/com/alibaba/citrus/asm/Handler.java deleted file mode 100644 index 21fef621e..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/Handler.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * Information about an exception handler block. - * - * @author Eric Bruneton - */ -class Handler { - - /** - * Beginning of the exception handler's scope (inclusive). - */ - Label start; - - /** - * End of the exception handler's scope (exclusive). - */ - Label end; - - /** - * Beginning of the exception handler's code. - */ - Label handler; - - /** - * Internal name of the type of exceptions handled by this handler, or - * null to catch any exceptions. - */ - String desc; - - /** - * Constant pool index of the internal name of the type of exceptions - * handled by this handler, or 0 to catch any exceptions. - */ - int type; - - /** - * Next exception handler block info. - */ - Handler next; -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/Item.java b/common/asm/src/main/java/com/alibaba/citrus/asm/Item.java deleted file mode 100644 index f6a831dad..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/Item.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * A constant pool item. Constant pool items can be created with the 'newXXX' - * methods in the {@link ClassWriter} class. - * - * @author Eric Bruneton - */ -final class Item { - - /** - * Index of this item in the constant pool. - */ - int index; - - /** - * Type of this constant pool item. A single class is used to represent all - * constant pool item types, in order to minimize the bytecode size of this - * package. The value of this field is one of {@link ClassWriter#INT}, - * {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT}, - * {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8}, - * {@link ClassWriter#STR}, {@link ClassWriter#CLASS}, - * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD}, - * {@link ClassWriter#METH}, {@link ClassWriter#IMETH}. Special Item types - * are used for Items that are stored in the ClassWriter - * {@link ClassWriter#typeTable}, instead of the constant pool, in order to - * avoid clashes with normal constant pool items in the ClassWriter constant - * pool's hash table. These special item types are - * {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and - * {@link ClassWriter#TYPE_MERGED}. - */ - int type; - - /** - * Value of this item, for an integer item. - */ - int intVal; - - /** - * Value of this item, for a long item. - */ - long longVal; - - /** - * First part of the value of this item, for items that do not hold a - * primitive value. - */ - String strVal1; - - /** - * Second part of the value of this item, for items that do not hold a - * primitive value. - */ - String strVal2; - - /** - * Third part of the value of this item, for items that do not hold a - * primitive value. - */ - String strVal3; - - /** - * The hash code value of this constant pool item. - */ - int hashCode; - - /** - * Link to another constant pool item, used for collision lists in the - * constant pool's hash table. - */ - Item next; - - /** - * Constructs an uninitialized {@link Item}. - */ - Item() { - } - - /** - * Constructs an uninitialized {@link Item} for constant pool element at - * given position. - * - * @param index index of the item to be constructed. - */ - Item(final int index) { - this.index = index; - } - - /** - * Constructs a copy of the given item. - * - * @param index index of the item to be constructed. - * @param i the item that must be copied into the item to be constructed. - */ - Item(final int index, final Item i) { - this.index = index; - type = i.type; - intVal = i.intVal; - longVal = i.longVal; - strVal1 = i.strVal1; - strVal2 = i.strVal2; - strVal3 = i.strVal3; - hashCode = i.hashCode; - } - - /** - * Sets this item to an integer item. - * - * @param intVal the value of this item. - */ - void set(final int intVal) { - this.type = ClassWriter.INT; - this.intVal = intVal; - this.hashCode = 0x7FFFFFFF & type + intVal; - } - - /** - * Sets this item to a long item. - * - * @param longVal the value of this item. - */ - void set(final long longVal) { - this.type = ClassWriter.LONG; - this.longVal = longVal; - this.hashCode = 0x7FFFFFFF & type + (int) longVal; - } - - /** - * Sets this item to a float item. - * - * @param floatVal the value of this item. - */ - void set(final float floatVal) { - this.type = ClassWriter.FLOAT; - this.intVal = Float.floatToRawIntBits(floatVal); - this.hashCode = 0x7FFFFFFF & type + (int) floatVal; - } - - /** - * Sets this item to a double item. - * - * @param doubleVal the value of this item. - */ - void set(final double doubleVal) { - this.type = ClassWriter.DOUBLE; - this.longVal = Double.doubleToRawLongBits(doubleVal); - this.hashCode = 0x7FFFFFFF & type + (int) doubleVal; - } - - /** - * Sets this item to an item that do not hold a primitive value. - * - * @param type the type of this item. - * @param strVal1 first part of the value of this item. - * @param strVal2 second part of the value of this item. - * @param strVal3 third part of the value of this item. - */ - void set(final int type, final String strVal1, final String strVal2, final String strVal3) { - this.type = type; - this.strVal1 = strVal1; - this.strVal2 = strVal2; - this.strVal3 = strVal3; - switch (type) { - case ClassWriter.UTF8: - case ClassWriter.STR: - case ClassWriter.CLASS: - case ClassWriter.TYPE_NORMAL: - hashCode = 0x7FFFFFFF & type + strVal1.hashCode(); - return; - case ClassWriter.NAME_TYPE: - hashCode = 0x7FFFFFFF & type + strVal1.hashCode() * strVal2.hashCode(); - return; - // ClassWriter.FIELD: - // ClassWriter.METH: - // ClassWriter.IMETH: - default: - hashCode = 0x7FFFFFFF & type + strVal1.hashCode() * strVal2.hashCode() * strVal3.hashCode(); - } - } - - /** - * Indicates if the given item is equal to this one. - * - * @param i the item to be compared to this one. - * @return true if the given item if equal to this one, - * false otherwise. - */ - boolean isEqualTo(final Item i) { - if (i.type == type) { - switch (type) { - case ClassWriter.INT: - case ClassWriter.FLOAT: - return i.intVal == intVal; - case ClassWriter.TYPE_MERGED: - case ClassWriter.LONG: - case ClassWriter.DOUBLE: - return i.longVal == longVal; - case ClassWriter.UTF8: - case ClassWriter.STR: - case ClassWriter.CLASS: - case ClassWriter.TYPE_NORMAL: - return i.strVal1.equals(strVal1); - case ClassWriter.TYPE_UNINIT: - return i.intVal == intVal && i.strVal1.equals(strVal1); - case ClassWriter.NAME_TYPE: - return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2); - // ClassWriter.FIELD: - // ClassWriter.METH: - // ClassWriter.IMETH: - default: - return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2) && i.strVal3.equals(strVal3); - } - } - return false; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/Label.java b/common/asm/src/main/java/com/alibaba/citrus/asm/Label.java deleted file mode 100644 index ad033e7cb..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/Label.java +++ /dev/null @@ -1,522 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * A label represents a position in the bytecode of a method. Labels are used - * for jump, goto, and switch instructions, and for try catch blocks. - * - * @author Eric Bruneton - */ -public class Label { - - /** - * Indicates if this label is only used for debug attributes. Such a label - * is not the start of a basic block, the target of a jump instruction, or - * an exception handler. It can be safely ignored in control flow graph - * analysis algorithms (for optimization purposes). - */ - static final int DEBUG = 1; - - /** - * Indicates if the position of this label is known. - */ - static final int RESOLVED = 2; - - /** - * Indicates if this label has been updated, after instruction resizing. - */ - static final int RESIZED = 4; - - /** - * Indicates if this basic block has been pushed in the basic block stack. - * See {@link MethodWriter#visitMaxs visitMaxs}. - */ - static final int PUSHED = 8; - - /** - * Indicates if this label is the target of a jump instruction, or the start - * of an exception handler. - */ - static final int TARGET = 16; - - /** - * Indicates if a stack map frame must be stored for this label. - */ - static final int STORE = 32; - - /** - * Indicates if this label corresponds to a reachable basic block. - */ - static final int REACHABLE = 64; - - /** - * Indicates if this basic block ends with a JSR instruction. - */ - static final int JSR = 128; - - /** - * Indicates if this basic block ends with a RET instruction. - */ - static final int RET = 256; - - /** - * Indicates if this basic block is the start of a subroutine. - */ - static final int SUBROUTINE = 512; - - /** - * Indicates if this subroutine basic block has been visited. - */ - static final int VISITED = 1024; - - /** - * Field used to associate user information to a label. Warning: this field - * is used by the ASM tree package. In order to use it with the ASM tree - * package you must override the - * {@link com.alibaba.citrus.asm.tree.MethodNode#getLabelNode} method. - */ - public Object info; - - /** - * Flags that indicate the status of this label. - * - * @see #DEBUG - * @see #RESOLVED - * @see #RESIZED - * @see #PUSHED - * @see #TARGET - * @see #STORE - * @see #REACHABLE - * @see #JSR - * @see #RET - */ - int status; - - /** - * The line number corresponding to this label, if known. - */ - int line; - - /** - * The position of this label in the code, if known. - */ - int position; - - /** - * Number of forward references to this label, times two. - */ - private int referenceCount; - - /** - * Informations about forward references. Each forward reference is - * described by two consecutive integers in this array: the first one is the - * position of the first byte of the bytecode instruction that contains the - * forward reference, while the second is the position of the first byte of - * the forward reference itself. In fact the sign of the first integer - * indicates if this reference uses 2 or 4 bytes, and its absolute value - * gives the position of the bytecode instruction. This array is also used - * as a bitset to store the subroutines to which a basic block belongs. This - * information is needed in {@linked MethodWriter#visitMaxs}, after all - * forward references have been resolved. Hence the same array can be used - * for both purposes without problems. - */ - private int[] srcAndRefPositions; - - // ------------------------------------------------------------------------ - - /* - * Fields for the control flow and data flow graph analysis algorithms (used - * to compute the maximum stack size or the stack map frames). A control - * flow graph contains one node per "basic block", and one edge per "jump" - * from one basic block to another. Each node (i.e., each basic block) is - * represented by the Label object that corresponds to the first instruction - * of this basic block. Each node also stores the list of its successors in - * the graph, as a linked list of Edge objects. The control flow analysis - * algorithms used to compute the maximum stack size or the stack map frames - * are similar and use two steps. The first step, during the visit of each - * instruction, builds information about the state of the local variables - * and the operand stack at the end of each basic block, called the - * "output frame", relatively to the frame state at the beginning of - * the basic block, which is called the "input frame", and which is - * unknown during this step. The second step, in {@link - * MethodWriter#visitMaxs}, is a fix point algorithm that computes - * information about the input frame of each basic block, from the input - * state of the first basic block (known from the method signature), and by - * the using the previously computed relative output frames. The algorithm - * used to compute the maximum stack size only computes the relative output - * and absolute input stack heights, while the algorithm used to compute - * stack map frames computes relative output frames and absolute input - * frames. - */ - - /** - * Start of the output stack relatively to the input stack. The exact - * semantics of this field depends on the algorithm that is used. When only - * the maximum stack size is computed, this field is the number of elements - * in the input stack. When the stack map frames are completely computed, - * this field is the offset of the first output stack element relatively to - * the top of the input stack. This offset is always negative or null. A - * null offset means that the output stack must be appended to the input - * stack. A -n offset means that the first n output stack elements must - * replace the top n input stack elements, and that the other elements must - * be appended to the input stack. - */ - int inputStackTop; - - /** - * Maximum height reached by the output stack, relatively to the top of the - * input stack. This maximum is always positive or null. - */ - int outputStackMax; - - /** - * Information about the input and output stack map frames of this basic - * block. This field is only used when {@link ClassWriter#COMPUTE_FRAMES} - * option is used. - */ - Frame frame; - - /** - * The successor of this label, in the order they are visited. This linked - * list does not include labels used for debug info only. If - * {@link ClassWriter#COMPUTE_FRAMES} option is used then, in addition, it - * does not contain successive labels that denote the same bytecode position - * (in this case only the first label appears in this list). - */ - Label successor; - - /** - * The successors of this node in the control flow graph. These successors - * are stored in a linked list of {@link Edge Edge} objects, linked to each - * other by their {@link Edge#next} field. - */ - Edge successors; - - /** - * The next basic block in the basic block stack. This stack is used in the - * main loop of the fix point algorithm used in the second step of the - * control flow analysis algorithms. - * - * @see MethodWriter#visitMaxs - */ - Label next; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructs a new label. - */ - public Label() { - } - - // ------------------------------------------------------------------------ - // Methods to compute offsets and to manage forward references - // ------------------------------------------------------------------------ - - /** - * Returns the offset corresponding to this label. This offset is computed - * from the start of the method's bytecode. This method is intended for - * {@link Attribute} sub classes, and is normally not needed by class - * generators or adapters. - * - * @return the offset corresponding to this label. - * @throws IllegalStateException if this label is not resolved yet. - */ - public int getOffset() { - if ((status & RESOLVED) == 0) { - throw new IllegalStateException("Label offset position has not been resolved yet"); - } - return position; - } - - /** - * Puts a reference to this label in the bytecode of a method. If the - * position of the label is known, the offset is computed and written - * directly. Otherwise, a null offset is written and a new forward reference - * is declared for this label. - * - * @param owner the code writer that calls this method. - * @param out the bytecode of the method. - * @param source the position of first byte of the bytecode instruction that - * contains this label. - * @param wideOffset true if the reference must be stored in 4 - * bytes, or false if it must be stored with 2 bytes. - * @throws IllegalArgumentException if this label has not been created by - * the given code writer. - */ - void put(final MethodWriter owner, final ByteVector out, final int source, final boolean wideOffset) { - if ((status & RESOLVED) == 0) { - if (wideOffset) { - addReference(-1 - source, out.length); - out.putInt(-1); - } else { - addReference(source, out.length); - out.putShort(-1); - } - } else { - if (wideOffset) { - out.putInt(position - source); - } else { - out.putShort(position - source); - } - } - } - - /** - * Adds a forward reference to this label. This method must be called only - * for a true forward reference, i.e. only if this label is not resolved - * yet. For backward references, the offset of the reference can be, and - * must be, computed and stored directly. - * - * @param sourcePosition the position of the referencing instruction. This - * position will be used to compute the offset of this forward - * reference. - * @param referencePosition the position where the offset for this forward - * reference must be stored. - */ - private void addReference(final int sourcePosition, final int referencePosition) { - if (srcAndRefPositions == null) { - srcAndRefPositions = new int[6]; - } - if (referenceCount >= srcAndRefPositions.length) { - int[] a = new int[srcAndRefPositions.length + 6]; - System.arraycopy(srcAndRefPositions, 0, a, 0, srcAndRefPositions.length); - srcAndRefPositions = a; - } - srcAndRefPositions[referenceCount++] = sourcePosition; - srcAndRefPositions[referenceCount++] = referencePosition; - } - - /** - * Resolves all forward references to this label. This method must be called - * when this label is added to the bytecode of the method, i.e. when its - * position becomes known. This method fills in the blanks that where left - * in the bytecode by each forward reference previously added to this label. - * - * @param owner the code writer that calls this method. - * @param position the position of this label in the bytecode. - * @param data the bytecode of the method. - * @return true if a blank that was left for this label was to - * small to store the offset. In such a case the corresponding jump - * instruction is replaced with a pseudo instruction (using unused - * opcodes) using an unsigned two bytes offset. These pseudo - * instructions will need to be replaced with true instructions with - * wider offsets (4 bytes instead of 2). This is done in - * {@link MethodWriter#resizeInstructions}. - * @throws IllegalArgumentException if this label has already been resolved, - * or if it has not been created by the given code writer. - */ - boolean resolve(final MethodWriter owner, final int position, final byte[] data) { - boolean needUpdate = false; - this.status |= RESOLVED; - this.position = position; - int i = 0; - while (i < referenceCount) { - int source = srcAndRefPositions[i++]; - int reference = srcAndRefPositions[i++]; - int offset; - if (source >= 0) { - offset = position - source; - if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE) { - /* - * changes the opcode of the jump instruction, in order to - * be able to find it later (see resizeInstructions in - * MethodWriter). These temporary opcodes are similar to - * jump instruction opcodes, except that the 2 bytes offset - * is unsigned (and can therefore represent values from 0 to - * 65535, which is sufficient since the size of a method is - * limited to 65535 bytes). - */ - int opcode = data[reference - 1] & 0xFF; - if (opcode <= Opcodes.JSR) { - // changes IFEQ ... JSR to opcodes 202 to 217 - data[reference - 1] = (byte) (opcode + 49); - } else { - // changes IFNULL and IFNONNULL to opcodes 218 and 219 - data[reference - 1] = (byte) (opcode + 20); - } - needUpdate = true; - } - data[reference++] = (byte) (offset >>> 8); - data[reference] = (byte) offset; - } else { - offset = position + source + 1; - data[reference++] = (byte) (offset >>> 24); - data[reference++] = (byte) (offset >>> 16); - data[reference++] = (byte) (offset >>> 8); - data[reference] = (byte) offset; - } - } - return needUpdate; - } - - /** - * Returns the first label of the series to which this label belongs. For an - * isolated label or for the first label in a series of successive labels, - * this method returns the label itself. For other labels it returns the - * first label of the series. - * - * @return the first label of the series to which this label belongs. - */ - Label getFirst() { - return !ClassReader.FRAMES || frame == null ? this : frame.owner; - } - - // ------------------------------------------------------------------------ - // Methods related to subroutines - // ------------------------------------------------------------------------ - - /** - * Returns true is this basic block belongs to the given subroutine. - * - * @param id a subroutine id. - * @return true is this basic block belongs to the given subroutine. - */ - boolean inSubroutine(final long id) { - if ((status & Label.VISITED) != 0) { - return (srcAndRefPositions[(int) (id >>> 32)] & (int) id) != 0; - } - return false; - } - - /** - * Returns true if this basic block and the given one belong to a common - * subroutine. - * - * @param block another basic block. - * @return true if this basic block and the given one belong to a common - * subroutine. - */ - boolean inSameSubroutine(final Label block) { - for (int i = 0; i < srcAndRefPositions.length; ++i) { - if ((srcAndRefPositions[i] & block.srcAndRefPositions[i]) != 0) { - return true; - } - } - return false; - } - - /** - * Marks this basic block as belonging to the given subroutine. - * - * @param id a subroutine id. - * @param nbSubroutines the total number of subroutines in the method. - */ - void addToSubroutine(final long id, final int nbSubroutines) { - if ((status & VISITED) == 0) { - status |= VISITED; - srcAndRefPositions = new int[(nbSubroutines - 1) / 32 + 1]; - } - srcAndRefPositions[(int) (id >>> 32)] |= (int) id; - } - - /** - * Finds the basic blocks that belong to a given subroutine, and marks these - * blocks as belonging to this subroutine. This recursive method follows the - * control flow graph to find all the blocks that are reachable from the - * current block WITHOUT following any JSR target. - * - * @param JSR a JSR block that jumps to this subroutine. If this JSR is not - * null it is added to the successor of the RET blocks found in - * the subroutine. - * @param id the id of this subroutine. - * @param nbSubroutines the total number of subroutines in the method. - */ - void visitSubroutine(final Label JSR, final long id, final int nbSubroutines) { - if (JSR != null) { - if ((status & VISITED) != 0) { - return; - } - status |= VISITED; - // adds JSR to the successors of this block, if it is a RET block - if ((status & RET) != 0) { - if (!inSameSubroutine(JSR)) { - Edge e = new Edge(); - e.info = inputStackTop; - e.successor = JSR.successors.successor; - e.next = successors; - successors = e; - } - } - } else { - // if this block already belongs to subroutine 'id', returns - if (inSubroutine(id)) { - return; - } - // marks this block as belonging to subroutine 'id' - addToSubroutine(id, nbSubroutines); - } - // calls this method recursively on each successor, except JSR targets - Edge e = successors; - while (e != null) { - // if this block is a JSR block, then 'successors.next' leads - // to the JSR target (see {@link #visitJumpInsn}) and must therefore - // not be followed - if ((status & Label.JSR) == 0 || e != successors.next) { - e.successor.visitSubroutine(JSR, id, nbSubroutines); - } - e = e.next; - } - } - - // ------------------------------------------------------------------------ - // Overriden Object methods - // ------------------------------------------------------------------------ - - /** - * Returns a string representation of this label. - * - * @return a string representation of this label. - */ - @Override - public String toString() { - return "L" + System.identityHashCode(this); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/MethodAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/MethodAdapter.java deleted file mode 100644 index bda9efaba..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/MethodAdapter.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * An empty {@link MethodVisitor} that delegates to another - * {@link MethodVisitor}. This class can be used as a super class to quickly - * implement usefull method adapter classes, just by overriding the necessary - * methods. - * - * @author Eric Bruneton - */ -public class MethodAdapter implements MethodVisitor { - - /** - * The {@link MethodVisitor} to which this adapter delegates calls. - */ - protected MethodVisitor mv; - - /** - * Constructs a new {@link MethodAdapter} object. - * - * @param mv the code visitor to which this adapter must delegate calls. - */ - public MethodAdapter(final MethodVisitor mv) { - this.mv = mv; - } - - public AnnotationVisitor visitAnnotationDefault() { - return mv.visitAnnotationDefault(); - } - - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - return mv.visitAnnotation(desc, visible); - } - - public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc, final boolean visible) { - return mv.visitParameterAnnotation(parameter, desc, visible); - } - - public void visitAttribute(final Attribute attr) { - mv.visitAttribute(attr); - } - - public void visitCode() { - mv.visitCode(); - } - - public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, - final Object[] stack) { - mv.visitFrame(type, nLocal, local, nStack, stack); - } - - public void visitInsn(final int opcode) { - mv.visitInsn(opcode); - } - - public void visitIntInsn(final int opcode, final int operand) { - mv.visitIntInsn(opcode, operand); - } - - public void visitVarInsn(final int opcode, final int var) { - mv.visitVarInsn(opcode, var); - } - - public void visitTypeInsn(final int opcode, final String type) { - mv.visitTypeInsn(opcode, type); - } - - public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { - mv.visitFieldInsn(opcode, owner, name, desc); - } - - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - mv.visitMethodInsn(opcode, owner, name, desc); - } - - public void visitJumpInsn(final int opcode, final Label label) { - mv.visitJumpInsn(opcode, label); - } - - public void visitLabel(final Label label) { - mv.visitLabel(label); - } - - public void visitLdcInsn(final Object cst) { - mv.visitLdcInsn(cst); - } - - public void visitIincInsn(final int var, final int increment) { - mv.visitIincInsn(var, increment); - } - - public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label[] labels) { - mv.visitTableSwitchInsn(min, max, dflt, labels); - } - - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { - mv.visitLookupSwitchInsn(dflt, keys, labels); - } - - public void visitMultiANewArrayInsn(final String desc, final int dims) { - mv.visitMultiANewArrayInsn(desc, dims); - } - - public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type) { - mv.visitTryCatchBlock(start, end, handler, type); - } - - public void visitLocalVariable(final String name, final String desc, final String signature, final Label start, - final Label end, final int index) { - mv.visitLocalVariable(name, desc, signature, start, end, index); - } - - public void visitLineNumber(final int line, final Label start) { - mv.visitLineNumber(line, start); - } - - public void visitMaxs(final int maxStack, final int maxLocals) { - mv.visitMaxs(maxStack, maxLocals); - } - - public void visitEnd() { - mv.visitEnd(); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/MethodVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/MethodVisitor.java deleted file mode 100644 index c6b9449ed..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/MethodVisitor.java +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * A visitor to visit a Java method. The methods of this interface must be - * called in the following order: [ visitAnnotationDefault ] ( - * visitAnnotation | visitParameterAnnotation | - * visitAttribute )* [ visitCode ( visitFrame | - * visitXInsn
| visitLabel | - * visitTryCatchBlock | visitLocalVariable | - * visitLineNumber)* visitMaxs ] visitEnd. In - * addition, the visitXInsn
and visitLabel methods - * must be called in the sequential order of the bytecode instructions of the - * visited code, visitTryCatchBlock must be called before the - * labels passed as arguments have been visited, and the - * visitLocalVariable and visitLineNumber methods must be - * called after the labels passed as arguments have been visited. - * - * @author Eric Bruneton - */ -public interface MethodVisitor { - - // ------------------------------------------------------------------------- - // Annotations and non standard attributes - // ------------------------------------------------------------------------- - - /** - * Visits the default value of this annotation interface method. - * - * @return a visitor to the visit the actual default value of this - * annotation interface method, or null if this visitor is - * not interested in visiting this default value. The 'name' - * parameters passed to the methods of this annotation visitor are - * ignored. Moreover, exacly one visit method must be called on this - * annotation visitor, followed by visitEnd. - */ - AnnotationVisitor visitAnnotationDefault(); - - /** - * Visits an annotation of this method. - * - * @param desc the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if - * this visitor is not interested in visiting this annotation. - */ - AnnotationVisitor visitAnnotation(String desc, boolean visible); - - /** - * Visits an annotation of a parameter this method. - * - * @param parameter the parameter index. - * @param desc the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if - * this visitor is not interested in visiting this annotation. - */ - AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible); - - /** - * Visits a non standard attribute of this method. - * - * @param attr an attribute. - */ - void visitAttribute(Attribute attr); - - /** - * Starts the visit of the method's code, if any (i.e. non abstract method). - */ - void visitCode(); - - /** - * Visits the current state of the local variables and operand stack - * elements. This method must(*) be called just before any - * instruction i that follows an unconditionnal branch instruction - * such as GOTO or THROW, that is the target of a jump instruction, or that - * starts an exception handler block. The visited types must describe the - * values of the local variables and of the operand stack elements just - * before i is executed.
- *
- * (*) this is mandatory only for classes whose version is greater than or - * equal to {@link Opcodes#V1_6 V1_6}.
- *
- * Packed frames are basically "deltas" from the state of the previous frame - * (very first frame is implicitly defined by the method's parameters and - * access flags): - *
    - *
  • {@link Opcodes#F_SAME} representing frame with exactly the same - * locals as the previous frame and with the empty stack.
  • - *
  • {@link Opcodes#F_SAME1} representing frame with exactly the same - * locals as the previous frame and with single value on the stack ( - * nStack is 1 and stack[0] contains value for the - * type of the stack item).
  • - *
  • {@link Opcodes#F_APPEND} representing frame with current locals are - * the same as the locals in the previous frame, except that additional - * locals are defined (nLocal is 1, 2 or 3 and - * local elements contains values representing added types).
  • - *
  • {@link Opcodes#F_CHOP} representing frame with current locals are the - * same as the locals in the previous frame, except that the last 1-3 locals - * are absent and with the empty stack (nLocals is 1, 2 or 3).
  • - *
  • {@link Opcodes#F_FULL} representing complete frame data.
  • - *
- * - * @param type the type of this stack map frame. Must be - * {@link Opcodes#F_NEW} for expanded frames, or - * {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, - * {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or - * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for - * compressed frames. - * @param nLocal the number of local variables in the visited frame. - * @param local the local variable types in this frame. This array must not - * be modified. Primitive types are represented by - * {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, - * {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, - * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or - * {@link Opcodes#UNINITIALIZED_THIS} (long and double are - * represented by a single element). Reference types are - * represented by String objects (representing internal names), - * and uninitialized types by Label objects (this label - * designates the NEW instruction that created this uninitialized - * value). - * @param nStack the number of operand stack elements in the visited frame. - * @param stack the operand stack types in this frame. This array must not - * be modified. Its content has the same format as the "local" - * array. - */ - void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack); - - // ------------------------------------------------------------------------- - // Normal instructions - // ------------------------------------------------------------------------- - - /** - * Visits a zero operand instruction. - * - * @param opcode the opcode of the instruction to be visited. This opcode is - * either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, - * ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, - * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, - * LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, - * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, - * SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, - * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, - * IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, - * FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, - * IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, - * L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S, - * LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN, - * DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, - * or MONITOREXIT. - */ - void visitInsn(int opcode); - - /** - * Visits an instruction with a single int operand. - * - * @param opcode the opcode of the instruction to be visited. This opcode is - * either BIPUSH, SIPUSH or NEWARRAY. - * @param operand the operand of the instruction to be visited.
- * When opcode is BIPUSH, operand value should be between - * Byte.MIN_VALUE and Byte.MAX_VALUE.
- * When opcode is SIPUSH, operand value should be between - * Short.MIN_VALUE and Short.MAX_VALUE.
- * When opcode is NEWARRAY, operand value should be one of - * {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR}, - * {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, - * {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT}, - * {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}. - */ - void visitIntInsn(int opcode, int operand); - - /** - * Visits a local variable instruction. A local variable instruction is an - * instruction that loads or stores the value of a local variable. - * - * @param opcode the opcode of the local variable instruction to be visited. - * This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, - * ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET. - * @param var the operand of the instruction to be visited. This operand is - * the index of a local variable. - */ - void visitVarInsn(int opcode, int var); - - /** - * Visits a type instruction. A type instruction is an instruction that - * takes the internal name of a class as parameter. - * - * @param opcode the opcode of the type instruction to be visited. This - * opcode is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF. - * @param type the operand of the instruction to be visited. This operand - * must be the internal name of an object or array class (see - * {@link Type#getInternalName() getInternalName}). - */ - void visitTypeInsn(int opcode, String type); - - /** - * Visits a field instruction. A field instruction is an instruction that - * loads or stores the value of a field of an object. - * - * @param opcode the opcode of the type instruction to be visited. This - * opcode is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. - * @param owner the internal name of the field's owner class (see - * {@link Type#getInternalName() getInternalName}). - * @param name the field's name. - * @param desc the field's descriptor (see {@link Type Type}). - */ - void visitFieldInsn(int opcode, String owner, String name, String desc); - - /** - * Visits a method instruction. A method instruction is an instruction that - * invokes a method. - * - * @param opcode the opcode of the type instruction to be visited. This - * opcode is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or - * INVOKEINTERFACE. - * @param owner the internal name of the method's owner class (see - * {@link Type#getInternalName() getInternalName}). - * @param name the method's name. - * @param desc the method's descriptor (see {@link Type Type}). - */ - void visitMethodInsn(int opcode, String owner, String name, String desc); - - /** - * Visits a jump instruction. A jump instruction is an instruction that may - * jump to another instruction. - * - * @param opcode the opcode of the type instruction to be visited. This - * opcode is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, - * IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, - * IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or - * IFNONNULL. - * @param label the operand of the instruction to be visited. This operand - * is a label that designates the instruction to which the jump - * instruction may jump. - */ - void visitJumpInsn(int opcode, Label label); - - /** - * Visits a label. A label designates the instruction that will be visited - * just after it. - * - * @param label a {@link Label Label} object. - */ - void visitLabel(Label label); - - // ------------------------------------------------------------------------- - // Special instructions - // ------------------------------------------------------------------------- - - /** - * Visits a LDC instruction. - * - * @param cst the constant to be loaded on the stack. This parameter must be - * a non null {@link Integer}, a {@link Float}, a {@link Long}, a - * {@link Double} a {@link String} (or a {@link Type} for - * .class constants, for classes whose version is 49.0 - * or more). - */ - void visitLdcInsn(Object cst); - - /** - * Visits an IINC instruction. - * - * @param var index of the local variable to be incremented. - * @param increment amount to increment the local variable by. - */ - void visitIincInsn(int var, int increment); - - /** - * Visits a TABLESWITCH instruction. - * - * @param min the minimum key value. - * @param max the maximum key value. - * @param dflt beginning of the default handler block. - * @param labels beginnings of the handler blocks. labels[i] is the - * beginning of the handler block for the min + i key. - */ - void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels); - - /** - * Visits a LOOKUPSWITCH instruction. - * - * @param dflt beginning of the default handler block. - * @param keys the values of the keys. - * @param labels beginnings of the handler blocks. labels[i] is the - * beginning of the handler block for the keys[i] key. - */ - void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels); - - /** - * Visits a MULTIANEWARRAY instruction. - * - * @param desc an array type descriptor (see {@link Type Type}). - * @param dims number of dimensions of the array to allocate. - */ - void visitMultiANewArrayInsn(String desc, int dims); - - // ------------------------------------------------------------------------- - // Exceptions table entries, debug information, max stack and max locals - // ------------------------------------------------------------------------- - - /** - * Visits a try catch block. - * - * @param start beginning of the exception handler's scope (inclusive). - * @param end end of the exception handler's scope (exclusive). - * @param handler beginning of the exception handler's code. - * @param type internal name of the type of exceptions handled by the - * handler, or null to catch any exceptions (for - * "finally" blocks). - * @throws IllegalArgumentException if one of the labels has already been - * visited by this visitor (by the {@link #visitLabel - * visitLabel} method). - */ - void visitTryCatchBlock(Label start, Label end, Label handler, String type); - - /** - * Visits a local variable declaration. - * - * @param name the name of a local variable. - * @param desc the type descriptor of this local variable. - * @param signature the type signature of this local variable. May be - * null if the local variable type does not use generic - * types. - * @param start the first instruction corresponding to the scope of this - * local variable (inclusive). - * @param end the last instruction corresponding to the scope of this local - * variable (exclusive). - * @param index the local variable's index. - * @throws IllegalArgumentException if one of the labels has not already - * been visited by this visitor (by the {@link #visitLabel - * visitLabel} method). - */ - void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index); - - /** - * Visits a line number declaration. - * - * @param line a line number. This number refers to the source file from - * which the class was compiled. - * @param start the first instruction corresponding to this line number. - * @throws IllegalArgumentException if start has not already been - * visited by this visitor (by the {@link #visitLabel - * visitLabel} method). - */ - void visitLineNumber(int line, Label start); - - /** - * Visits the maximum stack size and the maximum number of local variables - * of the method. - * - * @param maxStack maximum stack size of the method. - * @param maxLocals maximum number of local variables for the method. - */ - void visitMaxs(int maxStack, int maxLocals); - - /** - * Visits the end of the method. This method, which is the last one to be - * called, is used to inform the visitor that all the annotations and - * attributes of the method have been visited. - */ - void visitEnd(); -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/MethodWriter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/MethodWriter.java deleted file mode 100644 index 1d46f02ee..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/MethodWriter.java +++ /dev/null @@ -1,2489 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -/** - * A {@link MethodVisitor} that generates methods in bytecode form. Each visit - * method of this class appends the bytecode corresponding to the visited - * instruction to a byte vector, in the order these methods are called. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -class MethodWriter implements MethodVisitor { - - /** - * Pseudo access flag used to denote constructors. - */ - static final int ACC_CONSTRUCTOR = 262144; - - /** - * Frame has exactly the same locals as the previous stack map frame and - * number of stack items is zero. - */ - static final int SAME_FRAME = 0; // to 63 (0-3f) - - /** - * Frame has exactly the same locals as the previous stack map frame and - * number of stack items is 1 - */ - static final int SAME_LOCALS_1_STACK_ITEM_FRAME = 64; // to 127 (40-7f) - - /** - * Reserved for future use - */ - static final int RESERVED = 128; - - /** - * Frame has exactly the same locals as the previous stack map frame and - * number of stack items is 1. Offset is bigger then 63; - */ - static final int SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED = 247; // f7 - - /** - * Frame where current locals are the same as the locals in the previous - * frame, except that the k last locals are absent. The value of k is given - * by the formula 251-frame_type. - */ - static final int CHOP_FRAME = 248; // to 250 (f8-fA) - - /** - * Frame has exactly the same locals as the previous stack map frame and - * number of stack items is zero. Offset is bigger then 63; - */ - static final int SAME_FRAME_EXTENDED = 251; // fb - - /** - * Frame where current locals are the same as the locals in the previous - * frame, except that k additional locals are defined. The value of k is - * given by the formula frame_type-251. - */ - static final int APPEND_FRAME = 252; // to 254 // fc-fe - - /** - * Full frame - */ - static final int FULL_FRAME = 255; // ff - - /** - * Indicates that the stack map frames must be recomputed from scratch. In - * this case the maximum stack size and number of local variables is also - * recomputed from scratch. - * - * @see #compute - */ - private static final int FRAMES = 0; - - /** - * Indicates that the maximum stack size and number of local variables must - * be automatically computed. - * - * @see #compute - */ - private static final int MAXS = 1; - - /** - * Indicates that nothing must be automatically computed. - * - * @see #compute - */ - private static final int NOTHING = 2; - - /** - * Next method writer (see {@link ClassWriter#firstMethod firstMethod}). - */ - MethodWriter next; - - /** - * The class writer to which this method must be added. - */ - final ClassWriter cw; - - /** - * Access flags of this method. - */ - private int access; - - /** - * The index of the constant pool item that contains the name of this - * method. - */ - private final int name; - - /** - * The index of the constant pool item that contains the descriptor of this - * method. - */ - private final int desc; - - /** - * The descriptor of this method. - */ - private final String descriptor; - - /** - * The signature of this method. - */ - String signature; - - /** - * If not zero, indicates that the code of this method must be copied from - * the ClassReader associated to this writer in cw.cr. More - * precisely, this field gives the index of the first byte to copied from - * cw.cr.b. - */ - int classReaderOffset; - - /** - * If not zero, indicates that the code of this method must be copied from - * the ClassReader associated to this writer in cw.cr. More - * precisely, this field gives the number of bytes to copied from - * cw.cr.b. - */ - int classReaderLength; - - /** - * Number of exceptions that can be thrown by this method. - */ - int exceptionCount; - - /** - * The exceptions that can be thrown by this method. More precisely, this - * array contains the indexes of the constant pool items that contain the - * internal names of these exception classes. - */ - int[] exceptions; - - /** - * The annotation default attribute of this method. May be null. - */ - private ByteVector annd; - - /** - * The runtime visible annotations of this method. May be null. - */ - private AnnotationWriter anns; - - /** - * The runtime invisible annotations of this method. May be null. - */ - private AnnotationWriter ianns; - - /** - * The runtime visible parameter annotations of this method. May be - * null. - */ - private AnnotationWriter[] panns; - - /** - * The runtime invisible parameter annotations of this method. May be - * null. - */ - private AnnotationWriter[] ipanns; - - /** - * The number of synthetic parameters of this method. - */ - private int synthetics; - - /** - * The non standard attributes of the method. - */ - private Attribute attrs; - - /** - * The bytecode of this method. - */ - private ByteVector code = new ByteVector(); - - /** - * Maximum stack size of this method. - */ - private int maxStack; - - /** - * Maximum number of local variables for this method. - */ - private int maxLocals; - - /** - * Number of stack map frames in the StackMapTable attribute. - */ - private int frameCount; - - /** - * The StackMapTable attribute. - */ - private ByteVector stackMap; - - /** - * The offset of the last frame that was written in the StackMapTable - * attribute. - */ - private int previousFrameOffset; - - /** - * The last frame that was written in the StackMapTable attribute. - * - * @see #frame - */ - private int[] previousFrame; - - /** - * Index of the next element to be added in {@link #frame}. - */ - private int frameIndex; - - /** - * The current stack map frame. The first element contains the offset of the - * instruction to which the frame corresponds, the second element is the - * number of locals and the third one is the number of stack elements. The - * local variables start at index 3 and are followed by the operand stack - * values. In summary frame[0] = offset, frame[1] = nLocal, frame[2] = - * nStack, frame[3] = nLocal. All types are encoded as integers, with the - * same format as the one used in {@link Label}, but limited to BASE types. - */ - private int[] frame; - - /** - * Number of elements in the exception handler list. - */ - private int handlerCount; - - /** - * The first element in the exception handler list. - */ - private Handler firstHandler; - - /** - * The last element in the exception handler list. - */ - private Handler lastHandler; - - /** - * Number of entries in the LocalVariableTable attribute. - */ - private int localVarCount; - - /** - * The LocalVariableTable attribute. - */ - private ByteVector localVar; - - /** - * Number of entries in the LocalVariableTypeTable attribute. - */ - private int localVarTypeCount; - - /** - * The LocalVariableTypeTable attribute. - */ - private ByteVector localVarType; - - /** - * Number of entries in the LineNumberTable attribute. - */ - private int lineNumberCount; - - /** - * The LineNumberTable attribute. - */ - private ByteVector lineNumber; - - /** - * The non standard attributes of the method's code. - */ - private Attribute cattrs; - - /** - * Indicates if some jump instructions are too small and need to be resized. - */ - private boolean resize; - - /** - * The number of subroutines in this method. - */ - private int subroutines; - - // ------------------------------------------------------------------------ - - /* - * Fields for the control flow graph analysis algorithm (used to compute the - * maximum stack size). A control flow graph contains one node per - * "basic block", and one edge per "jump" from one basic block to another. - * Each node (i.e., each basic block) is represented by the Label object - * that corresponds to the first instruction of this basic block. Each node - * also stores the list of its successors in the graph, as a linked list of - * Edge objects. - */ - - /** - * Indicates what must be automatically computed. - * - * @see #FRAMES - * @see #MAXS - * @see #NOTHING - */ - private final int compute; - - /** - * A list of labels. This list is the list of basic blocks in the method, - * i.e. a list of Label objects linked to each other by their - * {@link Label#successor} field, in the order they are visited by - * {@link MethodVisitor#visitLabel}, and starting with the first basic - * block. - */ - private Label labels; - - /** - * The previous basic block. - */ - private Label previousBlock; - - /** - * The current basic block. - */ - private Label currentBlock; - - /** - * The (relative) stack size after the last visited instruction. This size - * is relative to the beginning of the current basic block, i.e., the true - * stack size after the last visited instruction is equal to the - * {@link Label#inputStackTop beginStackSize} of the current basic block - * plus stackSize. - */ - private int stackSize; - - /** - * The (relative) maximum stack size after the last visited instruction. - * This size is relative to the beginning of the current basic block, i.e., - * the true maximum stack size after the last visited instruction is equal - * to the {@link Label#inputStackTop beginStackSize} of the current basic - * block plus stackSize. - */ - private int maxStackSize; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructs a new {@link MethodWriter}. - * - * @param cw the class writer in which the method must be added. - * @param access the method's access flags (see {@link Opcodes}). - * @param name the method's name. - * @param desc the method's descriptor (see {@link Type}). - * @param signature the method's signature. May be null. - * @param exceptions the internal names of the method's exceptions. May be - * null. - * @param computeMaxs true if the maximum stack size and number of - * local variables must be automatically computed. - * @param computeFrames true if the stack map tables must be - * recomputed from scratch. - */ - MethodWriter(final ClassWriter cw, final int access, final String name, final String desc, final String signature, - final String[] exceptions, final boolean computeMaxs, final boolean computeFrames) { - if (cw.firstMethod == null) { - cw.firstMethod = this; - } else { - cw.lastMethod.next = this; - } - cw.lastMethod = this; - this.cw = cw; - this.access = access; - this.name = cw.newUTF8(name); - this.desc = cw.newUTF8(desc); - this.descriptor = desc; - if (ClassReader.SIGNATURES) { - this.signature = signature; - } - if (exceptions != null && exceptions.length > 0) { - exceptionCount = exceptions.length; - this.exceptions = new int[exceptionCount]; - for (int i = 0; i < exceptionCount; ++i) { - this.exceptions[i] = cw.newClass(exceptions[i]); - } - } - this.compute = computeFrames ? FRAMES : computeMaxs ? MAXS : NOTHING; - if (computeMaxs || computeFrames) { - if (computeFrames && "".equals(name)) { - this.access |= ACC_CONSTRUCTOR; - } - // updates maxLocals - int size = getArgumentsAndReturnSizes(descriptor) >> 2; - if ((access & Opcodes.ACC_STATIC) != 0) { - --size; - } - maxLocals = size; - // creates and visits the label for the first basic block - labels = new Label(); - labels.status |= Label.PUSHED; - visitLabel(labels); - } - } - - // ------------------------------------------------------------------------ - // Implementation of the MethodVisitor interface - // ------------------------------------------------------------------------ - - public AnnotationVisitor visitAnnotationDefault() { - if (!ClassReader.ANNOTATIONS) { - return null; - } - annd = new ByteVector(); - return new AnnotationWriter(cw, false, annd, null, 0); - } - - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write type, and reserve space for values count - bv.putShort(cw.newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2); - if (visible) { - aw.next = anns; - anns = aw; - } else { - aw.next = ianns; - ianns = aw; - } - return aw; - } - - public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc, final boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - if ("Ljava/lang/Synthetic;".equals(desc)) { - // workaround for a bug in javac with synthetic parameters - // see ClassReader.readParameterAnnotations - synthetics = Math.max(synthetics, parameter + 1); - return new AnnotationWriter(cw, false, bv, null, 0); - } - // write type, and reserve space for values count - bv.putShort(cw.newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2); - if (visible) { - if (panns == null) { - panns = new AnnotationWriter[Type.getArgumentTypes(descriptor).length]; - } - aw.next = panns[parameter]; - panns[parameter] = aw; - } else { - if (ipanns == null) { - ipanns = new AnnotationWriter[Type.getArgumentTypes(descriptor).length]; - } - aw.next = ipanns[parameter]; - ipanns[parameter] = aw; - } - return aw; - } - - public void visitAttribute(final Attribute attr) { - if (attr.isCodeAttribute()) { - attr.next = cattrs; - cattrs = attr; - } else { - attr.next = attrs; - attrs = attr; - } - } - - public void visitCode() { - } - - public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, - final Object[] stack) { - if (!ClassReader.FRAMES || compute == FRAMES) { - return; - } - - if (type == Opcodes.F_NEW) { - startFrame(code.length, nLocal, nStack); - for (int i = 0; i < nLocal; ++i) { - if (local[i] instanceof String) { - frame[frameIndex++] = Frame.OBJECT | cw.addType((String) local[i]); - } else if (local[i] instanceof Integer) { - frame[frameIndex++] = ((Integer) local[i]).intValue(); - } else { - frame[frameIndex++] = Frame.UNINITIALIZED - | cw.addUninitializedType("", ((Label) local[i]).position); - } - } - for (int i = 0; i < nStack; ++i) { - if (stack[i] instanceof String) { - frame[frameIndex++] = Frame.OBJECT | cw.addType((String) stack[i]); - } else if (stack[i] instanceof Integer) { - frame[frameIndex++] = ((Integer) stack[i]).intValue(); - } else { - frame[frameIndex++] = Frame.UNINITIALIZED - | cw.addUninitializedType("", ((Label) stack[i]).position); - } - } - endFrame(); - } else { - int delta; - if (stackMap == null) { - stackMap = new ByteVector(); - delta = code.length; - } else { - delta = code.length - previousFrameOffset - 1; - } - - switch (type) { - case Opcodes.F_FULL: - stackMap.putByte(FULL_FRAME).putShort(delta).putShort(nLocal); - for (int i = 0; i < nLocal; ++i) { - writeFrameType(local[i]); - } - stackMap.putShort(nStack); - for (int i = 0; i < nStack; ++i) { - writeFrameType(stack[i]); - } - break; - case Opcodes.F_APPEND: - stackMap.putByte(SAME_FRAME_EXTENDED + nLocal).putShort(delta); - for (int i = 0; i < nLocal; ++i) { - writeFrameType(local[i]); - } - break; - case Opcodes.F_CHOP: - stackMap.putByte(SAME_FRAME_EXTENDED - nLocal).putShort(delta); - break; - case Opcodes.F_SAME: - if (delta < 64) { - stackMap.putByte(delta); - } else { - stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta); - } - break; - case Opcodes.F_SAME1: - if (delta < 64) { - stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta); - } else { - stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED).putShort(delta); - } - writeFrameType(stack[0]); - break; - } - - previousFrameOffset = code.length; - ++frameCount; - } - } - - public void visitInsn(final int opcode) { - // adds the instruction to the bytecode of the method - code.putByte(opcode); - // update currentBlock - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(opcode, 0, null, null); - } else { - // updates current and max stack sizes - int size = stackSize + Frame.SIZE[opcode]; - if (size > maxStackSize) { - maxStackSize = size; - } - stackSize = size; - } - // if opcode == ATHROW or xRETURN, ends current block (no successor) - if (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN || opcode == Opcodes.ATHROW) { - noSuccessor(); - } - } - } - - public void visitIntInsn(final int opcode, final int operand) { - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(opcode, operand, null, null); - } else if (opcode != Opcodes.NEWARRAY) { - // updates current and max stack sizes only for NEWARRAY - // (stack size variation = 0 for BIPUSH or SIPUSH) - int size = stackSize + 1; - if (size > maxStackSize) { - maxStackSize = size; - } - stackSize = size; - } - } - // adds the instruction to the bytecode of the method - if (opcode == Opcodes.SIPUSH) { - code.put12(opcode, operand); - } else { // BIPUSH or NEWARRAY - code.put11(opcode, operand); - } - } - - public void visitVarInsn(final int opcode, final int var) { - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(opcode, var, null, null); - } else { - // updates current and max stack sizes - if (opcode == Opcodes.RET) { - // no stack change, but end of current block (no successor) - currentBlock.status |= Label.RET; - // save 'stackSize' here for future use - // (see {@link #findSubroutineSuccessors}) - currentBlock.inputStackTop = stackSize; - noSuccessor(); - } else { // xLOAD or xSTORE - int size = stackSize + Frame.SIZE[opcode]; - if (size > maxStackSize) { - maxStackSize = size; - } - stackSize = size; - } - } - } - if (compute != NOTHING) { - // updates max locals - int n; - if (opcode == Opcodes.LLOAD || opcode == Opcodes.DLOAD || opcode == Opcodes.LSTORE - || opcode == Opcodes.DSTORE) { - n = var + 2; - } else { - n = var + 1; - } - if (n > maxLocals) { - maxLocals = n; - } - } - // adds the instruction to the bytecode of the method - if (var < 4 && opcode != Opcodes.RET) { - int opt; - if (opcode < Opcodes.ISTORE) { - /* ILOAD_0 */ - opt = 26 + (opcode - Opcodes.ILOAD << 2) + var; - } else { - /* ISTORE_0 */ - opt = 59 + (opcode - Opcodes.ISTORE << 2) + var; - } - code.putByte(opt); - } else if (var >= 256) { - code.putByte(196 /* WIDE */).put12(opcode, var); - } else { - code.put11(opcode, var); - } - if (opcode >= Opcodes.ISTORE && compute == FRAMES && handlerCount > 0) { - visitLabel(new Label()); - } - } - - public void visitTypeInsn(final int opcode, final String type) { - Item i = cw.newClassItem(type); - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(opcode, code.length, cw, i); - } else if (opcode == Opcodes.NEW) { - // updates current and max stack sizes only if opcode == NEW - // (no stack change for ANEWARRAY, CHECKCAST, INSTANCEOF) - int size = stackSize + 1; - if (size > maxStackSize) { - maxStackSize = size; - } - stackSize = size; - } - } - // adds the instruction to the bytecode of the method - code.put12(opcode, i.index); - } - - public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { - Item i = cw.newFieldItem(owner, name, desc); - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(opcode, 0, cw, i); - } else { - int size; - // computes the stack size variation - char c = desc.charAt(0); - switch (opcode) { - case Opcodes.GETSTATIC: - size = stackSize + (c == 'D' || c == 'J' ? 2 : 1); - break; - case Opcodes.PUTSTATIC: - size = stackSize + (c == 'D' || c == 'J' ? -2 : -1); - break; - case Opcodes.GETFIELD: - size = stackSize + (c == 'D' || c == 'J' ? 1 : 0); - break; - // case Constants.PUTFIELD: - default: - size = stackSize + (c == 'D' || c == 'J' ? -3 : -2); - break; - } - // updates current and max stack sizes - if (size > maxStackSize) { - maxStackSize = size; - } - stackSize = size; - } - } - // adds the instruction to the bytecode of the method - code.put12(opcode, i.index); - } - - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - boolean itf = opcode == Opcodes.INVOKEINTERFACE; - Item i = cw.newMethodItem(owner, name, desc, itf); - int argSize = i.intVal; - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(opcode, 0, cw, i); - } else { - /* - * computes the stack size variation. In order not to recompute - * several times this variation for the same Item, we use the - * intVal field of this item to store this variation, once it - * has been computed. More precisely this intVal field stores - * the sizes of the arguments and of the return value - * corresponding to desc. - */ - if (argSize == 0) { - // the above sizes have not been computed yet, - // so we compute them... - argSize = getArgumentsAndReturnSizes(desc); - // ... and we save them in order - // not to recompute them in the future - i.intVal = argSize; - } - int size; - if (opcode == Opcodes.INVOKESTATIC) { - size = stackSize - (argSize >> 2) + (argSize & 0x03) + 1; - } else { - size = stackSize - (argSize >> 2) + (argSize & 0x03); - } - // updates current and max stack sizes - if (size > maxStackSize) { - maxStackSize = size; - } - stackSize = size; - } - } - // adds the instruction to the bytecode of the method - if (itf) { - if (argSize == 0) { - argSize = getArgumentsAndReturnSizes(desc); - i.intVal = argSize; - } - code.put12(Opcodes.INVOKEINTERFACE, i.index).put11(argSize >> 2, 0); - } else { - code.put12(opcode, i.index); - } - } - - public void visitJumpInsn(final int opcode, final Label label) { - Label nextInsn = null; - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(opcode, 0, null, null); - // 'label' is the target of a jump instruction - label.getFirst().status |= Label.TARGET; - // adds 'label' as a successor of this basic block - addSuccessor(Edge.NORMAL, label); - if (opcode != Opcodes.GOTO) { - // creates a Label for the next basic block - nextInsn = new Label(); - } - } else { - if (opcode == Opcodes.JSR) { - if ((label.status & Label.SUBROUTINE) == 0) { - label.status |= Label.SUBROUTINE; - ++subroutines; - } - currentBlock.status |= Label.JSR; - addSuccessor(stackSize + 1, label); - // creates a Label for the next basic block - nextInsn = new Label(); - /* - * note that, by construction in this method, a JSR block - * has at least two successors in the control flow graph: - * the first one leads the next instruction after the JSR, - * while the second one leads to the JSR target. - */ - } else { - // updates current stack size (max stack size unchanged - // because stack size variation always negative in this - // case) - stackSize += Frame.SIZE[opcode]; - addSuccessor(stackSize, label); - } - } - } - // adds the instruction to the bytecode of the method - if ((label.status & Label.RESOLVED) != 0 && label.position - code.length < Short.MIN_VALUE) { - /* - * case of a backward jump with an offset < -32768. In this case we - * automatically replace GOTO with GOTO_W, JSR with JSR_W and IFxxx - * with IFNOTxxx GOTO_W , where IFNOTxxx is the - * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where - * designates the instruction just after the GOTO_W. - */ - if (opcode == Opcodes.GOTO) { - code.putByte(200); // GOTO_W - } else if (opcode == Opcodes.JSR) { - code.putByte(201); // JSR_W - } else { - // if the IF instruction is transformed into IFNOT GOTO_W the - // next instruction becomes the target of the IFNOT instruction - if (nextInsn != null) { - nextInsn.status |= Label.TARGET; - } - code.putByte(opcode <= 166 ? (opcode + 1 ^ 1) - 1 : opcode ^ 1); - code.putShort(8); // jump offset - code.putByte(200); // GOTO_W - } - label.put(this, code, code.length - 1, true); - } else { - /* - * case of a backward jump with an offset >= -32768, or of a forward - * jump with, of course, an unknown offset. In these cases we store - * the offset in 2 bytes (which will be increased in - * resizeInstructions, if needed). - */ - code.putByte(opcode); - label.put(this, code, code.length - 1, false); - } - if (currentBlock != null) { - if (nextInsn != null) { - // if the jump instruction is not a GOTO, the next instruction - // is also a successor of this instruction. Calling visitLabel - // adds the label of this next instruction as a successor of the - // current block, and starts a new basic block - visitLabel(nextInsn); - } - if (opcode == Opcodes.GOTO) { - noSuccessor(); - } - } - } - - public void visitLabel(final Label label) { - // resolves previous forward references to label, if any - resize |= label.resolve(this, code.length, code.data); - // updates currentBlock - if ((label.status & Label.DEBUG) != 0) { - return; - } - if (compute == FRAMES) { - if (currentBlock != null) { - if (label.position == currentBlock.position) { - // successive labels, do not start a new basic block - currentBlock.status |= label.status & Label.TARGET; - label.frame = currentBlock.frame; - return; - } - // ends current block (with one new successor) - addSuccessor(Edge.NORMAL, label); - } - // begins a new current block - currentBlock = label; - if (label.frame == null) { - label.frame = new Frame(); - label.frame.owner = label; - } - // updates the basic block list - if (previousBlock != null) { - if (label.position == previousBlock.position) { - previousBlock.status |= label.status & Label.TARGET; - label.frame = previousBlock.frame; - currentBlock = previousBlock; - return; - } - previousBlock.successor = label; - } - previousBlock = label; - } else if (compute == MAXS) { - if (currentBlock != null) { - // ends current block (with one new successor) - currentBlock.outputStackMax = maxStackSize; - addSuccessor(stackSize, label); - } - // begins a new current block - currentBlock = label; - // resets the relative current and max stack sizes - stackSize = 0; - maxStackSize = 0; - // updates the basic block list - if (previousBlock != null) { - previousBlock.successor = label; - } - previousBlock = label; - } - } - - public void visitLdcInsn(final Object cst) { - Item i = cw.newConstItem(cst); - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(Opcodes.LDC, 0, cw, i); - } else { - int size; - // computes the stack size variation - if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE) { - size = stackSize + 2; - } else { - size = stackSize + 1; - } - // updates current and max stack sizes - if (size > maxStackSize) { - maxStackSize = size; - } - stackSize = size; - } - } - // adds the instruction to the bytecode of the method - int index = i.index; - if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE) { - code.put12(20 /* LDC2_W */, index); - } else if (index >= 256) { - code.put12(19 /* LDC_W */, index); - } else { - code.put11(Opcodes.LDC, index); - } - } - - public void visitIincInsn(final int var, final int increment) { - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(Opcodes.IINC, var, null, null); - } - } - if (compute != NOTHING) { - // updates max locals - int n = var + 1; - if (n > maxLocals) { - maxLocals = n; - } - } - // adds the instruction to the bytecode of the method - if (var > 255 || increment > 127 || increment < -128) { - code.putByte(196 /* WIDE */).put12(Opcodes.IINC, var).putShort(increment); - } else { - code.putByte(Opcodes.IINC).put11(var, increment); - } - } - - public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label[] labels) { - // adds the instruction to the bytecode of the method - int source = code.length; - code.putByte(Opcodes.TABLESWITCH); - code.length += (4 - code.length % 4) % 4; - dflt.put(this, code, source, true); - code.putInt(min).putInt(max); - for (int i = 0; i < labels.length; ++i) { - labels[i].put(this, code, source, true); - } - // updates currentBlock - visitSwitchInsn(dflt, labels); - } - - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { - // adds the instruction to the bytecode of the method - int source = code.length; - code.putByte(Opcodes.LOOKUPSWITCH); - code.length += (4 - code.length % 4) % 4; - dflt.put(this, code, source, true); - code.putInt(labels.length); - for (int i = 0; i < labels.length; ++i) { - code.putInt(keys[i]); - labels[i].put(this, code, source, true); - } - // updates currentBlock - visitSwitchInsn(dflt, labels); - } - - private void visitSwitchInsn(final Label dflt, final Label[] labels) { - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(Opcodes.LOOKUPSWITCH, 0, null, null); - // adds current block successors - addSuccessor(Edge.NORMAL, dflt); - dflt.getFirst().status |= Label.TARGET; - for (int i = 0; i < labels.length; ++i) { - addSuccessor(Edge.NORMAL, labels[i]); - labels[i].getFirst().status |= Label.TARGET; - } - } else { - // updates current stack size (max stack size unchanged) - --stackSize; - // adds current block successors - addSuccessor(stackSize, dflt); - for (int i = 0; i < labels.length; ++i) { - addSuccessor(stackSize, labels[i]); - } - } - // ends current block - noSuccessor(); - } - } - - public void visitMultiANewArrayInsn(final String desc, final int dims) { - Item i = cw.newClassItem(desc); - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(Opcodes.MULTIANEWARRAY, dims, cw, i); - } else { - // updates current stack size (max stack size unchanged because - // stack size variation always negative or null) - stackSize += 1 - dims; - } - } - // adds the instruction to the bytecode of the method - code.put12(Opcodes.MULTIANEWARRAY, i.index).putByte(dims); - } - - public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type) { - ++handlerCount; - Handler h = new Handler(); - h.start = start; - h.end = end; - h.handler = handler; - h.desc = type; - h.type = type != null ? cw.newClass(type) : 0; - if (lastHandler == null) { - firstHandler = h; - } else { - lastHandler.next = h; - } - lastHandler = h; - } - - public void visitLocalVariable(final String name, final String desc, final String signature, final Label start, - final Label end, final int index) { - if (signature != null) { - if (localVarType == null) { - localVarType = new ByteVector(); - } - ++localVarTypeCount; - localVarType.putShort(start.position).putShort(end.position - start.position).putShort(cw.newUTF8(name)) - .putShort(cw.newUTF8(signature)).putShort(index); - } - if (localVar == null) { - localVar = new ByteVector(); - } - ++localVarCount; - localVar.putShort(start.position).putShort(end.position - start.position).putShort(cw.newUTF8(name)).putShort( - cw.newUTF8(desc)).putShort(index); - if (compute != NOTHING) { - // updates max locals - char c = desc.charAt(0); - int n = index + (c == 'J' || c == 'D' ? 2 : 1); - if (n > maxLocals) { - maxLocals = n; - } - } - } - - public void visitLineNumber(final int line, final Label start) { - if (lineNumber == null) { - lineNumber = new ByteVector(); - } - ++lineNumberCount; - lineNumber.putShort(start.position); - lineNumber.putShort(line); - } - - public void visitMaxs(final int maxStack, final int maxLocals) { - if (ClassReader.FRAMES && compute == FRAMES) { - // completes the control flow graph with exception handler blocks - Handler handler = firstHandler; - while (handler != null) { - Label l = handler.start.getFirst(); - Label h = handler.handler.getFirst(); - Label e = handler.end.getFirst(); - // computes the kind of the edges to 'h' - String t = handler.desc == null ? "java/lang/Throwable" : handler.desc; - int kind = Frame.OBJECT | cw.addType(t); - // h is an exception handler - h.status |= Label.TARGET; - // adds 'h' as a successor of labels between 'start' and 'end' - while (l != e) { - // creates an edge to 'h' - Edge b = new Edge(); - b.info = kind; - b.successor = h; - // adds it to the successors of 'l' - b.next = l.successors; - l.successors = b; - // goes to the next label - l = l.successor; - } - handler = handler.next; - } - - // creates and visits the first (implicit) frame - Frame f = labels.frame; - Type[] args = Type.getArgumentTypes(descriptor); - f.initInputFrame(cw, access, args, this.maxLocals); - visitFrame(f); - - /* - * fix point algorithm: mark the first basic block as 'changed' - * (i.e. put it in the 'changed' list) and, while there are changed - * basic blocks, choose one, mark it as unchanged, and update its - * successors (which can be changed in the process). - */ - int max = 0; - Label changed = labels; - while (changed != null) { - // removes a basic block from the list of changed basic blocks - Label l = changed; - changed = changed.next; - l.next = null; - f = l.frame; - // a reacheable jump target must be stored in the stack map - if ((l.status & Label.TARGET) != 0) { - l.status |= Label.STORE; - } - // all visited labels are reacheable, by definition - l.status |= Label.REACHABLE; - // updates the (absolute) maximum stack size - int blockMax = f.inputStack.length + l.outputStackMax; - if (blockMax > max) { - max = blockMax; - } - // updates the successors of the current basic block - Edge e = l.successors; - while (e != null) { - Label n = e.successor.getFirst(); - boolean change = f.merge(cw, n.frame, e.info); - if (change && n.next == null) { - // if n has changed and is not already in the 'changed' - // list, adds it to this list - n.next = changed; - changed = n; - } - e = e.next; - } - } - this.maxStack = max; - - // visits all the frames that must be stored in the stack map - Label l = labels; - while (l != null) { - f = l.frame; - if ((l.status & Label.STORE) != 0) { - visitFrame(f); - } - if ((l.status & Label.REACHABLE) == 0) { - // finds start and end of dead basic block - Label k = l.successor; - int start = l.position; - int end = (k == null ? code.length : k.position) - 1; - // if non empty basic block - if (end >= start) { - // replaces instructions with NOP ... NOP ATHROW - for (int i = start; i < end; ++i) { - code.data[i] = Opcodes.NOP; - } - code.data[end] = (byte) Opcodes.ATHROW; - // emits a frame for this unreachable block - startFrame(start, 0, 1); - frame[frameIndex++] = Frame.OBJECT | cw.addType("java/lang/Throwable"); - endFrame(); - } - } - l = l.successor; - } - } else if (compute == MAXS) { - // completes the control flow graph with exception handler blocks - Handler handler = firstHandler; - while (handler != null) { - Label l = handler.start; - Label h = handler.handler; - Label e = handler.end; - // adds 'h' as a successor of labels between 'start' and 'end' - while (l != e) { - // creates an edge to 'h' - Edge b = new Edge(); - b.info = Edge.EXCEPTION; - b.successor = h; - // adds it to the successors of 'l' - if ((l.status & Label.JSR) == 0) { - b.next = l.successors; - l.successors = b; - } else { - // if l is a JSR block, adds b after the first two edges - // to preserve the hypothesis about JSR block successors - // order (see {@link #visitJumpInsn}) - b.next = l.successors.next.next; - l.successors.next.next = b; - } - // goes to the next label - l = l.successor; - } - handler = handler.next; - } - - if (subroutines > 0) { - // completes the control flow graph with the RET successors - /* - * first step: finds the subroutines. This step determines, for - * each basic block, to which subroutine(s) it belongs. - */ - // finds the basic blocks that belong to the "main" subroutine - int id = 0; - labels.visitSubroutine(null, 1, subroutines); - // finds the basic blocks that belong to the real subroutines - Label l = labels; - while (l != null) { - if ((l.status & Label.JSR) != 0) { - // the subroutine is defined by l's TARGET, not by l - Label subroutine = l.successors.next.successor; - // if this subroutine has not been visited yet... - if ((subroutine.status & Label.VISITED) == 0) { - // ...assigns it a new id and finds its basic blocks - id += 1; - subroutine.visitSubroutine(null, id / 32L << 32 | 1L << id % 32, subroutines); - } - } - l = l.successor; - } - // second step: finds the successors of RET blocks - l = labels; - while (l != null) { - if ((l.status & Label.JSR) != 0) { - Label L = labels; - while (L != null) { - L.status &= ~Label.VISITED; - L = L.successor; - } - // the subroutine is defined by l's TARGET, not by l - Label subroutine = l.successors.next.successor; - subroutine.visitSubroutine(l, 0, subroutines); - } - l = l.successor; - } - } - - /* - * control flow analysis algorithm: while the block stack is not - * empty, pop a block from this stack, update the max stack size, - * compute the true (non relative) begin stack size of the - * successors of this block, and push these successors onto the - * stack (unless they have already been pushed onto the stack). - * Note: by hypothesis, the {@link Label#inputStackTop} of the - * blocks in the block stack are the true (non relative) beginning - * stack sizes of these blocks. - */ - int max = 0; - Label stack = labels; - while (stack != null) { - // pops a block from the stack - Label l = stack; - stack = stack.next; - // computes the true (non relative) max stack size of this block - int start = l.inputStackTop; - int blockMax = start + l.outputStackMax; - // updates the global max stack size - if (blockMax > max) { - max = blockMax; - } - // analyzes the successors of the block - Edge b = l.successors; - if ((l.status & Label.JSR) != 0) { - // ignores the first edge of JSR blocks (virtual successor) - b = b.next; - } - while (b != null) { - l = b.successor; - // if this successor has not already been pushed... - if ((l.status & Label.PUSHED) == 0) { - // computes its true beginning stack size... - l.inputStackTop = b.info == Edge.EXCEPTION ? 1 : start + b.info; - // ...and pushes it onto the stack - l.status |= Label.PUSHED; - l.next = stack; - stack = l; - } - b = b.next; - } - } - this.maxStack = max; - } else { - this.maxStack = maxStack; - this.maxLocals = maxLocals; - } - } - - public void visitEnd() { - } - - // ------------------------------------------------------------------------ - // Utility methods: control flow analysis algorithm - // ------------------------------------------------------------------------ - - /** - * Computes the size of the arguments and of the return value of a method. - * - * @param desc the descriptor of a method. - * @return the size of the arguments of the method (plus one for the - * implicit this argument), argSize, and the size of its return - * value, retSize, packed into a single int i = - * (argSize << 2) | retSize (argSize is therefore equal to - * i >> 2, and retSize to i & 0x03). - */ - static int getArgumentsAndReturnSizes(final String desc) { - int n = 1; - int c = 1; - while (true) { - char car = desc.charAt(c++); - if (car == ')') { - car = desc.charAt(c); - return n << 2 | (car == 'V' ? 0 : car == 'D' || car == 'J' ? 2 : 1); - } else if (car == 'L') { - while (desc.charAt(c++) != ';') { - } - n += 1; - } else if (car == '[') { - while ((car = desc.charAt(c)) == '[') { - ++c; - } - if (car == 'D' || car == 'J') { - n -= 1; - } - } else if (car == 'D' || car == 'J') { - n += 2; - } else { - n += 1; - } - } - } - - /** - * Adds a successor to the {@link #currentBlock currentBlock} block. - * - * @param info information about the control flow edge to be added. - * @param successor the successor block to be added to the current block. - */ - private void addSuccessor(final int info, final Label successor) { - // creates and initializes an Edge object... - Edge b = new Edge(); - b.info = info; - b.successor = successor; - // ...and adds it to the successor list of the currentBlock block - b.next = currentBlock.successors; - currentBlock.successors = b; - } - - /** - * Ends the current basic block. This method must be used in the case where - * the current basic block does not have any successor. - */ - private void noSuccessor() { - if (compute == FRAMES) { - Label l = new Label(); - l.frame = new Frame(); - l.frame.owner = l; - l.resolve(this, code.length, code.data); - previousBlock.successor = l; - previousBlock = l; - } else { - currentBlock.outputStackMax = maxStackSize; - } - currentBlock = null; - } - - // ------------------------------------------------------------------------ - // Utility methods: stack map frames - // ------------------------------------------------------------------------ - - /** - * Visits a frame that has been computed from scratch. - * - * @param f the frame that must be visited. - */ - private void visitFrame(final Frame f) { - int i, t; - int nTop = 0; - int nLocal = 0; - int nStack = 0; - int[] locals = f.inputLocals; - int[] stacks = f.inputStack; - // computes the number of locals (ignores TOP types that are just after - // a LONG or a DOUBLE, and all trailing TOP types) - for (i = 0; i < locals.length; ++i) { - t = locals[i]; - if (t == Frame.TOP) { - ++nTop; - } else { - nLocal += nTop + 1; - nTop = 0; - } - if (t == Frame.LONG || t == Frame.DOUBLE) { - ++i; - } - } - // computes the stack size (ignores TOP types that are just after - // a LONG or a DOUBLE) - for (i = 0; i < stacks.length; ++i) { - t = stacks[i]; - ++nStack; - if (t == Frame.LONG || t == Frame.DOUBLE) { - ++i; - } - } - // visits the frame and its content - startFrame(f.owner.position, nLocal, nStack); - for (i = 0; nLocal > 0; ++i, --nLocal) { - t = locals[i]; - frame[frameIndex++] = t; - if (t == Frame.LONG || t == Frame.DOUBLE) { - ++i; - } - } - for (i = 0; i < stacks.length; ++i) { - t = stacks[i]; - frame[frameIndex++] = t; - if (t == Frame.LONG || t == Frame.DOUBLE) { - ++i; - } - } - endFrame(); - } - - /** - * Starts the visit of a stack map frame. - * - * @param offset the offset of the instruction to which the frame - * corresponds. - * @param nLocal the number of local variables in the frame. - * @param nStack the number of stack elements in the frame. - */ - private void startFrame(final int offset, final int nLocal, final int nStack) { - int n = 3 + nLocal + nStack; - if (frame == null || frame.length < n) { - frame = new int[n]; - } - frame[0] = offset; - frame[1] = nLocal; - frame[2] = nStack; - frameIndex = 3; - } - - /** - * Checks if the visit of the current frame {@link #frame} is finished, and - * if yes, write it in the StackMapTable attribute. - */ - private void endFrame() { - if (previousFrame != null) { // do not write the first frame - if (stackMap == null) { - stackMap = new ByteVector(); - } - writeFrame(); - ++frameCount; - } - previousFrame = frame; - frame = null; - } - - /** - * Compress and writes the current frame {@link #frame} in the StackMapTable - * attribute. - */ - private void writeFrame() { - int clocalsSize = frame[1]; - int cstackSize = frame[2]; - if ((cw.version & 0xFFFF) < Opcodes.V1_6) { - stackMap.putShort(frame[0]).putShort(clocalsSize); - writeFrameTypes(3, 3 + clocalsSize); - stackMap.putShort(cstackSize); - writeFrameTypes(3 + clocalsSize, 3 + clocalsSize + cstackSize); - return; - } - int localsSize = previousFrame[1]; - int type = FULL_FRAME; - int k = 0; - int delta; - if (frameCount == 0) { - delta = frame[0]; - } else { - delta = frame[0] - previousFrame[0] - 1; - } - if (cstackSize == 0) { - k = clocalsSize - localsSize; - switch (k) { - case -3: - case -2: - case -1: - type = CHOP_FRAME; - localsSize = clocalsSize; - break; - case 0: - type = delta < 64 ? SAME_FRAME : SAME_FRAME_EXTENDED; - break; - case 1: - case 2: - case 3: - type = APPEND_FRAME; - break; - } - } else if (clocalsSize == localsSize && cstackSize == 1) { - type = delta < 63 ? SAME_LOCALS_1_STACK_ITEM_FRAME : SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED; - } - if (type != FULL_FRAME) { - // verify if locals are the same - int l = 3; - for (int j = 0; j < localsSize; j++) { - if (frame[l] != previousFrame[l]) { - type = FULL_FRAME; - break; - } - l++; - } - } - switch (type) { - case SAME_FRAME: - stackMap.putByte(delta); - break; - case SAME_LOCALS_1_STACK_ITEM_FRAME: - stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta); - writeFrameTypes(3 + clocalsSize, 4 + clocalsSize); - break; - case SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED: - stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED).putShort(delta); - writeFrameTypes(3 + clocalsSize, 4 + clocalsSize); - break; - case SAME_FRAME_EXTENDED: - stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta); - break; - case CHOP_FRAME: - stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta); - break; - case APPEND_FRAME: - stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta); - writeFrameTypes(3 + localsSize, 3 + clocalsSize); - break; - // case FULL_FRAME: - default: - stackMap.putByte(FULL_FRAME).putShort(delta).putShort(clocalsSize); - writeFrameTypes(3, 3 + clocalsSize); - stackMap.putShort(cstackSize); - writeFrameTypes(3 + clocalsSize, 3 + clocalsSize + cstackSize); - } - } - - /** - * Writes some types of the current frame {@link #frame} into the - * StackMapTableAttribute. This method converts types from the format used - * in {@link Label} to the format used in StackMapTable attributes. In - * particular, it converts type table indexes to constant pool indexes. - * - * @param start index of the first type in {@link #frame} to write. - * @param end index of last type in {@link #frame} to write (exclusive). - */ - private void writeFrameTypes(final int start, final int end) { - for (int i = start; i < end; ++i) { - int t = frame[i]; - int d = t & Frame.DIM; - if (d == 0) { - int v = t & Frame.BASE_VALUE; - switch (t & Frame.BASE_KIND) { - case Frame.OBJECT: - stackMap.putByte(7).putShort(cw.newClass(cw.typeTable[v].strVal1)); - break; - case Frame.UNINITIALIZED: - stackMap.putByte(8).putShort(cw.typeTable[v].intVal); - break; - default: - stackMap.putByte(v); - } - } else { - StringBuilder buf = new StringBuilder(); - d >>= 28; - while (d-- > 0) { - buf.append('['); - } - if ((t & Frame.BASE_KIND) == Frame.OBJECT) { - buf.append('L'); - buf.append(cw.typeTable[t & Frame.BASE_VALUE].strVal1); - buf.append(';'); - } else { - switch (t & 0xF) { - case 1: - buf.append('I'); - break; - case 2: - buf.append('F'); - break; - case 3: - buf.append('D'); - break; - case 9: - buf.append('Z'); - break; - case 10: - buf.append('B'); - break; - case 11: - buf.append('C'); - break; - case 12: - buf.append('S'); - break; - default: - buf.append('J'); - } - } - stackMap.putByte(7).putShort(cw.newClass(buf.toString())); - } - } - } - - private void writeFrameType(final Object type) { - if (type instanceof String) { - stackMap.putByte(7).putShort(cw.newClass((String) type)); - } else if (type instanceof Integer) { - stackMap.putByte(((Integer) type).intValue()); - } else { - stackMap.putByte(8).putShort(((Label) type).position); - } - } - - // ------------------------------------------------------------------------ - // Utility methods: dump bytecode array - // ------------------------------------------------------------------------ - - /** - * Returns the size of the bytecode of this method. - * - * @return the size of the bytecode of this method. - */ - final int getSize() { - if (classReaderOffset != 0) { - return 6 + classReaderLength; - } - if (resize) { - // replaces the temporary jump opcodes introduced by Label.resolve. - if (ClassReader.RESIZE) { - resizeInstructions(); - } else { - throw new RuntimeException("Method code too large!"); - } - } - int size = 8; - if (code.length > 0) { - cw.newUTF8("Code"); - size += 18 + code.length + 8 * handlerCount; - if (localVar != null) { - cw.newUTF8("LocalVariableTable"); - size += 8 + localVar.length; - } - if (localVarType != null) { - cw.newUTF8("LocalVariableTypeTable"); - size += 8 + localVarType.length; - } - if (lineNumber != null) { - cw.newUTF8("LineNumberTable"); - size += 8 + lineNumber.length; - } - if (stackMap != null) { - boolean zip = (cw.version & 0xFFFF) >= Opcodes.V1_6; - cw.newUTF8(zip ? "StackMapTable" : "StackMap"); - size += 8 + stackMap.length; - } - if (cattrs != null) { - size += cattrs.getSize(cw, code.data, code.length, maxStack, maxLocals); - } - } - if (exceptionCount > 0) { - cw.newUTF8("Exceptions"); - size += 8 + 2 * exceptionCount; - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0 && (cw.version & 0xffff) < Opcodes.V1_5) { - cw.newUTF8("Synthetic"); - size += 6; - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - cw.newUTF8("Deprecated"); - size += 6; - } - if (ClassReader.SIGNATURES && signature != null) { - cw.newUTF8("Signature"); - cw.newUTF8(signature); - size += 8; - } - if (ClassReader.ANNOTATIONS && annd != null) { - cw.newUTF8("AnnotationDefault"); - size += 6 + annd.length; - } - if (ClassReader.ANNOTATIONS && anns != null) { - cw.newUTF8("RuntimeVisibleAnnotations"); - size += 8 + anns.getSize(); - } - if (ClassReader.ANNOTATIONS && ianns != null) { - cw.newUTF8("RuntimeInvisibleAnnotations"); - size += 8 + ianns.getSize(); - } - if (ClassReader.ANNOTATIONS && panns != null) { - cw.newUTF8("RuntimeVisibleParameterAnnotations"); - size += 7 + 2 * (panns.length - synthetics); - for (int i = panns.length - 1; i >= synthetics; --i) { - size += panns[i] == null ? 0 : panns[i].getSize(); - } - } - if (ClassReader.ANNOTATIONS && ipanns != null) { - cw.newUTF8("RuntimeInvisibleParameterAnnotations"); - size += 7 + 2 * (ipanns.length - synthetics); - for (int i = ipanns.length - 1; i >= synthetics; --i) { - size += ipanns[i] == null ? 0 : ipanns[i].getSize(); - } - } - if (attrs != null) { - size += attrs.getSize(cw, null, 0, -1, -1); - } - return size; - } - - /** - * Puts the bytecode of this method in the given byte vector. - * - * @param out the byte vector into which the bytecode of this method must be - * copied. - */ - final void put(final ByteVector out) { - out.putShort(access).putShort(name).putShort(desc); - if (classReaderOffset != 0) { - out.putByteArray(cw.cr.b, classReaderOffset, classReaderLength); - return; - } - int attributeCount = 0; - if (code.length > 0) { - ++attributeCount; - } - if (exceptionCount > 0) { - ++attributeCount; - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0 && (cw.version & 0xffff) < Opcodes.V1_5) { - ++attributeCount; - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - ++attributeCount; - } - if (ClassReader.SIGNATURES && signature != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && annd != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && anns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && ianns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && panns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && ipanns != null) { - ++attributeCount; - } - if (attrs != null) { - attributeCount += attrs.getCount(); - } - out.putShort(attributeCount); - if (code.length > 0) { - int size = 12 + code.length + 8 * handlerCount; - if (localVar != null) { - size += 8 + localVar.length; - } - if (localVarType != null) { - size += 8 + localVarType.length; - } - if (lineNumber != null) { - size += 8 + lineNumber.length; - } - if (stackMap != null) { - size += 8 + stackMap.length; - } - if (cattrs != null) { - size += cattrs.getSize(cw, code.data, code.length, maxStack, maxLocals); - } - out.putShort(cw.newUTF8("Code")).putInt(size); - out.putShort(maxStack).putShort(maxLocals); - out.putInt(code.length).putByteArray(code.data, 0, code.length); - out.putShort(handlerCount); - if (handlerCount > 0) { - Handler h = firstHandler; - while (h != null) { - out.putShort(h.start.position).putShort(h.end.position).putShort(h.handler.position).putShort( - h.type); - h = h.next; - } - } - attributeCount = 0; - if (localVar != null) { - ++attributeCount; - } - if (localVarType != null) { - ++attributeCount; - } - if (lineNumber != null) { - ++attributeCount; - } - if (stackMap != null) { - ++attributeCount; - } - if (cattrs != null) { - attributeCount += cattrs.getCount(); - } - out.putShort(attributeCount); - if (localVar != null) { - out.putShort(cw.newUTF8("LocalVariableTable")); - out.putInt(localVar.length + 2).putShort(localVarCount); - out.putByteArray(localVar.data, 0, localVar.length); - } - if (localVarType != null) { - out.putShort(cw.newUTF8("LocalVariableTypeTable")); - out.putInt(localVarType.length + 2).putShort(localVarTypeCount); - out.putByteArray(localVarType.data, 0, localVarType.length); - } - if (lineNumber != null) { - out.putShort(cw.newUTF8("LineNumberTable")); - out.putInt(lineNumber.length + 2).putShort(lineNumberCount); - out.putByteArray(lineNumber.data, 0, lineNumber.length); - } - if (stackMap != null) { - boolean zip = (cw.version & 0xFFFF) >= Opcodes.V1_6; - out.putShort(cw.newUTF8(zip ? "StackMapTable" : "StackMap")); - out.putInt(stackMap.length + 2).putShort(frameCount); - out.putByteArray(stackMap.data, 0, stackMap.length); - } - if (cattrs != null) { - cattrs.put(cw, code.data, code.length, maxLocals, maxStack, out); - } - } - if (exceptionCount > 0) { - out.putShort(cw.newUTF8("Exceptions")).putInt(2 * exceptionCount + 2); - out.putShort(exceptionCount); - for (int i = 0; i < exceptionCount; ++i) { - out.putShort(exceptions[i]); - } - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0 && (cw.version & 0xffff) < Opcodes.V1_5) { - out.putShort(cw.newUTF8("Synthetic")).putInt(0); - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - out.putShort(cw.newUTF8("Deprecated")).putInt(0); - } - if (ClassReader.SIGNATURES && signature != null) { - out.putShort(cw.newUTF8("Signature")).putInt(2).putShort(cw.newUTF8(signature)); - } - if (ClassReader.ANNOTATIONS && annd != null) { - out.putShort(cw.newUTF8("AnnotationDefault")); - out.putInt(annd.length); - out.putByteArray(annd.data, 0, annd.length); - } - if (ClassReader.ANNOTATIONS && anns != null) { - out.putShort(cw.newUTF8("RuntimeVisibleAnnotations")); - anns.put(out); - } - if (ClassReader.ANNOTATIONS && ianns != null) { - out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations")); - ianns.put(out); - } - if (ClassReader.ANNOTATIONS && panns != null) { - out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations")); - AnnotationWriter.put(panns, synthetics, out); - } - if (ClassReader.ANNOTATIONS && ipanns != null) { - out.putShort(cw.newUTF8("RuntimeInvisibleParameterAnnotations")); - AnnotationWriter.put(ipanns, synthetics, out); - } - if (attrs != null) { - attrs.put(cw, null, 0, -1, -1, out); - } - } - - // ------------------------------------------------------------------------ - // Utility methods: instruction resizing (used to handle GOTO_W and JSR_W) - // ------------------------------------------------------------------------ - - /** - * Resizes and replaces the temporary instructions inserted by - * {@link Label#resolve} for wide forward jumps, while keeping jump offsets - * and instruction addresses consistent. This may require to resize other - * existing instructions, or even to introduce new instructions: for - * example, increasing the size of an instruction by 2 at the middle of a - * method can increases the offset of an IFEQ instruction from 32766 to - * 32768, in which case IFEQ 32766 must be replaced with IFNEQ 8 GOTO_W - * 32765. This, in turn, may require to increase the size of another jump - * instruction, and so on... All these operations are handled automatically - * by this method. - *

- * This method must be called after all the method that is being built - * has been visited. In particular, the {@link Label Label} objects used - * to construct the method are no longer valid after this method has been - * called. - */ - private void resizeInstructions() { - byte[] b = code.data; // bytecode of the method - int u, v, label; // indexes in b - int i, j; // loop indexes - /* - * 1st step: As explained above, resizing an instruction may require to - * resize another one, which may require to resize yet another one, and - * so on. The first step of the algorithm consists in finding all the - * instructions that need to be resized, without modifying the code. - * This is done by the following "fix point" algorithm: Parse the code - * to find the jump instructions whose offset will need more than 2 - * bytes to be stored (the future offset is computed from the current - * offset and from the number of bytes that will be inserted or removed - * between the source and target instructions). For each such - * instruction, adds an entry in (a copy of) the indexes and sizes - * arrays (if this has not already been done in a previous iteration!). - * If at least one entry has been added during the previous step, go - * back to the beginning, otherwise stop. In fact the real algorithm is - * complicated by the fact that the size of TABLESWITCH and LOOKUPSWITCH - * instructions depends on their position in the bytecode (because of - * padding). In order to ensure the convergence of the algorithm, the - * number of bytes to be added or removed from these instructions is - * over estimated during the previous loop, and computed exactly only - * after the loop is finished (this requires another pass to parse the - * bytecode of the method). - */ - int[] allIndexes = new int[0]; // copy of indexes - int[] allSizes = new int[0]; // copy of sizes - boolean[] resize; // instructions to be resized - int newOffset; // future offset of a jump instruction - - resize = new boolean[code.length]; - - // 3 = loop again, 2 = loop ended, 1 = last pass, 0 = done - int state = 3; - do { - if (state == 3) { - state = 2; - } - u = 0; - while (u < b.length) { - int opcode = b[u] & 0xFF; // opcode of current instruction - int insert = 0; // bytes to be added after this instruction - - switch (ClassWriter.TYPE[opcode]) { - case ClassWriter.NOARG_INSN: - case ClassWriter.IMPLVAR_INSN: - u += 1; - break; - case ClassWriter.LABEL_INSN: - if (opcode > 201) { - // converts temporary opcodes 202 to 217, 218 and - // 219 to IFEQ ... JSR (inclusive), IFNULL and - // IFNONNULL - opcode = opcode < 218 ? opcode - 49 : opcode - 20; - label = u + readUnsignedShort(b, u + 1); - } else { - label = u + readShort(b, u + 1); - } - newOffset = getNewOffset(allIndexes, allSizes, u, label); - if (newOffset < Short.MIN_VALUE || newOffset > Short.MAX_VALUE) { - if (!resize[u]) { - if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) { - // two additional bytes will be required to - // replace this GOTO or JSR instruction with - // a GOTO_W or a JSR_W - insert = 2; - } else { - // five additional bytes will be required to - // replace this IFxxx instruction with - // IFNOTxxx GOTO_W , where IFNOTxxx - // is the "opposite" opcode of IFxxx (i.e., - // IFNE for IFEQ) and where designates - // the instruction just after the GOTO_W. - insert = 5; - } - resize[u] = true; - } - } - u += 3; - break; - case ClassWriter.LABELW_INSN: - u += 5; - break; - case ClassWriter.TABL_INSN: - if (state == 1) { - // true number of bytes to be added (or removed) - // from this instruction = (future number of padding - // bytes - current number of padding byte) - - // previously over estimated variation = - // = ((3 - newOffset%4) - (3 - u%4)) - u%4 - // = (-newOffset%4 + u%4) - u%4 - // = -(newOffset & 3) - newOffset = getNewOffset(allIndexes, allSizes, 0, u); - insert = -(newOffset & 3); - } else if (!resize[u]) { - // over estimation of the number of bytes to be - // added to this instruction = 3 - current number - // of padding bytes = 3 - (3 - u%4) = u%4 = u & 3 - insert = u & 3; - resize[u] = true; - } - // skips instruction - u = u + 4 - (u & 3); - u += 4 * (readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12; - break; - case ClassWriter.LOOK_INSN: - if (state == 1) { - // like TABL_INSN - newOffset = getNewOffset(allIndexes, allSizes, 0, u); - insert = -(newOffset & 3); - } else if (!resize[u]) { - // like TABL_INSN - insert = u & 3; - resize[u] = true; - } - // skips instruction - u = u + 4 - (u & 3); - u += 8 * readInt(b, u + 4) + 8; - break; - case ClassWriter.WIDE_INSN: - opcode = b[u + 1] & 0xFF; - if (opcode == Opcodes.IINC) { - u += 6; - } else { - u += 4; - } - break; - case ClassWriter.VAR_INSN: - case ClassWriter.SBYTE_INSN: - case ClassWriter.LDC_INSN: - u += 2; - break; - case ClassWriter.SHORT_INSN: - case ClassWriter.LDCW_INSN: - case ClassWriter.FIELDORMETH_INSN: - case ClassWriter.TYPE_INSN: - case ClassWriter.IINC_INSN: - u += 3; - break; - case ClassWriter.ITFMETH_INSN: - u += 5; - break; - // case ClassWriter.MANA_INSN: - default: - u += 4; - break; - } - if (insert != 0) { - // adds a new (u, insert) entry in the allIndexes and - // allSizes arrays - int[] newIndexes = new int[allIndexes.length + 1]; - int[] newSizes = new int[allSizes.length + 1]; - System.arraycopy(allIndexes, 0, newIndexes, 0, allIndexes.length); - System.arraycopy(allSizes, 0, newSizes, 0, allSizes.length); - newIndexes[allIndexes.length] = u; - newSizes[allSizes.length] = insert; - allIndexes = newIndexes; - allSizes = newSizes; - if (insert > 0) { - state = 3; - } - } - } - if (state < 3) { - --state; - } - } while (state != 0); - - // 2nd step: - // copies the bytecode of the method into a new bytevector, updates the - // offsets, and inserts (or removes) bytes as requested. - - ByteVector newCode = new ByteVector(code.length); - - u = 0; - while (u < code.length) { - int opcode = b[u] & 0xFF; - switch (ClassWriter.TYPE[opcode]) { - case ClassWriter.NOARG_INSN: - case ClassWriter.IMPLVAR_INSN: - newCode.putByte(opcode); - u += 1; - break; - case ClassWriter.LABEL_INSN: - if (opcode > 201) { - // changes temporary opcodes 202 to 217 (inclusive), 218 - // and 219 to IFEQ ... JSR (inclusive), IFNULL and - // IFNONNULL - opcode = opcode < 218 ? opcode - 49 : opcode - 20; - label = u + readUnsignedShort(b, u + 1); - } else { - label = u + readShort(b, u + 1); - } - newOffset = getNewOffset(allIndexes, allSizes, u, label); - if (resize[u]) { - // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx - // with IFNOTxxx GOTO_W , where IFNOTxxx is - // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) - // and where designates the instruction just after - // the GOTO_W. - if (opcode == Opcodes.GOTO) { - newCode.putByte(200); // GOTO_W - } else if (opcode == Opcodes.JSR) { - newCode.putByte(201); // JSR_W - } else { - newCode.putByte(opcode <= 166 ? (opcode + 1 ^ 1) - 1 : opcode ^ 1); - newCode.putShort(8); // jump offset - newCode.putByte(200); // GOTO_W - // newOffset now computed from start of GOTO_W - newOffset -= 3; - } - newCode.putInt(newOffset); - } else { - newCode.putByte(opcode); - newCode.putShort(newOffset); - } - u += 3; - break; - case ClassWriter.LABELW_INSN: - label = u + readInt(b, u + 1); - newOffset = getNewOffset(allIndexes, allSizes, u, label); - newCode.putByte(opcode); - newCode.putInt(newOffset); - u += 5; - break; - case ClassWriter.TABL_INSN: - // skips 0 to 3 padding bytes - v = u; - u = u + 4 - (v & 3); - // reads and copies instruction - newCode.putByte(Opcodes.TABLESWITCH); - newCode.length += (4 - newCode.length % 4) % 4; - label = v + readInt(b, u); - u += 4; - newOffset = getNewOffset(allIndexes, allSizes, v, label); - newCode.putInt(newOffset); - j = readInt(b, u); - u += 4; - newCode.putInt(j); - j = readInt(b, u) - j + 1; - u += 4; - newCode.putInt(readInt(b, u - 4)); - for (; j > 0; --j) { - label = v + readInt(b, u); - u += 4; - newOffset = getNewOffset(allIndexes, allSizes, v, label); - newCode.putInt(newOffset); - } - break; - case ClassWriter.LOOK_INSN: - // skips 0 to 3 padding bytes - v = u; - u = u + 4 - (v & 3); - // reads and copies instruction - newCode.putByte(Opcodes.LOOKUPSWITCH); - newCode.length += (4 - newCode.length % 4) % 4; - label = v + readInt(b, u); - u += 4; - newOffset = getNewOffset(allIndexes, allSizes, v, label); - newCode.putInt(newOffset); - j = readInt(b, u); - u += 4; - newCode.putInt(j); - for (; j > 0; --j) { - newCode.putInt(readInt(b, u)); - u += 4; - label = v + readInt(b, u); - u += 4; - newOffset = getNewOffset(allIndexes, allSizes, v, label); - newCode.putInt(newOffset); - } - break; - case ClassWriter.WIDE_INSN: - opcode = b[u + 1] & 0xFF; - if (opcode == Opcodes.IINC) { - newCode.putByteArray(b, u, 6); - u += 6; - } else { - newCode.putByteArray(b, u, 4); - u += 4; - } - break; - case ClassWriter.VAR_INSN: - case ClassWriter.SBYTE_INSN: - case ClassWriter.LDC_INSN: - newCode.putByteArray(b, u, 2); - u += 2; - break; - case ClassWriter.SHORT_INSN: - case ClassWriter.LDCW_INSN: - case ClassWriter.FIELDORMETH_INSN: - case ClassWriter.TYPE_INSN: - case ClassWriter.IINC_INSN: - newCode.putByteArray(b, u, 3); - u += 3; - break; - case ClassWriter.ITFMETH_INSN: - newCode.putByteArray(b, u, 5); - u += 5; - break; - // case MANA_INSN: - default: - newCode.putByteArray(b, u, 4); - u += 4; - break; - } - } - - // recomputes the stack map frames - if (frameCount > 0) { - if (compute == FRAMES) { - frameCount = 0; - stackMap = null; - previousFrame = null; - frame = null; - Frame f = new Frame(); - f.owner = labels; - Type[] args = Type.getArgumentTypes(descriptor); - f.initInputFrame(cw, access, args, maxLocals); - visitFrame(f); - Label l = labels; - while (l != null) { - /* - * here we need the original label position. getNewOffset - * must therefore never have been called for this label. - */ - u = l.position - 3; - if ((l.status & Label.STORE) != 0 || u >= 0 && resize[u]) { - getNewOffset(allIndexes, allSizes, l); - // TODO update offsets in UNINITIALIZED values - visitFrame(l.frame); - } - l = l.successor; - } - } else { - /* - * Resizing an existing stack map frame table is really hard. - * Not only the table must be parsed to update the offets, but - * new frames may be needed for jump instructions that were - * inserted by this method. And updating the offsets or - * inserting frames can change the format of the following - * frames, in case of packed frames. In practice the whole table - * must be recomputed. For this the frames are marked as - * potentially invalid. This will cause the whole class to be - * reread and rewritten with the COMPUTE_FRAMES option (see the - * ClassWriter.toByteArray method). This is not very efficient - * but is much easier and requires much less code than any other - * method I can think of. - */ - cw.invalidFrames = true; - } - } - // updates the exception handler block labels - Handler h = firstHandler; - while (h != null) { - getNewOffset(allIndexes, allSizes, h.start); - getNewOffset(allIndexes, allSizes, h.end); - getNewOffset(allIndexes, allSizes, h.handler); - h = h.next; - } - // updates the instructions addresses in the - // local var and line number tables - for (i = 0; i < 2; ++i) { - ByteVector bv = i == 0 ? localVar : localVarType; - if (bv != null) { - b = bv.data; - u = 0; - while (u < bv.length) { - label = readUnsignedShort(b, u); - newOffset = getNewOffset(allIndexes, allSizes, 0, label); - writeShort(b, u, newOffset); - label += readUnsignedShort(b, u + 2); - newOffset = getNewOffset(allIndexes, allSizes, 0, label) - newOffset; - writeShort(b, u + 2, newOffset); - u += 10; - } - } - } - if (lineNumber != null) { - b = lineNumber.data; - u = 0; - while (u < lineNumber.length) { - writeShort(b, u, getNewOffset(allIndexes, allSizes, 0, readUnsignedShort(b, u))); - u += 4; - } - } - // updates the labels of the other attributes - Attribute attr = cattrs; - while (attr != null) { - Label[] labels = attr.getLabels(); - if (labels != null) { - for (i = labels.length - 1; i >= 0; --i) { - getNewOffset(allIndexes, allSizes, labels[i]); - } - } - attr = attr.next; - } - - // replaces old bytecodes with new ones - code = newCode; - } - - /** - * Reads an unsigned short value in the given byte array. - * - * @param b a byte array. - * @param index the start index of the value to be read. - * @return the read value. - */ - static int readUnsignedShort(final byte[] b, final int index) { - return (b[index] & 0xFF) << 8 | b[index + 1] & 0xFF; - } - - /** - * Reads a signed short value in the given byte array. - * - * @param b a byte array. - * @param index the start index of the value to be read. - * @return the read value. - */ - static short readShort(final byte[] b, final int index) { - return (short) ((b[index] & 0xFF) << 8 | b[index + 1] & 0xFF); - } - - /** - * Reads a signed int value in the given byte array. - * - * @param b a byte array. - * @param index the start index of the value to be read. - * @return the read value. - */ - static int readInt(final byte[] b, final int index) { - return (b[index] & 0xFF) << 24 | (b[index + 1] & 0xFF) << 16 | (b[index + 2] & 0xFF) << 8 | b[index + 3] & 0xFF; - } - - /** - * Writes a short value in the given byte array. - * - * @param b a byte array. - * @param index where the first byte of the short value must be written. - * @param s the value to be written in the given byte array. - */ - static void writeShort(final byte[] b, final int index, final int s) { - b[index] = (byte) (s >>> 8); - b[index + 1] = (byte) s; - } - - /** - * Computes the future value of a bytecode offset. - *

- * Note: it is possible to have several entries for the same instruction in - * the indexes and sizes: two entries (index=a,size=b) and - * (index=a,size=b') are equivalent to a single entry (index=a,size=b+b'). - * - * @param indexes current positions of the instructions to be resized. Each - * instruction must be designated by the index of its last - * byte, plus one (or, in other words, by the index of the - * first byte of the next instruction). - * @param sizes the number of bytes to be added to the above - * instructions. More precisely, for each i < len, - * sizes[i] bytes will be added at the end of the - * instruction designated by indexes[i] or, if - * sizes[i] is negative, the last | - * sizes[i]| bytes of the instruction will be removed - * (the instruction size must not become negative or - * null). - * @param begin index of the first byte of the source instruction. - * @param end index of the first byte of the target instruction. - * @return the future value of the given bytecode offset. - */ - static int getNewOffset(final int[] indexes, final int[] sizes, final int begin, final int end) { - int offset = end - begin; - for (int i = 0; i < indexes.length; ++i) { - if (begin < indexes[i] && indexes[i] <= end) { - // forward jump - offset += sizes[i]; - } else if (end < indexes[i] && indexes[i] <= begin) { - // backward jump - offset -= sizes[i]; - } - } - return offset; - } - - /** - * Updates the offset of the given label. - * - * @param indexes current positions of the instructions to be resized. Each - * instruction must be designated by the index of its last - * byte, plus one (or, in other words, by the index of the - * first byte of the next instruction). - * @param sizes the number of bytes to be added to the above - * instructions. More precisely, for each i < len, - * sizes[i] bytes will be added at the end of the - * instruction designated by indexes[i] or, if - * sizes[i] is negative, the last | - * sizes[i]| bytes of the instruction will be removed - * (the instruction size must not become negative or - * null). - * @param label the label whose offset must be updated. - */ - static void getNewOffset(final int[] indexes, final int[] sizes, final Label label) { - if ((label.status & Label.RESIZED) == 0) { - label.position = getNewOffset(indexes, sizes, 0, label.position); - label.status |= Label.RESIZED; - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/AdviceAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/AdviceAdapter.java deleted file mode 100644 index e98c9a071..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/AdviceAdapter.java +++ /dev/null @@ -1,613 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; - -/** - * A {@link com.alibaba.citrus.asm.MethodAdapter} to insert before, after and - * around advices in methods and constructors. - *

- * The behavior for constructors is like this: - *

    - *
  1. as long as the INVOKESPECIAL for the object initialization has not been - * reached, every bytecode instruction is dispatched in the ctor code visitor
  2. - *
  3. when this one is reached, it is only added in the ctor code visitor and a - * JP invoke is added
  4. - *
  5. after that, only the other code visitor receives the instructions
  6. - *
- * - * @author Eugene Kuleshov - * @author Eric Bruneton - */ -public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes { - private static final Object THIS = new Object(); - private static final Object OTHER = new Object(); - - protected int methodAccess; - protected String methodDesc; - - private boolean constructor; - private boolean superInitialized; - private List stackFrame; - private Map branches; - - /** - * Creates a new {@link AdviceAdapter}. - * - * @param mv the method visitor to which this adapter delegates calls. - * @param access the method's access flags (see {@link Opcodes}). - * @param name the method's name. - * @param desc the method's descriptor (see {@link Type Type}). - */ - protected AdviceAdapter(final MethodVisitor mv, final int access, final String name, final String desc) { - super(mv, access, name, desc); - methodAccess = access; - methodDesc = desc; - - constructor = "".equals(name); - } - - @Override - public void visitCode() { - mv.visitCode(); - if (constructor) { - stackFrame = new ArrayList(); - branches = new HashMap(); - } else { - superInitialized = true; - onMethodEnter(); - } - } - - @Override - public void visitLabel(final Label label) { - mv.visitLabel(label); - - if (constructor && branches != null) { - List frame = (List) branches.get(label); - if (frame != null) { - stackFrame = frame; - branches.remove(label); - } - } - } - - @Override - public void visitInsn(final int opcode) { - if (constructor) { - int s; - switch (opcode) { - case RETURN: // empty stack - onMethodExit(opcode); - break; - - case IRETURN: // 1 before n/a after - case FRETURN: // 1 before n/a after - case ARETURN: // 1 before n/a after - case ATHROW: // 1 before n/a after - popValue(); - onMethodExit(opcode); - break; - - case LRETURN: // 2 before n/a after - case DRETURN: // 2 before n/a after - popValue(); - popValue(); - onMethodExit(opcode); - break; - - case NOP: - case LALOAD: // remove 2 add 2 - case DALOAD: // remove 2 add 2 - case LNEG: - case DNEG: - case FNEG: - case INEG: - case L2D: - case D2L: - case F2I: - case I2B: - case I2C: - case I2S: - case I2F: - case ARRAYLENGTH: - break; - - case ACONST_NULL: - case ICONST_M1: - case ICONST_0: - case ICONST_1: - case ICONST_2: - case ICONST_3: - case ICONST_4: - case ICONST_5: - case FCONST_0: - case FCONST_1: - case FCONST_2: - case F2L: // 1 before 2 after - case F2D: - case I2L: - case I2D: - pushValue(OTHER); - break; - - case LCONST_0: - case LCONST_1: - case DCONST_0: - case DCONST_1: - pushValue(OTHER); - pushValue(OTHER); - break; - - case IALOAD: // remove 2 add 1 - case FALOAD: // remove 2 add 1 - case AALOAD: // remove 2 add 1 - case BALOAD: // remove 2 add 1 - case CALOAD: // remove 2 add 1 - case SALOAD: // remove 2 add 1 - case POP: - case IADD: - case FADD: - case ISUB: - case LSHL: // 3 before 2 after - case LSHR: // 3 before 2 after - case LUSHR: // 3 before 2 after - case L2I: // 2 before 1 after - case L2F: // 2 before 1 after - case D2I: // 2 before 1 after - case D2F: // 2 before 1 after - case FSUB: - case FMUL: - case FDIV: - case FREM: - case FCMPL: // 2 before 1 after - case FCMPG: // 2 before 1 after - case IMUL: - case IDIV: - case IREM: - case ISHL: - case ISHR: - case IUSHR: - case IAND: - case IOR: - case IXOR: - case MONITORENTER: - case MONITOREXIT: - popValue(); - break; - - case POP2: - case LSUB: - case LMUL: - case LDIV: - case LREM: - case LADD: - case LAND: - case LOR: - case LXOR: - case DADD: - case DMUL: - case DSUB: - case DDIV: - case DREM: - popValue(); - popValue(); - break; - - case IASTORE: - case FASTORE: - case AASTORE: - case BASTORE: - case CASTORE: - case SASTORE: - case LCMP: // 4 before 1 after - case DCMPL: - case DCMPG: - popValue(); - popValue(); - popValue(); - break; - - case LASTORE: - case DASTORE: - popValue(); - popValue(); - popValue(); - popValue(); - break; - - case DUP: - pushValue(peekValue()); - break; - - case DUP_X1: - s = stackFrame.size(); - stackFrame.add(s - 2, stackFrame.get(s - 1)); - break; - - case DUP_X2: - s = stackFrame.size(); - stackFrame.add(s - 3, stackFrame.get(s - 1)); - break; - - case DUP2: - s = stackFrame.size(); - stackFrame.add(s - 2, stackFrame.get(s - 1)); - stackFrame.add(s - 2, stackFrame.get(s - 1)); - break; - - case DUP2_X1: - s = stackFrame.size(); - stackFrame.add(s - 3, stackFrame.get(s - 1)); - stackFrame.add(s - 3, stackFrame.get(s - 1)); - break; - - case DUP2_X2: - s = stackFrame.size(); - stackFrame.add(s - 4, stackFrame.get(s - 1)); - stackFrame.add(s - 4, stackFrame.get(s - 1)); - break; - - case SWAP: - s = stackFrame.size(); - stackFrame.add(s - 2, stackFrame.get(s - 1)); - stackFrame.remove(s); - break; - } - } else { - switch (opcode) { - case RETURN: - case IRETURN: - case FRETURN: - case ARETURN: - case LRETURN: - case DRETURN: - case ATHROW: - onMethodExit(opcode); - break; - } - } - mv.visitInsn(opcode); - } - - @Override - public void visitVarInsn(final int opcode, final int var) { - super.visitVarInsn(opcode, var); - - if (constructor) { - switch (opcode) { - case ILOAD: - case FLOAD: - pushValue(OTHER); - break; - case LLOAD: - case DLOAD: - pushValue(OTHER); - pushValue(OTHER); - break; - case ALOAD: - pushValue(var == 0 ? THIS : OTHER); - break; - case ASTORE: - case ISTORE: - case FSTORE: - popValue(); - break; - case LSTORE: - case DSTORE: - popValue(); - popValue(); - break; - } - } - } - - @Override - public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { - mv.visitFieldInsn(opcode, owner, name, desc); - - if (constructor) { - char c = desc.charAt(0); - boolean longOrDouble = c == 'J' || c == 'D'; - switch (opcode) { - case GETSTATIC: - pushValue(OTHER); - if (longOrDouble) { - pushValue(OTHER); - } - break; - case PUTSTATIC: - popValue(); - if (longOrDouble) { - popValue(); - } - break; - case PUTFIELD: - popValue(); - if (longOrDouble) { - popValue(); - popValue(); - } - break; - // case GETFIELD: - default: - if (longOrDouble) { - pushValue(OTHER); - } - } - } - } - - @Override - public void visitIntInsn(final int opcode, final int operand) { - mv.visitIntInsn(opcode, operand); - - if (constructor && opcode != NEWARRAY) { - pushValue(OTHER); - } - } - - @Override - public void visitLdcInsn(final Object cst) { - mv.visitLdcInsn(cst); - - if (constructor) { - pushValue(OTHER); - if (cst instanceof Double || cst instanceof Long) { - pushValue(OTHER); - } - } - } - - @Override - public void visitMultiANewArrayInsn(final String desc, final int dims) { - mv.visitMultiANewArrayInsn(desc, dims); - - if (constructor) { - for (int i = 0; i < dims; i++) { - popValue(); - } - pushValue(OTHER); - } - } - - @Override - public void visitTypeInsn(final int opcode, final String type) { - mv.visitTypeInsn(opcode, type); - - // ANEWARRAY, CHECKCAST or INSTANCEOF don't change stack - if (constructor && opcode == NEW) { - pushValue(OTHER); - } - } - - @Override - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - mv.visitMethodInsn(opcode, owner, name, desc); - - if (constructor) { - Type[] types = Type.getArgumentTypes(desc); - for (Type element : types) { - popValue(); - if (element.getSize() == 2) { - popValue(); - } - } - switch (opcode) { - // case INVOKESTATIC: - // break; - - case INVOKEINTERFACE: - case INVOKEVIRTUAL: - popValue(); // objectref - break; - - case INVOKESPECIAL: - Object type = popValue(); // objectref - if (type == THIS && !superInitialized) { - onMethodEnter(); - superInitialized = true; - // once super has been initialized it is no longer - // necessary to keep track of stack state - constructor = false; - } - break; - } - - Type returnType = Type.getReturnType(desc); - if (returnType != Type.VOID_TYPE) { - pushValue(OTHER); - if (returnType.getSize() == 2) { - pushValue(OTHER); - } - } - } - } - - @Override - public void visitJumpInsn(final int opcode, final Label label) { - mv.visitJumpInsn(opcode, label); - - if (constructor) { - switch (opcode) { - case IFEQ: - case IFNE: - case IFLT: - case IFGE: - case IFGT: - case IFLE: - case IFNULL: - case IFNONNULL: - popValue(); - break; - - case IF_ICMPEQ: - case IF_ICMPNE: - case IF_ICMPLT: - case IF_ICMPGE: - case IF_ICMPGT: - case IF_ICMPLE: - case IF_ACMPEQ: - case IF_ACMPNE: - popValue(); - popValue(); - break; - - case JSR: - pushValue(OTHER); - break; - } - addBranch(label); - } - } - - @Override - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { - mv.visitLookupSwitchInsn(dflt, keys, labels); - - if (constructor) { - popValue(); - addBranches(dflt, labels); - } - } - - @Override - public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label[] labels) { - mv.visitTableSwitchInsn(min, max, dflt, labels); - - if (constructor) { - popValue(); - addBranches(dflt, labels); - } - } - - private void addBranches(final Label dflt, final Label[] labels) { - addBranch(dflt); - for (Label element : labels) { - addBranch(element); - } - } - - private void addBranch(final Label label) { - if (branches.containsKey(label)) { - return; - } - branches.put(label, new ArrayList(stackFrame)); - } - - private Object popValue() { - return stackFrame.remove(stackFrame.size() - 1); - } - - private Object peekValue() { - return stackFrame.get(stackFrame.size() - 1); - } - - private void pushValue(final Object o) { - stackFrame.add(o); - } - - /** - * Called at the beginning of the method or after super class class call in - * the constructor.
- *
- * Custom code can use or change all the local variables, but should not - * change state of the stack. - */ - protected void onMethodEnter() { - } - - /** - * Called before explicit exit from the method using either return or throw. - * Top element on the stack contains the return value or exception instance. - * For example: - * - *
-     *   public void onMethodExit(int opcode) {
-     *     if(opcode==RETURN) {
-     *         visitInsn(ACONST_NULL);
-     *     } else if(opcode==ARETURN || opcode==ATHROW) {
-     *         dup();
-     *     } else {
-     *         if(opcode==LRETURN || opcode==DRETURN) {
-     *             dup2();
-     *         } else {
-     *             dup();
-     *         }
-     *         box(Type.getReturnType(this.methodDesc));
-     *     }
-     *     visitIntInsn(SIPUSH, opcode);
-     *     visitMethodInsn(INVOKESTATIC, owner, "onExit", "(Ljava/lang/Object;I)V");
-     *   }
-     *   // an actual call back method
-     *   public static void onExit(int opcode, Object param) {
-     *     ...
-     * 
- * - *
- *
- * Custom code can use or change all the local variables, but should not - * change state of the stack. - * - * @param opcode one of the RETURN, IRETURN, FRETURN, ARETURN, LRETURN, - * DRETURN or ATHROW - */ - protected void onMethodExit(int opcode) { - } - - // TODO onException, onMethodCall - -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/AnalyzerAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/AnalyzerAdapter.java deleted file mode 100644 index 4957988dd..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/AnalyzerAdapter.java +++ /dev/null @@ -1,851 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodAdapter; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; - -/** - * A {@link MethodAdapter} that keeps track of stack map frame changes between - * {@link #visitFrame(int, int, Object[], int, Object[]) visitFrame} calls. This - * adapter must be used with the - * {@link com.alibaba.citrus.asm.ClassReader#EXPAND_FRAMES} option. Each - * visitXXX instruction delegates to the next visitor in the chain, if - * any, and then simulates the effect of this instruction on the stack map - * frame, represented by {@link #locals} and {@link #stack}. The next visitor in - * the chain can get the state of the stack map frame before each - * instruction by reading the value of these fields in its visitXXX - * methods (this requires a reference to the AnalyzerAdapter that is before it - * in the chain). - * - * @author Eric Bruneton - */ -public class AnalyzerAdapter extends MethodAdapter { - - /** - * List of the local variable slots for current execution - * frame. Primitive types are represented by {@link Opcodes#TOP}, - * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, - * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or - * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a - * two elements, the second one being TOP). Reference types are represented - * by String objects (representing internal names), and uninitialized types - * by Label objects (this label designates the NEW instruction that created - * this uninitialized value). This field is null for unreacheable - * instructions. - */ - public List locals; - - /** - * List of the operand stack slots for current execution frame. - * Primitive types are represented by {@link Opcodes#TOP}, - * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, - * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or - * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a - * two elements, the second one being TOP). Reference types are represented - * by String objects (representing internal names), and uninitialized types - * by Label objects (this label designates the NEW instruction that created - * this uninitialized value). This field is null for unreacheable - * instructions. - */ - public List stack; - - /** - * The labels that designate the next instruction to be visited. May be - * null. - */ - private List labels; - - /** - * Information about uninitialized types in the current execution frame. - * This map associates internal names to Label objects. Each label - * designates a NEW instruction that created the currently uninitialized - * types, and the associated internal name represents the NEW operand, i.e. - * the final, initialized type value. - */ - private final Map uninitializedTypes; - - /** - * The maximum stack size of this method. - */ - private int maxStack; - - /** - * The maximum number of local variables of this method. - */ - private int maxLocals; - - /** - * Creates a new {@link AnalyzerAdapter}. - * - * @param owner the owner's class name. - * @param access the method's access flags (see {@link Opcodes}). - * @param name the method's name. - * @param desc the method's descriptor (see {@link Type Type}). - * @param mv the method visitor to which this adapter delegates calls. May - * be null. - */ - public AnalyzerAdapter(final String owner, final int access, final String name, final String desc, - final MethodVisitor mv) { - super(mv); - locals = new ArrayList(); - stack = new ArrayList(); - uninitializedTypes = new HashMap(); - - if ((access & Opcodes.ACC_STATIC) == 0) { - if ("".equals(name)) { - locals.add(Opcodes.UNINITIALIZED_THIS); - } else { - locals.add(owner); - } - } - Type[] types = Type.getArgumentTypes(desc); - for (int i = 0; i < types.length; ++i) { - Type type = types[i]; - switch (type.getSort()) { - case Type.BOOLEAN: - case Type.CHAR: - case Type.BYTE: - case Type.SHORT: - case Type.INT: - locals.add(Opcodes.INTEGER); - break; - case Type.FLOAT: - locals.add(Opcodes.FLOAT); - break; - case Type.LONG: - locals.add(Opcodes.LONG); - locals.add(Opcodes.TOP); - break; - case Type.DOUBLE: - locals.add(Opcodes.DOUBLE); - locals.add(Opcodes.TOP); - break; - case Type.ARRAY: - locals.add(types[i].getDescriptor()); - break; - // case Type.OBJECT: - default: - locals.add(types[i].getInternalName()); - } - } - } - - @Override - public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, - final Object[] stack) { - if (type != Opcodes.F_NEW) { // uncompressed frame - throw new IllegalStateException("ClassReader.accept() should be called with EXPAND_FRAMES flag"); - } - - if (mv != null) { - mv.visitFrame(type, nLocal, local, nStack, stack); - } - - if (this.locals != null) { - this.locals.clear(); - this.stack.clear(); - } else { - this.locals = new ArrayList(); - this.stack = new ArrayList(); - } - visitFrameTypes(nLocal, local, this.locals); - visitFrameTypes(nStack, stack, this.stack); - maxStack = Math.max(maxStack, this.stack.size()); - } - - private static void visitFrameTypes(final int n, final Object[] types, final List result) { - for (int i = 0; i < n; ++i) { - Object type = types[i]; - result.add(type); - if (type == Opcodes.LONG || type == Opcodes.DOUBLE) { - result.add(Opcodes.TOP); - } - } - } - - @Override - public void visitInsn(final int opcode) { - if (mv != null) { - mv.visitInsn(opcode); - } - execute(opcode, 0, null); - if (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN || opcode == Opcodes.ATHROW) { - this.locals = null; - this.stack = null; - } - } - - @Override - public void visitIntInsn(final int opcode, final int operand) { - if (mv != null) { - mv.visitIntInsn(opcode, operand); - } - execute(opcode, operand, null); - } - - @Override - public void visitVarInsn(final int opcode, final int var) { - if (mv != null) { - mv.visitVarInsn(opcode, var); - } - execute(opcode, var, null); - } - - @Override - public void visitTypeInsn(final int opcode, final String type) { - if (opcode == Opcodes.NEW) { - if (labels == null) { - Label l = new Label(); - labels = new ArrayList(3); - labels.add(l); - if (mv != null) { - mv.visitLabel(l); - } - } - for (int i = 0; i < labels.size(); ++i) { - uninitializedTypes.put(labels.get(i), type); - } - } - if (mv != null) { - mv.visitTypeInsn(opcode, type); - } - execute(opcode, 0, type); - } - - @Override - public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { - if (mv != null) { - mv.visitFieldInsn(opcode, owner, name, desc); - } - execute(opcode, 0, desc); - } - - @Override - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - if (mv != null) { - mv.visitMethodInsn(opcode, owner, name, desc); - } - pop(desc); - if (opcode != Opcodes.INVOKESTATIC) { - Object t = pop(); - if (opcode == Opcodes.INVOKESPECIAL && name.charAt(0) == '<') { - Object u; - if (t == Opcodes.UNINITIALIZED_THIS) { - u = owner; - } else { - u = uninitializedTypes.get(t); - } - for (int i = 0; i < locals.size(); ++i) { - if (locals.get(i) == t) { - locals.set(i, u); - } - } - for (int i = 0; i < stack.size(); ++i) { - if (stack.get(i) == t) { - stack.set(i, u); - } - } - } - } - pushDesc(desc); - labels = null; - } - - @Override - public void visitJumpInsn(final int opcode, final Label label) { - if (mv != null) { - mv.visitJumpInsn(opcode, label); - } - execute(opcode, 0, null); - if (opcode == Opcodes.GOTO) { - this.locals = null; - this.stack = null; - } - } - - @Override - public void visitLabel(final Label label) { - if (mv != null) { - mv.visitLabel(label); - } - if (labels == null) { - labels = new ArrayList(3); - } - labels.add(label); - } - - @Override - public void visitLdcInsn(final Object cst) { - if (mv != null) { - mv.visitLdcInsn(cst); - } - if (cst instanceof Integer) { - push(Opcodes.INTEGER); - } else if (cst instanceof Long) { - push(Opcodes.LONG); - push(Opcodes.TOP); - } else if (cst instanceof Float) { - push(Opcodes.FLOAT); - } else if (cst instanceof Double) { - push(Opcodes.DOUBLE); - push(Opcodes.TOP); - } else if (cst instanceof String) { - push("java/lang/String"); - } else if (cst instanceof Type) { - push("java/lang/Class"); - } else { - throw new IllegalArgumentException(); - } - labels = null; - } - - @Override - public void visitIincInsn(final int var, final int increment) { - if (mv != null) { - mv.visitIincInsn(var, increment); - } - execute(Opcodes.IINC, var, null); - } - - @Override - public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label[] labels) { - if (mv != null) { - mv.visitTableSwitchInsn(min, max, dflt, labels); - } - execute(Opcodes.TABLESWITCH, 0, null); - this.locals = null; - this.stack = null; - } - - @Override - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { - if (mv != null) { - mv.visitLookupSwitchInsn(dflt, keys, labels); - } - execute(Opcodes.LOOKUPSWITCH, 0, null); - this.locals = null; - this.stack = null; - } - - @Override - public void visitMultiANewArrayInsn(final String desc, final int dims) { - if (mv != null) { - mv.visitMultiANewArrayInsn(desc, dims); - } - execute(Opcodes.MULTIANEWARRAY, dims, desc); - } - - @Override - public void visitMaxs(final int maxStack, final int maxLocals) { - if (mv != null) { - this.maxStack = Math.max(this.maxStack, maxStack); - this.maxLocals = Math.max(this.maxLocals, maxLocals); - mv.visitMaxs(this.maxStack, this.maxLocals); - } - } - - // ------------------------------------------------------------------------ - - private Object get(final int local) { - maxLocals = Math.max(maxLocals, local); - return local < locals.size() ? locals.get(local) : Opcodes.TOP; - } - - private void set(final int local, final Object type) { - maxLocals = Math.max(maxLocals, local); - while (local >= locals.size()) { - locals.add(Opcodes.TOP); - } - locals.set(local, type); - } - - private void push(final Object type) { - stack.add(type); - maxStack = Math.max(maxStack, stack.size()); - } - - private void pushDesc(final String desc) { - int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0; - switch (desc.charAt(index)) { - case 'V': - return; - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - push(Opcodes.INTEGER); - return; - case 'F': - push(Opcodes.FLOAT); - return; - case 'J': - push(Opcodes.LONG); - push(Opcodes.TOP); - return; - case 'D': - push(Opcodes.DOUBLE); - push(Opcodes.TOP); - return; - case '[': - if (index == 0) { - push(desc); - } else { - push(desc.substring(index, desc.length())); - } - break; - // case 'L': - default: - if (index == 0) { - push(desc.substring(1, desc.length() - 1)); - } else { - push(desc.substring(index + 1, desc.length() - 1)); - } - } - } - - private Object pop() { - return stack.remove(stack.size() - 1); - } - - private void pop(final int n) { - int size = stack.size(); - int end = size - n; - for (int i = size - 1; i >= end; --i) { - stack.remove(i); - } - } - - private void pop(final String desc) { - char c = desc.charAt(0); - if (c == '(') { - int n = 0; - Type[] types = Type.getArgumentTypes(desc); - for (int i = 0; i < types.length; ++i) { - n += types[i].getSize(); - } - pop(n); - } else if (c == 'J' || c == 'D') { - pop(2); - } else { - pop(1); - } - } - - private void execute(final int opcode, final int iarg, final String sarg) { - if (this.locals == null) { - return; - } - Object t1, t2, t3, t4; - switch (opcode) { - case Opcodes.NOP: - case Opcodes.INEG: - case Opcodes.LNEG: - case Opcodes.FNEG: - case Opcodes.DNEG: - case Opcodes.I2B: - case Opcodes.I2C: - case Opcodes.I2S: - case Opcodes.GOTO: - case Opcodes.RETURN: - break; - case Opcodes.ACONST_NULL: - push(Opcodes.NULL); - break; - case Opcodes.ICONST_M1: - case Opcodes.ICONST_0: - case Opcodes.ICONST_1: - case Opcodes.ICONST_2: - case Opcodes.ICONST_3: - case Opcodes.ICONST_4: - case Opcodes.ICONST_5: - case Opcodes.BIPUSH: - case Opcodes.SIPUSH: - push(Opcodes.INTEGER); - break; - case Opcodes.LCONST_0: - case Opcodes.LCONST_1: - push(Opcodes.LONG); - push(Opcodes.TOP); - break; - case Opcodes.FCONST_0: - case Opcodes.FCONST_1: - case Opcodes.FCONST_2: - push(Opcodes.FLOAT); - break; - case Opcodes.DCONST_0: - case Opcodes.DCONST_1: - push(Opcodes.DOUBLE); - push(Opcodes.TOP); - break; - case Opcodes.ILOAD: - case Opcodes.FLOAD: - case Opcodes.ALOAD: - push(get(iarg)); - break; - case Opcodes.LLOAD: - case Opcodes.DLOAD: - push(get(iarg)); - push(Opcodes.TOP); - break; - case Opcodes.IALOAD: - case Opcodes.BALOAD: - case Opcodes.CALOAD: - case Opcodes.SALOAD: - pop(2); - push(Opcodes.INTEGER); - break; - case Opcodes.LALOAD: - case Opcodes.D2L: - pop(2); - push(Opcodes.LONG); - push(Opcodes.TOP); - break; - case Opcodes.FALOAD: - pop(2); - push(Opcodes.FLOAT); - break; - case Opcodes.DALOAD: - case Opcodes.L2D: - pop(2); - push(Opcodes.DOUBLE); - push(Opcodes.TOP); - break; - case Opcodes.AALOAD: - pop(1); - t1 = pop(); - pushDesc(((String) t1).substring(1)); - break; - case Opcodes.ISTORE: - case Opcodes.FSTORE: - case Opcodes.ASTORE: - t1 = pop(); - set(iarg, t1); - if (iarg > 0) { - t2 = get(iarg - 1); - if (t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) { - set(iarg - 1, Opcodes.TOP); - } - } - break; - case Opcodes.LSTORE: - case Opcodes.DSTORE: - pop(1); - t1 = pop(); - set(iarg, t1); - set(iarg + 1, Opcodes.TOP); - if (iarg > 0) { - t2 = get(iarg - 1); - if (t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) { - set(iarg - 1, Opcodes.TOP); - } - } - break; - case Opcodes.IASTORE: - case Opcodes.BASTORE: - case Opcodes.CASTORE: - case Opcodes.SASTORE: - case Opcodes.FASTORE: - case Opcodes.AASTORE: - pop(3); - break; - case Opcodes.LASTORE: - case Opcodes.DASTORE: - pop(4); - break; - case Opcodes.POP: - case Opcodes.IFEQ: - case Opcodes.IFNE: - case Opcodes.IFLT: - case Opcodes.IFGE: - case Opcodes.IFGT: - case Opcodes.IFLE: - case Opcodes.IRETURN: - case Opcodes.FRETURN: - case Opcodes.ARETURN: - case Opcodes.TABLESWITCH: - case Opcodes.LOOKUPSWITCH: - case Opcodes.ATHROW: - case Opcodes.MONITORENTER: - case Opcodes.MONITOREXIT: - case Opcodes.IFNULL: - case Opcodes.IFNONNULL: - pop(1); - break; - case Opcodes.POP2: - case Opcodes.IF_ICMPEQ: - case Opcodes.IF_ICMPNE: - case Opcodes.IF_ICMPLT: - case Opcodes.IF_ICMPGE: - case Opcodes.IF_ICMPGT: - case Opcodes.IF_ICMPLE: - case Opcodes.IF_ACMPEQ: - case Opcodes.IF_ACMPNE: - case Opcodes.LRETURN: - case Opcodes.DRETURN: - pop(2); - break; - case Opcodes.DUP: - t1 = pop(); - push(t1); - push(t1); - break; - case Opcodes.DUP_X1: - t1 = pop(); - t2 = pop(); - push(t1); - push(t2); - push(t1); - break; - case Opcodes.DUP_X2: - t1 = pop(); - t2 = pop(); - t3 = pop(); - push(t1); - push(t3); - push(t2); - push(t1); - break; - case Opcodes.DUP2: - t1 = pop(); - t2 = pop(); - push(t2); - push(t1); - push(t2); - push(t1); - break; - case Opcodes.DUP2_X1: - t1 = pop(); - t2 = pop(); - t3 = pop(); - push(t2); - push(t1); - push(t3); - push(t2); - push(t1); - break; - case Opcodes.DUP2_X2: - t1 = pop(); - t2 = pop(); - t3 = pop(); - t4 = pop(); - push(t2); - push(t1); - push(t4); - push(t3); - push(t2); - push(t1); - break; - case Opcodes.SWAP: - t1 = pop(); - t2 = pop(); - push(t1); - push(t2); - break; - case Opcodes.IADD: - case Opcodes.ISUB: - case Opcodes.IMUL: - case Opcodes.IDIV: - case Opcodes.IREM: - case Opcodes.IAND: - case Opcodes.IOR: - case Opcodes.IXOR: - case Opcodes.ISHL: - case Opcodes.ISHR: - case Opcodes.IUSHR: - case Opcodes.L2I: - case Opcodes.D2I: - case Opcodes.FCMPL: - case Opcodes.FCMPG: - pop(2); - push(Opcodes.INTEGER); - break; - case Opcodes.LADD: - case Opcodes.LSUB: - case Opcodes.LMUL: - case Opcodes.LDIV: - case Opcodes.LREM: - case Opcodes.LAND: - case Opcodes.LOR: - case Opcodes.LXOR: - pop(4); - push(Opcodes.LONG); - push(Opcodes.TOP); - break; - case Opcodes.FADD: - case Opcodes.FSUB: - case Opcodes.FMUL: - case Opcodes.FDIV: - case Opcodes.FREM: - case Opcodes.L2F: - case Opcodes.D2F: - pop(2); - push(Opcodes.FLOAT); - break; - case Opcodes.DADD: - case Opcodes.DSUB: - case Opcodes.DMUL: - case Opcodes.DDIV: - case Opcodes.DREM: - pop(4); - push(Opcodes.DOUBLE); - push(Opcodes.TOP); - break; - case Opcodes.LSHL: - case Opcodes.LSHR: - case Opcodes.LUSHR: - pop(3); - push(Opcodes.LONG); - push(Opcodes.TOP); - break; - case Opcodes.IINC: - set(iarg, Opcodes.INTEGER); - break; - case Opcodes.I2L: - case Opcodes.F2L: - pop(1); - push(Opcodes.LONG); - push(Opcodes.TOP); - break; - case Opcodes.I2F: - pop(1); - push(Opcodes.FLOAT); - break; - case Opcodes.I2D: - case Opcodes.F2D: - pop(1); - push(Opcodes.DOUBLE); - push(Opcodes.TOP); - break; - case Opcodes.F2I: - case Opcodes.ARRAYLENGTH: - case Opcodes.INSTANCEOF: - pop(1); - push(Opcodes.INTEGER); - break; - case Opcodes.LCMP: - case Opcodes.DCMPL: - case Opcodes.DCMPG: - pop(4); - push(Opcodes.INTEGER); - break; - case Opcodes.JSR: - case Opcodes.RET: - throw new RuntimeException("JSR/RET are not supported"); - case Opcodes.GETSTATIC: - pushDesc(sarg); - break; - case Opcodes.PUTSTATIC: - pop(sarg); - break; - case Opcodes.GETFIELD: - pop(1); - pushDesc(sarg); - break; - case Opcodes.PUTFIELD: - pop(sarg); - pop(); - break; - case Opcodes.NEW: - push(labels.get(0)); - break; - case Opcodes.NEWARRAY: - pop(); - switch (iarg) { - case Opcodes.T_BOOLEAN: - pushDesc("[Z"); - break; - case Opcodes.T_CHAR: - pushDesc("[C"); - break; - case Opcodes.T_BYTE: - pushDesc("[B"); - break; - case Opcodes.T_SHORT: - pushDesc("[S"); - break; - case Opcodes.T_INT: - pushDesc("[I"); - break; - case Opcodes.T_FLOAT: - pushDesc("[F"); - break; - case Opcodes.T_DOUBLE: - pushDesc("[D"); - break; - // case Opcodes.T_LONG: - default: - pushDesc("[J"); - break; - } - break; - case Opcodes.ANEWARRAY: - pop(); - pushDesc("[" + Type.getObjectType(sarg)); - break; - case Opcodes.CHECKCAST: - pop(); - pushDesc(Type.getObjectType(sarg).getDescriptor()); - break; - // case Opcodes.MULTIANEWARRAY: - default: - pop(iarg); - pushDesc(sarg); - break; - } - labels = null; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/CodeSizeEvaluator.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/CodeSizeEvaluator.java deleted file mode 100644 index 87744da19..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/CodeSizeEvaluator.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodAdapter; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * A {@link MethodAdapter} that can be used to approximate method size. - * - * @author Eugene Kuleshov - */ -public class CodeSizeEvaluator extends MethodAdapter implements Opcodes { - - private int minSize; - - private int maxSize; - - public CodeSizeEvaluator(final MethodVisitor mv) { - super(mv); - } - - public int getMinSize() { - return this.minSize; - } - - public int getMaxSize() { - return this.maxSize; - } - - @Override - public void visitInsn(final int opcode) { - minSize += 1; - maxSize += 1; - if (mv != null) { - mv.visitInsn(opcode); - } - } - - @Override - public void visitIntInsn(final int opcode, final int operand) { - if (opcode == SIPUSH) { - minSize += 3; - maxSize += 3; - } else { - minSize += 2; - maxSize += 2; - } - if (mv != null) { - mv.visitIntInsn(opcode, operand); - } - } - - @Override - public void visitVarInsn(final int opcode, final int var) { - if (var < 4 && opcode != RET) { - minSize += 1; - maxSize += 1; - } else if (var >= 256) { - minSize += 4; - maxSize += 4; - } else { - minSize += 2; - maxSize += 2; - } - if (mv != null) { - mv.visitVarInsn(opcode, var); - } - } - - @Override - public void visitTypeInsn(final int opcode, final String type) { - minSize += 3; - maxSize += 3; - if (mv != null) { - mv.visitTypeInsn(opcode, type); - } - } - - @Override - public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { - minSize += 3; - maxSize += 3; - if (mv != null) { - mv.visitFieldInsn(opcode, owner, name, desc); - } - } - - @Override - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - if (opcode == INVOKEINTERFACE) { - minSize += 5; - maxSize += 5; - } else { - minSize += 3; - maxSize += 3; - } - if (mv != null) { - mv.visitMethodInsn(opcode, owner, name, desc); - } - } - - @Override - public void visitJumpInsn(final int opcode, final Label label) { - minSize += 3; - if (opcode == GOTO || opcode == JSR) { - maxSize += 5; - } else { - maxSize += 8; - } - if (mv != null) { - mv.visitJumpInsn(opcode, label); - } - } - - @Override - public void visitLdcInsn(final Object cst) { - if (cst instanceof Long || cst instanceof Double) { - minSize += 3; - maxSize += 3; - } else { - minSize += 2; - maxSize += 3; - } - if (mv != null) { - mv.visitLdcInsn(cst); - } - } - - @Override - public void visitIincInsn(final int var, final int increment) { - if (var > 255 || increment > 127 || increment < -128) { - minSize += 6; - maxSize += 6; - } else { - minSize += 3; - maxSize += 3; - } - if (mv != null) { - mv.visitIincInsn(var, increment); - } - } - - @Override - public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label[] labels) { - minSize += 13 + labels.length * 4; - maxSize += 16 + labels.length * 4; - if (mv != null) { - mv.visitTableSwitchInsn(min, max, dflt, labels); - } - } - - @Override - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { - minSize += 9 + keys.length * 8; - maxSize += 12 + keys.length * 8; - if (mv != null) { - mv.visitLookupSwitchInsn(dflt, keys, labels); - } - } - - @Override - public void visitMultiANewArrayInsn(final String desc, final int dims) { - minSize += 4; - maxSize += 4; - if (mv != null) { - mv.visitMultiANewArrayInsn(desc, dims); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/EmptyVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/EmptyVisitor.java deleted file mode 100644 index 05f20bf7e..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/EmptyVisitor.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * An empty implementation of the ASM visitor interfaces. - * - * @author Eric Bruneton - */ -public class EmptyVisitor implements ClassVisitor, FieldVisitor, MethodVisitor, AnnotationVisitor { - - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - } - - public void visitSource(final String source, final String debug) { - } - - public void visitOuterClass(final String owner, final String name, final String desc) { - } - - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - return this; - } - - public void visitAttribute(final Attribute attr) { - } - - public void visitInnerClass(final String name, final String outerName, final String innerName, final int access) { - } - - public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, - final Object value) { - return this; - } - - public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, - final String[] exceptions) { - return this; - } - - public void visitEnd() { - } - - public AnnotationVisitor visitAnnotationDefault() { - return this; - } - - public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc, final boolean visible) { - return this; - } - - public void visitCode() { - } - - public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, - final Object[] stack) { - } - - public void visitInsn(final int opcode) { - } - - public void visitIntInsn(final int opcode, final int operand) { - } - - public void visitVarInsn(final int opcode, final int var) { - } - - public void visitTypeInsn(final int opcode, final String type) { - } - - public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { - } - - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - } - - public void visitJumpInsn(final int opcode, final Label label) { - } - - public void visitLabel(final Label label) { - } - - public void visitLdcInsn(final Object cst) { - } - - public void visitIincInsn(final int var, final int increment) { - } - - public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label[] labels) { - } - - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { - } - - public void visitMultiANewArrayInsn(final String desc, final int dims) { - } - - public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type) { - } - - public void visitLocalVariable(final String name, final String desc, final String signature, final Label start, - final Label end, final int index) { - } - - public void visitLineNumber(final int line, final Label start) { - } - - public void visitMaxs(final int maxStack, final int maxLocals) { - } - - public void visit(final String name, final Object value) { - } - - public void visitEnum(final String name, final String desc, final String value) { - } - - public AnnotationVisitor visitAnnotation(final String name, final String desc) { - return this; - } - - public AnnotationVisitor visitArray(final String name) { - return this; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/GeneratorAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/GeneratorAdapter.java deleted file mode 100644 index 39d3baa5d..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/GeneratorAdapter.java +++ /dev/null @@ -1,1425 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; - -/** - * A {@link com.alibaba.citrus.asm.MethodAdapter} with convenient methods to - * generate code. For example, using this adapter, the class below - * - *
- * public class Example {
- *     public static void main(String[] args) {
- *         System.out.println("Hello world!");
- *     }
- * }
- * 
- * - * can be generated as follows: - * - *
- * ClassWriter cw = new ClassWriter(true);
- * cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);
- * 
- * Method m = Method.getMethod("void <init> ()");
- * GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null, cw);
- * mg.loadThis();
- * mg.invokeConstructor(Type.getType(Object.class), m);
- * mg.returnValue();
- * mg.endMethod();
- * 
- * m = Method.getMethod("void main (String[])");
- * mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, null, null, cw);
- * mg.getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class));
- * mg.push("Hello world!");
- * mg.invokeVirtual(Type.getType(PrintStream.class), Method.getMethod("void println (String)"));
- * mg.returnValue();
- * mg.endMethod();
- * 
- * cw.visitEnd();
- * 
- * - * @author Juozas Baliuka - * @author Chris Nokleberg - * @author Eric Bruneton - */ -public class GeneratorAdapter extends LocalVariablesSorter { - - private static final String CLDESC = "Ljava/lang/Class;"; - - private static final Type BYTE_TYPE = Type.getObjectType("java/lang/Byte"); - - private static final Type BOOLEAN_TYPE = Type.getObjectType("java/lang/Boolean"); - - private static final Type SHORT_TYPE = Type.getObjectType("java/lang/Short"); - - private static final Type CHARACTER_TYPE = Type.getObjectType("java/lang/Character"); - - private static final Type INTEGER_TYPE = Type.getObjectType("java/lang/Integer"); - - private static final Type FLOAT_TYPE = Type.getObjectType("java/lang/Float"); - - private static final Type LONG_TYPE = Type.getObjectType("java/lang/Long"); - - private static final Type DOUBLE_TYPE = Type.getObjectType("java/lang/Double"); - - private static final Type NUMBER_TYPE = Type.getObjectType("java/lang/Number"); - - private static final Type OBJECT_TYPE = Type.getObjectType("java/lang/Object"); - - private static final Method BOOLEAN_VALUE = Method.getMethod("boolean booleanValue()"); - - private static final Method CHAR_VALUE = Method.getMethod("char charValue()"); - - private static final Method INT_VALUE = Method.getMethod("int intValue()"); - - private static final Method FLOAT_VALUE = Method.getMethod("float floatValue()"); - - private static final Method LONG_VALUE = Method.getMethod("long longValue()"); - - private static final Method DOUBLE_VALUE = Method.getMethod("double doubleValue()"); - - /** - * Constant for the {@link #math math} method. - */ - public static final int ADD = Opcodes.IADD; - - /** - * Constant for the {@link #math math} method. - */ - public static final int SUB = Opcodes.ISUB; - - /** - * Constant for the {@link #math math} method. - */ - public static final int MUL = Opcodes.IMUL; - - /** - * Constant for the {@link #math math} method. - */ - public static final int DIV = Opcodes.IDIV; - - /** - * Constant for the {@link #math math} method. - */ - public static final int REM = Opcodes.IREM; - - /** - * Constant for the {@link #math math} method. - */ - public static final int NEG = Opcodes.INEG; - - /** - * Constant for the {@link #math math} method. - */ - public static final int SHL = Opcodes.ISHL; - - /** - * Constant for the {@link #math math} method. - */ - public static final int SHR = Opcodes.ISHR; - - /** - * Constant for the {@link #math math} method. - */ - public static final int USHR = Opcodes.IUSHR; - - /** - * Constant for the {@link #math math} method. - */ - public static final int AND = Opcodes.IAND; - - /** - * Constant for the {@link #math math} method. - */ - public static final int OR = Opcodes.IOR; - - /** - * Constant for the {@link #math math} method. - */ - public static final int XOR = Opcodes.IXOR; - - /** - * Constant for the {@link #ifCmp ifCmp} method. - */ - public static final int EQ = Opcodes.IFEQ; - - /** - * Constant for the {@link #ifCmp ifCmp} method. - */ - public static final int NE = Opcodes.IFNE; - - /** - * Constant for the {@link #ifCmp ifCmp} method. - */ - public static final int LT = Opcodes.IFLT; - - /** - * Constant for the {@link #ifCmp ifCmp} method. - */ - public static final int GE = Opcodes.IFGE; - - /** - * Constant for the {@link #ifCmp ifCmp} method. - */ - public static final int GT = Opcodes.IFGT; - - /** - * Constant for the {@link #ifCmp ifCmp} method. - */ - public static final int LE = Opcodes.IFLE; - - /** - * Access flags of the method visited by this adapter. - */ - private final int access; - - /** - * Return type of the method visited by this adapter. - */ - private final Type returnType; - - /** - * Argument types of the method visited by this adapter. - */ - private final Type[] argumentTypes; - - /** - * Types of the local variables of the method visited by this adapter. - */ - private final List localTypes = new ArrayList(); - - /** - * Creates a new {@link GeneratorAdapter}. - * - * @param mv the method visitor to which this adapter delegates calls. - * @param access the method's access flags (see {@link Opcodes}). - * @param name the method's name. - * @param desc the method's descriptor (see {@link Type Type}). - */ - public GeneratorAdapter(final MethodVisitor mv, final int access, final String name, final String desc) { - super(access, desc, mv); - this.access = access; - this.returnType = Type.getReturnType(desc); - this.argumentTypes = Type.getArgumentTypes(desc); - } - - /** - * Creates a new {@link GeneratorAdapter}. - * - * @param access access flags of the adapted method. - * @param method the adapted method. - * @param mv the method visitor to which this adapter delegates calls. - */ - public GeneratorAdapter(final int access, final Method method, final MethodVisitor mv) { - super(access, method.getDescriptor(), mv); - this.access = access; - this.returnType = method.getReturnType(); - this.argumentTypes = method.getArgumentTypes(); - } - - /** - * Creates a new {@link GeneratorAdapter}. - * - * @param access access flags of the adapted method. - * @param method the adapted method. - * @param signature the signature of the adapted method (may be - * null). - * @param exceptions the exceptions thrown by the adapted method (may be - * null). - * @param cv the class visitor to which this adapter delegates calls. - */ - public GeneratorAdapter(final int access, final Method method, final String signature, final Type[] exceptions, - final ClassVisitor cv) { - this(access, method, cv.visitMethod(access, method.getName(), method.getDescriptor(), signature, - getInternalNames(exceptions))); - } - - /** - * Returns the internal names of the given types. - * - * @param types a set of types. - * @return the internal names of the given types. - */ - private static String[] getInternalNames(final Type[] types) { - if (types == null) { - return null; - } - String[] names = new String[types.length]; - for (int i = 0; i < names.length; ++i) { - names[i] = types[i].getInternalName(); - } - return names; - } - - // ------------------------------------------------------------------------ - // Instructions to push constants on the stack - // ------------------------------------------------------------------------ - - /** - * Generates the instruction to push the given value on the stack. - * - * @param value the value to be pushed on the stack. - */ - public void push(final boolean value) { - push(value ? 1 : 0); - } - - /** - * Generates the instruction to push the given value on the stack. - * - * @param value the value to be pushed on the stack. - */ - public void push(final int value) { - if (value >= -1 && value <= 5) { - mv.visitInsn(Opcodes.ICONST_0 + value); - } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) { - mv.visitIntInsn(Opcodes.BIPUSH, value); - } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) { - mv.visitIntInsn(Opcodes.SIPUSH, value); - } else { - mv.visitLdcInsn(new Integer(value)); - } - } - - /** - * Generates the instruction to push the given value on the stack. - * - * @param value the value to be pushed on the stack. - */ - public void push(final long value) { - if (value == 0L || value == 1L) { - mv.visitInsn(Opcodes.LCONST_0 + (int) value); - } else { - mv.visitLdcInsn(new Long(value)); - } - } - - /** - * Generates the instruction to push the given value on the stack. - * - * @param value the value to be pushed on the stack. - */ - public void push(final float value) { - int bits = Float.floatToIntBits(value); - if (bits == 0L || bits == 0x3f800000 || bits == 0x40000000) { // 0..2 - mv.visitInsn(Opcodes.FCONST_0 + (int) value); - } else { - mv.visitLdcInsn(new Float(value)); - } - } - - /** - * Generates the instruction to push the given value on the stack. - * - * @param value the value to be pushed on the stack. - */ - public void push(final double value) { - long bits = Double.doubleToLongBits(value); - if (bits == 0L || bits == 0x3ff0000000000000L) { // +0.0d and 1.0d - mv.visitInsn(Opcodes.DCONST_0 + (int) value); - } else { - mv.visitLdcInsn(new Double(value)); - } - } - - /** - * Generates the instruction to push the given value on the stack. - * - * @param value the value to be pushed on the stack. May be null. - */ - public void push(final String value) { - if (value == null) { - mv.visitInsn(Opcodes.ACONST_NULL); - } else { - mv.visitLdcInsn(value); - } - } - - /** - * Generates the instruction to push the given value on the stack. - * - * @param value the value to be pushed on the stack. - */ - public void push(final Type value) { - if (value == null) { - mv.visitInsn(Opcodes.ACONST_NULL); - } else { - switch (value.getSort()) { - case Type.BOOLEAN: - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Boolean", "TYPE", CLDESC); - break; - case Type.CHAR: - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Char", "TYPE", CLDESC); - break; - case Type.BYTE: - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Byte", "TYPE", CLDESC); - break; - case Type.SHORT: - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Short", "TYPE", CLDESC); - break; - case Type.INT: - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Integer", "TYPE", CLDESC); - break; - case Type.FLOAT: - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Float", "TYPE", CLDESC); - break; - case Type.LONG: - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Long", "TYPE", CLDESC); - break; - case Type.DOUBLE: - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Double", "TYPE", CLDESC); - break; - default: - mv.visitLdcInsn(value); - } - } - } - - // ------------------------------------------------------------------------ - // Instructions to load and store method arguments - // ------------------------------------------------------------------------ - - /** - * Returns the index of the given method argument in the frame's local - * variables array. - * - * @param arg the index of a method argument. - * @return the index of the given method argument in the frame's local - * variables array. - */ - private int getArgIndex(final int arg) { - int index = (access & Opcodes.ACC_STATIC) == 0 ? 1 : 0; - for (int i = 0; i < arg; i++) { - index += argumentTypes[i].getSize(); - } - return index; - } - - /** - * Generates the instruction to push a local variable on the stack. - * - * @param type the type of the local variable to be loaded. - * @param index an index in the frame's local variables array. - */ - private void loadInsn(final Type type, final int index) { - mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), index); - } - - /** - * Generates the instruction to store the top stack value in a local - * variable. - * - * @param type the type of the local variable to be stored. - * @param index an index in the frame's local variables array. - */ - private void storeInsn(final Type type, final int index) { - mv.visitVarInsn(type.getOpcode(Opcodes.ISTORE), index); - } - - /** - * Generates the instruction to load 'this' on the stack. - */ - public void loadThis() { - if ((access & Opcodes.ACC_STATIC) != 0) { - throw new IllegalStateException("no 'this' pointer within static method"); - } - mv.visitVarInsn(Opcodes.ALOAD, 0); - } - - /** - * Generates the instruction to load the given method argument on the stack. - * - * @param arg the index of a method argument. - */ - public void loadArg(final int arg) { - loadInsn(argumentTypes[arg], getArgIndex(arg)); - } - - /** - * Generates the instructions to load the given method arguments on the - * stack. - * - * @param arg the index of the first method argument to be loaded. - * @param count the number of method arguments to be loaded. - */ - public void loadArgs(final int arg, final int count) { - int index = getArgIndex(arg); - for (int i = 0; i < count; ++i) { - Type t = argumentTypes[arg + i]; - loadInsn(t, index); - index += t.getSize(); - } - } - - /** - * Generates the instructions to load all the method arguments on the stack. - */ - public void loadArgs() { - loadArgs(0, argumentTypes.length); - } - - /** - * Generates the instructions to load all the method arguments on the stack, - * as a single object array. - */ - public void loadArgArray() { - push(argumentTypes.length); - newArray(OBJECT_TYPE); - for (int i = 0; i < argumentTypes.length; i++) { - dup(); - push(i); - loadArg(i); - box(argumentTypes[i]); - arrayStore(OBJECT_TYPE); - } - } - - /** - * Generates the instruction to store the top stack value in the given - * method argument. - * - * @param arg the index of a method argument. - */ - public void storeArg(final int arg) { - storeInsn(argumentTypes[arg], getArgIndex(arg)); - } - - // ------------------------------------------------------------------------ - // Instructions to load and store local variables - // ------------------------------------------------------------------------ - - /** - * Returns the type of the given local variable. - * - * @param local a local variable identifier, as returned by - * {@link LocalVariablesSorter#newLocal(Type) newLocal()}. - * @return the type of the given local variable. - */ - public Type getLocalType(final int local) { - return (Type) localTypes.get(local - firstLocal); - } - - @Override - protected void setLocalType(final int local, final Type type) { - int index = local - firstLocal; - while (localTypes.size() < index + 1) { - localTypes.add(null); - } - localTypes.set(index, type); - } - - /** - * Generates the instruction to load the given local variable on the stack. - * - * @param local a local variable identifier, as returned by - * {@link LocalVariablesSorter#newLocal(Type) newLocal()}. - */ - public void loadLocal(final int local) { - loadInsn(getLocalType(local), local); - } - - /** - * Generates the instruction to load the given local variable on the stack. - * - * @param local a local variable identifier, as returned by - * {@link LocalVariablesSorter#newLocal(Type) newLocal()}. - * @param type the type of this local variable. - */ - public void loadLocal(final int local, final Type type) { - setLocalType(local, type); - loadInsn(type, local); - } - - /** - * Generates the instruction to store the top stack value in the given local - * variable. - * - * @param local a local variable identifier, as returned by - * {@link LocalVariablesSorter#newLocal(Type) newLocal()}. - */ - public void storeLocal(final int local) { - storeInsn(getLocalType(local), local); - } - - /** - * Generates the instruction to store the top stack value in the given local - * variable. - * - * @param local a local variable identifier, as returned by - * {@link LocalVariablesSorter#newLocal(Type) newLocal()}. - * @param type the type of this local variable. - */ - public void storeLocal(final int local, final Type type) { - setLocalType(local, type); - storeInsn(type, local); - } - - /** - * Generates the instruction to load an element from an array. - * - * @param type the type of the array element to be loaded. - */ - public void arrayLoad(final Type type) { - mv.visitInsn(type.getOpcode(Opcodes.IALOAD)); - } - - /** - * Generates the instruction to store an element in an array. - * - * @param type the type of the array element to be stored. - */ - public void arrayStore(final Type type) { - mv.visitInsn(type.getOpcode(Opcodes.IASTORE)); - } - - // ------------------------------------------------------------------------ - // Instructions to manage the stack - // ------------------------------------------------------------------------ - - /** - * Generates a POP instruction. - */ - public void pop() { - mv.visitInsn(Opcodes.POP); - } - - /** - * Generates a POP2 instruction. - */ - public void pop2() { - mv.visitInsn(Opcodes.POP2); - } - - /** - * Generates a DUP instruction. - */ - public void dup() { - mv.visitInsn(Opcodes.DUP); - } - - /** - * Generates a DUP2 instruction. - */ - public void dup2() { - mv.visitInsn(Opcodes.DUP2); - } - - /** - * Generates a DUP_X1 instruction. - */ - public void dupX1() { - mv.visitInsn(Opcodes.DUP_X1); - } - - /** - * Generates a DUP_X2 instruction. - */ - public void dupX2() { - mv.visitInsn(Opcodes.DUP_X2); - } - - /** - * Generates a DUP2_X1 instruction. - */ - public void dup2X1() { - mv.visitInsn(Opcodes.DUP2_X1); - } - - /** - * Generates a DUP2_X2 instruction. - */ - public void dup2X2() { - mv.visitInsn(Opcodes.DUP2_X2); - } - - /** - * Generates a SWAP instruction. - */ - public void swap() { - mv.visitInsn(Opcodes.SWAP); - } - - /** - * Generates the instructions to swap the top two stack values. - * - * @param prev type of the top - 1 stack value. - * @param type type of the top stack value. - */ - public void swap(final Type prev, final Type type) { - if (type.getSize() == 1) { - if (prev.getSize() == 1) { - swap(); // same as dupX1(), pop(); - } else { - dupX2(); - pop(); - } - } else { - if (prev.getSize() == 1) { - dup2X1(); - pop2(); - } else { - dup2X2(); - pop2(); - } - } - } - - // ------------------------------------------------------------------------ - // Instructions to do mathematical and logical operations - // ------------------------------------------------------------------------ - - /** - * Generates the instruction to do the specified mathematical or logical - * operation. - * - * @param op a mathematical or logical operation. Must be one of ADD, SUB, - * MUL, DIV, REM, NEG, SHL, SHR, USHR, AND, OR, XOR. - * @param type the type of the operand(s) for this operation. - */ - public void math(final int op, final Type type) { - mv.visitInsn(type.getOpcode(op)); - } - - /** - * Generates the instructions to compute the bitwise negation of the top - * stack value. - */ - public void not() { - mv.visitInsn(Opcodes.ICONST_1); - mv.visitInsn(Opcodes.IXOR); - } - - /** - * Generates the instruction to increment the given local variable. - * - * @param local the local variable to be incremented. - * @param amount the amount by which the local variable must be incremented. - */ - public void iinc(final int local, final int amount) { - mv.visitIincInsn(local, amount); - } - - /** - * Generates the instructions to cast a numerical value from one type to - * another. - * - * @param from the type of the top stack value - * @param to the type into which this value must be cast. - */ - public void cast(final Type from, final Type to) { - if (from != to) { - if (from == Type.DOUBLE_TYPE) { - if (to == Type.FLOAT_TYPE) { - mv.visitInsn(Opcodes.D2F); - } else if (to == Type.LONG_TYPE) { - mv.visitInsn(Opcodes.D2L); - } else { - mv.visitInsn(Opcodes.D2I); - cast(Type.INT_TYPE, to); - } - } else if (from == Type.FLOAT_TYPE) { - if (to == Type.DOUBLE_TYPE) { - mv.visitInsn(Opcodes.F2D); - } else if (to == Type.LONG_TYPE) { - mv.visitInsn(Opcodes.F2L); - } else { - mv.visitInsn(Opcodes.F2I); - cast(Type.INT_TYPE, to); - } - } else if (from == Type.LONG_TYPE) { - if (to == Type.DOUBLE_TYPE) { - mv.visitInsn(Opcodes.L2D); - } else if (to == Type.FLOAT_TYPE) { - mv.visitInsn(Opcodes.L2F); - } else { - mv.visitInsn(Opcodes.L2I); - cast(Type.INT_TYPE, to); - } - } else { - if (to == Type.BYTE_TYPE) { - mv.visitInsn(Opcodes.I2B); - } else if (to == Type.CHAR_TYPE) { - mv.visitInsn(Opcodes.I2C); - } else if (to == Type.DOUBLE_TYPE) { - mv.visitInsn(Opcodes.I2D); - } else if (to == Type.FLOAT_TYPE) { - mv.visitInsn(Opcodes.I2F); - } else if (to == Type.LONG_TYPE) { - mv.visitInsn(Opcodes.I2L); - } else if (to == Type.SHORT_TYPE) { - mv.visitInsn(Opcodes.I2S); - } - } - } - } - - // ------------------------------------------------------------------------ - // Instructions to do boxing and unboxing operations - // ------------------------------------------------------------------------ - - /** - * Generates the instructions to box the top stack value. This value is - * replaced by its boxed equivalent on top of the stack. - * - * @param type the type of the top stack value. - */ - public void box(final Type type) { - if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { - return; - } - if (type == Type.VOID_TYPE) { - push((String) null); - } else { - Type boxed = type; - switch (type.getSort()) { - case Type.BYTE: - boxed = BYTE_TYPE; - break; - case Type.BOOLEAN: - boxed = BOOLEAN_TYPE; - break; - case Type.SHORT: - boxed = SHORT_TYPE; - break; - case Type.CHAR: - boxed = CHARACTER_TYPE; - break; - case Type.INT: - boxed = INTEGER_TYPE; - break; - case Type.FLOAT: - boxed = FLOAT_TYPE; - break; - case Type.LONG: - boxed = LONG_TYPE; - break; - case Type.DOUBLE: - boxed = DOUBLE_TYPE; - break; - } - newInstance(boxed); - if (type.getSize() == 2) { - // Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o - dupX2(); - dupX2(); - pop(); - } else { - // p -> po -> opo -> oop -> o - dupX1(); - swap(); - } - invokeConstructor(boxed, new Method("", Type.VOID_TYPE, new Type[] { type })); - } - } - - /** - * Generates the instructions to unbox the top stack value. This value is - * replaced by its unboxed equivalent on top of the stack. - * - * @param type the type of the top stack value. - */ - public void unbox(final Type type) { - Type t = NUMBER_TYPE; - Method sig = null; - switch (type.getSort()) { - case Type.VOID: - return; - case Type.CHAR: - t = CHARACTER_TYPE; - sig = CHAR_VALUE; - break; - case Type.BOOLEAN: - t = BOOLEAN_TYPE; - sig = BOOLEAN_VALUE; - break; - case Type.DOUBLE: - sig = DOUBLE_VALUE; - break; - case Type.FLOAT: - sig = FLOAT_VALUE; - break; - case Type.LONG: - sig = LONG_VALUE; - break; - case Type.INT: - case Type.SHORT: - case Type.BYTE: - sig = INT_VALUE; - } - if (sig == null) { - checkCast(type); - } else { - checkCast(t); - invokeVirtual(t, sig); - } - } - - // ------------------------------------------------------------------------ - // Instructions to jump to other instructions - // ------------------------------------------------------------------------ - - /** - * Creates a new {@link Label}. - * - * @return a new {@link Label}. - */ - public Label newLabel() { - return new Label(); - } - - /** - * Marks the current code position with the given label. - * - * @param label a label. - */ - public void mark(final Label label) { - mv.visitLabel(label); - } - - /** - * Marks the current code position with a new label. - * - * @return the label that was created to mark the current code position. - */ - public Label mark() { - Label label = new Label(); - mv.visitLabel(label); - return label; - } - - /** - * Generates the instructions to jump to a label based on the comparison of - * the top two stack values. - * - * @param type the type of the top two stack values. - * @param mode how these values must be compared. One of EQ, NE, LT, GE, GT, - * LE. - * @param label where to jump if the comparison result is true. - */ - public void ifCmp(final Type type, final int mode, final Label label) { - int intOp = -1; - switch (type.getSort()) { - case Type.LONG: - mv.visitInsn(Opcodes.LCMP); - break; - case Type.DOUBLE: - mv.visitInsn(Opcodes.DCMPG); - break; - case Type.FLOAT: - mv.visitInsn(Opcodes.FCMPG); - break; - case Type.ARRAY: - case Type.OBJECT: - switch (mode) { - case EQ: - mv.visitJumpInsn(Opcodes.IF_ACMPEQ, label); - return; - case NE: - mv.visitJumpInsn(Opcodes.IF_ACMPNE, label); - return; - } - throw new IllegalArgumentException("Bad comparison for type " + type); - default: - switch (mode) { - case EQ: - intOp = Opcodes.IF_ICMPEQ; - break; - case NE: - intOp = Opcodes.IF_ICMPNE; - break; - case GE: - intOp = Opcodes.IF_ICMPGE; - break; - case LT: - intOp = Opcodes.IF_ICMPLT; - break; - case LE: - intOp = Opcodes.IF_ICMPLE; - break; - case GT: - intOp = Opcodes.IF_ICMPGT; - break; - } - mv.visitJumpInsn(intOp, label); - return; - } - int jumpMode = mode; - switch (mode) { - case GE: - jumpMode = LT; - break; - case LE: - jumpMode = GT; - break; - } - mv.visitJumpInsn(jumpMode, label); - } - - /** - * Generates the instructions to jump to a label based on the comparison of - * the top two integer stack values. - * - * @param mode how these values must be compared. One of EQ, NE, LT, GE, GT, - * LE. - * @param label where to jump if the comparison result is true. - */ - public void ifICmp(final int mode, final Label label) { - ifCmp(Type.INT_TYPE, mode, label); - } - - /** - * Generates the instructions to jump to a label based on the comparison of - * the top integer stack value with zero. - * - * @param mode how these values must be compared. One of EQ, NE, LT, GE, GT, - * LE. - * @param label where to jump if the comparison result is true. - */ - public void ifZCmp(final int mode, final Label label) { - mv.visitJumpInsn(mode, label); - } - - /** - * Generates the instruction to jump to the given label if the top stack - * value is null. - * - * @param label where to jump if the condition is true. - */ - public void ifNull(final Label label) { - mv.visitJumpInsn(Opcodes.IFNULL, label); - } - - /** - * Generates the instruction to jump to the given label if the top stack - * value is not null. - * - * @param label where to jump if the condition is true. - */ - public void ifNonNull(final Label label) { - mv.visitJumpInsn(Opcodes.IFNONNULL, label); - } - - /** - * Generates the instruction to jump to the given label. - * - * @param label where to jump if the condition is true. - */ - public void goTo(final Label label) { - mv.visitJumpInsn(Opcodes.GOTO, label); - } - - /** - * Generates a RET instruction. - * - * @param local a local variable identifier, as returned by - * {@link LocalVariablesSorter#newLocal(Type) newLocal()}. - */ - public void ret(final int local) { - mv.visitVarInsn(Opcodes.RET, local); - } - - /** - * Generates the instructions for a switch statement. - * - * @param keys the switch case keys. - * @param generator a generator to generate the code for the switch cases. - */ - public void tableSwitch(final int[] keys, final TableSwitchGenerator generator) { - float density; - if (keys.length == 0) { - density = 0; - } else { - density = (float) keys.length / (keys[keys.length - 1] - keys[0] + 1); - } - tableSwitch(keys, generator, density >= 0.5f); - } - - /** - * Generates the instructions for a switch statement. - * - * @param keys the switch case keys. - * @param generator a generator to generate the code for the switch cases. - * @param useTable true to use a TABLESWITCH instruction, or - * false to use a LOOKUPSWITCH instruction. - */ - public void tableSwitch(final int[] keys, final TableSwitchGenerator generator, final boolean useTable) { - for (int i = 1; i < keys.length; ++i) { - if (keys[i] < keys[i - 1]) { - throw new IllegalArgumentException("keys must be sorted ascending"); - } - } - Label def = newLabel(); - Label end = newLabel(); - if (keys.length > 0) { - int len = keys.length; - int min = keys[0]; - int max = keys[len - 1]; - int range = max - min + 1; - if (useTable) { - Label[] labels = new Label[range]; - Arrays.fill(labels, def); - for (int i = 0; i < len; ++i) { - labels[keys[i] - min] = newLabel(); - } - mv.visitTableSwitchInsn(min, max, def, labels); - for (int i = 0; i < range; ++i) { - Label label = labels[i]; - if (label != def) { - mark(label); - generator.generateCase(i + min, end); - } - } - } else { - Label[] labels = new Label[len]; - for (int i = 0; i < len; ++i) { - labels[i] = newLabel(); - } - mv.visitLookupSwitchInsn(def, keys, labels); - for (int i = 0; i < len; ++i) { - mark(labels[i]); - generator.generateCase(keys[i], end); - } - } - } - mark(def); - generator.generateDefault(); - mark(end); - } - - /** - * Generates the instruction to return the top stack value to the caller. - */ - public void returnValue() { - mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN)); - } - - // ------------------------------------------------------------------------ - // Instructions to load and store fields - // ------------------------------------------------------------------------ - - /** - * Generates a get field or set field instruction. - * - * @param opcode the instruction's opcode. - * @param ownerType the class in which the field is defined. - * @param name the name of the field. - * @param fieldType the type of the field. - */ - private void fieldInsn(final int opcode, final Type ownerType, final String name, final Type fieldType) { - mv.visitFieldInsn(opcode, ownerType.getInternalName(), name, fieldType.getDescriptor()); - } - - /** - * Generates the instruction to push the value of a static field on the - * stack. - * - * @param owner the class in which the field is defined. - * @param name the name of the field. - * @param type the type of the field. - */ - public void getStatic(final Type owner, final String name, final Type type) { - fieldInsn(Opcodes.GETSTATIC, owner, name, type); - } - - /** - * Generates the instruction to store the top stack value in a static field. - * - * @param owner the class in which the field is defined. - * @param name the name of the field. - * @param type the type of the field. - */ - public void putStatic(final Type owner, final String name, final Type type) { - fieldInsn(Opcodes.PUTSTATIC, owner, name, type); - } - - /** - * Generates the instruction to push the value of a non static field on the - * stack. - * - * @param owner the class in which the field is defined. - * @param name the name of the field. - * @param type the type of the field. - */ - public void getField(final Type owner, final String name, final Type type) { - fieldInsn(Opcodes.GETFIELD, owner, name, type); - } - - /** - * Generates the instruction to store the top stack value in a non static - * field. - * - * @param owner the class in which the field is defined. - * @param name the name of the field. - * @param type the type of the field. - */ - public void putField(final Type owner, final String name, final Type type) { - fieldInsn(Opcodes.PUTFIELD, owner, name, type); - } - - // ------------------------------------------------------------------------ - // Instructions to invoke methods - // ------------------------------------------------------------------------ - - /** - * Generates an invoke method instruction. - * - * @param opcode the instruction's opcode. - * @param type the class in which the method is defined. - * @param method the method to be invoked. - */ - private void invokeInsn(final int opcode, final Type type, final Method method) { - String owner = type.getSort() == Type.ARRAY ? type.getDescriptor() : type.getInternalName(); - mv.visitMethodInsn(opcode, owner, method.getName(), method.getDescriptor()); - } - - /** - * Generates the instruction to invoke a normal method. - * - * @param owner the class in which the method is defined. - * @param method the method to be invoked. - */ - public void invokeVirtual(final Type owner, final Method method) { - invokeInsn(Opcodes.INVOKEVIRTUAL, owner, method); - } - - /** - * Generates the instruction to invoke a constructor. - * - * @param type the class in which the constructor is defined. - * @param method the constructor to be invoked. - */ - public void invokeConstructor(final Type type, final Method method) { - invokeInsn(Opcodes.INVOKESPECIAL, type, method); - } - - /** - * Generates the instruction to invoke a static method. - * - * @param owner the class in which the method is defined. - * @param method the method to be invoked. - */ - public void invokeStatic(final Type owner, final Method method) { - invokeInsn(Opcodes.INVOKESTATIC, owner, method); - } - - /** - * Generates the instruction to invoke an interface method. - * - * @param owner the class in which the method is defined. - * @param method the method to be invoked. - */ - public void invokeInterface(final Type owner, final Method method) { - invokeInsn(Opcodes.INVOKEINTERFACE, owner, method); - } - - // ------------------------------------------------------------------------ - // Instructions to create objects and arrays - // ------------------------------------------------------------------------ - - /** - * Generates a type dependent instruction. - * - * @param opcode the instruction's opcode. - * @param type the instruction's operand. - */ - private void typeInsn(final int opcode, final Type type) { - mv.visitTypeInsn(opcode, type.getInternalName()); - } - - /** - * Generates the instruction to create a new object. - * - * @param type the class of the object to be created. - */ - public void newInstance(final Type type) { - typeInsn(Opcodes.NEW, type); - } - - /** - * Generates the instruction to create a new array. - * - * @param type the type of the array elements. - */ - public void newArray(final Type type) { - int typ; - switch (type.getSort()) { - case Type.BOOLEAN: - typ = Opcodes.T_BOOLEAN; - break; - case Type.CHAR: - typ = Opcodes.T_CHAR; - break; - case Type.BYTE: - typ = Opcodes.T_BYTE; - break; - case Type.SHORT: - typ = Opcodes.T_SHORT; - break; - case Type.INT: - typ = Opcodes.T_INT; - break; - case Type.FLOAT: - typ = Opcodes.T_FLOAT; - break; - case Type.LONG: - typ = Opcodes.T_LONG; - break; - case Type.DOUBLE: - typ = Opcodes.T_DOUBLE; - break; - default: - typeInsn(Opcodes.ANEWARRAY, type); - return; - } - mv.visitIntInsn(Opcodes.NEWARRAY, typ); - } - - // ------------------------------------------------------------------------ - // Miscelaneous instructions - // ------------------------------------------------------------------------ - - /** - * Generates the instruction to compute the length of an array. - */ - public void arrayLength() { - mv.visitInsn(Opcodes.ARRAYLENGTH); - } - - /** - * Generates the instruction to throw an exception. - */ - public void throwException() { - mv.visitInsn(Opcodes.ATHROW); - } - - /** - * Generates the instructions to create and throw an exception. The - * exception class must have a constructor with a single String argument. - * - * @param type the class of the exception to be thrown. - * @param msg the detailed message of the exception. - */ - public void throwException(final Type type, final String msg) { - newInstance(type); - dup(); - push(msg); - invokeConstructor(type, Method.getMethod("void (String)")); - throwException(); - } - - /** - * Generates the instruction to check that the top stack value is of the - * given type. - * - * @param type a class or interface type. - */ - public void checkCast(final Type type) { - if (!type.equals(OBJECT_TYPE)) { - typeInsn(Opcodes.CHECKCAST, type); - } - } - - /** - * Generates the instruction to test if the top stack value is of the given - * type. - * - * @param type a class or interface type. - */ - public void instanceOf(final Type type) { - typeInsn(Opcodes.INSTANCEOF, type); - } - - /** - * Generates the instruction to get the monitor of the top stack value. - */ - public void monitorEnter() { - mv.visitInsn(Opcodes.MONITORENTER); - } - - /** - * Generates the instruction to release the monitor of the top stack value. - */ - public void monitorExit() { - mv.visitInsn(Opcodes.MONITOREXIT); - } - - // ------------------------------------------------------------------------ - // Non instructions - // ------------------------------------------------------------------------ - - /** - * Marks the end of the visited method. - */ - public void endMethod() { - if ((access & Opcodes.ACC_ABSTRACT) == 0) { - mv.visitMaxs(0, 0); - } - mv.visitEnd(); - } - - /** - * Marks the start of an exception handler. - * - * @param start beginning of the exception handler's scope (inclusive). - * @param end end of the exception handler's scope (exclusive). - * @param exception internal name of the type of exceptions handled by the - * handler. - */ - public void catchException(final Label start, final Label end, final Type exception) { - mv.visitTryCatchBlock(start, end, mark(), exception.getInternalName()); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/JSRInlinerAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/JSRInlinerAdapter.java deleted file mode 100644 index d0e856d74..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/JSRInlinerAdapter.java +++ /dev/null @@ -1,706 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; -import com.alibaba.citrus.asm.tree.AbstractInsnNode; -import com.alibaba.citrus.asm.tree.InsnList; -import com.alibaba.citrus.asm.tree.InsnNode; -import com.alibaba.citrus.asm.tree.JumpInsnNode; -import com.alibaba.citrus.asm.tree.LabelNode; -import com.alibaba.citrus.asm.tree.LocalVariableNode; -import com.alibaba.citrus.asm.tree.LookupSwitchInsnNode; -import com.alibaba.citrus.asm.tree.MethodNode; -import com.alibaba.citrus.asm.tree.TableSwitchInsnNode; -import com.alibaba.citrus.asm.tree.TryCatchBlockNode; - -/** - * A {@link com.alibaba.citrus.asm.MethodAdapter} that removes JSR instructions - * and inlines the referenced subroutines. Explanation of how it works - * TODO - * - * @author Niko Matsakis - */ -public class JSRInlinerAdapter extends MethodNode implements Opcodes { - - private static final boolean LOGGING = false; - - /** - * The visitor to which we will emit a translation of this method without - * internal subroutines. - */ - private final MethodVisitor mv; - - /** - * For each label that is jumped to by a JSR, we create a Subroutine - * instance. Map is the generic type. - */ - private final Map subroutineHeads = new HashMap(); - - /** - * This subroutine instance denotes the line of execution that is not - * contained within any subroutine; i.e., the "subroutine" that is executing - * when a method first begins. - */ - private final Subroutine mainSubroutine = new Subroutine(); - - /** - * This BitSet contains the index of every instruction that belongs to more - * than one subroutine. This should not happen often. - */ - private final BitSet dualCitizens = new BitSet(); - - /** - * Creates a new JSRInliner. - * - * @param mv the MethodVisitor to send the resulting inlined - * method code to (use null for none). - * @param access the method's access flags (see {@link Opcodes}). This - * parameter also indicates if the method is synthetic and/or - * deprecated. - * @param name the method's name. - * @param desc the method's descriptor (see {@link Type}). - * @param signature the method's signature. May be null. - * @param exceptions the internal names of the method's exception classes - * (see {@link Type#getInternalName() getInternalName}). May be - * null. - */ - public JSRInlinerAdapter(final MethodVisitor mv, final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - super(access, name, desc, signature, exceptions); - this.mv = mv; - } - - /** - * Detects a JSR instruction and sets a flag to indicate we will need to do - * inlining. - */ - @Override - public void visitJumpInsn(final int opcode, final Label lbl) { - super.visitJumpInsn(opcode, lbl); - LabelNode ln = ((JumpInsnNode) instructions.getLast()).label; - if (opcode == JSR && !subroutineHeads.containsKey(ln)) { - subroutineHeads.put(ln, new Subroutine()); - } - } - - /** - * If any JSRs were seen, triggers the inlining process. Otherwise, forwards - * the byte codes untouched. - */ - @Override - public void visitEnd() { - if (!subroutineHeads.isEmpty()) { - markSubroutines(); - if (LOGGING) { - log(mainSubroutine.toString()); - Iterator it = subroutineHeads.values().iterator(); - while (it.hasNext()) { - Subroutine sub = (Subroutine) it.next(); - log(sub.toString()); - } - } - emitCode(); - } - - // Forward the translate opcodes on if appropriate: - if (mv != null) { - accept(mv); - } - } - - /** - * Walks the method and determines which internal subroutine(s), if any, - * each instruction is a method of. - */ - private void markSubroutines() { - BitSet anyvisited = new BitSet(); - - // First walk the main subroutine and find all those instructions which - // can be reached without invoking any JSR at all - markSubroutineWalk(mainSubroutine, 0, anyvisited); - - // Go through the head of each subroutine and find any nodes reachable - // to that subroutine without following any JSR links. - for (Iterator it = subroutineHeads.entrySet().iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry) it.next(); - LabelNode lab = (LabelNode) entry.getKey(); - Subroutine sub = (Subroutine) entry.getValue(); - int index = instructions.indexOf(lab); - markSubroutineWalk(sub, index, anyvisited); - } - } - - /** - * Performs a depth first search walking the normal byte code path starting - * at index, and adding each instruction encountered into the - * subroutine sub. After this walk is complete, iterates over - * the exception handlers to ensure that we also include those byte codes - * which are reachable through an exception that may be thrown during the - * execution of the subroutine. Invoked from markSubroutines(). - * - * @param sub the subroutine whose instructions must be computed. - * @param index an instruction of this subroutine. - * @param anyvisited indexes of the already visited instructions, i.e. - * marked as part of this subroutine or any previously computed - * subroutine. - */ - private void markSubroutineWalk(final Subroutine sub, final int index, final BitSet anyvisited) { - if (LOGGING) { - log("markSubroutineWalk: sub=" + sub + " index=" + index); - } - - // First find those instructions reachable via normal execution - markSubroutineWalkDFS(sub, index, anyvisited); - - // Now, make sure we also include any applicable exception handlers - boolean loop = true; - while (loop) { - loop = false; - for (Iterator it = tryCatchBlocks.iterator(); it.hasNext();) { - TryCatchBlockNode trycatch = (TryCatchBlockNode) it.next(); - - if (LOGGING) { - // TODO use of default toString(). - log("Scanning try/catch " + trycatch); - } - - // If the handler has already been processed, skip it. - int handlerindex = instructions.indexOf(trycatch.handler); - if (sub.instructions.get(handlerindex)) { - continue; - } - - int startindex = instructions.indexOf(trycatch.start); - int endindex = instructions.indexOf(trycatch.end); - int nextbit = sub.instructions.nextSetBit(startindex); - if (nextbit != -1 && nextbit < endindex) { - if (LOGGING) { - log("Adding exception handler: " + startindex + '-' + endindex + " due to " + nextbit - + " handler " + handlerindex); - } - markSubroutineWalkDFS(sub, handlerindex, anyvisited); - loop = true; - } - } - } - } - - /** - * Performs a simple DFS of the instructions, assigning each to the - * subroutine sub. Starts from index. Invoked only - * by markSubroutineWalk(). - * - * @param sub the subroutine whose instructions must be computed. - * @param index an instruction of this subroutine. - * @param anyvisited indexes of the already visited instructions, i.e. - * marked as part of this subroutine or any previously computed - * subroutine. - */ - private void markSubroutineWalkDFS(final Subroutine sub, int index, final BitSet anyvisited) { - while (true) { - AbstractInsnNode node = instructions.get(index); - - // don't visit a node twice - if (sub.instructions.get(index)) { - return; - } - sub.instructions.set(index); - - // check for those nodes already visited by another subroutine - if (anyvisited.get(index)) { - dualCitizens.set(index); - if (LOGGING) { - log("Instruction #" + index + " is dual citizen."); - } - } - anyvisited.set(index); - - if (node.getType() == AbstractInsnNode.JUMP_INSN && node.getOpcode() != JSR) { - // we do not follow recursively called subroutines here; but any - // other sort of branch we do follow - JumpInsnNode jnode = (JumpInsnNode) node; - int destidx = instructions.indexOf(jnode.label); - markSubroutineWalkDFS(sub, destidx, anyvisited); - } - if (node.getType() == AbstractInsnNode.TABLESWITCH_INSN) { - TableSwitchInsnNode tsnode = (TableSwitchInsnNode) node; - int destidx = instructions.indexOf(tsnode.dflt); - markSubroutineWalkDFS(sub, destidx, anyvisited); - for (int i = tsnode.labels.size() - 1; i >= 0; --i) { - LabelNode l = (LabelNode) tsnode.labels.get(i); - destidx = instructions.indexOf(l); - markSubroutineWalkDFS(sub, destidx, anyvisited); - } - } - if (node.getType() == AbstractInsnNode.LOOKUPSWITCH_INSN) { - LookupSwitchInsnNode lsnode = (LookupSwitchInsnNode) node; - int destidx = instructions.indexOf(lsnode.dflt); - markSubroutineWalkDFS(sub, destidx, anyvisited); - for (int i = lsnode.labels.size() - 1; i >= 0; --i) { - LabelNode l = (LabelNode) lsnode.labels.get(i); - destidx = instructions.indexOf(l); - markSubroutineWalkDFS(sub, destidx, anyvisited); - } - } - - // check to see if this opcode falls through to the next instruction - // or not; if not, return. - switch (instructions.get(index).getOpcode()) { - case GOTO: - case RET: - case TABLESWITCH: - case LOOKUPSWITCH: - case IRETURN: - case LRETURN: - case FRETURN: - case DRETURN: - case ARETURN: - case RETURN: - case ATHROW: - /* - * note: this either returns from this subroutine, or a - * parent subroutine which invoked it - */ - return; - } - - // Use tail recursion here in the form of an outer while loop to - // avoid our stack growing needlessly: - index++; - } - } - - /** - * Creates the new instructions, inlining each instantiation of each - * subroutine until the code is fully elaborated. - */ - private void emitCode() { - LinkedList worklist = new LinkedList(); - // Create an instantiation of the "root" subroutine, which is just the - // main routine - worklist.add(new Instantiation(null, mainSubroutine)); - - // Emit instantiations of each subroutine we encounter, including the - // main subroutine - InsnList newInstructions = new InsnList(); - List newTryCatchBlocks = new ArrayList(); - List newLocalVariables = new ArrayList(); - while (!worklist.isEmpty()) { - Instantiation inst = (Instantiation) worklist.removeFirst(); - emitSubroutine(inst, worklist, newInstructions, newTryCatchBlocks, newLocalVariables); - } - instructions = newInstructions; - tryCatchBlocks = newTryCatchBlocks; - localVariables = newLocalVariables; - } - - /** - * Emits one instantiation of one subroutine, specified by - * instant. May add new instantiations that are invoked by this - * one to the worklist parameter, and new try/catch blocks to - * newTryCatchBlocks. - * - * @param instant the instantiation that must be performed. - * @param worklist list of the instantiations that remain to be done. - * @param newInstructions the instruction list to which the instantiated - * code must be appended. - * @param newTryCatchBlocks the exception handler list to which the - * instantiated handlers must be appended. - */ - private void emitSubroutine(final Instantiation instant, final List worklist, final InsnList newInstructions, - final List newTryCatchBlocks, final List newLocalVariables) { - LabelNode duplbl = null; - - if (LOGGING) { - log("--------------------------------------------------------"); - log("Emitting instantiation of subroutine " + instant.subroutine); - } - - // Emit the relevant instructions for this instantiation, translating - // labels and jump targets as we go: - for (int i = 0, c = instructions.size(); i < c; i++) { - AbstractInsnNode insn = instructions.get(i); - Instantiation owner = instant.findOwner(i); - - // Always remap labels: - if (insn.getType() == AbstractInsnNode.LABEL) { - // Translate labels into their renamed equivalents. - // Avoid adding the same label more than once. Note - // that because we own this instruction the gotoTable - // and the rangeTable will always agree. - LabelNode ilbl = (LabelNode) insn; - LabelNode remap = instant.rangeLabel(ilbl); - if (LOGGING) { - // TODO use of default toString(). - log("Translating lbl #" + i + ':' + ilbl + " to " + remap); - } - if (remap != duplbl) { - newInstructions.add(remap); - duplbl = remap; - } - continue; - } - - // We don't want to emit instructions that were already - // emitted by a subroutine higher on the stack. Note that - // it is still possible for a given instruction to be - // emitted twice because it may belong to two subroutines - // that do not invoke each other. - if (owner != instant) { - continue; - } - - if (LOGGING) { - log("Emitting inst #" + i); - } - - if (insn.getOpcode() == RET) { - // Translate RET instruction(s) to a jump to the return label - // for the appropriate instantiation. The problem is that the - // subroutine may "fall through" to the ret of a parent - // subroutine; therefore, to find the appropriate ret label we - // find the lowest subroutine on the stack that claims to own - // this instruction. See the class javadoc comment for an - // explanation on why this technique is safe (note: it is only - // safe if the input is verifiable). - LabelNode retlabel = null; - for (Instantiation p = instant; p != null; p = p.previous) { - if (p.subroutine.ownsInstruction(i)) { - retlabel = p.returnLabel; - } - } - if (retlabel == null) { - // This is only possible if the mainSubroutine owns a RET - // instruction, which should never happen for verifiable - // code. - throw new RuntimeException("Instruction #" + i + " is a RET not owned by any subroutine"); - } - newInstructions.add(new JumpInsnNode(GOTO, retlabel)); - } else if (insn.getOpcode() == JSR) { - LabelNode lbl = ((JumpInsnNode) insn).label; - Subroutine sub = (Subroutine) subroutineHeads.get(lbl); - Instantiation newinst = new Instantiation(instant, sub); - LabelNode startlbl = newinst.gotoLabel(lbl); - - if (LOGGING) { - log(" Creating instantiation of subr " + sub); - } - - // Rather than JSRing, we will jump to the inline version and - // push NULL for what was once the return value. This hack - // allows us to avoid doing any sort of data flow analysis to - // figure out which instructions manipulate the old return value - // pointer which is now known to be unneeded. - newInstructions.add(new InsnNode(ACONST_NULL)); - newInstructions.add(new JumpInsnNode(GOTO, startlbl)); - newInstructions.add(newinst.returnLabel); - - // Insert this new instantiation into the queue to be emitted - // later. - worklist.add(newinst); - } else { - newInstructions.add(insn.clone(instant)); - } - } - - // Emit try/catch blocks that are relevant to this method. - for (Iterator it = tryCatchBlocks.iterator(); it.hasNext();) { - TryCatchBlockNode trycatch = (TryCatchBlockNode) it.next(); - - if (LOGGING) { - // TODO use of default toString(). - log("try catch block original labels=" + trycatch.start + '-' + trycatch.end + "->" + trycatch.handler); - } - - final LabelNode start = instant.rangeLabel(trycatch.start); - final LabelNode end = instant.rangeLabel(trycatch.end); - - // Ignore empty try/catch regions - if (start == end) { - if (LOGGING) { - log(" try catch block empty in this subroutine"); - } - continue; - } - - final LabelNode handler = instant.gotoLabel(trycatch.handler); - - if (LOGGING) { - // TODO use of default toString(). - log(" try catch block new labels=" + start + '-' + end + "->" + handler); - } - - if (start == null || end == null || handler == null) { - throw new RuntimeException("Internal error!"); - } - - newTryCatchBlocks.add(new TryCatchBlockNode(start, end, handler, trycatch.type)); - } - - for (Iterator it = localVariables.iterator(); it.hasNext();) { - LocalVariableNode lvnode = (LocalVariableNode) it.next(); - if (LOGGING) { - log("local var " + lvnode.name); - } - final LabelNode start = instant.rangeLabel(lvnode.start); - final LabelNode end = instant.rangeLabel(lvnode.end); - if (start == end) { - if (LOGGING) { - log(" local variable empty in this sub"); - } - continue; - } - newLocalVariables.add(new LocalVariableNode(lvnode.name, lvnode.desc, lvnode.signature, start, end, - lvnode.index)); - } - } - - private static void log(final String str) { - System.err.println(str); - } - - protected static class Subroutine { - - public final BitSet instructions = new BitSet(); - - public void addInstruction(final int idx) { - instructions.set(idx); - } - - public boolean ownsInstruction(final int idx) { - return instructions.get(idx); - } - - @Override - public String toString() { - return "Subroutine: " + instructions; - } - } - - /** - * A class that represents an instantiation of a subroutine. Each - * instantiation has an associate "stack" --- which is a listing of those - * instantiations that were active when this particular instance of this - * subroutine was invoked. Each instantiation also has a map from the - * original labels of the program to the labels appropriate for this - * instantiation, and finally a label to return to. - */ - private class Instantiation extends AbstractMap { - - /** - * Previous instantiations; the stack must be statically predictable to - * be inlinable. - */ - final Instantiation previous; - - /** - * The subroutine this is an instantiation of. - */ - public final Subroutine subroutine; - - /** - * This table maps Labels from the original source to Labels pointing at - * code specific to this instantiation, for use in remapping try/catch - * blocks,as well as gotos. Note that in the presence of dual citizens - * instructions, that is, instructions which belong to more than one - * subroutine due to the merging of control flow without a RET - * instruction, we will map the target label of a GOTO to the label used - * by the instantiation lowest on the stack. This avoids code - * duplication during inlining in most cases. - * - * @see #findOwner(int) - */ - public final Map rangeTable = new HashMap(); - - /** - * All returns for this instantiation will be mapped to this label - */ - public final LabelNode returnLabel; - - private Instantiation(final Instantiation prev, final Subroutine sub) { - previous = prev; - subroutine = sub; - for (Instantiation p = prev; p != null; p = p.previous) { - if (p.subroutine == sub) { - throw new RuntimeException("Recursive invocation of " + sub); - } - } - - // Determine the label to return to when this subroutine terminates - // via RET: note that the main subroutine never terminates via RET. - if (prev != null) { - returnLabel = new LabelNode(); - } else { - returnLabel = null; - } - - // Each instantiation will remap the labels from the code above to - // refer to its particular copy of its own instructions. Note that - // we collapse labels which point at the same instruction into one: - // this is fairly common as we are often ignoring large chunks of - // instructions, so what were previously distinct labels become - // duplicates. - LabelNode duplbl = null; - for (int i = 0, c = instructions.size(); i < c; i++) { - AbstractInsnNode insn = instructions.get(i); - - if (insn.getType() == AbstractInsnNode.LABEL) { - LabelNode ilbl = (LabelNode) insn; - - if (duplbl == null) { - // if we already have a label pointing at this spot, - // don't recreate it. - duplbl = new LabelNode(); - } - - // Add an entry in the rangeTable for every label - // in the original code which points at the next - // instruction of our own to be emitted. - rangeTable.put(ilbl, duplbl); - } else if (findOwner(i) == this) { - // We will emit this instruction, so clear the 'duplbl' flag - // since the next Label will refer to a distinct - // instruction. - duplbl = null; - } - } - } - - /** - * Returns the "owner" of a particular instruction relative to this - * instantiation: the owner referes to the Instantiation which will emit - * the version of this instruction that we will execute. Typically, the - * return value is either this or null. - * this indicates that this instantiation will generate the - * version of this instruction that we will execute, and - * null indicates that this instantiation never executes - * the given instruction. Sometimes, however, an instruction can belong - * to multiple subroutines; this is called a "dual citizen" instruction - * (though it may belong to more than 2 subroutines), and occurs when - * multiple subroutines branch to common points of control. In this - * case, the owner is the subroutine that appears lowest on the stack, - * and which also owns the instruction in question. - * - * @param i the index of the instruction in the original code - * @return the "owner" of a particular instruction relative to this - * instantiation. - */ - public Instantiation findOwner(final int i) { - if (!subroutine.ownsInstruction(i)) { - return null; - } - if (!dualCitizens.get(i)) { - return this; - } - Instantiation own = this; - for (Instantiation p = previous; p != null; p = p.previous) { - if (p.subroutine.ownsInstruction(i)) { - own = p; - } - } - return own; - } - - /** - * Looks up the label l in the gotoTable, thus - * translating it from a Label in the original code, to a Label in the - * inlined code that is appropriate for use by an instruction that - * branched to the original label. - * - * @param l The label we will be translating - * @return a label for use by a branch instruction in the inlined code - * @see #rangeLabel - */ - public LabelNode gotoLabel(final LabelNode l) { - // owner should never be null, because owner is only null - // if an instruction cannot be reached from this subroutine - Instantiation owner = findOwner(instructions.indexOf(l)); - return (LabelNode) owner.rangeTable.get(l); - } - - /** - * Looks up the label l in the rangeTable, - * thus translating it from a Label in the original code, to a Label in - * the inlined code that is appropriate for use by an try/catch or - * variable use annotation. - * - * @param l The label we will be translating - * @return a label for use by a try/catch or variable annotation in the - * original code - * @see #rangeTable - */ - public LabelNode rangeLabel(final LabelNode l) { - return (LabelNode) rangeTable.get(l); - } - - // AbstractMap implementation - - @Override - public Set entrySet() { - return null; - } - - @Override - public Object get(final Object o) { - return gotoLabel((LabelNode) o); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/LocalVariablesSorter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/LocalVariablesSorter.java deleted file mode 100644 index 3fcb4a5b3..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/LocalVariablesSorter.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodAdapter; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; - -/** - * A {@link MethodAdapter} that renumbers local variables in their order of - * appearance. This adapter allows one to easily add new local variables to a - * method. It may be used by inheriting from this class, but the preferred way - * of using it is via delegation: the next visitor in the chain can indeed add - * new locals when needed by calling {@link #newLocal} on this adapter (this - * requires a reference back to this {@link LocalVariablesSorter}). - * - * @author Chris Nokleberg - * @author Eugene Kuleshov - * @author Eric Bruneton - */ -public class LocalVariablesSorter extends MethodAdapter { - - private static final Type OBJECT_TYPE = Type.getObjectType("java/lang/Object"); - - /** - * Mapping from old to new local variable indexes. A local variable at index - * i of size 1 is remapped to 'mapping[2*i]', while a local variable at - * index i of size 2 is remapped to 'mapping[2*i+1]'. - */ - private int[] mapping = new int[40]; - - /** - * Array used to store stack map local variable types after remapping. - */ - private Object[] newLocals = new Object[20]; - - /** - * Index of the first local variable, after formal parameters. - */ - protected final int firstLocal; - - /** - * Index of the next local variable to be created by {@link #newLocal}. - */ - protected int nextLocal; - - /** - * Indicates if at least one local variable has moved due to remapping. - */ - private boolean changed; - - /** - * Creates a new {@link LocalVariablesSorter}. - * - * @param access access flags of the adapted method. - * @param desc the method's descriptor (see {@link Type Type}). - * @param mv the method visitor to which this adapter delegates calls. - */ - public LocalVariablesSorter(final int access, final String desc, final MethodVisitor mv) { - super(mv); - Type[] args = Type.getArgumentTypes(desc); - nextLocal = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0; - for (Type element : args) { - nextLocal += element.getSize(); - } - firstLocal = nextLocal; - } - - @Override - public void visitVarInsn(final int opcode, final int var) { - Type type; - switch (opcode) { - case Opcodes.LLOAD: - case Opcodes.LSTORE: - type = Type.LONG_TYPE; - break; - - case Opcodes.DLOAD: - case Opcodes.DSTORE: - type = Type.DOUBLE_TYPE; - break; - - case Opcodes.FLOAD: - case Opcodes.FSTORE: - type = Type.FLOAT_TYPE; - break; - - case Opcodes.ILOAD: - case Opcodes.ISTORE: - type = Type.INT_TYPE; - break; - - case Opcodes.ALOAD: - case Opcodes.ASTORE: - type = OBJECT_TYPE; - break; - - // case RET: - default: - type = Type.VOID_TYPE; - } - mv.visitVarInsn(opcode, remap(var, type)); - } - - @Override - public void visitIincInsn(final int var, final int increment) { - mv.visitIincInsn(remap(var, Type.INT_TYPE), increment); - } - - @Override - public void visitMaxs(final int maxStack, final int maxLocals) { - mv.visitMaxs(maxStack, nextLocal); - } - - @Override - public void visitLocalVariable(final String name, final String desc, final String signature, final Label start, - final Label end, final int index) { - int newIndex = remap(index, Type.getType(desc)); - mv.visitLocalVariable(name, desc, signature, start, end, newIndex); - } - - @Override - public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, - final Object[] stack) { - if (type != Opcodes.F_NEW) { // uncompressed frame - throw new IllegalStateException("ClassReader.accept() should be called with EXPAND_FRAMES flag"); - } - - if (!changed) { // optimization for the case where mapping = identity - mv.visitFrame(type, nLocal, local, nStack, stack); - return; - } - - // creates a copy of newLocals - Object[] oldLocals = new Object[newLocals.length]; - System.arraycopy(newLocals, 0, oldLocals, 0, oldLocals.length); - - // copies types from 'local' to 'newLocals' - // 'newLocals' already contains the variables added with 'newLocal' - - int index = 0; // old local variable index - int number = 0; // old local variable number - for (; number < nLocal; ++number) { - Object t = local[number]; - int size = t == Opcodes.LONG || t == Opcodes.DOUBLE ? 2 : 1; - if (t != Opcodes.TOP) { - setFrameLocal(remap(index, size), t); - } - index += size; - } - - // removes TOP after long and double types as well as trailing TOPs - - index = 0; - number = 0; - for (int i = 0; index < newLocals.length; ++i) { - Object t = newLocals[index++]; - if (t != null && t != Opcodes.TOP) { - newLocals[i] = t; - number = i + 1; - if (t == Opcodes.LONG || t == Opcodes.DOUBLE) { - index += 1; - } - } else { - newLocals[i] = Opcodes.TOP; - } - } - - // visits remapped frame - mv.visitFrame(type, number, newLocals, nStack, stack); - - // restores original value of 'newLocals' - newLocals = oldLocals; - } - - // ------------- - - /** - * Creates a new local variable of the given type. - * - * @param type the type of the local variable to be created. - * @return the identifier of the newly created local variable. - */ - public int newLocal(final Type type) { - Object t; - switch (type.getSort()) { - case Type.BOOLEAN: - case Type.CHAR: - case Type.BYTE: - case Type.SHORT: - case Type.INT: - t = Opcodes.INTEGER; - break; - case Type.FLOAT: - t = Opcodes.FLOAT; - break; - case Type.LONG: - t = Opcodes.LONG; - break; - case Type.DOUBLE: - t = Opcodes.DOUBLE; - break; - case Type.ARRAY: - t = type.getDescriptor(); - break; - // case Type.OBJECT: - default: - t = type.getInternalName(); - break; - } - int local = nextLocal; - nextLocal += type.getSize(); - setLocalType(local, type); - setFrameLocal(local, t); - return local; - } - - /** - * Sets the current type of the given local variable. The default - * implementation of this method does nothing. - * - * @param local a local variable identifier, as returned by - * {@link #newLocal newLocal()}. - * @param type the type of the value being stored in the local variable - */ - protected void setLocalType(final int local, final Type type) { - } - - private void setFrameLocal(final int local, final Object type) { - int l = newLocals.length; - if (local >= l) { - Object[] a = new Object[Math.max(2 * l, local + 1)]; - System.arraycopy(newLocals, 0, a, 0, l); - newLocals = a; - } - newLocals[local] = type; - } - - private int remap(final int var, final Type type) { - if (var < firstLocal) { - return var; - } - int key = 2 * var + type.getSize() - 1; - int size = mapping.length; - if (key >= size) { - int[] newMapping = new int[Math.max(2 * size, key + 1)]; - System.arraycopy(mapping, 0, newMapping, 0, size); - mapping = newMapping; - } - int value = mapping[key]; - if (value == 0) { - value = newLocalMapping(type); - setLocalType(value, type); - mapping[key] = value + 1; - } else { - value--; - } - if (value != var) { - changed = true; - } - return value; - } - - protected int newLocalMapping(final Type type) { - int local = nextLocal; - nextLocal += type.getSize(); - return local; - } - - private int remap(final int var, final int size) { - if (var < firstLocal || !changed) { - return var; - } - int key = 2 * var + size - 1; - int value = key < mapping.length ? mapping[key] : 0; - if (value == 0) { - throw new IllegalStateException("Unknown local variable " + var); - } - return value - 1; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/Remapper.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/Remapper.java deleted file mode 100644 index bbde088b3..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/Remapper.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.alibaba.citrus.asm.commons; - -import com.alibaba.citrus.asm.Type; -import com.alibaba.citrus.asm.signature.SignatureReader; -import com.alibaba.citrus.asm.signature.SignatureVisitor; -import com.alibaba.citrus.asm.signature.SignatureWriter; - -/** - * A class responsible for remapping types and names. Subclasses can override - * the following methods: - *
    - *
  • {@link #map(String)} - map type
  • - *
  • {@link #mapFieldName(String, String, String)} - map field name
  • - *
  • {@link #mapMethodName(String, String, String)} - map method name
  • - *
- * - * @author Eugene Kuleshov - */ -public abstract class Remapper { - - public String mapDesc(String desc) { - Type t = Type.getType(desc); - switch (t.getSort()) { - case Type.ARRAY: - String s = mapDesc(t.getElementType().getDescriptor()); - for (int i = 0; i < t.getDimensions(); ++i) { - s = '[' + s; - } - return s; - case Type.OBJECT: - String newType = map(t.getInternalName()); - if (newType != null) { - return 'L' + newType + ';'; - } - } - return desc; - } - - private Type mapType(Type t) { - switch (t.getSort()) { - case Type.ARRAY: - String s = mapDesc(t.getElementType().getDescriptor()); - for (int i = 0; i < t.getDimensions(); ++i) { - s = '[' + s; - } - return Type.getType(s); - case Type.OBJECT: - s = map(t.getInternalName()); - if (s != null) { - return Type.getObjectType(s); - } - } - return t; - } - - public String mapType(String type) { - if (type == null) { - return null; - } - return mapType(Type.getObjectType(type)).getInternalName(); - } - - public String[] mapTypes(String[] types) { - String[] newTypes = null; - boolean needMapping = false; - for (int i = 0; i < types.length; i++) { - String type = types[i]; - String newType = map(type); - if (newType != null && newTypes == null) { - newTypes = new String[types.length]; - if (i > 0) { - System.arraycopy(types, 0, newTypes, 0, i); - } - needMapping = true; - } - if (needMapping) { - newTypes[i] = newType == null ? type : newType; - } - } - return needMapping ? newTypes : types; - } - - public String mapMethodDesc(String desc) { - if ("()V".equals(desc)) { - return desc; - } - - Type[] args = Type.getArgumentTypes(desc); - String s = "("; - for (Type element : args) { - s += mapDesc(element.getDescriptor()); - } - Type returnType = Type.getReturnType(desc); - if (returnType == Type.VOID_TYPE) { - return s + ")V"; - } - return s + ')' + mapDesc(returnType.getDescriptor()); - } - - public Object mapValue(Object value) { - return value instanceof Type ? mapType((Type) value) : value; - } - - /** - * @param typeSignature true if signature is a FieldTypeSignature, such as - * the signature parameter of the ClassVisitor.visitField or - * MethodVisitor.visitLocalVariable methods - */ - public String mapSignature(String signature, boolean typeSignature) { - if (signature == null) { - return null; - } - SignatureReader r = new SignatureReader(signature); - SignatureWriter w = new SignatureWriter(); - SignatureVisitor a = createRemappingSignatureAdapter(w); - if (typeSignature) { - r.acceptType(a); - } else { - r.accept(a); - } - return w.toString(); - } - - protected SignatureVisitor createRemappingSignatureAdapter(SignatureVisitor v) { - return new RemappingSignatureAdapter(v, this); - } - - /** - * Map method name to the new name. Subclasses can override. - */ - public String mapMethodName(String owner, String name, String desc) { - return name; - } - - /** - * Map field name to the new name. Subclasses can override. - */ - public String mapFieldName(String owner, String name, String desc) { - return name; - } - - /** - * Map type name to the new name. Subclasses can override. - */ - public String map(String typeName) { - return typeName; - } - -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingAnnotationAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingAnnotationAdapter.java deleted file mode 100644 index 1ccd7b73e..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingAnnotationAdapter.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.alibaba.citrus.asm.commons; - -import com.alibaba.citrus.asm.AnnotationVisitor; - -/** - * An AnnotationVisitor adapter for type remapping. - * - * @author Eugene Kuleshov - */ -public class RemappingAnnotationAdapter implements AnnotationVisitor { - - private final AnnotationVisitor av; - - private final Remapper renamer; - - public RemappingAnnotationAdapter(AnnotationVisitor av, Remapper renamer) { - this.av = av; - this.renamer = renamer; - } - - public void visit(String name, Object value) { - av.visit(name, renamer.mapValue(value)); - } - - public void visitEnum(String name, String desc, String value) { - av.visitEnum(name, renamer.mapType(desc), value); - } - - public AnnotationVisitor visitAnnotation(String name, String desc) { - AnnotationVisitor v = av.visitAnnotation(name, renamer.mapType(desc)); - return v == null ? null : v == av ? this : new RemappingAnnotationAdapter(v, renamer); - } - - public AnnotationVisitor visitArray(String name) { - AnnotationVisitor v = av.visitArray(name); - return v == null ? null : v == av ? this : new RemappingAnnotationAdapter(v, renamer); - } - - public void visitEnd() { - av.visitEnd(); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingClassAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingClassAdapter.java deleted file mode 100644 index 008f0a913..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingClassAdapter.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.alibaba.citrus.asm.commons; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.ClassAdapter; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * A ClassAdapter for type remapping. - * - * @author Eugene Kuleshov - */ -public class RemappingClassAdapter extends ClassAdapter { - - protected final Remapper remapper; - - protected String className; - - public RemappingClassAdapter(ClassVisitor cv, Remapper remapper) { - super(cv); - this.remapper = remapper; - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - this.className = name; - super.visit(version, access, remapper.mapType(name), remapper.mapSignature(signature, false), remapper - .mapType(superName), interfaces == null ? null : remapper.mapTypes(interfaces)); - } - - @Override - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - AnnotationVisitor av; - av = super.visitAnnotation(remapper.mapType(desc), visible); - return av == null ? null : createRemappingAnnotationAdapter(av); - } - - @Override - public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { - FieldVisitor fv = super.visitField(access, remapper.mapFieldName(className, name, desc), - remapper.mapDesc(desc), remapper.mapSignature(signature, true), remapper.mapValue(value)); - return fv == null ? null : createRemappingFieldAdapter(fv); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - String newDesc = remapper.mapMethodDesc(desc); - MethodVisitor mv = super.visitMethod(access, remapper.mapMethodName(className, name, desc), newDesc, remapper - .mapSignature(signature, false), exceptions == null ? null : remapper.mapTypes(exceptions)); - return mv == null ? null : createRemappingMethodAdapter(access, newDesc, mv); - } - - @Override - public void visitInnerClass(String name, String outerName, String innerName, int access) { - super.visitInnerClass(remapper.mapType(name), outerName == null ? null : remapper.mapType(outerName), - innerName, // TODO should it be changed? - access); - } - - @Override - public void visitOuterClass(String owner, String name, String desc) { - super.visitOuterClass(remapper.mapType(owner), name == null ? null : remapper.mapMethodName(owner, name, desc), - desc == null ? null : remapper.mapMethodDesc(desc)); - } - - protected FieldVisitor createRemappingFieldAdapter(FieldVisitor fv) { - return new RemappingFieldAdapter(fv, remapper); - } - - protected MethodVisitor createRemappingMethodAdapter(int access, String newDesc, MethodVisitor mv) { - return new RemappingMethodAdapter(access, newDesc, mv, remapper); - } - - protected AnnotationVisitor createRemappingAnnotationAdapter(AnnotationVisitor av) { - return new RemappingAnnotationAdapter(av, remapper); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingFieldAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingFieldAdapter.java deleted file mode 100644 index d7b444e07..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingFieldAdapter.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.alibaba.citrus.asm.commons; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.FieldVisitor; - -/** - * A FieldVisitor adapter for type remapping. - * - * @author Eugene Kuleshov - */ -public class RemappingFieldAdapter implements FieldVisitor { - - private final FieldVisitor fv; - - private final Remapper remapper; - - public RemappingFieldAdapter(FieldVisitor fv, Remapper remapper) { - this.fv = fv; - this.remapper = remapper; - } - - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - AnnotationVisitor av = fv.visitAnnotation(desc, visible); - return av == null ? null : new RemappingAnnotationAdapter(av, remapper); - } - - public void visitAttribute(Attribute attr) { - fv.visitAttribute(attr); - } - - public void visitEnd() { - fv.visitEnd(); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingMethodAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingMethodAdapter.java deleted file mode 100644 index 66de67e33..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingMethodAdapter.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.alibaba.citrus.asm.commons; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * A MethodAdapter for type mapping. - * - * @author Eugene Kuleshov - */ -public class RemappingMethodAdapter extends LocalVariablesSorter { - - protected final Remapper remapper; - - public RemappingMethodAdapter(int access, String desc, MethodVisitor mv, Remapper renamer) { - super(access, desc, mv); - this.remapper = renamer; - } - - @Override - public void visitFieldInsn(int opcode, String owner, String name, String desc) { - super.visitFieldInsn(opcode, remapper.mapType(owner), remapper.mapFieldName(owner, name, desc), remapper - .mapDesc(desc)); - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc) { - super.visitMethodInsn(opcode, remapper.mapType(owner), remapper.mapMethodName(owner, name, desc), remapper - .mapMethodDesc(desc)); - } - - @Override - public void visitTypeInsn(int opcode, String type) { - super.visitTypeInsn(opcode, remapper.mapType(type)); - } - - @Override - public void visitLdcInsn(Object cst) { - super.visitLdcInsn(remapper.mapValue(cst)); - } - - @Override - public void visitMultiANewArrayInsn(String desc, int dims) { - super.visitMultiANewArrayInsn(remapper.mapDesc(desc), dims); - } - - @Override - public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { - super.visitTryCatchBlock(start, end, handler, // - type == null ? null : remapper.mapType(type)); - } - - @Override - public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { - super.visitLocalVariable(name, remapper.mapDesc(desc), remapper.mapSignature(signature, true), start, end, - index); - } - - @Override - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - AnnotationVisitor av = mv.visitAnnotation(desc, visible); - return av == null ? av : new RemappingAnnotationAdapter(av, remapper); - } - - @Override - public AnnotationVisitor visitAnnotationDefault() { - AnnotationVisitor av = mv.visitAnnotationDefault(); - return av == null ? av : new RemappingAnnotationAdapter(av, remapper); - } - - @Override - public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { - AnnotationVisitor av = mv.visitParameterAnnotation(parameter, desc, visible); - return av == null ? av : new RemappingAnnotationAdapter(av, remapper); - } - - @Override - public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) { - super.visitFrame(type, nLocal, remapEntries(nLocal, local), nStack, remapEntries(nStack, stack)); - } - - private Object[] remapEntries(int n, Object[] entries) { - for (int i = 0; i < n; i++) { - if (entries[i] instanceof String) { - Object[] newEntries = new Object[n]; - if (i > 0) { - System.arraycopy(entries, 0, newEntries, 0, i); - } - do { - Object t = entries[i]; - newEntries[i++] = t instanceof String ? remapper.mapType((String) t) : t; - } while (i < n); - return newEntries; - } - } - return entries; - } - -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingSignatureAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingSignatureAdapter.java deleted file mode 100644 index ef974bb5a..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/RemappingSignatureAdapter.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.alibaba.citrus.asm.commons; - -import com.alibaba.citrus.asm.signature.SignatureVisitor; - -/** - * A SignatureVisitor adapter for type mapping. - * - * @author Eugene Kuleshov - */ -public class RemappingSignatureAdapter implements SignatureVisitor { - private final SignatureVisitor v; - private final Remapper remapper; - private String className; - - public RemappingSignatureAdapter(SignatureVisitor v, Remapper remapper) { - this.v = v; - this.remapper = remapper; - } - - public void visitClassType(String name) { - className = name; - v.visitClassType(remapper.mapType(name)); - } - - public void visitInnerClassType(String name) { - className = className + '$' + name; - String remappedName = remapper.mapType(className); - v.visitInnerClassType(remappedName.substring(remappedName.lastIndexOf('$') + 1)); - } - - public void visitFormalTypeParameter(String name) { - v.visitFormalTypeParameter(name); - } - - public void visitTypeVariable(String name) { - v.visitTypeVariable(name); - } - - public SignatureVisitor visitArrayType() { - v.visitArrayType(); - return this; - } - - public void visitBaseType(char descriptor) { - v.visitBaseType(descriptor); - } - - public SignatureVisitor visitClassBound() { - v.visitClassBound(); - return this; - } - - public SignatureVisitor visitExceptionType() { - v.visitExceptionType(); - return this; - } - - public SignatureVisitor visitInterface() { - v.visitInterface(); - return this; - } - - public SignatureVisitor visitInterfaceBound() { - v.visitInterfaceBound(); - return this; - } - - public SignatureVisitor visitParameterType() { - v.visitParameterType(); - return this; - } - - public SignatureVisitor visitReturnType() { - v.visitReturnType(); - return this; - } - - public SignatureVisitor visitSuperclass() { - v.visitSuperclass(); - return this; - } - - public void visitTypeArgument() { - v.visitTypeArgument(); - } - - public SignatureVisitor visitTypeArgument(char wildcard) { - v.visitTypeArgument(wildcard); - return this; - } - - public void visitEnd() { - v.visitEnd(); - } - -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/SerialVersionUIDAdder.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/SerialVersionUIDAdder.java deleted file mode 100644 index 1bd5985c3..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/SerialVersionUIDAdder.java +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutput; -import java.io.DataOutputStream; -import java.io.IOException; -import java.security.MessageDigest; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; - -import com.alibaba.citrus.asm.ClassAdapter; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * A {@link ClassAdapter} that adds a serial version unique identifier to a - * class if missing. Here is typical usage of this class: - * - *
- *   ClassWriter cw = new ClassWriter(...);
- *   ClassVisitor sv = new SerialVersionUIDAdder(cw);
- *   ClassVisitor ca = new MyClassAdapter(sv);
- *   new ClassReader(orginalClass).accept(ca, false);
- * 
- * - * The SVUID algorithm can be found http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html: - * - *
- * The serialVersionUID is computed using the signature of a stream of bytes
- * that reflect the class definition. The National Institute of Standards and
- * Technology (NIST) Secure Hash Algorithm (SHA-1) is used to compute a
- * signature for the stream. The first two 32-bit quantities are used to form a
- * 64-bit hash. A java.lang.DataOutputStream is used to convert primitive data
- * types to a sequence of bytes. The values input to the stream are defined by
- * the Java Virtual Machine (VM) specification for classes.
- * The sequence of items in the stream is as follows:
- * 1. The class name written using UTF encoding.
- * 2. The class modifiers written as a 32-bit integer.
- * 3. The name of each interface sorted by name written using UTF encoding.
- * 4. For each field of the class sorted by field name (except private static
- * and private transient fields):
- * 1. The name of the field in UTF encoding.
- * 2. The modifiers of the field written as a 32-bit integer.
- * 3. The descriptor of the field in UTF encoding
- * 5. If a class initializer exists, write out the following:
- * 1. The name of the method, <clinit>, in UTF encoding.
- * 2. The modifier of the method, java.lang.reflect.Modifier.STATIC,
- * written as a 32-bit integer.
- * 3. The descriptor of the method, ()V, in UTF encoding.
- * 6. For each non-private constructor sorted by method name and signature:
- * 1. The name of the method, <init>, in UTF encoding.
- * 2. The modifiers of the method written as a 32-bit integer.
- * 3. The descriptor of the method in UTF encoding.
- * 7. For each non-private method sorted by method name and signature:
- * 1. The name of the method in UTF encoding.
- * 2. The modifiers of the method written as a 32-bit integer.
- * 3. The descriptor of the method in UTF encoding.
- * 8. The SHA-1 algorithm is executed on the stream of bytes produced by
- * DataOutputStream and produces five 32-bit values sha[0..4].
- * 9. The hash value is assembled from the first and second 32-bit values of 
- * the SHA-1 message digest. If the result of the message digest, the five
- * 32-bit words H0 H1 H2 H3 H4, is in an array of five int values named 
- * sha, the hash value would be computed as follows:
- * long hash = ((sha[0] >>> 24) & 0xFF) |
- * ((sha[0] >>> 16) & 0xFF) << 8 |
- * ((sha[0] >>> 8) & 0xFF) << 16 |
- * ((sha[0] >>> 0) & 0xFF) << 24 |
- * ((sha[1] >>> 24) & 0xFF) << 32 |
- * ((sha[1] >>> 16) & 0xFF) << 40 |
- * ((sha[1] >>> 8) & 0xFF) << 48 |
- * ((sha[1] >>> 0) & 0xFF) << 56;
- * 
- * - * @author Rajendra Inamdar, Vishal Vishnoi - */ -public class SerialVersionUIDAdder extends ClassAdapter { - - /** - * Flag that indicates if we need to compute SVUID. - */ - protected boolean computeSVUID; - - /** - * Set to true if the class already has SVUID. - */ - protected boolean hasSVUID; - - /** - * Classes access flags. - */ - protected int access; - - /** - * Internal name of the class - */ - protected String name; - - /** - * Interfaces implemented by the class. - */ - protected String[] interfaces; - - /** - * Collection of fields. (except private static and private transient - * fields) - */ - protected Collection svuidFields; - - /** - * Set to true if the class has static initializer. - */ - protected boolean hasStaticInitializer; - - /** - * Collection of non-private constructors. - */ - protected Collection svuidConstructors; - - /** - * Collection of non-private methods. - */ - protected Collection svuidMethods; - - /** - * Creates a new {@link SerialVersionUIDAdder}. - * - * @param cv a {@link ClassVisitor} to which this visitor will delegate - * calls. - */ - public SerialVersionUIDAdder(final ClassVisitor cv) { - super(cv); - svuidFields = new ArrayList(); - svuidConstructors = new ArrayList(); - svuidMethods = new ArrayList(); - } - - // ------------------------------------------------------------------------ - // Overriden methods - // ------------------------------------------------------------------------ - - /* - * Visit class header and get class name, access , and intefraces - * informatoin (step 1,2, and 3) for SVUID computation. - */ - @Override - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - computeSVUID = (access & Opcodes.ACC_INTERFACE) == 0; - - if (computeSVUID) { - this.name = name; - this.access = access; - this.interfaces = interfaces; - } - - super.visit(version, access, name, signature, superName, interfaces); - } - - /* - * Visit the methods and get constructor and method information (step 5 and - * 7). Also determince if there is a class initializer (step 6). - */ - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, - final String[] exceptions) { - if (computeSVUID) { - if ("".equals(name)) { - hasStaticInitializer = true; - } - /* - * Remembers non private constructors and methods for SVUID - * computation For constructor and method modifiers, only the - * ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, - * ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT and ACC_STRICT flags - * are used. - */ - int mods = access - & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC - | Opcodes.ACC_FINAL | Opcodes.ACC_SYNCHRONIZED | Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_STRICT); - - // all non private methods - if ((access & Opcodes.ACC_PRIVATE) == 0) { - if ("".equals(name)) { - svuidConstructors.add(new Item(name, mods, desc)); - } else if (!"".equals(name)) { - svuidMethods.add(new Item(name, mods, desc)); - } - } - } - - return cv.visitMethod(access, name, desc, signature, exceptions); - } - - /* - * Gets class field information for step 4 of the alogrithm. Also determines - * if the class already has a SVUID. - */ - @Override - public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, - final Object value) { - if (computeSVUID) { - if ("serialVersionUID".equals(name)) { - // since the class already has SVUID, we won't be computing it. - computeSVUID = false; - hasSVUID = true; - } - /* - * Remember field for SVUID computation For field modifiers, only - * the ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, - * ACC_FINAL, ACC_VOLATILE, and ACC_TRANSIENT flags are used when - * computing serialVersionUID values. - */ - int mods = access - & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC - | Opcodes.ACC_FINAL | Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT); - - if ((access & Opcodes.ACC_PRIVATE) == 0 || (access & (Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)) == 0) { - svuidFields.add(new Item(name, mods, desc)); - } - } - - return super.visitField(access, name, desc, signature, value); - } - - /* - * Add the SVUID if class doesn't have one - */ - @Override - public void visitEnd() { - // compute SVUID and add it to the class - if (computeSVUID && !hasSVUID) { - try { - cv.visitField(Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, "serialVersionUID", "J", null, new Long( - computeSVUID())); - } catch (Throwable e) { - throw new RuntimeException("Error while computing SVUID for " + name, e); - } - } - - super.visitEnd(); - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - /** - * Returns the value of SVUID if the class doesn't have one already. Please - * note that 0 is returned if the class already has SVUID, thus use - * isHasSVUID to determine if the class already had an SVUID. - * - * @return Returns the serial version UID - */ - protected long computeSVUID() throws IOException { - ByteArrayOutputStream bos; - DataOutputStream dos = null; - long svuid = 0; - - try { - bos = new ByteArrayOutputStream(); - dos = new DataOutputStream(bos); - - /* - * 1. The class name written using UTF encoding. - */ - dos.writeUTF(name.replace('/', '.')); - - /* - * 2. The class modifiers written as a 32-bit integer. - */ - dos.writeInt(access - & (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT)); - - /* - * 3. The name of each interface sorted by name written using UTF - * encoding. - */ - Arrays.sort(interfaces); - for (String element : interfaces) { - dos.writeUTF(element.replace('/', '.')); - } - - /* - * 4. For each field of the class sorted by field name (except - * private static and private transient fields): 1. The name of the - * field in UTF encoding. 2. The modifiers of the field written as a - * 32-bit integer. 3. The descriptor of the field in UTF encoding - * Note that field signatutes are not dot separated. Method and - * constructor signatures are dot separated. Go figure... - */ - writeItems(svuidFields, dos, false); - - /* - * 5. If a class initializer exists, write out the following: 1. The - * name of the method, , in UTF encoding. 2. The modifier of - * the method, java.lang.reflect.Modifier.STATIC, written as a - * 32-bit integer. 3. The descriptor of the method, ()V, in UTF - * encoding. - */ - if (hasStaticInitializer) { - dos.writeUTF(""); - dos.writeInt(Opcodes.ACC_STATIC); - dos.writeUTF("()V"); - } // if.. - - /* - * 6. For each non-private constructor sorted by method name and - * signature: 1. The name of the method, , in UTF encoding. 2. - * The modifiers of the method written as a 32-bit integer. 3. The - * descriptor of the method in UTF encoding. - */ - writeItems(svuidConstructors, dos, true); - - /* - * 7. For each non-private method sorted by method name and - * signature: 1. The name of the method in UTF encoding. 2. The - * modifiers of the method written as a 32-bit integer. 3. The - * descriptor of the method in UTF encoding. - */ - writeItems(svuidMethods, dos, true); - - dos.flush(); - - /* - * 8. The SHA-1 algorithm is executed on the stream of bytes - * produced by DataOutputStream and produces five 32-bit values - * sha[0..4]. - */ - byte[] hashBytes = computeSHAdigest(bos.toByteArray()); - - /* - * 9. The hash value is assembled from the first and second 32-bit - * values of the SHA-1 message digest. If the result of the message - * digest, the five 32-bit words H0 H1 H2 H3 H4, is in an array of - * five int values named sha, the hash value would be computed as - * follows: long hash = ((sha[0] >>> 24) & 0xFF) | ((sha[0] >>> 16) - * & 0xFF) << 8 | ((sha[0] >>> 8) & 0xFF) << 16 | ((sha[0] >>> 0) & - * 0xFF) << 24 | ((sha[1] >>> 24) & 0xFF) << 32 | ((sha[1] >>> 16) & - * 0xFF) << 40 | ((sha[1] >>> 8) & 0xFF) << 48 | ((sha[1] >>> 0) & - * 0xFF) << 56; - */ - for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) { - svuid = svuid << 8 | hashBytes[i] & 0xFF; - } - } finally { - // close the stream (if open) - if (dos != null) { - dos.close(); - } - } - - return svuid; - } - - /** - * Returns the SHA-1 message digest of the given value. - * - * @param value the value whose SHA message digest must be computed. - * @return the SHA-1 message digest of the given value. - */ - protected byte[] computeSHAdigest(final byte[] value) { - try { - return MessageDigest.getInstance("SHA").digest(value); - } catch (Exception e) { - throw new UnsupportedOperationException(e.toString()); - } - } - - /** - * Sorts the items in the collection and writes it to the data output stream - * - * @param itemCollection collection of items - * @param dos a DataOutputStream value - * @param dotted a boolean value - * @exception IOException if an error occurs - */ - private static void writeItems(final Collection itemCollection, final DataOutput dos, final boolean dotted) - throws IOException { - int size = itemCollection.size(); - Item[] items = (Item[]) itemCollection.toArray(new Item[size]); - Arrays.sort(items); - for (int i = 0; i < size; i++) { - dos.writeUTF(items[i].name); - dos.writeInt(items[i].access); - dos.writeUTF(dotted ? items[i].desc.replace('/', '.') : items[i].desc); - } - } - - // ------------------------------------------------------------------------ - // Inner classes - // ------------------------------------------------------------------------ - - static class Item implements Comparable { - - final String name; - - final int access; - - final String desc; - - Item(final String name, final int access, final String desc) { - this.name = name; - this.access = access; - this.desc = desc; - } - - public int compareTo(final Object o) { - Item other = (Item) o; - int retVal = name.compareTo(other.name); - if (retVal == 0) { - retVal = desc.compareTo(other.desc); - } - return retVal; - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/SimpleRemapper.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/SimpleRemapper.java deleted file mode 100644 index 5c566221d..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/SimpleRemapper.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.alibaba.citrus.asm.commons; - -import java.util.Collections; -import java.util.Map; - -public class SimpleRemapper extends Remapper { - - private final Map mapping; - - public SimpleRemapper(Map mapping) { - this.mapping = mapping; - } - - public SimpleRemapper(String oldName, String newName) { - this.mapping = Collections.singletonMap(oldName, newName); - } - - @Override - public String mapMethodName(String owner, String name, String desc) { - String s = map(owner + '.' + name + desc); - return s == null ? name : s; - } - - @Override - public String mapFieldName(String owner, String name, String desc) { - String s = map(owner + '.' + name); - return s == null ? name : s; - } - - @Override - public String map(String key) { - return (String) mapping.get(key); - } - -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/StaticInitMerger.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/StaticInitMerger.java deleted file mode 100644 index b075ba495..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/StaticInitMerger.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import com.alibaba.citrus.asm.ClassAdapter; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * A {@link ClassAdapter} that merges clinit methods into a single one. - * - * @author Eric Bruneton - */ -public class StaticInitMerger extends ClassAdapter { - - private String name; - - private MethodVisitor clinit; - - private final String prefix; - - private int counter; - - public StaticInitMerger(final String prefix, final ClassVisitor cv) { - super(cv); - this.prefix = prefix; - } - - @Override - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - cv.visit(version, access, name, signature, superName, interfaces); - this.name = name; - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, - final String[] exceptions) { - MethodVisitor mv; - if ("".equals(name)) { - int a = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC; - String n = prefix + counter++; - mv = cv.visitMethod(a, n, desc, signature, exceptions); - - if (clinit == null) { - clinit = cv.visitMethod(a, name, desc, null, null); - } - clinit.visitMethodInsn(Opcodes.INVOKESTATIC, this.name, n, desc); - } else { - mv = cv.visitMethod(access, name, desc, signature, exceptions); - } - return mv; - } - - @Override - public void visitEnd() { - if (clinit != null) { - clinit.visitInsn(Opcodes.RETURN); - clinit.visitMaxs(0, 0); - } - cv.visitEnd(); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/TableSwitchGenerator.java b/common/asm/src/main/java/com/alibaba/citrus/asm/commons/TableSwitchGenerator.java deleted file mode 100644 index 59f6277e3..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/TableSwitchGenerator.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import com.alibaba.citrus.asm.Label; - -/** - * A code generator for switch statements. - * - * @author Juozas Baliuka - * @author Chris Nokleberg - * @author Eric Bruneton - */ -public interface TableSwitchGenerator { - - /** - * Generates the code for a switch case. - * - * @param key the switch case key. - * @param end a label that corresponds to the end of the switch statement. - */ - void generateCase(int key, Label end); - - /** - * Generates the code for the default switch case. - */ - void generateDefault(); -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/AnnotationConstantsCollector.java b/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/AnnotationConstantsCollector.java deleted file mode 100644 index 7a0513c72..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/AnnotationConstantsCollector.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.optimizer; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Type; - -/** - * An {@link AnnotationVisitor} that collects the {@link Constant}s of the - * annotations it visits. - * - * @author Eric Bruneton - */ -public class AnnotationConstantsCollector implements AnnotationVisitor { - - private final AnnotationVisitor av; - - private final ConstantPool cp; - - public AnnotationConstantsCollector(final AnnotationVisitor av, final ConstantPool cp) { - this.av = av; - this.cp = cp; - } - - public void visit(final String name, final Object value) { - if (name != null) { - cp.newUTF8(name); - } - if (value instanceof Byte) { - cp.newInteger(((Byte) value).byteValue()); - } else if (value instanceof Boolean) { - cp.newInteger(((Boolean) value).booleanValue() ? 1 : 0); - } else if (value instanceof Character) { - cp.newInteger(((Character) value).charValue()); - } else if (value instanceof Short) { - cp.newInteger(((Short) value).shortValue()); - } else if (value instanceof Type) { - cp.newUTF8(((Type) value).getDescriptor()); - } else if (value instanceof byte[]) { - byte[] v = (byte[]) value; - for (byte element : v) { - cp.newInteger(element); - } - } else if (value instanceof boolean[]) { - boolean[] v = (boolean[]) value; - for (boolean element : v) { - cp.newInteger(element ? 1 : 0); - } - } else if (value instanceof short[]) { - short[] v = (short[]) value; - for (short element : v) { - cp.newInteger(element); - } - } else if (value instanceof char[]) { - char[] v = (char[]) value; - for (char element : v) { - cp.newInteger(element); - } - } else if (value instanceof int[]) { - int[] v = (int[]) value; - for (int element : v) { - cp.newInteger(element); - } - } else if (value instanceof long[]) { - long[] v = (long[]) value; - for (long element : v) { - cp.newLong(element); - } - } else if (value instanceof float[]) { - float[] v = (float[]) value; - for (float element : v) { - cp.newFloat(element); - } - } else if (value instanceof double[]) { - double[] v = (double[]) value; - for (double element : v) { - cp.newDouble(element); - } - } else { - cp.newConst(value); - } - av.visit(name, value); - } - - public void visitEnum(final String name, final String desc, final String value) { - if (name != null) { - cp.newUTF8(name); - } - cp.newUTF8(desc); - cp.newUTF8(value); - av.visitEnum(name, desc, value); - } - - public AnnotationVisitor visitAnnotation(final String name, final String desc) { - if (name != null) { - cp.newUTF8(name); - } - cp.newUTF8(desc); - return new AnnotationConstantsCollector(av.visitAnnotation(name, desc), cp); - } - - public AnnotationVisitor visitArray(final String name) { - if (name != null) { - cp.newUTF8(name); - } - return new AnnotationConstantsCollector(av.visitArray(name), cp); - } - - public void visitEnd() { - av.visitEnd(); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/ClassConstantsCollector.java b/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/ClassConstantsCollector.java deleted file mode 100644 index 28b4aa9b4..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/ClassConstantsCollector.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.optimizer; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.ClassAdapter; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * A {@link ClassVisitor} that collects the {@link Constant}s of the classes it - * visits. - * - * @author Eric Bruneton - */ -public class ClassConstantsCollector extends ClassAdapter { - - private final ConstantPool cp; - - public ClassConstantsCollector(final ClassVisitor cv, final ConstantPool cp) { - super(cv); - this.cp = cp; - } - - @Override - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - cp.newUTF8("Deprecated"); - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0) { - cp.newUTF8("Synthetic"); - } - cp.newClass(name); - if (signature != null) { - cp.newUTF8("Signature"); - cp.newUTF8(signature); - } - if (superName != null) { - cp.newClass(superName); - } - if (interfaces != null) { - for (int i = 0; i < interfaces.length; ++i) { - cp.newClass(interfaces[i]); - } - } - cv.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public void visitSource(final String source, final String debug) { - if (source != null) { - cp.newUTF8("SourceFile"); - cp.newUTF8(source); - } - if (debug != null) { - cp.newUTF8("SourceDebugExtension"); - } - cv.visitSource(source, debug); - } - - @Override - public void visitOuterClass(final String owner, final String name, final String desc) { - cp.newUTF8("EnclosingMethod"); - cp.newClass(owner); - if (name != null && desc != null) { - cp.newNameType(name, desc); - } - cv.visitOuterClass(owner, name, desc); - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - cp.newUTF8(desc); - if (visible) { - cp.newUTF8("RuntimeVisibleAnnotations"); - } else { - cp.newUTF8("RuntimeInvisibleAnnotations"); - } - return new AnnotationConstantsCollector(cv.visitAnnotation(desc, visible), cp); - } - - @Override - public void visitAttribute(final Attribute attr) { - // can do nothing - cv.visitAttribute(attr); - } - - @Override - public void visitInnerClass(final String name, final String outerName, final String innerName, final int access) { - cp.newUTF8("InnerClasses"); - if (name != null) { - cp.newClass(name); - } - if (outerName != null) { - cp.newClass(outerName); - } - if (innerName != null) { - cp.newUTF8(innerName); - } - cv.visitInnerClass(name, outerName, innerName, access); - } - - @Override - public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, - final Object value) { - if ((access & Opcodes.ACC_SYNTHETIC) != 0) { - cp.newUTF8("Synthetic"); - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - cp.newUTF8("Deprecated"); - } - cp.newUTF8(name); - cp.newUTF8(desc); - if (signature != null) { - cp.newUTF8("Signature"); - cp.newUTF8(signature); - } - if (value != null) { - cp.newConst(value); - } - return new FieldConstantsCollector(cv.visitField(access, name, desc, signature, value), cp); - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, - final String[] exceptions) { - if ((access & Opcodes.ACC_SYNTHETIC) != 0) { - cp.newUTF8("Synthetic"); - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - cp.newUTF8("Deprecated"); - } - cp.newUTF8(name); - cp.newUTF8(desc); - if (signature != null) { - cp.newUTF8("Signature"); - cp.newUTF8(signature); - } - if (exceptions != null) { - cp.newUTF8("Exceptions"); - for (int i = 0; i < exceptions.length; ++i) { - cp.newClass(exceptions[i]); - } - } - return new MethodConstantsCollector(cv.visitMethod(access, name, desc, signature, exceptions), cp); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/ClassOptimizer.java b/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/ClassOptimizer.java deleted file mode 100644 index 1292daaed..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/ClassOptimizer.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.optimizer; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.ClassAdapter; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.commons.Remapper; -import com.alibaba.citrus.asm.commons.RemappingClassAdapter; - -/** - * A {@link ClassAdapter} that renames fields and methods, and removes debug - * info. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public class ClassOptimizer extends RemappingClassAdapter { - - private String pkgName; - - public ClassOptimizer(final ClassVisitor cv, final Remapper remapper) { - super(cv, remapper); - } - - // ------------------------------------------------------------------------ - // Overridden methods - // ------------------------------------------------------------------------ - - @Override - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - super.visit(version, access, name, null, superName, interfaces); - pkgName = name.substring(0, name.lastIndexOf('/')); - } - - @Override - public void visitSource(final String source, final String debug) { - // remove debug info - } - - @Override - public void visitOuterClass(final String owner, final String name, final String desc) { - // remove debug info - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - // remove annotations - return null; - } - - @Override - public void visitAttribute(final Attribute attr) { - // remove non standard attributes - } - - @Override - public void visitInnerClass(final String name, final String outerName, final String innerName, final int access) { - // remove debug info - } - - @Override - public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, - final Object value) { - String s = remapper.mapFieldName(className, name, desc); - if ("-".equals(s)) { - return null; - } - if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0) { - if ((access & Opcodes.ACC_FINAL) != 0 && (access & Opcodes.ACC_STATIC) != 0 && desc.length() == 1) { - return null; - } - if ("com/alibaba/citrus/asm".equals(pkgName) && s.equals(name)) { - System.out.println("INFO: " + s + " could be renamed"); - } - super.visitField(access, name, desc, null, value); - } else { - if (!s.equals(name)) { - throw new RuntimeException("The public or protected field " + className + '.' + name - + " must not be renamed."); - } - super.visitField(access, name, desc, null, value); - } - return null; // remove debug info - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, - final String[] exceptions) { - String s = remapper.mapMethodName(className, name, desc); - if ("-".equals(s)) { - return null; - } - if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0) { - if ("com/alibaba/citrus/asm".equals(pkgName) && !name.startsWith("<") && s.equals(name)) { - System.out.println("INFO: " + s + " could be renamed"); - } - return super.visitMethod(access, name, desc, null, exceptions); - } else { - if (!s.equals(name)) { - throw new RuntimeException("The public or protected method " + className + '.' + name + desc - + " must not be renamed."); - } - return super.visitMethod(access, name, desc, null, exceptions); - } - } - - @Override - protected MethodVisitor createRemappingMethodAdapter(int access, String newDesc, MethodVisitor mv) { - return new MethodOptimizer(access, newDesc, mv, remapper); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/Constant.java b/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/Constant.java deleted file mode 100644 index a76296abc..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/Constant.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.optimizer; - -import com.alibaba.citrus.asm.ClassWriter; - -/** - * A constant pool item. - * - * @author Eric Bruneton - */ -class Constant { - - /** - * Type of this constant pool item. A single class is used to represent all - * constant pool item types, in order to minimize the bytecode size of this - * package. The value of this field is I, J, F, D, S, s, C, T, G, M, or N - * (for Constant Integer, Long, Float, Double, STR, UTF8, Class, NameType, - * Fieldref, Methodref, or InterfaceMethodref constant pool items - * respectively). - */ - char type; - - /** - * Value of this item, for an integer item. - */ - int intVal; - - /** - * Value of this item, for a long item. - */ - long longVal; - - /** - * Value of this item, for a float item. - */ - float floatVal; - - /** - * Value of this item, for a double item. - */ - double doubleVal; - - /** - * First part of the value of this item, for items that do not hold a - * primitive value. - */ - String strVal1; - - /** - * Second part of the value of this item, for items that do not hold a - * primitive value. - */ - String strVal2; - - /** - * Third part of the value of this item, for items that do not hold a - * primitive value. - */ - String strVal3; - - /** - * The hash code value of this constant pool item. - */ - int hashCode; - - Constant() { - } - - Constant(final Constant i) { - type = i.type; - intVal = i.intVal; - longVal = i.longVal; - floatVal = i.floatVal; - doubleVal = i.doubleVal; - strVal1 = i.strVal1; - strVal2 = i.strVal2; - strVal3 = i.strVal3; - hashCode = i.hashCode; - } - - /** - * Sets this item to an integer item. - * - * @param intVal the value of this item. - */ - void set(final int intVal) { - this.type = 'I'; - this.intVal = intVal; - this.hashCode = 0x7FFFFFFF & type + intVal; - } - - /** - * Sets this item to a long item. - * - * @param longVal the value of this item. - */ - void set(final long longVal) { - this.type = 'J'; - this.longVal = longVal; - this.hashCode = 0x7FFFFFFF & type + (int) longVal; - } - - /** - * Sets this item to a float item. - * - * @param floatVal the value of this item. - */ - void set(final float floatVal) { - this.type = 'F'; - this.floatVal = floatVal; - this.hashCode = 0x7FFFFFFF & type + (int) floatVal; - } - - /** - * Sets this item to a double item. - * - * @param doubleVal the value of this item. - */ - void set(final double doubleVal) { - this.type = 'D'; - this.doubleVal = doubleVal; - this.hashCode = 0x7FFFFFFF & type + (int) doubleVal; - } - - /** - * Sets this item to an item that do not hold a primitive value. - * - * @param type the type of this item. - * @param strVal1 first part of the value of this item. - * @param strVal2 second part of the value of this item. - * @param strVal3 third part of the value of this item. - */ - void set(final char type, final String strVal1, final String strVal2, final String strVal3) { - this.type = type; - this.strVal1 = strVal1; - this.strVal2 = strVal2; - this.strVal3 = strVal3; - switch (type) { - case 's': - case 'S': - case 'C': - hashCode = 0x7FFFFFFF & type + strVal1.hashCode(); - return; - case 'T': - hashCode = 0x7FFFFFFF & type + strVal1.hashCode() * strVal2.hashCode(); - return; - // case 'G': - // case 'M': - // case 'N': - default: - hashCode = 0x7FFFFFFF & type + strVal1.hashCode() * strVal2.hashCode() * strVal3.hashCode(); - } - } - - void write(final ClassWriter cw) { - switch (type) { - case 'I': - cw.newConst(new Integer(intVal)); - break; - case 'J': - cw.newConst(new Long(longVal)); - break; - case 'F': - cw.newConst(new Float(floatVal)); - break; - case 'D': - cw.newConst(new Double(doubleVal)); - break; - case 'S': - cw.newConst(strVal1); - break; - case 's': - cw.newUTF8(strVal1); - break; - case 'C': - cw.newClass(strVal1); - break; - case 'T': - cw.newNameType(strVal1, strVal2); - break; - case 'G': - cw.newField(strVal1, strVal2, strVal3); - break; - case 'M': - cw.newMethod(strVal1, strVal2, strVal3, false); - break; - case 'N': - cw.newMethod(strVal1, strVal2, strVal3, true); - break; - } - } - - @Override - public boolean equals(final Object o) { - if (!(o instanceof Constant)) { - return false; - } - Constant c = (Constant) o; - if (c.type == type) { - switch (type) { - case 'I': - return c.intVal == intVal; - case 'J': - return c.longVal == longVal; - case 'F': - return Float.compare(c.floatVal, floatVal) == 0; - case 'D': - return Double.compare(c.doubleVal, doubleVal) == 0; - case 's': - case 'S': - case 'C': - return c.strVal1.equals(strVal1); - case 'T': - return c.strVal1.equals(strVal1) && c.strVal2.equals(strVal2); - // case 'G': - // case 'M': - // case 'N': - default: - return c.strVal1.equals(strVal1) && c.strVal2.equals(strVal2) && c.strVal3.equals(strVal3); - } - } - return false; - } - - @Override - public int hashCode() { - return hashCode; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/ConstantPool.java b/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/ConstantPool.java deleted file mode 100644 index 0e8dd4283..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/ConstantPool.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.optimizer; - -import java.util.HashMap; - -import com.alibaba.citrus.asm.Type; - -/** - * A constant pool. - * - * @author Eric Bruneton - */ -public class ConstantPool extends HashMap { - - private static final long serialVersionUID = 8116336539141134351L; - - private final Constant key1 = new Constant(); - - private final Constant key2 = new Constant(); - - private final Constant key3 = new Constant(); - - public Constant newInteger(final int value) { - key1.set(value); - Constant result = get(key1); - if (result == null) { - result = new Constant(key1); - put(result); - } - return result; - } - - public Constant newFloat(final float value) { - key1.set(value); - Constant result = get(key1); - if (result == null) { - result = new Constant(key1); - put(result); - } - return result; - } - - public Constant newLong(final long value) { - key1.set(value); - Constant result = get(key1); - if (result == null) { - result = new Constant(key1); - put(result); - } - return result; - } - - public Constant newDouble(final double value) { - key1.set(value); - Constant result = get(key1); - if (result == null) { - result = new Constant(key1); - put(result); - } - return result; - } - - public Constant newUTF8(final String value) { - key1.set('s', value, null, null); - Constant result = get(key1); - if (result == null) { - result = new Constant(key1); - put(result); - } - return result; - } - - private Constant newString(final String value) { - key2.set('S', value, null, null); - Constant result = get(key2); - if (result == null) { - newUTF8(value); - result = new Constant(key2); - put(result); - } - return result; - } - - public Constant newClass(final String value) { - key2.set('C', value, null, null); - Constant result = get(key2); - if (result == null) { - newUTF8(value); - result = new Constant(key2); - put(result); - } - return result; - } - - public Constant newConst(final Object cst) { - if (cst instanceof Integer) { - int val = ((Integer) cst).intValue(); - return newInteger(val); - } else if (cst instanceof Float) { - float val = ((Float) cst).floatValue(); - return newFloat(val); - } else if (cst instanceof Long) { - long val = ((Long) cst).longValue(); - return newLong(val); - } else if (cst instanceof Double) { - double val = ((Double) cst).doubleValue(); - return newDouble(val); - } else if (cst instanceof String) { - return newString((String) cst); - } else if (cst instanceof Type) { - Type t = (Type) cst; - return newClass(t.getSort() == Type.OBJECT ? t.getInternalName() : t.getDescriptor()); - } else { - throw new IllegalArgumentException("value " + cst); - } - } - - public Constant newField(final String owner, final String name, final String desc) { - key3.set('G', owner, name, desc); - Constant result = get(key3); - if (result == null) { - newClass(owner); - newNameType(name, desc); - result = new Constant(key3); - put(result); - } - return result; - } - - public Constant newMethod(final String owner, final String name, final String desc, final boolean itf) { - key3.set(itf ? 'N' : 'M', owner, name, desc); - Constant result = get(key3); - if (result == null) { - newClass(owner); - newNameType(name, desc); - result = new Constant(key3); - put(result); - } - return result; - } - - public Constant newNameType(final String name, final String desc) { - key2.set('T', name, desc, null); - Constant result = get(key2); - if (result == null) { - newUTF8(name); - newUTF8(desc); - result = new Constant(key2); - put(result); - } - return result; - } - - private Constant get(final Constant key) { - return (Constant) get((Object) key); - } - - private void put(final Constant cst) { - put(cst, cst); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/FieldConstantsCollector.java b/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/FieldConstantsCollector.java deleted file mode 100644 index c0a18ace2..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/FieldConstantsCollector.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.optimizer; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.FieldVisitor; - -/** - * A {@link FieldVisitor} that collects the {@link Constant}s of the fields it - * visits. - * - * @author Eric Bruneton - */ -public class FieldConstantsCollector implements FieldVisitor { - - private final FieldVisitor fv; - - private final ConstantPool cp; - - public FieldConstantsCollector(final FieldVisitor fv, final ConstantPool cp) { - this.fv = fv; - this.cp = cp; - } - - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - cp.newUTF8(desc); - if (visible) { - cp.newUTF8("RuntimeVisibleAnnotations"); - } else { - cp.newUTF8("RuntimeInvisibleAnnotations"); - } - return new AnnotationConstantsCollector(fv.visitAnnotation(desc, visible), cp); - } - - public void visitAttribute(final Attribute attr) { - // can do nothing - fv.visitAttribute(attr); - } - - public void visitEnd() { - fv.visitEnd(); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/JarOptimizer.java b/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/JarOptimizer.java deleted file mode 100644 index 191fae857..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/JarOptimizer.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.optimizer; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.LineNumberReader; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.zip.GZIPInputStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import java.util.zip.ZipOutputStream; - -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.commons.EmptyVisitor; - -/** - * A Jar file optimizer. - * - * @author Eric Bruneton - */ -public class JarOptimizer { - - private static final Set API = new HashSet(); - private static final Map HIERARCHY = new HashMap(); - - public static void main(final String[] args) throws IOException { - File f = new File(args[0]); - InputStream is = new GZIPInputStream(new FileInputStream(f)); - BufferedReader lnr = new LineNumberReader(new InputStreamReader(is)); - while (true) { - String line = lnr.readLine(); - if (line != null) { - if (line.startsWith("class")) { - String c = line.substring(6, line.lastIndexOf(' ')); - String sc = line.substring(line.lastIndexOf(' ') + 1); - HIERARCHY.put(c, sc); - } else { - API.add(line); - } - } else { - break; - } - } - optimize(new File(args[1])); - } - - static void optimize(final File f) throws IOException { - if (f.isDirectory()) { - File[] files = f.listFiles(); - for (int i = 0; i < files.length; ++i) { - optimize(files[i]); - } - } else if (f.getName().endsWith(".jar")) { - File g = new File(f.getParentFile(), f.getName() + ".new"); - ZipFile zf = new ZipFile(f); - ZipOutputStream out = new ZipOutputStream(new FileOutputStream(g)); - Enumeration e = zf.entries(); - byte[] buf = new byte[10000]; - while (e.hasMoreElements()) { - ZipEntry ze = (ZipEntry) e.nextElement(); - if (ze.isDirectory()) { - continue; - } - out.putNextEntry(ze); - if (ze.getName().endsWith(".class")) { - ClassReader cr = new ClassReader(zf.getInputStream(ze)); - // cr.accept(new ClassDump(), 0); - cr.accept(new ClassVerifier(), 0); - } - InputStream is = zf.getInputStream(ze); - int n; - do { - n = is.read(buf, 0, buf.length); - if (n != -1) { - out.write(buf, 0, n); - } - } while (n != -1); - out.closeEntry(); - } - out.close(); - zf.close(); - f.delete(); - g.renameTo(f); - } - } - - static class ClassDump extends EmptyVisitor { - - String owner; - - @Override - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - owner = name; - if (owner.startsWith("java/")) { - System.out.println("class " + name + ' ' + superName); - } - } - - @Override - public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, - final Object value) { - if (owner.startsWith("java/")) { - System.out.println(owner + ' ' + name); - } - return null; - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - if (owner.startsWith("java/")) { - System.out.println(owner + ' ' + name + desc); - } - return null; - } - } - - static class ClassVerifier extends EmptyVisitor { - - String owner; - String method; - - @Override - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - owner = name; - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - method = name + desc; - return this; - } - - @Override - public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { - check(owner, name); - } - - @Override - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - check(owner, name + desc); - } - - private void check(String owner, String member) { - if (owner.startsWith("java/")) { - String o = owner; - while (o != null) { - if (API.contains(o + ' ' + member)) { - return; - } - o = (String) HIERARCHY.get(o); - } - System.out.println("WARNING: " + owner + ' ' + member + " called in " + this.owner + ' ' + method - + " is not defined in JDK 1.3 API"); - } - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/MethodConstantsCollector.java b/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/MethodConstantsCollector.java deleted file mode 100644 index 11e864578..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/MethodConstantsCollector.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.optimizer; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodAdapter; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * An {@link MethodVisitor} that collects the {@link Constant}s of the methods - * it visits. - * - * @author Eric Bruneton - */ -public class MethodConstantsCollector extends MethodAdapter { - - private final ConstantPool cp; - - public MethodConstantsCollector(final MethodVisitor mv, final ConstantPool cp) { - super(mv); - this.cp = cp; - } - - @Override - public AnnotationVisitor visitAnnotationDefault() { - cp.newUTF8("AnnotationDefault"); - return new AnnotationConstantsCollector(mv.visitAnnotationDefault(), cp); - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - cp.newUTF8(desc); - if (visible) { - cp.newUTF8("RuntimeVisibleAnnotations"); - } else { - cp.newUTF8("RuntimeInvisibleAnnotations"); - } - return new AnnotationConstantsCollector(mv.visitAnnotation(desc, visible), cp); - } - - @Override - public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc, final boolean visible) { - cp.newUTF8(desc); - if (visible) { - cp.newUTF8("RuntimeVisibleParameterAnnotations"); - } else { - cp.newUTF8("RuntimeInvisibleParameterAnnotations"); - } - return new AnnotationConstantsCollector(mv.visitParameterAnnotation(parameter, desc, visible), cp); - } - - @Override - public void visitTypeInsn(final int opcode, final String type) { - cp.newClass(type); - mv.visitTypeInsn(opcode, type); - } - - @Override - public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { - cp.newField(owner, name, desc); - mv.visitFieldInsn(opcode, owner, name, desc); - } - - @Override - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - boolean itf = opcode == Opcodes.INVOKEINTERFACE; - cp.newMethod(owner, name, desc, itf); - mv.visitMethodInsn(opcode, owner, name, desc); - } - - @Override - public void visitLdcInsn(final Object cst) { - cp.newConst(cst); - mv.visitLdcInsn(cst); - } - - @Override - public void visitMultiANewArrayInsn(final String desc, final int dims) { - cp.newClass(desc); - mv.visitMultiANewArrayInsn(desc, dims); - } - - @Override - public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type) { - if (type != null) { - cp.newClass(type); - } - mv.visitTryCatchBlock(start, end, handler, type); - } - - @Override - public void visitLocalVariable(final String name, final String desc, final String signature, final Label start, - final Label end, final int index) { - if (signature != null) { - cp.newUTF8("LocalVariableTypeTable"); - cp.newUTF8(name); - cp.newUTF8(signature); - } - cp.newUTF8("LocalVariableTable"); - cp.newUTF8(name); - cp.newUTF8(desc); - mv.visitLocalVariable(name, desc, signature, start, end, index); - } - - @Override - public void visitLineNumber(final int line, final Label start) { - cp.newUTF8("LineNumberTable"); - mv.visitLineNumber(line, start); - } - - @Override - public void visitMaxs(final int maxStack, final int maxLocals) { - cp.newUTF8("Code"); - mv.visitMaxs(maxStack, maxLocals); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/MethodOptimizer.java b/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/MethodOptimizer.java deleted file mode 100644 index be820b080..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/MethodOptimizer.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.optimizer; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodAdapter; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.commons.Remapper; -import com.alibaba.citrus.asm.commons.RemappingMethodAdapter; - -/** - * A {@link MethodAdapter} that renames fields and methods, and removes debug - * info. - * - * @author Eugene Kuleshov - */ -public class MethodOptimizer extends RemappingMethodAdapter { - - public MethodOptimizer(int access, String desc, MethodVisitor mv, Remapper remapper) { - super(access, desc, mv, remapper); - } - - // ------------------------------------------------------------------------ - // Overridden methods - // ------------------------------------------------------------------------ - - @Override - public AnnotationVisitor visitAnnotationDefault() { - // remove annotations - return null; - } - - @Override - public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc, final boolean visible) { - // remove annotations - return null; - } - - @Override - public void visitLocalVariable(final String name, final String desc, final String signature, final Label start, - final Label end, final int index) { - // remove debug info - } - - @Override - public void visitLineNumber(final int line, final Label start) { - // remove debug info - } - - @Override - public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) { - // remove frame info - } - - @Override - public void visitAttribute(Attribute attr) { - // remove non standard attributes - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/NameMapping.java b/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/NameMapping.java deleted file mode 100644 index 958661f75..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/NameMapping.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.optimizer; - -import java.io.FileInputStream; -import java.io.IOException; -import java.util.HashSet; -import java.util.Properties; -import java.util.Set; - -import com.alibaba.citrus.asm.Type; - -/** - * A MAPPING from names to names, used to rename classes, fields and methods. - * - * @author Eric Bruneton - */ -public class NameMapping extends Properties { - - private static final long serialVersionUID = 6781182560182954276L; - public final Set unused; - - public NameMapping(final String file) throws IOException { - load(new FileInputStream(file)); - unused = new HashSet(keySet()); - } - - public String map(final String name) { - String s = (String) get(name); - if (s == null) { - int p = name.indexOf('.'); - if (p == -1) { - s = name; - } else { - int q = name.indexOf('('); - if (q == -1) { - s = name.substring(p + 1); - } else { - s = name.substring(p + 1, q); - } - } - } else { - unused.remove(name); - } - return s; - } - - public String fix(final String desc) { - if (desc.startsWith("(")) { - Type[] arguments = Type.getArgumentTypes(desc); - Type result = Type.getReturnType(desc); - for (int i = 0; i < arguments.length; ++i) { - arguments[i] = fix(arguments[i]); - } - result = fix(result); - return Type.getMethodDescriptor(result, arguments); - } else { - return fix(Type.getType(desc)).getDescriptor(); - } - } - - private Type fix(final Type t) { - if (t.getSort() == Type.OBJECT) { - return Type.getObjectType(map(t.getInternalName())); - } else if (t.getSort() == Type.ARRAY) { - String s = fix(t.getElementType()).getDescriptor(); - for (int i = 0; i < t.getDimensions(); ++i) { - s = '[' + s; - } - return Type.getType(s); - } else { - return t; - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/Shrinker.java b/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/Shrinker.java deleted file mode 100644 index aed7c088e..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/optimizer/Shrinker.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.optimizer; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Properties; -import java.util.Set; -import java.util.TreeSet; - -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.commons.Remapper; -import com.alibaba.citrus.asm.commons.SimpleRemapper; - -/** - * A class file shrinker utility. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public class Shrinker { - - static final Properties MAPPING = new Properties(); - - public static void main(final String[] args) throws IOException { - int n = args.length - 1; - for (int i = 0; i < n - 1; ++i) { - MAPPING.load(new FileInputStream(args[i])); - } - final Set unused = new HashSet(MAPPING.keySet()); - - File f = new File(args[n - 1]); - File d = new File(args[n]); - - optimize(f, d, new SimpleRemapper(MAPPING) { - @Override - public String map(String key) { - String s = super.map(key); - if (s != null) { - unused.remove(key); - } - return s; - } - }); - - Iterator i = unused.iterator(); - while (i.hasNext()) { - String s = (String) i.next(); - if (!s.endsWith("/remove")) { - System.out.println("INFO: unused mapping " + s); - } - } - } - - static void optimize(final File f, final File d, final Remapper remapper) throws IOException { - if (f.isDirectory()) { - File[] files = f.listFiles(); - for (int i = 0; i < files.length; ++i) { - optimize(files[i], d, remapper); - } - } else if (f.getName().endsWith(".class")) { - ConstantPool cp = new ConstantPool(); - ClassReader cr = new ClassReader(new FileInputStream(f)); - ClassWriter cw = new ClassWriter(0); - ClassConstantsCollector ccc = new ClassConstantsCollector(cw, cp); - ClassOptimizer co = new ClassOptimizer(ccc, remapper); - cr.accept(co, ClassReader.SKIP_DEBUG); - - Set constants = new TreeSet(new ConstantComparator()); - constants.addAll(cp.values()); - - cr = new ClassReader(cw.toByteArray()); - cw = new ClassWriter(0); - Iterator i = constants.iterator(); - while (i.hasNext()) { - Constant c = (Constant) i.next(); - c.write(cw); - } - cr.accept(cw, ClassReader.SKIP_DEBUG); - - if (MAPPING.getProperty(cr.getClassName() + "/remove") != null) { - return; - } - String n = remapper.mapType(cr.getClassName()); - File g = new File(d, n + ".class"); - if (!g.exists() || g.lastModified() < f.lastModified()) { - g.getParentFile().mkdirs(); - OutputStream os = new FileOutputStream(g); - os.write(cw.toByteArray()); - os.close(); - } - } - } - - static class ConstantComparator implements Comparator { - - public int compare(final Object o1, final Object o2) { - Constant c1 = (Constant) o1; - Constant c2 = (Constant) o2; - int d = getSort(c1) - getSort(c2); - if (d == 0) { - switch (c1.type) { - case 'I': - return new Integer(c1.intVal).compareTo(new Integer(c2.intVal)); - case 'J': - return new Long(c1.longVal).compareTo(new Long(c2.longVal)); - case 'F': - return new Float(c1.floatVal).compareTo(new Float(c2.floatVal)); - case 'D': - return new Double(c1.doubleVal).compareTo(new Double(c2.doubleVal)); - case 's': - case 'S': - case 'C': - return c1.strVal1.compareTo(c2.strVal1); - case 'T': - d = c1.strVal1.compareTo(c2.strVal1); - if (d == 0) { - d = c1.strVal2.compareTo(c2.strVal2); - } - break; - default: - d = c1.strVal1.compareTo(c2.strVal1); - if (d == 0) { - d = c1.strVal2.compareTo(c2.strVal2); - if (d == 0) { - d = c1.strVal3.compareTo(c2.strVal3); - } - } - } - } - return d; - } - - private static int getSort(final Constant c) { - switch (c.type) { - case 'I': - return 0; - case 'J': - return 1; - case 'F': - return 2; - case 'D': - return 3; - case 's': - return 4; - case 'S': - return 5; - case 'C': - return 6; - case 'T': - return 7; - case 'G': - return 8; - case 'M': - return 9; - default: - return 10; - } - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/signature/SignatureReader.java b/common/asm/src/main/java/com/alibaba/citrus/asm/signature/SignatureReader.java deleted file mode 100644 index 1de3dd1dd..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/signature/SignatureReader.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.signature; - -/** - * A type signature parser to make a signature visitor visit an existing - * signature. - * - * @author Thomas Hallgren - * @author Eric Bruneton - */ -public class SignatureReader { - - /** - * The signature to be read. - */ - private final String signature; - - /** - * Constructs a {@link SignatureReader} for the given signature. - * - * @param signature A ClassSignature, MethodTypeSignature, or - * FieldTypeSignature. - */ - public SignatureReader(final String signature) { - this.signature = signature; - } - - /** - * Makes the given visitor visit the signature of this - * {@link SignatureReader}. This signature is the one specified in the - * constructor (see {@link #SignatureReader(String) SignatureReader}). This - * method is intended to be called on a {@link SignatureReader} that was - * created using a ClassSignature (such as the signature - * parameter of the {@link com.alibaba.citrus.asm.ClassVisitor#visit - * ClassVisitor.visit} method) or a MethodTypeSignature (such as the - * signature parameter of the - * {@link com.alibaba.citrus.asm.ClassVisitor#visitMethod - * ClassVisitor.visitMethod} method). - * - * @param v the visitor that must visit this signature. - */ - public void accept(final SignatureVisitor v) { - String signature = this.signature; - int len = signature.length(); - int pos; - char c; - - if (signature.charAt(0) == '<') { - pos = 2; - do { - int end = signature.indexOf(':', pos); - v.visitFormalTypeParameter(signature.substring(pos - 1, end)); - pos = end + 1; - - c = signature.charAt(pos); - if (c == 'L' || c == '[' || c == 'T') { - pos = parseType(signature, pos, v.visitClassBound()); - } - - while ((c = signature.charAt(pos++)) == ':') { - pos = parseType(signature, pos, v.visitInterfaceBound()); - } - } while (c != '>'); - } else { - pos = 0; - } - - if (signature.charAt(pos) == '(') { - pos++; - while (signature.charAt(pos) != ')') { - pos = parseType(signature, pos, v.visitParameterType()); - } - pos = parseType(signature, pos + 1, v.visitReturnType()); - while (pos < len) { - pos = parseType(signature, pos + 1, v.visitExceptionType()); - } - } else { - pos = parseType(signature, pos, v.visitSuperclass()); - while (pos < len) { - pos = parseType(signature, pos, v.visitInterface()); - } - } - } - - /** - * Makes the given visitor visit the signature of this - * {@link SignatureReader}. This signature is the one specified in the - * constructor (see {@link #SignatureReader(String) SignatureReader}). This - * method is intended to be called on a {@link SignatureReader} that was - * created using a FieldTypeSignature, such as the - * signature parameter of the - * {@link com.alibaba.citrus.asm.ClassVisitor#visitField - * ClassVisitor.visitField} or - * {@link com.alibaba.citrus.asm.MethodVisitor#visitLocalVariable - * MethodVisitor.visitLocalVariable} methods. - * - * @param v the visitor that must visit this signature. - */ - public void acceptType(final SignatureVisitor v) { - parseType(this.signature, 0, v); - } - - /** - * Parses a field type signature and makes the given visitor visit it. - * - * @param signature a string containing the signature that must be parsed. - * @param pos index of the first character of the signature to parsed. - * @param v the visitor that must visit this signature. - * @return the index of the first character after the parsed signature. - */ - private static int parseType(final String signature, int pos, final SignatureVisitor v) { - char c; - int start, end; - boolean visited, inner; - String name; - - switch (c = signature.charAt(pos++)) { - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - case 'F': - case 'J': - case 'D': - case 'V': - v.visitBaseType(c); - return pos; - - case '[': - return parseType(signature, pos, v.visitArrayType()); - - case 'T': - end = signature.indexOf(';', pos); - v.visitTypeVariable(signature.substring(pos, end)); - return end + 1; - - default: // case 'L': - start = pos; - visited = false; - inner = false; - for (;;) { - switch (c = signature.charAt(pos++)) { - case '.': - case ';': - if (!visited) { - name = signature.substring(start, pos - 1); - if (inner) { - v.visitInnerClassType(name); - } else { - v.visitClassType(name); - } - } - if (c == ';') { - v.visitEnd(); - return pos; - } - start = pos; - visited = false; - inner = true; - break; - - case '<': - name = signature.substring(start, pos - 1); - if (inner) { - v.visitInnerClassType(name); - } else { - v.visitClassType(name); - } - visited = true; - top: for (;;) { - switch (c = signature.charAt(pos)) { - case '>': - break top; - case '*': - ++pos; - v.visitTypeArgument(); - break; - case '+': - case '-': - pos = parseType(signature, pos + 1, v.visitTypeArgument(c)); - break; - default: - pos = parseType(signature, pos, v.visitTypeArgument('=')); - break; - } - } - } - } - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/signature/SignatureVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/signature/SignatureVisitor.java deleted file mode 100644 index 8dea231b1..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/signature/SignatureVisitor.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.signature; - -/** - * A visitor to visit a generic signature. The methods of this interface must be - * called in one of the three following orders (the last one is the only valid - * order for a {@link SignatureVisitor} that is returned by a method of this - * interface): - *
    - *
  • ClassSignature = ( visitFormalTypeParameter - * visitClassBound? visitInterfaceBound* )* ( - * visitSuperClass visitInterface* )
  • - *
  • MethodSignature = ( visitFormalTypeParameter - * visitClassBound? visitInterfaceBound* )* ( - * visitParameterType* visitReturnType - * visitExceptionType* )
  • - *
  • TypeSignature = visitBaseType | - * visitTypeVariable | visitArrayType | ( - * visitClassType visitTypeArgument* ( - * visitInnerClassType visitTypeArgument* )* visitEnd - * ) )
  • - *
- * - * @author Thomas Hallgren - * @author Eric Bruneton - */ -public interface SignatureVisitor { - - /** - * Wildcard for an "extends" type argument. - */ - char EXTENDS = '+'; - - /** - * Wildcard for a "super" type argument. - */ - char SUPER = '-'; - - /** - * Wildcard for a normal type argument. - */ - char INSTANCEOF = '='; - - /** - * Visits a formal type parameter. - * - * @param name the name of the formal parameter. - */ - void visitFormalTypeParameter(String name); - - /** - * Visits the class bound of the last visited formal type parameter. - * - * @return a non null visitor to visit the signature of the class bound. - */ - SignatureVisitor visitClassBound(); - - /** - * Visits an interface bound of the last visited formal type parameter. - * - * @return a non null visitor to visit the signature of the interface bound. - */ - SignatureVisitor visitInterfaceBound(); - - /** - * Visits the type of the super class. - * - * @return a non null visitor to visit the signature of the super class - * type. - */ - SignatureVisitor visitSuperclass(); - - /** - * Visits the type of an interface implemented by the class. - * - * @return a non null visitor to visit the signature of the interface type. - */ - SignatureVisitor visitInterface(); - - /** - * Visits the type of a method parameter. - * - * @return a non null visitor to visit the signature of the parameter type. - */ - SignatureVisitor visitParameterType(); - - /** - * Visits the return type of the method. - * - * @return a non null visitor to visit the signature of the return type. - */ - SignatureVisitor visitReturnType(); - - /** - * Visits the type of a method exception. - * - * @return a non null visitor to visit the signature of the exception type. - */ - SignatureVisitor visitExceptionType(); - - /** - * Visits a signature corresponding to a primitive type. - * - * @param descriptor the descriptor of the primitive type, or 'V' for - * void. - */ - void visitBaseType(char descriptor); - - /** - * Visits a signature corresponding to a type variable. - * - * @param name the name of the type variable. - */ - void visitTypeVariable(String name); - - /** - * Visits a signature corresponding to an array type. - * - * @return a non null visitor to visit the signature of the array element - * type. - */ - SignatureVisitor visitArrayType(); - - /** - * Starts the visit of a signature corresponding to a class or interface - * type. - * - * @param name the internal name of the class or interface. - */ - void visitClassType(String name); - - /** - * Visits an inner class. - * - * @param name the local name of the inner class in its enclosing class. - */ - void visitInnerClassType(String name); - - /** - * Visits an unbounded type argument of the last visited class or inner - * class type. - */ - void visitTypeArgument(); - - /** - * Visits a type argument of the last visited class or inner class type. - * - * @param wildcard '+', '-' or '='. - * @return a non null visitor to visit the signature of the type argument. - */ - SignatureVisitor visitTypeArgument(char wildcard); - - /** - * Ends the visit of a signature corresponding to a class or interface type. - */ - void visitEnd(); -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/signature/SignatureWriter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/signature/SignatureWriter.java deleted file mode 100644 index 89fa1131d..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/signature/SignatureWriter.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.signature; - -/** - * A signature visitor that generates signatures in string format. - * - * @author Thomas Hallgren - * @author Eric Bruneton - */ -public class SignatureWriter implements SignatureVisitor { - - /** - * Buffer used to construct the signature. - */ - private final StringBuilder buf = new StringBuilder(); - - /** - * Indicates if the signature contains formal type parameters. - */ - private boolean hasFormals; - - /** - * Indicates if the signature contains method parameter types. - */ - private boolean hasParameters; - - /** - * Stack used to keep track of class types that have arguments. Each element - * of this stack is a boolean encoded in one bit. The top of the stack is - * the lowest order bit. Pushing false = *2, pushing true = *2+1, popping = - * /2. - */ - private int argumentStack; - - /** - * Constructs a new {@link SignatureWriter} object. - */ - public SignatureWriter() { - } - - // ------------------------------------------------------------------------ - // Implementation of the SignatureVisitor interface - // ------------------------------------------------------------------------ - - public void visitFormalTypeParameter(final String name) { - if (!hasFormals) { - hasFormals = true; - buf.append('<'); - } - buf.append(name); - buf.append(':'); - } - - public SignatureVisitor visitClassBound() { - return this; - } - - public SignatureVisitor visitInterfaceBound() { - buf.append(':'); - return this; - } - - public SignatureVisitor visitSuperclass() { - endFormals(); - return this; - } - - public SignatureVisitor visitInterface() { - return this; - } - - public SignatureVisitor visitParameterType() { - endFormals(); - if (!hasParameters) { - hasParameters = true; - buf.append('('); - } - return this; - } - - public SignatureVisitor visitReturnType() { - endFormals(); - if (!hasParameters) { - buf.append('('); - } - buf.append(')'); - return this; - } - - public SignatureVisitor visitExceptionType() { - buf.append('^'); - return this; - } - - public void visitBaseType(final char descriptor) { - buf.append(descriptor); - } - - public void visitTypeVariable(final String name) { - buf.append('T'); - buf.append(name); - buf.append(';'); - } - - public SignatureVisitor visitArrayType() { - buf.append('['); - return this; - } - - public void visitClassType(final String name) { - buf.append('L'); - buf.append(name); - argumentStack *= 2; - } - - public void visitInnerClassType(final String name) { - endArguments(); - buf.append('.'); - buf.append(name); - argumentStack *= 2; - } - - public void visitTypeArgument() { - if (argumentStack % 2 == 0) { - ++argumentStack; - buf.append('<'); - } - buf.append('*'); - } - - public SignatureVisitor visitTypeArgument(final char wildcard) { - if (argumentStack % 2 == 0) { - ++argumentStack; - buf.append('<'); - } - if (wildcard != '=') { - buf.append(wildcard); - } - return this; - } - - public void visitEnd() { - endArguments(); - buf.append(';'); - } - - /** - * Returns the signature that was built by this signature writer. - * - * @return the signature that was built by this signature writer. - */ - @Override - public String toString() { - return buf.toString(); - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - /** - * Ends the formal type parameters section of the signature. - */ - private void endFormals() { - if (hasFormals) { - hasFormals = false; - buf.append('>'); - } - } - - /** - * Ends the type arguments of a class or inner class type. - */ - private void endArguments() { - if (argumentStack % 2 != 0) { - buf.append('>'); - } - argumentStack /= 2; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/AbstractInsnNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/AbstractInsnNode.java deleted file mode 100644 index 5e8903734..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/AbstractInsnNode.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.List; -import java.util.Map; - -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * A node that represents a bytecode instruction. An instruction can appear - * at most once in at most one {@link InsnList} at a time. - * - * @author Eric Bruneton - */ -public abstract class AbstractInsnNode { - - /** - * The type of {@link InsnNode} instructions. - */ - public static final int INSN = 0; - - /** - * The type of {@link IntInsnNode} instructions. - */ - public static final int INT_INSN = 1; - - /** - * The type of {@link VarInsnNode} instructions. - */ - public static final int VAR_INSN = 2; - - /** - * The type of {@link TypeInsnNode} instructions. - */ - public static final int TYPE_INSN = 3; - - /** - * The type of {@link FieldInsnNode} instructions. - */ - public static final int FIELD_INSN = 4; - - /** - * The type of {@link MethodInsnNode} instructions. - */ - public static final int METHOD_INSN = 5; - - /** - * The type of {@link JumpInsnNode} instructions. - */ - public static final int JUMP_INSN = 6; - - /** - * The type of {@link LabelNode} "instructions". - */ - public static final int LABEL = 7; - - /** - * The type of {@link LdcInsnNode} instructions. - */ - public static final int LDC_INSN = 8; - - /** - * The type of {@link IincInsnNode} instructions. - */ - public static final int IINC_INSN = 9; - - /** - * The type of {@link TableSwitchInsnNode} instructions. - */ - public static final int TABLESWITCH_INSN = 10; - - /** - * The type of {@link LookupSwitchInsnNode} instructions. - */ - public static final int LOOKUPSWITCH_INSN = 11; - - /** - * The type of {@link MultiANewArrayInsnNode} instructions. - */ - public static final int MULTIANEWARRAY_INSN = 12; - - /** - * The type of {@link FrameNode} "instructions". - */ - public static final int FRAME = 13; - - /** - * The type of {@link LineNumberNode} "instructions". - */ - public static final int LINE = 14; - - /** - * The opcode of this instruction. - */ - protected int opcode; - - /** - * Previous instruction in the list to which this instruction belongs. - */ - AbstractInsnNode prev; - - /** - * Next instruction in the list to which this instruction belongs. - */ - AbstractInsnNode next; - - /** - * Index of this instruction in the list to which it belongs. The value of - * this field is correct only when {@link InsnList#cache} is not null. A - * value of -1 indicates that this instruction does not belong to any - * {@link InsnList}. - */ - int index; - - /** - * Constructs a new {@link AbstractInsnNode}. - * - * @param opcode the opcode of the instruction to be constructed. - */ - protected AbstractInsnNode(final int opcode) { - this.opcode = opcode; - this.index = -1; - } - - /** - * Returns the opcode of this instruction. - * - * @return the opcode of this instruction. - */ - public int getOpcode() { - return opcode; - } - - /** - * Returns the type of this instruction. - * - * @return the type of this instruction, i.e. one the constants defined in - * this class. - */ - public abstract int getType(); - - /** - * Returns the previous instruction in the list to which this instruction - * belongs, if any. - * - * @return the previous instruction in the list to which this instruction - * belongs, if any. May be null. - */ - public AbstractInsnNode getPrevious() { - return prev; - } - - /** - * Returns the next instruction in the list to which this instruction - * belongs, if any. - * - * @return the next instruction in the list to which this instruction - * belongs, if any. May be null. - */ - public AbstractInsnNode getNext() { - return next; - } - - /** - * Makes the given code visitor visit this instruction. - * - * @param cv a code visitor. - */ - public abstract void accept(final MethodVisitor cv); - - /** - * Returns a copy of this instruction. - * - * @param labels a map from LabelNodes to cloned LabelNodes. - * @return a copy of this instruction. The returned instruction does not - * belong to any {@link InsnList}. - */ - public abstract AbstractInsnNode clone(final Map labels); - - /** - * Returns the clone of the given label. - * - * @param label a label. - * @param map a map from LabelNodes to cloned LabelNodes. - * @return the clone of the given label. - */ - static LabelNode clone(final LabelNode label, final Map map) { - return (LabelNode) map.get(label); - } - - /** - * Returns the clones of the given labels. - * - * @param labels a list of labels. - * @param map a map from LabelNodes to cloned LabelNodes. - * @return the clones of the given labels. - */ - static LabelNode[] clone(final List labels, final Map map) { - LabelNode[] clones = new LabelNode[labels.size()]; - for (int i = 0; i < clones.length; ++i) { - clones[i] = (LabelNode) map.get(labels.get(i)); - } - return clones; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/AnnotationNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/AnnotationNode.java deleted file mode 100644 index 2d7c7d703..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/AnnotationNode.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.ArrayList; -import java.util.List; - -import com.alibaba.citrus.asm.AnnotationVisitor; - -/** - * A node that represents an annotationn. - * - * @author Eric Bruneton - */ -public class AnnotationNode implements AnnotationVisitor { - - /** - * The class descriptor of the annotation class. - */ - public String desc; - - /** - * The name value pairs of this annotation. Each name value pair is stored - * as two consecutive elements in the list. The name is a {@link String}, - * and the value may be a {@link Byte}, {@link Boolean}, {@link Character}, - * {@link Short}, {@link Integer}, {@link Long}, {@link Float}, - * {@link Double}, {@link String} or {@link com.alibaba.citrus.asm.Type}, or - * an two elements String array (for enumeration values), a - * {@link AnnotationNode}, or a {@link List} of values of one of the - * preceding types. The list may be null if there is no name value - * pair. - */ - public List values; - - /** - * Constructs a new {@link AnnotationNode}. - * - * @param desc the class descriptor of the annotation class. - */ - public AnnotationNode(final String desc) { - this.desc = desc; - } - - /** - * Constructs a new {@link AnnotationNode} to visit an array value. - * - * @param values where the visited values must be stored. - */ - AnnotationNode(final List values) { - this.values = values; - } - - // ------------------------------------------------------------------------ - // Implementation of the AnnotationVisitor interface - // ------------------------------------------------------------------------ - - public void visit(final String name, final Object value) { - if (values == null) { - values = new ArrayList(this.desc != null ? 2 : 1); - } - if (this.desc != null) { - values.add(name); - } - values.add(value); - } - - public void visitEnum(final String name, final String desc, final String value) { - if (values == null) { - values = new ArrayList(this.desc != null ? 2 : 1); - } - if (this.desc != null) { - values.add(name); - } - values.add(new String[] { desc, value }); - } - - public AnnotationVisitor visitAnnotation(final String name, final String desc) { - if (values == null) { - values = new ArrayList(this.desc != null ? 2 : 1); - } - if (this.desc != null) { - values.add(name); - } - AnnotationNode annotation = new AnnotationNode(desc); - values.add(annotation); - return annotation; - } - - public AnnotationVisitor visitArray(final String name) { - if (values == null) { - values = new ArrayList(this.desc != null ? 2 : 1); - } - if (this.desc != null) { - values.add(name); - } - List array = new ArrayList(); - values.add(array); - return new AnnotationNode(array); - } - - public void visitEnd() { - } - - // ------------------------------------------------------------------------ - // Accept methods - // ------------------------------------------------------------------------ - - /** - * Makes the given visitor visit this annotation. - * - * @param av an annotation visitor. Maybe null. - */ - public void accept(final AnnotationVisitor av) { - if (av != null) { - if (values != null) { - for (int i = 0; i < values.size(); i += 2) { - String name = (String) values.get(i); - Object value = values.get(i + 1); - accept(av, name, value); - } - } - av.visitEnd(); - } - } - - /** - * Makes the given visitor visit a given annotation value. - * - * @param av an annotation visitor. Maybe null. - * @param name the value name. - * @param value the actual value. - */ - static void accept(final AnnotationVisitor av, final String name, final Object value) { - if (av != null) { - if (value instanceof String[]) { - String[] typeconst = (String[]) value; - av.visitEnum(name, typeconst[0], typeconst[1]); - } else if (value instanceof AnnotationNode) { - AnnotationNode an = (AnnotationNode) value; - an.accept(av.visitAnnotation(name, an.desc)); - } else if (value instanceof List) { - AnnotationVisitor v = av.visitArray(name); - List array = (List) value; - for (int j = 0; j < array.size(); ++j) { - accept(v, null, array.get(j)); - } - v.visitEnd(); - } else { - av.visit(name, value); - } - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/ClassNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/ClassNode.java deleted file mode 100644 index 626144e57..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/ClassNode.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * A node that represents a class. - * - * @author Eric Bruneton - */ -public class ClassNode extends MemberNode implements ClassVisitor { - - /** - * The class version. - */ - public int version; - - /** - * The class's access flags (see {@link com.alibaba.citrus.asm.Opcodes}). - * This field also indicates if the class is deprecated. - */ - public int access; - - /** - * The internal name of the class (see - * {@link com.alibaba.citrus.asm.Type#getInternalName() getInternalName}). - */ - public String name; - - /** - * The signature of the class. Mayt be null. - */ - public String signature; - - /** - * The internal of name of the super class (see - * {@link com.alibaba.citrus.asm.Type#getInternalName() getInternalName}). - * For interfaces, the super class is {@link Object}. May be null, - * but only for the {@link Object} class. - */ - public String superName; - - /** - * The internal names of the class's interfaces (see - * {@link com.alibaba.citrus.asm.Type#getInternalName() getInternalName}). - * This list is a list of {@link String} objects. - */ - public List interfaces; - - /** - * The name of the source file from which this class was compiled. May be - * null. - */ - public String sourceFile; - - /** - * Debug information to compute the correspondance between source and - * compiled elements of the class. May be null. - */ - public String sourceDebug; - - /** - * The internal name of the enclosing class of the class. May be - * null. - */ - public String outerClass; - - /** - * The name of the method that contains the class, or null if the - * class is not enclosed in a method. - */ - public String outerMethod; - - /** - * The descriptor of the method that contains the class, or null if - * the class is not enclosed in a method. - */ - public String outerMethodDesc; - - /** - * Informations about the inner classes of this class. This list is a list - * of {@link InnerClassNode} objects. - * - * @associates com.alibaba.citrus.asm.tree.InnerClassNode - */ - public List innerClasses; - - /** - * The fields of this class. This list is a list of {@link FieldNode} - * objects. - * - * @associates com.alibaba.citrus.asm.tree.FieldNode - */ - public List fields; - - /** - * The methods of this class. This list is a list of {@link MethodNode} - * objects. - * - * @associates com.alibaba.citrus.asm.tree.MethodNode - */ - public List methods; - - /** - * Constructs a new {@link ClassNode}. - */ - public ClassNode() { - this.interfaces = new ArrayList(); - this.innerClasses = new ArrayList(); - this.fields = new ArrayList(); - this.methods = new ArrayList(); - } - - // ------------------------------------------------------------------------ - // Implementation of the ClassVisitor interface - // ------------------------------------------------------------------------ - - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - this.version = version; - this.access = access; - this.name = name; - this.signature = signature; - this.superName = superName; - if (interfaces != null) { - this.interfaces.addAll(Arrays.asList(interfaces)); - } - } - - public void visitSource(final String file, final String debug) { - sourceFile = file; - sourceDebug = debug; - } - - public void visitOuterClass(final String owner, final String name, final String desc) { - outerClass = owner; - outerMethod = name; - outerMethodDesc = desc; - } - - public void visitInnerClass(final String name, final String outerName, final String innerName, final int access) { - InnerClassNode icn = new InnerClassNode(name, outerName, innerName, access); - innerClasses.add(icn); - } - - public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, - final Object value) { - FieldNode fn = new FieldNode(access, name, desc, signature, value); - fields.add(fn); - return fn; - } - - public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, - final String[] exceptions) { - MethodNode mn = new MethodNode(access, name, desc, signature, exceptions); - methods.add(mn); - return mn; - } - - // ------------------------------------------------------------------------ - // Accept method - // ------------------------------------------------------------------------ - - /** - * Makes the given class visitor visit this class. - * - * @param cv a class visitor. - */ - public void accept(final ClassVisitor cv) { - // visits header - String[] interfaces = new String[this.interfaces.size()]; - this.interfaces.toArray(interfaces); - cv.visit(version, access, name, signature, superName, interfaces); - // visits source - if (sourceFile != null || sourceDebug != null) { - cv.visitSource(sourceFile, sourceDebug); - } - // visits outer class - if (outerClass != null) { - cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc); - } - // visits attributes - int i, n; - n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); - for (i = 0; i < n; ++i) { - AnnotationNode an = (AnnotationNode) visibleAnnotations.get(i); - an.accept(cv.visitAnnotation(an.desc, true)); - } - n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); - for (i = 0; i < n; ++i) { - AnnotationNode an = (AnnotationNode) invisibleAnnotations.get(i); - an.accept(cv.visitAnnotation(an.desc, false)); - } - n = attrs == null ? 0 : attrs.size(); - for (i = 0; i < n; ++i) { - cv.visitAttribute((Attribute) attrs.get(i)); - } - // visits inner classes - for (i = 0; i < innerClasses.size(); ++i) { - ((InnerClassNode) innerClasses.get(i)).accept(cv); - } - // visits fields - for (i = 0; i < fields.size(); ++i) { - ((FieldNode) fields.get(i)).accept(cv); - } - // visits methods - for (i = 0; i < methods.size(); ++i) { - ((MethodNode) methods.get(i)).accept(cv); - } - // visits end - cv.visitEnd(); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/FieldInsnNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/FieldInsnNode.java deleted file mode 100644 index ae55ad05c..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/FieldInsnNode.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.Map; - -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * A node that represents a field instruction. A field instruction is an - * instruction that loads or stores the value of a field of an object. - * - * @author Eric Bruneton - */ -public class FieldInsnNode extends AbstractInsnNode { - - /** - * The internal name of the field's owner class (see - * {@link com.alibaba.citrus.asm.Type#getInternalName() getInternalName}). - */ - public String owner; - - /** - * The field's name. - */ - public String name; - - /** - * The field's descriptor (see {@link com.alibaba.citrus.asm.Type}). - */ - public String desc; - - /** - * Constructs a new {@link FieldInsnNode}. - * - * @param opcode the opcode of the type instruction to be constructed. This - * opcode must be GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. - * @param owner the internal name of the field's owner class (see - * {@link com.alibaba.citrus.asm.Type#getInternalName() - * getInternalName}). - * @param name the field's name. - * @param desc the field's descriptor (see - * {@link com.alibaba.citrus.asm.Type}). - */ - public FieldInsnNode(final int opcode, final String owner, final String name, final String desc) { - super(opcode); - this.owner = owner; - this.name = name; - this.desc = desc; - } - - /** - * Sets the opcode of this instruction. - * - * @param opcode the new instruction opcode. This opcode must be GETSTATIC, - * PUTSTATIC, GETFIELD or PUTFIELD. - */ - public void setOpcode(final int opcode) { - this.opcode = opcode; - } - - @Override - public int getType() { - return FIELD_INSN; - } - - @Override - public void accept(final MethodVisitor cv) { - cv.visitFieldInsn(opcode, owner, name, desc); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new FieldInsnNode(opcode, owner, name, desc); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/FieldNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/FieldNode.java deleted file mode 100644 index cc873b218..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/FieldNode.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.FieldVisitor; - -/** - * A node that represents a field. - * - * @author Eric Bruneton - */ -public class FieldNode extends MemberNode implements FieldVisitor { - - /** - * The field's access flags (see {@link com.alibaba.citrus.asm.Opcodes}). - * This field also indicates if the field is synthetic and/or deprecated. - */ - public int access; - - /** - * The field's name. - */ - public String name; - - /** - * The field's descriptor (see {@link com.alibaba.citrus.asm.Type}). - */ - public String desc; - - /** - * The field's signature. May be null. - */ - public String signature; - - /** - * The field's initial value. This field, which may be null if the - * field does not have an initial value, must be an {@link Integer}, a - * {@link Float}, a {@link Long}, a {@link Double} or a {@link String}. - */ - public Object value; - - /** - * Constructs a new {@link FieldNode}. - * - * @param access the field's access flags (see - * {@link com.alibaba.citrus.asm.Opcodes}). This parameter also - * indicates if the field is synthetic and/or deprecated. - * @param name the field's name. - * @param desc the field's descriptor (see - * {@link com.alibaba.citrus.asm.Type Type}). - * @param signature the field's signature. - * @param value the field's initial value. This parameter, which may be - * null if the field does not have an initial value, - * must be an {@link Integer}, a {@link Float}, a {@link Long}, a - * {@link Double} or a {@link String}. - */ - public FieldNode(final int access, final String name, final String desc, final String signature, final Object value) { - this.access = access; - this.name = name; - this.desc = desc; - this.signature = signature; - this.value = value; - } - - /** - * Makes the given class visitor visit this field. - * - * @param cv a class visitor. - */ - public void accept(final ClassVisitor cv) { - FieldVisitor fv = cv.visitField(access, name, desc, signature, value); - if (fv == null) { - return; - } - int i, n; - n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); - for (i = 0; i < n; ++i) { - AnnotationNode an = (AnnotationNode) visibleAnnotations.get(i); - an.accept(fv.visitAnnotation(an.desc, true)); - } - n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); - for (i = 0; i < n; ++i) { - AnnotationNode an = (AnnotationNode) invisibleAnnotations.get(i); - an.accept(fv.visitAnnotation(an.desc, false)); - } - n = attrs == null ? 0 : attrs.size(); - for (i = 0; i < n; ++i) { - fv.visitAttribute((Attribute) attrs.get(i)); - } - fv.visitEnd(); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/FrameNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/FrameNode.java deleted file mode 100644 index a88a0cba1..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/FrameNode.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * A node that represents a stack map frame. These nodes are pseudo instruction - * nodes in order to be inserted in an instruction list. In fact these nodes - * must(*) be inserted just before any instruction node i that - * follows an unconditionnal branch instruction such as GOTO or THROW, that is - * the target of a jump instruction, or that starts an exception handler block. - * The stack map frame types must describe the values of the local variables and - * of the operand stack elements just before i is executed.
- *
- * (*) this is mandatory only for classes whose version is greater than or equal - * to {@link Opcodes#V1_6 V1_6}. - * - * @author Eric Bruneton - */ -public class FrameNode extends AbstractInsnNode { - - /** - * The type of this frame. Must be {@link Opcodes#F_NEW} for expanded - * frames, or {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, - * {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or - * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames. - */ - public int type; - - /** - * The types of the local variables of this stack map frame. Elements of - * this list can be Integer, String or LabelNode objects (for primitive, - * reference and uninitialized types respectively - see - * {@link MethodVisitor}). - */ - public List local; - - /** - * The types of the operand stack elements of this stack map frame. Elements - * of this list can be Integer, String or LabelNode objects (for primitive, - * reference and uninitialized types respectively - see - * {@link MethodVisitor}). - */ - public List stack; - - private FrameNode() { - super(-1); - } - - /** - * Constructs a new {@link FrameNode}. - * - * @param type the type of this frame. Must be {@link Opcodes#F_NEW} for - * expanded frames, or {@link Opcodes#F_FULL}, - * {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, - * {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, - * {@link Opcodes#F_SAME1} for compressed frames. - * @param nLocal number of local variables of this stack map frame. - * @param local the types of the local variables of this stack map frame. - * Elements of this list can be Integer, String or LabelNode - * objects (for primitive, reference and uninitialized types - * respectively - see {@link MethodVisitor}). - * @param nStack number of operand stack elements of this stack map frame. - * @param stack the types of the operand stack elements of this stack map - * frame. Elements of this list can be Integer, String or - * LabelNode objects (for primitive, reference and uninitialized - * types respectively - see {@link MethodVisitor}). - */ - public FrameNode(final int type, final int nLocal, final Object[] local, final int nStack, final Object[] stack) { - super(-1); - this.type = type; - switch (type) { - case Opcodes.F_NEW: - case Opcodes.F_FULL: - this.local = asList(nLocal, local); - this.stack = asList(nStack, stack); - break; - case Opcodes.F_APPEND: - this.local = asList(nLocal, local); - break; - case Opcodes.F_CHOP: - this.local = asList(nLocal, local); - break; - case Opcodes.F_SAME: - break; - case Opcodes.F_SAME1: - this.stack = asList(1, stack); - break; - } - } - - @Override - public int getType() { - return FRAME; - } - - /** - * Makes the given visitor visit this stack map frame. - * - * @param mv a method visitor. - */ - @Override - public void accept(final MethodVisitor mv) { - switch (type) { - case Opcodes.F_NEW: - case Opcodes.F_FULL: - mv.visitFrame(type, local.size(), asArray(local), stack.size(), asArray(stack)); - break; - case Opcodes.F_APPEND: - mv.visitFrame(type, local.size(), asArray(local), 0, null); - break; - case Opcodes.F_CHOP: - mv.visitFrame(type, local.size(), asArray(local), 0, null); - break; - case Opcodes.F_SAME: - mv.visitFrame(type, 0, null, 0, null); - break; - case Opcodes.F_SAME1: - mv.visitFrame(type, 0, null, 1, asArray(stack)); - break; - } - } - - @Override - public AbstractInsnNode clone(final Map labels) { - FrameNode clone = new FrameNode(); - clone.type = type; - if (local != null) { - clone.local = new ArrayList(); - for (int i = 0; i < local.size(); ++i) { - Object l = local.get(i); - if (l instanceof LabelNode) { - l = labels.get(l); - } - clone.local.add(l); - } - } - if (stack != null) { - clone.stack = new ArrayList(); - for (int i = 0; i < stack.size(); ++i) { - Object s = stack.get(i); - if (s instanceof LabelNode) { - s = labels.get(s); - } - clone.stack.add(s); - } - } - return clone; - } - - // ------------------------------------------------------------------------ - - private static List asList(final int n, final Object[] o) { - return Arrays.asList(o).subList(0, n); - } - - private static Object[] asArray(final List l) { - Object[] objs = new Object[l.size()]; - for (int i = 0; i < objs.length; ++i) { - Object o = l.get(i); - if (o instanceof LabelNode) { - o = ((LabelNode) o).getLabel(); - } - objs[i] = o; - } - return objs; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/IincInsnNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/IincInsnNode.java deleted file mode 100644 index af410fada..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/IincInsnNode.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.Map; - -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * A node that represents an IINC instruction. - * - * @author Eric Bruneton - */ -public class IincInsnNode extends AbstractInsnNode { - - /** - * Index of the local variable to be incremented. - */ - public int var; - - /** - * Amount to increment the local variable by. - */ - public int incr; - - /** - * Constructs a new {@link IincInsnNode}. - * - * @param var index of the local variable to be incremented. - * @param incr increment amount to increment the local variable by. - */ - public IincInsnNode(final int var, final int incr) { - super(Opcodes.IINC); - this.var = var; - this.incr = incr; - } - - @Override - public int getType() { - return IINC_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitIincInsn(var, incr); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new IincInsnNode(var, incr); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/InnerClassNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/InnerClassNode.java deleted file mode 100644 index f25de9f2c..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/InnerClassNode.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import com.alibaba.citrus.asm.ClassVisitor; - -/** - * A node that represents an inner class. - * - * @author Eric Bruneton - */ -public class InnerClassNode { - - /** - * The internal name of an inner class (see - * {@link com.alibaba.citrus.asm.Type#getInternalName() getInternalName}). - */ - public String name; - - /** - * The internal name of the class to which the inner class belongs (see - * {@link com.alibaba.citrus.asm.Type#getInternalName() getInternalName}). - * May be null. - */ - public String outerName; - - /** - * The (simple) name of the inner class inside its enclosing class. May be - * null for anonymous inner classes. - */ - public String innerName; - - /** - * The access flags of the inner class as originally declared in the - * enclosing class. - */ - public int access; - - /** - * Constructs a new {@link InnerClassNode}. - * - * @param name the internal name of an inner class (see - * {@link com.alibaba.citrus.asm.Type#getInternalName() - * getInternalName}). - * @param outerName the internal name of the class to which the inner class - * belongs (see - * {@link com.alibaba.citrus.asm.Type#getInternalName() - * getInternalName}). May be null. - * @param innerName the (simple) name of the inner class inside its - * enclosing class. May be null for anonymous inner - * classes. - * @param access the access flags of the inner class as originally declared - * in the enclosing class. - */ - public InnerClassNode(final String name, final String outerName, final String innerName, final int access) { - this.name = name; - this.outerName = outerName; - this.innerName = innerName; - this.access = access; - } - - /** - * Makes the given class visitor visit this inner class. - * - * @param cv a class visitor. - */ - public void accept(final ClassVisitor cv) { - cv.visitInnerClass(name, outerName, innerName, access); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/InsnList.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/InsnList.java deleted file mode 100644 index 754f54dde..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/InsnList.java +++ /dev/null @@ -1,655 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.ListIterator; -import java.util.NoSuchElementException; - -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * A doubly linked list of {@link AbstractInsnNode} objects. This - * implementation is not thread safe. - */ -public class InsnList { - - /** - * Indicates if preconditions of methods of this class must be checked. - * Checking preconditions causes the {@link #indexOf indexOf}, - * {@link #set set}, {@link #insert(AbstractInsnNode, AbstractInsnNode)}, - * {@link #insert(AbstractInsnNode, InsnList)}, {@link #remove remove} and - * {@link #clear} methods to execute in O(n) time instead of O(1). - */ - public static boolean check; - - /** - * The number of instructions in this list. - */ - private int size; - - /** - * The first instruction in this list. May be null. - */ - private AbstractInsnNode first; - - /** - * The last instruction in this list. May be null. - */ - private AbstractInsnNode last; - - /** - * A cache of the instructions of this list. This cache is used to improve - * the performance of the {@link #get} method. - */ - private AbstractInsnNode[] cache; - - /** - * Returns the number of instructions in this list. - * - * @return the number of instructions in this list. - */ - public int size() { - return size; - } - - /** - * Returns the first instruction in this list. - * - * @return the first instruction in this list, or null if the list - * is empty. - */ - public AbstractInsnNode getFirst() { - return first; - } - - /** - * Returns the last instruction in this list. - * - * @return the last instruction in this list, or null if the list - * is empty. - */ - public AbstractInsnNode getLast() { - return last; - } - - /** - * Returns the instruction whose index is given. This method builds a cache - * of the instructions in this list to avoid scanning the whole list each - * time it is called. Once the cache is built, this method run in constant - * time. This cache is invalidated by all the methods that modify the list. - * - * @param index the index of the instruction that must be returned. - * @return the instruction whose index is given. - * @throws IndexOutOfBoundsException if (index < 0 || index >= size()). - */ - public AbstractInsnNode get(final int index) { - if (index < 0 || index >= size) { - throw new IndexOutOfBoundsException(); - } - if (cache == null) { - cache = toArray(); - } - return cache[index]; - } - - /** - * Returns true if the given instruction belongs to this list. This - * method always scans the instructions of this list until it finds the - * given instruction or reaches the end of the list. - * - * @param insn an instruction. - * @return true if the given instruction belongs to this list. - */ - public boolean contains(final AbstractInsnNode insn) { - AbstractInsnNode i = first; - while (i != null && i != insn) { - i = i.next; - } - return i != null; - } - - /** - * Returns the index of the given instruction in this list. This method - * builds a cache of the instruction indexes to avoid scanning the whole - * list each time it is called. Once the cache is built, this method run in - * constant time. The cache is invalidated by all the methods that modify - * the list. - * - * @param insn an instruction of this list. - * @return the index of the given instruction in this list. The result of - * this method is undefined if the given instruction does not belong - * to this list. Use {@link #contains contains} to test if an - * instruction belongs to an instruction list or not. - * @throws IllegalArgumentException if {@link #check} is true and - * if insn does not belong to this list. - */ - public int indexOf(final AbstractInsnNode insn) { - if (check && !contains(insn)) { - throw new IllegalArgumentException(); - } - if (cache == null) { - cache = toArray(); - } - return insn.index; - } - - /** - * Makes the given visitor visit all of the instructions in this list. - * - * @param mv the method visitor that must visit the instructions. - */ - public void accept(final MethodVisitor mv) { - AbstractInsnNode insn = first; - while (insn != null) { - insn.accept(mv); - insn = insn.next; - } - } - - /** - * Returns an iterator over the instructions in this list. - * - * @return an iterator over the instructions in this list. - */ - public ListIterator iterator() { - return iterator(0); - } - - /** - * Returns an iterator over the instructions in this list. - * - * @return an iterator over the instructions in this list. - */ - public ListIterator iterator(int index) { - return new InsnListIterator(index); - } - - /** - * Returns an array containing all of the instructions in this list. - * - * @return an array containing all of the instructions in this list. - */ - public AbstractInsnNode[] toArray() { - int i = 0; - AbstractInsnNode elem = first; - AbstractInsnNode[] insns = new AbstractInsnNode[size]; - while (elem != null) { - insns[i] = elem; - elem.index = i++; - elem = elem.next; - } - return insns; - } - - /** - * Replaces an instruction of this list with another instruction. - * - * @param location an instruction of this list. - * @param insn another instruction, which must not belong to any - * {@link InsnList}. - * @throws IllegalArgumentException if {@link #check} is true, and - * if i does not belong to this list or if insn belongs to an - * instruction list. - */ - public void set(final AbstractInsnNode location, final AbstractInsnNode insn) { - if (check && !(contains(location) && insn.index == -1)) { - throw new IllegalArgumentException(); - } - AbstractInsnNode next = location.next; - insn.next = next; - if (next != null) { - next.prev = insn; - } else { - last = insn; - } - AbstractInsnNode prev = location.prev; - insn.prev = prev; - if (prev != null) { - prev.next = insn; - } else { - first = insn; - } - if (cache != null) { - int index = location.index; - cache[index] = insn; - insn.index = index; - } else { - insn.index = 0; // insn now belongs to an InsnList - } - location.index = -1; // i no longer belongs to an InsnList - location.prev = null; - location.next = null; - } - - /** - * Adds the given instruction to the end of this list. - * - * @param insn an instruction, which must not belong to any - * {@link InsnList}. - * @throws IllegalArgumentException if {@link #check} is true, and - * if insn belongs to an instruction list. - */ - public void add(final AbstractInsnNode insn) { - if (check && insn.index != -1) { - throw new IllegalArgumentException(); - } - ++size; - if (last == null) { - first = insn; - last = insn; - } else { - last.next = insn; - insn.prev = last; - } - last = insn; - cache = null; - insn.index = 0; // insn now belongs to an InsnList - } - - /** - * Adds the given instructions to the end of this list. - * - * @param insns an instruction list, which is cleared during the process. - * @throws IllegalArgumentException if {@link #check} is true, and - * if insn == this. - */ - public void add(final InsnList insns) { - if (check && insns == this) { - throw new IllegalArgumentException(); - } - if (insns.size == 0) { - return; - } - size += insns.size; - if (last == null) { - first = insns.first; - last = insns.last; - } else { - AbstractInsnNode elem = insns.first; - last.next = elem; - elem.prev = last; - last = insns.last; - } - cache = null; - insns.removeAll(false); - } - - /** - * Inserts the given instruction at the begining of this list. - * - * @param insn an instruction, which must not belong to any - * {@link InsnList}. - * @throws IllegalArgumentException if {@link #check} is true, and - * if insn belongs to an instruction list. - */ - public void insert(final AbstractInsnNode insn) { - if (check && insn.index != -1) { - throw new IllegalArgumentException(); - } - ++size; - if (first == null) { - first = insn; - last = insn; - } else { - first.prev = insn; - insn.next = first; - } - first = insn; - cache = null; - insn.index = 0; // insn now belongs to an InsnList - } - - /** - * Inserts the given instructions at the begining of this list. - * - * @param insns an instruction list, which is cleared during the process. - * @throws IllegalArgumentException if {@link #check} is true, and - * if insn == this. - */ - public void insert(final InsnList insns) { - if (check && insns == this) { - throw new IllegalArgumentException(); - } - if (insns.size == 0) { - return; - } - size += insns.size; - if (first == null) { - first = insns.first; - last = insns.last; - } else { - AbstractInsnNode elem = insns.last; - first.prev = elem; - elem.next = first; - first = insns.first; - } - cache = null; - insns.removeAll(false); - } - - /** - * Inserts the given instruction after the specified instruction. - * - * @param location an instruction of this list after which insn must - * be inserted. - * @param insn the instruction to be inserted, which must not belong to - * any {@link InsnList}. - * @throws IllegalArgumentException if {@link #check} is true, and - * if i does not belong to this list or if insn belongs to an - * instruction list. - */ - public void insert(final AbstractInsnNode location, final AbstractInsnNode insn) { - if (check && !(contains(location) && insn.index == -1)) { - throw new IllegalArgumentException(); - } - ++size; - AbstractInsnNode next = location.next; - if (next == null) { - last = insn; - } else { - next.prev = insn; - } - location.next = insn; - insn.next = next; - insn.prev = location; - cache = null; - insn.index = 0; // insn now belongs to an InsnList - } - - /** - * Inserts the given instructions after the specified instruction. - * - * @param location an instruction of this list after which the - * instructions must be inserted. - * @param insns the instruction list to be inserted, which is cleared during - * the process. - * @throws IllegalArgumentException if {@link #check} is true, and - * if i does not belong to this list or if insns == this. - */ - public void insert(final AbstractInsnNode location, final InsnList insns) { - if (check && !(contains(location) && insns != this)) { - throw new IllegalArgumentException(); - } - if (insns.size == 0) { - return; - } - size += insns.size; - AbstractInsnNode ifirst = insns.first; - AbstractInsnNode ilast = insns.last; - AbstractInsnNode next = location.next; - if (next == null) { - last = ilast; - } else { - next.prev = ilast; - } - location.next = ifirst; - ilast.next = next; - ifirst.prev = location; - cache = null; - insns.removeAll(false); - } - - /** - * Inserts the given instruction before the specified instruction. - * - * @param location an instruction of this list before which insn must - * be inserted. - * @param insn the instruction to be inserted, which must not belong to - * any {@link InsnList}. - * @throws IllegalArgumentException if {@link #check} is true, and - * if i does not belong to this list or if insn belongs to an - * instruction list. - */ - public void insertBefore(final AbstractInsnNode location, final AbstractInsnNode insn) { - if (check && !(contains(location) && insn.index == -1)) { - throw new IllegalArgumentException(); - } - ++size; - AbstractInsnNode prev = location.prev; - if (prev == null) { - first = insn; - } else { - prev.next = insn; - } - location.prev = insn; - insn.next = location; - insn.prev = prev; - cache = null; - insn.index = 0; // insn now belongs to an InsnList - } - - /** - * Inserts the given instructions before the specified instruction. - * - * @param location an instruction of this list before which the - * instructions must be inserted. - * @param insns the instruction list to be inserted, which is cleared during - * the process. - * @throws IllegalArgumentException if {@link #check} is true, and - * if i does not belong to this list or if insns == this. - */ - public void insertBefore(final AbstractInsnNode location, final InsnList insns) { - if (check && !(contains(location) && insns != this)) { - throw new IllegalArgumentException(); - } - if (insns.size == 0) { - return; - } - size += insns.size; - AbstractInsnNode ifirst = insns.first; - AbstractInsnNode ilast = insns.last; - AbstractInsnNode prev = location.prev; - if (prev == null) { - first = ifirst; - } else { - prev.next = ifirst; - } - location.prev = ilast; - ilast.next = location; - ifirst.prev = prev; - cache = null; - insns.removeAll(false); - } - - /** - * Removes the given instruction from this list. - * - * @param insn the instruction of this list that must be removed. - * @throws IllegalArgumentException if {@link #check} is true, and - * if insn does not belong to this list. - */ - public void remove(final AbstractInsnNode insn) { - if (check && !contains(insn)) { - throw new IllegalArgumentException(); - } - --size; - AbstractInsnNode next = insn.next; - AbstractInsnNode prev = insn.prev; - if (next == null) { - if (prev == null) { - first = null; - last = null; - } else { - prev.next = null; - last = prev; - } - } else { - if (prev == null) { - first = next; - next.prev = null; - } else { - prev.next = next; - next.prev = prev; - } - } - cache = null; - insn.index = -1; // insn no longer belongs to an InsnList - insn.prev = null; - insn.next = null; - } - - /** - * Removes all of the instructions of this list. - * - * @param mark if the instructions must be marked as no longer belonging to - * any {@link InsnList}. - */ - private void removeAll(final boolean mark) { - if (mark) { - AbstractInsnNode insn = first; - while (insn != null) { - AbstractInsnNode next = insn.next; - insn.index = -1; // insn no longer belongs to an InsnList - insn.prev = null; - insn.next = null; - insn = next; - } - } - size = 0; - first = null; - last = null; - cache = null; - } - - /** - * Removes all of the instructions of this list. - */ - public void clear() { - removeAll(check); - } - - /** - * Reset all labels in the instruction list. This method should be called - * before reusing same instructions list between several - * ClassWriters. - */ - public void resetLabels() { - AbstractInsnNode insn = first; - while (insn != null) { - if (insn instanceof LabelNode) { - ((LabelNode) insn).resetLabel(); - } - insn = insn.next; - } - } - - private final class InsnListIterator implements ListIterator { - AbstractInsnNode next; - AbstractInsnNode prev; - - private InsnListIterator(int index) { - if (index == size()) { - next = null; - prev = getLast(); - } else { - next = get(index); - prev = next.prev; - } - } - - public boolean hasNext() { - return next != null; - } - - public Object next() { - if (next == null) { - throw new NoSuchElementException(); - } - AbstractInsnNode result = next; - prev = result; - next = result.next; - return result; - } - - public void remove() { - InsnList.this.remove(prev); - prev = prev.prev; - } - - public boolean hasPrevious() { - return prev != null; - } - - public Object previous() { - AbstractInsnNode result = prev; - next = result; - prev = result.prev; - return result; - } - - public int nextIndex() { - if (next == null) { - return size(); - } - if (cache == null) { - cache = toArray(); - } - return next.index; - } - - public int previousIndex() { - if (prev == null) { - return -1; - } - if (cache == null) { - cache = toArray(); - } - return prev.index; - } - - public void add(Object o) { - InsnList.this.insertBefore(next, (AbstractInsnNode) o); - prev = (AbstractInsnNode) o; - } - - public void set(Object o) { - InsnList.this.set(next.prev, (AbstractInsnNode) o); - prev = (AbstractInsnNode) o; - } - } - -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/InsnNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/InsnNode.java deleted file mode 100644 index abe1bd98a..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/InsnNode.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.Map; - -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * A node that represents a zero operand instruction. - * - * @author Eric Bruneton - */ -public class InsnNode extends AbstractInsnNode { - - /** - * Constructs a new {@link InsnNode}. - * - * @param opcode the opcode of the instruction to be constructed. This - * opcode must be NOP, ACONST_NULL, ICONST_M1, ICONST_0, - * ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, - * LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, - * IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, - * SALOAD, IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, - * CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, - * DUP2_X1, DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, - * FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, - * IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, - * ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, - * I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, - * I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, - * LRETURN, FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, - * ATHROW, MONITORENTER, or MONITOREXIT. - */ - public InsnNode(final int opcode) { - super(opcode); - } - - @Override - public int getType() { - return INSN; - } - - /** - * Makes the given visitor visit this instruction. - * - * @param mv a method visitor. - */ - @Override - public void accept(final MethodVisitor mv) { - mv.visitInsn(opcode); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new InsnNode(opcode); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/IntInsnNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/IntInsnNode.java deleted file mode 100644 index da1b8863d..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/IntInsnNode.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.Map; - -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * A node that represents an instruction with a single int operand. - * - * @author Eric Bruneton - */ -public class IntInsnNode extends AbstractInsnNode { - - /** - * The operand of this instruction. - */ - public int operand; - - /** - * Constructs a new {@link IntInsnNode}. - * - * @param opcode the opcode of the instruction to be constructed. This - * opcode must be BIPUSH, SIPUSH or NEWARRAY. - * @param operand the operand of the instruction to be constructed. - */ - public IntInsnNode(final int opcode, final int operand) { - super(opcode); - this.operand = operand; - } - - /** - * Sets the opcode of this instruction. - * - * @param opcode the new instruction opcode. This opcode must be BIPUSH, - * SIPUSH or NEWARRAY. - */ - public void setOpcode(final int opcode) { - this.opcode = opcode; - } - - @Override - public int getType() { - return INT_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitIntInsn(opcode, operand); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new IntInsnNode(opcode, operand); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/JumpInsnNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/JumpInsnNode.java deleted file mode 100644 index c88e851cc..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/JumpInsnNode.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.Map; - -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * A node that represents a jump instruction. A jump instruction is an - * instruction that may jump to another instruction. - * - * @author Eric Bruneton - */ -public class JumpInsnNode extends AbstractInsnNode { - - /** - * The operand of this instruction. This operand is a label that designates - * the instruction to which this instruction may jump. - */ - public LabelNode label; - - /** - * Constructs a new {@link JumpInsnNode}. - * - * @param opcode the opcode of the type instruction to be constructed. This - * opcode must be IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, - * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, - * IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. - * @param label the operand of the instruction to be constructed. This - * operand is a label that designates the instruction to which - * the jump instruction may jump. - */ - public JumpInsnNode(final int opcode, final LabelNode label) { - super(opcode); - this.label = label; - } - - /** - * Sets the opcode of this instruction. - * - * @param opcode the new instruction opcode. This opcode must be IFEQ, IFNE, - * IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, - * IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, - * JSR, IFNULL or IFNONNULL. - */ - public void setOpcode(final int opcode) { - this.opcode = opcode; - } - - @Override - public int getType() { - return JUMP_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitJumpInsn(opcode, label.getLabel()); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new JumpInsnNode(opcode, clone(label, labels)); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/LabelNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/LabelNode.java deleted file mode 100644 index eb652ac4b..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/LabelNode.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.Map; - -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * An {@link AbstractInsnNode} that encapsulates a {@link Label}. - */ -public class LabelNode extends AbstractInsnNode { - - private Label label; - - public LabelNode() { - super(-1); - } - - public LabelNode(final Label label) { - super(-1); - this.label = label; - } - - @Override - public int getType() { - return LABEL; - } - - public Label getLabel() { - if (label == null) { - label = new Label(); - } - return label; - } - - @Override - public void accept(final MethodVisitor cv) { - cv.visitLabel(getLabel()); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return (LabelNode) labels.get(this); - } - - public void resetLabel() { - label = null; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/LdcInsnNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/LdcInsnNode.java deleted file mode 100644 index 20a31c87c..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/LdcInsnNode.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.Map; - -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * A node that represents an LDC instruction. - * - * @author Eric Bruneton - */ -public class LdcInsnNode extends AbstractInsnNode { - - /** - * The constant to be loaded on the stack. This parameter must be a non null - * {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a - * {@link String} or a {@link com.alibaba.citrus.asm.Type}. - */ - public Object cst; - - /** - * Constructs a new {@link LdcInsnNode}. - * - * @param cst the constant to be loaded on the stack. This parameter must be - * a non null {@link Integer}, a {@link Float}, a {@link Long}, a - * {@link Double} or a {@link String}. - */ - public LdcInsnNode(final Object cst) { - super(Opcodes.LDC); - this.cst = cst; - } - - @Override - public int getType() { - return LDC_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitLdcInsn(cst); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new LdcInsnNode(cst); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/LineNumberNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/LineNumberNode.java deleted file mode 100644 index a69892194..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/LineNumberNode.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.Map; - -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * A node that represents a line number declaration. These nodes are pseudo - * instruction nodes in order to be inserted in an instruction list. - * - * @author Eric Bruneton - */ -public class LineNumberNode extends AbstractInsnNode { - - /** - * A line number. This number refers to the source file from which the class - * was compiled. - */ - public int line; - - /** - * The first instruction corresponding to this line number. - */ - public LabelNode start; - - /** - * Constructs a new {@link LineNumberNode}. - * - * @param line a line number. This number refers to the source file from - * which the class was compiled. - * @param start the first instruction corresponding to this line number. - */ - public LineNumberNode(final int line, final LabelNode start) { - super(-1); - this.line = line; - this.start = start; - } - - @Override - public int getType() { - return LINE; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitLineNumber(line, start.getLabel()); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new LineNumberNode(line, clone(start, labels)); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/LocalVariableNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/LocalVariableNode.java deleted file mode 100644 index bb150bd29..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/LocalVariableNode.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * A node that represents a local variable declaration. - * - * @author Eric Bruneton - */ -public class LocalVariableNode { - - /** - * The name of a local variable. - */ - public String name; - - /** - * The type descriptor of this local variable. - */ - public String desc; - - /** - * The signature of this local variable. May be null. - */ - public String signature; - - /** - * The first instruction corresponding to the scope of this local variable - * (inclusive). - */ - public LabelNode start; - - /** - * The last instruction corresponding to the scope of this local variable - * (exclusive). - */ - public LabelNode end; - - /** - * The local variable's index. - */ - public int index; - - /** - * Constructs a new {@link LocalVariableNode}. - * - * @param name the name of a local variable. - * @param desc the type descriptor of this local variable. - * @param signature the signature of this local variable. May be - * null. - * @param start the first instruction corresponding to the scope of this - * local variable (inclusive). - * @param end the last instruction corresponding to the scope of this local - * variable (exclusive). - * @param index the local variable's index. - */ - public LocalVariableNode(final String name, final String desc, final String signature, final LabelNode start, - final LabelNode end, final int index) { - this.name = name; - this.desc = desc; - this.signature = signature; - this.start = start; - this.end = end; - this.index = index; - } - - /** - * Makes the given visitor visit this local variable declaration. - * - * @param mv a method visitor. - */ - public void accept(final MethodVisitor mv) { - mv.visitLocalVariable(name, desc, signature, start.getLabel(), end.getLabel(), index); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/LookupSwitchInsnNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/LookupSwitchInsnNode.java deleted file mode 100644 index 0820a1b92..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/LookupSwitchInsnNode.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * A node that represents a LOOKUPSWITCH instruction. - * - * @author Eric Bruneton - */ -public class LookupSwitchInsnNode extends AbstractInsnNode { - - /** - * Beginning of the default handler block. - */ - public LabelNode dflt; - - /** - * The values of the keys. This list is a list of {@link Integer} objects. - */ - public List keys; - - /** - * Beginnings of the handler blocks. This list is a list of - * {@link LabelNode} objects. - */ - public List labels; - - /** - * Constructs a new {@link LookupSwitchInsnNode}. - * - * @param dflt beginning of the default handler block. - * @param keys the values of the keys. - * @param labels beginnings of the handler blocks. labels[i] is the - * beginning of the handler block for the keys[i] key. - */ - public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys, final LabelNode[] labels) { - super(Opcodes.LOOKUPSWITCH); - this.dflt = dflt; - this.keys = new ArrayList(keys == null ? 0 : keys.length); - this.labels = new ArrayList(labels == null ? 0 : labels.length); - if (keys != null) { - for (int i = 0; i < keys.length; ++i) { - this.keys.add(new Integer(keys[i])); - } - } - if (labels != null) { - this.labels.addAll(Arrays.asList(labels)); - } - } - - @Override - public int getType() { - return LOOKUPSWITCH_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - int[] keys = new int[this.keys.size()]; - for (int i = 0; i < keys.length; ++i) { - keys[i] = ((Integer) this.keys.get(i)).intValue(); - } - Label[] labels = new Label[this.labels.size()]; - for (int i = 0; i < labels.length; ++i) { - labels[i] = ((LabelNode) this.labels.get(i)).getLabel(); - } - mv.visitLookupSwitchInsn(dflt.getLabel(), keys, labels); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - LookupSwitchInsnNode clone = new LookupSwitchInsnNode(clone(dflt, labels), null, clone(this.labels, labels)); - clone.keys.addAll(keys); - return clone; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/MemberNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/MemberNode.java deleted file mode 100644 index 7d97f99b5..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/MemberNode.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.ArrayList; -import java.util.List; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; - -/** - * An abstract class, field or method node. - * - * @author Eric Bruneton - */ -public abstract class MemberNode { - - /** - * The runtime visible annotations of this class, field or method. This list - * is a list of {@link AnnotationNode} objects. May be null. - * - * @associates com.alibaba.citrus.asm.tree.AnnotationNode - * @label visible - */ - public List visibleAnnotations; - - /** - * The runtime invisible annotations of this class, field or method. This - * list is a list of {@link AnnotationNode} objects. May be null. - * - * @associates com.alibaba.citrus.asm.tree.AnnotationNode - * @label invisible - */ - public List invisibleAnnotations; - - /** - * The non standard attributes of this class, field or method. This list is - * a list of {@link Attribute} objects. May be null. - * - * @associates com.alibaba.citrus.asm.Attribute - */ - public List attrs; - - /** - * Constructs a new {@link MemberNode}. - */ - protected MemberNode() { - } - - /** - * Visits an annotation of this class, field or method. - * - * @param desc the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values. - */ - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - AnnotationNode an = new AnnotationNode(desc); - if (visible) { - if (visibleAnnotations == null) { - visibleAnnotations = new ArrayList(1); - } - visibleAnnotations.add(an); - } else { - if (invisibleAnnotations == null) { - invisibleAnnotations = new ArrayList(1); - } - invisibleAnnotations.add(an); - } - return an; - } - - /** - * Visits a non standard attribute of this class, field or method. - * - * @param attr an attribute. - */ - public void visitAttribute(final Attribute attr) { - if (attrs == null) { - attrs = new ArrayList(1); - } - attrs.add(attr); - } - - /** - * Visits the end of this class, field or method. - */ - public void visitEnd() { - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/MethodInsnNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/MethodInsnNode.java deleted file mode 100644 index 6c078d5e2..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/MethodInsnNode.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.Map; - -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * A node that represents a method instruction. A method instruction is an - * instruction that invokes a method. - * - * @author Eric Bruneton - */ -public class MethodInsnNode extends AbstractInsnNode { - - /** - * The internal name of the method's owner class (see - * {@link com.alibaba.citrus.asm.Type#getInternalName() getInternalName}). - */ - public String owner; - - /** - * The method's name. - */ - public String name; - - /** - * The method's descriptor (see {@link com.alibaba.citrus.asm.Type}). - */ - public String desc; - - /** - * Constructs a new {@link MethodInsnNode}. - * - * @param opcode the opcode of the type instruction to be constructed. This - * opcode must be INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or - * INVOKEINTERFACE. - * @param owner the internal name of the method's owner class (see - * {@link com.alibaba.citrus.asm.Type#getInternalName() - * getInternalName}). - * @param name the method's name. - * @param desc the method's descriptor (see - * {@link com.alibaba.citrus.asm.Type}). - */ - public MethodInsnNode(final int opcode, final String owner, final String name, final String desc) { - super(opcode); - this.owner = owner; - this.name = name; - this.desc = desc; - } - - /** - * Sets the opcode of this instruction. - * - * @param opcode the new instruction opcode. This opcode must be - * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE. - */ - public void setOpcode(final int opcode) { - this.opcode = opcode; - } - - @Override - public int getType() { - return METHOD_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitMethodInsn(opcode, owner, name, desc); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new MethodInsnNode(opcode, owner, name, desc); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/MethodNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/MethodNode.java deleted file mode 100644 index ac78f747a..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/MethodNode.java +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; - -/** - * A node that represents a method. - * - * @author Eric Bruneton - */ -public class MethodNode extends MemberNode implements MethodVisitor { - - /** - * The method's access flags (see {@link Opcodes}). This field also - * indicates if the method is synthetic and/or deprecated. - */ - public int access; - - /** - * The method's name. - */ - public String name; - - /** - * The method's descriptor (see {@link Type}). - */ - public String desc; - - /** - * The method's signature. May be null. - */ - public String signature; - - /** - * The internal names of the method's exception classes (see - * {@link Type#getInternalName() getInternalName}). This list is a list of - * {@link String} objects. - */ - public List exceptions; - - /** - * The default value of this annotation interface method. This field must be - * a {@link Byte}, {@link Boolean}, {@link Character}, {@link Short}, - * {@link Integer}, {@link Long}, {@link Float}, {@link Double}, - * {@link String} or {@link Type}, or an two elements String array (for - * enumeration values), a {@link AnnotationNode}, or a {@link List} of - * values of one of the preceding types. May be null. - */ - public Object annotationDefault; - - /** - * The runtime visible parameter annotations of this method. These lists are - * lists of {@link AnnotationNode} objects. May be null. - * - * @associates com.alibaba.citrus.asm.tree.AnnotationNode - * @label invisible parameters - */ - public List[] visibleParameterAnnotations; - - /** - * The runtime invisible parameter annotations of this method. These lists - * are lists of {@link AnnotationNode} objects. May be null. - * - * @associates com.alibaba.citrus.asm.tree.AnnotationNode - * @label visible parameters - */ - public List[] invisibleParameterAnnotations; - - /** - * The instructions of this method. This list is a list of - * {@link AbstractInsnNode} objects. - * - * @associates com.alibaba.citrus.asm.tree.AbstractInsnNode - * @label instructions - */ - public InsnList instructions; - - /** - * The try catch blocks of this method. This list is a list of - * {@link TryCatchBlockNode} objects. - * - * @associates com.alibaba.citrus.asm.tree.TryCatchBlockNode - */ - public List tryCatchBlocks; - - /** - * The maximum stack size of this method. - */ - public int maxStack; - - /** - * The maximum number of local variables of this method. - */ - public int maxLocals; - - /** - * The local variables of this method. This list is a list of - * {@link LocalVariableNode} objects. May be null - * - * @associates com.alibaba.citrus.asm.tree.LocalVariableNode - */ - public List localVariables; - - /** - * Constructs an unitialized {@link MethodNode}. - */ - public MethodNode() { - this.instructions = new InsnList(); - } - - /** - * Constructs a new {@link MethodNode}. - * - * @param access the method's access flags (see {@link Opcodes}). This - * parameter also indicates if the method is synthetic and/or - * deprecated. - * @param name the method's name. - * @param desc the method's descriptor (see {@link Type}). - * @param signature the method's signature. May be null. - * @param exceptions the internal names of the method's exception classes - * (see {@link Type#getInternalName() getInternalName}). May be - * null. - */ - public MethodNode(final int access, final String name, final String desc, final String signature, - final String[] exceptions) { - this(); - this.access = access; - this.name = name; - this.desc = desc; - this.signature = signature; - this.exceptions = new ArrayList(exceptions == null ? 0 : exceptions.length); - boolean isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0; - if (!isAbstract) { - this.localVariables = new ArrayList(5); - } - this.tryCatchBlocks = new ArrayList(); - if (exceptions != null) { - this.exceptions.addAll(Arrays.asList(exceptions)); - } - } - - // ------------------------------------------------------------------------ - // Implementation of the MethodVisitor interface - // ------------------------------------------------------------------------ - - public AnnotationVisitor visitAnnotationDefault() { - return new AnnotationNode(new ArrayList(0) { - private static final long serialVersionUID = 2234167535779425609L; - - @Override - public boolean add(final Object o) { - annotationDefault = o; - return super.add(o); - } - }); - } - - public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc, final boolean visible) { - AnnotationNode an = new AnnotationNode(desc); - if (visible) { - if (visibleParameterAnnotations == null) { - int params = Type.getArgumentTypes(this.desc).length; - visibleParameterAnnotations = new List[params]; - } - if (visibleParameterAnnotations[parameter] == null) { - visibleParameterAnnotations[parameter] = new ArrayList(1); - } - visibleParameterAnnotations[parameter].add(an); - } else { - if (invisibleParameterAnnotations == null) { - int params = Type.getArgumentTypes(this.desc).length; - invisibleParameterAnnotations = new List[params]; - } - if (invisibleParameterAnnotations[parameter] == null) { - invisibleParameterAnnotations[parameter] = new ArrayList(1); - } - invisibleParameterAnnotations[parameter].add(an); - } - return an; - } - - public void visitCode() { - } - - public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, - final Object[] stack) { - instructions.add(new FrameNode(type, nLocal, local == null ? null : getLabelNodes(local), nStack, - stack == null ? null : getLabelNodes(stack))); - } - - public void visitInsn(final int opcode) { - instructions.add(new InsnNode(opcode)); - } - - public void visitIntInsn(final int opcode, final int operand) { - instructions.add(new IntInsnNode(opcode, operand)); - } - - public void visitVarInsn(final int opcode, final int var) { - instructions.add(new VarInsnNode(opcode, var)); - } - - public void visitTypeInsn(final int opcode, final String type) { - instructions.add(new TypeInsnNode(opcode, type)); - } - - public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { - instructions.add(new FieldInsnNode(opcode, owner, name, desc)); - } - - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - instructions.add(new MethodInsnNode(opcode, owner, name, desc)); - } - - public void visitJumpInsn(final int opcode, final Label label) { - instructions.add(new JumpInsnNode(opcode, getLabelNode(label))); - } - - public void visitLabel(final Label label) { - instructions.add(getLabelNode(label)); - } - - public void visitLdcInsn(final Object cst) { - instructions.add(new LdcInsnNode(cst)); - } - - public void visitIincInsn(final int var, final int increment) { - instructions.add(new IincInsnNode(var, increment)); - } - - public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label[] labels) { - instructions.add(new TableSwitchInsnNode(min, max, getLabelNode(dflt), getLabelNodes(labels))); - } - - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { - instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt), keys, getLabelNodes(labels))); - } - - public void visitMultiANewArrayInsn(final String desc, final int dims) { - instructions.add(new MultiANewArrayInsnNode(desc, dims)); - } - - public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type) { - tryCatchBlocks.add(new TryCatchBlockNode(getLabelNode(start), getLabelNode(end), getLabelNode(handler), type)); - } - - public void visitLocalVariable(final String name, final String desc, final String signature, final Label start, - final Label end, final int index) { - localVariables.add(new LocalVariableNode(name, desc, signature, getLabelNode(start), getLabelNode(end), index)); - } - - public void visitLineNumber(final int line, final Label start) { - instructions.add(new LineNumberNode(line, getLabelNode(start))); - } - - public void visitMaxs(final int maxStack, final int maxLocals) { - this.maxStack = maxStack; - this.maxLocals = maxLocals; - } - - /** - * Returns the LabelNode corresponding to the given Label. Creates a new - * LabelNode if necessary. The default implementation of this method uses - * the {@link Label#info} field to store associations between labels and - * label nodes. - * - * @param l a Label. - * @return the LabelNode corresponding to l. - */ - protected LabelNode getLabelNode(final Label l) { - if (!(l.info instanceof LabelNode)) { - l.info = new LabelNode(l); - } - return (LabelNode) l.info; - } - - private LabelNode[] getLabelNodes(final Label[] l) { - LabelNode[] nodes = new LabelNode[l.length]; - for (int i = 0; i < l.length; ++i) { - nodes[i] = getLabelNode(l[i]); - } - return nodes; - } - - private Object[] getLabelNodes(final Object[] objs) { - Object[] nodes = new Object[objs.length]; - for (int i = 0; i < objs.length; ++i) { - Object o = objs[i]; - if (o instanceof Label) { - o = getLabelNode((Label) o); - } - nodes[i] = o; - } - return nodes; - } - - // ------------------------------------------------------------------------ - // Accept method - // ------------------------------------------------------------------------ - - /** - * Makes the given class visitor visit this method. - * - * @param cv a class visitor. - */ - public void accept(final ClassVisitor cv) { - String[] exceptions = new String[this.exceptions.size()]; - this.exceptions.toArray(exceptions); - MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); - if (mv != null) { - accept(mv); - } - } - - /** - * Makes the given method visitor visit this method. - * - * @param mv a method visitor. - */ - public void accept(final MethodVisitor mv) { - // visits the method attributes - int i, j, n; - if (annotationDefault != null) { - AnnotationVisitor av = mv.visitAnnotationDefault(); - AnnotationNode.accept(av, null, annotationDefault); - if (av != null) { - av.visitEnd(); - } - } - n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); - for (i = 0; i < n; ++i) { - AnnotationNode an = (AnnotationNode) visibleAnnotations.get(i); - an.accept(mv.visitAnnotation(an.desc, true)); - } - n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); - for (i = 0; i < n; ++i) { - AnnotationNode an = (AnnotationNode) invisibleAnnotations.get(i); - an.accept(mv.visitAnnotation(an.desc, false)); - } - n = visibleParameterAnnotations == null ? 0 : visibleParameterAnnotations.length; - for (i = 0; i < n; ++i) { - List l = visibleParameterAnnotations[i]; - if (l == null) { - continue; - } - for (j = 0; j < l.size(); ++j) { - AnnotationNode an = (AnnotationNode) l.get(j); - an.accept(mv.visitParameterAnnotation(i, an.desc, true)); - } - } - n = invisibleParameterAnnotations == null ? 0 : invisibleParameterAnnotations.length; - for (i = 0; i < n; ++i) { - List l = invisibleParameterAnnotations[i]; - if (l == null) { - continue; - } - for (j = 0; j < l.size(); ++j) { - AnnotationNode an = (AnnotationNode) l.get(j); - an.accept(mv.visitParameterAnnotation(i, an.desc, false)); - } - } - n = attrs == null ? 0 : attrs.size(); - for (i = 0; i < n; ++i) { - mv.visitAttribute((Attribute) attrs.get(i)); - } - // visits the method's code - if (instructions.size() > 0) { - mv.visitCode(); - // visits try catch blocks - for (i = 0; i < tryCatchBlocks.size(); ++i) { - ((TryCatchBlockNode) tryCatchBlocks.get(i)).accept(mv); - } - // visits instructions - instructions.accept(mv); - // visits local variables - n = localVariables == null ? 0 : localVariables.size(); - for (i = 0; i < n; ++i) { - ((LocalVariableNode) localVariables.get(i)).accept(mv); - } - // visits maxs - mv.visitMaxs(maxStack, maxLocals); - } - mv.visitEnd(); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/MultiANewArrayInsnNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/MultiANewArrayInsnNode.java deleted file mode 100644 index b3f2a5c62..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/MultiANewArrayInsnNode.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.Map; - -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * A node that represents a MULTIANEWARRAY instruction. - * - * @author Eric Bruneton - */ -public class MultiANewArrayInsnNode extends AbstractInsnNode { - - /** - * An array type descriptor (see {@link com.alibaba.citrus.asm.Type}). - */ - public String desc; - - /** - * Number of dimensions of the array to allocate. - */ - public int dims; - - /** - * Constructs a new {@link MultiANewArrayInsnNode}. - * - * @param desc an array type descriptor (see - * {@link com.alibaba.citrus.asm.Type}). - * @param dims number of dimensions of the array to allocate. - */ - public MultiANewArrayInsnNode(final String desc, final int dims) { - super(Opcodes.MULTIANEWARRAY); - this.desc = desc; - this.dims = dims; - } - - @Override - public int getType() { - return MULTIANEWARRAY_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitMultiANewArrayInsn(desc, dims); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new MultiANewArrayInsnNode(desc, dims); - } - -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/TableSwitchInsnNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/TableSwitchInsnNode.java deleted file mode 100644 index e43cca330..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/TableSwitchInsnNode.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * A node that represents a TABLESWITCH instruction. - * - * @author Eric Bruneton - */ -public class TableSwitchInsnNode extends AbstractInsnNode { - - /** - * The minimum key value. - */ - public int min; - - /** - * The maximum key value. - */ - public int max; - - /** - * Beginning of the default handler block. - */ - public LabelNode dflt; - - /** - * Beginnings of the handler blocks. This list is a list of - * {@link LabelNode} objects. - */ - public List labels; - - /** - * Constructs a new {@link TableSwitchInsnNode}. - * - * @param min the minimum key value. - * @param max the maximum key value. - * @param dflt beginning of the default handler block. - * @param labels beginnings of the handler blocks. labels[i] is the - * beginning of the handler block for the min + i key. - */ - public TableSwitchInsnNode(final int min, final int max, final LabelNode dflt, final LabelNode[] labels) { - super(Opcodes.TABLESWITCH); - this.min = min; - this.max = max; - this.dflt = dflt; - this.labels = new ArrayList(); - if (labels != null) { - this.labels.addAll(Arrays.asList(labels)); - } - } - - @Override - public int getType() { - return TABLESWITCH_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - Label[] labels = new Label[this.labels.size()]; - for (int i = 0; i < labels.length; ++i) { - labels[i] = ((LabelNode) this.labels.get(i)).getLabel(); - } - mv.visitTableSwitchInsn(min, max, dflt.getLabel(), labels); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new TableSwitchInsnNode(min, max, clone(dflt, labels), clone(this.labels, labels)); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/TryCatchBlockNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/TryCatchBlockNode.java deleted file mode 100644 index e98567585..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/TryCatchBlockNode.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * A node that represents a try catch block. - * - * @author Eric Bruneton - */ -public class TryCatchBlockNode { - - /** - * Beginning of the exception handler's scope (inclusive). - */ - public LabelNode start; - - /** - * End of the exception handler's scope (exclusive). - */ - public LabelNode end; - - /** - * Beginning of the exception handler's code. - */ - public LabelNode handler; - - /** - * Internal name of the type of exceptions handled by the handler. May be - * null to catch any exceptions (for "finally" blocks). - */ - public String type; - - /** - * Constructs a new {@link TryCatchBlockNode}. - * - * @param start beginning of the exception handler's scope (inclusive). - * @param end end of the exception handler's scope (exclusive). - * @param handler beginning of the exception handler's code. - * @param type internal name of the type of exceptions handled by the - * handler, or null to catch any exceptions (for - * "finally" blocks). - */ - public TryCatchBlockNode(final LabelNode start, final LabelNode end, final LabelNode handler, final String type) { - this.start = start; - this.end = end; - this.handler = handler; - this.type = type; - } - - /** - * Makes the given visitor visit this try catch block. - * - * @param mv a method visitor. - */ - public void accept(final MethodVisitor mv) { - mv.visitTryCatchBlock(start.getLabel(), end.getLabel(), handler == null ? null : handler.getLabel(), type); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/TypeInsnNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/TypeInsnNode.java deleted file mode 100644 index 68347899d..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/TypeInsnNode.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.Map; - -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * A node that represents a type instruction. A type instruction is an - * instruction that takes a type descriptor as parameter. - * - * @author Eric Bruneton - */ -public class TypeInsnNode extends AbstractInsnNode { - - /** - * The operand of this instruction. This operand is an internal name (see - * {@link com.alibaba.citrus.asm.Type}). - */ - public String desc; - - /** - * Constructs a new {@link TypeInsnNode}. - * - * @param opcode the opcode of the type instruction to be constructed. This - * opcode must be NEW, ANEWARRAY, CHECKCAST or INSTANCEOF. - * @param desc the operand of the instruction to be constructed. This - * operand is an internal name (see - * {@link com.alibaba.citrus.asm.Type}). - */ - public TypeInsnNode(final int opcode, final String desc) { - super(opcode); - this.desc = desc; - } - - /** - * Sets the opcode of this instruction. - * - * @param opcode the new instruction opcode. This opcode must be NEW, - * ANEWARRAY, CHECKCAST or INSTANCEOF. - */ - public void setOpcode(final int opcode) { - this.opcode = opcode; - } - - @Override - public int getType() { - return TYPE_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitTypeInsn(opcode, desc); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new TypeInsnNode(opcode, desc); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/VarInsnNode.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/VarInsnNode.java deleted file mode 100644 index 3eca06140..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/VarInsnNode.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.Map; - -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * A node that represents a local variable instruction. A local variable - * instruction is an instruction that loads or stores the value of a local - * variable. - * - * @author Eric Bruneton - */ -public class VarInsnNode extends AbstractInsnNode { - - /** - * The operand of this instruction. This operand is the index of a local - * variable. - */ - public int var; - - /** - * Constructs a new {@link VarInsnNode}. - * - * @param opcode the opcode of the local variable instruction to be - * constructed. This opcode must be ILOAD, LLOAD, FLOAD, DLOAD, - * ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET. - * @param var the operand of the instruction to be constructed. This operand - * is the index of a local variable. - */ - public VarInsnNode(final int opcode, final int var) { - super(opcode); - this.var = var; - } - - /** - * Sets the opcode of this instruction. - * - * @param opcode the new instruction opcode. This opcode must be ILOAD, - * LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, - * ASTORE or RET. - */ - public void setOpcode(final int opcode) { - this.opcode = opcode; - } - - @Override - public int getType() { - return VAR_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitVarInsn(opcode, var); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new VarInsnNode(opcode, var); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Analyzer.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Analyzer.java deleted file mode 100644 index b352a164c..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Analyzer.java +++ /dev/null @@ -1,494 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; -import com.alibaba.citrus.asm.tree.AbstractInsnNode; -import com.alibaba.citrus.asm.tree.IincInsnNode; -import com.alibaba.citrus.asm.tree.InsnList; -import com.alibaba.citrus.asm.tree.JumpInsnNode; -import com.alibaba.citrus.asm.tree.LabelNode; -import com.alibaba.citrus.asm.tree.LookupSwitchInsnNode; -import com.alibaba.citrus.asm.tree.MethodNode; -import com.alibaba.citrus.asm.tree.TableSwitchInsnNode; -import com.alibaba.citrus.asm.tree.TryCatchBlockNode; -import com.alibaba.citrus.asm.tree.VarInsnNode; - -/** - * A semantic bytecode analyzer. This class does not fully check that JSR and - * RET instructions are valid. - * - * @author Eric Bruneton - */ -public class Analyzer implements Opcodes { - - private final Interpreter interpreter; - - private int n; - - private InsnList insns; - - private List[] handlers; - - private Frame[] frames; - - private Subroutine[] subroutines; - - private boolean[] queued; - - private int[] queue; - - private int top; - - /** - * Constructs a new {@link Analyzer}. - * - * @param interpreter the interpreter to be used to symbolically interpret - * the bytecode instructions. - */ - public Analyzer(final Interpreter interpreter) { - this.interpreter = interpreter; - } - - /** - * Analyzes the given method. - * - * @param owner the internal name of the class to which the method belongs. - * @param m the method to be analyzed. - * @return the symbolic state of the execution stack frame at each bytecode - * instruction of the method. The size of the returned array is - * equal to the number of instructions (and labels) of the method. A - * given frame is null if and only if the corresponding - * instruction cannot be reached (dead code). - * @throws AnalyzerException if a problem occurs during the analysis. - */ - public Frame[] analyze(final String owner, final MethodNode m) throws AnalyzerException { - if ((m.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0) { - frames = new Frame[0]; - return frames; - } - n = m.instructions.size(); - insns = m.instructions; - handlers = new List[n]; - frames = new Frame[n]; - subroutines = new Subroutine[n]; - queued = new boolean[n]; - queue = new int[n]; - top = 0; - - // computes exception handlers for each instruction - for (int i = 0; i < m.tryCatchBlocks.size(); ++i) { - TryCatchBlockNode tcb = (TryCatchBlockNode) m.tryCatchBlocks.get(i); - int begin = insns.indexOf(tcb.start); - int end = insns.indexOf(tcb.end); - for (int j = begin; j < end; ++j) { - List insnHandlers = handlers[j]; - if (insnHandlers == null) { - insnHandlers = new ArrayList(); - handlers[j] = insnHandlers; - } - insnHandlers.add(tcb); - } - } - - // computes the subroutine for each instruction: - Subroutine main = new Subroutine(null, m.maxLocals, null); - List subroutineCalls = new ArrayList(); - Map subroutineHeads = new HashMap(); - findSubroutine(0, main, subroutineCalls); - while (!subroutineCalls.isEmpty()) { - JumpInsnNode jsr = (JumpInsnNode) subroutineCalls.remove(0); - Subroutine sub = (Subroutine) subroutineHeads.get(jsr.label); - if (sub == null) { - sub = new Subroutine(jsr.label, m.maxLocals, jsr); - subroutineHeads.put(jsr.label, sub); - findSubroutine(insns.indexOf(jsr.label), sub, subroutineCalls); - } else { - sub.callers.add(jsr); - } - } - for (int i = 0; i < n; ++i) { - if (subroutines[i] != null && subroutines[i].start == null) { - subroutines[i] = null; - } - } - - // initializes the data structures for the control flow analysis - Frame current = newFrame(m.maxLocals, m.maxStack); - Frame handler = newFrame(m.maxLocals, m.maxStack); - Type[] args = Type.getArgumentTypes(m.desc); - int local = 0; - if ((m.access & ACC_STATIC) == 0) { - Type ctype = Type.getObjectType(owner); - current.setLocal(local++, interpreter.newValue(ctype)); - } - for (int i = 0; i < args.length; ++i) { - current.setLocal(local++, interpreter.newValue(args[i])); - if (args[i].getSize() == 2) { - current.setLocal(local++, interpreter.newValue(null)); - } - } - while (local < m.maxLocals) { - current.setLocal(local++, interpreter.newValue(null)); - } - merge(0, current, null); - - // control flow analysis - while (top > 0) { - int insn = queue[--top]; - Frame f = frames[insn]; - Subroutine subroutine = subroutines[insn]; - queued[insn] = false; - - try { - AbstractInsnNode insnNode = m.instructions.get(insn); - int insnOpcode = insnNode.getOpcode(); - int insnType = insnNode.getType(); - - if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE - || insnType == AbstractInsnNode.FRAME) { - merge(insn + 1, f, subroutine); - newControlFlowEdge(insn, insn + 1); - } else { - current.init(f).execute(insnNode, interpreter); - subroutine = subroutine == null ? null : subroutine.copy(); - - if (insnNode instanceof JumpInsnNode) { - JumpInsnNode j = (JumpInsnNode) insnNode; - if (insnOpcode != GOTO && insnOpcode != JSR) { - merge(insn + 1, current, subroutine); - newControlFlowEdge(insn, insn + 1); - } - int jump = insns.indexOf(j.label); - if (insnOpcode == JSR) { - merge(jump, current, new Subroutine(j.label, m.maxLocals, j)); - } else { - merge(jump, current, subroutine); - } - newControlFlowEdge(insn, jump); - } else if (insnNode instanceof LookupSwitchInsnNode) { - LookupSwitchInsnNode lsi = (LookupSwitchInsnNode) insnNode; - int jump = insns.indexOf(lsi.dflt); - merge(jump, current, subroutine); - newControlFlowEdge(insn, jump); - for (int j = 0; j < lsi.labels.size(); ++j) { - LabelNode label = (LabelNode) lsi.labels.get(j); - jump = insns.indexOf(label); - merge(jump, current, subroutine); - newControlFlowEdge(insn, jump); - } - } else if (insnNode instanceof TableSwitchInsnNode) { - TableSwitchInsnNode tsi = (TableSwitchInsnNode) insnNode; - int jump = insns.indexOf(tsi.dflt); - merge(jump, current, subroutine); - newControlFlowEdge(insn, jump); - for (int j = 0; j < tsi.labels.size(); ++j) { - LabelNode label = (LabelNode) tsi.labels.get(j); - jump = insns.indexOf(label); - merge(jump, current, subroutine); - newControlFlowEdge(insn, jump); - } - } else if (insnOpcode == RET) { - if (subroutine == null) { - throw new AnalyzerException("RET instruction outside of a sub routine"); - } - for (int i = 0; i < subroutine.callers.size(); ++i) { - Object caller = subroutine.callers.get(i); - int call = insns.indexOf((AbstractInsnNode) caller); - if (frames[call] != null) { - merge(call + 1, frames[call], current, subroutines[call], subroutine.access); - newControlFlowEdge(insn, call + 1); - } - } - } else if (insnOpcode != ATHROW && (insnOpcode < IRETURN || insnOpcode > RETURN)) { - if (subroutine != null) { - if (insnNode instanceof VarInsnNode) { - int var = ((VarInsnNode) insnNode).var; - subroutine.access[var] = true; - if (insnOpcode == LLOAD || insnOpcode == DLOAD || insnOpcode == LSTORE - || insnOpcode == DSTORE) { - subroutine.access[var + 1] = true; - } - } else if (insnNode instanceof IincInsnNode) { - int var = ((IincInsnNode) insnNode).var; - subroutine.access[var] = true; - } - } - merge(insn + 1, current, subroutine); - newControlFlowEdge(insn, insn + 1); - } - } - - List insnHandlers = handlers[insn]; - if (insnHandlers != null) { - for (int i = 0; i < insnHandlers.size(); ++i) { - TryCatchBlockNode tcb = (TryCatchBlockNode) insnHandlers.get(i); - Type type; - if (tcb.type == null) { - type = Type.getObjectType("java/lang/Throwable"); - } else { - type = Type.getObjectType(tcb.type); - } - int jump = insns.indexOf(tcb.handler); - if (newControlFlowExceptionEdge(insn, jump)) { - handler.init(f); - handler.clearStack(); - handler.push(interpreter.newValue(type)); - merge(jump, handler, subroutine); - } - } - } - } catch (AnalyzerException e) { - throw new AnalyzerException("Error at instruction " + insn + ": " + e.getMessage(), e); - } catch (Exception e) { - throw new AnalyzerException("Error at instruction " + insn + ": " + e.getMessage(), e); - } - } - - return frames; - } - - private void findSubroutine(int insn, final Subroutine sub, final List calls) throws AnalyzerException { - while (true) { - if (insn < 0 || insn >= n) { - throw new AnalyzerException("Execution can fall off end of the code"); - } - if (subroutines[insn] != null) { - return; - } - subroutines[insn] = sub.copy(); - AbstractInsnNode node = insns.get(insn); - - // calls findSubroutine recursively on normal successors - if (node instanceof JumpInsnNode) { - if (node.getOpcode() == JSR) { - // do not follow a JSR, it leads to another subroutine! - calls.add(node); - } else { - JumpInsnNode jnode = (JumpInsnNode) node; - findSubroutine(insns.indexOf(jnode.label), sub, calls); - } - } else if (node instanceof TableSwitchInsnNode) { - TableSwitchInsnNode tsnode = (TableSwitchInsnNode) node; - findSubroutine(insns.indexOf(tsnode.dflt), sub, calls); - for (int i = tsnode.labels.size() - 1; i >= 0; --i) { - LabelNode l = (LabelNode) tsnode.labels.get(i); - findSubroutine(insns.indexOf(l), sub, calls); - } - } else if (node instanceof LookupSwitchInsnNode) { - LookupSwitchInsnNode lsnode = (LookupSwitchInsnNode) node; - findSubroutine(insns.indexOf(lsnode.dflt), sub, calls); - for (int i = lsnode.labels.size() - 1; i >= 0; --i) { - LabelNode l = (LabelNode) lsnode.labels.get(i); - findSubroutine(insns.indexOf(l), sub, calls); - } - } - - // calls findSubroutine recursively on exception handler successors - List insnHandlers = handlers[insn]; - if (insnHandlers != null) { - for (int i = 0; i < insnHandlers.size(); ++i) { - TryCatchBlockNode tcb = (TryCatchBlockNode) insnHandlers.get(i); - findSubroutine(insns.indexOf(tcb.handler), sub, calls); - } - } - - // if insn does not falls through to the next instruction, return. - switch (node.getOpcode()) { - case GOTO: - case RET: - case TABLESWITCH: - case LOOKUPSWITCH: - case IRETURN: - case LRETURN: - case FRETURN: - case DRETURN: - case ARETURN: - case RETURN: - case ATHROW: - return; - } - insn++; - } - } - - /** - * Returns the symbolic stack frame for each instruction of the last - * recently analyzed method. - * - * @return the symbolic state of the execution stack frame at each bytecode - * instruction of the method. The size of the returned array is - * equal to the number of instructions (and labels) of the method. A - * given frame is null if the corresponding instruction - * cannot be reached, or if an error occured during the analysis of - * the method. - */ - public Frame[] getFrames() { - return frames; - } - - /** - * Returns the exception handlers for the given instruction. - * - * @param insn the index of an instruction of the last recently analyzed - * method. - * @return a list of {@link TryCatchBlockNode} objects. - */ - public List getHandlers(final int insn) { - return handlers[insn]; - } - - /** - * Constructs a new frame with the given size. - * - * @param nLocals the maximum number of local variables of the frame. - * @param nStack the maximum stack size of the frame. - * @return the created frame. - */ - protected Frame newFrame(final int nLocals, final int nStack) { - return new Frame(nLocals, nStack); - } - - /** - * Constructs a new frame that is identical to the given frame. - * - * @param src a frame. - * @return the created frame. - */ - protected Frame newFrame(final Frame src) { - return new Frame(src); - } - - /** - * Creates a control flow graph edge. The default implementation of this - * method does nothing. It can be overriden in order to construct the - * control flow graph of a method (this method is called by the - * {@link #analyze analyze} method during its visit of the method's code). - * - * @param insn an instruction index. - * @param successor index of a successor instruction. - */ - protected void newControlFlowEdge(final int insn, final int successor) { - } - - /** - * Creates a control flow graph edge corresponding to an exception handler. - * The default implementation of this method does nothing. It can be - * overriden in order to construct the control flow graph of a method (this - * method is called by the {@link #analyze analyze} method during its visit - * of the method's code). - * - * @param insn an instruction index. - * @param successor index of a successor instruction. - * @return true if this edge must be considered in the data flow analysis - * performed by this analyzer, or false otherwise. The default - * implementation of this method always returns true. - */ - protected boolean newControlFlowExceptionEdge(final int insn, final int successor) { - return true; - } - - // ------------------------------------------------------------------------- - - private void merge(final int insn, final Frame frame, final Subroutine subroutine) throws AnalyzerException { - Frame oldFrame = frames[insn]; - Subroutine oldSubroutine = subroutines[insn]; - boolean changes; - - if (oldFrame == null) { - frames[insn] = newFrame(frame); - changes = true; - } else { - changes = oldFrame.merge(frame, interpreter); - } - - if (oldSubroutine == null) { - if (subroutine != null) { - subroutines[insn] = subroutine.copy(); - changes = true; - } - } else { - if (subroutine != null) { - changes |= oldSubroutine.merge(subroutine); - } - } - if (changes && !queued[insn]) { - queued[insn] = true; - queue[top++] = insn; - } - } - - private void merge(final int insn, final Frame beforeJSR, final Frame afterRET, - final Subroutine subroutineBeforeJSR, final boolean[] access) throws AnalyzerException { - Frame oldFrame = frames[insn]; - Subroutine oldSubroutine = subroutines[insn]; - boolean changes; - - afterRET.merge(beforeJSR, access); - - if (oldFrame == null) { - frames[insn] = newFrame(afterRET); - changes = true; - } else { - changes = oldFrame.merge(afterRET, access); - } - - if (oldSubroutine != null && subroutineBeforeJSR != null) { - changes |= oldSubroutine.merge(subroutineBeforeJSR); - } - if (changes && !queued[insn]) { - queued[insn] = true; - queue[top++] = insn; - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/AnalyzerException.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/AnalyzerException.java deleted file mode 100644 index bd5bc4c8a..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/AnalyzerException.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -/** - * Thrown if a problem occurs during the analysis of a method. - * - * @author Bing Ran - * @author Eric Bruneton - */ -public class AnalyzerException extends Exception { - - private static final long serialVersionUID = -4536650880210566822L; - - public AnalyzerException(final String msg) { - super(msg); - } - - public AnalyzerException(final String msg, final Throwable exception) { - super(msg, exception); - } - - public AnalyzerException(final String msg, final Object expected, final Value encountered) { - super((msg == null ? "Expected " : msg + ": expected ") + expected + ", but found " + encountered); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/BasicInterpreter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/BasicInterpreter.java deleted file mode 100644 index 82b0a6c14..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/BasicInterpreter.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import java.util.List; - -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; -import com.alibaba.citrus.asm.tree.AbstractInsnNode; -import com.alibaba.citrus.asm.tree.FieldInsnNode; -import com.alibaba.citrus.asm.tree.IntInsnNode; -import com.alibaba.citrus.asm.tree.LdcInsnNode; -import com.alibaba.citrus.asm.tree.MethodInsnNode; -import com.alibaba.citrus.asm.tree.MultiANewArrayInsnNode; -import com.alibaba.citrus.asm.tree.TypeInsnNode; - -/** - * An {@link Interpreter} for {@link BasicValue} values. - * - * @author Eric Bruneton - * @author Bing Ran - */ -public class BasicInterpreter implements Opcodes, Interpreter { - - public Value newValue(final Type type) { - if (type == null) { - return BasicValue.UNINITIALIZED_VALUE; - } - switch (type.getSort()) { - case Type.VOID: - return null; - case Type.BOOLEAN: - case Type.CHAR: - case Type.BYTE: - case Type.SHORT: - case Type.INT: - return BasicValue.INT_VALUE; - case Type.FLOAT: - return BasicValue.FLOAT_VALUE; - case Type.LONG: - return BasicValue.LONG_VALUE; - case Type.DOUBLE: - return BasicValue.DOUBLE_VALUE; - case Type.ARRAY: - case Type.OBJECT: - return BasicValue.REFERENCE_VALUE; - default: - throw new Error("Internal error"); - } - } - - public Value newOperation(final AbstractInsnNode insn) { - switch (insn.getOpcode()) { - case ACONST_NULL: - return newValue(Type.getObjectType("null")); - case ICONST_M1: - case ICONST_0: - case ICONST_1: - case ICONST_2: - case ICONST_3: - case ICONST_4: - case ICONST_5: - return BasicValue.INT_VALUE; - case LCONST_0: - case LCONST_1: - return BasicValue.LONG_VALUE; - case FCONST_0: - case FCONST_1: - case FCONST_2: - return BasicValue.FLOAT_VALUE; - case DCONST_0: - case DCONST_1: - return BasicValue.DOUBLE_VALUE; - case BIPUSH: - case SIPUSH: - return BasicValue.INT_VALUE; - case LDC: - Object cst = ((LdcInsnNode) insn).cst; - if (cst instanceof Integer) { - return BasicValue.INT_VALUE; - } else if (cst instanceof Float) { - return BasicValue.FLOAT_VALUE; - } else if (cst instanceof Long) { - return BasicValue.LONG_VALUE; - } else if (cst instanceof Double) { - return BasicValue.DOUBLE_VALUE; - } else if (cst instanceof Type) { - return newValue(Type.getObjectType("java/lang/Class")); - } else { - return newValue(Type.getType(cst.getClass())); - } - case JSR: - return BasicValue.RETURNADDRESS_VALUE; - case GETSTATIC: - return newValue(Type.getType(((FieldInsnNode) insn).desc)); - case NEW: - return newValue(Type.getObjectType(((TypeInsnNode) insn).desc)); - default: - throw new Error("Internal error."); - } - } - - public Value copyOperation(final AbstractInsnNode insn, final Value value) throws AnalyzerException { - return value; - } - - public Value unaryOperation(final AbstractInsnNode insn, final Value value) throws AnalyzerException { - switch (insn.getOpcode()) { - case INEG: - case IINC: - case L2I: - case F2I: - case D2I: - case I2B: - case I2C: - case I2S: - return BasicValue.INT_VALUE; - case FNEG: - case I2F: - case L2F: - case D2F: - return BasicValue.FLOAT_VALUE; - case LNEG: - case I2L: - case F2L: - case D2L: - return BasicValue.LONG_VALUE; - case DNEG: - case I2D: - case L2D: - case F2D: - return BasicValue.DOUBLE_VALUE; - case IFEQ: - case IFNE: - case IFLT: - case IFGE: - case IFGT: - case IFLE: - case TABLESWITCH: - case LOOKUPSWITCH: - case IRETURN: - case LRETURN: - case FRETURN: - case DRETURN: - case ARETURN: - case PUTSTATIC: - return null; - case GETFIELD: - return newValue(Type.getType(((FieldInsnNode) insn).desc)); - case NEWARRAY: - switch (((IntInsnNode) insn).operand) { - case T_BOOLEAN: - return newValue(Type.getType("[Z")); - case T_CHAR: - return newValue(Type.getType("[C")); - case T_BYTE: - return newValue(Type.getType("[B")); - case T_SHORT: - return newValue(Type.getType("[S")); - case T_INT: - return newValue(Type.getType("[I")); - case T_FLOAT: - return newValue(Type.getType("[F")); - case T_DOUBLE: - return newValue(Type.getType("[D")); - case T_LONG: - return newValue(Type.getType("[J")); - default: - throw new AnalyzerException("Invalid array type"); - } - case ANEWARRAY: - String desc = ((TypeInsnNode) insn).desc; - return newValue(Type.getType("[" + Type.getObjectType(desc))); - case ARRAYLENGTH: - return BasicValue.INT_VALUE; - case ATHROW: - return null; - case CHECKCAST: - desc = ((TypeInsnNode) insn).desc; - return newValue(Type.getObjectType(desc)); - case INSTANCEOF: - return BasicValue.INT_VALUE; - case MONITORENTER: - case MONITOREXIT: - case IFNULL: - case IFNONNULL: - return null; - default: - throw new Error("Internal error."); - } - } - - public Value binaryOperation(final AbstractInsnNode insn, final Value value1, final Value value2) - throws AnalyzerException { - switch (insn.getOpcode()) { - case IALOAD: - case BALOAD: - case CALOAD: - case SALOAD: - case IADD: - case ISUB: - case IMUL: - case IDIV: - case IREM: - case ISHL: - case ISHR: - case IUSHR: - case IAND: - case IOR: - case IXOR: - return BasicValue.INT_VALUE; - case FALOAD: - case FADD: - case FSUB: - case FMUL: - case FDIV: - case FREM: - return BasicValue.FLOAT_VALUE; - case LALOAD: - case LADD: - case LSUB: - case LMUL: - case LDIV: - case LREM: - case LSHL: - case LSHR: - case LUSHR: - case LAND: - case LOR: - case LXOR: - return BasicValue.LONG_VALUE; - case DALOAD: - case DADD: - case DSUB: - case DMUL: - case DDIV: - case DREM: - return BasicValue.DOUBLE_VALUE; - case AALOAD: - return BasicValue.REFERENCE_VALUE; - case LCMP: - case FCMPL: - case FCMPG: - case DCMPL: - case DCMPG: - return BasicValue.INT_VALUE; - case IF_ICMPEQ: - case IF_ICMPNE: - case IF_ICMPLT: - case IF_ICMPGE: - case IF_ICMPGT: - case IF_ICMPLE: - case IF_ACMPEQ: - case IF_ACMPNE: - case PUTFIELD: - return null; - default: - throw new Error("Internal error."); - } - } - - public Value ternaryOperation(final AbstractInsnNode insn, final Value value1, final Value value2, - final Value value3) throws AnalyzerException { - return null; - } - - public Value naryOperation(final AbstractInsnNode insn, final List values) throws AnalyzerException { - if (insn.getOpcode() == MULTIANEWARRAY) { - return newValue(Type.getType(((MultiANewArrayInsnNode) insn).desc)); - } else { - return newValue(Type.getReturnType(((MethodInsnNode) insn).desc)); - } - } - - public Value merge(final Value v, final Value w) { - if (!v.equals(w)) { - return BasicValue.UNINITIALIZED_VALUE; - } - return v; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/BasicValue.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/BasicValue.java deleted file mode 100644 index d28e82471..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/BasicValue.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import com.alibaba.citrus.asm.Type; - -/** - * A {@link Value} that is represented by its type in a seven types type system. - * This type system distinguishes the UNINITIALZED, INT, FLOAT, LONG, DOUBLE, - * REFERENCE and RETURNADDRESS types. - * - * @author Eric Bruneton - */ -public class BasicValue implements Value { - - public static final Value UNINITIALIZED_VALUE = new BasicValue(null); - - public static final Value INT_VALUE = new BasicValue(Type.INT_TYPE); - - public static final Value FLOAT_VALUE = new BasicValue(Type.FLOAT_TYPE); - - public static final Value LONG_VALUE = new BasicValue(Type.LONG_TYPE); - - public static final Value DOUBLE_VALUE = new BasicValue(Type.DOUBLE_TYPE); - - public static final Value REFERENCE_VALUE = new BasicValue(Type.getObjectType("java/lang/Object")); - - public static final Value RETURNADDRESS_VALUE = new BasicValue(null); - - private final Type type; - - public BasicValue(final Type type) { - this.type = type; - } - - public Type getType() { - return type; - } - - public int getSize() { - return type == Type.LONG_TYPE || type == Type.DOUBLE_TYPE ? 2 : 1; - } - - public boolean isReference() { - return type != null && (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY); - } - - @Override - public boolean equals(final Object value) { - if (value == this) { - return true; - } else if (value instanceof BasicValue) { - if (type == null) { - return ((BasicValue) value).type == null; - } else { - return type.equals(((BasicValue) value).type); - } - } else { - return false; - } - } - - @Override - public int hashCode() { - return type == null ? 0 : type.hashCode(); - } - - @Override - public String toString() { - if (this == UNINITIALIZED_VALUE) { - return "."; - } else if (this == RETURNADDRESS_VALUE) { - return "A"; - } else if (this == REFERENCE_VALUE) { - return "R"; - } else { - return type.getDescriptor(); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/BasicVerifier.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/BasicVerifier.java deleted file mode 100644 index 25ca41858..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/BasicVerifier.java +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import java.util.List; - -import com.alibaba.citrus.asm.Type; -import com.alibaba.citrus.asm.tree.AbstractInsnNode; -import com.alibaba.citrus.asm.tree.FieldInsnNode; -import com.alibaba.citrus.asm.tree.MethodInsnNode; - -/** - * An extended {@link BasicInterpreter} that checks that bytecode instructions - * are correctly used. - * - * @author Eric Bruneton - * @author Bing Ran - */ -public class BasicVerifier extends BasicInterpreter { - - @Override - public Value copyOperation(final AbstractInsnNode insn, final Value value) throws AnalyzerException { - Value expected; - switch (insn.getOpcode()) { - case ILOAD: - case ISTORE: - expected = BasicValue.INT_VALUE; - break; - case FLOAD: - case FSTORE: - expected = BasicValue.FLOAT_VALUE; - break; - case LLOAD: - case LSTORE: - expected = BasicValue.LONG_VALUE; - break; - case DLOAD: - case DSTORE: - expected = BasicValue.DOUBLE_VALUE; - break; - case ALOAD: - if (!((BasicValue) value).isReference()) { - throw new AnalyzerException(null, "an object reference", value); - } - return value; - case ASTORE: - if (!((BasicValue) value).isReference() && value != BasicValue.RETURNADDRESS_VALUE) { - throw new AnalyzerException(null, "an object reference or a return address", value); - } - return value; - default: - return value; - } - // type is necessarily a primitive type here, - // so value must be == to expected value - if (value != expected) { - throw new AnalyzerException(null, expected, value); - } - return value; - } - - @Override - public Value unaryOperation(final AbstractInsnNode insn, final Value value) throws AnalyzerException { - Value expected; - switch (insn.getOpcode()) { - case INEG: - case IINC: - case I2F: - case I2L: - case I2D: - case I2B: - case I2C: - case I2S: - case IFEQ: - case IFNE: - case IFLT: - case IFGE: - case IFGT: - case IFLE: - case TABLESWITCH: - case LOOKUPSWITCH: - case IRETURN: - case NEWARRAY: - case ANEWARRAY: - expected = BasicValue.INT_VALUE; - break; - case FNEG: - case F2I: - case F2L: - case F2D: - case FRETURN: - expected = BasicValue.FLOAT_VALUE; - break; - case LNEG: - case L2I: - case L2F: - case L2D: - case LRETURN: - expected = BasicValue.LONG_VALUE; - break; - case DNEG: - case D2I: - case D2F: - case D2L: - case DRETURN: - expected = BasicValue.DOUBLE_VALUE; - break; - case GETFIELD: - expected = newValue(Type.getObjectType(((FieldInsnNode) insn).owner)); - break; - case CHECKCAST: - if (!((BasicValue) value).isReference()) { - throw new AnalyzerException(null, "an object reference", value); - } - return super.unaryOperation(insn, value); - case ARRAYLENGTH: - if (!isArrayValue(value)) { - throw new AnalyzerException(null, "an array reference", value); - } - return super.unaryOperation(insn, value); - case ARETURN: - case ATHROW: - case INSTANCEOF: - case MONITORENTER: - case MONITOREXIT: - case IFNULL: - case IFNONNULL: - if (!((BasicValue) value).isReference()) { - throw new AnalyzerException(null, "an object reference", value); - } - return super.unaryOperation(insn, value); - case PUTSTATIC: - expected = newValue(Type.getType(((FieldInsnNode) insn).desc)); - break; - default: - throw new Error("Internal error."); - } - if (!isSubTypeOf(value, expected)) { - throw new AnalyzerException(null, expected, value); - } - return super.unaryOperation(insn, value); - } - - @Override - public Value binaryOperation(final AbstractInsnNode insn, final Value value1, final Value value2) - throws AnalyzerException { - Value expected1; - Value expected2; - switch (insn.getOpcode()) { - case IALOAD: - expected1 = newValue(Type.getType("[I")); - expected2 = BasicValue.INT_VALUE; - break; - case BALOAD: - if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) { - expected1 = newValue(Type.getType("[Z")); - } else { - expected1 = newValue(Type.getType("[B")); - } - expected2 = BasicValue.INT_VALUE; - break; - case CALOAD: - expected1 = newValue(Type.getType("[C")); - expected2 = BasicValue.INT_VALUE; - break; - case SALOAD: - expected1 = newValue(Type.getType("[S")); - expected2 = BasicValue.INT_VALUE; - break; - case LALOAD: - expected1 = newValue(Type.getType("[J")); - expected2 = BasicValue.INT_VALUE; - break; - case FALOAD: - expected1 = newValue(Type.getType("[F")); - expected2 = BasicValue.INT_VALUE; - break; - case DALOAD: - expected1 = newValue(Type.getType("[D")); - expected2 = BasicValue.INT_VALUE; - break; - case AALOAD: - expected1 = newValue(Type.getType("[Ljava/lang/Object;")); - expected2 = BasicValue.INT_VALUE; - break; - case IADD: - case ISUB: - case IMUL: - case IDIV: - case IREM: - case ISHL: - case ISHR: - case IUSHR: - case IAND: - case IOR: - case IXOR: - case IF_ICMPEQ: - case IF_ICMPNE: - case IF_ICMPLT: - case IF_ICMPGE: - case IF_ICMPGT: - case IF_ICMPLE: - expected1 = BasicValue.INT_VALUE; - expected2 = BasicValue.INT_VALUE; - break; - case FADD: - case FSUB: - case FMUL: - case FDIV: - case FREM: - case FCMPL: - case FCMPG: - expected1 = BasicValue.FLOAT_VALUE; - expected2 = BasicValue.FLOAT_VALUE; - break; - case LADD: - case LSUB: - case LMUL: - case LDIV: - case LREM: - case LAND: - case LOR: - case LXOR: - case LCMP: - expected1 = BasicValue.LONG_VALUE; - expected2 = BasicValue.LONG_VALUE; - break; - case LSHL: - case LSHR: - case LUSHR: - expected1 = BasicValue.LONG_VALUE; - expected2 = BasicValue.INT_VALUE; - break; - case DADD: - case DSUB: - case DMUL: - case DDIV: - case DREM: - case DCMPL: - case DCMPG: - expected1 = BasicValue.DOUBLE_VALUE; - expected2 = BasicValue.DOUBLE_VALUE; - break; - case IF_ACMPEQ: - case IF_ACMPNE: - expected1 = BasicValue.REFERENCE_VALUE; - expected2 = BasicValue.REFERENCE_VALUE; - break; - case PUTFIELD: - FieldInsnNode fin = (FieldInsnNode) insn; - expected1 = newValue(Type.getObjectType(fin.owner)); - expected2 = newValue(Type.getType(fin.desc)); - break; - default: - throw new Error("Internal error."); - } - if (!isSubTypeOf(value1, expected1)) { - throw new AnalyzerException("First argument", expected1, value1); - } else if (!isSubTypeOf(value2, expected2)) { - throw new AnalyzerException("Second argument", expected2, value2); - } - if (insn.getOpcode() == AALOAD) { - return getElementValue(value1); - } else { - return super.binaryOperation(insn, value1, value2); - } - } - - @Override - public Value ternaryOperation(final AbstractInsnNode insn, final Value value1, final Value value2, - final Value value3) throws AnalyzerException { - Value expected1; - Value expected3; - switch (insn.getOpcode()) { - case IASTORE: - expected1 = newValue(Type.getType("[I")); - expected3 = BasicValue.INT_VALUE; - break; - case BASTORE: - if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) { - expected1 = newValue(Type.getType("[Z")); - } else { - expected1 = newValue(Type.getType("[B")); - } - expected3 = BasicValue.INT_VALUE; - break; - case CASTORE: - expected1 = newValue(Type.getType("[C")); - expected3 = BasicValue.INT_VALUE; - break; - case SASTORE: - expected1 = newValue(Type.getType("[S")); - expected3 = BasicValue.INT_VALUE; - break; - case LASTORE: - expected1 = newValue(Type.getType("[J")); - expected3 = BasicValue.LONG_VALUE; - break; - case FASTORE: - expected1 = newValue(Type.getType("[F")); - expected3 = BasicValue.FLOAT_VALUE; - break; - case DASTORE: - expected1 = newValue(Type.getType("[D")); - expected3 = BasicValue.DOUBLE_VALUE; - break; - case AASTORE: - expected1 = value1; - expected3 = BasicValue.REFERENCE_VALUE; - break; - default: - throw new Error("Internal error."); - } - if (!isSubTypeOf(value1, expected1)) { - throw new AnalyzerException("First argument", "a " + expected1 + " array reference", value1); - } else if (value2 != BasicValue.INT_VALUE) { - throw new AnalyzerException("Second argument", BasicValue.INT_VALUE, value2); - } else if (!isSubTypeOf(value3, expected3)) { - throw new AnalyzerException("Third argument", expected3, value3); - } - return null; - } - - @Override - public Value naryOperation(final AbstractInsnNode insn, final List values) throws AnalyzerException { - int opcode = insn.getOpcode(); - if (opcode == MULTIANEWARRAY) { - for (int i = 0; i < values.size(); ++i) { - if (values.get(i) != BasicValue.INT_VALUE) { - throw new AnalyzerException(null, BasicValue.INT_VALUE, (Value) values.get(i)); - } - } - } else { - int i = 0; - int j = 0; - if (opcode != INVOKESTATIC) { - Type owner = Type.getObjectType(((MethodInsnNode) insn).owner); - if (!isSubTypeOf((Value) values.get(i++), newValue(owner))) { - throw new AnalyzerException("Method owner", newValue(owner), (Value) values.get(0)); - } - } - Type[] args = Type.getArgumentTypes(((MethodInsnNode) insn).desc); - while (i < values.size()) { - Value expected = newValue(args[j++]); - Value encountered = (Value) values.get(i++); - if (!isSubTypeOf(encountered, expected)) { - throw new AnalyzerException("Argument " + j, expected, encountered); - } - } - } - return super.naryOperation(insn, values); - } - - protected boolean isArrayValue(final Value value) { - return ((BasicValue) value).isReference(); - } - - protected Value getElementValue(final Value objectArrayValue) throws AnalyzerException { - return BasicValue.REFERENCE_VALUE; - } - - protected boolean isSubTypeOf(final Value value, final Value expected) { - return value == expected; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Frame.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Frame.java deleted file mode 100644 index e869af7ba..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Frame.java +++ /dev/null @@ -1,677 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import java.util.ArrayList; -import java.util.List; - -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; -import com.alibaba.citrus.asm.tree.AbstractInsnNode; -import com.alibaba.citrus.asm.tree.IincInsnNode; -import com.alibaba.citrus.asm.tree.MethodInsnNode; -import com.alibaba.citrus.asm.tree.MultiANewArrayInsnNode; -import com.alibaba.citrus.asm.tree.VarInsnNode; - -/** - * A symbolic execution stack frame. A stack frame contains a set of local - * variable slots, and an operand stack. Warning: long and double values are - * represented by two slots in local variables, and by one slot in - * the operand stack. - * - * @author Eric Bruneton - */ -public class Frame { - - /** - * The local variables and operand stack of this frame. - */ - private Value[] values; - - /** - * The number of local variables of this frame. - */ - private int locals; - - /** - * The number of elements in the operand stack. - */ - private int top; - - /** - * Constructs a new frame with the given size. - * - * @param nLocals the maximum number of local variables of the frame. - * @param nStack the maximum stack size of the frame. - */ - public Frame(final int nLocals, final int nStack) { - this.values = new Value[nLocals + nStack]; - this.locals = nLocals; - } - - /** - * Constructs a new frame that is identical to the given frame. - * - * @param src a frame. - */ - public Frame(final Frame src) { - this(src.locals, src.values.length - src.locals); - init(src); - } - - /** - * Copies the state of the given frame into this frame. - * - * @param src a frame. - * @return this frame. - */ - public Frame init(final Frame src) { - System.arraycopy(src.values, 0, values, 0, values.length); - top = src.top; - return this; - } - - /** - * Returns the maximum number of local variables of this frame. - * - * @return the maximum number of local variables of this frame. - */ - public int getLocals() { - return locals; - } - - /** - * Returns the value of the given local variable. - * - * @param i a local variable index. - * @return the value of the given local variable. - * @throws IndexOutOfBoundsException if the variable does not exist. - */ - public Value getLocal(final int i) throws IndexOutOfBoundsException { - if (i >= locals) { - throw new IndexOutOfBoundsException("Trying to access an inexistant local variable"); - } - return values[i]; - } - - /** - * Sets the value of the given local variable. - * - * @param i a local variable index. - * @param value the new value of this local variable. - * @throws IndexOutOfBoundsException if the variable does not exist. - */ - public void setLocal(final int i, final Value value) throws IndexOutOfBoundsException { - if (i >= locals) { - throw new IndexOutOfBoundsException("Trying to access an inexistant local variable"); - } - values[i] = value; - } - - /** - * Returns the number of values in the operand stack of this frame. Long and - * double values are treated as single values. - * - * @return the number of values in the operand stack of this frame. - */ - public int getStackSize() { - return top; - } - - /** - * Returns the value of the given operand stack slot. - * - * @param i the index of an operand stack slot. - * @return the value of the given operand stack slot. - * @throws IndexOutOfBoundsException if the operand stack slot does not - * exist. - */ - public Value getStack(final int i) throws IndexOutOfBoundsException { - return values[i + locals]; - } - - /** - * Clears the operand stack of this frame. - */ - public void clearStack() { - top = 0; - } - - /** - * Pops a value from the operand stack of this frame. - * - * @return the value that has been popped from the stack. - * @throws IndexOutOfBoundsException if the operand stack is empty. - */ - public Value pop() throws IndexOutOfBoundsException { - if (top == 0) { - throw new IndexOutOfBoundsException("Cannot pop operand off an empty stack."); - } - return values[--top + locals]; - } - - /** - * Pushes a value into the operand stack of this frame. - * - * @param value the value that must be pushed into the stack. - * @throws IndexOutOfBoundsException if the operand stack is full. - */ - public void push(final Value value) throws IndexOutOfBoundsException { - if (top + locals >= values.length) { - throw new IndexOutOfBoundsException("Insufficient maximum stack size."); - } - values[top++ + locals] = value; - } - - public void execute(final AbstractInsnNode insn, final Interpreter interpreter) throws AnalyzerException { - Value value1, value2, value3, value4; - List values; - int var; - - switch (insn.getOpcode()) { - case Opcodes.NOP: - break; - case Opcodes.ACONST_NULL: - case Opcodes.ICONST_M1: - case Opcodes.ICONST_0: - case Opcodes.ICONST_1: - case Opcodes.ICONST_2: - case Opcodes.ICONST_3: - case Opcodes.ICONST_4: - case Opcodes.ICONST_5: - case Opcodes.LCONST_0: - case Opcodes.LCONST_1: - case Opcodes.FCONST_0: - case Opcodes.FCONST_1: - case Opcodes.FCONST_2: - case Opcodes.DCONST_0: - case Opcodes.DCONST_1: - case Opcodes.BIPUSH: - case Opcodes.SIPUSH: - case Opcodes.LDC: - push(interpreter.newOperation(insn)); - break; - case Opcodes.ILOAD: - case Opcodes.LLOAD: - case Opcodes.FLOAD: - case Opcodes.DLOAD: - case Opcodes.ALOAD: - push(interpreter.copyOperation(insn, getLocal(((VarInsnNode) insn).var))); - break; - case Opcodes.IALOAD: - case Opcodes.LALOAD: - case Opcodes.FALOAD: - case Opcodes.DALOAD: - case Opcodes.AALOAD: - case Opcodes.BALOAD: - case Opcodes.CALOAD: - case Opcodes.SALOAD: - value2 = pop(); - value1 = pop(); - push(interpreter.binaryOperation(insn, value1, value2)); - break; - case Opcodes.ISTORE: - case Opcodes.LSTORE: - case Opcodes.FSTORE: - case Opcodes.DSTORE: - case Opcodes.ASTORE: - value1 = interpreter.copyOperation(insn, pop()); - var = ((VarInsnNode) insn).var; - setLocal(var, value1); - if (value1.getSize() == 2) { - setLocal(var + 1, interpreter.newValue(null)); - } - if (var > 0) { - Value local = getLocal(var - 1); - if (local != null && local.getSize() == 2) { - setLocal(var - 1, interpreter.newValue(null)); - } - } - break; - case Opcodes.IASTORE: - case Opcodes.LASTORE: - case Opcodes.FASTORE: - case Opcodes.DASTORE: - case Opcodes.AASTORE: - case Opcodes.BASTORE: - case Opcodes.CASTORE: - case Opcodes.SASTORE: - value3 = pop(); - value2 = pop(); - value1 = pop(); - interpreter.ternaryOperation(insn, value1, value2, value3); - break; - case Opcodes.POP: - if (pop().getSize() == 2) { - throw new AnalyzerException("Illegal use of POP"); - } - break; - case Opcodes.POP2: - if (pop().getSize() == 1) { - if (pop().getSize() != 1) { - throw new AnalyzerException("Illegal use of POP2"); - } - } - break; - case Opcodes.DUP: - value1 = pop(); - if (value1.getSize() != 1) { - throw new AnalyzerException("Illegal use of DUP"); - } - push(interpreter.copyOperation(insn, value1)); - push(interpreter.copyOperation(insn, value1)); - break; - case Opcodes.DUP_X1: - value1 = pop(); - value2 = pop(); - if (value1.getSize() != 1 || value2.getSize() != 1) { - throw new AnalyzerException("Illegal use of DUP_X1"); - } - push(interpreter.copyOperation(insn, value1)); - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - break; - case Opcodes.DUP_X2: - value1 = pop(); - if (value1.getSize() == 1) { - value2 = pop(); - if (value2.getSize() == 1) { - value3 = pop(); - if (value3.getSize() == 1) { - push(interpreter.copyOperation(insn, value1)); - push(interpreter.copyOperation(insn, value3)); - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - break; - } - } else { - push(interpreter.copyOperation(insn, value1)); - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - break; - } - } - throw new AnalyzerException("Illegal use of DUP_X2"); - case Opcodes.DUP2: - value1 = pop(); - if (value1.getSize() == 1) { - value2 = pop(); - if (value2.getSize() == 1) { - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - break; - } - } else { - push(interpreter.copyOperation(insn, value1)); - push(interpreter.copyOperation(insn, value1)); - break; - } - throw new AnalyzerException("Illegal use of DUP2"); - case Opcodes.DUP2_X1: - value1 = pop(); - if (value1.getSize() == 1) { - value2 = pop(); - if (value2.getSize() == 1) { - value3 = pop(); - if (value3.getSize() == 1) { - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - push(interpreter.copyOperation(insn, value3)); - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - break; - } - } - } else { - value2 = pop(); - if (value2.getSize() == 1) { - push(interpreter.copyOperation(insn, value1)); - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - break; - } - } - throw new AnalyzerException("Illegal use of DUP2_X1"); - case Opcodes.DUP2_X2: - value1 = pop(); - if (value1.getSize() == 1) { - value2 = pop(); - if (value2.getSize() == 1) { - value3 = pop(); - if (value3.getSize() == 1) { - value4 = pop(); - if (value4.getSize() == 1) { - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - push(interpreter.copyOperation(insn, value4)); - push(interpreter.copyOperation(insn, value3)); - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - break; - } - } else { - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - push(interpreter.copyOperation(insn, value3)); - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - break; - } - } - } else { - value2 = pop(); - if (value2.getSize() == 1) { - value3 = pop(); - if (value3.getSize() == 1) { - push(interpreter.copyOperation(insn, value1)); - push(interpreter.copyOperation(insn, value3)); - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - break; - } - } else { - push(interpreter.copyOperation(insn, value1)); - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - break; - } - } - throw new AnalyzerException("Illegal use of DUP2_X2"); - case Opcodes.SWAP: - value2 = pop(); - value1 = pop(); - if (value1.getSize() != 1 || value2.getSize() != 1) { - throw new AnalyzerException("Illegal use of SWAP"); - } - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - break; - case Opcodes.IADD: - case Opcodes.LADD: - case Opcodes.FADD: - case Opcodes.DADD: - case Opcodes.ISUB: - case Opcodes.LSUB: - case Opcodes.FSUB: - case Opcodes.DSUB: - case Opcodes.IMUL: - case Opcodes.LMUL: - case Opcodes.FMUL: - case Opcodes.DMUL: - case Opcodes.IDIV: - case Opcodes.LDIV: - case Opcodes.FDIV: - case Opcodes.DDIV: - case Opcodes.IREM: - case Opcodes.LREM: - case Opcodes.FREM: - case Opcodes.DREM: - value2 = pop(); - value1 = pop(); - push(interpreter.binaryOperation(insn, value1, value2)); - break; - case Opcodes.INEG: - case Opcodes.LNEG: - case Opcodes.FNEG: - case Opcodes.DNEG: - push(interpreter.unaryOperation(insn, pop())); - break; - case Opcodes.ISHL: - case Opcodes.LSHL: - case Opcodes.ISHR: - case Opcodes.LSHR: - case Opcodes.IUSHR: - case Opcodes.LUSHR: - case Opcodes.IAND: - case Opcodes.LAND: - case Opcodes.IOR: - case Opcodes.LOR: - case Opcodes.IXOR: - case Opcodes.LXOR: - value2 = pop(); - value1 = pop(); - push(interpreter.binaryOperation(insn, value1, value2)); - break; - case Opcodes.IINC: - var = ((IincInsnNode) insn).var; - setLocal(var, interpreter.unaryOperation(insn, getLocal(var))); - break; - case Opcodes.I2L: - case Opcodes.I2F: - case Opcodes.I2D: - case Opcodes.L2I: - case Opcodes.L2F: - case Opcodes.L2D: - case Opcodes.F2I: - case Opcodes.F2L: - case Opcodes.F2D: - case Opcodes.D2I: - case Opcodes.D2L: - case Opcodes.D2F: - case Opcodes.I2B: - case Opcodes.I2C: - case Opcodes.I2S: - push(interpreter.unaryOperation(insn, pop())); - break; - case Opcodes.LCMP: - case Opcodes.FCMPL: - case Opcodes.FCMPG: - case Opcodes.DCMPL: - case Opcodes.DCMPG: - value2 = pop(); - value1 = pop(); - push(interpreter.binaryOperation(insn, value1, value2)); - break; - case Opcodes.IFEQ: - case Opcodes.IFNE: - case Opcodes.IFLT: - case Opcodes.IFGE: - case Opcodes.IFGT: - case Opcodes.IFLE: - interpreter.unaryOperation(insn, pop()); - break; - case Opcodes.IF_ICMPEQ: - case Opcodes.IF_ICMPNE: - case Opcodes.IF_ICMPLT: - case Opcodes.IF_ICMPGE: - case Opcodes.IF_ICMPGT: - case Opcodes.IF_ICMPLE: - case Opcodes.IF_ACMPEQ: - case Opcodes.IF_ACMPNE: - value2 = pop(); - value1 = pop(); - interpreter.binaryOperation(insn, value1, value2); - break; - case Opcodes.GOTO: - break; - case Opcodes.JSR: - push(interpreter.newOperation(insn)); - break; - case Opcodes.RET: - break; - case Opcodes.TABLESWITCH: - case Opcodes.LOOKUPSWITCH: - case Opcodes.IRETURN: - case Opcodes.LRETURN: - case Opcodes.FRETURN: - case Opcodes.DRETURN: - case Opcodes.ARETURN: - interpreter.unaryOperation(insn, pop()); - break; - case Opcodes.RETURN: - break; - case Opcodes.GETSTATIC: - push(interpreter.newOperation(insn)); - break; - case Opcodes.PUTSTATIC: - interpreter.unaryOperation(insn, pop()); - break; - case Opcodes.GETFIELD: - push(interpreter.unaryOperation(insn, pop())); - break; - case Opcodes.PUTFIELD: - value2 = pop(); - value1 = pop(); - interpreter.binaryOperation(insn, value1, value2); - break; - case Opcodes.INVOKEVIRTUAL: - case Opcodes.INVOKESPECIAL: - case Opcodes.INVOKESTATIC: - case Opcodes.INVOKEINTERFACE: - values = new ArrayList(); - String desc = ((MethodInsnNode) insn).desc; - for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) { - values.add(0, pop()); - } - if (insn.getOpcode() != Opcodes.INVOKESTATIC) { - values.add(0, pop()); - } - if (Type.getReturnType(desc) == Type.VOID_TYPE) { - interpreter.naryOperation(insn, values); - } else { - push(interpreter.naryOperation(insn, values)); - } - break; - case Opcodes.NEW: - push(interpreter.newOperation(insn)); - break; - case Opcodes.NEWARRAY: - case Opcodes.ANEWARRAY: - case Opcodes.ARRAYLENGTH: - push(interpreter.unaryOperation(insn, pop())); - break; - case Opcodes.ATHROW: - interpreter.unaryOperation(insn, pop()); - break; - case Opcodes.CHECKCAST: - case Opcodes.INSTANCEOF: - push(interpreter.unaryOperation(insn, pop())); - break; - case Opcodes.MONITORENTER: - case Opcodes.MONITOREXIT: - interpreter.unaryOperation(insn, pop()); - break; - case Opcodes.MULTIANEWARRAY: - values = new ArrayList(); - for (int i = ((MultiANewArrayInsnNode) insn).dims; i > 0; --i) { - values.add(0, pop()); - } - push(interpreter.naryOperation(insn, values)); - break; - case Opcodes.IFNULL: - case Opcodes.IFNONNULL: - interpreter.unaryOperation(insn, pop()); - break; - default: - throw new RuntimeException("Illegal opcode"); - } - } - - /** - * Merges this frame with the given frame. - * - * @param frame a frame. - * @param interpreter the interpreter used to merge values. - * @return true if this frame has been changed as a result of the - * merge operation, or false otherwise. - * @throws AnalyzerException if the frames have incompatible sizes. - */ - public boolean merge(final Frame frame, final Interpreter interpreter) throws AnalyzerException { - if (top != frame.top) { - throw new AnalyzerException("Incompatible stack heights"); - } - boolean changes = false; - for (int i = 0; i < locals + top; ++i) { - Value v = interpreter.merge(values[i], frame.values[i]); - if (v != values[i]) { - values[i] = v; - changes |= true; - } - } - return changes; - } - - /** - * Merges this frame with the given frame (case of a RET instruction). - * - * @param frame a frame - * @param access the local variables that have been accessed by the - * subroutine to which the RET instruction corresponds. - * @return true if this frame has been changed as a result of the - * merge operation, or false otherwise. - */ - public boolean merge(final Frame frame, final boolean[] access) { - boolean changes = false; - for (int i = 0; i < locals; ++i) { - if (!access[i] && !values[i].equals(frame.values[i])) { - values[i] = frame.values[i]; - changes = true; - } - } - return changes; - } - - /** - * Returns a string representation of this frame. - * - * @return a string representation of this frame. - */ - @Override - public String toString() { - StringBuilder b = new StringBuilder(); - for (int i = 0; i < getLocals(); ++i) { - b.append(getLocal(i)); - } - b.append(' '); - for (int i = 0; i < getStackSize(); ++i) { - b.append(getStack(i).toString()); - } - return b.toString(); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Interpreter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Interpreter.java deleted file mode 100644 index 4500cc554..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Interpreter.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import java.util.List; - -import com.alibaba.citrus.asm.Type; -import com.alibaba.citrus.asm.tree.AbstractInsnNode; - -/** - * A semantic bytecode interpreter. More precisely, this interpreter only - * manages the computation of values from other values: it does not manage the - * transfer of values to or from the stack, and to or from the local variables. - * This separation allows a generic bytecode {@link Analyzer} to work with - * various semantic interpreters, without needing to duplicate the code to - * simulate the transfer of values. - * - * @author Eric Bruneton - */ -public interface Interpreter { - - /** - * Creates a new value that represents the given type. Called for method - * parameters (including this), exception handler variable and - * with null type for variables reserved by long and double - * types. - * - * @param type a primitive or reference type, or null to represent - * an uninitialized value. - * @return a value that represents the given type. The size of the returned - * value must be equal to the size of the given type. - */ - Value newValue(Type type); - - /** - * Interprets a bytecode instruction without arguments. This method is - * called for the following opcodes: ACONST_NULL, ICONST_M1, ICONST_0, - * ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, - * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, BIPUSH, SIPUSH, LDC, - * JSR, GETSTATIC, NEW - * - * @param insn the bytecode instruction to be interpreted. - * @return the result of the interpretation of the given instruction. - * @throws AnalyzerException if an error occured during the interpretation. - */ - Value newOperation(AbstractInsnNode insn) throws AnalyzerException; - - /** - * Interprets a bytecode instruction that moves a value on the stack or to - * or from local variables. This method is called for the following opcodes: - * ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, - * ASTORE, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP - * - * @param insn the bytecode instruction to be interpreted. - * @param value the value that must be moved by the instruction. - * @return the result of the interpretation of the given instruction. The - * returned value must be equal to the given value. - * @throws AnalyzerException if an error occured during the interpretation. - */ - Value copyOperation(AbstractInsnNode insn, Value value) throws AnalyzerException; - - /** - * Interprets a bytecode instruction with a single argument. This method is - * called for the following opcodes: INEG, LNEG, FNEG, DNEG, IINC, I2L, I2F, - * I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S, IFEQ, - * IFNE, IFLT, IFGE, IFGT, IFLE, TABLESWITCH, LOOKUPSWITCH, IRETURN, - * LRETURN, FRETURN, DRETURN, ARETURN, PUTSTATIC, GETFIELD, NEWARRAY, - * ANEWARRAY, ARRAYLENGTH, ATHROW, CHECKCAST, INSTANCEOF, MONITORENTER, - * MONITOREXIT, IFNULL, IFNONNULL - * - * @param insn the bytecode instruction to be interpreted. - * @param value the argument of the instruction to be interpreted. - * @return the result of the interpretation of the given instruction. - * @throws AnalyzerException if an error occured during the interpretation. - */ - Value unaryOperation(AbstractInsnNode insn, Value value) throws AnalyzerException; - - /** - * Interprets a bytecode instruction with two arguments. This method is - * called for the following opcodes: IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, - * BALOAD, CALOAD, SALOAD, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, - * IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, - * ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, - * LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, - * IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, PUTFIELD - * - * @param insn the bytecode instruction to be interpreted. - * @param value1 the first argument of the instruction to be interpreted. - * @param value2 the second argument of the instruction to be interpreted. - * @return the result of the interpretation of the given instruction. - * @throws AnalyzerException if an error occured during the interpretation. - */ - Value binaryOperation(AbstractInsnNode insn, Value value1, Value value2) throws AnalyzerException; - - /** - * Interprets a bytecode instruction with three arguments. This method is - * called for the following opcodes: IASTORE, LASTORE, FASTORE, DASTORE, - * AASTORE, BASTORE, CASTORE, SASTORE - * - * @param insn the bytecode instruction to be interpreted. - * @param value1 the first argument of the instruction to be interpreted. - * @param value2 the second argument of the instruction to be interpreted. - * @param value3 the third argument of the instruction to be interpreted. - * @return the result of the interpretation of the given instruction. - * @throws AnalyzerException if an error occured during the interpretation. - */ - Value ternaryOperation(AbstractInsnNode insn, Value value1, Value value2, Value value3) throws AnalyzerException; - - /** - * Interprets a bytecode instruction with a variable number of arguments. - * This method is called for the following opcodes: INVOKEVIRTUAL, - * INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE, MULTIANEWARRAY - * - * @param insn the bytecode instruction to be interpreted. - * @param values the arguments of the instruction to be interpreted. - * @return the result of the interpretation of the given instruction. - * @throws AnalyzerException if an error occured during the interpretation. - */ - Value naryOperation(AbstractInsnNode insn, List values) throws AnalyzerException; - - /** - * Merges two values. The merge operation must return a value that - * represents both values (for instance, if the two values are two types, - * the merged value must be a common super type of the two types. If the two - * values are integer intervals, the merged value must be an interval that - * contains the previous ones. Likewise for other types of values). - * - * @param v a value. - * @param w another value. - * @return the merged value. If the merged value is equal to v, - * this method must return v. - */ - Value merge(Value v, Value w); -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/SimpleVerifier.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/SimpleVerifier.java deleted file mode 100644 index 327f3a3c4..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/SimpleVerifier.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import java.util.List; - -import com.alibaba.citrus.asm.Type; - -/** - * An extended {@link BasicVerifier} that performs more precise verifications. - * This verifier computes exact class types, instead of using a single - * "object reference" type (as done in the {@link BasicVerifier}). - * - * @author Eric Bruneton - * @author Bing Ran - */ -public class SimpleVerifier extends BasicVerifier { - - /** - * The class that is verified. - */ - private final Type currentClass; - - /** - * The super class of the class that is verified. - */ - private final Type currentSuperClass; - - /** - * The interfaces implemented by the class that is verified. - */ - private final List currentClassInterfaces; - - /** - * If the class that is verified is an interface. - */ - private final boolean isInterface; - - /** - * Constructs a new {@link SimpleVerifier}. - */ - public SimpleVerifier() { - this(null, null, false); - } - - /** - * Constructs a new {@link SimpleVerifier} to verify a specific class. This - * class will not be loaded into the JVM since it may be incorrect. - * - * @param currentClass the class that is verified. - * @param currentSuperClass the super class of the class that is verified. - * @param isInterface if the class that is verified is an interface. - */ - public SimpleVerifier(final Type currentClass, final Type currentSuperClass, final boolean isInterface) { - this(currentClass, currentSuperClass, null, isInterface); - } - - /** - * Constructs a new {@link SimpleVerifier} to verify a specific class. This - * class will not be loaded into the JVM since it may be incorrect. - * - * @param currentClass the class that is verified. - * @param currentSuperClass the super class of the class that is verified. - * @param currentClassInterfaces the interfaces implemented by the class - * that is verified. - * @param isInterface if the class that is verified is an interface. - */ - public SimpleVerifier(final Type currentClass, final Type currentSuperClass, final List currentClassInterfaces, - final boolean isInterface) { - this.currentClass = currentClass; - this.currentSuperClass = currentSuperClass; - this.currentClassInterfaces = currentClassInterfaces; - this.isInterface = isInterface; - } - - @Override - public Value newValue(final Type type) { - if (type == null) { - return BasicValue.UNINITIALIZED_VALUE; - } - - boolean isArray = type.getSort() == Type.ARRAY; - if (isArray) { - switch (type.getElementType().getSort()) { - case Type.BOOLEAN: - case Type.CHAR: - case Type.BYTE: - case Type.SHORT: - return new BasicValue(type); - } - } - - Value v = super.newValue(type); - if (v == BasicValue.REFERENCE_VALUE) { - if (isArray) { - v = newValue(type.getElementType()); - String desc = ((BasicValue) v).getType().getDescriptor(); - for (int i = 0; i < type.getDimensions(); ++i) { - desc = '[' + desc; - } - v = new BasicValue(Type.getType(desc)); - } else { - v = new BasicValue(type); - } - } - return v; - } - - @Override - protected boolean isArrayValue(final Value value) { - Type t = ((BasicValue) value).getType(); - return t != null && ("Lnull;".equals(t.getDescriptor()) || t.getSort() == Type.ARRAY); - } - - @Override - protected Value getElementValue(final Value objectArrayValue) throws AnalyzerException { - Type arrayType = ((BasicValue) objectArrayValue).getType(); - if (arrayType != null) { - if (arrayType.getSort() == Type.ARRAY) { - return newValue(Type.getType(arrayType.getDescriptor().substring(1))); - } else if ("Lnull;".equals(arrayType.getDescriptor())) { - return objectArrayValue; - } - } - throw new Error("Internal error"); - } - - @Override - protected boolean isSubTypeOf(final Value value, final Value expected) { - Type expectedType = ((BasicValue) expected).getType(); - Type type = ((BasicValue) value).getType(); - switch (expectedType.getSort()) { - case Type.INT: - case Type.FLOAT: - case Type.LONG: - case Type.DOUBLE: - return type == expectedType; - case Type.ARRAY: - case Type.OBJECT: - if ("Lnull;".equals(type.getDescriptor())) { - return true; - } else if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { - return isAssignableFrom(expectedType, type); - } else { - return false; - } - default: - throw new Error("Internal error"); - } - } - - @Override - public Value merge(final Value v, final Value w) { - if (!v.equals(w)) { - Type t = ((BasicValue) v).getType(); - Type u = ((BasicValue) w).getType(); - if (t != null && (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)) { - if (u != null && (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY)) { - if ("Lnull;".equals(t.getDescriptor())) { - return w; - } - if ("Lnull;".equals(u.getDescriptor())) { - return v; - } - if (isAssignableFrom(t, u)) { - return v; - } - if (isAssignableFrom(u, t)) { - return w; - } - // TODO case of array classes of the same dimension - // TODO should we look also for a common super interface? - // problem: there may be several possible common super - // interfaces - do { - if (t == null || isInterface(t)) { - return BasicValue.REFERENCE_VALUE; - } - t = getSuperClass(t); - if (isAssignableFrom(t, u)) { - return newValue(t); - } - } while (true); - } - } - return BasicValue.UNINITIALIZED_VALUE; - } - return v; - } - - protected boolean isInterface(final Type t) { - if (currentClass != null && t.equals(currentClass)) { - return isInterface; - } - return getClass(t).isInterface(); - } - - protected Type getSuperClass(final Type t) { - if (currentClass != null && t.equals(currentClass)) { - return currentSuperClass; - } - Class c = getClass(t).getSuperclass(); - return c == null ? null : Type.getType(c); - } - - protected boolean isAssignableFrom(final Type t, final Type u) { - if (t.equals(u)) { - return true; - } - if (currentClass != null && t.equals(currentClass)) { - if (getSuperClass(u) == null) { - return false; - } else { - return isAssignableFrom(t, getSuperClass(u)); - } - } - if (currentClass != null && u.equals(currentClass)) { - if (isAssignableFrom(t, currentSuperClass)) { - return true; - } - if (currentClassInterfaces != null) { - for (int i = 0; i < currentClassInterfaces.size(); ++i) { - Type v = (Type) currentClassInterfaces.get(i); - if (isAssignableFrom(t, v)) { - return true; - } - } - } - return false; - } - return getClass(t).isAssignableFrom(getClass(u)); - } - - protected Class getClass(final Type t) { - try { - if (t.getSort() == Type.ARRAY) { - return Class.forName(t.getDescriptor().replace('/', '.')); - } - return Class.forName(t.getClassName()); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e.toString()); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/SmallSet.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/SmallSet.java deleted file mode 100644 index 198d7228e..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/SmallSet.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import java.util.AbstractSet; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -/** - * A set of at most two elements. - * - * @author Eric Bruneton - */ -class SmallSet extends AbstractSet implements Iterator { - - // if e1 is null, e2 must be null; otherwise e2 must be different from e1 - - Object e1, e2; - - static final Set EMPTY_SET = new SmallSet(null, null); - - SmallSet(final Object e1, final Object e2) { - this.e1 = e1; - this.e2 = e2; - } - - // ------------------------------------------------------------------------- - // Implementation of inherited abstract methods - // ------------------------------------------------------------------------- - - @Override - public Iterator iterator() { - return new SmallSet(e1, e2); - } - - @Override - public int size() { - return e1 == null ? 0 : e2 == null ? 1 : 2; - } - - // ------------------------------------------------------------------------- - // Implementation of the Iterator interface - // ------------------------------------------------------------------------- - - public boolean hasNext() { - return e1 != null; - } - - public Object next() { - Object e = e1; - e1 = e2; - e2 = null; - return e; - } - - public void remove() { - } - - // ------------------------------------------------------------------------- - // Utility methods - // ------------------------------------------------------------------------- - - Set union(final SmallSet s) { - if (s.e1 == e1 && s.e2 == e2 || s.e1 == e2 && s.e2 == e1) { - return this; // if the two sets are equal, return this - } - if (s.e1 == null) { - return this; // if s is empty, return this - } - if (e1 == null) { - return s; // if this is empty, return s - } - if (s.e2 == null) { // s contains exactly one element - if (e2 == null) { - return new SmallSet(e1, s.e1); // necessarily e1 != s.e1 - } else if (s.e1 == e1 || s.e1 == e2) { // s is included in this - return this; - } - } - if (e2 == null) { // this contains exactly one element - // if (s.e2 == null) { // cannot happen - // return new SmallSet(e1, s.e1); // necessarily e1 != s.e1 - // } else - if (e1 == s.e1 || e1 == s.e2) { // this in included in s - return s; - } - } - // here we know that there are at least 3 distinct elements - HashSet r = new HashSet(4); - r.add(e1); - if (e2 != null) { - r.add(e2); - } - r.add(s.e1); - if (s.e2 != null) { - r.add(s.e2); - } - return r; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/SourceInterpreter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/SourceInterpreter.java deleted file mode 100644 index ed98b83d5..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/SourceInterpreter.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; -import com.alibaba.citrus.asm.tree.AbstractInsnNode; -import com.alibaba.citrus.asm.tree.FieldInsnNode; -import com.alibaba.citrus.asm.tree.LdcInsnNode; -import com.alibaba.citrus.asm.tree.MethodInsnNode; - -/** - * An {@link Interpreter} for {@link SourceValue} values. - * - * @author Eric Bruneton - */ -public class SourceInterpreter implements Opcodes, Interpreter { - - public Value newValue(final Type type) { - return new SourceValue(type == null ? 1 : type.getSize()); - } - - public Value newOperation(final AbstractInsnNode insn) { - int size; - switch (insn.getOpcode()) { - case LCONST_0: - case LCONST_1: - case DCONST_0: - case DCONST_1: - size = 2; - break; - case LDC: - Object cst = ((LdcInsnNode) insn).cst; - size = cst instanceof Long || cst instanceof Double ? 2 : 1; - break; - case GETSTATIC: - size = Type.getType(((FieldInsnNode) insn).desc).getSize(); - break; - default: - size = 1; - } - return new SourceValue(size, insn); - } - - public Value copyOperation(final AbstractInsnNode insn, final Value value) { - return new SourceValue(value.getSize(), insn); - } - - public Value unaryOperation(final AbstractInsnNode insn, final Value value) { - int size; - switch (insn.getOpcode()) { - case LNEG: - case DNEG: - case I2L: - case I2D: - case L2D: - case F2L: - case F2D: - case D2L: - size = 2; - break; - case GETFIELD: - size = Type.getType(((FieldInsnNode) insn).desc).getSize(); - break; - default: - size = 1; - } - return new SourceValue(size, insn); - } - - public Value binaryOperation(final AbstractInsnNode insn, final Value value1, final Value value2) { - int size; - switch (insn.getOpcode()) { - case LALOAD: - case DALOAD: - case LADD: - case DADD: - case LSUB: - case DSUB: - case LMUL: - case DMUL: - case LDIV: - case DDIV: - case LREM: - case DREM: - case LSHL: - case LSHR: - case LUSHR: - case LAND: - case LOR: - case LXOR: - size = 2; - break; - default: - size = 1; - } - return new SourceValue(size, insn); - } - - public Value ternaryOperation(final AbstractInsnNode insn, final Value value1, final Value value2, - final Value value3) { - return new SourceValue(1, insn); - } - - public Value naryOperation(final AbstractInsnNode insn, final List values) { - int size; - if (insn.getOpcode() == MULTIANEWARRAY) { - size = 1; - } else { - size = Type.getReturnType(((MethodInsnNode) insn).desc).getSize(); - } - return new SourceValue(size, insn); - } - - public Value merge(final Value v, final Value w) { - SourceValue dv = (SourceValue) v; - SourceValue dw = (SourceValue) w; - if (dv.insns instanceof SmallSet && dw.insns instanceof SmallSet) { - Set s = ((SmallSet) dv.insns).union((SmallSet) dw.insns); - if (s == dv.insns && dv.size == dw.size) { - return v; - } else { - return new SourceValue(Math.min(dv.size, dw.size), s); - } - } - if (dv.size != dw.size || !dv.insns.containsAll(dw.insns)) { - Set s = new HashSet(); - s.addAll(dv.insns); - s.addAll(dw.insns); - return new SourceValue(Math.min(dv.size, dw.size), s); - } - return v; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/SourceValue.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/SourceValue.java deleted file mode 100644 index fccc7325f..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/SourceValue.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import java.util.Set; - -import com.alibaba.citrus.asm.tree.AbstractInsnNode; - -/** - * A {@link Value} that is represented by its type in a two types type system. - * This type system distinguishes the ONEWORD and TWOWORDS types. - * - * @author Eric Bruneton - */ -public class SourceValue implements Value { - - /** - * The size of this value. - */ - public final int size; - - /** - * The instructions that can produce this value. For example, for the Java - * code below, the instructions that can produce the value of i at - * line 5 are the txo ISTORE instructions at line 1 and 3: - * - *
-     * 1: i = 0;
-     * 2: if (...) {
-     * 3:   i = 1;
-     * 4: }
-     * 5: return i;
-     * 
- * - * This field is a set of {@link AbstractInsnNode} objects. - */ - public final Set insns; - - public SourceValue(final int size) { - this(size, SmallSet.EMPTY_SET); - } - - public SourceValue(final int size, final AbstractInsnNode insn) { - this.size = size; - this.insns = new SmallSet(insn, null); - } - - public SourceValue(final int size, final Set insns) { - this.size = size; - this.insns = insns; - } - - public int getSize() { - return size; - } - - @Override - public boolean equals(final Object value) { - if (!(value instanceof SourceValue)) { - return false; - } - SourceValue v = (SourceValue) value; - return size == v.size && insns.equals(v.insns); - } - - @Override - public int hashCode() { - return insns.hashCode(); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Subroutine.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Subroutine.java deleted file mode 100644 index fa52ed773..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Subroutine.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import java.util.ArrayList; -import java.util.List; - -import com.alibaba.citrus.asm.tree.JumpInsnNode; -import com.alibaba.citrus.asm.tree.LabelNode; - -/** - * A method subroutine (corresponds to a JSR instruction). - * - * @author Eric Bruneton - */ -class Subroutine { - - LabelNode start; - - boolean[] access; - - List callers; - - private Subroutine() { - } - - Subroutine(final LabelNode start, final int maxLocals, final JumpInsnNode caller) { - this.start = start; - this.access = new boolean[maxLocals]; - this.callers = new ArrayList(); - callers.add(caller); - } - - public Subroutine copy() { - Subroutine result = new Subroutine(); - result.start = start; - result.access = new boolean[access.length]; - System.arraycopy(access, 0, result.access, 0, access.length); - result.callers = new ArrayList(callers); - return result; - } - - public boolean merge(final Subroutine subroutine) throws AnalyzerException { - boolean changes = false; - for (int i = 0; i < access.length; ++i) { - if (subroutine.access[i] && !access[i]) { - access[i] = true; - changes = true; - } - } - if (subroutine.start == start) { - for (int i = 0; i < subroutine.callers.size(); ++i) { - Object caller = subroutine.callers.get(i); - if (!callers.contains(caller)) { - callers.add(caller); - changes = true; - } - } - } - return changes; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Value.java b/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Value.java deleted file mode 100644 index 32820fcf6..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/tree/analysis/Value.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -/** - * An immutable symbolic value for semantic interpretation of bytecode. - * - * @author Eric Bruneton - */ -public interface Value { - - /** - * Returns the size of this value in words. - * - * @return either 1 or 2. - */ - int getSize(); -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifiable.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifiable.java deleted file mode 100644 index bd965f16e..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifiable.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import java.util.Map; - -/** - * An attribute that can print the ASM code to create an equivalent attribute. - * Implementation should print the ASM code that generates attribute data - * structures for current attribute state. - * - * @author Eugene Kuleshov - */ -public interface ASMifiable { - - /** - * Prints the ASM code to create an attribute equal to this attribute. - * - * @param buf A buffer used for printing Java code. - * @param varName name of the variable in a printed code used to store - * attribute instance. - * @param labelNames map of label instances to their names. - */ - void asmify(StringBuilder buf, String varName, Map labelNames); -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierAbstractVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierAbstractVisitor.java deleted file mode 100644 index 272adb18e..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierAbstractVisitor.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import java.util.Map; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.Type; - -/** - * An abstract ASMifier visitor. - * - * @author Eric Bruneton - */ -public class ASMifierAbstractVisitor extends AbstractVisitor { - - /** - * The name of the variable for this visitor in the produced code. - */ - protected String name; - - /** - * The label names. This map associates String values to Label keys. It is - * used only in ASMifierMethodVisitor. - */ - Map labelNames; - - /** - * Constructs a new {@link ASMifierAbstractVisitor}. - * - * @param name the name of the variable for this visitor in the produced - * code. - */ - protected ASMifierAbstractVisitor(final String name) { - this.name = name; - } - - /** - * Prints the ASM code that generates the given annotation. - * - * @param desc the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values. - */ - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - buf.setLength(0); - buf.append("{\n").append("av0 = ").append(name).append(".visitAnnotation("); - appendConstant(desc); - buf.append(", ").append(visible).append(");\n"); - text.add(buf.toString()); - ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0); - text.add(av.getText()); - text.add("}\n"); - return av; - } - - /** - * Prints the ASM code that generates the given attribute. - * - * @param attr an attribute. - */ - public void visitAttribute(final Attribute attr) { - buf.setLength(0); - buf.append("// ATTRIBUTE ").append(attr.type).append('\n'); - if (attr instanceof ASMifiable) { - buf.append("{\n"); - ((ASMifiable) attr).asmify(buf, "attr", labelNames); - buf.append(name).append(".visitAttribute(attr);\n"); - buf.append("}\n"); - } - text.add(buf.toString()); - } - - /** - * Prints the ASM code to end the visit. - */ - public void visitEnd() { - buf.setLength(0); - buf.append(name).append(".visitEnd();\n"); - text.add(buf.toString()); - } - - /** - * Appends a string representation of the given constant to the given - * buffer. - * - * @param cst an {@link Integer}, {@link Float}, {@link Long}, - * {@link Double} or {@link String} object. May be null. - */ - void appendConstant(final Object cst) { - appendConstant(buf, cst); - } - - /** - * Appends a string representation of the given constant to the given - * buffer. - * - * @param buf a string buffer. - * @param cst an {@link Integer}, {@link Float}, {@link Long}, - * {@link Double} or {@link String} object. May be null. - */ - static void appendConstant(final StringBuilder buf, final Object cst) { - if (cst == null) { - buf.append("null"); - } else if (cst instanceof String) { - appendString(buf, (String) cst); - } else if (cst instanceof Type) { - buf.append("Type.getType(\""); - buf.append(((Type) cst).getDescriptor()); - buf.append("\")"); - } else if (cst instanceof Byte) { - buf.append("new Byte((byte)").append(cst).append(')'); - } else if (cst instanceof Boolean) { - buf.append(((Boolean) cst).booleanValue() ? "Boolean.TRUE" : "Boolean.FALSE"); - } else if (cst instanceof Short) { - buf.append("new Short((short)").append(cst).append(')'); - } else if (cst instanceof Character) { - int c = ((Character) cst).charValue(); - buf.append("new Character((char)").append(c).append(')'); - } else if (cst instanceof Integer) { - buf.append("new Integer(").append(cst).append(')'); - } else if (cst instanceof Float) { - buf.append("new Float(\"").append(cst).append("\")"); - } else if (cst instanceof Long) { - buf.append("new Long(").append(cst).append("L)"); - } else if (cst instanceof Double) { - buf.append("new Double(\"").append(cst).append("\")"); - } else if (cst instanceof byte[]) { - byte[] v = (byte[]) cst; - buf.append("new byte[] {"); - for (int i = 0; i < v.length; i++) { - buf.append(i == 0 ? "" : ",").append(v[i]); - } - buf.append('}'); - } else if (cst instanceof boolean[]) { - boolean[] v = (boolean[]) cst; - buf.append("new boolean[] {"); - for (int i = 0; i < v.length; i++) { - buf.append(i == 0 ? "" : ",").append(v[i]); - } - buf.append('}'); - } else if (cst instanceof short[]) { - short[] v = (short[]) cst; - buf.append("new short[] {"); - for (int i = 0; i < v.length; i++) { - buf.append(i == 0 ? "" : ",").append("(short)").append(v[i]); - } - buf.append('}'); - } else if (cst instanceof char[]) { - char[] v = (char[]) cst; - buf.append("new char[] {"); - for (int i = 0; i < v.length; i++) { - buf.append(i == 0 ? "" : ",").append("(char)").append((int) v[i]); - } - buf.append('}'); - } else if (cst instanceof int[]) { - int[] v = (int[]) cst; - buf.append("new int[] {"); - for (int i = 0; i < v.length; i++) { - buf.append(i == 0 ? "" : ",").append(v[i]); - } - buf.append('}'); - } else if (cst instanceof long[]) { - long[] v = (long[]) cst; - buf.append("new long[] {"); - for (int i = 0; i < v.length; i++) { - buf.append(i == 0 ? "" : ",").append(v[i]).append('L'); - } - buf.append('}'); - } else if (cst instanceof float[]) { - float[] v = (float[]) cst; - buf.append("new float[] {"); - for (int i = 0; i < v.length; i++) { - buf.append(i == 0 ? "" : ",").append(v[i]).append('f'); - } - buf.append('}'); - } else if (cst instanceof double[]) { - double[] v = (double[]) cst; - buf.append("new double[] {"); - for (int i = 0; i < v.length; i++) { - buf.append(i == 0 ? "" : ",").append(v[i]).append('d'); - } - buf.append('}'); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierAnnotationVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierAnnotationVisitor.java deleted file mode 100644 index afd890c2a..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierAnnotationVisitor.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import com.alibaba.citrus.asm.AnnotationVisitor; - -/** - * An {@link AnnotationVisitor} that prints the ASM code that generates the - * annotations it visits. - * - * @author Eric Bruneton - */ -public class ASMifierAnnotationVisitor extends AbstractVisitor implements AnnotationVisitor { - - /** - * Identifier of the annotation visitor variable in the produced code. - */ - protected final int id; - - /** - * Constructs a new {@link ASMifierAnnotationVisitor}. - * - * @param id identifier of the annotation visitor variable in the produced - * code. - */ - public ASMifierAnnotationVisitor(final int id) { - this.id = id; - } - - // ------------------------------------------------------------------------ - // Implementation of the AnnotationVisitor interface - // ------------------------------------------------------------------------ - - public void visit(final String name, final Object value) { - buf.setLength(0); - buf.append("av").append(id).append(".visit("); - ASMifierAbstractVisitor.appendConstant(buf, name); - buf.append(", "); - ASMifierAbstractVisitor.appendConstant(buf, value); - buf.append(");\n"); - text.add(buf.toString()); - } - - public void visitEnum(final String name, final String desc, final String value) { - buf.setLength(0); - buf.append("av").append(id).append(".visitEnum("); - ASMifierAbstractVisitor.appendConstant(buf, name); - buf.append(", "); - ASMifierAbstractVisitor.appendConstant(buf, desc); - buf.append(", "); - ASMifierAbstractVisitor.appendConstant(buf, value); - buf.append(");\n"); - text.add(buf.toString()); - } - - public AnnotationVisitor visitAnnotation(final String name, final String desc) { - buf.setLength(0); - buf.append("{\n"); - buf.append("AnnotationVisitor av").append(id + 1).append(" = av"); - buf.append(id).append(".visitAnnotation("); - ASMifierAbstractVisitor.appendConstant(buf, name); - buf.append(", "); - ASMifierAbstractVisitor.appendConstant(buf, desc); - buf.append(");\n"); - text.add(buf.toString()); - ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(id + 1); - text.add(av.getText()); - text.add("}\n"); - return av; - } - - public AnnotationVisitor visitArray(final String name) { - buf.setLength(0); - buf.append("{\n"); - buf.append("AnnotationVisitor av").append(id + 1).append(" = av"); - buf.append(id).append(".visitArray("); - ASMifierAbstractVisitor.appendConstant(buf, name); - buf.append(");\n"); - text.add(buf.toString()); - ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(id + 1); - text.add(av.getText()); - text.add("}\n"); - return av; - } - - public void visitEnd() { - buf.setLength(0); - buf.append("av").append(id).append(".visitEnd();\n"); - text.add(buf.toString()); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierClassVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierClassVisitor.java deleted file mode 100644 index 3be81b772..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierClassVisitor.java +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import java.io.FileInputStream; -import java.io.PrintWriter; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * A {@link ClassVisitor} that prints the ASM code that generates the classes it - * visits. This class visitor can be used to quickly write ASM code to generate - * some given bytecode: - *
    - *
  • write the Java source code equivalent to the bytecode you want to - * generate;
  • - *
  • compile it with javac;
  • - *
  • make a {@link ASMifierClassVisitor} visit this compiled class (see the - * {@link #main main} method);
  • - *
  • edit the generated source code, if necessary.
  • - *
- * The source code printed when visiting the Hello class is the - * following: - *

- *

- * - *
- * import com.alibaba.citrus.asm.*;
- * 
- * public class HelloDump implements Opcodes {
- *     public static byte[] dump() throws Exception {
- *         ClassWriter cw = new ClassWriter(0);
- *         FieldVisitor fv;
- *         MethodVisitor mv;
- *         AnnotationVisitor av0;
- *         cw.visit(49, ACC_PUBLIC + ACC_SUPER, "Hello", null, "java/lang/Object", null);
- *         cw.visitSource("Hello.java", null);
- *         {
- *             mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
- *             mv.visitVarInsn(ALOAD, 0);
- *             mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
- *             mv.visitInsn(RETURN);
- *             mv.visitMaxs(1, 1);
- *             mv.visitEnd();
- *         }
- *         {
- *             mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
- *             mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
- *             mv.visitLdcInsn("hello");
- *             mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
- *             mv.visitInsn(RETURN);
- *             mv.visitMaxs(2, 1);
- *             mv.visitEnd();
- *         }
- *         cw.visitEnd();
- *         return cw.toByteArray();
- *     }
- * }
- * 
- * 
- * - *
where Hello is defined by: - *

- *

- * - *
- * public class Hello {
- *     public static void main(String[] args) {
- *         System.out.println("hello");
- *     }
- * }
- * 
- * - *
- * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public class ASMifierClassVisitor extends ASMifierAbstractVisitor implements ClassVisitor { - - /** - * Pseudo access flag used to distinguish class access flags. - */ - private static final int ACCESS_CLASS = 262144; - - /** - * Pseudo access flag used to distinguish field access flags. - */ - private static final int ACCESS_FIELD = 524288; - - /** - * Pseudo access flag used to distinguish inner class flags. - */ - private static final int ACCESS_INNER = 1048576; - - /** - * The print writer to be used to print the class. - */ - protected final PrintWriter pw; - - /** - * Prints the ASM source code to generate the given class to the standard - * output. - *

- * Usage: ASMifierClassVisitor [-debug] <fully qualified class name or - * class file name> - * - * @param args the command line arguments. - * @throws Exception if the class cannot be found, or if an IO exception - * occurs. - */ - public static void main(final String[] args) throws Exception { - int i = 0; - int flags = ClassReader.SKIP_DEBUG; - - boolean ok = true; - if (args.length < 1 || args.length > 2) { - ok = false; - } - if (ok && "-debug".equals(args[0])) { - i = 1; - flags = 0; - if (args.length != 2) { - ok = false; - } - } - if (!ok) { - System.err.println("Prints the ASM code to generate the given class."); - System.err.println("Usage: ASMifierClassVisitor [-debug] " - + ""); - return; - } - ClassReader cr; - if (args[i].endsWith(".class") || args[i].indexOf('\\') > -1 || args[i].indexOf('/') > -1) { - cr = new ClassReader(new FileInputStream(args[i])); - } else { - cr = new ClassReader(args[i]); - } - cr.accept(new ASMifierClassVisitor(new PrintWriter(System.out)), getDefaultAttributes(), flags); - } - - /** - * Constructs a new {@link ASMifierClassVisitor} object. - * - * @param pw the print writer to be used to print the class. - */ - public ASMifierClassVisitor(final PrintWriter pw) { - super("cw"); - this.pw = pw; - } - - // ------------------------------------------------------------------------ - // Implementation of the ClassVisitor interface - // ------------------------------------------------------------------------ - - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - String simpleName; - int n = name.lastIndexOf('/'); - if (n == -1) { - simpleName = name; - } else { - text.add("package asm." + name.substring(0, n).replace('/', '.') + ";\n"); - simpleName = name.substring(n + 1); - } - text.add("import java.util.*;\n"); - text.add("import com.alibaba.citrus.asm.*;\n"); - text.add("import com.alibaba.citrus.asm.attrs.*;\n"); - text.add("public class " + simpleName + "Dump implements Opcodes {\n\n"); - text.add("public static byte[] dump () throws Exception {\n\n"); - text.add("ClassWriter cw = new ClassWriter(0);\n"); - text.add("FieldVisitor fv;\n"); - text.add("MethodVisitor mv;\n"); - text.add("AnnotationVisitor av0;\n\n"); - - buf.setLength(0); - buf.append("cw.visit("); - switch (version) { - case Opcodes.V1_1: - buf.append("V1_1"); - break; - case Opcodes.V1_2: - buf.append("V1_2"); - break; - case Opcodes.V1_3: - buf.append("V1_3"); - break; - case Opcodes.V1_4: - buf.append("V1_4"); - break; - case Opcodes.V1_5: - buf.append("V1_5"); - break; - case Opcodes.V1_6: - buf.append("V1_6"); - break; - default: - buf.append(version); - break; - } - buf.append(", "); - appendAccess(access | ACCESS_CLASS); - buf.append(", "); - appendConstant(name); - buf.append(", "); - appendConstant(signature); - buf.append(", "); - appendConstant(superName); - buf.append(", "); - if (interfaces != null && interfaces.length > 0) { - buf.append("new String[] {"); - for (int i = 0; i < interfaces.length; ++i) { - buf.append(i == 0 ? " " : ", "); - appendConstant(interfaces[i]); - } - buf.append(" }"); - } else { - buf.append("null"); - } - buf.append(");\n\n"); - text.add(buf.toString()); - } - - public void visitSource(final String file, final String debug) { - buf.setLength(0); - buf.append("cw.visitSource("); - appendConstant(file); - buf.append(", "); - appendConstant(debug); - buf.append(");\n\n"); - text.add(buf.toString()); - } - - public void visitOuterClass(final String owner, final String name, final String desc) { - buf.setLength(0); - buf.append("cw.visitOuterClass("); - appendConstant(owner); - buf.append(", "); - appendConstant(name); - buf.append(", "); - appendConstant(desc); - buf.append(");\n\n"); - text.add(buf.toString()); - } - - public void visitInnerClass(final String name, final String outerName, final String innerName, final int access) { - buf.setLength(0); - buf.append("cw.visitInnerClass("); - appendConstant(name); - buf.append(", "); - appendConstant(outerName); - buf.append(", "); - appendConstant(innerName); - buf.append(", "); - appendAccess(access | ACCESS_INNER); - buf.append(");\n\n"); - text.add(buf.toString()); - } - - public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, - final Object value) { - buf.setLength(0); - buf.append("{\n"); - buf.append("fv = cw.visitField("); - appendAccess(access | ACCESS_FIELD); - buf.append(", "); - appendConstant(name); - buf.append(", "); - appendConstant(desc); - buf.append(", "); - appendConstant(signature); - buf.append(", "); - appendConstant(value); - buf.append(");\n"); - text.add(buf.toString()); - ASMifierFieldVisitor aav = new ASMifierFieldVisitor(); - text.add(aav.getText()); - text.add("}\n"); - return aav; - } - - public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, - final String[] exceptions) { - buf.setLength(0); - buf.append("{\n"); - buf.append("mv = cw.visitMethod("); - appendAccess(access); - buf.append(", "); - appendConstant(name); - buf.append(", "); - appendConstant(desc); - buf.append(", "); - appendConstant(signature); - buf.append(", "); - if (exceptions != null && exceptions.length > 0) { - buf.append("new String[] {"); - for (int i = 0; i < exceptions.length; ++i) { - buf.append(i == 0 ? " " : ", "); - appendConstant(exceptions[i]); - } - buf.append(" }"); - } else { - buf.append("null"); - } - buf.append(");\n"); - text.add(buf.toString()); - ASMifierMethodVisitor acv = createASMifierMethodVisitor(); - text.add(acv.getText()); - text.add("}\n"); - return acv; - } - - protected ASMifierMethodVisitor createASMifierMethodVisitor() { - return new ASMifierMethodVisitor(); - } - - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - buf.setLength(0); - buf.append("{\n"); - buf.append("av0 = cw.visitAnnotation("); - appendConstant(desc); - buf.append(", "); - buf.append(visible); - buf.append(");\n"); - text.add(buf.toString()); - ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0); - text.add(av.getText()); - text.add("}\n"); - return av; - } - - public void visitEnd() { - text.add("cw.visitEnd();\n\n"); - text.add("return cw.toByteArray();\n"); - text.add("}\n"); - text.add("}\n"); - printList(pw, text); - pw.flush(); - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - /** - * Appends a string representation of the given access modifiers to - * {@link #buf buf}. - * - * @param access some access modifiers. - */ - void appendAccess(final int access) { - boolean first = true; - if ((access & Opcodes.ACC_PUBLIC) != 0) { - buf.append("ACC_PUBLIC"); - first = false; - } - if ((access & Opcodes.ACC_PRIVATE) != 0) { - buf.append("ACC_PRIVATE"); - first = false; - } - if ((access & Opcodes.ACC_PROTECTED) != 0) { - buf.append("ACC_PROTECTED"); - first = false; - } - if ((access & Opcodes.ACC_FINAL) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_FINAL"); - first = false; - } - if ((access & Opcodes.ACC_STATIC) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_STATIC"); - first = false; - } - if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) { - if (!first) { - buf.append(" + "); - } - if ((access & ACCESS_CLASS) == 0) { - buf.append("ACC_SYNCHRONIZED"); - } else { - buf.append("ACC_SUPER"); - } - first = false; - } - if ((access & Opcodes.ACC_VOLATILE) != 0 && (access & ACCESS_FIELD) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_VOLATILE"); - first = false; - } - if ((access & Opcodes.ACC_BRIDGE) != 0 && (access & ACCESS_CLASS) == 0 && (access & ACCESS_FIELD) == 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_BRIDGE"); - first = false; - } - if ((access & Opcodes.ACC_VARARGS) != 0 && (access & ACCESS_CLASS) == 0 && (access & ACCESS_FIELD) == 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_VARARGS"); - first = false; - } - if ((access & Opcodes.ACC_TRANSIENT) != 0 && (access & ACCESS_FIELD) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_TRANSIENT"); - first = false; - } - if ((access & Opcodes.ACC_NATIVE) != 0 && (access & ACCESS_CLASS) == 0 && (access & ACCESS_FIELD) == 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_NATIVE"); - first = false; - } - if ((access & Opcodes.ACC_ENUM) != 0 - && ((access & ACCESS_CLASS) != 0 || (access & ACCESS_FIELD) != 0 || (access & ACCESS_INNER) != 0)) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_ENUM"); - first = false; - } - if ((access & Opcodes.ACC_ANNOTATION) != 0 && (access & ACCESS_CLASS) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_ANNOTATION"); - first = false; - } - if ((access & Opcodes.ACC_ABSTRACT) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_ABSTRACT"); - first = false; - } - if ((access & Opcodes.ACC_INTERFACE) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_INTERFACE"); - first = false; - } - if ((access & Opcodes.ACC_STRICT) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_STRICT"); - first = false; - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_SYNTHETIC"); - first = false; - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_DEPRECATED"); - first = false; - } - if (first) { - buf.append('0'); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierFieldVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierFieldVisitor.java deleted file mode 100644 index 43e41040d..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierFieldVisitor.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import com.alibaba.citrus.asm.FieldVisitor; - -/** - * A {@link FieldVisitor} that prints the ASM code that generates the fields it - * visits. - * - * @author Eric Bruneton - */ -public class ASMifierFieldVisitor extends ASMifierAbstractVisitor implements FieldVisitor { - - /** - * Constructs a new {@link ASMifierFieldVisitor}. - */ - public ASMifierFieldVisitor() { - super("fv"); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierMethodVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierMethodVisitor.java deleted file mode 100644 index ea2e79847..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/ASMifierMethodVisitor.java +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import java.util.HashMap; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * A {@link MethodVisitor} that prints the ASM code that generates the methods - * it visits. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public class ASMifierMethodVisitor extends ASMifierAbstractVisitor implements MethodVisitor { - - /** - * Constructs a new {@link ASMifierMethodVisitor} object. - */ - public ASMifierMethodVisitor() { - super("mv"); - this.labelNames = new HashMap(); - } - - public AnnotationVisitor visitAnnotationDefault() { - buf.setLength(0); - buf.append("{\n").append("av0 = mv.visitAnnotationDefault();\n"); - text.add(buf.toString()); - ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0); - text.add(av.getText()); - text.add("}\n"); - return av; - } - - public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc, final boolean visible) { - buf.setLength(0); - buf.append("{\n").append("av0 = mv.visitParameterAnnotation(").append(parameter).append(", "); - appendConstant(desc); - buf.append(", ").append(visible).append(");\n"); - text.add(buf.toString()); - ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0); - text.add(av.getText()); - text.add("}\n"); - return av; - } - - public void visitCode() { - text.add("mv.visitCode();\n"); - } - - public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, - final Object[] stack) { - buf.setLength(0); - switch (type) { - case Opcodes.F_NEW: - case Opcodes.F_FULL: - declareFrameTypes(nLocal, local); - declareFrameTypes(nStack, stack); - if (type == Opcodes.F_NEW) { - buf.append("mv.visitFrame(Opcodes.F_NEW, "); - } else { - buf.append("mv.visitFrame(Opcodes.F_FULL, "); - } - buf.append(nLocal).append(", new Object[] {"); - appendFrameTypes(nLocal, local); - buf.append("}, ").append(nStack).append(", new Object[] {"); - appendFrameTypes(nStack, stack); - buf.append('}'); - break; - case Opcodes.F_APPEND: - declareFrameTypes(nLocal, local); - buf.append("mv.visitFrame(Opcodes.F_APPEND,").append(nLocal).append(", new Object[] {"); - appendFrameTypes(nLocal, local); - buf.append("}, 0, null"); - break; - case Opcodes.F_CHOP: - buf.append("mv.visitFrame(Opcodes.F_CHOP,").append(nLocal).append(", null, 0, null"); - break; - case Opcodes.F_SAME: - buf.append("mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null"); - break; - case Opcodes.F_SAME1: - declareFrameTypes(1, stack); - buf.append("mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"); - appendFrameTypes(1, stack); - buf.append('}'); - break; - } - buf.append(");\n"); - text.add(buf.toString()); - } - - public void visitInsn(final int opcode) { - buf.setLength(0); - buf.append("mv.visitInsn(").append(OPCODES[opcode]).append(");\n"); - text.add(buf.toString()); - } - - public void visitIntInsn(final int opcode, final int operand) { - buf.setLength(0); - buf.append("mv.visitIntInsn(").append(OPCODES[opcode]).append(", ").append( - opcode == Opcodes.NEWARRAY ? TYPES[operand] : Integer.toString(operand)).append(");\n"); - text.add(buf.toString()); - } - - public void visitVarInsn(final int opcode, final int var) { - buf.setLength(0); - buf.append("mv.visitVarInsn(").append(OPCODES[opcode]).append(", ").append(var).append(");\n"); - text.add(buf.toString()); - } - - public void visitTypeInsn(final int opcode, final String type) { - buf.setLength(0); - buf.append("mv.visitTypeInsn(").append(OPCODES[opcode]).append(", "); - appendConstant(type); - buf.append(");\n"); - text.add(buf.toString()); - } - - public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { - buf.setLength(0); - buf.append("mv.visitFieldInsn(").append(OPCODES[opcode]).append(", "); - appendConstant(owner); - buf.append(", "); - appendConstant(name); - buf.append(", "); - appendConstant(desc); - buf.append(");\n"); - text.add(buf.toString()); - } - - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - buf.setLength(0); - buf.append("mv.visitMethodInsn(").append(OPCODES[opcode]).append(", "); - appendConstant(owner); - buf.append(", "); - appendConstant(name); - buf.append(", "); - appendConstant(desc); - buf.append(");\n"); - text.add(buf.toString()); - } - - public void visitJumpInsn(final int opcode, final Label label) { - buf.setLength(0); - declareLabel(label); - buf.append("mv.visitJumpInsn(").append(OPCODES[opcode]).append(", "); - appendLabel(label); - buf.append(");\n"); - text.add(buf.toString()); - } - - public void visitLabel(final Label label) { - buf.setLength(0); - declareLabel(label); - buf.append("mv.visitLabel("); - appendLabel(label); - buf.append(");\n"); - text.add(buf.toString()); - } - - public void visitLdcInsn(final Object cst) { - buf.setLength(0); - buf.append("mv.visitLdcInsn("); - appendConstant(cst); - buf.append(");\n"); - text.add(buf.toString()); - } - - public void visitIincInsn(final int var, final int increment) { - buf.setLength(0); - buf.append("mv.visitIincInsn(").append(var).append(", ").append(increment).append(");\n"); - text.add(buf.toString()); - } - - public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label[] labels) { - buf.setLength(0); - for (int i = 0; i < labels.length; ++i) { - declareLabel(labels[i]); - } - declareLabel(dflt); - - buf.append("mv.visitTableSwitchInsn(").append(min).append(", ").append(max).append(", "); - appendLabel(dflt); - buf.append(", new Label[] {"); - for (int i = 0; i < labels.length; ++i) { - buf.append(i == 0 ? " " : ", "); - appendLabel(labels[i]); - } - buf.append(" });\n"); - text.add(buf.toString()); - } - - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { - buf.setLength(0); - for (int i = 0; i < labels.length; ++i) { - declareLabel(labels[i]); - } - declareLabel(dflt); - - buf.append("mv.visitLookupSwitchInsn("); - appendLabel(dflt); - buf.append(", new int[] {"); - for (int i = 0; i < keys.length; ++i) { - buf.append(i == 0 ? " " : ", ").append(keys[i]); - } - buf.append(" }, new Label[] {"); - for (int i = 0; i < labels.length; ++i) { - buf.append(i == 0 ? " " : ", "); - appendLabel(labels[i]); - } - buf.append(" });\n"); - text.add(buf.toString()); - } - - public void visitMultiANewArrayInsn(final String desc, final int dims) { - buf.setLength(0); - buf.append("mv.visitMultiANewArrayInsn("); - appendConstant(desc); - buf.append(", ").append(dims).append(");\n"); - text.add(buf.toString()); - } - - public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type) { - buf.setLength(0); - declareLabel(start); - declareLabel(end); - declareLabel(handler); - buf.append("mv.visitTryCatchBlock("); - appendLabel(start); - buf.append(", "); - appendLabel(end); - buf.append(", "); - appendLabel(handler); - buf.append(", "); - appendConstant(type); - buf.append(");\n"); - text.add(buf.toString()); - } - - public void visitLocalVariable(final String name, final String desc, final String signature, final Label start, - final Label end, final int index) { - buf.setLength(0); - buf.append("mv.visitLocalVariable("); - appendConstant(name); - buf.append(", "); - appendConstant(desc); - buf.append(", "); - appendConstant(signature); - buf.append(", "); - appendLabel(start); - buf.append(", "); - appendLabel(end); - buf.append(", ").append(index).append(");\n"); - text.add(buf.toString()); - } - - public void visitLineNumber(final int line, final Label start) { - buf.setLength(0); - buf.append("mv.visitLineNumber(").append(line).append(", "); - appendLabel(start); - buf.append(");\n"); - text.add(buf.toString()); - } - - public void visitMaxs(final int maxStack, final int maxLocals) { - buf.setLength(0); - buf.append("mv.visitMaxs(").append(maxStack).append(", ").append(maxLocals).append(");\n"); - text.add(buf.toString()); - } - - private void declareFrameTypes(final int n, final Object[] o) { - for (int i = 0; i < n; ++i) { - if (o[i] instanceof Label) { - declareLabel((Label) o[i]); - } - } - } - - private void appendFrameTypes(final int n, final Object[] o) { - for (int i = 0; i < n; ++i) { - if (i > 0) { - buf.append(", "); - } - if (o[i] instanceof String) { - appendConstant(o[i]); - } else if (o[i] instanceof Integer) { - switch (((Integer) o[i]).intValue()) { - case 0: - buf.append("Opcodes.TOP"); - break; - case 1: - buf.append("Opcodes.INTEGER"); - break; - case 2: - buf.append("Opcodes.FLOAT"); - break; - case 3: - buf.append("Opcodes.DOUBLE"); - break; - case 4: - buf.append("Opcodes.LONG"); - break; - case 5: - buf.append("Opcodes.NULL"); - break; - case 6: - buf.append("Opcodes.UNINITIALIZED_THIS"); - break; - } - } else { - appendLabel((Label) o[i]); - } - } - } - - /** - * Appends a declaration of the given label to {@link #buf buf}. This - * declaration is of the form "Label lXXX = new Label();". Does nothing if - * the given label has already been declared. - * - * @param l a label. - */ - private void declareLabel(final Label l) { - String name = (String) labelNames.get(l); - if (name == null) { - name = "l" + labelNames.size(); - labelNames.put(l, name); - buf.append("Label ").append(name).append(" = new Label();\n"); - } - } - - /** - * Appends the name of the given label to {@link #buf buf}. The given label - * must already have a name. One way to ensure this is to always call - * {@link #declareLabel declared} before calling this method. - * - * @param l a label. - */ - private void appendLabel(final Label l) { - buf.append((String) labelNames.get(l)); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/AbstractVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/AbstractVisitor.java deleted file mode 100644 index 06076ee68..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/AbstractVisitor.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; - -import com.alibaba.citrus.asm.Attribute; - -/** - * An abstract visitor. - * - * @author Eric Bruneton - */ -public abstract class AbstractVisitor { - - /** - * The names of the Java Virtual Machine opcodes. - */ - public static final String[] OPCODES; - /** - * Types for operand parameter of the - * {@link com.alibaba.citrus.asm.MethodVisitor#visitIntInsn} method when - * opcode is NEWARRAY. - */ - public static final String[] TYPES; - - static { - String s = "NOP,ACONST_NULL,ICONST_M1,ICONST_0,ICONST_1,ICONST_2," - + "ICONST_3,ICONST_4,ICONST_5,LCONST_0,LCONST_1,FCONST_0," - + "FCONST_1,FCONST_2,DCONST_0,DCONST_1,BIPUSH,SIPUSH,LDC,,," - + "ILOAD,LLOAD,FLOAD,DLOAD,ALOAD,,,,,,,,,,,,,,,,,,,,,IALOAD," - + "LALOAD,FALOAD,DALOAD,AALOAD,BALOAD,CALOAD,SALOAD,ISTORE," - + "LSTORE,FSTORE,DSTORE,ASTORE,,,,,,,,,,,,,,,,,,,,,IASTORE," - + "LASTORE,FASTORE,DASTORE,AASTORE,BASTORE,CASTORE,SASTORE,POP," - + "POP2,DUP,DUP_X1,DUP_X2,DUP2,DUP2_X1,DUP2_X2,SWAP,IADD,LADD," - + "FADD,DADD,ISUB,LSUB,FSUB,DSUB,IMUL,LMUL,FMUL,DMUL,IDIV,LDIV," - + "FDIV,DDIV,IREM,LREM,FREM,DREM,INEG,LNEG,FNEG,DNEG,ISHL,LSHL," - + "ISHR,LSHR,IUSHR,LUSHR,IAND,LAND,IOR,LOR,IXOR,LXOR,IINC,I2L," - + "I2F,I2D,L2I,L2F,L2D,F2I,F2L,F2D,D2I,D2L,D2F,I2B,I2C,I2S,LCMP," - + "FCMPL,FCMPG,DCMPL,DCMPG,IFEQ,IFNE,IFLT,IFGE,IFGT,IFLE," - + "IF_ICMPEQ,IF_ICMPNE,IF_ICMPLT,IF_ICMPGE,IF_ICMPGT,IF_ICMPLE," - + "IF_ACMPEQ,IF_ACMPNE,GOTO,JSR,RET,TABLESWITCH,LOOKUPSWITCH," - + "IRETURN,LRETURN,FRETURN,DRETURN,ARETURN,RETURN,GETSTATIC," - + "PUTSTATIC,GETFIELD,PUTFIELD,INVOKEVIRTUAL,INVOKESPECIAL," - + "INVOKESTATIC,INVOKEINTERFACE,,NEW,NEWARRAY,ANEWARRAY," - + "ARRAYLENGTH,ATHROW,CHECKCAST,INSTANCEOF,MONITORENTER," - + "MONITOREXIT,,MULTIANEWARRAY,IFNULL,IFNONNULL,"; - OPCODES = new String[200]; - int i = 0; - int j = 0; - int l; - while ((l = s.indexOf(',', j)) > 0) { - OPCODES[i++] = j + 1 == l ? null : s.substring(j, l); - j = l + 1; - } - - s = "T_BOOLEAN,T_CHAR,T_FLOAT,T_DOUBLE,T_BYTE,T_SHORT,T_INT,T_LONG,"; - TYPES = new String[12]; - j = 0; - i = 4; - while ((l = s.indexOf(',', j)) > 0) { - TYPES[i++] = s.substring(j, l); - j = l + 1; - } - } - - /** - * The text to be printed. Since the code of methods is not necessarily - * visited in sequential order, one method after the other, but can be - * interlaced (some instructions from method one, then some instructions - * from method two, then some instructions from method one again...), it is - * not possible to print the visited instructions directly to a sequential - * stream. A class is therefore printed in a two steps process: a string - * tree is constructed during the visit, and printed to a sequential stream - * at the end of the visit. This string tree is stored in this field, as a - * string list that can contain other string lists, which can themselves - * contain other string lists, and so on. - */ - public final List text; - - /** - * A buffer that can be used to create strings. - */ - protected final StringBuilder buf; - - /** - * Constructs a new {@link AbstractVisitor}. - */ - protected AbstractVisitor() { - this.text = new ArrayList(); - this.buf = new StringBuilder(); - } - - /** - * Returns the text constructed by this visitor. - * - * @return the text constructed by this visitor. - */ - public List getText() { - return text; - } - - /** - * Prints the text constructed by this visitor. - * - * @param pw the print writer to be used. - */ - public void print(final PrintWriter pw) { - printList(pw, text); - } - - /** - * Appends a quoted string to a given buffer. - * - * @param buf the buffer where the string must be added. - * @param s the string to be added. - */ - public static void appendString(final StringBuilder buf, final String s) { - buf.append('\"'); - for (int i = 0; i < s.length(); ++i) { - char c = s.charAt(i); - if (c == '\n') { - buf.append("\\n"); - } else if (c == '\r') { - buf.append("\\r"); - } else if (c == '\\') { - buf.append("\\\\"); - } else if (c == '"') { - buf.append("\\\""); - } else if (c < 0x20 || c > 0x7f) { - buf.append("\\u"); - if (c < 0x10) { - buf.append("000"); - } else if (c < 0x100) { - buf.append("00"); - } else if (c < 0x1000) { - buf.append('0'); - } - buf.append(Integer.toString(c, 16)); - } else { - buf.append(c); - } - } - buf.append('\"'); - } - - /** - * Prints the given string tree. - * - * @param pw the writer to be used to print the tree. - * @param l a string tree, i.e., a string list that can contain other string - * lists, and so on recursively. - */ - static void printList(final PrintWriter pw, final List l) { - for (int i = 0; i < l.size(); ++i) { - Object o = l.get(i); - if (o instanceof List) { - printList(pw, (List) o); - } else { - pw.print(o.toString()); - } - } - } - - /** - * Returns the default {@link ASMifiable} prototypes. - * - * @return the default {@link ASMifiable} prototypes. - */ - public static Attribute[] getDefaultAttributes() { - return new Attribute[0]; - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckAnnotationAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckAnnotationAdapter.java deleted file mode 100644 index e0b911d01..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckAnnotationAdapter.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Type; - -/** - * An {@link AnnotationVisitor} that checks that its methods are properly used. - * - * @author Eric Bruneton - */ -public class CheckAnnotationAdapter implements AnnotationVisitor { - - private final AnnotationVisitor av; - - private final boolean named; - - private boolean end; - - public CheckAnnotationAdapter(final AnnotationVisitor av) { - this(av, true); - } - - CheckAnnotationAdapter(final AnnotationVisitor av, final boolean named) { - this.av = av; - this.named = named; - } - - public void visit(final String name, final Object value) { - checkEnd(); - checkName(name); - if (!(value instanceof Byte || value instanceof Boolean || value instanceof Character || value instanceof Short - || value instanceof Integer || value instanceof Long || value instanceof Float - || value instanceof Double || value instanceof String || value instanceof Type - || value instanceof byte[] || value instanceof boolean[] || value instanceof char[] - || value instanceof short[] || value instanceof int[] || value instanceof long[] - || value instanceof float[] || value instanceof double[])) { - throw new IllegalArgumentException("Invalid annotation value"); - } - if (av != null) { - av.visit(name, value); - } - } - - public void visitEnum(final String name, final String desc, final String value) { - checkEnd(); - checkName(name); - CheckMethodAdapter.checkDesc(desc, false); - if (value == null) { - throw new IllegalArgumentException("Invalid enum value"); - } - if (av != null) { - av.visitEnum(name, desc, value); - } - } - - public AnnotationVisitor visitAnnotation(final String name, final String desc) { - checkEnd(); - checkName(name); - CheckMethodAdapter.checkDesc(desc, false); - return new CheckAnnotationAdapter(av == null ? null : av.visitAnnotation(name, desc)); - } - - public AnnotationVisitor visitArray(final String name) { - checkEnd(); - checkName(name); - return new CheckAnnotationAdapter(av == null ? null : av.visitArray(name), false); - } - - public void visitEnd() { - checkEnd(); - end = true; - if (av != null) { - av.visitEnd(); - } - } - - private void checkEnd() { - if (end) { - throw new IllegalStateException("Cannot call a visit method after visitEnd has been called"); - } - } - - private void checkName(final String name) { - if (named && name == null) { - throw new IllegalArgumentException("Annotation value name must not be null"); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckClassAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckClassAdapter.java deleted file mode 100644 index d57f6ecb3..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckClassAdapter.java +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import java.io.FileInputStream; -import java.io.PrintWriter; -import java.util.List; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.ClassAdapter; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; -import com.alibaba.citrus.asm.tree.ClassNode; -import com.alibaba.citrus.asm.tree.MethodNode; -import com.alibaba.citrus.asm.tree.TryCatchBlockNode; -import com.alibaba.citrus.asm.tree.analysis.Analyzer; -import com.alibaba.citrus.asm.tree.analysis.Frame; -import com.alibaba.citrus.asm.tree.analysis.SimpleVerifier; - -/** - * A {@link ClassAdapter} that checks that its methods are properly used. More - * precisely this class adapter checks each method call individually, based - * only on its arguments, but does not check the sequence - * of method calls. For example, the invalid sequence - * visitField(ACC_PUBLIC, "i", "I", null) visitField(ACC_PUBLIC, - * "i", "D", null) will not be detected by this class adapter. - *

- * CheckClassAdapter can be also used to verify bytecode - * transformations in order to make sure transformed bytecode is sane. For - * example: - * - *

- *   InputStream is = ...; // get bytes for the source class
- *   ClassReader cr = new ClassReader(is);
- *   ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
- *   ClassVisitor cv = new <b>MyClassAdapter</b>(new CheckClassAdapter(cw));
- *   cr.accept(cv, 0);
- * 
- *   StringWriter sw = new StringWriter();
- *   PrintWriter pw = new PrintWriter(sw);
- *   CheckClassAdapter.verify(new ClassReader(cw.toByteArray()), false, pw);
- *   assertTrue(sw.toString(), sw.toString().length()==0);
- * 
- * - * Above code runs transformed bytecode trough the - * CheckClassAdapter. It won't be exactly the same verification as - * JVM does, but it run data flow analysis for the code of each method and - * checks that expectations are met for each method instruction. - *

- * If method bytecode has errors, assertion text will show the erroneous - * instruction number and dump of the failed method with information about - * locals and stack slot for each instruction. For example (format is - - * insnNumber locals : stack): - * - *

- * com.alibaba.citrus.asm.tree.analysis.AnalyzerException: Error at instruction 71: Expected I, but found .
- *   at com.alibaba.citrus.asm.tree.analysis.Analyzer.analyze(Analyzer.java:289)
- *   at com.alibaba.citrus.asm.util.CheckClassAdapter.verify(CheckClassAdapter.java:135)
- * ...
- * remove()V
- * 00000 LinkedBlockingQueue$Itr . . . . . . . .  :
- *   ICONST_0
- * 00001 LinkedBlockingQueue$Itr . . . . . . . .  : I
- *   ISTORE 2
- * 00001 LinkedBlockingQueue$Itr <b>.</b> I . . . . . .  :
- * ...
- * 
- * 00071 LinkedBlockingQueue$Itr <b>.</b> I . . . . . .  : 
- *   ILOAD 1
- * 00072 <b>?</b>                
- *   INVOKESPECIAL java/lang/Integer.<init> (I)V
- * ...
- * 
- * - * In the above output you can see that variable 1 loaded by - * ILOAD 1 instruction at position 00071 is not - * initialized. You can also see that at the beginning of the method (code - * inserted by the transformation) variable 2 is initialized. - *

- * Note that when used like that, CheckClassAdapter.verify() can - * trigger additional class loading, because it is using - * SimpleVerifier. - * - * @author Eric Bruneton - */ -public class CheckClassAdapter extends ClassAdapter { - - /** - * true if the visit method has been called. - */ - private boolean start; - - /** - * true if the visitSource method has been called. - */ - private boolean source; - - /** - * true if the visitOuterClass method has been called. - */ - private boolean outer; - - /** - * true if the visitEnd method has been called. - */ - private boolean end; - - /** - * Checks a given class. - *

- * Usage: CheckClassAdapter <fully qualified class name or class file - * name> - * - * @param args the command line arguments. - * @throws Exception if the class cannot be found, or if an IO exception - * occurs. - */ - public static void main(final String[] args) throws Exception { - if (args.length != 1) { - System.err.println("Verifies the given class."); - System.err.println("Usage: CheckClassAdapter " + ""); - return; - } - ClassReader cr; - if (args[0].endsWith(".class")) { - cr = new ClassReader(new FileInputStream(args[0])); - } else { - cr = new ClassReader(args[0]); - } - - verify(cr, false, new PrintWriter(System.err)); - } - - /** - * Checks a given class - * - * @param cr a ClassReader that contains bytecode for the - * analysis. - * @param dump true if bytecode should be printed out not only when errors - * are found. - * @param pw write where results going to be printed - */ - public static void verify(final ClassReader cr, final boolean dump, final PrintWriter pw) { - ClassNode cn = new ClassNode(); - cr.accept(new CheckClassAdapter(cn), ClassReader.SKIP_DEBUG); - - Type syperType = cn.superName == null ? null : Type.getObjectType(cn.superName); - List methods = cn.methods; - for (int i = 0; i < methods.size(); ++i) { - MethodNode method = (MethodNode) methods.get(i); - Analyzer a = new Analyzer(new SimpleVerifier(Type.getObjectType(cn.name), syperType, false)); - try { - a.analyze(cn.name, method); - if (!dump) { - continue; - } - } catch (Exception e) { - e.printStackTrace(pw); - } - Frame[] frames = a.getFrames(); - - TraceMethodVisitor mv = new TraceMethodVisitor(); - - pw.println(method.name + method.desc); - for (int j = 0; j < method.instructions.size(); ++j) { - method.instructions.get(j).accept(mv); - - StringBuilder s = new StringBuilder(); - Frame f = frames[j]; - if (f == null) { - s.append('?'); - } else { - for (int k = 0; k < f.getLocals(); ++k) { - s.append(getShortName(f.getLocal(k).toString())).append(' '); - } - s.append(" : "); - for (int k = 0; k < f.getStackSize(); ++k) { - s.append(getShortName(f.getStack(k).toString())).append(' '); - } - } - while (s.length() < method.maxStack + method.maxLocals + 1) { - s.append(' '); - } - pw.print(Integer.toString(j + 100000).substring(1)); - pw.print(" " + s + " : " + mv.buf); // mv.text.get(j)); - } - for (int j = 0; j < method.tryCatchBlocks.size(); ++j) { - ((TryCatchBlockNode) method.tryCatchBlocks.get(j)).accept(mv); - pw.print(" " + mv.buf); - } - pw.println(); - } - pw.flush(); - } - - private static String getShortName(final String name) { - int n = name.lastIndexOf('/'); - int k = name.length(); - if (name.charAt(k - 1) == ';') { - k--; - } - return n == -1 ? name : name.substring(n + 1, k); - } - - /** - * Constructs a new {@link CheckClassAdapter}. - * - * @param cv the class visitor to which this adapter must delegate calls. - */ - public CheckClassAdapter(final ClassVisitor cv) { - super(cv); - } - - // ------------------------------------------------------------------------ - // Implementation of the ClassVisitor interface - // ------------------------------------------------------------------------ - - @Override - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - if (start) { - throw new IllegalStateException("visit must be called only once"); - } - start = true; - checkState(); - checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER + Opcodes.ACC_INTERFACE - + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + Opcodes.ACC_ANNOTATION + Opcodes.ACC_ENUM - + Opcodes.ACC_DEPRECATED); - if (name == null || !name.endsWith("package-info")) { - CheckMethodAdapter.checkInternalName(name, "class name"); - } - if ("java/lang/Object".equals(name)) { - if (superName != null) { - throw new IllegalArgumentException("The super class name of the Object class must be 'null'"); - } - } else { - CheckMethodAdapter.checkInternalName(superName, "super class name"); - } - if (signature != null) { - CheckMethodAdapter.checkClassSignature(signature); - } - if ((access & Opcodes.ACC_INTERFACE) != 0) { - if (!"java/lang/Object".equals(superName)) { - throw new IllegalArgumentException("The super class name of interfaces must be 'java/lang/Object'"); - } - } - if (interfaces != null) { - for (int i = 0; i < interfaces.length; ++i) { - CheckMethodAdapter.checkInternalName(interfaces[i], "interface name at index " + i); - } - } - cv.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public void visitSource(final String file, final String debug) { - checkState(); - if (source) { - throw new IllegalStateException("visitSource can be called only once."); - } - source = true; - cv.visitSource(file, debug); - } - - @Override - public void visitOuterClass(final String owner, final String name, final String desc) { - checkState(); - if (outer) { - throw new IllegalStateException("visitOuterClass can be called only once."); - } - outer = true; - if (owner == null) { - throw new IllegalArgumentException("Illegal outer class owner"); - } - if (desc != null) { - CheckMethodAdapter.checkMethodDesc(desc); - } - cv.visitOuterClass(owner, name, desc); - } - - @Override - public void visitInnerClass(final String name, final String outerName, final String innerName, final int access) { - checkState(); - CheckMethodAdapter.checkInternalName(name, "class name"); - if (outerName != null) { - CheckMethodAdapter.checkInternalName(outerName, "outer class name"); - } - if (innerName != null) { - CheckMethodAdapter.checkIdentifier(innerName, "inner class name"); - } - checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_PRIVATE + Opcodes.ACC_PROTECTED + Opcodes.ACC_STATIC - + Opcodes.ACC_FINAL + Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC - + Opcodes.ACC_ANNOTATION + Opcodes.ACC_ENUM); - cv.visitInnerClass(name, outerName, innerName, access); - } - - @Override - public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, - final Object value) { - checkState(); - checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_PRIVATE + Opcodes.ACC_PROTECTED + Opcodes.ACC_STATIC - + Opcodes.ACC_FINAL + Opcodes.ACC_VOLATILE + Opcodes.ACC_TRANSIENT + Opcodes.ACC_SYNTHETIC - + Opcodes.ACC_ENUM + Opcodes.ACC_DEPRECATED); - CheckMethodAdapter.checkIdentifier(name, "field name"); - CheckMethodAdapter.checkDesc(desc, false); - if (signature != null) { - CheckMethodAdapter.checkFieldSignature(signature); - } - if (value != null) { - CheckMethodAdapter.checkConstant(value); - } - FieldVisitor av = cv.visitField(access, name, desc, signature, value); - return new CheckFieldAdapter(av); - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, - final String[] exceptions) { - checkState(); - checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_PRIVATE + Opcodes.ACC_PROTECTED + Opcodes.ACC_STATIC - + Opcodes.ACC_FINAL + Opcodes.ACC_SYNCHRONIZED + Opcodes.ACC_BRIDGE + Opcodes.ACC_VARARGS - + Opcodes.ACC_NATIVE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_STRICT + Opcodes.ACC_SYNTHETIC - + Opcodes.ACC_DEPRECATED); - CheckMethodAdapter.checkMethodIdentifier(name, "method name"); - CheckMethodAdapter.checkMethodDesc(desc); - if (signature != null) { - CheckMethodAdapter.checkMethodSignature(signature); - } - if (exceptions != null) { - for (int i = 0; i < exceptions.length; ++i) { - CheckMethodAdapter.checkInternalName(exceptions[i], "exception name at index " + i); - } - } - return new CheckMethodAdapter(cv.visitMethod(access, name, desc, signature, exceptions)); - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - checkState(); - CheckMethodAdapter.checkDesc(desc, false); - return new CheckAnnotationAdapter(cv.visitAnnotation(desc, visible)); - } - - @Override - public void visitAttribute(final Attribute attr) { - checkState(); - if (attr == null) { - throw new IllegalArgumentException("Invalid attribute (must not be null)"); - } - cv.visitAttribute(attr); - } - - @Override - public void visitEnd() { - checkState(); - end = true; - cv.visitEnd(); - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - /** - * Checks that the visit method has been called and that visitEnd has not - * been called. - */ - private void checkState() { - if (!start) { - throw new IllegalStateException("Cannot visit member before visit has been called."); - } - if (end) { - throw new IllegalStateException("Cannot visit member after visitEnd has been called."); - } - } - - /** - * Checks that the given access flags do not contain invalid flags. This - * method also checks that mutually incompatible flags are not set - * simultaneously. - * - * @param access the access flags to be checked - * @param possibleAccess the valid access flags. - */ - static void checkAccess(final int access, final int possibleAccess) { - if ((access & ~possibleAccess) != 0) { - throw new IllegalArgumentException("Invalid access flags: " + access); - } - int pub = (access & Opcodes.ACC_PUBLIC) == 0 ? 0 : 1; - int pri = (access & Opcodes.ACC_PRIVATE) == 0 ? 0 : 1; - int pro = (access & Opcodes.ACC_PROTECTED) == 0 ? 0 : 1; - if (pub + pri + pro > 1) { - throw new IllegalArgumentException("public private and protected are mutually exclusive: " + access); - } - int fin = (access & Opcodes.ACC_FINAL) == 0 ? 0 : 1; - int abs = (access & Opcodes.ACC_ABSTRACT) == 0 ? 0 : 1; - if (fin + abs > 1) { - throw new IllegalArgumentException("final and abstract are mutually exclusive: " + access); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckFieldAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckFieldAdapter.java deleted file mode 100644 index 7a22f3b77..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckFieldAdapter.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.FieldVisitor; - -/** - * A {@link FieldVisitor} that checks that its methods are properly used. - */ -public class CheckFieldAdapter implements FieldVisitor { - - private final FieldVisitor fv; - - private boolean end; - - public CheckFieldAdapter(final FieldVisitor fv) { - this.fv = fv; - } - - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - checkEnd(); - CheckMethodAdapter.checkDesc(desc, false); - return new CheckAnnotationAdapter(fv.visitAnnotation(desc, visible)); - } - - public void visitAttribute(final Attribute attr) { - checkEnd(); - if (attr == null) { - throw new IllegalArgumentException("Invalid attribute (must not be null)"); - } - fv.visitAttribute(attr); - } - - public void visitEnd() { - checkEnd(); - end = true; - fv.visitEnd(); - } - - private void checkEnd() { - if (end) { - throw new IllegalStateException("Cannot call a visit method after visitEnd has been called"); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckMethodAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckMethodAdapter.java deleted file mode 100644 index 35090029c..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckMethodAdapter.java +++ /dev/null @@ -1,1235 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import java.util.HashMap; -import java.util.Map; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodAdapter; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; - -/** - * A {@link MethodAdapter} that checks that its methods are properly used. More - * precisely this code adapter checks each instruction individually (i.e., each - * visit method checks some preconditions based only on its arguments - - * such as the fact that the given opcode is correct for a given visit method), - * but does not check the sequence of instructions. For example, - * in a method whose signature is void m (), the invalid instruction - * IRETURN, or the invalid sequence IADD L2I will not be detected by this - * code adapter. - * - * @author Eric Bruneton - */ -public class CheckMethodAdapter extends MethodAdapter { - - /** - * true if the visitCode method has been called. - */ - private boolean startCode; - - /** - * true if the visitMaxs method has been called. - */ - private boolean endCode; - - /** - * true if the visitEnd method has been called. - */ - private boolean endMethod; - - /** - * The already visited labels. This map associate Integer values to Label - * keys. - */ - private final Map labels; - - /** - * Code of the visit method to be used for each opcode. - */ - private static final int[] TYPE; - - static { - String s = "BBBBBBBBBBBBBBBBCCIAADDDDDAAAAAAAAAAAAAAAAAAAABBBBBBBBDD" - + "DDDAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - + "BBBBBBBBBBBBBBBBBBBJBBBBBBBBBBBBBBBBBBBBHHHHHHHHHHHHHHHHD" + "KLBBBBBBFFFFGGGGAECEBBEEBBAMHHAA"; - TYPE = new int[s.length()]; - for (int i = 0; i < TYPE.length; ++i) { - TYPE[i] = s.charAt(i) - 'A' - 1; - } - } - - // code to generate the above string - // public static void main (String[] args) { - // int[] TYPE = new int[] { - // 0, //NOP - // 0, //ACONST_NULL - // 0, //ICONST_M1 - // 0, //ICONST_0 - // 0, //ICONST_1 - // 0, //ICONST_2 - // 0, //ICONST_3 - // 0, //ICONST_4 - // 0, //ICONST_5 - // 0, //LCONST_0 - // 0, //LCONST_1 - // 0, //FCONST_0 - // 0, //FCONST_1 - // 0, //FCONST_2 - // 0, //DCONST_0 - // 0, //DCONST_1 - // 1, //BIPUSH - // 1, //SIPUSH - // 7, //LDC - // -1, //LDC_W - // -1, //LDC2_W - // 2, //ILOAD - // 2, //LLOAD - // 2, //FLOAD - // 2, //DLOAD - // 2, //ALOAD - // -1, //ILOAD_0 - // -1, //ILOAD_1 - // -1, //ILOAD_2 - // -1, //ILOAD_3 - // -1, //LLOAD_0 - // -1, //LLOAD_1 - // -1, //LLOAD_2 - // -1, //LLOAD_3 - // -1, //FLOAD_0 - // -1, //FLOAD_1 - // -1, //FLOAD_2 - // -1, //FLOAD_3 - // -1, //DLOAD_0 - // -1, //DLOAD_1 - // -1, //DLOAD_2 - // -1, //DLOAD_3 - // -1, //ALOAD_0 - // -1, //ALOAD_1 - // -1, //ALOAD_2 - // -1, //ALOAD_3 - // 0, //IALOAD - // 0, //LALOAD - // 0, //FALOAD - // 0, //DALOAD - // 0, //AALOAD - // 0, //BALOAD - // 0, //CALOAD - // 0, //SALOAD - // 2, //ISTORE - // 2, //LSTORE - // 2, //FSTORE - // 2, //DSTORE - // 2, //ASTORE - // -1, //ISTORE_0 - // -1, //ISTORE_1 - // -1, //ISTORE_2 - // -1, //ISTORE_3 - // -1, //LSTORE_0 - // -1, //LSTORE_1 - // -1, //LSTORE_2 - // -1, //LSTORE_3 - // -1, //FSTORE_0 - // -1, //FSTORE_1 - // -1, //FSTORE_2 - // -1, //FSTORE_3 - // -1, //DSTORE_0 - // -1, //DSTORE_1 - // -1, //DSTORE_2 - // -1, //DSTORE_3 - // -1, //ASTORE_0 - // -1, //ASTORE_1 - // -1, //ASTORE_2 - // -1, //ASTORE_3 - // 0, //IASTORE - // 0, //LASTORE - // 0, //FASTORE - // 0, //DASTORE - // 0, //AASTORE - // 0, //BASTORE - // 0, //CASTORE - // 0, //SASTORE - // 0, //POP - // 0, //POP2 - // 0, //DUP - // 0, //DUP_X1 - // 0, //DUP_X2 - // 0, //DUP2 - // 0, //DUP2_X1 - // 0, //DUP2_X2 - // 0, //SWAP - // 0, //IADD - // 0, //LADD - // 0, //FADD - // 0, //DADD - // 0, //ISUB - // 0, //LSUB - // 0, //FSUB - // 0, //DSUB - // 0, //IMUL - // 0, //LMUL - // 0, //FMUL - // 0, //DMUL - // 0, //IDIV - // 0, //LDIV - // 0, //FDIV - // 0, //DDIV - // 0, //IREM - // 0, //LREM - // 0, //FREM - // 0, //DREM - // 0, //INEG - // 0, //LNEG - // 0, //FNEG - // 0, //DNEG - // 0, //ISHL - // 0, //LSHL - // 0, //ISHR - // 0, //LSHR - // 0, //IUSHR - // 0, //LUSHR - // 0, //IAND - // 0, //LAND - // 0, //IOR - // 0, //LOR - // 0, //IXOR - // 0, //LXOR - // 8, //IINC - // 0, //I2L - // 0, //I2F - // 0, //I2D - // 0, //L2I - // 0, //L2F - // 0, //L2D - // 0, //F2I - // 0, //F2L - // 0, //F2D - // 0, //D2I - // 0, //D2L - // 0, //D2F - // 0, //I2B - // 0, //I2C - // 0, //I2S - // 0, //LCMP - // 0, //FCMPL - // 0, //FCMPG - // 0, //DCMPL - // 0, //DCMPG - // 6, //IFEQ - // 6, //IFNE - // 6, //IFLT - // 6, //IFGE - // 6, //IFGT - // 6, //IFLE - // 6, //IF_ICMPEQ - // 6, //IF_ICMPNE - // 6, //IF_ICMPLT - // 6, //IF_ICMPGE - // 6, //IF_ICMPGT - // 6, //IF_ICMPLE - // 6, //IF_ACMPEQ - // 6, //IF_ACMPNE - // 6, //GOTO - // 6, //JSR - // 2, //RET - // 9, //TABLESWITCH - // 10, //LOOKUPSWITCH - // 0, //IRETURN - // 0, //LRETURN - // 0, //FRETURN - // 0, //DRETURN - // 0, //ARETURN - // 0, //RETURN - // 4, //GETSTATIC - // 4, //PUTSTATIC - // 4, //GETFIELD - // 4, //PUTFIELD - // 5, //INVOKEVIRTUAL - // 5, //INVOKESPECIAL - // 5, //INVOKESTATIC - // 5, //INVOKEINTERFACE - // -1, //UNUSED - // 3, //NEW - // 1, //NEWARRAY - // 3, //ANEWARRAY - // 0, //ARRAYLENGTH - // 0, //ATHROW - // 3, //CHECKCAST - // 3, //INSTANCEOF - // 0, //MONITORENTER - // 0, //MONITOREXIT - // -1, //WIDE - // 11, //MULTIANEWARRAY - // 6, //IFNULL - // 6, //IFNONNULL - // -1, //GOTO_W - // -1 //JSR_W - // }; - // for (int i = 0; i < TYPE.length; ++i) { - // System.out.print((char)(TYPE[i] + 1 + 'A')); - // } - // System.out.println(); - // } - - /** - * Constructs a new {@link CheckMethodAdapter} object. - * - * @param cv the code visitor to which this adapter must delegate calls. - */ - public CheckMethodAdapter(final MethodVisitor cv) { - super(cv); - this.labels = new HashMap(); - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - checkEndMethod(); - checkDesc(desc, false); - return new CheckAnnotationAdapter(mv.visitAnnotation(desc, visible)); - } - - @Override - public AnnotationVisitor visitAnnotationDefault() { - checkEndMethod(); - return new CheckAnnotationAdapter(mv.visitAnnotationDefault(), false); - } - - @Override - public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc, final boolean visible) { - checkEndMethod(); - checkDesc(desc, false); - return new CheckAnnotationAdapter(mv.visitParameterAnnotation(parameter, desc, visible)); - } - - public void visitAttribute(final Attribute attr) { - checkEndMethod(); - if (attr == null) { - throw new IllegalArgumentException("Invalid attribute (must not be null)"); - } - mv.visitAttribute(attr); - } - - public void visitCode() { - startCode = true; - mv.visitCode(); - } - - public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, - final Object[] stack) { - int mLocal; - int mStack; - switch (type) { - case Opcodes.F_NEW: - case Opcodes.F_FULL: - mLocal = Integer.MAX_VALUE; - mStack = Integer.MAX_VALUE; - break; - - case Opcodes.F_SAME: - mLocal = 0; - mStack = 0; - break; - - case Opcodes.F_SAME1: - mLocal = 0; - mStack = 1; - break; - - case Opcodes.F_APPEND: - case Opcodes.F_CHOP: - mLocal = 3; - mStack = 0; - break; - - default: - throw new IllegalArgumentException("Invalid frame type " + type); - } - - if (nLocal > mLocal) { - throw new IllegalArgumentException("Invalid nLocal=" + nLocal + " for frame type " + type); - } - if (nStack > mStack) { - throw new IllegalArgumentException("Invalid nStack=" + nStack + " for frame type " + type); - } - - if (type != Opcodes.F_CHOP) { - if (nLocal > 0 && (local == null || local.length < nLocal)) { - throw new IllegalArgumentException("Array local[] is shorter than nLocal"); - } - for (int i = 0; i < nLocal; ++i) { - checkFrameValue(local[i]); - } - } - if (nStack > 0 && (stack == null || stack.length < nStack)) { - throw new IllegalArgumentException("Array stack[] is shorter than nStack"); - } - for (int i = 0; i < nStack; ++i) { - checkFrameValue(stack[i]); - } - - mv.visitFrame(type, nLocal, local, nStack, stack); - } - - public void visitInsn(final int opcode) { - checkStartCode(); - checkEndCode(); - checkOpcode(opcode, 0); - mv.visitInsn(opcode); - } - - public void visitIntInsn(final int opcode, final int operand) { - checkStartCode(); - checkEndCode(); - checkOpcode(opcode, 1); - switch (opcode) { - case Opcodes.BIPUSH: - checkSignedByte(operand, "Invalid operand"); - break; - case Opcodes.SIPUSH: - checkSignedShort(operand, "Invalid operand"); - break; - // case Constants.NEWARRAY: - default: - if (operand < Opcodes.T_BOOLEAN || operand > Opcodes.T_LONG) { - throw new IllegalArgumentException("Invalid operand (must be an array type code T_...): " + operand); - } - } - mv.visitIntInsn(opcode, operand); - } - - public void visitVarInsn(final int opcode, final int var) { - checkStartCode(); - checkEndCode(); - checkOpcode(opcode, 2); - checkUnsignedShort(var, "Invalid variable index"); - mv.visitVarInsn(opcode, var); - } - - public void visitTypeInsn(final int opcode, final String type) { - checkStartCode(); - checkEndCode(); - checkOpcode(opcode, 3); - checkInternalName(type, "type"); - if (opcode == Opcodes.NEW && type.charAt(0) == '[') { - throw new IllegalArgumentException("NEW cannot be used to create arrays: " + type); - } - mv.visitTypeInsn(opcode, type); - } - - public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { - checkStartCode(); - checkEndCode(); - checkOpcode(opcode, 4); - checkInternalName(owner, "owner"); - checkIdentifier(name, "name"); - checkDesc(desc, false); - mv.visitFieldInsn(opcode, owner, name, desc); - } - - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - checkStartCode(); - checkEndCode(); - checkOpcode(opcode, 5); - checkMethodIdentifier(name, "name"); - checkInternalName(owner, "owner"); - checkMethodDesc(desc); - mv.visitMethodInsn(opcode, owner, name, desc); - } - - public void visitJumpInsn(final int opcode, final Label label) { - checkStartCode(); - checkEndCode(); - checkOpcode(opcode, 6); - checkLabel(label, false, "label"); - mv.visitJumpInsn(opcode, label); - } - - public void visitLabel(final Label label) { - checkStartCode(); - checkEndCode(); - checkLabel(label, false, "label"); - if (labels.get(label) != null) { - throw new IllegalArgumentException("Already visited label"); - } - labels.put(label, new Integer(labels.size())); - mv.visitLabel(label); - } - - public void visitLdcInsn(final Object cst) { - checkStartCode(); - checkEndCode(); - if (!(cst instanceof Type)) { - checkConstant(cst); - } - mv.visitLdcInsn(cst); - } - - public void visitIincInsn(final int var, final int increment) { - checkStartCode(); - checkEndCode(); - checkUnsignedShort(var, "Invalid variable index"); - checkSignedShort(increment, "Invalid increment"); - mv.visitIincInsn(var, increment); - } - - public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label[] labels) { - checkStartCode(); - checkEndCode(); - if (max < min) { - throw new IllegalArgumentException("Max = " + max + " must be greater than or equal to min = " + min); - } - checkLabel(dflt, false, "default label"); - if (labels == null || labels.length != max - min + 1) { - throw new IllegalArgumentException("There must be max - min + 1 labels"); - } - for (int i = 0; i < labels.length; ++i) { - checkLabel(labels[i], false, "label at index " + i); - } - mv.visitTableSwitchInsn(min, max, dflt, labels); - } - - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { - checkEndCode(); - checkStartCode(); - checkLabel(dflt, false, "default label"); - if (keys == null || labels == null || keys.length != labels.length) { - throw new IllegalArgumentException("There must be the same number of keys and labels"); - } - for (int i = 0; i < labels.length; ++i) { - checkLabel(labels[i], false, "label at index " + i); - } - mv.visitLookupSwitchInsn(dflt, keys, labels); - } - - public void visitMultiANewArrayInsn(final String desc, final int dims) { - checkStartCode(); - checkEndCode(); - checkDesc(desc, false); - if (desc.charAt(0) != '[') { - throw new IllegalArgumentException("Invalid descriptor (must be an array type descriptor): " + desc); - } - if (dims < 1) { - throw new IllegalArgumentException("Invalid dimensions (must be greater than 0): " + dims); - } - if (dims > desc.lastIndexOf('[') + 1) { - throw new IllegalArgumentException("Invalid dimensions (must not be greater than dims(desc)): " + dims); - } - mv.visitMultiANewArrayInsn(desc, dims); - } - - public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type) { - checkStartCode(); - checkEndCode(); - if (type != null) { - checkInternalName(type, "type"); - } - mv.visitTryCatchBlock(start, end, handler, type); - } - - public void visitLocalVariable(final String name, final String desc, final String signature, final Label start, - final Label end, final int index) { - checkStartCode(); - checkEndCode(); - checkIdentifier(name, "name"); - checkDesc(desc, false); - checkLabel(start, true, "start label"); - checkLabel(end, true, "end label"); - checkUnsignedShort(index, "Invalid variable index"); - int s = ((Integer) labels.get(start)).intValue(); - int e = ((Integer) labels.get(end)).intValue(); - if (e < s) { - throw new IllegalArgumentException("Invalid start and end labels (end must be greater than start)"); - } - mv.visitLocalVariable(name, desc, signature, start, end, index); - } - - public void visitLineNumber(final int line, final Label start) { - checkStartCode(); - checkEndCode(); - checkUnsignedShort(line, "Invalid line number"); - checkLabel(start, true, "start label"); - mv.visitLineNumber(line, start); - } - - public void visitMaxs(final int maxStack, final int maxLocals) { - checkStartCode(); - checkEndCode(); - endCode = true; - checkUnsignedShort(maxStack, "Invalid max stack"); - checkUnsignedShort(maxLocals, "Invalid max locals"); - mv.visitMaxs(maxStack, maxLocals); - } - - public void visitEnd() { - checkEndMethod(); - endMethod = true; - mv.visitEnd(); - } - - // ------------------------------------------------------------------------- - - /** - * Checks that the visitCode method has been called. - */ - void checkStartCode() { - if (!startCode) { - throw new IllegalStateException("Cannot visit instructions before visitCode has been called."); - } - } - - /** - * Checks that the visitMaxs method has not been called. - */ - void checkEndCode() { - if (endCode) { - throw new IllegalStateException("Cannot visit instructions after visitMaxs has been called."); - } - } - - /** - * Checks that the visitEnd method has not been called. - */ - void checkEndMethod() { - if (endMethod) { - throw new IllegalStateException("Cannot visit elements after visitEnd has been called."); - } - } - - /** - * Checks a stack frame value. - * - * @param value the value to be checked. - */ - static void checkFrameValue(final Object value) { - if (value == Opcodes.TOP || value == Opcodes.INTEGER || value == Opcodes.FLOAT || value == Opcodes.LONG - || value == Opcodes.DOUBLE || value == Opcodes.NULL || value == Opcodes.UNINITIALIZED_THIS) { - return; - } - if (value instanceof String) { - checkInternalName((String) value, "Invalid stack frame value"); - return; - } - if (!(value instanceof Label)) { - throw new IllegalArgumentException("Invalid stack frame value: " + value); - } - } - - /** - * Checks that the type of the given opcode is equal to the given type. - * - * @param opcode the opcode to be checked. - * @param type the expected opcode type. - */ - static void checkOpcode(final int opcode, final int type) { - if (opcode < 0 || opcode > 199 || TYPE[opcode] != type) { - throw new IllegalArgumentException("Invalid opcode: " + opcode); - } - } - - /** - * Checks that the given value is a signed byte. - * - * @param value the value to be checked. - * @param msg an message to be used in case of error. - */ - static void checkSignedByte(final int value, final String msg) { - if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) { - throw new IllegalArgumentException(msg + " (must be a signed byte): " + value); - } - } - - /** - * Checks that the given value is a signed short. - * - * @param value the value to be checked. - * @param msg an message to be used in case of error. - */ - static void checkSignedShort(final int value, final String msg) { - if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) { - throw new IllegalArgumentException(msg + " (must be a signed short): " + value); - } - } - - /** - * Checks that the given value is an unsigned short. - * - * @param value the value to be checked. - * @param msg an message to be used in case of error. - */ - static void checkUnsignedShort(final int value, final String msg) { - if (value < 0 || value > 65535) { - throw new IllegalArgumentException(msg + " (must be an unsigned short): " + value); - } - } - - /** - * Checks that the given value is an {@link Integer}, a{@link Float}, a - * {@link Long}, a {@link Double} or a {@link String}. - * - * @param cst the value to be checked. - */ - static void checkConstant(final Object cst) { - if (!(cst instanceof Integer) && !(cst instanceof Float) && !(cst instanceof Long) && !(cst instanceof Double) - && !(cst instanceof String)) { - throw new IllegalArgumentException("Invalid constant: " + cst); - } - } - - /** - * Checks that the given string is a valid Java identifier. - * - * @param name the string to be checked. - * @param msg a message to be used in case of error. - */ - static void checkIdentifier(final String name, final String msg) { - checkIdentifier(name, 0, -1, msg); - } - - /** - * Checks that the given substring is a valid Java identifier. - * - * @param name the string to be checked. - * @param start index of the first character of the identifier (inclusive). - * @param end index of the last character of the identifier (exclusive). -1 - * is equivalent to name.length() if name is not - * null. - * @param msg a message to be used in case of error. - */ - static void checkIdentifier(final String name, final int start, final int end, final String msg) { - if (name == null || (end == -1 ? name.length() <= start : end <= start)) { - throw new IllegalArgumentException("Invalid " + msg + " (must not be null or empty)"); - } - if (!Character.isJavaIdentifierStart(name.charAt(start))) { - throw new IllegalArgumentException("Invalid " + msg + " (must be a valid Java identifier): " + name); - } - int max = end == -1 ? name.length() : end; - for (int i = start + 1; i < max; ++i) { - if (!Character.isJavaIdentifierPart(name.charAt(i))) { - throw new IllegalArgumentException("Invalid " + msg + " (must be a valid Java identifier): " + name); - } - } - } - - /** - * Checks that the given string is a valid Java identifier or is equal to - * '<init>' or '<clinit>'. - * - * @param name the string to be checked. - * @param msg a message to be used in case of error. - */ - static void checkMethodIdentifier(final String name, final String msg) { - if (name == null || name.length() == 0) { - throw new IllegalArgumentException("Invalid " + msg + " (must not be null or empty)"); - } - if ("".equals(name) || "".equals(name)) { - return; - } - if (!Character.isJavaIdentifierStart(name.charAt(0))) { - throw new IllegalArgumentException("Invalid " + msg - + " (must be a '', '' or a valid Java identifier): " + name); - } - for (int i = 1; i < name.length(); ++i) { - if (!Character.isJavaIdentifierPart(name.charAt(i))) { - throw new IllegalArgumentException("Invalid " + msg - + " (must be '' or '' or a valid Java identifier): " + name); - } - } - } - - /** - * Checks that the given string is a valid internal class name. - * - * @param name the string to be checked. - * @param msg a message to be used in case of error. - */ - static void checkInternalName(final String name, final String msg) { - if (name == null || name.length() == 0) { - throw new IllegalArgumentException("Invalid " + msg + " (must not be null or empty)"); - } - if (name.charAt(0) == '[') { - checkDesc(name, false); - } else { - checkInternalName(name, 0, -1, msg); - } - } - - /** - * Checks that the given substring is a valid internal class name. - * - * @param name the string to be checked. - * @param start index of the first character of the identifier (inclusive). - * @param end index of the last character of the identifier (exclusive). -1 - * is equivalent to name.length() if name is not - * null. - * @param msg a message to be used in case of error. - */ - static void checkInternalName(final String name, final int start, final int end, final String msg) { - int max = end == -1 ? name.length() : end; - try { - int begin = start; - int slash; - do { - slash = name.indexOf('/', begin + 1); - if (slash == -1 || slash > max) { - slash = max; - } - checkIdentifier(name, begin, slash, null); - begin = slash + 1; - } while (slash != max); - } catch (IllegalArgumentException _) { - throw new IllegalArgumentException("Invalid " + msg - + " (must be a fully qualified class name in internal form): " + name); - } - } - - /** - * Checks that the given string is a valid type descriptor. - * - * @param desc the string to be checked. - * @param canBeVoid true if V can be considered valid. - */ - static void checkDesc(final String desc, final boolean canBeVoid) { - int end = checkDesc(desc, 0, canBeVoid); - if (end != desc.length()) { - throw new IllegalArgumentException("Invalid descriptor: " + desc); - } - } - - /** - * Checks that a the given substring is a valid type descriptor. - * - * @param desc the string to be checked. - * @param start index of the first character of the identifier (inclusive). - * @param canBeVoid true if V can be considered valid. - * @return the index of the last character of the type decriptor, plus one. - */ - static int checkDesc(final String desc, final int start, final boolean canBeVoid) { - if (desc == null || start >= desc.length()) { - throw new IllegalArgumentException("Invalid type descriptor (must not be null or empty)"); - } - int index; - switch (desc.charAt(start)) { - case 'V': - if (canBeVoid) { - return start + 1; - } else { - throw new IllegalArgumentException("Invalid descriptor: " + desc); - } - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - case 'F': - case 'J': - case 'D': - return start + 1; - case '[': - index = start + 1; - while (index < desc.length() && desc.charAt(index) == '[') { - ++index; - } - if (index < desc.length()) { - return checkDesc(desc, index, false); - } else { - throw new IllegalArgumentException("Invalid descriptor: " + desc); - } - case 'L': - index = desc.indexOf(';', start); - if (index == -1 || index - start < 2) { - throw new IllegalArgumentException("Invalid descriptor: " + desc); - } - try { - checkInternalName(desc, start + 1, index, null); - } catch (IllegalArgumentException _) { - throw new IllegalArgumentException("Invalid descriptor: " + desc); - } - return index + 1; - default: - throw new IllegalArgumentException("Invalid descriptor: " + desc); - } - } - - /** - * Checks that the given string is a valid method descriptor. - * - * @param desc the string to be checked. - */ - static void checkMethodDesc(final String desc) { - if (desc == null || desc.length() == 0) { - throw new IllegalArgumentException("Invalid method descriptor (must not be null or empty)"); - } - if (desc.charAt(0) != '(' || desc.length() < 3) { - throw new IllegalArgumentException("Invalid descriptor: " + desc); - } - int start = 1; - if (desc.charAt(start) != ')') { - do { - if (desc.charAt(start) == 'V') { - throw new IllegalArgumentException("Invalid descriptor: " + desc); - } - start = checkDesc(desc, start, false); - } while (start < desc.length() && desc.charAt(start) != ')'); - } - start = checkDesc(desc, start + 1, true); - if (start != desc.length()) { - throw new IllegalArgumentException("Invalid descriptor: " + desc); - } - } - - /** - * Checks a class signature. - * - * @param signature a string containing the signature that must be checked. - */ - static void checkClassSignature(final String signature) { - // ClassSignature: - // FormalTypeParameters? ClassTypeSignature ClassTypeSignature* - - int pos = 0; - if (getChar(signature, 0) == '<') { - pos = checkFormalTypeParameters(signature, pos); - } - pos = checkClassTypeSignature(signature, pos); - while (getChar(signature, pos) == 'L') { - pos = checkClassTypeSignature(signature, pos); - } - if (pos != signature.length()) { - throw new IllegalArgumentException(signature + ": error at index " + pos); - } - } - - /** - * Checks a method signature. - * - * @param signature a string containing the signature that must be checked. - */ - static void checkMethodSignature(final String signature) { - // MethodTypeSignature: - // FormalTypeParameters? ( TypeSignature* ) ( TypeSignature | V ) ( - // ^ClassTypeSignature | ^TypeVariableSignature )* - - int pos = 0; - if (getChar(signature, 0) == '<') { - pos = checkFormalTypeParameters(signature, pos); - } - pos = checkChar('(', signature, pos); - while ("ZCBSIFJDL[T".indexOf(getChar(signature, pos)) != -1) { - pos = checkTypeSignature(signature, pos); - } - pos = checkChar(')', signature, pos); - if (getChar(signature, pos) == 'V') { - ++pos; - } else { - pos = checkTypeSignature(signature, pos); - } - while (getChar(signature, pos) == '^') { - ++pos; - if (getChar(signature, pos) == 'L') { - pos = checkClassTypeSignature(signature, pos); - } else { - pos = checkTypeVariableSignature(signature, pos); - } - } - if (pos != signature.length()) { - throw new IllegalArgumentException(signature + ": error at index " + pos); - } - } - - /** - * Checks a field signature. - * - * @param signature a string containing the signature that must be checked. - */ - static void checkFieldSignature(final String signature) { - int pos = checkFieldTypeSignature(signature, 0); - if (pos != signature.length()) { - throw new IllegalArgumentException(signature + ": error at index " + pos); - } - } - - /** - * Checks the formal type parameters of a class or method signature. - * - * @param signature a string containing the signature that must be checked. - * @param pos index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkFormalTypeParameters(final String signature, int pos) { - // FormalTypeParameters: - // < FormalTypeParameter+ > - - pos = checkChar('<', signature, pos); - pos = checkFormalTypeParameter(signature, pos); - while (getChar(signature, pos) != '>') { - pos = checkFormalTypeParameter(signature, pos); - } - return pos + 1; - } - - /** - * Checks a formal type parameter of a class or method signature. - * - * @param signature a string containing the signature that must be checked. - * @param pos index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkFormalTypeParameter(final String signature, int pos) { - // FormalTypeParameter: - // Identifier : FieldTypeSignature? (: FieldTypeSignature)* - - pos = checkIdentifier(signature, pos); - pos = checkChar(':', signature, pos); - if ("L[T".indexOf(getChar(signature, pos)) != -1) { - pos = checkFieldTypeSignature(signature, pos); - } - while (getChar(signature, pos) == ':') { - pos = checkFieldTypeSignature(signature, pos + 1); - } - return pos; - } - - /** - * Checks a field type signature. - * - * @param signature a string containing the signature that must be checked. - * @param pos index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkFieldTypeSignature(final String signature, int pos) { - // FieldTypeSignature: - // ClassTypeSignature | ArrayTypeSignature | TypeVariableSignature - // - // ArrayTypeSignature: - // [ TypeSignature - - switch (getChar(signature, pos)) { - case 'L': - return checkClassTypeSignature(signature, pos); - case '[': - return checkTypeSignature(signature, pos + 1); - default: - return checkTypeVariableSignature(signature, pos); - } - } - - /** - * Checks a class type signature. - * - * @param signature a string containing the signature that must be checked. - * @param pos index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkClassTypeSignature(final String signature, int pos) { - // ClassTypeSignature: - // L Identifier ( / Identifier )* TypeArguments? ( . Identifier - // TypeArguments? )* ; - - pos = checkChar('L', signature, pos); - pos = checkIdentifier(signature, pos); - while (getChar(signature, pos) == '/') { - pos = checkIdentifier(signature, pos + 1); - } - if (getChar(signature, pos) == '<') { - pos = checkTypeArguments(signature, pos); - } - while (getChar(signature, pos) == '.') { - pos = checkIdentifier(signature, pos + 1); - if (getChar(signature, pos) == '<') { - pos = checkTypeArguments(signature, pos); - } - } - return checkChar(';', signature, pos); - } - - /** - * Checks the type arguments in a class type signature. - * - * @param signature a string containing the signature that must be checked. - * @param pos index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkTypeArguments(final String signature, int pos) { - // TypeArguments: - // < TypeArgument+ > - - pos = checkChar('<', signature, pos); - pos = checkTypeArgument(signature, pos); - while (getChar(signature, pos) != '>') { - pos = checkTypeArgument(signature, pos); - } - return pos + 1; - } - - /** - * Checks a type argument in a class type signature. - * - * @param signature a string containing the signature that must be checked. - * @param pos index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkTypeArgument(final String signature, int pos) { - // TypeArgument: - // * | ( ( + | - )? FieldTypeSignature ) - - char c = getChar(signature, pos); - if (c == '*') { - return pos + 1; - } else if (c == '+' || c == '-') { - pos++; - } - return checkFieldTypeSignature(signature, pos); - } - - /** - * Checks a type variable signature. - * - * @param signature a string containing the signature that must be checked. - * @param pos index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkTypeVariableSignature(final String signature, int pos) { - // TypeVariableSignature: - // T Identifier ; - - pos = checkChar('T', signature, pos); - pos = checkIdentifier(signature, pos); - return checkChar(';', signature, pos); - } - - /** - * Checks a type signature. - * - * @param signature a string containing the signature that must be checked. - * @param pos index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkTypeSignature(final String signature, int pos) { - // TypeSignature: - // Z | C | B | S | I | F | J | D | FieldTypeSignature - - switch (getChar(signature, pos)) { - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - case 'F': - case 'J': - case 'D': - return pos + 1; - default: - return checkFieldTypeSignature(signature, pos); - } - } - - /** - * Checks an identifier. - * - * @param signature a string containing the signature that must be checked. - * @param pos index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkIdentifier(final String signature, int pos) { - if (!Character.isJavaIdentifierStart(getChar(signature, pos))) { - throw new IllegalArgumentException(signature + ": identifier expected at index " + pos); - } - ++pos; - while (Character.isJavaIdentifierPart(getChar(signature, pos))) { - ++pos; - } - return pos; - } - - /** - * Checks a single character. - * - * @param signature a string containing the signature that must be checked. - * @param pos index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkChar(final char c, final String signature, int pos) { - if (getChar(signature, pos) == c) { - return pos + 1; - } - throw new IllegalArgumentException(signature + ": '" + c + "' expected at index " + pos); - } - - /** - * Returns the signature car at the given index. - * - * @param signature a signature. - * @param pos an index in signature. - * @return the character at the given index, or 0 if there is no such - * character. - */ - private static char getChar(final String signature, int pos) { - return pos < signature.length() ? signature.charAt(pos) : (char) 0; - } - - /** - * Checks that the given label is not null. This method can also check that - * the label has been visited. - * - * @param label the label to be checked. - * @param checkVisited true to check that the label has been - * visited. - * @param msg a message to be used in case of error. - */ - void checkLabel(final Label label, final boolean checkVisited, final String msg) { - if (label == null) { - throw new IllegalArgumentException("Invalid " + msg + " (must not be null)"); - } - if (checkVisited && labels.get(label) == null) { - throw new IllegalArgumentException("Invalid " + msg + " (must be visited first)"); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckSignatureAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckSignatureAdapter.java deleted file mode 100644 index d90c89f25..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/CheckSignatureAdapter.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import com.alibaba.citrus.asm.signature.SignatureVisitor; - -/** - * A {@link SignatureVisitor} that checks that its methods are properly used. - * - * @author Eric Bruneton - */ -public class CheckSignatureAdapter implements SignatureVisitor { - - /** - * Type to be used to check class signatures. See - * {@link #CheckSignatureAdapter(int, SignatureVisitor) - * CheckSignatureAdapter}. - */ - public static final int CLASS_SIGNATURE = 0; - - /** - * Type to be used to check method signatures. See - * {@link #CheckSignatureAdapter(int, SignatureVisitor) - * CheckSignatureAdapter}. - */ - public static final int METHOD_SIGNATURE = 1; - - /** - * Type to be used to check type signatures.See - * {@link #CheckSignatureAdapter(int, SignatureVisitor) - * CheckSignatureAdapter}. - */ - public static final int TYPE_SIGNATURE = 2; - - private static final int EMPTY = 1; - - private static final int FORMAL = 2; - - private static final int BOUND = 4; - - private static final int SUPER = 8; - - private static final int PARAM = 16; - - private static final int RETURN = 32; - - private static final int SIMPLE_TYPE = 64; - - private static final int CLASS_TYPE = 128; - - private static final int END = 256; - - /** - * Type of the signature to be checked. - */ - private final int type; - - /** - * State of the automaton used to check the order of method calls. - */ - private int state; - - /** - * true if the checked type signature can be 'V'. - */ - private boolean canBeVoid; - - /** - * The visitor to which this adapter must delegate calls. May be - * null. - */ - private final SignatureVisitor sv; - - /** - * Creates a new {@link CheckSignatureAdapter} object. - * - * @param type the type of signature to be checked. See - * {@link #CLASS_SIGNATURE}, {@link #METHOD_SIGNATURE} and - * {@link #TYPE_SIGNATURE}. - * @param sv the visitor to which this adapter must delegate calls. May be - * null. - */ - public CheckSignatureAdapter(final int type, final SignatureVisitor sv) { - this.type = type; - this.state = EMPTY; - this.sv = sv; - } - - // class and method signatures - - public void visitFormalTypeParameter(final String name) { - if (type == TYPE_SIGNATURE || state != EMPTY && state != FORMAL && state != BOUND) { - throw new IllegalStateException(); - } - CheckMethodAdapter.checkIdentifier(name, "formal type parameter"); - state = FORMAL; - if (sv != null) { - sv.visitFormalTypeParameter(name); - } - } - - public SignatureVisitor visitClassBound() { - if (state != FORMAL) { - throw new IllegalStateException(); - } - state = BOUND; - SignatureVisitor v = sv == null ? null : sv.visitClassBound(); - return new CheckSignatureAdapter(TYPE_SIGNATURE, v); - } - - public SignatureVisitor visitInterfaceBound() { - if (state != FORMAL && state != BOUND) { - throw new IllegalArgumentException(); - } - SignatureVisitor v = sv == null ? null : sv.visitInterfaceBound(); - return new CheckSignatureAdapter(TYPE_SIGNATURE, v); - } - - // class signatures - - public SignatureVisitor visitSuperclass() { - if (type != CLASS_SIGNATURE || (state & (EMPTY | FORMAL | BOUND)) == 0) { - throw new IllegalArgumentException(); - } - state = SUPER; - SignatureVisitor v = sv == null ? null : sv.visitSuperclass(); - return new CheckSignatureAdapter(TYPE_SIGNATURE, v); - } - - public SignatureVisitor visitInterface() { - if (state != SUPER) { - throw new IllegalStateException(); - } - SignatureVisitor v = sv == null ? null : sv.visitInterface(); - return new CheckSignatureAdapter(TYPE_SIGNATURE, v); - } - - // method signatures - - public SignatureVisitor visitParameterType() { - if (type != METHOD_SIGNATURE || (state & (EMPTY | FORMAL | BOUND | PARAM)) == 0) { - throw new IllegalArgumentException(); - } - state = PARAM; - SignatureVisitor v = sv == null ? null : sv.visitParameterType(); - return new CheckSignatureAdapter(TYPE_SIGNATURE, v); - } - - public SignatureVisitor visitReturnType() { - if (type != METHOD_SIGNATURE || (state & (EMPTY | FORMAL | BOUND | PARAM)) == 0) { - throw new IllegalArgumentException(); - } - state = RETURN; - SignatureVisitor v = sv == null ? null : sv.visitReturnType(); - CheckSignatureAdapter cv = new CheckSignatureAdapter(TYPE_SIGNATURE, v); - cv.canBeVoid = true; - return cv; - } - - public SignatureVisitor visitExceptionType() { - if (state != RETURN) { - throw new IllegalStateException(); - } - SignatureVisitor v = sv == null ? null : sv.visitExceptionType(); - return new CheckSignatureAdapter(TYPE_SIGNATURE, v); - } - - // type signatures - - public void visitBaseType(final char descriptor) { - if (type != TYPE_SIGNATURE || state != EMPTY) { - throw new IllegalStateException(); - } - if (descriptor == 'V') { - if (!canBeVoid) { - throw new IllegalArgumentException(); - } - } else { - if ("ZCBSIFJD".indexOf(descriptor) == -1) { - throw new IllegalArgumentException(); - } - } - state = SIMPLE_TYPE; - if (sv != null) { - sv.visitBaseType(descriptor); - } - } - - public void visitTypeVariable(final String name) { - if (type != TYPE_SIGNATURE || state != EMPTY) { - throw new IllegalStateException(); - } - CheckMethodAdapter.checkIdentifier(name, "type variable"); - state = SIMPLE_TYPE; - if (sv != null) { - sv.visitTypeVariable(name); - } - } - - public SignatureVisitor visitArrayType() { - if (type != TYPE_SIGNATURE || state != EMPTY) { - throw new IllegalStateException(); - } - state = SIMPLE_TYPE; - SignatureVisitor v = sv == null ? null : sv.visitArrayType(); - return new CheckSignatureAdapter(TYPE_SIGNATURE, v); - } - - public void visitClassType(final String name) { - if (type != TYPE_SIGNATURE || state != EMPTY) { - throw new IllegalStateException(); - } - CheckMethodAdapter.checkInternalName(name, "class name"); - state = CLASS_TYPE; - if (sv != null) { - sv.visitClassType(name); - } - } - - public void visitInnerClassType(final String name) { - if (state != CLASS_TYPE) { - throw new IllegalStateException(); - } - CheckMethodAdapter.checkIdentifier(name, "inner class name"); - if (sv != null) { - sv.visitInnerClassType(name); - } - } - - public void visitTypeArgument() { - if (state != CLASS_TYPE) { - throw new IllegalStateException(); - } - if (sv != null) { - sv.visitTypeArgument(); - } - } - - public SignatureVisitor visitTypeArgument(final char wildcard) { - if (state != CLASS_TYPE) { - throw new IllegalStateException(); - } - if ("+-=".indexOf(wildcard) == -1) { - throw new IllegalArgumentException(); - } - SignatureVisitor v = sv == null ? null : sv.visitTypeArgument(wildcard); - return new CheckSignatureAdapter(TYPE_SIGNATURE, v); - } - - public void visitEnd() { - if (state != CLASS_TYPE) { - throw new IllegalStateException(); - } - state = END; - if (sv != null) { - sv.visitEnd(); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceAbstractVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceAbstractVisitor.java deleted file mode 100644 index 79173b9eb..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceAbstractVisitor.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; - -/** - * An abstract trace visitor. - * - * @author Eric Bruneton - */ -public abstract class TraceAbstractVisitor extends AbstractVisitor { - - /** - * Constant used in {@link #appendDescriptor appendDescriptor} for internal - * type names in bytecode notation. - */ - public static final int INTERNAL_NAME = 0; - - /** - * Constant used in {@link #appendDescriptor appendDescriptor} for field - * descriptors, formatted in bytecode notation - */ - public static final int FIELD_DESCRIPTOR = 1; - - /** - * Constant used in {@link #appendDescriptor appendDescriptor} for field - * signatures, formatted in bytecode notation - */ - public static final int FIELD_SIGNATURE = 2; - - /** - * Constant used in {@link #appendDescriptor appendDescriptor} for method - * descriptors, formatted in bytecode notation - */ - public static final int METHOD_DESCRIPTOR = 3; - - /** - * Constant used in {@link #appendDescriptor appendDescriptor} for method - * signatures, formatted in bytecode notation - */ - public static final int METHOD_SIGNATURE = 4; - - /** - * Constant used in {@link #appendDescriptor appendDescriptor} for class - * signatures, formatted in bytecode notation - */ - public static final int CLASS_SIGNATURE = 5; - - /** - * Constant used in {@link #appendDescriptor appendDescriptor} for field or - * method return value signatures, formatted in default Java notation - * (non-bytecode) - */ - public static final int TYPE_DECLARATION = 6; - - /** - * Constant used in {@link #appendDescriptor appendDescriptor} for class - * signatures, formatted in default Java notation (non-bytecode) - */ - public static final int CLASS_DECLARATION = 7; - - /** - * Constant used in {@link #appendDescriptor appendDescriptor} for method - * parameter signatures, formatted in default Java notation (non-bytecode) - */ - public static final int PARAMETERS_DECLARATION = 8; - - /** - * Tab for class members. - */ - protected String tab = " "; - - /** - * Prints a disassembled view of the given annotation. - * - * @param desc the class descriptor of the annotation class. - * @param visible true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values. - */ - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - buf.setLength(0); - buf.append(tab).append('@'); - appendDescriptor(FIELD_DESCRIPTOR, desc); - buf.append('('); - text.add(buf.toString()); - TraceAnnotationVisitor tav = createTraceAnnotationVisitor(); - text.add(tav.getText()); - text.add(visible ? ")\n" : ") // invisible\n"); - return tav; - } - - /** - * Prints a disassembled view of the given attribute. - * - * @param attr an attribute. - */ - public void visitAttribute(final Attribute attr) { - buf.setLength(0); - buf.append(tab).append("ATTRIBUTE "); - appendDescriptor(-1, attr.type); - - if (attr instanceof Traceable) { - ((Traceable) attr).trace(buf, null); - } else { - buf.append(" : unknown\n"); - } - - text.add(buf.toString()); - } - - /** - * Does nothing. - */ - public void visitEnd() { - // does nothing - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - protected TraceAnnotationVisitor createTraceAnnotationVisitor() { - return new TraceAnnotationVisitor(); - } - - /** - * Appends an internal name, a type descriptor or a type signature to - * {@link #buf buf}. - * - * @param type indicates if desc is an internal name, a field descriptor, a - * method descriptor, a class signature, ... - * @param desc an internal name, type descriptor, or type signature. May be - * null. - */ - protected void appendDescriptor(final int type, final String desc) { - if (type == CLASS_SIGNATURE || type == FIELD_SIGNATURE || type == METHOD_SIGNATURE) { - if (desc != null) { - buf.append("// signature ").append(desc).append('\n'); - } - } else { - buf.append(desc); - } - } - -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceAnnotationVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceAnnotationVisitor.java deleted file mode 100644 index 63f1acb57..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceAnnotationVisitor.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Type; - -/** - * An {@link AnnotationVisitor} that prints a disassembled view of the - * annotations it visits. - * - * @author Eric Bruneton - */ -public class TraceAnnotationVisitor extends TraceAbstractVisitor implements AnnotationVisitor { - - /** - * The {@link AnnotationVisitor} to which this visitor delegates calls. May - * be null. - */ - protected AnnotationVisitor av; - - private int valueNumber = 0; - - /** - * Constructs a new {@link TraceAnnotationVisitor}. - */ - public TraceAnnotationVisitor() { - // ignore - } - - // ------------------------------------------------------------------------ - // Implementation of the AnnotationVisitor interface - // ------------------------------------------------------------------------ - - public void visit(final String name, final Object value) { - buf.setLength(0); - appendComa(valueNumber++); - - if (name != null) { - buf.append(name).append('='); - } - - if (value instanceof String) { - visitString((String) value); - } else if (value instanceof Type) { - visitType((Type) value); - } else if (value instanceof Byte) { - visitByte(((Byte) value).byteValue()); - } else if (value instanceof Boolean) { - visitBoolean(((Boolean) value).booleanValue()); - } else if (value instanceof Short) { - visitShort(((Short) value).shortValue()); - } else if (value instanceof Character) { - visitChar(((Character) value).charValue()); - } else if (value instanceof Integer) { - visitInt(((Integer) value).intValue()); - } else if (value instanceof Float) { - visitFloat(((Float) value).floatValue()); - } else if (value instanceof Long) { - visitLong(((Long) value).longValue()); - } else if (value instanceof Double) { - visitDouble(((Double) value).doubleValue()); - } else if (value.getClass().isArray()) { - buf.append('{'); - if (value instanceof byte[]) { - byte[] v = (byte[]) value; - for (int i = 0; i < v.length; i++) { - appendComa(i); - visitByte(v[i]); - } - } else if (value instanceof boolean[]) { - boolean[] v = (boolean[]) value; - for (int i = 0; i < v.length; i++) { - appendComa(i); - visitBoolean(v[i]); - } - } else if (value instanceof short[]) { - short[] v = (short[]) value; - for (int i = 0; i < v.length; i++) { - appendComa(i); - visitShort(v[i]); - } - } else if (value instanceof char[]) { - char[] v = (char[]) value; - for (int i = 0; i < v.length; i++) { - appendComa(i); - visitChar(v[i]); - } - } else if (value instanceof int[]) { - int[] v = (int[]) value; - for (int i = 0; i < v.length; i++) { - appendComa(i); - visitInt(v[i]); - } - } else if (value instanceof long[]) { - long[] v = (long[]) value; - for (int i = 0; i < v.length; i++) { - appendComa(i); - visitLong(v[i]); - } - } else if (value instanceof float[]) { - float[] v = (float[]) value; - for (int i = 0; i < v.length; i++) { - appendComa(i); - visitFloat(v[i]); - } - } else if (value instanceof double[]) { - double[] v = (double[]) value; - for (int i = 0; i < v.length; i++) { - appendComa(i); - visitDouble(v[i]); - } - } - buf.append('}'); - } - - text.add(buf.toString()); - - if (av != null) { - av.visit(name, value); - } - } - - private void visitInt(final int value) { - buf.append(value); - } - - private void visitLong(final long value) { - buf.append(value).append('L'); - } - - private void visitFloat(final float value) { - buf.append(value).append('F'); - } - - private void visitDouble(final double value) { - buf.append(value).append('D'); - } - - private void visitChar(final char value) { - buf.append("(char)").append((int) value); - } - - private void visitShort(final short value) { - buf.append("(short)").append(value); - } - - private void visitByte(final byte value) { - buf.append("(byte)").append(value); - } - - private void visitBoolean(final boolean value) { - buf.append(value); - } - - private void visitString(final String value) { - appendString(buf, value); - } - - private void visitType(final Type value) { - buf.append(value.getClassName()).append(".class"); - } - - public void visitEnum(final String name, final String desc, final String value) { - buf.setLength(0); - appendComa(valueNumber++); - if (name != null) { - buf.append(name).append('='); - } - appendDescriptor(FIELD_DESCRIPTOR, desc); - buf.append('.').append(value); - text.add(buf.toString()); - - if (av != null) { - av.visitEnum(name, desc, value); - } - } - - public AnnotationVisitor visitAnnotation(final String name, final String desc) { - buf.setLength(0); - appendComa(valueNumber++); - if (name != null) { - buf.append(name).append('='); - } - buf.append('@'); - appendDescriptor(FIELD_DESCRIPTOR, desc); - buf.append('('); - text.add(buf.toString()); - TraceAnnotationVisitor tav = createTraceAnnotationVisitor(); - text.add(tav.getText()); - text.add(")"); - if (av != null) { - tav.av = av.visitAnnotation(name, desc); - } - return tav; - } - - public AnnotationVisitor visitArray(final String name) { - buf.setLength(0); - appendComa(valueNumber++); - if (name != null) { - buf.append(name).append('='); - } - buf.append('{'); - text.add(buf.toString()); - TraceAnnotationVisitor tav = createTraceAnnotationVisitor(); - text.add(tav.getText()); - text.add("}"); - if (av != null) { - tav.av = av.visitArray(name); - } - return tav; - } - - @Override - public void visitEnd() { - if (av != null) { - av.visitEnd(); - } - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - private void appendComa(final int i) { - if (i != 0) { - buf.append(", "); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceClassVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceClassVisitor.java deleted file mode 100644 index dbe6fd04f..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceClassVisitor.java +++ /dev/null @@ -1,488 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import java.io.FileInputStream; -import java.io.PrintWriter; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.signature.SignatureReader; - -/** - * A {@link ClassVisitor} that prints a disassembled view of the classes it - * visits. This class visitor can be used alone (see the {@link #main main} - * method) to disassemble a class. It can also be used in the middle of class - * visitor chain to trace the class that is visited at a given point in this - * chain. This may be uselful for debugging purposes. - *

- * The trace printed when visiting the Hello class is the following: - *

- *

- * - *
- * // class version 49.0 (49)
- * // access flags 33
- * public class Hello {
- *  // compiled from: Hello.java
- *   // access flags 1
- *   public <init> ()V
- *     ALOAD 0
- *     INVOKESPECIAL java/lang/Object <init> ()V
- *     RETURN
- *     MAXSTACK = 1
- *     MAXLOCALS = 1
- *   // access flags 9
- *   public static main ([Ljava/lang/String;)V
- *     GETSTATIC java/lang/System out Ljava/io/PrintStream;
- *     LDC "hello"
- *     INVOKEVIRTUAL java/io/PrintStream println (Ljava/lang/String;)V
- *     RETURN
- *     MAXSTACK = 2
- *     MAXLOCALS = 1
- * }
- * 
- * - *
where Hello is defined by: - *

- *

- * - *
- * public class Hello {
- *     public static void main(String[] args) {
- *         System.out.println("hello");
- *     }
- * }
- * 
- * - *
- * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public class TraceClassVisitor extends TraceAbstractVisitor implements ClassVisitor { - - /** - * The {@link ClassVisitor} to which this visitor delegates calls. May be - * null. - */ - protected final ClassVisitor cv; - - /** - * The print writer to be used to print the class. - */ - protected final PrintWriter pw; - - /** - * Prints a disassembled view of the given class to the standard output. - *

- * Usage: TraceClassVisitor [-debug] <fully qualified class name or class - * file name > - * - * @param args the command line arguments. - * @throws Exception if the class cannot be found, or if an IO exception - * occurs. - */ - public static void main(final String[] args) throws Exception { - int i = 0; - int flags = ClassReader.SKIP_DEBUG; - - boolean ok = true; - if (args.length < 1 || args.length > 2) { - ok = false; - } - if (ok && "-debug".equals(args[0])) { - i = 1; - flags = 0; - if (args.length != 2) { - ok = false; - } - } - if (!ok) { - System.err.println("Prints a disassembled view of the given class."); - System.err - .println("Usage: TraceClassVisitor [-debug] " + ""); - return; - } - ClassReader cr; - if (args[i].endsWith(".class") || args[i].indexOf('\\') > -1 || args[i].indexOf('/') > -1) { - cr = new ClassReader(new FileInputStream(args[i])); - } else { - cr = new ClassReader(args[i]); - } - cr.accept(new TraceClassVisitor(new PrintWriter(System.out)), getDefaultAttributes(), flags); - } - - /** - * Constructs a new {@link TraceClassVisitor}. - * - * @param pw the print writer to be used to print the class. - */ - public TraceClassVisitor(final PrintWriter pw) { - this(null, pw); - } - - /** - * Constructs a new {@link TraceClassVisitor}. - * - * @param cv the {@link ClassVisitor} to which this visitor delegates calls. - * May be null. - * @param pw the print writer to be used to print the class. - */ - public TraceClassVisitor(final ClassVisitor cv, final PrintWriter pw) { - this.cv = cv; - this.pw = pw; - } - - // ------------------------------------------------------------------------ - // Implementation of the ClassVisitor interface - // ------------------------------------------------------------------------ - - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - int major = version & 0xFFFF; - int minor = version >>> 16; - buf.setLength(0); - buf.append("// class version ").append(major).append('.').append(minor).append(" (").append(version).append( - ")\n"); - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - buf.append("// DEPRECATED\n"); - } - buf.append("// access flags ").append(access).append('\n'); - - appendDescriptor(CLASS_SIGNATURE, signature); - if (signature != null) { - TraceSignatureVisitor sv = new TraceSignatureVisitor(access); - SignatureReader r = new SignatureReader(signature); - r.accept(sv); - buf.append("// declaration: ").append(name).append(sv.getDeclaration()).append('\n'); - } - - appendAccess(access & ~Opcodes.ACC_SUPER); - if ((access & Opcodes.ACC_ANNOTATION) != 0) { - buf.append("@interface "); - } else if ((access & Opcodes.ACC_INTERFACE) != 0) { - buf.append("interface "); - } else if ((access & Opcodes.ACC_ENUM) == 0) { - buf.append("class "); - } - appendDescriptor(INTERNAL_NAME, name); - - if (superName != null && !"java/lang/Object".equals(superName)) { - buf.append(" extends "); - appendDescriptor(INTERNAL_NAME, superName); - buf.append(' '); - } - if (interfaces != null && interfaces.length > 0) { - buf.append(" implements "); - for (int i = 0; i < interfaces.length; ++i) { - appendDescriptor(INTERNAL_NAME, interfaces[i]); - buf.append(' '); - } - } - buf.append(" {\n\n"); - - text.add(buf.toString()); - - if (cv != null) { - cv.visit(version, access, name, signature, superName, interfaces); - } - } - - public void visitSource(final String file, final String debug) { - buf.setLength(0); - if (file != null) { - buf.append(tab).append("// compiled from: ").append(file).append('\n'); - } - if (debug != null) { - buf.append(tab).append("// debug info: ").append(debug).append('\n'); - } - if (buf.length() > 0) { - text.add(buf.toString()); - } - - if (cv != null) { - cv.visitSource(file, debug); - } - } - - public void visitOuterClass(final String owner, final String name, final String desc) { - buf.setLength(0); - buf.append(tab).append("OUTERCLASS "); - appendDescriptor(INTERNAL_NAME, owner); - buf.append(' '); - if (name != null) { - buf.append(name).append(' '); - } - appendDescriptor(METHOD_DESCRIPTOR, desc); - buf.append('\n'); - text.add(buf.toString()); - - if (cv != null) { - cv.visitOuterClass(owner, name, desc); - } - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - text.add("\n"); - AnnotationVisitor tav = super.visitAnnotation(desc, visible); - if (cv != null) { - ((TraceAnnotationVisitor) tav).av = cv.visitAnnotation(desc, visible); - } - return tav; - } - - @Override - public void visitAttribute(final Attribute attr) { - text.add("\n"); - super.visitAttribute(attr); - - if (cv != null) { - cv.visitAttribute(attr); - } - } - - public void visitInnerClass(final String name, final String outerName, final String innerName, final int access) { - buf.setLength(0); - buf.append(tab).append("// access flags "); - buf.append(access & ~Opcodes.ACC_SUPER).append('\n'); - buf.append(tab); - appendAccess(access); - buf.append("INNERCLASS "); - appendDescriptor(INTERNAL_NAME, name); - buf.append(' '); - appendDescriptor(INTERNAL_NAME, outerName); - buf.append(' '); - appendDescriptor(INTERNAL_NAME, innerName); - buf.append('\n'); - text.add(buf.toString()); - - if (cv != null) { - cv.visitInnerClass(name, outerName, innerName, access); - } - } - - public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, - final Object value) { - buf.setLength(0); - buf.append('\n'); - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - buf.append(tab).append("// DEPRECATED\n"); - } - buf.append(tab).append("// access flags ").append(access).append('\n'); - if (signature != null) { - buf.append(tab); - appendDescriptor(FIELD_SIGNATURE, signature); - - TraceSignatureVisitor sv = new TraceSignatureVisitor(0); - SignatureReader r = new SignatureReader(signature); - r.acceptType(sv); - buf.append(tab).append("// declaration: ").append(sv.getDeclaration()).append('\n'); - } - - buf.append(tab); - appendAccess(access); - - appendDescriptor(FIELD_DESCRIPTOR, desc); - buf.append(' ').append(name); - if (value != null) { - buf.append(" = "); - if (value instanceof String) { - buf.append('\"').append(value).append('\"'); - } else { - buf.append(value); - } - } - - buf.append('\n'); - text.add(buf.toString()); - - TraceFieldVisitor tav = createTraceFieldVisitor(); - text.add(tav.getText()); - - if (cv != null) { - tav.fv = cv.visitField(access, name, desc, signature, value); - } - - return tav; - } - - public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, - final String[] exceptions) { - buf.setLength(0); - buf.append('\n'); - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - buf.append(tab).append("// DEPRECATED\n"); - } - buf.append(tab).append("// access flags ").append(access).append('\n'); - - if (signature != null) { - buf.append(tab); - appendDescriptor(METHOD_SIGNATURE, signature); - - TraceSignatureVisitor v = new TraceSignatureVisitor(0); - SignatureReader r = new SignatureReader(signature); - r.accept(v); - String genericDecl = v.getDeclaration(); - String genericReturn = v.getReturnType(); - String genericExceptions = v.getExceptions(); - - buf.append(tab).append("// declaration: ").append(genericReturn).append(' ').append(name).append( - genericDecl); - if (genericExceptions != null) { - buf.append(" throws ").append(genericExceptions); - } - buf.append('\n'); - } - - buf.append(tab); - appendAccess(access); - if ((access & Opcodes.ACC_NATIVE) != 0) { - buf.append("native "); - } - if ((access & Opcodes.ACC_VARARGS) != 0) { - buf.append("varargs "); - } - if ((access & Opcodes.ACC_BRIDGE) != 0) { - buf.append("bridge "); - } - - buf.append(name); - appendDescriptor(METHOD_DESCRIPTOR, desc); - if (exceptions != null && exceptions.length > 0) { - buf.append(" throws "); - for (int i = 0; i < exceptions.length; ++i) { - appendDescriptor(INTERNAL_NAME, exceptions[i]); - buf.append(' '); - } - } - - buf.append('\n'); - text.add(buf.toString()); - - TraceMethodVisitor tcv = createTraceMethodVisitor(); - text.add(tcv.getText()); - - if (cv != null) { - tcv.mv = cv.visitMethod(access, name, desc, signature, exceptions); - } - - return tcv; - } - - @Override - public void visitEnd() { - text.add("}\n"); - - print(pw); - pw.flush(); - - if (cv != null) { - cv.visitEnd(); - } - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - protected TraceFieldVisitor createTraceFieldVisitor() { - return new TraceFieldVisitor(); - } - - protected TraceMethodVisitor createTraceMethodVisitor() { - return new TraceMethodVisitor(); - } - - /** - * Appends a string representation of the given access modifiers to - * {@link #buf buf}. - * - * @param access some access modifiers. - */ - private void appendAccess(final int access) { - if ((access & Opcodes.ACC_PUBLIC) != 0) { - buf.append("public "); - } - if ((access & Opcodes.ACC_PRIVATE) != 0) { - buf.append("private "); - } - if ((access & Opcodes.ACC_PROTECTED) != 0) { - buf.append("protected "); - } - if ((access & Opcodes.ACC_FINAL) != 0) { - buf.append("final "); - } - if ((access & Opcodes.ACC_STATIC) != 0) { - buf.append("static "); - } - if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) { - buf.append("synchronized "); - } - if ((access & Opcodes.ACC_VOLATILE) != 0) { - buf.append("volatile "); - } - if ((access & Opcodes.ACC_TRANSIENT) != 0) { - buf.append("transient "); - } - if ((access & Opcodes.ACC_ABSTRACT) != 0) { - buf.append("abstract "); - } - if ((access & Opcodes.ACC_STRICT) != 0) { - buf.append("strictfp "); - } - if ((access & Opcodes.ACC_ENUM) != 0) { - buf.append("enum "); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceFieldVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceFieldVisitor.java deleted file mode 100644 index 45e939401..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceFieldVisitor.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.FieldVisitor; - -/** - * A {@link FieldVisitor} that prints a disassembled view of the fields it - * visits. - * - * @author Eric Bruneton - */ -public class TraceFieldVisitor extends TraceAbstractVisitor implements FieldVisitor { - - /** - * The {@link FieldVisitor} to which this visitor delegates calls. May be - * null. - */ - protected FieldVisitor fv; - - @Override - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - AnnotationVisitor av = super.visitAnnotation(desc, visible); - if (fv != null) { - ((TraceAnnotationVisitor) av).av = fv.visitAnnotation(desc, visible); - } - return av; - } - - @Override - public void visitAttribute(final Attribute attr) { - super.visitAttribute(attr); - - if (fv != null) { - fv.visitAttribute(attr); - } - } - - @Override - public void visitEnd() { - super.visitEnd(); - - if (fv != null) { - fv.visitEnd(); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceMethodVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceMethodVisitor.java deleted file mode 100644 index ca783937c..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceMethodVisitor.java +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import java.util.HashMap; -import java.util.Map; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; -import com.alibaba.citrus.asm.signature.SignatureReader; - -/** - * A {@link MethodVisitor} that prints a disassembled view of the methods it - * visits. - * - * @author Eric Bruneton - */ -public class TraceMethodVisitor extends TraceAbstractVisitor implements MethodVisitor { - - /** - * The {@link MethodVisitor} to which this visitor delegates calls. May be - * null. - */ - protected MethodVisitor mv; - - /** - * Tab for bytecode instructions. - */ - protected String tab2 = " "; - - /** - * Tab for table and lookup switch instructions. - */ - protected String tab3 = " "; - - /** - * Tab for labels. - */ - protected String ltab = " "; - - /** - * The label names. This map associate String values to Label keys. - */ - protected final Map labelNames; - - /** - * Constructs a new {@link TraceMethodVisitor}. - */ - public TraceMethodVisitor() { - this(null); - } - - /** - * Constructs a new {@link TraceMethodVisitor}. - * - * @param mv the {@link MethodVisitor} to which this visitor delegates - * calls. May be null. - */ - public TraceMethodVisitor(final MethodVisitor mv) { - this.labelNames = new HashMap(); - this.mv = mv; - } - - // ------------------------------------------------------------------------ - // Implementation of the MethodVisitor interface - // ------------------------------------------------------------------------ - - @Override - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - AnnotationVisitor av = super.visitAnnotation(desc, visible); - if (mv != null) { - ((TraceAnnotationVisitor) av).av = mv.visitAnnotation(desc, visible); - } - return av; - } - - @Override - public void visitAttribute(final Attribute attr) { - buf.setLength(0); - buf.append(tab).append("ATTRIBUTE "); - appendDescriptor(-1, attr.type); - - if (attr instanceof Traceable) { - ((Traceable) attr).trace(buf, labelNames); - } else { - buf.append(" : unknown\n"); - } - - text.add(buf.toString()); - if (mv != null) { - mv.visitAttribute(attr); - } - } - - public AnnotationVisitor visitAnnotationDefault() { - text.add(tab2 + "default="); - TraceAnnotationVisitor tav = createTraceAnnotationVisitor(); - text.add(tav.getText()); - text.add("\n"); - if (mv != null) { - tav.av = mv.visitAnnotationDefault(); - } - return tav; - } - - public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc, final boolean visible) { - buf.setLength(0); - buf.append(tab2).append('@'); - appendDescriptor(FIELD_DESCRIPTOR, desc); - buf.append('('); - text.add(buf.toString()); - TraceAnnotationVisitor tav = createTraceAnnotationVisitor(); - text.add(tav.getText()); - text.add(visible ? ") // parameter " : ") // invisible, parameter "); - text.add(new Integer(parameter)); - text.add("\n"); - if (mv != null) { - tav.av = mv.visitParameterAnnotation(parameter, desc, visible); - } - return tav; - } - - public void visitCode() { - if (mv != null) { - mv.visitCode(); - } - } - - public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, - final Object[] stack) { - buf.setLength(0); - buf.append(ltab); - buf.append("FRAME "); - switch (type) { - case Opcodes.F_NEW: - case Opcodes.F_FULL: - buf.append("FULL ["); - appendFrameTypes(nLocal, local); - buf.append("] ["); - appendFrameTypes(nStack, stack); - buf.append(']'); - break; - case Opcodes.F_APPEND: - buf.append("APPEND ["); - appendFrameTypes(nLocal, local); - buf.append(']'); - break; - case Opcodes.F_CHOP: - buf.append("CHOP ").append(nLocal); - break; - case Opcodes.F_SAME: - buf.append("SAME"); - break; - case Opcodes.F_SAME1: - buf.append("SAME1 "); - appendFrameTypes(1, stack); - break; - } - buf.append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitFrame(type, nLocal, local, nStack, stack); - } - } - - public void visitInsn(final int opcode) { - buf.setLength(0); - buf.append(tab2).append(OPCODES[opcode]).append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitInsn(opcode); - } - } - - public void visitIntInsn(final int opcode, final int operand) { - buf.setLength(0); - buf.append(tab2).append(OPCODES[opcode]).append(' ').append( - opcode == Opcodes.NEWARRAY ? TYPES[operand] : Integer.toString(operand)).append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitIntInsn(opcode, operand); - } - } - - public void visitVarInsn(final int opcode, final int var) { - buf.setLength(0); - buf.append(tab2).append(OPCODES[opcode]).append(' ').append(var).append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitVarInsn(opcode, var); - } - } - - public void visitTypeInsn(final int opcode, final String type) { - buf.setLength(0); - buf.append(tab2).append(OPCODES[opcode]).append(' '); - appendDescriptor(INTERNAL_NAME, type); - buf.append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitTypeInsn(opcode, type); - } - } - - public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { - buf.setLength(0); - buf.append(tab2).append(OPCODES[opcode]).append(' '); - appendDescriptor(INTERNAL_NAME, owner); - buf.append('.').append(name).append(" : "); - appendDescriptor(FIELD_DESCRIPTOR, desc); - buf.append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitFieldInsn(opcode, owner, name, desc); - } - } - - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - buf.setLength(0); - buf.append(tab2).append(OPCODES[opcode]).append(' '); - appendDescriptor(INTERNAL_NAME, owner); - buf.append('.').append(name).append(' '); - appendDescriptor(METHOD_DESCRIPTOR, desc); - buf.append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitMethodInsn(opcode, owner, name, desc); - } - } - - public void visitJumpInsn(final int opcode, final Label label) { - buf.setLength(0); - buf.append(tab2).append(OPCODES[opcode]).append(' '); - appendLabel(label); - buf.append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitJumpInsn(opcode, label); - } - } - - public void visitLabel(final Label label) { - buf.setLength(0); - buf.append(ltab); - appendLabel(label); - buf.append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitLabel(label); - } - } - - public void visitLdcInsn(final Object cst) { - buf.setLength(0); - buf.append(tab2).append("LDC "); - if (cst instanceof String) { - AbstractVisitor.appendString(buf, (String) cst); - } else if (cst instanceof Type) { - buf.append(((Type) cst).getDescriptor()).append(".class"); - } else { - buf.append(cst); - } - buf.append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitLdcInsn(cst); - } - } - - public void visitIincInsn(final int var, final int increment) { - buf.setLength(0); - buf.append(tab2).append("IINC ").append(var).append(' ').append(increment).append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitIincInsn(var, increment); - } - } - - public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label[] labels) { - buf.setLength(0); - buf.append(tab2).append("TABLESWITCH\n"); - for (int i = 0; i < labels.length; ++i) { - buf.append(tab3).append(min + i).append(": "); - appendLabel(labels[i]); - buf.append('\n'); - } - buf.append(tab3).append("default: "); - appendLabel(dflt); - buf.append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitTableSwitchInsn(min, max, dflt, labels); - } - } - - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { - buf.setLength(0); - buf.append(tab2).append("LOOKUPSWITCH\n"); - for (int i = 0; i < labels.length; ++i) { - buf.append(tab3).append(keys[i]).append(": "); - appendLabel(labels[i]); - buf.append('\n'); - } - buf.append(tab3).append("default: "); - appendLabel(dflt); - buf.append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitLookupSwitchInsn(dflt, keys, labels); - } - } - - public void visitMultiANewArrayInsn(final String desc, final int dims) { - buf.setLength(0); - buf.append(tab2).append("MULTIANEWARRAY "); - appendDescriptor(FIELD_DESCRIPTOR, desc); - buf.append(' ').append(dims).append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitMultiANewArrayInsn(desc, dims); - } - } - - public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type) { - buf.setLength(0); - buf.append(tab2).append("TRYCATCHBLOCK "); - appendLabel(start); - buf.append(' '); - appendLabel(end); - buf.append(' '); - appendLabel(handler); - buf.append(' '); - appendDescriptor(INTERNAL_NAME, type); - buf.append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitTryCatchBlock(start, end, handler, type); - } - } - - public void visitLocalVariable(final String name, final String desc, final String signature, final Label start, - final Label end, final int index) { - buf.setLength(0); - buf.append(tab2).append("LOCALVARIABLE ").append(name).append(' '); - appendDescriptor(FIELD_DESCRIPTOR, desc); - buf.append(' '); - appendLabel(start); - buf.append(' '); - appendLabel(end); - buf.append(' ').append(index).append('\n'); - - if (signature != null) { - buf.append(tab2); - appendDescriptor(FIELD_SIGNATURE, signature); - - TraceSignatureVisitor sv = new TraceSignatureVisitor(0); - SignatureReader r = new SignatureReader(signature); - r.acceptType(sv); - buf.append(tab2).append("// declaration: ").append(sv.getDeclaration()).append('\n'); - } - text.add(buf.toString()); - - if (mv != null) { - mv.visitLocalVariable(name, desc, signature, start, end, index); - } - } - - public void visitLineNumber(final int line, final Label start) { - buf.setLength(0); - buf.append(tab2).append("LINENUMBER ").append(line).append(' '); - appendLabel(start); - buf.append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitLineNumber(line, start); - } - } - - public void visitMaxs(final int maxStack, final int maxLocals) { - buf.setLength(0); - buf.append(tab2).append("MAXSTACK = ").append(maxStack).append('\n'); - text.add(buf.toString()); - - buf.setLength(0); - buf.append(tab2).append("MAXLOCALS = ").append(maxLocals).append('\n'); - text.add(buf.toString()); - - if (mv != null) { - mv.visitMaxs(maxStack, maxLocals); - } - } - - @Override - public void visitEnd() { - super.visitEnd(); - - if (mv != null) { - mv.visitEnd(); - } - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - private void appendFrameTypes(final int n, final Object[] o) { - for (int i = 0; i < n; ++i) { - if (i > 0) { - buf.append(' '); - } - if (o[i] instanceof String) { - String desc = (String) o[i]; - if (desc.startsWith("[")) { - appendDescriptor(FIELD_DESCRIPTOR, desc); - } else { - appendDescriptor(INTERNAL_NAME, desc); - } - } else if (o[i] instanceof Integer) { - switch (((Integer) o[i]).intValue()) { - case 0: - appendDescriptor(FIELD_DESCRIPTOR, "T"); - break; - case 1: - appendDescriptor(FIELD_DESCRIPTOR, "I"); - break; - case 2: - appendDescriptor(FIELD_DESCRIPTOR, "F"); - break; - case 3: - appendDescriptor(FIELD_DESCRIPTOR, "D"); - break; - case 4: - appendDescriptor(FIELD_DESCRIPTOR, "J"); - break; - case 5: - appendDescriptor(FIELD_DESCRIPTOR, "N"); - break; - case 6: - appendDescriptor(FIELD_DESCRIPTOR, "U"); - break; - } - } else { - appendLabel((Label) o[i]); - } - } - } - - /** - * Appends the name of the given label to {@link #buf buf}. Creates a new - * label name if the given label does not yet have one. - * - * @param l a label. - */ - protected void appendLabel(final Label l) { - String name = (String) labelNames.get(l); - if (name == null) { - name = "L" + labelNames.size(); - labelNames.put(l, name); - } - buf.append(name); - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceSignatureVisitor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceSignatureVisitor.java deleted file mode 100644 index a35429537..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/TraceSignatureVisitor.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.signature.SignatureVisitor; - -/** - * A {@link SignatureVisitor} that prints a disassembled view of the signature - * it visits. - * - * @author Eugene Kuleshov - * @author Eric Bruneton - */ -public class TraceSignatureVisitor implements SignatureVisitor { - - private final StringBuilder declaration; - - private boolean isInterface; - - private boolean seenFormalParameter; - - private boolean seenInterfaceBound; - - private boolean seenParameter; - - private boolean seenInterface; - - private StringBuilder returnType; - - private StringBuilder exceptions; - - /** - * Stack used to keep track of class types that have arguments. Each element - * of this stack is a boolean encoded in one bit. The top of the stack is - * the lowest order bit. Pushing false = *2, pushing true = *2+1, popping = - * /2. - */ - private int argumentStack; - - /** - * Stack used to keep track of array class types. Each element of this stack - * is a boolean encoded in one bit. The top of the stack is the lowest order - * bit. Pushing false = *2, pushing true = *2+1, popping = /2. - */ - private int arrayStack; - - private String separator = ""; - - public TraceSignatureVisitor(final int access) { - isInterface = (access & Opcodes.ACC_INTERFACE) != 0; - this.declaration = new StringBuilder(); - } - - private TraceSignatureVisitor(final StringBuilder buf) { - this.declaration = buf; - } - - public void visitFormalTypeParameter(final String name) { - declaration.append(seenFormalParameter ? ", " : "<").append(name); - seenFormalParameter = true; - seenInterfaceBound = false; - } - - public SignatureVisitor visitClassBound() { - separator = " extends "; - startType(); - return this; - } - - public SignatureVisitor visitInterfaceBound() { - separator = seenInterfaceBound ? ", " : " extends "; - seenInterfaceBound = true; - startType(); - return this; - } - - public SignatureVisitor visitSuperclass() { - endFormals(); - separator = " extends "; - startType(); - return this; - } - - public SignatureVisitor visitInterface() { - separator = seenInterface ? ", " : isInterface ? " extends " : " implements "; - seenInterface = true; - startType(); - return this; - } - - public SignatureVisitor visitParameterType() { - endFormals(); - if (seenParameter) { - declaration.append(", "); - } else { - seenParameter = true; - declaration.append('('); - } - startType(); - return this; - } - - public SignatureVisitor visitReturnType() { - endFormals(); - if (seenParameter) { - seenParameter = false; - } else { - declaration.append('('); - } - declaration.append(')'); - returnType = new StringBuilder(); - return new TraceSignatureVisitor(returnType); - } - - public SignatureVisitor visitExceptionType() { - if (exceptions == null) { - exceptions = new StringBuilder(); - } else { - exceptions.append(", "); - } - // startType(); - return new TraceSignatureVisitor(exceptions); - } - - public void visitBaseType(final char descriptor) { - switch (descriptor) { - case 'V': - declaration.append("void"); - break; - case 'B': - declaration.append("byte"); - break; - case 'J': - declaration.append("long"); - break; - case 'Z': - declaration.append("boolean"); - break; - case 'I': - declaration.append("int"); - break; - case 'S': - declaration.append("short"); - break; - case 'C': - declaration.append("char"); - break; - case 'F': - declaration.append("float"); - break; - // case 'D': - default: - declaration.append("double"); - break; - } - endType(); - } - - public void visitTypeVariable(final String name) { - declaration.append(name); - endType(); - } - - public SignatureVisitor visitArrayType() { - startType(); - arrayStack |= 1; - return this; - } - - public void visitClassType(final String name) { - if ("java/lang/Object".equals(name)) { - // Map - // or - // abstract public V get(Object key); (seen in Dictionary.class) - // should have Object - // but java.lang.String extends java.lang.Object is unnecessary - boolean needObjectClass = argumentStack % 2 != 0 || seenParameter; - if (needObjectClass) { - declaration.append(separator).append(name.replace('/', '.')); - } - } else { - declaration.append(separator).append(name.replace('/', '.')); - } - separator = ""; - argumentStack *= 2; - } - - public void visitInnerClassType(final String name) { - if (argumentStack % 2 != 0) { - declaration.append('>'); - } - argumentStack /= 2; - declaration.append('.'); - declaration.append(separator).append(name.replace('/', '.')); - separator = ""; - argumentStack *= 2; - } - - public void visitTypeArgument() { - if (argumentStack % 2 == 0) { - ++argumentStack; - declaration.append('<'); - } else { - declaration.append(", "); - } - declaration.append('?'); - } - - public SignatureVisitor visitTypeArgument(final char tag) { - if (argumentStack % 2 == 0) { - ++argumentStack; - declaration.append('<'); - } else { - declaration.append(", "); - } - - if (tag == EXTENDS) { - declaration.append("? extends "); - } else if (tag == SUPER) { - declaration.append("? super "); - } - - startType(); - return this; - } - - public void visitEnd() { - if (argumentStack % 2 != 0) { - declaration.append('>'); - } - argumentStack /= 2; - endType(); - } - - public String getDeclaration() { - return declaration.toString(); - } - - public String getReturnType() { - return returnType == null ? null : returnType.toString(); - } - - public String getExceptions() { - return exceptions == null ? null : exceptions.toString(); - } - - // ----------------------------------------------- - - private void endFormals() { - if (seenFormalParameter) { - declaration.append('>'); - seenFormalParameter = false; - } - } - - private void startType() { - arrayStack *= 2; - } - - private void endType() { - if (arrayStack % 2 == 0) { - arrayStack /= 2; - } else { - while (arrayStack % 2 != 0) { - arrayStack /= 2; - declaration.append("[]"); - } - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/util/Traceable.java b/common/asm/src/main/java/com/alibaba/citrus/asm/util/Traceable.java deleted file mode 100644 index 170a088ee..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/util/Traceable.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import java.util.Map; - -/** - * An attribute that can print eadable representation of the attribute. - * Implementation should construct readable output from an attribute data - * structures for current attribute state. Such representation could be used in - * unit test assertions. - * - * @author Eugene Kuleshov - */ -public interface Traceable { - - /** - * Build a human readable representation of the attribute. - * - * @param buf A buffer used for printing Java code. - * @param labelNames map of label instances to their names. - */ - void trace(StringBuilder buf, Map labelNames); -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/xml/ASMContentHandler.java b/common/asm/src/main/java/com/alibaba/citrus/asm/xml/ASMContentHandler.java deleted file mode 100644 index 5cd728384..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/xml/ASMContentHandler.java +++ /dev/null @@ -1,1217 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM XML Adapter - * Copyright (c) 2004, Eugene Kuleshov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.xml; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; - -/** - * A {@link org.xml.sax.ContentHandler ContentHandler} that transforms XML - * document into Java class file. This class can be feeded by any kind of SAX - * 2.0 event producers, e.g. XML parser, XSLT or XPath engines, or custom code. - * - * @see com.alibaba.citrus.asm.xml.SAXClassAdapter - * @see com.alibaba.citrus.asm.xml.Processor - * @author Eugene Kuleshov - */ -public class ASMContentHandler extends DefaultHandler implements Opcodes { - - /** - * Stack of the intermediate processing contexts. - */ - private final List stack = new ArrayList(); - - /** - * Complete name of the current element. - */ - private String match = ""; - - /** - * true if the maximum stack size and number of local variables - * must be automatically computed. - */ - protected boolean computeMax; - - /** - * Output stream to write result bytecode. - */ - protected OutputStream os; - - /** - * Current instance of the {@link ClassWriter ClassWriter} used to write - * class bytecode. - */ - protected ClassWriter cw; - - /** - * Map of the active {@link Label Label} instances for current method. - */ - protected Map labels; - - private static final String BASE = "class"; - - private final RuleSet RULES = new RuleSet(); - { - RULES.add(BASE, new ClassRule()); - RULES.add(BASE + "/interfaces/interface", new InterfaceRule()); - RULES.add(BASE + "/interfaces", new InterfacesRule()); - RULES.add(BASE + "/outerclass", new OuterClassRule()); - RULES.add(BASE + "/innerclass", new InnerClassRule()); - RULES.add(BASE + "/source", new SourceRule()); - RULES.add(BASE + "/field", new FieldRule()); - - RULES.add(BASE + "/method", new MethodRule()); - RULES.add(BASE + "/method/exceptions/exception", new ExceptionRule()); - RULES.add(BASE + "/method/exceptions", new ExceptionsRule()); - - RULES.add(BASE + "/method/annotationDefault", new AnnotationDefaultRule()); - - RULES.add(BASE + "/method/code/*", new OpcodesRule()); // opcodes - - RULES.add(BASE + "/method/code/frame", new FrameRule()); - RULES.add(BASE + "/method/code/frame/local", new FrameTypeRule()); - RULES.add(BASE + "/method/code/frame/stack", new FrameTypeRule()); - - RULES.add(BASE + "/method/code/TABLESWITCH", new TableSwitchRule()); - RULES.add(BASE + "/method/code/TABLESWITCH/label", new TableSwitchLabelRule()); - RULES.add(BASE + "/method/code/LOOKUPSWITCH", new LookupSwitchRule()); - RULES.add(BASE + "/method/code/LOOKUPSWITCH/label", new LookupSwitchLabelRule()); - - RULES.add(BASE + "/method/code/Label", new LabelRule()); - RULES.add(BASE + "/method/code/TryCatch", new TryCatchRule()); - RULES.add(BASE + "/method/code/LineNumber", new LineNumberRule()); - RULES.add(BASE + "/method/code/LocalVar", new LocalVarRule()); - RULES.add(BASE + "/method/code/Max", new MaxRule()); - - RULES.add("*/annotation", new AnnotationRule()); - RULES.add("*/parameterAnnotation", new AnnotationParameterRule()); - RULES.add("*/annotationValue", new AnnotationValueRule()); - RULES.add("*/annotationValueAnnotation", new AnnotationValueAnnotationRule()); - RULES.add("*/annotationValueEnum", new AnnotationValueEnumRule()); - RULES.add("*/annotationValueArray", new AnnotationValueArrayRule()); - } - - private static interface OpcodeGroup { - public static final int INSN = 0; - public static final int INSN_INT = 1; - public static final int INSN_VAR = 2; - public static final int INSN_TYPE = 3; - public static final int INSN_FIELD = 4; - public static final int INSN_METHOD = 5; - public static final int INSN_JUMP = 6; - public static final int INSN_LDC = 7; - public static final int INSN_IINC = 8; - public static final int INSN_MULTIANEWARRAY = 9; - } - - /** - * Map of the opcode names to opcode and opcode group - */ - static final Map OPCODES = new HashMap(); - static { - addOpcode("NOP", NOP, OpcodeGroup.INSN); - addOpcode("ACONST_NULL", ACONST_NULL, OpcodeGroup.INSN); - addOpcode("ICONST_M1", ICONST_M1, OpcodeGroup.INSN); - addOpcode("ICONST_0", ICONST_0, OpcodeGroup.INSN); - addOpcode("ICONST_1", ICONST_1, OpcodeGroup.INSN); - addOpcode("ICONST_2", ICONST_2, OpcodeGroup.INSN); - addOpcode("ICONST_3", ICONST_3, OpcodeGroup.INSN); - addOpcode("ICONST_4", ICONST_4, OpcodeGroup.INSN); - addOpcode("ICONST_5", ICONST_5, OpcodeGroup.INSN); - addOpcode("LCONST_0", LCONST_0, OpcodeGroup.INSN); - addOpcode("LCONST_1", LCONST_1, OpcodeGroup.INSN); - addOpcode("FCONST_0", FCONST_0, OpcodeGroup.INSN); - addOpcode("FCONST_1", FCONST_1, OpcodeGroup.INSN); - addOpcode("FCONST_2", FCONST_2, OpcodeGroup.INSN); - addOpcode("DCONST_0", DCONST_0, OpcodeGroup.INSN); - addOpcode("DCONST_1", DCONST_1, OpcodeGroup.INSN); - addOpcode("BIPUSH", BIPUSH, OpcodeGroup.INSN_INT); - addOpcode("SIPUSH", SIPUSH, OpcodeGroup.INSN_INT); - addOpcode("LDC", LDC, OpcodeGroup.INSN_LDC); - addOpcode("ILOAD", ILOAD, OpcodeGroup.INSN_VAR); - addOpcode("LLOAD", LLOAD, OpcodeGroup.INSN_VAR); - addOpcode("FLOAD", FLOAD, OpcodeGroup.INSN_VAR); - addOpcode("DLOAD", DLOAD, OpcodeGroup.INSN_VAR); - addOpcode("ALOAD", ALOAD, OpcodeGroup.INSN_VAR); - addOpcode("IALOAD", IALOAD, OpcodeGroup.INSN); - addOpcode("LALOAD", LALOAD, OpcodeGroup.INSN); - addOpcode("FALOAD", FALOAD, OpcodeGroup.INSN); - addOpcode("DALOAD", DALOAD, OpcodeGroup.INSN); - addOpcode("AALOAD", AALOAD, OpcodeGroup.INSN); - addOpcode("BALOAD", BALOAD, OpcodeGroup.INSN); - addOpcode("CALOAD", CALOAD, OpcodeGroup.INSN); - addOpcode("SALOAD", SALOAD, OpcodeGroup.INSN); - addOpcode("ISTORE", ISTORE, OpcodeGroup.INSN_VAR); - addOpcode("LSTORE", LSTORE, OpcodeGroup.INSN_VAR); - addOpcode("FSTORE", FSTORE, OpcodeGroup.INSN_VAR); - addOpcode("DSTORE", DSTORE, OpcodeGroup.INSN_VAR); - addOpcode("ASTORE", ASTORE, OpcodeGroup.INSN_VAR); - addOpcode("IASTORE", IASTORE, OpcodeGroup.INSN); - addOpcode("LASTORE", LASTORE, OpcodeGroup.INSN); - addOpcode("FASTORE", FASTORE, OpcodeGroup.INSN); - addOpcode("DASTORE", DASTORE, OpcodeGroup.INSN); - addOpcode("AASTORE", AASTORE, OpcodeGroup.INSN); - addOpcode("BASTORE", BASTORE, OpcodeGroup.INSN); - addOpcode("CASTORE", CASTORE, OpcodeGroup.INSN); - addOpcode("SASTORE", SASTORE, OpcodeGroup.INSN); - addOpcode("POP", POP, OpcodeGroup.INSN); - addOpcode("POP2", POP2, OpcodeGroup.INSN); - addOpcode("DUP", DUP, OpcodeGroup.INSN); - addOpcode("DUP_X1", DUP_X1, OpcodeGroup.INSN); - addOpcode("DUP_X2", DUP_X2, OpcodeGroup.INSN); - addOpcode("DUP2", DUP2, OpcodeGroup.INSN); - addOpcode("DUP2_X1", DUP2_X1, OpcodeGroup.INSN); - addOpcode("DUP2_X2", DUP2_X2, OpcodeGroup.INSN); - addOpcode("SWAP", SWAP, OpcodeGroup.INSN); - addOpcode("IADD", IADD, OpcodeGroup.INSN); - addOpcode("LADD", LADD, OpcodeGroup.INSN); - addOpcode("FADD", FADD, OpcodeGroup.INSN); - addOpcode("DADD", DADD, OpcodeGroup.INSN); - addOpcode("ISUB", ISUB, OpcodeGroup.INSN); - addOpcode("LSUB", LSUB, OpcodeGroup.INSN); - addOpcode("FSUB", FSUB, OpcodeGroup.INSN); - addOpcode("DSUB", DSUB, OpcodeGroup.INSN); - addOpcode("IMUL", IMUL, OpcodeGroup.INSN); - addOpcode("LMUL", LMUL, OpcodeGroup.INSN); - addOpcode("FMUL", FMUL, OpcodeGroup.INSN); - addOpcode("DMUL", DMUL, OpcodeGroup.INSN); - addOpcode("IDIV", IDIV, OpcodeGroup.INSN); - addOpcode("LDIV", LDIV, OpcodeGroup.INSN); - addOpcode("FDIV", FDIV, OpcodeGroup.INSN); - addOpcode("DDIV", DDIV, OpcodeGroup.INSN); - addOpcode("IREM", IREM, OpcodeGroup.INSN); - addOpcode("LREM", LREM, OpcodeGroup.INSN); - addOpcode("FREM", FREM, OpcodeGroup.INSN); - addOpcode("DREM", DREM, OpcodeGroup.INSN); - addOpcode("INEG", INEG, OpcodeGroup.INSN); - addOpcode("LNEG", LNEG, OpcodeGroup.INSN); - addOpcode("FNEG", FNEG, OpcodeGroup.INSN); - addOpcode("DNEG", DNEG, OpcodeGroup.INSN); - addOpcode("ISHL", ISHL, OpcodeGroup.INSN); - addOpcode("LSHL", LSHL, OpcodeGroup.INSN); - addOpcode("ISHR", ISHR, OpcodeGroup.INSN); - addOpcode("LSHR", LSHR, OpcodeGroup.INSN); - addOpcode("IUSHR", IUSHR, OpcodeGroup.INSN); - addOpcode("LUSHR", LUSHR, OpcodeGroup.INSN); - addOpcode("IAND", IAND, OpcodeGroup.INSN); - addOpcode("LAND", LAND, OpcodeGroup.INSN); - addOpcode("IOR", IOR, OpcodeGroup.INSN); - addOpcode("LOR", LOR, OpcodeGroup.INSN); - addOpcode("IXOR", IXOR, OpcodeGroup.INSN); - addOpcode("LXOR", LXOR, OpcodeGroup.INSN); - addOpcode("IINC", IINC, OpcodeGroup.INSN_IINC); - addOpcode("I2L", I2L, OpcodeGroup.INSN); - addOpcode("I2F", I2F, OpcodeGroup.INSN); - addOpcode("I2D", I2D, OpcodeGroup.INSN); - addOpcode("L2I", L2I, OpcodeGroup.INSN); - addOpcode("L2F", L2F, OpcodeGroup.INSN); - addOpcode("L2D", L2D, OpcodeGroup.INSN); - addOpcode("F2I", F2I, OpcodeGroup.INSN); - addOpcode("F2L", F2L, OpcodeGroup.INSN); - addOpcode("F2D", F2D, OpcodeGroup.INSN); - addOpcode("D2I", D2I, OpcodeGroup.INSN); - addOpcode("D2L", D2L, OpcodeGroup.INSN); - addOpcode("D2F", D2F, OpcodeGroup.INSN); - addOpcode("I2B", I2B, OpcodeGroup.INSN); - addOpcode("I2C", I2C, OpcodeGroup.INSN); - addOpcode("I2S", I2S, OpcodeGroup.INSN); - addOpcode("LCMP", LCMP, OpcodeGroup.INSN); - addOpcode("FCMPL", FCMPL, OpcodeGroup.INSN); - addOpcode("FCMPG", FCMPG, OpcodeGroup.INSN); - addOpcode("DCMPL", DCMPL, OpcodeGroup.INSN); - addOpcode("DCMPG", DCMPG, OpcodeGroup.INSN); - addOpcode("IFEQ", IFEQ, OpcodeGroup.INSN_JUMP); - addOpcode("IFNE", IFNE, OpcodeGroup.INSN_JUMP); - addOpcode("IFLT", IFLT, OpcodeGroup.INSN_JUMP); - addOpcode("IFGE", IFGE, OpcodeGroup.INSN_JUMP); - addOpcode("IFGT", IFGT, OpcodeGroup.INSN_JUMP); - addOpcode("IFLE", IFLE, OpcodeGroup.INSN_JUMP); - addOpcode("IF_ICMPEQ", IF_ICMPEQ, OpcodeGroup.INSN_JUMP); - addOpcode("IF_ICMPNE", IF_ICMPNE, OpcodeGroup.INSN_JUMP); - addOpcode("IF_ICMPLT", IF_ICMPLT, OpcodeGroup.INSN_JUMP); - addOpcode("IF_ICMPGE", IF_ICMPGE, OpcodeGroup.INSN_JUMP); - addOpcode("IF_ICMPGT", IF_ICMPGT, OpcodeGroup.INSN_JUMP); - addOpcode("IF_ICMPLE", IF_ICMPLE, OpcodeGroup.INSN_JUMP); - addOpcode("IF_ACMPEQ", IF_ACMPEQ, OpcodeGroup.INSN_JUMP); - addOpcode("IF_ACMPNE", IF_ACMPNE, OpcodeGroup.INSN_JUMP); - addOpcode("GOTO", GOTO, OpcodeGroup.INSN_JUMP); - addOpcode("JSR", JSR, OpcodeGroup.INSN_JUMP); - addOpcode("RET", RET, OpcodeGroup.INSN_VAR); - addOpcode("IRETURN", IRETURN, OpcodeGroup.INSN); - addOpcode("LRETURN", LRETURN, OpcodeGroup.INSN); - addOpcode("FRETURN", FRETURN, OpcodeGroup.INSN); - addOpcode("DRETURN", DRETURN, OpcodeGroup.INSN); - addOpcode("ARETURN", ARETURN, OpcodeGroup.INSN); - addOpcode("RETURN", RETURN, OpcodeGroup.INSN); - addOpcode("GETSTATIC", GETSTATIC, OpcodeGroup.INSN_FIELD); - addOpcode("PUTSTATIC", PUTSTATIC, OpcodeGroup.INSN_FIELD); - addOpcode("GETFIELD", GETFIELD, OpcodeGroup.INSN_FIELD); - addOpcode("PUTFIELD", PUTFIELD, OpcodeGroup.INSN_FIELD); - addOpcode("INVOKEVIRTUAL", INVOKEVIRTUAL, OpcodeGroup.INSN_METHOD); - addOpcode("INVOKESPECIAL", INVOKESPECIAL, OpcodeGroup.INSN_METHOD); - addOpcode("INVOKESTATIC", INVOKESTATIC, OpcodeGroup.INSN_METHOD); - addOpcode("INVOKEINTERFACE", INVOKEINTERFACE, OpcodeGroup.INSN_METHOD); - addOpcode("NEW", NEW, OpcodeGroup.INSN_TYPE); - addOpcode("NEWARRAY", NEWARRAY, OpcodeGroup.INSN_INT); - addOpcode("ANEWARRAY", ANEWARRAY, OpcodeGroup.INSN_TYPE); - addOpcode("ARRAYLENGTH", ARRAYLENGTH, OpcodeGroup.INSN); - addOpcode("ATHROW", ATHROW, OpcodeGroup.INSN); - addOpcode("CHECKCAST", CHECKCAST, OpcodeGroup.INSN_TYPE); - addOpcode("INSTANCEOF", INSTANCEOF, OpcodeGroup.INSN_TYPE); - addOpcode("MONITORENTER", MONITORENTER, OpcodeGroup.INSN); - addOpcode("MONITOREXIT", MONITOREXIT, OpcodeGroup.INSN); - addOpcode("MULTIANEWARRAY", MULTIANEWARRAY, OpcodeGroup.INSN_MULTIANEWARRAY); - addOpcode("IFNULL", IFNULL, OpcodeGroup.INSN_JUMP); - addOpcode("IFNONNULL", IFNONNULL, OpcodeGroup.INSN_JUMP); - } - - private static void addOpcode(String operStr, int oper, int group) { - OPCODES.put(operStr, new Opcode(oper, group)); - } - - private static final Map TYPES = new HashMap(); - static { - String[] types = SAXCodeAdapter.TYPES; - for (int i = 0; i < types.length; i++) { - TYPES.put(types[i], new Integer(i)); - } - } - - /** - * Constructs a new {@link ASMContentHandler ASMContentHandler} object. - * - * @param os output stream to write generated class. - * @param computeMax true if the maximum stack size and the maximum - * number of local variables must be automatically computed. This - * value is passed to {@link ClassWriter ClassWriter} instance. - */ - public ASMContentHandler(final OutputStream os, final boolean computeMax) { - this.os = os; - this.computeMax = computeMax; - } - - /** - * Returns the bytecode of the class that was build with underneath class - * writer. - * - * @return the bytecode of the class that was build with underneath class - * writer or null if there are no classwriter created. - */ - public byte[] toByteArray() { - return cw == null ? null : cw.toByteArray(); - } - - /** - * Process notification of the start of an XML element being reached. - * - * @param ns - The Namespace URI, or the empty string if the element has no - * Namespace URI or if Namespace processing is not being - * performed. - * @param lName - The local name (without prefix), or the empty string if - * Namespace processing is not being performed. - * @param qName - The qualified name (with prefix), or the empty string if - * qualified names are not available. - * @param list - The attributes attached to the element. If there are no - * attributes, it shall be an empty Attributes object. - * @exception SAXException if a parsing error is to be reported - */ - public final void startElement(final String ns, final String lName, final String qName, final Attributes list) - throws SAXException { - // the actual element name is either in lName or qName, depending - // on whether the parser is namespace aware - String name = lName == null || lName.length() == 0 ? qName : lName; - - // Compute the current matching rule - StringBuilder sb = new StringBuilder(match); - if (match.length() > 0) { - sb.append('/'); - } - sb.append(name); - match = sb.toString(); - - // Fire "begin" events for all relevant rules - Rule r = (Rule) RULES.match(match); - if (r != null) { - r.begin(name, list); - } - } - - /** - * Process notification of the end of an XML element being reached. - * - * @param ns - The Namespace URI, or the empty string if the element has no - * Namespace URI or if Namespace processing is not being - * performed. - * @param lName - The local name (without prefix), or the empty string if - * Namespace processing is not being performed. - * @param qName - The qualified XML 1.0 name (with prefix), or the empty - * string if qualified names are not available. - * @exception SAXException if a parsing error is to be reported - */ - public final void endElement(final String ns, final String lName, final String qName) throws SAXException { - // the actual element name is either in lName or qName, depending - // on whether the parser is namespace aware - String name = lName == null || lName.length() == 0 ? qName : lName; - - // Fire "end" events for all relevant rules in reverse order - Rule r = (Rule) RULES.match(match); - if (r != null) { - r.end(name); - } - - // Recover the previous match expression - int slash = match.lastIndexOf('/'); - if (slash >= 0) { - match = match.substring(0, slash); - } else { - match = ""; - } - } - - /** - * Process notification of the end of a document and write generated - * bytecode into output stream. - * - * @exception SAXException if parsing or writing error is to be reported. - */ - public final void endDocument() throws SAXException { - try { - os.write(toByteArray()); - } catch (IOException ex) { - throw new SAXException(ex.toString(), ex); - } - } - - /** - * Return the top object on the stack without removing it. If there are no - * objects on the stack, return null. - * - * @return the top object on the stack without removing it. - */ - final Object peek() { - int size = stack.size(); - return size == 0 ? null : stack.get(size - 1); - } - - /** - * Pop the top object off of the stack, and return it. If there are no - * objects on the stack, return null. - * - * @return the top object off of the stack. - */ - final Object pop() { - int size = stack.size(); - return size == 0 ? null : stack.remove(size - 1); - } - - /** - * Push a new object onto the top of the object stack. - * - * @param object The new object - */ - final void push(final Object object) { - stack.add(object); - } - - private static final class RuleSet { - - private final Map rules = new HashMap(); - - private final List lpatterns = new ArrayList(); - - private final List rpatterns = new ArrayList(); - - public void add(final String path, final Object rule) { - String pattern = path; - if (path.startsWith("*/")) { - pattern = path.substring(1); - lpatterns.add(pattern); - } else if (path.endsWith("/*")) { - pattern = path.substring(0, path.length() - 1); - rpatterns.add(pattern); - } - rules.put(pattern, rule); - } - - public Object match(final String path) { - if (rules.containsKey(path)) { - return rules.get(path); - } - - int n = path.lastIndexOf('/'); - for (Iterator it = lpatterns.iterator(); it.hasNext();) { - String pattern = (String) it.next(); - if (path.substring(n).endsWith(pattern)) { - return rules.get(pattern); - } - } - - for (Iterator it = rpatterns.iterator(); it.hasNext();) { - String pattern = (String) it.next(); - if (path.startsWith(pattern)) { - return rules.get(pattern); - } - } - - return null; - } - } - - /** - * Rule - */ - protected abstract class Rule { - - public void begin(final String name, final Attributes attrs) throws SAXException { - } - - public void end(final String name) { - } - - protected final Object getValue(final String desc, final String val) throws SAXException { - Object value = null; - if (val != null) { - if ("Ljava/lang/String;".equals(desc)) { - value = decode(val); - } else if ("Ljava/lang/Integer;".equals(desc) || "I".equals(desc) || "S".equals(desc) - || "B".equals(desc) || "C".equals(desc) || "Z".equals(desc)) { - value = new Integer(val); - - } else if ("Ljava/lang/Short;".equals(desc)) { - value = new Short(val); - - } else if ("Ljava/lang/Byte;".equals(desc)) { - value = new Byte(val); - - } else if ("Ljava/lang/Character;".equals(desc)) { - value = new Character(decode(val).charAt(0)); - - } else if ("Ljava/lang/Boolean;".equals(desc)) { - value = Boolean.valueOf(val); - - } else if ("Ljava/lang/Long;".equals(desc) || "J".equals(desc)) { - value = new Long(val); - } else if ("Ljava/lang/Float;".equals(desc) || "F".equals(desc)) { - value = new Float(val); - } else if ("Ljava/lang/Double;".equals(desc) || "D".equals(desc)) { - value = new Double(val); - } else if (Type.getDescriptor(Type.class).equals(desc)) { - value = Type.getType(val); - - } else { - // TODO use of default toString(). - throw new SAXException("Invalid value:" + val + " desc:" + desc + " ctx:" + this); - } - } - return value; - } - - private final String decode(final String val) throws SAXException { - StringBuilder sb = new StringBuilder(val.length()); - try { - int n = 0; - while (n < val.length()) { - char c = val.charAt(n); - if (c == '\\') { - n++; - c = val.charAt(n); - if (c == '\\') { - sb.append('\\'); - } else { - n++; // skip 'u' - sb.append((char) Integer.parseInt(val.substring(n, n + 4), 16)); - n += 3; - } - } else { - sb.append(c); - } - n++; - } - - } catch (RuntimeException ex) { - throw new SAXException(ex); - } - return sb.toString(); - } - - protected final Label getLabel(final Object label) { - Label lbl = (Label) labels.get(label); - if (lbl == null) { - lbl = new Label(); - labels.put(label, lbl); - } - return lbl; - } - - // TODO verify move to stack - protected final MethodVisitor getCodeVisitor() { - return (MethodVisitor) peek(); - } - - protected final int getAccess(final String s) { - int access = 0; - if (s.indexOf("public") != -1) { - access |= ACC_PUBLIC; - } - if (s.indexOf("private") != -1) { - access |= ACC_PRIVATE; - } - if (s.indexOf("protected") != -1) { - access |= ACC_PROTECTED; - } - if (s.indexOf("static") != -1) { - access |= ACC_STATIC; - } - if (s.indexOf("final") != -1) { - access |= ACC_FINAL; - } - if (s.indexOf("super") != -1) { - access |= ACC_SUPER; - } - if (s.indexOf("synchronized") != -1) { - access |= ACC_SYNCHRONIZED; - } - if (s.indexOf("volatile") != -1) { - access |= ACC_VOLATILE; - } - if (s.indexOf("bridge") != -1) { - access |= ACC_BRIDGE; - } - if (s.indexOf("varargs") != -1) { - access |= ACC_VARARGS; - } - if (s.indexOf("transient") != -1) { - access |= ACC_TRANSIENT; - } - if (s.indexOf("native") != -1) { - access |= ACC_NATIVE; - } - if (s.indexOf("interface") != -1) { - access |= ACC_INTERFACE; - } - if (s.indexOf("abstract") != -1) { - access |= ACC_ABSTRACT; - } - if (s.indexOf("strict") != -1) { - access |= ACC_STRICT; - } - if (s.indexOf("synthetic") != -1) { - access |= ACC_SYNTHETIC; - } - if (s.indexOf("annotation") != -1) { - access |= ACC_ANNOTATION; - } - if (s.indexOf("enum") != -1) { - access |= ACC_ENUM; - } - if (s.indexOf("deprecated") != -1) { - access |= ACC_DEPRECATED; - } - return access; - } - } - - /** - * ClassRule - */ - private final class ClassRule extends Rule { - - public final void begin(final String name, final Attributes attrs) { - int major = Integer.parseInt(attrs.getValue("major")); - int minor = Integer.parseInt(attrs.getValue("minor")); - cw = new ClassWriter(computeMax ? ClassWriter.COMPUTE_MAXS : 0); - Map vals = new HashMap(); - vals.put("version", new Integer(minor << 16 | major)); - vals.put("access", attrs.getValue("access")); - vals.put("name", attrs.getValue("name")); - vals.put("parent", attrs.getValue("parent")); - vals.put("source", attrs.getValue("source")); - vals.put("signature", attrs.getValue("signature")); - vals.put("interfaces", new ArrayList()); - push(vals); - // values will be extracted in InterfacesRule.end(); - } - } - - private final class SourceRule extends Rule { - - public void begin(final String name, final Attributes attrs) { - String file = attrs.getValue("file"); - String debug = attrs.getValue("debug"); - cw.visitSource(file, debug); - } - } - - /** - * InterfaceRule - */ - private final class InterfaceRule extends Rule { - - public final void begin(final String name, final Attributes attrs) { - ((List) ((HashMap) peek()).get("interfaces")).add(attrs.getValue("name")); - } - } - - /** - * InterfacesRule - */ - private final class InterfacesRule extends Rule { - - public final void end(final String element) { - Map vals = (HashMap) pop(); - int version = ((Integer) vals.get("version")).intValue(); - int access = getAccess((String) vals.get("access")); - String name = (String) vals.get("name"); - String signature = (String) vals.get("signature"); - String parent = (String) vals.get("parent"); - List infs = (List) vals.get("interfaces"); - String[] interfaces = (String[]) infs.toArray(new String[infs.size()]); - cw.visit(version, access, name, signature, parent, interfaces); - push(cw); - } - } - - /** - * OuterClassRule - */ - private final class OuterClassRule extends Rule { - - public final void begin(final String element, final Attributes attrs) { - String owner = attrs.getValue("owner"); - String name = attrs.getValue("name"); - String desc = attrs.getValue("desc"); - cw.visitOuterClass(owner, name, desc); - } - } - - /** - * InnerClassRule - */ - private final class InnerClassRule extends Rule { - - public final void begin(final String element, final Attributes attrs) { - int access = getAccess(attrs.getValue("access")); - String name = attrs.getValue("name"); - String outerName = attrs.getValue("outerName"); - String innerName = attrs.getValue("innerName"); - cw.visitInnerClass(name, outerName, innerName, access); - } - } - - /** - * FieldRule - */ - private final class FieldRule extends Rule { - - public final void begin(final String element, final Attributes attrs) throws SAXException { - int access = getAccess(attrs.getValue("access")); - String name = attrs.getValue("name"); - String signature = attrs.getValue("signature"); - String desc = attrs.getValue("desc"); - Object value = getValue(desc, attrs.getValue("value")); - push(cw.visitField(access, name, desc, signature, value)); - } - - public void end(final String name) { - ((FieldVisitor) pop()).visitEnd(); - } - } - - /** - * MethodRule - */ - private final class MethodRule extends Rule { - - public final void begin(final String name, final Attributes attrs) { - labels = new HashMap(); - Map vals = new HashMap(); - vals.put("access", attrs.getValue("access")); - vals.put("name", attrs.getValue("name")); - vals.put("desc", attrs.getValue("desc")); - vals.put("signature", attrs.getValue("signature")); - vals.put("exceptions", new ArrayList()); - push(vals); - // values will be extracted in ExceptionsRule.end(); - } - - public final void end(final String name) { - ((MethodVisitor) pop()).visitEnd(); - labels = null; - } - } - - /** - * ExceptionRule - */ - private final class ExceptionRule extends Rule { - - public final void begin(final String name, final Attributes attrs) { - ((List) ((HashMap) peek()).get("exceptions")).add(attrs.getValue("name")); - } - } - - /** - * ExceptionsRule - */ - private final class ExceptionsRule extends Rule { - - public final void end(final String element) { - Map vals = (HashMap) pop(); - int access = getAccess((String) vals.get("access")); - String name = (String) vals.get("name"); - String desc = (String) vals.get("desc"); - String signature = (String) vals.get("signature"); - List excs = (List) vals.get("exceptions"); - String[] exceptions = (String[]) excs.toArray(new String[excs.size()]); - - push(cw.visitMethod(access, name, desc, signature, exceptions)); - } - } - - /** - * TableSwitchRule - */ - private class TableSwitchRule extends Rule { - - public final void begin(final String name, final Attributes attrs) { - Map vals = new HashMap(); - vals.put("min", attrs.getValue("min")); - vals.put("max", attrs.getValue("max")); - vals.put("dflt", attrs.getValue("dflt")); - vals.put("labels", new ArrayList()); - push(vals); - } - - public final void end(final String name) { - Map vals = (HashMap) pop(); - int min = Integer.parseInt((String) vals.get("min")); - int max = Integer.parseInt((String) vals.get("max")); - Label dflt = getLabel(vals.get("dflt")); - List lbls = (List) vals.get("labels"); - Label[] labels = (Label[]) lbls.toArray(new Label[lbls.size()]); - getCodeVisitor().visitTableSwitchInsn(min, max, dflt, labels); - } - } - - /** - * TableSwitchLabelRule - */ - private final class TableSwitchLabelRule extends Rule { - - public final void begin(final String name, final Attributes attrs) { - ((List) ((HashMap) peek()).get("labels")).add(getLabel(attrs.getValue("name"))); - } - } - - /** - * LookupSwitchRule - */ - private final class LookupSwitchRule extends Rule { - - public final void begin(final String name, final Attributes attrs) { - Map vals = new HashMap(); - vals.put("dflt", attrs.getValue("dflt")); - vals.put("labels", new ArrayList()); - vals.put("keys", new ArrayList()); - push(vals); - } - - public final void end(final String name) { - Map vals = (HashMap) pop(); - Label dflt = getLabel(vals.get("dflt")); - List keyList = (List) vals.get("keys"); - List lbls = (List) vals.get("labels"); - Label[] labels = (Label[]) lbls.toArray(new Label[lbls.size()]); - int[] keys = new int[keyList.size()]; - for (int i = 0; i < keys.length; i++) { - keys[i] = Integer.parseInt((String) keyList.get(i)); - } - getCodeVisitor().visitLookupSwitchInsn(dflt, keys, labels); - } - } - - /** - * LookupSwitchLabelRule - */ - private final class LookupSwitchLabelRule extends Rule { - - public final void begin(final String name, final Attributes attrs) { - Map vals = (HashMap) peek(); - ((List) vals.get("labels")).add(getLabel(attrs.getValue("name"))); - ((List) vals.get("keys")).add(attrs.getValue("key")); - } - } - - /** - * FrameRule - */ - private final class FrameRule extends Rule { - - public void begin(final String name, final Attributes attrs) { - Map typeLists = new HashMap(); - typeLists.put("local", new ArrayList()); - typeLists.put("stack", new ArrayList()); - push(attrs.getValue("type")); - push(attrs.getValue("count") == null ? "0" : attrs.getValue("count")); - push(typeLists); - } - - public void end(final String name) { - Map typeLists = (HashMap) pop(); - List locals = (List) typeLists.get("local"); - int nLocal = locals.size(); - Object[] local = locals.toArray(); - List stacks = (List) typeLists.get("stack"); - int nStack = stacks.size(); - Object[] stack = stacks.toArray(); - String count = (String) pop(); - String type = (String) pop(); - if ("NEW".equals(type)) { - getCodeVisitor().visitFrame(F_NEW, nLocal, local, nStack, stack); - } else if ("FULL".equals(type)) { - getCodeVisitor().visitFrame(F_FULL, nLocal, local, nStack, stack); - } else if ("APPEND".equals(type)) { - getCodeVisitor().visitFrame(F_APPEND, nLocal, local, 0, null); - } else if ("CHOP".equals(type)) { - getCodeVisitor().visitFrame(F_CHOP, Integer.parseInt(count), null, 0, null); - } else if ("SAME".equals(type)) { - getCodeVisitor().visitFrame(F_SAME, 0, null, 0, null); - } else if ("SAME1".equals(type)) { - getCodeVisitor().visitFrame(F_SAME1, 0, null, nStack, stack); - } - } - } - - private final class FrameTypeRule extends Rule { - - public void begin(final String name, final Attributes attrs) { - List types = (List) ((HashMap) peek()).get(name); - String type = attrs.getValue("type"); - if ("uninitialized".equals(type)) { - types.add(getLabel(attrs.getValue("label"))); - } else { - Integer t = (Integer) TYPES.get(type); - if (t == null) { - types.add(type); - } else { - types.add(t); - } - } - } - } - - /** - * LabelRule - */ - private final class LabelRule extends Rule { - - public final void begin(final String name, final Attributes attrs) { - getCodeVisitor().visitLabel(getLabel(attrs.getValue("name"))); - } - } - - /** - * TryCatchRule - */ - private final class TryCatchRule extends Rule { - - public final void begin(final String name, final Attributes attrs) { - Label start = getLabel(attrs.getValue("start")); - Label end = getLabel(attrs.getValue("end")); - Label handler = getLabel(attrs.getValue("handler")); - String type = attrs.getValue("type"); - getCodeVisitor().visitTryCatchBlock(start, end, handler, type); - } - } - - /** - * LineNumberRule - */ - private final class LineNumberRule extends Rule { - - public final void begin(final String name, final Attributes attrs) { - int line = Integer.parseInt(attrs.getValue("line")); - Label start = getLabel(attrs.getValue("start")); - getCodeVisitor().visitLineNumber(line, start); - } - } - - /** - * LocalVarRule - */ - private final class LocalVarRule extends Rule { - - public final void begin(final String element, final Attributes attrs) { - String name = attrs.getValue("name"); - String desc = attrs.getValue("desc"); - String signature = attrs.getValue("signature"); - Label start = getLabel(attrs.getValue("start")); - Label end = getLabel(attrs.getValue("end")); - int var = Integer.parseInt(attrs.getValue("var")); - getCodeVisitor().visitLocalVariable(name, desc, signature, start, end, var); - } - } - - /** - * OpcodesRule - */ - private final class OpcodesRule extends Rule { - - // public boolean match( String match, String element) { - // return match.startsWith( path) && OPCODES.containsKey( element); - // } - - public final void begin(final String element, final Attributes attrs) throws SAXException { - Opcode o = (Opcode) OPCODES.get(element); - if (o == null) { - throw new SAXException("Invalid element: " + element + " at " + match); - } - - switch (o.type) { - case OpcodeGroup.INSN: - getCodeVisitor().visitInsn(o.opcode); - break; - - case OpcodeGroup.INSN_FIELD: - getCodeVisitor().visitFieldInsn(o.opcode, attrs.getValue("owner"), attrs.getValue("name"), - attrs.getValue("desc")); - break; - - case OpcodeGroup.INSN_INT: - getCodeVisitor().visitIntInsn(o.opcode, Integer.parseInt(attrs.getValue("value"))); - break; - - case OpcodeGroup.INSN_JUMP: - getCodeVisitor().visitJumpInsn(o.opcode, getLabel(attrs.getValue("label"))); - break; - - case OpcodeGroup.INSN_METHOD: - getCodeVisitor().visitMethodInsn(o.opcode, attrs.getValue("owner"), attrs.getValue("name"), - attrs.getValue("desc")); - break; - - case OpcodeGroup.INSN_TYPE: - getCodeVisitor().visitTypeInsn(o.opcode, attrs.getValue("desc")); - break; - - case OpcodeGroup.INSN_VAR: - getCodeVisitor().visitVarInsn(o.opcode, Integer.parseInt(attrs.getValue("var"))); - break; - - case OpcodeGroup.INSN_IINC: - getCodeVisitor().visitIincInsn(Integer.parseInt(attrs.getValue("var")), - Integer.parseInt(attrs.getValue("inc"))); - break; - - case OpcodeGroup.INSN_LDC: - getCodeVisitor().visitLdcInsn(getValue(attrs.getValue("desc"), attrs.getValue("cst"))); - break; - - case OpcodeGroup.INSN_MULTIANEWARRAY: - getCodeVisitor().visitMultiANewArrayInsn(attrs.getValue("desc"), - Integer.parseInt(attrs.getValue("dims"))); - break; - - default: - throw new Error("Internal error"); - - } - } - } - - /** - * MaxRule - */ - private final class MaxRule extends Rule { - - public final void begin(final String element, final Attributes attrs) { - int maxStack = Integer.parseInt(attrs.getValue("maxStack")); - int maxLocals = Integer.parseInt(attrs.getValue("maxLocals")); - getCodeVisitor().visitMaxs(maxStack, maxLocals); - } - } - - private final class AnnotationRule extends Rule { - - public void begin(final String name, final Attributes attrs) { - String desc = attrs.getValue("desc"); - boolean visible = Boolean.valueOf(attrs.getValue("visible")).booleanValue(); - - Object v = peek(); - if (v instanceof ClassVisitor) { - push(((ClassVisitor) v).visitAnnotation(desc, visible)); - } else if (v instanceof FieldVisitor) { - push(((FieldVisitor) v).visitAnnotation(desc, visible)); - } else if (v instanceof MethodVisitor) { - push(((MethodVisitor) v).visitAnnotation(desc, visible)); - } - } - - public void end(final String name) { - AnnotationVisitor av = (AnnotationVisitor) pop(); - if (av != null) { - av.visitEnd(); - } - } - } - - private final class AnnotationParameterRule extends Rule { - - public void begin(final String name, final Attributes attrs) { - int parameter = Integer.parseInt(attrs.getValue("parameter")); - String desc = attrs.getValue("desc"); - boolean visible = Boolean.valueOf(attrs.getValue("visible")).booleanValue(); - - push(((MethodVisitor) peek()).visitParameterAnnotation(parameter, desc, visible)); - } - - public void end(final String name) { - AnnotationVisitor av = (AnnotationVisitor) pop(); - if (av != null) { - av.visitEnd(); - } - } - } - - private final class AnnotationValueRule extends Rule { - - public void begin(final String nm, final Attributes attrs) throws SAXException { - AnnotationVisitor av = (AnnotationVisitor) peek(); - if (av != null) { - av.visit(attrs.getValue("name"), getValue(attrs.getValue("desc"), attrs.getValue("value"))); - } - } - } - - private final class AnnotationValueEnumRule extends Rule { - - public void begin(final String nm, final Attributes attrs) { - AnnotationVisitor av = (AnnotationVisitor) peek(); - if (av != null) { - av.visitEnum(attrs.getValue("name"), attrs.getValue("desc"), attrs.getValue("value")); - } - } - } - - private final class AnnotationValueAnnotationRule extends Rule { - - public void begin(final String nm, final Attributes attrs) { - AnnotationVisitor av = (AnnotationVisitor) peek(); - push(av == null ? null : av.visitAnnotation(attrs.getValue("name"), attrs.getValue("desc"))); - } - - public void end(final String name) { - AnnotationVisitor av = (AnnotationVisitor) pop(); - if (av != null) { - av.visitEnd(); - } - } - } - - private final class AnnotationValueArrayRule extends Rule { - - public void begin(final String nm, final Attributes attrs) { - AnnotationVisitor av = (AnnotationVisitor) peek(); - push(av == null ? null : av.visitArray(attrs.getValue("name"))); - } - - public void end(final String name) { - AnnotationVisitor av = (AnnotationVisitor) pop(); - if (av != null) { - av.visitEnd(); - } - } - } - - private final class AnnotationDefaultRule extends Rule { - - public void begin(final String nm, final Attributes attrs) { - MethodVisitor av = (MethodVisitor) peek(); - push(av == null ? null : av.visitAnnotationDefault()); - } - - public void end(final String name) { - AnnotationVisitor av = (AnnotationVisitor) pop(); - if (av != null) { - av.visitEnd(); - } - } - } - - /** - * Opcode - */ - private static final class Opcode { - - public final int opcode; - - public final int type; - - private Opcode(final int opcode, final int type) { - this.opcode = opcode; - this.type = type; - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/xml/Processor.java b/common/asm/src/main/java/com/alibaba/citrus/asm/xml/Processor.java deleted file mode 100644 index 9eef91b29..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/xml/Processor.java +++ /dev/null @@ -1,998 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM XML Adapter - * Copyright (c) 2004, Eugene Kuleshov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.xml; - -import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import java.util.zip.ZipOutputStream; - -import javax.xml.transform.Source; -import javax.xml.transform.Templates; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.sax.SAXSource; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamSource; - -import org.xml.sax.Attributes; -import org.xml.sax.ContentHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.ext.LexicalHandler; -import org.xml.sax.helpers.AttributesImpl; -import org.xml.sax.helpers.DefaultHandler; -import org.xml.sax.helpers.XMLReaderFactory; - -import com.alibaba.citrus.asm.ClassReader; - -/** - * Processor is a command line tool that can be used for bytecode waving - * directed by XSL transformation. - *

- * In order to use a concrete XSLT engine, system property - * javax.xml.transform.TransformerFactory must be set to one of the - * following values.

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
jd.xsltjd.xml.xslt.trax.TransformerFactoryImpl
Saxonnet.sf.saxon.TransformerFactoryImpl
Cauchocom.caucho.xsl.Xsl
Xalan interpeterorg.apache.xalan.processor.TransformerFactory
Xalan xsltcorg.apache.xalan.xsltc.trax.TransformerFactoryImpl
- *
- * - * @author Eugene Kuleshov - */ -public class Processor { - - public static final int BYTECODE = 1; - - public static final int MULTI_XML = 2; - - public static final int SINGLE_XML = 3; - - private static final String SINGLE_XML_NAME = "classes.xml"; - - private final int inRepresentation; - - private final int outRepresentation; - - private final InputStream input; - - private final OutputStream output; - - private final Source xslt; - - private final boolean computeMax; - - private int n = 0; - - public Processor(final int inRepresenation, final int outRepresentation, final InputStream input, - final OutputStream output, final Source xslt) { - this.inRepresentation = inRepresenation; - this.outRepresentation = outRepresentation; - this.input = input; - this.output = output; - this.xslt = xslt; - this.computeMax = true; - } - - public int process() throws TransformerException, IOException, SAXException { - ZipInputStream zis = new ZipInputStream(input); - final ZipOutputStream zos = new ZipOutputStream(output); - final OutputStreamWriter osw = new OutputStreamWriter(zos); - - Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - - TransformerFactory tf = TransformerFactory.newInstance(); - if (!tf.getFeature(SAXSource.FEATURE) || !tf.getFeature(SAXResult.FEATURE)) { - return 0; - } - - SAXTransformerFactory saxtf = (SAXTransformerFactory) tf; - Templates templates = null; - if (xslt != null) { - templates = saxtf.newTemplates(xslt); - } - - // configuring outHandlerFactory - // /////////////////////////////////////////////////////// - - EntryElement entryElement = getEntryElement(zos); - - ContentHandler outDocHandler = null; - switch (outRepresentation) { - case BYTECODE: - outDocHandler = new OutputSlicingHandler(new ASMContentHandlerFactory(zos, computeMax), entryElement, - false); - break; - - case MULTI_XML: - outDocHandler = new OutputSlicingHandler(new SAXWriterFactory(osw, true), entryElement, true); - break; - - case SINGLE_XML: - ZipEntry outputEntry = new ZipEntry(SINGLE_XML_NAME); - zos.putNextEntry(outputEntry); - outDocHandler = new SAXWriter(osw, false); - break; - - } - - // configuring inputDocHandlerFactory - // ///////////////////////////////////////////////// - ContentHandler inDocHandler; - if (templates == null) { - inDocHandler = outDocHandler; - } else { - inDocHandler = new InputSlicingHandler("class", outDocHandler, new TransformerHandlerFactory(saxtf, - templates, outDocHandler)); - } - ContentHandlerFactory inDocHandlerFactory = new SubdocumentHandlerFactory(inDocHandler); - - if (inDocHandler != null && inRepresentation != SINGLE_XML) { - inDocHandler.startDocument(); - inDocHandler.startElement("", "classes", "classes", new AttributesImpl()); - } - - int i = 0; - ZipEntry ze; - while ((ze = zis.getNextEntry()) != null) { - update(ze.getName(), n++); - if (isClassEntry(ze)) { - processEntry(zis, ze, inDocHandlerFactory); - } else { - OutputStream os = entryElement.openEntry(getName(ze)); - copyEntry(zis, os); - entryElement.closeEntry(); - } - - i++; - } - - if (inDocHandler != null && inRepresentation != SINGLE_XML) { - inDocHandler.endElement("", "classes", "classes"); - inDocHandler.endDocument(); - } - - if (outRepresentation == SINGLE_XML) { - zos.closeEntry(); - } - zos.flush(); - zos.close(); - - return i; - } - - private void copyEntry(final InputStream is, final OutputStream os) throws IOException { - if (outRepresentation == SINGLE_XML) { - return; - } - - byte[] buff = new byte[2048]; - int i; - while ((i = is.read(buff)) != -1) { - os.write(buff, 0, i); - } - } - - private boolean isClassEntry(final ZipEntry ze) { - String name = ze.getName(); - return inRepresentation == SINGLE_XML && name.equals(SINGLE_XML_NAME) || name.endsWith(".class") - || name.endsWith(".class.xml"); - } - - private void processEntry(final ZipInputStream zis, final ZipEntry ze, final ContentHandlerFactory handlerFactory) { - ContentHandler handler = handlerFactory.createContentHandler(); - try { - - // if (CODE2ASM.equals(command)) { // read bytecode and process it - // // with TraceClassVisitor - // ClassReader cr = new ClassReader(readEntry(zis, ze)); - // cr.accept(new TraceClassVisitor(null, new PrintWriter(os)), - // false); - // } - - boolean singleInputDocument = inRepresentation == SINGLE_XML; - if (inRepresentation == BYTECODE) { // read bytecode and process it - // with handler - ClassReader cr = new ClassReader(readEntry(zis, ze)); - cr.accept(new SAXClassAdapter(handler, singleInputDocument), 0); - - } else { // read XML and process it with handler - XMLReader reader = XMLReaderFactory.createXMLReader(); - reader.setContentHandler(handler); - reader.parse(new InputSource(singleInputDocument ? (InputStream) new ProtectedInputStream(zis) - : new ByteArrayInputStream(readEntry(zis, ze)))); - - } - } catch (Exception ex) { - update(ze.getName(), 0); - update(ex, 0); - } - } - - private EntryElement getEntryElement(final ZipOutputStream zos) { - if (outRepresentation == SINGLE_XML) { - return new SingleDocElement(zos); - } - return new ZipEntryElement(zos); - } - - // private ContentHandlerFactory getHandlerFactory( - // OutputStream os, - // SAXTransformerFactory saxtf, - // Templates templates) - // { - // ContentHandlerFactory factory = null; - // if (templates == null) { - // if (outputRepresentation == BYTECODE) { // factory used to write - // // bytecode - // factory = new ASMContentHandlerFactory(os, computeMax); - // } else { // factory used to write XML - // factory = new SAXWriterFactory(os, true); - // } - // } else { - // if (outputRepresentation == BYTECODE) { // factory used to transform - // // and then write bytecode - // factory = new ASMTransformerHandlerFactory(saxtf, - // templates, - // os, - // computeMax); - // } else { // factory used to transformand then write XML - // factory = new TransformerHandlerFactory(saxtf, - // templates, - // os, - // outputRepresentation == SINGLE_XML); - // } - // } - // return factory; - // } - - private String getName(final ZipEntry ze) { - String name = ze.getName(); - if (isClassEntry(ze)) { - if (inRepresentation != BYTECODE && outRepresentation == BYTECODE) { - name = name.substring(0, name.length() - 4); // .class.xml to - // .class - } else if (inRepresentation == BYTECODE && outRepresentation != BYTECODE) { - name += ".xml"; // .class to .class.xml - } - // } else if( CODE2ASM.equals( command)) { - // name = name.substring( 0, name.length()-6).concat( ".asm"); - } - return name; - } - - private static byte[] readEntry(final InputStream zis, final ZipEntry ze) throws IOException { - long size = ze.getSize(); - if (size > -1) { - byte[] buff = new byte[(int) size]; - int k = 0; - int n; - while ((n = zis.read(buff, k, buff.length - k)) > 0) { - k += n; - } - return buff; - } - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - byte[] buff = new byte[4096]; - int i; - while ((i = zis.read(buff)) != -1) { - bos.write(buff, 0, i); - } - return bos.toByteArray(); - } - - /* - * (non-Javadoc) - * @see java.util.Observer#update(java.util.Observable, java.lang.Object) - */ - protected void update(final Object arg, final int n) { - if (arg instanceof Throwable) { - ((Throwable) arg).printStackTrace(); - } else { - if (n % 100 == 0) { - System.err.println(n + " " + arg); - } - } - } - - public static void main(final String[] args) throws Exception { - if (args.length < 2) { - showUsage(); - return; - } - - int inRepresentation = getRepresentation(args[0]); - int outRepresentation = getRepresentation(args[1]); - - InputStream is = System.in; - OutputStream os = new BufferedOutputStream(System.out); - - Source xslt = null; - // boolean computeMax = true; - - for (int i = 2; i < args.length; i++) { - if ("-in".equals(args[i])) { - is = new FileInputStream(args[++i]); - - } else if ("-out".equals(args[i])) { - os = new BufferedOutputStream(new FileOutputStream(args[++i])); - - } else if ("-xslt".equals(args[i])) { - xslt = new StreamSource(new FileInputStream(args[++i])); - - // } else if( "-computemax".equals( args[ i].toLowerCase())) { - // computeMax = true; - - } else { - showUsage(); - return; - - } - } - - if (inRepresentation == 0 || outRepresentation == 0) { - showUsage(); - return; - } - - Processor m = new Processor(inRepresentation, outRepresentation, is, os, xslt); - - long l1 = System.currentTimeMillis(); - int n = m.process(); - long l2 = System.currentTimeMillis(); - System.err.println(n); - System.err.println(l2 - l1 + "ms " + 1000f * n / (l2 - l1) + " resources/sec"); - } - - private static int getRepresentation(final String s) { - if ("code".equals(s)) { - return BYTECODE; - } else if ("xml".equals(s)) { - return MULTI_XML; - } else if ("singlexml".equals(s)) { - return SINGLE_XML; - } - return 0; - } - - private static void showUsage() { - System.err - .println("Usage: Main [-in ] [-out ] [-xslt ]"); - System.err.println(" when -in or -out is omitted sysin and sysout would be used"); - System.err.println(" and - code | xml | singlexml"); - } - - /** - * IputStream wrapper class used to protect input streams from being closed - * by some stupid XML parsers. - */ - private static final class ProtectedInputStream extends InputStream { - private final InputStream is; - - private ProtectedInputStream(final InputStream is) { - this.is = is; - } - - @Override - public final void close() throws IOException { - } - - @Override - public final int read() throws IOException { - return is.read(); - } - - @Override - public final int read(final byte[] b, final int off, final int len) throws IOException { - return is.read(b, off, len); - } - - @Override - public final int available() throws IOException { - return is.available(); - } - } - - /** - * A {@link ContentHandlerFactory ContentHandlerFactory} is used to create - * {@link org.xml.sax.ContentHandler ContentHandler} instances for concrete - * context. - */ - private static interface ContentHandlerFactory { - - /** - * Creates an instance of the content handler. - * - * @return content handler - */ - ContentHandler createContentHandler(); - - } - - /** - * SAXWriterFactory - */ - private static final class SAXWriterFactory implements ContentHandlerFactory { - private final Writer w; - - private final boolean optimizeEmptyElements; - - private SAXWriterFactory(final Writer w, final boolean optimizeEmptyElements) { - this.w = w; - this.optimizeEmptyElements = optimizeEmptyElements; - } - - public final ContentHandler createContentHandler() { - return new SAXWriter(w, optimizeEmptyElements); - } - - } - - /** - * ASMContentHandlerFactory - */ - private static final class ASMContentHandlerFactory implements ContentHandlerFactory { - private OutputStream os; - - private final boolean computeMax; - - private ASMContentHandlerFactory(final OutputStream os, final boolean computeMax) { - this.os = os; - this.computeMax = computeMax; - } - - public final ContentHandler createContentHandler() { - return new ASMContentHandler(os, computeMax); - } - - } - - /** - * TransformerHandlerFactory - */ - private static final class TransformerHandlerFactory implements ContentHandlerFactory { - private SAXTransformerFactory saxtf; - - private final Templates templates; - - private ContentHandler outputHandler; - - private TransformerHandlerFactory(final SAXTransformerFactory saxtf, final Templates templates, - final ContentHandler outputHandler) { - this.saxtf = saxtf; - this.templates = templates; - this.outputHandler = outputHandler; - } - - public final ContentHandler createContentHandler() { - try { - TransformerHandler handler = saxtf.newTransformerHandler(templates); - handler.setResult(new SAXResult(outputHandler)); - return handler; - } catch (TransformerConfigurationException ex) { - throw new RuntimeException(ex.toString()); - } - } - } - - /** - * SubdocumentHandlerFactory - */ - private static final class SubdocumentHandlerFactory implements ContentHandlerFactory { - private final ContentHandler subdocumentHandler; - - private SubdocumentHandlerFactory(final ContentHandler subdocumentHandler) { - this.subdocumentHandler = subdocumentHandler; - } - - public final ContentHandler createContentHandler() { - return subdocumentHandler; - } - - } - - /** - * A {@link org.xml.sax.ContentHandler ContentHandler} and - * {@link org.xml.sax.ext.LexicalHandler LexicalHandler} that serializes XML - * from SAX 2.0 events into {@link java.io.Writer Writer}.
- * This implementation does not support namespaces, entity definitions - * (uncluding DTD), CDATA and text elements.
- */ - private static final class SAXWriter extends DefaultHandler implements LexicalHandler { - private static final char[] OFF = " " - .toCharArray(); - - private Writer w; - - private final boolean optimizeEmptyElements; - - private boolean openElement = false; - - private int ident = 0; - - /** - * Creates SAXWriter. - * - * @param w writer - * @param optimizeEmptyElements if set to true, short XML - * syntax will be used for empty elements - */ - private SAXWriter(final Writer w, final boolean optimizeEmptyElements) { - this.w = w; - this.optimizeEmptyElements = optimizeEmptyElements; - } - - @Override - public final void startElement(final String ns, final String localName, final String qName, - final Attributes atts) throws SAXException { - try { - closeElement(); - - writeIdent(); - w.write('<' + qName); - if (atts != null && atts.getLength() > 0) { - writeAttributes(atts); - } - - if (optimizeEmptyElements) { - openElement = true; - } else { - w.write(">\n"); - } - ident += 2; - - } catch (IOException ex) { - throw new SAXException(ex); - - } - } - - @Override - public final void endElement(final String ns, final String localName, final String qName) throws SAXException { - ident -= 2; - try { - if (openElement) { - w.write("/>\n"); - openElement = false; - } else { - writeIdent(); - w.write("\n"); - } - - } catch (IOException ex) { - throw new SAXException(ex); - - } - } - - @Override - public final void endDocument() throws SAXException { - try { - w.flush(); - - } catch (IOException ex) { - throw new SAXException(ex); - - } - } - - public final void comment(final char[] ch, final int off, final int len) throws SAXException { - try { - closeElement(); - - writeIdent(); - w.write("\n"); - - } catch (IOException ex) { - throw new SAXException(ex); - - } - } - - public final void startDTD(final String arg0, final String arg1, final String arg2) throws SAXException { - } - - public final void endDTD() throws SAXException { - } - - public final void startEntity(final String arg0) throws SAXException { - } - - public final void endEntity(final String arg0) throws SAXException { - } - - public final void startCDATA() throws SAXException { - } - - public final void endCDATA() throws SAXException { - } - - private final void writeAttributes(final Attributes atts) throws IOException { - StringBuilder sb = new StringBuilder(); - int len = atts.getLength(); - for (int i = 0; i < len; i++) { - sb.append(' ').append(atts.getLocalName(i)).append("=\"").append(esc(atts.getValue(i))).append('\"'); - } - w.write(sb.toString()); - } - - /** - * Encode string with escaping. - * - * @param str string to encode. - * @return encoded string - */ - private static final String esc(final String str) { - StringBuilder sb = new StringBuilder(str.length()); - for (int i = 0; i < str.length(); i++) { - char ch = str.charAt(i); - switch (ch) { - case '&': - sb.append("&"); - break; - - case '<': - sb.append("<"); - break; - - case '>': - sb.append(">"); - break; - - case '\"': - sb.append("""); - break; - - default: - if (ch > 0x7f) { - sb.append("&#").append(Integer.toString(ch)).append(';'); - } else { - sb.append(ch); - } - - } - } - return sb.toString(); - } - - private final void writeIdent() throws IOException { - int n = ident; - while (n > 0) { - if (n > OFF.length) { - w.write(OFF); - n -= OFF.length; - } else { - w.write(OFF, 0, n); - n = 0; - } - } - } - - private final void closeElement() throws IOException { - if (openElement) { - w.write(">\n"); - } - openElement = false; - } - - } - - /** - * A {@link org.xml.sax.ContentHandler ContentHandler} that splits XML - * documents into smaller chunks. Each chunk is processed by the nested - * {@link org.xml.sax.ContentHandler ContentHandler} obtained from - * {@link java.net.ContentHandlerFactory ContentHandlerFactory}. This is - * useful for running XSLT engine against large XML document that will - * hardly fit into the memory all together. - *

- * TODO use complete path for subdocumentRoot - */ - private static final class InputSlicingHandler extends DefaultHandler { - private String subdocumentRoot; - - private final ContentHandler rootHandler; - - private ContentHandlerFactory subdocumentHandlerFactory; - - private boolean subdocument = false; - - private ContentHandler subdocumentHandler; - - /** - * Constructs a new {@link InputSlicingHandler SubdocumentHandler} - * object. - * - * @param subdocumentRoot name/path to the root element of the - * subdocument - * @param rootHandler content handler for the entire document - * (subdocument envelope). - * @param subdocumentHandlerFactory a {@link ContentHandlerFactory - * ContentHandlerFactory} used to create - * {@link ContentHandler ContentHandler} instances for - * subdocuments. - */ - private InputSlicingHandler(final String subdocumentRoot, final ContentHandler rootHandler, - final ContentHandlerFactory subdocumentHandlerFactory) { - this.subdocumentRoot = subdocumentRoot; - this.rootHandler = rootHandler; - this.subdocumentHandlerFactory = subdocumentHandlerFactory; - } - - @Override - public final void startElement(final String namespaceURI, final String localName, final String qName, - final Attributes list) throws SAXException { - if (subdocument) { - subdocumentHandler.startElement(namespaceURI, localName, qName, list); - } else if (localName.equals(subdocumentRoot)) { - subdocumentHandler = subdocumentHandlerFactory.createContentHandler(); - subdocumentHandler.startDocument(); - subdocumentHandler.startElement(namespaceURI, localName, qName, list); - subdocument = true; - } else if (rootHandler != null) { - rootHandler.startElement(namespaceURI, localName, qName, list); - } - } - - @Override - public final void endElement(final String namespaceURI, final String localName, final String qName) - throws SAXException { - if (subdocument) { - subdocumentHandler.endElement(namespaceURI, localName, qName); - if (localName.equals(subdocumentRoot)) { - subdocumentHandler.endDocument(); - subdocument = false; - } - } else if (rootHandler != null) { - rootHandler.endElement(namespaceURI, localName, qName); - } - } - - @Override - public final void startDocument() throws SAXException { - if (rootHandler != null) { - rootHandler.startDocument(); - } - } - - @Override - public final void endDocument() throws SAXException { - if (rootHandler != null) { - rootHandler.endDocument(); - - } - } - - @Override - public final void characters(final char[] buff, final int offset, final int size) throws SAXException { - if (subdocument) { - subdocumentHandler.characters(buff, offset, size); - } else if (rootHandler != null) { - rootHandler.characters(buff, offset, size); - } - } - - } - - /** - * A {@link org.xml.sax.ContentHandler ContentHandler} that splits XML - * documents into smaller chunks. Each chunk is processed by the nested - * {@link org.xml.sax.ContentHandler ContentHandler} obtained from - * {@link java.net.ContentHandlerFactory ContentHandlerFactory}. This is - * useful for running XSLT engine against large XML document that will - * hardly fit into the memory all together. - *

- * TODO use complete path for subdocumentRoot - */ - private static final class OutputSlicingHandler extends DefaultHandler { - private final String subdocumentRoot; - - private ContentHandlerFactory subdocumentHandlerFactory; - - private final EntryElement entryElement; - - private boolean isXml; - - private boolean subdocument = false; - - private ContentHandler subdocumentHandler; - - /** - * Constructs a new {@link OutputSlicingHandler SubdocumentHandler} - * object. - * - * @param subdocumentHandlerFactory a {@link ContentHandlerFactory - * ContentHandlerFactory} used to create - * {@link ContentHandler ContentHandler} instances for - * subdocuments. - * @param entryElement TODO. - * @param isXml TODO. - */ - private OutputSlicingHandler(final ContentHandlerFactory subdocumentHandlerFactory, - final EntryElement entryElement, final boolean isXml) { - this.subdocumentRoot = "class"; - this.subdocumentHandlerFactory = subdocumentHandlerFactory; - this.entryElement = entryElement; - this.isXml = isXml; - } - - @Override - public final void startElement(final String namespaceURI, final String localName, final String qName, - final Attributes list) throws SAXException { - if (subdocument) { - subdocumentHandler.startElement(namespaceURI, localName, qName, list); - } else if (localName.equals(subdocumentRoot)) { - String name = list.getValue("name"); - if (name == null || name.length() == 0) { - throw new SAXException("Class element without name attribute."); - } - try { - entryElement.openEntry(isXml ? name + ".class.xml" : name + ".class"); - } catch (IOException ex) { - throw new SAXException(ex.toString(), ex); - } - subdocumentHandler = subdocumentHandlerFactory.createContentHandler(); - subdocumentHandler.startDocument(); - subdocumentHandler.startElement(namespaceURI, localName, qName, list); - subdocument = true; - } - } - - @Override - public final void endElement(final String namespaceURI, final String localName, final String qName) - throws SAXException { - if (subdocument) { - subdocumentHandler.endElement(namespaceURI, localName, qName); - if (localName.equals(subdocumentRoot)) { - subdocumentHandler.endDocument(); - subdocument = false; - try { - entryElement.closeEntry(); - } catch (IOException ex) { - throw new SAXException(ex.toString(), ex); - } - } - } - } - - @Override - public final void startDocument() throws SAXException { - } - - @Override - public final void endDocument() throws SAXException { - } - - @Override - public final void characters(final char[] buff, final int offset, final int size) throws SAXException { - if (subdocument) { - subdocumentHandler.characters(buff, offset, size); - } - } - - } - - private static interface EntryElement { - - OutputStream openEntry(String name) throws IOException; - - void closeEntry() throws IOException; - - } - - private static final class SingleDocElement implements EntryElement { - private final OutputStream os; - - private SingleDocElement(final OutputStream os) { - this.os = os; - } - - public OutputStream openEntry(final String name) throws IOException { - return os; - } - - public void closeEntry() throws IOException { - os.flush(); - } - - } - - private static final class ZipEntryElement implements EntryElement { - private ZipOutputStream zos; - - private ZipEntryElement(final ZipOutputStream zos) { - this.zos = zos; - } - - public OutputStream openEntry(final String name) throws IOException { - ZipEntry entry = new ZipEntry(name); - zos.putNextEntry(entry); - return zos; - } - - public void closeEntry() throws IOException { - zos.flush(); - zos.closeEntry(); - } - - } - -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXAdapter.java deleted file mode 100644 index 880967c8c..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXAdapter.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM XML Adapter - * Copyright (c) 2004, Eugene Kuleshov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.xml; - -import org.xml.sax.Attributes; -import org.xml.sax.ContentHandler; -import org.xml.sax.SAXException; - -import com.alibaba.citrus.asm.Attribute; - -/** - * SAXAdapter - * - * @author Eugene Kuleshov - */ -public abstract class SAXAdapter { - - private final ContentHandler h; - - protected SAXAdapter(final ContentHandler h) { - this.h = h; - } - - protected ContentHandler getContentHandler() { - return h; - } - - protected void addDocumentStart() { - try { - h.startDocument(); - } catch (SAXException ex) { - throw new RuntimeException(ex.getException()); - } - } - - protected void addDocumentEnd() { - try { - h.endDocument(); - } catch (SAXException ex) { - throw new RuntimeException(ex.toString()); - } - } - - protected final void addStart(final String name, final Attributes attrs) { - try { - h.startElement("", name, name, attrs); - } catch (SAXException ex) { - throw new RuntimeException(ex.toString()); - } - } - - protected final void addEnd(final String name) { - try { - h.endElement("", name, name); - } catch (SAXException ex) { - throw new RuntimeException(ex.toString()); - } - } - - protected final void addElement(final String name, final Attributes attrs) { - addStart(name, attrs); - addEnd(name); - } - - public void visitAttribute(final Attribute attr) { - // nothing to do - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXAnnotationAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXAnnotationAdapter.java deleted file mode 100644 index 736b1e0bb..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXAnnotationAdapter.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM XML Adapter - * Copyright (c) 2004, Eugene Kuleshov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.xml; - -import org.xml.sax.ContentHandler; -import org.xml.sax.helpers.AttributesImpl; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Type; - -/** - * SAXAnnotationAdapter - * - * @author Eugene Kuleshov - */ -public class SAXAnnotationAdapter extends SAXAdapter implements AnnotationVisitor { - private final String elementName; - - public SAXAnnotationAdapter(final ContentHandler h, final String elementName, final int visible, final String name, - final String desc) { - this(h, elementName, visible, desc, name, -1); - } - - public SAXAnnotationAdapter(final ContentHandler h, final String elementName, final int visible, - final int parameter, final String desc) { - this(h, elementName, visible, desc, null, parameter); - } - - private SAXAnnotationAdapter(final ContentHandler h, final String elementName, final int visible, - final String desc, final String name, final int parameter) { - super(h); - this.elementName = elementName; - - AttributesImpl att = new AttributesImpl(); - if (name != null) { - att.addAttribute("", "name", "name", "", name); - } - if (visible != 0) { - att.addAttribute("", "visible", "visible", "", visible > 0 ? "true" : "false"); - } - if (parameter != -1) { - att.addAttribute("", "parameter", "parameter", "", Integer.toString(parameter)); - } - if (desc != null) { - att.addAttribute("", "desc", "desc", "", desc); - } - - addStart(elementName, att); - } - - public void visit(final String name, final Object value) { - Class c = value.getClass(); - if (c.isArray()) { - AnnotationVisitor av = visitArray(name); - if (value instanceof byte[]) { - byte[] b = (byte[]) value; - for (byte element : b) { - av.visit(null, new Byte(element)); - } - - } else if (value instanceof char[]) { - char[] b = (char[]) value; - for (char element : b) { - av.visit(null, new Character(element)); - } - - } else if (value instanceof short[]) { - short[] b = (short[]) value; - for (short element : b) { - av.visit(null, new Short(element)); - } - - } else if (value instanceof boolean[]) { - boolean[] b = (boolean[]) value; - for (boolean element : b) { - av.visit(null, Boolean.valueOf(element)); - } - - } else if (value instanceof int[]) { - int[] b = (int[]) value; - for (int element : b) { - av.visit(null, new Integer(element)); - } - - } else if (value instanceof long[]) { - long[] b = (long[]) value; - for (long element : b) { - av.visit(null, new Long(element)); - } - - } else if (value instanceof float[]) { - float[] b = (float[]) value; - for (float element : b) { - av.visit(null, new Float(element)); - } - - } else if (value instanceof double[]) { - double[] b = (double[]) value; - for (double element : b) { - av.visit(null, new Double(element)); - } - - } - av.visitEnd(); - } else { - addValueElement("annotationValue", name, Type.getDescriptor(c), value.toString()); - } - } - - public void visitEnum(final String name, final String desc, final String value) { - addValueElement("annotationValueEnum", name, desc, value); - } - - public AnnotationVisitor visitAnnotation(final String name, final String desc) { - return new SAXAnnotationAdapter(getContentHandler(), "annotationValueAnnotation", 0, name, desc); - } - - public AnnotationVisitor visitArray(final String name) { - return new SAXAnnotationAdapter(getContentHandler(), "annotationValueArray", 0, name, null); - } - - public void visitEnd() { - addEnd(elementName); - } - - private void addValueElement(final String element, final String name, final String desc, final String value) { - AttributesImpl att = new AttributesImpl(); - if (name != null) { - att.addAttribute("", "name", "name", "", name); - } - if (desc != null) { - att.addAttribute("", "desc", "desc", "", desc); - } - if (value != null) { - att.addAttribute("", "value", "value", "", SAXClassAdapter.encode(value)); - } - - addElement(element, att); - } - -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXClassAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXClassAdapter.java deleted file mode 100644 index e7d21cb7e..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXClassAdapter.java +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM XML Adapter - * Copyright (c) 2004, Eugene Kuleshov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.xml; - -import org.xml.sax.ContentHandler; -import org.xml.sax.helpers.AttributesImpl; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * A {@link com.alibaba.citrus.asm.ClassVisitor ClassVisitor} that generates SAX - * 2.0 events from the visited class. It can feed any kind of - * {@link org.xml.sax.ContentHandler ContentHandler}, e.g. XML serializer, XSLT - * or XQuery engines. - * - * @see com.alibaba.citrus.asm.xml.Processor - * @see com.alibaba.citrus.asm.xml.ASMContentHandler - * @author Eugene Kuleshov - */ -public final class SAXClassAdapter extends SAXAdapter implements ClassVisitor { - private final boolean singleDocument; - - /** - * Pseudo access flag used to distinguish class access flags. - */ - private static final int ACCESS_CLASS = 262144; - - /** - * Pseudo access flag used to distinguish field access flags. - */ - private static final int ACCESS_FIELD = 524288; - - /** - * Pseudo access flag used to distinguish inner class flags. - */ - private static final int ACCESS_INNER = 1048576; - - /** - * Constructs a new {@link SAXClassAdapter SAXClassAdapter} object. - * - * @param h content handler that will be used to send SAX 2.0 events. - * @param singleDocument if true adapter will not produce - * {@link ContentHandler#startDocument() startDocument()} and - * {@link ContentHandler#endDocument() endDocument()} events. - */ - public SAXClassAdapter(final ContentHandler h, boolean singleDocument) { - super(h); - this.singleDocument = singleDocument; - if (!singleDocument) { - addDocumentStart(); - } - } - - public void visitSource(final String source, final String debug) { - AttributesImpl att = new AttributesImpl(); - if (source != null) { - att.addAttribute("", "file", "file", "", encode(source)); - } - if (debug != null) { - att.addAttribute("", "debug", "debug", "", encode(debug)); - } - - addElement("source", att); - } - - public void visitOuterClass(final String owner, final String name, final String desc) { - AttributesImpl att = new AttributesImpl(); - att.addAttribute("", "owner", "owner", "", owner); - if (name != null) { - att.addAttribute("", "name", "name", "", name); - } - if (desc != null) { - att.addAttribute("", "desc", "desc", "", desc); - } - - addElement("outerclass", att); - } - - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - return new SAXAnnotationAdapter(getContentHandler(), "annotation", visible ? 1 : -1, null, desc); - } - - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - StringBuilder sb = new StringBuilder(); - appendAccess(access | ACCESS_CLASS, sb); - - AttributesImpl att = new AttributesImpl(); - att.addAttribute("", "access", "access", "", sb.toString()); - if (name != null) { - att.addAttribute("", "name", "name", "", name); - } - if (signature != null) { - att.addAttribute("", "signature", "signature", "", encode(signature)); - } - if (superName != null) { - att.addAttribute("", "parent", "parent", "", superName); - } - att.addAttribute("", "major", "major", "", Integer.toString(version & 0xFFFF)); - att.addAttribute("", "minor", "minor", "", Integer.toString(version >>> 16)); - addStart("class", att); - - addStart("interfaces", new AttributesImpl()); - if (interfaces != null && interfaces.length > 0) { - for (String element : interfaces) { - AttributesImpl att2 = new AttributesImpl(); - att2.addAttribute("", "name", "name", "", element); - addElement("interface", att2); - } - } - addEnd("interfaces"); - } - - public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, - final Object value) { - StringBuilder sb = new StringBuilder(); - appendAccess(access | ACCESS_FIELD, sb); - - AttributesImpl att = new AttributesImpl(); - att.addAttribute("", "access", "access", "", sb.toString()); - att.addAttribute("", "name", "name", "", name); - att.addAttribute("", "desc", "desc", "", desc); - if (signature != null) { - att.addAttribute("", "signature", "signature", "", encode(signature)); - } - if (value != null) { - att.addAttribute("", "value", "value", "", encode(value.toString())); - } - - return new SAXFieldAdapter(getContentHandler(), att); - } - - public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, - final String[] exceptions) { - StringBuilder sb = new StringBuilder(); - appendAccess(access, sb); - - AttributesImpl att = new AttributesImpl(); - att.addAttribute("", "access", "access", "", sb.toString()); - att.addAttribute("", "name", "name", "", name); - att.addAttribute("", "desc", "desc", "", desc); - if (signature != null) { - att.addAttribute("", "signature", "signature", "", signature); - } - addStart("method", att); - - addStart("exceptions", new AttributesImpl()); - if (exceptions != null && exceptions.length > 0) { - for (String element : exceptions) { - AttributesImpl att2 = new AttributesImpl(); - att2.addAttribute("", "name", "name", "", element); - addElement("exception", att2); - } - } - addEnd("exceptions"); - - return new SAXCodeAdapter(getContentHandler(), access); - } - - public final void visitInnerClass(final String name, final String outerName, final String innerName, - final int access) { - StringBuilder sb = new StringBuilder(); - appendAccess(access | ACCESS_INNER, sb); - - AttributesImpl att = new AttributesImpl(); - att.addAttribute("", "access", "access", "", sb.toString()); - if (name != null) { - att.addAttribute("", "name", "name", "", name); - } - if (outerName != null) { - att.addAttribute("", "outerName", "outerName", "", outerName); - } - if (innerName != null) { - att.addAttribute("", "innerName", "innerName", "", innerName); - } - addElement("innerclass", att); - } - - public final void visitEnd() { - addEnd("class"); - if (!singleDocument) { - addDocumentEnd(); - } - } - - static final String encode(final String s) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (c == '\\') { - sb.append("\\\\"); - } else if (c < 0x20 || c > 0x7f) { - sb.append("\\u"); - if (c < 0x10) { - sb.append("000"); - } else if (c < 0x100) { - sb.append("00"); - } else if (c < 0x1000) { - sb.append('0'); - } - sb.append(Integer.toString(c, 16)); - } else { - sb.append(c); - } - } - return sb.toString(); - } - - static void appendAccess(final int access, final StringBuilder sb) { - if ((access & Opcodes.ACC_PUBLIC) != 0) { - sb.append("public "); - } - if ((access & Opcodes.ACC_PRIVATE) != 0) { - sb.append("private "); - } - if ((access & Opcodes.ACC_PROTECTED) != 0) { - sb.append("protected "); - } - if ((access & Opcodes.ACC_FINAL) != 0) { - sb.append("final "); - } - if ((access & Opcodes.ACC_STATIC) != 0) { - sb.append("static "); - } - if ((access & Opcodes.ACC_SUPER) != 0) { - if ((access & ACCESS_CLASS) == 0) { - sb.append("synchronized "); - } else { - sb.append("super "); - } - } - if ((access & Opcodes.ACC_VOLATILE) != 0) { - if ((access & ACCESS_FIELD) == 0) { - sb.append("bridge "); - } else { - sb.append("volatile "); - } - } - if ((access & Opcodes.ACC_TRANSIENT) != 0) { - if ((access & ACCESS_FIELD) == 0) { - sb.append("varargs "); - } else { - sb.append("transient "); - } - } - if ((access & Opcodes.ACC_NATIVE) != 0) { - sb.append("native "); - } - if ((access & Opcodes.ACC_STRICT) != 0) { - sb.append("strict "); - } - if ((access & Opcodes.ACC_INTERFACE) != 0) { - sb.append("interface "); - } - if ((access & Opcodes.ACC_ABSTRACT) != 0) { - sb.append("abstract "); - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0) { - sb.append("synthetic "); - } - if ((access & Opcodes.ACC_ANNOTATION) != 0) { - sb.append("annotation "); - } - if ((access & Opcodes.ACC_ENUM) != 0) { - sb.append("enum "); - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - sb.append("deprecated "); - } - } -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXCodeAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXCodeAdapter.java deleted file mode 100644 index 5852f27ae..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXCodeAdapter.java +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM XML Adapter - * Copyright (c) 2004, Eugene Kuleshov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.xml; - -import java.util.HashMap; -import java.util.Map; - -import org.xml.sax.ContentHandler; -import org.xml.sax.helpers.AttributesImpl; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; -import com.alibaba.citrus.asm.util.AbstractVisitor; - -/** - * A {@link MethodVisitor} that generates SAX 2.0 events from the visited - * method. - * - * @see com.alibaba.citrus.asm.xml.SAXClassAdapter - * @see com.alibaba.citrus.asm.xml.Processor - * @author Eugene Kuleshov - */ -public final class SAXCodeAdapter extends SAXAdapter implements MethodVisitor { - - static final String[] TYPES = { "top", "int", "float", "double", "long", "null", "uninitializedThis" }; - - private final Map labelNames; - - /** - * Constructs a new {@link SAXCodeAdapter SAXCodeAdapter} object. - * - * @param h content handler that will be used to send SAX 2.0 events. - */ - public SAXCodeAdapter(final ContentHandler h, final int access) { - super(h); - labelNames = new HashMap(); - - if ((access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE | Opcodes.ACC_NATIVE)) == 0) { - addStart("code", new AttributesImpl()); - } - } - - public final void visitCode() { - } - - public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, - final Object[] stack) { - AttributesImpl attrs = new AttributesImpl(); - switch (type) { - case Opcodes.F_NEW: - case Opcodes.F_FULL: - if (type == Opcodes.F_NEW) { - attrs.addAttribute("", "type", "type", "", "NEW"); - } else { - attrs.addAttribute("", "type", "type", "", "FULL"); - } - addStart("frame", attrs); - appendFrameTypes(true, nLocal, local); - appendFrameTypes(false, nStack, stack); - break; - case Opcodes.F_APPEND: - attrs.addAttribute("", "type", "type", "", "APPEND"); - addStart("frame", attrs); - appendFrameTypes(true, nLocal, local); - break; - case Opcodes.F_CHOP: - attrs.addAttribute("", "type", "type", "", "CHOP"); - attrs.addAttribute("", "count", "count", "", Integer.toString(nLocal)); - addStart("frame", attrs); - break; - case Opcodes.F_SAME: - attrs.addAttribute("", "type", "type", "", "SAME"); - addStart("frame", attrs); - break; - case Opcodes.F_SAME1: - attrs.addAttribute("", "type", "type", "", "SAME1"); - addStart("frame", attrs); - appendFrameTypes(false, 1, stack); - break; - } - addEnd("frame"); - } - - private void appendFrameTypes(final boolean local, final int n, final Object[] types) { - for (int i = 0; i < n; ++i) { - Object type = types[i]; - AttributesImpl attrs = new AttributesImpl(); - if (type instanceof String) { - attrs.addAttribute("", "type", "type", "", (String) type); - } else if (type instanceof Integer) { - attrs.addAttribute("", "type", "type", "", TYPES[((Integer) type).intValue()]); - } else { - attrs.addAttribute("", "type", "type", "", "uninitialized"); - attrs.addAttribute("", "label", "label", "", getLabel((Label) type)); - } - addElement(local ? "local" : "stack", attrs); - } - } - - public final void visitInsn(final int opcode) { - addElement(AbstractVisitor.OPCODES[opcode], new AttributesImpl()); - } - - public final void visitIntInsn(final int opcode, final int operand) { - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "value", "value", "", Integer.toString(operand)); - addElement(AbstractVisitor.OPCODES[opcode], attrs); - } - - public final void visitVarInsn(final int opcode, final int var) { - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "var", "var", "", Integer.toString(var)); - addElement(AbstractVisitor.OPCODES[opcode], attrs); - } - - public final void visitTypeInsn(final int opcode, final String type) { - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "desc", "desc", "", type); - addElement(AbstractVisitor.OPCODES[opcode], attrs); - } - - public final void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "owner", "owner", "", owner); - attrs.addAttribute("", "name", "name", "", name); - attrs.addAttribute("", "desc", "desc", "", desc); - addElement(AbstractVisitor.OPCODES[opcode], attrs); - } - - public final void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "owner", "owner", "", owner); - attrs.addAttribute("", "name", "name", "", name); - attrs.addAttribute("", "desc", "desc", "", desc); - addElement(AbstractVisitor.OPCODES[opcode], attrs); - } - - public final void visitJumpInsn(final int opcode, final Label label) { - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "label", "label", "", getLabel(label)); - addElement(AbstractVisitor.OPCODES[opcode], attrs); - } - - public final void visitLabel(final Label label) { - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "name", "name", "", getLabel(label)); - addElement("Label", attrs); - } - - public final void visitLdcInsn(final Object cst) { - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "cst", "cst", "", SAXClassAdapter.encode(cst.toString())); - attrs.addAttribute("", "desc", "desc", "", Type.getDescriptor(cst.getClass())); - addElement(AbstractVisitor.OPCODES[Opcodes.LDC], attrs); - } - - public final void visitIincInsn(final int var, final int increment) { - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "var", "var", "", Integer.toString(var)); - attrs.addAttribute("", "inc", "inc", "", Integer.toString(increment)); - addElement(AbstractVisitor.OPCODES[Opcodes.IINC], attrs); - } - - public final void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label[] labels) { - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "min", "min", "", Integer.toString(min)); - attrs.addAttribute("", "max", "max", "", Integer.toString(max)); - attrs.addAttribute("", "dflt", "dflt", "", getLabel(dflt)); - String o = AbstractVisitor.OPCODES[Opcodes.TABLESWITCH]; - addStart(o, attrs); - for (Label element : labels) { - AttributesImpl att2 = new AttributesImpl(); - att2.addAttribute("", "name", "name", "", getLabel(element)); - addElement("label", att2); - } - addEnd(o); - } - - public final void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { - AttributesImpl att = new AttributesImpl(); - att.addAttribute("", "dflt", "dflt", "", getLabel(dflt)); - String o = AbstractVisitor.OPCODES[Opcodes.LOOKUPSWITCH]; - addStart(o, att); - for (int i = 0; i < labels.length; i++) { - AttributesImpl att2 = new AttributesImpl(); - att2.addAttribute("", "name", "name", "", getLabel(labels[i])); - att2.addAttribute("", "key", "key", "", Integer.toString(keys[i])); - addElement("label", att2); - } - addEnd(o); - } - - public final void visitMultiANewArrayInsn(final String desc, final int dims) { - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "desc", "desc", "", desc); - attrs.addAttribute("", "dims", "dims", "", Integer.toString(dims)); - addElement(AbstractVisitor.OPCODES[Opcodes.MULTIANEWARRAY], attrs); - } - - public final void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type) { - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "start", "start", "", getLabel(start)); - attrs.addAttribute("", "end", "end", "", getLabel(end)); - attrs.addAttribute("", "handler", "handler", "", getLabel(handler)); - if (type != null) { - attrs.addAttribute("", "type", "type", "", type); - } - addElement("TryCatch", attrs); - } - - public final void visitMaxs(final int maxStack, final int maxLocals) { - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "maxStack", "maxStack", "", Integer.toString(maxStack)); - attrs.addAttribute("", "maxLocals", "maxLocals", "", Integer.toString(maxLocals)); - addElement("Max", attrs); - - addEnd("code"); - } - - public void visitLocalVariable(final String name, final String desc, final String signature, final Label start, - final Label end, final int index) { - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "name", "name", "", name); - attrs.addAttribute("", "desc", "desc", "", desc); - if (signature != null) { - attrs.addAttribute("", "signature", "signature", "", SAXClassAdapter.encode(signature)); - } - attrs.addAttribute("", "start", "start", "", getLabel(start)); - attrs.addAttribute("", "end", "end", "", getLabel(end)); - attrs.addAttribute("", "var", "var", "", Integer.toString(index)); - addElement("LocalVar", attrs); - } - - public final void visitLineNumber(final int line, final Label start) { - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "line", "line", "", Integer.toString(line)); - attrs.addAttribute("", "start", "start", "", getLabel(start)); - addElement("LineNumber", attrs); - } - - public AnnotationVisitor visitAnnotationDefault() { - return new SAXAnnotationAdapter(getContentHandler(), "annotationDefault", 0, null, null); - } - - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - return new SAXAnnotationAdapter(getContentHandler(), "annotation", visible ? 1 : -1, null, desc); - } - - public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc, final boolean visible) { - return new SAXAnnotationAdapter(getContentHandler(), "parameterAnnotation", visible ? 1 : -1, parameter, desc); - } - - public void visitEnd() { - addEnd("method"); - } - - private final String getLabel(final Label label) { - String name = (String) labelNames.get(label); - if (name == null) { - name = Integer.toString(labelNames.size()); - labelNames.put(label, name); - } - return name; - } - -} diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXFieldAdapter.java b/common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXFieldAdapter.java deleted file mode 100644 index 4eb106cd8..000000000 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/xml/SAXFieldAdapter.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM XML Adapter - * Copyright (c) 2004, Eugene Kuleshov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.xml; - -import org.xml.sax.Attributes; -import org.xml.sax.ContentHandler; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.FieldVisitor; - -/** - * SAXFieldAdapter - * - * @author Eugene Kuleshov - */ -public class SAXFieldAdapter extends SAXAdapter implements FieldVisitor { - - public SAXFieldAdapter(final ContentHandler h, final Attributes att) { - super(h); - addStart("field", att); - } - - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - return new SAXAnnotationAdapter(getContentHandler(), "annotation", visible ? 1 : -1, null, desc); - } - - public void visitEnd() { - addEnd("field"); - } -} diff --git a/common/asm/src/main/resources/com/alibaba/citrus/ASM_LICENSE.txt b/common/asm/src/main/resources/com/alibaba/citrus/ASM_LICENSE.txt deleted file mode 100644 index d0cd82def..000000000 --- a/common/asm/src/main/resources/com/alibaba/citrus/ASM_LICENSE.txt +++ /dev/null @@ -1,28 +0,0 @@ - - ASM: a very small and fast Java bytecode manipulation framework - Copyright (c) 2000-2005 INRIA, France Telecom - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - 3. Neither the name of the copyright holders nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - THE POSSIBILITY OF SUCH DAMAGE. diff --git a/common/asm/src/main/resources/com/alibaba/citrus/asm/attrs/package.html b/common/asm/src/main/resources/com/alibaba/citrus/asm/attrs/package.html deleted file mode 100644 index f2a8aee3e..000000000 --- a/common/asm/src/main/resources/com/alibaba/citrus/asm/attrs/package.html +++ /dev/null @@ -1,48 +0,0 @@ - - - -Provides an implementation for optional class, field and method attributes. - -

- -By default ASM strips optional attributes, in order to keep them in -the bytecode that is being readed you should pass an array of required attribute -instances to {@link com.alibaba.citrus.asm.ClassReader#accept(com.alibaba.citrus.asm.ClassVisitor, com.alibaba.citrus.asm.Attribute[], boolean) ClassReader.accept()} method. -In order to add custom attributes to the manually constructed bytecode concrete -subclasses of the {@link com.alibaba.citrus.asm.Attribute Attribute} can be passed to -the visitAttribute methods of the -{@link com.alibaba.citrus.asm.ClassVisitor ClassVisitor}, -{@link com.alibaba.citrus.asm.FieldVisitor FieldVisitor} and -{@link com.alibaba.citrus.asm.MethodVisitor MethodVisitor} interfaces. - -@since ASM 1.4.1 - - diff --git a/common/asm/src/main/resources/com/alibaba/citrus/asm/commons/package.html b/common/asm/src/main/resources/com/alibaba/citrus/asm/commons/package.html deleted file mode 100644 index 07e634e77..000000000 --- a/common/asm/src/main/resources/com/alibaba/citrus/asm/commons/package.html +++ /dev/null @@ -1,48 +0,0 @@ - - - -Provides some useful class and method adapters. The preferred way of using -these adapters is by chaining them together and to custom adapters (instead of -inheriting from them). Indeed this approach provides more combination -possibilities than inheritance. For instance, suppose you want to implement an -adapter MyAdapter than needs sorted local variables and intermediate stack map -frame values taking into account the local variables sort. By using inheritance, -this would require MyAdapter to extend AnalyzerAdapter, itself extending -LocalVariablesSorter. But AnalyzerAdapter is not a subclass of -LocalVariablesSorter, so this is not possible. On the contrary, by using -delegation, you can make LocalVariablesSorter delegate to AnalyzerAdapter, -itself delegating to MyAdapter. In this case AnalyzerAdapter computes -intermediate frames based on the output of LocalVariablesSorter, and MyAdapter -can add new locals by calling the newLocal method on LocalVariablesSorter, and -can get the stack map frame state before each instruction by reading the locals -and stack fields in AnalyzerAdapter (this requires references from MyAdapter -back to LocalVariablesSorter and AnalyzerAdapter). - \ No newline at end of file diff --git a/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/jdk1.2.2_017.txt.gz b/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/jdk1.2.2_017.txt.gz deleted file mode 100644 index 39cdf9d911f227b374c93ab1e7d59daab8c0b582..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113814 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

l 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

1Vek5D+eN)2urd*Q? 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 R7u2@S{{T6jnLV8u5CFwtkIn!9 diff --git a/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-annotations.properties b/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-annotations.properties deleted file mode 100644 index 3792448cc..000000000 --- a/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-annotations.properties +++ /dev/null @@ -1,23 +0,0 @@ -# class mappings - -com/alibaba/citrus/asm/AnnotationWriter/remove=true - -# field mappings - -com/alibaba/citrus/asm/ClassWriter.anns=- -com/alibaba/citrus/asm/ClassWriter.ianns=- - -com/alibaba/citrus/asm/FieldWriter.anns=- -com/alibaba/citrus/asm/FieldWriter.ianns=- - -com/alibaba/citrus/asm/MethodWriter.annd=- -com/alibaba/citrus/asm/MethodWriter.anns=- -com/alibaba/citrus/asm/MethodWriter.ianns=- -com/alibaba/citrus/asm/MethodWriter.panns=- -com/alibaba/citrus/asm/MethodWriter.ipanns=- - -# method mappings - -com/alibaba/citrus/asm/ClassReader.readAnnotationValue(I[CLjava/lang/String;Lcom/alibaba/citrus/asm/AnnotationVisitor;)I=- -com/alibaba/citrus/asm/ClassReader.readAnnotationValues(I[CZLcom/alibaba/citrus/asm/AnnotationVisitor;)I=- -com/alibaba/citrus/asm/ClassReader.readParameterAnnotations(I[CZLcom/alibaba/citrus/asm/MethodVisitor;)V=- diff --git a/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-frames.properties b/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-frames.properties deleted file mode 100644 index 95ff980f9..000000000 --- a/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-frames.properties +++ /dev/null @@ -1,32 +0,0 @@ -# class mappings - -com/alibaba/citrus/asm/Frame/remove=true - -# field mappings - -com/alibaba/citrus/asm/ClassWriter.typeCount=- -com/alibaba/citrus/asm/ClassWriter.typeTable=- - -com/alibaba/citrus/asm/Label.frame=- - -com/alibaba/citrus/asm/MethodWriter.frameCount=- -com/alibaba/citrus/asm/MethodWriter.stackMap=- -com/alibaba/citrus/asm/MethodWriter.previousFrameOffset=- -com/alibaba/citrus/asm/MethodWriter.previousFrame=- -com/alibaba/citrus/asm/MethodWriter.frameIndex=- -com/alibaba/citrus/asm/MethodWriter.frame=- - -# method mappings - -com/alibaba/citrus/asm/ClassReader.readFrameType([Ljava/lang/Object;II[C[Lcom/alibaba/citrus/asm/Label;)I=- - -com/alibaba/citrus/asm/ClassWriter.addType(Ljava/lang/String;)I=- -com/alibaba/citrus/asm/ClassWriter.addUninitializedType(Ljava/lang/String;I)I=- -com/alibaba/citrus/asm/ClassWriter.addType(Lcom/alibaba/citrus/asm/Item;)Lcom/alibaba/citrus/asm/Item;=- -com/alibaba/citrus/asm/ClassWriter.getMergedType(II)I=- - -com/alibaba/citrus/asm/MethodWriter.startFrame(III)V=- -com/alibaba/citrus/asm/MethodWriter.endFrame()V=- -com/alibaba/citrus/asm/MethodWriter.writeFrame()V=- -com/alibaba/citrus/asm/MethodWriter.writeFrameTypes(II)V=- -com/alibaba/citrus/asm/MethodWriter.writeFrameType(Ljava/lang/Object;)V=- diff --git a/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-resize.properties b/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-resize.properties deleted file mode 100644 index 14ca03835..000000000 --- a/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-resize.properties +++ /dev/null @@ -1,7 +0,0 @@ -# class mappings - -# field mappings - -# method mappings - -com/alibaba/citrus/asm/MethodWriter.resizeInstructions()V=- \ No newline at end of file diff --git a/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-signatures.properties b/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-signatures.properties deleted file mode 100644 index faaa13095..000000000 --- a/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-signatures.properties +++ /dev/null @@ -1,13 +0,0 @@ -# class mappings - -com/alibaba/citrus/asm/signature/SignatureReader/remove=true -com/alibaba/citrus/asm/signature/SignatureVisitor/remove=true -com/alibaba/citrus/asm/signature/SignatureWriter/remove=true - -# field mappings - -com/alibaba/citrus/asm/ClassWriter.signature=- - -com/alibaba/citrus/asm/FieldWriter.signature=- - -com/alibaba/citrus/asm/MethodWriter.signature=- diff --git a/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-writer.properties b/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-writer.properties deleted file mode 100644 index 38554e075..000000000 --- a/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink-writer.properties +++ /dev/null @@ -1,38 +0,0 @@ -# class mappings - -com/alibaba/citrus/asm/AnnotationWriter/remove=true -com/alibaba/citrus/asm/ByteVector/remove=true -com/alibaba/citrus/asm/ClassAdapter/remove=true -com/alibaba/citrus/asm/ClassWriter/remove=true -com/alibaba/citrus/asm/Edge/remove=true -com/alibaba/citrus/asm/FieldWriter/remove=true -com/alibaba/citrus/asm/Frame/remove=true -com/alibaba/citrus/asm/Handler/remove=true -com/alibaba/citrus/asm/Item/remove=true -com/alibaba/citrus/asm/MethodAdapter/remove=true -com/alibaba/citrus/asm/MethodWriter/remove=true - -# field mappings - -com/alibaba/citrus/asm/Label.position=- -com/alibaba/citrus/asm/Label.referenceCount=- -com/alibaba/citrus/asm/Label.srcAndRefPositions=- -com/alibaba/citrus/asm/Label.inputStackTop=- -com/alibaba/citrus/asm/Label.outputStackMax=- -com/alibaba/citrus/asm/Label.frame=- -com/alibaba/citrus/asm/Label.successor=- -com/alibaba/citrus/asm/Label.successors=- -com/alibaba/citrus/asm/Label.next=- - -# method mappings - -com/alibaba/citrus/asm/ClassReader.copyPool(Lcom/alibaba/citrus/asm/ClassWriter;)V=- - -com/alibaba/citrus/asm/Label.addReference(II)V=- -com/alibaba/citrus/asm/Label.put(Lcom/alibaba/citrus/asm/MethodWriter;Lcom/alibaba/citrus/asm/ByteVector;IZ)V=- -com/alibaba/citrus/asm/Label.resolve(Lcom/alibaba/citrus/asm/MethodWriter;I[B)Z=- -com/alibaba/citrus/asm/Label.getFirst()Lcom/alibaba/citrus/asm/Label;=- -com/alibaba/citrus/asm/Label.inSubroutine(J)Z=- -com/alibaba/citrus/asm/Label.inSameSubroutine(Lcom/alibaba/citrus/asm/Label;)Z=- -com/alibaba/citrus/asm/Label.addToSubroutine(JI)V=- -com/alibaba/citrus/asm/Label.visitSubroutine(Lcom/alibaba/citrus/asm/Label;JI)V=- diff --git a/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink.properties b/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink.properties deleted file mode 100644 index c104add4d..000000000 --- a/common/asm/src/main/resources/com/alibaba/citrus/asm/optimizer/shrink.properties +++ /dev/null @@ -1,282 +0,0 @@ -# class mappings - -#com/alibaba/citrus/asm/Edge=com/alibaba/citrus/asm/a -#com/alibaba/citrus/asm/Item=com/alibaba/citrus/asm/b -#com/alibaba/citrus/asm/FieldWriter=com/alibaba/citrus/asm/c -#com/alibaba/citrus/asm/MethodWriter=com/alibaba/citrus/asm/d -#com/alibaba/citrus/asm/AnnotationWriter=com/alibaba/citrus/asm/e - -# field mappings - -com/alibaba/citrus/asm/AnnotationWriter.cw=a -com/alibaba/citrus/asm/AnnotationWriter.size=b -com/alibaba/citrus/asm/AnnotationWriter.named=c -com/alibaba/citrus/asm/AnnotationWriter.bv=d -com/alibaba/citrus/asm/AnnotationWriter.parent=e -com/alibaba/citrus/asm/AnnotationWriter.offset=f -com/alibaba/citrus/asm/AnnotationWriter.next=g -com/alibaba/citrus/asm/AnnotationWriter.prev=h - -com/alibaba/citrus/asm/Attribute.next=a -com/alibaba/citrus/asm/Attribute.value=b - -com/alibaba/citrus/asm/ByteVector.data=a -com/alibaba/citrus/asm/ByteVector.length=b - -com/alibaba/citrus/asm/ClassReader.items=a -com/alibaba/citrus/asm/ClassReader.strings=c -com/alibaba/citrus/asm/ClassReader.maxStringLength=d -#com/alibaba/citrus/asm/ClassReader.header=e - -com/alibaba/citrus/asm/ClassWriter.TYPE=a -com/alibaba/citrus/asm/ClassWriter.version=b -com/alibaba/citrus/asm/ClassWriter.index=c -com/alibaba/citrus/asm/ClassWriter.pool=d -com/alibaba/citrus/asm/ClassWriter.items=e -com/alibaba/citrus/asm/ClassWriter.threshold=f -com/alibaba/citrus/asm/ClassWriter.key=g -com/alibaba/citrus/asm/ClassWriter.key2=h -com/alibaba/citrus/asm/ClassWriter.key3=i -com/alibaba/citrus/asm/ClassWriter.access=j -com/alibaba/citrus/asm/ClassWriter.name=k -com/alibaba/citrus/asm/ClassWriter.signature=l -com/alibaba/citrus/asm/ClassWriter.superName=m -com/alibaba/citrus/asm/ClassWriter.interfaceCount=n -com/alibaba/citrus/asm/ClassWriter.interfaces=o -com/alibaba/citrus/asm/ClassWriter.sourceFile=p -com/alibaba/citrus/asm/ClassWriter.sourceDebug=q -com/alibaba/citrus/asm/ClassWriter.enclosingMethodOwner=r -com/alibaba/citrus/asm/ClassWriter.enclosingMethod=s -com/alibaba/citrus/asm/ClassWriter.anns=t -com/alibaba/citrus/asm/ClassWriter.ianns=u -com/alibaba/citrus/asm/ClassWriter.attrs=v -com/alibaba/citrus/asm/ClassWriter.innerClassesCount=w -com/alibaba/citrus/asm/ClassWriter.innerClasses=x -com/alibaba/citrus/asm/ClassWriter.firstField=y -com/alibaba/citrus/asm/ClassWriter.lastField=z -com/alibaba/citrus/asm/ClassWriter.firstMethod=A -com/alibaba/citrus/asm/ClassWriter.lastMethod=B -com/alibaba/citrus/asm/ClassWriter.computeMaxs=C -com/alibaba/citrus/asm/ClassWriter.typeCount=D -com/alibaba/citrus/asm/ClassWriter.typeTable=E -com/alibaba/citrus/asm/ClassWriter.thisName=F -com/alibaba/citrus/asm/ClassWriter.computeFrames=G -com/alibaba/citrus/asm/ClassWriter.computeMaxs=H -com/alibaba/citrus/asm/ClassWriter.invalidFrames=I -com/alibaba/citrus/asm/ClassWriter.cr=J - -com/alibaba/citrus/asm/Edge.info=a -com/alibaba/citrus/asm/Edge.successor=b -com/alibaba/citrus/asm/Edge.next=c - -com/alibaba/citrus/asm/Handler.start=a -com/alibaba/citrus/asm/Handler.end=b -com/alibaba/citrus/asm/Handler.handler=c -com/alibaba/citrus/asm/Handler.desc=d -com/alibaba/citrus/asm/Handler.type=e -com/alibaba/citrus/asm/Handler.next=f - -com/alibaba/citrus/asm/FieldWriter.next=a -com/alibaba/citrus/asm/FieldWriter.cw=b -com/alibaba/citrus/asm/FieldWriter.access=c -com/alibaba/citrus/asm/FieldWriter.name=d -com/alibaba/citrus/asm/FieldWriter.desc=e -com/alibaba/citrus/asm/FieldWriter.signature=f -com/alibaba/citrus/asm/FieldWriter.value=g -com/alibaba/citrus/asm/FieldWriter.anns=h -com/alibaba/citrus/asm/FieldWriter.ianns=i -com/alibaba/citrus/asm/FieldWriter.attrs=j - -com/alibaba/citrus/asm/Item.index=a -com/alibaba/citrus/asm/Item.type=b -com/alibaba/citrus/asm/Item.intVal=c -com/alibaba/citrus/asm/Item.longVal=d -com/alibaba/citrus/asm/Item.strVal1=g -com/alibaba/citrus/asm/Item.strVal2=h -com/alibaba/citrus/asm/Item.strVal3=i -com/alibaba/citrus/asm/Item.hashCode=j -com/alibaba/citrus/asm/Item.next=k - -com/alibaba/citrus/asm/Label.status=a -com/alibaba/citrus/asm/Label.line=b -com/alibaba/citrus/asm/Label.position=c -com/alibaba/citrus/asm/Label.referenceCount=d -com/alibaba/citrus/asm/Label.srcAndRefPositions=e -com/alibaba/citrus/asm/Label.inputStackTop=f -com/alibaba/citrus/asm/Label.outputStackMax=g -com/alibaba/citrus/asm/Label.frame=h -com/alibaba/citrus/asm/Label.successor=i -com/alibaba/citrus/asm/Label.successors=j -com/alibaba/citrus/asm/Label.next=k - -com/alibaba/citrus/asm/Frame.SIZE=a -com/alibaba/citrus/asm/Frame.owner=b -com/alibaba/citrus/asm/Frame.inputLocals=c -com/alibaba/citrus/asm/Frame.inputStack=d -com/alibaba/citrus/asm/Frame.outputLocals=e -com/alibaba/citrus/asm/Frame.outputStack=f -com/alibaba/citrus/asm/Frame.outputStackTop=g -com/alibaba/citrus/asm/Frame.initializationCount=h -com/alibaba/citrus/asm/Frame.initializations=i - -com/alibaba/citrus/asm/MethodWriter.next=a -com/alibaba/citrus/asm/MethodWriter.cw=b -com/alibaba/citrus/asm/MethodWriter.access=c -com/alibaba/citrus/asm/MethodWriter.name=d -com/alibaba/citrus/asm/MethodWriter.desc=e -com/alibaba/citrus/asm/MethodWriter.descriptor=f -com/alibaba/citrus/asm/MethodWriter.signature=g -com/alibaba/citrus/asm/MethodWriter.classReaderOffset=h -com/alibaba/citrus/asm/MethodWriter.classReaderLength=i -com/alibaba/citrus/asm/MethodWriter.exceptionCount=j -com/alibaba/citrus/asm/MethodWriter.exceptions=k -com/alibaba/citrus/asm/MethodWriter.annd=l -com/alibaba/citrus/asm/MethodWriter.anns=m -com/alibaba/citrus/asm/MethodWriter.ianns=n -com/alibaba/citrus/asm/MethodWriter.panns=o -com/alibaba/citrus/asm/MethodWriter.ipanns=p -com/alibaba/citrus/asm/MethodWriter.attrs=q -com/alibaba/citrus/asm/MethodWriter.code=r -com/alibaba/citrus/asm/MethodWriter.maxStack=s -com/alibaba/citrus/asm/MethodWriter.maxLocals=t -com/alibaba/citrus/asm/MethodWriter.frameCount=u -com/alibaba/citrus/asm/MethodWriter.stackMap=v -com/alibaba/citrus/asm/MethodWriter.previousFrameOffset=w -com/alibaba/citrus/asm/MethodWriter.previousFrame=x -com/alibaba/citrus/asm/MethodWriter.frameIndex=y -com/alibaba/citrus/asm/MethodWriter.frame=z -com/alibaba/citrus/asm/MethodWriter.handlerCount=A -com/alibaba/citrus/asm/MethodWriter.firstHandler=B -com/alibaba/citrus/asm/MethodWriter.lastHandler=C -com/alibaba/citrus/asm/MethodWriter.localVarCount=D -com/alibaba/citrus/asm/MethodWriter.localVar=E -com/alibaba/citrus/asm/MethodWriter.localVarTypeCount=F -com/alibaba/citrus/asm/MethodWriter.localVarType=G -com/alibaba/citrus/asm/MethodWriter.lineNumberCount=H -com/alibaba/citrus/asm/MethodWriter.lineNumber=I -com/alibaba/citrus/asm/MethodWriter.cattrs=J -com/alibaba/citrus/asm/MethodWriter.resize=K -com/alibaba/citrus/asm/MethodWriter.subroutines=L -com/alibaba/citrus/asm/MethodWriter.compute=M -com/alibaba/citrus/asm/MethodWriter.labels=N -com/alibaba/citrus/asm/MethodWriter.previousBlock=O -com/alibaba/citrus/asm/MethodWriter.currentBlock=P -com/alibaba/citrus/asm/MethodWriter.stackSize=Q -com/alibaba/citrus/asm/MethodWriter.maxStackSize=R -com/alibaba/citrus/asm/MethodWriter.synthetics=S - -com/alibaba/citrus/asm/Type.sort=a -com/alibaba/citrus/asm/Type.buf=b -com/alibaba/citrus/asm/Type.off=c -com/alibaba/citrus/asm/Type.len=d - -com/alibaba/citrus/asm/signature/SignatureReader.signature=a - -com/alibaba/citrus/asm/signature/SignatureWriter.buf=a -com/alibaba/citrus/asm/signature/SignatureWriter.hasFormals=b -com/alibaba/citrus/asm/signature/SignatureWriter.hasParameters=c -com/alibaba/citrus/asm/signature/SignatureWriter.argumentStack=d - -# method mappings - -com/alibaba/citrus/asm/AnnotationWriter.getSize()I=a -com/alibaba/citrus/asm/AnnotationWriter.put([Lcom/alibaba/citrus/asm/AnnotationWriter;ILcom/alibaba/citrus/asm/ByteVector;)V=a -com/alibaba/citrus/asm/AnnotationWriter.put(Lcom/alibaba/citrus/asm/ByteVector;)V=a - -com/alibaba/citrus/asm/Attribute.getCount()I=a -com/alibaba/citrus/asm/Attribute.getSize(Lcom/alibaba/citrus/asm/ClassWriter;[BIII)I=a -com/alibaba/citrus/asm/Attribute.put(Lcom/alibaba/citrus/asm/ClassWriter;[BIIILcom/alibaba/citrus/asm/ByteVector;)V=a - -com/alibaba/citrus/asm/ByteVector.enlarge(I)V=a -com/alibaba/citrus/asm/ByteVector.put11(II)Lcom/alibaba/citrus/asm/ByteVector;=a -com/alibaba/citrus/asm/ByteVector.put12(II)Lcom/alibaba/citrus/asm/ByteVector;=b - -com/alibaba/citrus/asm/ClassReader.copyPool(Lcom/alibaba/citrus/asm/ClassWriter;)V=a -com/alibaba/citrus/asm/ClassReader.readAnnotationValue(I[CLjava/lang/String;Lcom/alibaba/citrus/asm/AnnotationVisitor;)I=a -com/alibaba/citrus/asm/ClassReader.readAnnotationValues(I[CZLcom/alibaba/citrus/asm/AnnotationVisitor;)I=a -com/alibaba/citrus/asm/ClassReader.readAttribute([Lcom/alibaba/citrus/asm/Attribute;Ljava/lang/String;II[CI[Lcom/alibaba/citrus/asm/Label;)Lcom/alibaba/citrus/asm/Attribute;=a -com/alibaba/citrus/asm/ClassReader.readClass(Ljava/io/InputStream;)[B=a -com/alibaba/citrus/asm/ClassReader.readParameterAnnotations(ILjava/lang/String;[CZLcom/alibaba/citrus/asm/MethodVisitor;)V=a -com/alibaba/citrus/asm/ClassReader.readUTF(II[C)Ljava/lang/String;=a -com/alibaba/citrus/asm/ClassReader.readFrameType([Ljava/lang/Object;II[C[Lcom/alibaba/citrus/asm/Label;)I=a - -com/alibaba/citrus/asm/ClassWriter.get(Lcom/alibaba/citrus/asm/Item;)Lcom/alibaba/citrus/asm/Item;=a -com/alibaba/citrus/asm/ClassWriter.newClassItem(Ljava/lang/String;)Lcom/alibaba/citrus/asm/Item;=a -com/alibaba/citrus/asm/ClassWriter.newConstItem(Ljava/lang/Object;)Lcom/alibaba/citrus/asm/Item;=a -com/alibaba/citrus/asm/ClassWriter.newDouble(D)Lcom/alibaba/citrus/asm/Item;=a -com/alibaba/citrus/asm/ClassWriter.newFloat(F)Lcom/alibaba/citrus/asm/Item;=a -com/alibaba/citrus/asm/ClassWriter.newInteger(I)Lcom/alibaba/citrus/asm/Item;=a -com/alibaba/citrus/asm/ClassWriter.newLong(J)Lcom/alibaba/citrus/asm/Item;=a -com/alibaba/citrus/asm/ClassWriter.newMethodItem(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)Lcom/alibaba/citrus/asm/Item;=a -com/alibaba/citrus/asm/ClassWriter.newString(Ljava/lang/String;)Lcom/alibaba/citrus/asm/Item;=b -com/alibaba/citrus/asm/ClassWriter.put122(III)V=a -com/alibaba/citrus/asm/ClassWriter.put(Lcom/alibaba/citrus/asm/Item;)V=b -com/alibaba/citrus/asm/ClassWriter.newFieldItem(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/alibaba/citrus/asm/Item;=a -com/alibaba/citrus/asm/ClassWriter.addType(Ljava/lang/String;)I=c -com/alibaba/citrus/asm/ClassWriter.addUninitializedType(Ljava/lang/String;I)I=a -com/alibaba/citrus/asm/ClassWriter.addType(Lcom/alibaba/citrus/asm/Item;)Lcom/alibaba/citrus/asm/Item;=c -com/alibaba/citrus/asm/ClassWriter.getMergedType(II)I=a - -com/alibaba/citrus/asm/FieldWriter.getSize()I=a -com/alibaba/citrus/asm/FieldWriter.put(Lcom/alibaba/citrus/asm/ByteVector;)V=a - -com/alibaba/citrus/asm/Item.isEqualTo(Lcom/alibaba/citrus/asm/Item;)Z=a -com/alibaba/citrus/asm/Item.set(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V=a -com/alibaba/citrus/asm/Item.set(D)V=a -com/alibaba/citrus/asm/Item.set(F)V=a -com/alibaba/citrus/asm/Item.set(I)V=a -com/alibaba/citrus/asm/Item.set(J)V=a - -com/alibaba/citrus/asm/Label.addReference(II)V=a -com/alibaba/citrus/asm/Label.put(Lcom/alibaba/citrus/asm/MethodWriter;Lcom/alibaba/citrus/asm/ByteVector;IZ)V=a -com/alibaba/citrus/asm/Label.resolve(Lcom/alibaba/citrus/asm/MethodWriter;I[B)Z=a -com/alibaba/citrus/asm/Label.getFirst()Lcom/alibaba/citrus/asm/Label;=a -com/alibaba/citrus/asm/Label.inSubroutine(J)Z=a -com/alibaba/citrus/asm/Label.inSameSubroutine(Lcom/alibaba/citrus/asm/Label;)Z=a -com/alibaba/citrus/asm/Label.addToSubroutine(JI)V=a -com/alibaba/citrus/asm/Label.visitSubroutine(Lcom/alibaba/citrus/asm/Label;JI)V=b - -com/alibaba/citrus/asm/Frame.get(I)I=a -com/alibaba/citrus/asm/Frame.set(II)V=a -com/alibaba/citrus/asm/Frame.push(I)V=b -com/alibaba/citrus/asm/Frame.push(Lcom/alibaba/citrus/asm/ClassWriter;Ljava/lang/String;)V=a -com/alibaba/citrus/asm/Frame.type(Lcom/alibaba/citrus/asm/ClassWriter;Ljava/lang/String;)I=b -com/alibaba/citrus/asm/Frame.pop()I=a -com/alibaba/citrus/asm/Frame.pop(Ljava/lang/String;)V=a -com/alibaba/citrus/asm/Frame.pop(I)V=c -com/alibaba/citrus/asm/Frame.init(I)V=d -com/alibaba/citrus/asm/Frame.init(Lcom/alibaba/citrus/asm/ClassWriter;I)I=a -com/alibaba/citrus/asm/Frame.initInputFrame(Lcom/alibaba/citrus/asm/ClassWriter;I[Lcom/alibaba/citrus/asm/Type;I)V=a -com/alibaba/citrus/asm/Frame.execute(IILcom/alibaba/citrus/asm/ClassWriter;Lcom/alibaba/citrus/asm/Item;)V=a -com/alibaba/citrus/asm/Frame.merge(Lcom/alibaba/citrus/asm/ClassWriter;Lcom/alibaba/citrus/asm/Frame;I)Z=a -com/alibaba/citrus/asm/Frame.merge(Lcom/alibaba/citrus/asm/ClassWriter;I[II)Z=a - -com/alibaba/citrus/asm/MethodWriter.visitSwitchInsn(Lcom/alibaba/citrus/asm/Label;[Lcom/alibaba/citrus/asm/Label;)V=a -com/alibaba/citrus/asm/MethodWriter.addSuccessor(ILcom/alibaba/citrus/asm/Label;)V=a -com/alibaba/citrus/asm/MethodWriter.getArgumentsAndReturnSizes(Ljava/lang/String;)I=a -com/alibaba/citrus/asm/MethodWriter.getNewOffset([I[III)I=a -com/alibaba/citrus/asm/MethodWriter.getSize()I=a -com/alibaba/citrus/asm/MethodWriter.put(Lcom/alibaba/citrus/asm/ByteVector;)V=a -com/alibaba/citrus/asm/MethodWriter.readInt([BI)I=a -com/alibaba/citrus/asm/MethodWriter.readShort([BI)S=b -com/alibaba/citrus/asm/MethodWriter.readUnsignedShort([BI)I=c -com/alibaba/citrus/asm/MethodWriter.writeShort([BII)V=a -com/alibaba/citrus/asm/MethodWriter.visitFrame(Lcom/alibaba/citrus/asm/Frame;)V=b -com/alibaba/citrus/asm/MethodWriter.startFrame(III)V=a -com/alibaba/citrus/asm/MethodWriter.endFrame()V=b -com/alibaba/citrus/asm/MethodWriter.writeFrame()V=c -com/alibaba/citrus/asm/MethodWriter.resizeInstructions()V=d -com/alibaba/citrus/asm/MethodWriter.noSuccessor()V=e -com/alibaba/citrus/asm/MethodWriter.writeFrameTypes(II)V=a -com/alibaba/citrus/asm/MethodWriter.writeFrameType(Ljava/lang/Object;)V=a -com/alibaba/citrus/asm/MethodWriter.getNewOffset([I[ILcom/alibaba/citrus/asm/Label;)V=a - -com/alibaba/citrus/asm/Type.getType([CI)Lcom/alibaba/citrus/asm/Type;=a -com/alibaba/citrus/asm/Type.getDescriptor(Ljava/lang/StringBuffer;)V=a -com/alibaba/citrus/asm/Type.getDescriptor(Ljava/lang/StringBuffer;Ljava/lang/Class;)V=a - -com/alibaba/citrus/asm/signature/SignatureReader.parseType(Ljava/lang/String;ILcom/alibaba/citrus/asm/signature/SignatureVisitor;)I=a - -com/alibaba/citrus/asm/signature/SignatureWriter.endFormals()V=a -com/alibaba/citrus/asm/signature/SignatureWriter.endArguments()V=b - \ No newline at end of file diff --git a/common/asm/src/main/resources/com/alibaba/citrus/asm/package.html b/common/asm/src/main/resources/com/alibaba/citrus/asm/package.html deleted file mode 100644 index f988ff25e..000000000 --- a/common/asm/src/main/resources/com/alibaba/citrus/asm/package.html +++ /dev/null @@ -1,87 +0,0 @@ - - - -Provides a small and fast bytecode manipulation framework. - -

-In addition to these main interfaces, ASM provides a {@link -com.alibaba.citrus.asm.ClassReader ClassReader} class, that can parse an -existing class and make a given visitor visit it. ASM also provides -a {@link com.alibaba.citrus.asm.ClassWriter ClassWriter} class, which is -a visitor that generates Java class files. - -

-In order to generate a class from scratch, only the {@link -com.alibaba.citrus.asm.ClassWriter ClassWriter} class is necessary. Indeed, -in order to generate a class, one must just call its visitXXX -methods with the appropriate arguments to generate the desired fields -and methods. See the "helloworld" example in the ASM distribution for -more details about class generation. - -

-In order to modify existing classes, one must use a {@link -com.alibaba.citrus.asm.ClassReader ClassReader} class to analyze -the original class, a class modifier, and a {@link com.alibaba.citrus.asm.ClassWriter -ClassWriter} to construct the modified class. The class modifier -is just a {@link com.alibaba.citrus.asm.ClassVisitor ClassVisitor} -that delegates most of the work to another {@link com.alibaba.citrus.asm.ClassVisitor -ClassVisitor}, but that sometimes changes some parameter values, -or call additional methods, in order to implement the desired -modification process. In order to make it easier to implement such -class modifiers, ASM provides the {@link com.alibaba.citrus.asm.ClassAdapter -ClassAdapter} and {@link com.alibaba.citrus.asm.MethodAdapter MethodAdapter} -classes, which implement the {@link com.alibaba.citrus.asm.ClassVisitor ClassVisitor} -and {@link com.alibaba.citrus.asm.MethodVisitor MethodVisitor} interfaces by -delegating all work to other visitors. See the "adapt" example in the ASM -distribution for more details about class modification. - -

-The size of the core ASM library, asm.jar, is only 42KB, which is much -smaller than the size of the -BCEL library (504KB), and than the -size of the -SERP library (150KB). ASM is also -much faster than these tools. Indeed the overhead of a load time class -transformation process is of the order of 60% with ASM, 700% or more with BCEL, -and 1100% or more with SERP (see the test/perf directory in the ASM -distribution)! - -@since ASM 1.3 - - diff --git a/common/asm/src/main/resources/com/alibaba/citrus/asm/signature/package.html b/common/asm/src/main/resources/com/alibaba/citrus/asm/signature/package.html deleted file mode 100644 index 21f103a30..000000000 --- a/common/asm/src/main/resources/com/alibaba/citrus/asm/signature/package.html +++ /dev/null @@ -1,36 +0,0 @@ - - - -Provides support for type signatures. - -@since ASM 2.0 - - diff --git a/common/asm/src/main/resources/com/alibaba/citrus/asm/tree/analysis/package.html b/common/asm/src/main/resources/com/alibaba/citrus/asm/tree/analysis/package.html deleted file mode 100644 index 3c693483b..000000000 --- a/common/asm/src/main/resources/com/alibaba/citrus/asm/tree/analysis/package.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - -

-Provides a framework for static code analysis based on the asm.tree package. -

- -

-Basic usage: -

- -
-ClassReader cr = new ClassReader(bytecode);
-ClassNode cn = new ClassNode();
-cr.accept(cn, ClassReader.SKIP_DEBUG);
-
-List methods = cn.methods;
-for (int i = 0; i < methods.size(); ++i) {
-    MethodNode method = (MethodNode) methods.get(i);
-    if (method.instructions.size() > 0) {
-        Analyzer a = new Analyzer(new BasicInterpreter());
-        a.analyze(cn.name, method);
-        Frame[] frames = a.getFrames();
-        // Elements of the frames arrray now contains info for each instruction 
-        // from the analyzed method. BasicInterpreter creates BasicValue, that
-        // is using simplified type system that distinguishes the UNINITIALZED, 
-        // INT, FLOAT, LONG, DOUBLE, REFERENCE and RETURNADDRESS types.
-        ...
-    }
-}   
-
- -

-@since ASM 1.4.3 -

- - - diff --git a/common/asm/src/main/resources/com/alibaba/citrus/asm/tree/package.html b/common/asm/src/main/resources/com/alibaba/citrus/asm/tree/package.html deleted file mode 100644 index db6864535..000000000 --- a/common/asm/src/main/resources/com/alibaba/citrus/asm/tree/package.html +++ /dev/null @@ -1,192 +0,0 @@ - - - - -

-Provides an ASM visitor that constructs a tree representation of the -classes it visits. This class adapter can be useful to implement "complex" -class manipulation operations, i.e., operations that would be very hard to -implement without using a tree representation (such as optimizing the number -of local variables used by a method). -

- -

-However, this class adapter has a cost: it makes ASM bigger and slower. Indeed -it requires more than twenty new classes, and multiplies the time needed to -transform a class by almost two (it is almost two times faster to read, "modify" -and write a class with a ClassAdapter than with a ClassNode). This is why -this package is bundled in an optional asm-tree.jar library that -is separated from (but requires) the asm.jar library, which contains -the core ASM framework. This is also why it is recommended -not to use this class adapter when it is possible. -

- -

-The root class is the ClassNode, that can be created from existing bytecode. For example: -

- -
-  ClassReader cr = new ClassReader(source);
-  ClassNode cn = new ClassNode();
-  cr.accept(cn, true);
-
- -

-Now content of ClassNode can be modified and then -serialized back into bytecode: -

- -
-  ClassWriter cw = new ClassWriter(true);
-  cn.accept(cw);
-
- -

-Using simple ClassAdapter it is possible to create MethodNode instances per-method. -In this example MethodNode is acting as a buffer that is flushed out at visitEnd() call: -

- -
-  ClassReader cr = new ClassReader(source);
-  ClassWriter cw = new ClassWriter();
-  ClassAdapter ca = new ClassAdapter(cw) {
-      public MethodVisitor visitMethod(int access, String name, 
-          String desc, String signature, String[] exceptions) {
-        final MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
-        MethodNode mn = new MethodNode(access, name, desc, signature, exceptions) {
-            public void visitEnd() {
-              // transform or analyze method code using tree API
-              accept(mv);
-            }
-          };
-      }
-    };
-  cr.accept(ca, true);
-
- -

-Several strategies can be used to construct method code from scratch. The first -option is to create a MethodNode, and then create XXXInsnNode instances and -add them to the instructions list: -

- -
-MethodNode m = new MethodNode(...);
-m.instructions.add(new VarInsnNode(ALOAD, 0));
-...
-
- -

-Alternatively, you can use the fact that MethodNode is a MethodVisitor, and use -that to create the XXXInsnNode and add them to the instructions list through -the standard MethodVisitor interface: -

- -
-MethodNode m = new MethodNode(...);
-m.visitVarInsn(ALOAD, 0);
-...
-
- -

-If you cannot generate all the instructions in sequential order, i.e. if you -need to save some pointer in the instruction list and then insert instructions -at that place after other instructions have been generated, you can use InsnList -methods insert() and insertBefore() to insert instructions at saved pointer. -

- -
-MethodNode m = new MethodNode(...);
-m.visitVarInsn(ALOAD, 0);
-AbstractInsnNode ptr = m.instructions.getLast();
-m.visitVarInsn(ALOAD, 1);
-// inserts an instruction between ALOAD 0 and ALOAD 1
-m.instructions.insert(ptr, new VarInsnNode(ALOAD, 0));
-...
-
- -

-If you need to insert instructions while iterating over an existing instruction -list, you can also use several strategies. The first one is to use a -ListIterator over the instruction list: -

- -
-ListIterator it = m.instructions.iterator();
-while (it.hasNext()) {
-    AbstractInsnNode n = (AbstractInsnNode) it.next();
-    if (...) {
-        it.add(new VarInsnNode(ALOAD, 0));
-    }
-}
-
- -

-It is also possible to convert instruction list into the array and iterate trough -array elements: -

- -
-AbstractInsnNode[] insns = m.instructions.toArray();
-for(int i = 0; i<insns.length; i++) {
-    AbstractInsnNode n = insns[i];
-    if (...) {
-        m.instructions.insert(n, new VarInsnNode(ALOAD, 0));
-    }
-}
-
- -

-If you want to insert these instructions through the MethodVisitor interface, -you can use another instance of MethodNode as a MethodVisitor and then -insert instructions collected by that instance into the instruction list. -For example: -

- -
-AbstractInsnNode[] insns = m.instructions.toArray();
-for(int i = 0; i<insns.length; i++) {
-    AbstractInsnNode n = insns[i];
-    if (...) {
-        MethodNode mn = new MethodNode();
-        mn.visitVarInsn(ALOAD, 0);
-        mn.visitVarInsn(ALOAD, 1);
-        m.instructions.insert(n, mn.instructions);
-    }
-}
-
- -

-@since ASM 1.3.3 -

- - - diff --git a/common/asm/src/main/resources/com/alibaba/citrus/asm/util/package.html b/common/asm/src/main/resources/com/alibaba/citrus/asm/util/package.html deleted file mode 100644 index e967b8b10..000000000 --- a/common/asm/src/main/resources/com/alibaba/citrus/asm/util/package.html +++ /dev/null @@ -1,40 +0,0 @@ - - - -Provides ASM visitors that can be useful for programming and -debugging purposes. These class visitors are normally not used by applications -at runtime. This is why they are bundled in an optional asm-util.jar -library that is separated from (but requires) the asm.jar library, -which contains the core ASM framework. - -@since ASM 1.3.2 - - diff --git a/common/asm/src/main/resources/com/alibaba/citrus/asm/xml/asm-xml.dtd b/common/asm/src/main/resources/com/alibaba/citrus/asm/xml/asm-xml.dtd deleted file mode 100644 index c1bd7ef7a..000000000 --- a/common/asm/src/main/resources/com/alibaba/citrus/asm/xml/asm-xml.dtd +++ /dev/null @@ -1,340 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/common/asm/src/main/resources/com/alibaba/citrus/asm/xml/package.html b/common/asm/src/main/resources/com/alibaba/citrus/asm/xml/package.html deleted file mode 100644 index 1557781d6..000000000 --- a/common/asm/src/main/resources/com/alibaba/citrus/asm/xml/package.html +++ /dev/null @@ -1,96 +0,0 @@ - - - -Provides SAX 2.0 adapters for ASM -visitors to convert classes to and from XML. -These adapters can be chained with other SAX compliant content handlers and -filters, eg. XSLT or XQuery engines. This package is bundled as -a separate asm-xml.jar library and requires asm.jar. -

-ASMContentHandler and SAXClassAdapter/SAXCodeAdapter -are using asm-xml.dtd. -Here is the example of bytecode to bytecode XSLT transformation. - -

-    SAXTransformerFactory saxtf = ( SAXTransformerFactory) TransformerFactory.newInstance();
-    Templates templates = saxtf.newTemplates( xsltSource);
-
-    TransformerHandler handler = saxtf.newTransformerHandler( templates);
-    handler.setResult( new SAXResult( new ASMContentHandler( outputStream, computeMax)));
-
-    ClassReader cr = new ClassReader( bytecode);
-    cr.accept( new SAXClassAdapter( handler, cr.getVersion(), false), false);
-
- -See JAXP and SAX documentation for more detils. - -

-There are few illustrations of the bytecode transformation with XSLT in -examples directory. The following XSLT procesors has been tested. - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Enginejavax.xml.transform.TransformerFactory property
jd.xsltjd.xml.xslt.trax.TransformerFactoryImpl
Saxonnet.sf.saxon.TransformerFactoryImpl
Cauchocom.caucho.xsl.Xsl
Xalan interpeterorg.apache.xalan.processor.TransformerFactory
Xalan xsltcorg.apache.xalan.xsltc.trax.TransformerFactoryImpl
-
- -@since ASM 1.4.3 - - - diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/AbstractTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/AbstractTest.java deleted file mode 100644 index b0f62be69..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/AbstractTest.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -import java.io.File; -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.net.URL; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.util.TraceClassVisitor; - -/** - * Super class for test suites based on a jar file. - * - * @author Eugene Kuleshov - * @author Eric Bruneton - */ -public abstract class AbstractTest extends TestCase { - - protected String n; - - private URL url; - - public AbstractTest() { - super("test"); - } - - protected void init(final String n, final URL url) { - this.n = n; - this.url = url; - } - - protected InputStream openStream() { - try { - return url.openStream(); - } catch (Exception e) { - throw new RuntimeException("Failed to open: " + url); - } - } - - protected TestSuite getSuite() throws Exception { - return getSuite(new AsmTestParams()); - } - - protected TestSuite getSuite(AsmTestParams params) throws Exception { - String suiteName = getClass().getName(); - if (params.getParts() > 1) { - suiteName += "-" + params.getPart(); - } - System.out.println("Creating suite: " + suiteName); - TestSuite suite = new TestSuite(suiteName); - File[] files = params.getFiles(); - String clazz = params.getInclude(); - String excludeClazz = params.getExclude(); - int parts = params.getParts(); - int part = params.getPart(); - int maxCount = params.getMaxCount(); - int id = 0; - for (File f : files) { - if (f.isDirectory()) { - scanDirectory("", f, suite, clazz, excludeClazz); - } else { - String baseurl = "jar:" + f.toURI().toURL().toExternalForm() + "!/"; - ZipFile zip = new ZipFile(f); - Enumeration entries = zip.entries(); - while (entries.hasMoreElements() && (maxCount <= 0 || id < maxCount)) { - ZipEntry e = (ZipEntry) entries.nextElement(); - String n = e.getName(); - String p = n.replace('/', '.'); - if (n.endsWith(".class") && (clazz == null || p.indexOf(clazz) != -1) - && (excludeClazz == null || p.indexOf(excludeClazz) == -1)) { - n = p.substring(0, p.length() - 6); - if (id % parts == part) { - AbstractTest t = getClass().newInstance(); - URL url = new URL(baseurl + e.getName()); - t.init(n, url); - suite.addTest(t); - } - ++id; - } - } - zip.close(); - } - } - return suite; - } - - private void scanDirectory(final String path, final File f, final TestSuite suite, final String clazz, - final String excludeClazz) throws Exception { - File[] fs = f.listFiles(); - for (int i = 0; i < fs.length; ++i) { - String n = fs[i].getName(); - String qn = path.length() == 0 ? n : path + "." + n; - if (fs[i].isDirectory()) { - scanDirectory(qn, fs[i], suite, clazz, excludeClazz); - } else if (qn.endsWith(".class") && (clazz == null || qn.indexOf(clazz) != -1) - && (excludeClazz == null || qn.indexOf(excludeClazz) == -1)) { - qn = qn.substring(0, qn.length() - 6); - AbstractTest t = getClass().newInstance(); - t.init(qn, fs[i].toURI().toURL()); - suite.addTest(t); - } - } - } - - public abstract void test() throws Exception; - - public void assertEquals(final ClassReader cr1, final ClassReader cr2) throws Exception { - assertEquals(cr1, cr2, null, null); - } - - public void assertEquals(final ClassReader cr1, final ClassReader cr2, final ClassAdapter filter1, - final ClassAdapter filter2) throws Exception { - if (!Arrays.equals(cr1.b, cr2.b)) { - StringWriter sw1 = new StringWriter(); - StringWriter sw2 = new StringWriter(); - ClassVisitor cv1 = new TraceClassVisitor(new PrintWriter(sw1)); - ClassVisitor cv2 = new TraceClassVisitor(new PrintWriter(sw2)); - if (filter1 != null) { - filter1.cv = cv1; - } - if (filter2 != null) { - filter2.cv = cv2; - } - cr1.accept(filter1 == null ? cv1 : filter1, 0); - cr2.accept(filter2 == null ? cv2 : filter2, 0); - String s1 = sw1.toString(); - String s2 = sw2.toString(); - assertEquals("different data", s1, s2); - } - } - - @Override - public String getName() { - return super.getName() + ": " + n; - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/AnnotationsTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/AnnotationsTest.java deleted file mode 100644 index 3442ce6c9..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/AnnotationsTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.commons.EmptyVisitor; - -/** - * Annotations tests. - * - * @author Eric Bruneton - */ -public class AnnotationsTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new AnnotationsTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - ClassWriter cw1 = new ClassWriter(0); - ClassWriter cw2 = new ClassWriter(0); - cr.accept(new RemoveAnnotationsAdapter1(cw1), 0); - cr.accept(new RemoveAnnotationsAdapter2(cw2), 0); - assertEquals(new ClassReader(cw2.toByteArray()), new ClassReader(cw1.toByteArray())); - } - - static class RemoveAnnotationsAdapter1 extends ClassAdapter { - - public RemoveAnnotationsAdapter1(final ClassVisitor cv) { - super(cv); - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - return new EmptyVisitor(); - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - return new MethodAdapter(cv.visitMethod(access, name, desc, signature, exceptions)) { - - @Override - public AnnotationVisitor visitAnnotationDefault() { - return new EmptyVisitor(); - } - - @Override - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - return new EmptyVisitor(); - } - - @Override - public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { - return new EmptyVisitor(); - } - }; - } - } - - static class RemoveAnnotationsAdapter2 extends ClassAdapter { - - public RemoveAnnotationsAdapter2(final ClassVisitor cv) { - super(cv); - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - return null; - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - return new MethodAdapter(cv.visitMethod(access, name, desc, signature, exceptions)) { - - @Override - public AnnotationVisitor visitAnnotationDefault() { - return null; - } - - @Override - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - return null; - } - - @Override - public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { - return null; - } - }; - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/AsmTestParams.java b/common/asm/src/test/java/com/alibaba/citrus/asm/AsmTestParams.java deleted file mode 100644 index 6db5ed6c5..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/AsmTestParams.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.alibaba.citrus.asm; - -import static com.alibaba.citrus.test.TestEnvStatic.*; -import static com.alibaba.citrus.test.TestUtil.*; - -import java.io.File; -import java.io.IOException; - -import com.alibaba.citrus.asm.test.cases.Generator; -import com.alibaba.citrus.test.TestUtil; - -/** - * 帮助asm测试。 - * - * @author Michael Zhou - */ -public class AsmTestParams { - private final static File cases = TestUtil.getClassesDir(AsmTestParams.class); - private final static File output = new File(destdir, "output"); - private final static File[] defaultFiles; - private final static String defaultInclude; - private final static String defaultExclude; - private File[] files = defaultFiles; - private String include = defaultInclude; - private String exclude = defaultExclude; - private int parts = 1; - private int part = 0; - private int maxCount = 5000; - - static { - File testJar = new File(getJavaHome(), "jre/lib/rt.jar"); - - if (!testJar.exists()) { - testJar = new File(getJavaHome(), "../Classes/classes.jar"); // mac style - - if (!testJar.exists()) { - throw new IllegalArgumentException("could not find jar file: jre/lib/rt.jar or classes.jar"); - } - } - - defaultFiles = new File[] { testJar, cases }; - defaultInclude = ""; - defaultExclude = AsmTestParams.class.getPackage().getName(); - - // 生成测试用的class文件 - try { - Generator.main(new String[] { cases.getAbsolutePath() }); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public AsmTestParams() { - String maxCount = System.getProperty("maxCount"); - - if (maxCount != null) { - try { - this.maxCount = Integer.parseInt(maxCount); - } catch (NumberFormatException e) { - } - } - } - - public AsmTestParams(String clazz) { - this(); - this.include = clazz; - } - - public AsmTestParams(int parts, int part) { - this(); - this.parts = parts; - this.part = part; - } - - public File getOutput() { - return output; - } - - public String getClassPath(String relativePath) { - return new File(cases, relativePath).getAbsolutePath(); - } - - public File[] getFiles() { - return files; - } - - public String getInclude() { - return include; - } - - public String getExclude() { - return exclude; - } - - public int getParts() { - return parts; - } - - public int getPart() { - return part; - } - - public int getMaxCount() { - return maxCount; - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/AttributeUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/AttributeUnitTest.java deleted file mode 100644 index 6251a257d..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/AttributeUnitTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -import junit.framework.TestCase; - -/** - * Attribute unit tests. - * - * @author Eric Bruneton - */ -public class AttributeUnitTest extends TestCase { - - public void testUnknown() { - assertTrue(new Attribute("Comment").isUnknown()); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassAdapterTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/ClassAdapterTest.java deleted file mode 100644 index 304d476a4..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassAdapterTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -import junit.framework.TestSuite; - -/** - * ClassAdapter tests. - * - * @author Eric Bruneton - */ -public class ClassAdapterTest extends AbstractTest { - - private final static TestClassLoader LOADER = new TestClassLoader(); - - public static TestSuite suite() throws Exception { - return new ClassAdapterTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - cr.accept(new ClassAdapter(cw), 0); - byte[] b = cw.toByteArray(); - try { - LOADER.defineClass(n, b); - } catch (ClassFormatError cfe) { - fail(cfe.getMessage()); - } catch (Throwable ignored) { - } - } - - // ------------------------------------------------------------------------ - - static class TestClassLoader extends ClassLoader { - - public Class defineClass(final String name, final byte[] b) { - return defineClass(name, b, 0, b.length); - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassReaderTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/ClassReaderTest.java deleted file mode 100644 index 4a7d2aad0..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassReaderTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.commons.EmptyVisitor; - -/** - * ClassReader tests. - * - * @author Eric Bruneton - */ -public class ClassReaderTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new ClassReaderTest().getSuite(); - } - - @Override - public void test() throws Exception { - new ClassReader(openStream()).accept(new EmptyVisitor(), 0); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassReaderUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/ClassReaderUnitTest.java deleted file mode 100644 index 4dcba5aae..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassReaderUnitTest.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -import java.io.IOException; -import java.io.InputStream; - -import junit.framework.TestCase; - -/** - * ClassReader unit tests. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public class ClassReaderUnitTest extends TestCase implements Opcodes { - - public void testIllegalConstructorArgument() { - try { - new ClassReader((InputStream) null); - fail(); - } catch (IOException e) { - } - } - - public void testGetItem() throws IOException { - ClassReader cr = new ClassReader(getClass().getName()); - int item = cr.getItem(1); - assertTrue(item >= 10); - assertTrue(item < cr.header); - } - - public void testReadByte() throws IOException { - ClassReader cr = new ClassReader(getClass().getName()); - assertEquals(cr.b[0] & 0xFF, cr.readByte(0)); - } - - public void testGetAccess() throws Exception { - String name = getClass().getName(); - assertEquals(Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, new ClassReader(name).getAccess()); - } - - public void testGetClassName() throws Exception { - String name = getClass().getName(); - assertEquals(name.replace('.', '/'), new ClassReader(name).getClassName()); - } - - public void testGetSuperName() throws Exception { - assertEquals(TestCase.class.getName().replace('.', '/'), new ClassReader(getClass().getName()).getSuperName()); - assertEquals(null, new ClassReader(Object.class.getName()).getSuperName()); - } - - public void testGetInterfaces() throws Exception { - String[] interfaces = new ClassReader(getClass().getName()).getInterfaces(); - assertNotNull(interfaces); - assertEquals(1, interfaces.length); - assertEquals(Opcodes.class.getName().replace('.', '/'), interfaces[0]); - - interfaces = new ClassReader(Opcodes.class.getName()).getInterfaces(); - assertNotNull(interfaces); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterComputeFramesTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterComputeFramesTest.java deleted file mode 100644 index 83f542d63..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterComputeFramesTest.java +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.lang.instrument.ClassFileTransformer; -import java.lang.instrument.IllegalClassFormatException; -import java.lang.instrument.Instrumentation; -import java.security.ProtectionDomain; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.util.TraceClassVisitor; - -/** - * ClassWriter tests. - * - * @author Eric Bruneton - */ -public class ClassWriterComputeFramesTest extends AbstractTest { - - public static void premain(final String agentArgs, final Instrumentation inst) { - inst.addTransformer(new ClassFileTransformer() { - public byte[] transform(final ClassLoader loader, final String className, final Class classBeingRedefined, - final ProtectionDomain domain, final byte[] classFileBuffer) - throws IllegalClassFormatException { - String n = className.replace('/', '.'); - if (n.indexOf("junit") != -1) { - return null; - } - if (agentArgs.length() == 0 || n.indexOf(agentArgs) != -1) { - return transformClass(n, classFileBuffer); - } else { - return null; - } - } - }); - } - - private static byte[] transformClass(final String n, final byte[] clazz) { - ClassReader cr = new ClassReader(clazz); - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES) { - @Override - protected String getCommonSuperClass(final String type1, final String type2) { - if (n.equals("pkg.Frames")) { - return super.getCommonSuperClass(type1, type2); - } - ClassInfo c, d; - try { - c = new ClassInfo(type1, getClass().getClassLoader()); - d = new ClassInfo(type2, getClass().getClassLoader()); - } catch (Throwable e) { - throw new RuntimeException(e); - } - if (c.isAssignableFrom(d)) { - return type1; - } - if (d.isAssignableFrom(c)) { - return type2; - } - if (c.isInterface() || d.isInterface()) { - return "java/lang/Object"; - } else { - do { - c = c.getSuperclass(); - } while (!c.isAssignableFrom(d)); - return c.getType().getInternalName(); - } - } - }; - cr.accept(new ClassAdapter(cw) { - - @Override - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - super.visit(Opcodes.V1_6, access, name, signature, superName, interfaces); - } - - }, ClassReader.SKIP_FRAMES); - return cw.toByteArray(); - } - - public static TestSuite suite() throws Exception { - TestSuite suite = new TestSuite(ClassWriterComputeFramesTest.class.getName()); - - suite.addTest(new ClassWriterComputeFramesTest().getSuite(new AsmTestParams(2, 0))); - suite.addTest(new ClassWriterComputeFramesTest().getSuite(new AsmTestParams(2, 1))); - - return suite; - } - - @Override - public void test() throws Exception { - try { - Class.forName(n, true, getClass().getClassLoader()); - } catch (NoClassDefFoundError ncdfe) { - // ignored - } catch (UnsatisfiedLinkError ule) { - // ignored - } catch (ClassFormatError cfe) { - fail(cfe.getMessage()); - } catch (VerifyError ve) { - String s = n.replace('.', '/') + ".class"; - InputStream is = getClass().getClassLoader().getResourceAsStream(s); - ClassReader cr = new ClassReader(is); - byte[] b = transformClass("", cr.b); - StringWriter sw1 = new StringWriter(); - StringWriter sw2 = new StringWriter(); - sw2.write(ve.toString() + "\n"); - ClassVisitor cv1 = new TraceClassVisitor(new PrintWriter(sw1)); - ClassVisitor cv2 = new TraceClassVisitor(new PrintWriter(sw2)); - cr.accept(cv1, 0); - new ClassReader(b).accept(cv2, 0); - String s1 = sw1.toString(); - String s2 = sw2.toString(); - assertEquals("different data", s1, s2); - } - } -} - -/** - * @author Eugene Kuleshov - */ -class ClassInfo { - - private Type type; - - private ClassLoader loader; - - int access; - - String superClass; - - String[] interfaces; - - public ClassInfo(final String type, final ClassLoader loader) { - this.loader = loader; - this.type = Type.getObjectType(type); - String s = type.replace('.', '/') + ".class"; - InputStream is = null; - ClassReader cr; - try { - is = loader.getResourceAsStream(s); - cr = new ClassReader(is); - } catch (IOException e) { - throw new RuntimeException(e); - } finally { - if (is != null) { - try { - is.close(); - } catch (Exception e) { - } - } - } - - // optimized version - int h = cr.header; - ClassInfo.this.access = cr.readUnsignedShort(h); - char[] buf = new char[2048]; - // String name = cr.readClass( cr.header + 2, buf); - - int v = cr.getItem(cr.readUnsignedShort(h + 4)); - ClassInfo.this.superClass = v == 0 ? null : cr.readUTF8(v, buf); - ClassInfo.this.interfaces = new String[cr.readUnsignedShort(h + 6)]; - h += 8; - for (int i = 0; i < interfaces.length; ++i) { - interfaces[i] = cr.readClass(h, buf); - h += 2; - } - } - - String getName() { - return type.getInternalName(); - } - - Type getType() { - return type; - } - - int getModifiers() { - return access; - } - - ClassInfo getSuperclass() { - if (superClass == null) { - return null; - } - return new ClassInfo(superClass, loader); - } - - ClassInfo[] getInterfaces() { - if (interfaces == null) { - return new ClassInfo[0]; - } - ClassInfo[] result = new ClassInfo[interfaces.length]; - for (int i = 0; i < result.length; ++i) { - result[i] = new ClassInfo(interfaces[i], loader); - } - return result; - } - - boolean isInterface() { - return (getModifiers() & Opcodes.ACC_INTERFACE) > 0; - } - - private boolean implementsInterface(final ClassInfo that) { - for (ClassInfo c = this; c != null; c = c.getSuperclass()) { - ClassInfo[] tis = c.getInterfaces(); - for (int i = 0; i < tis.length; ++i) { - ClassInfo ti = tis[i]; - if (ti.type.equals(that.type) || ti.implementsInterface(that)) { - return true; - } - } - } - return false; - } - - private boolean isSubclassOf(final ClassInfo that) { - for (ClassInfo c = this; c != null; c = c.getSuperclass()) { - if (c.getSuperclass() != null && c.getSuperclass().type.equals(that.type)) { - return true; - } - } - return false; - } - - public boolean isAssignableFrom(final ClassInfo that) { - if (this == that) { - return true; - } - - if (that.isSubclassOf(this)) { - return true; - } - - if (that.implementsInterface(this)) { - return true; - } - - if (that.isInterface() && getType().getDescriptor().equals("Ljava/lang/Object;")) { - return true; - } - - return false; - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterComputeMaxsTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterComputeMaxsTest.java deleted file mode 100644 index 475172a0e..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterComputeMaxsTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -import junit.framework.TestSuite; - -/** - * ClassWriter tests. - * - * @author Eric Bruneton - */ -public class ClassWriterComputeMaxsTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new ClassWriterComputeMaxsTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - cr.accept(cw, 0); - // computed maxStack and maxLocals may differ from original class - // assertEquals(cr, new ClassReader(cw.toByteArray())); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterComputeMaxsUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterComputeMaxsUnitTest.java deleted file mode 100644 index 8d31ddf24..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterComputeMaxsUnitTest.java +++ /dev/null @@ -1,952 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -import java.io.ByteArrayInputStream; -import java.io.FileInputStream; -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.StringTokenizer; - -import junit.framework.TestCase; - -import com.alibaba.citrus.asm.commons.EmptyVisitor; - -/** - * ClassWriter unit tests for COMPUTE_MAXS option with JSR instructions. - * - * @author Eric Bruneton - */ -public class ClassWriterComputeMaxsUnitTest extends TestCase { - - private Field successors; - - private Field successor; - - private Field succ; - - private Field next; - - protected ClassWriter cw; - - protected MethodVisitor mv; - - private Label start; - - protected void setUp() throws Exception { - Class lClass = Label.class; - Class eClass = Edge.class; - try { - successors = lClass.getDeclaredField("successors"); - successor = lClass.getDeclaredField("successor"); - succ = eClass.getDeclaredField("successor"); - next = eClass.getDeclaredField("next"); - } catch (Exception exception) { - String f = "src/com/alibaba/citrus/asm/optimizer/shrink.properties"; - Properties p = new Properties(); - p.load(new FileInputStream(f)); - String l = Type.getInternalName(lClass) + "."; - String e = Type.getInternalName(eClass) + "."; - successors = lClass.getDeclaredField(p.getProperty(l + "successors")); - successor = lClass.getDeclaredField(p.getProperty(l + "successor")); - succ = eClass.getDeclaredField(p.getProperty(e + "successor")); - next = eClass.getDeclaredField(p.getProperty(e + "next")); - } - cw = new ClassWriter(isComputeMaxs() ? ClassWriter.COMPUTE_MAXS : 0); - cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, "C", null, "java/lang/Object", null); - mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", "()V", null, null); - mv.visitCode(); - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "", "()V"); - mv.visitInsn(Opcodes.RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "m", "()V", null, null); - mv.visitCode(); - start = new Label(); - LABEL(start); - } - - protected boolean isComputeMaxs() { - return true; - } - - private void NOP() { - mv.visitInsn(Opcodes.NOP); - } - - private void PUSH() { - mv.visitInsn(Opcodes.ICONST_0); - } - - private void ICONST_0() { - mv.visitInsn(Opcodes.ICONST_0); - } - - private void ISTORE(final int var) { - mv.visitVarInsn(Opcodes.ISTORE, var); - } - - private void ALOAD(final int var) { - mv.visitVarInsn(Opcodes.ALOAD, var); - } - - private void ILOAD(final int var) { - mv.visitVarInsn(Opcodes.ILOAD, var); - } - - private void ASTORE(final int var) { - mv.visitVarInsn(Opcodes.ASTORE, var); - } - - private void RET(final int var) { - mv.visitVarInsn(Opcodes.RET, var); - } - - private void ATHROW() { - mv.visitInsn(Opcodes.ATHROW); - } - - private void ACONST_NULL() { - mv.visitInsn(Opcodes.ACONST_NULL); - } - - private void RETURN() { - mv.visitInsn(Opcodes.RETURN); - } - - private void LABEL(final Label l) { - mv.visitLabel(l); - } - - private void IINC(final int var, final int amnt) { - mv.visitIincInsn(var, amnt); - } - - private void GOTO(final Label l) { - mv.visitJumpInsn(Opcodes.GOTO, l); - } - - private void JSR(final Label l) { - mv.visitJumpInsn(Opcodes.JSR, l); - } - - private void IFNONNULL(final Label l) { - mv.visitJumpInsn(Opcodes.IFNONNULL, l); - } - - private void IFNE(final Label l) { - mv.visitJumpInsn(Opcodes.IFNE, l); - } - - private void TRYCATCH(final Label start, final Label end, final Label handler) { - mv.visitTryCatchBlock(start, end, handler, null); - } - - protected void assertMaxs(final int maxStack, final int maxLocals) { - mv.visitMaxs(0, 0); - mv.visitEnd(); - cw.visitEnd(); - byte[] b = cw.toByteArray(); - ClassReader cr = new ClassReader(b); - cr.accept(new EmptyVisitor() { - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - if (name.equals("m")) { - return new EmptyVisitor() { - public void visitMaxs(final int realMaxStack, final int realMaxLocals) { - assertEquals("maxStack", maxStack, realMaxStack); - assertEquals("maxLocals", maxLocals, realMaxLocals); - } - }; - } else { - return new EmptyVisitor(); - } - } - }, 0); - - try { - TestClassLoader loader = new TestClassLoader(); - Class c = loader.defineClass("C", b); - c.newInstance(); - } catch (Throwable t) { - fail(t.getMessage()); - } - } - - protected void assertGraph(final String graph) { - Map expected = new HashMap(); - Properties p = new Properties(); - try { - p.load(new ByteArrayInputStream(graph.getBytes())); - } catch (Exception e) { - fail(); - } - Iterator i = p.keySet().iterator(); - while (i.hasNext()) { - String key = (String) i.next(); - String value = p.getProperty(key); - StringTokenizer st = new StringTokenizer(value, ","); - Set s = new HashSet(); - while (st.hasMoreTokens()) { - s.add(st.nextToken()); - } - expected.put(key, s); - } - - Map actual = new HashMap(); - try { - Label l = start; - while (l != null) { - String key = "N" + l.getOffset(); - Set value = new HashSet(); - Edge e = (Edge) successors.get(l); - while (e != null) { - value.add("N" + ((Label) succ.get(e)).getOffset()); - e = (Edge) next.get(e); - } - actual.put(key, value); - l = (Label) successor.get(l); - } - } catch (Exception e) { - fail(); - } - - assertEquals(expected, actual); - } - - protected static class TestClassLoader extends ClassLoader { - - public TestClassLoader() { - } - - public Class defineClass(final String name, final byte[] b) { - return defineClass(name, b, 0, b.length); - } - } - - /** - * Tests a method which has the most basic try{}finally form - * imaginable: - * - *
-     * public void a() {
-     *     int a = 0;
-     *     try {
-     *         a++;
-     *     } finally {
-     *         a--;
-     *     }
-     * }
-     * 
- */ - public void testBasic() { - Label L0 = new Label(); - Label L1 = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - Label L4 = new Label(); - - ICONST_0(); // N0 - ISTORE(1); - - /* L0: body of try block */ - LABEL(L0); // N2 - IINC(1, 1); - GOTO(L1); - - /* L2: exception handler */ - LABEL(L2); // N8 - ASTORE(3); - JSR(L3); - ALOAD(3); // N12 - ATHROW(); - - /* L3: subroutine */ - LABEL(L3); // N14 - ASTORE(2); - IINC(1, -1); - PUSH(); - PUSH(); - RET(2); - - /* L1: non-exceptional exit from try block */ - LABEL(L1); // N22 - JSR(L3); - PUSH(); // N25 - PUSH(); - LABEL(L4); // N27 - RETURN(); - - TRYCATCH(L0, L2, L2); - TRYCATCH(L1, L4, L2); - - assertMaxs(4, 4); - assertGraph("N0=N2\n" + "N2=N22,N8\n" + "N8=N14,N12\n" + "N12=\n" + "N14=N12,N25\n" + "N22=N14,N25,N8\n" - + "N25=N27,N8\n" + "N27=\n"); - } - - /** - * Tests a method which has an if/else-if w/in the finally clause: - * - *
-     * public void a() {
-     *     int a = 0;
-     *     try {
-     *         a++;
-     *     } finally {
-     *         if (a == 0)
-     *             a += 2;
-     *         else
-     *             a += 3;
-     *     }
-     * }
-     * 
- */ - public void testIfElseInFinally() { - Label L0 = new Label(); - Label L1 = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - Label L4 = new Label(); - Label L5 = new Label(); - Label L6 = new Label(); - - ICONST_0(); // N0 - ISTORE(1); - - /* L0: body of try block */ - LABEL(L0); // N2 - IINC(1, 1); - GOTO(L1); - - /* L2: exception handler */ - LABEL(L2); // N8 - ASTORE(3); - JSR(L3); - PUSH(); // N12 - PUSH(); - ALOAD(3); - ATHROW(); - - /* L3: subroutine */ - LABEL(L3); // N16 - ASTORE(2); - PUSH(); - PUSH(); - ILOAD(1); - IFNE(L4); - IINC(1, 2); - GOTO(L5); - - LABEL(L4); // N29 - IINC(1, 3); - - LABEL(L5); // N32 common exit - RET(2); - - /* L1: non-exceptional exit from try block */ - LABEL(L1); // N34 - JSR(L3); - LABEL(L6); // N37 - RETURN(); - - TRYCATCH(L0, L2, L2); - TRYCATCH(L1, L6, L2); - - assertMaxs(5, 4); - assertGraph("N0=N2\n" + "N2=N34,N8\n" + "N8=N16,N12\n" + "N12=\n" + "N16=N29,N32\n" + "N29=N32\n" - + "N32=N37,N12\n" + "N34=N16,N37,N8\n" + "N37=\n"); - - } - - /** - * Tests a simple nested finally: - * - *
-     * public void a1() {
-     *     int a = 0;
-     *     try {
-     *         a += 1;
-     *     } finally {
-     *         try {
-     *             a += 2;
-     *         } finally {
-     *             a += 3;
-     *         }
-     *     }
-     * }
-     * 
- */ - public void testSimpleNestedFinally() { - Label L0 = new Label(); - Label L1 = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - Label L4 = new Label(); - Label L5 = new Label(); - - ICONST_0(); // N0 - ISTORE(1); - - // L0: Body of try block: - LABEL(L0); // N2 - IINC(1, 1); - JSR(L3); - GOTO(L1); // N8 - - // L2: First exception handler: - LABEL(L2); // N11 - ASTORE(4); - JSR(L3); - ALOAD(4); // N16 - ATHROW(); - - // L3: First subroutine: - LABEL(L3); // N19 - ASTORE(2); - IINC(1, 2); - JSR(L4); - PUSH(); // N26 - PUSH(); - RET(2); - - // L5: Second exception handler: - LABEL(L5); // N30 - ASTORE(5); - JSR(L4); - ALOAD(5); // N35 - ATHROW(); - - // L4: Second subroutine: - LABEL(L4); // N38 - ASTORE(3); - PUSH(); - PUSH(); - IINC(1, 3); - RET(3); - - // L1: On normal exit, try block jumps here: - LABEL(L1); // N46 - RETURN(); - - TRYCATCH(L0, L2, L2); - TRYCATCH(L3, L5, L5); - - assertMaxs(5, 6); - assertGraph("N0=N2\n" + "N2=N11,N19,N8\n" + "N8=N11,N46\n" + "N11=N19,N16\n" + "N16=\n" + "N19=N26,N30,N38\n" - + "N26=N16,N30,N8\n" + "N30=N38,N35\n" + "N35=\n" + "N38=N26,N35\n" + "N46=\n"); - } - - /** - * This tests a subroutine which has no ret statement, but ends in a - * "return" instead. We structure this as a try/finally with a break in the - * finally. Because the while loop is infinite, it's clear from the byte - * code that the only path which reaches the RETURN instruction is through - * the subroutine. - * - *
-     * public void a1() {
-     *     int a = 0;
-     *     while (true) {
-     *         try {
-     *             a += 1;
-     *         } finally {
-     *             a += 2;
-     *             break;
-     *         }
-     *     }
-     * }
-     * 
- */ - public void testSubroutineWithNoRet() { - Label L0 = new Label(); - Label L1 = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - Label L4 = new Label(); - - ICONST_0(); // N0 - ISTORE(1); - - // L0: while loop header/try block - LABEL(L0); // N2 - IINC(1, 1); - JSR(L1); - GOTO(L2); // N8 - - // L3: implicit catch block - LABEL(L3); // N11 - ASTORE(2); - JSR(L1); - PUSH(); // N15 - PUSH(); - ALOAD(2); - ATHROW(); - - // L1: subroutine ... - LABEL(L1); // N19 - ASTORE(3); - IINC(1, 2); - GOTO(L4); // ...not that it does not return! - - // L2: end of the loop... goes back to the top! - LABEL(L2); // N26 - GOTO(L0); - - // L4: - LABEL(L4); // N29 - RETURN(); - - TRYCATCH(L0, L3, L3); - - assertMaxs(1, 4); - assertGraph("N0=N2\n" + "N2=N11,N19,N8\n" + "N8=N11,N26\n" + "N11=N19,N15\n" + "N15=\n" + "N19=N29\n" - + "N26=N2\n" + "N29=\n"); - } - - /** - * This tests a subroutine which has no ret statement, but ends in a - * "return" instead. - * - *
-     *   ACONST_NULL
-     *   JSR L0
-     * L0:
-     *   ASTORE 0 
-     *   ASTORE 0
-     *   RETURN
-     * 
- */ - public void testSubroutineWithNoRet2() { - Label L0 = new Label(); - Label L1 = new Label(); - - ACONST_NULL(); // N0 - JSR(L0); - NOP(); // N4 - LABEL(L0); // N5 - ASTORE(0); - ASTORE(0); - RETURN(); - LABEL(L1); // N8 - mv.visitLocalVariable("i", "I", null, L0, L1, 1); - - assertMaxs(2, 2); - assertGraph("N0=N4,N5\n" + "N4=N5\n" + "N5=\n" + "N8=\n"); - } - - /** - * This tests a subroutine which has no ret statement, but instead exits - * implicitely by branching to code which is not part of the subroutine. - * (Sadly, this is legal) We structure this as a try/finally in a loop with - * a break in the finally. The loop is not trivially infinite, so the RETURN - * statement is reachable both from the JSR subroutine and from the main - * entry point. - * - *
-     * public void a1() {
-     *     int a = 0;
-     *     while (null == null) {
-     *         try {
-     *             a += 1;
-     *         } finally {
-     *             a += 2;
-     *             break;
-     *         }
-     *     }
-     * }
-     * 
- */ - public void testImplicitExit() { - Label L0 = new Label(); - Label L1 = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - Label L4 = new Label(); - Label L5 = new Label(); - - ICONST_0(); // N0 - ISTORE(1); - - // L5: while loop header - LABEL(L5); // N2 - ACONST_NULL(); - IFNONNULL(L4); - - // L0: try block - LABEL(L0); // N6 - IINC(1, 1); - JSR(L1); - GOTO(L2); // N12 - - // L3: implicit catch block - LABEL(L3); // N15 - ASTORE(2); - JSR(L1); - ALOAD(2); // N19 - PUSH(); - PUSH(); - ATHROW(); - - // L1: subroutine ... - LABEL(L1); // N23 - ASTORE(3); - IINC(1, 2); - GOTO(L4); // ...not that it does not return! - - // L2: end of the loop... goes back to the top! - LABEL(L2); // N30 - GOTO(L0); - - // L4: - LABEL(L4); // N33 - RETURN(); - - TRYCATCH(L0, L3, L3); - - assertMaxs(1, 4); - assertGraph("N0=N2\n" + "N2=N6,N33\n" + "N6=N23,N12,N15\n" + "N12=N30,N15\n" + "N15=N23,N19\n" + "N19=\n" - + "N23=N33\n" + "N30=N6\n" + "N33=\n"); - } - - /** - * Tests a nested try/finally with implicit exit from one subroutine to the - * other subroutine. Equivalent to the following java code: - * - *
-     * void m(boolean b) {
-     *     try {
-     *         return;
-     *     } finally {
-     *         while (b) {
-     *             try {
-     *                 return;
-     *             } finally {
-     *                 // NOTE --- this break avoids the second return above (weird)
-     *                 if (b)
-     *                     break;
-     *             }
-     *         }
-     *     }
-     * }
-     * 
- * - * This example is from the paper, "Subroutine Inlining and Bytecode - * Abstraction to Simplify Static and Dynamic Analysis" by Cyrille Artho and - * Armin Biere. - */ - public void testImplicitExitToAnotherSubroutine() { - Label T1 = new Label(); - Label C1 = new Label(); - Label S1 = new Label(); - Label L = new Label(); - Label C2 = new Label(); - Label S2 = new Label(); - Label W = new Label(); - Label X = new Label(); - - // variable numbers: - int b = 1; - int e1 = 2; - int e2 = 3; - int r1 = 4; - int r2 = 5; - - ICONST_0(); // N0 - ISTORE(1); - - // T1: first try: - LABEL(T1); // N2 - JSR(S1); - RETURN(); // N5 - - // C1: exception handler for first try - LABEL(C1); // N6 - ASTORE(e1); - JSR(S1); - PUSH(); // N10 - PUSH(); - ALOAD(e1); - ATHROW(); - - // S1: first finally handler - LABEL(S1); // N14 - ASTORE(r1); - PUSH(); - PUSH(); - GOTO(W); - - // L: body of while loop, also second try - LABEL(L); // N21 - JSR(S2); - RETURN(); // N24 - - // C2: exception handler for second try - LABEL(C2); // N25 - ASTORE(e2); - PUSH(); - PUSH(); - JSR(S2); - ALOAD(e2); // N31 - ATHROW(); - - // S2: second finally handler - LABEL(S2); // N33 - ASTORE(r2); - ILOAD(b); - IFNE(X); - RET(r2); - - // W: test for the while loop - LABEL(W); // N41 - ILOAD(b); - IFNE(L); // falls through to X - - // X: exit from finally{} block - LABEL(X); // N45 - RET(r1); - - TRYCATCH(T1, C1, C1); - TRYCATCH(L, C2, C2); - - assertMaxs(5, 6); - assertGraph("N0=N2\n" + "N2=N6,N5,N14\n" + "N5=N6\n" + "N6=N14,N10\n" + "N10=\n" + "N14=N41\n" - + "N21=N24,N25,N33\n" + "N24=N25\n" + "N25=N31,N33\n" + "N31=\n" + "N33=N31,N45,N24\n" - + "N41=N45,N21\n" + "N45=N5,N10\n"); - } - - public void testImplicitExitToAnotherSubroutine2() { - Label L1 = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - - ICONST_0(); // N0 - ISTORE(1); - JSR(L1); - RETURN(); // N5 - - LABEL(L1); // N6 - ASTORE(2); - JSR(L2); - GOTO(L3); // N10 - - LABEL(L2); // N13 - ASTORE(3); - ILOAD(1); - IFNE(L3); - RET(3); - - LABEL(L3); // N20 - RET(2); - - assertMaxs(1, 4); - assertGraph("N0=N6,N5\n" + "N5=\n" + "N6=N10,N13\n" + "N10=N20\n" + "N13=N20,N10\n" + "N20=N5\n"); - } - - /** - * This tests a simple subroutine where the control flow jumps back and - * forth between the subroutine and the caller. This would not normally be - * produced by a java compiler. - */ - public void testInterleavedCode() { - Label L1 = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - Label L4 = new Label(); - - ICONST_0(); // N0 - ISTORE(1); - JSR(L1); - GOTO(L2); // N5 - - // L1: subroutine 1 - LABEL(L1); // N8 - ASTORE(2); - IINC(1, 1); - GOTO(L3); - - // L2: second part of main subroutine - LABEL(L2); // N15 - IINC(1, 2); - GOTO(L4); - - // L3: second part of subroutine 1 - LABEL(L3); // N21 - IINC(1, 4); - PUSH(); - PUSH(); - RET(2); - - // L4: third part of main subroutine - LABEL(L4); // N28 - PUSH(); - PUSH(); - RETURN(); - - assertMaxs(4, 3); - assertGraph("N0=N5,N8\n" + "N5=N15\n" + "N8=N21\n" + "N15=N28\n" + "N21=N5\n" + "N28=\n"); - } - - /** - * Tests a nested try/finally with implicit exit from one subroutine to the - * other subroutine, and with a surrounding try/catch thrown in the mix. - * Equivalent to the following java code: - * - *
-     * void m(int b) {
-     *     try {
-     *         try {
-     *             return;
-     *         } finally {
-     *             while (b) {
-     *                 try {
-     *                     return;
-     *                 } finally {
-     *                     // NOTE --- this break avoids the second return above (weird)
-     *                     if (b)
-     *                         break;
-     *                 }
-     *             }
-     *         }
-     *     } catch (Exception e) {
-     *         b += 3;
-     *         return;
-     *     }
-     * }
-     * 
- */ - public void testImplicitExitInTryCatch() { - Label T1 = new Label(); - Label C1 = new Label(); - Label S1 = new Label(); - Label L = new Label(); - Label C2 = new Label(); - Label S2 = new Label(); - Label W = new Label(); - Label X = new Label(); - Label OC = new Label(); - - // variable numbers: - int b = 1; - int e1 = 2; - int e2 = 3; - int r1 = 4; - int r2 = 5; - - ICONST_0(); // N0 - ISTORE(1); - - // T1: first try: - LABEL(T1); // N2 - JSR(S1); - RETURN(); // N5 - - // C1: exception handler for first try - LABEL(C1); // N6 - ASTORE(e1); - JSR(S1); - ALOAD(e1); // N10 - ATHROW(); - - // S1: first finally handler - LABEL(S1); // N12 - ASTORE(r1); - GOTO(W); - - // L: body of while loop, also second try - LABEL(L); // N17 - JSR(S2); - PUSH(); // N20 - PUSH(); - RETURN(); - - // C2: exception handler for second try - LABEL(C2); // N23 - ASTORE(e2); - JSR(S2); - ALOAD(e2); // N27 - ATHROW(); - - // S2: second finally handler - LABEL(S2); // N29 - ASTORE(r2); - ILOAD(b); - IFNE(X); - PUSH(); - PUSH(); - RET(r2); - - // W: test for the while loop - LABEL(W); // N39 - ILOAD(b); - IFNE(L); // falls through to X - - // X: exit from finally{} block - LABEL(X); // N43 - RET(r1); - - // OC: outermost catch - LABEL(OC); // N45 - IINC(b, 3); - RETURN(); - - TRYCATCH(T1, C1, C1); - TRYCATCH(L, C2, C2); - TRYCATCH(T1, OC, OC); - - assertMaxs(4, 6); - assertGraph("N0=N2\n" + "N2=N6,N45,N5,N12\n" + "N5=N6,N45\n" + "N6=N45,N12,N10\n" + "N10=N45\n" - + "N12=N39,N45\n" + "N17=N23,N45,N20,N29\n" + "N20=N23,N45\n" + "N23=N45,N27,N29\n" + "N27=N45\n" - + "N29=N43,N45,N20,N27\n" + "N39=N43,N45,N17\n" + "N43=N45,N5,N10\n" + "N45=\n"); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterCopyPoolTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterCopyPoolTest.java deleted file mode 100644 index 930c3610b..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterCopyPoolTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -import junit.framework.TestSuite; - -/** - * ClassWriter tests for copyPool() optimization. - * - * @author Eugene Kuleshov - */ -public class ClassWriterCopyPoolTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new ClassWriterCopyPoolTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - ClassWriter cw1 = new ClassWriter(0); - ClassWriter cw2 = new ClassWriter(cr, 0); - cr.accept(new ChangeExceptionAdapter(cw1), 0); - cr.accept(new ChangeExceptionAdapter(cw2), 0); - assertEquals(new ClassReader(cw1.toByteArray()), new ClassReader(cw2.toByteArray())); - } - - static class ChangeExceptionAdapter extends ClassAdapter { - - public ChangeExceptionAdapter(final ClassVisitor cv) { - super(cv); - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - if (exceptions != null && exceptions.length > 0) { - exceptions[0] = "java/lang/Throwable"; - } - return super.visitMethod(access, name, desc, signature, exceptions); - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterResizeInsnsTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterResizeInsnsTest.java deleted file mode 100644 index a17fd1155..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterResizeInsnsTest.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.instrument.IllegalClassFormatException; -import java.lang.instrument.Instrumentation; -import java.security.ProtectionDomain; -import java.util.HashSet; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.attrs.CodeComment; - -public class ClassWriterResizeInsnsTest extends AbstractTest { - - public static void premain(final String agentArgs, final Instrumentation inst) { - inst.addTransformer(new ClassFileTransformer() { - public byte[] transform(final ClassLoader loader, final String className, final Class classBeingRedefined, - final ProtectionDomain domain, byte[] b) throws IllegalClassFormatException { - String n = className.replace('/', '.'); - if (agentArgs.length() == 0 || n.indexOf(agentArgs) != -1) { - try { - b = transformClass(b, ClassWriter.COMPUTE_FRAMES); - if (n.equals("pkg.FrameMap")) { - transformClass(b, 0); - } - return b; - } catch (Throwable e) { - return transformClass(b, 0); - } - } else { - return null; - } - } - }); - } - - private static byte[] transformClass(final byte[] clazz, final int flags) { - ClassReader cr = new ClassReader(clazz); - ClassWriter cw = new ClassWriter(flags) { - @Override - protected String getCommonSuperClass(final String type1, final String type2) { - ClassInfo c, d; - try { - c = new ClassInfo(type1, getClass().getClassLoader()); - d = new ClassInfo(type2, getClass().getClassLoader()); - } catch (Throwable e) { - throw new RuntimeException(e); - } - if (c.isAssignableFrom(d)) { - return type1; - } - if (d.isAssignableFrom(c)) { - return type2; - } - if (c.isInterface() || d.isInterface()) { - return "java/lang/Object"; - } else { - do { - c = c.getSuperclass(); - } while (!c.isAssignableFrom(d)); - return c.getType().getInternalName(); - } - } - }; - ClassAdapter ca = new ClassAdapter(cw) { - - private boolean transformed = false; - - @Override - public void visit(int version, int access, String name, String signature, String superName, - String[] interfaces) { - if (flags == ClassWriter.COMPUTE_FRAMES) { - version = Opcodes.V1_6; - } - super.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - return new MethodAdapter(cv.visitMethod(access, name, desc, signature, exceptions)) { - private HashSet labels = new HashSet(); - - @Override - public void visitLabel(final Label label) { - super.visitLabel(label); - labels.add(label); - } - - @Override - public void visitJumpInsn(final int opcode, final Label label) { - super.visitJumpInsn(opcode, label); - if (opcode != Opcodes.GOTO) { - if (!transformed && !labels.contains(label)) { - transformed = true; - for (int i = 0; i < 33000; ++i) { - mv.visitInsn(Opcodes.NOP); - } - } - } - } - }; - } - }; - cr.accept(ca, new Attribute[] { new CodeComment() }, 0); - return cw.toByteArray(); - } - - public static TestSuite suite() throws Exception { - return new ClassWriterResizeInsnsTest().getSuite(new AsmTestParams("com.sun.corba")); - } - - @Override - public void test() throws Exception { - try { - Class.forName(n, true, getClass().getClassLoader()); - } catch (NoClassDefFoundError ncdfe) { - // ignored - } catch (UnsatisfiedLinkError ule) { - // ignored - } catch (ClassFormatError cfe) { - fail(cfe.getMessage()); - } catch (VerifyError ve) { - fail(ve.toString()); - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterTest.java deleted file mode 100644 index 710de9768..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -import junit.framework.TestSuite; - -/** - * ClassWriter tests. - * - * @author Eric Bruneton - */ -public class ClassWriterTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new ClassWriterTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - ClassWriter cw = new ClassWriter(0); - cr.accept(cw, 0); - assertEquals(cr, new ClassReader(cw.toByteArray())); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterUnitTest.java deleted file mode 100644 index 9d304e1ba..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/ClassWriterUnitTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -import junit.framework.TestCase; - -/** - * ClassWriter unit tests. - * - * @author Eric Bruneton - */ -public class ClassWriterUnitTest extends TestCase { - - public void testNewConst() { - ClassWriter cw = new ClassWriter(0); - cw.newConst(new Byte((byte) 0)); - cw.newConst(new Character('0')); - cw.newConst(new Short((short) 0)); - cw.newConst(Boolean.FALSE); - cw.newField("A", "f", "I"); - cw.newMethod("A", "m", "()V", false); - } - - public void testIllegalNewConstArgument() { - ClassWriter cw = new ClassWriter(0); - try { - cw.newConst(new Object()); - fail(); - } catch (RuntimeException e) { - } - } - - public void testIllegalGetCommonSuperClassArguments() { - ClassWriter cw = new ClassWriter(0); - try { - cw.getCommonSuperClass("-", "-"); - fail(); - } catch (RuntimeException e) { - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/LabelUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/LabelUnitTest.java deleted file mode 100644 index d236643fc..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/LabelUnitTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -import junit.framework.TestCase; - -/** - * Label unit tests. - * - * @author Eric Bruneton - */ -public class LabelUnitTest extends TestCase { - - public void testToString() { - new Label().toString(); - } - - public void testGetOffset() { - Label l = new Label(); - ClassWriter cw = new ClassWriter(0); - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "m", "()V", null, null); - mv.visitCode(); - mv.visitLabel(l); - assertEquals(0, l.getOffset()); - } - - public void testIllegalGetOffsetState() { - try { - new Label().getOffset(); - fail(); - } catch (RuntimeException e) { - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/TypeUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/TypeUnitTest.java deleted file mode 100644 index 73fb18105..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/TypeUnitTest.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.util.Arrays; - -import junit.framework.TestCase; - -/** - * Type unit tests. - * - * @author Eric Bruneton - */ -public class TypeUnitTest extends TestCase implements Opcodes { - - public void testConstants() { - assertEquals(Type.INT_TYPE, Type.getType(Integer.TYPE)); - assertEquals(Type.VOID_TYPE, Type.getType(Void.TYPE)); - assertEquals(Type.BOOLEAN_TYPE, Type.getType(Boolean.TYPE)); - assertEquals(Type.BYTE_TYPE, Type.getType(Byte.TYPE)); - assertEquals(Type.CHAR_TYPE, Type.getType(Character.TYPE)); - assertEquals(Type.SHORT_TYPE, Type.getType(Short.TYPE)); - assertEquals(Type.DOUBLE_TYPE, Type.getType(Double.TYPE)); - assertEquals(Type.FLOAT_TYPE, Type.getType(Float.TYPE)); - assertEquals(Type.LONG_TYPE, Type.getType(Long.TYPE)); - } - - public void testInternalName() { - String s1 = Type.getType(TypeUnitTest.class).getInternalName(); - String s2 = Type.getInternalName(TypeUnitTest.class); - assertEquals(s1, s2); - } - - public void testConstructorDescriptor() { - for (int i = 0; i < String.class.getConstructors().length; ++i) { - Constructor c = String.class.getConstructors()[i]; - Type.getConstructorDescriptor(c); - } - } - - public void testMethodDescriptor() { - for (int i = 0; i < Arrays.class.getMethods().length; ++i) { - Method m = Arrays.class.getMethods()[i]; - Type[] args = Type.getArgumentTypes(m); - Type r = Type.getReturnType(m); - String d1 = Type.getMethodDescriptor(r, args); - String d2 = Type.getMethodDescriptor(m); - assertEquals(d1, d2); - } - } - - public void testGetOpcode() { - Type object = Type.getType("Ljava/lang/Object;"); - assertEquals(BALOAD, Type.BOOLEAN_TYPE.getOpcode(IALOAD)); - assertEquals(BALOAD, Type.BYTE_TYPE.getOpcode(IALOAD)); - assertEquals(CALOAD, Type.CHAR_TYPE.getOpcode(IALOAD)); - assertEquals(SALOAD, Type.SHORT_TYPE.getOpcode(IALOAD)); - assertEquals(IALOAD, Type.INT_TYPE.getOpcode(IALOAD)); - assertEquals(FALOAD, Type.FLOAT_TYPE.getOpcode(IALOAD)); - assertEquals(LALOAD, Type.LONG_TYPE.getOpcode(IALOAD)); - assertEquals(DALOAD, Type.DOUBLE_TYPE.getOpcode(IALOAD)); - assertEquals(AALOAD, object.getOpcode(IALOAD)); - assertEquals(IADD, Type.BOOLEAN_TYPE.getOpcode(IADD)); - assertEquals(IADD, Type.BYTE_TYPE.getOpcode(IADD)); - assertEquals(IADD, Type.CHAR_TYPE.getOpcode(IADD)); - assertEquals(IADD, Type.SHORT_TYPE.getOpcode(IADD)); - assertEquals(IADD, Type.INT_TYPE.getOpcode(IADD)); - assertEquals(FADD, Type.FLOAT_TYPE.getOpcode(IADD)); - assertEquals(LADD, Type.LONG_TYPE.getOpcode(IADD)); - assertEquals(DADD, Type.DOUBLE_TYPE.getOpcode(IADD)); - } - - public void testHashcode() { - Type.getType("Ljava/lang/Object;").hashCode(); - } - - public void testObjectType() throws Exception { - Type t1 = Type.getObjectType("java/lang/Object"); - Type t2 = Type.getType("Ljava/lang/Object;"); - assertEquals(t2.getSort(), t1.getSort()); - assertEquals(t2.getClassName(), t1.getClassName()); - assertEquals(t2.getDescriptor(), t1.getDescriptor()); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/attrs/CodeComment.java b/common/asm/src/test/java/com/alibaba/citrus/asm/attrs/CodeComment.java deleted file mode 100644 index 7fc8aad60..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/attrs/CodeComment.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.attrs; - -import java.util.Map; - -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.ByteVector; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.util.ASMifiable; -import com.alibaba.citrus.asm.util.Traceable; - -/** - * A non standard code attribute used for testing purposes. - * - * @author Eric Bruneton - */ -public class CodeComment extends Attribute implements ASMifiable, Traceable { - - public CodeComment() { - super("CodeComment"); - } - - @Override - public boolean isUnknown() { - return false; - } - - @Override - public boolean isCodeAttribute() { - return true; - } - - @Override - protected Attribute read(final ClassReader cr, final int off, final int len, final char[] buf, final int codeOff, - final Label[] labels) { - - return new CodeComment(); - } - - @Override - protected ByteVector write(final ClassWriter cw, final byte[] code, final int len, final int maxStack, - final int maxLocals) { - return new ByteVector(); - } - - @Override - protected Label[] getLabels() { - super.getLabels(); - return new Label[] { new Label() }; - } - - public void asmify(final StringBuilder buf, final String varName, final Map labelNames) { - buf.append("Attribute ").append(varName).append(" = new com.alibaba.citrus.asm.attrs.CodeComment();"); - } - - public void trace(final StringBuilder buf, final Map labelNames) { - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/attrs/Comment.java b/common/asm/src/test/java/com/alibaba/citrus/asm/attrs/Comment.java deleted file mode 100644 index f4ba8f4a7..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/attrs/Comment.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.attrs; - -import java.util.Map; - -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.ByteVector; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.util.ASMifiable; -import com.alibaba.citrus.asm.util.Traceable; - -/** - * A non standard attribute used for testing purposes. - * - * @author Eric Bruneton - */ -public class Comment extends Attribute implements ASMifiable, Traceable { - - public Comment() { - super("Comment"); - } - - @Override - public boolean isUnknown() { - return false; - } - - @Override - protected Attribute read(final ClassReader cr, final int off, final int len, final char[] buf, final int codeOff, - final Label[] labels) { - - return new Comment(); - } - - @Override - protected ByteVector write(final ClassWriter cw, final byte[] code, final int len, final int maxStack, - final int maxLocals) { - return new ByteVector(); - } - - public void asmify(final StringBuilder buf, final String varName, final Map labelNames) { - buf.append("Attribute ").append(varName).append(" = new com.alibaba.citrus.asm.attrs.Comment();"); - } - - public void trace(final StringBuilder buf, final Map labelNames) { - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/AdviceAdapterTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/commons/AdviceAdapterTest.java deleted file mode 100644 index 8b5ec1f00..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/AdviceAdapterTest.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import junit.framework.TestSuite; -import junit.textui.TestRunner; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.ClassAdapter; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * AdviceAdapter tests. - * - * @author Eugene Kuleshov - */ -public class AdviceAdapterTest extends AbstractTest { - - public static void main(final String[] args) throws Exception { - TestRunner.run(AdviceAdapterTest.suite()); - } - - public static TestSuite suite() throws Exception { - return new AdviceAdapterTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - ClassWriter cw1 = new ClassWriter(0); - ClassWriter cw2 = new ClassWriter(0); - cr.accept(new ReferenceClassAdapter(cw1), ClassReader.EXPAND_FRAMES); - cr.accept(new AdviceClassAdapter(cw2), ClassReader.EXPAND_FRAMES); - assertEquals(new ClassReader(cw1.toByteArray()), new ClassReader(cw2.toByteArray())); - } - - static class ReferenceClassAdapter extends ClassAdapter { - - public ReferenceClassAdapter(final ClassVisitor cv) { - super(cv); - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); - - if (mv == null || (access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) > 0) { - return mv; - } - - return new LocalVariablesSorter(access, desc, mv); - } - } - - static class AdviceClassAdapter extends ClassAdapter { - - public AdviceClassAdapter(final ClassVisitor cv) { - super(cv); - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); - - if (mv == null || (access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) > 0) { - return mv; - } - - return new AdviceAdapter(mv, access, name, desc) { - @Override - protected void onMethodEnter() { - // mv.visitInsn(NOP); - // mv.visitInsn(NOP); - // mv.visitInsn(NOP); - } - - @Override - protected void onMethodExit(final int opcode) { - // mv.visitInsn(NOP); - // mv.visitInsn(NOP); - // mv.visitInsn(NOP); - // mv.visitInsn(NOP); - } - }; - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/AdviceAdapterUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/commons/AdviceAdapterUnitTest.java deleted file mode 100644 index bb6f89cf2..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/AdviceAdapterUnitTest.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.ClassAdapter; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * Simple example of using AdviceAdapter to implement tracing callback - * - * @author Eugene Kuleshov - */ -public class AdviceAdapterUnitTest extends AbstractTest { - - @Override - public void test() throws Exception { - Class c = getClass(); - String name = c.getName(); - AdvisingClassLoader cl = new AdvisingClassLoader(name + "$"); - Class cc = cl.loadClass(name + "$B"); - Method m = cc.getMethod("run", new Class[] { Integer.TYPE }); - try { - m.invoke(null, new Object[] { new Integer(0) }); - } catch (InvocationTargetException e) { - throw (Exception) e.getTargetException(); - } - } - - private static class AdvisingClassLoader extends ClassLoader { - private String prefix; - - public AdvisingClassLoader(final String prefix) throws IOException { - this.prefix = prefix; - } - - @Override - public Class loadClass(final String name) throws ClassNotFoundException { - if (name.startsWith(prefix)) { - try { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - ClassReader cr = new ClassReader(getClass().getResourceAsStream( - "/" + name.replace('.', '/') + ".class")); - cr.accept(new AdviceClassAdapter(cw), ClassReader.EXPAND_FRAMES); - byte[] bytecode = cw.toByteArray(); - return super.defineClass(name, bytecode, 0, bytecode.length); - } catch (IOException ex) { - throw new ClassNotFoundException("Load error: " + ex.toString(), ex); - } - } - return super.loadClass(name); - } - - } - - // test callback - private static int n = 0; - - public static void enter(final String msg) { - System.err.println(off().append("enter ").append(msg).toString()); - n++; - } - - public static void exit(final String msg) { - n--; - System.err.println(off().append("<").toString()); - } - - private static StringBuilder off() { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < n; i++) { - sb.append(" "); - } - return sb; - } - - static class AdviceClassAdapter extends ClassAdapter implements Opcodes { - private String cname; - - public AdviceClassAdapter(final ClassVisitor cv) { - super(cv); - } - - @Override - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - this.cname = name; - super.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); - - if (mv == null || (access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) > 0) { - return mv; - } - - return new AdviceAdapter(mv, access, name, desc) { - @Override - protected void onMethodEnter() { - mv.visitLdcInsn(cname + "." + name + desc); - mv.visitMethodInsn(INVOKESTATIC, "com/alibaba/citrus/asm/commons/AdviceAdapterUnitTest", "enter", - "(Ljava/lang/String;)V"); - } - - @Override - protected void onMethodExit(final int opcode) { - mv.visitLdcInsn(cname + "." + name + desc); - mv.visitMethodInsn(INVOKESTATIC, "com/alibaba/citrus/asm/commons/AdviceAdapterUnitTest", "exit", - "(Ljava/lang/String;)V"); - } - - }; - } - } - - // TEST CLASSES - - public static class A { - final String s; - - public A(final String s) { - this.s = s; - } - - public A(final A a) { - this.s = a.s; - } - } - - public static class B extends A { - - public B() { - super(new B("")); - test(this); - } - - public B(final A a) { - super(a); - test(this); - } - - public B(final String s) { - super(s == null ? new A("") : new A(s)); - test(this); - } - - private static A aa; - - public B(final String s, final A a) { - this(s == null ? aa = new A(s) : a); - A aa = new A(""); - test(aa); - } - - public B(final String s, final String s1) { - super(s != null ? new A(getA(s1).s) : new A(s)); - test(this); - } - - private void test(final Object b) { - } - - private static A getA(final String s) { - return new A(s); - } - - // execute all - public static void run(final int n) { - new B(); - new B(new A("")); - new B(new B()); - new B("", new A("")); - new B("", ""); - } - - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/AnalyzerAdapterTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/commons/AnalyzerAdapterTest.java deleted file mode 100644 index d7a632847..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/AnalyzerAdapterTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.ClassAdapter; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * AnalyzerAdapter tests. - * - * @author Eric Bruneton - */ -public class AnalyzerAdapterTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new AnalyzerAdapterTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - if (cr.readInt(4) != Opcodes.V1_6) { - try { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - cr = new ClassReader(cw.toByteArray()); - } catch (Exception e) { - return; - } - } - ClassWriter cw = new ClassWriter(0); - ClassVisitor cv = new ClassAdapter(cw) { - - private String owner; - - @Override - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - owner = name; - cv.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); - return new AnalyzerAdapter(owner, access, name, desc, mv); - } - }; - cr.accept(cv, ClassReader.EXPAND_FRAMES); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/CodeSizeEvaluatorTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/commons/CodeSizeEvaluatorTest.java deleted file mode 100644 index 7fb08e84b..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/CodeSizeEvaluatorTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.ClassAdapter; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; - -public class CodeSizeEvaluatorTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new CodeSizeEvaluatorTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - cr.accept(new ClassAdapter(new ClassWriter(0)) { - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); - return new CodeSizeEvaluator(mv) { - @Override - public void visitMaxs(final int maxStack, final int maxLocals) { - Label end = new Label(); - mv.visitLabel(end); - mv.visitMaxs(maxStack, maxLocals); - int size = end.getOffset(); - assertTrue(getMinSize() + " <= " + size + " <= " + getMaxSize(), getMinSize() <= size - && size <= getMaxSize()); - } - }; - } - }, 0); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/GASMifierClassVisitor.java b/common/asm/src/test/java/com/alibaba/citrus/asm/commons/GASMifierClassVisitor.java deleted file mode 100644 index 554db3242..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/GASMifierClassVisitor.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import java.io.FileInputStream; -import java.io.PrintWriter; - -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.util.ASMifierClassVisitor; - -/** - * Sub class of the ASMifier class visitor used to test GeneratorAdapter. - * - * @author Eric Bruneton - */ -public class GASMifierClassVisitor extends ASMifierClassVisitor { - - /** - * Prints the ASM source code to generate the given class to the standard - * output. - *

- * Usage: ASMifierClassVisitor [-debug] <fully qualified class name or - * class file name> - * - * @param args the command line arguments. - * @throws Exception if the class cannot be found, or if an IO exception - * occurs. - */ - public static void main(final String[] args) throws Exception { - int i = 0; - int flags = ClassReader.SKIP_DEBUG; - - boolean ok = true; - if (args.length < 1 || args.length > 2) { - ok = false; - } - if (ok && args[0].equals("-debug")) { - i = 1; - flags = 0; - if (args.length != 2) { - ok = false; - } - } - if (!ok) { - System.err.println("Prints the ASM code to generate the given class."); - System.err.println("Usage: GASMifierClassVisitor [-debug] " - + ""); - System.exit(-1); - } - ClassReader cr; - if (args[i].endsWith(".class")) { - cr = new ClassReader(new FileInputStream(args[i])); - } else { - cr = new ClassReader(args[i]); - } - cr.accept(new GASMifierClassVisitor(new PrintWriter(System.out)), getDefaultAttributes(), - ClassReader.EXPAND_FRAMES | flags); - } - - public GASMifierClassVisitor(final PrintWriter pw) { - super(pw); - } - - @Override - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - super.visit(version, access, name, signature, superName, interfaces); - int n; - if (name.lastIndexOf('/') != -1) { - n = 1; - } else { - n = 0; - } - text.set(n + 5, "ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);\n"); - text.set(n + 7, "GeneratorAdapter mg;\n"); - text.add(n + 1, "import com.alibaba.citrus.asm.commons.*;\n"); - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, - final String[] exceptions) { - buf.setLength(0); - buf.append("{\n"); - buf.append("mg = new GeneratorAdapter("); - buf.append(access); - buf.append(", "); - buf.append(GASMifierMethodVisitor.getMethod(name, desc)); - buf.append(", "); - if (signature == null) { - buf.append("null"); - } else { - buf.append('"').append(signature).append('"'); - } - buf.append(", "); - if (exceptions != null && exceptions.length > 0) { - buf.append("new Type[] {"); - for (int i = 0; i < exceptions.length; ++i) { - buf.append(i == 0 ? " " : ", "); - buf.append(GASMifierMethodVisitor.getType(exceptions[i])); - } - buf.append(" }"); - } else { - buf.append("null"); - } - buf.append(", cw);\n"); - text.add(buf.toString()); - GASMifierMethodVisitor acv = new GASMifierMethodVisitor(access, desc); - text.add(acv.getText()); - text.add("}\n"); - return new LocalVariablesSorter(access, desc, acv); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/GASMifierMethodVisitor.java b/common/asm/src/test/java/com/alibaba/citrus/asm/commons/GASMifierMethodVisitor.java deleted file mode 100644 index eb19354a2..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/GASMifierMethodVisitor.java +++ /dev/null @@ -1,1072 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; -import com.alibaba.citrus.asm.util.ASMifierAbstractVisitor; -import com.alibaba.citrus.asm.util.ASMifierAnnotationVisitor; - -/** - * A {@link MethodVisitor} that prints the ASM code that generates the methods - * it visits by using the GeneratorAdapter class. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public class GASMifierMethodVisitor extends ASMifierAbstractVisitor implements MethodVisitor, Opcodes { - - int access; - - Type[] argumentTypes; - - int firstLocal; - - Map locals; - - List localTypes; - - int lastOpcode = -1; - - HashMap labelNames; - - public GASMifierMethodVisitor(final int access, final String desc) { - super("mg"); - this.access = access; - this.labelNames = new HashMap(); - this.argumentTypes = Type.getArgumentTypes(desc); - int nextLocal = (Opcodes.ACC_STATIC & access) != 0 ? 0 : 1; - for (Type element : argumentTypes) { - nextLocal += element.getSize(); - } - this.firstLocal = nextLocal; - this.locals = new HashMap(); - this.localTypes = new ArrayList(); - } - - public AnnotationVisitor visitAnnotationDefault() { - buf.setLength(0); - buf.append("{\n").append("av0 = mg.visitAnnotationDefault();\n"); - text.add(buf.toString()); - ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0); - text.add(av.getText()); - text.add("}\n"); - return av; - } - - public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc, final boolean visible) { - buf.setLength(0); - buf.append("{\n").append("av0 = mg.visitParameterAnnotation(").append(parameter).append(", \""); - buf.append(desc); - buf.append("\", ").append(visible).append(");\n"); - text.add(buf.toString()); - ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0); - text.add(av.getText()); - text.add("}\n"); - return av; - } - - public void visitCode() { - text.add("mg.visitCode();\n"); - } - - public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, - final Object[] stack) { - buf.setLength(0); - switch (type) { - case Opcodes.F_NEW: - case Opcodes.F_FULL: - declareFrameTypes(nLocal, local); - declareFrameTypes(nStack, stack); - if (type == Opcodes.F_NEW) { - buf.append("mg.visitFrame(Opcodes.F_NEW, "); - } else { - buf.append("mg.visitFrame(Opcodes.F_FULL, "); - } - buf.append(nLocal).append(", new Object[] {"); - appendFrameTypes(nLocal, local); - buf.append("}, ").append(nStack).append(", new Object[] {"); - appendFrameTypes(nStack, stack); - buf.append("}"); - break; - case Opcodes.F_APPEND: - declareFrameTypes(nLocal, local); - buf.append("mg.visitFrame(Opcodes.F_APPEND,").append(nLocal).append(", new Object[] {"); - appendFrameTypes(nLocal, local); - buf.append("}, 0, null"); - break; - case Opcodes.F_CHOP: - buf.append("mg.visitFrame(Opcodes.F_CHOP,").append(nLocal).append(", null, 0, null"); - break; - case Opcodes.F_SAME: - buf.append("mg.visitFrame(Opcodes.F_SAME, 0, null, 0, null"); - break; - case Opcodes.F_SAME1: - declareFrameTypes(1, stack); - buf.append("mg.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"); - appendFrameTypes(1, stack); - buf.append("}"); - break; - } - buf.append(");\n"); - text.add(buf.toString()); - } - - public void visitInsn(final int opcode) { - buf.setLength(0); - switch (opcode) { - case IRETURN: - case LRETURN: - case FRETURN: - case DRETURN: - case ARETURN: - case RETURN: - buf.append("mg.returnValue();\n"); - break; - case NOP: - buf.append("mg.visitInsn(Opcodes.NOP);\n"); - break; - case ACONST_NULL: - buf.append("mg.push((String)null);\n"); - break; - case ICONST_M1: - case ICONST_0: - case ICONST_1: - case ICONST_2: - case ICONST_3: - case ICONST_4: - case ICONST_5: - buf.append("mg.push(").append(opcode - ICONST_0).append(");\n"); - break; - case LCONST_0: - case LCONST_1: - buf.append("mg.push(").append(opcode - LCONST_0).append("L);\n"); - break; - case FCONST_0: - case FCONST_1: - case FCONST_2: - buf.append("mg.push(").append(opcode - FCONST_0).append("f);\n"); - break; - case DCONST_0: - case DCONST_1: - buf.append("mg.push(").append(opcode - DCONST_0).append("d);\n"); - break; - case POP: - buf.append("mg.pop();\n"); - break; - case POP2: - buf.append("mg.pop2();\n"); - break; - case DUP: - buf.append("mg.dup();\n"); - break; - case DUP_X1: - buf.append("mg.dupX1();\n"); - break; - case DUP_X2: - buf.append("mg.dupX2();\n"); - break; - case DUP2: - buf.append("mg.dup2();\n"); - break; - case DUP2_X1: - buf.append("mg.dup2X1();\n"); - break; - case DUP2_X2: - buf.append("mg.dup2X2();\n"); - break; - case SWAP: - buf.append("mg.swap();\n"); - break; - case MONITORENTER: - buf.append("mg.monitorEnter();\n"); - break; - case MONITOREXIT: - buf.append("mg.monitorExit();\n"); - break; - case ARRAYLENGTH: - buf.append("mg.arrayLength();\n"); - break; - case IALOAD: - buf.append("mg.arrayLoad(Type.INT_TYPE);\n"); - break; - case LALOAD: - buf.append("mg.arrayLoad(Type.LONG_TYPE);\n"); - break; - case FALOAD: - buf.append("mg.arrayLoad(Type.FLOAT_TYPE);\n"); - break; - case DALOAD: - buf.append("mg.arrayLoad(Type.DOUBLE_TYPE);\n"); - break; - case AALOAD: - buf.append("mg.arrayLoad(" + getType("java/lang/Object") + ");\n"); - break; - case BALOAD: - buf.append("mg.arrayLoad(Type.BYTE_TYPE);\n"); - break; - case CALOAD: - buf.append("mg.arrayLoad(Type.CHAR_TYPE);\n"); - break; - case SALOAD: - buf.append("mg.arrayLoad(Type.SHORT_TYPE);\n"); - break; - case IASTORE: - buf.append("mg.arrayStore(Type.INT_TYPE);\n"); - break; - case LASTORE: - buf.append("mg.arrayStore(Type.LONG_TYPE);\n"); - break; - case FASTORE: - buf.append("mg.arrayStore(Type.FLOAT_TYPE);\n"); - break; - case DASTORE: - buf.append("mg.arrayStore(Type.DOUBLE_TYPE);\n"); - break; - case AASTORE: - buf.append("mg.arrayStore(" + getType("java/lang/Object") + ");\n"); - break; - case BASTORE: - buf.append("mg.arrayStore(Type.BYTE_TYPE);\n"); - break; - case CASTORE: - buf.append("mg.arrayStore(Type.CHAR_TYPE);\n"); - break; - case SASTORE: - buf.append("mg.arrayStore(Type.SHORT_TYPE);\n"); - break; - case IADD: - buf.append("mg.math(GeneratorAdapter.ADD, Type.INT_TYPE);\n"); - break; - case LADD: - buf.append("mg.math(GeneratorAdapter.ADD, Type.LONG_TYPE);\n"); - break; - case FADD: - buf.append("mg.math(GeneratorAdapter.ADD, Type.FLOAT_TYPE);\n"); - break; - case DADD: - buf.append("mg.math(GeneratorAdapter.ADD, Type.DOUBLE_TYPE);\n"); - break; - case ISUB: - buf.append("mg.math(GeneratorAdapter.SUB, Type.INT_TYPE);\n"); - break; - case LSUB: - buf.append("mg.math(GeneratorAdapter.SUB, Type.LONG_TYPE);\n"); - break; - case FSUB: - buf.append("mg.math(GeneratorAdapter.SUB, Type.FLOAT_TYPE);\n"); - break; - case DSUB: - buf.append("mg.math(GeneratorAdapter.SUB, Type.DOUBLE_TYPE);\n"); - break; - case IMUL: - buf.append("mg.math(GeneratorAdapter.MUL, Type.INT_TYPE);\n"); - break; - case LMUL: - buf.append("mg.math(GeneratorAdapter.MUL, Type.LONG_TYPE);\n"); - break; - case FMUL: - buf.append("mg.math(GeneratorAdapter.MUL, Type.FLOAT_TYPE);\n"); - break; - case DMUL: - buf.append("mg.math(GeneratorAdapter.MUL, Type.DOUBLE_TYPE);\n"); - break; - case IDIV: - buf.append("mg.math(GeneratorAdapter.DIV, Type.INT_TYPE);\n"); - break; - case LDIV: - buf.append("mg.math(GeneratorAdapter.DIV, Type.LONG_TYPE);\n"); - break; - case FDIV: - buf.append("mg.math(GeneratorAdapter.DIV, Type.FLOAT_TYPE);\n"); - break; - case DDIV: - buf.append("mg.math(GeneratorAdapter.DIV, Type.DOUBLE_TYPE);\n"); - break; - case IREM: - buf.append("mg.math(GeneratorAdapter.REM, Type.INT_TYPE);\n"); - break; - case LREM: - buf.append("mg.math(GeneratorAdapter.REM, Type.LONG_TYPE);\n"); - break; - case FREM: - buf.append("mg.math(GeneratorAdapter.REM, Type.FLOAT_TYPE);\n"); - break; - case DREM: - buf.append("mg.math(GeneratorAdapter.REM, Type.DOUBLE_TYPE);\n"); - break; - case INEG: - buf.append("mg.math(GeneratorAdapter.NEG, Type.INT_TYPE);\n"); - break; - case LNEG: - buf.append("mg.math(GeneratorAdapter.NEG, Type.LONG_TYPE);\n"); - break; - case FNEG: - buf.append("mg.math(GeneratorAdapter.NEG, Type.FLOAT_TYPE);\n"); - break; - case DNEG: - buf.append("mg.math(GeneratorAdapter.NEG, Type.DOUBLE_TYPE);\n"); - break; - case ISHL: - buf.append("mg.math(GeneratorAdapter.SHL, Type.INT_TYPE);\n"); - break; - case LSHL: - buf.append("mg.math(GeneratorAdapter.SHL, Type.LONG_TYPE);\n"); - break; - case ISHR: - buf.append("mg.math(GeneratorAdapter.SHR, Type.INT_TYPE);\n"); - break; - case LSHR: - buf.append("mg.math(GeneratorAdapter.SHR, Type.LONG_TYPE);\n"); - break; - case IUSHR: - buf.append("mg.math(GeneratorAdapter.USHR, Type.INT_TYPE);\n"); - break; - case LUSHR: - buf.append("mg.math(GeneratorAdapter.USHR, Type.LONG_TYPE);\n"); - break; - case IAND: - buf.append("mg.math(GeneratorAdapter.AND, Type.INT_TYPE);\n"); - break; - case LAND: - buf.append("mg.math(GeneratorAdapter.AND, Type.LONG_TYPE);\n"); - break; - case IOR: - buf.append("mg.math(GeneratorAdapter.OR, Type.INT_TYPE);\n"); - break; - case LOR: - buf.append("mg.math(GeneratorAdapter.OR, Type.LONG_TYPE);\n"); - break; - case IXOR: - buf.append("mg.math(GeneratorAdapter.XOR, Type.INT_TYPE);\n"); - break; - case LXOR: - buf.append("mg.math(GeneratorAdapter.XOR, Type.LONG_TYPE);\n"); - break; - case ATHROW: - buf.append("mg.throwException();\n"); - break; - case I2L: - buf.append("mg.cast(Type.INT_TYPE, Type.LONG_TYPE);\n"); - break; - case I2F: - buf.append("mg.cast(Type.INT_TYPE, Type.FLOAT_TYPE);\n"); - break; - case I2D: - buf.append("mg.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);\n"); - break; - case L2I: - buf.append("mg.cast(Type.LONG_TYPE, Type.INT_TYPE);\n"); - break; - case L2F: - buf.append("mg.cast(Type.LONG_TYPE, Type.FLOAT_TYPE);\n"); - break; - case L2D: - buf.append("mg.cast(Type.LONG_TYPE, Type.DOUBLE_TYPE);\n"); - break; - case F2I: - buf.append("mg.cast(Type.FLOAT_TYPE, Type.INT_TYPE);\n"); - break; - case F2L: - buf.append("mg.cast(Type.FLOAT_TYPE, Type.LONG_TYPE);\n"); - break; - case F2D: - buf.append("mg.cast(Type.FLOAT_TYPE, Type.DOUBLE_TYPE);\n"); - break; - case D2I: - buf.append("mg.cast(Type.DOUBLE_TYPE, Type.INT_TYPE);\n"); - break; - case D2L: - buf.append("mg.cast(Type.DOUBLE_TYPE, Type.LONG_TYPE);\n"); - break; - case D2F: - buf.append("mg.cast(Type.DOUBLE_TYPE, Type.FLOAT_TYPE);\n"); - break; - case I2B: - // TODO detect if previous element in 'text' is a cast, - // for possible optimisations (e.g. cast(F,I) cast(I,B) = - // cast(F,B)) - buf.append("mg.cast(Type.INT_TYPE, Type.BYTE_TYPE);\n"); - break; - case I2C: // idem - buf.append("mg.cast(Type.INT_TYPE, Type.CHAR_TYPE);\n"); - break; - case I2S: // idem - buf.append("mg.cast(Type.INT_TYPE, Type.SHORT_TYPE);\n"); - break; - case LCMP: - case FCMPL: - case FCMPG: - case DCMPL: - case DCMPG: - // TODO detect xCMPy IF_ICMP -> ifCmp(..., ..., label) - buf.append("mg.visitInsn(").append(OPCODES[opcode]).append(");\n"); - break; - default: - throw new RuntimeException("unexpected case"); - } - text.add(buf.toString()); - lastOpcode = opcode; - } - - public void visitIntInsn(final int opcode, final int operand) { - buf.setLength(0); - if (opcode == NEWARRAY) { - String type; - switch (operand) { - case T_BOOLEAN: - type = "Type.BOOLEAN_TYPE"; - break; - case T_CHAR: - type = "Type.CHAR_TYPE"; - break; - case T_FLOAT: - type = "Type.FLOAT_TYPE"; - break; - case T_DOUBLE: - type = "Type.DOUBLE_TYPE"; - break; - case T_BYTE: - type = "Type.BYTE_TYPE"; - break; - case T_SHORT: - type = "Type.SHORT_TYPE"; - break; - case T_INT: - type = "Type.INT_TYPE"; - break; - case T_LONG: - type = "Type.LONG_TYPE"; - break; - default: - throw new RuntimeException("unexpected case"); - } - buf.append("mg.newArray(").append(type).append(");\n"); - } else { - buf.append("mg.push(").append(operand).append(");\n"); - } - text.add(buf.toString()); - lastOpcode = opcode; - } - - public void visitVarInsn(final int opcode, final int var) { - buf.setLength(0); - try { - switch (opcode) { - case RET: - buf.append("mg.ret("); - if (var < firstLocal) { - buf.append(var); - } else { - int v = generateNewLocal(var, "Type.INT_TYPE"); - buf.append("local").append(v); - } - buf.append(");\n"); - break; - - case ILOAD: - generateLoadLocal(var, "Type.INT_TYPE"); - break; - case LLOAD: - generateLoadLocal(var, "Type.LONG_TYPE"); - break; - case FLOAD: - generateLoadLocal(var, "Type.FLOAT_TYPE"); - break; - case DLOAD: - generateLoadLocal(var, "Type.DOUBLE_TYPE"); - break; - case ALOAD: - generateLoadLocal(var, getType("java/lang/Object")); - break; - - case ISTORE: - generateStoreLocal(var, "Type.INT_TYPE"); - break; - case LSTORE: - generateStoreLocal(var, "Type.LONG_TYPE"); - break; - case FSTORE: - generateStoreLocal(var, "Type.FLOAT_TYPE"); - break; - case DSTORE: - generateStoreLocal(var, "Type.DOUBLE_TYPE"); - break; - case ASTORE: - generateStoreLocal(var, getType("java/lang/Object")); - break; - - default: - throw new RuntimeException("unexpected case"); - } - } catch (Exception e) { - buf.append("mg.visitVarInsn(" + OPCODES[opcode] + ", " + var + ");\n"); - } - text.add(buf.toString()); - lastOpcode = opcode; - } - - private void generateLoadLocal(final int var, final String type) { - if (var < firstLocal) { - if (var == 0 && (access & ACC_STATIC) == 0) { - buf.append("mg.loadThis();\n"); - } else { - int index = getArgIndex(var); - buf.append("mg.loadArg(").append(index).append(");\n"); - } - } else { - int local = generateNewLocal(var, type); - buf.append("mg.loadLocal(local").append(local); - if (!type.equals(localTypes.get(local))) { - localTypes.set(local, type); - buf.append(", ").append(type); - } - buf.append(");\n"); - } - } - - private void generateStoreLocal(final int var, final String type) { - if (var < firstLocal) { - if (var == 0 && (access & ACC_STATIC) == 0) { - buf.append("mg.visitVarInsn(ASTORE, " + var + ");\n"); - } else { - int index = getArgIndex(var); - buf.append("mg.storeArg(").append(index).append(");\n"); - } - } else { - int local = generateNewLocal(var, type); - buf.append("mg.storeLocal(local").append(local); - if (!type.equals(localTypes.get(local))) { - localTypes.set(local, type); - buf.append(", ").append(type); - } - buf.append(");\n"); - } - } - - private int generateNewLocal(final int var, final String type) { - Integer i = (Integer) locals.get(new Integer(var)); - if (i == null) { - int local = locals.size(); - locals.put(new Integer(var), new Integer(local)); - localTypes.add(type); - buf.append("int local" + local + " = mg.newLocal(" + type + ");\n"); - return local; - } - return i.intValue(); - } - - private int getArgIndex(final int var) { - int nextLocal = (Opcodes.ACC_STATIC & access) != 0 ? 0 : 1; - int i = 0; - while (nextLocal != var) { - nextLocal += argumentTypes[i++].getSize(); - } - return i; - } - - public void visitTypeInsn(final int opcode, final String type) { - String typ = getType(type); - buf.setLength(0); - if (opcode == NEW) { - buf.append("mg.newInstance(").append(typ).append(");\n"); - } else if (opcode == ANEWARRAY) { - buf.append("mg.newArray(").append(typ).append(");\n"); - } else if (opcode == CHECKCAST) { - buf.append("mg.checkCast(").append(typ).append(");\n"); - } else if (opcode == INSTANCEOF) { - buf.append("mg.instanceOf(").append(typ).append(");\n"); - } - text.add(buf.toString()); - lastOpcode = opcode; - } - - public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { - buf.setLength(0); - switch (opcode) { - case GETFIELD: - buf.append("mg.getField("); - break; - case PUTFIELD: - buf.append("mg.putField("); - break; - case GETSTATIC: - buf.append("mg.getStatic("); - break; - case PUTSTATIC: - buf.append("mg.putStatic("); - break; - default: - throw new RuntimeException("unexpected case"); - } - buf.append(getType(owner)); - buf.append(", \""); - buf.append(name); - buf.append("\", "); - buf.append(getDescType(desc)); - buf.append(");\n"); - text.add(buf.toString()); - lastOpcode = opcode; - } - - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - buf.setLength(0); - switch (opcode) { - case INVOKEVIRTUAL: - buf.append("mg.invokeVirtual("); - break; - case INVOKESPECIAL: - buf.append("mg.invokeConstructor("); - break; - case INVOKESTATIC: - buf.append("mg.invokeStatic("); - break; - case INVOKEINTERFACE: - buf.append("mg.invokeInterface("); - break; - default: - throw new RuntimeException("unexpected case"); - } - if (owner.charAt(0) == '[') { - buf.append(getDescType(owner)); - } else { - buf.append(getType(owner)); - } - buf.append(", "); - buf.append(getMethod(name, desc)); - buf.append(");\n"); - text.add(buf.toString()); - lastOpcode = opcode; - } - - public void visitJumpInsn(final int opcode, final Label label) { - buf.setLength(0); - declareLabel(label); - if (opcode == GOTO || opcode == IFNULL || opcode == IFNONNULL) { - if (opcode == GOTO) { - buf.append("mg.goTo("); - } - if (opcode == IFNULL) { - buf.append("mg.ifNull("); - } - if (opcode == IFNONNULL) { - buf.append("mg.ifNonNull("); - } - appendLabel(label); - buf.append(");\n"); - } else if (opcode == IF_ICMPEQ) { - buf.append("mg.ifICmp(GeneratorAdapter.EQ, "); - appendLabel(label); - buf.append(");\n"); - } else if (opcode == IF_ICMPNE) { - buf.append("mg.ifICmp(GeneratorAdapter.NE, "); - appendLabel(label); - buf.append(");\n"); - } else if (opcode == IF_ICMPLT) { - buf.append("mg.ifICmp(GeneratorAdapter.LT, "); - appendLabel(label); - buf.append(");\n"); - } else if (opcode == IF_ICMPGE) { - buf.append("mg.ifICmp(GeneratorAdapter.GE, "); - appendLabel(label); - buf.append(");\n"); - } else if (opcode == IF_ICMPGT) { - buf.append("mg.ifICmp(GeneratorAdapter.GT, "); - appendLabel(label); - buf.append(");\n"); - } else if (opcode == IF_ICMPLE) { - buf.append("mg.ifICmp(GeneratorAdapter.LE, "); - appendLabel(label); - buf.append(");\n"); - } else if (opcode == IF_ACMPEQ) { - buf.append("mg.ifCmp("); - buf.append(getType("java/lang/Object")).append(", ").append("GeneratorAdapter.EQ, "); - appendLabel(label); - buf.append(");\n"); - } else if (opcode == IF_ACMPNE) { - buf.append("mg.ifCmp("); - buf.append(getType("java/lang/Object")).append(", ").append("GeneratorAdapter.NE, "); - appendLabel(label); - buf.append(");\n"); - } else if (opcode == IFEQ) { - buf.append("mg.ifZCmp(GeneratorAdapter.EQ, "); - appendLabel(label); - buf.append(");\n"); - } else if (opcode == IFNE) { - buf.append("mg.ifZCmp(GeneratorAdapter.NE, "); - appendLabel(label); - buf.append(");\n"); - } else if (opcode == IFLT) { - buf.append("mg.ifZCmp(GeneratorAdapter.LT, "); - appendLabel(label); - buf.append(");\n"); - } else if (opcode == IFGE) { - buf.append("mg.ifZCmp(GeneratorAdapter.GE, "); - appendLabel(label); - buf.append(");\n"); - } else if (opcode == IFGT) { - buf.append("mg.ifZCmp(GeneratorAdapter.GT, "); - appendLabel(label); - buf.append(");\n"); - } else if (opcode == IFLE) { - buf.append("mg.ifZCmp(GeneratorAdapter.LE, "); - appendLabel(label); - buf.append(");\n"); - } else { - buf.append("mg.visitJumpInsn(").append(OPCODES[opcode]).append(", "); - appendLabel(label); - buf.append(");\n"); - } - text.add(buf.toString()); - lastOpcode = opcode; - } - - public void visitLabel(final Label label) { - buf.setLength(0); - declareLabel(label); - buf.append("mg.mark("); - appendLabel(label); - buf.append(");\n"); - text.add(buf.toString()); - lastOpcode = -1; - } - - public void visitLdcInsn(final Object cst) { - buf.setLength(0); - buf.append("mg.push("); - if (cst == null) { - buf.append("(String)null"); - } else if (cst instanceof Long) { - buf.append(cst + "L"); - } else if (cst instanceof Float) { - float f = ((Float) cst).floatValue(); - if (Float.isNaN(f)) { - buf.append("Float.NaN"); - } else if (Float.isInfinite(f)) { - buf.append(f > 0 ? "Float.POSITIVE_INFINITY" : "Float.NEGATIVE_INFINITY"); - } else { - buf.append(cst + "f"); - } - } else if (cst instanceof Double) { - double d = ((Double) cst).doubleValue(); - if (Double.isNaN(d)) { - buf.append("Double.NaN"); - } else if (Double.isInfinite(d)) { - buf.append(d > 0 ? "Double.POSITIVE_INFINITY" : "Double.NEGATIVE_INFINITY"); - } else { - buf.append(cst + "d"); - } - } else if (cst instanceof String) { - appendString(buf, (String) cst); - } else if (cst instanceof Type) { - buf.append("Type.getType(\"").append(cst).append("\")"); - } else { - buf.append(cst); - } - buf.append(");\n"); - text.add(buf.toString()); - lastOpcode = LDC; - } - - public void visitIincInsn(final int var, final int increment) { - buf.setLength(0); - if (var < firstLocal) { - buf.append("mg.iinc(").append(var); - } else { - int v = generateNewLocal(var, "Type.INT_TYPE"); - buf.append("mg.iinc(local").append(v); - } - buf.append(", ").append(increment).append(");\n"); - text.add(buf.toString()); - lastOpcode = IINC; - } - - public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label labels[]) { - buf.setLength(0); - for (int i = 0; i < labels.length; ++i) { - declareLabel(labels[i]); - } - declareLabel(dflt); - - buf.append("mg.visitTableSwitchInsn(").append(min).append(", ").append(max).append(", "); - appendLabel(dflt); - buf.append(", new Label[] {"); - for (int i = 0; i < labels.length; ++i) { - buf.append(i == 0 ? " " : ", "); - appendLabel(labels[i]); - } - buf.append(" }); // TODO\n"); - text.add(buf.toString()); - lastOpcode = TABLESWITCH; - } - - public void visitLookupSwitchInsn(final Label dflt, final int keys[], final Label labels[]) { - buf.setLength(0); - for (int i = 0; i < labels.length; ++i) { - declareLabel(labels[i]); - } - declareLabel(dflt); - - buf.append("mg.visitLookupSwitchInsn("); - appendLabel(dflt); - buf.append(", new int[] {"); - for (int i = 0; i < keys.length; ++i) { - buf.append(i == 0 ? " " : ", ").append(keys[i]); - } - buf.append(" }, new Label[] {"); - for (int i = 0; i < labels.length; ++i) { - buf.append(i == 0 ? " " : ", "); - appendLabel(labels[i]); - } - buf.append(" }); // TODO\n"); - text.add(buf.toString()); - lastOpcode = LOOKUPSWITCH; - } - - public void visitMultiANewArrayInsn(final String desc, final int dims) { - buf.setLength(0); - buf.append("mg.visitMultiANewArrayInsn(\""); - buf.append(desc); - buf.append("\", ").append(dims).append(");\n"); - text.add(buf.toString()); - lastOpcode = MULTIANEWARRAY; - } - - public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type) { - buf.setLength(0); - declareLabel(start); - declareLabel(end); - declareLabel(handler); - buf.append("mg.visitTryCatchBlock("); - appendLabel(start); - buf.append(", "); - appendLabel(end); - buf.append(", "); - appendLabel(handler); - buf.append(", "); - if (type == null) { - buf.append("null"); - } else { - buf.append('"').append(type).append('"'); - } - buf.append("); // TODO\n"); - text.add(buf.toString()); - lastOpcode = -1; - } - - public void visitLocalVariable(final String name, final String desc, final String signature, final Label start, - final Label end, final int index) { - buf.setLength(0); - buf.append("mg.visitLocalVariable(\""); - buf.append(name); - buf.append("\", \""); - buf.append(desc); - buf.append("\", "); - if (signature == null) { - buf.append("null"); - } else { - buf.append('"').append(signature).append('"'); - } - buf.append(", "); - appendLabel(start); - buf.append(", "); - appendLabel(end); - buf.append(", ").append(index).append(");\n"); - text.add(buf.toString()); - lastOpcode = -1; - } - - public void visitLineNumber(final int line, final Label start) { - buf.setLength(0); - buf.append("mg.visitLineNumber(").append(line).append(", "); - appendLabel(start); - buf.append(");\n"); - text.add(buf.toString()); - lastOpcode = -1; - } - - public void visitMaxs(final int maxStack, final int maxLocals) { - text.add("mg.endMethod();\n"); - lastOpcode = -1; - } - - public void visitEnd() { - // does nothing - } - - static String getType(final String internalName) { - return "Type.getObjectType(\"" + internalName + "\")"; - } - - static String getDescType(final String desc) { - if (desc.equals("Z")) { - return "Type.BOOLEAN_TYPE"; - } - if (desc.equals("B")) { - return "Type.BYTE_TYPE"; - } - if (desc.equals("C")) { - return "Type.CHAR_TYPE"; - } - if (desc.equals("D")) { - return "Type.DOUBLE_TYPE"; - } - if (desc.equals("F")) { - return "Type.FLOAT_TYPE"; - } - if (desc.equals("I")) { - return "Type.INT_TYPE"; - } - if (desc.equals("J")) { - return "Type.LONG_TYPE"; - } - if (desc.equals("S")) { - return "Type.SHORT_TYPE"; - } - if (desc.equals("V")) { - return "Type.VOID_TYPE"; - } - return "Type.getType(\"" + desc + "\")"; - } - - static String getMethod(final String name, final String desc) { - Type rt = Type.getReturnType(desc); - Type[] argt = Type.getArgumentTypes(desc); - StringBuilder buf = new StringBuilder(); - buf.append("Method.getMethod(\""); - buf.append(rt.getClassName()).append(' '); - buf.append(name).append('('); - for (int i = 0; i < argt.length; ++i) { - if (i > 0) { - buf.append(','); - } - buf.append(argt[i].getClassName()); - } - buf.append(")\")"); - return buf.toString(); - } - - private void declareFrameTypes(final int n, final Object[] o) { - for (int i = 0; i < n; ++i) { - if (o[i] instanceof Label) { - declareLabel((Label) o[i]); - } - } - } - - private void appendFrameTypes(final int n, final Object[] o) { - for (int i = 0; i < n; ++i) { - if (i > 0) { - buf.append(", "); - } - if (o[i] instanceof String) { - buf.append('"').append(o[i]).append('"'); - } else if (o[i] instanceof Integer) { - switch (((Integer) o[i]).intValue()) { - case 0: - buf.append("Opcodes.TOP"); - break; - case 1: - buf.append("Opcodes.INTEGER"); - break; - case 2: - buf.append("Opcodes.FLOAT"); - break; - case 3: - buf.append("Opcodes.DOUBLE"); - break; - case 4: - buf.append("Opcodes.LONG"); - break; - case 5: - buf.append("Opcodes.NULL"); - break; - case 6: - buf.append("Opcodes.UNINITIALIZED_THIS"); - break; - } - } else { - appendLabel((Label) o[i]); - } - } - } - - /** - * Appends a declaration of the given label to {@link #buf buf}. This - * declaration is of the form "Label lXXX = new Label();". Does nothing if - * the given label has already been declared. - * - * @param l a label. - */ - private void declareLabel(final Label l) { - String name = (String) labelNames.get(l); - if (name == null) { - name = "label" + labelNames.size(); - labelNames.put(l, name); - buf.append("Label ").append(name).append(" = mg.newLabel();\n"); - } - } - - /** - * Appends the name of the given label to {@link #buf buf}. The given label - * must already have a name. One way to ensure this is to always call - * {@link #declareLabel declared} before calling this method. - * - * @param l a label. - */ - private void appendLabel(final Label l) { - buf.append((String) labelNames.get(l)); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/GASMifierTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/commons/GASMifierTest.java deleted file mode 100644 index 985b55947..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/GASMifierTest.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import java.io.PrintWriter; -import java.io.StringReader; -import java.io.StringWriter; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; - -import junit.framework.TestSuite; - -import org.codehaus.janino.ClassLoaderIClassLoader; -import org.codehaus.janino.DebuggingInformation; -import org.codehaus.janino.IClassLoader; -import org.codehaus.janino.Parser; -import org.codehaus.janino.Scanner; -import org.codehaus.janino.UnitCompiler; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.AsmTestParams; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.ClassAdapter; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.MethodAdapter; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.attrs.CodeComment; -import com.alibaba.citrus.asm.attrs.Comment; - -/** - * GASMifier tests. - * - * @author Eugene Kuleshov - * @author Eric Bruneton - */ -public class GASMifierTest extends AbstractTest { - - public static final Compiler COMPILER = new Compiler(); - - private final static TestClassLoader LOADER = new TestClassLoader(); - - public static TestSuite suite() throws Exception { - return new GASMifierTest().getSuite(new AsmTestParams("java.lang")); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - - if (cr.b.length > 20000) { - return; - } - - StringWriter sw = new StringWriter(); - GASMifierClassVisitor cv = new GASMifierClassVisitor(new PrintWriter(sw)); - cr.accept(cv, new Attribute[] { new Comment(), new CodeComment() }, ClassReader.EXPAND_FRAMES); - - String generated = sw.toString(); - - byte[] generatorClassData; - try { - generatorClassData = COMPILER.compile(n, generated); - } catch (Exception ex) { - trace(generated); - throw ex; - } - - ClassWriter cw = new ClassWriter(0); - cr.accept(new ClassAdapter(cw) { - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - return new LocalVariablesSorter(access, desc, super.visitMethod(access, name, desc, signature, - exceptions)); - } - }, new Attribute[] { new Comment(), new CodeComment() }, ClassReader.EXPAND_FRAMES); - cr = new ClassReader(cw.toByteArray()); - - String nd = n + "Dump"; - if (n.indexOf('.') != -1) { - nd = "asm." + nd; - } - - Class c = LOADER.defineClass(nd, generatorClassData); - Method m = c.getMethod("dump", new Class[0]); - byte[] b; - try { - b = (byte[]) m.invoke(null, new Object[0]); - } catch (InvocationTargetException ex) { - trace(generated); - throw (Exception) ex.getTargetException(); - } - - try { - assertEquals(cr, new ClassReader(b), new Filter(), new Filter()); - } catch (Throwable e) { - trace(generated); - assertEquals(cr, new ClassReader(b), new Filter(), new Filter()); - } - } - - private void trace(final String generated) { - if (System.getProperty("asm.test.class") != null) { - System.err.println(generated); - } - } - - private static class TestClassLoader extends ClassLoader { - - public Class defineClass(final String name, final byte[] b) { - return defineClass(name, b, 0, b.length); - } - } - - private static class Compiler { - - final static IClassLoader CL = new ClassLoaderIClassLoader(new URLClassLoader(new URL[0])); - - public byte[] compile(final String name, final String source) throws Exception { - Parser p = new Parser(new Scanner(name, new StringReader(source))); - UnitCompiler uc = new UnitCompiler(p.parseCompilationUnit(), CL); - return uc.compileUnit(DebuggingInformation.ALL)[0].toByteArray(); - } - } - - private static class Filter extends ClassAdapter { - - public Filter() { - super(null); - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - return new MethodAdapter(super.visitMethod(access, name, desc, signature, exceptions)) { - @Override - public void visitMaxs(final int maxStack, final int maxLocals) { - super.visitMaxs(0, 0); - } - }; - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/JSRInlinerAdapterTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/commons/JSRInlinerAdapterTest.java deleted file mode 100644 index c5daa3abf..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/JSRInlinerAdapterTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.ClassAdapter; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * JSRInliner tests. - * - * @author Eric Bruneton - */ -public class JSRInlinerAdapterTest extends AbstractTest { - - private final static TestClassLoader LOADER = new TestClassLoader(); - - public static TestSuite suite() throws Exception { - return new JSRInlinerAdapterTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - ClassWriter cw = new ClassWriter(0); - cr.accept(new ClassAdapter(cw) { - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); - return new JSRInlinerAdapter(mv, access, name, desc, signature, exceptions); - } - }, 0); - byte[] b = cw.toByteArray(); - try { - LOADER.defineClass(n, b); - } catch (ClassFormatError cfe) { - fail(cfe.getMessage()); - } catch (Throwable ignored) { - } - } - - // ------------------------------------------------------------------------ - - static class TestClassLoader extends ClassLoader { - - public Class defineClass(final String name, final byte[] b) { - return defineClass(name, b, 0, b.length); - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/JSRInlinerAdapterUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/commons/JSRInlinerAdapterUnitTest.java deleted file mode 100644 index 2f1c07e4f..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/JSRInlinerAdapterUnitTest.java +++ /dev/null @@ -1,1878 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import junit.framework.TestCase; - -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.tree.MethodNode; -import com.alibaba.citrus.asm.util.TraceMethodVisitor; - -/** - * JsrInlinerTest - * - * @author Eugene Kuleshov, Niko Matsakis, Eric Bruneton - */ -public class JSRInlinerAdapterUnitTest extends TestCase { - - private JSRInlinerAdapter jsr; - private MethodNode exp; - private MethodVisitor current; - - @Override - protected void setUp() throws Exception { - super.setUp(); - jsr = new JSRInlinerAdapter(null, 0, "m", "()V", null, null) { - @Override - public void visitEnd() { - System.err.println("started w/ method:" + name); - TraceMethodVisitor mv = new TraceMethodVisitor(); - for (int i = 0; i < instructions.size(); ++i) { - instructions.get(i).accept(mv); - System.err.print(Integer.toString(i + 100000).substring(1)); - System.err.print(" : " + mv.text.get(i)); - } - super.visitEnd(); - System.err.println("finished w/ method:" + name); - } - }; - exp = new MethodNode(0, "m", "()V", null, null); - } - - private void setCurrent(final MethodVisitor cv) { - this.current = cv; - } - - private void ICONST_0() { - this.current.visitInsn(Opcodes.ICONST_0); - } - - private void ISTORE(final int var) { - this.current.visitVarInsn(Opcodes.ISTORE, var); - } - - private void ALOAD(final int var) { - this.current.visitVarInsn(Opcodes.ALOAD, var); - } - - private void ILOAD(final int var) { - this.current.visitVarInsn(Opcodes.ILOAD, var); - } - - private void ASTORE(final int var) { - this.current.visitVarInsn(Opcodes.ASTORE, var); - } - - private void RET(final int var) { - this.current.visitVarInsn(Opcodes.RET, var); - } - - private void ATHROW() { - this.current.visitInsn(Opcodes.ATHROW); - } - - private void ACONST_NULL() { - this.current.visitInsn(Opcodes.ACONST_NULL); - } - - private void RETURN() { - this.current.visitInsn(Opcodes.RETURN); - } - - private void LABEL(final Label l) { - this.current.visitLabel(l); - } - - private void IINC(final int var, final int amnt) { - this.current.visitIincInsn(var, amnt); - } - - private void GOTO(final Label l) { - this.current.visitJumpInsn(Opcodes.GOTO, l); - } - - private void JSR(final Label l) { - this.current.visitJumpInsn(Opcodes.JSR, l); - } - - private void IFNONNULL(final Label l) { - this.current.visitJumpInsn(Opcodes.IFNONNULL, l); - } - - private void IFNE(final Label l) { - this.current.visitJumpInsn(Opcodes.IFNE, l); - } - - private void TRYCATCH(final Label start, final Label end, final Label handler) { - this.current.visitTryCatchBlock(start, end, handler, null); - } - - private void LINE(final int line, final Label start) { - this.current.visitLineNumber(line, start); - } - - private void LOCALVAR(final String name, final String desc, final int index, final Label start, final Label end) { - this.current.visitLocalVariable(name, desc, null, start, end, index); - } - - private void END(final int maxStack, final int maxLocals) { - this.current.visitMaxs(maxStack, maxLocals); - this.current.visitEnd(); - ClassWriter cw = new ClassWriter(0); - cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, "C", null, "java/lang/Object", null); - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", "()V", null, null); - mv.visitCode(); - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "", "()V"); - mv.visitInsn(Opcodes.RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - ((MethodNode) this.current).accept(cw); - cw.visitEnd(); - byte[] b = cw.toByteArray(); - try { - TestClassLoader loader = new TestClassLoader(); - Class c = loader.defineClass("C", b); - c.newInstance(); - } catch (Throwable t) { - fail(t.getMessage()); - } - this.current = null; - } - - static class TestClassLoader extends ClassLoader { - - public Class defineClass(final String name, final byte[] b) { - return defineClass(name, b, 0, b.length); - } - } - - /** - * Tests a method which has the most basic try{}finally form - * imaginable: - * - *

-     * public void a() {
-     *     int a = 0;
-     *     try {
-     *         a++;
-     *     } finally {
-     *         a--;
-     *     }
-     * }
-     * 
- */ - public void testBasic() { - { - Label L0 = new Label(); - Label L1 = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - Label L4 = new Label(); - - setCurrent(jsr); - ICONST_0(); - ISTORE(1); - - /* L0: body of try block */ - LABEL(L0); - IINC(1, 1); - GOTO(L1); - - /* L2: exception handler */ - LABEL(L2); - ASTORE(3); - JSR(L3); - ALOAD(3); - ATHROW(); - - /* L3: subroutine */ - LABEL(L3); - ASTORE(2); - IINC(1, -1); - RET(2); - - /* L1: non-exceptional exit from try block */ - LABEL(L1); - JSR(L3); - LABEL(L4); // L4 - RETURN(); - - TRYCATCH(L0, L2, L2); - TRYCATCH(L1, L4, L2); - - END(1, 4); - } - - { - Label L0 = new Label(); - Label L1 = new Label(); - Label L2 = new Label(); - Label L3_1a = new Label(); - Label L3_1b = new Label(); - Label L3_2a = new Label(); - Label L3_2b = new Label(); - Label L4 = new Label(); - - setCurrent(exp); - ICONST_0(); - ISTORE(1); - // L0: try/catch block - LABEL(L0); - IINC(1, 1); - GOTO(L1); - - // L2: Exception handler: - LABEL(L2); - ASTORE(3); - ACONST_NULL(); - GOTO(L3_1a); - LABEL(L3_1b); // L3_1b; - ALOAD(3); - ATHROW(); - - // L1: On non-exceptional exit, try block leads here: - LABEL(L1); - ACONST_NULL(); - GOTO(L3_2a); - LABEL(L3_2b); // L3_2b - LABEL(L4); // L4 - RETURN(); - - // L3_1a: First instantiation of subroutine: - LABEL(L3_1a); - ASTORE(2); - IINC(1, -1); - GOTO(L3_1b); - LABEL(new Label()); // extra label emitted due to impl quirks - - // L3_2a: Second instantiation of subroutine: - LABEL(L3_2a); - ASTORE(2); - IINC(1, -1); - GOTO(L3_2b); - LABEL(new Label()); // extra label emitted due to impl quirks - - TRYCATCH(L0, L2, L2); - TRYCATCH(L1, L4, L2); - - END(1, 4); - } - - assertEquals(exp, jsr); - } - - /** - * Tests a method which has an if/else-if w/in the finally clause: - * - *
-     * public void a() {
-     *     int a = 0;
-     *     try {
-     *         a++;
-     *     } finally {
-     *         if (a == 0)
-     *             a += 2;
-     *         else
-     *             a += 3;
-     *     }
-     * }
-     * 
- */ - public void testIfElseInFinally() { - { - Label L0 = new Label(); - Label L1 = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - Label L4 = new Label(); - Label L5 = new Label(); - Label L6 = new Label(); - - setCurrent(jsr); - ICONST_0(); - ISTORE(1); - - /* L0: body of try block */ - LABEL(L0); - IINC(1, 1); - GOTO(L1); - - /* L2: exception handler */ - LABEL(L2); - ASTORE(3); - JSR(L3); - ALOAD(3); - ATHROW(); - - /* L3: subroutine */ - LABEL(L3); - ASTORE(2); - ILOAD(1); - IFNE(L4); - IINC(1, 2); - GOTO(L5); - LABEL(L4); // L4: a != 0 - IINC(1, 3); - LABEL(L5); // L5: common exit - RET(2); - - /* L1: non-exceptional exit from try block */ - LABEL(L1); - JSR(L3); - LABEL(L6); // L6 is used in the TRYCATCH below - RETURN(); - - TRYCATCH(L0, L2, L2); - TRYCATCH(L1, L6, L2); - - END(1, 4); - } - - { - Label L0 = new Label(); - Label L1 = new Label(); - Label L2 = new Label(); - Label L3_1a = new Label(); - Label L3_1b = new Label(); - Label L3_2a = new Label(); - Label L3_2b = new Label(); - Label L4_1 = new Label(); - Label L4_2 = new Label(); - Label L5_1 = new Label(); - Label L5_2 = new Label(); - Label L6 = new Label(); - - setCurrent(exp); - ICONST_0(); - ISTORE(1); - // L0: try/catch block - LABEL(L0); - IINC(1, 1); - GOTO(L1); - - // L2: Exception handler: - LABEL(L2); - ASTORE(3); - ACONST_NULL(); - GOTO(L3_1a); - LABEL(L3_1b); // L3_1b; - ALOAD(3); - ATHROW(); - - // L1: On non-exceptional exit, try block leads here: - LABEL(L1); - ACONST_NULL(); - GOTO(L3_2a); - LABEL(L3_2b); // L3_2b - LABEL(L6); // L6 - RETURN(); - - // L3_1a: First instantiation of subroutine: - LABEL(L3_1a); - ASTORE(2); - ILOAD(1); - IFNE(L4_1); - IINC(1, 2); - GOTO(L5_1); - LABEL(L4_1); // L4_1: a != 0 - IINC(1, 3); - LABEL(L5_1); // L5_1: common exit - GOTO(L3_1b); - LABEL(new Label()); // extra label emitted due to impl quirks - - // L3_2a: First instantiation of subroutine: - LABEL(L3_2a); - ASTORE(2); - ILOAD(1); - IFNE(L4_2); - IINC(1, 2); - GOTO(L5_2); - LABEL(L4_2); // L4_2: a != 0 - IINC(1, 3); - LABEL(L5_2); // L5_2: common exit - GOTO(L3_2b); - LABEL(new Label()); // extra label emitted due to impl quirks - - TRYCATCH(L0, L2, L2); - TRYCATCH(L1, L6, L2); - - END(1, 4); - } - - assertEquals(exp, jsr); - } - - /** - * Tests a simple nested finally: - * - *
-     * public void a1() {
-     *     int a = 0;
-     *     try {
-     *         a += 1;
-     *     } finally {
-     *         try {
-     *             a += 2;
-     *         } finally {
-     *             a += 3;
-     *         }
-     *     }
-     * }
-     * 
- */ - public void testSimpleNestedFinally() { - { - Label L0 = new Label(); - Label L1 = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - Label L4 = new Label(); - Label L5 = new Label(); - - setCurrent(jsr); - - ICONST_0(); - ISTORE(1); - - // L0: Body of try block: - LABEL(L0); - IINC(1, 1); - JSR(L3); - GOTO(L1); - - // L2: First exception handler: - LABEL(L2); - JSR(L3); - ATHROW(); - - // L3: First subroutine: - LABEL(L3); - ASTORE(2); - IINC(1, 2); - JSR(L4); - RET(2); - - // L5: Second exception handler: - LABEL(L5); - JSR(L4); - ATHROW(); - - // L4: Second subroutine: - LABEL(L4); - ASTORE(3); - IINC(1, 3); - RET(3); - - // L1: On normal exit, try block jumps here: - LABEL(L1); - RETURN(); - - TRYCATCH(L0, L2, L2); - TRYCATCH(L3, L5, L5); - - END(2, 6); - } - - { - Label L0 = new Label(); - Label L1 = new Label(); - Label L2 = new Label(); - Label L3_1a = new Label(); - Label L3_1b = new Label(); - Label L3_2a = new Label(); - Label L3_2b = new Label(); - Label L4_1a = new Label(); - Label L4_1b = new Label(); - Label L4_2a = new Label(); - Label L4_2b = new Label(); - Label L4_3a = new Label(); - Label L4_3b = new Label(); - Label L4_4a = new Label(); - Label L4_4b = new Label(); - Label L5_1 = new Label(); - Label L5_2 = new Label(); - - setCurrent(exp); - - ICONST_0(); - ISTORE(1); - - // L0: Body of try block: - LABEL(L0); - IINC(1, 1); - ACONST_NULL(); - GOTO(L3_1a); - LABEL(L3_1b); // L3_1b - GOTO(L1); - - // L2: First exception handler: - LABEL(L2); - ACONST_NULL(); - GOTO(L3_2a); - LABEL(L3_2b); // L3_2b - ATHROW(); - - // L1: On normal exit, try block jumps here: - LABEL(L1); - RETURN(); - - // L3_1a: First instantiation of first subroutine: - LABEL(L3_1a); - ASTORE(2); - IINC(1, 2); - ACONST_NULL(); - GOTO(L4_1a); - LABEL(L4_1b); // L4_1b - GOTO(L3_1b); - LABEL(L5_1); // L5_1 - ACONST_NULL(); - GOTO(L4_2a); - LABEL(L4_2b); // L4_2b - ATHROW(); - LABEL(new Label()); // extra label emitted due to impl quirks - - // L3_2a: Second instantiation of first subroutine: - LABEL(L3_2a); - ASTORE(2); - IINC(1, 2); - ACONST_NULL(); - GOTO(L4_3a); - LABEL(L4_3b); // L4_3b - GOTO(L3_2b); - LABEL(L5_2); // L5_2 - ACONST_NULL(); - GOTO(L4_4a); - LABEL(L4_4b); // L4_4b - ATHROW(); - LABEL(new Label()); // extra label emitted due to impl quirks - - // L4_1a: First instantiation of second subroutine: - LABEL(L4_1a); - ASTORE(3); - IINC(1, 3); - GOTO(L4_1b); - LABEL(new Label()); // extra label emitted due to impl quirks - - // L4_2a: Second instantiation of second subroutine: - LABEL(L4_2a); - ASTORE(3); - IINC(1, 3); - GOTO(L4_2b); - LABEL(new Label()); // extra label emitted due to impl quirks - - // L4_3a: Third instantiation of second subroutine: - LABEL(L4_3a); - ASTORE(3); - IINC(1, 3); - GOTO(L4_3b); - LABEL(new Label()); // extra label emitted due to impl quirks - - // L4_4a: Fourth instantiation of second subroutine: - LABEL(L4_4a); - ASTORE(3); - IINC(1, 3); - GOTO(L4_4b); - LABEL(new Label()); // extra label emitted due to impl quirks - - TRYCATCH(L0, L2, L2); - TRYCATCH(L3_1a, L5_1, L5_1); - TRYCATCH(L3_2a, L5_2, L5_2); - - END(2, 6); - } - - assertEquals(exp, jsr); - } - - /** - * This tests a subroutine which has no ret statement, but ends in a - * "return" instead. We structure this as a try/finally with a break in the - * finally. Because the while loop is infinite, it's clear from the byte - * code that the only path which reaches the RETURN instruction is through - * the subroutine. - * - *
-     * public void a1() {
-     *     int a = 0;
-     *     while (true) {
-     *         try {
-     *             a += 1;
-     *         } finally {
-     *             a += 2;
-     *             break;
-     *         }
-     *     }
-     * }
-     * 
- */ - public void testSubroutineWithNoRet() { - { - Label L0 = new Label(); - Label L1 = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - Label L4 = new Label(); - - setCurrent(jsr); - ICONST_0(); - ISTORE(1); - - // L0: while loop header/try block - LABEL(L0); - IINC(1, 1); - JSR(L1); - GOTO(L2); - - // L3: implicit catch block - LABEL(L3); - ASTORE(2); - JSR(L1); - ALOAD(2); - ATHROW(); - - // L1: subroutine ... - LABEL(L1); - ASTORE(3); - IINC(1, 2); - GOTO(L4); // ...not that it does not return! - - // L2: end of the loop... goes back to the top! - LABEL(L2); - GOTO(L0); - - // L4: - LABEL(L4); - RETURN(); - - TRYCATCH(L0, L3, L3); - - END(1, 4); - } - - { - Label L0 = new Label(); - Label L1_1a = new Label(); - Label L1_1b = new Label(); - Label L1_2a = new Label(); - Label L1_2b = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - Label L4_1 = new Label(); - Label L4_2 = new Label(); - - setCurrent(exp); - ICONST_0(); - ISTORE(1); - - // L0: while loop header/try block - LABEL(L0); - IINC(1, 1); - ACONST_NULL(); - GOTO(L1_1a); - LABEL(L1_1b); // L1_1b - GOTO(L2); - - // L3: implicit catch block - LABEL(L3); - ASTORE(2); - ACONST_NULL(); - GOTO(L1_2a); - LABEL(L1_2b); // L1_2b - ALOAD(2); - ATHROW(); - - // L2: end of the loop... goes back to the top! - LABEL(L2); - GOTO(L0); - LABEL(new Label()); // extra label emitted due to impl quirks - - // L1_1a: first instantiation of subroutine ... - LABEL(L1_1a); - ASTORE(3); - IINC(1, 2); - GOTO(L4_1); // ...not that it does not return! - LABEL(L4_1); - RETURN(); - - // L1_2a: second instantiation of subroutine ... - LABEL(L1_2a); - ASTORE(3); - IINC(1, 2); - GOTO(L4_2); // ...not that it does not return! - LABEL(L4_2); - RETURN(); - - TRYCATCH(L0, L3, L3); - - END(1, 4); - } - - assertEquals(exp, jsr); - } - - /** - * This tests a subroutine which has no ret statement, but ends in a - * "return" instead. - * - *
-     *   JSR L0
-     * L0:
-     *   ASTORE 0 
-     *   RETURN
-     * 
- */ - public void testSubroutineWithNoRet2() { - { - Label L0 = new Label(); - - setCurrent(jsr); - JSR(L0); - LABEL(L0); - ASTORE(0); - RETURN(); - END(1, 1); - } - - { - Label L0_1a = new Label(); - Label L0_1b = new Label(); - - setCurrent(exp); - - ACONST_NULL(); - GOTO(L0_1a); - LABEL(L0_1b); - - // L0_1a: First instantiation of subroutine: - LABEL(L0_1a); - ASTORE(0); - RETURN(); - LABEL(new Label()); // extra label emitted due to impl quirks - - END(1, 1); - } - - assertEquals(exp, jsr); - } - - /** - * This tests a subroutine which has no ret statement, but instead exits - * implicitely by branching to code which is not part of the subroutine. - * (Sadly, this is legal) We structure this as a try/finally in a loop with - * a break in the finally. The loop is not trivially infinite, so the RETURN - * statement is reachable both from the JSR subroutine and from the main - * entry point. - * - *
-     * public void a1() {
-     *     int a = 0;
-     *     while (null == null) {
-     *         try {
-     *             a += 1;
-     *         } finally {
-     *             a += 2;
-     *             break;
-     *         }
-     *     }
-     * }
-     * 
- */ - public void testImplicitExit() { - { - Label L0 = new Label(); - Label L1 = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - Label L4 = new Label(); - Label L5 = new Label(); - - setCurrent(jsr); - ICONST_0(); - ISTORE(1); - - // L5: while loop header - LABEL(L5); - ACONST_NULL(); - IFNONNULL(L4); - - // L0: try block - LABEL(L0); - IINC(1, 1); - JSR(L1); - GOTO(L2); - - // L3: implicit catch block - LABEL(L3); - ASTORE(2); - JSR(L1); - ALOAD(2); - ATHROW(); - - // L1: subroutine ... - LABEL(L1); - ASTORE(3); - IINC(1, 2); - GOTO(L4); // ...not that it does not return! - - // L2: end of the loop... goes back to the top! - LABEL(L2); - GOTO(L0); - - // L4: - LABEL(L4); - RETURN(); - - TRYCATCH(L0, L3, L3); - - END(1, 4); - } - - { - Label L0 = new Label(); - Label L1_1a = new Label(); - Label L1_1b = new Label(); - Label L1_2a = new Label(); - Label L1_2b = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - Label L4 = new Label(); - Label L5 = new Label(); - - setCurrent(exp); - ICONST_0(); - ISTORE(1); - - // L5: while loop header - LABEL(L5); - ACONST_NULL(); - IFNONNULL(L4); - - // L0: while loop header/try block - LABEL(L0); - IINC(1, 1); - ACONST_NULL(); - GOTO(L1_1a); - LABEL(L1_1b); // L1_1b - GOTO(L2); - - // L3: implicit catch block - LABEL(L3); - ASTORE(2); - ACONST_NULL(); - GOTO(L1_2a); - LABEL(L1_2b); // L1_2b - ALOAD(2); - ATHROW(); - - // L2: end of the loop... goes back to the top! - LABEL(L2); - GOTO(L0); - - // L4: exit, not part of subroutine - // Note that the two subroutine instantiations branch here - LABEL(L4); - RETURN(); - - // L1_1a: first instantiation of subroutine ... - LABEL(L1_1a); - ASTORE(3); - IINC(1, 2); - GOTO(L4); // ...note that it does not return! - LABEL(new Label()); // extra label emitted due to impl quirks - - // L1_2a: second instantiation of subroutine ... - LABEL(L1_2a); - ASTORE(3); - IINC(1, 2); - GOTO(L4); // ...note that it does not return! - LABEL(new Label()); // extra label emitted due to impl quirks - - TRYCATCH(L0, L3, L3); - - END(1, 4); - } - - assertEquals(exp, jsr); - } - - /** - * Tests a nested try/finally with implicit exit from one subroutine to the - * other subroutine. Equivalent to the following java code: - * - *
-     * void m(boolean b) {
-     *     try {
-     *         return;
-     *     } finally {
-     *         while (b) {
-     *             try {
-     *                 return;
-     *             } finally {
-     *                 // NOTE --- this break avoids the second return above (weird)
-     *                 if (b)
-     *                     break;
-     *             }
-     *         }
-     *     }
-     * }
-     * 
- * - * This example is from the paper, "Subroutine Inlining and Bytecode - * Abstraction to Simplify Static and Dynamic Analysis" by Cyrille Artho and - * Armin Biere. - */ - public void testImplicitExitToAnotherSubroutine() { - { - Label T1 = new Label(); - Label C1 = new Label(); - Label S1 = new Label(); - Label L = new Label(); - Label C2 = new Label(); - Label S2 = new Label(); - Label W = new Label(); - Label X = new Label(); - - // variable numbers: - int b = 1; - int e1 = 2; - int e2 = 3; - int r1 = 4; - int r2 = 5; - - setCurrent(jsr); - - ICONST_0(); - ISTORE(1); - - // T1: first try: - LABEL(T1); - JSR(S1); - RETURN(); - - // C1: exception handler for first try - LABEL(C1); - ASTORE(e1); - JSR(S1); - ALOAD(e1); - ATHROW(); - - // S1: first finally handler - LABEL(S1); - ASTORE(r1); - GOTO(W); - - // L: body of while loop, also second try - LABEL(L); - JSR(S2); - RETURN(); - - // C2: exception handler for second try - LABEL(C2); - ASTORE(e2); - JSR(S2); - ALOAD(e2); - ATHROW(); - - // S2: second finally handler - LABEL(S2); - ASTORE(r2); - ILOAD(b); - IFNE(X); - RET(r2); - - // W: test for the while loop - LABEL(W); - ILOAD(b); - IFNE(L); // falls through to X - - // X: exit from finally{} block - LABEL(X); - RET(r1); - - TRYCATCH(T1, C1, C1); - TRYCATCH(L, C2, C2); - - END(1, 6); - } - - { - Label T1 = new Label(); - Label C1 = new Label(); - Label S1_1a = new Label(); - Label S1_1b = new Label(); - Label S1_2a = new Label(); - Label S1_2b = new Label(); - Label L_1 = new Label(); - Label L_2 = new Label(); - Label C2_1 = new Label(); - Label C2_2 = new Label(); - Label S2_1_1a = new Label(); - Label S2_1_1b = new Label(); - Label S2_1_2a = new Label(); - Label S2_1_2b = new Label(); - Label S2_2_1a = new Label(); - Label S2_2_1b = new Label(); - Label S2_2_2a = new Label(); - Label S2_2_2b = new Label(); - Label W_1 = new Label(); - Label W_2 = new Label(); - Label X_1 = new Label(); - Label X_2 = new Label(); - - // variable numbers: - int b = 1; - int e1 = 2; - int e2 = 3; - int r1 = 4; - int r2 = 5; - - setCurrent(exp); - - // --- Main Subroutine --- - - ICONST_0(); - ISTORE(1); - - // T1: first try: - LABEL(T1); - ACONST_NULL(); - GOTO(S1_1a); - LABEL(S1_1b); - RETURN(); - - // C1: exception handler for first try - LABEL(C1); - ASTORE(e1); - ACONST_NULL(); - GOTO(S1_2a); - LABEL(S1_2b); - ALOAD(e1); - ATHROW(); - LABEL(new Label()); // extra label emitted due to impl quirks - - // --- First instantiation of first subroutine --- - - // S1: first finally handler - LABEL(S1_1a); - ASTORE(r1); - GOTO(W_1); - - // L_1: body of while loop, also second try - LABEL(L_1); - ACONST_NULL(); - GOTO(S2_1_1a); - LABEL(S2_1_1b); - RETURN(); - - // C2_1: exception handler for second try - LABEL(C2_1); - ASTORE(e2); - ACONST_NULL(); - GOTO(S2_1_2a); - LABEL(S2_1_2b); - ALOAD(e2); - ATHROW(); - - // W_1: test for the while loop - LABEL(W_1); - ILOAD(b); - IFNE(L_1); // falls through to X_1 - - // X_1: exit from finally{} block - LABEL(X_1); - GOTO(S1_1b); - - // --- Second instantiation of first subroutine --- - - // S1: first finally handler - LABEL(S1_2a); - ASTORE(r1); - GOTO(W_2); - - // L_2: body of while loop, also second try - LABEL(L_2); - ACONST_NULL(); - GOTO(S2_2_1a); - LABEL(S2_2_1b); - RETURN(); - - // C2_2: exception handler for second try - LABEL(C2_2); - ASTORE(e2); - ACONST_NULL(); - GOTO(S2_2_2a); - LABEL(S2_2_2b); - ALOAD(e2); - ATHROW(); - - // W_2: test for the while loop - LABEL(W_2); - ILOAD(b); - IFNE(L_2); // falls through to X_2 - - // X_2: exit from finally{} block - LABEL(X_2); - GOTO(S1_2b); - - // --- Second subroutine's 4 instantiations --- - - // S2_1_1a: - LABEL(S2_1_1a); - ASTORE(r2); - ILOAD(b); - IFNE(X_1); - GOTO(S2_1_1b); - LABEL(new Label()); // extra label emitted due to impl quirks - - // S2_1_2a: - LABEL(S2_1_2a); - ASTORE(r2); - ILOAD(b); - IFNE(X_1); - GOTO(S2_1_2b); - LABEL(new Label()); // extra label emitted due to impl quirks - - // S2_2_1a: - LABEL(S2_2_1a); - ASTORE(r2); - ILOAD(b); - IFNE(X_2); - GOTO(S2_2_1b); - LABEL(new Label()); // extra label emitted due to impl quirks - - // S2_2_2a: - LABEL(S2_2_2a); - ASTORE(r2); - ILOAD(b); - IFNE(X_2); - GOTO(S2_2_2b); - LABEL(new Label()); // extra label emitted due to impl quirks - - TRYCATCH(T1, C1, C1); - TRYCATCH(L_1, C2_1, C2_1); // duplicated try/finally for each... - TRYCATCH(L_2, C2_2, C2_2); // ...instantiation of first sub - - END(1, 6); - } - - assertEquals(exp, jsr); - } - - /** - * This tests two subroutines, neither of which exit. Instead, they both - * branch to a common set of code which returns from the method. This code - * is not reachable except through these subroutines, and since they do not - * invoke each other, it must be copied into both of them. I don't believe - * this can be represented in Java. - */ - public void testCommonCodeWhichMustBeDuplicated() { - { - Label L1 = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - - setCurrent(jsr); - ICONST_0(); - ISTORE(1); - - // Invoke the two subroutines, each twice: - JSR(L1); - JSR(L1); - JSR(L2); - JSR(L2); - RETURN(); - - // L1: subroutine 1 - LABEL(L1); - IINC(1, 1); - GOTO(L3); // ...note that it does not return! - - // L2: subroutine 2 - LABEL(L2); - IINC(1, 2); - GOTO(L3); // ...note that it does not return! - - // L3: common code to both subroutines: exit method - LABEL(L3); - RETURN(); - - END(1, 2); - } - - { - Label L1_1a = new Label(); - Label L1_1b = new Label(); - Label L1_2a = new Label(); - Label L1_2b = new Label(); - Label L2_1a = new Label(); - Label L2_1b = new Label(); - Label L2_2a = new Label(); - Label L2_2b = new Label(); - Label L3_1 = new Label(); - Label L3_2 = new Label(); - Label L3_3 = new Label(); - Label L3_4 = new Label(); - - setCurrent(exp); - ICONST_0(); - ISTORE(1); - - // Invoke the two subroutines, each twice: - ACONST_NULL(); - GOTO(L1_1a); - LABEL(L1_1b); - ACONST_NULL(); - GOTO(L1_2a); - LABEL(L1_2b); - ACONST_NULL(); - GOTO(L2_1a); - LABEL(L2_1b); - ACONST_NULL(); - GOTO(L2_2a); - LABEL(L2_2b); - RETURN(); - LABEL(new Label()); // extra label emitted due to impl quirks - - // L1_1a: instantiation 1 of subroutine 1 - LABEL(L1_1a); - IINC(1, 1); - GOTO(L3_1); // ...note that it does not return! - LABEL(L3_1); - RETURN(); - - // L1_2a: instantiation 2 of subroutine 1 - LABEL(L1_2a); - IINC(1, 1); - GOTO(L3_2); // ...note that it does not return! - LABEL(L3_2); - RETURN(); - - // L2_1a: instantiation 1 of subroutine 2 - LABEL(L2_1a); - IINC(1, 2); - GOTO(L3_3); // ...note that it does not return! - LABEL(L3_3); - RETURN(); - - // L2_2a: instantiation 2 of subroutine 2 - LABEL(L2_2a); - IINC(1, 2); - GOTO(L3_4); // ...note that it does not return! - LABEL(L3_4); - RETURN(); - - END(1, 2); - } - - assertEquals(exp, jsr); - } - - /** - * This tests a simple subroutine where the control flow jumps back and - * forth between the subroutine and the caller. This would not normally be - * produced by a java compiler. - */ - public void testInterleavedCode() { - { - Label L1 = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - Label L4 = new Label(); - - setCurrent(jsr); - ICONST_0(); - ISTORE(1); - - // Invoke the subroutine, each twice: - JSR(L1); - GOTO(L2); - - // L1: subroutine 1 - LABEL(L1); - ASTORE(2); - IINC(1, 1); - GOTO(L3); - - // L2: second part of main subroutine - LABEL(L2); - IINC(1, 2); - GOTO(L4); - - // L3: second part of subroutine 1 - LABEL(L3); - IINC(1, 4); - RET(2); - - // L4: third part of main subroutine - LABEL(L4); - JSR(L1); - RETURN(); - - END(1, 3); - } - - { - Label L1_1a = new Label(); - Label L1_1b = new Label(); - Label L1_2a = new Label(); - Label L1_2b = new Label(); - Label L2 = new Label(); - Label L3_1 = new Label(); - Label L3_2 = new Label(); - Label L4 = new Label(); - - setCurrent(exp); - - // Main routine: - ICONST_0(); - ISTORE(1); - ACONST_NULL(); - GOTO(L1_1a); - LABEL(L1_1b); - GOTO(L2); - LABEL(L2); - IINC(1, 2); - GOTO(L4); - LABEL(L4); - ACONST_NULL(); - GOTO(L1_2a); - LABEL(L1_2b); - RETURN(); - - // L1_1: instantiation #1 - LABEL(L1_1a); - ASTORE(2); - IINC(1, 1); - GOTO(L3_1); - LABEL(L3_1); - IINC(1, 4); - GOTO(L1_1b); - LABEL(new Label()); // extra label emitted due to impl quirks - - // L1_2: instantiation #2 - LABEL(L1_2a); - ASTORE(2); - IINC(1, 1); - GOTO(L3_2); - LABEL(L3_2); - IINC(1, 4); - GOTO(L1_2b); - LABEL(new Label()); // extra label emitted due to impl quirks - - END(1, 3); - } - - assertEquals(exp, jsr); - } - - /** - * Tests a nested try/finally with implicit exit from one subroutine to the - * other subroutine, and with a surrounding try/catch thrown in the mix. - * Equivalent to the following java code: - * - *
-     * void m(int b) {
-     *     try {
-     *         try {
-     *             return;
-     *         } finally {
-     *             while (b) {
-     *                 try {
-     *                     return;
-     *                 } finally {
-     *                     // NOTE --- this break avoids the second return above (weird)
-     *                     if (b)
-     *                         break;
-     *                 }
-     *             }
-     *         }
-     *     } catch (Exception e) {
-     *         b += 3;
-     *         return;
-     *     }
-     * }
-     * 
- */ - public void testImplicitExitInTryCatch() { - { - Label T1 = new Label(); - Label C1 = new Label(); - Label S1 = new Label(); - Label L = new Label(); - Label C2 = new Label(); - Label S2 = new Label(); - Label W = new Label(); - Label X = new Label(); - Label OT = new Label(); - Label OC = new Label(); - - // variable numbers: - int b = 1; - int e1 = 2; - int e2 = 3; - int r1 = 4; - int r2 = 5; - - setCurrent(jsr); - - ICONST_0(); - ISTORE(1); - - // OT: outermost try - LABEL(OT); - - // T1: first try: - LABEL(T1); - JSR(S1); - RETURN(); - - // C1: exception handler for first try - LABEL(C1); - ASTORE(e1); - JSR(S1); - ALOAD(e1); - ATHROW(); - - // S1: first finally handler - LABEL(S1); - ASTORE(r1); - GOTO(W); - - // L: body of while loop, also second try - LABEL(L); - JSR(S2); - RETURN(); - - // C2: exception handler for second try - LABEL(C2); - ASTORE(e2); - JSR(S2); - ALOAD(e2); - ATHROW(); - - // S2: second finally handler - LABEL(S2); - ASTORE(r2); - ILOAD(b); - IFNE(X); - RET(r2); - - // W: test for the while loop - LABEL(W); - ILOAD(b); - IFNE(L); // falls through to X - - // X: exit from finally{} block - LABEL(X); - RET(r1); - - // OC: outermost catch - LABEL(OC); - IINC(b, 3); - RETURN(); - - TRYCATCH(T1, C1, C1); - TRYCATCH(L, C2, C2); - TRYCATCH(OT, OC, OC); - - END(1, 6); - } - - { - Label T1 = new Label(); - Label C1 = new Label(); - Label S1_1a = new Label(); - Label S1_1b = new Label(); - Label S1_2a = new Label(); - Label S1_2b = new Label(); - Label L_1 = new Label(); - Label L_2 = new Label(); - Label C2_1 = new Label(); - Label C2_2 = new Label(); - Label S2_1_1a = new Label(); - Label S2_1_1b = new Label(); - Label S2_1_2a = new Label(); - Label S2_1_2b = new Label(); - Label S2_2_1a = new Label(); - Label S2_2_1b = new Label(); - Label S2_2_2a = new Label(); - Label S2_2_2b = new Label(); - Label W_1 = new Label(); - Label W_2 = new Label(); - Label X_1 = new Label(); - Label X_2 = new Label(); - Label OT_1 = S1_1a; - Label OT_2 = S1_2a; - Label OT_1_1 = S2_1_1a; - Label OT_1_2 = S2_1_2a; - Label OT_2_1 = S2_2_1a; - Label OT_2_2 = S2_2_2a; - Label OC = new Label(); - Label OC_1 = new Label(); - Label OC_2 = new Label(); - Label OC_1_1 = new Label(); - Label OC_1_2 = new Label(); - Label OC_2_1 = new Label(); - Label OC_2_2 = new Label(); - - // variable numbers: - int b = 1; - int e1 = 2; - int e2 = 3; - int r1 = 4; - int r2 = 5; - - setCurrent(exp); - - // --- Main Subroutine --- - - ICONST_0(); - ISTORE(1); - - // T1: outermost try / first try: - LABEL(T1); - ACONST_NULL(); - GOTO(S1_1a); - LABEL(S1_1b); - RETURN(); - - // C1: exception handler for first try - LABEL(C1); - ASTORE(e1); - ACONST_NULL(); - GOTO(S1_2a); - LABEL(S1_2b); - ALOAD(e1); - ATHROW(); - - // OC: Outermost catch - LABEL(OC); - IINC(b, 3); - RETURN(); - - // --- First instantiation of first subroutine --- - - // S1: first finally handler - LABEL(S1_1a); - ASTORE(r1); - GOTO(W_1); - - // L_1: body of while loop, also second try - LABEL(L_1); - ACONST_NULL(); - GOTO(S2_1_1a); - LABEL(S2_1_1b); - RETURN(); - - // C2_1: exception handler for second try - LABEL(C2_1); - ASTORE(e2); - ACONST_NULL(); - GOTO(S2_1_2a); - LABEL(S2_1_2b); - ALOAD(e2); - ATHROW(); - - // W_1: test for the while loop - LABEL(W_1); - ILOAD(b); - IFNE(L_1); // falls through to X_1 - - // X_1: exit from finally{} block - LABEL(X_1); - GOTO(S1_1b); - - LABEL(OC_1); - - // --- Second instantiation of first subroutine --- - - // S1: first finally handler - LABEL(S1_2a); - ASTORE(r1); - GOTO(W_2); - - // L_2: body of while loop, also second try - LABEL(L_2); - ACONST_NULL(); - GOTO(S2_2_1a); - LABEL(S2_2_1b); - RETURN(); - - // C2_2: exception handler for second try - LABEL(C2_2); - ASTORE(e2); - ACONST_NULL(); - GOTO(S2_2_2a); - LABEL(S2_2_2b); - ALOAD(e2); - ATHROW(); - - // W_2: test for the while loop - LABEL(W_2); - ILOAD(b); - IFNE(L_2); // falls through to X_2 - - // X_2: exit from finally{} block - LABEL(X_2); - GOTO(S1_2b); - - LABEL(OC_2); - - // --- Second subroutine's 4 instantiations --- - - // S2_1_1a: - LABEL(S2_1_1a); - ASTORE(r2); - ILOAD(b); - IFNE(X_1); - GOTO(S2_1_1b); - LABEL(OC_1_1); - - // S2_1_2a: - LABEL(S2_1_2a); - ASTORE(r2); - ILOAD(b); - IFNE(X_1); - GOTO(S2_1_2b); - LABEL(OC_1_2); - - // S2_2_1a: - LABEL(S2_2_1a); - ASTORE(r2); - ILOAD(b); - IFNE(X_2); - GOTO(S2_2_1b); - LABEL(OC_2_1); - - // S2_2_2a: - LABEL(S2_2_2a); - ASTORE(r2); - ILOAD(b); - IFNE(X_2); - GOTO(S2_2_2b); - LABEL(OC_2_2); - - // main subroutine handlers: - TRYCATCH(T1, C1, C1); - TRYCATCH(T1, OC, OC); - - // first instance of first sub try/catch handlers: - TRYCATCH(L_1, C2_1, C2_1); - TRYCATCH(OT_1, OC_1, OC); // note: reuses handler code from main - // sub - - // second instance of first sub try/catch handlers: - TRYCATCH(L_2, C2_2, C2_2); - TRYCATCH(OT_2, OC_2, OC); - - // all 4 instances of second sub: - TRYCATCH(OT_1_1, OC_1_1, OC); - TRYCATCH(OT_1_2, OC_1_2, OC); - TRYCATCH(OT_2_1, OC_2_1, OC); - TRYCATCH(OT_2_2, OC_2_2, OC); - - END(1, 6); - } - - assertEquals(exp, jsr); - } - - /** - * Tests a method which has line numbers and local variable declarations. - * - *
-     *   public void a() {
-     * 1    int a = 0;
-     * 2    try {
-     * 3      a++;
-     * 4    } finally {
-     * 5      a--;
-     * 6    }
-     *   }
-     *   LV "a" from 1 to 6
-     * 
- */ - public void testBasicLineNumberAndLocalVars() { - { - Label LM1 = new Label(); - Label L0 = new Label(); - Label L1 = new Label(); - Label L2 = new Label(); - Label L3 = new Label(); - Label L4 = new Label(); - - setCurrent(jsr); - LABEL(LM1); - LINE(1, LM1); - ICONST_0(); - ISTORE(1); - - /* L0: body of try block */ - LABEL(L0); - LINE(3, L0); - IINC(1, 1); - GOTO(L1); - - /* L2: exception handler */ - LABEL(L2); - ASTORE(3); - JSR(L3); - ALOAD(3); - ATHROW(); - - /* L3: subroutine */ - LABEL(L3); - LINE(5, L3); - ASTORE(2); - IINC(1, -1); - RET(2); - - /* L1: non-exceptional exit from try block */ - LABEL(L1); - JSR(L3); - LABEL(L4); // L4 - RETURN(); - - TRYCATCH(L0, L2, L2); - TRYCATCH(L1, L4, L2); - LOCALVAR("a", "I", 1, LM1, L4); - - END(1, 4); - } - - { - Label LM1 = new Label(); - Label L0 = new Label(); - Label L1 = new Label(); - Label L2 = new Label(); - Label L3_1a = new Label(); - Label L3_1b = new Label(); - Label L3_1c = new Label(); - Label L3_2a = new Label(); - Label L3_2b = new Label(); - Label L3_2c = new Label(); - Label L4 = new Label(); - - setCurrent(exp); - LABEL(LM1); - LINE(1, LM1); - ICONST_0(); - ISTORE(1); - // L0: try/catch block - LABEL(L0); - LINE(3, L0); - IINC(1, 1); - GOTO(L1); - - // L2: Exception handler: - LABEL(L2); - ASTORE(3); - ACONST_NULL(); - GOTO(L3_1a); - LABEL(L3_1b); // L3_1b; - ALOAD(3); - ATHROW(); - - // L1: On non-exceptional exit, try block leads here: - LABEL(L1); - ACONST_NULL(); - GOTO(L3_2a); - LABEL(L3_2b); // L3_2b - LABEL(L4); // L4 - RETURN(); - - // L3_1a: First instantiation of subroutine: - LABEL(L3_1a); - LINE(5, L3_1a); - ASTORE(2); - IINC(1, -1); - GOTO(L3_1b); - LABEL(L3_1c); - - // L3_2a: Second instantiation of subroutine: - LABEL(L3_2a); - LINE(5, L3_2a); - ASTORE(2); - IINC(1, -1); - GOTO(L3_2b); - LABEL(L3_2c); - - TRYCATCH(L0, L2, L2); - TRYCATCH(L1, L4, L2); - LOCALVAR("a", "I", 1, LM1, L4); - LOCALVAR("a", "I", 1, L3_1a, L3_1c); - LOCALVAR("a", "I", 1, L3_2a, L3_2c); - - END(1, 4); - } - - assertEquals(exp, jsr); - } - - public void assertEquals(final MethodNode exp, final MethodNode actual) { - String textexp = getText(exp); - String textact = getText(actual); - System.err.println("Expected=" + textexp); - System.err.println("Actual=" + textact); - assertEquals(textexp, textact); - } - - private String getText(final MethodNode mn) { - TraceMethodVisitor tmv = new TraceMethodVisitor(null); - mn.accept(tmv); - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < tmv.text.size(); i++) { - sb.append(tmv.text.get(i)); - } - return sb.toString(); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/LocalVariablesSorterTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/commons/LocalVariablesSorterTest.java deleted file mode 100644 index 9bae5ab35..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/LocalVariablesSorterTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.ClassAdapter; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * LocalVariableSorter tests. - * - * @author Eric Bruneton - */ -public class LocalVariablesSorterTest extends AbstractTest { - - private final static TestClassLoader LOADER = new TestClassLoader(); - - public static TestSuite suite() throws Exception { - return new LocalVariablesSorterTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - ClassWriter cw = new ClassWriter(0); - cr.accept(new ClassAdapter(cw) { - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - return new LocalVariablesSorter(access, desc, super.visitMethod(access, name, desc, signature, - exceptions)); - } - }, ClassReader.EXPAND_FRAMES); - byte[] b = cw.toByteArray(); - try { - LOADER.defineClass(n, b); - } catch (ClassFormatError cfe) { - fail(cfe.getMessage()); - } catch (Throwable ignored) { - } - } - - // ------------------------------------------------------------------------ - - static class TestClassLoader extends ClassLoader { - - public Class defineClass(final String name, final byte[] b) { - return defineClass(name, b, 0, b.length); - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/LocalVariablesSorterTest2.java b/common/asm/src/test/java/com/alibaba/citrus/asm/commons/LocalVariablesSorterTest2.java deleted file mode 100644 index 42a60909f..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/LocalVariablesSorterTest2.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.lang.instrument.ClassFileTransformer; -import java.lang.instrument.IllegalClassFormatException; -import java.lang.instrument.Instrumentation; -import java.security.ProtectionDomain; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.AsmTestParams; -import com.alibaba.citrus.asm.ClassAdapter; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.util.TraceClassVisitor; - -/** - * LocalVariablesSorter tests. - * - * @author Eric Bruneton - */ -public class LocalVariablesSorterTest2 extends AbstractTest { - - public static void premain(final String agentArgs, final Instrumentation inst) { - inst.addTransformer(new ClassFileTransformer() { - public byte[] transform(final ClassLoader loader, final String className, final Class classBeingRedefined, - final ProtectionDomain domain, final byte[] classFileBuffer) - throws IllegalClassFormatException { - String n = className.replace('/', '.'); - if (agentArgs.length() == 0 || n.indexOf(agentArgs) != -1) { - return transformClass(classFileBuffer); - } else { - return null; - } - } - }); - } - - private static byte[] transformClass(final byte[] clazz) { - ClassReader cr = new ClassReader(clazz); - ClassWriter cw = new ClassWriter(0); - cr.accept(new ClassAdapter(cw) { - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - return new LocalVariablesSorter(access, desc, cv.visitMethod(access, name, desc, signature, exceptions)); - } - - }, ClassReader.EXPAND_FRAMES); - return cw.toByteArray(); - } - - public static TestSuite suite() throws Exception { - TestSuite suite = new TestSuite(LocalVariablesSorterTest2.class.getName()); - - suite.addTest(new LocalVariablesSorterTest2().getSuite(new AsmTestParams(2, 0))); - suite.addTest(new LocalVariablesSorterTest2().getSuite(new AsmTestParams(2, 1))); - - return suite; - } - - @Override - public void test() throws Exception { - try { - Class.forName(n, true, getClass().getClassLoader()); - } catch (NoClassDefFoundError ncdfe) { - // ignored - } catch (UnsatisfiedLinkError ule) { - // ignored - } catch (ClassFormatError cfe) { - fail(cfe.getMessage()); - } catch (VerifyError ve) { - String s = n.replace('.', '/') + ".class"; - InputStream is = getClass().getClassLoader().getResourceAsStream(s); - ClassReader cr = new ClassReader(is); - byte[] b = transformClass(cr.b); - StringWriter sw1 = new StringWriter(); - StringWriter sw2 = new StringWriter(); - sw2.write(ve.toString() + "\n"); - ClassVisitor cv1 = new TraceClassVisitor(new PrintWriter(sw1)); - ClassVisitor cv2 = new TraceClassVisitor(new PrintWriter(sw2)); - cr.accept(cv1, 0); - new ClassReader(b).accept(cv2, 0); - String s1 = sw1.toString(); - String s2 = sw2.toString(); - assertEquals("different data", s1, s2); - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/RemappingClassAdapterTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/commons/RemappingClassAdapterTest.java deleted file mode 100644 index 4bdd3a5a0..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/RemappingClassAdapterTest.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.alibaba.citrus.asm.commons; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import junit.framework.TestCase; - -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; -import com.alibaba.citrus.asm.tree.ClassNode; -import com.alibaba.citrus.asm.tree.FieldInsnNode; -import com.alibaba.citrus.asm.tree.FieldNode; -import com.alibaba.citrus.asm.tree.FrameNode; -import com.alibaba.citrus.asm.tree.InnerClassNode; -import com.alibaba.citrus.asm.tree.LdcInsnNode; -import com.alibaba.citrus.asm.tree.MethodInsnNode; -import com.alibaba.citrus.asm.tree.MethodNode; -import com.alibaba.citrus.asm.tree.MultiANewArrayInsnNode; -import com.alibaba.citrus.asm.tree.TryCatchBlockNode; -import com.alibaba.citrus.asm.tree.TypeInsnNode; - -public class RemappingClassAdapterTest extends TestCase implements Opcodes { - - public void testRemappingClassAdapter() throws Exception { - Map map = new HashMap(); - map.put("Boo", "B1"); - map.put("Coo", "C1"); - map.put("Doo", "D1"); - Remapper remapper = new SimpleRemapper(map); - - ClassNode cn = new ClassNode(); - dump(new RemappingClassAdapter(cn, remapper)); - - assertEquals("D1", cn.name); - assertEquals("B1", cn.superName); - assertEquals(Arrays.asList(new String[] { "I", "I", "C1", "J", "B1" }), cn.interfaces); - - assertEquals("LB1;", field(cn, 0).desc); - assertEquals("[LB1;", field(cn, 1).desc); - - assertEquals("D1", innerClass(cn, 0).name); - assertEquals("B1", innerClass(cn, 0).outerName); - // assertEquals("Doo", innerClass(cn, 0).innerName); - - assertEquals("B1", cn.outerClass); - assertEquals("([[LB1;LC1;LD1;)LC1;", cn.outerMethodDesc); - - MethodNode mn0 = (MethodNode) cn.methods.get(0); - Iterator it = mn0.instructions.iterator(); - - FieldInsnNode n0 = (FieldInsnNode) it.next(); - assertEquals("D1", n0.owner); - assertEquals("LB1;", n0.desc); - - assertEquals(Type.getType("LB1;"), ((LdcInsnNode) it.next()).cst); - assertEquals(Type.getType("[LD1;"), ((LdcInsnNode) it.next()).cst); - assertEquals(Type.getType("[I"), ((LdcInsnNode) it.next()).cst); - assertEquals(Type.getType("J"), ((LdcInsnNode) it.next()).cst); - - assertEquals("B1", ((TypeInsnNode) it.next()).desc); - assertEquals("[LD1;", ((TypeInsnNode) it.next()).desc); - assertEquals("[I", ((TypeInsnNode) it.next()).desc); - assertEquals("J", ((TypeInsnNode) it.next()).desc); - - MultiANewArrayInsnNode n3 = (MultiANewArrayInsnNode) it.next(); - assertEquals("[[LB1;", n3.desc); - - MethodInsnNode n4 = (MethodInsnNode) it.next(); - assertEquals("D1", n4.owner); - assertEquals("([[LB1;LC1;LD1;)LC1;", n4.desc); - - FrameNode fn0 = (FrameNode) it.next(); - assertEquals(Collections.EMPTY_LIST, fn0.local); - assertEquals(Collections.EMPTY_LIST, fn0.stack); - - assertEquals(Arrays.asList(new Object[] { "B1", "C1", "D1" }), ((FrameNode) it.next()).local); - assertEquals(Arrays.asList(new Object[] { Opcodes.INTEGER, "C1", Opcodes.INTEGER, "D1" }), ((FrameNode) it - .next()).local); - assertEquals(Arrays.asList(new Object[] { Opcodes.INTEGER, Opcodes.INTEGER }), ((FrameNode) it.next()).local); - // assertEquals(Collections.EMPTY_LIST, fn0.stack); - - TryCatchBlockNode tryCatchBlockNode = (TryCatchBlockNode) mn0.tryCatchBlocks.get(0); - assertEquals("C1", tryCatchBlockNode.type); - - MethodNode mn1 = (MethodNode) cn.methods.get(1); - assertEquals("([[LB1;LC1;LD1;)V", mn1.desc); - assertEquals(Arrays.asList(new String[] { "I", "J" }), mn1.exceptions); - } - - private FieldNode field(ClassNode cn, int n) { - return (FieldNode) cn.fields.get(n); - } - - private InnerClassNode innerClass(ClassNode cn, int n) { - return (InnerClassNode) cn.innerClasses.get(n); - } - - public static void dump(ClassVisitor cv) throws Exception { - cv.visit(V1_5, 0, "Doo", null, "Boo", new String[] { "I", "I", "Coo", "J", "Boo" }); - - cv.visitInnerClass("Doo", "Boo", "Doo", 0); - - cv.visitOuterClass("Boo", "foo", "([[LBoo;LCoo;LDoo;)LCoo;"); - - cv.visitField(0, "boo", "LBoo;", null, null).visitEnd(); - cv.visitField(0, "boo1", "[LBoo;", null, null).visitEnd(); - cv.visitField(0, "s", "Ljava/lang/String;", null, null).visitEnd(); - cv.visitField(0, "i", "I", null, null).visitEnd(); - - MethodVisitor mv; - - mv = cv.visitMethod(0, "foo", "()V", null, null); - mv.visitCode(); - mv.visitFieldInsn(GETFIELD, "Doo", "boo", "LBoo;"); - - mv.visitLdcInsn(Type.getType("LBoo;")); - mv.visitLdcInsn(Type.getType("[LDoo;")); - mv.visitLdcInsn(Type.getType("[I")); - mv.visitLdcInsn(Type.getType("J")); - - mv.visitTypeInsn(ANEWARRAY, "Boo"); - mv.visitTypeInsn(ANEWARRAY, "[LDoo;"); - mv.visitTypeInsn(ANEWARRAY, "[I"); - mv.visitTypeInsn(ANEWARRAY, "J"); - - mv.visitMultiANewArrayInsn("[[LBoo;", 2); - mv.visitMethodInsn(INVOKEVIRTUAL, "Doo", "goo", "([[LBoo;LCoo;LDoo;)LCoo;"); - - mv.visitFrame(Opcodes.F_NEW, 0, new Object[5], 0, new Object[10]); - mv.visitFrame(Opcodes.F_NEW, 3, new Object[] { "Boo", "Coo", "Doo" }, 0, new Object[0]); - mv.visitFrame(Opcodes.F_NEW, 4, new Object[] { Opcodes.INTEGER, "Coo", Opcodes.INTEGER, "Doo" }, 0, - new Object[0]); - mv.visitFrame(Opcodes.F_NEW, 2, new Object[] { Opcodes.INTEGER, Opcodes.INTEGER }, 0, new Object[0]); - - Label l = new Label(); - - mv.visitLocalVariable("boo", "LBoo;", null, l, l, 1); - mv.visitLocalVariable("boo1", "[LBoo;", null, l, l, 3); - mv.visitLocalVariable("boo2", "[[LBoo;", null, l, l, 4); - mv.visitMaxs(0, 0); - - mv.visitTryCatchBlock(l, l, l, "Coo"); - - mv.visitEnd(); - - mv = cv.visitMethod(0, "goo", "([[LBoo;LCoo;LDoo;)V", null, new String[] { "I", "J" }); - mv.visitEnd(); - - cv.visitEnd(); - } - - // /* - public static class Boo { - } - - public static interface Coo { - } - - public static class Doo extends Boo implements Coo { - Boo boo = new Boo(); - Boo[] boo1 = new Boo[2]; - String s = ""; - int i = 5; - - static final Class c1 = Boo.class; - static final Class c2 = Boo[].class; - - public Doo() { - } - - public Doo(int i, Coo coo, Boo boo) { - } - - void foo() { - class Eoo { - String s; - } - - Eoo e = new Eoo(); - e.s = "aaa"; - - // visitFieldInsn(int, String, String, String) - // visitLocalVariable(String, String, String, Label, Label, int) - Boo boo = this.boo; - - // visitLdcInsn(Object) - Class cc = Boo.class; - - // visitTypeInsn(int, String) - Boo[] boo1 = new Boo[2]; - - // visitMultiANewArrayInsn(String, int) - Boo[][] boo2 = new Boo[2][2]; - - // visitMethodInsn(int, String, String, String) - goo(boo2, this, this); - } - - Coo goo(Boo[][] boo2, Coo coo, Doo doo) { - return null; - } - } - // */ -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/RemappingClassAdapterTest2.java b/common/asm/src/test/java/com/alibaba/citrus/asm/commons/RemappingClassAdapterTest2.java deleted file mode 100644 index 8a9ee8811..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/RemappingClassAdapterTest2.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2007 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.alibaba.citrus.asm.commons; - -import java.util.HashMap; -import java.util.Map; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassWriter; - -public class RemappingClassAdapterTest2 extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new RemappingClassAdapterTest2().getSuite(); - } - - @Override - public void test() throws Exception { - ClassWriter cw = new ClassWriter(0); - ClassReader cr = new ClassReader(openStream()); - Map map = new HashMap() { - private static final long serialVersionUID = 3905592816523598893L; - - @Override - public Object get(Object key) { - return "Foo"; - } - }; - cr.accept(new RemappingClassAdapter(cw, new SimpleRemapper(map)), ClassReader.EXPAND_FRAMES); - } - -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/SerialVersionUIDAdderTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/commons/SerialVersionUIDAdderTest.java deleted file mode 100644 index a31553c52..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/SerialVersionUIDAdderTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.ClassReader; - -/** - * SerialVerionUIDAdder tests. - * - * @author Eric Bruneton - */ -public class SerialVersionUIDAdderTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new SerialVersionUIDAdderTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - cr.accept(new SerialVersionUIDAdder(new EmptyVisitor()), 0); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/SerialVersionUIDAdderUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/commons/SerialVersionUIDAdderUnitTest.java deleted file mode 100644 index 1eb17187e..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/SerialVersionUIDAdderUnitTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import java.io.IOException; -import java.io.Serializable; - -import junit.framework.TestCase; - -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassVisitor; - -/** - * Test for the SerialVerionUid computation. - * - * @author Alexandre Vasseur - * @author Eric Bruneton - */ -@SuppressWarnings("serial") -public class SerialVersionUIDAdderUnitTest extends TestCase implements Serializable { - protected final static int aField = 32; - - static { - System.gc(); - } - - public Object[] aMethod() { - return null; - } - - private long computeSerialVersionUID(final String className) throws IOException { - final long[] svuid = new long[1]; - ClassVisitor cv = new SerialVersionUIDAdder(new EmptyVisitor()) { - @Override - protected long computeSVUID() throws IOException { - svuid[0] = super.computeSVUID(); - return svuid[0]; - } - }; - new ClassReader(className).accept(cv, 0); - return svuid[0]; - } - - public void test() throws Throwable { - long UID = computeSerialVersionUID(getClass().getName()); - assertEquals(-5253732574863322352L, UID); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/StaticInitMergerTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/commons/StaticInitMergerTest.java deleted file mode 100644 index 47125fb6f..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/commons/StaticInitMergerTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.commons; - -import junit.framework.TestCase; - -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * StaticInitMerger tests. - * - * @author Eric Bruneton - */ -public class StaticInitMergerTest extends TestCase implements Opcodes { - - private final static TestClassLoader LOADER = new TestClassLoader(); - - public void test() throws Exception { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - ClassVisitor cv = new StaticInitMerger("$clinit$", cw); - cv.visit(V1_1, ACC_PUBLIC, "A", null, "java/lang/Object", null); - cv.visitField(ACC_PUBLIC + ACC_STATIC, "counter", "I", null, null); - for (int i = 0; i < 5; ++i) { - MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitFieldInsn(GETSTATIC, "A", "counter", "I"); - mv.visitInsn(ICONST_1); - mv.visitInsn(IADD); - mv.visitFieldInsn(PUTSTATIC, "A", "counter", "I"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - } - MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - cv.visitEnd(); - - Class c = LOADER.defineClass("A", cw.toByteArray()); - assertEquals(c.getField("counter").getInt(c.newInstance()), 5); - } - - // ------------------------------------------------------------------------ - - static class TestClassLoader extends ClassLoader { - - public Class defineClass(final String name, final byte[] b) { - return defineClass(name, b, 0, b.length); - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/signature/SignatureUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/signature/SignatureUnitTest.java deleted file mode 100644 index 77823ef63..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/signature/SignatureUnitTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.signature; - -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.util.TraceSignatureVisitorUnitTest; -import com.alibaba.citrus.asm.util.TraceSignatureVisitorUnitTest.TestData; - -/** - * Signature tests. - * - * @author Eugene Kuleshov - * @author Eric Bruneton - */ -public class SignatureUnitTest extends TestCase { - - public static TestSuite suite() { - TestSuite suite = new TestSuite(SignatureUnitTest.class.getName()); - for (String element : TraceSignatureVisitorUnitTest.DATA) { - suite.addTest(new SignatureUnitTest(new TestData(element))); - } - return suite; - } - - private TestData data; - - private SignatureUnitTest(final TestData data) { - super("testSignature"); - this.data = data; - } - - public void testSignature() { - SignatureWriter wrt = new SignatureWriter(); - SignatureReader rdr = new SignatureReader(data.signature); - switch (data.type) { - case 'C': - case 'M': - rdr.accept(wrt); - break; - case 'F': - rdr.acceptType(wrt); - break; - default: - return; - } - assertEquals(data.signature, wrt.toString()); - } - - @Override - public String getName() { - return super.getName() + " " + data.signature; - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/signature/SignatureWriterTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/signature/SignatureWriterTest.java deleted file mode 100644 index 528180b9f..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/signature/SignatureWriterTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.signature; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.commons.EmptyVisitor; - -/** - * Signature tests. - * - * @author Eric Bruneton - */ -public class SignatureWriterTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new SignatureWriterTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - cr.accept(new EmptyVisitor() { - @Override - public void visit(int version, int access, String name, String signature, String superName, - String[] interfaces) { - if (signature != null) { - SignatureReader sr = new SignatureReader(signature); - SignatureWriter sw = new SignatureWriter(); - sr.accept(sw); - assertEquals(signature, sw.toString()); - } - } - - @Override - public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { - if (signature != null) { - SignatureReader sr = new SignatureReader(signature); - SignatureWriter sw = new SignatureWriter(); - sr.acceptType(sw); - assertEquals(signature, sw.toString()); - } - return null; - } - - @Override - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - if (signature != null) { - SignatureReader sr = new SignatureReader(signature); - SignatureWriter sw = new SignatureWriter(); - sr.accept(sw); - assertEquals(signature, sw.toString()); - } - return null; - } - - }, 0); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Annotation.java b/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Annotation.java deleted file mode 100644 index 8e9847a44..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Annotation.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.test.cases; - -import java.io.IOException; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Type; - -/** - * Generates an annotation class with values of all types and a class using it. - * - * @author Eric Bruneton - */ -public class Annotation extends Generator { - - final static int M = ACC_PUBLIC + ACC_ABSTRACT; - - final static String STRING = "Ljava/lang/String;"; - - final static String CLASS = "Ljava/lang/Class;"; - - final static String DOC = "Ljava/lang/annotation/Documented;"; - - final static String DEPRECATED = "Ljava/lang/Deprecated;"; - - public void generate(final String dir) throws IOException { - generate(dir, "pkg/Annotation.class", dumpAnnotation()); - generate(dir, "pkg/Annotated.class", dumpAnnotated()); - } - - public byte[] dumpAnnotation() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - MethodVisitor mv; - AnnotationVisitor av0, av1; - - cw.visit(V1_5, ACC_PUBLIC + ACC_ANNOTATION + ACC_ABSTRACT + ACC_INTERFACE, "pkg/Annotation", null, - "java/lang/Object", new String[] { "java/lang/annotation/Annotation" }); - - mv = cw.visitMethod(M, "byteValue", "()B", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, new Byte((byte) 1)); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "charValue", "()C", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, new Character((char) 1)); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "booleanValue", "()Z", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, Boolean.TRUE); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "intValue", "()I", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, new Integer(1)); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "shortValue", "()S", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, new Short((short) 1)); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "longValue", "()J", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, new Long(1L)); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "floatValue", "()F", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, new Float("1.0")); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "doubleValue", "()D", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, new Double("1.0")); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "stringValue", "()" + STRING, null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, "1"); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "classValue", "()" + CLASS, null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, Type.getType("Lpkg/Annotation;")); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "enumValue", "()Lpkg/Enum;", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visitEnum(null, "Lpkg/Enum;", "V1"); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "annotationValue", "()" + DOC, null, null); - av0 = mv.visitAnnotationDefault(); - av1 = av0.visitAnnotation(null, DOC); - av1.visitEnd(); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "byteArrayValue", "()[B", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, new byte[] { 0, 1 }); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "charArrayValue", "()[C", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, new char[] { '0', '1' }); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "booleanArrayValue", "()[Z", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, new boolean[] { false, true }); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "intArrayValue", "()[I", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, new int[] { 0, 1 }); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "shortArrayValue", "()[S", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, new short[] { (short) 0, (short) 1 }); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "longArrayValue", "()[J", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, new long[] { 0L, 1L }); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "floatArrayValue", "()[F", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, new float[] { 0.0f, 1.0f }); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "doubleArrayValue", "()[D", null, null); - av0 = mv.visitAnnotationDefault(); - av0.visit(null, new double[] { 0.0d, 1.0d }); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "stringArrayValue", "()" + STRING, null, null); - av0 = mv.visitAnnotationDefault(); - av1 = av0.visitArray(null); - av1.visit(null, "0"); - av1.visit(null, "1"); - av1.visitEnd(); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "classArrayValue", "()[" + CLASS, null, null); - av0 = mv.visitAnnotationDefault(); - av1 = av0.visitArray(null); - av1.visit(null, Type.getType("Lpkg/Annotation;")); - av1.visit(null, Type.getType("Lpkg/Annotation;")); - av1.visitEnd(); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "enumArrayValue", "()[Lpkg/Enum;", null, null); - av0 = mv.visitAnnotationDefault(); - av1 = av0.visitArray(null); - av1.visitEnum(null, "Lpkg/Enum;", "V0"); - av1.visitEnum(null, "Lpkg/Enum;", "V1"); - av1.visitEnd(); - av0.visitEnd(); - mv.visitEnd(); - - mv = cw.visitMethod(M, "annotationArrayValue", "()[" + DOC, null, null); - av0 = mv.visitAnnotationDefault(); - av1 = av0.visitArray(null); - av1.visitAnnotation(null, DOC).visitEnd(); - av1.visitAnnotation(null, DOC).visitEnd(); - av1.visitEnd(); - av0.visitEnd(); - mv.visitEnd(); - - cw.visitEnd(); - - return cw.toByteArray(); - } - - public byte[] dumpAnnotated() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - FieldVisitor fv; - MethodVisitor mv; - AnnotationVisitor av0, av1; - - cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, "pkg/Annotated", null, "java/lang/Object", null); - - // visible class annotation - cw.visitAnnotation(DEPRECATED, true).visitEnd(); - - // invisible class annotation, with values of all types - av0 = cw.visitAnnotation("Lpkg/Annotation;", false); - av0.visit("byteValue", new Byte((byte) 0)); - av0.visit("charValue", new Character((char) 48)); - av0.visit("booleanValue", Boolean.FALSE); - av0.visit("intValue", new Integer(0)); - av0.visit("shortValue", new Short((short) 0)); - av0.visit("longValue", new Long(0L)); - av0.visit("floatValue", new Float("0.0")); - av0.visit("doubleValue", new Double("0.0")); - av0.visit("stringValue", "0"); - av0.visitEnum("enumValue", "Lpkg/Enum;", "V0"); - av0.visitAnnotation("annotationValue", DOC).visitEnd(); - av0.visit("classValue", Type.getType("Lpkg/Annotation;")); - av0.visit("byteArrayValue", new byte[] { 1, 0 }); - av0.visit("charArrayValue", new char[] { '1', '0' }); - av0.visit("booleanArrayValue", new boolean[] { true, false }); - av0.visit("intArrayValue", new int[] { 1, 0 }); - av0.visit("shortArrayValue", new short[] { (short) 1, (short) 0 }); - av0.visit("longArrayValue", new long[] { 1L, 0L }); - av0.visit("floatArrayValue", new float[] { 1.0f, 0.0f }); - av0.visit("doubleArrayValue", new double[] { 1.0d, 0.0d }); - av1 = av0.visitArray("stringArrayValue"); - av1.visit(null, "1"); - av1.visit(null, "0"); - av1.visitEnd(); - av0.visitArray("classArrayValue").visitEnd(); - av1 = av0.visitArray("enumArrayValue"); - av1.visitEnum(null, "Lpkg/Enum;", "V1"); - av1.visitEnum(null, "Lpkg/Enum;", "V2"); - av1.visitEnd(); - av0.visitArray("annotationArrayValue").visitEnd(); - av0.visitEnd(); - - fv = cw.visitField(ACC_PUBLIC, "f", "I", null, null); - // visible field annotation - fv.visitAnnotation(DEPRECATED, true).visitEnd(); - // invisible field annotation - av0 = fv.visitAnnotation("Lpkg/Annotation;", false); - av0.visitEnum("enumValue", "Lpkg/Enum;", "V0"); - av0.visitEnd(); - fv.visitEnd(); - - mv = cw.visitMethod(ACC_PUBLIC, "", "(IIIIIIIIII)V", null, null); - // visible method annotation - mv.visitAnnotation(DEPRECATED, true).visitEnd(); - // invisible method annotation - av0 = mv.visitAnnotation("Lpkg/Annotation;", false); - av0.visitAnnotation("annotationValue", DOC).visitEnd(); - av0.visitEnd(); - // synthetic parameter annotation - mv.visitParameterAnnotation(0, "Ljava/lang/Synthetic;", false); - // visible parameter annotation - mv.visitParameterAnnotation(8, DEPRECATED, true).visitEnd(); - // invisible parameter annotation - av0 = mv.visitParameterAnnotation(8, "Lpkg/Annotation;", false); - av0.visitArray("stringArrayValue").visitEnd(); - av0.visitEnd(); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - return cw.toByteArray(); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Attribute.java b/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Attribute.java deleted file mode 100644 index 968f98b12..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Attribute.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.test.cases; - -import java.io.IOException; - -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.attrs.CodeComment; -import com.alibaba.citrus.asm.attrs.Comment; - -/** - * Generates a class with non standard attributes. Covers class, field, method - * and code attributes. Also covers the V1_3 class version and the SYNTHETIC - * access flag for classes. - * - * @author Eric Bruneton - */ -public class Attribute extends Generator { - - @Override - public void generate(final String dir) throws IOException { - generate(dir, "pkg/Attribute.class", dump()); - } - - public byte[] dump() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - FieldVisitor fv; - MethodVisitor mv; - - cw.visit(V1_3, ACC_PUBLIC + ACC_SYNTHETIC, "pkg/Attribute", null, "java/lang/Object", null); - - cw.visitAttribute(new Comment()); - - fv = cw.visitField(ACC_PUBLIC, "f", "I", null, null); - fv.visitAttribute(new Comment()); - fv.visitEnd(); - - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitAttribute(new Comment()); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); - - /* - * the following instructions are designed so that this method will be - * resized by the method resizing test, in order to cover the code that - * recomputes the code attribute labels in the resizeInstructions method - * (see MethodWriter). - */ - Label l0 = new Label(); - mv.visitInsn(ICONST_0); - mv.visitJumpInsn(IFEQ, l0); - // many NOPs will be introduced here by the method resizing test - mv.visitJumpInsn(GOTO, l0); - mv.visitLabel(l0); - - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitAttribute(new CodeComment()); - mv.visitEnd(); - - cw.visitEnd(); - return cw.toByteArray(); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Debug.java b/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Debug.java deleted file mode 100644 index 510c81402..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Debug.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.test.cases; - -import java.io.IOException; - -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * Generates a class with debug information. Covers line number tables, local - * variable tables, source file, source debug, etc. Also covers the - * serialVersionUID field (to cover a branch in SerialVersionUIDAdder). - * - * @author Eric Bruneton - */ -public class Debug extends Generator { - - @Override - public void generate(final String dir) throws IOException { - generate(dir, "pkg/Debug.class", dump()); - } - - public byte[] dump() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - - cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, "pkg/Debug", null, "java/lang/Object", - new String[] { "java/io/Serializable" }); - - cw.visitSource("Debug.java", "source-debug"); - - FieldVisitor fv = cw.visitField(ACC_FINAL + ACC_STATIC, "serialVersionUID", "J", null, new Long(1L)); - fv.visitEnd(); - - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitCode(); - Label l0 = new Label(); - Label l1 = new Label(); - Label l2 = new Label(); - mv.visitLabel(l0); - mv.visitLineNumber(3, l0); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); - mv.visitInsn(ICONST_0); - mv.visitJumpInsn(IFEQ, l1); - mv.visitJumpInsn(GOTO, l1); - mv.visitLabel(l1); - mv.visitLineNumber(3, l1); - mv.visitInsn(RETURN); - mv.visitLabel(l2); - mv.visitLocalVariable("this", "Lpkg/Debug;", "Lpkg/Debug;", l0, l2, 0); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - cw.visitEnd(); - - return cw.toByteArray(); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Enum.java b/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Enum.java deleted file mode 100644 index 7229a886d..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Enum.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.test.cases; - -import java.io.IOException; - -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Type; - -/** - * Generates an enum class. - * - * @author Eric Bruneton - */ -public class Enum extends Generator { - - @Override - public void generate(final String dir) throws IOException { - generate(dir, "pkg/Enum.class", dump()); - } - - public byte[] dump() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - FieldVisitor fv; - MethodVisitor mv; - - cw.visit(V1_5, ACC_PUBLIC + ACC_FINAL + ACC_SUPER + ACC_ENUM, "pkg/Enum", "Ljava/lang/Enum;", - "java/lang/Enum", null); - - fv = cw.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC + ACC_ENUM, "V0", "Lpkg/Enum;", null, null); - fv.visitEnd(); - - fv = cw.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC + ACC_ENUM, "V1", "Lpkg/Enum;", null, null); - fv.visitEnd(); - - fv = cw.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC + ACC_ENUM, "V2", "Lpkg/Enum;", null, null); - fv.visitEnd(); - - fv = cw.visitField(ACC_PRIVATE + ACC_FINAL + ACC_STATIC + ACC_SYNTHETIC, "$VALUES", "[Lpkg/Enum;", null, null); - fv.visitEnd(); - - mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, "values", "()[Lpkg/Enum;", null, null); - mv.visitCode(); - mv.visitFieldInsn(GETSTATIC, "pkg/Enum", "$VALUES", "[Lpkg/Enum;"); - mv.visitMethodInsn(INVOKEVIRTUAL, "[Lpkg/Enum;", "clone", "()Ljava/lang/Object;"); - mv.visitTypeInsn(CHECKCAST, "[Lpkg/Enum;"); - mv.visitInsn(ARETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "valueOf", "(Ljava/lang/String;)Lpkg/Enum;", null, null); - mv.visitCode(); - mv.visitLdcInsn(Type.getType("Lpkg/Enum;")); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Enum", "valueOf", - "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;"); - mv.visitTypeInsn(CHECKCAST, "pkg/Enum"); - mv.visitInsn(ARETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - mv = cw.visitMethod(ACC_PRIVATE, "", "(Ljava/lang/String;I)V", "()V", null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 1); - mv.visitVarInsn(ILOAD, 2); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Enum", "", "(Ljava/lang/String;I)V"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - mv = cw.visitMethod(ACC_STATIC, "", "()V", null, null); - mv.visitCode(); - mv.visitTypeInsn(NEW, "pkg/Enum"); - mv.visitInsn(DUP); - mv.visitLdcInsn("V0"); - mv.visitInsn(ICONST_0); - mv.visitMethodInsn(INVOKESPECIAL, "pkg/Enum", "", "(Ljava/lang/String;I)V"); - mv.visitFieldInsn(PUTSTATIC, "pkg/Enum", "V0", "Lpkg/Enum;"); - mv.visitTypeInsn(NEW, "pkg/Enum"); - mv.visitInsn(DUP); - mv.visitLdcInsn("V1"); - mv.visitInsn(ICONST_1); - mv.visitMethodInsn(INVOKESPECIAL, "pkg/Enum", "", "(Ljava/lang/String;I)V"); - mv.visitFieldInsn(PUTSTATIC, "pkg/Enum", "V1", "Lpkg/Enum;"); - mv.visitTypeInsn(NEW, "pkg/Enum"); - mv.visitInsn(DUP); - mv.visitLdcInsn("V2"); - mv.visitInsn(ICONST_2); - mv.visitMethodInsn(INVOKESPECIAL, "pkg/Enum", "", "(Ljava/lang/String;I)V"); - mv.visitFieldInsn(PUTSTATIC, "pkg/Enum", "V2", "Lpkg/Enum;"); - mv.visitInsn(ICONST_3); - mv.visitTypeInsn(ANEWARRAY, "pkg/Enum"); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitFieldInsn(GETSTATIC, "pkg/Enum", "V0", "Lpkg/Enum;"); - mv.visitInsn(AASTORE); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_1); - mv.visitFieldInsn(GETSTATIC, "pkg/Enum", "V1", "Lpkg/Enum;"); - mv.visitInsn(AASTORE); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_2); - mv.visitFieldInsn(GETSTATIC, "pkg/Enum", "V2", "Lpkg/Enum;"); - mv.visitInsn(AASTORE); - mv.visitFieldInsn(PUTSTATIC, "pkg/Enum", "$VALUES", "[Lpkg/Enum;"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - cw.visitEnd(); - - return cw.toByteArray(); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Frames.java b/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Frames.java deleted file mode 100644 index 0f6f41183..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Frames.java +++ /dev/null @@ -1,684 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.test.cases; - -import java.io.IOException; - -import com.alibaba.citrus.asm.ClassAdapter; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodAdapter; -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * Generates classes with StackMap and StackMapTable attributes. Covers all - * frame (FULL, SAME, etc.) and frame element types (TOP, NULL, INTEGER, etc.). - * Also covers the V1_6 class version. - * - * @author Eric Bruneton - */ -public class Frames extends Generator { - - final static int M = ACC_STATIC; - final static String I1 = "Ljava/io/Serializable;"; - final static String I2 = "Ljava/lang/Comparable;"; - - public void generate(final String dir) throws IOException { - byte[] b = dump(); - ClassWriter cw = new ClassWriter(0); - ClassReader cr = new ClassReader(b); - cr.accept(new RenameAdapter(cw), ClassReader.EXPAND_FRAMES); - - generate(dir, "pkg/FrameTable.class", b); - generate(dir, "pkg/FrameMap.class", cw.toByteArray()); - } - - public byte[] dump() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - MethodVisitor mv; - FieldVisitor fv; - - cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "pkg/FrameTable", null, "java/lang/Object", null); - - fv = cw.visitField(M, "long", "Ljava/lang/Long;", null, null); - fv.visitEnd(); - - fv = cw.visitField(M, "double", "Ljava/lang/Double;", null, null); - fv.visitEnd(); - - fv = cw.visitField(M, "number", "Ljava/lang/Number;", null, null); - fv.visitEnd(); - - fv = cw.visitField(M, "serializable", I1, null, null); - fv.visitEnd(); - - fv = cw.visitField(M, "comparable", I2, null, null); - fv.visitEnd(); - - fv = cw.visitField(M, "longArray", "[Ljava/lang/Long;", null, null); - fv.visitEnd(); - - fv = cw.visitField(M, "intArray", "[I", null, null); - fv.visitEnd(); - - fv = cw.visitField(M, "floatArray", "[F", null, null); - fv.visitEnd(); - - fv = cw.visitField(M, "objectArray", "[Ljava/lang/Object;", null, null); - fv.visitEnd(); - - mv = cw.visitMethod(ACC_PUBLIC, "", "(Ljava/lang/Object;)V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - uninitializedThisType(cw); - uninitializedLocalType(cw); - uninitializedStackType(cw); - nullType(cw); - topType(cw); - arrayTypes(cw); - - mergeTypes(cw); - mergeStackTypes(cw); - mergeNullArray(cw); - - appendAndChopFrame(cw); - sameLocals1stackItemFrame(cw); - sameLocals1stackItemFrame2(cw); - sameLocals1stackItemFrameExtended(cw); - sameFrameExtended(cw); - - deadCode(cw); - - cw.visitEnd(); - - return cw.toByteArray(); - } - - private void uninitializedThisType(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "", "(I)V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - Label l0 = new Label(); - mv.visitLabel(l0); - mv.visitTypeInsn(NEW, "pkg/FrameTable"); - mv.visitInsn(DUP); - mv.visitVarInsn(ILOAD, 1); - Label l1 = new Label(); - mv.visitJumpInsn(IFNE, l1); - mv.visitInsn(ACONST_NULL); - Label l2 = new Label(); - mv.visitJumpInsn(GOTO, l2); - mv.visitFrame(F_FULL, 2, new Object[] { UNINITIALIZED_THIS, INTEGER }, 3, new Object[] { UNINITIALIZED_THIS, - l0, l0 }); - mv.visitLabel(l1); - mv.visitTypeInsn(NEW, "java/lang/Object"); - mv.visitInsn(DUP); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); - mv.visitFrame(F_FULL, 2, new Object[] { UNINITIALIZED_THIS, INTEGER }, 4, new Object[] { UNINITIALIZED_THIS, - l0, l0, "java/lang/Object" }); - mv.visitLabel(l2); - mv.visitMethodInsn(INVOKESPECIAL, "pkg/FrameTable", "", "(Ljava/lang/Object;)V"); - mv.visitMethodInsn(INVOKESPECIAL, "pkg/FrameTable", "", "(Ljava/lang/Object;)V"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void uninitializedLocalType(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "uninitializedLocalType", "(Z)V", null, null); - mv.visitCode(); - Label l0 = new Label(); - mv.visitLabel(l0); - mv.visitTypeInsn(NEW, "java/lang/Long"); - mv.visitVarInsn(ASTORE, 2); - mv.visitVarInsn(ALOAD, 2); - mv.visitVarInsn(ILOAD, 1); - Label l1 = new Label(); - mv.visitJumpInsn(IFEQ, l1); - mv.visitInsn(LCONST_0); - Label l2 = new Label(); - mv.visitJumpInsn(GOTO, l2); - mv.visitFrame(F_FULL, 3, new Object[] { "pkg/FrameTable", INTEGER, l0 }, 1, new Object[] { l0 }); - mv.visitLabel(l1); - mv.visitInsn(LCONST_1); - mv.visitFrame(F_FULL, 3, new Object[] { "pkg/FrameTable", INTEGER, l0 }, 2, new Object[] { l0, LONG }); - mv.visitLabel(l2); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Long", "", "(J)V"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void uninitializedStackType(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "uninitializedStackType", "(Z)V", null, null); - mv.visitCode(); - Label l0 = new Label(); - mv.visitLabel(l0); - mv.visitTypeInsn(NEW, "java/lang/Long"); - mv.visitInsn(DUP); - mv.visitVarInsn(ILOAD, 1); - Label l1 = new Label(); - mv.visitJumpInsn(IFEQ, l1); - mv.visitInsn(LCONST_0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Long", "", "(J)V"); - Label l2 = new Label(); - mv.visitJumpInsn(GOTO, l2); - mv.visitFrame(F_FULL, 1, new Object[] { "pkg/FrameTable" }, 2, new Object[] { l0, l0 }); - mv.visitLabel(l1); - mv.visitInsn(LCONST_1); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Long", "", "(J)V"); - mv.visitFrame(F_SAME1, 0, null, 1, new Object[] { "java/lang/Long" }); - mv.visitLabel(l2); - mv.visitVarInsn(ASTORE, 2); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void nullType(final ClassWriter cw) { - MethodVisitor mv = cw - .visitMethod(ACC_PUBLIC, "nullType", "(Ljava/lang/String;Ljava/lang/String;)V", null, null); - mv.visitCode(); - mv.visitInsn(ACONST_NULL); - mv.visitVarInsn(ASTORE, 2); - mv.visitVarInsn(ALOAD, 0); - mv.visitInsn(ACONST_NULL); - mv.visitVarInsn(ALOAD, 1); - Label l0 = new Label(); - mv.visitJumpInsn(IFNONNULL, l0); - mv.visitVarInsn(ALOAD, 2); - Label l1 = new Label(); - mv.visitJumpInsn(GOTO, l1); - mv.visitFrame(F_FULL, 3, new Object[] { "pkg/FrameTable", "java/lang/String", NULL }, 2, new Object[] { - "pkg/FrameTable", NULL }); - mv.visitLabel(l0); - mv.visitVarInsn(ALOAD, 1); - mv.visitFrame(F_FULL, 3, new Object[] { "pkg/FrameTable", "java/lang/String", NULL }, 3, new Object[] { - "pkg/FrameTable", NULL, "java/lang/String" }); - mv.visitLabel(l1); - mv.visitMethodInsn(INVOKEVIRTUAL, "pkg/FrameTable", "nullType", "(Ljava/lang/String;Ljava/lang/String;)V"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void topType(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "topType", "(ZBCSIFJDLjava/lang/Object;)V", null, null); - mv.visitCode(); - mv.visitVarInsn(ILOAD, 5); - mv.visitVarInsn(ISTORE, 13); - mv.visitVarInsn(ILOAD, 1); - Label l0 = new Label(); - mv.visitJumpInsn(IFEQ, l0); - mv.visitInsn(RETURN); - mv.visitFrame(F_APPEND, 2, new Object[] { TOP, INTEGER }, 0, null); - mv.visitLabel(l0); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void arrayTypes(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "fullFrame", - "(Ljava/lang/String;[[Z[B[C[S[I[F[J[D[Ljava/lang/Object;)V", null, null); - mv.visitCode(); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 11); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 13); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 15); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 17); - mv.visitVarInsn(ALOAD, 1); - Label l0 = new Label(); - mv.visitJumpInsn(IFNONNULL, l0); - mv.visitInsn(RETURN); - mv.visitFrame(F_FULL, 15, new Object[] { "pkg/FrameTable", "java/lang/String", "[[Z", "[B", "[C", "[S", "[I", - "[F", "[J", "[D", "[Ljava/lang/Object;", LONG, LONG, LONG, LONG }, 0, new Object[] {}); - mv.visitLabel(l0); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void mergeTypes(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "mergeTypes", "(Z)V", null, null); - mv.visitCode(); - Label l0 = new Label(); - mv.visitFieldInsn(GETSTATIC, "pkg/FrameTable", "long", "Ljava/lang/Long;"); - mv.visitVarInsn(ASTORE, 2); - mv.visitFieldInsn(GETSTATIC, "pkg/FrameTable", "number", "Ljava/lang/Number;"); - mv.visitVarInsn(ASTORE, 3); - mv.visitFieldInsn(GETSTATIC, "pkg/FrameTable", "number", "Ljava/lang/Long;"); - mv.visitVarInsn(ASTORE, 4); - mv.visitFieldInsn(GETSTATIC, "pkg/FrameTable", "comparable", "Ljava/lang/Comparable;"); - mv.visitVarInsn(ASTORE, 5); - mv.visitInsn(ACONST_NULL); - mv.visitVarInsn(ASTORE, 6); - mv.visitFieldInsn(GETSTATIC, "pkg/FrameTable", "double", "Ljava/lang/Double;"); - mv.visitVarInsn(ASTORE, 7); - mv.visitInsn(ICONST_0); - mv.visitVarInsn(ISTORE, 8); - mv.visitFieldInsn(GETSTATIC, "pkg/FrameTable", "intArray", "[I"); - mv.visitVarInsn(ASTORE, 9); - mv.visitFieldInsn(GETSTATIC, "pkg/FrameTable", "double", "Ljava/lang/Double;"); - mv.visitVarInsn(ASTORE, 10); - mv.visitInsn(ACONST_NULL); - mv.visitVarInsn(ASTORE, 11); - - mv.visitFrame(F_FULL, 12, new Object[] { "pkg/FrameTable", INTEGER, "java/lang/Number", "java/lang/Number", - "java/lang/Number", "java/lang/Object", NULL, "java/lang/Double", TOP, "java/lang/Object", - "java/lang/Object", "[Ljava/lang/Object;" }, 0, null); - mv.visitLabel(l0); - mv.visitVarInsn(ALOAD, 11); - mv.visitInsn(ICONST_0); - mv.visitInsn(ACONST_NULL); - mv.visitInsn(AASTORE); - - mv.visitFieldInsn(GETSTATIC, "pkg/FrameTable", "double", "Ljava/lang/Double;"); - mv.visitVarInsn(ASTORE, 2); - mv.visitFieldInsn(GETSTATIC, "pkg/FrameTable", "double", "Ljava/lang/Double;"); - mv.visitVarInsn(ASTORE, 3); - mv.visitFieldInsn(GETSTATIC, "pkg/FrameTable", "number", "Ljava/lang/Number;"); - mv.visitVarInsn(ASTORE, 4); - mv.visitFieldInsn(GETSTATIC, "pkg/FrameTable", "serializable", "Ljava/io/Serializable;"); - mv.visitVarInsn(ASTORE, 5); - mv.visitInsn(ACONST_NULL); - mv.visitVarInsn(ASTORE, 6); - mv.visitInsn(ACONST_NULL); - mv.visitVarInsn(ASTORE, 7); - mv.visitInsn(ACONST_NULL); - mv.visitVarInsn(ASTORE, 8); - mv.visitFieldInsn(GETSTATIC, "pkg/FrameTable", "floatArray", "[F"); - mv.visitVarInsn(ASTORE, 9); - mv.visitFieldInsn(GETSTATIC, "pkg/FrameTable", "intArray", "[I"); - mv.visitVarInsn(ASTORE, 10); - mv.visitInsn(ICONST_1); - mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); - mv.visitVarInsn(ASTORE, 11); - - mv.visitJumpInsn(GOTO, l0); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void mergeStackTypes(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "mergeStackTypes", "(Z)V", null, null); - mv.visitCode(); - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_1); - mv.visitVarInsn(ILOAD, 1); - Label l0 = new Label(); - mv.visitJumpInsn(IFEQ, l0); - mv.visitInsn(ICONST_0); - Label l1 = new Label(); - mv.visitJumpInsn(GOTO, l1); - mv.visitFrame(F_FULL, 1, new Object[] { "pkg/FrameTable" }, 2, new Object[] { INTEGER, INTEGER }); - mv.visitLabel(l0); - mv.visitInsn(DUP); - mv.visitFrame(F_FULL, 1, new Object[] { "pkg/FrameTable" }, 3, new Object[] { INTEGER, INTEGER, INTEGER }); - mv.visitLabel(l1); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void mergeNullArray(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "mergeNullArray", "(Z)I", null, null); - mv.visitCode(); - mv.visitVarInsn(ILOAD, 1); - Label l1 = new Label(); - mv.visitJumpInsn(IFEQ, l1); - mv.visitInsn(ACONST_NULL); - mv.visitVarInsn(ASTORE, 2); - mv.visitVarInsn(ILOAD, 1); - Label l2 = new Label(); - mv.visitJumpInsn(IFEQ, l2); - mv.visitFieldInsn(GETSTATIC, "pkg/FrameTable", "longArray", "[Ljava/lang/Long;"); - mv.visitVarInsn(ASTORE, 2); - mv.visitFrame(F_APPEND, 1, new Object[] { "[Ljava/lang/Long;" }, 0, null); - mv.visitLabel(l2); - mv.visitVarInsn(ALOAD, 2); - Label l3 = new Label(); - mv.visitJumpInsn(IFNULL, l3); - mv.visitVarInsn(ALOAD, 2); - mv.visitInsn(ARRAYLENGTH); - Label l4 = new Label(); - mv.visitJumpInsn(IFNE, l4); - mv.visitFrame(F_SAME, 0, null, 0, null); - mv.visitLabel(l3); - mv.visitInsn(ACONST_NULL); - mv.visitVarInsn(ASTORE, 3); - Label l5 = new Label(); - mv.visitJumpInsn(GOTO, l5); - mv.visitFrame(F_SAME, 0, null, 0, null); - mv.visitLabel(l4); - mv.visitVarInsn(ALOAD, 2); - mv.visitInsn(ICONST_0); - mv.visitInsn(AALOAD); - mv.visitVarInsn(ASTORE, 3); - mv.visitVarInsn(ILOAD, 1); - mv.visitJumpInsn(IFNE, l5); - mv.visitInsn(ACONST_NULL); - mv.visitVarInsn(ASTORE, 3); - mv.visitFrame(F_SAME, 0, null, 0, null); - mv.visitLabel(l5); - mv.visitVarInsn(ILOAD, 1); - mv.visitInsn(IRETURN); - mv.visitFrame(F_CHOP, 1, null, 0, null); - mv.visitLabel(l1); - mv.visitVarInsn(ILOAD, 1); - mv.visitInsn(IRETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void appendAndChopFrame(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "appendAndChopFrame", "(I)V", null, null); - mv.visitCode(); - mv.visitInsn(ICONST_0); - mv.visitVarInsn(ISTORE, 2); - mv.visitFrame(F_APPEND, 1, new Object[] { INTEGER }, 0, null); - Label l0 = new Label(); - mv.visitLabel(l0); - mv.visitVarInsn(ILOAD, 2); - mv.visitVarInsn(ILOAD, 1); - Label l1 = new Label(); - mv.visitJumpInsn(IF_ICMPGE, l1); - mv.visitIincInsn(2, 1); - mv.visitJumpInsn(GOTO, l0); - mv.visitFrame(F_CHOP, 1, null, 0, null); - mv.visitLabel(l1); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void sameLocals1stackItemFrame(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "sameLocals1stackItemFrame", "()I", null, null); - mv.visitCode(); - Label l0 = new Label(); - Label l1 = new Label(); - mv.visitTryCatchBlock(l0, l1, l0, null); - mv.visitInsn(ICONST_0); - mv.visitInsn(IRETURN); - mv.visitFrame(F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" }); - mv.visitLabel(l0); - mv.visitVarInsn(ASTORE, 1); - mv.visitLabel(l1); - mv.visitInsn(ICONST_0); - mv.visitInsn(IRETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void sameLocals1stackItemFrame2(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "sameLocals1stackItemFrame2", "()V", null, null); - mv.visitCode(); - Label l0 = new Label(); - Label l1 = new Label(); - Label l2 = new Label(); - mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Exception"); - Label l3 = new Label(); - mv.visitTryCatchBlock(l0, l1, l3, null); - Label l4 = new Label(); - mv.visitTryCatchBlock(l2, l4, l3, null); - Label l5 = new Label(); - mv.visitTryCatchBlock(l3, l5, l3, null); - mv.visitLabel(l0); - mv.visitTypeInsn(NEW, "java/lang/Object"); - mv.visitInsn(DUP); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); - mv.visitVarInsn(ASTORE, 1); - mv.visitLabel(l1); - Label l6 = new Label(); - mv.visitJumpInsn(GOTO, l6); - mv.visitFrame(F_SAME1, 0, null, 1, new Object[] { "java/lang/Exception" }); - mv.visitLabel(l2); - mv.visitVarInsn(ASTORE, 2); - mv.visitLabel(l4); - mv.visitJumpInsn(GOTO, l6); - mv.visitFrame(F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" }); - mv.visitLabel(l3); - mv.visitVarInsn(ASTORE, 3); - mv.visitLabel(l5); - mv.visitVarInsn(ALOAD, 3); - mv.visitInsn(ATHROW); - mv.visitFrame(F_SAME, 0, null, 0, null); - mv.visitLabel(l6); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void sameLocals1stackItemFrameExtended(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "sameLocals1stackItemFrameExtended", "()I", null, null); - mv.visitCode(); - Label l0 = new Label(); - Label l1 = new Label(); - Label l2 = new Label(); - mv.visitTryCatchBlock(l0, l1, l2, null); - Label l3 = new Label(); - mv.visitTryCatchBlock(l2, l3, l2, null); - mv.visitLabel(l0); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 1); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 3); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 5); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 7); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 9); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 11); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 13); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 15); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 17); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 19); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 21); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 23); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 25); - mv.visitLabel(l1); - mv.visitInsn(ICONST_0); - mv.visitInsn(IRETURN); - mv.visitFrame(F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" }); - mv.visitLabel(l2); - mv.visitVarInsn(ASTORE, 27); - mv.visitLabel(l3); - mv.visitInsn(ICONST_0); - mv.visitInsn(IRETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void sameFrameExtended(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "sameFrameExtended", "(Z)V", null, null); - mv.visitCode(); - mv.visitFrame(F_SAME, 0, null, 0, null); - Label l0 = new Label(); - mv.visitLabel(l0); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 2); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 4); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 6); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 8); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 10); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 12); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 14); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 16); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 18); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 20); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 22); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 24); - mv.visitLdcInsn(new Long(11L)); - mv.visitVarInsn(LSTORE, 26); - mv.visitVarInsn(ILOAD, 1); - Label l1 = new Label(); - mv.visitJumpInsn(IFEQ, l1); - mv.visitInsn(RETURN); - mv.visitFrame(F_SAME, 0, null, 0, null); - mv.visitLabel(l1); - mv.visitJumpInsn(GOTO, l0); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void deadCode(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "deadCode", "(Z)V", null, null); - mv.visitCode(); - Label l0 = new Label(); - Label l1 = new Label(); - Label l2 = new Label(); - Label l3 = new Label(); - mv.visitTryCatchBlock(l0, l1, l1, "java/lang/Exception"); - mv.visitTryCatchBlock(l2, l3, l3, "java/lang/Exception"); - mv.visitJumpInsn(GOTO, l2); - mv.visitFrame(F_SAME, 0, null, 0, null); - mv.visitLabel(l0); - mv.visitInsn(RETURN); - mv.visitFrame(F_SAME1, 0, null, 1, new Object[] { "java/lang/Exception" }); - mv.visitLabel(l1); - mv.visitVarInsn(ASTORE, 2); - mv.visitInsn(RETURN); - mv.visitFrame(F_FULL, 0, new Object[] { "pkg/FrameTable", INTEGER }, 0, null); - mv.visitLabel(l2); - mv.visitInsn(RETURN); - mv.visitFrame(F_SAME1, 0, null, 1, new Object[] { "java/lang/Exception" }); - mv.visitLabel(l3); - mv.visitVarInsn(ASTORE, 2); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - /** - * Ad hoc class adapter used to rename the FrameTable class and to change - * its class version. - * - * @author Eric Bruneton - */ - static class RenameAdapter extends ClassAdapter { - - public RenameAdapter(final ClassVisitor cv) { - super(cv); - } - - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - super.visit(V1_5, access, "pkg/FrameMap", signature, superName, interfaces); - } - - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - return new MethodAdapter(super.visitMethod(access, name, desc, signature, exceptions)) { - public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, - final Object[] stack) { - Object[] clocal = new Object[local.length]; - for (int i = 0; i < clocal.length; ++i) { - clocal[i] = local[i]; - if ("pkg/FrameTable".equals(clocal[i])) { - clocal[i] = "pkg/FrameMap"; - } - } - Object[] cstack = new Object[stack.length]; - for (int i = 0; i < cstack.length; ++i) { - cstack[i] = stack[i]; - if ("pkg/FrameTable".equals(cstack[i])) { - cstack[i] = "pkg/FrameMap"; - } - } - super.visitFrame(type, nLocal, clocal, nStack, cstack); - } - - public void visitTypeInsn(final int opcode, final String desc) { - if (desc.equals("pkg/FrameTable")) { - super.visitTypeInsn(opcode, "pkg/FrameMap"); - } else { - super.visitTypeInsn(opcode, desc); - } - } - - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - if (owner.equals("pkg/FrameTable")) { - super.visitMethodInsn(opcode, "pkg/FrameMap", name, desc); - } else { - super.visitMethodInsn(opcode, owner, name, desc); - } - } - }; - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Generator.java b/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Generator.java deleted file mode 100644 index 4324172ca..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Generator.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.test.cases; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; - -import com.alibaba.citrus.asm.Opcodes; - -/** - * Generates classes designed so that the "conform" test suite, applied to these - * classes, covers all the ASM code base. - * - * @author Eric Bruneton - */ -public class Generator implements Opcodes { - - public static void main(final String[] args) throws IOException { - Generator generators[] = { new Annotation(), new Attribute(), new Debug(), new Enum(), new Frames(), - new Insns(), new Interface(), new JSR(), new Outer(), new Wide() }; - for (int i = 0; i < generators.length; ++i) { - generators[i].generate(args[0]); - } - } - - protected void generate(final String dir) throws IOException { - } - - protected void generate(final String dir, final String path, final byte[] clazz) throws IOException { - File f = new File(new File(dir), path); - f.getParentFile().mkdirs(); - FileOutputStream o = new FileOutputStream(f); - o.write(clazz); - o.close(); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Insns.java b/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Insns.java deleted file mode 100644 index 4e3184c81..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Insns.java +++ /dev/null @@ -1,746 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.test.cases; - -import java.io.IOException; - -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Type; - -/** - * Generates a class that contain all bytecode instruction types (except JSR and - * RET). Also covers access flags, signatures, and unicode characters. - * - * @author Eric Bruneton - */ -public class Insns extends Generator { - - public void generate(final String dir) throws IOException { - generate(dir, "pkg/Insns.class", dump()); - } - - public byte[] dump() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - FieldVisitor fv; - MethodVisitor mv; - - cw - .visit( - V1_5, - ACC_PUBLIC + ACC_SUPER, - "pkg/Insns", - "Ljava/util/ArrayList;LInterface;", - "java/util/ArrayList", new String[] { "Interface" }); - - fv = cw.visitField(ACC_PRIVATE + ACC_FINAL, "z", "Z", null, new Integer(1)); - fv.visitEnd(); - - fv = cw.visitField(ACC_PROTECTED, "b", "B", null, null); - fv.visitEnd(); - - fv = cw.visitField(ACC_PUBLIC, "c", "C", null, null); - fv.visitEnd(); - - fv = cw.visitField(ACC_STATIC, "s", "S", null, null); - fv.visitEnd(); - - fv = cw.visitField(ACC_PRIVATE + ACC_TRANSIENT, "i", "I", null, null); - fv.visitEnd(); - - fv = cw.visitField(ACC_PRIVATE + ACC_VOLATILE, "l", "J", null, null); - fv.visitEnd(); - - fv = cw.visitField(0, "f", "F", null, null); - fv.visitEnd(); - - fv = cw.visitField(0, "d", "D", null, null); - fv.visitEnd(); - - fv = cw.visitField(0, "str", "Ljava/lang/String;", null, ""); - fv.visitEnd(); - - fv = cw.visitField(0, "e", "Ljava/lang/Object;", "TE;", null); - fv.visitEnd(); - - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "", "()V"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - mv = cw.visitMethod(ACC_PUBLIC + ACC_SYNCHRONIZED, "m", "(ZBCSIFJDLjava/lang/Object;)Ljava/lang/Object;", - "(ZBCSIFJDTE;)TE;", null); - mv.visitCode(); - mv.visitInsn(ACONST_NULL); - mv.visitInsn(ARETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - // instruction types - constInsns(cw); - varInsns(cw); - arrayInsns(cw); - stackInsns(cw); - mathInsns(cw); - castInsns(cw); - jumpInsns(cw); - returnInsns(cw); - fieldInsns(cw); - methodInsns(cw); - monitorInsns(cw); - - // various method types not covered by other test cases - varargMethod(cw); - bridgeMethod(cw); - nativeMethod(cw); - clinitMethod(cw); - - cw.visitEnd(); - - return cw.toByteArray(); - } - - private void constInsns(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "constInsns", "()V", null, null); - mv.visitInsn(NOP); - mv.visitInsn(ACONST_NULL); - mv.visitInsn(ICONST_M1); - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_1); - mv.visitInsn(ICONST_2); - mv.visitInsn(ICONST_3); - mv.visitInsn(ICONST_4); - mv.visitInsn(ICONST_5); - mv.visitInsn(LCONST_0); - mv.visitInsn(LCONST_1); - mv.visitInsn(FCONST_0); - mv.visitInsn(FCONST_1); - mv.visitInsn(FCONST_2); - mv.visitInsn(DCONST_0); - mv.visitInsn(DCONST_1); - mv.visitIntInsn(BIPUSH, 16); - mv.visitIntInsn(SIPUSH, 256); - mv.visitLdcInsn(new Integer(65536)); - mv.visitLdcInsn(new Long(128L)); - mv.visitLdcInsn(new Float("128.0")); - mv.visitLdcInsn(new Double("128.0")); - mv.visitLdcInsn("\n\r\u0009\"\\"); - mv - .visitLdcInsn("\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u1111\u0111\u0011\u0001"); - mv.visitLdcInsn(Type.getType("Ljava/lang/Object;")); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void varInsns(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "varInsns", "(IJFDD)V", null, null); - mv.visitVarInsn(ILOAD, 1); - mv.visitVarInsn(IINC, 1); - mv.visitVarInsn(ISTORE, 1); - mv.visitVarInsn(LLOAD, 2); - mv.visitVarInsn(LSTORE, 2); - mv.visitVarInsn(FLOAD, 4); - mv.visitVarInsn(FSTORE, 4); - mv.visitVarInsn(DLOAD, 5); - mv.visitVarInsn(DSTORE, 5); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ASTORE, 0); - mv.visitInsn(ICONST_0); - mv.visitVarInsn(ISTORE, 3); - mv.visitInsn(LCONST_0); - mv.visitVarInsn(LSTORE, 6); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void arrayInsns(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "arrayInsns", "()V", null, null); - // boolean arrays - mv.visitInsn(ICONST_1); - mv.visitIntInsn(NEWARRAY, T_BOOLEAN); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(BASTORE); - mv.visitInsn(ICONST_0); - mv.visitInsn(BALOAD); - // byte arrays - mv.visitInsn(ICONST_1); - mv.visitIntInsn(NEWARRAY, T_BYTE); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(BASTORE); - mv.visitInsn(ICONST_0); - mv.visitInsn(BALOAD); - // char arrays - mv.visitInsn(ICONST_1); - mv.visitIntInsn(NEWARRAY, T_CHAR); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(CASTORE); - mv.visitInsn(ICONST_0); - mv.visitInsn(CALOAD); - // short arrays - mv.visitInsn(ICONST_1); - mv.visitIntInsn(NEWARRAY, T_SHORT); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(SASTORE); - mv.visitInsn(ICONST_0); - mv.visitInsn(SALOAD); - // int arrays - mv.visitInsn(ICONST_1); - mv.visitIntInsn(NEWARRAY, T_INT); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(IASTORE); - mv.visitInsn(ICONST_0); - mv.visitInsn(IALOAD); - // long arrays - mv.visitInsn(ICONST_1); - mv.visitIntInsn(NEWARRAY, T_LONG); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitInsn(LCONST_0); - mv.visitInsn(LASTORE); - mv.visitInsn(ICONST_0); - mv.visitInsn(LALOAD); - // float arrays - mv.visitInsn(ICONST_1); - mv.visitIntInsn(NEWARRAY, T_FLOAT); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitInsn(FCONST_0); - mv.visitInsn(FASTORE); - mv.visitInsn(ICONST_0); - mv.visitInsn(FALOAD); - // double arrays - mv.visitInsn(ICONST_1); - mv.visitIntInsn(NEWARRAY, T_DOUBLE); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitInsn(DCONST_0); - mv.visitInsn(DASTORE); - mv.visitInsn(ICONST_0); - mv.visitInsn(DALOAD); - // object arrays - mv.visitInsn(ICONST_1); - mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitInsn(ACONST_NULL); - mv.visitInsn(AASTORE); - mv.visitInsn(ICONST_0); - mv.visitInsn(AALOAD); - // multi dimensional arrays - mv.visitInsn(ICONST_1); - mv.visitTypeInsn(ANEWARRAY, "[I"); - mv.visitInsn(ICONST_1); - mv.visitInsn(ICONST_2); - mv.visitInsn(ICONST_3); - mv.visitMultiANewArrayInsn("[[[I", 3); - // array length - mv.visitInsn(ARRAYLENGTH); - // end method - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void stackInsns(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "stackInsns", "()V", null, null); - // pop - mv.visitInsn(ICONST_0); - mv.visitInsn(POP); - // pop2 (two variants) - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(POP2); - mv.visitInsn(LCONST_0); - mv.visitInsn(POP2); - // dup - mv.visitInsn(ICONST_0); - mv.visitInsn(DUP); - // dup_x1 - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(DUP_X1); - // dup_x2 (two variants) - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(DUP_X2); - mv.visitInsn(LCONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(DUP_X2); - // dup2 (two variants) - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(DUP2); - mv.visitInsn(LCONST_0); - mv.visitInsn(DUP2); - // dup2_x1 (two variants) - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(DUP2_X1); - mv.visitInsn(ICONST_0); - mv.visitInsn(LCONST_0); - mv.visitInsn(DUP2_X1); - // dup2_x2 (four variants) - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(DUP2_X2); - mv.visitInsn(LCONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(DUP2_X2); - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_0); - mv.visitInsn(LCONST_0); - mv.visitInsn(DUP2_X2); - mv.visitInsn(LCONST_0); - mv.visitInsn(LCONST_0); - mv.visitInsn(DUP2_X2); - // swap - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_1); - mv.visitInsn(SWAP); - // end method - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void mathInsns(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "mathInsns", "(IJFD)V", null, null); - // int math insns - for (int i = 0; i < 12; ++i) { - mv.visitVarInsn(ILOAD, 1); - } - mv.visitInsn(IADD); - mv.visitInsn(ISUB); - mv.visitInsn(IMUL); - mv.visitInsn(IDIV); - mv.visitInsn(IREM); - mv.visitInsn(INEG); - mv.visitInsn(ISHL); - mv.visitInsn(ISHR); - mv.visitInsn(IUSHR); - mv.visitInsn(IAND); - mv.visitInsn(IOR); - mv.visitInsn(IXOR); - // long math insns - for (int i = 0; i < 9; ++i) { - mv.visitVarInsn(LLOAD, 2); - } - mv.visitInsn(LADD); - mv.visitInsn(LSUB); - mv.visitInsn(LMUL); - mv.visitInsn(LDIV); - mv.visitInsn(LREM); - mv.visitInsn(LNEG); - mv.visitVarInsn(ILOAD, 1); - mv.visitInsn(LSHL); - mv.visitVarInsn(ILOAD, 1); - mv.visitInsn(LSHR); - mv.visitVarInsn(ILOAD, 1); - mv.visitInsn(LUSHR); - mv.visitInsn(LAND); - mv.visitInsn(LOR); - mv.visitInsn(LXOR); - // float math insns - for (int i = 0; i < 6; ++i) { - mv.visitVarInsn(FLOAD, 4); - } - mv.visitInsn(FADD); - mv.visitInsn(FSUB); - mv.visitInsn(FMUL); - mv.visitInsn(FDIV); - mv.visitInsn(FREM); - mv.visitInsn(FNEG); - // double math insns - for (int i = 0; i < 6; ++i) { - mv.visitVarInsn(DLOAD, 5); - } - mv.visitInsn(DADD); - mv.visitInsn(DSUB); - mv.visitInsn(DMUL); - mv.visitInsn(DDIV); - mv.visitInsn(DREM); - mv.visitInsn(DNEG); - // end method - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void castInsns(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "castInsns", "(IJFD)V", null, null); - // I2x - mv.visitVarInsn(ILOAD, 1); - mv.visitInsn(I2L); - mv.visitVarInsn(LSTORE, 2); - mv.visitVarInsn(ILOAD, 1); - mv.visitInsn(I2F); - mv.visitVarInsn(FSTORE, 4); - mv.visitVarInsn(ILOAD, 1); - mv.visitInsn(I2D); - mv.visitVarInsn(DSTORE, 5); - // L2x - mv.visitVarInsn(LLOAD, 2); - mv.visitInsn(L2I); - mv.visitVarInsn(ISTORE, 1); - mv.visitVarInsn(LLOAD, 2); - mv.visitInsn(L2F); - mv.visitVarInsn(FSTORE, 4); - mv.visitVarInsn(LLOAD, 2); - mv.visitInsn(L2D); - mv.visitVarInsn(DSTORE, 5); - // F2x - mv.visitVarInsn(FLOAD, 4); - mv.visitInsn(F2I); - mv.visitVarInsn(ISTORE, 1); - mv.visitVarInsn(FLOAD, 4); - mv.visitInsn(F2L); - mv.visitVarInsn(LSTORE, 2); - mv.visitVarInsn(FLOAD, 4); - mv.visitInsn(F2D); - mv.visitVarInsn(DSTORE, 5); - // D2x - mv.visitVarInsn(DLOAD, 5); - mv.visitInsn(D2I); - mv.visitVarInsn(ISTORE, 1); - mv.visitVarInsn(DLOAD, 5); - mv.visitInsn(D2L); - mv.visitVarInsn(LSTORE, 2); - mv.visitVarInsn(DLOAD, 5); - mv.visitInsn(D2F); - mv.visitVarInsn(FSTORE, 4); - // I2B - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ILOAD, 1); - mv.visitInsn(I2B); - mv.visitFieldInsn(PUTFIELD, "pkg/Insns", "b", "B"); - // I2C - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ILOAD, 1); - mv.visitInsn(I2C); - mv.visitFieldInsn(PUTFIELD, "pkg/Insns", "c", "C"); - // I2S - mv.visitVarInsn(ILOAD, 1); - mv.visitInsn(I2S); - mv.visitFieldInsn(PUTSTATIC, "pkg/Insns", "s", "S"); - // checkcast - mv.visitInsn(ACONST_NULL); - mv.visitTypeInsn(CHECKCAST, "java/lang/String"); - mv.visitInsn(ACONST_NULL); - mv.visitTypeInsn(CHECKCAST, "[[I"); - // instanceof - mv.visitInsn(ACONST_NULL); - mv.visitTypeInsn(INSTANCEOF, "java/lang/String"); - // end method - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void jumpInsns(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "jumpInsns", "(IJFD)V", null, null); - Label l0 = new Label(); - // ifxx - mv.visitVarInsn(ILOAD, 1); - mv.visitJumpInsn(IFNE, l0); - mv.visitVarInsn(ILOAD, 1); - mv.visitJumpInsn(IFEQ, l0); - mv.visitVarInsn(ILOAD, 1); - mv.visitJumpInsn(IFLE, l0); - mv.visitVarInsn(ILOAD, 1); - mv.visitJumpInsn(IFGE, l0); - mv.visitVarInsn(ILOAD, 1); - mv.visitJumpInsn(IFLT, l0); - mv.visitVarInsn(ILOAD, 1); - mv.visitJumpInsn(IFGT, l0); - // ificmpxx - mv.visitVarInsn(ILOAD, 1); - mv.visitVarInsn(ILOAD, 1); - mv.visitJumpInsn(IF_ICMPNE, l0); - mv.visitVarInsn(ILOAD, 1); - mv.visitVarInsn(ILOAD, 1); - mv.visitJumpInsn(IF_ICMPEQ, l0); - mv.visitVarInsn(ILOAD, 1); - mv.visitVarInsn(ILOAD, 1); - mv.visitJumpInsn(IF_ICMPLE, l0); - mv.visitVarInsn(ILOAD, 1); - mv.visitVarInsn(ILOAD, 1); - mv.visitJumpInsn(IF_ICMPGE, l0); - mv.visitVarInsn(ILOAD, 1); - mv.visitVarInsn(ILOAD, 1); - mv.visitJumpInsn(IF_ICMPLT, l0); - mv.visitVarInsn(ILOAD, 1); - mv.visitVarInsn(ILOAD, 1); - mv.visitJumpInsn(IF_ICMPGT, l0); - // lcmp - mv.visitVarInsn(LLOAD, 2); - mv.visitVarInsn(LLOAD, 2); - mv.visitInsn(LCMP); - mv.visitJumpInsn(IFNE, l0); - // fcmpx - mv.visitVarInsn(FLOAD, 4); - mv.visitVarInsn(FLOAD, 4); - mv.visitInsn(FCMPL); - mv.visitJumpInsn(IFNE, l0); - mv.visitVarInsn(FLOAD, 4); - mv.visitVarInsn(FLOAD, 4); - mv.visitInsn(FCMPG); - mv.visitJumpInsn(IFNE, l0); - // dcmpx - mv.visitVarInsn(DLOAD, 5); - mv.visitVarInsn(DLOAD, 5); - mv.visitInsn(DCMPL); - mv.visitJumpInsn(IFNE, l0); - mv.visitVarInsn(DLOAD, 5); - mv.visitVarInsn(DLOAD, 5); - mv.visitInsn(DCMPG); - mv.visitJumpInsn(IFNE, l0); - // ifacmp - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 0); - mv.visitJumpInsn(IF_ACMPNE, l0); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 0); - mv.visitJumpInsn(IF_ACMPEQ, l0); - // ifnull - mv.visitVarInsn(ALOAD, 0); - mv.visitJumpInsn(IFNULL, l0); - mv.visitInsn(ICONST_0); - mv.visitVarInsn(ISTORE, 7); - mv.visitVarInsn(ALOAD, 0); - mv.visitJumpInsn(IFNONNULL, l0); - mv.visitInsn(ICONST_0); - mv.visitVarInsn(ISTORE, 7); - mv.visitVarInsn(ALOAD, 0); - // tableswitch - Label l1 = new Label(); - Label l2 = new Label(); - Label l3 = new Label(); - mv.visitVarInsn(ILOAD, 1); - mv.visitTableSwitchInsn(0, 2, l3, new Label[] { l1, l2, l3 }); - mv.visitLabel(l1); - mv.visitInsn(ICONST_1); - mv.visitVarInsn(ISTORE, 7); - mv.visitJumpInsn(GOTO, l3); - mv.visitLabel(l2); - mv.visitInsn(ICONST_2); - mv.visitVarInsn(ISTORE, 7); - mv.visitJumpInsn(GOTO, l3); - mv.visitLabel(l3); - mv.visitVarInsn(ILOAD, 7); - // lookupswitch - Label l4 = new Label(); - Label l5 = new Label(); - Label l6 = new Label(); - mv.visitVarInsn(ILOAD, 1); - mv.visitLookupSwitchInsn(l6, new int[] { 0, 1, 2 }, new Label[] { l4, l5, l6 }); - mv.visitLabel(l4); - mv.visitInsn(ICONST_1); - mv.visitVarInsn(ISTORE, 7); - mv.visitJumpInsn(GOTO, l6); - mv.visitLabel(l5); - mv.visitInsn(ICONST_2); - mv.visitVarInsn(ISTORE, 7); - mv.visitJumpInsn(GOTO, l6); - mv.visitLabel(l6); - mv.visitVarInsn(ILOAD, 7); - // throw - mv.visitInsn(ACONST_NULL); - mv.visitInsn(ATHROW); - // misc instructions to cover code in MethodWriter.resizeInsns - mv.visitLabel(l0); - mv.visitInsn(ICONST_1); - mv.visitInsn(ICONST_2); - mv.visitMultiANewArrayInsn("[[I", 2); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "size", "()V"); - // end method - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void returnInsns(final ClassWriter cw) { - MethodVisitor mv; - mv = cw.visitMethod(ACC_STATIC, "ireturnInsn", "()I", null, null); - mv.visitCode(); - mv.visitInsn(ICONST_0); - mv.visitInsn(IRETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - mv = cw.visitMethod(ACC_PRIVATE, "lreturnInsn", "()J", null, null); - mv.visitCode(); - mv.visitInsn(LCONST_0); - mv.visitInsn(LRETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - mv = cw.visitMethod(0, "freturnInsn", "()F", null, null); - mv.visitCode(); - mv.visitInsn(FCONST_0); - mv.visitInsn(FRETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - mv = cw.visitMethod(0, "dreturnInsn", "()D", null, null); - mv.visitCode(); - mv.visitInsn(DCONST_0); - mv.visitInsn(DRETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void fieldInsns(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "fieldInsns", "()V", null, null); - mv.visitFieldInsn(GETSTATIC, "pkg/Insns", "s", "S"); - mv.visitFieldInsn(PUTSTATIC, "pkg/Insns", "s", "S"); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, "pkg/Insns", "i", "I"); - mv.visitFieldInsn(PUTFIELD, "pkg/Insns", "i", "I"); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, "pkg/Insns", "l", "J"); - mv.visitFieldInsn(PUTFIELD, "pkg/Insns", "l", "J"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void methodInsns(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "methodInsns", "()V", null, null); - // invokstatic - mv.visitMethodInsn(INVOKESTATIC, "pkg/Insns", "ireturn", "()I"); - // invokespecial - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "pkg/Insns", "lreturn", "()J"); - // invokevirtual - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKEVIRTUAL, "pkg/Insns", "freturn", "()F"); - // invokeinterface - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "size", "()I"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void monitorInsns(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "monitorInsns", "()V", null, null); - mv.visitVarInsn(ALOAD, 0); - mv.visitInsn(MONITORENTER); - mv.visitVarInsn(ALOAD, 0); - mv.visitInsn(MONITOREXIT); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void varargMethod(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_VARARGS + ACC_STRICT, "varargMethod", - "([Ljava/lang/Object;)V", "([Ljava/lang/Object;)V^TF;", new String[] { "java/lang/Exception" }); - mv.visitCode(); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void bridgeMethod(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "get", "(I)Ljava/lang/String;", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ILOAD, 1); - mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "get", "(I)Ljava/lang/Object;"); - mv.visitTypeInsn(CHECKCAST, "java/lang/String"); - mv.visitInsn(ARETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - mv = cw.visitMethod(ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "get", "(I)Ljava/lang/Object;", "(I)TE;", null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ILOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, "pkg/Insns", "get", "(I)Ljava/lang/String;"); - mv.visitInsn(ARETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void nativeMethod(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PRIVATE + ACC_NATIVE, "nativeMethod", "()V", null, null); - mv.visitEnd(); - } - - private void clinitMethod(final ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_STATIC, "", "()V", null, null); - mv.visitCode(); - mv.visitInsn(ICONST_1); - mv.visitFieldInsn(PUTSTATIC, "pkg/Insns", "s", "S"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Interface.java b/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Interface.java deleted file mode 100644 index cf8887d14..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Interface.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.test.cases; - -import java.io.IOException; - -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * Generates an interface class. Also covers signatures, default package and non - * null minor class version number. - * - * @author Eric Bruneton - */ -public class Interface extends Generator { - - @Override - public void generate(final String dir) throws IOException { - generate(dir, "Interface.class", dump()); - } - - public byte[] dump() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - - cw.visit(1 << 16 | V1_5, ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE, "Interface", - "Ljava/lang/Object;", "java/lang/Object", null); - - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "m", - "(ZBCSIFJDLjava/lang/Object;)Ljava/lang/Object;", "(ZBCSIFJDTE;)TE;", null); - mv.visitEnd(); - - cw.visitEnd(); - - return cw.toByteArray(); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/JSR.java b/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/JSR.java deleted file mode 100644 index c43844e37..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/JSR.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.test.cases; - -import java.io.IOException; - -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * Generates classes with JSR/RET instructions. Covers forward and backward JSR - * and JSR_W instructions. Also covers the wide form of IFNULL instruction, and - * the V1_1 class version (these jump instructions are not directly generated in - * their 'wide' form, but are transformed to this form by the method resizing - * test). - * - * @author Eric Bruneton - */ -public class JSR extends Generator { - - @Override - public void generate(final String dir) throws IOException { - generate(dir, "pkg/JSR1.class", dumpForwardJSR()); - generate(dir, "pkg/JSR2.class", dumpBackwardJSR()); - } - - public byte[] dumpForwardJSR() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - MethodVisitor mv; - - cw.visit(V1_1, ACC_PUBLIC, "pkg/JSR1", null, "java/lang/Object", null); - - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - mv = cw.visitMethod(ACC_PUBLIC, "forwardJSR", "([I)V", null, null); - mv.visitCode(); - Label l0 = new Label(); - Label l1 = new Label(); - Label l2 = new Label(); - Label l3 = new Label(); - Label l4 = new Label(); - Label l5 = new Label(); - mv.visitTryCatchBlock(l0, l1, l2, null); - mv.visitTryCatchBlock(l2, l3, l2, null); - mv.visitLabel(l0); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, "pkg/JSR1", "forwardJSR", "([I)V"); - mv.visitJumpInsn(JSR, l4); // forward JSR, will give forward JSR_W - - // many NOPs will be introduced here by the method resizing test - - mv.visitLabel(l1); - mv.visitJumpInsn(GOTO, l5); - mv.visitLabel(l2); - mv.visitVarInsn(ASTORE, 2); - mv.visitJumpInsn(JSR, l4); - mv.visitLabel(l3); - mv.visitVarInsn(ALOAD, 2); - mv.visitInsn(ATHROW); - mv.visitLabel(l4); - mv.visitVarInsn(ASTORE, 3); - mv.visitInsn(DCONST_0); - mv.visitVarInsn(DSTORE, 4); - mv.visitVarInsn(RET, 3); - mv.visitLabel(l5); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - cw.visitEnd(); - - return cw.toByteArray(); - } - - public byte[] dumpBackwardJSR() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - MethodVisitor mv; - - cw.visit(V1_1, ACC_PUBLIC, "pkg/JSR2", null, "java/lang/Object", null); - - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - mv = cw.visitMethod(ACC_PUBLIC, "backwardJSR", "([I)V", null, null); - mv.visitCode(); - Label l0 = new Label(); - Label l1 = new Label(); - Label l2 = new Label(); - Label l3 = new Label(); - Label l4 = new Label(); - Label l5 = new Label(); - Label l6 = new Label(); - mv.visitTryCatchBlock(l0, l1, l2, null); - mv.visitTryCatchBlock(l2, l3, l2, null); - mv.visitInsn(ICONST_0); - mv.visitVarInsn(ISTORE, 4); - mv.visitJumpInsn(GOTO, l0); - mv.visitLabel(l4); - mv.visitVarInsn(ASTORE, 3); - mv.visitIincInsn(4, 1); - mv.visitVarInsn(RET, 3); - - /* extra instructions only used to trigger method resizing */ - mv.visitLabel(l0); - mv.visitInsn(ACONST_NULL); - mv.visitJumpInsn(IFNULL, l6); // will give wide IFNULL - // many NOPs will be introduced here by the method resizing test - mv.visitJumpInsn(GOTO, l6); - mv.visitLabel(l6); - - mv.visitJumpInsn(JSR, l4); // backward JSR, will give JSR_W - mv.visitLabel(l1); - mv.visitJumpInsn(GOTO, l5); - mv.visitLabel(l2); - mv.visitVarInsn(ASTORE, 2); - mv.visitJumpInsn(JSR, l4); - mv.visitLabel(l3); - mv.visitVarInsn(ALOAD, 2); - mv.visitInsn(ATHROW); - mv.visitLabel(l5); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - cw.visitEnd(); - - return cw.toByteArray(); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Outer.java b/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Outer.java deleted file mode 100644 index e22e80a15..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Outer.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.test.cases; - -import java.io.IOException; - -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * Generates a class with two inner classes. Covers all features used by inner - * classes (visitInner, visitOuter, synthetic members, etc). Also covers the - * V1_4 class version and the DEPRECATED access flag. - * - * @author Eric Bruneton - */ -public class Outer extends Generator { - - @Override - public void generate(final String dir) throws IOException { - generate(dir, "pkg/Outer.class", dump()); - generate(dir, "pkg/Outer$1.class", dump1()); - generate(dir, "pkg/Outer$Inner.class", dumpInner()); - } - - public byte[] dump() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - FieldVisitor fv; - MethodVisitor mv; - - cw.visit(V1_4, ACC_PUBLIC + ACC_SUPER + ACC_DEPRECATED, "pkg/Outer", null, "java/lang/Object", null); - - cw.visitInnerClass("pkg/Outer$Inner", "pkg/Outer", "C", 0); - cw.visitInnerClass("pkg/Outer$1", null, null, 0); - - fv = cw.visitField(ACC_PRIVATE + ACC_DEPRECATED, "i", "I", null, null); - fv.visitEnd(); - - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - mv = cw.visitMethod(ACC_DEPRECATED, "m", "()V", null, null); - mv.visitCode(); - mv.visitTypeInsn(NEW, "pkg/Outer$1"); - mv.visitInsn(DUP); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "pkg/Outer$1", "", "(Lpkg/Outer;)V"); - mv.visitInsn(POP); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - mv = cw.visitMethod(ACC_STATIC + ACC_SYNTHETIC, "access$000", "(Lpkg/Outer;)I", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, "pkg/Outer", "i", "I"); - mv.visitInsn(IRETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - cw.visitEnd(); - - return cw.toByteArray(); - } - - public static byte[] dump1() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - FieldVisitor fv; - MethodVisitor mv; - - cw.visit(V1_4, ACC_SUPER, "pkg/Outer$1", null, "pkg/Outer", null); - - cw.visitOuterClass("pkg/Outer", "m", "()V"); - cw.visitInnerClass("pkg/Outer$1", null, null, 0); - - fv = cw.visitField(ACC_FINAL + ACC_SYNTHETIC, "this$0", "Lpkg/Outer;", null, null); - fv.visitEnd(); - - mv = cw.visitMethod(0, "", "(Lpkg/Outer;)V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 1); - mv.visitFieldInsn(PUTFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;"); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "pkg/Outer", "", "()V"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - mv = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null); - mv.visitCode(); - mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); - mv.visitInsn(DUP); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "", "()V"); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", - "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"); - mv.visitLdcInsn(" "); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", - "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;"); - mv.visitMethodInsn(INVOKESTATIC, "pkg/Outer", "access$000", "(Lpkg/Outer;)I"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); - mv.visitInsn(ARETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - cw.visitEnd(); - - return cw.toByteArray(); - } - - public static byte[] dumpInner() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - FieldVisitor fv; - MethodVisitor mv; - - cw.visit(V1_4, ACC_SUPER, "pkg/Outer$Inner", null, "java/lang/Object", null); - - cw.visitInnerClass("pkg/Outer$Inner", "pkg/Outer", "C", 0); - - fv = cw.visitField(ACC_FINAL + ACC_SYNTHETIC, "this$0", "Lpkg/Outer;", null, null); - fv.visitEnd(); - - mv = cw.visitMethod(0, "", "(Lpkg/Outer;)V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 1); - mv.visitFieldInsn(PUTFIELD, "pkg/Outer$Inner", "this$0", "Lpkg/Outer;"); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - cw.visitEnd(); - - return cw.toByteArray(); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Wide.java b/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Wide.java deleted file mode 100644 index 067a7f0ae..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/test/cases/Wide.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.test.cases; - -import java.io.IOException; - -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; - -/** - * Generates a class which uses a lot of locals and constant pool values. Covers - * the 'wide' form of instructions that have one (xLOAD and xSTORE, LDC, IINC, - * GOTO and IF instructions - these jump instructions are not directly generated - * in their 'wide' form, but are transformed to this form by the method resizing - * test). Also covers the V1_2 class version. - * - * @author Eric Bruneton - */ -public class Wide extends Generator { - - @Override - public void generate(final String dir) throws IOException { - generate(dir, "pkg/Wide.class", dump()); - } - - public byte[] dump() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - MethodVisitor mv; - - cw.visit(V1_2, ACC_PUBLIC, "pkg/Wide", null, "java/lang/Object", null); - - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); - for (int i = 0; i < 256; ++i) { - mv.visitLdcInsn(Integer.toString(i)); // wide form - mv.visitInsn(POP); - } - mv.visitInsn(RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - mv = cw.visitMethod(ACC_PUBLIC, "wideLocals", "(I)I", null, null); - mv.visitCode(); - Label l0 = new Label(); - Label l1 = new Label(); - mv.visitJumpInsn(GOTO, l1); // will give GOTO_W - - mv.visitLabel(l0); - mv.visitIincInsn(300, 1); // covers 'update maxlocals' in MethodWriter - mv.visitVarInsn(ILOAD, 300); // will give wide form - mv.visitJumpInsn(IFEQ, l1); // will give long forward jump - - // many NOPs will be introduced here by the method resizing test - - mv.visitVarInsn(ILOAD, 300); // will give wide form - mv.visitInsn(IRETURN); - - mv.visitLabel(l1); - for (int i = 1; i < 300; ++i) { - mv.visitVarInsn(ILOAD, i); - if (i <= 5) { - mv.visitInsn(ICONST_0 + i); - } else if (i <= Byte.MAX_VALUE) { - mv.visitIntInsn(BIPUSH, i); - } else { - mv.visitIntInsn(SIPUSH, i); - } - mv.visitInsn(IADD); - mv.visitVarInsn(ISTORE, i + 1); - } - mv.visitInsn(ICONST_0); - mv.visitJumpInsn(IFEQ, l0); // will give long backward jump - mv.visitJumpInsn(GOTO, l0); // will give long backward goto - - mv.visitMaxs(0, 0); - mv.visitEnd(); - - cw.visitEnd(); - - return cw.toByteArray(); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/ClassNodeTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/tree/ClassNodeTest.java deleted file mode 100644 index e9d72dd80..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/ClassNodeTest.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.commons.EmptyVisitor; - -/** - * ClassNode tests. - * - * @author Eric Bruneton - */ -public class ClassNodeTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new ClassNodeTest().getSuite(); - } - - @Override - public void test() throws Exception { - InsnList.check = false; - ClassReader cr = new ClassReader(openStream()); - ClassNode cn = new ClassNode(); - cr.accept(cn, 0); - // clone instructions for testing clone methods - for (int i = 0; i < cn.methods.size(); ++i) { - MethodNode mn = (MethodNode) cn.methods.get(i); - Iterator it = mn.instructions.iterator(); - Map m = new HashMap() { - private static final long serialVersionUID = -6584953308559937925L; - - @Override - public Object get(final Object o) { - return o; - } - }; - while (it.hasNext()) { - AbstractInsnNode insn = (AbstractInsnNode) it.next(); - mn.instructions.set(insn, insn.clone(m)); - } - } - // test accept with visitors that remove class members - cn.accept(new EmptyVisitor() { - @Override - public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { - return null; - } - - @Override - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - return null; - } - }); - ClassWriter cw = new ClassWriter(0); - cn.accept(cw); - assertEquals(cr, new ClassReader(cw.toByteArray())); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/ClassNodeUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/tree/ClassNodeUnitTest.java deleted file mode 100644 index 1143862e3..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/ClassNodeUnitTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import junit.framework.TestCase; - -import com.alibaba.citrus.asm.Opcodes; - -/** - * ClassNode unit tests. - * - * @author Eric Bruneton - */ -public class ClassNodeUnitTest extends TestCase implements Opcodes { - - public void testFrameNode() { - FrameNode fn = new FrameNode(F_SAME, 0, null, 0, null); - assertEquals(AbstractInsnNode.FRAME, fn.getType()); - } - - public void testInsnNode() { - InsnNode in = new InsnNode(NOP); - assertEquals(in.getOpcode(), NOP); - assertEquals(AbstractInsnNode.INSN, in.getType()); - } - - public void testIntInsnNode() { - IntInsnNode iin = new IntInsnNode(BIPUSH, 0); - iin.setOpcode(SIPUSH); - assertEquals(SIPUSH, iin.getOpcode()); - assertEquals(AbstractInsnNode.INT_INSN, iin.getType()); - } - - public void testVarInsnNode() { - VarInsnNode vn = new VarInsnNode(ALOAD, 0); - vn.setOpcode(ASTORE); - assertEquals(ASTORE, vn.getOpcode()); - assertEquals(AbstractInsnNode.VAR_INSN, vn.getType()); - } - - public void testTypeInsnNode() { - TypeInsnNode tin = new TypeInsnNode(NEW, "java/lang/Object"); - tin.setOpcode(CHECKCAST); - assertEquals(CHECKCAST, tin.getOpcode()); - assertEquals(AbstractInsnNode.TYPE_INSN, tin.getType()); - } - - public void testFieldInsnNode() { - FieldInsnNode fn = new FieldInsnNode(GETSTATIC, "owner", "name", "I"); - fn.setOpcode(PUTSTATIC); - assertEquals(PUTSTATIC, fn.getOpcode()); - assertEquals(AbstractInsnNode.FIELD_INSN, fn.getType()); - } - - public void testMethodInsnNode() { - MethodInsnNode mn = new MethodInsnNode(INVOKESTATIC, "owner", "name", "I"); - mn.setOpcode(INVOKESPECIAL); - assertEquals(INVOKESPECIAL, mn.getOpcode()); - assertEquals(AbstractInsnNode.METHOD_INSN, mn.getType()); - } - - public void testJumpInsnNode() { - JumpInsnNode jn = new JumpInsnNode(GOTO, new LabelNode()); - jn.setOpcode(IFEQ); - assertEquals(IFEQ, jn.getOpcode()); - assertEquals(AbstractInsnNode.JUMP_INSN, jn.getType()); - } - - public void testLabelNode() { - LabelNode ln = new LabelNode(); - assertEquals(AbstractInsnNode.LABEL, ln.getType()); - assertTrue(ln.getLabel() != null); - } - - public void testIincInsnNode() { - IincInsnNode iincn = new IincInsnNode(1, 1); - assertEquals(AbstractInsnNode.IINC_INSN, iincn.getType()); - } - - public void testLdcInsnNode() { - LdcInsnNode ldcn = new LdcInsnNode("s"); - assertEquals(AbstractInsnNode.LDC_INSN, ldcn.getType()); - } - - public void testLookupSwitchInsnNode() { - LookupSwitchInsnNode lsn = new LookupSwitchInsnNode(null, null, null); - assertEquals(AbstractInsnNode.LOOKUPSWITCH_INSN, lsn.getType()); - } - - public void testTableSwitchInsnNode() { - TableSwitchInsnNode tsn = new TableSwitchInsnNode(0, 1, null, null); - assertEquals(AbstractInsnNode.TABLESWITCH_INSN, tsn.getType()); - } - - public void testMultiANewArrayInsnNode() { - MultiANewArrayInsnNode manan = new MultiANewArrayInsnNode("[[I", 2); - assertEquals(AbstractInsnNode.MULTIANEWARRAY_INSN, manan.getType()); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/InsnListUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/tree/InsnListUnitTest.java deleted file mode 100644 index 9a625d487..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/InsnListUnitTest.java +++ /dev/null @@ -1,697 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree; - -import java.util.ListIterator; -import java.util.NoSuchElementException; - -import junit.framework.TestCase; - -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodAdapter; - -/** - * InsnList unit tests. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public class InsnListUnitTest extends TestCase { - - InsnList l1; - - InsnList l2; - - InsnNode in1; - - InsnNode in2; - - @Override - protected void setUp() throws Exception { - super.setUp(); - InsnList.check = true; - l1 = new InsnList(); - l2 = new InsnList(); - in1 = new InsnNode(0); - in2 = new InsnNode(0); - l2.add(in1); - l2.add(in2); - } - - protected void assertEquals(final AbstractInsnNode[] expected, final AbstractInsnNode[] value) { - assertEquals(expected.length, value.length); - for (int i = 0; i < value.length; ++i) { - assertEquals(expected[i], value[i]); - } - } - - public void testSize() { - assertEquals(0, l1.size()); - } - - public void testGetFirst() { - assertEquals(null, l1.getFirst()); - } - - public void testGetLast() { - assertEquals(null, l1.getLast()); - } - - public void testInvalidGet() { - try { - l1.get(0); - fail(); - } catch (IndexOutOfBoundsException e) { - } - } - - public void testContains() { - assertEquals(false, l1.contains(new InsnNode(0))); - } - - public void testIterator() { - InsnNode insn = new InsnNode(0); - - // iteration - ListIterator it = l2.iterator(); - assertTrue(it.hasNext()); - assertEquals(in1, it.next()); - assertTrue(it.hasNext()); - assertEquals(in2, it.next()); - assertFalse(it.hasNext()); - assertTrue(it.hasPrevious()); - assertEquals(in2, it.previous()); - assertTrue(it.hasPrevious()); - assertEquals(in1, it.previous()); - assertFalse(it.hasPrevious()); - - l2.add(insn); - - // remove() - it = l2.iterator(); - assertTrue(it.hasNext()); - assertEquals(in1, it.next()); - assertTrue(it.hasNext()); - assertEquals(in2, it.next()); - assertTrue(it.hasNext()); - it.remove(); // remove in2 - assertTrue(it.hasNext()); - assertEquals(insn, it.next()); - assertFalse(it.hasNext()); - assertTrue(it.hasPrevious()); - - it = l2.iterator(); - assertTrue(it.hasNext()); - assertEquals(in1, it.next()); - assertTrue(it.hasNext()); - assertEquals(insn, it.next()); - assertFalse(it.hasNext()); - - l2.remove(insn); - l2.insert(in1, in2); - - // add() then next() - it = l2.iterator(); - assertTrue(it.hasNext()); - assertEquals(in1, it.next()); - it.add(insn); - assertEquals(in2, it.next()); - - l2.remove(insn); - - // add() then previous() - it = l2.iterator(); - assertTrue(it.hasNext()); - assertEquals(in1, it.next()); - it.add(insn); - assertEquals(insn, it.previous()); - assertEquals(insn, it.next()); - assertTrue(it.hasNext()); - assertEquals(in2, it.next()); - assertFalse(it.hasNext()); - - l2.remove(insn); - - // set() then previous() - it = l2.iterator(); - assertTrue(it.hasNext()); - assertEquals(in1, it.next()); - it.set(insn); - assertEquals(insn, it.previous()); - assertEquals(insn, it.next()); - assertTrue(it.hasNext()); - - l2.remove(insn); - l2.insertBefore(in2, in1); - - // add() then next() - it = l2.iterator(); - assertTrue(it.hasNext()); - assertEquals(in1, it.next()); - it.set(insn); - assertEquals(in2, it.next()); - } - - public void testIterator2() { - ListIterator it = l2.iterator(l2.size()); - - assertFalse(it.hasNext()); - assertTrue(it.hasPrevious()); - assertEquals(1, it.previousIndex()); - assertEquals(in2, it.previous()); - assertTrue(it.hasPrevious()); - assertEquals(0, it.previousIndex()); - assertEquals(in1, it.previous()); - assertFalse(it.hasPrevious()); - - assertEquals(-1, it.previousIndex()); - - assertTrue(it.hasNext()); - assertEquals(0, it.nextIndex()); - assertEquals(in1, it.next()); - assertTrue(it.hasNext()); - assertEquals(1, it.nextIndex()); - - InsnNode insn = new InsnNode(0); - it.add(insn); - - assertEquals(2, it.nextIndex()); - assertEquals(in2, it.next()); - assertFalse(it.hasNext()); - assertEquals(3, it.nextIndex()); - } - - public void testIterator3() { - try { - new InsnList().iterator().next(); - fail(); - } catch (NoSuchElementException e) { - } - } - - public void testInvalidIndexOf() { - try { - l1.indexOf(new InsnNode(0)); - fail(); - } catch (IllegalArgumentException e) { - } - } - - public void testToArray() { - assertEquals(0, l1.toArray().length); - } - - public void testInvalidSet() { - try { - l1.set(new InsnNode(0), new InsnNode(0)); - fail(); - } catch (IllegalArgumentException e) { - } - } - - public void testSet() { - l1.add(new InsnNode(0)); - AbstractInsnNode insn = new InsnNode(0); - l1.set(l1.getFirst(), insn); - assertEquals(1, l1.size()); - assertEquals(insn, l1.getFirst()); - - l1.remove(insn); - l1.add(new InsnNode(0)); - - l1.set(l1.get(0), insn); - assertEquals(1, l1.size()); - assertEquals(insn, l1.getFirst()); - - l1.remove(insn); - l1.add(new InsnNode(0)); - l1.add(new InsnNode(0)); - - l1.set(l1.get(1), insn); - assertEquals(2, l1.size()); - assertEquals(insn, l1.get(1)); - } - - public void testInvalidAdd() { - try { - l1.add(in1); - fail(); - } catch (IllegalArgumentException e) { - } - } - - public void testAddEmpty() { - InsnNode insn = new InsnNode(0); - l1.add(insn); - assertEquals(1, l1.size()); - assertEquals(insn, l1.getFirst()); - assertEquals(insn, l1.getLast()); - assertEquals(insn, l1.get(0)); - assertEquals(true, l1.contains(insn)); - assertEquals(0, l1.indexOf(insn)); - assertEquals(new AbstractInsnNode[] { insn }, l1.toArray()); - assertEquals(null, insn.getPrevious()); - assertEquals(null, insn.getNext()); - } - - public void testAddNonEmpty() { - InsnNode insn = new InsnNode(0); - l1.add(new InsnNode(0)); - l1.add(insn); - assertEquals(2, l1.size()); - assertEquals(insn, l1.getLast()); - assertEquals(1, l1.indexOf(insn)); - assertEquals(insn, l1.get(1)); - assertEquals(true, l1.contains(insn)); - } - - public void testAddEmptyList() { - l1.add(new InsnList()); - assertEquals(0, l1.size()); - assertEquals(null, l1.getFirst()); - assertEquals(null, l1.getLast()); - assertEquals(new AbstractInsnNode[0], l1.toArray()); - } - - public void testInvalidAddAll() { - try { - l1.add(l1); - fail(); - } catch (IllegalArgumentException e) { - } - } - - public void testAddAllEmpty() { - l1.add(l2); - assertEquals(2, l1.size()); - assertEquals(in1, l1.getFirst()); - assertEquals(in2, l1.getLast()); - assertEquals(in1, l1.get(0)); - assertEquals(true, l1.contains(in1)); - assertEquals(true, l1.contains(in2)); - assertEquals(0, l1.indexOf(in1)); - assertEquals(1, l1.indexOf(in2)); - assertEquals(new AbstractInsnNode[] { in1, in2 }, l1.toArray()); - } - - public void testAddAllNonEmpty() { - InsnNode insn = new InsnNode(0); - l1.add(insn); - l1.add(l2); - assertEquals(3, l1.size()); - assertEquals(insn, l1.getFirst()); - assertEquals(in2, l1.getLast()); - assertEquals(insn, l1.get(0)); - assertEquals(true, l1.contains(insn)); - assertEquals(true, l1.contains(in1)); - assertEquals(true, l1.contains(in2)); - assertEquals(0, l1.indexOf(insn)); - assertEquals(1, l1.indexOf(in1)); - assertEquals(2, l1.indexOf(in2)); - assertEquals(new AbstractInsnNode[] { insn, in1, in2 }, l1.toArray()); - } - - public void testInvalidInsert() { - try { - l1.insert(in1); - fail(); - } catch (IllegalArgumentException e) { - } - } - - public void testInsertEmpty() { - InsnNode insn = new InsnNode(0); - l1.insert(insn); - assertEquals(1, l1.size()); - assertEquals(insn, l1.getFirst()); - assertEquals(insn, l1.getLast()); - assertEquals(insn, l1.get(0)); - assertEquals(true, l1.contains(insn)); - assertEquals(0, l1.indexOf(insn)); - assertEquals(new AbstractInsnNode[] { insn }, l1.toArray()); - } - - public void testInsertNonEmpty() { - InsnNode insn = new InsnNode(0); - l1.add(new InsnNode(0)); - l1.insert(insn); - assertEquals(2, l1.size()); - assertEquals(insn, l1.getFirst()); - assertEquals(insn, l1.get(0)); - assertEquals(true, l1.contains(insn)); - assertEquals(0, l1.indexOf(insn)); - } - - public void testInvalidInsertAll() { - try { - l1.insert(l1); - fail(); - } catch (IllegalArgumentException e) { - } - } - - public void testInsertAllEmptyList() { - l1.insert(new InsnList()); - assertEquals(0, l1.size()); - assertEquals(null, l1.getFirst()); - assertEquals(null, l1.getLast()); - assertEquals(new AbstractInsnNode[0], l1.toArray()); - } - - public void testInsertAllEmpty() { - l1.insert(l2); - assertEquals(2, l1.size(), 2); - assertEquals(in1, l1.getFirst()); - assertEquals(in2, l1.getLast()); - assertEquals(in1, l1.get(0)); - assertEquals(true, l1.contains(in1)); - assertEquals(true, l1.contains(in2)); - assertEquals(0, l1.indexOf(in1)); - assertEquals(1, l1.indexOf(in2)); - assertEquals(new AbstractInsnNode[] { in1, in2 }, l1.toArray()); - } - - public void testInsertAllNonEmpty() { - InsnNode insn = new InsnNode(0); - l1.add(insn); - l1.insert(l2); - assertEquals(3, l1.size()); - assertEquals(in1, l1.getFirst()); - assertEquals(insn, l1.getLast()); - assertEquals(in1, l1.get(0)); - assertEquals(true, l1.contains(insn)); - assertEquals(true, l1.contains(in1)); - assertEquals(true, l1.contains(in2)); - assertEquals(0, l1.indexOf(in1)); - assertEquals(1, l1.indexOf(in2)); - assertEquals(2, l1.indexOf(insn)); - assertEquals(new AbstractInsnNode[] { in1, in2, insn }, l1.toArray()); - } - - public void testInvalidInsert2() { - try { - l1.insert(new InsnNode(0), new InsnNode(0)); - fail(); - } catch (IllegalArgumentException e) { - } - } - - public void testInsert2NotLast() { - InsnNode insn = new InsnNode(0); - l2.insert(in1, insn); - assertEquals(3, l2.size()); - assertEquals(in1, l2.getFirst()); - assertEquals(in2, l2.getLast()); - assertEquals(in1, l2.get(0)); - assertEquals(true, l2.contains(insn)); - assertEquals(1, l2.indexOf(insn)); - assertEquals(new AbstractInsnNode[] { in1, insn, in2 }, l2.toArray()); - } - - public void testInsert2Last() { - InsnNode insn = new InsnNode(0); - l2.insert(in2, insn); - assertEquals(3, l2.size()); - assertEquals(in1, l2.getFirst()); - assertEquals(insn, l2.getLast()); - assertEquals(in1, l2.get(0)); - assertEquals(true, l2.contains(insn)); - assertEquals(2, l2.indexOf(insn)); - assertEquals(new AbstractInsnNode[] { in1, in2, insn }, l2.toArray()); - } - - public void testInsertBefore() { - InsnNode insn = new InsnNode(0); - l2.insertBefore(in2, insn); - assertEquals(3, l2.size()); - assertEquals(in1, l2.getFirst()); - assertEquals(in2, l2.getLast()); - assertEquals(insn, l2.get(1)); - assertEquals(true, l2.contains(insn)); - assertEquals(1, l2.indexOf(insn)); - assertEquals(new AbstractInsnNode[] { in1, insn, in2 }, l2.toArray()); - } - - public void testInsertBeforeFirst() { - InsnNode insn = new InsnNode(0); - l2.insertBefore(in1, insn); - assertEquals(3, l2.size()); - assertEquals(insn, l2.getFirst()); - assertEquals(in2, l2.getLast()); - assertEquals(insn, l2.get(0)); - assertEquals(true, l2.contains(insn)); - assertEquals(0, l2.indexOf(insn)); - assertEquals(new AbstractInsnNode[] { insn, in1, in2 }, l2.toArray()); - } - - public void testInvalidInsertBefore() { - try { - l1.insertBefore(new InsnNode(0), new InsnNode(0)); - fail(); - } catch (IllegalArgumentException e) { - } - } - - public void testInvalidInsertAll2() { - try { - l1.insert(new InsnNode(0), new InsnList()); - fail(); - } catch (IllegalArgumentException e) { - } - } - - public void testInsertAll2EmptyList() { - InsnNode insn = new InsnNode(0); - l1.add(insn); - l1.insert(insn, new InsnList()); - assertEquals(1, l1.size()); - assertEquals(insn, l1.getFirst()); - assertEquals(insn, l1.getLast()); - assertEquals(new AbstractInsnNode[] { insn }, l1.toArray()); - } - - public void testInsertAll2NotLast() { - InsnNode insn = new InsnNode(0); - l1.add(insn); - l1.add(new InsnNode(0)); - l1.insert(insn, l2); - assertEquals(4, l1.size()); - assertEquals(insn, l1.getFirst()); - assertEquals(insn, l1.get(0)); - assertEquals(true, l1.contains(insn)); - assertEquals(true, l1.contains(in1)); - assertEquals(true, l1.contains(in2)); - assertEquals(0, l1.indexOf(insn)); - assertEquals(1, l1.indexOf(in1)); - assertEquals(2, l1.indexOf(in2)); - } - - public void testInsertAll2Last() { - InsnNode insn = new InsnNode(0); - l1.add(insn); - l1.insert(insn, l2); - assertEquals(3, l1.size()); - assertEquals(insn, l1.getFirst()); - assertEquals(in2, l1.getLast()); - assertEquals(insn, l1.get(0)); - assertEquals(true, l1.contains(insn)); - assertEquals(true, l1.contains(in1)); - assertEquals(true, l1.contains(in2)); - assertEquals(0, l1.indexOf(insn)); - assertEquals(1, l1.indexOf(in1)); - assertEquals(2, l1.indexOf(in2)); - assertEquals(new AbstractInsnNode[] { insn, in1, in2 }, l1.toArray()); - } - - public void testInvalidInsertBeforeAll() { - try { - l1.insertBefore(new InsnNode(0), new InsnList()); - fail(); - } catch (IllegalArgumentException e) { - } - } - - public void testInsertBeforeAll2EmptyList() { - InsnNode insn = new InsnNode(0); - l1.add(insn); - l1.insertBefore(insn, new InsnList()); - assertEquals(1, l1.size()); - assertEquals(insn, l1.getFirst()); - assertEquals(insn, l1.getLast()); - assertEquals(new AbstractInsnNode[] { insn }, l1.toArray()); - } - - public void testInsertBeforeAll2NotLast() { - InsnNode insn = new InsnNode(0); - l1.add(new InsnNode(0)); - l1.add(insn); - l1.insertBefore(insn, l2); - assertEquals(4, l1.size()); - assertEquals(in1, l1.get(1)); - assertEquals(in2, l1.get(2)); - assertEquals(true, l1.contains(insn)); - assertEquals(true, l1.contains(in1)); - assertEquals(true, l1.contains(in2)); - assertEquals(3, l1.indexOf(insn)); - assertEquals(1, l1.indexOf(in1)); - assertEquals(2, l1.indexOf(in2)); - } - - public void testInsertBeforeAll2First() { - InsnNode insn = new InsnNode(0); - l1.insert(insn); - l1.insertBefore(insn, l2); - assertEquals(3, l1.size()); - assertEquals(in1, l1.getFirst()); - assertEquals(insn, l1.getLast()); - assertEquals(in1, l1.get(0)); - assertEquals(true, l1.contains(insn)); - assertEquals(true, l1.contains(in1)); - assertEquals(true, l1.contains(in2)); - assertEquals(2, l1.indexOf(insn)); - assertEquals(0, l1.indexOf(in1)); - assertEquals(1, l1.indexOf(in2)); - assertEquals(new AbstractInsnNode[] { in1, in2, insn }, l1.toArray()); - } - - public void testInvalidRemove() { - try { - l1.remove(new InsnNode(0)); - } catch (IllegalArgumentException e) { - } - } - - public void testRemoveSingle() { - InsnNode insn = new InsnNode(0); - l1.add(insn); - l1.remove(insn); - assertEquals(0, l1.size()); - assertEquals(null, l1.getFirst()); - assertEquals(null, l1.getLast()); - assertEquals(false, l1.contains(insn)); - assertEquals(new AbstractInsnNode[0], l1.toArray()); - assertEquals(null, insn.getPrevious()); - assertEquals(null, insn.getNext()); - } - - public void testRemoveFirst() { - InsnNode insn = new InsnNode(0); - l1.add(insn); - l1.add(new InsnNode(0)); - l1.remove(insn); - assertEquals(false, l1.contains(insn)); - assertEquals(null, insn.getPrevious()); - assertEquals(null, insn.getNext()); - } - - public void testRemoveMiddle() { - InsnNode insn = new InsnNode(0); - l1.add(new InsnNode(0)); - l1.add(insn); - l1.add(new InsnNode(0)); - l1.remove(insn); - assertEquals(false, l1.contains(insn)); - assertEquals(null, insn.getPrevious()); - assertEquals(null, insn.getNext()); - } - - public void testRemoveLast() { - InsnNode insn = new InsnNode(0); - l1.add(new InsnNode(0)); - l1.add(insn); - l1.remove(insn); - assertEquals(false, l1.contains(insn)); - assertEquals(null, insn.getPrevious()); - assertEquals(null, insn.getNext()); - } - - public void testClear() { - InsnNode insn = new InsnNode(0); - l1.add(new InsnNode(0)); - l1.add(insn); - l1.add(new InsnNode(0)); - l1.clear(); - assertEquals(0, l1.size()); - assertEquals(null, l1.getFirst()); - assertEquals(null, l1.getLast()); - assertEquals(false, l1.contains(insn)); - assertEquals(new AbstractInsnNode[0], l1.toArray()); - assertEquals(null, insn.getPrevious()); - assertEquals(null, insn.getNext()); - } - - public void testAcceptor1() { - l1.add(new InsnNode(55)); - l1.add(new InsnNode(77)); - - final InsnList lst = new InsnList(); - l1.accept(new MethodAdapter(null) { - @Override - public void visitInsn(int opcode) { - lst.add(new InsnNode(opcode)); - } - }); - - assertEquals(55, lst.get(0).opcode); - assertEquals(77, lst.get(1).opcode); - } - - public void testResetLabels() throws Exception { - LabelNode labelNode = new LabelNode(); - - l1.add(new InsnNode(55)); - l1.add(labelNode); - l1.add(new InsnNode(55)); - - Label label = labelNode.getLabel(); - assertNotNull(label); - - l1.resetLabels(); - - assertNotSame(label, labelNode.getLabel()); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/AnalyzerUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/AnalyzerUnitTest.java deleted file mode 100644 index d75c7f766..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/AnalyzerUnitTest.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassWriterComputeMaxsUnitTest; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.commons.EmptyVisitor; -import com.alibaba.citrus.asm.tree.MethodNode; - -/** - * Analyzer unit tests for methods with JSR instructions. - * - * @author Eric Bruneton - */ -public class AnalyzerUnitTest extends ClassWriterComputeMaxsUnitTest { - - @Override - protected boolean isComputeMaxs() { - return false; - } - - @Override - protected void assertMaxs(final int maxStack, final int maxLocals) { - mv.visitMaxs(maxStack, maxLocals); - mv.visitEnd(); - cw.visitEnd(); - byte[] b = cw.toByteArray(); - ClassReader cr = new ClassReader(b); - cr.accept(new EmptyVisitor() { - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - if (name.equals("m")) { - return new MethodNode(access, name, desc, signature, exceptions) { - @Override - public void visitEnd() { - Analyzer a = new Analyzer(new BasicInterpreter()); - try { - Frame[] frames = a.analyze("C", this); - int mStack = 0; - int mLocals = 0; - for (int i = 0; i < frames.length; ++i) { - if (frames[i] != null) { - mStack = Math.max(mStack, frames[i].getStackSize()); - mLocals = Math.max(mLocals, frames[i].getLocals()); - } - } - assertEquals("maxStack", maxStack, mStack); - assertEquals("maxLocals", maxLocals, mLocals); - } catch (Exception e) { - fail(e.getMessage()); - } - } - }; - } else { - return new EmptyVisitor(); - } - } - }, 0); - - try { - TestClassLoader loader = new TestClassLoader(); - Class c = loader.defineClass("C", b); - c.newInstance(); - } catch (Throwable t) { - fail(t.getMessage()); - } - } - - @Override - protected void assertGraph(final String graph) { - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/BasicInterpreterTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/BasicInterpreterTest.java deleted file mode 100644 index 6b7b7b9ed..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/BasicInterpreterTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import java.util.List; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.tree.ClassNode; -import com.alibaba.citrus.asm.tree.MethodNode; - -/** - * Analysis tests. - * - * @author Eric Bruneton - */ -public class BasicInterpreterTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new BasicInterpreterTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - ClassNode cn = new ClassNode(); - cr.accept(cn, 0); - List methods = cn.methods; - for (int i = 0; i < methods.size(); ++i) { - MethodNode method = (MethodNode) methods.get(i); - Analyzer a = new Analyzer(new BasicInterpreter()); - a.analyze(cn.name, method); - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/BasicVerifierTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/BasicVerifierTest.java deleted file mode 100644 index 422969094..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/BasicVerifierTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import java.util.List; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.tree.ClassNode; -import com.alibaba.citrus.asm.tree.MethodNode; - -/** - * Analysis tests. - * - * @author Eric Bruneton - */ -public class BasicVerifierTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new BasicVerifierTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - ClassNode cn = new ClassNode(); - cr.accept(cn, 0); - List methods = cn.methods; - for (int i = 0; i < methods.size(); ++i) { - MethodNode method = (MethodNode) methods.get(i); - Analyzer a = new Analyzer(new BasicVerifier()); - a.analyze(cn.name, method); - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/SimpleVerifierTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/SimpleVerifierTest.java deleted file mode 100644 index 97403f605..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/SimpleVerifierTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import java.util.List; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.AsmTestParams; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.tree.ClassNode; -import com.alibaba.citrus.asm.tree.MethodNode; - -/** - * Verifier tests. - * - * @author Eric Bruneton - */ -public class SimpleVerifierTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - TestSuite suite = new TestSuite(SimpleVerifierTest.class.getName()); - - suite.addTest(new SimpleVerifierTest().getSuite(new AsmTestParams(2, 0))); - suite.addTest(new SimpleVerifierTest().getSuite(new AsmTestParams(2, 1))); - - return suite; - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - ClassNode cn = new ClassNode(); - cr.accept(cn, 0); - List methods = cn.methods; - for (int i = 0; i < methods.size(); ++i) { - MethodNode method = (MethodNode) methods.get(i); - Analyzer a = new Analyzer(new SimpleVerifier()); - a.analyze(cn.name, method); - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/SimpleVerifierUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/SimpleVerifierUnitTest.java deleted file mode 100644 index 48afda114..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/SimpleVerifierUnitTest.java +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import junit.framework.TestCase; - -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; -import com.alibaba.citrus.asm.tree.MethodNode; - -/** - * SimpleVerifier unit tests. - * - * @author Eric Bruneton - */ -public class SimpleVerifierUnitTest extends TestCase implements Opcodes { - - private Analyzer a; - - private MethodNode mn; - - @Override - protected void setUp() { - Type c = Type.getType("LC;"); - Type d = Type.getType("Ljava/lang/Number;"); - a = new Analyzer(new SimpleVerifier(c, d, false)); - mn = new MethodNode(ACC_PUBLIC, "m", "()V", null, null); - } - - private void assertValid() throws AnalyzerException { - mn.visitInsn(RETURN); - mn.visitMaxs(10, 10); - a.analyze("C", mn); - Frame[] frames = a.getFrames(); - for (int i = 0; i < frames.length; ++i) { - if (frames[i] != null) { - frames[i].toString(); - } - } - a.getHandlers(0); - } - - private void assertInvalid() { - mn.visitInsn(RETURN); - mn.visitMaxs(10, 10); - try { - a.analyze("C", mn); - fail(); - } catch (AnalyzerException e) { - } catch (RuntimeException e) { - } - } - - public void testInvalidOpcode() { - mn.visitInsn(-1); - assertInvalid(); - } - - public void testInvalidPop() { - mn.visitInsn(LCONST_0); - mn.visitInsn(POP); - assertInvalid(); - } - - public void testInvalidPop2() { - mn.visitInsn(LCONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(POP2); - assertInvalid(); - } - - public void testInvalidDup() { - mn.visitInsn(LCONST_0); - mn.visitInsn(DUP); - assertInvalid(); - } - - public void testInvalidDupx1() { - mn.visitInsn(LCONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(DUP_X1); - assertInvalid(); - } - - public void testInvalidDupx2() { - mn.visitInsn(LCONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(DUP_X2); - assertInvalid(); - } - - public void testInvalidDup2() { - mn.visitInsn(LCONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(DUP2); - assertInvalid(); - } - - public void testInvalidDup2x1() { - mn.visitInsn(LCONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(DUP2_X1); - assertInvalid(); - } - - public void testInvalidDup2x2() { - mn.visitInsn(LCONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(DUP2_X2); - assertInvalid(); - } - - public void testInvalidSwap() { - mn.visitInsn(LCONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(SWAP); - assertInvalid(); - } - - public void testInvalidGetLocal() { - mn.visitVarInsn(ALOAD, 10); - assertInvalid(); - } - - public void testInvalidSetLocal() { - mn.visitInsn(ACONST_NULL); - mn.visitVarInsn(ASTORE, 10); - assertInvalid(); - } - - public void testInvalidEmptyStack() { - mn.visitInsn(POP); - assertInvalid(); - } - - public void testInvalidFullStack() { - mn.visitInsn(ICONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(ICONST_0); - assertInvalid(); - } - - public void testInconsistentStackHeights() { - Label l0 = new Label(); - mn.visitInsn(ICONST_0); - mn.visitJumpInsn(IFEQ, l0); - mn.visitInsn(ICONST_0); - mn.visitLabel(l0); - assertInvalid(); - } - - public void testInvalidNewArray() { - mn.visitInsn(ICONST_1); - mn.visitIntInsn(NEWARRAY, -1); - assertInvalid(); - } - - public void testInvalidAload() { - mn.visitInsn(ICONST_0); - mn.visitVarInsn(ISTORE, 1); - mn.visitVarInsn(ALOAD, 1); - assertInvalid(); - } - - public void testInvalidAstore() { - mn.visitInsn(ICONST_0); - mn.visitVarInsn(ASTORE, 1); - assertInvalid(); - } - - public void testInvalidIstore() { - mn.visitInsn(ACONST_NULL); - mn.visitVarInsn(ISTORE, 1); - assertInvalid(); - } - - public void testInvalidCheckcast() { - mn.visitInsn(ICONST_0); - mn.visitTypeInsn(CHECKCAST, "java/lang/String"); - assertInvalid(); - } - - public void testInvalidArraylength() { - mn.visitInsn(ICONST_0); - mn.visitInsn(ARRAYLENGTH); - assertInvalid(); - } - - public void testInvalidAthrow() { - mn.visitInsn(ICONST_0); - mn.visitInsn(ATHROW); - assertInvalid(); - } - - public void testInvalidIneg() { - mn.visitInsn(FCONST_0); - mn.visitInsn(INEG); - assertInvalid(); - } - - public void testInvalidIadd() { - mn.visitInsn(FCONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(IADD); - assertInvalid(); - } - - public void testInvalidIsub() { - mn.visitInsn(ICONST_0); - mn.visitInsn(FCONST_0); - mn.visitInsn(ISUB); - assertInvalid(); - } - - public void testInvalidIastore() { - mn.visitInsn(ICONST_1); - mn.visitIntInsn(NEWARRAY, T_INT); - mn.visitInsn(FCONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(IASTORE); - assertInvalid(); - } - - public void testInvalidFastore() { - mn.visitInsn(ICONST_1); - mn.visitIntInsn(NEWARRAY, T_FLOAT); - mn.visitInsn(ICONST_0); - mn.visitInsn(ICONST_0); - mn.visitInsn(FASTORE); - assertInvalid(); - } - - public void testInvalidLastore() { - mn.visitInsn(ICONST_1); - mn.visitInsn(ICONST_0); - mn.visitInsn(LCONST_0); - mn.visitInsn(LASTORE); - assertInvalid(); - } - - public void testInvalidMultianewarray() { - mn.visitInsn(FCONST_1); - mn.visitInsn(ICONST_2); - mn.visitMultiANewArrayInsn("[[I", 2); - assertInvalid(); - } - - public void testInvalidInvokevirtual() { - mn.visitInsn(ACONST_NULL); - mn.visitTypeInsn(CHECKCAST, "java/lang/Object"); - mn.visitMethodInsn(INVOKEVIRTUAL, "java/util/List", "size", "()I"); - assertInvalid(); - } - - public void testInvalidInvokeinterface() { - mn.visitInsn(ACONST_NULL); - mn.visitTypeInsn(CHECKCAST, "java/util/List"); - mn.visitInsn(FCONST_0); - mn.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;"); - assertInvalid(); - } - - public void testInvalidRet() { - mn.visitVarInsn(RET, 1); - assertInvalid(); - } - - public void testInvalidFalloff() { - mn.visitMaxs(10, 10); - try { - a.analyze("C", mn); - fail(); - } catch (AnalyzerException e) { - } catch (RuntimeException e) { - } - } - - public void testInvalidSubroutineFalloff() { - Label l0 = new Label(); - Label l1 = new Label(); - mn.visitJumpInsn(GOTO, l0); - mn.visitLabel(l1); - mn.visitVarInsn(ASTORE, 1); - mn.visitVarInsn(RET, 1); - mn.visitLabel(l0); - mn.visitJumpInsn(JSR, l1); - mn.visitMaxs(10, 10); - try { - a.analyze("C", mn); - fail(); - } catch (AnalyzerException e) { - } catch (RuntimeException e) { - } - } - - public void testNestedSubroutines() throws AnalyzerException { - Label l0 = new Label(); - Label l1 = new Label(); - mn.visitJumpInsn(JSR, l0); - mn.visitInsn(RETURN); - mn.visitLabel(l0); - mn.visitVarInsn(ASTORE, 1); - mn.visitJumpInsn(JSR, l1); - mn.visitJumpInsn(JSR, l1); - mn.visitVarInsn(RET, 1); - mn.visitLabel(l1); - mn.visitVarInsn(ASTORE, 2); - mn.visitVarInsn(RET, 2); - assertValid(); - } - - public void testSubroutineLocalsAccess() throws AnalyzerException { - MethodVisitor mv = mn; - mv.visitCode(); - Label l0 = new Label(); - Label l1 = new Label(); - Label l2 = new Label(); - Label l3 = new Label(); - mv.visitTryCatchBlock(l0, l0, l1, null); - mv.visitTryCatchBlock(l0, l2, l2, "java/lang/RuntimeException"); - mv.visitLabel(l0); - mv.visitJumpInsn(JSR, l3); - mv.visitInsn(RETURN); - mv.visitLabel(l1); - mv.visitVarInsn(ASTORE, 1); - mv.visitJumpInsn(JSR, l3); - mv.visitVarInsn(ALOAD, 1); - mv.visitInsn(ATHROW); - mv.visitLabel(l3); - mv.visitVarInsn(ASTORE, 2); - mv.visitInsn(ACONST_NULL); - mv.visitVarInsn(ASTORE, 3); - mv.visitVarInsn(RET, 2); - mv.visitLabel(l2); - mv.visitVarInsn(ASTORE, 4); - mv.visitVarInsn(ALOAD, 4); - mv.visitInsn(ATHROW); - assertValid(); - } - - public void _testOverlappingSubroutines() { - // TODO currently Analyzer can not detect this situation. The problem - // is that other overlapping subroutine situations are valid, such as - // when a nested subroutine implicitely returns to its parent - // subroutine, without a RET. - Label l0 = new Label(); - Label l1 = new Label(); - Label l2 = new Label(); - mn.visitJumpInsn(JSR, l0); - mn.visitJumpInsn(JSR, l1); - mn.visitInsn(RETURN); - mn.visitLabel(l0); - mn.visitVarInsn(ASTORE, 1); - mn.visitJumpInsn(GOTO, l2); - mn.visitLabel(l1); - mn.visitVarInsn(ASTORE, 1); - mn.visitLabel(l2); - mn.visitVarInsn(RET, 1); - assertInvalid(); - } - - public void testMerge() throws AnalyzerException { - Label l0 = new Label(); - mn.visitVarInsn(ALOAD, 0); - mn.visitVarInsn(ASTORE, 1); - mn.visitInsn(ACONST_NULL); - mn.visitTypeInsn(CHECKCAST, "java/lang/Number"); - mn.visitVarInsn(ASTORE, 2); - mn.visitVarInsn(ALOAD, 0); - mn.visitVarInsn(ASTORE, 3); - mn.visitLabel(l0); - mn.visitInsn(ACONST_NULL); - mn.visitTypeInsn(CHECKCAST, "java/lang/Number"); - mn.visitVarInsn(ASTORE, 1); - mn.visitVarInsn(ALOAD, 0); - mn.visitVarInsn(ASTORE, 2); - mn.visitInsn(ACONST_NULL); - mn.visitTypeInsn(CHECKCAST, "java/lang/Integer"); - mn.visitVarInsn(ASTORE, 3); - mn.visitJumpInsn(GOTO, l0); - assertValid(); - } - - public void testClassNotFound() { - Label l0 = new Label(); - mn.visitVarInsn(ALOAD, 0); - mn.visitVarInsn(ASTORE, 1); - mn.visitLabel(l0); - mn.visitInsn(ACONST_NULL); - mn.visitTypeInsn(CHECKCAST, "D"); - mn.visitVarInsn(ASTORE, 1); - mn.visitJumpInsn(GOTO, l0); - mn.visitMaxs(10, 10); - try { - a.analyze("C", mn); - fail(); - } catch (Exception e) { - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/SmallSetUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/SmallSetUnitTest.java deleted file mode 100644 index cf8bd5766..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/SmallSetUnitTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import java.util.Set; - -import junit.framework.TestCase; - -/** - * SmallSet unit tests. - * - * @author Eric Bruneton - */ -public class SmallSetUnitTest extends TestCase { - - private final Object A = new Object(); - private final Object B = new Object(); - private final Object C = new Object(); - private final Object D = new Object(); - - public void testSubsetUnion() { - SmallSet s1 = new SmallSet(A, B); - SmallSet s2 = new SmallSet(A, null); - Set u = s1.union(s2); - Set v = s2.union(s1); - assertEquals(u, v); - s1.remove(); - } - - public void testDisjointUnion() { - SmallSet s1 = new SmallSet(A, B); - SmallSet s2 = new SmallSet(C, D); - Set u = s1.union(s2); - Set v = s2.union(s1); - assertEquals(u, v); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/SourceInterpreterTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/SourceInterpreterTest.java deleted file mode 100644 index c843fb3e3..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/SourceInterpreterTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import java.util.List; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.tree.ClassNode; -import com.alibaba.citrus.asm.tree.MethodNode; - -/** - * SourceInterpreter tests. - * - * @author Eric Bruneton - */ -public class SourceInterpreterTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new SourceInterpreterTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - ClassNode cn = new ClassNode(); - cr.accept(cn, 0); - List methods = cn.methods; - for (int i = 0; i < methods.size(); ++i) { - MethodNode method = (MethodNode) methods.get(i); - Analyzer a = new Analyzer(new SourceInterpreter()); - a.analyze(cn.name, method); - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/ValueUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/ValueUnitTest.java deleted file mode 100644 index daa6c37d5..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/tree/analysis/ValueUnitTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.tree.analysis; - -import junit.framework.TestCase; - -/** - * BasicValue and SourceValue unit tests. - * - * @author Eric Bruneton - */ -public class ValueUnitTest extends TestCase { - - public void testBasicValue() { - assertFalse(BasicValue.INT_VALUE.equals(new Object())); - BasicValue.INT_VALUE.hashCode(); - BasicValue.UNINITIALIZED_VALUE.toString(); - BasicValue.RETURNADDRESS_VALUE.toString(); - BasicValue.REFERENCE_VALUE.toString(); - } - - public void testSourceValue() { - new SourceValue(1).hashCode(); - assertFalse(new SourceValue(1).equals(null)); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/util/ASMifierTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/util/ASMifierTest.java deleted file mode 100644 index 88dddb30c..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/util/ASMifierTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import java.io.PrintWriter; -import java.io.StringReader; -import java.io.StringWriter; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; - -import junit.framework.TestSuite; - -import org.codehaus.janino.ClassLoaderIClassLoader; -import org.codehaus.janino.DebuggingInformation; -import org.codehaus.janino.IClassLoader; -import org.codehaus.janino.Parser; -import org.codehaus.janino.Scanner; -import org.codehaus.janino.UnitCompiler; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.AsmTestParams; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.attrs.CodeComment; -import com.alibaba.citrus.asm.attrs.Comment; - -/** - * ASMifier tests. - * - * @author Eugene Kuleshov - * @author Eric Bruneton - */ -public class ASMifierTest extends AbstractTest { - - public static final Compiler COMPILER = new Compiler(); - - public static final TestClassLoader LOADER = new TestClassLoader(); - - public static TestSuite suite() throws Exception { - return new ASMifierTest().getSuite(new AsmTestParams("java.lang")); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - - if (cr.b.length > 20000) { - return; - } - - StringWriter sw = new StringWriter(); - ASMifierClassVisitor cv = new ASMifierClassVisitor(new PrintWriter(sw)); - cr.accept(cv, new Attribute[] { new Comment(), new CodeComment() }, 0); - - String generated = sw.toString(); - - byte[] generatorClassData; - try { - generatorClassData = COMPILER.compile(n, generated); - } catch (Exception ex) { - System.err.println(generated); - System.err.println("------------------"); - throw ex; - } - - String nd = n + "Dump"; - if (n.indexOf('.') != -1) { - nd = "asm." + nd; - } - - Class c = LOADER.defineClass(nd, generatorClassData); - Method m = c.getMethod("dump", new Class[0]); - byte[] b = (byte[]) m.invoke(null, new Object[0]); - - assertEquals(cr, new ClassReader(b)); - } - - public static class TestClassLoader extends ClassLoader { - - public Class defineClass(final String name, final byte[] b) { - return defineClass(name, b, 0, b.length); - } - } - - public static class Compiler { - - final static IClassLoader CL = new ClassLoaderIClassLoader(new URLClassLoader(new URL[0])); - - public byte[] compile(final String name, final String source) throws Exception { - Parser p = new Parser(new Scanner(name, new StringReader(source))); - UnitCompiler uc = new UnitCompiler(p.parseCompilationUnit(), CL); - return uc.compileUnit(DebuggingInformation.ALL)[0].toByteArray(); - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/util/ASMifierUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/util/ASMifierUnitTest.java deleted file mode 100644 index af20e3bf3..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/util/ASMifierUnitTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import junit.framework.TestCase; - -import com.alibaba.citrus.asm.AsmTestParams; - -/** - * ASMifierClassVisitor unit tests - * - * @author Eric Bruneton - */ -public class ASMifierUnitTest extends TestCase { - - public void testASMifierClassVisitor() throws Exception { - String s = getClass().getName(); - ASMifierClassVisitor.main(new String[0]); - ASMifierClassVisitor.main(new String[] { "-debug" }); - ASMifierClassVisitor.main(new String[] { s }); - ASMifierClassVisitor.main(new String[] { "-debug", s }); - ASMifierClassVisitor.main(new String[] { new AsmTestParams().getClassPath("Interface.class") }); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/util/CheckClassAdapterTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/util/CheckClassAdapterTest.java deleted file mode 100644 index c42738f5c..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/util/CheckClassAdapterTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassWriter; - -/** - * CheckClassAdapter tests. - * - * @author Eric Bruneton - */ -public class CheckClassAdapterTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new CheckClassAdapterTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - ClassWriter cw = new ClassWriter(0); - cr.accept(new CheckClassAdapter(cw), 0); - assertEquals(cr, new ClassReader(cw.toByteArray())); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/util/CheckClassAdapterUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/util/CheckClassAdapterUnitTest.java deleted file mode 100644 index 292f1d8ad..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/util/CheckClassAdapterUnitTest.java +++ /dev/null @@ -1,807 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import java.io.PrintWriter; - -import junit.framework.TestCase; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.AsmTestParams; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.Label; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.attrs.Comment; -import com.alibaba.citrus.asm.commons.EmptyVisitor; - -public class CheckClassAdapterUnitTest extends TestCase implements Opcodes { - - public void testCheckClassVisitor() throws Exception { - String s = getClass().getName(); - CheckClassAdapter.main(new String[0]); - CheckClassAdapter.main(new String[] { s }); - CheckClassAdapter.main(new String[] { new AsmTestParams().getClassPath("Interface.class") }); - } - - public void testVerifyValidClass() throws Exception { - ClassReader cr = new ClassReader(getClass().getName()); - CheckClassAdapter.verify(cr, true, new PrintWriter(System.err)); - } - - public void testVerifyInvalidClass() { - ClassWriter cw = new ClassWriter(0); - cw.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null); - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "m", "()V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ISTORE, 30); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 31); - mv.visitEnd(); - cw.visitEnd(); - ClassReader cr = new ClassReader(cw.toByteArray()); - CheckClassAdapter.verify(cr, true, new PrintWriter(System.err)); - } - - public void testIllegalClassAccessFlag() { - ClassVisitor cv = new CheckClassAdapter(new EmptyVisitor()); - try { - cv.visit(V1_1, 1 << 20, "C", null, "java/lang/Object", null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalSuperClass() { - ClassVisitor cv = new CheckClassAdapter(new EmptyVisitor()); - try { - cv.visit(V1_1, ACC_PUBLIC, "java/lang/Object", null, "java/lang/Object", null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalInterfaceSuperClass() { - ClassVisitor cv = new CheckClassAdapter(new EmptyVisitor()); - try { - cv.visit(V1_1, ACC_INTERFACE, "I", null, "C", null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalClassSignature() { - ClassVisitor cv = new CheckClassAdapter(new EmptyVisitor()); - try { - cv.visit(V1_1, ACC_PUBLIC, "C", "LC;I", "java/lang/Object", null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalClassAccessFlagSet() { - ClassVisitor cv = new CheckClassAdapter(new EmptyVisitor()); - try { - cv.visit(V1_1, ACC_FINAL + ACC_ABSTRACT, "C", null, "java/lang/Object", null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalClassMemberVisitBeforeStart() { - ClassVisitor cv = new CheckClassAdapter(new EmptyVisitor()); - try { - cv.visitSource(null, null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalClassAttribute() { - ClassVisitor cv = new CheckClassAdapter(new EmptyVisitor()); - cv.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null); - try { - cv.visitAttribute(null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMultipleVisitCalls() { - ClassVisitor cv = new CheckClassAdapter(new EmptyVisitor()); - cv.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null); - try { - cv.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMultipleVisitSourceCalls() { - ClassVisitor cv = new CheckClassAdapter(new EmptyVisitor()); - cv.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null); - cv.visitSource(null, null); - try { - cv.visitSource(null, null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalOuterClassName() { - ClassVisitor cv = new CheckClassAdapter(new EmptyVisitor()); - cv.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null); - try { - cv.visitOuterClass(null, null, null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMultipleVisitOuterClassCalls() { - ClassVisitor cv = new CheckClassAdapter(new EmptyVisitor()); - cv.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null); - cv.visitOuterClass("name", null, null); - try { - cv.visitOuterClass(null, null, null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFieldAccessFlagSet() { - ClassVisitor cv = new CheckClassAdapter(new EmptyVisitor()); - cv.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null); - try { - cv.visitField(ACC_PUBLIC + ACC_PRIVATE, "i", "I", null, null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFieldSignature() { - ClassVisitor cv = new CheckClassAdapter(new EmptyVisitor()); - cv.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null); - try { - cv.visitField(ACC_PUBLIC, "i", "I", "L;", null); - fail(); - } catch (Exception e) { - } - try { - cv.visitField(ACC_PUBLIC, "i", "I", "LC+", null); - fail(); - } catch (Exception e) { - } - try { - cv.visitField(ACC_PUBLIC, "i", "I", "LC;I", null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalClassMemberVisitAfterEnd() { - ClassVisitor cv = new CheckClassAdapter(new EmptyVisitor()); - cv.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null); - cv.visitEnd(); - try { - cv.visitSource(null, null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFieldMemberVisitAfterEnd() { - FieldVisitor fv = new CheckFieldAdapter(new EmptyVisitor()); - fv.visitEnd(); - try { - fv.visitAttribute(new Comment()); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFieldAttribute() { - FieldVisitor fv = new CheckFieldAdapter(new EmptyVisitor()); - try { - fv.visitAttribute(null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalAnnotationDesc() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - try { - mv.visitParameterAnnotation(0, "'", true); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalAnnotationName() { - AnnotationVisitor av = new CheckAnnotationAdapter(new EmptyVisitor()); - try { - av.visit(null, new Integer(0)); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalAnnotationValue() { - AnnotationVisitor av = new CheckAnnotationAdapter(new EmptyVisitor()); - try { - av.visit("name", new Object()); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalAnnotationEnumValue() { - AnnotationVisitor av = new CheckAnnotationAdapter(new EmptyVisitor()); - try { - av.visitEnum("name", "Lpkg/Enum;", null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalAnnotationValueAfterEnd() { - AnnotationVisitor av = new CheckAnnotationAdapter(new EmptyVisitor()); - av.visitEnd(); - try { - av.visit("name", new Integer(0)); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMethodMemberVisitAfterEnd() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitEnd(); - try { - mv.visitAttribute(new Comment()); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMethodAttribute() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - try { - mv.visitAttribute(null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMethodSignature() { - ClassVisitor cv = new CheckClassAdapter(new EmptyVisitor()); - cv.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null); - try { - cv.visitMethod(ACC_PUBLIC, "m", "()V", ";>()V^LA;X", null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMethodInsnVisitBeforeStart() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - try { - mv.visitInsn(NOP); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFrameType() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitFrame(123, 0, null, 0, null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFrameLocalCount() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitFrame(F_SAME, 1, new Object[] { INTEGER }, 0, null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFrameStackCount() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitFrame(F_SAME, 0, null, 1, new Object[] { INTEGER }); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFrameLocalArray() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitFrame(F_APPEND, 1, new Object[0], 0, null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFrameStackArray() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitFrame(F_SAME1, 0, null, 1, new Object[0]); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFrameValue() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitFrame(F_FULL, 1, new Object[] { "LC;" }, 0, null); - fail(); - } catch (Exception e) { - } - try { - mv.visitFrame(F_FULL, 1, new Object[] { new Integer(0) }, 0, null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMethodInsn() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitInsn(-1); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalByteInsnOperand() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitIntInsn(BIPUSH, Integer.MAX_VALUE); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalShortInsnOperand() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitIntInsn(SIPUSH, Integer.MAX_VALUE); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalVarInsnOperand() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitVarInsn(ALOAD, -1); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalIntInsnOperand() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitIntInsn(NEWARRAY, 0); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalTypeInsnOperand() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitTypeInsn(NEW, "[I"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalLabelInsnOperand() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - Label l = new Label(); - mv.visitLabel(l); - try { - mv.visitLabel(l); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalTableSwitchParameters1() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitTableSwitchInsn(1, 0, new Label(), new Label[0]); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalTableSwitchParameters2() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitTableSwitchInsn(0, 1, null, new Label[0]); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalTableSwitchParameters3() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitTableSwitchInsn(0, 1, new Label(), null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalTableSwitchParameters4() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitTableSwitchInsn(0, 1, new Label(), new Label[0]); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalLookupSwitchParameters1() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitLookupSwitchInsn(new Label(), null, new Label[0]); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalLookupSwitchParameters2() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitLookupSwitchInsn(new Label(), new int[0], null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalLookupSwitchParameters3() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitLookupSwitchInsn(new Label(), new int[0], new Label[1]); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFieldInsnNullOwner() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitFieldInsn(GETFIELD, null, "i", "I"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFieldInsnOwner() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitFieldInsn(GETFIELD, "-", "i", "I"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFieldInsnNullName() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitFieldInsn(GETFIELD, "C", null, "I"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFieldInsnName() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitFieldInsn(GETFIELD, "C", "-", "I"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFieldInsnName2() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - - try { - mv.visitFieldInsn(GETFIELD, "C", "a-", "I"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFieldInsnNullDesc() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitFieldInsn(GETFIELD, "C", "i", null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFieldInsnVoidDesc() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitFieldInsn(GETFIELD, "C", "i", "V"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFieldInsnPrimitiveDesc() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitFieldInsn(GETFIELD, "C", "i", "II"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFieldInsnArrayDesc() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitFieldInsn(GETFIELD, "C", "i", "["); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFieldInsnReferenceDesc() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitFieldInsn(GETFIELD, "C", "i", "L"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalFieldInsnReferenceDesc2() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitFieldInsn(GETFIELD, "C", "i", "L-;"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMethodInsnNullName() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitMethodInsn(INVOKEVIRTUAL, "C", null, "()V"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMethodInsnName() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitMethodInsn(INVOKEVIRTUAL, "C", "-", "()V"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMethodInsnName2() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitMethodInsn(INVOKEVIRTUAL, "C", "a-", "()V"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMethodInsnNullDesc() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitMethodInsn(INVOKEVIRTUAL, "C", "m", null); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMethodInsnDesc() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitMethodInsn(INVOKEVIRTUAL, "C", "m", "I"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMethodInsnParameterDesc() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitMethodInsn(INVOKEVIRTUAL, "C", "m", "(V)V"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMethodInsnReturnDesc() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitMethodInsn(INVOKEVIRTUAL, "C", "m", "()VV"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalLdcInsnOperand() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitLdcInsn(new Object()); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMultiANewArrayDesc() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitMultiANewArrayInsn("I", 1); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMultiANewArrayDims() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitMultiANewArrayInsn("[[I", 0); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalMultiANewArrayDims2() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitMultiANewArrayInsn("[[I", 3); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalLocalVariableLabels() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - Label m = new Label(); - Label n = new Label(); - mv.visitLabel(n); - mv.visitInsn(NOP); - mv.visitLabel(m); - try { - mv.visitLocalVariable("i", "I", null, m, n, 0); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalLineNumerLabel() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - try { - mv.visitLineNumber(0, new Label()); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalInsnVisitAfterEnd() { - MethodVisitor mv = new CheckMethodAdapter(new EmptyVisitor()); - mv.visitCode(); - mv.visitMaxs(0, 0); - try { - mv.visitInsn(NOP); - fail(); - } catch (Exception e) { - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/util/CheckSignatureAdapterTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/util/CheckSignatureAdapterTest.java deleted file mode 100644 index 4635d041b..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/util/CheckSignatureAdapterTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.commons.EmptyVisitor; -import com.alibaba.citrus.asm.signature.SignatureReader; -import com.alibaba.citrus.asm.signature.SignatureWriter; - -/** - * CheckSignatureAdapter tests. - * - * @author Eric Bruneton - */ -public class CheckSignatureAdapterTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new CheckSignatureAdapterTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - cr.accept(new EmptyVisitor() { - @Override - public void visit(int version, int access, String name, String signature, String superName, - String[] interfaces) { - if (signature != null) { - SignatureReader sr = new SignatureReader(signature); - SignatureWriter sw = new SignatureWriter(); - sr.accept(new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, sw)); - assertEquals(signature, sw.toString()); - } - } - - @Override - public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { - if (signature != null) { - SignatureReader sr = new SignatureReader(signature); - SignatureWriter sw = new SignatureWriter(); - sr.acceptType(new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, sw)); - assertEquals(signature, sw.toString()); - } - return null; - } - - @Override - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - if (signature != null) { - SignatureReader sr = new SignatureReader(signature); - SignatureWriter sw = new SignatureWriter(); - sr.accept(new CheckSignatureAdapter(CheckSignatureAdapter.METHOD_SIGNATURE, sw)); - assertEquals(signature, sw.toString()); - } - return null; - } - - }, 0); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/util/CheckSignatureAdapterUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/util/CheckSignatureAdapterUnitTest.java deleted file mode 100644 index 5df114096..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/util/CheckSignatureAdapterUnitTest.java +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.signature.SignatureReader; -import com.alibaba.citrus.asm.signature.SignatureVisitor; -import com.alibaba.citrus.asm.signature.SignatureWriter; -import com.alibaba.citrus.asm.util.TraceSignatureVisitorUnitTest.TestData; - -/** - * CheckSignatureAdapter tests. - * - * @author Eric Bruneton - */ -public class CheckSignatureAdapterUnitTest extends TestCase { - - public static TestSuite suite() { - TestSuite suite = new TestSuite(CheckSignatureAdapterUnitTest.class.getName()); - for (String element : TraceSignatureVisitorUnitTest.DATA) { - suite.addTest(new CheckSignatureAdapterUnitTest(new TestData(element))); - } - suite.addTestSuite(CheckSignatureAdapterUnitTest.class); - return suite; - } - - private TestData data; - - private SignatureVisitor sv; - - public CheckSignatureAdapterUnitTest() { - } - - private CheckSignatureAdapterUnitTest(final TestData data) { - super("checkSignature"); - this.data = data; - } - - public void checkSignature() { - SignatureWriter wrt = new SignatureWriter(); - SignatureReader rdr = new SignatureReader(data.signature); - switch (data.type) { - case 'C': - rdr.accept(new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, wrt)); - break; - case 'M': - rdr.accept(new CheckSignatureAdapter(CheckSignatureAdapter.METHOD_SIGNATURE, wrt)); - break; - case 'F': - rdr.acceptType(new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, wrt)); - break; - default: - return; - } - assertEquals(data.signature, wrt.toString()); - } - - public void testIllegalFormalTypeParam() { - setup(CheckSignatureAdapter.TYPE_SIGNATURE); - try { - sv.visitFormalTypeParameter("T"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalClassBound() { - setup(CheckSignatureAdapter.CLASS_SIGNATURE); - try { - sv.visitClassBound(); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalInterfaceBound() { - setup(CheckSignatureAdapter.CLASS_SIGNATURE); - try { - sv.visitInterfaceBound(); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalSuperclass() { - setup(CheckSignatureAdapter.METHOD_SIGNATURE); - try { - sv.visitSuperclass(); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalInterface() { - setup(CheckSignatureAdapter.CLASS_SIGNATURE); - try { - sv.visitInterface(); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalParameterType() { - setup(CheckSignatureAdapter.CLASS_SIGNATURE); - try { - sv.visitParameterType(); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalReturnType() { - setup(CheckSignatureAdapter.METHOD_SIGNATURE); - try { - sv.visitReturnType(); - sv.visitReturnType(); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalExceptionType() { - setup(CheckSignatureAdapter.METHOD_SIGNATURE); - try { - sv.visitExceptionType(); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalBaseType() { - setup(CheckSignatureAdapter.TYPE_SIGNATURE); - try { - sv.visitBaseType('I'); - sv.visitBaseType('I'); - fail(); - } catch (Exception e) { - } - setup(CheckSignatureAdapter.TYPE_SIGNATURE); - try { - sv.visitBaseType('V'); - fail(); - } catch (Exception e) { - } - setup(CheckSignatureAdapter.TYPE_SIGNATURE); - try { - sv.visitBaseType('A'); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalTypeVariable() { - setup(CheckSignatureAdapter.TYPE_SIGNATURE); - try { - sv.visitTypeVariable("T"); - sv.visitTypeVariable("T"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalArrayType() { - setup(CheckSignatureAdapter.TYPE_SIGNATURE); - try { - sv.visitArrayType(); - sv.visitArrayType(); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalClassType() { - setup(CheckSignatureAdapter.TYPE_SIGNATURE); - try { - sv.visitClassType("A"); - sv.visitClassType("A"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalInnerClassType() { - setup(CheckSignatureAdapter.TYPE_SIGNATURE); - try { - sv.visitInnerClassType("A"); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalTypeArgument() { - setup(CheckSignatureAdapter.TYPE_SIGNATURE); - try { - sv.visitTypeArgument(); - fail(); - } catch (Exception e) { - } - setup(CheckSignatureAdapter.TYPE_SIGNATURE); - try { - sv.visitTypeArgument('+'); - fail(); - } catch (Exception e) { - } - setup(CheckSignatureAdapter.TYPE_SIGNATURE); - try { - sv.visitClassType("A"); - sv.visitTypeArgument('*'); - fail(); - } catch (Exception e) { - } - } - - public void testIllegalEnd() { - setup(CheckSignatureAdapter.TYPE_SIGNATURE); - try { - sv.visitEnd(); - fail(); - } catch (Exception e) { - } - } - - @Override - public String getName() { - if (data == null) { - return super.getName(); - } else { - return super.getName() + " " + data.signature; - } - } - - private void setup(int type) { - sv = new CheckSignatureAdapter(type, null); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/util/TraceClassAdapterTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/util/TraceClassAdapterTest.java deleted file mode 100644 index 19a158ee9..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/util/TraceClassAdapterTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import java.io.CharArrayWriter; -import java.io.PrintWriter; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.attrs.CodeComment; -import com.alibaba.citrus.asm.attrs.Comment; - -/** - * CheckClassAdapter tests. - * - * @author Eric Bruneton - */ -public class TraceClassAdapterTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new TraceClassAdapterTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - ClassWriter cw = new ClassWriter(0); - ClassVisitor cv = new TraceClassVisitor(cw, new PrintWriter(new CharArrayWriter())); - cr.accept(cv, new Attribute[] { new Comment(), new CodeComment() }, 0); - assertEquals(cr, new ClassReader(cw.toByteArray())); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/util/TraceClassAdapterUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/util/TraceClassAdapterUnitTest.java deleted file mode 100644 index 53aead976..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/util/TraceClassAdapterUnitTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import junit.framework.TestCase; - -import com.alibaba.citrus.asm.AsmTestParams; - -/** - * TraceClassAdapter unit tests - * - * @author Eric Bruneton - */ -public class TraceClassAdapterUnitTest extends TestCase { - - public void testTraceClassVisitor() throws Exception { - String s = getClass().getName(); - TraceClassVisitor.main(new String[0]); - TraceClassVisitor.main(new String[] { "-debug" }); - TraceClassVisitor.main(new String[] { s }); - TraceClassVisitor.main(new String[] { "-debug", s }); - TraceClassVisitor.main(new String[] { new AsmTestParams().getClassPath("Interface.class") }); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/util/TraceSignatureVisitorUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/util/TraceSignatureVisitorUnitTest.java deleted file mode 100644 index ff152a8cc..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/util/TraceSignatureVisitorUnitTest.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.util; - -import java.util.StringTokenizer; - -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.signature.SignatureReader; - -/** - * TraceSignatureVisitor unit tests. - * - * @author Eugene Kuleshov - */ -public class TraceSignatureVisitorUnitTest extends TestCase { - - public final static String[] DATA = { - "C|E|> implements java.lang.Comparable, java.io.Serializable" - + "|;>Ljava/lang/Object;Ljava/lang/Comparable;Ljava/io/Serializable;", - - "C|I| extends java.lang.reflect.Type" - + "|Ljava/lang/Object;Ljava/lang/reflect/Type;", - - "C|C| extends java.util.AbstractMap implements java.util.concurrent.ConcurrentMap, java.io.Serializable" - + "|Ljava/util/AbstractMap;Ljava/util/concurrent/ConcurrentMap;Ljava/io/Serializable;", - - "C|C|, V> extends java.util.AbstractMap implements java.io.Serializable, java.lang.Cloneable" - + "|;V:Ljava/lang/Object;>Ljava/util/AbstractMap;Ljava/io/Serializable;Ljava/lang/Cloneable;", - - "F|C|java.lang.Class|Ljava/lang/Class<*>;", - - "F|C|java.lang.reflect.Constructor|Ljava/lang/reflect/Constructor;", - - "F|C|T[]|[TT;", - - "F|C|java.util.Hashtable|Ljava/util/Hashtable<**>;", - - "F|C|java.util.concurrent.atomic.AtomicReferenceFieldUpdater" - + "|Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater;", - - "F|C|AA|LAA<[[B>;", - - "F|C|AA[][]>" - + "|LAA<[[Ljava/util/Map;>;", - - "F|C|java.util.Hashtable" - + "|Ljava/util/Hashtable;", - - "M|C|void(boolean, byte, char, short, int, float, long, double)" + "|(ZBCSIFJD)V", - - "M|C|void()E, F|()V^TE;^TF;", - - "M|C|java.lang.Class()" - + "|()Ljava/lang/Class<+TE;>;", - - "M|C|java.lang.Class()" - + "|()Ljava/lang/Class<-TE;>;", - - "M|C|void(A.B)|(LA.B;)V", - - "M|C|void(A.B)|(LA.B;)V", - - "M|C|void(java.lang.String, java.lang.Class, java.lang.reflect.Method[], java.lang.reflect.Method, java.lang.reflect.Method)" - + "|(Ljava/lang/String;Ljava/lang/Class<*>;[Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;)V", - - "M|C|java.util.Map(java.lang.Object, java.util.Map)" - + "|(Ljava/lang/Object;Ljava/util/Map;)Ljava/util/Map;", - - "M|C|java.util.Map(java.lang.Object, java.util.Map, T)" - + "|(Ljava/lang/Object;Ljava/util/Map;TT;)Ljava/util/Map;", - - "M|C|java.util.Map>(java.lang.Object, java.util.Map, T)" - + "|;>(Ljava/lang/Object;Ljava/util/Map;TT;)Ljava/util/Map;", }; - - public static TestSuite suite() { - TestSuite suite = new TestSuite(TraceSignatureVisitorUnitTest.class.getName()); - for (String element : DATA) { - suite.addTest(new TraceSignatureVisitorUnitTest(new TestData(element))); - } - return suite; - } - - private TestData data; - - private TraceSignatureVisitorUnitTest(final TestData data) { - super("testSignature"); - this.data = data; - } - - public void testSignature() { - TraceSignatureVisitor d = new TraceSignatureVisitor(data.access); - SignatureReader r = new SignatureReader(data.signature); - - switch (data.type) { - case 'C': - r.accept(d); - assertEquals(data.declaration, d.getDeclaration()); - break; - case 'F': - r.acceptType(d); - assertEquals(data.declaration, d.getDeclaration()); - break; - case 'M': - r.accept(d); - String fullMethodDeclaration = d.getReturnType() + d.getDeclaration() - + (d.getExceptions() != null ? d.getExceptions() : ""); - assertEquals(data.declaration, fullMethodDeclaration); - break; - } - } - - @Override - public String getName() { - return super.getName() + " " + data.signature; - } - - public static class TestData { - - public final char type; - - public final int access; - - public final String declaration; - - public final String signature; - - public TestData(final String data) { - StringTokenizer st = new StringTokenizer(data, "|"); - this.type = st.nextToken().charAt(0); - - String acc = st.nextToken(); - switch (acc.charAt(0)) { - case 'E': - this.access = Opcodes.ACC_ENUM; - break; - case 'I': - this.access = Opcodes.ACC_INTERFACE; - break; - case 'A': - this.access = Opcodes.ACC_ANNOTATION; - break; - default: - this.access = 0; - } - - this.declaration = st.nextToken(); - this.signature = st.nextToken(); - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/xml/ASMContentHandlerUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/xml/ASMContentHandlerUnitTest.java deleted file mode 100644 index 9286cb122..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/xml/ASMContentHandlerUnitTest.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.xml; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import junit.framework.TestCase; - -import org.xml.sax.SAXException; -import org.xml.sax.helpers.AttributesImpl; - -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Opcodes; - -/** - * ASMContentHandler unit tests - * - * @author Eric Bruneton - */ -public class ASMContentHandlerUnitTest extends TestCase implements Opcodes { - - ASMContentHandler h; - - ClassVisitor cv; - - MethodVisitor mv; - - @Override - protected void setUp() throws Exception { - h = new ASMContentHandler(new ByteArrayOutputStream() { - @Override - public void write(final byte[] b) throws IOException { - throw new IOException(); - } - }, false); - cv = new SAXClassAdapter(h, true); - cv.visit(V1_5, ACC_PUBLIC, "C", null, "java/lang/Object", null); - } - - protected void methodSetUp() { - mv = cv.visitMethod(0, "", "()V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); - } - - public void testInvalidOpcode() { - methodSetUp(); - AttributesImpl attrs = new AttributesImpl(); - try { - h.startElement("", "opcode", "", attrs); - h.endElement("", "opcode", ""); - fail(); - } catch (SAXException e) { - } - } - - public void testInvalidValueDescriptor() { - methodSetUp(); - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "desc", "desc", "", "desc"); - attrs.addAttribute("", "cst", "cst", "", ""); - try { - h.startElement("", "LDC", "", attrs); - h.endElement("", "LDC", ""); - fail(); - } catch (SAXException e) { - } - } - - public void testInvalidValue() { - methodSetUp(); - AttributesImpl attrs = new AttributesImpl(); - attrs.addAttribute("", "desc", "desc", "", "Ljava/lang/String;"); - attrs.addAttribute("", "cst", "cst", "", "\\"); - try { - h.startElement("", "LDC", "", attrs); - h.endElement("", "LDC", ""); - fail(); - } catch (SAXException e) { - } - } - - public void testIOException() { - cv.visitEnd(); - try { - h.endDocument(); - } catch (SAXException e) { - } - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/xml/SAXAdapterTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/xml/SAXAdapterTest.java deleted file mode 100644 index cfa906fa6..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/xml/SAXAdapterTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM XML Adapter - * Copyright (c) 2004, Eugene Kuleshov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.xml; - -import java.io.ByteArrayOutputStream; - -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TransformerHandler; - -import junit.framework.TestSuite; - -import com.alibaba.citrus.asm.AbstractTest; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.Label; - -/** - * SAXAdapter tests - * - * @author Eugene Kuleshov - */ -public class SAXAdapterTest extends AbstractTest { - - public static TestSuite suite() throws Exception { - return new SAXAdapterTest().getSuite(); - } - - @Override - public void test() throws Exception { - ClassReader cr = new ClassReader(openStream()); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - - SAXTransformerFactory saxtf = (SAXTransformerFactory) TransformerFactory.newInstance(); - TransformerHandler handler = saxtf.newTransformerHandler(); - handler.setResult(new SAXResult(new ASMContentHandler(bos, false))); - handler.startDocument(); - cr.accept(new SAXClassAdapter(handler, false), 0); - handler.endDocument(); - - ClassWriter cw = new ClassWriter(0); - cr.accept(cw, new Attribute[] { new Attribute("Comment") { - @Override - protected Attribute read(final ClassReader cr, final int off, final int len, final char[] buf, - final int codeOff, final Label[] labels) { - return null; // skip these attributes - } - }, new Attribute("CodeComment") { - @Override - protected Attribute read(final ClassReader cr, final int off, final int len, final char[] buf, - final int codeOff, final Label[] labels) { - return null; // skip these attributes - } - } }, 0); - - assertEquals(new ClassReader(cw.toByteArray()), new ClassReader(bos.toByteArray())); - } -} diff --git a/common/asm/src/test/java/com/alibaba/citrus/asm/xml/SAXAdapterUnitTest.java b/common/asm/src/test/java/com/alibaba/citrus/asm/xml/SAXAdapterUnitTest.java deleted file mode 100644 index 7b5100102..000000000 --- a/common/asm/src/test/java/com/alibaba/citrus/asm/xml/SAXAdapterUnitTest.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*** - * ASM tests - * Copyright (c) 2002-2005 France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.alibaba.citrus.asm.xml; - -import junit.framework.TestCase; - -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -/** - * SAXAdapter unit tests - * - * @author Eric Bruneton - */ -public class SAXAdapterUnitTest extends TestCase { - - SAXAdapter sa; - - @Override - protected void setUp() { - sa = new SAXAdapter(new DefaultHandler() { - - @Override - public void startDocument() throws SAXException { - throw new SAXException(); - } - - @Override - public void endDocument() throws SAXException { - throw new SAXException(); - } - - @Override - public void startElement(final String arg0, final String arg1, final String arg2, final Attributes arg3) - throws SAXException { - throw new SAXException(); - } - - @Override - public void endElement(final String arg0, final String arg1, final String arg2) throws SAXException { - throw new SAXException(); - } - }) { - }; - } - - public void testInvalidAddDocumentStart() { - try { - sa.addDocumentStart(); - fail(); - } catch (Exception e) { - } - } - - public void testInvalidAddDocumentEnd() { - try { - sa.addDocumentEnd(); - fail(); - } catch (Exception e) { - } - } - - public void testInvalidAddStart() { - try { - sa.addStart("name", null); - fail(); - } catch (Exception e) { - } - } - - public void testInvalidAddEnd() { - try { - sa.addEnd("name"); - fail(); - } catch (Exception e) { - } - } -} diff --git a/common/codegen/.cvsignore b/common/codegen/.cvsignore deleted file mode 100644 index c2912e595..000000000 --- a/common/codegen/.cvsignore +++ /dev/null @@ -1,13 +0,0 @@ -.project -.classpath -target -classes -tmp -temp -*.log -*.jpx -*.jpx.local -*.library -*.cache -.properties* -*~ diff --git a/common/codegen/pom.xml b/common/codegen/pom.xml deleted file mode 100644 index 8e6012156..000000000 --- a/common/codegen/pom.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - citrus-parent - com.alibaba.citrus - 3.0.8 - ../../pom.xml - - 4.0.0 - citrus-common-codegen - Bytecode Generation Tools - - - ${project.groupId} - citrus-common-util - - - ${project.groupId} - citrus-common-asm - - - ${project.groupId} - citrus-test-util - - - diff --git a/common/codegen/src/main/java/com/alibaba/citrus/codegen/ClassBuilder.java b/common/codegen/src/main/java/com/alibaba/citrus/codegen/ClassBuilder.java deleted file mode 100644 index 9debf56f9..000000000 --- a/common/codegen/src/main/java/com/alibaba/citrus/codegen/ClassBuilder.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.alibaba.citrus.codegen; - -import static com.alibaba.citrus.asm.Opcodes.*; -import static com.alibaba.citrus.codegen.util.CodegenConstant.*; -import static com.alibaba.citrus.codegen.util.TypeUtil.*; -import static com.alibaba.citrus.util.Assert.*; - -import java.lang.reflect.Method; - -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.Type; - -/** - * 用来生成一个类或接口的工具。 - * - * @author Michael Zhou - */ -public abstract class ClassBuilder { - private final ClassWriter cw; - private final ClassVisitor cv; // decorated cw - private final boolean isInterface; - private final String className; - private final Type classType; - private final Type superType; - private final Type[] interfaceTypes; - private Member lastMember; - - /** - * 创建一个ClassBuilder。 - * - * @param cw ClassWriter对象。 - * @param access 访问性,如果是-1,则取默认值public。 - * @param isInterface 是否为接口。 - * @param className 要生成的类名 - * @param superclass 父类 - * @param interfaces 接口 - * @param classVersion 二进制版本,如果是-1,则取默认值。 - * @param source 源文件名,如果是null,则取默认值。 - */ - public ClassBuilder(ClassWriter cw, int access, boolean isInterface, String className, Class superclass, - Class[] interfaces, int classVersion, String source) { - // class writer/visitor - this.cw = cw; - this.cv = decorate(cw); - - // access - if (access < 0) { - access = ACC_PUBLIC; // 默认值 - } - - access |= ACC_SUPER; // for backward-compatibility - - if (isInterface) { - access |= ACC_ABSTRACT | ACC_INTERFACE; - } - - // isInterface - this.isInterface = isInterface; - - // className - this.className = assertNotNull(className, "className"); - this.classType = getTypeFromClassName(className); - - // superclass - if (superclass == null) { - this.superType = OBJECT_TYPE; - } else { - this.superType = getTypeFromClass(superclass); - } - - // interfaces - this.interfaceTypes = getTypes(interfaces); - - // classVersion - if (classVersion < 0) { - classVersion = DEFAULT_CLASS_VERSION; - } - - // source - if (source == null) { - source = DEFAULT_SOURCE; - } - - cv.visit(classVersion, access, classType.getInternalName(), null, superType.getInternalName(), - getInternalNames(interfaceTypes)); - - if (source != null) { - cv.visitSource(source, null); - } - } - - /** - * 取得ClassVisitor。 - */ - public ClassVisitor getClassVisitor() { - return cv; - } - - /** - * 取得当前的类名。 - */ - public String getClassName() { - return className; - } - - /** - * 判断是否为接口。 - */ - public boolean isInterface() { - return isInterface; - } - - /** - * 取得当前的类型信息。 - */ - public Type getType() { - return classType; - } - - /** - * 取得父类的类型信息。 - */ - public Type getSuperType() { - return superType; - } - - /** - * 创建一个public常量field。 - */ - public FieldBuilder addConstantField(Class fieldType, String fieldName, Object value) { - return addField(ACC_PUBLIC | ACC_CONSTANT, fieldType, fieldName, value); - } - - /** - * 创建一个常量field。 - */ - public FieldBuilder addConstantField(int access, Class fieldType, String fieldName, Object value) { - return addField(access | ACC_CONSTANT, fieldType, fieldName, value); - } - - /** - * 创建一个private field。 - */ - public FieldBuilder addField(Class fieldType, String fieldName, Object value) { - return addField(-1, fieldType, fieldName, value); - } - - /** - * 创建一个field。 - */ - public FieldBuilder addField(int access, Class fieldType, String fieldName, Object value) { - FieldBuilder fb = setMember(new FieldMember(this, access, fieldType, fieldName, value)); - - return fb; - } - - /** - * 创建public构造函数。 - */ - public MethodBuilder addConstructor(Class[] parameterTypes, Class[] exceptionTypes) { - return addMethod(-1, null, CONSTRUCTOR_NAME, parameterTypes, exceptionTypes); - } - - /** - * 创建构造函数。 - */ - public MethodBuilder addConstructor(int access, Class[] parameterTypes, Class[] exceptionTypes) { - return addMethod(access, null, CONSTRUCTOR_NAME, parameterTypes, exceptionTypes); - } - - /** - * 创建静态构造函数。 - */ - public MethodBuilder addStaticConstructor() { - return addMethod(-1, null, STATIC_CONSTRUCTOR_NAME, null, null); - } - - /** - * 创建public方法。 - */ - public MethodBuilder addMethod(Method method) { - return addMethod(-1, method.getReturnType(), method.getName(), method.getParameterTypes(), - method.getExceptionTypes()); - } - - /** - * 创建public方法。 - */ - public MethodBuilder addMethod(Class returnType, String methodName, Class[] parameterTypes, - Class[] exceptionTypes) { - return addMethod(-1, returnType, methodName, parameterTypes, exceptionTypes); - } - - /** - * 创建方法。 - */ - public MethodBuilder addMethod(int access, Class returnType, String methodName, Class[] parameterTypes, - Class[] exceptionTypes) { - MethodBuilder mb = setMember(new MethodMember(this, access, returnType, methodName, parameterTypes, - exceptionTypes)); - - return mb; - } - - /** - * 生成class。 - */ - public final Class toClass() { - setMember(null); - cv.visitEnd(); - byte[] bytes = cw.toByteArray(); - - return defineClass(getClassName(), bytes); - } - - /** - * 给子类一个机会包装class writer。 - */ - protected ClassVisitor decorate(ClassVisitor cv) { - return cv; - } - - /** - * 定义并装载类。 - */ - protected abstract Class defineClass(String className, byte[] bytes); - - /** - * 包括end方法的class成员。 - */ - private interface Member { - void end(); - } - - /** - * 结束前一个成员,开始新的成员。 - */ - private M setMember(M member) { - if (lastMember != null) { - lastMember.end(); - } - - lastMember = member; - - return member; - } - - /** - * 可自动结束的FieldBuilder。 - */ - private class FieldMember extends FieldBuilder implements Member { - protected FieldMember(ClassBuilder cb, int access, Class fieldType, String fieldName, Object value) { - super(cb, access, fieldType, fieldName, value); - } - - public void end() { - endField(); - } - } - - /** - * 可自动结束的MethodBuilder。 - */ - private class MethodMember extends MethodBuilder implements Member { - protected MethodMember(ClassBuilder cb, int access, Class returnType, String methodName, - Class[] parameterTypes, Class[] exceptionTypes) { - super(cb, access, returnType, methodName, parameterTypes, exceptionTypes); - } - - public void end() { - endMethod(); - } - } -} diff --git a/common/codegen/src/main/java/com/alibaba/citrus/codegen/ClassPool.java b/common/codegen/src/main/java/com/alibaba/citrus/codegen/ClassPool.java deleted file mode 100644 index d6a222547..000000000 --- a/common/codegen/src/main/java/com/alibaba/citrus/codegen/ClassPool.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.alibaba.citrus.codegen; - -import static com.alibaba.citrus.codegen.util.CodegenConstant.*; -import static com.alibaba.citrus.codegen.util.CodegenUtil.*; -import static com.alibaba.citrus.codegen.util.TypeUtil.*; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; - -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.util.TraceClassVisitor; - -/** - * 动态生成和保存类或接口。 - * - * @author Michael Zhou - */ -public class ClassPool { - private final BytecodeLoader classLoader; - private boolean debugging; - private File debuggingLocation; - private int classWriterFlags; - private String packageName; - - /** - * 创建一个ClassPool,使用装载ClassPool类的 - * ClassLoader。 - */ - public ClassPool() { - this(null); - } - - /** - * 创建一个ClassPool,使用指定的ClassLoader。 - */ - public ClassPool(ClassLoader parentClassLoader) { - if (parentClassLoader == null) { - parentClassLoader = getClass().getClassLoader(); - } - - this.classLoader = new BytecodeLoader(parentClassLoader); - this.classWriterFlags = DEFAULT_CLASS_WRITER_FLAGS; - this.packageName = DEFAULT_PACKAGE_NAME; - } - - /** - * 取得ClassLoader。 - */ - public ClassLoader getClassLoader() { - return classLoader; - } - - /** - * 是否保存class源文件和目标文件? - */ - public boolean isDebugging() { - return debugging; - } - - /** - * 设置参数:是否保存class源文件和目标文件? - */ - public void setDebugging(boolean debugging) { - this.debugging = debugging; - } - - /** - * Class的源代码和二进制文件将被输出到该目录。 - */ - public File getDebuggingLocation() { - return debuggingLocation; - } - - /** - * 设置class的源代码和二进制文件的输出目录。 - */ - public void setDebuggingLocation(File debuggingLocation) { - this.debuggingLocation = debuggingLocation; - } - - /** - * 取得ClassWriter的标志位。 - */ - public int getClassWriterFlags() { - return classWriterFlags; - } - - /** - * 设置ClassWriter的标志位。 - */ - public void setClassWriterFlags(int classWriterFlags) { - this.classWriterFlags = classWriterFlags; - } - - /** - * 取得生成代码的package名称。 - */ - public String getPackageName() { - return packageName; - } - - /** - * 设置生成代码的package名称。 - */ - public void setPackageName(String packageName) { - this.packageName = packageName; - } - - /** - * 基于指定的basename生成一个唯一类名,返回用来创建该类型的ClassBuilder。 - */ - public ClassBuilder createClass(String basename, Class superclass, Class[] interfaces) { - return createClassOrInterface(-1, false, basename, superclass, interfaces, -1, null); - } - - /** - * 基于指定的basename生成一个唯一类名,返回用来创建该类型的ClassBuilder。 - */ - public ClassBuilder createClass(int access, String basename, Class superclass, Class[] interfaces) { - return createClassOrInterface(access, false, basename, superclass, interfaces, -1, null); - } - - /** - * 基于指定的basename生成一个唯一类名,返回用来创建该类型的ClassBuilder。 - */ - public ClassBuilder createClass(int access, String basename, Class superclass, Class[] interfaces, - int classVersion, String source) { - return createClassOrInterface(access, false, basename, superclass, interfaces, classVersion, source); - } - - /** - * 基于指定的basename生成一个唯一接口名,返回用来创建该类型的ClassBuilder。 - */ - public ClassBuilder createInterface(String basename, Class[] interfaces) { - return createClassOrInterface(-1, true, basename, null, interfaces, -1, null); - } - - /** - * 基于指定的basename生成一个唯一接口名,返回用来创建该类型的ClassBuilder。 - */ - public ClassBuilder createInterface(int access, String basename, Class[] interfaces) { - return createClassOrInterface(access, true, basename, null, interfaces, -1, null); - } - - /** - * 基于指定的basename生成一个唯一接口名,返回用来创建该类型的ClassBuilder。 - */ - public ClassBuilder createInterface(int access, String basename, Class[] interfaces, int classVersion, - String source) { - return createClassOrInterface(access, true, basename, null, interfaces, classVersion, source); - } - - /** - * 基于指定的basename生成一个唯一类名,返回用来创建该类型的ClassBuilder。 - */ - private ClassBuilder createClassOrInterface(int access, boolean isInterface, String basename, Class superclass, - Class[] interfaces, int classVersion, String source) { - String className = generateClassName(basename, getPackageName()); - ClassWriter cw = new DebuggingClassWriter(); - - return new PooledClassBuilder(cw, access, isInterface, className, superclass, interfaces, classVersion, source); - } - - /** - * 用来装载bytecode的ClassLoader。 - */ - private static class BytecodeLoader extends ClassLoader { - public BytecodeLoader(ClassLoader parentClassLoader) { - super(parentClassLoader); - } - - public Class defineClass(String className, byte[] bytes) { - return defineClass(className, bytes, 0, bytes.length, getClass().getProtectionDomain()); - } - } - - /** - * 动态生成类或接口。 - */ - private class PooledClassBuilder extends ClassBuilder { - public PooledClassBuilder(ClassWriter cw, int access, boolean isInterface, String className, - Class superclass, Class[] interfaces, int classVersion, String source) { - super(cw, access, isInterface, className, superclass, interfaces, classVersion, source); - } - - @Override - public Class defineClass(String className, byte[] bytes) { - return classLoader.defineClass(className, bytes); - } - } - - /** - * 支持debugging的类创建器。 - */ - private class DebuggingClassWriter extends ClassWriter { - private String className; - - public DebuggingClassWriter() { - super(classWriterFlags); - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - if (debugging) { - this.className = getTypeFromInternalName(name).getClassName(); - } - - super.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public byte[] toByteArray() { - byte[] bytes = super.toByteArray(); - - if (className != null) { - if (debuggingLocation == null) { - debuggingLocation = new File(System.getProperty("java.io.tmpdir")); - } - - File baseFile = new File(debuggingLocation, className.replace('.', File.separatorChar)); - File classDir = baseFile.getParentFile(); - - classDir.mkdirs(); - - if (classDir.exists() && classDir.isDirectory()) { - try { - // 输出class文件 - File classFile = new File(classDir, baseFile.getName() + ".class"); - OutputStream out = new BufferedOutputStream(new FileOutputStream(classFile)); - - try { - out.write(bytes); - } finally { - out.close(); - } - - // 输出asm文件 - File asmFile = new File(classDir, baseFile.getName() + ".asm"); - out = new BufferedOutputStream(new FileOutputStream(asmFile)); - - try { - ClassReader cr = new ClassReader(bytes); - PrintWriter pw = new PrintWriter(new OutputStreamWriter(out, "UTF-8")); - TraceClassVisitor tcv = new TraceClassVisitor(null, pw); - - cr.accept(tcv, 0); - pw.flush(); - } finally { - out.close(); - } - } catch (IOException e) { - } - } - } - - return bytes; - } - } -} diff --git a/common/codegen/src/main/java/com/alibaba/citrus/codegen/CodeBuilder.java b/common/codegen/src/main/java/com/alibaba/citrus/codegen/CodeBuilder.java deleted file mode 100644 index edbebfc83..000000000 --- a/common/codegen/src/main/java/com/alibaba/citrus/codegen/CodeBuilder.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.alibaba.citrus.codegen; - -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.commons.GeneratorAdapter; - -/** - * 用来生成method body代码的工具。 - * - * @author Michael Zhou - */ -public class CodeBuilder extends GeneratorAdapter { - private final MethodBuilder mb; - - /** - * 创建CodeBuilder。 - */ - public CodeBuilder(MethodBuilder mb, MethodVisitor mv, int access, String name, String desc) { - super(mv, access, name, desc); - this.mb = mb; - mv.visitCode(); - } - - /** - * 取得当前代码所在MethodBuilder。 - */ - public MethodBuilder getMethodBuilder() { - return mb; - } - - /** - * 取得用来生成代码的MethodVisitor。 - */ - public MethodVisitor getMethodVisitor() { - return mv; - } -} diff --git a/common/codegen/src/main/java/com/alibaba/citrus/codegen/FieldBuilder.java b/common/codegen/src/main/java/com/alibaba/citrus/codegen/FieldBuilder.java deleted file mode 100644 index 7c811dff0..000000000 --- a/common/codegen/src/main/java/com/alibaba/citrus/codegen/FieldBuilder.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.alibaba.citrus.codegen; - -import static com.alibaba.citrus.asm.Opcodes.*; -import static com.alibaba.citrus.codegen.util.CodegenConstant.*; -import static com.alibaba.citrus.codegen.util.TypeUtil.*; -import static com.alibaba.citrus.util.Assert.*; - -import com.alibaba.citrus.asm.AnnotationVisitor; -import com.alibaba.citrus.asm.Attribute; -import com.alibaba.citrus.asm.FieldVisitor; -import com.alibaba.citrus.asm.Type; - -/** - * 用来生成一个field的工具。 - * - * @author Michael Zhou - */ -public abstract class FieldBuilder { - private final ClassBuilder cb; - private final FieldVisitor fv; - private final boolean isConstant; - private final Type fieldType; - private final String fieldName; - - /** - * 创建一个FieldBuilder。 - * - * @param cb field所在的ClassBuilder对象 - * @param access 访问性,如果是-1,则取默认值。 - * @param fieldType field类型 - * @param fieldName field名称 - * @param value 字段值 - */ - protected FieldBuilder(ClassBuilder cb, int access, Class fieldType, String fieldName, Object value) { - // class builder - this.cb = cb; - - // access - if (access < 0) { // 默认值 - if (cb.isInterface()) { - access = ACC_PUBLIC | ACC_CONSTANT; // 对interface而言,必须为: public final static - } else { - access = ACC_PRIVATE; // 对于class而言,默认为: private - } - } - - // isConstant - this.isConstant = testBits(access, ACC_CONSTANT); - - // fieldType - this.fieldType = getTypeFromClass(assertNotNull(fieldType, "fieldClass")); - - // fieldName - this.fieldName = assertNotNull(fieldName, "fieldName"); - - // visit field - this.fv = decorate(cb.getClassVisitor().visitField(access, fieldName, this.fieldType.getDescriptor(), null, - value)); - } - - /** - * 取得field所在的ClassBuilder。 - */ - public ClassBuilder getClassBuilder() { - return cb; - } - - /** - * 取得FieldVisitor。 - */ - public FieldVisitor getFieldVisitor() { - return fv; - } - - /** - * 是否为常量。 - */ - public boolean isConstant() { - return isConstant; - } - - /** - * 取得field类型。 - */ - public Type getFieldType() { - return fieldType; - } - - /** - * 取得field名称。 - */ - public String getFieldName() { - return fieldName; - } - - /** - * 实现接口FieldVisitor。 - */ - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - return fv.visitAnnotation(desc, visible); - } - - /** - * 实现接口FieldVisitor。 - */ - public void visitAttribute(Attribute attr) { - fv.visitAttribute(attr); - } - - /** - * 结束field。 - */ - protected void endField() { - fv.visitEnd(); - } - - /** - * 给子类一个机会包装field visitor。 - */ - protected FieldVisitor decorate(FieldVisitor fv) { - return fv; - } -} diff --git a/common/codegen/src/main/java/com/alibaba/citrus/codegen/MethodBuilder.java b/common/codegen/src/main/java/com/alibaba/citrus/codegen/MethodBuilder.java deleted file mode 100644 index 06cf590e8..000000000 --- a/common/codegen/src/main/java/com/alibaba/citrus/codegen/MethodBuilder.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.alibaba.citrus.codegen; - -import static com.alibaba.citrus.asm.Opcodes.*; -import static com.alibaba.citrus.codegen.util.CodegenConstant.*; -import static com.alibaba.citrus.codegen.util.TypeUtil.*; -import static com.alibaba.citrus.util.Assert.*; - -import com.alibaba.citrus.asm.MethodVisitor; -import com.alibaba.citrus.asm.Type; - -/** - * 用来生成一个method的工具。 - * - * @author Michael Zhou - */ -public abstract class MethodBuilder { - private final ClassBuilder cb; - private final MethodVisitor mv; - private final int access; - private final String methodName; - private final Type returnType; - private final Type[] parameterTypes; - private final Type[] exceptionTypes; - private final String methodDesc; - private CodeBuilder codeBuilder; - - /** - * 创建MethodBuilder。 - * - * @param cb method所在的ClassBuilder对象 - * @param access 访问性,如果是-1,则取默认值。 - * @param returnType 返回类型,为null代表无返回值。 - * @param methodName method名称 - * @param parameterTypes 参数类型 - * @param exceptionTypes 异常类型 - */ - protected MethodBuilder(ClassBuilder cb, int access, Class returnType, String methodName, - Class[] parameterTypes, Class[] exceptionTypes) { - // class builder - this.cb = cb; - - // methodName - this.methodName = assertNotNull(methodName, "methodName"); - - // access - if (access < 0) { - if (isStaticConstructor()) { - access = ACC_STATIC; - } else { - access = ACC_PUBLIC; - } - } - - this.access = access; - - // method desc - this.returnType = getTypeFromClass(returnType == null ? void.class : returnType); - this.parameterTypes = getTypes(parameterTypes); - this.methodDesc = Type.getMethodDescriptor(this.returnType, this.parameterTypes); - - // exceptions - this.exceptionTypes = getTypes(exceptionTypes); - - // visit method - this.mv = decorate(cb.getClassVisitor().visitMethod(access, this.methodName, this.methodDesc, null, - getInternalNames(this.exceptionTypes))); - } - - /** - * 取得method所在的ClassBuilder。 - */ - public ClassBuilder getClassBuilder() { - return cb; - } - - /** - * 取得MethodVisitor。 - */ - public MethodVisitor getMethodVisitor() { - return mv; - } - - /** - * 取得返回类型。 - */ - public Type getReturnType() { - return returnType; - } - - /** - * 取得方法名。 - */ - public String getMethodName() { - return methodName; - } - - /** - * 是否为构造函数。 - */ - public boolean isConstructor() { - return CONSTRUCTOR_NAME.equals(methodName); - } - - /** - * 是否为静态构造函数。 - */ - public boolean isStaticConstructor() { - return STATIC_CONSTRUCTOR_NAME.equals(methodName); - } - - /** - * 取得参数类型。 - */ - public Type[] getParameterTypes() { - return parameterTypes; - } - - /** - * 取得异常类型。 - */ - public Type[] getExceptionTypes() { - return exceptionTypes; - } - - /** - * 开始代码。 - */ - public CodeBuilder startCode() { - if (codeBuilder == null) { - codeBuilder = new CodeBuilder(this, mv, access, methodName, methodDesc); - } - - return codeBuilder; - } - - /** - * 结束方法。 - */ - protected void endMethod() { - if (codeBuilder == null) { - mv.visitEnd(); // 对于interface和抽象方法 - } else { - codeBuilder.visitMaxs(1, 1); // auto calculate stacks and locals - codeBuilder.visitEnd(); - } - } - - /** - * 给子类一个机会包装method visitor。 - */ - protected MethodVisitor decorate(MethodVisitor mv) { - return mv; - } -} diff --git a/common/codegen/src/main/java/com/alibaba/citrus/codegen/util/CodegenUtil.java b/common/codegen/src/main/java/com/alibaba/citrus/codegen/util/CodegenUtil.java deleted file mode 100644 index ae6b44d6f..000000000 --- a/common/codegen/src/main/java/com/alibaba/citrus/codegen/util/CodegenUtil.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.alibaba.citrus.codegen.util; - -import static com.alibaba.citrus.codegen.util.CodegenConstant.*; - -import java.util.concurrent.atomic.AtomicLong; - -import com.alibaba.citrus.codegen.ClassBuilder; -import com.alibaba.citrus.codegen.CodeBuilder; -import com.alibaba.citrus.codegen.MethodBuilder; -import com.alibaba.citrus.util.StringUtil; - -/** - * 和生成类相关的工具。 - * - * @author Michael Zhou - */ -public class CodegenUtil { - private static final AtomicLong uid = new AtomicLong(System.currentTimeMillis()); - - /** - * 生成一个唯一字符串类名。 - *

- * 所生成的类名和指定baseClass的package相同。 - *

- */ - public static String generateClassName(Class baseClass) { - String baseName = baseClass != null ? baseClass.getName() : null; - - return generateClassName(baseName, null); - } - - /** - * 生成一个唯一字符串类名。 - *

- * 所生成的类名的package被替换成指定的packageReplacement。 - *

- */ - public static String generateClassName(Class baseClass, String packageReplacement) { - String baseName = baseClass != null ? baseClass.getName() : null; - - return generateClassName(baseName, packageReplacement); - } - - /** - * 生成一个唯一字符串类名。 - *

- * 所生成的类名和指定baseName的package相同。 - *

- */ - public static String generateClassName(String baseName) { - return generateClassName(baseName, null); - } - - /** - * 生成一个唯一字符串类名。 - */ - public static String generateClassName(String baseName, String packageReplacement) { - baseName = StringUtil.trimToEmpty(baseName); - packageReplacement = StringUtil.trim(packageReplacement); - - // 取得baseName的package - int index = baseName.lastIndexOf('.'); - - if (packageReplacement == null && index > 0) { - packageReplacement = baseName.substring(0, index); - } - - // 取得不包含package的baseName - if (index > 0) { - baseName = baseName.substring(index + 1); - } - - // 计算className - String className = "$" + baseName + "_" + uid(); - - if (!StringUtil.isEmpty(packageReplacement)) { - className = packageReplacement + "." + className; - } - - return className; - } - - /** - * 取得UID。 - */ - private static String uid() { - return StringUtil.longToString(uid.incrementAndGet()); - } - - /** - * 创建默认构造函数。 - */ - public static void addDefaultConstructor(ClassBuilder cb) { - MethodBuilder mb = cb.addConstructor(null, null); - CodeBuilder code = mb.startCode(); - - code.loadThis(); - code.invokeConstructor(cb.getSuperType(), new com.alibaba.citrus.asm.commons.Method(CONSTRUCTOR_NAME, "()V")); - code.returnValue(); - } - - /** - * 创建一个返回常量的toString()方法。 - */ - public static void addToString(ClassBuilder cb, String constantToString) { - MethodBuilder mb = cb.addMethod(String.class, "toString", null, null); - CodeBuilder code = mb.startCode(); - - code.push(constantToString); - code.returnValue(); - } -} diff --git a/common/codegen/src/test/java/com/alibaba/citrus/codegen/ClassGenerationTests.java b/common/codegen/src/test/java/com/alibaba/citrus/codegen/ClassGenerationTests.java deleted file mode 100644 index ef0f093eb..000000000 --- a/common/codegen/src/test/java/com/alibaba/citrus/codegen/ClassGenerationTests.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.alibaba.citrus.codegen; - -import static com.alibaba.citrus.asm.ClassReader.*; -import static com.alibaba.citrus.asm.Opcodes.*; -import static org.junit.Assert.*; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.lang.reflect.Method; - -import org.junit.Before; -import org.junit.Test; - -import com.alibaba.citrus.asm.ClassReader; -import com.alibaba.citrus.asm.ClassVisitor; -import com.alibaba.citrus.asm.Type; -import com.alibaba.citrus.asm.commons.Remapper; -import com.alibaba.citrus.asm.commons.RemappingClassAdapter; -import com.alibaba.citrus.asm.util.ASMifierClassVisitor; -import com.alibaba.citrus.codegen.util.CodegenUtil; -import com.alibaba.citrus.test.TestEnvStatic; - -public class ClassGenerationTests { - private ClassPool pool; - private File debuggingLocation; - - @Before - public void init() { - pool = new ClassPool(); - pool.setDebugging(true); - - debuggingLocation = new File(TestEnvStatic.destdir, "codegen"); - pool.setDebuggingLocation(debuggingLocation); - } - - @Test - public void generate() throws Exception { - ClassBuilder cb = pool.createClass("Test", null, null); - CodegenUtil.addDefaultConstructor(cb); - CodegenUtil.addToString(cb, "hello, world"); - - MethodBuilder mv = cb.addMethod(String.class, "test", null, null); - CodeBuilder code = mv.startCode(); - - int var1 = code.newLocal(Type.LONG_TYPE); - int var2 = code.newLocal(Type.getType(String.class)); - - code.visitCode(); - - code.push(10L); - code.storeLocal(var1); - - code.loadLocal(var1); - code.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(J)Ljava/lang/String;"); - code.storeLocal(var2); - - code.loadLocal(var2); - code.returnValue(); - - Class c = cb.toClass(); - - Object co = c.newInstance(); - - // toString() - assertEquals("hello, world", co.toString()); - - // test() - Method testMethod = c.getMethod("test"); - - assertEquals("10", testMethod.invoke(co)); - - System.out.println("==============================="); - System.out.println(dump(MyClass.class, null)); - System.out.println("==============================="); - System.out.println(dump(c, null)); - } - - private String dump(Class clazz, Remapper mapper) throws Exception { - InputStream is; - try { - is = new FileInputStream(new File(debuggingLocation, clazz.getName().replace('.', '/') + ".class")); - } catch (FileNotFoundException e) { - is = clazz.getClassLoader().getResourceAsStream(clazz.getName().replace('.', '/') + ".class"); - } - - ClassReader cr = new ClassReader(is); - StringWriter buf = new StringWriter(); - PrintWriter out = new PrintWriter(buf); - - ClassVisitor cv = new ASMifierClassVisitor(out); - - if (mapper != null) { - cv = new RemappingClassAdapter(cv, mapper); - } - - cr.accept(cv, SKIP_DEBUG); - - out.flush(); - out.close(); - is.close(); - - return buf.toString(); - } -} diff --git a/common/codegen/src/test/java/com/alibaba/citrus/codegen/MyClass.java b/common/codegen/src/test/java/com/alibaba/citrus/codegen/MyClass.java deleted file mode 100644 index 6f5911c01..000000000 --- a/common/codegen/src/test/java/com/alibaba/citrus/codegen/MyClass.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.alibaba.citrus.codegen; - -public class MyClass { - public MyClass() { - } - - @Override - public String toString() { - test(); - return "hello, world"; - } - - @SuppressWarnings("unused") - public void test() { - long i = 10; - String s = String.valueOf(i); - } -} diff --git a/common/codegen/src/test/java/com/alibaba/citrus/codegen/util/CodegenUtilTests.java b/common/codegen/src/test/java/com/alibaba/citrus/codegen/util/CodegenUtilTests.java deleted file mode 100644 index 7d10eedc2..000000000 --- a/common/codegen/src/test/java/com/alibaba/citrus/codegen/util/CodegenUtilTests.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.alibaba.citrus.codegen.util; - -import static org.junit.Assert.*; - -import java.util.Map; - -import org.junit.Test; - -import com.alibaba.citrus.util.CollectionUtil; - -/** - * 测试CodegenUtil。 - * - * @author Michael Zhou - */ -public class CodegenUtilTests { - - @Test - public void generateClassName_withClass() { - String value; - - value = CodegenUtil.generateClassName(String.class); - assertTrue(value.startsWith("java.lang.$String_")); - - value = CodegenUtil.generateClassName((Class) null); - assertTrue(value.startsWith("$_") && value.length() > 2); - } - - @Test - public void generateClassName_withClass_pacakge() { - String value; - - value = CodegenUtil.generateClassName(String.class, "codegen"); - assertTrue(value.startsWith("codegen.$String_")); - - value = CodegenUtil.generateClassName((Class) null, "codegen"); - assertTrue(value.startsWith("codegen.$_")); - - value = CodegenUtil.generateClassName(String.class, ""); - assertTrue(value.startsWith("$String_")); - - value = CodegenUtil.generateClassName((Class) null, ""); - assertTrue(value.startsWith("$_") && value.length() > 2); - } - - @Test - public void generateClassName_withClassName() { - String value; - - value = CodegenUtil.generateClassName("java.lang.String"); - assertTrue(value.startsWith("java.lang.$String_")); - - value = CodegenUtil.generateClassName(" java.lang.String "); - assertTrue(value.startsWith("java.lang.$String_")); - - value = CodegenUtil.generateClassName((String) null); - assertTrue(value.startsWith("$_") && value.length() > 2); - - value = CodegenUtil.generateClassName(" "); - assertTrue(value.startsWith("$_") && value.length() > 2); - } - - @Test - public void generateClassName_withClassName_pacakge() { - String value; - - value = CodegenUtil.generateClassName("java.lang.String", "codegen"); - assertTrue(value.startsWith("codegen.$String_")); - - value = CodegenUtil.generateClassName(" java.lang.String ", "codegen"); - assertTrue(value.startsWith("codegen.$String_")); - - value = CodegenUtil.generateClassName((String) null, "codegen"); - assertTrue(value.startsWith("codegen.$_")); - - value = CodegenUtil.generateClassName(" ", "codegen"); - assertTrue(value.startsWith("codegen.$_")); - - value = CodegenUtil.generateClassName("java.lang.String", ""); - assertTrue(value.startsWith("$String_")); - - value = CodegenUtil.generateClassName(" java.lang.String ", ""); - assertTrue(value.startsWith("$String_")); - - value = CodegenUtil.generateClassName((String) null, ""); - assertTrue(value.startsWith("$_")); - - value = CodegenUtil.generateClassName(" ", ""); - assertTrue(value.startsWith("$_")); - - value = CodegenUtil.generateClassName("", ""); - assertTrue(value.startsWith("$_")); - } - - @Test - public void uid() throws InterruptedException { - final Map names = CollectionUtil.createConcurrentHashMap(); - final int threadCount = 10; - final int loop = 10000; - - Thread[] threads = new Thread[threadCount]; - Runnable runnable = new Runnable() { - public void run() { - for (int i = 0; i < loop; i++) { - String name = CodegenUtil.generateClassName(""); - names.put(name, name); - } - } - }; - - for (int i = 0; i < threads.length; i++) { - threads[i] = new Thread(runnable, "thread " + (i + 1)); - } - - long start = System.currentTimeMillis(); - - for (Thread element : threads) { - element.start(); - } - - for (Thread element : threads) { - element.join(); - } - - System.out.printf("generateClassName duration: %,d ms\n\n", System.currentTimeMillis() - start); - - assertEquals(threadCount * loop, names.size()); - } -} diff --git a/common/codegen/src/test/java/com/alibaba/citrus/codegen/util/TypeUtilTests.java b/common/codegen/src/test/java/com/alibaba/citrus/codegen/util/TypeUtilTests.java deleted file mode 100644 index bd17748ff..000000000 --- a/common/codegen/src/test/java/com/alibaba/citrus/codegen/util/TypeUtilTests.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2010 Alibaba Group Holding Limited. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.alibaba.citrus.codegen.util; - -import static com.alibaba.citrus.test.TestUtil.*; -import static org.junit.Assert.*; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; - -import org.junit.Test; - -import com.alibaba.citrus.asm.Type; - -/** - * 测试TypeUtil类。 - * - * @author Michael Zhou - */ -public class TypeUtilTests { - @Test - public void internalNames() { - assertEquals("java/lang/String", TypeUtil.getInternalNameFromClassName(String.class.getName())); - - try { - TypeUtil.getInternalNameFromClassName(int.class.getName()); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e, exception("primitive")); - } - - try { - TypeUtil.getInternalNameFromClassName(int[].class.getName()); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e, exception("array")); - } - - try { - TypeUtil.getInternalNameFromClassName(String[].class.getName()); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e, exception("array")); - } - } - - @Test - public void descriptors() { - testDescriptor("I", int.class); - testDescriptor("[I", int[].class); - testDescriptor("Ljava/lang/Integer;", Integer.class); - testDescriptor("[[Ljava/lang/Integer;", Integer[][].class); - } - - private void testDescriptor(String descriptor, Class type) { - // className -> descriptor - assertEquals(descriptor, TypeUtil.getDescriptorFromClassName(type.getName())); - - // className -> Type - assertEquals(descriptor, TypeUtil.getTypeFromClassName(type.getName()).getDescriptor()); - - // class -> Type - assertEquals(descriptor, TypeUtil.getTypeFromClass(type).getDescriptor()); - } - - @Test(expected = IllegalArgumentException.class) - public void getDescriptorFromClassName() { - TypeUtil.getDescriptorFromClassName(null); - } - - @Test(expected = IllegalArgumentException.class) - public void getDescriptorFromClassName_2() { - TypeUtil.getDescriptorFromClassName(""); - } - - @Test(expected = IllegalArgumentException.class) - public void getTypeFromClassName() { - TypeUtil.getTypeFromClassName(null); - } - - @Test(expected = IllegalArgumentException.class) - public void getTypeFromClassName_2() { - TypeUtil.getTypeFromClassName(""); - } - - @Test(expected = IllegalArgumentException.class) - public void getTypeFromClass() { - TypeUtil.getTypeFromClass(null); - } - - @Test - public void getTypes() { - assertArrayEquals(new Type[0], TypeUtil.getTypes(null)); - assertArrayEquals(new Type[0], TypeUtil.getTypes(new Class[0])); - - assertArrayEquals(new Type[] { Type.getType("I"), Type.getType("[Ljava/lang/Integer;") }, - TypeUtil.getTypes(new Class[] { int.class, Integer[].class })); - } - - @Test - public void getInternalNames() { - assertArrayEquals(new String[0], TypeUtil.getInternalNames(null)); - assertArrayEquals(new String[0], TypeUtil.getInternalNames(new Type[0])); - - assertArrayEquals(new String[] { "java/lang/String", "java/lang/Integer" }, - TypeUtil.getInternalNames(TypeUtil.getTypes(new Class[] { String.class, Integer.class }))); - - try { - TypeUtil.getInternalNames(TypeUtil.getTypes(new Class[] { int.class, Integer[].class })); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e, exception("not", "internal name")); - } - } - - @Test - public void getConstructorSignature() { - for (Constructor constructor : String.class.getDeclaredConstructors()) { - com.alibaba.citrus.asm.commons.Method asmMethod = new com.alibaba.citrus.asm.commons.Method("", - Type.getConstructorDescriptor(constructor)); - - // 方式一 - MethodSignature signature = TypeUtil.getConstructorSignature(constructor); - - assertEquals(asmMethod.hashCode(), signature.hashCode()); - assertEquals(asmMethod, signature); - - // 方式二 - signature = TypeUtil.getConstructorSignature(constructor.getParameterTypes()); - - assertEquals(asmMethod.hashCode(), signature.hashCode()); - assertEquals(asmMethod, signature); - } - } - - @Test - public void getMethodSignature() { - for (Method method : String.class.getDeclaredMethods()) { - com.alibaba.citrus.asm.commons.Method asmMethod = new com.alibaba.citrus.asm.commons.Method( - method.getName(), Type.getMethodDescriptor(method)); - - // 方式一 - MethodSignature signature = TypeUtil.getMethodSignature(method); - - assertEquals(asmMethod.hashCode(), signature.hashCode()); - assertEquals(asmMethod, signature); - - // 方式二 - signature = TypeUtil.getMethodSignature(method.getName(), method.getReturnType(), - method.getParameterTypes()); - - assertEquals(asmMethod.hashCode(), signature.hashCode()); - assertEquals(asmMethod, signature); - } - } - - @Test - public void testBits() { - assertTrue(TypeUtil.testBits(6, 2)); - assertFalse(TypeUtil.testBits(6, 1)); - } -} diff --git a/common/generictype/pom.xml b/common/generictype/pom.xml index 62a16aea3..5606684d7 100644 --- a/common/generictype/pom.xml +++ b/common/generictype/pom.xml @@ -27,10 +27,6 @@ ${project.groupId} citrus-common-util - - ${project.groupId} - citrus-common-codegen - ${project.groupId} citrus-test-util diff --git a/common/generictype/src/main/java/com/alibaba/citrus/generictype/MethodInfo.java b/common/generictype/src/main/java/com/alibaba/citrus/generictype/MethodInfo.java index 7cf2a5fcf..003f328c5 100644 --- a/common/generictype/src/main/java/com/alibaba/citrus/generictype/MethodInfo.java +++ b/common/generictype/src/main/java/com/alibaba/citrus/generictype/MethodInfo.java @@ -21,7 +21,7 @@ import java.lang.reflect.Method; import java.util.List; -import com.alibaba.citrus.codegen.util.MethodSignature; +import com.alibaba.citrus.generictype.codegen.MethodSignature; /** * 代表一个{@link Method}或{@link Constructor}的信息。 diff --git a/common/codegen/src/main/java/com/alibaba/citrus/codegen/util/CodegenConstant.java b/common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/CodegenConstant.java similarity index 74% rename from common/codegen/src/main/java/com/alibaba/citrus/codegen/util/CodegenConstant.java rename to common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/CodegenConstant.java index 3e31bf7af..cd7c4161e 100644 --- a/common/codegen/src/main/java/com/alibaba/citrus/codegen/util/CodegenConstant.java +++ b/common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/CodegenConstant.java @@ -15,13 +15,10 @@ * limitations under the License. */ -package com.alibaba.citrus.codegen.util; +package com.alibaba.citrus.generictype.codegen; -import static com.alibaba.citrus.asm.Opcodes.*; - -import com.alibaba.citrus.asm.ClassWriter; -import com.alibaba.citrus.asm.Opcodes; -import com.alibaba.citrus.asm.Type; +import com.alibaba.citrus.generictype.codegen.asm.Opcodes; +import com.alibaba.citrus.generictype.codegen.asm.Type; /** * 和二进制码生成相关的常量。 @@ -29,9 +26,6 @@ * @author Michael Zhou */ public final class CodegenConstant { - /** 默认的ClassWriter标志位。 */ - public final static int DEFAULT_CLASS_WRITER_FLAGS = ClassWriter.COMPUTE_MAXS; - /** 默认的class文件版本。 */ public final static int DEFAULT_CLASS_VERSION = Opcodes.V1_5; @@ -44,9 +38,6 @@ public final class CodegenConstant { /** java.lang.Object对应的Type对象。 */ public final static Type OBJECT_TYPE = Type.getType(Object.class); - /** 常量修饰符。 */ - public final static int ACC_CONSTANT = ACC_STATIC | ACC_FINAL; - /** 构造函数的名称。 */ public final static String CONSTRUCTOR_NAME = ""; diff --git a/common/codegen/src/main/java/com/alibaba/citrus/codegen/util/MethodSignature.java b/common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/MethodSignature.java similarity index 75% rename from common/codegen/src/main/java/com/alibaba/citrus/codegen/util/MethodSignature.java rename to common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/MethodSignature.java index 69995c897..be07e3791 100644 --- a/common/codegen/src/main/java/com/alibaba/citrus/codegen/util/MethodSignature.java +++ b/common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/MethodSignature.java @@ -15,16 +15,16 @@ * limitations under the License. */ -package com.alibaba.citrus.codegen.util; +package com.alibaba.citrus.generictype.codegen; -import static com.alibaba.citrus.asm.Type.*; -import static com.alibaba.citrus.codegen.util.CodegenConstant.*; -import static com.alibaba.citrus.codegen.util.TypeUtil.*; +import static com.alibaba.citrus.generictype.codegen.CodegenConstant.*; +import static com.alibaba.citrus.generictype.codegen.TypeUtil.*; +import static com.alibaba.citrus.generictype.codegen.asm.Type.*; import java.lang.reflect.Constructor; import java.lang.reflect.Method; -import com.alibaba.citrus.asm.Type; +import com.alibaba.citrus.generictype.codegen.asm.Type; /** * 代表一个构造函数或方法的签名,用来辨别相同的方法。 @@ -34,7 +34,7 @@ * * @author Michael Zhou */ -public class MethodSignature extends com.alibaba.citrus.asm.commons.Method { +public class MethodSignature extends com.alibaba.citrus.generictype.codegen.asm.Method { public MethodSignature(String name, Class returnType, Class... parameterTypes) { super(name, getType(returnType), getTypes(parameterTypes)); } diff --git a/common/codegen/src/main/java/com/alibaba/citrus/codegen/util/TypeUtil.java b/common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/TypeUtil.java similarity index 94% rename from common/codegen/src/main/java/com/alibaba/citrus/codegen/util/TypeUtil.java rename to common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/TypeUtil.java index c17c9cbec..be691ec23 100644 --- a/common/codegen/src/main/java/com/alibaba/citrus/codegen/util/TypeUtil.java +++ b/common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/TypeUtil.java @@ -15,9 +15,9 @@ * limitations under the License. */ -package com.alibaba.citrus.codegen.util; +package com.alibaba.citrus.generictype.codegen; -import static com.alibaba.citrus.asm.Type.*; +import static com.alibaba.citrus.generictype.codegen.asm.Type.*; import static com.alibaba.citrus.util.Assert.*; import static com.alibaba.citrus.util.CollectionUtil.*; @@ -25,7 +25,7 @@ import java.lang.reflect.Method; import java.util.Map; -import com.alibaba.citrus.asm.Type; +import com.alibaba.citrus.generictype.codegen.asm.Type; import com.alibaba.citrus.util.StringUtil; /** diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/Method.java b/common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/asm/Method.java similarity index 96% rename from common/asm/src/main/java/com/alibaba/citrus/asm/commons/Method.java rename to common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/asm/Method.java index e6423e50b..f815cae8c 100644 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/commons/Method.java +++ b/common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/asm/Method.java @@ -44,13 +44,11 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ -package com.alibaba.citrus.asm.commons; +package com.alibaba.citrus.generictype.codegen.asm; import java.util.HashMap; import java.util.Map; -import com.alibaba.citrus.asm.Type; - /** * A named method descriptor. * @@ -58,6 +56,7 @@ * @author Chris Nokleberg * @author Eric Bruneton */ +@SuppressWarnings("all") public class Method { /** diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/Opcodes.java b/common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/asm/Opcodes.java similarity index 96% rename from common/asm/src/main/java/com/alibaba/citrus/asm/Opcodes.java rename to common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/asm/Opcodes.java index e082cb3a3..94b233247 100644 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/Opcodes.java +++ b/common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/asm/Opcodes.java @@ -44,7 +44,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ -package com.alibaba.citrus.asm; +package com.alibaba.citrus.generictype.codegen.asm; /** * Defines the JVM opcodes, access flags and array type codes. This interface diff --git a/common/asm/src/main/java/com/alibaba/citrus/asm/Type.java b/common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/asm/Type.java similarity index 96% rename from common/asm/src/main/java/com/alibaba/citrus/asm/Type.java rename to common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/asm/Type.java index 42d353486..e78439413 100644 --- a/common/asm/src/main/java/com/alibaba/citrus/asm/Type.java +++ b/common/generictype/src/main/java/com/alibaba/citrus/generictype/codegen/asm/Type.java @@ -44,7 +44,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ -package com.alibaba.citrus.asm; +package com.alibaba.citrus.generictype.codegen.asm; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -56,6 +56,7 @@ * @author Eric Bruneton * @author Chris Nokleberg */ +@SuppressWarnings("all") public class Type { /** diff --git a/common/generictype/src/main/java/com/alibaba/citrus/generictype/impl/MethodImpl.java b/common/generictype/src/main/java/com/alibaba/citrus/generictype/impl/MethodImpl.java index d0b571aac..d077497bd 100644 --- a/common/generictype/src/main/java/com/alibaba/citrus/generictype/impl/MethodImpl.java +++ b/common/generictype/src/main/java/com/alibaba/citrus/generictype/impl/MethodImpl.java @@ -17,7 +17,7 @@ package com.alibaba.citrus.generictype.impl; -import static com.alibaba.citrus.codegen.util.TypeUtil.*; +import static com.alibaba.citrus.generictype.codegen.TypeUtil.*; import static com.alibaba.citrus.util.CollectionUtil.*; import static java.lang.reflect.Modifier.*; import static java.util.Collections.*; @@ -29,12 +29,12 @@ import java.util.Iterator; import java.util.List; -import com.alibaba.citrus.codegen.util.MethodSignature; import com.alibaba.citrus.generictype.ClassTypeInfo; import com.alibaba.citrus.generictype.GenericDeclarationInfo; import com.alibaba.citrus.generictype.MethodInfo; import com.alibaba.citrus.generictype.TypeInfo; import com.alibaba.citrus.generictype.TypeVariableInfo; +import com.alibaba.citrus.generictype.codegen.MethodSignature; /** * 对{@link MethodInfo}的实现。 diff --git a/dist/test/pom.xml b/dist/test/pom.xml index 232711cec..0ba9986aa 100644 --- a/dist/test/pom.xml +++ b/dist/test/pom.xml @@ -43,7 +43,7 @@ ${project.groupId}:citrus-test-* - com.alibaba.citrus.asm:com.alibaba.citrus.hessian:com.alibaba.citrus.burlap:freemarker + com.alibaba.citrus.hessian:com.alibaba.citrus.burlap:freemarker diff --git a/dist/webx/pom.xml b/dist/webx/pom.xml index 9089f70c0..4a1869335 100644 --- a/dist/webx/pom.xml +++ b/dist/webx/pom.xml @@ -43,7 +43,7 @@ ${project.groupId}:* - com.alibaba.citrus.asm:com.alibaba.citrus.hessian:com.alibaba.citrus.burlap:freemarker + com.alibaba.citrus.hessian:com.alibaba.citrus.burlap:freemarker @@ -113,14 +113,6 @@ ${project.groupId} citrus-common-generictype - - ${project.groupId} - citrus-common-asm - - - ${project.groupId} - citrus-common-codegen - ${project.groupId} citrus-test-util diff --git a/pom.xml b/pom.xml index 02976f9d6..a939c1f5c 100644 --- a/pom.xml +++ b/pom.xml @@ -1,780 +1,768 @@ - - org.sonatype.oss - oss-parent - 7 - - 4.0.0 - com.alibaba.citrus - citrus-parent - pom - Citrus Parent Project - 3.0.8 - Another Java-based WEB Framework - http://www.openwebx.org/ - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - scm:git:https://github.com/webx/citrus - scm:git:git@github.com:webx/citrus.git - http://github.com/webx/citrus - - - - baobao - Michael Zhou - yizhi@taobao.com - - architect - developer - - - http://i54.tinypic.com/2jewmjr.jpg - - -6 - - - - 1.6 - UTF-8 - 3.0.8 - 2.5.6.SEC03 - 1.0 - 1.0 - 6.1.22 - ${java.encoding} - true - - - - spring3 - - 3.0.6.RELEASE - - - - deployment - - - 1.5 - - false - - - - - dist/webx - dist/test - common/expr - common/logconfig - common/util - common/springext - common/generictype - common/asm - common/hessian - common/codegen - test/util - test/webx - service/base - service/dataresolver - service/form - service/resource - service/upload - service/requestcontext - service/pipeline - service/configuration - service/mappingrule - service/moduleloader - service/pull - service/template - service/jsp - service/velocity - service/freemarker - service/uribroker - service/mail - webx/framework - webx/turbine - webx/dev - - - - org.slf4j - slf4j-api - - - org.slf4j - jcl-over-slf4j - - - - - - - - - ${project.groupId} - citrus-webx-all - ${webx-version} - - - ${project.groupId} - citrus-test-all - ${webx-version} - test - - - ${project.groupId} - citrus-common-logconfig - ${webx-version} - - - ${project.groupId} - citrus-common-expr - ${webx-version} - - - ${project.groupId} - citrus-common-util - ${webx-version} - - - ${project.groupId} - citrus-common-springext - ${webx-version} - - - ${project.groupId} - citrus-common-generictype - ${webx-version} - - - ${project.groupId} - citrus-common-asm - ${webx-version} - - - ${project.groupId} - citrus-common-hessian - ${webx-version} - - - ${project.groupId} - citrus-common-codegen - ${webx-version} - - - ${project.groupId} - citrus-test-util - ${webx-version} - test - - - ${project.groupId} - citrus-test-webx - ${webx-version} - test - - - ${project.groupId} - citrus-service-base - ${webx-version} - - - ${project.groupId} - citrus-service-dataresolver - ${webx-version} - - - ${project.groupId} - citrus-service-form - ${webx-version} - - - ${project.groupId} - citrus-service-resource - ${webx-version} - - - ${project.groupId} - citrus-service-upload - ${webx-version} - - - ${project.groupId} - citrus-service-requestcontext - ${webx-version} - - - ${project.groupId} - citrus-service-pipeline - ${webx-version} - - - ${project.groupId} - citrus-service-configuration - ${webx-version} - - - ${project.groupId} - citrus-service-mappingrule - ${webx-version} - - - ${project.groupId} - citrus-service-moduleloader - ${webx-version} - - - ${project.groupId} - citrus-service-pull - ${webx-version} - - - ${project.groupId} - citrus-service-template - ${webx-version} - - - ${project.groupId} - citrus-service-jsp - ${webx-version} - - - ${project.groupId} - citrus-service-velocity - ${webx-version} - - - ${project.groupId} - citrus-service-freemarker - ${webx-version} - - - ${project.groupId} - citrus-service-uribroker - ${webx-version} - - - ${project.groupId} - citrus-service-mail - ${webx-version} - - - ${project.groupId} - citrus-webx-framework - ${webx-version} - - - ${project.groupId} - citrus-webx-turbine - ${webx-version} - - - ${project.groupId} - citrus-webx-dev - ${webx-version} - - - - - - org.slf4j - slf4j-api - 1.6.1 - - - - org.slf4j - jcl-over-slf4j - 1.6.1 - - - - commons-logging - commons-logging - 1.1.1 - provided - - - - ch.qos.logback - logback-classic - 0.9.24 - runtime - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - runtime - - - log4j - log4j - 1.2.16 - runtime - - - - - - junit - junit - 4.8.2 - test - - - org.hamcrest - hamcrest-library - 1.1 - test - - - httpunit - httpunit - 1.7 - test - - - jtidy - jtidy - - - - - rhino - js - 1.7R1 - test - - - nekohtml - nekohtml - 1.9.6 - test - - - xerces - xercesImpl - 2.9.1 - test - - - xml-apis - xml-apis - - - - - xalan - xalan - 2.7.1 - test - - - xml-apis - xml-apis - - - - - org.easymock - easymockclassextension - 3.0 - test - - - org.apache.tomcat - jasper - 6.0.33 - test - - - org.jvnet.mock-javamail - mock-javamail - 1.7 - test - - - oro - oro - 2.0.8 - - - - - - ecs - ecs - 1.4.2 - - - org.apache.commons - commons-jexl - 2.0.1 - - - org.apache.velocity - velocity - 1.6.4 - - - org.freemarker - freemarker - 2.3.16 - - - commons-fileupload - commons-fileupload - 1.2.1 - - - commons-io - commons-io - 1.4 - - - commons-codec - commons-codec - 1.3 - - - org.codehaus.groovy - groovy-all - 1.6.3 - runtime - - - org.apache.ant - ant - - - org.apache.ant - ant-launcher - - - jline - jline - - - - - dom4j - dom4j - 1.6.1 - - - xml-apis - xml-apis - - - - - cglib - cglib-nodep - 2.2 - - - javax.servlet - servlet-api - 2.5 - provided - - - javax.mail - mail - 1.4.1 - provided - - - javax.activation - activation - 1.1 - provided - - - janino - janino - 2.5.10 - test - - - xml-apis - xml-apis - 1.3.04 - - - - - - org.springframework - spring-core - ${spring-version} - - - org.springframework - spring-beans - ${spring-version} - - - org.springframework - spring-aop - ${spring-version} - - - org.springframework - spring-context - ${spring-version} - - - org.springframework - spring-context-support - ${spring-version} - - - org.springframework - spring-tx - ${spring-version} - - - org.springframework - spring-jdbc - ${spring-version} - - - org.springframework - spring-orm - ${spring-version} - - - org.springframework - spring-web - ${spring-version} - - - org.springframework - spring-webmvc - ${spring-version} - - - org.springframework - spring-test - ${spring-version} - test - - - - - - - maven-deploy-plugin - false - - false - - - - maven-compiler-plugin - - 1.6 - ${java.version} - - - - maven-jar-plugin - - - - true - true - - - - - - maven-antrun-plugin - - - compile - - - - - - - - - - - run - - - - - - maven-surefire-plugin - - - **/*Tests.java - - -Xmx256m - - - - maven-eclipse-plugin - - true - - org.eclipse.jdt.launching.JRE_CONTAINER - - - - - maven-source-plugin - - - attach-sources - - jar-no-fork - - - - - - org.mortbay.jetty - maven-jetty-plugin - - citrus - 9999 - - - productionMode - false - - - - - - com.alibaba.citrus.tool - maven-springext-plugin - - - maven-gpg-plugin - - - sign-artifacts - verify - - sign - - - - - - - - - maven-antrun-plugin - 1.6 - - - maven-compiler-plugin - - 2.3.2 - - - maven-jar-plugin - 2.3.2 - - - maven-deploy-plugin - 2.7 - - true - - - - maven-eclipse-plugin - 2.8 - - - maven-shade-plugin - 1.4 - - - maven-source-plugin - 2.1.2 - - - maven-javadoc-plugin - 2.8 - - - maven-surefire-plugin - 2.10 - - - org.mortbay.jetty - maven-jetty-plugin - ${jetty-version} - - - com.alibaba.citrus.tool - maven-springext-plugin - ${springext-plugin-version} - - - maven-gpg-plugin - 1.4 - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.apache.maven.plugins - maven-antrun-plugin - [1.0,) - - run - - - - - - - - - org.apache.maven.plugins - maven-enforcer-plugin - [1.0,) - - enforce - - - - - - - - - - - - - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + org.sonatype.oss + oss-parent + 7 + + 4.0.0 + com.alibaba.citrus + citrus-parent + pom + Citrus Parent Project + 3.0.8 + Another Java-based WEB Framework + http://www.openwebx.org/ + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + scm:git:https://github.com/webx/citrus + scm:git:git@github.com:webx/citrus.git + http://github.com/webx/citrus + + + + baobao + Michael Zhou + yizhi@taobao.com + + architect + developer + + + http://i54.tinypic.com/2jewmjr.jpg + + -6 + + + + 1.6 + UTF-8 + 3.0.8 + 2.5.6.SEC03 + 1.0 + 1.0 + 6.1.22 + ${java.encoding} + true + + + + spring3 + + 3.0.6.RELEASE + + + + deployment + + + 1.5 + + false + + + + + dist/webx + dist/test + common/expr + common/logconfig + common/util + common/springext + common/generictype + common/hessian + test/util + test/webx + service/base + service/dataresolver + service/form + service/resource + service/upload + service/requestcontext + service/pipeline + service/configuration + service/mappingrule + service/moduleloader + service/pull + service/template + service/jsp + service/velocity + service/freemarker + service/uribroker + service/mail + webx/framework + webx/turbine + webx/dev + + + + org.slf4j + slf4j-api + + + org.slf4j + jcl-over-slf4j + + + + + + + + + ${project.groupId} + citrus-webx-all + ${webx-version} + + + ${project.groupId} + citrus-test-all + ${webx-version} + test + + + ${project.groupId} + citrus-common-logconfig + ${webx-version} + + + ${project.groupId} + citrus-common-expr + ${webx-version} + + + ${project.groupId} + citrus-common-util + ${webx-version} + + + ${project.groupId} + citrus-common-springext + ${webx-version} + + + ${project.groupId} + citrus-common-generictype + ${webx-version} + + + ${project.groupId} + citrus-common-hessian + ${webx-version} + + + ${project.groupId} + citrus-test-util + ${webx-version} + test + + + ${project.groupId} + citrus-test-webx + ${webx-version} + test + + + ${project.groupId} + citrus-service-base + ${webx-version} + + + ${project.groupId} + citrus-service-dataresolver + ${webx-version} + + + ${project.groupId} + citrus-service-form + ${webx-version} + + + ${project.groupId} + citrus-service-resource + ${webx-version} + + + ${project.groupId} + citrus-service-upload + ${webx-version} + + + ${project.groupId} + citrus-service-requestcontext + ${webx-version} + + + ${project.groupId} + citrus-service-pipeline + ${webx-version} + + + ${project.groupId} + citrus-service-configuration + ${webx-version} + + + ${project.groupId} + citrus-service-mappingrule + ${webx-version} + + + ${project.groupId} + citrus-service-moduleloader + ${webx-version} + + + ${project.groupId} + citrus-service-pull + ${webx-version} + + + ${project.groupId} + citrus-service-template + ${webx-version} + + + ${project.groupId} + citrus-service-jsp + ${webx-version} + + + ${project.groupId} + citrus-service-velocity + ${webx-version} + + + ${project.groupId} + citrus-service-freemarker + ${webx-version} + + + ${project.groupId} + citrus-service-uribroker + ${webx-version} + + + ${project.groupId} + citrus-service-mail + ${webx-version} + + + ${project.groupId} + citrus-webx-framework + ${webx-version} + + + ${project.groupId} + citrus-webx-turbine + ${webx-version} + + + ${project.groupId} + citrus-webx-dev + ${webx-version} + + + + + + org.slf4j + slf4j-api + 1.6.1 + + + + org.slf4j + jcl-over-slf4j + 1.6.1 + + + + commons-logging + commons-logging + 1.1.1 + provided + + + + ch.qos.logback + logback-classic + 0.9.24 + runtime + + + + org.slf4j + slf4j-log4j12 + 1.6.1 + runtime + + + log4j + log4j + 1.2.16 + runtime + + + + + + junit + junit + 4.8.2 + test + + + org.hamcrest + hamcrest-library + 1.1 + test + + + httpunit + httpunit + 1.7 + test + + + jtidy + jtidy + + + + + rhino + js + 1.7R1 + test + + + nekohtml + nekohtml + 1.9.6 + test + + + xerces + xercesImpl + 2.9.1 + test + + + xml-apis + xml-apis + + + + + xalan + xalan + 2.7.1 + test + + + xml-apis + xml-apis + + + + + org.easymock + easymockclassextension + 3.0 + test + + + org.apache.tomcat + jasper + 6.0.33 + test + + + org.jvnet.mock-javamail + mock-javamail + 1.7 + test + + + oro + oro + 2.0.8 + + + + + + ecs + ecs + 1.4.2 + + + org.apache.commons + commons-jexl + 2.0.1 + + + org.apache.velocity + velocity + 1.6.4 + + + org.freemarker + freemarker + 2.3.16 + + + commons-fileupload + commons-fileupload + 1.2.1 + + + commons-io + commons-io + 1.4 + + + commons-codec + commons-codec + 1.3 + + + org.codehaus.groovy + groovy-all + 1.6.3 + runtime + + + org.apache.ant + ant + + + org.apache.ant + ant-launcher + + + jline + jline + + + + + dom4j + dom4j + 1.6.1 + + + xml-apis + xml-apis + + + + + cglib + cglib-nodep + 2.2 + + + javax.servlet + servlet-api + 2.5 + provided + + + javax.mail + mail + 1.4.1 + provided + + + javax.activation + activation + 1.1 + provided + + + janino + janino + 2.5.10 + test + + + xml-apis + xml-apis + 1.3.04 + + + + + + org.springframework + spring-core + ${spring-version} + + + org.springframework + spring-beans + ${spring-version} + + + org.springframework + spring-aop + ${spring-version} + + + org.springframework + spring-context + ${spring-version} + + + org.springframework + spring-context-support + ${spring-version} + + + org.springframework + spring-tx + ${spring-version} + + + org.springframework + spring-jdbc + ${spring-version} + + + org.springframework + spring-orm + ${spring-version} + + + org.springframework + spring-web + ${spring-version} + + + org.springframework + spring-webmvc + ${spring-version} + + + org.springframework + spring-test + ${spring-version} + test + + + + + + + maven-deploy-plugin + false + + false + + + + maven-compiler-plugin + + 1.6 + ${java.version} + + + + maven-jar-plugin + + + + true + true + + + + + + maven-antrun-plugin + + + compile + + + + + + + + + + + run + + + + + + maven-surefire-plugin + + + **/*Tests.java + + -Xmx256m + + + + maven-eclipse-plugin + + true + + org.eclipse.jdt.launching.JRE_CONTAINER + + + + + maven-source-plugin + + + attach-sources + + jar-no-fork + + + + + + org.mortbay.jetty + maven-jetty-plugin + + citrus + 9999 + + + productionMode + false + + + + + + com.alibaba.citrus.tool + maven-springext-plugin + + + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + + + + + + maven-antrun-plugin + 1.6 + + + maven-compiler-plugin + + 2.3.2 + + + maven-jar-plugin + 2.3.2 + + + maven-deploy-plugin + 2.7 + + true + + + + maven-eclipse-plugin + 2.8 + + + maven-shade-plugin + 1.4 + + + maven-source-plugin + 2.1.2 + + + maven-javadoc-plugin + 2.8 + + + maven-surefire-plugin + 2.10 + + + org.mortbay.jetty + maven-jetty-plugin + ${jetty-version} + + + com.alibaba.citrus.tool + maven-springext-plugin + ${springext-plugin-version} + + + maven-gpg-plugin + 1.4 + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.apache.maven.plugins + maven-antrun-plugin + [1.0,) + + run + + + + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + [1.0,) + + enforce + + + + + + + + + + + + +

-The ASM framework is organized -around the {@link com.alibaba.citrus.asm.ClassVisitor ClassVisitor}, -{@link com.alibaba.citrus.asm.FieldVisitor FieldVisitor} and -{@link com.alibaba.citrus.asm.MethodVisitor MethodVisitor} interfaces, which allow -one to visit the fields and methods of a class, including the bytecode -instructions of each method. - -