From 8d07bd5e96349d33df321e669c27d3ea4fb695ec Mon Sep 17 00:00:00 2001 From: Konloch Date: Fri, 12 Apr 2019 21:42:04 -0600 Subject: [PATCH] java 10 fixes, auto RT finding, krakatau cache fixes --- libs/asm-7.1.jar | Bin 0 -> 114762 bytes libs/asm-analysis-7.1.jar | Bin 0 -> 33379 bytes libs/asm-commons-7.1.jar | Bin 0 -> 70394 bytes libs/asm-tree-7.1.jar | Bin 0 -> 50303 bytes src/org/objectweb/asm/AnnotationVisitor.java | 158 - src/org/objectweb/asm/AnnotationWriter.java | 359 -- src/org/objectweb/asm/Attribute.java | 232 -- src/org/objectweb/asm/ByteVector.java | 322 -- src/org/objectweb/asm/ClassReader.java | 2424 -------------- src/org/objectweb/asm/ClassVisitor.java | 285 -- src/org/objectweb/asm/ClassWriter.java | 1710 ---------- src/org/objectweb/asm/Context.java | 145 - src/org/objectweb/asm/Edge.java | 75 - src/org/objectweb/asm/FieldVisitor.java | 140 - src/org/objectweb/asm/FieldWriter.java | 322 -- src/org/objectweb/asm/Frame.java | 1434 -------- src/org/objectweb/asm/Handle.java | 166 - src/org/objectweb/asm/Handler.java | 118 - src/org/objectweb/asm/Item.java | 295 -- src/org/objectweb/asm/Label.java | 546 ---- src/org/objectweb/asm/MethodVisitor.java | 790 ----- src/org/objectweb/asm/MethodWriter.java | 2884 ----------------- src/org/objectweb/asm/Opcodes.java | 361 --- src/org/objectweb/asm/Type.java | 878 ----- src/org/objectweb/asm/TypePath.java | 191 -- src/org/objectweb/asm/TypeReference.java | 435 --- .../objectweb/asm/commons/AdviceAdapter.java | 639 ---- .../asm/commons/AnalyzerAdapter.java | 935 ------ .../asm/commons/CodeSizeEvaluator.java | 238 -- .../asm/commons/GeneratorAdapter.java | 1515 --------- .../asm/commons/InstructionAdapter.java | 1166 ------- .../asm/commons/JSRInlinerAdapter.java | 725 ----- .../asm/commons/LocalVariablesSorter.java | 369 --- src/org/objectweb/asm/commons/Method.java | 270 -- .../asm/commons/SerialVersionUIDAdder.java | 529 --- .../objectweb/asm/commons/SimpleRemapper.java | 75 - .../asm/commons/StaticInitMerger.java | 97 - .../asm/commons/TableSwitchGenerator.java | 55 - .../asm/commons/TryCatchBlockSorter.java | 97 - src/org/objectweb/asm/commons/cfg/Block.java | 204 -- .../asm/commons/cfg/BlockVisitor.java | 20 - .../asm/commons/cfg/CallVisitor.java | 39 - .../asm/commons/cfg/InsnVisitor.java | 288 -- .../asm/commons/cfg/graph/CallGraph.java | 14 - .../asm/commons/cfg/graph/Digraph.java | 133 - .../asm/commons/cfg/graph/FlowGraph.java | 20 - .../asm/commons/cfg/query/InsnQuery.java | 36 - .../asm/commons/cfg/query/MemberQuery.java | 64 - .../asm/commons/cfg/query/NumberQuery.java | 37 - .../asm/commons/cfg/tree/NodeTree.java | 55 - .../asm/commons/cfg/tree/NodeVisitor.java | 128 - .../objectweb/asm/commons/cfg/tree/Tree.java | 104 - .../commons/cfg/tree/node/AbstractNode.java | 490 --- .../commons/cfg/tree/node/ArithmeticNode.java | 78 - .../commons/cfg/tree/node/ConstantNode.java | 24 - .../commons/cfg/tree/node/ConversionNode.java | 54 - .../cfg/tree/node/FieldMemberNode.java | 27 - .../asm/commons/cfg/tree/node/IincNode.java | 23 - .../asm/commons/cfg/tree/node/JumpNode.java | 55 - .../cfg/tree/node/MethodMemberNode.java | 19 - .../asm/commons/cfg/tree/node/NumberNode.java | 81 - .../commons/cfg/tree/node/ReferenceNode.java | 75 - .../asm/commons/cfg/tree/node/TargetNode.java | 46 - .../asm/commons/cfg/tree/node/TypeNode.java | 19 - .../commons/cfg/tree/node/VariableNode.java | 19 - .../commons/cfg/tree/util/TreeBuilder.java | 224 -- .../asm/commons/cfg/tree/util/TreeSize.java | 19 - .../objectweb/asm/commons/util/Assembly.java | 258 -- .../asm/commons/util/JarArchive.java | 81 - .../asm/signature/SignatureReader.java | 223 -- .../asm/signature/SignatureVisitor.java | 231 -- .../asm/signature/SignatureWriter.java | 227 -- .../objectweb/asm/tree/AbstractInsnNode.java | 323 -- .../objectweb/asm/tree/AnnotationNode.java | 223 -- src/org/objectweb/asm/tree/ClassNode.java | 552 ---- src/org/objectweb/asm/tree/FieldInsnNode.java | 118 - src/org/objectweb/asm/tree/FieldNode.java | 309 -- src/org/objectweb/asm/tree/FrameNode.java | 204 -- src/org/objectweb/asm/tree/IincInsnNode.java | 81 - .../objectweb/asm/tree/InnerClassNode.java | 96 - src/org/objectweb/asm/tree/InsnList.java | 609 ---- src/org/objectweb/asm/tree/InsnNode.java | 86 - src/org/objectweb/asm/tree/IntInsnNode.java | 92 - .../asm/tree/InvokeDynamicInsnNode.java | 98 - src/org/objectweb/asm/tree/JumpInsnNode.java | 94 - src/org/objectweb/asm/tree/LabelNode.java | 78 - src/org/objectweb/asm/tree/LdcInsnNode.java | 83 - .../objectweb/asm/tree/LineNumberNode.java | 82 - .../asm/tree/LocalVariableAnnotationNode.java | 142 - .../objectweb/asm/tree/LocalVariableNode.java | 105 - .../asm/tree/LookupSwitchInsnNode.java | 115 - .../objectweb/asm/tree/MethodInsnNode.java | 144 - src/org/objectweb/asm/tree/MethodNode.java | 948 ------ .../asm/tree/MultiANewArrayInsnNode.java | 81 - src/org/objectweb/asm/tree/ParameterNode.java | 73 - .../asm/tree/TableSwitchInsnNode.java | 110 - .../objectweb/asm/tree/TryCatchBlockNode.java | 147 - .../asm/tree/TypeAnnotationNode.java | 92 - src/org/objectweb/asm/tree/TypeInsnNode.java | 88 - src/org/objectweb/asm/tree/VarInsnNode.java | 91 - .../objectweb/asm/tree/analysis/Analyzer.java | 531 --- .../asm/tree/analysis/AnalyzerException.java | 62 - .../asm/tree/analysis/BasicInterpreter.java | 358 -- .../asm/tree/analysis/BasicValue.java | 111 - .../asm/tree/analysis/BasicVerifier.java | 433 --- .../objectweb/asm/tree/analysis/Frame.java | 717 ---- .../asm/tree/analysis/Interpreter.java | 197 -- .../asm/tree/analysis/SimpleVerifier.java | 312 -- .../objectweb/asm/tree/analysis/SmallSet.java | 134 - .../asm/tree/analysis/SourceInterpreter.java | 198 -- .../asm/tree/analysis/SourceValue.java | 97 - .../asm/tree/analysis/Subroutine.java | 90 - .../objectweb/asm/tree/analysis/Value.java | 45 - src/org/objectweb/asm/util/ASMifiable.java | 56 - src/org/objectweb/asm/util/ASMifier.java | 1271 -------- .../asm/util/CheckAnnotationAdapter.java | 136 - .../objectweb/asm/util/CheckClassAdapter.java | 963 ------ .../objectweb/asm/util/CheckFieldAdapter.java | 118 - .../asm/util/CheckMethodAdapter.java | 1492 --------- .../asm/util/CheckSignatureAdapter.java | 325 -- src/org/objectweb/asm/util/Printer.java | 584 ---- src/org/objectweb/asm/util/Textifiable.java | 56 - src/org/objectweb/asm/util/Textifier.java | 1442 --------- .../asm/util/TraceAnnotationVisitor.java | 89 - .../objectweb/asm/util/TraceClassVisitor.java | 214 -- .../objectweb/asm/util/TraceFieldVisitor.java | 87 - .../asm/util/TraceMethodVisitor.java | 292 -- .../asm/util/TraceSignatureVisitor.java | 317 -- .../objectweb/asm/xml/ASMContentHandler.java | 1450 --------- src/org/objectweb/asm/xml/Processor.java | 1034 ------ src/org/objectweb/asm/xml/SAXAdapter.java | 89 - .../asm/xml/SAXAnnotationAdapter.java | 242 -- .../objectweb/asm/xml/SAXClassAdapter.java | 332 -- src/org/objectweb/asm/xml/SAXCodeAdapter.java | 412 --- .../objectweb/asm/xml/SAXFieldAdapter.java | 71 - .../club/bootloader/util/ClassTree.java | 12 - .../club/bytecodeviewer/BytecodeViewer.java | 177 +- .../decompilers/KrakatauDecompiler.java | 16 +- .../decompilers/KrakatauDisassembler.java | 13 +- .../bytecode/ClassNodeDecompiler.java | 3 +- .../bytecode/InstructionPattern.java | 12 +- .../bytecode/InstructionPrinter.java | 45 +- .../club/bytecodeviewer/gui/ClassViewer.java | 211 +- .../obfuscators/mapping/RefactorMapper.java | 2 - .../obfuscators/mapping/Refactorer.java | 3 +- .../obfuscators/mapping}/Remapper.java | 5 +- .../mapping}/RemappingAnnotationAdapter.java | 7 +- .../mapping}/RemappingClassAdapter.java | 271 +- .../mapping}/RemappingFieldAdapter.java | 7 +- .../mapping}/RemappingMethodAdapter.java | 8 +- .../mapping}/RemappingSignatureAdapter.java | 7 +- .../preinstalled/MaliciousCodeScanner.java | 4 +- .../searching/FieldCallSearch.java | 4 +- .../searching/MethodCallSearch.java | 4 +- .../searching/RegexInsnFinder.java | 14 +- 155 files changed, 459 insertions(+), 44382 deletions(-) create mode 100644 libs/asm-7.1.jar create mode 100644 libs/asm-analysis-7.1.jar create mode 100644 libs/asm-commons-7.1.jar create mode 100644 libs/asm-tree-7.1.jar delete mode 100644 src/org/objectweb/asm/AnnotationVisitor.java delete mode 100644 src/org/objectweb/asm/AnnotationWriter.java delete mode 100644 src/org/objectweb/asm/Attribute.java delete mode 100644 src/org/objectweb/asm/ByteVector.java delete mode 100644 src/org/objectweb/asm/ClassReader.java delete mode 100644 src/org/objectweb/asm/ClassVisitor.java delete mode 100644 src/org/objectweb/asm/ClassWriter.java delete mode 100644 src/org/objectweb/asm/Context.java delete mode 100644 src/org/objectweb/asm/Edge.java delete mode 100644 src/org/objectweb/asm/FieldVisitor.java delete mode 100644 src/org/objectweb/asm/FieldWriter.java delete mode 100644 src/org/objectweb/asm/Frame.java delete mode 100644 src/org/objectweb/asm/Handle.java delete mode 100644 src/org/objectweb/asm/Handler.java delete mode 100644 src/org/objectweb/asm/Item.java delete mode 100644 src/org/objectweb/asm/Label.java delete mode 100644 src/org/objectweb/asm/MethodVisitor.java delete mode 100644 src/org/objectweb/asm/MethodWriter.java delete mode 100644 src/org/objectweb/asm/Opcodes.java delete mode 100644 src/org/objectweb/asm/Type.java delete mode 100644 src/org/objectweb/asm/TypePath.java delete mode 100644 src/org/objectweb/asm/TypeReference.java delete mode 100644 src/org/objectweb/asm/commons/AdviceAdapter.java delete mode 100644 src/org/objectweb/asm/commons/AnalyzerAdapter.java delete mode 100644 src/org/objectweb/asm/commons/CodeSizeEvaluator.java delete mode 100644 src/org/objectweb/asm/commons/GeneratorAdapter.java delete mode 100644 src/org/objectweb/asm/commons/InstructionAdapter.java delete mode 100644 src/org/objectweb/asm/commons/JSRInlinerAdapter.java delete mode 100644 src/org/objectweb/asm/commons/LocalVariablesSorter.java delete mode 100644 src/org/objectweb/asm/commons/Method.java delete mode 100644 src/org/objectweb/asm/commons/SerialVersionUIDAdder.java delete mode 100644 src/org/objectweb/asm/commons/SimpleRemapper.java delete mode 100644 src/org/objectweb/asm/commons/StaticInitMerger.java delete mode 100644 src/org/objectweb/asm/commons/TableSwitchGenerator.java delete mode 100644 src/org/objectweb/asm/commons/TryCatchBlockSorter.java delete mode 100644 src/org/objectweb/asm/commons/cfg/Block.java delete mode 100644 src/org/objectweb/asm/commons/cfg/BlockVisitor.java delete mode 100644 src/org/objectweb/asm/commons/cfg/CallVisitor.java delete mode 100644 src/org/objectweb/asm/commons/cfg/InsnVisitor.java delete mode 100644 src/org/objectweb/asm/commons/cfg/graph/CallGraph.java delete mode 100644 src/org/objectweb/asm/commons/cfg/graph/Digraph.java delete mode 100644 src/org/objectweb/asm/commons/cfg/graph/FlowGraph.java delete mode 100644 src/org/objectweb/asm/commons/cfg/query/InsnQuery.java delete mode 100644 src/org/objectweb/asm/commons/cfg/query/MemberQuery.java delete mode 100644 src/org/objectweb/asm/commons/cfg/query/NumberQuery.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/NodeTree.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/NodeVisitor.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/Tree.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/node/AbstractNode.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/node/ArithmeticNode.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/node/ConstantNode.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/node/ConversionNode.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/node/FieldMemberNode.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/node/IincNode.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/node/JumpNode.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/node/MethodMemberNode.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/node/NumberNode.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/node/ReferenceNode.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/node/TargetNode.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/node/TypeNode.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/node/VariableNode.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/util/TreeBuilder.java delete mode 100644 src/org/objectweb/asm/commons/cfg/tree/util/TreeSize.java delete mode 100644 src/org/objectweb/asm/commons/util/Assembly.java delete mode 100644 src/org/objectweb/asm/commons/util/JarArchive.java delete mode 100644 src/org/objectweb/asm/signature/SignatureReader.java delete mode 100644 src/org/objectweb/asm/signature/SignatureVisitor.java delete mode 100644 src/org/objectweb/asm/signature/SignatureWriter.java delete mode 100644 src/org/objectweb/asm/tree/AbstractInsnNode.java delete mode 100644 src/org/objectweb/asm/tree/AnnotationNode.java delete mode 100644 src/org/objectweb/asm/tree/ClassNode.java delete mode 100644 src/org/objectweb/asm/tree/FieldInsnNode.java delete mode 100644 src/org/objectweb/asm/tree/FieldNode.java delete mode 100644 src/org/objectweb/asm/tree/FrameNode.java delete mode 100644 src/org/objectweb/asm/tree/IincInsnNode.java delete mode 100644 src/org/objectweb/asm/tree/InnerClassNode.java delete mode 100644 src/org/objectweb/asm/tree/InsnList.java delete mode 100644 src/org/objectweb/asm/tree/InsnNode.java delete mode 100644 src/org/objectweb/asm/tree/IntInsnNode.java delete mode 100644 src/org/objectweb/asm/tree/InvokeDynamicInsnNode.java delete mode 100644 src/org/objectweb/asm/tree/JumpInsnNode.java delete mode 100644 src/org/objectweb/asm/tree/LabelNode.java delete mode 100644 src/org/objectweb/asm/tree/LdcInsnNode.java delete mode 100644 src/org/objectweb/asm/tree/LineNumberNode.java delete mode 100644 src/org/objectweb/asm/tree/LocalVariableAnnotationNode.java delete mode 100644 src/org/objectweb/asm/tree/LocalVariableNode.java delete mode 100644 src/org/objectweb/asm/tree/LookupSwitchInsnNode.java delete mode 100644 src/org/objectweb/asm/tree/MethodInsnNode.java delete mode 100644 src/org/objectweb/asm/tree/MethodNode.java delete mode 100644 src/org/objectweb/asm/tree/MultiANewArrayInsnNode.java delete mode 100644 src/org/objectweb/asm/tree/ParameterNode.java delete mode 100644 src/org/objectweb/asm/tree/TableSwitchInsnNode.java delete mode 100644 src/org/objectweb/asm/tree/TryCatchBlockNode.java delete mode 100644 src/org/objectweb/asm/tree/TypeAnnotationNode.java delete mode 100644 src/org/objectweb/asm/tree/TypeInsnNode.java delete mode 100644 src/org/objectweb/asm/tree/VarInsnNode.java delete mode 100644 src/org/objectweb/asm/tree/analysis/Analyzer.java delete mode 100644 src/org/objectweb/asm/tree/analysis/AnalyzerException.java delete mode 100644 src/org/objectweb/asm/tree/analysis/BasicInterpreter.java delete mode 100644 src/org/objectweb/asm/tree/analysis/BasicValue.java delete mode 100644 src/org/objectweb/asm/tree/analysis/BasicVerifier.java delete mode 100644 src/org/objectweb/asm/tree/analysis/Frame.java delete mode 100644 src/org/objectweb/asm/tree/analysis/Interpreter.java delete mode 100644 src/org/objectweb/asm/tree/analysis/SimpleVerifier.java delete mode 100644 src/org/objectweb/asm/tree/analysis/SmallSet.java delete mode 100644 src/org/objectweb/asm/tree/analysis/SourceInterpreter.java delete mode 100644 src/org/objectweb/asm/tree/analysis/SourceValue.java delete mode 100644 src/org/objectweb/asm/tree/analysis/Subroutine.java delete mode 100644 src/org/objectweb/asm/tree/analysis/Value.java delete mode 100644 src/org/objectweb/asm/util/ASMifiable.java delete mode 100644 src/org/objectweb/asm/util/ASMifier.java delete mode 100644 src/org/objectweb/asm/util/CheckAnnotationAdapter.java delete mode 100644 src/org/objectweb/asm/util/CheckClassAdapter.java delete mode 100644 src/org/objectweb/asm/util/CheckFieldAdapter.java delete mode 100644 src/org/objectweb/asm/util/CheckMethodAdapter.java delete mode 100644 src/org/objectweb/asm/util/CheckSignatureAdapter.java delete mode 100644 src/org/objectweb/asm/util/Printer.java delete mode 100644 src/org/objectweb/asm/util/Textifiable.java delete mode 100644 src/org/objectweb/asm/util/Textifier.java delete mode 100644 src/org/objectweb/asm/util/TraceAnnotationVisitor.java delete mode 100644 src/org/objectweb/asm/util/TraceClassVisitor.java delete mode 100644 src/org/objectweb/asm/util/TraceFieldVisitor.java delete mode 100644 src/org/objectweb/asm/util/TraceMethodVisitor.java delete mode 100644 src/org/objectweb/asm/util/TraceSignatureVisitor.java delete mode 100644 src/org/objectweb/asm/xml/ASMContentHandler.java delete mode 100644 src/org/objectweb/asm/xml/Processor.java delete mode 100644 src/org/objectweb/asm/xml/SAXAdapter.java delete mode 100644 src/org/objectweb/asm/xml/SAXAnnotationAdapter.java delete mode 100644 src/org/objectweb/asm/xml/SAXClassAdapter.java delete mode 100644 src/org/objectweb/asm/xml/SAXCodeAdapter.java delete mode 100644 src/org/objectweb/asm/xml/SAXFieldAdapter.java rename src/{org/objectweb/asm/commons => the/bytecode/club/bytecodeviewer/obfuscators/mapping}/Remapper.java (98%) rename src/{org/objectweb/asm/commons => the/bytecode/club/bytecodeviewer/obfuscators/mapping}/RemappingAnnotationAdapter.java (92%) rename src/{org/objectweb/asm/commons => the/bytecode/club/bytecodeviewer/obfuscators/mapping}/RemappingClassAdapter.java (96%) rename src/{org/objectweb/asm/commons => the/bytecode/club/bytecodeviewer/obfuscators/mapping}/RemappingFieldAdapter.java (91%) rename src/{org/objectweb/asm/commons => the/bytecode/club/bytecodeviewer/obfuscators/mapping}/RemappingMethodAdapter.java (97%) rename src/{org/objectweb/asm/commons => the/bytecode/club/bytecodeviewer/obfuscators/mapping}/RemappingSignatureAdapter.java (94%) diff --git a/libs/asm-7.1.jar b/libs/asm-7.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..355eb08db9df7112a17def5a2a6efa6ae2b9c975 GIT binary patch literal 114762 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

^8{IM)4nS`l;S>|!;w$( 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 fZ>s)B{Ga;P`v% literal 0 HcmV?d00001 diff --git a/libs/asm-analysis-7.1.jar b/libs/asm-analysis-7.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..9b529c6c9ac1de51c77b147187bdaa9b72db677e GIT binary patch literal 33379 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 Z|I}=dkIBKOPbeQh93O0$2=2e0{eKdtf&Tyi literal 0 HcmV?d00001 diff --git a/libs/asm-commons-7.1.jar b/libs/asm-commons-7.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..31ffb987d5ee19917f7895a04b75cb1784a81567 GIT binary patch literal 70394 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 Hn+5nk(*H*t literal 0 HcmV?d00001 diff --git a/libs/asm-tree-7.1.jar b/libs/asm-tree-7.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..8e9ddbd9707820fa9c4df02057d6304a17042ad3 GIT binary patch literal 50303 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 M5I{isD(`>$KWG+JWdHyG literal 0 HcmV?d00001 diff --git a/src/org/objectweb/asm/AnnotationVisitor.java b/src/org/objectweb/asm/AnnotationVisitor.java deleted file mode 100644 index 867d9520..00000000 --- a/src/org/objectweb/asm/AnnotationVisitor.java +++ /dev/null @@ -1,158 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.asm; - -/** - * A visitor to visit a Java annotation. The methods of this class must be - * called in the following order: ( visit | visitEnum | - * visitAnnotation | visitArray )* visitEnd. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public abstract class AnnotationVisitor { - - /** - * The ASM API version implemented by this visitor. The value of this field - * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - protected final int api; - - /** - * The annotation visitor to which this visitor must delegate method calls. - * May be null. - */ - protected AnnotationVisitor av; - - /** - * Constructs a new {@link AnnotationVisitor}. - * - * @param api the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - public AnnotationVisitor(final int api) { - this(api, null); - } - - /** - * Constructs a new {@link AnnotationVisitor}. - * - * @param api the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @param av the annotation visitor to which this visitor must delegate - * method calls. May be null. - */ - public AnnotationVisitor(final int api, final AnnotationVisitor av) { - if (api != Opcodes.ASM4 && api != Opcodes.ASM5) { - throw new IllegalArgumentException(); - } - this.api = api; - this.av = av; - } - - /** - * 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} or OBJECT or ARRAY sort. 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). - */ - public void visit(String name, Object value) { - if (av != null) { - av.visit(name, 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. - */ - public void visitEnum(String name, String desc, String value) { - if (av != null) { - av.visitEnum(name, desc, 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. - */ - public AnnotationVisitor visitAnnotation(String name, String desc) { - if (av != null) { - return av.visitAnnotation(name, desc); - } - return null; - } - - /** - * 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. - */ - public AnnotationVisitor visitArray(String name) { - if (av != null) { - return av.visitArray(name); - } - return null; - } - - /** - * Visits the end of the annotation. - */ - public void visitEnd() { - if (av != null) { - av.visitEnd(); - } - } -} diff --git a/src/org/objectweb/asm/AnnotationWriter.java b/src/org/objectweb/asm/AnnotationWriter.java deleted file mode 100644 index d4d41702..00000000 --- a/src/org/objectweb/asm/AnnotationWriter.java +++ /dev/null @@ -1,359 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.asm; - -/** - * An {@link AnnotationVisitor} that generates annotations in bytecode form. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -final class AnnotationWriter extends 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) { - super(Opcodes.ASM5); - this.cw = cw; - this.named = named; - this.bv = bv; - this.parent = parent; - this.offset = offset; - } - - // ------------------------------------------------------------------------ - // Implementation of the AnnotationVisitor abstract class - // ------------------------------------------------------------------------ - - @Override - 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 (int i = 0; i < v.length; i++) { - bv.put12('B', cw.newInteger(v[i]).index); - } - } else if (value instanceof boolean[]) { - boolean[] v = (boolean[]) value; - bv.put12('[', v.length); - for (int i = 0; i < v.length; i++) { - bv.put12('Z', cw.newInteger(v[i] ? 1 : 0).index); - } - } else if (value instanceof short[]) { - short[] v = (short[]) value; - bv.put12('[', v.length); - for (int i = 0; i < v.length; i++) { - bv.put12('S', cw.newInteger(v[i]).index); - } - } else if (value instanceof char[]) { - char[] v = (char[]) value; - bv.put12('[', v.length); - for (int i = 0; i < v.length; i++) { - bv.put12('C', cw.newInteger(v[i]).index); - } - } else if (value instanceof int[]) { - int[] v = (int[]) value; - bv.put12('[', v.length); - for (int i = 0; i < v.length; i++) { - bv.put12('I', cw.newInteger(v[i]).index); - } - } else if (value instanceof long[]) { - long[] v = (long[]) value; - bv.put12('[', v.length); - for (int i = 0; i < v.length; i++) { - bv.put12('J', cw.newLong(v[i]).index); - } - } else if (value instanceof float[]) { - float[] v = (float[]) value; - bv.put12('[', v.length); - for (int i = 0; i < v.length; i++) { - bv.put12('F', cw.newFloat(v[i]).index); - } - } else if (value instanceof double[]) { - double[] v = (double[]) value; - bv.put12('[', v.length); - for (int i = 0; i < v.length; i++) { - bv.put12('D', cw.newDouble(v[i]).index); - } - } else { - Item i = cw.newConstItem(value); - bv.put12(".s.IFJDCS".charAt(i.type), i.index); - } - } - - @Override - 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)); - } - - @Override - 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); - } - - @Override - 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); - } - - @Override - 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; - } - } - } - - /** - * Puts the given type reference and type path into the given bytevector. - * LOCAL_VARIABLE and RESOURCE_VARIABLE target types are not supported. - * - * @param typeRef a reference to the annotated type. See {@link TypeReference}. - * @param typePath the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @param out where the type reference and type path must be put. - */ - static void putTarget(int typeRef, TypePath typePath, ByteVector out) { - switch (typeRef >>> 24) { - case 0x00: // CLASS_TYPE_PARAMETER - case 0x01: // METHOD_TYPE_PARAMETER - case 0x16: // METHOD_FORMAL_PARAMETER - out.putShort(typeRef >>> 16); - break; - case 0x13: // FIELD - case 0x14: // METHOD_RETURN - case 0x15: // METHOD_RECEIVER - out.putByte(typeRef >>> 24); - break; - case 0x47: // CAST - case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT - case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT - case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT - case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT - out.putInt(typeRef); - break; - // case 0x10: // CLASS_EXTENDS - // case 0x11: // CLASS_TYPE_PARAMETER_BOUND - // case 0x12: // METHOD_TYPE_PARAMETER_BOUND - // case 0x17: // THROWS - // case 0x42: // EXCEPTION_PARAMETER - // case 0x43: // INSTANCEOF - // case 0x44: // NEW - // case 0x45: // CONSTRUCTOR_REFERENCE - // case 0x46: // METHOD_REFERENCE - default: - out.put12(typeRef >>> 24, (typeRef & 0xFFFF00) >> 8); - break; - } - if (typePath == null) { - out.putByte(0); - } else { - int length = typePath.b[typePath.offset] * 2 + 1; - out.putByteArray(typePath.b, typePath.offset, length); - } - } -} diff --git a/src/org/objectweb/asm/Attribute.java b/src/org/objectweb/asm/Attribute.java deleted file mode 100644 index 9e33d9e3..00000000 --- a/src/org/objectweb/asm/Attribute.java +++ /dev/null @@ -1,232 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.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. - */ - public 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/src/org/objectweb/asm/ByteVector.java b/src/org/objectweb/asm/ByteVector.java deleted file mode 100644 index ac752bbf..00000000 --- a/src/org/objectweb/asm/ByteVector.java +++ /dev/null @@ -1,322 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.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 whose UTF8 encoded length must be less than 65536. - * @return this byte vector. - */ - public ByteVector putUTF8(final String s) { - int charLength = s.length(); - if (charLength > 65535) { - throw new IllegalArgumentException(); - } - int len = length; - if (len + 2 + charLength > data.length) { - enlarge(2 + charLength); - } - 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 { - length = len; - return encodeUTF8(s, i, 65535); - } - } - length = len; - return this; - } - - /** - * Puts an UTF8 string into this byte vector. The byte vector is - * automatically enlarged if necessary. The string length is encoded in two - * bytes before the encoded characters, if there is space for that (i.e. if - * this.length - i - 2 >= 0). - * - * @param s the String to encode. - * @param i the index of the first character to encode. The previous - * characters are supposed to have already been encoded, using - * only one byte per character. - * @param maxByteLength the maximum byte length of the encoded string, including the - * already encoded characters. - * @return this byte vector. - */ - ByteVector encodeUTF8(final String s, int i, int maxByteLength) { - int charLength = s.length(); - int byteLength = i; - char c; - 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; - } - } - if (byteLength > maxByteLength) { - throw new IllegalArgumentException(); - } - int start = length - i - 2; - if (start >= 0) { - data[start] = (byte) (byteLength >>> 8); - data[start + 1] = (byte) byteLength; - } - if (length + byteLength - i > data.length) { - enlarge(byteLength - i); - } - int len = length; - 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); - } - } - 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/src/org/objectweb/asm/ClassReader.java b/src/org/objectweb/asm/ClassReader.java deleted file mode 100644 index 30d36eb2..00000000 --- a/src/org/objectweb/asm/ClassReader.java +++ /dev/null @@ -1,2424 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.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; - // checks the class version - if (readShort(off + 6) > Opcodes.V1_8) { - throw new IllegalArgumentException(); - } - // 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: - case ClassWriter.INDY: - 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.HANDLE: - size = 4; - break; - // case ClassWriter.CLASS: - // case ClassWriter.STR: - // case ClassWriter.MTYPE - 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() { - return readClass(header + 4, 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.HANDLE: { - int fieldOrMethodRef = items[readUnsignedShort(index + 1)]; - nameType = items[readUnsignedShort(fieldOrMethodRef + 2)]; - item.set(ClassWriter.HANDLE_BASE + readByte(index), - readClass(fieldOrMethodRef, buf), - readUTF8(nameType, buf), readUTF8(nameType + 2, buf)); - break; - } - case ClassWriter.INDY: - if (classWriter.bootstrapMethods == null) { - copyBootstrapMethods(classWriter, items2, buf); - } - nameType = items[readUnsignedShort(index + 2)]; - item.set(readUTF8(nameType, buf), readUTF8(nameType + 2, buf), - readUnsignedShort(index)); - break; - // case ClassWriter.STR: - // case ClassWriter.CLASS: - // case ClassWriter.MTYPE - 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; - } - - /** - * Copies the bootstrap method data into the given {@link ClassWriter}. - * Should be called before the {@link #accept(ClassVisitor, int)} method. - * - * @param classWriter the {@link ClassWriter} to copy bootstrap methods into. - */ - private void copyBootstrapMethods(final ClassWriter classWriter, - final Item[] items, final char[] c) { - // finds the "BootstrapMethods" attribute - int u = getAttributes(); - boolean found = false; - for (int i = readUnsignedShort(u); i > 0; --i) { - String attrName = readUTF8(u + 2, c); - if ("BootstrapMethods".equals(attrName)) { - found = true; - break; - } - u += 6 + readInt(u + 4); - } - if (!found) { - return; - } - // copies the bootstrap methods in the class writer - int boostrapMethodCount = readUnsignedShort(u + 8); - for (int j = 0, v = u + 10; j < boostrapMethodCount; j++) { - int position = v - u - 10; - int hashCode = readConst(readUnsignedShort(v), c).hashCode(); - for (int k = readUnsignedShort(v + 2); k > 0; --k) { - hashCode ^= readConst(readUnsignedShort(v + 4), c).hashCode(); - v += 2; - } - v += 4; - Item item = new Item(j); - item.set(position, hashCode & 0x7FFFFFFF); - int index = item.hashCode % items.length; - item.next = items[index]; - items[index] = item; - } - int attrSize = readInt(u + 4); - ByteVector bootstrapMethods = new ByteVector(attrSize + 62); - bootstrapMethods.putByteArray(b, u + 10, attrSize - 2); - classWriter.bootstrapMethodsCount = boostrapMethodCount; - classWriter.bootstrapMethods = bootstrapMethods; - } - - /** - * 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, false)); - } - - /** - * Constructs a new {@link ClassReader} object. - * - * @param name the binary qualified name of the class to be read. - * @throws IOException if an exception occurs during reading. - */ - public ClassReader(final String name) throws IOException { - this(readClass( - ClassLoader.getSystemResourceAsStream(name.replace('.', '/') - + ".class"), true)); - } - - /** - * Reads the bytecode of a class. - * - * @param is an input stream from which to read the class. - * @param close true to close the input stream after reading. - * @return the bytecode read from the given input stream. - * @throws IOException if a problem occurs during reading. - */ - private static byte[] readClass(final InputStream is, boolean close) - throws IOException { - if (is == null) { - throw new IOException("Class not found"); - } - try { - 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) { - int last = is.read(); - if (last < 0) { - return b; - } - byte[] c = new byte[b.length + 1000]; - System.arraycopy(b, 0, c, 0, len); - c[len++] = (byte) last; - b = c; - } - } - } finally { - if (close) { - is.close(); - } - } - } - - // ------------------------------------------------------------------------ - // 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) { - int u = header; // current offset in the class file - char[] c = new char[maxStringLength]; // buffer used to read strings - - Context context = new Context(); - context.attrs = attrs; - context.flags = flags; - context.buffer = c; - - // reads the class declaration - int access = readUnsignedShort(u); - String name = readClass(u + 2, c); - String superClass = readClass(u + 4, c); - String[] interfaces = new String[readUnsignedShort(u + 6)]; - u += 8; - for (int i = 0; i < interfaces.length; ++i) { - interfaces[i] = readClass(u, c); - u += 2; - } - - // reads the class attributes - String signature = null; - String sourceFile = null; - String sourceDebug = null; - String enclosingOwner = null; - String enclosingName = null; - String enclosingDesc = null; - int anns = 0; - int ianns = 0; - int tanns = 0; - int itanns = 0; - int innerClasses = 0; - Attribute attributes = null; - - u = getAttributes(); - for (int i = readUnsignedShort(u); i > 0; --i) { - String attrName = readUTF8(u + 2, c); - // tests are sorted in decreasing frequency order - // (based on frequencies observed on typical classes) - if ("SourceFile".equals(attrName)) { - sourceFile = readUTF8(u + 8, c); - } else if ("InnerClasses".equals(attrName)) { - innerClasses = u + 8; - } else if ("EnclosingMethod".equals(attrName)) { - enclosingOwner = readClass(u + 8, c); - int item = readUnsignedShort(u + 10); - if (item != 0) { - enclosingName = readUTF8(items[item], c); - enclosingDesc = readUTF8(items[item] + 2, c); - } - } else if (SIGNATURES && "Signature".equals(attrName)) { - signature = readUTF8(u + 8, c); - } else if (ANNOTATIONS - && "RuntimeVisibleAnnotations".equals(attrName)) { - anns = u + 8; - } else if (ANNOTATIONS - && "RuntimeVisibleTypeAnnotations".equals(attrName)) { - tanns = u + 8; - } else if ("Deprecated".equals(attrName)) { - access |= Opcodes.ACC_DEPRECATED; - } else if ("Synthetic".equals(attrName)) { - access |= Opcodes.ACC_SYNTHETIC - | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE; - } else if ("SourceDebugExtension".equals(attrName)) { - int len = readInt(u + 4); - sourceDebug = readUTF(u + 8, len, new char[len]); - } else if (ANNOTATIONS - && "RuntimeInvisibleAnnotations".equals(attrName)) { - ianns = u + 8; - } else if (ANNOTATIONS - && "RuntimeInvisibleTypeAnnotations".equals(attrName)) { - itanns = u + 8; - } else if ("BootstrapMethods".equals(attrName)) { - int[] bootstrapMethods = new int[readUnsignedShort(u + 8)]; - for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) { - bootstrapMethods[j] = v; - v += 2 + readUnsignedShort(v + 2) << 1; - } - context.bootstrapMethods = bootstrapMethods; - } else { - Attribute attr = readAttribute(attrs, attrName, u + 8, - readInt(u + 4), c, -1, null); - if (attr != null) { - attr.next = attributes; - attributes = attr; - } - } - u += 6 + readInt(u + 4); - } - - // visits the class declaration - classVisitor.visit(readInt(items[1] - 7), access, name, signature, - superClass, interfaces); - - // visits the source and debug info - if ((flags & SKIP_DEBUG) == 0 - && (sourceFile != null || sourceDebug != null)) { - classVisitor.visitSource(sourceFile, sourceDebug); - } - - // visits the outer class - if (enclosingOwner != null) { - classVisitor.visitOuterClass(enclosingOwner, enclosingName, - enclosingDesc); - } - - // visits the class annotations and type annotations - if (ANNOTATIONS && anns != 0) { - for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) { - v = readAnnotationValues(v + 2, c, true, - classVisitor.visitAnnotation(readUTF8(v, c), true)); - } - } - if (ANNOTATIONS && ianns != 0) { - for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) { - v = readAnnotationValues(v + 2, c, true, - classVisitor.visitAnnotation(readUTF8(v, c), false)); - } - } - if (ANNOTATIONS && tanns != 0) { - for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) { - v = readAnnotationTarget(context, v); - v = readAnnotationValues(v + 2, c, true, - classVisitor.visitTypeAnnotation(context.typeRef, - context.typePath, readUTF8(v, c), true)); - } - } - if (ANNOTATIONS && itanns != 0) { - for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) { - v = readAnnotationTarget(context, v); - v = readAnnotationValues(v + 2, c, true, - classVisitor.visitTypeAnnotation(context.typeRef, - context.typePath, readUTF8(v, c), false)); - } - } - - // visits the attributes - while (attributes != null) { - Attribute attr = attributes.next; - attributes.next = null; - classVisitor.visitAttribute(attributes); - attributes = attr; - } - - // visits the inner classes - if (innerClasses != 0) { - int v = innerClasses + 2; - for (int i = readUnsignedShort(innerClasses); i > 0; --i) { - classVisitor.visitInnerClass(readClass(v, c), - readClass(v + 2, c), readUTF8(v + 4, c), - readUnsignedShort(v + 6)); - v += 8; - } - } - - // visits the fields and methods - u = header + 10 + 2 * interfaces.length; - for (int i = readUnsignedShort(u - 2); i > 0; --i) { - u = readField(classVisitor, context, u); - } - u += 2; - for (int i = readUnsignedShort(u - 2); i > 0; --i) { - u = readMethod(classVisitor, context, u); - } - - // visits the end of the class - classVisitor.visitEnd(); - } - - /** - * Reads a field and makes the given visitor visit it. - * - * @param classVisitor the visitor that must visit the field. - * @param context information about the class being parsed. - * @param u the start offset of the field in the class file. - * @return the offset of the first byte following the field in the class. - */ - private int readField(final ClassVisitor classVisitor, - final Context context, int u) { - // reads the field declaration - char[] c = context.buffer; - int access = readUnsignedShort(u); - String name = readUTF8(u + 2, c); - String desc = readUTF8(u + 4, c); - u += 6; - - // reads the field attributes - String signature = null; - int anns = 0; - int ianns = 0; - int tanns = 0; - int itanns = 0; - Object value = null; - Attribute attributes = null; - - for (int i = readUnsignedShort(u); i > 0; --i) { - String attrName = readUTF8(u + 2, c); - // tests are sorted in decreasing frequency order - // (based on frequencies observed on typical classes) - if ("ConstantValue".equals(attrName)) { - int item = readUnsignedShort(u + 8); - value = item == 0 ? null : readConst(item, c); - } else if (SIGNATURES && "Signature".equals(attrName)) { - signature = readUTF8(u + 8, c); - } else if ("Deprecated".equals(attrName)) { - access |= Opcodes.ACC_DEPRECATED; - } else if ("Synthetic".equals(attrName)) { - access |= Opcodes.ACC_SYNTHETIC - | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE; - } else if (ANNOTATIONS - && "RuntimeVisibleAnnotations".equals(attrName)) { - anns = u + 8; - } else if (ANNOTATIONS - && "RuntimeVisibleTypeAnnotations".equals(attrName)) { - tanns = u + 8; - } else if (ANNOTATIONS - && "RuntimeInvisibleAnnotations".equals(attrName)) { - ianns = u + 8; - } else if (ANNOTATIONS - && "RuntimeInvisibleTypeAnnotations".equals(attrName)) { - itanns = u + 8; - } else { - Attribute attr = readAttribute(context.attrs, attrName, u + 8, - readInt(u + 4), c, -1, null); - if (attr != null) { - attr.next = attributes; - attributes = attr; - } - } - u += 6 + readInt(u + 4); - } - u += 2; - - // visits the field declaration - FieldVisitor fv = classVisitor.visitField(access, name, desc, - signature, value); - if (fv == null) { - return u; - } - - // visits the field annotations and type annotations - if (ANNOTATIONS && anns != 0) { - for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) { - v = readAnnotationValues(v + 2, c, true, - fv.visitAnnotation(readUTF8(v, c), true)); - } - } - if (ANNOTATIONS && ianns != 0) { - for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) { - v = readAnnotationValues(v + 2, c, true, - fv.visitAnnotation(readUTF8(v, c), false)); - } - } - if (ANNOTATIONS && tanns != 0) { - for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) { - v = readAnnotationTarget(context, v); - v = readAnnotationValues(v + 2, c, true, - fv.visitTypeAnnotation(context.typeRef, - context.typePath, readUTF8(v, c), true)); - } - } - if (ANNOTATIONS && itanns != 0) { - for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) { - v = readAnnotationTarget(context, v); - v = readAnnotationValues(v + 2, c, true, - fv.visitTypeAnnotation(context.typeRef, - context.typePath, readUTF8(v, c), false)); - } - } - - // visits the field attributes - while (attributes != null) { - Attribute attr = attributes.next; - attributes.next = null; - fv.visitAttribute(attributes); - attributes = attr; - } - - // visits the end of the field - fv.visitEnd(); - - return u; - } - - /** - * Reads a method and makes the given visitor visit it. - * - * @param classVisitor the visitor that must visit the method. - * @param context information about the class being parsed. - * @param u the start offset of the method in the class file. - * @return the offset of the first byte following the method in the class. - */ - private int readMethod(final ClassVisitor classVisitor, - final Context context, int u) { - // reads the method declaration - char[] c = context.buffer; - context.access = readUnsignedShort(u); - context.name = readUTF8(u + 2, c); - context.desc = readUTF8(u + 4, c); - u += 6; - - // reads the method attributes - int code = 0; - int exception = 0; - String[] exceptions = null; - String signature = null; - int methodParameters = 0; - int anns = 0; - int ianns = 0; - int tanns = 0; - int itanns = 0; - int dann = 0; - int mpanns = 0; - int impanns = 0; - int firstAttribute = u; - Attribute attributes = null; - - for (int i = readUnsignedShort(u); i > 0; --i) { - String attrName = readUTF8(u + 2, c); - // tests are sorted in decreasing frequency order - // (based on frequencies observed on typical classes) - if ("Code".equals(attrName)) { - if ((context.flags & SKIP_CODE) == 0) { - code = u + 8; - } - } else if ("Exceptions".equals(attrName)) { - exceptions = new String[readUnsignedShort(u + 8)]; - exception = u + 10; - for (int j = 0; j < exceptions.length; ++j) { - exceptions[j] = readClass(exception, c); - exception += 2; - } - } else if (SIGNATURES && "Signature".equals(attrName)) { - signature = readUTF8(u + 8, c); - } else if ("Deprecated".equals(attrName)) { - context.access |= Opcodes.ACC_DEPRECATED; - } else if (ANNOTATIONS - && "RuntimeVisibleAnnotations".equals(attrName)) { - anns = u + 8; - } else if (ANNOTATIONS - && "RuntimeVisibleTypeAnnotations".equals(attrName)) { - tanns = u + 8; - } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) { - dann = u + 8; - } else if ("Synthetic".equals(attrName)) { - context.access |= Opcodes.ACC_SYNTHETIC - | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE; - } else if (ANNOTATIONS - && "RuntimeInvisibleAnnotations".equals(attrName)) { - ianns = u + 8; - } else if (ANNOTATIONS - && "RuntimeInvisibleTypeAnnotations".equals(attrName)) { - itanns = u + 8; - } else if (ANNOTATIONS - && "RuntimeVisibleParameterAnnotations".equals(attrName)) { - mpanns = u + 8; - } else if (ANNOTATIONS - && "RuntimeInvisibleParameterAnnotations".equals(attrName)) { - impanns = u + 8; - } else if ("MethodParameters".equals(attrName)) { - methodParameters = u + 8; - } else { - Attribute attr = readAttribute(context.attrs, attrName, u + 8, - readInt(u + 4), c, -1, null); - if (attr != null) { - attr.next = attributes; - attributes = attr; - } - } - u += 6 + readInt(u + 4); - } - u += 2; - - // visits the method declaration - MethodVisitor mv = classVisitor.visitMethod(context.access, - context.name, context.desc, signature, exceptions); - if (mv == null) { - return u; - } - - /* - * 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 && signature == mw.signature) { - boolean sameExceptions = false; - if (exceptions == null) { - sameExceptions = mw.exceptionCount == 0; - } else if (exceptions.length == mw.exceptionCount) { - sameExceptions = true; - for (int j = exceptions.length - 1; j >= 0; --j) { - exception -= 2; - if (mw.exceptions[j] != readUnsignedShort(exception)) { - 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 = firstAttribute; - mw.classReaderLength = u - firstAttribute; - return u; - } - } - } - - // visit the method parameters - if (methodParameters != 0) { - for (int i = b[methodParameters] & 0xFF, v = methodParameters + 1; i > 0; --i, v = v + 4) { - mv.visitParameter(readUTF8(v, c), readUnsignedShort(v + 2)); - } - } - - // visits the method annotations - if (ANNOTATIONS && dann != 0) { - AnnotationVisitor dv = mv.visitAnnotationDefault(); - readAnnotationValue(dann, c, null, dv); - if (dv != null) { - dv.visitEnd(); - } - } - if (ANNOTATIONS && anns != 0) { - for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) { - v = readAnnotationValues(v + 2, c, true, - mv.visitAnnotation(readUTF8(v, c), true)); - } - } - if (ANNOTATIONS && ianns != 0) { - for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) { - v = readAnnotationValues(v + 2, c, true, - mv.visitAnnotation(readUTF8(v, c), false)); - } - } - if (ANNOTATIONS && tanns != 0) { - for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) { - v = readAnnotationTarget(context, v); - v = readAnnotationValues(v + 2, c, true, - mv.visitTypeAnnotation(context.typeRef, - context.typePath, readUTF8(v, c), true)); - } - } - if (ANNOTATIONS && itanns != 0) { - for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) { - v = readAnnotationTarget(context, v); - v = readAnnotationValues(v + 2, c, true, - mv.visitTypeAnnotation(context.typeRef, - context.typePath, readUTF8(v, c), false)); - } - } - if (ANNOTATIONS && mpanns != 0) { - readParameterAnnotations(mv, context, mpanns, true); - } - if (ANNOTATIONS && impanns != 0) { - readParameterAnnotations(mv, context, impanns, false); - } - - // visits the method attributes - while (attributes != null) { - Attribute attr = attributes.next; - attributes.next = null; - mv.visitAttribute(attributes); - attributes = attr; - } - - // visits the method code - if (code != 0) { - mv.visitCode(); - readCode(mv, context, code); - } - - // visits the end of the method - mv.visitEnd(); - - return u; - } - - /** - * Reads the bytecode of a method and makes the given visitor visit it. - * - * @param mv the visitor that must visit the method's code. - * @param context information about the class being parsed. - * @param u the start offset of the code attribute in the class file. - */ - private void readCode(final MethodVisitor mv, final Context context, int u) { - // reads the header - byte[] b = this.b; - char[] c = context.buffer; - int maxStack = readUnsignedShort(u); - int maxLocals = readUnsignedShort(u + 2); - int codeLength = readInt(u + 4); - u += 8; - - // reads the bytecode to find the labels - int codeStart = u; - int codeEnd = u + codeLength; - Label[] labels = context.labels = new Label[codeLength + 2]; - readLabel(codeLength + 1, labels); - while (u < codeEnd) { - int offset = u - codeStart; - int opcode = b[u] & 0xFF; - switch (ClassWriter.TYPE[opcode]) { - case ClassWriter.NOARG_INSN: - case ClassWriter.IMPLVAR_INSN: - u += 1; - break; - case ClassWriter.LABEL_INSN: - readLabel(offset + readShort(u + 1), labels); - u += 3; - break; - case ClassWriter.LABELW_INSN: - readLabel(offset + readInt(u + 1), labels); - u += 5; - break; - case ClassWriter.WIDE_INSN: - opcode = b[u + 1] & 0xFF; - if (opcode == Opcodes.IINC) { - u += 6; - } else { - u += 4; - } - break; - case ClassWriter.TABL_INSN: - // skips 0 to 3 padding bytes - u = u + 4 - (offset & 3); - // reads instruction - readLabel(offset + readInt(u), labels); - for (int i = readInt(u + 8) - readInt(u + 4) + 1; i > 0; --i) { - readLabel(offset + readInt(u + 12), labels); - u += 4; - } - u += 12; - break; - case ClassWriter.LOOK_INSN: - // skips 0 to 3 padding bytes - u = u + 4 - (offset & 3); - // reads instruction - readLabel(offset + readInt(u), labels); - for (int i = readInt(u + 4); i > 0; --i) { - readLabel(offset + readInt(u + 12), labels); - u += 8; - } - u += 8; - 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: - case ClassWriter.INDYMETH_INSN: - u += 5; - break; - // case MANA_INSN: - default: - u += 4; - break; - } - } - - // reads the try catch entries to find the labels, and also visits them - for (int i = readUnsignedShort(u); i > 0; --i) { - Label start = readLabel(readUnsignedShort(u + 2), labels); - Label end = readLabel(readUnsignedShort(u + 4), labels); - Label handler = readLabel(readUnsignedShort(u + 6), labels); - String type = readUTF8(items[readUnsignedShort(u + 8)], c); - mv.visitTryCatchBlock(start, end, handler, type); - u += 8; - } - u += 2; - - // reads the code attributes - int[] tanns = null; // start index of each visible type annotation - int[] itanns = null; // start index of each invisible type annotation - int tann = 0; // current index in tanns array - int itann = 0; // current index in itanns array - int ntoff = -1; // next visible type annotation code offset - int nitoff = -1; // next invisible type annotation code offset - int varTable = 0; - int varTypeTable = 0; - boolean zip = true; - boolean unzip = (context.flags & EXPAND_FRAMES) != 0; - int stackMap = 0; - int stackMapSize = 0; - int frameCount = 0; - Context frame = null; - Attribute attributes = null; - - for (int i = readUnsignedShort(u); i > 0; --i) { - String attrName = readUTF8(u + 2, c); - if ("LocalVariableTable".equals(attrName)) { - if ((context.flags & SKIP_DEBUG) == 0) { - varTable = u + 8; - for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) { - int label = readUnsignedShort(v + 10); - if (labels[label] == null) { - readLabel(label, labels).status |= Label.DEBUG; - } - label += readUnsignedShort(v + 12); - if (labels[label] == null) { - readLabel(label, labels).status |= Label.DEBUG; - } - v += 10; - } - } - } else if ("LocalVariableTypeTable".equals(attrName)) { - varTypeTable = u + 8; - } else if ("LineNumberTable".equals(attrName)) { - if ((context.flags & SKIP_DEBUG) == 0) { - for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) { - int label = readUnsignedShort(v + 10); - if (labels[label] == null) { - readLabel(label, labels).status |= Label.DEBUG; - } - Label l = labels[label]; - while (l.line > 0) { - if (l.next == null) { - l.next = new Label(); - } - l = l.next; - } - l.line = readUnsignedShort(v + 12); - v += 4; - } - } - } else if (ANNOTATIONS - && "RuntimeVisibleTypeAnnotations".equals(attrName)) { - tanns = readTypeAnnotations(mv, context, u + 8, true); - ntoff = tanns.length == 0 || readByte(tanns[0]) < 0x43 ? -1 - : readUnsignedShort(tanns[0] + 1); - } else if (ANNOTATIONS - && "RuntimeInvisibleTypeAnnotations".equals(attrName)) { - itanns = readTypeAnnotations(mv, context, u + 8, false); - nitoff = itanns.length == 0 || readByte(itanns[0]) < 0x43 ? -1 - : readUnsignedShort(itanns[0] + 1); - } else if (FRAMES && "StackMapTable".equals(attrName)) { - if ((context.flags & SKIP_FRAMES) == 0) { - stackMap = u + 10; - stackMapSize = readInt(u + 4); - frameCount = readUnsignedShort(u + 8); - } - /* - * 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. - */ - /* - * This is not true for UNINITIALIZED type offsets. We solve - * this by parsing the stack map table without a full decoding - * (see below). - */ - } else if (FRAMES && "StackMap".equals(attrName)) { - if ((context.flags & SKIP_FRAMES) == 0) { - zip = false; - stackMap = u + 10; - stackMapSize = readInt(u + 4); - frameCount = readUnsignedShort(u + 8); - } - /* - * 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 (int j = 0; j < context.attrs.length; ++j) { - if (context.attrs[j].type.equals(attrName)) { - Attribute attr = context.attrs[j].read(this, u + 8, - readInt(u + 4), c, codeStart - 8, labels); - if (attr != null) { - attr.next = attributes; - attributes = attr; - } - } - } - } - u += 6 + readInt(u + 4); - } - u += 2; - - // generates the first (implicit) stack map frame - if (FRAMES && stackMap != 0) { - /* - * 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 - */ - frame = context; - frame.offset = -1; - frame.mode = 0; - frame.localCount = 0; - frame.localDiff = 0; - frame.stackCount = 0; - frame.local = new Object[maxLocals]; - frame.stack = new Object[maxStack]; - if (unzip) { - getImplicitFrame(context); - } - /* - * Finds labels for UNINITIALIZED frame types. Instead of decoding - * each element of the stack map table, we look for 3 consecutive - * bytes that "look like" an UNINITIALIZED type (tag 8, offset - * within code bounds, NEW instruction at this offset). We may find - * false positives (i.e. not real UNINITIALIZED types), but this - * should be rare, and the only consequence will be the creation of - * an unneeded label. This is better than creating a label for each - * NEW instruction, and faster than fully decoding the whole stack - * map table. - */ - for (int i = stackMap; i < stackMap + stackMapSize - 2; ++i) { - if (b[i] == 8) { // UNINITIALIZED FRAME TYPE - int v = readUnsignedShort(i + 1); - if (v >= 0 && v < codeLength) { - if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) { - readLabel(v, labels); - } - } - } - } - } - - // visits the instructions - u = codeStart; - while (u < codeEnd) { - int offset = u - codeStart; - - // visits the label and line number for this offset, if any - Label l = labels[offset]; - if (l != null) { - Label next = l.next; - l.next = null; - mv.visitLabel(l); - if ((context.flags & SKIP_DEBUG) == 0 && l.line > 0) { - mv.visitLineNumber(l.line, l); - while (next != null) { - mv.visitLineNumber(next.line, l); - next = next.next; - } - } - } - - // visits the frame for this offset, if any - while (FRAMES && frame != null - && (frame.offset == offset || frame.offset == -1)) { - // if there is a frame for this offset, makes the visitor visit - // it, and reads the next frame if there is one. - if (frame.offset != -1) { - if (!zip || unzip) { - mv.visitFrame(Opcodes.F_NEW, frame.localCount, - frame.local, frame.stackCount, frame.stack); - } else { - mv.visitFrame(frame.mode, frame.localDiff, frame.local, - frame.stackCount, frame.stack); - } - } - if (frameCount > 0) { - stackMap = readFrame(stackMap, zip, unzip, frame); - --frameCount; - } else { - frame = null; - } - } - - // visits the instruction at this offset - int opcode = b[u] & 0xFF; - switch (ClassWriter.TYPE[opcode]) { - case ClassWriter.NOARG_INSN: - mv.visitInsn(opcode); - u += 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); - } - u += 1; - break; - case ClassWriter.LABEL_INSN: - mv.visitJumpInsn(opcode, labels[offset + readShort(u + 1)]); - u += 3; - break; - case ClassWriter.LABELW_INSN: - mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]); - u += 5; - break; - case ClassWriter.WIDE_INSN: - opcode = b[u + 1] & 0xFF; - if (opcode == Opcodes.IINC) { - mv.visitIincInsn(readUnsignedShort(u + 2), readShort(u + 4)); - u += 6; - } else { - mv.visitVarInsn(opcode, readUnsignedShort(u + 2)); - u += 4; - } - break; - case ClassWriter.TABL_INSN: { - // skips 0 to 3 padding bytes - u = u + 4 - (offset & 3); - // reads instruction - int label = offset + readInt(u); - int min = readInt(u + 4); - int max = readInt(u + 8); - Label[] table = new Label[max - min + 1]; - u += 12; - for (int i = 0; i < table.length; ++i) { - table[i] = labels[offset + readInt(u)]; - u += 4; - } - mv.visitTableSwitchInsn(min, max, labels[label], table); - break; - } - case ClassWriter.LOOK_INSN: { - // skips 0 to 3 padding bytes - u = u + 4 - (offset & 3); - // reads instruction - int label = offset + readInt(u); - int len = readInt(u + 4); - int[] keys = new int[len]; - Label[] values = new Label[len]; - u += 8; - for (int i = 0; i < len; ++i) { - keys[i] = readInt(u); - values[i] = labels[offset + readInt(u + 4)]; - u += 8; - } - mv.visitLookupSwitchInsn(labels[label], keys, values); - break; - } - case ClassWriter.VAR_INSN: - mv.visitVarInsn(opcode, b[u + 1] & 0xFF); - u += 2; - break; - case ClassWriter.SBYTE_INSN: - mv.visitIntInsn(opcode, b[u + 1]); - u += 2; - break; - case ClassWriter.SHORT_INSN: - mv.visitIntInsn(opcode, readShort(u + 1)); - u += 3; - break; - case ClassWriter.LDC_INSN: - mv.visitLdcInsn(readConst(b[u + 1] & 0xFF, c)); - u += 2; - break; - case ClassWriter.LDCW_INSN: - mv.visitLdcInsn(readConst(readUnsignedShort(u + 1), c)); - u += 3; - break; - case ClassWriter.FIELDORMETH_INSN: - case ClassWriter.ITFMETH_INSN: { - int cpIndex = items[readUnsignedShort(u + 1)]; - boolean itf = b[cpIndex - 1] == ClassWriter.IMETH; - 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, itf); - } - if (opcode == Opcodes.INVOKEINTERFACE) { - u += 5; - } else { - u += 3; - } - break; - } - case ClassWriter.INDYMETH_INSN: { - int cpIndex = items[readUnsignedShort(u + 1)]; - int bsmIndex = context.bootstrapMethods[readUnsignedShort(cpIndex)]; - Handle bsm = (Handle) readConst(readUnsignedShort(bsmIndex), c); - int bsmArgCount = readUnsignedShort(bsmIndex + 2); - Object[] bsmArgs = new Object[bsmArgCount]; - bsmIndex += 4; - for (int i = 0; i < bsmArgCount; i++) { - bsmArgs[i] = readConst(readUnsignedShort(bsmIndex), c); - bsmIndex += 2; - } - cpIndex = items[readUnsignedShort(cpIndex + 2)]; - String iname = readUTF8(cpIndex, c); - String idesc = readUTF8(cpIndex + 2, c); - mv.visitInvokeDynamicInsn(iname, idesc, bsm, bsmArgs); - u += 5; - break; - } - case ClassWriter.TYPE_INSN: - mv.visitTypeInsn(opcode, readClass(u + 1, c)); - u += 3; - break; - case ClassWriter.IINC_INSN: - mv.visitIincInsn(b[u + 1] & 0xFF, b[u + 2]); - u += 3; - break; - // case MANA_INSN: - default: - mv.visitMultiANewArrayInsn(readClass(u + 1, c), b[u + 3] & 0xFF); - u += 4; - break; - } - - // visit the instruction annotations, if any - while (tanns != null && tann < tanns.length && ntoff <= offset) { - if (ntoff == offset) { - int v = readAnnotationTarget(context, tanns[tann]); - readAnnotationValues(v + 2, c, true, - mv.visitInsnAnnotation(context.typeRef, - context.typePath, readUTF8(v, c), true)); - } - ntoff = ++tann >= tanns.length || readByte(tanns[tann]) < 0x43 ? -1 - : readUnsignedShort(tanns[tann] + 1); - } - while (itanns != null && itann < itanns.length && nitoff <= offset) { - if (nitoff == offset) { - int v = readAnnotationTarget(context, itanns[itann]); - readAnnotationValues(v + 2, c, true, - mv.visitInsnAnnotation(context.typeRef, - context.typePath, readUTF8(v, c), false)); - } - nitoff = ++itann >= itanns.length - || readByte(itanns[itann]) < 0x43 ? -1 - : readUnsignedShort(itanns[itann] + 1); - } - } - if (labels[codeLength] != null) { - mv.visitLabel(labels[codeLength]); - } - - // visits the local variable tables - if ((context.flags & SKIP_DEBUG) == 0 && varTable != 0) { - int[] typeTable = null; - if (varTypeTable != 0) { - u = varTypeTable + 2; - typeTable = new int[readUnsignedShort(varTypeTable) * 3]; - for (int i = typeTable.length; i > 0; ) { - typeTable[--i] = u + 6; // signature - typeTable[--i] = readUnsignedShort(u + 8); // index - typeTable[--i] = readUnsignedShort(u); // start - u += 10; - } - } - u = varTable + 2; - for (int i = readUnsignedShort(varTable); i > 0; --i) { - int start = readUnsignedShort(u); - int length = readUnsignedShort(u + 2); - int index = readUnsignedShort(u + 8); - String vsignature = null; - if (typeTable != null) { - for (int j = 0; j < typeTable.length; j += 3) { - if (typeTable[j] == start && typeTable[j + 1] == index) { - vsignature = readUTF8(typeTable[j + 2], c); - break; - } - } - } - mv.visitLocalVariable(readUTF8(u + 4, c), readUTF8(u + 6, c), - vsignature, labels[start], labels[start + length], - index); - u += 10; - } - } - - // visits the local variables type annotations - if (tanns != null) { - for (int i = 0; i < tanns.length; ++i) { - if ((readByte(tanns[i]) >> 1) == (0x40 >> 1)) { - int v = readAnnotationTarget(context, tanns[i]); - v = readAnnotationValues(v + 2, c, true, - mv.visitLocalVariableAnnotation(context.typeRef, - context.typePath, context.start, - context.end, context.index, readUTF8(v, c), - true)); - } - } - } - if (itanns != null) { - for (int i = 0; i < itanns.length; ++i) { - if ((readByte(itanns[i]) >> 1) == (0x40 >> 1)) { - int v = readAnnotationTarget(context, itanns[i]); - v = readAnnotationValues(v + 2, c, true, - mv.visitLocalVariableAnnotation(context.typeRef, - context.typePath, context.start, - context.end, context.index, readUTF8(v, c), - false)); - } - } - } - - // visits the code attributes - while (attributes != null) { - Attribute attr = attributes.next; - attributes.next = null; - mv.visitAttribute(attributes); - attributes = attr; - } - - // visits the max stack and max locals values - mv.visitMaxs(maxStack, maxLocals); - } - - /** - * Parses a type annotation table to find the labels, and to visit the try - * catch block annotations. - * - * @param u the start offset of a type annotation table. - * @param mv the method visitor to be used to visit the try catch block - * annotations. - * @param context information about the class being parsed. - * @param visible if the type annotation table to parse contains runtime visible - * annotations. - * @return the start offset of each type annotation in the parsed table. - */ - private int[] readTypeAnnotations(final MethodVisitor mv, - final Context context, int u, boolean visible) { - char[] c = context.buffer; - int[] offsets = new int[readUnsignedShort(u)]; - u += 2; - for (int i = 0; i < offsets.length; ++i) { - offsets[i] = u; - int target = readInt(u); - switch (target >>> 24) { - case 0x00: // CLASS_TYPE_PARAMETER - case 0x01: // METHOD_TYPE_PARAMETER - case 0x16: // METHOD_FORMAL_PARAMETER - u += 2; - break; - case 0x13: // FIELD - case 0x14: // METHOD_RETURN - case 0x15: // METHOD_RECEIVER - u += 1; - break; - case 0x40: // LOCAL_VARIABLE - case 0x41: // RESOURCE_VARIABLE - for (int j = readUnsignedShort(u + 1); j > 0; --j) { - int start = readUnsignedShort(u + 3); - int length = readUnsignedShort(u + 5); - readLabel(start, context.labels); - readLabel(start + length, context.labels); - u += 6; - } - u += 3; - break; - case 0x47: // CAST - case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT - case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT - case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT - case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT - u += 4; - break; - // case 0x10: // CLASS_EXTENDS - // case 0x11: // CLASS_TYPE_PARAMETER_BOUND - // case 0x12: // METHOD_TYPE_PARAMETER_BOUND - // case 0x17: // THROWS - // case 0x42: // EXCEPTION_PARAMETER - // case 0x43: // INSTANCEOF - // case 0x44: // NEW - // case 0x45: // CONSTRUCTOR_REFERENCE - // case 0x46: // METHOD_REFERENCE - default: - u += 3; - break; - } - int pathLength = readByte(u); - if ((target >>> 24) == 0x42) { - TypePath path = pathLength == 0 ? null : new TypePath(b, u); - u += 1 + 2 * pathLength; - u = readAnnotationValues(u + 2, c, true, - mv.visitTryCatchAnnotation(target, path, - readUTF8(u, c), visible)); - } else { - u = readAnnotationValues(u + 3 + 2 * pathLength, c, true, null); - } - } - return offsets; - } - - /** - * Parses the header of a type annotation to extract its target_type and - * target_path (the result is stored in the given context), and returns the - * start offset of the rest of the type_annotation structure (i.e. the - * offset to the type_index field, which is followed by - * num_element_value_pairs and then the name,value pairs). - * - * @param context information about the class being parsed. This is where the - * extracted target_type and target_path must be stored. - * @param u the start offset of a type_annotation structure. - * @return the start offset of the rest of the type_annotation structure. - */ - private int readAnnotationTarget(final Context context, int u) { - int target = readInt(u); - switch (target >>> 24) { - case 0x00: // CLASS_TYPE_PARAMETER - case 0x01: // METHOD_TYPE_PARAMETER - case 0x16: // METHOD_FORMAL_PARAMETER - target &= 0xFFFF0000; - u += 2; - break; - case 0x13: // FIELD - case 0x14: // METHOD_RETURN - case 0x15: // METHOD_RECEIVER - target &= 0xFF000000; - u += 1; - break; - case 0x40: // LOCAL_VARIABLE - case 0x41: { // RESOURCE_VARIABLE - target &= 0xFF000000; - int n = readUnsignedShort(u + 1); - context.start = new Label[n]; - context.end = new Label[n]; - context.index = new int[n]; - u += 3; - for (int i = 0; i < n; ++i) { - int start = readUnsignedShort(u); - int length = readUnsignedShort(u + 2); - context.start[i] = readLabel(start, context.labels); - context.end[i] = readLabel(start + length, context.labels); - context.index[i] = readUnsignedShort(u + 4); - u += 6; - } - break; - } - case 0x47: // CAST - case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT - case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT - case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT - case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT - target &= 0xFF0000FF; - u += 4; - break; - // case 0x10: // CLASS_EXTENDS - // case 0x11: // CLASS_TYPE_PARAMETER_BOUND - // case 0x12: // METHOD_TYPE_PARAMETER_BOUND - // case 0x17: // THROWS - // case 0x42: // EXCEPTION_PARAMETER - // case 0x43: // INSTANCEOF - // case 0x44: // NEW - // case 0x45: // CONSTRUCTOR_REFERENCE - // case 0x46: // METHOD_REFERENCE - default: - target &= (target >>> 24) < 0x43 ? 0xFFFFFF00 : 0xFF000000; - u += 3; - break; - } - int pathLength = readByte(u); - context.typeRef = target; - context.typePath = pathLength == 0 ? null : new TypePath(b, u); - return u + 1 + 2 * pathLength; - } - - /** - * Reads parameter annotations and makes the given visitor visit them. - * - * @param mv the visitor that must visit the annotations. - * @param context information about the class being parsed. - * @param v start offset in {@link #b b} of the annotations to be read. - * @param visible true if the annotations to be read are visible at - * runtime. - */ - private void readParameterAnnotations(final MethodVisitor mv, - final Context context, int v, final boolean visible) { - 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(context.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(); - } - } - char[] c = context.buffer; - for (; i < n + synthetics; ++i) { - int j = readUnsignedShort(v); - v += 2; - for (; j > 0; --j) { - av = mv.visitParameterAnnotation(i, readUTF8(v, c), visible); - v = readAnnotationValues(v + 2, c, 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, (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, (short) readInt(items[readUnsignedShort(v)])); - v += 2; - break; - case 'C': // pointer to CONSTANT_Char - av.visit(name, (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; - } - - /** - * Computes the implicit frame of the method currently being parsed (as - * defined in the given {@link Context}) and stores it in the given context. - * - * @param frame information about the class being parsed. - */ - private void getImplicitFrame(final Context frame) { - String desc = frame.desc; - Object[] locals = frame.local; - int local = 0; - if ((frame.access & Opcodes.ACC_STATIC) == 0) { - if ("".equals(frame.name)) { - locals[local++] = Opcodes.UNINITIALIZED_THIS; - } else { - locals[local++] = readClass(header + 2, frame.buffer); - } - } - int i = 1; - loop: - while (true) { - int j = i; - switch (desc.charAt(i++)) { - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - locals[local++] = Opcodes.INTEGER; - break; - case 'F': - locals[local++] = Opcodes.FLOAT; - break; - case 'J': - locals[local++] = Opcodes.LONG; - break; - case 'D': - locals[local++] = Opcodes.DOUBLE; - break; - case '[': - while (desc.charAt(i) == '[') { - ++i; - } - if (desc.charAt(i) == 'L') { - ++i; - while (desc.charAt(i) != ';') { - ++i; - } - } - locals[local++] = desc.substring(j, ++i); - break; - case 'L': - while (desc.charAt(i) != ';') { - ++i; - } - locals[local++] = desc.substring(j + 1, i++); - break; - default: - break loop; - } - } - frame.localCount = local; - } - - /** - * Reads a stack map frame and stores the result in the given - * {@link Context} object. - * - * @param stackMap the start offset of a stack map frame in the class file. - * @param zip if the stack map frame at stackMap is compressed or not. - * @param unzip if the stack map frame must be uncompressed. - * @param frame where the parsed stack map frame must be stored. - * @return the offset of the first byte following the parsed frame. - */ - private int readFrame(int stackMap, boolean zip, boolean unzip, - Context frame) { - char[] c = frame.buffer; - Label[] labels = frame.labels; - int tag; - int delta; - if (zip) { - tag = b[stackMap++] & 0xFF; - } else { - tag = MethodWriter.FULL_FRAME; - frame.offset = -1; - } - frame.localDiff = 0; - if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME) { - delta = tag; - frame.mode = Opcodes.F_SAME; - frame.stackCount = 0; - } else if (tag < MethodWriter.RESERVED) { - delta = tag - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME; - stackMap = readFrameType(frame.stack, 0, stackMap, c, labels); - frame.mode = Opcodes.F_SAME1; - frame.stackCount = 1; - } else { - delta = readUnsignedShort(stackMap); - stackMap += 2; - if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { - stackMap = readFrameType(frame.stack, 0, stackMap, c, labels); - frame.mode = Opcodes.F_SAME1; - frame.stackCount = 1; - } else if (tag >= MethodWriter.CHOP_FRAME - && tag < MethodWriter.SAME_FRAME_EXTENDED) { - frame.mode = Opcodes.F_CHOP; - frame.localDiff = MethodWriter.SAME_FRAME_EXTENDED - tag; - frame.localCount -= frame.localDiff; - frame.stackCount = 0; - } else if (tag == MethodWriter.SAME_FRAME_EXTENDED) { - frame.mode = Opcodes.F_SAME; - frame.stackCount = 0; - } else if (tag < MethodWriter.FULL_FRAME) { - int local = unzip ? frame.localCount : 0; - for (int i = tag - MethodWriter.SAME_FRAME_EXTENDED; i > 0; i--) { - stackMap = readFrameType(frame.local, local++, stackMap, c, - labels); - } - frame.mode = Opcodes.F_APPEND; - frame.localDiff = tag - MethodWriter.SAME_FRAME_EXTENDED; - frame.localCount += frame.localDiff; - frame.stackCount = 0; - } else { // if (tag == FULL_FRAME) { - frame.mode = Opcodes.F_FULL; - int n = readUnsignedShort(stackMap); - stackMap += 2; - frame.localDiff = n; - frame.localCount = n; - for (int local = 0; n > 0; n--) { - stackMap = readFrameType(frame.local, local++, stackMap, c, - labels); - } - n = readUnsignedShort(stackMap); - stackMap += 2; - frame.stackCount = n; - for (int stack = 0; n > 0; n--) { - stackMap = readFrameType(frame.stack, stack++, stackMap, c, - labels); - } - } - } - frame.offset += delta + 1; - readLabel(frame.offset, labels); - return stackMap; - } - - /** - * Reads a stack map frame type and stores it at the given index in the - * given array. - * - * @param frame the array where the parsed type must be stored. - * @param index the index in 'frame' where the parsed type must be stored. - * @param v the start offset of the stack map frame type to read. - * @param buf a buffer to read strings. - * @param labels the labels of the method currently being parsed, indexed by - * their offset. If the parsed type is an Uninitialized type, a - * new label for the corresponding NEW instruction is stored in - * this array if it does not already exist. - * @return the offset of the first byte after the parsed type. - */ - 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]; - } - - /** - * Returns the start index of the attribute_info structure of this class. - * - * @return the start index of the attribute_info structure of this class. - */ - private int getAttributes() { - // skips the header - int u = header + 8 + readUnsignedShort(header + 6) * 2; - // skips fields and methods - for (int i = readUnsignedShort(u); i > 0; --i) { - for (int j = readUnsignedShort(u + 8); j > 0; --j) { - u += 6 + readInt(u + 12); - } - u += 8; - } - u += 2; - for (int i = readUnsignedShort(u); i > 0; --i) { - for (int j = readUnsignedShort(u + 8); j > 0; --j) { - u += 6 + readInt(u + 12); - } - u += 8; - } - // the attribute_info structure starts just after the methods - return u + 2; - } - - /** - * 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 number of constant pool items in {@link #b b}. - * - * @return the number of constant pool items in {@link #b b}. - */ - public int getItemCount() { - return items.length; - } - - /** - * 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]; - } - - /** - * Returns the maximum length of the strings contained in the constant pool - * of the class. - * - * @return the maximum length of the strings contained in the constant pool - * of the class. - */ - public int getMaxStringLength() { - return maxStringLength; - } - - /** - * 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); - if (index == 0 || item == 0) { - return null; - } - 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; - int st = 0; - char cc = 0; - while (index < endIndex) { - c = b[index++]; - switch (st) { - case 0: - c = c & 0xFF; - if (c < 0x80) { // 0xxxxxxx - buf[strLen++] = (char) c; - } else if (c < 0xE0 && c > 0xBF) { // 110x xxxx 10xx xxxx - cc = (char) (c & 0x1F); - st = 1; - } else { // 1110 xxxx 10xx xxxx 10xx xxxx - cc = (char) (c & 0x0F); - st = 2; - } - break; - - case 1: // byte 2 of 2-byte char or byte 3 of 3-byte char - buf[strLen++] = (char) ((cc << 6) | (c & 0x3F)); - st = 0; - break; - - case 2: // byte 2 of 3-byte char - cc = (char) ((cc << 6) | (c & 0x3F)); - st = 1; - 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}, {@link Type} or {@link Handle} 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 readInt(index); - case ClassWriter.FLOAT: - return Float.intBitsToFloat(readInt(index)); - case ClassWriter.LONG: - return readLong(index); - case ClassWriter.DOUBLE: - return Double.longBitsToDouble(readLong(index)); - case ClassWriter.CLASS: - return Type.getObjectType(readUTF8(index, buf)); - case ClassWriter.STR: - return readUTF8(index, buf); - case ClassWriter.MTYPE: - return Type.getMethodType(readUTF8(index, buf)); - default: // case ClassWriter.HANDLE_BASE + [1..9]: - int tag = readByte(index); - int[] items = this.items; - int cpIndex = items[readUnsignedShort(index + 1)]; - String owner = readClass(cpIndex, buf); - cpIndex = items[readUnsignedShort(cpIndex + 2)]; - String name = readUTF8(cpIndex, buf); - String desc = readUTF8(cpIndex + 2, buf); - return new Handle(tag, owner, name, desc); - } - } -} diff --git a/src/org/objectweb/asm/ClassVisitor.java b/src/org/objectweb/asm/ClassVisitor.java deleted file mode 100644 index de3f6f60..00000000 --- a/src/org/objectweb/asm/ClassVisitor.java +++ /dev/null @@ -1,285 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.asm; - -/** - * A visitor to visit a Java class. The methods of this class must be called in - * the following order: visit [ visitSource ] [ - * visitOuterClass ] ( visitAnnotation | - * visitTypeAnnotation | visitAttribute )* ( - * visitInnerClass | visitField | visitMethod )* - * visitEnd. - * - * @author Eric Bruneton - */ -public abstract class ClassVisitor { - - /** - * The ASM API version implemented by this visitor. The value of this field - * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - protected final int api; - - /** - * The class visitor to which this visitor must delegate method calls. May - * be null. - */ - protected ClassVisitor cv; - - /** - * Constructs a new {@link ClassVisitor}. - * - * @param api the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - public ClassVisitor(final int api) { - this(api, null); - } - - /** - * Constructs a new {@link ClassVisitor}. - * - * @param api the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @param cv the class visitor to which this visitor must delegate method - * calls. May be null. - */ - public ClassVisitor(final int api, final ClassVisitor cv) { - if (api != Opcodes.ASM4 && api != Opcodes.ASM5) { - throw new IllegalArgumentException(); - } - this.api = api; - this.cv = cv; - } - - /** - * 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. - */ - public void visit(int version, int access, String name, String signature, - String superName, String[] interfaces) { - if (cv != null) { - cv.visit(version, access, name, signature, superName, 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. - */ - public void visitSource(String source, String debug) { - if (cv != null) { - cv.visitSource(source, 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. - */ - public void visitOuterClass(String owner, String name, String desc) { - if (cv != null) { - cv.visitOuterClass(owner, name, 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. - */ - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - if (cv != null) { - return cv.visitAnnotation(desc, visible); - } - return null; - } - - /** - * Visits an annotation on a type in the class signature. - * - * @param typeRef a reference to the annotated type. The sort of this type - * reference must be {@link TypeReference#CLASS_TYPE_PARAMETER - * CLASS_TYPE_PARAMETER}, - * {@link TypeReference#CLASS_TYPE_PARAMETER_BOUND - * CLASS_TYPE_PARAMETER_BOUND} or - * {@link TypeReference#CLASS_EXTENDS CLASS_EXTENDS}. See - * {@link TypeReference}. - * @param typePath the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @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. - */ - public AnnotationVisitor visitTypeAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - if (api < Opcodes.ASM5) { - throw new RuntimeException(); - } - if (cv != null) { - return cv.visitTypeAnnotation(typeRef, typePath, desc, visible); - } - return null; - } - - /** - * Visits a non standard attribute of the class. - * - * @param attr an attribute. - */ - public void visitAttribute(Attribute attr) { - if (cv != null) { - cv.visitAttribute(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. - */ - public void visitInnerClass(String name, String outerName, - String innerName, int access) { - if (cv != null) { - cv.visitInnerClass(name, outerName, innerName, 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. - */ - public FieldVisitor visitField(int access, String name, String desc, - String signature, Object value) { - if (cv != null) { - return cv.visitField(access, name, desc, signature, value); - } - return null; - } - - /** - * 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. - */ - public MethodVisitor visitMethod(int access, String name, String desc, - String signature, String[] exceptions) { - if (cv != null) { - return cv.visitMethod(access, name, desc, signature, exceptions); - } - return null; - } - - /** - * 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. - */ - public void visitEnd() { - if (cv != null) { - cv.visitEnd(); - } - } -} diff --git a/src/org/objectweb/asm/ClassWriter.java b/src/org/objectweb/asm/ClassWriter.java deleted file mode 100644 index 68d4df93..00000000 --- a/src/org/objectweb/asm/ClassWriter.java +++ /dev/null @@ -1,1710 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.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 extends 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; - - /** - * Pseudo access flag to distinguish between the synthetic attribute and the - * synthetic access flag. - */ - static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000; - - /** - * Factor to convert from ACC_SYNTHETIC_ATTRIBUTE to Opcode.ACC_SYNTHETIC. - */ - static final int TO_ACC_SYNTHETIC = ACC_SYNTHETIC_ATTRIBUTE - / Opcodes.ACC_SYNTHETIC; - - /** - * 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/INVOKEDYNAMIC instruction. - */ - static final int ITFMETH_INSN = 7; - - /** - * The type of the INVOKEDYNAMIC instruction. - */ - static final int INDYMETH_INSN = 8; - - /** - * The type of instructions with a 2 bytes bytecode offset label. - */ - static final int LABEL_INSN = 9; - - /** - * The type of instructions with a 4 bytes bytecode offset label. - */ - static final int LABELW_INSN = 10; - - /** - * The type of the LDC instruction. - */ - static final int LDC_INSN = 11; - - /** - * The type of the LDC_W and LDC2_W instructions. - */ - static final int LDCW_INSN = 12; - - /** - * The type of the IINC instruction. - */ - static final int IINC_INSN = 13; - - /** - * The type of the TABLESWITCH instruction. - */ - static final int TABL_INSN = 14; - - /** - * The type of the LOOKUPSWITCH instruction. - */ - static final int LOOK_INSN = 15; - - /** - * The type of the MULTIANEWARRAY instruction. - */ - static final int MANA_INSN = 16; - - /** - * The type of the WIDE instruction. - */ - static final int WIDE_INSN = 17; - - /** - * 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; - - /** - * The type of CONSTANT_MethodType constant pool items. - */ - static final int MTYPE = 16; - - /** - * The type of CONSTANT_MethodHandle constant pool items. - */ - static final int HANDLE = 15; - - /** - * The type of CONSTANT_InvokeDynamic constant pool items. - */ - static final int INDY = 18; - - /** - * The base value for all CONSTANT_MethodHandle constant pool items. - * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9 - * different items. - */ - static final int HANDLE_BASE = 20; - - /** - * 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 = 30; - - /** - * 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 = 31; - - /** - * 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 = 32; - - /** - * The type of BootstrapMethods items. These items are stored in a special - * class attribute named BootstrapMethods and not in the constant pool. - */ - static final int BSM = 33; - - /** - * 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 reusable key used to look for items in the {@link #items} hash table. - */ - final Item key4; - - /** - * 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 runtime visible type annotations of this class. - */ - private AnnotationWriter tanns; - - /** - * The runtime invisible type annotations of this class. - */ - private AnnotationWriter itanns; - - /** - * 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 number of entries in the BootstrapMethods attribute. - */ - int bootstrapMethodsCount; - - /** - * The BootstrapMethods attribute. - */ - ByteVector bootstrapMethods; - - /** - * 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#fv} 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#fv} 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#mv} 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#mv} 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 boolean computeMaxs; - - /** - * true if the stack map frames must be recomputed from scratch. - */ - private 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 = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD" - + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA" - + "AAAAGGGGGGGHIFBFAAFFAARQJJKKJJJJJJJJJJJJJJJJJJ"; - 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; - // b[Constants.INVOKEDYNAMIC] = INDYMETH_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) { - super(Opcodes.ASM5); - index = 1; - pool = new ByteVector(); - items = new Item[256]; - threshold = (int) (0.75d * items.length); - key = new Item(); - key2 = new Item(); - key3 = new Item(); - key4 = 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 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. These option flags do not affect methods - * that are copied as is in the new class. This means that the - * maximum stack size nor the stack frames will be computed for - * these methods. 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 abstract class - // ------------------------------------------------------------------------ - - @Override - public final 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]); - } - } - } - - @Override - public final void visitSource(final String file, final String debug) { - if (file != null) { - sourceFile = newUTF8(file); - } - if (debug != null) { - sourceDebug = new ByteVector().encodeUTF8(debug, 0, - Integer.MAX_VALUE); - } - } - - @Override - public final void visitOuterClass(final String owner, final String name, - final String desc) { - enclosingMethodOwner = newClass(owner); - if (name != null && desc != null) { - enclosingMethod = newNameType(name, desc); - } - } - - @Override - public final 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; - } - - @Override - public final AnnotationVisitor visitTypeAnnotation(int typeRef, - TypePath typePath, final String desc, final boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write target_type and target_info - AnnotationWriter.putTarget(typeRef, typePath, bv); - // write type, and reserve space for values count - bv.putShort(newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, - bv.length - 2); - if (visible) { - aw.next = tanns; - tanns = aw; - } else { - aw.next = itanns; - itanns = aw; - } - return aw; - } - - @Override - public final void visitAttribute(final Attribute attr) { - attr.next = attrs; - attrs = attr; - } - - @Override - public final void visitInnerClass(final String name, - final String outerName, final String innerName, final int access) { - if (innerClasses == null) { - innerClasses = new ByteVector(); - } - // Sec. 4.7.6 of the JVMS states "Every CONSTANT_Class_info entry in the - // constant_pool table which represents a class or interface C that is - // not a package member must have exactly one corresponding entry in the - // classes array". To avoid duplicates we keep track in the intVal field - // of the Item of each CONSTANT_Class_info entry C whether an inner - // class entry has already been added for C (this field is unused for - // class entries, and changing its value does not change the hashcode - // and equality tests). If so we store the index of this inner class - // entry (plus one) in intVal. This hack allows duplicate detection in - // O(1) time. - Item nameItem = newClassItem(name); - if (nameItem.intVal == 0) { - ++innerClassesCount; - innerClasses.putShort(nameItem.index); - innerClasses.putShort(outerName == null ? 0 : newClass(outerName)); - innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName)); - innerClasses.putShort(access); - nameItem.intVal = innerClassesCount; - } else { - // Compare the inner classes entry nameItem.intVal - 1 with the - // arguments of this method and throw an exception if there is a - // difference? - } - } - - @Override - public final 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); - } - - @Override - public final 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); - } - - @Override - public final 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() { - if (index > 0xFFFF) { - throw new RuntimeException("Class file too large!"); - } - // 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 = (FieldWriter) fb.fv; - } - int nbMethods = 0; - MethodWriter mb = firstMethod; - while (mb != null) { - ++nbMethods; - size += mb.getSize(); - mb = (MethodWriter) mb.mv; - } - int attributeCount = 0; - if (bootstrapMethods != null) { - // we put it as first attribute in order to improve a bit - // ClassReader.copyBootstrapMethods - ++attributeCount; - size += 8 + bootstrapMethods.length; - newUTF8("BootstrapMethods"); - } - 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 + 6; - 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) { - if ((version & 0xFFFF) < Opcodes.V1_5 - || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) { - ++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 (ClassReader.ANNOTATIONS && tanns != null) { - ++attributeCount; - size += 8 + tanns.getSize(); - newUTF8("RuntimeVisibleTypeAnnotations"); - } - if (ClassReader.ANNOTATIONS && itanns != null) { - ++attributeCount; - size += 8 + itanns.getSize(); - newUTF8("RuntimeInvisibleTypeAnnotations"); - } - 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); - int mask = Opcodes.ACC_DEPRECATED | ACC_SYNTHETIC_ATTRIBUTE - | ((access & ACC_SYNTHETIC_ATTRIBUTE) / TO_ACC_SYNTHETIC); - out.putShort(access & ~mask).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 = (FieldWriter) fb.fv; - } - out.putShort(nbMethods); - mb = firstMethod; - while (mb != null) { - mb.put(out); - mb = (MethodWriter) mb.mv; - } - out.putShort(attributeCount); - if (bootstrapMethods != null) { - out.putShort(newUTF8("BootstrapMethods")); - out.putInt(bootstrapMethods.length + 2).putShort( - bootstrapMethodsCount); - out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length); - } - 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; - out.putShort(newUTF8("SourceDebugExtension")).putInt(len); - out.putByteArray(sourceDebug.data, 0, 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) { - if ((version & 0xFFFF) < Opcodes.V1_5 - || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) { - 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 (ClassReader.ANNOTATIONS && tanns != null) { - out.putShort(newUTF8("RuntimeVisibleTypeAnnotations")); - tanns.put(out); - } - if (ClassReader.ANNOTATIONS && itanns != null) { - out.putShort(newUTF8("RuntimeInvisibleTypeAnnotations")); - itanns.put(out); - } - if (attrs != null) { - attrs.put(this, null, 0, -1, -1, out); - } - if (invalidFrames) { - anns = null; - ianns = null; - attrs = null; - innerClassesCount = 0; - innerClasses = null; - bootstrapMethodsCount = 0; - bootstrapMethods = null; - firstField = null; - lastField = null; - firstMethod = null; - lastMethod = null; - computeMaxs = false; - computeFrames = true; - invalidFrames = false; - new ClassReader(out.data).accept(this, ClassReader.SKIP_FRAMES); - return 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; - int s = t.getSort(); - if (s == Type.OBJECT) { - return newClassItem(t.getInternalName()); - } else if (s == Type.METHOD) { - return newMethodTypeItem(t.getDescriptor()); - } else { // s == primitive type or array - return newClassItem(t.getDescriptor()); - } - } else if (cst instanceof Handle) { - Handle h = (Handle) cst; - return newHandleItem(h.tag, h.owner, h.name, h.desc); - } 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 method type 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 methodDesc method descriptor of the method type. - * @return a new or already existing method type reference item. - */ - Item newMethodTypeItem(final String methodDesc) { - key2.set(MTYPE, methodDesc, null, null); - Item result = get(key2); - if (result == null) { - pool.put12(MTYPE, newUTF8(methodDesc)); - result = new Item(index++, key2); - put(result); - } - return result; - } - - /** - * Adds a method type 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 methodDesc method descriptor of the method type. - * @return the index of a new or already existing method type reference - * item. - */ - public int newMethodType(final String methodDesc) { - return newMethodTypeItem(methodDesc).index; - } - - /** - * Adds a handle 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 tag the kind of this handle. Must be {@link Opcodes#H_GETFIELD}, - * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, - * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, - * {@link Opcodes#H_INVOKESTATIC}, - * {@link Opcodes#H_INVOKESPECIAL}, - * {@link Opcodes#H_NEWINVOKESPECIAL} or - * {@link Opcodes#H_INVOKEINTERFACE}. - * @param owner the internal name of the field or method owner class. - * @param name the name of the field or method. - * @param desc the descriptor of the field or method. - * @return a new or an already existing method type reference item. - */ - Item newHandleItem(final int tag, final String owner, final String name, - final String desc) { - key4.set(HANDLE_BASE + tag, owner, name, desc); - Item result = get(key4); - if (result == null) { - if (tag <= Opcodes.H_PUTSTATIC) { - put112(HANDLE, tag, newField(owner, name, desc)); - } else { - put112(HANDLE, - tag, - newMethod(owner, name, desc, - tag == Opcodes.H_INVOKEINTERFACE)); - } - result = new Item(index++, key4); - put(result); - } - return result; - } - - /** - * Adds a handle 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 tag the kind of this handle. Must be {@link Opcodes#H_GETFIELD}, - * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, - * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, - * {@link Opcodes#H_INVOKESTATIC}, - * {@link Opcodes#H_INVOKESPECIAL}, - * {@link Opcodes#H_NEWINVOKESPECIAL} or - * {@link Opcodes#H_INVOKEINTERFACE}. - * @param owner the internal name of the field or method owner class. - * @param name the name of the field or method. - * @param desc the descriptor of the field or method. - * @return the index of a new or already existing method type reference - * item. - */ - public int newHandle(final int tag, final String owner, final String name, - final String desc) { - return newHandleItem(tag, owner, name, desc).index; - } - - /** - * Adds an invokedynamic 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 name name of the invoked method. - * @param desc descriptor of the invoke method. - * @param bsm the bootstrap method. - * @param bsmArgs the bootstrap method constant arguments. - * @return a new or an already existing invokedynamic type reference item. - */ - Item newInvokeDynamicItem(final String name, final String desc, - final Handle bsm, final Object... bsmArgs) { - // cache for performance - ByteVector bootstrapMethods = this.bootstrapMethods; - if (bootstrapMethods == null) { - bootstrapMethods = this.bootstrapMethods = new ByteVector(); - } - - int position = bootstrapMethods.length; // record current position - - int hashCode = bsm.hashCode(); - bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name, - bsm.desc)); - - int argsLength = bsmArgs.length; - bootstrapMethods.putShort(argsLength); - - for (int i = 0; i < argsLength; i++) { - Object bsmArg = bsmArgs[i]; - hashCode ^= bsmArg.hashCode(); - bootstrapMethods.putShort(newConst(bsmArg)); - } - - byte[] data = bootstrapMethods.data; - int length = (1 + 1 + argsLength) << 1; // (bsm + argCount + arguments) - hashCode &= 0x7FFFFFFF; - Item result = items[hashCode % items.length]; - loop: - while (result != null) { - if (result.type != BSM || result.hashCode != hashCode) { - result = result.next; - continue; - } - - // because the data encode the size of the argument - // we don't need to test if these size are equals - int resultPosition = result.intVal; - for (int p = 0; p < length; p++) { - if (data[position + p] != data[resultPosition + p]) { - result = result.next; - continue loop; - } - } - break; - } - - int bootstrapMethodIndex; - if (result != null) { - bootstrapMethodIndex = result.index; - bootstrapMethods.length = position; // revert to old position - } else { - bootstrapMethodIndex = bootstrapMethodsCount++; - result = new Item(bootstrapMethodIndex); - result.set(position, hashCode); - put(result); - } - - // now, create the InvokeDynamic constant - key3.set(name, desc, bootstrapMethodIndex); - result = get(key3); - if (result == null) { - put122(INDY, bootstrapMethodIndex, newNameType(name, desc)); - result = new Item(index++, key3); - put(result); - } - return result; - } - - /** - * Adds an invokedynamic 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 name name of the invoked method. - * @param desc descriptor of the invoke method. - * @param bsm the bootstrap method. - * @param bsmArgs the bootstrap method constant arguments. - * @return the index of a new or already existing invokedynamic reference - * item. - */ - public int newInvokeDynamic(final String name, final String desc, - final Handle bsm, final Object... bsmArgs) { - return newInvokeDynamicItem(name, desc, bsm, bsmArgs).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); - index += 2; - put(result); - } - 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); - index += 2; - put(result); - } - 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) { - return newNameTypeItem(name, desc).index; - } - - /** - * 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. - * - * @param name a name. - * @param desc a type descriptor. - * @return a new or already existing name and type item. - */ - Item newNameTypeItem(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; - } - - /** - * 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; - ClassLoader classLoader = getClass().getClassLoader(); - try { - c = Class.forName(type1.replace('/', '.'), false, classLoader); - d = Class.forName(type2.replace('/', '.'), false, classLoader); - } 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 && (i.type != key.type || !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 + typeCount > 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); - } - - /** - * Puts two bytes and one short into the constant pool. - * - * @param b1 a byte. - * @param b2 another byte. - * @param s a short. - */ - private void put112(final int b1, final int b2, final int s) { - pool.put11(b1, b2).putShort(s); - } -} diff --git a/src/org/objectweb/asm/Context.java b/src/org/objectweb/asm/Context.java deleted file mode 100644 index 5e61d428..00000000 --- a/src/org/objectweb/asm/Context.java +++ /dev/null @@ -1,145 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.asm; - -/** - * Information about a class being parsed in a {@link ClassReader}. - * - * @author Eric Bruneton - */ -class Context { - - /** - * Prototypes of the attributes that must be parsed for this class. - */ - Attribute[] attrs; - - /** - * The {@link ClassReader} option flags for the parsing of this class. - */ - int flags; - - /** - * The buffer used to read strings. - */ - char[] buffer; - - /** - * The start index of each bootstrap method. - */ - int[] bootstrapMethods; - - /** - * The access flags of the method currently being parsed. - */ - int access; - - /** - * The name of the method currently being parsed. - */ - String name; - - /** - * The descriptor of the method currently being parsed. - */ - String desc; - - /** - * The label objects, indexed by bytecode offset, of the method currently - * being parsed (only bytecode offsets for which a label is needed have a - * non null associated Label object). - */ - Label[] labels; - - /** - * The target of the type annotation currently being parsed. - */ - int typeRef; - - /** - * The path of the type annotation currently being parsed. - */ - TypePath typePath; - - /** - * The offset of the latest stack map frame that has been parsed. - */ - int offset; - - /** - * The labels corresponding to the start of the local variable ranges in the - * local variable type annotation currently being parsed. - */ - Label[] start; - - /** - * The labels corresponding to the end of the local variable ranges in the - * local variable type annotation currently being parsed. - */ - Label[] end; - - /** - * The local variable indices for each local variable range in the local - * variable type annotation currently being parsed. - */ - int[] index; - - /** - * The encoding of the latest stack map frame that has been parsed. - */ - int mode; - - /** - * The number of locals in the latest stack map frame that has been parsed. - */ - int localCount; - - /** - * The number locals in the latest stack map frame that has been parsed, - * minus the number of locals in the previous frame. - */ - int localDiff; - - /** - * The local values of the latest stack map frame that has been parsed. - */ - Object[] local; - - /** - * The stack size of the latest stack map frame that has been parsed. - */ - int stackCount; - - /** - * The stack values of the latest stack map frame that has been parsed. - */ - Object[] stack; -} \ No newline at end of file diff --git a/src/org/objectweb/asm/Edge.java b/src/org/objectweb/asm/Edge.java deleted file mode 100644 index 2d341fe6..00000000 --- a/src/org/objectweb/asm/Edge.java +++ /dev/null @@ -1,75 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.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/src/org/objectweb/asm/FieldVisitor.java b/src/org/objectweb/asm/FieldVisitor.java deleted file mode 100644 index 59dba8f8..00000000 --- a/src/org/objectweb/asm/FieldVisitor.java +++ /dev/null @@ -1,140 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.asm; - -/** - * A visitor to visit a Java field. The methods of this class must be called in - * the following order: ( visitAnnotation | - * visitTypeAnnotation | visitAttribute )* visitEnd. - * - * @author Eric Bruneton - */ -public abstract class FieldVisitor { - - /** - * The ASM API version implemented by this visitor. The value of this field - * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - protected final int api; - - /** - * The field visitor to which this visitor must delegate method calls. May - * be null. - */ - protected FieldVisitor fv; - - /** - * Constructs a new {@link FieldVisitor}. - * - * @param api the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - public FieldVisitor(final int api) { - this(api, null); - } - - /** - * Constructs a new {@link FieldVisitor}. - * - * @param api the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @param fv the field visitor to which this visitor must delegate method - * calls. May be null. - */ - public FieldVisitor(final int api, final FieldVisitor fv) { - if (api != Opcodes.ASM4 && api != Opcodes.ASM5) { - throw new IllegalArgumentException(); - } - this.api = api; - this.fv = fv; - } - - /** - * 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. - */ - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - if (fv != null) { - return fv.visitAnnotation(desc, visible); - } - return null; - } - - /** - * Visits an annotation on the type of the field. - * - * @param typeRef a reference to the annotated type. The sort of this type - * reference must be {@link TypeReference#FIELD FIELD}. See - * {@link TypeReference}. - * @param typePath the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @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. - */ - public AnnotationVisitor visitTypeAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - if (api < Opcodes.ASM5) { - throw new RuntimeException(); - } - if (fv != null) { - return fv.visitTypeAnnotation(typeRef, typePath, desc, visible); - } - return null; - } - - /** - * Visits a non standard attribute of the field. - * - * @param attr an attribute. - */ - public void visitAttribute(Attribute attr) { - if (fv != null) { - fv.visitAttribute(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. - */ - public void visitEnd() { - if (fv != null) { - fv.visitEnd(); - } - } -} diff --git a/src/org/objectweb/asm/FieldWriter.java b/src/org/objectweb/asm/FieldWriter.java deleted file mode 100644 index b3f40b0c..00000000 --- a/src/org/objectweb/asm/FieldWriter.java +++ /dev/null @@ -1,322 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.asm; - -/** - * An {@link FieldVisitor} that generates Java fields in bytecode form. - * - * @author Eric Bruneton - */ -final class FieldWriter extends FieldVisitor { - - /** - * 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 runtime visible type annotations of this field. May be null. - */ - private AnnotationWriter tanns; - - /** - * The runtime invisible type annotations of this field. May be - * null. - */ - private AnnotationWriter itanns; - - /** - * 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) { - super(Opcodes.ASM5); - if (cw.firstField == null) { - cw.firstField = this; - } else { - cw.lastField.fv = 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 abstract class - // ------------------------------------------------------------------------ - - @Override - 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; - } - - @Override - public AnnotationVisitor visitTypeAnnotation(final int typeRef, - final TypePath typePath, final String desc, final boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write target_type and target_info - AnnotationWriter.putTarget(typeRef, typePath, bv); - // write type, and reserve space for values count - bv.putShort(cw.newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, - bv.length - 2); - if (visible) { - aw.next = tanns; - tanns = aw; - } else { - aw.next = itanns; - itanns = aw; - } - return aw; - } - - @Override - public void visitAttribute(final Attribute attr) { - attr.next = attrs; - attrs = attr; - } - - @Override - 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) { - if ((cw.version & 0xFFFF) < Opcodes.V1_5 - || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { - 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 (ClassReader.ANNOTATIONS && tanns != null) { - cw.newUTF8("RuntimeVisibleTypeAnnotations"); - size += 8 + tanns.getSize(); - } - if (ClassReader.ANNOTATIONS && itanns != null) { - cw.newUTF8("RuntimeInvisibleTypeAnnotations"); - size += 8 + itanns.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) { - final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC; - int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE - | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR); - out.putShort(access & ~mask).putShort(name).putShort(desc); - int attributeCount = 0; - if (value != 0) { - ++attributeCount; - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0) { - if ((cw.version & 0xFFFF) < Opcodes.V1_5 - || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { - ++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 (ClassReader.ANNOTATIONS && tanns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && itanns != 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) { - if ((cw.version & 0xFFFF) < Opcodes.V1_5 - || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { - 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 (ClassReader.ANNOTATIONS && tanns != null) { - out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations")); - tanns.put(out); - } - if (ClassReader.ANNOTATIONS && itanns != null) { - out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations")); - itanns.put(out); - } - if (attrs != null) { - attrs.put(cw, null, 0, -1, -1, out); - } - } -} diff --git a/src/org/objectweb/asm/Frame.java b/src/org/objectweb/asm/Frame.java deleted file mode 100644 index a565639d..00000000 --- a/src/org/objectweb/asm/Frame.java +++ /dev/null @@ -1,1434 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.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 beginning 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 below, 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; - - /** - * Flag used for LOCAL and STACK types. Indicates that if this type happens - * to be a long or double type (during the computations of input frames), - * then it must be set to TOP because the second word of this value has been - * reused to store other data in the basic block. Hence the first word no - * longer stores a valid long or double value. - */ - static final int TOP_IF_LONG_OR_DOUBLE = 0x800000; - - /** - * Mask to get the value of a frame type. - */ - static final int VALUE = 0x7FFFFF; - - /** - * 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, //INVOKEDYNAMIC, // visitInvokeDynamicInsn - // 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((Type.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: - push(OBJECT | cw.addType("java/lang/String")); - break; - case ClassWriter.MTYPE: - push(OBJECT | cw.addType("java/lang/invoke/MethodType")); - break; - // case ClassWriter.HANDLE_BASE + [1..9]: - default: - push(OBJECT | cw.addType("java/lang/invoke/MethodHandle")); - } - 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); - } else if ((t2 & KIND) != BASE) { - set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE); - } - } - 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); - } else if ((t2 & KIND) != BASE) { - set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE); - } - } - 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.INVOKEDYNAMIC: - pop(item.strVal2); - push(cw, item.strVal2); - 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 == BASE) { - t = s; - } else { - if (kind == LOCAL) { - t = dim + inputLocals[s & VALUE]; - } else { - t = dim + inputStack[nStack - (s & VALUE)]; - } - if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 - && (t == LONG || t == DOUBLE)) { - t = TOP; - } - } - } - } 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 == BASE) { - t = s; - } else { - if (kind == LOCAL) { - t = dim + inputLocals[s & VALUE]; - } else { - t = dim + inputStack[nStack - (s & VALUE)]; - } - if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 - && (t == LONG || t == DOUBLE)) { - t = TOP; - } - } - 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 t and u have the same dimension and same 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) = dim(u) - 1 | java/lang/Object - int vdim = ELEMENT_OF + (u & DIM); - v = vdim | OBJECT | cw.addType("java/lang/Object"); - } - } else if ((t & BASE_KIND) == OBJECT || (t & DIM) != 0) { - // if t is any other reference or array type, the merged type - // is min(udim, tdim) | java/lang/Object, where udim is the - // array dimension of u, minus 1 if u is an array type with a - // primitive element type (and similarly for tdim). - int tdim = (((t & DIM) == 0 || (t & BASE_KIND) == OBJECT) ? 0 - : ELEMENT_OF) + (t & DIM); - int udim = (((u & DIM) == 0 || (u & BASE_KIND) == OBJECT) ? 0 - : ELEMENT_OF) + (u & DIM); - v = Math.min(tdim, udim) | 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/src/org/objectweb/asm/Handle.java b/src/org/objectweb/asm/Handle.java deleted file mode 100644 index a886bce3..00000000 --- a/src/org/objectweb/asm/Handle.java +++ /dev/null @@ -1,166 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.asm; - -/** - * A reference to a field or a method. - * - * @author Remi Forax - * @author Eric Bruneton - */ -public final class Handle { - - /** - * The kind of field or method designated by this Handle. Should be - * {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, - * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, - * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, - * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or - * {@link Opcodes#H_INVOKEINTERFACE}. - */ - final int tag; - - /** - * The internal name of the class that owns the field or method designated - * by this handle. - */ - final String owner; - - /** - * The name of the field or method designated by this handle. - */ - final String name; - - /** - * The descriptor of the field or method designated by this handle. - */ - final String desc; - - /** - * Constructs a new field or method handle. - * - * @param tag the kind of field or method designated by this Handle. Must be - * {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, - * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, - * {@link Opcodes#H_INVOKEVIRTUAL}, - * {@link Opcodes#H_INVOKESTATIC}, - * {@link Opcodes#H_INVOKESPECIAL}, - * {@link Opcodes#H_NEWINVOKESPECIAL} or - * {@link Opcodes#H_INVOKEINTERFACE}. - * @param owner the internal name of the class that owns the field or method - * designated by this handle. - * @param name the name of the field or method designated by this handle. - * @param desc the descriptor of the field or method designated by this - * handle. - */ - public Handle(int tag, String owner, String name, String desc) { - this.tag = tag; - this.owner = owner; - this.name = name; - this.desc = desc; - } - - /** - * Returns the kind of field or method designated by this handle. - * - * @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, - * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, - * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, - * {@link Opcodes#H_INVOKESPECIAL}, - * {@link Opcodes#H_NEWINVOKESPECIAL} or - * {@link Opcodes#H_INVOKEINTERFACE}. - */ - public int getTag() { - return tag; - } - - /** - * Returns the internal name of the class that owns the field or method - * designated by this handle. - * - * @return the internal name of the class that owns the field or method - * designated by this handle. - */ - public String getOwner() { - return owner; - } - - /** - * Returns the name of the field or method designated by this handle. - * - * @return the name of the field or method designated by this handle. - */ - public String getName() { - return name; - } - - /** - * Returns the descriptor of the field or method designated by this handle. - * - * @return the descriptor of the field or method designated by this handle. - */ - public String getDesc() { - return desc; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof Handle)) { - return false; - } - Handle h = (Handle) obj; - return tag == h.tag && owner.equals(h.owner) && name.equals(h.name) - && desc.equals(h.desc); - } - - @Override - public int hashCode() { - return tag + owner.hashCode() * name.hashCode() * desc.hashCode(); - } - - /** - * Returns the textual representation of this handle. The textual - * representation is: - *

- *

-     * owner '.' name desc ' ' '(' tag ')'
-     * 
- *

- * . As this format is unambiguous, it can be parsed if necessary. - */ - @Override - public String toString() { - return owner + '.' + name + desc + " (" + tag + ')'; - } -} diff --git a/src/org/objectweb/asm/Handler.java b/src/org/objectweb/asm/Handler.java deleted file mode 100644 index e64e691c..00000000 --- a/src/org/objectweb/asm/Handler.java +++ /dev/null @@ -1,118 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.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; - - /** - * Removes the range between start and end from the given exception - * handlers. - * - * @param h an exception handler list. - * @param start the start of the range to be removed. - * @param end the end of the range to be removed. Maybe null. - * @return the exception handler list with the start-end range removed. - */ - static Handler remove(Handler h, Label start, Label end) { - if (h == null) { - return null; - } else { - h.next = remove(h.next, start, end); - } - int hstart = h.start.position; - int hend = h.end.position; - int s = start.position; - int e = end == null ? Integer.MAX_VALUE : end.position; - // if [hstart,hend[ and [s,e[ intervals intersect... - if (s < hend && e > hstart) { - if (s <= hstart) { - if (e >= hend) { - // [hstart,hend[ fully included in [s,e[, h removed - h = h.next; - } else { - // [hstart,hend[ minus [s,e[ = [e,hend[ - h.start = end; - } - } else if (e >= hend) { - // [hstart,hend[ minus [s,e[ = [hstart,s[ - h.end = start; - } else { - // [hstart,hend[ minus [s,e[ = [hstart,s[ + [e,hend[ - Handler g = new Handler(); - g.start = end; - g.end = h.end; - g.handler = h.handler; - g.desc = h.desc; - g.type = h.type; - g.next = h.next; - h.end = start; - h.next = g; - } - } - return h; - } -} diff --git a/src/org/objectweb/asm/Item.java b/src/org/objectweb/asm/Item.java deleted file mode 100644 index fc20b984..00000000 --- a/src/org/objectweb/asm/Item.java +++ /dev/null @@ -1,295 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.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}, - * {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}. - *

- * MethodHandle constant 9 variations are stored using a range of 9 values - * from {@link ClassWriter#HANDLE_BASE} + 1 to - * {@link ClassWriter#HANDLE_BASE} + 9. - *

- * 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. - */ - @SuppressWarnings("fallthrough") - 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.CLASS: - this.intVal = 0; // intVal of a class must be zero, see visitInnerClass - case ClassWriter.UTF8: - case ClassWriter.STR: - case ClassWriter.MTYPE: - 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: - // ClassWriter.HANDLE_BASE + 1..9 - default: - hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() - * strVal2.hashCode() * strVal3.hashCode()); - } - } - - /** - * Sets the item to an InvokeDynamic item. - * - * @param name invokedynamic's name. - * @param desc invokedynamic's desc. - * @param bsmIndex zero based index into the class attribute BootrapMethods. - */ - void set(String name, String desc, int bsmIndex) { - this.type = ClassWriter.INDY; - this.longVal = bsmIndex; - this.strVal1 = name; - this.strVal2 = desc; - this.hashCode = 0x7FFFFFFF & (ClassWriter.INDY + bsmIndex - * strVal1.hashCode() * strVal2.hashCode()); - } - - /** - * Sets the item to a BootstrapMethod item. - * - * @param position position in byte in the class attribute BootrapMethods. - * @param hashCode hashcode of the item. This hashcode is processed from the - * hashcode of the bootstrap method and the hashcode of all - * bootstrap arguments. - */ - void set(int position, int hashCode) { - this.type = ClassWriter.BSM; - this.intVal = position; - this.hashCode = hashCode; - } - - /** - * Indicates if the given item is equal to this one. This method assumes - * that the two items have the same {@link #type}. - * - * @param i the item to be compared to this one. Both items must have the - * same {@link #type}. - * @return true if the given item if equal to this one, - * false otherwise. - */ - boolean isEqualTo(final Item i) { - switch (type) { - case ClassWriter.UTF8: - case ClassWriter.STR: - case ClassWriter.CLASS: - case ClassWriter.MTYPE: - case ClassWriter.TYPE_NORMAL: - return i.strVal1.equals(strVal1); - case ClassWriter.TYPE_MERGED: - case ClassWriter.LONG: - case ClassWriter.DOUBLE: - return i.longVal == longVal; - case ClassWriter.INT: - case ClassWriter.FLOAT: - return i.intVal == intVal; - 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); - case ClassWriter.INDY: { - return i.longVal == longVal && i.strVal1.equals(strVal1) - && i.strVal2.equals(strVal2); - } - // case ClassWriter.FIELD: - // case ClassWriter.METH: - // case ClassWriter.IMETH: - // case ClassWriter.HANDLE_BASE + 1..9 - default: - return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2) - && i.strVal3.equals(strVal3); - } - } -} diff --git a/src/org/objectweb/asm/Label.java b/src/org/objectweb/asm/Label.java deleted file mode 100644 index edde4b02..00000000 --- a/src/org/objectweb/asm/Label.java +++ /dev/null @@ -1,546 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.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. A label - * designates the instruction that is just after. Note however that there - * can be other elements between a label and the instruction it designates (such - * as other labels, stack map frames, line numbers, etc.). - * - * @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 by a - * visitSubroutine(null, ...) call. - */ - static final int VISITED = 1024; - - /** - * Indicates if this subroutine basic block has been visited by a - * visitSubroutine(!null, ...) call. - */ - static final int VISITED2 = 2048; - - /** - * 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 org.objectweb.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. If there are - * several lines, each line is stored in a separate label, all linked via - * their next field (these links are created in ClassReader and removed just - * before visitLabel is called, so that this does not impact the rest of the - * code). - */ - 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. It is also used in - * {@link #visitSubroutine} to avoid using a recursive method, and in - * ClassReader to temporarily store multiple source lines for a label. - * - * @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) { - if ((status & VISITED) == 0 || (block.status & VISITED) == 0) { - return false; - } - 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 / 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 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) { - // user managed stack of labels, to avoid using a recursive method - // (recursivity can lead to stack overflow with very large methods) - Label stack = this; - while (stack != null) { - // removes a label l from the stack - Label l = stack; - stack = l.next; - l.next = null; - - if (JSR != null) { - if ((l.status & VISITED2) != 0) { - continue; - } - l.status |= VISITED2; - // adds JSR to the successors of l, if it is a RET block - if ((l.status & RET) != 0) { - if (!l.inSameSubroutine(JSR)) { - Edge e = new Edge(); - e.info = l.inputStackTop; - e.successor = JSR.successors.successor; - e.next = l.successors; - l.successors = e; - } - } - } else { - // if the l block already belongs to subroutine 'id', continue - if (l.inSubroutine(id)) { - continue; - } - // marks the l block as belonging to subroutine 'id' - l.addToSubroutine(id, nbSubroutines); - } - // pushes each successor of l on the stack, except JSR targets - Edge e = l.successors; - while (e != null) { - // if the l block is a JSR block, then 'l.successors.next' leads - // to the JSR target (see {@link #visitJumpInsn}) and must - // therefore not be followed - if ((l.status & Label.JSR) == 0 || e != l.successors.next) { - // pushes e.successor on the stack if it not already added - if (e.successor.next == null) { - e.successor.next = stack; - stack = e.successor; - } - } - 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/src/org/objectweb/asm/MethodVisitor.java b/src/org/objectweb/asm/MethodVisitor.java deleted file mode 100644 index fc9726eb..00000000 --- a/src/org/objectweb/asm/MethodVisitor.java +++ /dev/null @@ -1,790 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.asm; - - -/** - * A visitor to visit a Java method. The methods of this class must be called in - * the following order: ( visitParameter )* [ - * visitAnnotationDefault ] ( visitAnnotation | - * visitParameterAnnotation visitTypeAnnotation | - * visitAttribute )* [ visitCode ( visitFrame | - * visitXInsn | visitLabel | - * visitInsnAnnotation | visitTryCatchBlock | - * visitTryCatchAnnotation | visitLocalVariable | - * visitLocalVariableAnnotation | 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, - * visitInsnAnnotation must be called after the annotated - * instruction, visitTryCatchBlock must be called before the - * labels passed as arguments have been visited, - * visitTryCatchBlockAnnotation must be called after the - * corresponding try catch block has been visited, and the - * visitLocalVariable, visitLocalVariableAnnotation and - * visitLineNumber methods must be called after the labels - * passed as arguments have been visited. - * - * @author Eric Bruneton - */ -public abstract class MethodVisitor { - - /** - * The ASM API version implemented by this visitor. The value of this field - * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - protected final int api; - - /** - * The method visitor to which this visitor must delegate method calls. May - * be null. - */ - protected MethodVisitor mv; - - /** - * Constructs a new {@link MethodVisitor}. - * - * @param api the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - public MethodVisitor(final int api) { - this(api, null); - } - - /** - * Constructs a new {@link MethodVisitor}. - * - * @param api the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @param mv the method visitor to which this visitor must delegate method - * calls. May be null. - */ - public MethodVisitor(final int api, final MethodVisitor mv) { - if (api != Opcodes.ASM4 && api != Opcodes.ASM5) { - throw new IllegalArgumentException(); - } - this.api = api; - this.mv = mv; - } - - // ------------------------------------------------------------------------- - // Parameters, annotations and non standard attributes - // ------------------------------------------------------------------------- - - /** - * Visits a parameter of this method. - * - * @param name parameter name or null if none is provided. - * @param access the parameter's access flags, only ACC_FINAL, - * ACC_SYNTHETIC or/and ACC_MANDATED are - * allowed (see {@link Opcodes}). - */ - public void visitParameter(String name, int access) { - if (api < Opcodes.ASM5) { - throw new RuntimeException(); - } - if (mv != null) { - mv.visitParameter(name, access); - } - } - - /** - * 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. - */ - public AnnotationVisitor visitAnnotationDefault() { - if (mv != null) { - return mv.visitAnnotationDefault(); - } - return null; - } - - /** - * 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. - */ - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - if (mv != null) { - return mv.visitAnnotation(desc, visible); - } - return null; - } - - /** - * Visits an annotation on a type in the method signature. - * - * @param typeRef a reference to the annotated type. The sort of this type - * reference must be {@link TypeReference#METHOD_TYPE_PARAMETER - * METHOD_TYPE_PARAMETER}, - * {@link TypeReference#METHOD_TYPE_PARAMETER_BOUND - * METHOD_TYPE_PARAMETER_BOUND}, - * {@link TypeReference#METHOD_RETURN METHOD_RETURN}, - * {@link TypeReference#METHOD_RECEIVER METHOD_RECEIVER}, - * {@link TypeReference#METHOD_FORMAL_PARAMETER - * METHOD_FORMAL_PARAMETER} or {@link TypeReference#THROWS - * THROWS}. See {@link TypeReference}. - * @param typePath the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @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. - */ - public AnnotationVisitor visitTypeAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - if (api < Opcodes.ASM5) { - throw new RuntimeException(); - } - if (mv != null) { - return mv.visitTypeAnnotation(typeRef, typePath, desc, visible); - } - return null; - } - - /** - * 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. - */ - public AnnotationVisitor visitParameterAnnotation(int parameter, - String desc, boolean visible) { - if (mv != null) { - return mv.visitParameterAnnotation(parameter, desc, visible); - } - return null; - } - - /** - * Visits a non standard attribute of this method. - * - * @param attr an attribute. - */ - public void visitAttribute(Attribute attr) { - if (mv != null) { - mv.visitAttribute(attr); - } - } - - /** - * Starts the visit of the method's code, if any (i.e. non abstract method). - */ - public void visitCode() { - if (mv != null) { - mv.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 unconditional 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}.
- *
- * The frames of a method must be given either in expanded form, or in - * compressed form (all frames must use the same format, i.e. you must not - * mix expanded and compressed frames within a single method): - *

    - *
  • In expanded form, all frames must have the F_NEW type.
  • - *
  • In compressed form, frames are basically "deltas" from the state of - * the previous frame: - *
      - *
    • {@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.
    • - *
    - *
  • - *
- *
- * In both cases the first frame, corresponding to the method's parameters - * and access flags, is implicit and must not be visited. Also, it is - * illegal to visit two or more frames for the same code location (i.e., at - * least one instruction must be visited between two calls to visitFrame). - * - * @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. - * @throws IllegalStateException if a frame is visited just after another one, without any - * instruction between the two (unless this frame is a - * Opcodes#F_SAME frame, in which case it is silently ignored). - */ - public void visitFrame(int type, int nLocal, Object[] local, int nStack, - Object[] stack) { - if (mv != null) { - mv.visitFrame(type, nLocal, local, nStack, 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. - */ - public void visitInsn(int opcode) { - if (mv != null) { - mv.visitInsn(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}. - */ - public void visitIntInsn(int opcode, int operand) { - if (mv != null) { - mv.visitIntInsn(opcode, 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. - */ - public void visitVarInsn(int opcode, int var) { - if (mv != null) { - mv.visitVarInsn(opcode, 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}). - */ - public void visitTypeInsn(int opcode, String type) { - if (mv != null) { - mv.visitTypeInsn(opcode, 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}). - */ - public void visitFieldInsn(int opcode, String owner, String name, - String desc) { - if (mv != null) { - mv.visitFieldInsn(opcode, owner, name, 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}). - */ - @Deprecated - public void visitMethodInsn(int opcode, String owner, String name, - String desc) { - if (api >= Opcodes.ASM5) { - boolean itf = opcode == Opcodes.INVOKEINTERFACE; - visitMethodInsn(opcode, owner, name, desc, itf); - return; - } - if (mv != null) { - mv.visitMethodInsn(opcode, owner, name, 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}). - * @param itf if the method's owner class is an interface. - */ - public void visitMethodInsn(int opcode, String owner, String name, - String desc, boolean itf) { - if (api < Opcodes.ASM5) { - if (itf != (opcode == Opcodes.INVOKEINTERFACE)) { - throw new IllegalArgumentException( - "INVOKESPECIAL/STATIC on interfaces require ASM 5"); - } - visitMethodInsn(opcode, owner, name, desc); - return; - } - if (mv != null) { - mv.visitMethodInsn(opcode, owner, name, desc, itf); - } - } - - /** - * Visits an invokedynamic instruction. - * - * @param name the method's name. - * @param desc the method's descriptor (see {@link Type Type}). - * @param bsm the bootstrap method. - * @param bsmArgs the bootstrap method constant arguments. Each argument must be - * an {@link Integer}, {@link Float}, {@link Long}, - * {@link Double}, {@link String}, {@link Type} or {@link Handle} - * value. This method is allowed to modify the content of the - * array so a caller should expect that this array may change. - */ - public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, - Object... bsmArgs) { - if (mv != null) { - mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); - } - } - - /** - * 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. - */ - public void visitJumpInsn(int opcode, Label label) { - if (mv != null) { - mv.visitJumpInsn(opcode, label); - } - } - - /** - * Visits a label. A label designates the instruction that will be visited - * just after it. - * - * @param label a {@link Label Label} object. - */ - public void visitLabel(Label label) { - if (mv != null) { - mv.visitLabel(label); - } - } - - // ------------------------------------------------------------------------- - // Special instructions - // ------------------------------------------------------------------------- - - /** - * Visits a LDC instruction. Note that new constant types may be added in - * future versions of the Java Virtual Machine. To easily detect new - * constant types, implementations of this method should check for - * unexpected constant types, like this: - *

- *

-     * if (cst instanceof Integer) {
-     *     // ...
-     * } else if (cst instanceof Float) {
-     *     // ...
-     * } else if (cst instanceof Long) {
-     *     // ...
-     * } else if (cst instanceof Double) {
-     *     // ...
-     * } else if (cst instanceof String) {
-     *     // ...
-     * } else if (cst instanceof Type) {
-     *     int sort = ((Type) cst).getSort();
-     *     if (sort == Type.OBJECT) {
-     *         // ...
-     *     } else if (sort == Type.ARRAY) {
-     *         // ...
-     *     } else if (sort == Type.METHOD) {
-     *         // ...
-     *     } else {
-     *         // throw an exception
-     *     }
-     * } else if (cst instanceof Handle) {
-     *     // ...
-     * } else {
-     *     // throw an exception
-     * }
-     * 
- * - * @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}, a {@link Type} of OBJECT or - * ARRAY sort for .class constants, for classes whose - * version is 49.0, a {@link Type} of METHOD sort or a - * {@link Handle} for MethodType and MethodHandle constants, for - * classes whose version is 51.0. - */ - public void visitLdcInsn(Object cst) { - if (mv != null) { - mv.visitLdcInsn(cst); - } - } - - /** - * Visits an IINC instruction. - * - * @param var index of the local variable to be incremented. - * @param increment amount to increment the local variable by. - */ - public void visitIincInsn(int var, int increment) { - if (mv != null) { - mv.visitIincInsn(var, 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. - */ - public void visitTableSwitchInsn(int min, int max, Label dflt, - Label... labels) { - if (mv != null) { - mv.visitTableSwitchInsn(min, max, dflt, 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. - */ - public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { - if (mv != null) { - mv.visitLookupSwitchInsn(dflt, keys, 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. - */ - public void visitMultiANewArrayInsn(String desc, int dims) { - if (mv != null) { - mv.visitMultiANewArrayInsn(desc, dims); - } - } - - /** - * Visits an annotation on an instruction. This method must be called just - * after the annotated instruction. It can be called several times - * for the same instruction. - * - * @param typeRef a reference to the annotated type. The sort of this type - * reference must be {@link TypeReference#INSTANCEOF INSTANCEOF}, - * {@link TypeReference#NEW NEW}, - * {@link TypeReference#CONSTRUCTOR_REFERENCE - * CONSTRUCTOR_REFERENCE}, {@link TypeReference#METHOD_REFERENCE - * METHOD_REFERENCE}, {@link TypeReference#CAST CAST}, - * {@link TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT - * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, - * {@link TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT - * METHOD_INVOCATION_TYPE_ARGUMENT}, - * {@link TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT - * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or - * {@link TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT - * METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link TypeReference}. - * @param typePath the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @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. - */ - public AnnotationVisitor visitInsnAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - if (api < Opcodes.ASM5) { - throw new RuntimeException(); - } - if (mv != null) { - return mv.visitInsnAnnotation(typeRef, typePath, desc, visible); - } - return null; - } - - // ------------------------------------------------------------------------- - // 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). - */ - public void visitTryCatchBlock(Label start, Label end, Label handler, - String type) { - if (mv != null) { - mv.visitTryCatchBlock(start, end, handler, type); - } - } - - /** - * Visits an annotation on an exception handler type. This method must be - * called after the {@link #visitTryCatchBlock} for the annotated - * exception handler. It can be called several times for the same exception - * handler. - * - * @param typeRef a reference to the annotated type. The sort of this type - * reference must be {@link TypeReference#EXCEPTION_PARAMETER - * EXCEPTION_PARAMETER}. See {@link TypeReference}. - * @param typePath the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @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. - */ - public AnnotationVisitor visitTryCatchAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - if (api < Opcodes.ASM5) { - throw new RuntimeException(); - } - if (mv != null) { - return mv.visitTryCatchAnnotation(typeRef, typePath, desc, visible); - } - return null; - } - - /** - * 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). - */ - public void visitLocalVariable(String name, String desc, String signature, - Label start, Label end, int index) { - if (mv != null) { - mv.visitLocalVariable(name, desc, signature, start, end, index); - } - } - - /** - * Visits an annotation on a local variable type. - * - * @param typeRef a reference to the annotated type. The sort of this type - * reference must be {@link TypeReference#LOCAL_VARIABLE - * LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE - * RESOURCE_VARIABLE}. See {@link TypeReference}. - * @param typePath the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @param start the fist instructions corresponding to the continuous ranges - * that make the scope of this local variable (inclusive). - * @param end the last instructions corresponding to the continuous ranges - * that make the scope of this local variable (exclusive). This - * array must have the same size as the 'start' array. - * @param index the local variable's index in each range. This array must have - * the same size as the 'start' array. - * @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. - */ - public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, - TypePath typePath, Label[] start, Label[] end, int[] index, - String desc, boolean visible) { - if (api < Opcodes.ASM5) { - throw new RuntimeException(); - } - if (mv != null) { - return mv.visitLocalVariableAnnotation(typeRef, typePath, start, - end, index, desc, visible); - } - return null; - } - - /** - * 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). - */ - public void visitLineNumber(int line, Label start) { - if (mv != null) { - mv.visitLineNumber(line, 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. - */ - public void visitMaxs(int maxStack, int maxLocals) { - if (mv != null) { - mv.visitMaxs(maxStack, 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. - */ - public void visitEnd() { - if (mv != null) { - mv.visitEnd(); - } - } -} diff --git a/src/org/objectweb/asm/MethodWriter.java b/src/org/objectweb/asm/MethodWriter.java deleted file mode 100644 index f0f57627..00000000 --- a/src/org/objectweb/asm/MethodWriter.java +++ /dev/null @@ -1,2884 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.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 extends MethodVisitor { - - /** - * Pseudo access flag used to denote constructors. - */ - static final int ACC_CONSTRUCTOR = 0x80000; - - /** - * 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; - - /** - * 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 type annotations of this method. May be null - * . - */ - private AnnotationWriter tanns; - - /** - * The runtime invisible type annotations of this method. May be - * null. - */ - private AnnotationWriter itanns; - - /** - * 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 local variables in the current stack map frame. - */ - private int currentLocals; - - /** - * 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; - - /** - * 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 MethodParameters attribute. - */ - private int methodParametersCount; - - /** - * The MethodParameters attribute. - */ - private ByteVector methodParameters; - - /** - * 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 start offset of the last visited instruction. - */ - private int lastCodeOffset; - - /** - * The runtime visible type annotations of the code. May be null. - */ - private AnnotationWriter ctanns; - - /** - * The runtime invisible type annotations of the code. May be null. - */ - private AnnotationWriter ictanns; - - /** - * 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) { - super(Opcodes.ASM5); - if (cw.firstMethod == null) { - cw.firstMethod = this; - } else { - cw.lastMethod.mv = this; - } - cw.lastMethod = this; - this.cw = cw; - this.access = access; - if ("".equals(name)) { - this.access |= ACC_CONSTRUCTOR; - } - 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) { - // updates maxLocals - int size = Type.getArgumentsAndReturnSizes(descriptor) >> 2; - if ((access & Opcodes.ACC_STATIC) != 0) { - --size; - } - maxLocals = size; - currentLocals = size; - // creates and visits the label for the first basic block - labels = new Label(); - labels.status |= Label.PUSHED; - visitLabel(labels); - } - } - - // ------------------------------------------------------------------------ - // Implementation of the MethodVisitor abstract class - // ------------------------------------------------------------------------ - - @Override - public void visitParameter(String name, int access) { - if (methodParameters == null) { - methodParameters = new ByteVector(); - } - ++methodParametersCount; - methodParameters.putShort((name == null) ? 0 : cw.newUTF8(name)) - .putShort(access); - } - - @Override - public AnnotationVisitor visitAnnotationDefault() { - if (!ClassReader.ANNOTATIONS) { - return null; - } - annd = new ByteVector(); - return new AnnotationWriter(cw, false, annd, null, 0); - } - - @Override - 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; - } - - @Override - public AnnotationVisitor visitTypeAnnotation(final int typeRef, - final TypePath typePath, final String desc, final boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write target_type and target_info - AnnotationWriter.putTarget(typeRef, typePath, bv); - // write type, and reserve space for values count - bv.putShort(cw.newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, - bv.length - 2); - if (visible) { - aw.next = tanns; - tanns = aw; - } else { - aw.next = itanns; - itanns = aw; - } - return aw; - } - - @Override - 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; - } - - @Override - public void visitAttribute(final Attribute attr) { - if (attr.isCodeAttribute()) { - attr.next = cattrs; - cattrs = attr; - } else { - attr.next = attrs; - attrs = attr; - } - } - - @Override - public void visitCode() { - } - - @Override - 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) { - if (previousFrame == null) { - visitImplicitFirstFrame(); - } - currentLocals = nLocal; - int frameIndex = 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; - if (delta < 0) { - if (type == Opcodes.F_SAME) { - return; - } else { - throw new IllegalStateException(); - } - } - } - - switch (type) { - case Opcodes.F_FULL: - currentLocals = nLocal; - 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: - currentLocals += nLocal; - stackMap.putByte(SAME_FRAME_EXTENDED + nLocal).putShort(delta); - for (int i = 0; i < nLocal; ++i) { - writeFrameType(local[i]); - } - break; - case Opcodes.F_CHOP: - currentLocals -= nLocal; - 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; - } - - maxStack = Math.max(maxStack, nStack); - maxLocals = Math.max(maxLocals, currentLocals); - } - - @Override - public void visitInsn(final int opcode) { - lastCodeOffset = code.length; - // 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(); - } - } - } - - @Override - public void visitIntInsn(final int opcode, final int operand) { - lastCodeOffset = code.length; - // 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); - } - } - - @Override - public void visitVarInsn(final int opcode, final int var) { - lastCodeOffset = code.length; - // 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()); - } - } - - @Override - public void visitTypeInsn(final int opcode, final String type) { - lastCodeOffset = code.length; - 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); - } - - @Override - public void visitFieldInsn(final int opcode, final String owner, - final String name, final String desc) { - lastCodeOffset = code.length; - 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); - } - - @Override - public void visitMethodInsn(final int opcode, final String owner, - final String name, final String desc, final boolean itf) { - lastCodeOffset = code.length; - 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 = Type.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 (opcode == Opcodes.INVOKEINTERFACE) { - if (argSize == 0) { - argSize = Type.getArgumentsAndReturnSizes(desc); - i.intVal = argSize; - } - code.put12(Opcodes.INVOKEINTERFACE, i.index).put11(argSize >> 2, 0); - } else { - code.put12(opcode, i.index); - } - } - - @Override - public void visitInvokeDynamicInsn(final String name, final String desc, - final Handle bsm, final Object... bsmArgs) { - lastCodeOffset = code.length; - Item i = cw.newInvokeDynamicItem(name, desc, bsm, bsmArgs); - int argSize = i.intVal; - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(Opcodes.INVOKEDYNAMIC, 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 = Type.getArgumentsAndReturnSizes(desc); - // ... and we save them in order - // not to recompute them in the future - i.intVal = argSize; - } - int size = stackSize - (argSize >> 2) + (argSize & 0x03) + 1; - - // updates current and max stack sizes - if (size > maxStackSize) { - maxStackSize = size; - } - stackSize = size; - } - } - // adds the instruction to the bytecode of the method - code.put12(Opcodes.INVOKEDYNAMIC, i.index); - code.putShort(0); - } - - @Override - public void visitJumpInsn(final int opcode, final Label label) { - lastCodeOffset = code.length; - 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(); - } - } - } - - @Override - 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; - } - } - - @Override - public void visitLdcInsn(final Object cst) { - lastCodeOffset = code.length; - 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); - } - } - - @Override - public void visitIincInsn(final int var, final int increment) { - lastCodeOffset = code.length; - 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); - } - } - - @Override - public void visitTableSwitchInsn(final int min, final int max, - final Label dflt, final Label... labels) { - lastCodeOffset = code.length; - // adds the instruction to the bytecode of the method - int source = code.length; - code.putByte(Opcodes.TABLESWITCH); - code.putByteArray(null, 0, (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); - } - - @Override - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, - final Label[] labels) { - lastCodeOffset = code.length; - // adds the instruction to the bytecode of the method - int source = code.length; - code.putByte(Opcodes.LOOKUPSWITCH); - code.putByteArray(null, 0, (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(); - } - } - - @Override - public void visitMultiANewArrayInsn(final String desc, final int dims) { - lastCodeOffset = code.length; - 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); - } - - @Override - public AnnotationVisitor visitInsnAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write target_type and target_info - typeRef = (typeRef & 0xFF0000FF) | (lastCodeOffset << 8); - AnnotationWriter.putTarget(typeRef, typePath, bv); - // write type, and reserve space for values count - bv.putShort(cw.newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, - bv.length - 2); - if (visible) { - aw.next = ctanns; - ctanns = aw; - } else { - aw.next = ictanns; - ictanns = aw; - } - return aw; - } - - @Override - 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; - } - - @Override - public AnnotationVisitor visitTryCatchAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write target_type and target_info - AnnotationWriter.putTarget(typeRef, typePath, bv); - // write type, and reserve space for values count - bv.putShort(cw.newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, - bv.length - 2); - if (visible) { - aw.next = ctanns; - ctanns = aw; - } else { - aw.next = ictanns; - ictanns = aw; - } - return aw; - } - - @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) { - 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; - } - } - } - - @Override - public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, - TypePath typePath, Label[] start, Label[] end, int[] index, - String desc, boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write target_type and target_info - bv.putByte(typeRef >>> 24).putShort(start.length); - for (int i = 0; i < start.length; ++i) { - bv.putShort(start[i].position) - .putShort(end[i].position - start[i].position) - .putShort(index[i]); - } - if (typePath == null) { - bv.putByte(0); - } else { - int length = typePath.b[typePath.offset] * 2 + 1; - bv.putByteArray(typePath.b, typePath.offset, length); - } - // write type, and reserve space for values count - bv.putShort(cw.newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, - bv.length - 2); - if (visible) { - aw.next = ctanns; - ctanns = aw; - } else { - aw.next = ictanns; - ictanns = aw; - } - return aw; - } - - @Override - public void visitLineNumber(final int line, final Label start) { - if (lineNumber == null) { - lineNumber = new ByteVector(); - } - ++lineNumberCount; - lineNumber.putShort(start.position); - lineNumber.putShort(line); - } - - @Override - public void visitMaxs(final int maxStack, final int maxLocals) { - if (resize) { - // replaces the temporary jump opcodes introduced by Label.resolve. - if (ClassReader.RESIZE) { - resizeInstructions(); - } else { - throw new RuntimeException("Method code too large!"); - } - } - 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 reachable jump target must be stored in the stack map - if ((l.status & Label.TARGET) != 0) { - l.status |= Label.STORE; - } - // all visited labels are reachable, 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; - } - } - - // 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) { - max = Math.max(max, 1); - // 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 - int frameIndex = startFrame(start, 0, 1); - frame[frameIndex] = Frame.OBJECT - | cw.addType("java/lang/Throwable"); - endFrame(); - // removes the start-end range from the exception - // handlers - firstHandler = Handler.remove(firstHandler, l, k); - } - } - l = l.successor; - } - - handler = firstHandler; - handlerCount = 0; - while (handler != null) { - handlerCount += 1; - handler = handler.next; - } - - this.maxStack = max; - } 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.VISITED2; - 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 = Math.max(maxStack, max); - } else { - this.maxStack = maxStack; - this.maxLocals = maxLocals; - } - } - - @Override - public void visitEnd() { - } - - // ------------------------------------------------------------------------ - // Utility methods: control flow analysis algorithm - // ------------------------------------------------------------------------ - - /** - * 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 - int frameIndex = 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(); - } - - /** - * Visit the implicit first frame of this method. - */ - private void visitImplicitFirstFrame() { - // There can be at most descriptor.length() + 1 locals - int frameIndex = startFrame(0, descriptor.length() + 1, 0); - if ((access & Opcodes.ACC_STATIC) == 0) { - if ((access & ACC_CONSTRUCTOR) == 0) { - frame[frameIndex++] = Frame.OBJECT | cw.addType(cw.thisName); - } else { - frame[frameIndex++] = 6; // Opcodes.UNINITIALIZED_THIS; - } - } - int i = 1; - loop: - while (true) { - int j = i; - switch (descriptor.charAt(i++)) { - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - frame[frameIndex++] = 1; // Opcodes.INTEGER; - break; - case 'F': - frame[frameIndex++] = 2; // Opcodes.FLOAT; - break; - case 'J': - frame[frameIndex++] = 4; // Opcodes.LONG; - break; - case 'D': - frame[frameIndex++] = 3; // Opcodes.DOUBLE; - break; - case '[': - while (descriptor.charAt(i) == '[') { - ++i; - } - if (descriptor.charAt(i) == 'L') { - ++i; - while (descriptor.charAt(i) != ';') { - ++i; - } - } - frame[frameIndex++] = Frame.OBJECT - | cw.addType(descriptor.substring(j, ++i)); - break; - case 'L': - while (descriptor.charAt(i) != ';') { - ++i; - } - frame[frameIndex++] = Frame.OBJECT - | cw.addType(descriptor.substring(j + 1, i++)); - break; - default: - break loop; - } - } - frame[1] = frameIndex - 3; - 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. - * @return the index of the next element to be written in this frame. - */ - private int 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; - return 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 sb = new StringBuilder(); - d >>= 28; - while (d-- > 0) { - sb.append('['); - } - if ((t & Frame.BASE_KIND) == Frame.OBJECT) { - sb.append('L'); - sb.append(cw.typeTable[t & Frame.BASE_VALUE].strVal1); - sb.append(';'); - } else { - switch (t & 0xF) { - case 1: - sb.append('I'); - break; - case 2: - sb.append('F'); - break; - case 3: - sb.append('D'); - break; - case 9: - sb.append('Z'); - break; - case 10: - sb.append('B'); - break; - case 11: - sb.append('C'); - break; - case 12: - sb.append('S'); - break; - default: - sb.append('J'); - } - } - stackMap.putByte(7).putShort(cw.newClass(sb.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; - } - int size = 8; - if (code.length > 0) { - if (code.length > 65536) { - throw new RuntimeException("Method code too large!"); - } - 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 (ClassReader.ANNOTATIONS && ctanns != null) { - cw.newUTF8("RuntimeVisibleTypeAnnotations"); - size += 8 + ctanns.getSize(); - } - if (ClassReader.ANNOTATIONS && ictanns != null) { - cw.newUTF8("RuntimeInvisibleTypeAnnotations"); - size += 8 + ictanns.getSize(); - } - 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) { - if ((cw.version & 0xFFFF) < Opcodes.V1_5 - || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { - 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 (methodParameters != null) { - cw.newUTF8("MethodParameters"); - size += 7 + methodParameters.length; - } - 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 && tanns != null) { - cw.newUTF8("RuntimeVisibleTypeAnnotations"); - size += 8 + tanns.getSize(); - } - if (ClassReader.ANNOTATIONS && itanns != null) { - cw.newUTF8("RuntimeInvisibleTypeAnnotations"); - size += 8 + itanns.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) { - final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC; - int mask = ACC_CONSTRUCTOR | Opcodes.ACC_DEPRECATED - | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE - | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR); - out.putShort(access & ~mask).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) { - if ((cw.version & 0xFFFF) < Opcodes.V1_5 - || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { - ++attributeCount; - } - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - ++attributeCount; - } - if (ClassReader.SIGNATURES && signature != null) { - ++attributeCount; - } - if (methodParameters != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && annd != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && anns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && ianns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && tanns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && itanns != 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 (ClassReader.ANNOTATIONS && ctanns != null) { - size += 8 + ctanns.getSize(); - } - if (ClassReader.ANNOTATIONS && ictanns != null) { - size += 8 + ictanns.getSize(); - } - 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 (ClassReader.ANNOTATIONS && ctanns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && ictanns != 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 (ClassReader.ANNOTATIONS && ctanns != null) { - out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations")); - ctanns.put(out); - } - if (ClassReader.ANNOTATIONS && ictanns != null) { - out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations")); - ictanns.put(out); - } - 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) { - if ((cw.version & 0xFFFF) < Opcodes.V1_5 - || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { - 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 (methodParameters != null) { - out.putShort(cw.newUTF8("MethodParameters")); - out.putInt(methodParameters.length + 1).putByte( - methodParametersCount); - out.putByteArray(methodParameters.data, 0, methodParameters.length); - } - 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 && tanns != null) { - out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations")); - tanns.put(out); - } - if (ClassReader.ANNOTATIONS && itanns != null) { - out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations")); - itanns.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: - case ClassWriter.INDYMETH_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.putByteArray(null, 0, (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.putByteArray(null, 0, (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: - case ClassWriter.INDYMETH_INSN: - newCode.putByteArray(b, u, 5); - u += 5; - break; - // case MANA_INSN: - default: - newCode.putByteArray(b, u, 4); - u += 4; - break; - } - } - - // updates the stack map frame labels - if (compute == FRAMES) { - Label l = labels; - while (l != null) { - /* - * Detects the labels that are just after an IF instruction that - * has been resized with the IFNOT GOTO_W pattern. These labels - * are now the target of a jump instruction (the IFNOT - * instruction). Note that we need the original label position - * here. getNewOffset must therefore never have been called for - * this label. - */ - u = l.position - 3; - if (u >= 0 && resize[u]) { - l.status |= Label.TARGET; - } - getNewOffset(allIndexes, allSizes, l); - l = l.successor; - } - // Update the offsets in the uninitialized types - if (cw.typeTable != null) { - for (i = 0; i < cw.typeTable.length; ++i) { - Item item = cw.typeTable[i]; - if (item != null && item.type == ClassWriter.TYPE_UNINIT) { - item.intVal = getNewOffset(allIndexes, allSizes, 0, - item.intVal); - } - } - } - // The stack map frames are not serialized yet, so we don't need - // to update them. They will be serialized in visitMaxs. - } else if (frameCount > 0) { - /* - * 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/src/org/objectweb/asm/Opcodes.java b/src/org/objectweb/asm/Opcodes.java deleted file mode 100644 index ae2610a3..00000000 --- a/src/org/objectweb/asm/Opcodes.java +++ /dev/null @@ -1,361 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.asm; - -/** - * Defines the JVM opcodes, access flags and array type codes. This interface - * does not define all the JVM opcodes because some opcodes are automatically - * handled. For example, the xLOAD and xSTORE opcodes are automatically replaced - * by xLOAD_n and xSTORE_n opcodes when possible. The xLOAD_n and xSTORE_n - * opcodes are therefore not defined in this interface. Likewise for LDC, - * automatically replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and - * JSR_W. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public interface Opcodes { - - // ASM API versions - - int ASM4 = 4 << 16 | 0 << 8 | 0; - int ASM5 = 5 << 16 | 0 << 8 | 0; - - // versions - - int V1_1 = 3 << 16 | 45; - int V1_2 = 0 << 16 | 46; - int V1_3 = 0 << 16 | 47; - int V1_4 = 0 << 16 | 48; - int V1_5 = 0 << 16 | 49; - int V1_6 = 0 << 16 | 50; - int V1_7 = 0 << 16 | 51; - int V1_8 = 0 << 16 | 52; - - // access flags - - int ACC_PUBLIC = 0x0001; // class, field, method - int ACC_PRIVATE = 0x0002; // class, field, method - int ACC_PROTECTED = 0x0004; // class, field, method - int ACC_STATIC = 0x0008; // field, method - int ACC_FINAL = 0x0010; // class, field, method, parameter - int ACC_SUPER = 0x0020; // class - int ACC_SYNCHRONIZED = 0x0020; // method - int ACC_VOLATILE = 0x0040; // field - int ACC_BRIDGE = 0x0040; // method - int ACC_VARARGS = 0x0080; // method - int ACC_TRANSIENT = 0x0080; // field - int ACC_NATIVE = 0x0100; // method - int ACC_INTERFACE = 0x0200; // class - int ACC_ABSTRACT = 0x0400; // class, method - int ACC_STRICT = 0x0800; // method - int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter - int ACC_ANNOTATION = 0x2000; // class - int ACC_ENUM = 0x4000; // class(?) field inner - int ACC_MANDATED = 0x8000; // parameter - - // ASM specific pseudo access flags - - int ACC_DEPRECATED = 0x20000; // class, field, method - - // types for NEWARRAY - - int T_BOOLEAN = 4; - int T_CHAR = 5; - int T_FLOAT = 6; - int T_DOUBLE = 7; - int T_BYTE = 8; - int T_SHORT = 9; - int T_INT = 10; - int T_LONG = 11; - - // tags for Handle - - int H_GETFIELD = 1; - int H_GETSTATIC = 2; - int H_PUTFIELD = 3; - int H_PUTSTATIC = 4; - int H_INVOKEVIRTUAL = 5; - int H_INVOKESTATIC = 6; - int H_INVOKESPECIAL = 7; - int H_NEWINVOKESPECIAL = 8; - int H_INVOKEINTERFACE = 9; - - // stack map frame types - - /** - * Represents an expanded frame. See {@link ClassReader#EXPAND_FRAMES}. - */ - int F_NEW = -1; - - /** - * Represents a compressed frame with complete frame data. - */ - int F_FULL = 0; - - /** - * Represents a compressed frame where locals are the same as the locals in - * the previous frame, except that additional 1-3 locals are defined, and - * with an empty stack. - */ - int F_APPEND = 1; - - /** - * Represents a compressed frame where locals are the same as the locals in - * the previous frame, except that the last 1-3 locals are absent and with - * an empty stack. - */ - int F_CHOP = 2; - - /** - * Represents a compressed frame with exactly the same locals as the - * previous frame and with an empty stack. - */ - int F_SAME = 3; - - /** - * Represents a compressed frame with exactly the same locals as the - * previous frame and with a single value on the stack. - */ - int F_SAME1 = 4; - - Integer TOP = new Integer(0); - Integer INTEGER = new Integer(1); - Integer FLOAT = new Integer(2); - Integer DOUBLE = new Integer(3); - Integer LONG = new Integer(4); - Integer NULL = new Integer(5); - Integer UNINITIALIZED_THIS = new Integer(6); - - // opcodes // visit method (- = idem) - - int NOP = 0; // visitInsn - int ACONST_NULL = 1; // - - int ICONST_M1 = 2; // - - int ICONST_0 = 3; // - - int ICONST_1 = 4; // - - int ICONST_2 = 5; // - - int ICONST_3 = 6; // - - int ICONST_4 = 7; // - - int ICONST_5 = 8; // - - int LCONST_0 = 9; // - - int LCONST_1 = 10; // - - int FCONST_0 = 11; // - - int FCONST_1 = 12; // - - int FCONST_2 = 13; // - - int DCONST_0 = 14; // - - int DCONST_1 = 15; // - - int BIPUSH = 16; // visitIntInsn - int SIPUSH = 17; // - - int LDC = 18; // visitLdcInsn - // int LDC_W = 19; // - - // int LDC2_W = 20; // - - int ILOAD = 21; // visitVarInsn - int LLOAD = 22; // - - int FLOAD = 23; // - - int DLOAD = 24; // - - int ALOAD = 25; // - - // int ILOAD_0 = 26; // - - // int ILOAD_1 = 27; // - - // int ILOAD_2 = 28; // - - // int ILOAD_3 = 29; // - - // int LLOAD_0 = 30; // - - // int LLOAD_1 = 31; // - - // int LLOAD_2 = 32; // - - // int LLOAD_3 = 33; // - - // int FLOAD_0 = 34; // - - // int FLOAD_1 = 35; // - - // int FLOAD_2 = 36; // - - // int FLOAD_3 = 37; // - - // int DLOAD_0 = 38; // - - // int DLOAD_1 = 39; // - - // int DLOAD_2 = 40; // - - // int DLOAD_3 = 41; // - - // int ALOAD_0 = 42; // - - // int ALOAD_1 = 43; // - - // int ALOAD_2 = 44; // - - // int ALOAD_3 = 45; // - - int IALOAD = 46; // visitInsn - int LALOAD = 47; // - - int FALOAD = 48; // - - int DALOAD = 49; // - - int AALOAD = 50; // - - int BALOAD = 51; // - - int CALOAD = 52; // - - int SALOAD = 53; // - - int ISTORE = 54; // visitVarInsn - int LSTORE = 55; // - - int FSTORE = 56; // - - int DSTORE = 57; // - - int ASTORE = 58; // - - // int ISTORE_0 = 59; // - - // int ISTORE_1 = 60; // - - // int ISTORE_2 = 61; // - - // int ISTORE_3 = 62; // - - // int LSTORE_0 = 63; // - - // int LSTORE_1 = 64; // - - // int LSTORE_2 = 65; // - - // int LSTORE_3 = 66; // - - // int FSTORE_0 = 67; // - - // int FSTORE_1 = 68; // - - // int FSTORE_2 = 69; // - - // int FSTORE_3 = 70; // - - // int DSTORE_0 = 71; // - - // int DSTORE_1 = 72; // - - // int DSTORE_2 = 73; // - - // int DSTORE_3 = 74; // - - // int ASTORE_0 = 75; // - - // int ASTORE_1 = 76; // - - // int ASTORE_2 = 77; // - - // int ASTORE_3 = 78; // - - int IASTORE = 79; // visitInsn - int LASTORE = 80; // - - int FASTORE = 81; // - - int DASTORE = 82; // - - int AASTORE = 83; // - - int BASTORE = 84; // - - int CASTORE = 85; // - - int SASTORE = 86; // - - int POP = 87; // - - int POP2 = 88; // - - int DUP = 89; // - - int DUP_X1 = 90; // - - int DUP_X2 = 91; // - - int DUP2 = 92; // - - int DUP2_X1 = 93; // - - int DUP2_X2 = 94; // - - int SWAP = 95; // - - int IADD = 96; // - - int LADD = 97; // - - int FADD = 98; // - - int DADD = 99; // - - int ISUB = 100; // - - int LSUB = 101; // - - int FSUB = 102; // - - int DSUB = 103; // - - int IMUL = 104; // - - int LMUL = 105; // - - int FMUL = 106; // - - int DMUL = 107; // - - int IDIV = 108; // - - int LDIV = 109; // - - int FDIV = 110; // - - int DDIV = 111; // - - int IREM = 112; // - - int LREM = 113; // - - int FREM = 114; // - - int DREM = 115; // - - int INEG = 116; // - - int LNEG = 117; // - - int FNEG = 118; // - - int DNEG = 119; // - - int ISHL = 120; // - - int LSHL = 121; // - - int ISHR = 122; // - - int LSHR = 123; // - - int IUSHR = 124; // - - int LUSHR = 125; // - - int IAND = 126; // - - int LAND = 127; // - - int IOR = 128; // - - int LOR = 129; // - - int IXOR = 130; // - - int LXOR = 131; // - - int IINC = 132; // visitIincInsn - int I2L = 133; // visitInsn - int I2F = 134; // - - int I2D = 135; // - - int L2I = 136; // - - int L2F = 137; // - - int L2D = 138; // - - int F2I = 139; // - - int F2L = 140; // - - int F2D = 141; // - - int D2I = 142; // - - int D2L = 143; // - - int D2F = 144; // - - int I2B = 145; // - - int I2C = 146; // - - int I2S = 147; // - - int LCMP = 148; // - - int FCMPL = 149; // - - int FCMPG = 150; // - - int DCMPL = 151; // - - int DCMPG = 152; // - - int IFEQ = 153; // visitJumpInsn - int IFNE = 154; // - - int IFLT = 155; // - - int IFGE = 156; // - - int IFGT = 157; // - - int IFLE = 158; // - - int IF_ICMPEQ = 159; // - - int IF_ICMPNE = 160; // - - int IF_ICMPLT = 161; // - - int IF_ICMPGE = 162; // - - int IF_ICMPGT = 163; // - - int IF_ICMPLE = 164; // - - int IF_ACMPEQ = 165; // - - int IF_ACMPNE = 166; // - - int GOTO = 167; // - - int JSR = 168; // - - int RET = 169; // visitVarInsn - int TABLESWITCH = 170; // visiTableSwitchInsn - int LOOKUPSWITCH = 171; // visitLookupSwitch - int IRETURN = 172; // visitInsn - int LRETURN = 173; // - - int FRETURN = 174; // - - int DRETURN = 175; // - - int ARETURN = 176; // - - int RETURN = 177; // - - int GETSTATIC = 178; // visitFieldInsn - int PUTSTATIC = 179; // - - int GETFIELD = 180; // - - int PUTFIELD = 181; // - - int INVOKEVIRTUAL = 182; // visitMethodInsn - int INVOKESPECIAL = 183; // - - int INVOKESTATIC = 184; // - - int INVOKEINTERFACE = 185; // - - int INVOKEDYNAMIC = 186; // visitInvokeDynamicInsn - int NEW = 187; // visitTypeInsn - int NEWARRAY = 188; // visitIntInsn - int ANEWARRAY = 189; // visitTypeInsn - int ARRAYLENGTH = 190; // visitInsn - int ATHROW = 191; // - - int CHECKCAST = 192; // visitTypeInsn - int INSTANCEOF = 193; // - - int MONITORENTER = 194; // visitInsn - int MONITOREXIT = 195; // - - // int WIDE = 196; // NOT VISITED - int MULTIANEWARRAY = 197; // visitMultiANewArrayInsn - int IFNULL = 198; // visitJumpInsn - int IFNONNULL = 199; // - - // int GOTO_W = 200; // - - // int JSR_W = 201; // - -} diff --git a/src/org/objectweb/asm/Type.java b/src/org/objectweb/asm/Type.java deleted file mode 100644 index 599ed112..00000000 --- a/src/org/objectweb/asm/Type.java +++ /dev/null @@ -1,878 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.asm; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; - -/** - * A Java field or method type. This class can be used to make it easier to - * manipulate type and method descriptors. - * - * @author Eric Bruneton - * @author Chris Nokleberg - */ -public class Type { - - /** - * The sort of the void type. See {@link #getSort getSort}. - */ - public static final int VOID = 0; - - /** - * The sort of the boolean type. See {@link #getSort getSort}. - */ - public static final int BOOLEAN = 1; - - /** - * The sort of the char type. See {@link #getSort getSort}. - */ - public static final int CHAR = 2; - - /** - * The sort of the byte type. See {@link #getSort getSort}. - */ - public static final int BYTE = 3; - - /** - * The sort of the short type. See {@link #getSort getSort}. - */ - public static final int SHORT = 4; - - /** - * The sort of the int type. See {@link #getSort getSort}. - */ - public static final int INT = 5; - - /** - * The sort of the float type. See {@link #getSort getSort}. - */ - public static final int FLOAT = 6; - - /** - * The sort of the long type. See {@link #getSort getSort}. - */ - public static final int LONG = 7; - - /** - * The sort of the double type. See {@link #getSort getSort}. - */ - public static final int DOUBLE = 8; - - /** - * The sort of array reference types. See {@link #getSort getSort}. - */ - public static final int ARRAY = 9; - - /** - * The sort of object reference types. See {@link #getSort getSort}. - */ - public static final int OBJECT = 10; - - /** - * The sort of method types. See {@link #getSort getSort}. - */ - public static final int METHOD = 11; - - /** - * The void type. - */ - public static final Type VOID_TYPE = new Type(VOID, null, ('V' << 24) - | (5 << 16) | (0 << 8) | 0, 1); - - /** - * The boolean type. - */ - public static final Type BOOLEAN_TYPE = new Type(BOOLEAN, null, ('Z' << 24) - | (0 << 16) | (5 << 8) | 1, 1); - - /** - * The char type. - */ - public static final Type CHAR_TYPE = new Type(CHAR, null, ('C' << 24) - | (0 << 16) | (6 << 8) | 1, 1); - - /** - * The byte type. - */ - public static final Type BYTE_TYPE = new Type(BYTE, null, ('B' << 24) - | (0 << 16) | (5 << 8) | 1, 1); - - /** - * The short type. - */ - public static final Type SHORT_TYPE = new Type(SHORT, null, ('S' << 24) - | (0 << 16) | (7 << 8) | 1, 1); - - /** - * The int type. - */ - public static final Type INT_TYPE = new Type(INT, null, ('I' << 24) - | (0 << 16) | (0 << 8) | 1, 1); - - /** - * The float type. - */ - public static final Type FLOAT_TYPE = new Type(FLOAT, null, ('F' << 24) - | (2 << 16) | (2 << 8) | 1, 1); - - /** - * The long type. - */ - public static final Type LONG_TYPE = new Type(LONG, null, ('J' << 24) - | (1 << 16) | (1 << 8) | 2, 1); - - /** - * The double type. - */ - public static final Type DOUBLE_TYPE = new Type(DOUBLE, null, ('D' << 24) - | (3 << 16) | (3 << 8) | 2, 1); - - // ------------------------------------------------------------------------ - // Fields - // ------------------------------------------------------------------------ - - /** - * The sort of this Java type. - */ - private final int sort; - - /** - * A buffer containing the internal name of this Java type. This field is - * only used for reference types. - */ - private final char[] buf; - - /** - * The offset of the internal name of this Java type in {@link #buf buf} or, - * for primitive types, the size, descriptor and getOpcode offsets for this - * type (byte 0 contains the size, byte 1 the descriptor, byte 2 the offset - * for IALOAD or IASTORE, byte 3 the offset for all other instructions). - */ - private final int off; - - /** - * The length of the internal name of this Java type. - */ - private final int len; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructs a reference type. - * - * @param sort the sort of the reference type to be constructed. - * @param buf a buffer containing the descriptor of the previous type. - * @param off the offset of this descriptor in the previous buffer. - * @param len the length of this descriptor. - */ - private Type(final int sort, final char[] buf, final int off, final int len) { - this.sort = sort; - this.buf = buf; - this.off = off; - this.len = len; - } - - /** - * Returns the Java type corresponding to the given type descriptor. - * - * @param typeDescriptor a field or method type descriptor. - * @return the Java type corresponding to the given type descriptor. - */ - public static Type getType(final String typeDescriptor) { - return getType(typeDescriptor.toCharArray(), 0); - } - - /** - * Returns the Java type corresponding to the given internal name. - * - * @param internalName an internal name. - * @return the Java type corresponding to the given internal name. - */ - public static Type getObjectType(final String internalName) { - char[] buf = internalName.toCharArray(); - return new Type(buf[0] == '[' ? ARRAY : OBJECT, buf, 0, buf.length); - } - - /** - * Returns the Java type corresponding to the given method descriptor. - * Equivalent to Type.getType(methodDescriptor). - * - * @param methodDescriptor a method descriptor. - * @return the Java type corresponding to the given method descriptor. - */ - public static Type getMethodType(final String methodDescriptor) { - return getType(methodDescriptor.toCharArray(), 0); - } - - /** - * Returns the Java method type corresponding to the given argument and - * return types. - * - * @param returnType the return type of the method. - * @param argumentTypes the argument types of the method. - * @return the Java type corresponding to the given argument and return - * types. - */ - public static Type getMethodType(final Type returnType, - final Type... argumentTypes) { - return getType(getMethodDescriptor(returnType, argumentTypes)); - } - - /** - * Returns the Java type corresponding to the given class. - * - * @param c a class. - * @return the Java type corresponding to the given class. - */ - public static Type getType(final Class c) { - if (c.isPrimitive()) { - if (c == Integer.TYPE) { - return INT_TYPE; - } else if (c == Void.TYPE) { - return VOID_TYPE; - } else if (c == Boolean.TYPE) { - return BOOLEAN_TYPE; - } else if (c == Byte.TYPE) { - return BYTE_TYPE; - } else if (c == Character.TYPE) { - return CHAR_TYPE; - } else if (c == Short.TYPE) { - return SHORT_TYPE; - } else if (c == Double.TYPE) { - return DOUBLE_TYPE; - } else if (c == Float.TYPE) { - return FLOAT_TYPE; - } else /* if (c == Long.TYPE) */ { - return LONG_TYPE; - } - } else { - return getType(getDescriptor(c)); - } - } - - /** - * Returns the Java method type corresponding to the given constructor. - * - * @param c a {@link Constructor Constructor} object. - * @return the Java method type corresponding to the given constructor. - */ - public static Type getType(final Constructor c) { - return getType(getConstructorDescriptor(c)); - } - - /** - * Returns the Java method type corresponding to the given method. - * - * @param m a {@link Method Method} object. - * @return the Java method type corresponding to the given method. - */ - public static Type getType(final Method m) { - return getType(getMethodDescriptor(m)); - } - - /** - * Returns the Java types corresponding to the argument types of the given - * method descriptor. - * - * @param methodDescriptor a method descriptor. - * @return the Java types corresponding to the argument types of the given - * method descriptor. - */ - public static Type[] getArgumentTypes(final String methodDescriptor) { - char[] buf = methodDescriptor.toCharArray(); - int off = 1; - int size = 0; - while (true) { - char car = buf[off++]; - if (car == ')') { - break; - } else if (car == 'L') { - while (buf[off++] != ';') { - } - ++size; - } else if (car != '[') { - ++size; - } - } - Type[] args = new Type[size]; - off = 1; - size = 0; - while (buf[off] != ')') { - args[size] = getType(buf, off); - off += args[size].len + (args[size].sort == OBJECT ? 2 : 0); - size += 1; - } - return args; - } - - /** - * Returns the Java types corresponding to the argument types of the given - * method. - * - * @param method a method. - * @return the Java types corresponding to the argument types of the given - * method. - */ - public static Type[] getArgumentTypes(final Method method) { - Class[] classes = method.getParameterTypes(); - Type[] types = new Type[classes.length]; - for (int i = classes.length - 1; i >= 0; --i) { - types[i] = getType(classes[i]); - } - return types; - } - - /** - * Returns the Java type corresponding to the return type of the given - * method descriptor. - * - * @param methodDescriptor a method descriptor. - * @return the Java type corresponding to the return type of the given - * method descriptor. - */ - public static Type getReturnType(final String methodDescriptor) { - char[] buf = methodDescriptor.toCharArray(); - return getType(buf, methodDescriptor.indexOf(')') + 1); - } - - /** - * Returns the Java type corresponding to the return type of the given - * method. - * - * @param method a method. - * @return the Java type corresponding to the return type of the given - * method. - */ - public static Type getReturnType(final Method method) { - return getType(method.getReturnType()); - } - - /** - * 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). - */ - public 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; - } - } - } - - /** - * Returns the Java type corresponding to the given type descriptor. For - * method descriptors, buf is supposed to contain nothing more than the - * descriptor itself. - * - * @param buf a buffer containing a type descriptor. - * @param off the offset of this descriptor in the previous buffer. - * @return the Java type corresponding to the given type descriptor. - */ - private static Type getType(final char[] buf, final int off) { - int len; - switch (buf[off]) { - case 'V': - return VOID_TYPE; - case 'Z': - return BOOLEAN_TYPE; - case 'C': - return CHAR_TYPE; - case 'B': - return BYTE_TYPE; - case 'S': - return SHORT_TYPE; - case 'I': - return INT_TYPE; - case 'F': - return FLOAT_TYPE; - case 'J': - return LONG_TYPE; - case 'D': - return DOUBLE_TYPE; - case '[': - len = 1; - while (buf[off + len] == '[') { - ++len; - } - if (buf[off + len] == 'L') { - ++len; - while (buf[off + len] != ';') { - ++len; - } - } - return new Type(ARRAY, buf, off, len + 1); - case 'L': - len = 1; - while (buf[off + len] != ';') { - ++len; - } - return new Type(OBJECT, buf, off + 1, len - 1); - // case '(': - default: - return new Type(METHOD, buf, off, buf.length - off); - } - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Returns the sort of this Java type. - * - * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR}, - * {@link #BYTE BYTE}, {@link #SHORT SHORT}, {@link #INT INT}, - * {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE}, - * {@link #ARRAY ARRAY}, {@link #OBJECT OBJECT} or {@link #METHOD - * METHOD}. - */ - public int getSort() { - return sort; - } - - /** - * Returns the number of dimensions of this array type. This method should - * only be used for an array type. - * - * @return the number of dimensions of this array type. - */ - public int getDimensions() { - int i = 1; - while (buf[off + i] == '[') { - ++i; - } - return i; - } - - /** - * Returns the type of the elements of this array type. This method should - * only be used for an array type. - * - * @return Returns the type of the elements of this array type. - */ - public Type getElementType() { - return getType(buf, off + getDimensions()); - } - - /** - * Returns the binary name of the class corresponding to this type. This - * method must not be used on method types. - * - * @return the binary name of the class corresponding to this type. - */ - public String getClassName() { - switch (sort) { - case VOID: - return "void"; - case BOOLEAN: - return "boolean"; - case CHAR: - return "char"; - case BYTE: - return "byte"; - case SHORT: - return "short"; - case INT: - return "int"; - case FLOAT: - return "float"; - case LONG: - return "long"; - case DOUBLE: - return "double"; - case ARRAY: - StringBuilder sb = new StringBuilder(getElementType().getClassName()); - for (int i = getDimensions(); i > 0; --i) { - sb.append("[]"); - } - return sb.toString(); - case OBJECT: - return new String(buf, off, len).replace('/', '.'); - default: - return null; - } - } - - /** - * Returns the internal name of the class corresponding to this object or - * array type. The internal name of a class is its fully qualified name (as - * returned by Class.getName(), where '.' are replaced by '/'. This method - * should only be used for an object or array type. - * - * @return the internal name of the class corresponding to this object type. - */ - public String getInternalName() { - return new String(buf, off, len); - } - - /** - * Returns the argument types of methods of this type. This method should - * only be used for method types. - * - * @return the argument types of methods of this type. - */ - public Type[] getArgumentTypes() { - return getArgumentTypes(getDescriptor()); - } - - /** - * Returns the return type of methods of this type. This method should only - * be used for method types. - * - * @return the return type of methods of this type. - */ - public Type getReturnType() { - return getReturnType(getDescriptor()); - } - - /** - * Returns the size of the arguments and of the return value of methods of - * this type. This method should only be used for method types. - * - * @return the size of the arguments (plus one for the implicit this - * argument), argSize, and the size of the return value, retSize, - * packed into a single - * int i = (argSize << 2) | retSize - * (argSize is therefore equal to i >> 2, - * and retSize to i & 0x03). - */ - public int getArgumentsAndReturnSizes() { - return getArgumentsAndReturnSizes(getDescriptor()); - } - - // ------------------------------------------------------------------------ - // Conversion to type descriptors - // ------------------------------------------------------------------------ - - /** - * Returns the descriptor corresponding to this Java type. - * - * @return the descriptor corresponding to this Java type. - */ - public String getDescriptor() { - StringBuffer buf = new StringBuffer(); - getDescriptor(buf); - return buf.toString(); - } - - /** - * Returns the descriptor corresponding to the given argument and return - * types. - * - * @param returnType the return type of the method. - * @param argumentTypes the argument types of the method. - * @return the descriptor corresponding to the given argument and return - * types. - */ - public static String getMethodDescriptor(final Type returnType, - final Type... argumentTypes) { - StringBuffer buf = new StringBuffer(); - buf.append('('); - for (int i = 0; i < argumentTypes.length; ++i) { - argumentTypes[i].getDescriptor(buf); - } - buf.append(')'); - returnType.getDescriptor(buf); - return buf.toString(); - } - - /** - * Appends the descriptor corresponding to this Java type to the given - * string buffer. - * - * @param buf the string buffer to which the descriptor must be appended. - */ - private void getDescriptor(final StringBuffer buf) { - if (this.buf == null) { - // descriptor is in byte 3 of 'off' for primitive types (buf == - // null) - buf.append((char) ((off & 0xFF000000) >>> 24)); - } else if (sort == OBJECT) { - buf.append('L'); - buf.append(this.buf, off, len); - buf.append(';'); - } else { // sort == ARRAY || sort == METHOD - buf.append(this.buf, off, len); - } - } - - // ------------------------------------------------------------------------ - // Direct conversion from classes to type descriptors, - // without intermediate Type objects - // ------------------------------------------------------------------------ - - /** - * Returns the internal name of the given class. The internal name of a - * class is its fully qualified name, as returned by Class.getName(), where - * '.' are replaced by '/'. - * - * @param c an object or array class. - * @return the internal name of the given class. - */ - public static String getInternalName(final Class c) { - return c.getName().replace('.', '/'); - } - - /** - * Returns the descriptor corresponding to the given Java type. - * - * @param c an object class, a primitive class or an array class. - * @return the descriptor corresponding to the given class. - */ - public static String getDescriptor(final Class c) { - StringBuffer buf = new StringBuffer(); - getDescriptor(buf, c); - return buf.toString(); - } - - /** - * Returns the descriptor corresponding to the given constructor. - * - * @param c a {@link Constructor Constructor} object. - * @return the descriptor of the given constructor. - */ - public static String getConstructorDescriptor(final Constructor c) { - Class[] parameters = c.getParameterTypes(); - StringBuffer buf = new StringBuffer(); - buf.append('('); - for (int i = 0; i < parameters.length; ++i) { - getDescriptor(buf, parameters[i]); - } - return buf.append(")V").toString(); - } - - /** - * Returns the descriptor corresponding to the given method. - * - * @param m a {@link Method Method} object. - * @return the descriptor of the given method. - */ - public static String getMethodDescriptor(final Method m) { - Class[] parameters = m.getParameterTypes(); - StringBuffer buf = new StringBuffer(); - buf.append('('); - for (int i = 0; i < parameters.length; ++i) { - getDescriptor(buf, parameters[i]); - } - buf.append(')'); - getDescriptor(buf, m.getReturnType()); - return buf.toString(); - } - - /** - * Appends the descriptor of the given class to the given string buffer. - * - * @param buf the string buffer to which the descriptor must be appended. - * @param c the class whose descriptor must be computed. - */ - private static void getDescriptor(final StringBuffer buf, final Class c) { - Class d = c; - while (true) { - if (d.isPrimitive()) { - char car; - if (d == Integer.TYPE) { - car = 'I'; - } else if (d == Void.TYPE) { - car = 'V'; - } else if (d == Boolean.TYPE) { - car = 'Z'; - } else if (d == Byte.TYPE) { - car = 'B'; - } else if (d == Character.TYPE) { - car = 'C'; - } else if (d == Short.TYPE) { - car = 'S'; - } else if (d == Double.TYPE) { - car = 'D'; - } else if (d == Float.TYPE) { - car = 'F'; - } else /* if (d == Long.TYPE) */ { - car = 'J'; - } - buf.append(car); - return; - } else if (d.isArray()) { - buf.append('['); - d = d.getComponentType(); - } else { - buf.append('L'); - String name = d.getName(); - int len = name.length(); - for (int i = 0; i < len; ++i) { - char car = name.charAt(i); - buf.append(car == '.' ? '/' : car); - } - buf.append(';'); - return; - } - } - } - - // ------------------------------------------------------------------------ - // Corresponding size and opcodes - // ------------------------------------------------------------------------ - - /** - * Returns the size of values of this type. This method must not be used for - * method types. - * - * @return the size of values of this type, i.e., 2 for long and - * double, 0 for void and 1 otherwise. - */ - public int getSize() { - // the size is in byte 0 of 'off' for primitive types (buf == null) - return buf == null ? (off & 0xFF) : 1; - } - - /** - * Returns a JVM instruction opcode adapted to this Java type. This method - * must not be used for method types. - * - * @param opcode a JVM instruction opcode. This opcode must be one of ILOAD, - * ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, - * ISHL, ISHR, IUSHR, IAND, IOR, IXOR and IRETURN. - * @return an opcode that is similar to the given opcode, but adapted to - * this Java type. For example, if this type is float and - * opcode is IRETURN, this method returns FRETURN. - */ - public int getOpcode(final int opcode) { - if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) { - // the offset for IALOAD or IASTORE is in byte 1 of 'off' for - // primitive types (buf == null) - return opcode + (buf == null ? (off & 0xFF00) >> 8 : 4); - } else { - // the offset for other instructions is in byte 2 of 'off' for - // primitive types (buf == null) - return opcode + (buf == null ? (off & 0xFF0000) >> 16 : 4); - } - } - - // ------------------------------------------------------------------------ - // Equals, hashCode and toString - // ------------------------------------------------------------------------ - - /** - * Tests if the given object is equal to this type. - * - * @param o the object to be compared to this type. - * @return true if the given object is equal to this type. - */ - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (!(o instanceof Type)) { - return false; - } - Type t = (Type) o; - if (sort != t.sort) { - return false; - } - if (sort >= ARRAY) { - if (len != t.len) { - return false; - } - for (int i = off, j = t.off, end = i + len; i < end; i++, j++) { - if (buf[i] != t.buf[j]) { - return false; - } - } - } - return true; - } - - /** - * Returns a hash code value for this type. - * - * @return a hash code value for this type. - */ - @Override - public int hashCode() { - int hc = 13 * sort; - if (sort >= ARRAY) { - for (int i = off, end = i + len; i < end; i++) { - hc = 17 * (hc + buf[i]); - } - } - return hc; - } - - /** - * Returns a string representation of this type. - * - * @return the descriptor of this type. - */ - @Override - public String toString() { - return getDescriptor(); - } - - public char[] getBuf() { - return buf; - } - - public int getOff() { - return off; - } - - public int getLen() { - return len; - } -} \ No newline at end of file diff --git a/src/org/objectweb/asm/TypePath.java b/src/org/objectweb/asm/TypePath.java deleted file mode 100644 index c33ff50b..00000000 --- a/src/org/objectweb/asm/TypePath.java +++ /dev/null @@ -1,191 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2013 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 org.objectweb.asm; - -/** - * The path to a type argument, wildcard bound, array element type, or static - * inner type within an enclosing type. - * - * @author Eric Bruneton - */ -public class TypePath { - - /** - * A type path step that steps into the element type of an array type. See - * {@link #getStep getStep}. - */ - public final static int ARRAY_ELEMENT = 0; - - /** - * A type path step that steps into the nested type of a class type. See - * {@link #getStep getStep}. - */ - public final static int INNER_TYPE = 1; - - /** - * A type path step that steps into the bound of a wildcard type. See - * {@link #getStep getStep}. - */ - public final static int WILDCARD_BOUND = 2; - - /** - * A type path step that steps into a type argument of a generic type. See - * {@link #getStep getStep}. - */ - public final static int TYPE_ARGUMENT = 3; - - /** - * The byte array where the path is stored, in Java class file format. - */ - byte[] b; - - /** - * The offset of the first byte of the type path in 'b'. - */ - int offset; - - /** - * Creates a new type path. - * - * @param b the byte array containing the type path in Java class file - * format. - * @param offset the offset of the first byte of the type path in 'b'. - */ - TypePath(byte[] b, int offset) { - this.b = b; - this.offset = offset; - } - - /** - * Returns the length of this path. - * - * @return the length of this path. - */ - public int getLength() { - return b[offset]; - } - - /** - * Returns the value of the given step of this path. - * - * @param index an index between 0 and {@link #getLength()}, exclusive. - * @return {@link #ARRAY_ELEMENT ARRAY_ELEMENT}, {@link #INNER_TYPE - * INNER_TYPE}, {@link #WILDCARD_BOUND WILDCARD_BOUND}, or - * {@link #TYPE_ARGUMENT TYPE_ARGUMENT}. - */ - public int getStep(int index) { - return b[offset + 2 * index + 1]; - } - - /** - * Returns the index of the type argument that the given step is stepping - * into. This method should only be used for steps whose value is - * {@link #TYPE_ARGUMENT TYPE_ARGUMENT}. - * - * @param index an index between 0 and {@link #getLength()}, exclusive. - * @return the index of the type argument that the given step is stepping - * into. - */ - public int getStepArgument(int index) { - return b[offset + 2 * index + 2]; - } - - /** - * Converts a type path in string form, in the format used by - * {@link #toString()}, into a TypePath object. - * - * @param typePath a type path in string form, in the format used by - * {@link #toString()}. May be null or empty. - * @return the corresponding TypePath object, or null if the path is empty. - */ - public static TypePath fromString(final String typePath) { - if (typePath == null || typePath.length() == 0) { - return null; - } - int n = typePath.length(); - ByteVector out = new ByteVector(n); - out.putByte(0); - for (int i = 0; i < n; ) { - char c = typePath.charAt(i++); - if (c == '[') { - out.put11(ARRAY_ELEMENT, 0); - } else if (c == '.') { - out.put11(INNER_TYPE, 0); - } else if (c == '*') { - out.put11(WILDCARD_BOUND, 0); - } else if (c >= '0' && c <= '9') { - int typeArg = c - '0'; - while (i < n && (c = typePath.charAt(i)) >= '0' && c <= '9') { - typeArg = typeArg * 10 + c - '0'; - i += 1; - } - if (i < n && typePath.charAt(i) == ';') { - i += 1; - } - out.put11(TYPE_ARGUMENT, typeArg); - } - } - out.data[0] = (byte) (out.length / 2); - return new TypePath(out.data, 0); - } - - /** - * Returns a string representation of this type path. {@link #ARRAY_ELEMENT - * ARRAY_ELEMENT} steps are represented with '[', {@link #INNER_TYPE - * INNER_TYPE} steps with '.', {@link #WILDCARD_BOUND WILDCARD_BOUND} steps - * with '*' and {@link #TYPE_ARGUMENT TYPE_ARGUMENT} steps with their type - * argument index in decimal form followed by ';'. - */ - @Override - public String toString() { - int length = getLength(); - StringBuilder result = new StringBuilder(length * 2); - for (int i = 0; i < length; ++i) { - switch (getStep(i)) { - case ARRAY_ELEMENT: - result.append('['); - break; - case INNER_TYPE: - result.append('.'); - break; - case WILDCARD_BOUND: - result.append('*'); - break; - case TYPE_ARGUMENT: - result.append(getStepArgument(i)).append(';'); - break; - default: - result.append('_'); - } - } - return result.toString(); - } -} diff --git a/src/org/objectweb/asm/TypeReference.java b/src/org/objectweb/asm/TypeReference.java deleted file mode 100644 index 2ecd58f5..00000000 --- a/src/org/objectweb/asm/TypeReference.java +++ /dev/null @@ -1,435 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2013 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 org.objectweb.asm; - -/** - * A reference to a type appearing in a class, field or method declaration, or - * on an instruction. Such a reference designates the part of the class where - * the referenced type is appearing (e.g. an 'extends', 'implements' or 'throws' - * clause, a 'new' instruction, a 'catch' clause, a type cast, a local variable - * declaration, etc). - * - * @author Eric Bruneton - */ -public class TypeReference { - - /** - * The sort of type references that target a type parameter of a generic - * class. See {@link #getSort getSort}. - */ - public final static int CLASS_TYPE_PARAMETER = 0x00; - - /** - * The sort of type references that target a type parameter of a generic - * method. See {@link #getSort getSort}. - */ - public final static int METHOD_TYPE_PARAMETER = 0x01; - - /** - * The sort of type references that target the super class of a class or one - * of the interfaces it implements. See {@link #getSort getSort}. - */ - public final static int CLASS_EXTENDS = 0x10; - - /** - * The sort of type references that target a bound of a type parameter of a - * generic class. See {@link #getSort getSort}. - */ - public final static int CLASS_TYPE_PARAMETER_BOUND = 0x11; - - /** - * The sort of type references that target a bound of a type parameter of a - * generic method. See {@link #getSort getSort}. - */ - public final static int METHOD_TYPE_PARAMETER_BOUND = 0x12; - - /** - * The sort of type references that target the type of a field. See - * {@link #getSort getSort}. - */ - public final static int FIELD = 0x13; - - /** - * The sort of type references that target the return type of a method. See - * {@link #getSort getSort}. - */ - public final static int METHOD_RETURN = 0x14; - - /** - * The sort of type references that target the receiver type of a method. - * See {@link #getSort getSort}. - */ - public final static int METHOD_RECEIVER = 0x15; - - /** - * The sort of type references that target the type of a formal parameter of - * a method. See {@link #getSort getSort}. - */ - public final static int METHOD_FORMAL_PARAMETER = 0x16; - - /** - * The sort of type references that target the type of an exception declared - * in the throws clause of a method. See {@link #getSort getSort}. - */ - public final static int THROWS = 0x17; - - /** - * The sort of type references that target the type of a local variable in a - * method. See {@link #getSort getSort}. - */ - public final static int LOCAL_VARIABLE = 0x40; - - /** - * The sort of type references that target the type of a resource variable - * in a method. See {@link #getSort getSort}. - */ - public final static int RESOURCE_VARIABLE = 0x41; - - /** - * The sort of type references that target the type of the exception of a - * 'catch' clause in a method. See {@link #getSort getSort}. - */ - public final static int EXCEPTION_PARAMETER = 0x42; - - /** - * The sort of type references that target the type declared in an - * 'instanceof' instruction. See {@link #getSort getSort}. - */ - public final static int INSTANCEOF = 0x43; - - /** - * The sort of type references that target the type of the object created by - * a 'new' instruction. See {@link #getSort getSort}. - */ - public final static int NEW = 0x44; - - /** - * The sort of type references that target the receiver type of a - * constructor reference. See {@link #getSort getSort}. - */ - public final static int CONSTRUCTOR_REFERENCE = 0x45; - - /** - * The sort of type references that target the receiver type of a method - * reference. See {@link #getSort getSort}. - */ - public final static int METHOD_REFERENCE = 0x46; - - /** - * The sort of type references that target the type declared in an explicit - * or implicit cast instruction. See {@link #getSort getSort}. - */ - public final static int CAST = 0x47; - - /** - * The sort of type references that target a type parameter of a generic - * constructor in a constructor call. See {@link #getSort getSort}. - */ - public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48; - - /** - * The sort of type references that target a type parameter of a generic - * method in a method call. See {@link #getSort getSort}. - */ - public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49; - - /** - * The sort of type references that target a type parameter of a generic - * constructor in a constructor reference. See {@link #getSort getSort}. - */ - public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A; - - /** - * The sort of type references that target a type parameter of a generic - * method in a method reference. See {@link #getSort getSort}. - */ - public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B; - - /** - * The type reference value in Java class file format. - */ - private int value; - - /** - * Creates a new TypeReference. - * - * @param typeRef the int encoded value of the type reference, as received in a - * visit method related to type annotations, like - * visitTypeAnnotation. - */ - public TypeReference(int typeRef) { - this.value = typeRef; - } - - /** - * Returns a type reference of the given sort. - * - * @param sort {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN}, - * {@link #METHOD_RECEIVER METHOD_RECEIVER}, - * {@link #LOCAL_VARIABLE LOCAL_VARIABLE}, - * {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE}, - * {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW}, - * {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, or - * {@link #METHOD_REFERENCE METHOD_REFERENCE}. - * @return a type reference of the given sort. - */ - public static TypeReference newTypeReference(int sort) { - return new TypeReference(sort << 24); - } - - /** - * Returns a reference to a type parameter of a generic class or method. - * - * @param sort {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or - * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}. - * @param paramIndex the type parameter index. - * @return a reference to the given generic class or method type parameter. - */ - public static TypeReference newTypeParameterReference(int sort, - int paramIndex) { - return new TypeReference((sort << 24) | (paramIndex << 16)); - } - - /** - * Returns a reference to a type parameter bound of a generic class or - * method. - * - * @param sort {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or - * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}. - * @param paramIndex the type parameter index. - * @param boundIndex the type bound index within the above type parameters. - * @return a reference to the given generic class or method type parameter - * bound. - */ - public static TypeReference newTypeParameterBoundReference(int sort, - int paramIndex, int boundIndex) { - return new TypeReference((sort << 24) | (paramIndex << 16) - | (boundIndex << 8)); - } - - /** - * Returns a reference to the super class or to an interface of the - * 'implements' clause of a class. - * - * @param itfIndex the index of an interface in the 'implements' clause of a - * class, or -1 to reference the super class of the class. - * @return a reference to the given super type of a class. - */ - public static TypeReference newSuperTypeReference(int itfIndex) { - itfIndex &= 0xFFFF; - return new TypeReference((CLASS_EXTENDS << 24) | (itfIndex << 8)); - } - - /** - * Returns a reference to the type of a formal parameter of a method. - * - * @param paramIndex the formal parameter index. - * @return a reference to the type of the given method formal parameter. - */ - public static TypeReference newFormalParameterReference(int paramIndex) { - return new TypeReference((METHOD_FORMAL_PARAMETER << 24) - | (paramIndex << 16)); - } - - /** - * Returns a reference to the type of an exception, in a 'throws' clause of - * a method. - * - * @param exceptionIndex the index of an exception in a 'throws' clause of a method. - * @return a reference to the type of the given exception. - */ - public static TypeReference newExceptionReference(int exceptionIndex) { - return new TypeReference((THROWS << 24) | (exceptionIndex << 8)); - } - - /** - * Returns a reference to the type of the exception declared in a 'catch' - * clause of a method. - * - * @param tryCatchBlockIndex the index of a try catch block (using the order in which they - * are visited with visitTryCatchBlock). - * @return a reference to the type of the given exception. - */ - public static TypeReference newTryCatchReference(int tryCatchBlockIndex) { - return new TypeReference((EXCEPTION_PARAMETER << 24) - | (tryCatchBlockIndex << 8)); - } - - /** - * Returns a reference to the type of a type argument in a constructor or - * method call or reference. - * - * @param sort {@link #CAST CAST}, - * {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT - * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, - * {@link #METHOD_INVOCATION_TYPE_ARGUMENT - * METHOD_INVOCATION_TYPE_ARGUMENT}, - * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT - * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or - * {@link #METHOD_REFERENCE_TYPE_ARGUMENT - * METHOD_REFERENCE_TYPE_ARGUMENT}. - * @param argIndex the type argument index. - * @return a reference to the type of the given type argument. - */ - public static TypeReference newTypeArgumentReference(int sort, int argIndex) { - return new TypeReference((sort << 24) | argIndex); - } - - /** - * Returns the sort of this type reference. - * - * @return {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER}, - * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}, - * {@link #CLASS_EXTENDS CLASS_EXTENDS}, - * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND}, - * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}, - * {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN}, - * {@link #METHOD_RECEIVER METHOD_RECEIVER}, - * {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER}, - * {@link #THROWS THROWS}, {@link #LOCAL_VARIABLE LOCAL_VARIABLE}, - * {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE}, - * {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER}, - * {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW}, - * {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, - * {@link #METHOD_REFERENCE METHOD_REFERENCE}, {@link #CAST CAST}, - * {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT - * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, - * {@link #METHOD_INVOCATION_TYPE_ARGUMENT - * METHOD_INVOCATION_TYPE_ARGUMENT}, - * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT - * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or - * {@link #METHOD_REFERENCE_TYPE_ARGUMENT - * METHOD_REFERENCE_TYPE_ARGUMENT}. - */ - public int getSort() { - return value >>> 24; - } - - /** - * Returns the index of the type parameter referenced by this type - * reference. This method must only be used for type references whose sort - * is {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER}, - * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}, - * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or - * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}. - * - * @return a type parameter index. - */ - public int getTypeParameterIndex() { - return (value & 0x00FF0000) >> 16; - } - - /** - * Returns the index of the type parameter bound, within the type parameter - * {@link #getTypeParameterIndex}, referenced by this type reference. This - * method must only be used for type references whose sort is - * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or - * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}. - * - * @return a type parameter bound index. - */ - public int getTypeParameterBoundIndex() { - return (value & 0x0000FF00) >> 8; - } - - /** - * Returns the index of the "super type" of a class that is referenced by - * this type reference. This method must only be used for type references - * whose sort is {@link #CLASS_EXTENDS CLASS_EXTENDS}. - * - * @return the index of an interface in the 'implements' clause of a class, - * or -1 if this type reference references the type of the super - * class. - */ - public int getSuperTypeIndex() { - return (short) ((value & 0x00FFFF00) >> 8); - } - - /** - * Returns the index of the formal parameter whose type is referenced by - * this type reference. This method must only be used for type references - * whose sort is {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER}. - * - * @return a formal parameter index. - */ - public int getFormalParameterIndex() { - return (value & 0x00FF0000) >> 16; - } - - /** - * Returns the index of the exception, in a 'throws' clause of a method, - * whose type is referenced by this type reference. This method must only be - * used for type references whose sort is {@link #THROWS THROWS}. - * - * @return the index of an exception in the 'throws' clause of a method. - */ - public int getExceptionIndex() { - return (value & 0x00FFFF00) >> 8; - } - - /** - * Returns the index of the try catch block (using the order in which they - * are visited with visitTryCatchBlock), whose 'catch' type is referenced by - * this type reference. This method must only be used for type references - * whose sort is {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER} . - * - * @return the index of an exception in the 'throws' clause of a method. - */ - public int getTryCatchBlockIndex() { - return (value & 0x00FFFF00) >> 8; - } - - /** - * Returns the index of the type argument referenced by this type reference. - * This method must only be used for type references whose sort is - * {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT - * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, - * {@link #METHOD_INVOCATION_TYPE_ARGUMENT METHOD_INVOCATION_TYPE_ARGUMENT}, - * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT - * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or - * {@link #METHOD_REFERENCE_TYPE_ARGUMENT METHOD_REFERENCE_TYPE_ARGUMENT}. - * - * @return a type parameter index. - */ - public int getTypeArgumentIndex() { - return value & 0xFF; - } - - /** - * Returns the int encoded value of this type reference, suitable for use in - * visit methods related to type annotations, like visitTypeAnnotation. - * - * @return the int encoded value of this type reference. - */ - public int getValue() { - return value; - } -} diff --git a/src/org/objectweb/asm/commons/AdviceAdapter.java b/src/org/objectweb/asm/commons/AdviceAdapter.java deleted file mode 100644 index c9596ca6..00000000 --- a/src/org/objectweb/asm/commons/AdviceAdapter.java +++ /dev/null @@ -1,639 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.asm.commons; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.objectweb.asm.Handle; -import org.objectweb.asm.Label; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; - -/** - * A {@link org.objectweb.asm.MethodVisitor} 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 api the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @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 int api, final MethodVisitor mv, - final int access, final String name, final String desc) { - super(api, 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 = 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); - } - } - - @Deprecated - @Override - public void visitMethodInsn(final int opcode, final String owner, - final String name, final String desc) { - if (api >= Opcodes.ASM5) { - super.visitMethodInsn(opcode, owner, name, desc); - return; - } - doVisitMethodInsn(opcode, owner, name, desc, - opcode == Opcodes.INVOKEINTERFACE); - } - - @Override - public void visitMethodInsn(final int opcode, final String owner, - final String name, final String desc, final boolean itf) { - if (api < Opcodes.ASM5) { - super.visitMethodInsn(opcode, owner, name, desc, itf); - return; - } - doVisitMethodInsn(opcode, owner, name, desc, itf); - } - - private void doVisitMethodInsn(int opcode, final String owner, - final String name, final String desc, final boolean itf) { - mv.visitMethodInsn(opcode, owner, name, desc, itf); - if (constructor) { - Type[] types = Type.getArgumentTypes(desc); - for (int i = 0; i < types.length; i++) { - popValue(); - if (types[i].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 visitInvokeDynamicInsn(String name, String desc, Handle bsm, - Object... bsmArgs) { - mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); - if (constructor) { - Type[] types = Type.getArgumentTypes(desc); - for (int i = 0; i < types.length; i++) { - popValue(); - if (types[i].getSize() == 2) { - popValue(); - } - } - - 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); - } - } - - @Override - public void visitTryCatchBlock(Label start, Label end, Label handler, - String type) { - super.visitTryCatchBlock(start, end, handler, type); - if (constructor && !branches.containsKey(handler)) { - List stackFrame = new ArrayList(); - stackFrame.add(OTHER); - branches.put(handler, stackFrame); - } - } - - private void addBranches(final Label dflt, final Label[] labels) { - addBranch(dflt); - for (int i = 0; i < labels.length; i++) { - addBranch(labels[i]); - } - } - - 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 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(Object param, int opcode) {
-     *     ...
-     * 
- *

- *
- *
- *

- * 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/src/org/objectweb/asm/commons/AnalyzerAdapter.java b/src/org/objectweb/asm/commons/AnalyzerAdapter.java deleted file mode 100644 index c0ccbb6a..00000000 --- a/src/org/objectweb/asm/commons/AnalyzerAdapter.java +++ /dev/null @@ -1,935 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 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 org.objectweb.asm.commons; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.objectweb.asm.Handle; -import org.objectweb.asm.Label; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; - -/** - * A {@link MethodVisitor} 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 org.objectweb.asm.ClassReader#EXPAND_FRAMES} option. Each - * visitX 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 visitX methods (this - * requires a reference to the AnalyzerAdapter that is before it in the chain). - * If this adapter is used with a class that does not contain stack map table - * attributes (i.e., pre Java 6 classes) then this adapter may not be able to - * compute the stack map frame for each instruction. In this case no exception - * is thrown but the {@link #locals} and {@link #stack} fields will be null for - * these instructions. - * - * @author Eric Bruneton - */ -public class AnalyzerAdapter extends MethodVisitor { - - /** - * 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 - * 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 unreachable - * 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 - * 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 unreachable - * instructions. - */ - public List stack; - - /** - * The labels that designate the next instruction to be visited. May be - * null. - */ - private List