From d55923e6a04aff1775b7d4b458e345205000fb80 Mon Sep 17 00:00:00 2001 From: "Cloud.Liu" Date: Tue, 11 May 2021 20:24:28 +0800 Subject: [PATCH 1/3] =?UTF-8?q?REPORT-51412=20fix:=20third=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=8C=85=E6=BC=8F=E6=94=B9pom?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- base-third-project/base-third-step3/pom.xml | 1 - base-third-project/base-third-step8/pom.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/base-third-project/base-third-step3/pom.xml b/base-third-project/base-third-step3/pom.xml index e8da71e05..578c8b59f 100644 --- a/base-third-project/base-third-step3/pom.xml +++ b/base-third-project/base-third-step3/pom.xml @@ -16,7 +16,6 @@ ../../fine-itext - ../../fine-javassist ../../fine-jedis ../../fine-jboss-logging diff --git a/base-third-project/base-third-step8/pom.xml b/base-third-project/base-third-step8/pom.xml index af1c0c7cc..7590473d7 100644 --- a/base-third-project/base-third-step8/pom.xml +++ b/base-third-project/base-third-step8/pom.xml @@ -16,7 +16,6 @@ ../../fine-ehcache - ../../fine-transmittable-thread-local From 0f7c125ff12d3688b5a74c93abadc8ddc395ea3f Mon Sep 17 00:00:00 2001 From: "Cloud.Liu" Date: Tue, 11 May 2021 09:45:11 +0800 Subject: [PATCH 2/3] =?UTF-8?q?REPORT-51412=20fix:=20=E7=A7=BB=E9=99=A4fin?= =?UTF-8?q?e-third=E7=9A=84TTL=E5=92=8Cjavaassist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.third_step3-jdk11.gradle | 3 - build.third_step3.gradle | 3 - build.third_step8-jdk11.gradle | 2 - build.third_step8.gradle | 2 - fine-hibernate/pom.xml | 6 +- fine-javassist/.gitignore | 6 - fine-javassist/README.md | 2 - fine-javassist/pom.xml | 18 - .../third/javassist/ByteArrayClassPath.java | 99 - .../javassist/CannotCompileException.java | 120 - .../fr/third/javassist/ClassClassPath.java | 97 - .../java/com/fr/third/javassist/ClassMap.java | 173 -- .../com/fr/third/javassist/ClassPath.java | 68 - .../com/fr/third/javassist/ClassPool.java | 1164 ---------- .../com/fr/third/javassist/ClassPoolTail.java | 429 ---- .../com/fr/third/javassist/CodeConverter.java | 809 ------- .../java/com/fr/third/javassist/CtArray.java | 113 - .../com/fr/third/javassist/CtBehavior.java | 1215 ---------- .../java/com/fr/third/javassist/CtClass.java | 1558 ------------- .../com/fr/third/javassist/CtClassType.java | 1722 -------------- .../com/fr/third/javassist/CtConstructor.java | 403 ---- .../java/com/fr/third/javassist/CtField.java | 1414 ------------ .../java/com/fr/third/javassist/CtMember.java | 322 --- .../java/com/fr/third/javassist/CtMethod.java | 436 ---- .../com/fr/third/javassist/CtNewClass.java | 127 -- .../fr/third/javassist/CtNewConstructor.java | 317 --- .../com/fr/third/javassist/CtNewMethod.java | 476 ---- .../fr/third/javassist/CtNewNestedClass.java | 67 - .../javassist/CtNewWrappedConstructor.java | 103 - .../third/javassist/CtNewWrappedMethod.java | 199 -- .../fr/third/javassist/CtPrimitiveType.java | 112 - .../java/com/fr/third/javassist/Loader.java | 433 ---- .../fr/third/javassist/LoaderClassPath.java | 96 - .../java/com/fr/third/javassist/Modifier.java | 219 -- .../fr/third/javassist/NotFoundException.java | 30 - .../fr/third/javassist/SerialVersionUID.java | 212 -- .../com/fr/third/javassist/Translator.java | 71 - .../com/fr/third/javassist/URLClassPath.java | 179 -- .../third/javassist/bytecode/AccessFlag.java | 133 -- .../bytecode/AnnotationDefaultAttribute.java | 161 -- .../bytecode/AnnotationsAttribute.java | 703 ------ .../javassist/bytecode/AttributeInfo.java | 289 --- .../third/javassist/bytecode/BadBytecode.java | 40 - .../bytecode/BootstrapMethodsAttribute.java | 123 - .../third/javassist/bytecode/ByteArray.java | 77 - .../third/javassist/bytecode/ByteStream.java | 194 -- .../fr/third/javassist/bytecode/Bytecode.java | 1430 ------------ .../third/javassist/bytecode/ClassFile.java | 909 -------- .../javassist/bytecode/ClassFilePrinter.java | 154 -- .../javassist/bytecode/ClassFileWriter.java | 782 ------- .../javassist/bytecode/CodeAnalyzer.java | 267 --- .../javassist/bytecode/CodeAttribute.java | 594 ----- .../javassist/bytecode/CodeIterator.java | 1599 ------------- .../third/javassist/bytecode/ConstPool.java | 1991 ----------------- .../javassist/bytecode/ConstantAttribute.java | 73 - .../bytecode/DeprecatedAttribute.java | 56 - .../third/javassist/bytecode/Descriptor.java | 872 -------- .../bytecode/DuplicateMemberException.java | 31 - .../bytecode/EnclosingMethodAttribute.java | 134 -- .../javassist/bytecode/ExceptionTable.java | 281 --- .../bytecode/ExceptionsAttribute.java | 174 -- .../third/javassist/bytecode/FieldInfo.java | 269 --- .../bytecode/InnerClassesAttribute.java | 242 -- .../bytecode/InstructionPrinter.java | 295 --- .../bytecode/LineNumberAttribute.java | 182 -- .../bytecode/LocalVariableAttribute.java | 334 --- .../bytecode/LocalVariableTypeAttribute.java | 63 - .../third/javassist/bytecode/LongVector.java | 64 - .../third/javassist/bytecode/MethodInfo.java | 551 ----- .../fr/third/javassist/bytecode/Mnemonic.java | 239 -- .../fr/third/javassist/bytecode/Opcode.java | 449 ---- .../ParameterAnnotationsAttribute.java | 215 -- .../bytecode/SignatureAttribute.java | 1170 ---------- .../bytecode/SourceFileAttribute.java | 71 - .../fr/third/javassist/bytecode/StackMap.java | 575 ----- .../javassist/bytecode/StackMapTable.java | 1051 --------- .../bytecode/SyntheticAttribute.java | 56 - .../javassist/bytecode/analysis/Analyzer.java | 423 ---- .../bytecode/analysis/ControlFlow.java | 504 ----- .../javassist/bytecode/analysis/Executor.java | 1047 --------- .../javassist/bytecode/analysis/Frame.java | 289 --- .../bytecode/analysis/FramePrinter.java | 148 -- .../javassist/bytecode/analysis/IntQueue.java | 57 - .../bytecode/analysis/MultiArrayType.java | 130 -- .../bytecode/analysis/MultiType.java | 314 --- .../bytecode/analysis/Subroutine.java | 67 - .../bytecode/analysis/SubroutineScanner.java | 157 -- .../javassist/bytecode/analysis/Type.java | 593 ----- .../javassist/bytecode/analysis/Util.java | 48 - .../javassist/bytecode/analysis/package.html | 20 - .../bytecode/annotation/Annotation.java | 351 --- .../bytecode/annotation/AnnotationImpl.java | 305 --- .../annotation/AnnotationMemberValue.java | 97 - .../annotation/AnnotationsWriter.java | 356 --- .../bytecode/annotation/ArrayMemberValue.java | 146 -- .../annotation/BooleanMemberValue.java | 104 - .../bytecode/annotation/ByteMemberValue.java | 104 - .../bytecode/annotation/CharMemberValue.java | 105 - .../bytecode/annotation/ClassMemberValue.java | 140 -- .../annotation/DoubleMemberValue.java | 106 - .../bytecode/annotation/EnumMemberValue.java | 126 -- .../bytecode/annotation/FloatMemberValue.java | 106 - .../annotation/IntegerMemberValue.java | 111 - .../bytecode/annotation/LongMemberValue.java | 105 - .../bytecode/annotation/MemberValue.java | 88 - .../annotation/MemberValueVisitor.java | 39 - .../bytecode/annotation/NoSuchClassError.java | 40 - .../bytecode/annotation/ShortMemberValue.java | 105 - .../annotation/StringMemberValue.java | 105 - .../bytecode/annotation/package.html | 8 - .../fr/third/javassist/bytecode/package.html | 18 - .../bytecode/stackmap/BasicBlock.java | 411 ---- .../javassist/bytecode/stackmap/MapMaker.java | 605 ----- .../javassist/bytecode/stackmap/Tracer.java | 933 -------- .../javassist/bytecode/stackmap/TypeData.java | 786 ------- .../javassist/bytecode/stackmap/TypeTag.java | 30 - .../bytecode/stackmap/TypedBlock.java | 234 -- .../javassist/compiler/AccessorMaker.java | 261 --- .../fr/third/javassist/compiler/CodeGen.java | 1923 ---------------- .../javassist/compiler/CompileError.java | 53 - .../fr/third/javassist/compiler/Javac.java | 610 ----- .../third/javassist/compiler/JvstCodeGen.java | 712 ------ .../javassist/compiler/JvstTypeChecker.java | 282 --- .../javassist/compiler/KeywordTable.java | 33 - .../com/fr/third/javassist/compiler/Lex.java | 551 ----- .../javassist/compiler/MemberCodeGen.java | 1147 ---------- .../javassist/compiler/MemberResolver.java | 605 ----- .../javassist/compiler/NoFieldException.java | 40 - .../fr/third/javassist/compiler/Parser.java | 1343 ----------- .../javassist/compiler/ProceedHandler.java | 31 - .../third/javassist/compiler/SymbolTable.java | 45 - .../third/javassist/compiler/SyntaxError.java | 23 - .../fr/third/javassist/compiler/TokenId.java | 125 -- .../third/javassist/compiler/TypeChecker.java | 1018 --------- .../third/javassist/compiler/ast/ASTList.java | 160 -- .../third/javassist/compiler/ast/ASTree.java | 59 - .../javassist/compiler/ast/ArrayInit.java | 32 - .../javassist/compiler/ast/AssignExpr.java | 41 - .../third/javassist/compiler/ast/BinExpr.java | 42 - .../javassist/compiler/ast/CallExpr.java | 47 - .../javassist/compiler/ast/CastExpr.java | 56 - .../javassist/compiler/ast/CondExpr.java | 44 - .../javassist/compiler/ast/Declarator.java | 128 -- .../javassist/compiler/ast/DoubleConst.java | 95 - .../fr/third/javassist/compiler/ast/Expr.java | 85 - .../javassist/compiler/ast/FieldDecl.java | 35 - .../compiler/ast/InstanceOfExpr.java | 40 - .../javassist/compiler/ast/IntConst.java | 139 -- .../third/javassist/compiler/ast/Keyword.java | 36 - .../third/javassist/compiler/ast/Member.java | 40 - .../javassist/compiler/ast/MethodDecl.java | 46 - .../third/javassist/compiler/ast/NewExpr.java | 78 - .../fr/third/javassist/compiler/ast/Pair.java | 52 - .../third/javassist/compiler/ast/Stmnt.java | 60 - .../third/javassist/compiler/ast/StringL.java | 36 - .../third/javassist/compiler/ast/Symbol.java | 36 - .../javassist/compiler/ast/Variable.java | 39 - .../third/javassist/compiler/ast/Visitor.java | 52 - .../convert/TransformAccessArrayField.java | 269 --- .../javassist/convert/TransformAfter.java | 47 - .../javassist/convert/TransformBefore.java | 108 - .../javassist/convert/TransformCall.java | 130 -- .../convert/TransformFieldAccess.java | 82 - .../third/javassist/convert/TransformNew.java | 103 - .../javassist/convert/TransformNewClass.java | 83 - .../javassist/convert/TransformReadField.java | 96 - .../convert/TransformWriteField.java | 72 - .../third/javassist/convert/Transformer.java | 58 - .../com/fr/third/javassist/expr/Cast.java | 166 -- .../third/javassist/expr/ConstructorCall.java | 70 - .../com/fr/third/javassist/expr/Expr.java | 330 --- .../fr/third/javassist/expr/ExprEditor.java | 320 --- .../fr/third/javassist/expr/FieldAccess.java | 325 --- .../com/fr/third/javassist/expr/Handler.java | 146 -- .../fr/third/javassist/expr/Instanceof.java | 170 -- .../fr/third/javassist/expr/MethodCall.java | 247 -- .../com/fr/third/javassist/expr/NewArray.java | 283 --- .../com/fr/third/javassist/expr/NewExpr.java | 248 -- .../com/fr/third/javassist/expr/package.html | 8 - .../java/com/fr/third/javassist/package.html | 22 - .../com/fr/third/javassist/runtime/Cflow.java | 55 - .../com/fr/third/javassist/runtime/Desc.java | 161 -- .../fr/third/javassist/runtime/DotClass.java | 29 - .../com/fr/third/javassist/runtime/Inner.java | 25 - .../fr/third/javassist/runtime/package.html | 12 - .../javassist/scopedpool/ScopedClassPool.java | 309 --- .../scopedpool/ScopedClassPoolFactory.java | 39 - .../ScopedClassPoolFactoryImpl.java | 43 - .../scopedpool/ScopedClassPoolRepository.java | 98 - .../ScopedClassPoolRepositoryImpl.java | 188 -- .../scopedpool/SoftValueHashMap.java | 233 -- .../third/javassist/scopedpool/package.html | 7 - .../com/fr/third/javassist/tools/Dump.java | 58 - .../fr/third/javassist/tools/framedump.java | 48 - .../com/fr/third/javassist/tools/package.html | 6 - .../tools/reflect/CannotCreateException.java | 30 - .../tools/reflect/CannotInvokeException.java | 69 - .../tools/reflect/CannotReflectException.java | 35 - .../tools/reflect/ClassMetaobject.java | 370 --- .../javassist/tools/reflect/Compiler.java | 163 -- .../third/javassist/tools/reflect/Loader.java | 164 -- .../javassist/tools/reflect/Metalevel.java | 39 - .../javassist/tools/reflect/Metaobject.java | 237 -- .../javassist/tools/reflect/Reflection.java | 404 ---- .../third/javassist/tools/reflect/Sample.java | 57 - .../javassist/tools/reflect/package.html | 35 - .../javassist/tools/rmi/AppletServer.java | 251 --- .../javassist/tools/rmi/ObjectImporter.java | 301 --- .../tools/rmi/ObjectNotFoundException.java | 27 - .../fr/third/javassist/tools/rmi/Proxy.java | 26 - .../javassist/tools/rmi/RemoteException.java | 31 - .../third/javassist/tools/rmi/RemoteRef.java | 36 - .../fr/third/javassist/tools/rmi/Sample.java | 37 - .../javassist/tools/rmi/StubGenerator.java | 257 --- .../fr/third/javassist/tools/rmi/package.html | 16 - .../javassist/tools/web/BadHttpRequest.java | 35 - .../fr/third/javassist/tools/web/Viewer.java | 209 -- .../third/javassist/tools/web/Webserver.java | 409 ---- .../fr/third/javassist/tools/web/package.html | 7 - .../fr/third/javassist/util/HotSwapper.java | 253 --- .../com/fr/third/javassist/util/package.html | 5 - .../javassist/util/proxy/FactoryHelper.java | 237 -- .../javassist/util/proxy/MethodFilter.java | 31 - .../javassist/util/proxy/MethodHandler.java | 49 - .../fr/third/javassist/util/proxy/Proxy.java | 33 - .../javassist/util/proxy/ProxyFactory.java | 1445 ------------ .../javassist/util/proxy/ProxyObject.java | 44 - .../util/proxy/ProxyObjectInputStream.java | 100 - .../util/proxy/ProxyObjectOutputStream.java | 72 - .../javassist/util/proxy/RuntimeSupport.java | 271 --- .../javassist/util/proxy/SecurityActions.java | 136 -- .../javassist/util/proxy/SerializedProxy.java | 98 - .../third/javassist/util/proxy/package.html | 6 - fine-transmittable-thread-local/pom.xml | 36 - .../alibaba/ttl/TransmittableThreadLocal.java | 752 ------- .../com/fr/third/alibaba/ttl/TtlCallable.java | 260 --- .../com/fr/third/alibaba/ttl/TtlCopier.java | 29 - .../com/fr/third/alibaba/ttl/TtlEnhanced.java | 15 - .../third/alibaba/ttl/TtlRecursiveAction.java | 63 - .../third/alibaba/ttl/TtlRecursiveTask.java | 72 - .../com/fr/third/alibaba/ttl/TtlRunnable.java | 260 --- .../fr/third/alibaba/ttl/TtlTimerTask.java | 193 -- .../com/fr/third/alibaba/ttl/TtlUnwrap.java | 70 - .../com/fr/third/alibaba/ttl/TtlWrappers.java | 342 --- .../fr/third/alibaba/ttl/package-info.java | 9 - .../third/alibaba/ttl/spi/TtlAttachments.java | 38 - .../ttl/spi/TtlAttachmentsDelegate.java | 30 - .../fr/third/alibaba/ttl/spi/TtlEnhanced.java | 20 - .../fr/third/alibaba/ttl/spi/TtlWrapper.java | 25 - .../third/alibaba/ttl/spi/package-info.java | 9 - ...nheritableForkJoinWorkerThreadFactory.java | 20 - ...bleForkJoinWorkerThreadFactoryWrapper.java | 56 - .../DisableInheritableThreadFactory.java | 21 - ...isableInheritableThreadFactoryWrapper.java | 55 - .../threadpool/ExecutorServiceTtlWrapper.java | 100 - .../ttl/threadpool/ExecutorTtlWrapper.java | 55 - .../ScheduledExecutorServiceTtlWrapper.java | 60 - .../alibaba/ttl/threadpool/TtlExecutors.java | 170 -- .../ttl/threadpool/TtlForkJoinPoolHelper.java | 72 - .../alibaba/ttl/threadpool/TtlUtils.java | 39 - .../ttl/threadpool/agent/TtlAgent.java | 239 -- .../ttl/threadpool/agent/TtlTransformer.java | 71 - .../agent/internal/logging/Logger.java | 80 - .../internal/transformlet/ClassInfo.java | 77 - .../transformlet/JavassistTransformlet.java | 16 - .../impl/TtlExecutorTransformlet.java | 160 -- .../impl/TtlForkJoinTransformlet.java | 83 - .../impl/TtlTimerTaskTransformlet.java | 68 - .../internal/transformlet/impl/Utils.java | 82 - .../internal/transformlet/package-info.java | 7 - .../ttl/threadpool/agent/package-info.java | 10 - .../alibaba/ttl/threadpool/package-info.java | 6 - 272 files changed, 3 insertions(+), 63945 deletions(-) delete mode 100644 fine-javassist/.gitignore delete mode 100644 fine-javassist/README.md delete mode 100644 fine-javassist/pom.xml delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/ByteArrayClassPath.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CannotCompileException.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/ClassClassPath.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/ClassMap.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/ClassPath.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/ClassPool.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/ClassPoolTail.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CodeConverter.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CtArray.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CtBehavior.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CtClass.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CtClassType.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CtConstructor.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CtField.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CtMember.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CtMethod.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CtNewClass.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CtNewConstructor.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CtNewMethod.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CtNewNestedClass.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CtNewWrappedConstructor.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CtNewWrappedMethod.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/CtPrimitiveType.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/Loader.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/LoaderClassPath.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/Modifier.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/NotFoundException.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/SerialVersionUID.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/Translator.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/URLClassPath.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/AccessFlag.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/AnnotationDefaultAttribute.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/AnnotationsAttribute.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/AttributeInfo.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/BadBytecode.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/BootstrapMethodsAttribute.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ByteArray.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ByteStream.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/Bytecode.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ClassFile.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ClassFilePrinter.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ClassFileWriter.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/CodeAnalyzer.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/CodeAttribute.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/CodeIterator.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ConstPool.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ConstantAttribute.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/DeprecatedAttribute.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/Descriptor.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/DuplicateMemberException.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/EnclosingMethodAttribute.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ExceptionTable.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ExceptionsAttribute.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/FieldInfo.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/InnerClassesAttribute.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/InstructionPrinter.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/LineNumberAttribute.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/LocalVariableAttribute.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/LocalVariableTypeAttribute.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/LongVector.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/MethodInfo.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/Mnemonic.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/Opcode.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ParameterAnnotationsAttribute.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/SignatureAttribute.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/SourceFileAttribute.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/StackMap.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/StackMapTable.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/SyntheticAttribute.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Analyzer.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/ControlFlow.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Executor.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Frame.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/FramePrinter.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/IntQueue.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/MultiArrayType.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/MultiType.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Subroutine.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/SubroutineScanner.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Type.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Util.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/package.html delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/Annotation.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/AnnotationImpl.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/AnnotationMemberValue.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/AnnotationsWriter.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/ArrayMemberValue.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/BooleanMemberValue.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/ByteMemberValue.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/CharMemberValue.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/ClassMemberValue.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/DoubleMemberValue.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/EnumMemberValue.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/FloatMemberValue.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/IntegerMemberValue.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/LongMemberValue.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/MemberValue.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/MemberValueVisitor.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/NoSuchClassError.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/ShortMemberValue.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/StringMemberValue.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/package.html delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/package.html delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/BasicBlock.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/MapMaker.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/Tracer.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/TypeData.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/TypeTag.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/TypedBlock.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/AccessorMaker.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/CodeGen.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/CompileError.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/Javac.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/JvstCodeGen.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/JvstTypeChecker.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/KeywordTable.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/Lex.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/MemberCodeGen.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/MemberResolver.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/NoFieldException.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/Parser.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ProceedHandler.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/SymbolTable.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/SyntaxError.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/TokenId.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/TypeChecker.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/ASTList.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/ASTree.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/ArrayInit.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/AssignExpr.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/BinExpr.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/CallExpr.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/CastExpr.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/CondExpr.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Declarator.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/DoubleConst.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Expr.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/FieldDecl.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/InstanceOfExpr.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/IntConst.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Keyword.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Member.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/MethodDecl.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/NewExpr.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Pair.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Stmnt.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/StringL.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Symbol.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Variable.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Visitor.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformAccessArrayField.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformAfter.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformBefore.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformCall.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformFieldAccess.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformNew.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformNewClass.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformReadField.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformWriteField.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/convert/Transformer.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/expr/Cast.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/expr/ConstructorCall.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/expr/Expr.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/expr/ExprEditor.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/expr/FieldAccess.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/expr/Handler.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/expr/Instanceof.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/expr/MethodCall.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/expr/NewArray.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/expr/NewExpr.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/expr/package.html delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/package.html delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/runtime/Cflow.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/runtime/Desc.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/runtime/DotClass.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/runtime/Inner.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/runtime/package.html delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPool.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPoolFactory.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPoolFactoryImpl.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPoolRepository.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPoolRepositoryImpl.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/SoftValueHashMap.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/package.html delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/Dump.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/framedump.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/package.html delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/CannotCreateException.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/CannotInvokeException.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/CannotReflectException.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/ClassMetaobject.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Compiler.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Loader.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Metalevel.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Metaobject.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Reflection.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Sample.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/package.html delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/AppletServer.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/ObjectImporter.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/ObjectNotFoundException.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/Proxy.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/RemoteException.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/RemoteRef.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/Sample.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/StubGenerator.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/package.html delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/web/BadHttpRequest.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/web/Viewer.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/web/Webserver.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/tools/web/package.html delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/util/HotSwapper.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/util/package.html delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/FactoryHelper.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/MethodFilter.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/MethodHandler.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/Proxy.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/ProxyFactory.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/ProxyObject.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/ProxyObjectInputStream.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/ProxyObjectOutputStream.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/RuntimeSupport.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/SecurityActions.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/SerializedProxy.java delete mode 100644 fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/package.html delete mode 100644 fine-transmittable-thread-local/pom.xml delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TransmittableThreadLocal.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlCallable.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlCopier.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlEnhanced.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlRecursiveAction.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlRecursiveTask.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlRunnable.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlTimerTask.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlUnwrap.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlWrappers.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/package-info.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/TtlAttachments.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/TtlAttachmentsDelegate.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/TtlEnhanced.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/TtlWrapper.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/package-info.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/DisableInheritableForkJoinWorkerThreadFactory.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/DisableInheritableForkJoinWorkerThreadFactoryWrapper.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/DisableInheritableThreadFactory.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/DisableInheritableThreadFactoryWrapper.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/ExecutorServiceTtlWrapper.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/ExecutorTtlWrapper.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/ScheduledExecutorServiceTtlWrapper.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/TtlExecutors.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/TtlForkJoinPoolHelper.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/TtlUtils.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/TtlAgent.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/TtlTransformer.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/logging/Logger.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/ClassInfo.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/JavassistTransformlet.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/impl/TtlExecutorTransformlet.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/impl/TtlForkJoinTransformlet.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/impl/TtlTimerTaskTransformlet.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/impl/Utils.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/package-info.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/package-info.java delete mode 100644 fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/package-info.java diff --git a/build.third_step3-jdk11.gradle b/build.third_step3-jdk11.gradle index 4acc46051..fc3ae0ee1 100644 --- a/build.third_step3-jdk11.gradle +++ b/build.third_step3-jdk11.gradle @@ -31,7 +31,6 @@ sourceSets{ java{ srcDirs=[ "${srcDir}/fine-itext/src/main/java", - "${srcDir}/fine-javassist/src/main/java", "${srcDir}/fine-jedis/src/main/java", "${srcDir}/fine-jboss-logging/src/main/java" ] @@ -43,8 +42,6 @@ sourceSets{ def resourceDirs = [ "${srcDir}/fine-itext/src/main/java", "${srcDir}/fine-itext/src/main/resources", - "${srcDir}/fine-javassist/src/main/java", - "${srcDir}/fine-javassist/src/main/resources", "${srcDir}/fine-jedis/src/main/java", "${srcDir}/fine-jedis/src/main/resources", "${srcDir}/fine-jboss-logging/src/main/java", diff --git a/build.third_step3.gradle b/build.third_step3.gradle index f0a827de5..cb237ec7f 100644 --- a/build.third_step3.gradle +++ b/build.third_step3.gradle @@ -25,7 +25,6 @@ sourceSets{ java{ srcDirs=[ "${srcDir}/fine-itext/src/main/java", - "${srcDir}/fine-javassist/src/main/java", "${srcDir}/fine-jedis/src/main/java", "${srcDir}/fine-jboss-logging/src/main/java" ] @@ -84,8 +83,6 @@ task copyFiles(type:Copy,dependsOn:'compileJava'){ println "------------------------------------------------copyfiles" with dataContent.call("${srcDir}/fine-itext/src/main/java") with dataContent.call("${srcDir}/fine-itext/src/main/resources") - with dataContent.call("${srcDir}/fine-javassist/src/main/java") - with dataContent.call("${srcDir}/fine-javassist/src/main/resources") with dataContent.call("${srcDir}/fine-jedis/src/main/java") with dataContent.call("${srcDir}/fine-jedis/src/main/resources") with dataContent.call("${srcDir}/fine-jboss-logging/src/main/java") diff --git a/build.third_step8-jdk11.gradle b/build.third_step8-jdk11.gradle index 8de7ddd64..e17d553ce 100644 --- a/build.third_step8-jdk11.gradle +++ b/build.third_step8-jdk11.gradle @@ -26,7 +26,6 @@ sourceSets{ java{ srcDirs=[ "${srcDir}/fine-ehcache/src/main/java", - "${srcDir}/fine-transmittable-thread-local/src/main/java" ] } } @@ -35,7 +34,6 @@ sourceSets{ def resourceDirs = [ "${srcDir}/fine-ehcache/src/main/java", "${srcDir}/fine-ehcache/src/main/recources", - "${srcDir}/fine-transmittable-thread-local/src/main/java" ] sourceSets.main.java.outputDir = file('build/classes/8') diff --git a/build.third_step8.gradle b/build.third_step8.gradle index f9ee214d4..b3e4cd9c9 100644 --- a/build.third_step8.gradle +++ b/build.third_step8.gradle @@ -26,7 +26,6 @@ sourceSets{ java{ srcDirs=[ "${srcDir}/fine-ehcache/src/main/java", - "${srcDir}/fine-transmittable-thread-local/src/main/java" ] } } @@ -83,7 +82,6 @@ task copyFiles(type:Copy,dependsOn:'compileJava'){ println "------------------------------------------------copyfiles" with dataContent.call("${srcDir}/fine-ehcache/src/main/java") with dataContent.call("${srcDir}/fine-ehcache/src/main/recources") - with dataContent.call("${srcDir}/fine-transmittable-thread-local/src/main/java") into "${classesDir}" } } diff --git a/fine-hibernate/pom.xml b/fine-hibernate/pom.xml index 76ceb0b1f..a35e1c847 100644 --- a/fine-hibernate/pom.xml +++ b/fine-hibernate/pom.xml @@ -41,9 +41,9 @@ ${revision} - com.fr.third - fine-javassist - ${revision} + com.fr.essential + fine-javaassist + ${essentialVersion} com.fr.third diff --git a/fine-javassist/.gitignore b/fine-javassist/.gitignore deleted file mode 100644 index 5d453cd8b..000000000 --- a/fine-javassist/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -*.iml -.idea/ -.DS_Store -.project -.classpath -*.gradle \ No newline at end of file diff --git a/fine-javassist/README.md b/fine-javassist/README.md deleted file mode 100644 index a78ef5e7f..000000000 --- a/fine-javassist/README.md +++ /dev/null @@ -1,2 +0,0 @@ -源码地址:https://github.com/jboss-javassist/javassist
-版本:3.18 \ No newline at end of file diff --git a/fine-javassist/pom.xml b/fine-javassist/pom.xml deleted file mode 100644 index a075ff140..000000000 --- a/fine-javassist/pom.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - 4.0.0 - - - com.fr.third - step3 - ${revision} - ../base-third-project/base-third-step3 - - - fine-javassist - ${revision} - - - \ No newline at end of file diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/ByteArrayClassPath.java b/fine-javassist/src/main/java/com/fr/third/javassist/ByteArrayClassPath.java deleted file mode 100644 index 992c4f9d6..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/ByteArrayClassPath.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import java.io.*; -import java.net.URL; -import java.net.MalformedURLException; - -/** - * A ByteArrayClassPath contains bytes that is served as - * a class file to a ClassPool. It is useful to convert - * a byte array to a CtClass object. - * - *

For example, if you want to convert a byte array b - * into a CtClass object representing the class with a name - * classname, then do as following: - * - *

    - * ClassPool cp = ClassPool.getDefault();
    - * cp.insertClassPath(new ByteArrayClassPath(classname, b));
    - * CtClass cc = cp.get(classname);
    - * 
- * - *

The ClassPool object cp uses the created - * ByteArrayClassPath object as the source of the class file. - * - *

A ByteArrayClassPath must be instantiated for every - * class. It contains only a single class file. - * - * @see ClassPath - * @see ClassPool#insertClassPath(ClassPath) - * @see ClassPool#appendClassPath(ClassPath) - * @see ClassPool#makeClass(InputStream) - */ -public class ByteArrayClassPath implements ClassPath { - protected String classname; - protected byte[] classfile; - - /* - * Creates a ByteArrayClassPath containing the given - * bytes. - * - * @param name a fully qualified class name - * @param classfile the contents of a class file. - */ - public ByteArrayClassPath(String name, byte[] classfile) { - this.classname = name; - this.classfile = classfile; - } - - /** - * Closes this class path. - */ - public void close() {} - - public String toString() { - return "byte[]:" + classname; - } - - /** - * Opens the class file. - */ - public InputStream openClassfile(String classname) { - if(this.classname.equals(classname)) - return new ByteArrayInputStream(classfile); - else - return null; - } - - /** - * Obtains the URL. - */ - public URL find(String classname) { - if(this.classname.equals(classname)) { - String cname = classname.replace('.', '/') + ".class"; - try { - // return new File(cname).toURL(); - return new URL("file:/ByteArrayClassPath/" + cname); - } - catch (MalformedURLException e) {} - } - - return null; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CannotCompileException.java b/fine-javassist/src/main/java/com/fr/third/javassist/CannotCompileException.java deleted file mode 100644 index dee4fbf50..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CannotCompileException.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import com.fr.third.javassist.compiler.CompileError; - -/** - * Thrown when bytecode transformation has failed. - */ -public class CannotCompileException extends Exception { - private Throwable myCause; - - /** - * Gets the cause of this throwable. - * It is for JDK 1.3 compatibility. - */ - public Throwable getCause() { - return (myCause == this ? null : myCause); - } - - /** - * Initializes the cause of this throwable. - * It is for JDK 1.3 compatibility. - */ - public synchronized Throwable initCause(Throwable cause) { - myCause = cause; - return this; - } - - private String message; - - /** - * Gets a long message if it is available. - */ - public String getReason() { - if (message != null) - return message; - else - return this.toString(); - } - - /** - * Constructs a CannotCompileException with a message. - * - * @param msg the message. - */ - public CannotCompileException(String msg) { - super(msg); - message = msg; - initCause(null); - } - - /** - * Constructs a CannotCompileException with an Exception - * representing the cause. - * - * @param e the cause. - */ - public CannotCompileException(Throwable e) { - super("by " + e.toString()); - message = null; - initCause(e); - } - - /** - * Constructs a CannotCompileException with a detailed message - * and an Exception representing the cause. - * - * @param msg the message. - * @param e the cause. - */ - public CannotCompileException(String msg, Throwable e) { - this(msg); - initCause(e); - } - - /** - * Constructs a CannotCompileException with a - * NotFoundException. - */ - public CannotCompileException(NotFoundException e) { - this("cannot find " + e.getMessage(), e); - } - - /** - * Constructs a CannotCompileException with an CompileError. - */ - public CannotCompileException(CompileError e) { - this("[source error] " + e.getMessage(), e); - } - - /** - * Constructs a CannotCompileException - * with a ClassNotFoundException. - */ - public CannotCompileException(ClassNotFoundException e, String name) { - this("cannot find " + name, e); - } - - /** - * Constructs a CannotCompileException with a ClassFormatError. - */ - public CannotCompileException(ClassFormatError e, String name) { - this("invalid class format: " + name, e); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/ClassClassPath.java b/fine-javassist/src/main/java/com/fr/third/javassist/ClassClassPath.java deleted file mode 100644 index 637a511ad..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/ClassClassPath.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import java.io.InputStream; -import java.net.URL; - -/** - * A search-path for obtaining a class file - * by getResourceAsStream() in java.lang.Class. - * - *

Try adding a ClassClassPath when a program is running - * with a user-defined class loader and any class files are not found with - * the default ClassPool. For example, - * - *

    - * ClassPool cp = ClassPool.getDefault();
    - * cp.insertClassPath(new ClassClassPath(this.getClass()));
    - * 
- * - * This code snippet permanently adds a ClassClassPath - * to the default ClassPool. Note that the default - * ClassPool is a singleton. The added - * ClassClassPath uses a class object representing - * the class including the code snippet above. - * - * @see ClassPool#insertClassPath(ClassPath) - * @see ClassPool#appendClassPath(ClassPath) - * @see LoaderClassPath - */ -public class ClassClassPath implements ClassPath { - private Class thisClass; - - /** Creates a search path. - * - * @param c the Class object used to obtain a class - * file. getResourceAsStream() is called on - * this object. - */ - public ClassClassPath(Class c) { - thisClass = c; - } - - ClassClassPath() { - /* The value of thisClass was this.getClass() in early versions: - * - * thisClass = this.getClass(); - * - * However, this made openClassfile() not search all the system - * class paths if javassist.jar is put in jre/lib/ext/ - * (with JDK1.4). - */ - this(java.lang.Object.class); - } - - /** - * Obtains a class file by getResourceAsStream(). - */ - public InputStream openClassfile(String classname) { - String jarname = "/" + classname.replace('.', '/') + ".class"; - return thisClass.getResourceAsStream(jarname); - } - - /** - * Obtains the URL of the specified class file. - * - * @return null if the class file could not be found. - */ - public URL find(String classname) { - String jarname = "/" + classname.replace('.', '/') + ".class"; - return thisClass.getResource(jarname); - } - - /** - * Does nothing. - */ - public void close() { - } - - public String toString() { - return thisClass.getName() + ".class"; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/ClassMap.java b/fine-javassist/src/main/java/com/fr/third/javassist/ClassMap.java deleted file mode 100644 index 40f6e1898..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/ClassMap.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import com.fr.third.javassist.bytecode.Descriptor; - -/** - * A hash table associating class names with different names. - * - *

This hashtable is used for replacing class names in a class - * definition or a method body. Define a subclass of this class - * if a more complex mapping algorithm is needed. For example, - * - *

    class MyClassMap extends ClassMap {
    - *   public Object get(Object jvmClassName) {
    - *     String name = toJavaName((String)jvmClassName);
    - *     if (name.startsWith("java."))
    - *         return toJvmName("java2." + name.substring(5));
    - *     else
    - *         return super.get(jvmClassName);
    - *   }
    - * }
- * - *

This subclass maps java.lang.String to - * java2.lang.String. Note that get() - * receives and returns the internal representation of a class name. - * For example, the internal representation of java.lang.String - * is java/lang/String. - * - *

Note that this is a map from String to String. - * - * @see #get(Object) - * @see CtClass#replaceClassName(ClassMap) - * @see CtNewMethod#copy(CtMethod,String,CtClass,ClassMap) - */ -public class ClassMap extends java.util.HashMap { - private ClassMap parent; - - /** - * Constructs a hash table. - */ - public ClassMap() { parent = null; } - - ClassMap(ClassMap map) { parent = map; } - - /** - * Maps a class name to another name in this hashtable. - * The names are obtained with calling Class.getName(). - * This method translates the given class names into the - * internal form used in the JVM before putting it in - * the hashtable. - * - * @param oldname the original class name - * @param newname the substituted class name. - */ - public void put(CtClass oldname, CtClass newname) { - put(oldname.getName(), newname.getName()); - } - - /** - * Maps a class name to another name in this hashtable. - * If the hashtable contains another mapping from the same - * class name, the old mapping is replaced. - * This method translates the given class names into the - * internal form used in the JVM before putting it in - * the hashtable. - * - *

If oldname is identical to - * newname, then this method does not - * perform anything; it does not record the mapping from - * oldname to newname. See - * fix method. - * - * @param oldname the original class name. - * @param newname the substituted class name. - * @see #fix(String) - */ - public void put(String oldname, String newname) { - if (oldname == newname) - return; - - String oldname2 = toJvmName(oldname); - String s = (String)get(oldname2); - if (s == null || !s.equals(oldname2)) - super.put(oldname2, toJvmName(newname)); - } - - /** - * Is equivalent to put() except that - * the given mapping is not recorded into the hashtable - * if another mapping from oldname is - * already included. - * - * @param oldname the original class name. - * @param newname the substituted class name. - */ - public void putIfNone(String oldname, String newname) { - if (oldname == newname) - return; - - String oldname2 = toJvmName(oldname); - String s = (String)get(oldname2); - if (s == null) - super.put(oldname2, toJvmName(newname)); - } - - protected final void put0(Object oldname, Object newname) { - super.put(oldname, newname); - } - - /** - * Returns the class name to wihch the given jvmClassName - * is mapped. A subclass of this class should override this method. - * - *

This method receives and returns the internal representation of - * class name used in the JVM. - * - * @see #toJvmName(String) - * @see #toJavaName(String) - */ - public Object get(Object jvmClassName) { - Object found = super.get(jvmClassName); - if (found == null && parent != null) - return parent.get(jvmClassName); - else - return found; - } - - /** - * Prevents a mapping from the specified class name to another name. - */ - public void fix(CtClass clazz) { - fix(clazz.getName()); - } - - /** - * Prevents a mapping from the specified class name to another name. - */ - public void fix(String name) { - String name2 = toJvmName(name); - super.put(name2, name2); - } - - /** - * Converts a class name into the internal representation used in - * the JVM. - */ - public static String toJvmName(String classname) { - return Descriptor.toJvmName(classname); - } - - /** - * Converts a class name from the internal representation used in - * the JVM to the normal one used in Java. - */ - public static String toJavaName(String classname) { - return Descriptor.toJavaName(classname); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/ClassPath.java b/fine-javassist/src/main/java/com/fr/third/javassist/ClassPath.java deleted file mode 100644 index 929736479..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/ClassPath.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import java.io.InputStream; -import java.net.URL; - -/** - * ClassPath is an interface implemented by objects - * representing a class search path. - * ClassPool uses those objects for reading class files. - * - *

The users can define a class implementing this interface so that - * a class file is obtained from a non-standard source. - * - * @see ClassPool#insertClassPath(ClassPath) - * @see ClassPool#appendClassPath(ClassPath) - * @see ClassPool#removeClassPath(ClassPath) - */ -public interface ClassPath { - /** - * Opens a class file. - * This method may be called just to examine whether the class file - * exists as well as to read the contents of the file. - * - *

This method can return null if the specified class file is not - * found. If null is returned, the next search path is examined. - * However, if an error happens, this method must throw an exception - * so that the search will be terminated. - * - *

This method should not modify the contents of the class file. - * - * @param classname a fully-qualified class name - * @return the input stream for reading a class file - * @see Translator - */ - InputStream openClassfile(String classname) throws NotFoundException; - - /** - * Returns the uniform resource locator (URL) of the class file - * with the specified name. - * - * @param classname a fully-qualified class name. - * @return null if the specified class file could not be found. - */ - URL find(String classname); - - /** - * This method is invoked when the ClassPath object is - * detached from the search path. It will be an empty method in most of - * classes. - */ - void close(); -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/ClassPool.java b/fine-javassist/src/main/java/com/fr/third/javassist/ClassPool.java deleted file mode 100644 index aab9f804f..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/ClassPool.java +++ /dev/null @@ -1,1164 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.Method; -import java.net.URL; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.security.ProtectionDomain; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.ArrayList; -import java.util.Enumeration; - -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.bytecode.Descriptor; - -/** - * A container of CtClass objects. - * A CtClass object must be obtained from this object. - * If get() is called on this object, - * it searches various sources represented by ClassPath - * to find a class file and then it creates a CtClass object - * representing that class file. The created object is returned to the - * caller. - * - *

Memory consumption memo: - * - *

ClassPool objects hold all the CtClasses - * that have been created so that the consistency among modified classes - * can be guaranteed. Thus if a large number of CtClasses - * are processed, the ClassPool will consume a huge amount - * of memory. To avoid this, a ClassPool object - * should be recreated, for example, every hundred classes processed. - * Note that getDefault() is a singleton factory. - * Otherwise, detach() in CtClass should be used - * to avoid huge memory consumption. - * - *

ClassPool hierarchy: - * - *

ClassPools can make a parent-child hierarchy as - * java.lang.ClassLoaders. If a ClassPool has - * a parent pool, get() first asks the parent pool to find - * a class file. Only if the parent could not find the class file, - * get() searches the ClassPaths of - * the child ClassPool. This search order is reversed if - * ClassPath.childFirstLookup is true. - * - * @see CtClass - * @see com.fr.third.javassist.ClassPath - */ -public class ClassPool { - // used by toClass(). - private static java.lang.reflect.Method defineClass1, defineClass2; - private static java.lang.reflect.Method definePackage; - - static { - try { - AccessController.doPrivileged(new PrivilegedExceptionAction(){ - public Object run() throws Exception{ - Class cl = Class.forName("java.lang.ClassLoader"); - defineClass1 = cl.getDeclaredMethod("defineClass", - new Class[] { String.class, byte[].class, - int.class, int.class }); - - defineClass2 = cl.getDeclaredMethod("defineClass", - new Class[] { String.class, byte[].class, - int.class, int.class, ProtectionDomain.class }); - - definePackage = cl.getDeclaredMethod("definePackage", - new Class[] { String.class, String.class, String.class, - String.class, String.class, String.class, - String.class, java.net.URL.class }); - return null; - } - }); - } - catch (PrivilegedActionException pae) { - throw new RuntimeException("cannot initialize ClassPool", pae.getException()); - } - } - - /** - * Determines the search order. - * - *

If this field is true, get() first searches the - * class path associated to this ClassPool and then - * the class path associated with the parent ClassPool. - * Otherwise, the class path associated with the parent is searched - * first. - * - *

The default value is false. - */ - public boolean childFirstLookup = false; - - /** - * Turning the automatic pruning on/off. - * - *

If this field is true, CtClass objects are - * automatically pruned by default when toBytecode() etc. - * are called. The automatic pruning can be turned on/off individually - * for each CtClass object. - * - *

The initial value is false. - * - * @see CtClass#prune() - * @see CtClass#stopPruning(boolean) - * @see CtClass#detach() - */ - public static boolean doPruning = false; - - private int compressCount; - private static final int COMPRESS_THRESHOLD = 100; - - /* releaseUnmodifiedClassFile was introduced for avoiding a bug - of JBoss AOP. So the value should be true except for JBoss AOP. - */ - - /** - * If true, unmodified and not-recently-used class files are - * periodically released for saving memory. - * - *

The initial value is true. - */ - public static boolean releaseUnmodifiedClassFile = true; - - protected ClassPoolTail source; - protected ClassPool parent; - protected Hashtable classes; // should be synchronous - - /** - * Table of registered cflow variables. - */ - private Hashtable cflow = null; // should be synchronous. - - private static final int INIT_HASH_SIZE = 191; - - private ArrayList importedPackages; - - /** - * Creates a root class pool. No parent class pool is specified. - */ - public ClassPool() { - this(null); - } - - /** - * Creates a root class pool. If useDefaultPath is - * true, appendSystemPath() is called. Otherwise, - * this constructor is equivalent to the constructor taking no - * parameter. - * - * @param useDefaultPath true if the system search path is - * appended. - */ - public ClassPool(boolean useDefaultPath) { - this(null); - if (useDefaultPath) - appendSystemPath(); - } - - /** - * Creates a class pool. - * - * @param parent the parent of this class pool. If this is a root - * class pool, this parameter must be null. - * @see ClassPool#getDefault() - */ - public ClassPool(ClassPool parent) { - this.classes = new Hashtable(INIT_HASH_SIZE); - this.source = new ClassPoolTail(); - this.parent = parent; - if (parent == null) { - CtClass[] pt = CtClass.primitiveTypes; - for (int i = 0; i < pt.length; ++i) - classes.put(pt[i].getName(), pt[i]); - } - - this.cflow = null; - this.compressCount = 0; - clearImportedPackages(); - } - - /** - * Returns the default class pool. - * The returned object is always identical since this method is - * a singleton factory. - * - *

The default class pool searches the system search path, - * which usually includes the platform library, extension - * libraries, and the search path specified by the - * -classpath option or the CLASSPATH - * environment variable. - * - *

When this method is called for the first time, the default - * class pool is created with the following code snippet: - * - *

    ClassPool cp = new ClassPool(); - * cp.appendSystemPath(); - *
- * - *

If the default class pool cannot find any class files, - * try ClassClassPath and LoaderClassPath. - * - * @see ClassClassPath - * @see LoaderClassPath - */ - public static synchronized ClassPool getDefault() { - if (defaultPool == null) { - defaultPool = new ClassPool(null); - defaultPool.appendSystemPath(); - } - - return defaultPool; - } - - private static ClassPool defaultPool = null; - - /** - * Provide a hook so that subclasses can do their own - * caching of classes. - * - * @see #cacheCtClass(String,CtClass,boolean) - * @see #removeCached(String) - */ - protected CtClass getCached(String classname) { - return (CtClass)classes.get(classname); - } - - /** - * Provides a hook so that subclasses can do their own - * caching of classes. - * - * @see #getCached(String) - * @see #removeCached(String,CtClass) - */ - protected void cacheCtClass(String classname, CtClass c, boolean dynamic) { - classes.put(classname, c); - } - - /** - * Provide a hook so that subclasses can do their own - * caching of classes. - * - * @see #getCached(String) - * @see #cacheCtClass(String,CtClass,boolean) - */ - protected CtClass removeCached(String classname) { - return (CtClass)classes.remove(classname); - } - - /** - * Returns the class search path. - */ - public String toString() { - return source.toString(); - } - - /** - * This method is periodically invoked so that memory - * footprint will be minimized. - */ - void compress() { - if (compressCount++ > COMPRESS_THRESHOLD) { - compressCount = 0; - Enumeration e = classes.elements(); - while (e.hasMoreElements()) - ((CtClass)e.nextElement()).compress(); - } - } - - /** - * Record a package name so that the Javassist compiler searches - * the package to resolve a class name. - * Don't record the java.lang package, which has - * been implicitly recorded by default. - * - *

Since version 3.14, packageName can be a - * fully-qualified class name. - * - *

Note that get() in ClassPool does - * not search the recorded package. Only the compiler searches it. - * - * @param packageName the package name. - * It must not include the last '.' (dot). - * For example, "java.util" is valid but "java.util." is wrong. - * @since 3.1 - */ - public void importPackage(String packageName) { - importedPackages.add(packageName); - } - - /** - * Clear all the package names recorded by importPackage(). - * The java.lang package is not removed. - * - * @see #importPackage(String) - * @since 3.1 - */ - public void clearImportedPackages() { - importedPackages = new ArrayList(); - importedPackages.add("java.lang"); - } - - /** - * Returns all the package names recorded by importPackage(). - * - * @see #importPackage(String) - * @since 3.1 - */ - public Iterator getImportedPackages() { - return importedPackages.iterator(); - } - - /** - * Records a class name that never exists. - * For example, a package name can be recorded by this method. - * This would improve execution performance - * since get() quickly throw an exception - * without searching the class path at all - * if the given name is an invalid name recorded by this method. - * Note that searching the class path takes relatively long time. - * - *

The current implementation of this method performs nothing. - * - * @param name an invalid class name (separeted by dots). - * @deprecated - */ - public void recordInvalidClassName(String name) { - // source.recordInvalidClassName(name); - } - - /** - * Records the $cflow variable for the field specified - * by cname and fname. - * - * @param name variable name - * @param cname class name - * @param fname field name - */ - void recordCflow(String name, String cname, String fname) { - if (cflow == null) - cflow = new Hashtable(); - - cflow.put(name, new Object[] { cname, fname }); - } - - /** - * Undocumented method. Do not use; internal-use only. - * - * @param name the name of $cflow variable - */ - public Object[] lookupCflow(String name) { - if (cflow == null) - cflow = new Hashtable(); - - return (Object[])cflow.get(name); - } - - /** - * Reads a class file and constructs a CtClass - * object with a new name. - * This method is useful if you want to generate a new class as a copy - * of another class (except the class name). For example, - * - *

    -     * getAndRename("Point", "Pair")
    -     * 
- * - * returns a CtClass object representing Pair - * class. The definition of Pair is the same as that of - * Point class except the class name since Pair - * is defined by reading Point.class. - * - * @param orgName the original (fully-qualified) class name - * @param newName the new class name - */ - public CtClass getAndRename(String orgName, String newName) - throws NotFoundException - { - CtClass clazz = get0(orgName, false); - if (clazz == null) - throw new NotFoundException(orgName); - - if (clazz instanceof CtClassType) - ((CtClassType)clazz).setClassPool(this); - - clazz.setName(newName); // indirectly calls - // classNameChanged() in this class - return clazz; - } - - /* - * This method is invoked by CtClassType.setName(). It removes a - * CtClass object from the hash table and inserts it with the new - * name. Don't delegate to the parent. - */ - synchronized void classNameChanged(String oldname, CtClass clazz) { - CtClass c = (CtClass)getCached(oldname); - if (c == clazz) // must check this equation. - removeCached(oldname); // see getAndRename(). - - String newName = clazz.getName(); - checkNotFrozen(newName); - cacheCtClass(newName, clazz, false); - } - - /** - * Reads a class file from the source and returns a reference - * to the CtClass - * object representing that class file. If that class file has been - * already read, this method returns a reference to the - * CtClass created when that class file was read at the - * first time. - * - *

If classname ends with "[]", then this method - * returns a CtClass object for that array type. - * - *

To obtain an inner class, use "$" instead of "." for separating - * the enclosing class name and the inner class name. - * - * @param classname a fully-qualified class name. - */ - public CtClass get(String classname) throws NotFoundException { - CtClass clazz; - if (classname == null) - clazz = null; - else - clazz = get0(classname, true); - - if (clazz == null) - throw new NotFoundException(classname); - else { - clazz.incGetCounter(); - return clazz; - } - } - - /** - * Reads a class file from the source and returns a reference - * to the CtClass - * object representing that class file. - * This method is equivalent to get except - * that it returns null when a class file is - * not found and it never throws an exception. - * - * @param classname a fully-qualified class name. - * @return a CtClass object or null. - * @see #get(String) - * @see #find(String) - * @since 3.13 - */ - public CtClass getOrNull(String classname) { - CtClass clazz = null; - if (classname == null) - clazz = null; - else - try { - /* ClassPool.get0() never throws an exception - but its subclass may implement get0 that - may throw an exception. - */ - clazz = get0(classname, true); - } - catch (NotFoundException e){} - - if (clazz != null) - clazz.incGetCounter(); - - return clazz; - } - - /** - * Returns a CtClass object with the given name. - * This is almost equivalent to get(String) except - * that classname can be an array-type "descriptor" (an encoded - * type name) such as [Ljava/lang/Object;. - * - *

Using this method is not recommended; this method should be - * used only to obtain the CtClass object - * with a name returned from getClassInfo in - * javassist.bytecode.ClassPool. getClassInfo - * returns a fully-qualified class name but, if the class is an array - * type, it returns a descriptor. - * - * @param classname a fully-qualified class name or a descriptor - * representing an array type. - * @see #get(String) - * @see ConstPool#getClassInfo(int) - * @see Descriptor#toCtClass(String, ClassPool) - * @since 3.8.1 - */ - public CtClass getCtClass(String classname) throws NotFoundException { - if (classname.charAt(0) == '[') - return Descriptor.toCtClass(classname, this); - else - return get(classname); - } - - /** - * @param useCache false if the cached CtClass must be ignored. - * @param searchParent false if the parent class pool is not searched. - * @return null if the class could not be found. - */ - protected synchronized CtClass get0(String classname, boolean useCache) - throws NotFoundException - { - CtClass clazz = null; - if (useCache) { - clazz = getCached(classname); - if (clazz != null) - return clazz; - } - - if (!childFirstLookup && parent != null) { - clazz = parent.get0(classname, useCache); - if (clazz != null) - return clazz; - } - - clazz = createCtClass(classname, useCache); - if (clazz != null) { - // clazz.getName() != classname if classname is "[L;". - if (useCache) - cacheCtClass(clazz.getName(), clazz, false); - - return clazz; - } - - if (childFirstLookup && parent != null) - clazz = parent.get0(classname, useCache); - - return clazz; - } - - /** - * Creates a CtClass object representing the specified class. - * It first examines whether or not the corresponding class - * file exists. If yes, it creates a CtClass object. - * - * @return null if the class file could not be found. - */ - protected CtClass createCtClass(String classname, boolean useCache) { - // accept "[L;" as a class name. - if (classname.charAt(0) == '[') - classname = Descriptor.toClassName(classname); - - if (classname.endsWith("[]")) { - String base = classname.substring(0, classname.indexOf('[')); - if ((!useCache || getCached(base) == null) && find(base) == null) - return null; - else - return new CtArray(classname, this); - } - else - if (find(classname) == null) - return null; - else - return new CtClassType(classname, this); - } - - /** - * Searches the class path to obtain the URL of the class file - * specified by classname. It is also used to determine whether - * the class file exists. - * - * @param classname a fully-qualified class name. - * @return null if the class file could not be found. - * @see CtClass#getURL() - */ - public URL find(String classname) { - return source.find(classname); - } - - /* - * Is invoked by CtClassType.setName() and methods in this class. - * This method throws an exception if the class is already frozen or - * if this class pool cannot edit the class since it is in a parent - * class pool. - * - * @see checkNotExists(String) - */ - void checkNotFrozen(String classname) throws RuntimeException { - CtClass clazz = getCached(classname); - if (clazz == null) { - if (!childFirstLookup && parent != null) { - try { - clazz = parent.get0(classname, true); - } - catch (NotFoundException e) {} - if (clazz != null) - throw new RuntimeException(classname - + " is in a parent ClassPool. Use the parent."); - } - } - else - if (clazz.isFrozen()) - throw new RuntimeException(classname - + ": frozen class (cannot edit)"); - } - - /* - * This method returns null if this or its parent class pool does - * not contain a CtClass object with the class name. - * - * @see checkNotFrozen(String) - */ - CtClass checkNotExists(String classname) { - CtClass clazz = getCached(classname); - if (clazz == null) - if (!childFirstLookup && parent != null) { - try { - clazz = parent.get0(classname, true); - } - catch (NotFoundException e) {} - } - - return clazz; - } - - /* for CtClassType.getClassFile2(). Don't delegate to the parent. - */ - InputStream openClassfile(String classname) throws NotFoundException { - return source.openClassfile(classname); - } - - void writeClassfile(String classname, OutputStream out) - throws NotFoundException, IOException, com.fr.third.javassist.CannotCompileException - { - source.writeClassfile(classname, out); - } - - /** - * Reads class files from the source and returns an array of - * CtClass - * objects representing those class files. - * - *

If an element of classnames ends with "[]", - * then this method - * returns a CtClass object for that array type. - * - * @param classnames an array of fully-qualified class name. - */ - public CtClass[] get(String[] classnames) throws NotFoundException { - if (classnames == null) - return new CtClass[0]; - - int num = classnames.length; - CtClass[] result = new CtClass[num]; - for (int i = 0; i < num; ++i) - result[i] = get(classnames[i]); - - return result; - } - - /** - * Reads a class file and obtains a compile-time method. - * - * @param classname the class name - * @param methodname the method name - * @see CtClass#getDeclaredMethod(String) - */ - public CtMethod getMethod(String classname, String methodname) - throws NotFoundException - { - CtClass c = get(classname); - return c.getDeclaredMethod(methodname); - } - - /** - * Creates a new class (or interface) from the given class file. - * If there already exists a class with the same name, the new class - * overwrites that previous class. - * - *

This method is used for creating a CtClass object - * directly from a class file. The qualified class name is obtained - * from the class file; you do not have to explicitly give the name. - * - * @param classfile class file. - * @throws RuntimeException if there is a frozen class with the - * the same name. - * @see #makeClassIfNew(InputStream) - * @see ByteArrayClassPath - */ - public CtClass makeClass(InputStream classfile) - throws IOException, RuntimeException - { - return makeClass(classfile, true); - } - - /** - * Creates a new class (or interface) from the given class file. - * If there already exists a class with the same name, the new class - * overwrites that previous class. - * - *

This method is used for creating a CtClass object - * directly from a class file. The qualified class name is obtained - * from the class file; you do not have to explicitly give the name. - * - * @param classfile class file. - * @param ifNotFrozen throws a RuntimeException if this parameter is true - * and there is a frozen class with the same name. - * @see ByteArrayClassPath - */ - public CtClass makeClass(InputStream classfile, boolean ifNotFrozen) - throws IOException, RuntimeException - { - compress(); - classfile = new BufferedInputStream(classfile); - CtClass clazz = new CtClassType(classfile, this); - clazz.checkModify(); - String classname = clazz.getName(); - if (ifNotFrozen) - checkNotFrozen(classname); - - cacheCtClass(classname, clazz, true); - return clazz; - } - - /** - * Creates a new class (or interface) from the given class file. - * If there already exists a class with the same name, this method - * returns the existing class; a new class is never created from - * the given class file. - * - *

This method is used for creating a CtClass object - * directly from a class file. The qualified class name is obtained - * from the class file; you do not have to explicitly give the name. - * - * @param classfile the class file. - * @see #makeClass(InputStream) - * @see ByteArrayClassPath - * @since 3.9 - */ - public CtClass makeClassIfNew(InputStream classfile) - throws IOException, RuntimeException - { - compress(); - classfile = new BufferedInputStream(classfile); - CtClass clazz = new CtClassType(classfile, this); - clazz.checkModify(); - String classname = clazz.getName(); - CtClass found = checkNotExists(classname); - if (found != null) - return found; - else { - cacheCtClass(classname, clazz, true); - return clazz; - } - } - - /** - * Creates a new public class. - * If there already exists a class with the same name, the new class - * overwrites that previous class. - * - *

If no constructor is explicitly added to the created new - * class, Javassist generates constructors and adds it when - * the class file is generated. It generates a new constructor - * for each constructor of the super class. The new constructor - * takes the same set of parameters and invokes the - * corresponding constructor of the super class. All the received - * parameters are passed to it. - * - * @param classname a fully-qualified class name. - * @throws RuntimeException if the existing class is frozen. - */ - public CtClass makeClass(String classname) throws RuntimeException { - return makeClass(classname, null); - } - - /** - * Creates a new public class. - * If there already exists a class/interface with the same name, - * the new class overwrites that previous class. - * - *

If no constructor is explicitly added to the created new - * class, Javassist generates constructors and adds it when - * the class file is generated. It generates a new constructor - * for each constructor of the super class. The new constructor - * takes the same set of parameters and invokes the - * corresponding constructor of the super class. All the received - * parameters are passed to it. - * - * @param classname a fully-qualified class name. - * @param superclass the super class. - * @throws RuntimeException if the existing class is frozen. - */ - public synchronized CtClass makeClass(String classname, CtClass superclass) - throws RuntimeException - { - checkNotFrozen(classname); - CtClass clazz = new CtNewClass(classname, this, false, superclass); - cacheCtClass(classname, clazz, true); - return clazz; - } - - /** - * Creates a new public nested class. - * This method is called by CtClassType.makeNestedClass(). - * - * @param classname a fully-qualified class name. - * @return the nested class. - */ - synchronized CtClass makeNestedClass(String classname) { - checkNotFrozen(classname); - CtClass clazz = new CtNewNestedClass(classname, this, false, null); - cacheCtClass(classname, clazz, true); - return clazz; - } - - /** - * Creates a new public interface. - * If there already exists a class/interface with the same name, - * the new interface overwrites that previous one. - * - * @param name a fully-qualified interface name. - * @throws RuntimeException if the existing interface is frozen. - */ - public CtClass makeInterface(String name) throws RuntimeException { - return makeInterface(name, null); - } - - /** - * Creates a new public interface. - * If there already exists a class/interface with the same name, - * the new interface overwrites that previous one. - * - * @param name a fully-qualified interface name. - * @param superclass the super interface. - * @throws RuntimeException if the existing interface is frozen. - */ - public synchronized CtClass makeInterface(String name, CtClass superclass) - throws RuntimeException - { - checkNotFrozen(name); - CtClass clazz = new CtNewClass(name, this, true, superclass); - cacheCtClass(name, clazz, true); - return clazz; - } - - /** - * Appends the system search path to the end of the - * search path. The system search path - * usually includes the platform library, extension - * libraries, and the search path specified by the - * -classpath option or the CLASSPATH - * environment variable. - * - * @return the appended class path. - */ - public com.fr.third.javassist.ClassPath appendSystemPath() { - return source.appendSystemPath(); - } - - /** - * Insert a ClassPath object at the head of the - * search path. - * - * @return the inserted class path. - * @see com.fr.third.javassist.ClassPath - * @see URLClassPath - * @see ByteArrayClassPath - */ - public com.fr.third.javassist.ClassPath insertClassPath(com.fr.third.javassist.ClassPath cp) { - return source.insertClassPath(cp); - } - - /** - * Appends a ClassPath object to the end of the - * search path. - * - * @return the appended class path. - * @see com.fr.third.javassist.ClassPath - * @see URLClassPath - * @see ByteArrayClassPath - */ - public com.fr.third.javassist.ClassPath appendClassPath(com.fr.third.javassist.ClassPath cp) { - return source.appendClassPath(cp); - } - - /** - * Inserts a directory or a jar (or zip) file at the head of the - * search path. - * - * @param pathname the path name of the directory or jar file. - * It must not end with a path separator ("/"). - * If the path name ends with "/*", then all the - * jar files matching the path name are inserted. - * - * @return the inserted class path. - * @throws NotFoundException if the jar file is not found. - */ - public com.fr.third.javassist.ClassPath insertClassPath(String pathname) - throws NotFoundException - { - return source.insertClassPath(pathname); - } - - /** - * Appends a directory or a jar (or zip) file to the end of the - * search path. - * - * @param pathname the path name of the directory or jar file. - * It must not end with a path separator ("/"). - * If the path name ends with "/*", then all the - * jar files matching the path name are appended. - * - * @return the appended class path. - * @throws NotFoundException if the jar file is not found. - */ - public com.fr.third.javassist.ClassPath appendClassPath(String pathname) - throws NotFoundException - { - return source.appendClassPath(pathname); - } - - /** - * Detatches the ClassPath object from the search path. - * The detached ClassPath object cannot be added - * to the path again. - */ - public void removeClassPath(ClassPath cp) { - source.removeClassPath(cp); - } - - /** - * Appends directories and jar files for search. - * - *

The elements of the given path list must be separated by colons - * in Unix or semi-colons in Windows. - * - * @param pathlist a (semi)colon-separated list of - * the path names of directories and jar files. - * The directory name must not end with a path - * separator ("/"). - * @throws NotFoundException if a jar file is not found. - */ - public void appendPathList(String pathlist) throws NotFoundException { - char sep = File.pathSeparatorChar; - int i = 0; - for (;;) { - int j = pathlist.indexOf(sep, i); - if (j < 0) { - appendClassPath(pathlist.substring(i)); - break; - } - else { - appendClassPath(pathlist.substring(i, j)); - i = j + 1; - } - } - } - - /** - * Converts the given class to a java.lang.Class object. - * Once this method is called, further modifications are not - * allowed any more. - * To load the class, this method uses the context class loader - * of the current thread. It is obtained by calling - * getClassLoader(). - * - *

This behavior can be changed by subclassing the pool and changing - * the getClassLoader() method. - * If the program is running on some application - * server, the context class loader might be inappropriate to load the - * class. - * - *

This method is provided for convenience. If you need more - * complex functionality, you should write your own class loader. - * - *

Warining: A Class object returned by this method may not - * work with a security manager or a signed jar file because a - * protection domain is not specified. - * - * @see #toClass(CtClass, java.lang.ClassLoader, ProtectionDomain) - * @see #getClassLoader() - */ - public Class toClass(CtClass clazz) throws com.fr.third.javassist.CannotCompileException { - // Some subclasses of ClassPool may override toClass(CtClass,ClassLoader). - // So we should call that method instead of toClass(.., ProtectionDomain). - return toClass(clazz, getClassLoader()); - } - - /** - * Get the classloader for toClass(), getAnnotations() in - * CtClass, etc. - * - *

The default is the context class loader. - * - * @return the classloader for the pool - * @see #toClass(CtClass) - * @see CtClass#getAnnotations() - */ - public ClassLoader getClassLoader() { - return getContextClassLoader(); - } - - /** - * Obtains a class loader that seems appropriate to look up a class - * by name. - */ - static ClassLoader getContextClassLoader() { - return Thread.currentThread().getContextClassLoader(); - } - - /** - * Converts the class to a java.lang.Class object. - * Do not override this method any more at a subclass because - * toClass(CtClass) never calls this method. - * - *

Warining: A Class object returned by this method may not - * work with a security manager or a signed jar file because a - * protection domain is not specified. - * - * @deprecated Replaced by {@link #toClass(CtClass,ClassLoader,ProtectionDomain)}. - * A subclass of ClassPool that has been - * overriding this method should be modified. It should override - * {@link #toClass(CtClass,ClassLoader,ProtectionDomain)}. - */ - public Class toClass(CtClass ct, ClassLoader loader) - throws com.fr.third.javassist.CannotCompileException - { - return toClass(ct, loader, null); - } - - /** - * Converts the class to a java.lang.Class object. - * Once this method is called, further modifications are not allowed - * any more. - * - *

The class file represented by the given CtClass is - * loaded by the given class loader to construct a - * java.lang.Class object. Since a private method - * on the class loader is invoked through the reflection API, - * the caller must have permissions to do that. - * - *

An easy way to obtain ProtectionDomain object is - * to call getProtectionDomain() - * in java.lang.Class. It returns the domain that the - * class belongs to. - * - *

This method is provided for convenience. If you need more - * complex functionality, you should write your own class loader. - * - * @param loader the class loader used to load this class. - * For example, the loader returned by - * getClassLoader() can be used - * for this parameter. - * @param domain the protection domain for the class. - * If it is null, the default domain created - * by java.lang.ClassLoader is used. - * - * @see #getClassLoader() - * @since 3.3 - */ - public Class toClass(CtClass ct, ClassLoader loader, ProtectionDomain domain) - throws com.fr.third.javassist.CannotCompileException - { - try { - byte[] b = ct.toBytecode(); - java.lang.reflect.Method method; - Object[] args; - if (domain == null) { - method = defineClass1; - args = new Object[] { ct.getName(), b, new Integer(0), - new Integer(b.length)}; - } - else { - method = defineClass2; - args = new Object[] { ct.getName(), b, new Integer(0), - new Integer(b.length), domain}; - } - - return (Class)toClass2(method, loader, args); - } - catch (RuntimeException e) { - throw e; - } - catch (java.lang.reflect.InvocationTargetException e) { - throw new com.fr.third.javassist.CannotCompileException(e.getTargetException()); - } - catch (Exception e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - private static synchronized Object toClass2(Method method, - ClassLoader loader, Object[] args) - throws Exception - { - method.setAccessible(true); - try { - return method.invoke(loader, args); - } - finally { - method.setAccessible(false); - } - } - - /** - * Defines a new package. If the package is already defined, this method - * performs nothing. - * - *

You do not necessarily need to - * call this method. If this method is called, then - * getPackage() on the Class object returned - * by toClass() will return a non-null object. - * - * @param loader the class loader passed to toClass() or - * the default one obtained by getClassLoader(). - * @param name the package name. - * @see #getClassLoader() - * @see #toClass(CtClass) - * @see CtClass#toClass() - * @since 3.16 - */ - public void makePackage(ClassLoader loader, String name) - throws com.fr.third.javassist.CannotCompileException - { - Object[] args = new Object[] { - name, null, null, null, null, null, null, null }; - Throwable t; - try { - toClass2(definePackage, loader, args); - return; - } - catch (java.lang.reflect.InvocationTargetException e) { - t = e.getTargetException(); - if (t == null) - t = e; - else if (t instanceof IllegalArgumentException) { - // if the package is already defined, an IllegalArgumentException - // is thrown. - return; - } - } - catch (Exception e) { - t = e; - } - - throw new CannotCompileException(t); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/ClassPoolTail.java b/fine-javassist/src/main/java/com/fr/third/javassist/ClassPoolTail.java deleted file mode 100644 index 183ea89a0..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/ClassPoolTail.java +++ /dev/null @@ -1,429 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import java.io.*; -import java.util.jar.*; -import java.net.MalformedURLException; -import java.net.URL; - -final class ClassPathList { - ClassPathList next; - com.fr.third.javassist.ClassPath path; - - ClassPathList(com.fr.third.javassist.ClassPath p, ClassPathList n) { - next = n; - path = p; - } -} - -final class DirClassPath implements com.fr.third.javassist.ClassPath { - String directory; - - DirClassPath(String dirName) { - directory = dirName; - } - - public InputStream openClassfile(String classname) { - try { - char sep = File.separatorChar; - String filename = directory + sep - + classname.replace('.', sep) + ".class"; - return new FileInputStream(filename.toString()); - } - catch (FileNotFoundException e) {} - catch (SecurityException e) {} - return null; - } - - public URL find(String classname) { - char sep = File.separatorChar; - String filename = directory + sep - + classname.replace('.', sep) + ".class"; - File f = new File(filename); - if (f.exists()) - try { - return f.getCanonicalFile().toURI().toURL(); - } - catch (MalformedURLException e) {} - catch (IOException e) {} - - return null; - } - - public void close() {} - - public String toString() { - return directory; - } -} - -final class JarDirClassPath implements com.fr.third.javassist.ClassPath { - JarClassPath[] jars; - - JarDirClassPath(String dirName) throws NotFoundException { - File[] files = new File(dirName).listFiles(new FilenameFilter() { - public boolean accept(File dir, String name) { - name = name.toLowerCase(); - return name.endsWith(".jar") || name.endsWith(".zip"); - } - }); - - if (files != null) { - jars = new JarClassPath[files.length]; - for (int i = 0; i < files.length; i++) - jars[i] = new JarClassPath(files[i].getPath()); - } - } - - public InputStream openClassfile(String classname) throws NotFoundException { - if (jars != null) - for (int i = 0; i < jars.length; i++) { - InputStream is = jars[i].openClassfile(classname); - if (is != null) - return is; - } - - return null; // not found - } - - public URL find(String classname) { - if (jars != null) - for (int i = 0; i < jars.length; i++) { - URL url = jars[i].find(classname); - if (url != null) - return url; - } - - return null; // not found - } - - public void close() { - if (jars != null) - for (int i = 0; i < jars.length; i++) - jars[i].close(); - } -} - -final class JarClassPath implements com.fr.third.javassist.ClassPath { - JarFile jarfile; - String jarfileURL; - - JarClassPath(String pathname) throws NotFoundException { - try { - jarfile = new JarFile(pathname); - jarfileURL = new File(pathname).getCanonicalFile() - .toURI().toURL().toString(); - return; - } - catch (IOException e) {} - throw new NotFoundException(pathname); - } - - public InputStream openClassfile(String classname) - throws NotFoundException - { - try { - String jarname = classname.replace('.', '/') + ".class"; - JarEntry je = jarfile.getJarEntry(jarname); - if (je != null) - return jarfile.getInputStream(je); - else - return null; // not found - } - catch (IOException e) {} - throw new NotFoundException("broken jar file?: " - + jarfile.getName()); - } - - public URL find(String classname) { - String jarname = classname.replace('.', '/') + ".class"; - JarEntry je = jarfile.getJarEntry(jarname); - if (je != null) - try { - return new URL("jar:" + jarfileURL + "!/" + jarname); - } - catch (MalformedURLException e) {} - - return null; // not found - } - - public void close() { - try { - jarfile.close(); - jarfile = null; - } - catch (IOException e) {} - } - - public String toString() { - return jarfile == null ? "" : jarfile.toString(); - } -} - -final class ClassPoolTail { - protected ClassPathList pathList; - - public ClassPoolTail() { - pathList = null; - } - - public String toString() { - StringBuffer buf = new StringBuffer(); - buf.append("[class path: "); - ClassPathList list = pathList; - while (list != null) { - buf.append(list.path.toString()); - buf.append(File.pathSeparatorChar); - list = list.next; - } - - buf.append(']'); - return buf.toString(); - } - - public synchronized com.fr.third.javassist.ClassPath insertClassPath(com.fr.third.javassist.ClassPath cp) { - pathList = new ClassPathList(cp, pathList); - return cp; - } - - public synchronized com.fr.third.javassist.ClassPath appendClassPath(com.fr.third.javassist.ClassPath cp) { - ClassPathList tail = new ClassPathList(cp, null); - ClassPathList list = pathList; - if (list == null) - pathList = tail; - else { - while (list.next != null) - list = list.next; - - list.next = tail; - } - - return cp; - } - - public synchronized void removeClassPath(com.fr.third.javassist.ClassPath cp) { - ClassPathList list = pathList; - if (list != null) - if (list.path == cp) - pathList = list.next; - else { - while (list.next != null) - if (list.next.path == cp) - list.next = list.next.next; - else - list = list.next; - } - - cp.close(); - } - - public com.fr.third.javassist.ClassPath appendSystemPath() { - return appendClassPath(new ClassClassPath()); - } - - public com.fr.third.javassist.ClassPath insertClassPath(String pathname) - throws NotFoundException - { - return insertClassPath(makePathObject(pathname)); - } - - public com.fr.third.javassist.ClassPath appendClassPath(String pathname) - throws NotFoundException - { - return appendClassPath(makePathObject(pathname)); - } - - private static ClassPath makePathObject(String pathname) - throws NotFoundException - { - String lower = pathname.toLowerCase(); - if (lower.endsWith(".jar") || lower.endsWith(".zip")) - return new JarClassPath(pathname); - - int len = pathname.length(); - if (len > 2 && pathname.charAt(len - 1) == '*' - && (pathname.charAt(len - 2) == '/' - || pathname.charAt(len - 2) == File.separatorChar)) { - String dir = pathname.substring(0, len - 2); - return new JarDirClassPath(dir); - } - - return new DirClassPath(pathname); - } - - /** - * This method does not close the output stream. - */ - void writeClassfile(String classname, OutputStream out) - throws NotFoundException, IOException, CannotCompileException - { - InputStream fin = openClassfile(classname); - if (fin == null) - throw new NotFoundException(classname); - - try { - copyStream(fin, out); - } - finally { - fin.close(); - } - } - - /* - -- faster version -- - void checkClassName(String classname) throws NotFoundException { - if (find(classname) == null) - throw new NotFoundException(classname); - } - - -- slower version -- - - void checkClassName(String classname) throws NotFoundException { - InputStream fin = openClassfile(classname); - try { - fin.close(); - } - catch (IOException e) {} - } - */ - - - /** - * Opens the class file for the class specified by - * classname. - * - * @param classname a fully-qualified class name - * @return null if the file has not been found. - * @throws NotFoundException if any error is reported by ClassPath. - */ - InputStream openClassfile(String classname) - throws NotFoundException - { - ClassPathList list = pathList; - InputStream ins = null; - NotFoundException error = null; - while (list != null) { - try { - ins = list.path.openClassfile(classname); - } - catch (NotFoundException e) { - if (error == null) - error = e; - } - - if (ins == null) - list = list.next; - else - return ins; - } - - if (error != null) - throw error; - else - return null; // not found - } - - /** - * Searches the class path to obtain the URL of the class file - * specified by classname. It is also used to determine whether - * the class file exists. - * - * @param classname a fully-qualified class name. - * @return null if the class file could not be found. - */ - public URL find(String classname) { - ClassPathList list = pathList; - URL url = null; - while (list != null) { - url = list.path.find(classname); - if (url == null) - list = list.next; - else - return url; - } - - return null; - } - - /** - * Reads from an input stream until it reaches the end. - * - * @return the contents of that input stream - */ - public static byte[] readStream(InputStream fin) throws IOException { - byte[][] bufs = new byte[8][]; - int bufsize = 4096; - - for (int i = 0; i < 8; ++i) { - bufs[i] = new byte[bufsize]; - int size = 0; - int len = 0; - do { - len = fin.read(bufs[i], size, bufsize - size); - if (len >= 0) - size += len; - else { - byte[] result = new byte[bufsize - 4096 + size]; - int s = 0; - for (int j = 0; j < i; ++j) { - System.arraycopy(bufs[j], 0, result, s, s + 4096); - s = s + s + 4096; - } - - System.arraycopy(bufs[i], 0, result, s, size); - return result; - } - } while (size < bufsize); - bufsize *= 2; - } - - throw new IOException("too much data"); - } - - /** - * Reads from an input stream and write to an output stream - * until it reaches the end. This method does not close the - * streams. - */ - public static void copyStream(InputStream fin, OutputStream fout) - throws IOException - { - int bufsize = 4096; - byte[] buf = null; - for (int i = 0; i < 64; ++i) { - if (i < 8) { - bufsize *= 2; - buf = new byte[bufsize]; - } - int size = 0; - int len = 0; - do { - len = fin.read(buf, size, bufsize - size); - if (len >= 0) - size += len; - else { - fout.write(buf, 0, size); - return; - } - } while (size < bufsize); - fout.write(buf); - } - - throw new IOException("too much data"); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CodeConverter.java b/fine-javassist/src/main/java/com/fr/third/javassist/CodeConverter.java deleted file mode 100644 index 1aef102bc..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CodeConverter.java +++ /dev/null @@ -1,809 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.convert.TransformCall; -import com.fr.third.javassist.expr.ExprEditor; - -/** - * Simple translator of method bodies - * (also see the javassist.expr package). - * - *

Instances of this class specifies how to instrument of the - * bytecodes representing a method body. They are passed to - * CtClass.instrument() or - * CtMethod.instrument() as a parameter. - * - *

Example: - *

    - * ClassPool cp = ClassPool.getDefault();
    - * CtClass point = cp.get("Point");
    - * CtClass singleton = cp.get("Singleton");
    - * CtClass client = cp.get("Client");
    - * CodeConverter conv = new CodeConverter();
    - * conv.replaceNew(point, singleton, "makePoint");
    - * client.instrument(conv);
    - * 
- * - *

This program substitutes "Singleton.makePoint()" - * for all occurrences of "new Point()" - * appearing in methods declared in a Client class. - * - * @see CtClass#instrument(CodeConverter) - * @see CtMethod#instrument(CodeConverter) - * @see ExprEditor - */ -public class CodeConverter { - protected com.fr.third.javassist.convert.Transformer transformers = null; - - /** - * Modify a method body so that instantiation of the specified class - * is replaced with a call to the specified static method. For example, - * replaceNew(ctPoint, ctSingleton, "createPoint") - * (where ctPoint and ctSingleton are - * compile-time classes for class Point and class - * Singleton, respectively) - * replaces all occurrences of: - * - *

    new Point(x, y)
- * - * in the method body with: - * - *
    Singleton.createPoint(x, y)
- * - *

This enables to intercept instantiation of Point - * and change the samentics. For example, the following - * createPoint() implements the singleton pattern: - * - *

    public static Point createPoint(int x, int y) {
    -     *     if (aPoint == null)
    -     *         aPoint = new Point(x, y);
    -     *     return aPoint;
    -     * }
    -     * 
- * - *

The static method call substituted for the original new - * expression must be - * able to receive the same set of parameters as the original - * constructor. If there are multiple constructors with different - * parameter types, then there must be multiple static methods - * with the same name but different parameter types. - * - *

The return type of the substituted static method must be - * the exactly same as the type of the instantiated class specified by - * newClass. - * - * @param newClass the instantiated class. - * @param calledClass the class in which the static method is - * declared. - * @param calledMethod the name of the static method. - */ - public void replaceNew(CtClass newClass, - CtClass calledClass, String calledMethod) { - transformers = new com.fr.third.javassist.convert.TransformNew(transformers, newClass.getName(), - calledClass.getName(), calledMethod); - } - - /** - * Modify a method body so that instantiation of the class - * specified by oldClass - * is replaced with instantiation of another class newClass. - * For example, - * replaceNew(ctPoint, ctPoint2) - * (where ctPoint and ctPoint2 are - * compile-time classes for class Point and class - * Point2, respectively) - * replaces all occurrences of: - * - *

    new Point(x, y)
- * - * in the method body with: - * - *
    new Point2(x, y)
- * - *

Note that Point2 must be type-compatible with Point. - * It must have the same set of methods, fields, and constructors as the - * replaced class. - */ - public void replaceNew(CtClass oldClass, CtClass newClass) { - transformers = new com.fr.third.javassist.convert.TransformNewClass(transformers, oldClass.getName(), - newClass.getName()); - } - - /** - * Modify a method body so that field read/write expressions access - * a different field from the original one. - * - *

Note that this method changes only the filed name and the class - * declaring the field; the type of the target object does not change. - * Therefore, the substituted field must be declared in the same class - * or a superclass of the original class. - * - *

Also, clazz and newClass must specify - * the class directly declaring the field. They must not specify - * a subclass of that class. - * - * @param field the originally accessed field. - * @param newClass the class declaring the substituted field. - * @param newFieldname the name of the substituted field. - */ - public void redirectFieldAccess(CtField field, - CtClass newClass, String newFieldname) { - transformers = new com.fr.third.javassist.convert.TransformFieldAccess(transformers, field, - newClass.getName(), - newFieldname); - } - - /** - * Modify a method body so that an expression reading the specified - * field is replaced with a call to the specified static method. - * This static method receives the target object of the original - * read expression as a parameter. It must return a value of - * the same type as the field. - * - *

For example, the program below - * - *

    Point p = new Point();
    -     * int newX = p.x + 3;
- * - *

can be translated into: - * - *

    Point p = new Point();
    -     * int newX = Accessor.readX(p) + 3;
- * - *

where - * - *

    public class Accessor {
    -     *     public static int readX(Object target) { ... }
    -     * }
- * - *

The type of the parameter of readX() must - * be java.lang.Object independently of the actual - * type of target. The return type must be the same - * as the field type. - * - * @param field the field. - * @param calledClass the class in which the static method is - * declared. - * @param calledMethod the name of the static method. - */ - public void replaceFieldRead(CtField field, - CtClass calledClass, String calledMethod) { - transformers = new com.fr.third.javassist.convert.TransformReadField(transformers, field, - calledClass.getName(), - calledMethod); - } - - /** - * Modify a method body so that an expression writing the specified - * field is replaced with a call to the specified static method. - * This static method receives two parameters: the target object of - * the original - * write expression and the assigned value. The return type of the - * static method is void. - * - *

For example, the program below - * - *

    Point p = new Point();
    -     * p.x = 3;
- * - *

can be translated into: - * - *

    Point p = new Point();
    -     * Accessor.writeX(3);
- * - *

where - * - *

    public class Accessor {
    -     *     public static void writeX(Object target, int value) { ... }
    -     * }
- * - *

The type of the first parameter of writeX() must - * be java.lang.Object independently of the actual - * type of target. The type of the second parameter - * is the same as the field type. - * - * @param field the field. - * @param calledClass the class in which the static method is - * declared. - * @param calledMethod the name of the static method. - */ - public void replaceFieldWrite(CtField field, - CtClass calledClass, String calledMethod) { - transformers = new com.fr.third.javassist.convert.TransformWriteField(transformers, field, - calledClass.getName(), - calledMethod); - } - - /** - * Modify a method body, so that ALL accesses to an array are replaced with - * calls to static methods within another class. In the case of reading an - * element from the array, this is replaced with a call to a static method with - * the array and the index as arguments, the return value is the value read from - * the array. If writing to an array, this is replaced with a call to a static - * method with the array, index and new value as parameters, the return value of - * the static method is void. - * - *

The calledClass parameter is the class containing the static methods to be used - * for array replacement. The names parameter points to an implementation of - * ArrayAccessReplacementMethodNames which specifies the names of the method to be - * used for access for each type of array. For example reading from an int[] will - * require a different method than if writing to an int[], and writing to a long[] - * will require a different method than if writing to a byte[]. If the implementation - * of ArrayAccessReplacementMethodNames does not contain the name for access for a - * type of array, that access is not replaced. - * - *

A default implementation of ArrayAccessReplacementMethodNames called - * DefaultArrayAccessReplacementMethodNames has been provided and is what is used in the - * following example. This also assumes that 'foo.ArrayAdvisor' is the name of the - * CtClass passed in. - * - *

If we have the following class: - *

class POJO{
-     *    int[] ints = new int[]{1, 2, 3, 4, 5};
-     *    long[] longs = new int[]{10, 20, 30};
-     *    Object objects = new Object[]{true, false};
-     *    Integer[] integers = new Integer[]{new Integer(10)};
-     * }
-     * 
- * and this is accessed as: - *
POJO p = new POJO();
-     * 
-     * //Write to int array
-     * p.ints[2] = 7;
-     * 
-     * //Read from int array
-     * int i = p.ints[2];
-     * 
-     * //Write to long array
-     * p.longs[2] = 1000L;
-     * 
-     * //Read from long array
-     * long l = p.longs[2];
-     * 
-     * //Write to Object array
-     * p.objects[2] = "Hello";
-     * 
-     * //Read from Object array
-     * Object o = p.objects[2];
-     * 
-     * //Write to Integer array
-     * Integer integer = new Integer(5);
-     * p.integers[0] = integer;
-     * 
-     * //Read from Object array
-     * integer = p.integers[0];
-     * 
- * - * Following instrumentation we will have - *
POJO p = new POJO();
-     * 
-     * //Write to int array
-     * ArrayAdvisor.arrayWriteInt(p.ints, 2, 7);
-     * 
-     * //Read from int array
-     * int i = ArrayAdvisor.arrayReadInt(p.ints, 2);
-     * 
-     * //Write to long array
-     * ArrayAdvisor.arrayWriteLong(p.longs, 2, 1000L);
-     * 
-     * //Read from long array
-     * long l = ArrayAdvisor.arrayReadLong(p.longs, 2);
-     * 
-     * //Write to Object array
-     * ArrayAdvisor.arrayWriteObject(p.objects, 2, "Hello");
-     * 
-     * //Read from Object array
-     * Object o = ArrayAdvisor.arrayReadObject(p.objects, 2);
-     * 
-     * //Write to Integer array
-     * Integer integer = new Integer(5);
-     * ArrayAdvisor.arrayWriteObject(p.integers, 0, integer);
-     * 
-     * //Read from Object array
-     * integer = ArrayAdvisor.arrayWriteObject(p.integers, 0);
-     * 
- * - * @see DefaultArrayAccessReplacementMethodNames - * - * @param calledClass the class containing the static methods. - * @param names contains the names of the methods to replace - * the different kinds of array access with. - */ - public void replaceArrayAccess(CtClass calledClass, ArrayAccessReplacementMethodNames names) - throws NotFoundException - { - transformers = new com.fr.third.javassist.convert.TransformAccessArrayField(transformers, calledClass.getName(), names); - } - - /** - * Modify method invocations in a method body so that a different - * method will be invoked. - * - *

Note that the target object, the parameters, or - * the type of invocation - * (static method call, interface call, or private method call) - * are not modified. Only the method name is changed. The substituted - * method must have the same signature that the original one has. - * If the original method is a static method, the substituted method - * must be static. - * - * @param origMethod original method - * @param substMethod substituted method - */ - public void redirectMethodCall(CtMethod origMethod, - CtMethod substMethod) - throws com.fr.third.javassist.CannotCompileException - { - String d1 = origMethod.getMethodInfo2().getDescriptor(); - String d2 = substMethod.getMethodInfo2().getDescriptor(); - if (!d1.equals(d2)) - throw new com.fr.third.javassist.CannotCompileException("signature mismatch: " - + substMethod.getLongName()); - - int mod1 = origMethod.getModifiers(); - int mod2 = substMethod.getModifiers(); - if (Modifier.isStatic(mod1) != Modifier.isStatic(mod2) - || (Modifier.isPrivate(mod1) && !Modifier.isPrivate(mod2)) - || origMethod.getDeclaringClass().isInterface() - != substMethod.getDeclaringClass().isInterface()) - throw new com.fr.third.javassist.CannotCompileException("invoke-type mismatch " - + substMethod.getLongName()); - - transformers = new com.fr.third.javassist.convert.TransformCall(transformers, origMethod, - substMethod); - } - - /** - * Correct invocations to a method that has been renamed. - * If a method is renamed, calls to that method must be also - * modified so that the method with the new name will be called. - * - *

The method must be declared in the same class before and - * after it is renamed. - * - *

Note that the target object, the parameters, or - * the type of invocation - * (static method call, interface call, or private method call) - * are not modified. Only the method name is changed. - * - * @param oldMethodName the old name of the method. - * @param newMethod the method with the new name. - * @see CtMethod#setName(String) - */ - public void redirectMethodCall(String oldMethodName, - CtMethod newMethod) - throws com.fr.third.javassist.CannotCompileException - { - transformers - = new TransformCall(transformers, oldMethodName, newMethod); - } - - /** - * Insert a call to another method before an existing method call. - * That "before" method must be static. The return type must be - * void. As parameters, the before method receives - * the target object and all the parameters to the originally invoked - * method. For example, if the originally invoked method is - * move(): - * - *

    class Point {
    -     *     Point move(int x, int y) { ... }
    -     * }
- * - *

Then the before method must be something like this: - * - *

    class Verbose {
    -     *     static void print(Point target, int x, int y) { ... }
    -     * }
- * - *

The CodeConverter would translate bytecode - * equivalent to: - * - *

    Point p2 = p.move(x + y, 0);
- * - *

into the bytecode equivalent to: - * - *

    int tmp1 = x + y;
    -     * int tmp2 = 0;
    -     * Verbose.print(p, tmp1, tmp2);
    -     * Point p2 = p.move(tmp1, tmp2);
- * - * @param origMethod the method originally invoked. - * @param beforeMethod the method invoked before - * origMethod. - */ - public void insertBeforeMethod(CtMethod origMethod, - CtMethod beforeMethod) - throws com.fr.third.javassist.CannotCompileException - { - try { - transformers = new com.fr.third.javassist.convert.TransformBefore(transformers, origMethod, - beforeMethod); - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - /** - * Inserts a call to another method after an existing method call. - * That "after" method must be static. The return type must be - * void. As parameters, the after method receives - * the target object and all the parameters to the originally invoked - * method. For example, if the originally invoked method is - * move(): - * - *
    class Point {
    -     *     Point move(int x, int y) { ... }
    -     * }
- * - *

Then the after method must be something like this: - * - *

    class Verbose {
    -     *     static void print(Point target, int x, int y) { ... }
    -     * }
- * - *

The CodeConverter would translate bytecode - * equivalent to: - * - *

    Point p2 = p.move(x + y, 0);
- * - *

into the bytecode equivalent to: - * - *

    int tmp1 = x + y;
    -     * int tmp2 = 0;
    -     * Point p2 = p.move(tmp1, tmp2);
    -     * Verbose.print(p, tmp1, tmp2);
- * - * @param origMethod the method originally invoked. - * @param afterMethod the method invoked after - * origMethod. - */ - public void insertAfterMethod(CtMethod origMethod, - CtMethod afterMethod) - throws com.fr.third.javassist.CannotCompileException - { - try { - transformers = new com.fr.third.javassist.convert.TransformAfter(transformers, origMethod, - afterMethod); - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - /** - * Performs code conversion. - */ - protected void doit(CtClass clazz, com.fr.third.javassist.bytecode.MethodInfo minfo, com.fr.third.javassist.bytecode.ConstPool cp) - throws com.fr.third.javassist.CannotCompileException - { - com.fr.third.javassist.convert.Transformer t; - CodeAttribute codeAttr = minfo.getCodeAttribute(); - if (codeAttr == null || transformers == null) - return; - for (t = transformers; t != null; t = t.getNext()) - t.initialize(cp, clazz, minfo); - - com.fr.third.javassist.bytecode.CodeIterator iterator = codeAttr.iterator(); - while (iterator.hasNext()) { - try { - int pos = iterator.next(); - for (t = transformers; t != null; t = t.getNext()) - pos = t.transform(clazz, pos, iterator, cp); - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - int locals = 0; - int stack = 0; - for (t = transformers; t != null; t = t.getNext()) { - int s = t.extraLocals(); - if (s > locals) - locals = s; - - s = t.extraStack(); - if (s > stack) - stack = s; - } - - for (t = transformers; t != null; t = t.getNext()) - t.clean(); - - if (locals > 0) - codeAttr.setMaxLocals(codeAttr.getMaxLocals() + locals); - - if (stack > 0) - codeAttr.setMaxStack(codeAttr.getMaxStack() + stack); - - try { - minfo.rebuildStackMapIf6(clazz.getClassPool(), - clazz.getClassFile2()); - } - catch (com.fr.third.javassist.bytecode.BadBytecode b) { - throw new CannotCompileException(b.getMessage(), b); - } - } - - /** - * Interface containing the method names to be used - * as array access replacements. - * - * @author Kabir Khan - * @version $Revision: 1.16 $ - */ - public interface ArrayAccessReplacementMethodNames - { - /** - * Returns the name of a static method with the signature - * (Ljava/lang/Object;I)B to replace reading from a byte[]. - */ - String byteOrBooleanRead(); - - /** - * Returns the name of a static method with the signature - * (Ljava/lang/Object;IB)V to replace writing to a byte[]. - */ - String byteOrBooleanWrite(); - - /** - * @return the name of a static method with the signature - * (Ljava/lang/Object;I)C to replace reading from a char[]. - */ - String charRead(); - - /** - * Returns the name of a static method with the signature - * (Ljava/lang/Object;IC)V to replace writing to a byte[]. - */ - String charWrite(); - - /** - * Returns the name of a static method with the signature - * (Ljava/lang/Object;I)D to replace reading from a double[]. - */ - String doubleRead(); - - /** - * Returns the name of a static method with the signature - * (Ljava/lang/Object;ID)V to replace writing to a double[]. - */ - String doubleWrite(); - - /** - * Returns the name of a static method with the signature - * (Ljava/lang/Object;I)F to replace reading from a float[]. - */ - String floatRead(); - - /** - * Returns the name of a static method with the signature - * (Ljava/lang/Object;IF)V to replace writing to a float[]. - */ - String floatWrite(); - - /** - * Returns the name of a static method with the signature - * (Ljava/lang/Object;I)I to replace reading from a int[]. - */ - String intRead(); - - /** - * Returns the name of a static method with the signature - * (Ljava/lang/Object;II)V to replace writing to a int[]. - */ - String intWrite(); - - /** - * Returns the name of a static method with the signature - * (Ljava/lang/Object;I)J to replace reading from a long[]. - */ - String longRead(); - - /** - * Returns the name of a static method with the signature - * (Ljava/lang/Object;IJ)V to replace writing to a long[]. - */ - String longWrite(); - - /** - * Returns the name of a static method with the signature - * (Ljava/lang/Object;I)Ljava/lang/Object; - * to replace reading from a Object[] (or any subclass of object). - */ - String objectRead(); - - /** - * Returns the name of a static method with the signature - * (Ljava/lang/Object;ILjava/lang/Object;)V - * to replace writing to a Object[] (or any subclass of object). - */ - String objectWrite(); - - /** - * Returns the name of a static method with the signature - * (Ljava/lang/Object;I)S to replace reading from a short[]. - */ - String shortRead(); - - /** - * Returns the name of a static method with the signature - * (Ljava/lang/Object;IS)V to replace writing to a short[]. - */ - String shortWrite(); - } - - /** - * Default implementation of the ArrayAccessReplacementMethodNames - * interface giving default values for method names to be used for replacing - * accesses to array elements. - * - * @author Kabir Khan - * @version $Revision: 1.16 $ - */ - public static class DefaultArrayAccessReplacementMethodNames - implements ArrayAccessReplacementMethodNames - { - /** - * Returns "arrayReadByteOrBoolean" as the name of the static method with the signature - * (Ljava/lang/Object;I)B to replace reading from a byte[]. - */ - public String byteOrBooleanRead() - { - return "arrayReadByteOrBoolean"; - } - - /** - * Returns "arrayWriteByteOrBoolean" as the name of the static method with the signature - * (Ljava/lang/Object;IB)V to replace writing to a byte[]. - */ - public String byteOrBooleanWrite() - { - return "arrayWriteByteOrBoolean"; - } - - /** - * Returns "arrayReadChar" as the name of the static method with the signature - * (Ljava/lang/Object;I)C to replace reading from a char[]. - */ - public String charRead() - { - return "arrayReadChar"; - } - - /** - * Returns "arrayWriteChar" as the name of the static method with the signature - * (Ljava/lang/Object;IC)V to replace writing to a byte[]. - */ - public String charWrite() - { - return "arrayWriteChar"; - } - - /** - * Returns "arrayReadDouble" as the name of the static method with the signature - * (Ljava/lang/Object;I)D to replace reading from a double[]. - */ - public String doubleRead() - { - return "arrayReadDouble"; - } - - /** - * Returns "arrayWriteDouble" as the name of the static method with the signature - * (Ljava/lang/Object;ID)V to replace writing to a double[]. - */ - public String doubleWrite() - { - return "arrayWriteDouble"; - } - - /** - * Returns "arrayReadFloat" as the name of the static method with the signature - * (Ljava/lang/Object;I)F to replace reading from a float[]. - */ - public String floatRead() - { - return "arrayReadFloat"; - } - - /** - * Returns "arrayWriteFloat" as the name of the static method with the signature - * (Ljava/lang/Object;IF)V to replace writing to a float[]. - */ - public String floatWrite() - { - return "arrayWriteFloat"; - } - - /** - * Returns "arrayReadInt" as the name of the static method with the signature - * (Ljava/lang/Object;I)I to replace reading from a int[]. - */ - public String intRead() - { - return "arrayReadInt"; - } - - /** - * Returns "arrayWriteInt" as the name of the static method with the signature - * (Ljava/lang/Object;II)V to replace writing to a int[]. - */ - public String intWrite() - { - return "arrayWriteInt"; - } - - /** - * Returns "arrayReadLong" as the name of the static method with the signature - * (Ljava/lang/Object;I)J to replace reading from a long[]. - */ - public String longRead() - { - return "arrayReadLong"; - } - - /** - * Returns "arrayWriteLong" as the name of the static method with the signature - * (Ljava/lang/Object;IJ)V to replace writing to a long[]. - */ - public String longWrite() - { - return "arrayWriteLong"; - } - - /** - * Returns "arrayReadObject" as the name of the static method with the signature - * (Ljava/lang/Object;I)Ljava/lang/Object; to replace reading from a Object[] (or any subclass of object). - */ - public String objectRead() - { - return "arrayReadObject"; - } - - /** - * Returns "arrayWriteObject" as the name of the static method with the signature - * (Ljava/lang/Object;ILjava/lang/Object;)V to replace writing to a Object[] (or any subclass of object). - */ - public String objectWrite() - { - return "arrayWriteObject"; - } - - /** - * Returns "arrayReadShort" as the name of the static method with the signature - * (Ljava/lang/Object;I)S to replace reading from a short[]. - */ - public String shortRead() - { - return "arrayReadShort"; - } - - /** - * Returns "arrayWriteShort" as the name of the static method with the signature - * (Ljava/lang/Object;IS)V to replace writing to a short[]. - */ - public String shortWrite() - { - return "arrayWriteShort"; - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CtArray.java b/fine-javassist/src/main/java/com/fr/third/javassist/CtArray.java deleted file mode 100644 index de43889c5..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CtArray.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -/** - * Array types. - */ -final class CtArray extends CtClass { - protected com.fr.third.javassist.ClassPool pool; - - // the name of array type ends with "[]". - CtArray(String name, com.fr.third.javassist.ClassPool cp) { - super(name); - pool = cp; - } - - public ClassPool getClassPool() { - return pool; - } - - public boolean isArray() { - return true; - } - - private CtClass[] interfaces = null; - - public int getModifiers() { - int mod = Modifier.FINAL; - try { - mod |= getComponentType().getModifiers() - & (Modifier.PROTECTED | Modifier.PUBLIC | Modifier.PRIVATE); - } - catch (NotFoundException e) {} - return mod; - } - - public CtClass[] getInterfaces() throws NotFoundException { - if (interfaces == null) { - Class[] intfs = Object[].class.getInterfaces(); - // java.lang.Cloneable and java.io.Serializable. - // If the JVM is CLDC, intfs is empty. - interfaces = new CtClass[intfs.length]; - for (int i = 0; i < intfs.length; i++) - interfaces[i] = pool.get(intfs[i].getName()); - } - - return interfaces; - } - - public boolean subtypeOf(CtClass clazz) throws NotFoundException { - if (super.subtypeOf(clazz)) - return true; - - String cname = clazz.getName(); - if (cname.equals(javaLangObject)) - return true; - - CtClass[] intfs = getInterfaces(); - for (int i = 0; i < intfs.length; i++) - if (intfs[i].subtypeOf(clazz)) - return true; - - return clazz.isArray() - && getComponentType().subtypeOf(clazz.getComponentType()); - } - - public CtClass getComponentType() throws NotFoundException { - String name = getName(); - return pool.get(name.substring(0, name.length() - 2)); - } - - public CtClass getSuperclass() throws NotFoundException { - return pool.get(javaLangObject); - } - - public CtMethod[] getMethods() { - try { - return getSuperclass().getMethods(); - } - catch (NotFoundException e) { - return super.getMethods(); - } - } - - public CtMethod getMethod(String name, String desc) - throws NotFoundException - { - return getSuperclass().getMethod(name, desc); - } - - public CtConstructor[] getConstructors() { - try { - return getSuperclass().getConstructors(); - } - catch (NotFoundException e) { - return super.getConstructors(); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CtBehavior.java b/fine-javassist/src/main/java/com/fr/third/javassist/CtBehavior.java deleted file mode 100644 index a227327a6..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CtBehavior.java +++ /dev/null @@ -1,1215 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.expr.Expr; -import com.fr.third.javassist.runtime.Cflow; -import com.fr.third.javassist.compiler.Javac; -import com.fr.third.javassist.compiler.CompileError; -import com.fr.third.javassist.expr.ExprEditor; - -/** - * CtBehavior represents a method, a constructor, - * or a static constructor (class initializer). - * It is the abstract super class of - * CtMethod and CtConstructor. - * - *

To directly read or modify bytecode, obtain MethodInfo - * objects. - * - * @see #getMethodInfo() - */ -public abstract class CtBehavior extends CtMember { - protected com.fr.third.javassist.bytecode.MethodInfo methodInfo; - - protected CtBehavior(CtClass clazz, com.fr.third.javassist.bytecode.MethodInfo minfo) { - super(clazz); - methodInfo = minfo; - } - - /** - * @param isCons true if this is a constructor. - */ - void copy(CtBehavior src, boolean isCons, com.fr.third.javassist.ClassMap map) - throws com.fr.third.javassist.CannotCompileException - { - CtClass declaring = declaringClass; - com.fr.third.javassist.bytecode.MethodInfo srcInfo = src.methodInfo; - CtClass srcClass = src.getDeclaringClass(); - com.fr.third.javassist.bytecode.ConstPool cp = declaring.getClassFile2().getConstPool(); - - map = new com.fr.third.javassist.ClassMap(map); - map.put(srcClass.getName(), declaring.getName()); - try { - boolean patch = false; - CtClass srcSuper = srcClass.getSuperclass(); - CtClass destSuper = declaring.getSuperclass(); - String destSuperName = null; - if (srcSuper != null && destSuper != null) { - String srcSuperName = srcSuper.getName(); - destSuperName = destSuper.getName(); - if (!srcSuperName.equals(destSuperName)) - if (srcSuperName.equals(CtClass.javaLangObject)) - patch = true; - else - map.putIfNone(srcSuperName, destSuperName); - } - - // a stack map table is copied from srcInfo. - methodInfo = new com.fr.third.javassist.bytecode.MethodInfo(cp, srcInfo.getName(), srcInfo, map); - if (isCons && patch) - methodInfo.setSuperclass(destSuperName); - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - protected void extendToString(StringBuffer buffer) { - buffer.append(' '); - buffer.append(getName()); - buffer.append(' '); - buffer.append(methodInfo.getDescriptor()); - } - - /** - * Returns the method or constructor name followed by parameter types - * such as javassist.CtBehavior.stBody(String). - * - * @since 3.5 - */ - public abstract String getLongName(); - - /** - * Returns the MethodInfo representing this method/constructor in the - * class file. - * - *

If you modify the bytecode through the returned - * MethodInfo object, you might have to explicitly - * rebuild a stack map table. Javassist does not automatically - * rebuild it for avoiding unnecessary rebuilding. - * - * @see com.fr.third.javassist.bytecode.MethodInfo#rebuildStackMap(com.fr.third.javassist.ClassPool) - */ - public com.fr.third.javassist.bytecode.MethodInfo getMethodInfo() { - declaringClass.checkModify(); - return methodInfo; - } - - /** - * Returns the MethodInfo representing the method/constructor in the - * class file (read only). - * Normal applications do not need calling this method. Use - * getMethodInfo(). - * - *

The MethodInfo object obtained by this method - * is read only. Changes to this object might not be reflected - * on a class file generated by toBytecode(), - * toClass(), etc in CtClass. - * - *

This method is available even if the CtClass - * containing this method is frozen. However, if the class is - * frozen, the MethodInfo might be also pruned. - * - * @see #getMethodInfo() - * @see CtClass#isFrozen() - * @see CtClass#prune() - */ - public com.fr.third.javassist.bytecode.MethodInfo getMethodInfo2() { return methodInfo; } - - /** - * Obtains the modifiers of the method/constructor. - * - * @return modifiers encoded with - * javassist.Modifier. - * @see Modifier - */ - public int getModifiers() { - return com.fr.third.javassist.bytecode.AccessFlag.toModifier(methodInfo.getAccessFlags()); - } - - /** - * Sets the encoded modifiers of the method/constructor. - * - *

Changing the modifiers may cause a problem. - * For example, if a non-static method is changed to static, - * the method will be rejected by the bytecode verifier. - * - * @see Modifier - */ - public void setModifiers(int mod) { - declaringClass.checkModify(); - methodInfo.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.of(mod)); - } - - /** - * Returns true if the class has the specified annotation class. - * - * @param clz the annotation class. - * @return true if the annotation is found, - * otherwise false. - * @since 3.11 - */ - public boolean hasAnnotation(Class clz) { - com.fr.third.javassist.bytecode.MethodInfo mi = getMethodInfo2(); - com.fr.third.javassist.bytecode.AnnotationsAttribute ainfo = (com.fr.third.javassist.bytecode.AnnotationsAttribute) - mi.getAttribute(com.fr.third.javassist.bytecode.AnnotationsAttribute.invisibleTag); - com.fr.third.javassist.bytecode.AnnotationsAttribute ainfo2 = (com.fr.third.javassist.bytecode.AnnotationsAttribute) - mi.getAttribute(com.fr.third.javassist.bytecode.AnnotationsAttribute.visibleTag); - return CtClassType.hasAnnotationType(clz, - getDeclaringClass().getClassPool(), - ainfo, ainfo2); - } - - /** - * Returns the annotation if the class has the specified annotation class. - * For example, if an annotation @Author is associated - * with this method/constructor, an Author object is returned. - * The member values can be obtained by calling methods on - * the Author object. - * - * @param clz the annotation class. - * @return the annotation if found, otherwise null. - * @since 3.11 - */ - public Object getAnnotation(Class clz) throws ClassNotFoundException { - com.fr.third.javassist.bytecode.MethodInfo mi = getMethodInfo2(); - com.fr.third.javassist.bytecode.AnnotationsAttribute ainfo = (com.fr.third.javassist.bytecode.AnnotationsAttribute) - mi.getAttribute(com.fr.third.javassist.bytecode.AnnotationsAttribute.invisibleTag); - com.fr.third.javassist.bytecode.AnnotationsAttribute ainfo2 = (com.fr.third.javassist.bytecode.AnnotationsAttribute) - mi.getAttribute(com.fr.third.javassist.bytecode.AnnotationsAttribute.visibleTag); - return CtClassType.getAnnotationType(clz, - getDeclaringClass().getClassPool(), - ainfo, ainfo2); - } - - /** - * Returns the annotations associated with this method or constructor. - * - * @return an array of annotation-type objects. - * @see #getAvailableAnnotations() - * @since 3.1 - */ - public Object[] getAnnotations() throws ClassNotFoundException { - return getAnnotations(false); - } - - /** - * Returns the annotations associated with this method or constructor. - * If any annotations are not on the classpath, they are not included - * in the returned array. - * - * @return an array of annotation-type objects. - * @see #getAnnotations() - * @since 3.3 - */ - public Object[] getAvailableAnnotations(){ - try{ - return getAnnotations(true); - } - catch (ClassNotFoundException e){ - throw new RuntimeException("Unexpected exception", e); - } - } - - private Object[] getAnnotations(boolean ignoreNotFound) - throws ClassNotFoundException - { - com.fr.third.javassist.bytecode.MethodInfo mi = getMethodInfo2(); - com.fr.third.javassist.bytecode.AnnotationsAttribute ainfo = (com.fr.third.javassist.bytecode.AnnotationsAttribute) - mi.getAttribute(com.fr.third.javassist.bytecode.AnnotationsAttribute.invisibleTag); - com.fr.third.javassist.bytecode.AnnotationsAttribute ainfo2 = (com.fr.third.javassist.bytecode.AnnotationsAttribute) - mi.getAttribute(com.fr.third.javassist.bytecode.AnnotationsAttribute.visibleTag); - return CtClassType.toAnnotationType(ignoreNotFound, - getDeclaringClass().getClassPool(), - ainfo, ainfo2); - } - - /** - * Returns the parameter annotations associated with this method or constructor. - * - * @return an array of annotation-type objects. The length of the returned array is - * equal to the number of the formal parameters. If each parameter has no - * annotation, the elements of the returned array are empty arrays. - * - * @see #getAvailableParameterAnnotations() - * @see #getAnnotations() - * @since 3.1 - */ - public Object[][] getParameterAnnotations() throws ClassNotFoundException { - return getParameterAnnotations(false); - } - - /** - * Returns the parameter annotations associated with this method or constructor. - * If any annotations are not on the classpath, they are not included in the - * returned array. - * - * @return an array of annotation-type objects. The length of the returned array is - * equal to the number of the formal parameters. If each parameter has no - * annotation, the elements of the returned array are empty arrays. - * - * @see #getParameterAnnotations() - * @see #getAvailableAnnotations() - * @since 3.3 - */ - public Object[][] getAvailableParameterAnnotations(){ - try { - return getParameterAnnotations(true); - } - catch(ClassNotFoundException e) { - throw new RuntimeException("Unexpected exception", e); - } - } - - Object[][] getParameterAnnotations(boolean ignoreNotFound) - throws ClassNotFoundException - { - com.fr.third.javassist.bytecode.MethodInfo mi = getMethodInfo2(); - com.fr.third.javassist.bytecode.ParameterAnnotationsAttribute ainfo = (com.fr.third.javassist.bytecode.ParameterAnnotationsAttribute) - mi.getAttribute(com.fr.third.javassist.bytecode.ParameterAnnotationsAttribute.invisibleTag); - com.fr.third.javassist.bytecode.ParameterAnnotationsAttribute ainfo2 = (com.fr.third.javassist.bytecode.ParameterAnnotationsAttribute) - mi.getAttribute(com.fr.third.javassist.bytecode.ParameterAnnotationsAttribute.visibleTag); - return CtClassType.toAnnotationType(ignoreNotFound, - getDeclaringClass().getClassPool(), - ainfo, ainfo2, mi); - } - - /** - * Obtains parameter types of this method/constructor. - */ - public CtClass[] getParameterTypes() throws NotFoundException { - return com.fr.third.javassist.bytecode.Descriptor.getParameterTypes(methodInfo.getDescriptor(), - declaringClass.getClassPool()); - } - - /** - * Obtains the type of the returned value. - */ - CtClass getReturnType0() throws NotFoundException { - return com.fr.third.javassist.bytecode.Descriptor.getReturnType(methodInfo.getDescriptor(), - declaringClass.getClassPool()); - } - - /** - * Returns the method signature (the parameter types - * and the return type). - * The method signature is represented by a character string - * called method descriptor, which is defined in the JVM specification. - * If two methods/constructors have - * the same parameter types - * and the return type, getSignature() returns the - * same string (the return type of constructors is void). - * - *

Note that the returned string is not the type signature - * contained in the SignatureAttirbute. It is - * a descriptor. - * - * @see com.fr.third.javassist.bytecode.Descriptor - * @see #getGenericSignature() - */ - public String getSignature() { - return methodInfo.getDescriptor(); - } - - /** - * Returns the generic signature of the method. - * It represents parameter types including type variables. - * - * @see com.fr.third.javassist.bytecode.SignatureAttribute#toMethodSignature(String) - * @since 3.17 - */ - public String getGenericSignature() { - com.fr.third.javassist.bytecode.SignatureAttribute sa - = (com.fr.third.javassist.bytecode.SignatureAttribute)methodInfo.getAttribute(com.fr.third.javassist.bytecode.SignatureAttribute.tag); - return sa == null ? null : sa.getSignature(); - } - - /** - * Set the generic signature of the method. - * It represents parameter types including type variables. - * See {@link CtClass#setGenericSignature(String)} - * for a code sample. - * - * @param sig a new generic signature. - * @see com.fr.third.javassist.bytecode.SignatureAttribute.MethodSignature#encode() - * @since 3.17 - */ - public void setGenericSignature(String sig) { - declaringClass.checkModify(); - methodInfo.addAttribute(new com.fr.third.javassist.bytecode.SignatureAttribute(methodInfo.getConstPool(), sig)); - } - - /** - * Obtains exceptions that this method/constructor may throw. - * - * @return a zero-length array if there is no throws clause. - */ - public CtClass[] getExceptionTypes() throws NotFoundException { - String[] exceptions; - com.fr.third.javassist.bytecode.ExceptionsAttribute ea = methodInfo.getExceptionsAttribute(); - if (ea == null) - exceptions = null; - else - exceptions = ea.getExceptions(); - - return declaringClass.getClassPool().get(exceptions); - } - - /** - * Sets exceptions that this method/constructor may throw. - */ - public void setExceptionTypes(CtClass[] types) throws NotFoundException { - declaringClass.checkModify(); - if (types == null || types.length == 0) { - methodInfo.removeExceptionsAttribute(); - return; - } - - String[] names = new String[types.length]; - for (int i = 0; i < types.length; ++i) - names[i] = types[i].getName(); - - com.fr.third.javassist.bytecode.ExceptionsAttribute ea = methodInfo.getExceptionsAttribute(); - if (ea == null) { - ea = new com.fr.third.javassist.bytecode.ExceptionsAttribute(methodInfo.getConstPool()); - methodInfo.setExceptionsAttribute(ea); - } - - ea.setExceptions(names); - } - - /** - * Returns true if the body is empty. - */ - public abstract boolean isEmpty(); - - /** - * Sets a method/constructor body. - * - * @param src the source code representing the body. - * It must be a single statement or block. - * If it is null, the substituted - * body does nothing except returning zero or null. - */ - public void setBody(String src) throws com.fr.third.javassist.CannotCompileException { - setBody(src, null, null); - } - - /** - * Sets a method/constructor body. - * - * @param src the source code representing the body. - * It must be a single statement or block. - * If it is null, the substituted - * body does nothing except returning zero or null. - * @param delegateObj the source text specifying the object - * that is called on by $proceed(). - * @param delegateMethod the name of the method - * that is called by $proceed(). - */ - public void setBody(String src, - String delegateObj, String delegateMethod) - throws com.fr.third.javassist.CannotCompileException - { - CtClass cc = declaringClass; - cc.checkModify(); - try { - Javac jv = new Javac(cc); - if (delegateMethod != null) - jv.recordProceed(delegateObj, delegateMethod); - - com.fr.third.javassist.bytecode.Bytecode b = jv.compileBody(this, src); - methodInfo.setCodeAttribute(b.toCodeAttribute()); - methodInfo.setAccessFlags(methodInfo.getAccessFlags() - & ~com.fr.third.javassist.bytecode.AccessFlag.ABSTRACT); - methodInfo.rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2()); - declaringClass.rebuildClassFile(); - } - catch (CompileError e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - static void setBody0(CtClass srcClass, com.fr.third.javassist.bytecode.MethodInfo srcInfo, - CtClass destClass, com.fr.third.javassist.bytecode.MethodInfo destInfo, - com.fr.third.javassist.ClassMap map) - throws com.fr.third.javassist.CannotCompileException - { - destClass.checkModify(); - - map = new ClassMap(map); - map.put(srcClass.getName(), destClass.getName()); - try { - com.fr.third.javassist.bytecode.CodeAttribute cattr = srcInfo.getCodeAttribute(); - if (cattr != null) { - com.fr.third.javassist.bytecode.ConstPool cp = destInfo.getConstPool(); - com.fr.third.javassist.bytecode.CodeAttribute ca = (com.fr.third.javassist.bytecode.CodeAttribute)cattr.copy(cp, map); - destInfo.setCodeAttribute(ca); - // a stack map table is copied to destInfo. - } - } - catch (com.fr.third.javassist.bytecode.CodeAttribute.RuntimeCopyException e) { - /* the exception may be thrown by copy() in CodeAttribute. - */ - throw new com.fr.third.javassist.CannotCompileException(e); - } - - destInfo.setAccessFlags(destInfo.getAccessFlags() - & ~com.fr.third.javassist.bytecode.AccessFlag.ABSTRACT); - destClass.rebuildClassFile(); - } - - /** - * Obtains an attribute with the given name. - * If that attribute is not found in the class file, this - * method returns null. - * - *

Note that an attribute is a data block specified by - * the class file format. It is not an annotation. - * See {@link com.fr.third.javassist.bytecode.AttributeInfo}. - * - * @param name attribute name - */ - public byte[] getAttribute(String name) { - com.fr.third.javassist.bytecode.AttributeInfo ai = methodInfo.getAttribute(name); - if (ai == null) - return null; - else - return ai.get(); - } - - /** - * Adds an attribute. The attribute is saved in the class file. - * - *

Note that an attribute is a data block specified by - * the class file format. It is not an annotation. - * See {@link com.fr.third.javassist.bytecode.AttributeInfo}. - * - * @param name attribute name - * @param data attribute value - */ - public void setAttribute(String name, byte[] data) { - declaringClass.checkModify(); - methodInfo.addAttribute(new com.fr.third.javassist.bytecode.AttributeInfo(methodInfo.getConstPool(), - name, data)); - } - - /** - * Declares to use $cflow for this method/constructor. - * If $cflow is used, the class files modified - * with Javassist requires a support class - * javassist.runtime.Cflow at runtime - * (other Javassist classes are not required at runtime). - * - *

Every $cflow variable is given a unique name. - * For example, if the given name is "Point.paint", - * then the variable is indicated by $cflow(Point.paint). - * - * @param name $cflow name. It can include - * alphabets, numbers, _, - * $, and . (dot). - * - * @see Cflow - */ - public void useCflow(String name) throws com.fr.third.javassist.CannotCompileException { - CtClass cc = declaringClass; - cc.checkModify(); - ClassPool pool = cc.getClassPool(); - String fname; - int i = 0; - while (true) { - fname = "_cflow$" + i++; - try { - cc.getDeclaredField(fname); - } - catch(NotFoundException e) { - break; - } - } - - pool.recordCflow(name, declaringClass.getName(), fname); - try { - CtClass type = pool.get("javassist.runtime.Cflow"); - CtField field = new CtField(type, fname, cc); - field.setModifiers(Modifier.PUBLIC | Modifier.STATIC); - cc.addField(field, CtField.Initializer.byNew(type)); - insertBefore(fname + ".enter();", false); - String src = fname + ".exit();"; - insertAfter(src, true); - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - /** - * Declares a new local variable. The scope of this variable is the - * whole method body. The initial value of that variable is not set. - * The declared variable can be accessed in the code snippet inserted - * by insertBefore(), insertAfter(), etc. - * - *

If the second parameter asFinally to - * insertAfter() is true, the declared local variable - * is not visible from the code inserted by insertAfter(). - * - * @param name the name of the variable - * @param type the type of the variable - * @see #insertBefore(String) - * @see #insertAfter(String) - */ - public void addLocalVariable(String name, CtClass type) - throws com.fr.third.javassist.CannotCompileException - { - declaringClass.checkModify(); - com.fr.third.javassist.bytecode.ConstPool cp = methodInfo.getConstPool(); - com.fr.third.javassist.bytecode.CodeAttribute ca = methodInfo.getCodeAttribute(); - if (ca == null) - throw new com.fr.third.javassist.CannotCompileException("no method body"); - - com.fr.third.javassist.bytecode.LocalVariableAttribute va = (com.fr.third.javassist.bytecode.LocalVariableAttribute)ca.getAttribute( - com.fr.third.javassist.bytecode.LocalVariableAttribute.tag); - if (va == null) { - va = new com.fr.third.javassist.bytecode.LocalVariableAttribute(cp); - ca.getAttributes().add(va); - } - - int maxLocals = ca.getMaxLocals(); - String desc = com.fr.third.javassist.bytecode.Descriptor.of(type); - va.addEntry(0, ca.getCodeLength(), - cp.addUtf8Info(name), cp.addUtf8Info(desc), maxLocals); - ca.setMaxLocals(maxLocals + com.fr.third.javassist.bytecode.Descriptor.dataSize(desc)); - } - - /** - * Inserts a new parameter, which becomes the first parameter. - */ - public void insertParameter(CtClass type) - throws com.fr.third.javassist.CannotCompileException - { - declaringClass.checkModify(); - String desc = methodInfo.getDescriptor(); - String desc2 = com.fr.third.javassist.bytecode.Descriptor.insertParameter(type, desc); - try { - addParameter2(Modifier.isStatic(getModifiers()) ? 0 : 1, type, desc); - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - - methodInfo.setDescriptor(desc2); - } - - /** - * Appends a new parameter, which becomes the last parameter. - */ - public void addParameter(CtClass type) - throws com.fr.third.javassist.CannotCompileException - { - declaringClass.checkModify(); - String desc = methodInfo.getDescriptor(); - String desc2 = com.fr.third.javassist.bytecode.Descriptor.appendParameter(type, desc); - int offset = Modifier.isStatic(getModifiers()) ? 0 : 1; - try { - addParameter2(offset + com.fr.third.javassist.bytecode.Descriptor.paramSize(desc), type, desc); - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - - methodInfo.setDescriptor(desc2); - } - - private void addParameter2(int where, CtClass type, String desc) - throws com.fr.third.javassist.bytecode.BadBytecode - { - com.fr.third.javassist.bytecode.CodeAttribute ca = methodInfo.getCodeAttribute(); - if (ca != null) { - int size = 1; - char typeDesc = 'L'; - int classInfo = 0; - if (type.isPrimitive()) { - CtPrimitiveType cpt = (CtPrimitiveType)type; - size = cpt.getDataSize(); - typeDesc = cpt.getDescriptor(); - } - else - classInfo = methodInfo.getConstPool().addClassInfo(type); - - ca.insertLocalVar(where, size); - com.fr.third.javassist.bytecode.LocalVariableAttribute va - = (com.fr.third.javassist.bytecode.LocalVariableAttribute)ca.getAttribute(com.fr.third.javassist.bytecode.LocalVariableAttribute.tag); - if (va != null) - va.shiftIndex(where, size); - - com.fr.third.javassist.bytecode.LocalVariableTypeAttribute lvta - = (com.fr.third.javassist.bytecode.LocalVariableTypeAttribute)ca.getAttribute(com.fr.third.javassist.bytecode.LocalVariableTypeAttribute.tag); - if (lvta != null) - lvta.shiftIndex(where, size); - - com.fr.third.javassist.bytecode.StackMapTable smt = (com.fr.third.javassist.bytecode.StackMapTable)ca.getAttribute(com.fr.third.javassist.bytecode.StackMapTable.tag); - if (smt != null) - smt.insertLocal(where, com.fr.third.javassist.bytecode.StackMapTable.typeTagOf(typeDesc), classInfo); - - com.fr.third.javassist.bytecode.StackMap sm = (com.fr.third.javassist.bytecode.StackMap)ca.getAttribute(com.fr.third.javassist.bytecode.StackMap.tag); - if (sm != null) - sm.insertLocal(where, com.fr.third.javassist.bytecode.StackMapTable.typeTagOf(typeDesc), classInfo); - } - } - - /** - * Modifies the method/constructor body. - * - * @param converter specifies how to modify. - */ - public void instrument(CodeConverter converter) - throws com.fr.third.javassist.CannotCompileException - { - declaringClass.checkModify(); - com.fr.third.javassist.bytecode.ConstPool cp = methodInfo.getConstPool(); - converter.doit(getDeclaringClass(), methodInfo, cp); - } - - /** - * Modifies the method/constructor body. - * - *

While executing this method, only replace() - * in Expr is available for bytecode modification. - * Other methods such as insertBefore() may collapse - * the bytecode because the ExprEditor loses - * its current position. - * - * @param editor specifies how to modify. - * @see Expr#replace(String) - * @see #insertBefore(String) - */ - public void instrument(ExprEditor editor) - throws com.fr.third.javassist.CannotCompileException - { - // if the class is not frozen, - // does not turn the modified flag on. - if (declaringClass.isFrozen()) - declaringClass.checkModify(); - - if (editor.doit(declaringClass, methodInfo)) - declaringClass.checkModify(); - } - - /** - * Inserts bytecode at the beginning of the body. - * - *

If this object represents a constructor, - * the bytecode is inserted before - * a constructor in the super class or this class is called. - * Therefore, the inserted bytecode is subject to constraints described - * in Section 4.8.2 of The Java Virtual Machine Specification (2nd ed). - * For example, it cannot access instance fields or methods although - * it may assign a value to an instance field directly declared in this - * class. Accessing static fields and methods is allowed. - * Use insertBeforeBody() in CtConstructor. - * - * @param src the source code representing the inserted bytecode. - * It must be a single statement or block. - * @see CtConstructor#insertBeforeBody(String) - */ - public void insertBefore(String src) throws com.fr.third.javassist.CannotCompileException { - insertBefore(src, true); - } - - private void insertBefore(String src, boolean rebuild) - throws com.fr.third.javassist.CannotCompileException - { - CtClass cc = declaringClass; - cc.checkModify(); - com.fr.third.javassist.bytecode.CodeAttribute ca = methodInfo.getCodeAttribute(); - if (ca == null) - throw new com.fr.third.javassist.CannotCompileException("no method body"); - - com.fr.third.javassist.bytecode.CodeIterator iterator = ca.iterator(); - Javac jv = new Javac(cc); - try { - int nvars = jv.recordParams(getParameterTypes(), - Modifier.isStatic(getModifiers())); - jv.recordParamNames(ca, nvars); - jv.recordLocalVariables(ca, 0); - jv.recordType(getReturnType0()); - jv.compileStmnt(src); - com.fr.third.javassist.bytecode.Bytecode b = jv.getBytecode(); - int stack = b.getMaxStack(); - int locals = b.getMaxLocals(); - - if (stack > ca.getMaxStack()) - ca.setMaxStack(stack); - - if (locals > ca.getMaxLocals()) - ca.setMaxLocals(locals); - - int pos = iterator.insertEx(b.get()); - iterator.insert(b.getExceptionTable(), pos); - if (rebuild) - methodInfo.rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2()); - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - catch (CompileError e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - /** - * Inserts bytecode at the end of the body. - * The bytecode is inserted just before every return insturction. - * It is not executed when an exception is thrown. - * - * @param src the source code representing the inserted bytecode. - * It must be a single statement or block. - */ - public void insertAfter(String src) - throws com.fr.third.javassist.CannotCompileException - { - insertAfter(src, false); - } - - /** - * Inserts bytecode at the end of the body. - * The bytecode is inserted just before every return insturction. - * - * @param src the source code representing the inserted bytecode. - * It must be a single statement or block. - * @param asFinally true if the inserted bytecode is executed - * not only when the control normally returns - * but also when an exception is thrown. - * If this parameter is true, the inserted code cannot - * access local variables. - */ - public void insertAfter(String src, boolean asFinally) - throws com.fr.third.javassist.CannotCompileException - { - CtClass cc = declaringClass; - cc.checkModify(); - com.fr.third.javassist.bytecode.ConstPool pool = methodInfo.getConstPool(); - com.fr.third.javassist.bytecode.CodeAttribute ca = methodInfo.getCodeAttribute(); - if (ca == null) - throw new com.fr.third.javassist.CannotCompileException("no method body"); - - com.fr.third.javassist.bytecode.CodeIterator iterator = ca.iterator(); - int retAddr = ca.getMaxLocals(); - com.fr.third.javassist.bytecode.Bytecode b = new com.fr.third.javassist.bytecode.Bytecode(pool, 0, retAddr + 1); - b.setStackDepth(ca.getMaxStack() + 1); - Javac jv = new Javac(b, cc); - try { - int nvars = jv.recordParams(getParameterTypes(), - Modifier.isStatic(getModifiers())); - jv.recordParamNames(ca, nvars); - CtClass rtype = getReturnType0(); - int varNo = jv.recordReturnType(rtype, true); - jv.recordLocalVariables(ca, 0); - - // finally clause for exceptions - int handlerLen = insertAfterHandler(asFinally, b, rtype, varNo, - jv, src); - int handlerPos = iterator.getCodeLength(); - if (asFinally) - ca.getExceptionTable().add(getStartPosOfBody(ca), handlerPos, handlerPos, 0); - - int adviceLen = 0; - int advicePos = 0; - boolean noReturn = true; - while (iterator.hasNext()) { - int pos = iterator.next(); - if (pos >= handlerPos) - break; - - int c = iterator.byteAt(pos); - if (c == com.fr.third.javassist.bytecode.Opcode.ARETURN || c == com.fr.third.javassist.bytecode.Opcode.IRETURN - || c == com.fr.third.javassist.bytecode.Opcode.FRETURN || c == com.fr.third.javassist.bytecode.Opcode.LRETURN - || c == com.fr.third.javassist.bytecode.Opcode.DRETURN || c == com.fr.third.javassist.bytecode.Opcode.RETURN) { - if (noReturn) { - // finally clause for normal termination - adviceLen = insertAfterAdvice(b, jv, src, pool, rtype, varNo); - handlerPos = iterator.append(b.get()); - iterator.append(b.getExceptionTable(), handlerPos); - advicePos = iterator.getCodeLength() - adviceLen; - handlerLen = advicePos - handlerPos; - noReturn = false; - } - insertGoto(iterator, advicePos, pos); - advicePos = iterator.getCodeLength() - adviceLen; - handlerPos = advicePos - handlerLen; - } - } - - if (noReturn) { - handlerPos = iterator.append(b.get()); - iterator.append(b.getExceptionTable(), handlerPos); - } - - ca.setMaxStack(b.getMaxStack()); - ca.setMaxLocals(b.getMaxLocals()); - methodInfo.rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2()); - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - catch (CompileError e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - private int insertAfterAdvice(com.fr.third.javassist.bytecode.Bytecode code, Javac jv, String src, - com.fr.third.javassist.bytecode.ConstPool cp, CtClass rtype, int varNo) - throws CompileError - { - int pc = code.currentPc(); - if (rtype == CtClass.voidType) { - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.ACONST_NULL); - code.addAstore(varNo); - jv.compileStmnt(src); - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.RETURN); - if (code.getMaxLocals() < 1) - code.setMaxLocals(1); - } - else { - code.addStore(varNo, rtype); - jv.compileStmnt(src); - code.addLoad(varNo, rtype); - if (rtype.isPrimitive()) - code.addOpcode(((CtPrimitiveType)rtype).getReturnOp()); - else - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.ARETURN); - } - - return code.currentPc() - pc; - } - - /* - * assert subr > pos - */ - private void insertGoto(com.fr.third.javassist.bytecode.CodeIterator iterator, int subr, int pos) - throws com.fr.third.javassist.bytecode.BadBytecode - { - iterator.setMark(subr); - // the gap length might be a multiple of 4. - iterator.writeByte(com.fr.third.javassist.bytecode.Opcode.NOP, pos); - boolean wide = subr + 2 - pos > Short.MAX_VALUE; - pos = iterator.insertGapAt(pos, wide ? 4 : 2, false).position; - int offset = iterator.getMark() - pos; - if (wide) { - iterator.writeByte(com.fr.third.javassist.bytecode.Opcode.GOTO_W, pos); - iterator.write32bit(offset, pos + 1); - } - else if (offset <= Short.MAX_VALUE) { - iterator.writeByte(com.fr.third.javassist.bytecode.Opcode.GOTO, pos); - iterator.write16bit(offset, pos + 1); - } - else { - pos = iterator.insertGapAt(pos, 2, false).position; - iterator.writeByte(com.fr.third.javassist.bytecode.Opcode.GOTO_W, pos); - iterator.write32bit(iterator.getMark() - pos, pos + 1); - } - } - - /* insert a finally clause - */ - private int insertAfterHandler(boolean asFinally, com.fr.third.javassist.bytecode.Bytecode b, - CtClass rtype, int returnVarNo, - Javac javac, String src) - throws CompileError - { - if (!asFinally) - return 0; - - int var = b.getMaxLocals(); - b.incMaxLocals(1); - int pc = b.currentPc(); - b.addAstore(var); // store an exception - if (rtype.isPrimitive()) { - char c = ((CtPrimitiveType)rtype).getDescriptor(); - if (c == 'D') { - b.addDconst(0.0); - b.addDstore(returnVarNo); - } - else if (c == 'F') { - b.addFconst(0); - b.addFstore(returnVarNo); - } - else if (c == 'J') { - b.addLconst(0); - b.addLstore(returnVarNo); - } - else if (c == 'V') { - b.addOpcode(com.fr.third.javassist.bytecode.Opcode.ACONST_NULL); - b.addAstore(returnVarNo); - } - else { // int, boolean, char, short, ... - b.addIconst(0); - b.addIstore(returnVarNo); - } - } - else { - b.addOpcode(com.fr.third.javassist.bytecode.Opcode.ACONST_NULL); - b.addAstore(returnVarNo); - } - - javac.compileStmnt(src); - b.addAload(var); - b.addOpcode(com.fr.third.javassist.bytecode.Opcode.ATHROW); - return b.currentPc() - pc; - } - - /* -- OLD version -- - - public void insertAfter(String src) throws CannotCompileException { - declaringClass.checkModify(); - CodeAttribute ca = methodInfo.getCodeAttribute(); - CodeIterator iterator = ca.iterator(); - Bytecode b = new Bytecode(methodInfo.getConstPool(), - ca.getMaxStack(), ca.getMaxLocals()); - b.setStackDepth(ca.getMaxStack()); - Javac jv = new Javac(b, declaringClass); - try { - jv.recordParams(getParameterTypes(), - Modifier.isStatic(getModifiers())); - CtClass rtype = getReturnType0(); - int varNo = jv.recordReturnType(rtype, true); - boolean isVoid = rtype == CtClass.voidType; - if (isVoid) { - b.addOpcode(Opcode.ACONST_NULL); - b.addAstore(varNo); - jv.compileStmnt(src); - } - else { - b.addStore(varNo, rtype); - jv.compileStmnt(src); - b.addLoad(varNo, rtype); - } - - byte[] code = b.get(); - ca.setMaxStack(b.getMaxStack()); - ca.setMaxLocals(b.getMaxLocals()); - while (iterator.hasNext()) { - int pos = iterator.next(); - int c = iterator.byteAt(pos); - if (c == Opcode.ARETURN || c == Opcode.IRETURN - || c == Opcode.FRETURN || c == Opcode.LRETURN - || c == Opcode.DRETURN || c == Opcode.RETURN) - iterator.insert(pos, code); - } - } - catch (NotFoundException e) { - throw new CannotCompileException(e); - } - catch (CompileError e) { - throw new CannotCompileException(e); - } - catch (BadBytecode e) { - throw new CannotCompileException(e); - } - } - */ - - /** - * Adds a catch clause that handles an exception thrown in the - * body. The catch clause must end with a return or throw statement. - * - * @param src the source code representing the catch clause. - * It must be a single statement or block. - * @param exceptionType the type of the exception handled by the - * catch clause. - */ - public void addCatch(String src, CtClass exceptionType) - throws com.fr.third.javassist.CannotCompileException - { - addCatch(src, exceptionType, "$e"); - } - - /** - * Adds a catch clause that handles an exception thrown in the - * body. The catch clause must end with a return or throw statement. - * - * @param src the source code representing the catch clause. - * It must be a single statement or block. - * @param exceptionType the type of the exception handled by the - * catch clause. - * @param exceptionName the name of the variable containing the - * caught exception, for example, - * $e. - */ - public void addCatch(String src, CtClass exceptionType, - String exceptionName) - throws com.fr.third.javassist.CannotCompileException - { - CtClass cc = declaringClass; - cc.checkModify(); - com.fr.third.javassist.bytecode.ConstPool cp = methodInfo.getConstPool(); - com.fr.third.javassist.bytecode.CodeAttribute ca = methodInfo.getCodeAttribute(); - com.fr.third.javassist.bytecode.CodeIterator iterator = ca.iterator(); - com.fr.third.javassist.bytecode.Bytecode b = new com.fr.third.javassist.bytecode.Bytecode(cp, ca.getMaxStack(), ca.getMaxLocals()); - b.setStackDepth(1); - Javac jv = new Javac(b, cc); - try { - jv.recordParams(getParameterTypes(), - Modifier.isStatic(getModifiers())); - int var = jv.recordVariable(exceptionType, exceptionName); - b.addAstore(var); - jv.compileStmnt(src); - - int stack = b.getMaxStack(); - int locals = b.getMaxLocals(); - - if (stack > ca.getMaxStack()) - ca.setMaxStack(stack); - - if (locals > ca.getMaxLocals()) - ca.setMaxLocals(locals); - - int len = iterator.getCodeLength(); - int pos = iterator.append(b.get()); - ca.getExceptionTable().add(getStartPosOfBody(ca), len, len, - cp.addClassInfo(exceptionType)); - iterator.append(b.getExceptionTable(), pos); - methodInfo.rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2()); - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - catch (CompileError e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - /* CtConstructor overrides this method. - */ - int getStartPosOfBody(com.fr.third.javassist.bytecode.CodeAttribute ca) throws com.fr.third.javassist.CannotCompileException { - return 0; - } - - /** - * Inserts bytecode at the specified line in the body. - * It is equivalent to: - * - *
insertAt(lineNum, true, src) - * - *
See this method as well. - * - * @param lineNum the line number. The bytecode is inserted at the - * beginning of the code at the line specified by this - * line number. - * @param src the source code representing the inserted bytecode. - * It must be a single statement or block. - * @return the line number at which the bytecode has been inserted. - * - * @see CtBehavior#insertAt(int,boolean,String) - */ - public int insertAt(int lineNum, String src) - throws com.fr.third.javassist.CannotCompileException - { - return insertAt(lineNum, true, src); - } - - /** - * Inserts bytecode at the specified line in the body. - * - *

If there is not - * a statement at the specified line, the bytecode might be inserted - * at the line including the first statement after that line specified. - * For example, if there is only a closing brace at that line, the - * bytecode would be inserted at another line below. - * To know exactly where the bytecode will be inserted, call with - * modify set to false. - * - * @param lineNum the line number. The bytecode is inserted at the - * beginning of the code at the line specified by this - * line number. - * @param modify if false, this method does not insert the bytecode. - * It instead only returns the line number at which - * the bytecode would be inserted. - * @param src the source code representing the inserted bytecode. - * It must be a single statement or block. - * If modify is false, the value of src can be null. - * @return the line number at which the bytecode has been inserted. - */ - public int insertAt(int lineNum, boolean modify, String src) - throws com.fr.third.javassist.CannotCompileException - { - CodeAttribute ca = methodInfo.getCodeAttribute(); - if (ca == null) - throw new com.fr.third.javassist.CannotCompileException("no method body"); - - com.fr.third.javassist.bytecode.LineNumberAttribute ainfo - = (com.fr.third.javassist.bytecode.LineNumberAttribute)ca.getAttribute(com.fr.third.javassist.bytecode.LineNumberAttribute.tag); - if (ainfo == null) - throw new com.fr.third.javassist.CannotCompileException("no line number info"); - - com.fr.third.javassist.bytecode.LineNumberAttribute.Pc pc = ainfo.toNearPc(lineNum); - lineNum = pc.line; - int index = pc.index; - if (!modify) - return lineNum; - - CtClass cc = declaringClass; - cc.checkModify(); - com.fr.third.javassist.bytecode.CodeIterator iterator = ca.iterator(); - Javac jv = new Javac(cc); - try { - jv.recordLocalVariables(ca, index); - jv.recordParams(getParameterTypes(), - Modifier.isStatic(getModifiers())); - jv.setMaxLocals(ca.getMaxLocals()); - jv.compileStmnt(src); - com.fr.third.javassist.bytecode.Bytecode b = jv.getBytecode(); - int locals = b.getMaxLocals(); - int stack = b.getMaxStack(); - ca.setMaxLocals(locals); - - /* We assume that there is no values in the operand stack - * at the position where the bytecode is inserted. - */ - if (stack > ca.getMaxStack()) - ca.setMaxStack(stack); - - index = iterator.insertAt(index, b.get()); - iterator.insert(b.getExceptionTable(), index); - methodInfo.rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2()); - return lineNum; - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - catch (CompileError e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new CannotCompileException(e); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CtClass.java b/fine-javassist/src/main/java/com/fr/third/javassist/CtClass.java deleted file mode 100644 index d49aed305..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CtClass.java +++ /dev/null @@ -1,1558 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import java.io.BufferedOutputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.net.URL; -import java.security.ProtectionDomain; -import java.util.Collection; - -import com.fr.third.javassist.bytecode.AttributeInfo; -import com.fr.third.javassist.compiler.AccessorMaker; -import com.fr.third.javassist.bytecode.ClassFile; -import com.fr.third.javassist.bytecode.Descriptor; -import com.fr.third.javassist.bytecode.Opcode; -import com.fr.third.javassist.bytecode.SignatureAttribute; -import com.fr.third.javassist.expr.ExprEditor; - -/* Note: - * - * This class is an abstract class and several methods just return null - * or throw an exception. Those methods are overridden in subclasses - * of this class. Read the source code of CtClassType if you are - * interested in the implementation of Javassist. - * - * Subclasses of CtClass are CtClassType, CtPrimitiveType, and CtArray. - */ - -/** - * An instance of CtClass represents a class. - * It is obtained from ClassPool. - * - * @see com.fr.third.javassist.ClassPool#get(String) - */ -public abstract class CtClass { - protected String qualifiedName; - - /** - * If the value of this field is not null, then all class - * files modified by Javassist are saved under the directory - * specified by this variable. For example, if the value is - * "./debug", then all class files are saved - * there. The directory name must not end with a directory - * separator such as /. - * - *

The default value is null. - * - * @see #debugWriteFile(String) - * @since 3.16 - */ - public static String debugDump = null; - - /** - * The version number of this release. - */ - public static final String version = "3.18.2-GA"; - - /** - * Prints the version number and the copyright notice. - * - *

The following command invokes this method: - * - *

    java -jar javassist.jar
- */ - public static void main(String[] args) { - System.out.println("Javassist version " + CtClass.version); - System.out.println("Copyright (C) 1999-2014 Shigeru Chiba." - + " All Rights Reserved."); - } - - static final String javaLangObject = "java.lang.Object"; - - /** - * The CtClass object representing - * the boolean type. - */ - public static CtClass booleanType; - - /** - * The CtClass object representing - * the char type. - */ - public static CtClass charType; - - /** - * The CtClass object representing - * the byte type. - */ - public static CtClass byteType; - - /** - * The CtClass object representing - * the short type. - */ - public static CtClass shortType; - - /** - * The CtClass object representing - * the int type. - */ - public static CtClass intType; - - /** - * The CtClass object representing - * the long type. - */ - public static CtClass longType; - - /** - * The CtClass object representing - * the float type. - */ - public static CtClass floatType; - - /** - * The CtClass object representing - * the double type. - */ - public static CtClass doubleType; - - /** - * The CtClass object representing - * the void type. - */ - public static CtClass voidType; - - static CtClass[] primitiveTypes; - - static { - primitiveTypes = new CtClass[9]; - - booleanType = - new CtPrimitiveType("boolean", 'Z', "java.lang.Boolean", - "booleanValue", "()Z", Opcode.IRETURN, - Opcode.T_BOOLEAN, 1); - primitiveTypes[0] = booleanType; - - charType = new CtPrimitiveType("char", 'C', "java.lang.Character", - "charValue", "()C", Opcode.IRETURN, - Opcode.T_CHAR, 1); - primitiveTypes[1] = charType; - - byteType = new CtPrimitiveType("byte", 'B', "java.lang.Byte", - "byteValue", "()B", Opcode.IRETURN, - Opcode.T_BYTE, 1); - primitiveTypes[2] = byteType; - - shortType = new CtPrimitiveType("short", 'S', "java.lang.Short", - "shortValue", "()S", Opcode.IRETURN, - Opcode.T_SHORT, 1); - primitiveTypes[3] = shortType; - - intType = new CtPrimitiveType("int", 'I', "java.lang.Integer", - "intValue", "()I", Opcode.IRETURN, - Opcode.T_INT, 1); - primitiveTypes[4] = intType; - - longType = new CtPrimitiveType("long", 'J', "java.lang.Long", - "longValue", "()J", Opcode.LRETURN, - Opcode.T_LONG, 2); - primitiveTypes[5] = longType; - - floatType = new CtPrimitiveType("float", 'F', "java.lang.Float", - "floatValue", "()F", Opcode.FRETURN, - Opcode.T_FLOAT, 1); - primitiveTypes[6] = floatType; - - doubleType = new CtPrimitiveType("double", 'D', "java.lang.Double", - "doubleValue", "()D", Opcode.DRETURN, - Opcode.T_DOUBLE, 2); - primitiveTypes[7] = doubleType; - - voidType = new CtPrimitiveType("void", 'V', "java.lang.Void", - null, null, Opcode.RETURN, 0, 0); - primitiveTypes[8] = voidType; - } - - protected CtClass(String name) { - qualifiedName = name; - } - - /** - * Converts the object to a string. - */ - public String toString() { - StringBuffer buf = new StringBuffer(getClass().getName()); - buf.append("@"); - buf.append(Integer.toHexString(hashCode())); - buf.append("["); - extendToString(buf); - buf.append("]"); - return buf.toString(); - } - - /** - * Implemented in subclasses to add to the {@link #toString()} result. - * Subclasses should put a space before each token added to the buffer. - */ - protected void extendToString(StringBuffer buffer) { - buffer.append(getName()); - } - - /** - * Returns a ClassPool for this class. - */ - public com.fr.third.javassist.ClassPool getClassPool() { return null; } - - /** - * Returns a class file for this class. - * - *

This method is not available if isFrozen() - * is true. - */ - public ClassFile getClassFile() { - checkModify(); - return getClassFile2(); - } - - /** - * Returns a class file for this class (read only). - * Normal applications do not need calling this method. Use - * getClassFile(). - * - *

The ClassFile object obtained by this method - * is read only. Changes to this object might not be reflected - * on a class file generated by toBytecode(), - * toClass(), etc. - * - *

This method is available even if isFrozen() - * is true. However, if the class is frozen, it might be also - * pruned. - * - * @see CtClass#getClassFile() - * @see CtClass#isFrozen() - * @see CtClass#prune() - */ - public ClassFile getClassFile2() { return null; } - - /** - * Undocumented method. Do not use; internal-use only. - */ - public AccessorMaker getAccessorMaker() { - return null; - } - - /** - * Returns the uniform resource locator (URL) of the class file. - */ - public URL getURL() throws NotFoundException { - throw new NotFoundException(getName()); - } - - /** - * Returns true if the definition of the class has been modified. - */ - public boolean isModified() { return false; } - - /** - * Returns true if the class has been loaded or written out - * and thus it cannot be modified any more. - * - * @see #defrost() - * @see #detach() - */ - public boolean isFrozen() { return true; } - - /** - * Makes the class frozen. - * - * @see #isFrozen() - * @see #defrost() - * @since 3.6 - */ - public void freeze() {} - - /* Note: this method is overridden by CtClassType - */ - void checkModify() throws RuntimeException { - if (isFrozen()) - throw new RuntimeException(getName() + " class is frozen"); - - // isModified() must return true after this method is invoked. - } - - /** - * Defrosts the class so that the class can be modified again. - * - *

To avoid changes that will be never reflected, - * the class is frozen to be unmodifiable if it is loaded or - * written out. This method should be called only in a case - * that the class will be reloaded or written out later again. - * - *

If defrost() will be called later, pruning - * must be disallowed in advance. - * - * @see #isFrozen() - * @see #stopPruning(boolean) - * @see #detach() - */ - public void defrost() { - throw new RuntimeException("cannot defrost " + getName()); - } - - /** - * Returns true if this object represents a primitive - * Java type: boolean, byte, char, short, int, long, float, double, - * or void. - */ - public boolean isPrimitive() { return false; } - - /** - * Returns true if this object represents an array type. - */ - public boolean isArray() { - return false; - } - - /** - * If this object represents an array, this method returns the component - * type of the array. Otherwise, it returns null. - */ - public CtClass getComponentType() throws NotFoundException { - return null; - } - - /** - * Returns true if this class extends or implements - * clazz. It also returns true if - * this class is the same as clazz. - */ - public boolean subtypeOf(CtClass clazz) throws NotFoundException { - return this == clazz || getName().equals(clazz.getName()); - } - - /** - * Obtains the fully-qualified name of the class. - */ - public String getName() { return qualifiedName; } - - /** - * Obtains the not-qualified class name. - */ - public final String getSimpleName() { - String qname = qualifiedName; - int index = qname.lastIndexOf('.'); - if (index < 0) - return qname; - else - return qname.substring(index + 1); - } - - /** - * Obtains the package name. It may be null. - */ - public final String getPackageName() { - String qname = qualifiedName; - int index = qname.lastIndexOf('.'); - if (index < 0) - return null; - else - return qname.substring(0, index); - } - - /** - * Sets the class name - * - * @param name fully-qualified name - */ - public void setName(String name) { - checkModify(); - if (name != null) - qualifiedName = name; - } - - /** - * Returns the generic signature of the class. - * - *

The generics of Java is implemented by the erasure technique. - * After compilation, all type parameters are dropped off from the - * main part of a class file. However, for reflection, the type - * parameters are encoded into generic signatures and attached - * to a class file. - * - * @return null if the generic signature is not included. - * @see SignatureAttribute#toClassSignature(String) - * @see CtMember#getGenericSignature() - * @since 3.17 - */ - public String getGenericSignature() { return null; } - - /** - * Sets the generic signature of the class. - * - *

The generics of Java is implemented by the erasure technique. - * After compilation, all type parameters are dropped off from the - * main part of a class file. However, for reflection, the type - * parameters must be encoded into generic signatures and attached - * to a class file. - * - *

For example, - * - *

class List {
-     *     T value;
-     *     T get() { return value; }
-     *     void set(T v) { value = v; }
-     * }
-     * 
- * - *

this class is generated by the following code: - * - *

-     * ClassPool pool = ClassPool.getDefault();
-     * CtClass cc = pool.makeClass("List");
-     * CtClass objectClass = pool.get(CtClass.javaLangObject);
-     * ClassSignature cs = new ClassSignature(
-     *                         new TypeParameter[] { new TypeParameter("T") });
-     * cc.setGenericSignature(cs.encode());    // <T:Ljava/lang/Object;>Ljava/lang/Object;
-     *
-     * CtField f = new CtField(objClass, "value", cc);
-     * TypeVariable tvar = new TypeVariable("T");
-     * f.setGenericSignature(tvar.encode());   // TT;
-     * cc.addField(f);
-     *
-     * CtMethod m = CtNewMethod.make("public Object get(){return value;}", cc);
-     * MethodSignature ms = new MethodSignature(null, null, tvar, null);
-     * m.setGenericSignature(ms.encode());     // ()TT;
-     * cc.addMethod(m);
-     *
-     * CtMethod m2 = CtNewMethod.make("public void set(Object v){value = v;}", cc);
-     * MethodSignature ms2 = new MethodSignature(null, new Type[] { tvar },
-     *                                           new BaseType("void"), null);
-     * m2.setGenericSignature(ms2.encode());   // (TT;)V;
-     * cc.addMethod(m2);
-     *
-     * cc.writeFile();
-     * 
- * - *

The generated class file is equivalent to the following: - * - *

class List {
-     *     Object value;
-     *     Object get() { return value; }
-     *     void set(Object v) { value = v; }
-     * }
- * - *

but it includes generic signatures for the class, the field, - * and the methods so that the type variable T can be - * accessible through reflection. - * - * @param sig a generic signature. - * @see SignatureAttribute.ClassSignature#encode() - * @see SignatureAttribute.MethodSignature#encode() - * @see CtMember#setGenericSignature(String) - * @since 3.17 - */ - public void setGenericSignature(String sig) { checkModify(); } - - /** - * Substitutes newName for all occurrences of a class - * name oldName in the class file. - * - * @param oldName replaced class name - * @param newName substituted class name - */ - public void replaceClassName(String oldName, String newName) { - checkModify(); - } - - /** - * Changes class names appearing in the class file according to the - * given map. - * - *

All the class names appearing in the class file are tested - * with map to determine whether each class name is - * replaced or not. Thus this method can be used for collecting - * all the class names in the class file. To do that, first define - * a subclass of ClassMap so that get() - * records all the given parameters. Then, make an instance of - * that subclass as an empty hash-table. Finally, pass that instance - * to this method. After this method finishes, that instance would - * contain all the class names appearing in the class file. - * - * @param map the hashtable associating replaced class names - * with substituted names. - */ - public void replaceClassName(com.fr.third.javassist.ClassMap map) { - checkModify(); - } - - /** - * Returns a collection of the names of all the classes - * referenced in this class. - * That collection includes the name of this class. - * - *

This method may return null. - * - * @return a Collection<String> object. - */ - public synchronized Collection getRefClasses() { - ClassFile cf = getClassFile2(); - if (cf != null) { - com.fr.third.javassist.ClassMap cm = new com.fr.third.javassist.ClassMap() { - public void put(String oldname, String newname) { - put0(oldname, newname); - } - - public Object get(Object jvmClassName) { - String n = toJavaName((String)jvmClassName); - put0(n, n); - return null; - } - - public void fix(String name) {} - }; - cf.getRefClasses(cm); - return cm.values(); - } - else - return null; - } - - /** - * Determines whether this object represents a class or an interface. - * It returns true if this object represents an interface. - */ - public boolean isInterface() { - return false; - } - - /** - * Determines whether this object represents an annotation type. - * It returns true if this object represents an annotation type. - * - * @since 3.2 - */ - public boolean isAnnotation() { - return false; - } - - /** - * Determines whether this object represents an enum. - * It returns true if this object represents an enum. - * - * @since 3.2 - */ - public boolean isEnum() { - return false; - } - - /** - * Returns the modifiers for this class, encoded in an integer. - * For decoding, use javassist.Modifier. - * - *

If the class is a static nested class (a.k.a. static inner class), - * the returned modifiers include Modifier.STATIC. - * - * @see Modifier - */ - public int getModifiers() { - return 0; - } - - /** - * Returns true if the class has the specified annotation class. - * - * @param clz the annotation class. - * @return true if the annotation is found, otherwise false. - * @since 3.11 - */ - public boolean hasAnnotation(Class clz) { - return false; - } - - /** - * Returns the annotation if the class has the specified annotation class. - * For example, if an annotation @Author is associated - * with this class, an Author object is returned. - * The member values can be obtained by calling methods on - * the Author object. - * - * @param clz the annotation class. - * @return the annotation if found, otherwise null. - * @since 3.11 - */ - public Object getAnnotation(Class clz) throws ClassNotFoundException { - return null; - } - - /** - * Returns the annotations associated with this class. - * For example, if an annotation @Author is associated - * with this class, the returned array contains an Author - * object. The member values can be obtained by calling methods on - * the Author object. - * - * @return an array of annotation-type objects. - * @see CtMember#getAnnotations() - * @since 3.1 - */ - public Object[] getAnnotations() throws ClassNotFoundException { - return new Object[0]; - } - - /** - * Returns the annotations associated with this class. - * This method is equivalent to getAnnotations() - * except that, if any annotations are not on the classpath, - * they are not included in the returned array. - * - * @return an array of annotation-type objects. - * @see #getAnnotations() - * @see CtMember#getAvailableAnnotations() - * @since 3.3 - */ - public Object[] getAvailableAnnotations(){ - return new Object[0]; - } - - /** - * Returns an array of nested classes declared in the class. - * Nested classes are inner classes, anonymous classes, local classes, - * and static nested classes. This simply calls getNestedClasses(). - * - * @see #getNestedClasses() - * @since 3.15 - */ - public CtClass[] getDeclaredClasses() throws NotFoundException { - return getNestedClasses(); - } - - /** - * Returns an array of nested classes declared in the class. - * Nested classes are inner classes, anonymous classes, local classes, - * and static nested classes. - * - * @since 3.2 - */ - public CtClass[] getNestedClasses() throws NotFoundException { - return new CtClass[0]; - } - - /** - * Sets the modifiers. - * - *

If the class is a nested class, this method also modifies - * the class declaring that nested class (i.e. the enclosing - * class is modified). - * - * @param mod modifiers encoded by - * javassist.Modifier - * @see Modifier - */ - public void setModifiers(int mod) { - checkModify(); - } - - /** - * Determines whether the class directly or indirectly extends - * the given class. If this class extends a class A and - * the class A extends a class B, then subclassof(B) returns true. - * - *

This method returns true if the given class is identical to - * the class represented by this object. - */ - public boolean subclassOf(CtClass superclass) { - return false; - } - - /** - * Obtains the class object representing the superclass of the - * class. - * It returns null if this object represents the - * java.lang.Object class and thus it does not have - * the super class. - * - *

If this object represents an interface, this method - * always returns the java.lang.Object class. - * To obtain the super interfaces - * extended by that interface, call getInterfaces(). - */ - public CtClass getSuperclass() throws NotFoundException { - return null; - } - - /** - * Changes a super class unless this object represents an interface. - * The new super class must be compatible with the old one; for example, - * it should inherit from the old super class. - * - *

If this object represents an interface, this method is equivalent - * to addInterface(); it appends clazz to - * the list of the super interfaces extended by that interface. - * Note that an interface can extend multiple super interfaces. - * - * @see #replaceClassName(String, String) - * @see #replaceClassName(ClassMap) - */ - public void setSuperclass(CtClass clazz) throws com.fr.third.javassist.CannotCompileException { - checkModify(); - } - - /** - * Obtains the class objects representing the interfaces implemented - * by the class or, if this object represents an interface, the interfaces - * extended by that interface. - */ - public CtClass[] getInterfaces() throws NotFoundException { - return new CtClass[0]; - } - - /** - * Sets implemented interfaces. If this object represents an interface, - * this method sets the interfaces extended by that interface. - * - * @param list a list of the CtClass objects - * representing interfaces, or - * null if the class implements - * no interfaces. - */ - public void setInterfaces(CtClass[] list) { - checkModify(); - } - - /** - * Adds an interface. - * - * @param anInterface the added interface. - */ - public void addInterface(CtClass anInterface) { - checkModify(); - } - - /** - * If this class is a member class or interface of another class, - * then the class enclosing this class is returned. - * - * @return null if this class is a top-level class or an anonymous class. - */ - public CtClass getDeclaringClass() throws NotFoundException { - return null; - } - - /** - * Returns the immediately enclosing method of this class. - * This method works only with JDK 1.5 or later. - * - * @return null if this class is not a local class or an anonymous - * class. - */ - public CtMethod getEnclosingMethod() throws NotFoundException { - return null; - } - - /** - * Makes a new public nested class. If this method is called, - * the CtClass, which encloses the nested class, is modified - * since a class file includes a list of nested classes. - * - *

The current implementation only supports a static nested class. - * isStatic must be true. - * - * @param name the simple name of the nested class. - * @param isStatic true if the nested class is static. - */ - public CtClass makeNestedClass(String name, boolean isStatic) { - throw new RuntimeException(getName() + " is not a class"); - } - - /** - * Returns an array containing CtField objects - * representing all the non-private fields of the class. - * That array includes non-private fields inherited from the - * superclasses. - */ - public CtField[] getFields() { return new CtField[0]; } - - /** - * Returns the field with the specified name. The returned field - * may be a private field declared in a super class or interface. - */ - public CtField getField(String name) throws NotFoundException { - return getField(name, null); - } - - /** - * Returns the field with the specified name and type. The returned field - * may be a private field declared in a super class or interface. - * Unlike Java, the JVM allows a class to have - * multiple fields with the same name but different types. - * - * @param name the field name. - * @param desc the type descriptor of the field. It is available by - * {@link CtField#getSignature()}. - * @see CtField#getSignature() - */ - public CtField getField(String name, String desc) throws NotFoundException { - throw new NotFoundException(name); - } - - /** - * @return null if the specified field is not found. - */ - CtField getField2(String name, String desc) { return null; } - - /** - * Gets all the fields declared in the class. The inherited fields - * are not included. - * - *

Note: the result does not include inherited fields. - */ - public CtField[] getDeclaredFields() { return new CtField[0]; } - - /** - * Retrieves the field with the specified name among the fields - * declared in the class. - * - *

Note: this method does not search the super classes. - */ - public CtField getDeclaredField(String name) throws NotFoundException { - throw new NotFoundException(name); - } - - /** - * Retrieves the field with the specified name and type among the fields - * declared in the class. Unlike Java, the JVM allows a class to have - * multiple fields with the same name but different types. - * - *

Note: this method does not search the super classes. - * - * @param name the field name. - * @param desc the type descriptor of the field. It is available by - * {@link CtField#getSignature()}. - * @see CtField#getSignature() - */ - public CtField getDeclaredField(String name, String desc) throws NotFoundException { - throw new NotFoundException(name); - } - - /** - * Gets all the constructors and methods declared in the class. - */ - public com.fr.third.javassist.CtBehavior[] getDeclaredBehaviors() { - return new com.fr.third.javassist.CtBehavior[0]; - } - - /** - * Returns an array containing CtConstructor objects - * representing all the non-private constructors of the class. - */ - public CtConstructor[] getConstructors() { - return new CtConstructor[0]; - } - - /** - * Returns the constructor with the given signature, - * which is represented by a character string - * called method descriptor. - * For details of the method descriptor, see the JVM specification - * or javassist.bytecode.Descriptor. - * - * @param desc method descriptor - * @see Descriptor - */ - public CtConstructor getConstructor(String desc) - throws NotFoundException - { - throw new NotFoundException("no such constructor"); - } - - /** - * Gets all the constructors declared in the class. - * - * @see CtConstructor - */ - public CtConstructor[] getDeclaredConstructors() { - return new CtConstructor[0]; - } - - /** - * Returns a constructor receiving the specified parameters. - * - * @param params parameter types. - */ - public CtConstructor getDeclaredConstructor(CtClass[] params) - throws NotFoundException - { - String desc = Descriptor.ofConstructor(params); - return getConstructor(desc); - } - - /** - * Gets the class initializer (static constructor) - * declared in the class. - * This method returns null if - * no class initializer is not declared. - * - * @see #makeClassInitializer() - * @see CtConstructor - */ - public CtConstructor getClassInitializer() { - return null; - } - - /** - * Returns an array containing CtMethod objects - * representing all the non-private methods of the class. - * That array includes non-private methods inherited from the - * superclasses. - */ - public CtMethod[] getMethods() { - return new CtMethod[0]; - } - - /** - * Returns the method with the given name and signature. - * The returned method may be declared in a super class. - * The method signature is represented by a character string - * called method descriptor, - * which is defined in the JVM specification. - * - * @param name method name - * @param desc method descriptor - * @see CtBehavior#getSignature() - * @see Descriptor - */ - public CtMethod getMethod(String name, String desc) - throws NotFoundException - { - throw new NotFoundException(name); - } - - /** - * Gets all methods declared in the class. The inherited methods - * are not included. - * - * @see CtMethod - */ - public CtMethod[] getDeclaredMethods() { - return new CtMethod[0]; - } - - /** - * Retrieves the method with the specified name and parameter types - * among the methods declared in the class. - * - *

Note: this method does not search the superclasses. - * - * @param name method name - * @param params parameter types - * @see CtMethod - */ - public CtMethod getDeclaredMethod(String name, CtClass[] params) - throws NotFoundException - { - throw new NotFoundException(name); - } - - /** - * Retrieves the method with the specified name among the methods - * declared in the class. If there are multiple methods with - * the specified name, then this method returns one of them. - * - *

Note: this method does not search the superclasses. - * - * @see CtMethod - */ - public CtMethod getDeclaredMethod(String name) throws NotFoundException { - throw new NotFoundException(name); - } - - /** - * Makes an empty class initializer (static constructor). - * If the class already includes a class initializer, - * this method returns it. - * - * @see #getClassInitializer() - */ - public CtConstructor makeClassInitializer() - throws com.fr.third.javassist.CannotCompileException - { - throw new com.fr.third.javassist.CannotCompileException("not a class"); - } - - /** - * Adds a constructor. To add a class initializer (static constructor), - * call makeClassInitializer(). - * - * @see #makeClassInitializer() - */ - public void addConstructor(CtConstructor c) - throws com.fr.third.javassist.CannotCompileException - { - checkModify(); - } - - /** - * Removes a constructor declared in this class. - * - * @param c removed constructor. - * @throws NotFoundException if the constructor is not found. - */ - public void removeConstructor(CtConstructor c) throws NotFoundException { - checkModify(); - } - - /** - * Adds a method. - */ - public void addMethod(CtMethod m) throws com.fr.third.javassist.CannotCompileException { - checkModify(); - } - - /** - * Removes a method declared in this class. - * - * @param m removed method. - * @throws NotFoundException if the method is not found. - */ - public void removeMethod(CtMethod m) throws NotFoundException { - checkModify(); - } - - /** - * Adds a field. - * - *

The CtField belonging to another - * CtClass cannot be directly added to this class. - * Only a field created for this class can be added. - * - * @see CtField#CtField(CtField,CtClass) - */ - public void addField(CtField f) throws com.fr.third.javassist.CannotCompileException { - addField(f, (CtField.Initializer)null); - } - - /** - * Adds a field with an initial value. - * - *

The CtField belonging to another - * CtClass cannot be directly added to this class. - * Only a field created for this class can be added. - * - *

The initial value is given as an expression written in Java. - * Any regular Java expression can be used for specifying the initial - * value. The followings are examples. - * - *

    -     * cc.addField(f, "0")               // the initial value is 0.
    -     * cc.addField(f, "i + 1")           // i + 1.
    -     * cc.addField(f, "new Point()");    // a Point object.
    -     * 
- * - *

Here, the type of variable cc is CtClass. - * The type of f is CtField. - * - *

Note: do not change the modifier of the field - * (in particular, do not add or remove static - * to/from the modifier) - * after it is added to the class by addField(). - * - * @param init an expression for the initial value. - * - * @see CtField.Initializer#byExpr(String) - * @see CtField#CtField(CtField,CtClass) - */ - public void addField(CtField f, String init) - throws com.fr.third.javassist.CannotCompileException - { - checkModify(); - } - - /** - * Adds a field with an initial value. - * - *

The CtField belonging to another - * CtClass cannot be directly added to this class. - * Only a field created for this class can be added. - * - *

For example, - * - *

    -     * CtClass cc = ...;
    -     * addField(new CtField(CtClass.intType, "i", cc),
    -     *          CtField.Initializer.constant(1));
    -     * 
- * - *

This code adds an int field named "i". The - * initial value of this field is 1. - * - * @param init specifies the initial value of the field. - * - * @see CtField#CtField(CtField,CtClass) - */ - public void addField(CtField f, CtField.Initializer init) - throws com.fr.third.javassist.CannotCompileException - { - checkModify(); - } - - /** - * Removes a field declared in this class. - * - * @param f removed field. - * @throws NotFoundException if the field is not found. - */ - public void removeField(CtField f) throws NotFoundException { - checkModify(); - } - - /** - * Obtains an attribute with the given name. - * If that attribute is not found in the class file, this - * method returns null. - * - *

This is a convenient method mainly for obtaining - * a user-defined attribute. For dealing with attributes, see the - * javassist.bytecode package. For example, the following - * expression returns all the attributes of a class file. - * - *

    -     * getClassFile().getAttributes()
    -     * 
- * - * @param name attribute name - * @see AttributeInfo - */ - public byte[] getAttribute(String name) { - return null; - } - - /** - * Adds a named attribute. - * An arbitrary data (smaller than 64Kb) can be saved in the class - * file. Some attribute name are reserved by the JVM. - * The attributes with the non-reserved names are ignored when a - * class file is loaded into the JVM. - * If there is already an attribute with - * the same name, this method substitutes the new one for it. - * - *

This is a convenient method mainly for adding - * a user-defined attribute. For dealing with attributes, see the - * javassist.bytecode package. For example, the following - * expression adds an attribute info to a class file. - * - *

    -     * getClassFile().addAttribute(info)
    -     * 
- * - * @param name attribute name - * @param data attribute value - * @see AttributeInfo - */ - public void setAttribute(String name, byte[] data) { - checkModify(); - } - - /** - * Applies the given converter to all methods and constructors - * declared in the class. This method calls instrument() - * on every CtMethod and CtConstructor object - * in the class. - * - * @param converter specifies how to modify. - */ - public void instrument(com.fr.third.javassist.CodeConverter converter) - throws com.fr.third.javassist.CannotCompileException - { - checkModify(); - } - - /** - * Modifies the bodies of all methods and constructors - * declared in the class. This method calls instrument() - * on every CtMethod and CtConstructor object - * in the class. - * - * @param editor specifies how to modify. - */ - public void instrument(ExprEditor editor) - throws com.fr.third.javassist.CannotCompileException - { - checkModify(); - } - - /** - * Converts this class to a java.lang.Class object. - * Once this method is called, further modifications are not - * allowed any more. - * To load the class, this method uses the context class loader - * of the current thread. If the program is running on some application - * server, the context class loader might be inappropriate to load the - * class. - * - *

This method is provided for convenience. If you need more - * complex functionality, you should write your own class loader. - * - *

Note: this method calls toClass() - * in ClassPool. - * - *

Warining: A Class object returned by this method may not - * work with a security manager or a signed jar file because a - * protection domain is not specified. - * - * @see #toClass(java.lang.ClassLoader,ProtectionDomain) - * @see com.fr.third.javassist.ClassPool#toClass(CtClass) - */ - public Class toClass() throws com.fr.third.javassist.CannotCompileException { - return getClassPool().toClass(this); - } - - /** - * Converts this class to a java.lang.Class object. - * Once this method is called, further modifications are not allowed - * any more. - * - *

The class file represented by this CtClass is - * loaded by the given class loader to construct a - * java.lang.Class object. Since a private method - * on the class loader is invoked through the reflection API, - * the caller must have permissions to do that. - * - *

An easy way to obtain ProtectionDomain object is - * to call getProtectionDomain() - * in java.lang.Class. It returns the domain that - * the class belongs to. - * - *

This method is provided for convenience. If you need more - * complex functionality, you should write your own class loader. - * - *

Note: this method calls toClass() - * in ClassPool. - * - * @param loader the class loader used to load this class. - * If it is null, the class loader returned by - * {@link com.fr.third.javassist.ClassPool#getClassLoader()} is used. - * @param domain the protection domain that the class belongs to. - * If it is null, the default domain created - * by java.lang.ClassLoader is used. - * @see com.fr.third.javassist.ClassPool#toClass(CtClass,java.lang.ClassLoader) - * @since 3.3 - */ - public Class toClass(ClassLoader loader, ProtectionDomain domain) - throws com.fr.third.javassist.CannotCompileException - { - com.fr.third.javassist.ClassPool cp = getClassPool(); - if (loader == null) - loader = cp.getClassLoader(); - - return cp.toClass(this, loader, domain); - } - - /** - * Converts this class to a java.lang.Class object. - * - *

Warining: A Class object returned by this method may not - * work with a security manager or a signed jar file because a - * protection domain is not specified. - * - * @deprecated Replaced by {@link #toClass(ClassLoader,ProtectionDomain)} - */ - public final Class toClass(ClassLoader loader) - throws com.fr.third.javassist.CannotCompileException - { - return getClassPool().toClass(this, loader); - } - - /** - * Removes this CtClass object from the - * ClassPool. - * After this method is called, any method cannot be called on the - * removed CtClass object. - * - *

If get() in ClassPool is called - * with the name of the removed method, - * the ClassPool will read the class file again - * and constructs another CtClass object representing - * the same class. - */ - public void detach() { - com.fr.third.javassist.ClassPool cp = getClassPool(); - CtClass obj = cp.removeCached(getName()); - if (obj != this) - cp.cacheCtClass(getName(), obj, false); - } - - /** - * Disallows (or allows) automatically pruning this CtClass - * object. - * - *

- * Javassist can automatically prune a CtClass object - * when toBytecode() (or toClass(), - * writeFile()) is called. - * Since a ClassPool holds all instances of CtClass - * even after toBytecode() (or toClass(), - * writeFile()) is called, pruning may significantly - * save memory consumption. - * - *

If ClassPool.doPruning is true, the automatic pruning - * is on by default. Otherwise, it is off. The default value of - * ClassPool.doPruning is false. - * - * @param stop disallow pruning if true. Otherwise, allow. - * @return the previous status of pruning. true if pruning is already stopped. - * - * @see #detach() - * @see #prune() - * @see com.fr.third.javassist.ClassPool#doPruning - */ - public boolean stopPruning(boolean stop) { return true; } - - /** - * Discards unnecessary attributes, in particular, - * CodeAttributes (method bodies) of the class, - * to minimize the memory footprint. - * After calling this method, the class is read only. - * It cannot be modified any more. - * Furthermore, toBytecode(), - * writeFile(), toClass(), - * or instrument() cannot be called. - * However, the method names and signatures in the class etc. - * are still accessible. - * - *

toBytecode(), writeFile(), and - * toClass() internally call this method if - * automatic pruning is on. - * - *

According to some experiments, pruning does not really reduce - * memory consumption. Only about 20%. Since pruning takes time, - * it might not pay off. So the automatic pruning is off by default. - * - * @see #stopPruning(boolean) - * @see #detach() - * @see ClassPool#doPruning - * - * @see #toBytecode() - * @see #toClass() - * @see #writeFile() - * @see #instrument(CodeConverter) - * @see #instrument(ExprEditor) - */ - public void prune() {} - - /* Called by get() in ClassPool. - * CtClassType overrides this method. - */ - void incGetCounter() {} - - /** - * If this method is called, the class file will be - * rebuilt when it is finally generated by - * toBytecode() and writeFile(). - * For a performance reason, the symbol table of the - * class file may contain unused entries, for example, - * after a method or a filed is deleted. - * This method - * removes those unused entries. This removal will - * minimize the size of the class file. - * - * @since 3.8.1 - */ - public void rebuildClassFile() {} - - /** - * Converts this class to a class file. - * Once this method is called, further modifications are not - * possible any more. - * - * @return the contents of the class file. - */ - public byte[] toBytecode() throws IOException, com.fr.third.javassist.CannotCompileException { - ByteArrayOutputStream barray = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(barray); - try { - toBytecode(out); - } - finally { - out.close(); - } - - return barray.toByteArray(); - } - - /** - * Writes a class file represented by this CtClass - * object in the current directory. - * Once this method is called, further modifications are not - * possible any more. - * - * @see #debugWriteFile() - */ - public void writeFile() - throws NotFoundException, IOException, com.fr.third.javassist.CannotCompileException - { - writeFile("."); - } - - /** - * Writes a class file represented by this CtClass - * object on a local disk. - * Once this method is called, further modifications are not - * possible any more. - * - * @param directoryName it must end without a directory separator. - * @see #debugWriteFile(String) - */ - public void writeFile(String directoryName) - throws com.fr.third.javassist.CannotCompileException, IOException - { - DataOutputStream out = makeFileOutput(directoryName); - try { - toBytecode(out); - } - finally { - out.close(); - } - } - - protected DataOutputStream makeFileOutput(String directoryName) { - String classname = getName(); - String filename = directoryName + File.separatorChar - + classname.replace('.', File.separatorChar) + ".class"; - int pos = filename.lastIndexOf(File.separatorChar); - if (pos > 0) { - String dir = filename.substring(0, pos); - if (!dir.equals(".")) - new File(dir).mkdirs(); - } - - return new DataOutputStream(new BufferedOutputStream( - new DelayedFileOutputStream(filename))); - } - - /** - * Writes a class file as writeFile() does although this - * method does not prune or freeze the class after writing the class - * file. Note that, once writeFile() or toBytecode() - * is called, it cannot be called again since the class is pruned and frozen. - * This method would be useful for debugging. - */ - public void debugWriteFile() { - debugWriteFile("."); - } - - /** - * Writes a class file as writeFile() does although this - * method does not prune or freeze the class after writing the class - * file. Note that, once writeFile() or toBytecode() - * is called, it cannot be called again since the class is pruned and frozen. - * This method would be useful for debugging. - * - * @param directoryName it must end without a directory separator. - */ - public void debugWriteFile(String directoryName) { - try { - boolean p = stopPruning(true); - writeFile(directoryName); - defrost(); - stopPruning(p); - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - - static class DelayedFileOutputStream extends OutputStream { - private FileOutputStream file; - private String filename; - - DelayedFileOutputStream(String name) { - file = null; - filename = name; - } - - private void init() throws IOException { - if (file == null) - file = new FileOutputStream(filename); - } - - public void write(int b) throws IOException { - init(); - file.write(b); - } - - public void write(byte[] b) throws IOException { - init(); - file.write(b); - } - - public void write(byte[] b, int off, int len) throws IOException { - init(); - file.write(b, off, len); - - } - - public void flush() throws IOException { - init(); - file.flush(); - } - - public void close() throws IOException { - init(); - file.close(); - } - } - - /** - * Converts this class to a class file. - * Once this method is called, further modifications are not - * possible any more. - * - *

This method dose not close the output stream in the end. - * - * @param out the output stream that a class file is written to. - */ - public void toBytecode(DataOutputStream out) - throws com.fr.third.javassist.CannotCompileException, IOException - { - throw new CannotCompileException("not a class"); - } - - /** - * Makes a unique member name. This method guarantees that - * the returned name is not used as a prefix of any methods - * or fields visible in this class. - * If the returned name is XYZ, then any method or field names - * in this class do not start with XYZ. - * - * @param prefix the prefix of the member name. - */ - public String makeUniqueName(String prefix) { - throw new RuntimeException("not available in " + getName()); - } - - /* Invoked from ClassPool#compress(). - * This method is overridden by CtClassType. - */ - void compress() {} -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CtClassType.java b/fine-javassist/src/main/java/com/fr/third/javassist/CtClassType.java deleted file mode 100644 index cac3ce2bb..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CtClassType.java +++ /dev/null @@ -1,1722 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import java.lang.ref.WeakReference; -import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.List; -import java.util.Set; - -import com.fr.third.javassist.bytecode.AccessFlag; -import com.fr.third.javassist.bytecode.AttributeInfo; -import com.fr.third.javassist.bytecode.AnnotationsAttribute; -import com.fr.third.javassist.bytecode.BadBytecode; -import com.fr.third.javassist.bytecode.Bytecode; -import com.fr.third.javassist.bytecode.ClassFile; -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.bytecode.ConstantAttribute; -import com.fr.third.javassist.bytecode.CodeIterator; -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.bytecode.Descriptor; -import com.fr.third.javassist.bytecode.EnclosingMethodAttribute; -import com.fr.third.javassist.bytecode.FieldInfo; -import com.fr.third.javassist.bytecode.InnerClassesAttribute; -import com.fr.third.javassist.bytecode.MethodInfo; -import com.fr.third.javassist.bytecode.ParameterAnnotationsAttribute; -import com.fr.third.javassist.bytecode.SignatureAttribute; -import com.fr.third.javassist.bytecode.annotation.Annotation; -import com.fr.third.javassist.compiler.AccessorMaker; -import com.fr.third.javassist.compiler.CompileError; -import com.fr.third.javassist.compiler.Javac; -import com.fr.third.javassist.expr.ExprEditor; - -/** - * Class types. - */ -class CtClassType extends com.fr.third.javassist.CtClass { - com.fr.third.javassist.ClassPool classPool; - boolean wasChanged; - private boolean wasFrozen; - boolean wasPruned; - boolean gcConstPool; // if true, the constant pool entries will be garbage collected. - ClassFile classfile; - byte[] rawClassfile; // backup storage - - private WeakReference memberCache; - private AccessorMaker accessors; - - private FieldInitLink fieldInitializers; - private Hashtable hiddenMethods; // must be synchronous - private int uniqueNumberSeed; - - private boolean doPruning = com.fr.third.javassist.ClassPool.doPruning; - private int getCount; - private static final int GET_THRESHOLD = 2; // see compress() - - CtClassType(String name, com.fr.third.javassist.ClassPool cp) { - super(name); - classPool = cp; - wasChanged = wasFrozen = wasPruned = gcConstPool = false; - classfile = null; - rawClassfile = null; - memberCache = null; - accessors = null; - fieldInitializers = null; - hiddenMethods = null; - uniqueNumberSeed = 0; - getCount = 0; - } - - CtClassType(InputStream ins, com.fr.third.javassist.ClassPool cp) throws IOException { - this((String)null, cp); - classfile = new ClassFile(new DataInputStream(ins)); - qualifiedName = classfile.getName(); - } - - protected void extendToString(StringBuffer buffer) { - if (wasChanged) - buffer.append("changed "); - - if (wasFrozen) - buffer.append("frozen "); - - if (wasPruned) - buffer.append("pruned "); - - buffer.append(Modifier.toString(getModifiers())); - buffer.append(" class "); - buffer.append(getName()); - - try { - com.fr.third.javassist.CtClass ext = getSuperclass(); - if (ext != null) { - String name = ext.getName(); - if (!name.equals("java.lang.Object")) - buffer.append(" extends " + ext.getName()); - } - } - catch (NotFoundException e) { - buffer.append(" extends ??"); - } - - try { - com.fr.third.javassist.CtClass[] intf = getInterfaces(); - if (intf.length > 0) - buffer.append(" implements "); - - for (int i = 0; i < intf.length; ++i) { - buffer.append(intf[i].getName()); - buffer.append(", "); - } - } - catch (NotFoundException e) { - buffer.append(" extends ??"); - } - - CtMember.Cache memCache = getMembers(); - exToString(buffer, " fields=", - memCache.fieldHead(), memCache.lastField()); - exToString(buffer, " constructors=", - memCache.consHead(), memCache.lastCons()); - exToString(buffer, " methods=", - memCache.methodHead(), memCache.lastMethod()); - } - - private void exToString(StringBuffer buffer, String msg, - CtMember head, CtMember tail) { - buffer.append(msg); - while (head != tail) { - head = head.next(); - buffer.append(head); - buffer.append(", "); - } - } - - public AccessorMaker getAccessorMaker() { - if (accessors == null) - accessors = new AccessorMaker(this); - - return accessors; - } - - public ClassFile getClassFile2() { - ClassFile cfile = classfile; - if (cfile != null) - return cfile; - - classPool.compress(); - if (rawClassfile != null) { - try { - classfile = new ClassFile(new DataInputStream( - new ByteArrayInputStream(rawClassfile))); - rawClassfile = null; - getCount = GET_THRESHOLD; - return classfile; - } - catch (IOException e) { - throw new RuntimeException(e.toString(), e); - } - } - - InputStream fin = null; - try { - fin = classPool.openClassfile(getName()); - if (fin == null) - throw new NotFoundException(getName()); - - fin = new BufferedInputStream(fin); - ClassFile cf = new ClassFile(new DataInputStream(fin)); - if (!cf.getName().equals(qualifiedName)) - throw new RuntimeException("cannot find " + qualifiedName + ": " - + cf.getName() + " found in " - + qualifiedName.replace('.', '/') + ".class"); - - classfile = cf; - return cf; - } - catch (NotFoundException e) { - throw new RuntimeException(e.toString(), e); - } - catch (IOException e) { - throw new RuntimeException(e.toString(), e); - } - finally { - if (fin != null) - try { - fin.close(); - } - catch (IOException e) {} - } - } - - /* Inherited from CtClass. Called by get() in ClassPool. - * - * @see javassist.CtClass#incGetCounter() - * @see #toBytecode(DataOutputStream) - */ - final void incGetCounter() { ++getCount; } - - /** - * Invoked from ClassPool#compress(). - * It releases the class files that have not been recently used - * if they are unmodified. - */ - void compress() { - if (getCount < GET_THRESHOLD) - if (!isModified() && com.fr.third.javassist.ClassPool.releaseUnmodifiedClassFile) - removeClassFile(); - else if (isFrozen() && !wasPruned) - saveClassFile(); - - getCount = 0; - } - - /** - * Converts a ClassFile object into a byte array - * for saving memory space. - */ - private synchronized void saveClassFile() { - /* getMembers() and releaseClassFile() are also synchronized. - */ - if (classfile == null || hasMemberCache() != null) - return; - - ByteArrayOutputStream barray = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(barray); - try { - classfile.write(out); - barray.close(); - rawClassfile = barray.toByteArray(); - classfile = null; - } - catch (IOException e) {} - } - - private synchronized void removeClassFile() { - if (classfile != null && !isModified() && hasMemberCache() == null) - classfile = null; - } - - public com.fr.third.javassist.ClassPool getClassPool() { return classPool; } - - void setClassPool(com.fr.third.javassist.ClassPool cp) { classPool = cp; } - - public URL getURL() throws NotFoundException { - URL url = classPool.find(getName()); - if (url == null) - throw new NotFoundException(getName()); - else - return url; - } - - public boolean isModified() { return wasChanged; } - - public boolean isFrozen() { return wasFrozen; } - - public void freeze() { wasFrozen = true; } - - void checkModify() throws RuntimeException { - if (isFrozen()) { - String msg = getName() + " class is frozen"; - if (wasPruned) - msg += " and pruned"; - - throw new RuntimeException(msg); - } - - wasChanged = true; - } - - public void defrost() { - checkPruned("defrost"); - wasFrozen = false; - } - - public boolean subtypeOf(com.fr.third.javassist.CtClass clazz) throws NotFoundException { - int i; - String cname = clazz.getName(); - if (this == clazz || getName().equals(cname)) - return true; - - ClassFile file = getClassFile2(); - String supername = file.getSuperclass(); - if (supername != null && supername.equals(cname)) - return true; - - String[] ifs = file.getInterfaces(); - int num = ifs.length; - for (i = 0; i < num; ++i) - if (ifs[i].equals(cname)) - return true; - - if (supername != null && classPool.get(supername).subtypeOf(clazz)) - return true; - - for (i = 0; i < num; ++i) - if (classPool.get(ifs[i]).subtypeOf(clazz)) - return true; - - return false; - } - - public void setName(String name) throws RuntimeException { - String oldname = getName(); - if (name.equals(oldname)) - return; - - // check this in advance although classNameChanged() below does. - classPool.checkNotFrozen(name); - ClassFile cf = getClassFile2(); - super.setName(name); - cf.setName(name); - nameReplaced(); - classPool.classNameChanged(oldname, this); - } - - public String getGenericSignature() { - SignatureAttribute sa - = (SignatureAttribute)getClassFile2().getAttribute(SignatureAttribute.tag); - return sa == null ? null : sa.getSignature(); - } - - public void setGenericSignature(String sig) { - ClassFile cf = getClassFile(); - SignatureAttribute sa = new SignatureAttribute(cf.getConstPool(), sig); - cf.addAttribute(sa); - } - - public void replaceClassName(ClassMap classnames) - throws RuntimeException - { - String oldClassName = getName(); - String newClassName - = (String)classnames.get(Descriptor.toJvmName(oldClassName)); - if (newClassName != null) { - newClassName = Descriptor.toJavaName(newClassName); - // check this in advance although classNameChanged() below does. - classPool.checkNotFrozen(newClassName); - } - - super.replaceClassName(classnames); - ClassFile cf = getClassFile2(); - cf.renameClass(classnames); - nameReplaced(); - - if (newClassName != null) { - super.setName(newClassName); - classPool.classNameChanged(oldClassName, this); - } - } - - public void replaceClassName(String oldname, String newname) - throws RuntimeException - { - String thisname = getName(); - if (thisname.equals(oldname)) - setName(newname); - else { - super.replaceClassName(oldname, newname); - getClassFile2().renameClass(oldname, newname); - nameReplaced(); - } - } - - public boolean isInterface() { - return Modifier.isInterface(getModifiers()); - } - - public boolean isAnnotation() { - return Modifier.isAnnotation(getModifiers()); - } - - public boolean isEnum() { - return Modifier.isEnum(getModifiers()); - } - - public int getModifiers() { - ClassFile cf = getClassFile2(); - int acc = cf.getAccessFlags(); - acc = AccessFlag.clear(acc, AccessFlag.SUPER); - int inner = cf.getInnerAccessFlags(); - if (inner != -1 && (inner & AccessFlag.STATIC) != 0) - acc |= AccessFlag.STATIC; - - return AccessFlag.toModifier(acc); - } - - public com.fr.third.javassist.CtClass[] getNestedClasses() throws NotFoundException { - ClassFile cf = getClassFile2(); - InnerClassesAttribute ica - = (InnerClassesAttribute)cf.getAttribute(InnerClassesAttribute.tag); - if (ica == null) - return new com.fr.third.javassist.CtClass[0]; - - String thisName = cf.getName() + "$"; - int n = ica.tableLength(); - ArrayList list = new ArrayList(n); - for (int i = 0; i < n; i++) { - String name = ica.innerClass(i); - if (name != null) - if (name.startsWith(thisName)) { - // if it is an immediate nested class - if (name.lastIndexOf('$') < thisName.length()) - list.add(classPool.get(name)); - } - } - - return (com.fr.third.javassist.CtClass[])list.toArray(new com.fr.third.javassist.CtClass[list.size()]); - } - - public void setModifiers(int mod) { - ClassFile cf = getClassFile2(); - if (Modifier.isStatic(mod)) { - int flags = cf.getInnerAccessFlags(); - if (flags != -1 && (flags & AccessFlag.STATIC) != 0) - mod = mod & ~Modifier.STATIC; - else - throw new RuntimeException("cannot change " + getName() + " into a static class"); - } - - checkModify(); - cf.setAccessFlags(AccessFlag.of(mod)); - } - - public boolean hasAnnotation(Class clz) { - ClassFile cf = getClassFile2(); - AnnotationsAttribute ainfo = (AnnotationsAttribute) - cf.getAttribute(AnnotationsAttribute.invisibleTag); - AnnotationsAttribute ainfo2 = (AnnotationsAttribute) - cf.getAttribute(AnnotationsAttribute.visibleTag); - return hasAnnotationType(clz, getClassPool(), ainfo, ainfo2); - } - - static boolean hasAnnotationType(Class clz, com.fr.third.javassist.ClassPool cp, - AnnotationsAttribute a1, AnnotationsAttribute a2) - { - Annotation[] anno1, anno2; - - if (a1 == null) - anno1 = null; - else - anno1 = a1.getAnnotations(); - - if (a2 == null) - anno2 = null; - else - anno2 = a2.getAnnotations(); - - String typeName = clz.getName(); - if (anno1 != null) - for (int i = 0; i < anno1.length; i++) - if (anno1[i].getTypeName().equals(typeName)) - return true; - - if (anno2 != null) - for (int i = 0; i < anno2.length; i++) - if (anno2[i].getTypeName().equals(typeName)) - return true; - - return false; - } - - public Object getAnnotation(Class clz) throws ClassNotFoundException { - ClassFile cf = getClassFile2(); - AnnotationsAttribute ainfo = (AnnotationsAttribute) - cf.getAttribute(AnnotationsAttribute.invisibleTag); - AnnotationsAttribute ainfo2 = (AnnotationsAttribute) - cf.getAttribute(AnnotationsAttribute.visibleTag); - return getAnnotationType(clz, getClassPool(), ainfo, ainfo2); - } - - static Object getAnnotationType(Class clz, com.fr.third.javassist.ClassPool cp, - AnnotationsAttribute a1, AnnotationsAttribute a2) - throws ClassNotFoundException - { - Annotation[] anno1, anno2; - - if (a1 == null) - anno1 = null; - else - anno1 = a1.getAnnotations(); - - if (a2 == null) - anno2 = null; - else - anno2 = a2.getAnnotations(); - - String typeName = clz.getName(); - if (anno1 != null) - for (int i = 0; i < anno1.length; i++) - if (anno1[i].getTypeName().equals(typeName)) - return toAnnoType(anno1[i], cp); - - if (anno2 != null) - for (int i = 0; i < anno2.length; i++) - if (anno2[i].getTypeName().equals(typeName)) - return toAnnoType(anno2[i], cp); - - return null; - } - - public Object[] getAnnotations() throws ClassNotFoundException { - return getAnnotations(false); - } - - public Object[] getAvailableAnnotations(){ - try { - return getAnnotations(true); - } - catch (ClassNotFoundException e) { - throw new RuntimeException("Unexpected exception ", e); - } - } - - private Object[] getAnnotations(boolean ignoreNotFound) - throws ClassNotFoundException - { - ClassFile cf = getClassFile2(); - AnnotationsAttribute ainfo = (AnnotationsAttribute) - cf.getAttribute(AnnotationsAttribute.invisibleTag); - AnnotationsAttribute ainfo2 = (AnnotationsAttribute) - cf.getAttribute(AnnotationsAttribute.visibleTag); - return toAnnotationType(ignoreNotFound, getClassPool(), ainfo, ainfo2); - } - - static Object[] toAnnotationType(boolean ignoreNotFound, com.fr.third.javassist.ClassPool cp, - AnnotationsAttribute a1, AnnotationsAttribute a2) - throws ClassNotFoundException - { - Annotation[] anno1, anno2; - int size1, size2; - - if (a1 == null) { - anno1 = null; - size1 = 0; - } - else { - anno1 = a1.getAnnotations(); - size1 = anno1.length; - } - - if (a2 == null) { - anno2 = null; - size2 = 0; - } - else { - anno2 = a2.getAnnotations(); - size2 = anno2.length; - } - - if (!ignoreNotFound){ - Object[] result = new Object[size1 + size2]; - for (int i = 0; i < size1; i++) - result[i] = toAnnoType(anno1[i], cp); - - for (int j = 0; j < size2; j++) - result[j + size1] = toAnnoType(anno2[j], cp); - - return result; - } - else{ - ArrayList annotations = new ArrayList(); - for (int i = 0 ; i < size1 ; i++){ - try{ - annotations.add(toAnnoType(anno1[i], cp)); - } - catch(ClassNotFoundException e){} - } - for (int j = 0; j < size2; j++) { - try{ - annotations.add(toAnnoType(anno2[j], cp)); - } - catch(ClassNotFoundException e){} - } - - return annotations.toArray(); - } - } - - static Object[][] toAnnotationType(boolean ignoreNotFound, com.fr.third.javassist.ClassPool cp, - ParameterAnnotationsAttribute a1, - ParameterAnnotationsAttribute a2, - MethodInfo minfo) - throws ClassNotFoundException - { - int numParameters = 0; - if (a1 != null) - numParameters = a1.numParameters(); - else if (a2 != null) - numParameters = a2.numParameters(); - else - numParameters = Descriptor.numOfParameters(minfo.getDescriptor()); - - Object[][] result = new Object[numParameters][]; - for (int i = 0; i < numParameters; i++) { - Annotation[] anno1, anno2; - int size1, size2; - - if (a1 == null) { - anno1 = null; - size1 = 0; - } - else { - anno1 = a1.getAnnotations()[i]; - size1 = anno1.length; - } - - if (a2 == null) { - anno2 = null; - size2 = 0; - } - else { - anno2 = a2.getAnnotations()[i]; - size2 = anno2.length; - } - - if (!ignoreNotFound){ - result[i] = new Object[size1 + size2]; - for (int j = 0; j < size1; ++j) - result[i][j] = toAnnoType(anno1[j], cp); - - for (int j = 0; j < size2; ++j) - result[i][j + size1] = toAnnoType(anno2[j], cp); - } - else{ - ArrayList annotations = new ArrayList(); - for (int j = 0 ; j < size1 ; j++){ - try{ - annotations.add(toAnnoType(anno1[j], cp)); - } - catch(ClassNotFoundException e){} - } - for (int j = 0; j < size2; j++){ - try{ - annotations.add(toAnnoType(anno2[j], cp)); - } - catch(ClassNotFoundException e){} - } - - result[i] = annotations.toArray(); - } - } - - return result; - } - - private static Object toAnnoType(Annotation anno, ClassPool cp) - throws ClassNotFoundException - { - try { - ClassLoader cl = cp.getClassLoader(); - return anno.toAnnotationType(cl, cp); - } - catch (ClassNotFoundException e) { - ClassLoader cl2 = cp.getClass().getClassLoader(); - return anno.toAnnotationType(cl2, cp); - } - } - - public boolean subclassOf(com.fr.third.javassist.CtClass superclass) { - if (superclass == null) - return false; - - String superName = superclass.getName(); - com.fr.third.javassist.CtClass curr = this; - try { - while (curr != null) { - if (curr.getName().equals(superName)) - return true; - - curr = curr.getSuperclass(); - } - } - catch (Exception ignored) {} - return false; - } - - public com.fr.third.javassist.CtClass getSuperclass() throws NotFoundException { - String supername = getClassFile2().getSuperclass(); - if (supername == null) - return null; - else - return classPool.get(supername); - } - - public void setSuperclass(com.fr.third.javassist.CtClass clazz) throws com.fr.third.javassist.CannotCompileException { - checkModify(); - if (isInterface()) - addInterface(clazz); - else - getClassFile2().setSuperclass(clazz.getName()); - } - - public com.fr.third.javassist.CtClass[] getInterfaces() throws NotFoundException { - String[] ifs = getClassFile2().getInterfaces(); - int num = ifs.length; - com.fr.third.javassist.CtClass[] ifc = new com.fr.third.javassist.CtClass[num]; - for (int i = 0; i < num; ++i) - ifc[i] = classPool.get(ifs[i]); - - return ifc; - } - - public void setInterfaces(com.fr.third.javassist.CtClass[] list) { - checkModify(); - String[] ifs; - if (list == null) - ifs = new String[0]; - else { - int num = list.length; - ifs = new String[num]; - for (int i = 0; i < num; ++i) - ifs[i] = list[i].getName(); - } - - getClassFile2().setInterfaces(ifs); - } - - public void addInterface(com.fr.third.javassist.CtClass anInterface) { - checkModify(); - if (anInterface != null) - getClassFile2().addInterface(anInterface.getName()); - } - - public com.fr.third.javassist.CtClass getDeclaringClass() throws NotFoundException { - ClassFile cf = getClassFile2(); - InnerClassesAttribute ica = (InnerClassesAttribute)cf.getAttribute( - InnerClassesAttribute.tag); - if (ica == null) - return null; - - String name = getName(); - int n = ica.tableLength(); - for (int i = 0; i < n; ++i) - if (name.equals(ica.innerClass(i))) { - String outName = ica.outerClass(i); - if (outName != null) - return classPool.get(outName); - else { - // maybe anonymous or local class. - EnclosingMethodAttribute ema - = (EnclosingMethodAttribute)cf.getAttribute( - EnclosingMethodAttribute.tag); - if (ema != null) - return classPool.get(ema.className()); - } - } - - return null; - } - - public CtMethod getEnclosingMethod() throws NotFoundException { - ClassFile cf = getClassFile2(); - EnclosingMethodAttribute ema - = (EnclosingMethodAttribute)cf.getAttribute( - EnclosingMethodAttribute.tag); - if (ema != null) { - com.fr.third.javassist.CtClass enc = classPool.get(ema.className()); - return enc.getMethod(ema.methodName(), ema.methodDescriptor()); - } - - return null; - } - - public com.fr.third.javassist.CtClass makeNestedClass(String name, boolean isStatic) { - if (!isStatic) - throw new RuntimeException( - "sorry, only nested static class is supported"); - - checkModify(); - com.fr.third.javassist.CtClass c = classPool.makeNestedClass(getName() + "$" + name); - ClassFile cf = getClassFile2(); - ClassFile cf2 = c.getClassFile2(); - InnerClassesAttribute ica = (InnerClassesAttribute)cf.getAttribute( - InnerClassesAttribute.tag); - if (ica == null) { - ica = new InnerClassesAttribute(cf.getConstPool()); - cf.addAttribute(ica); - } - - ica.append(c.getName(), this.getName(), name, - (cf2.getAccessFlags() & ~AccessFlag.SUPER) | AccessFlag.STATIC); - cf2.addAttribute(ica.copy(cf2.getConstPool(), null)); - return c; - } - - /* flush cached names. - */ - private void nameReplaced() { - CtMember.Cache cache = hasMemberCache(); - if (cache != null) { - CtMember mth = cache.methodHead(); - CtMember tail = cache.lastMethod(); - while (mth != tail) { - mth = mth.next(); - mth.nameReplaced(); - } - } - } - - /** - * Returns null if members are not cached. - */ - protected CtMember.Cache hasMemberCache() { - if (memberCache != null) - return (CtMember.Cache)memberCache.get(); - else - return null; - } - - protected synchronized CtMember.Cache getMembers() { - CtMember.Cache cache = null; - if (memberCache == null - || (cache = (CtMember.Cache)memberCache.get()) == null) { - cache = new CtMember.Cache(this); - makeFieldCache(cache); - makeBehaviorCache(cache); - memberCache = new WeakReference(cache); - } - - return cache; - } - - private void makeFieldCache(CtMember.Cache cache) { - List list = getClassFile2().getFields(); - int n = list.size(); - for (int i = 0; i < n; ++i) { - FieldInfo finfo = (FieldInfo)list.get(i); - CtField newField = new CtField(finfo, this); - cache.addField(newField); - } - } - - private void makeBehaviorCache(CtMember.Cache cache) { - List list = getClassFile2().getMethods(); - int n = list.size(); - for (int i = 0; i < n; ++i) { - MethodInfo minfo = (MethodInfo)list.get(i); - if (minfo.isMethod()) { - CtMethod newMethod = new CtMethod(minfo, this); - cache.addMethod(newMethod); - } - else { - CtConstructor newCons = new CtConstructor(minfo, this); - cache.addConstructor(newCons); - } - } - } - - public CtField[] getFields() { - ArrayList alist = new ArrayList(); - getFields(alist, this); - return (CtField[])alist.toArray(new CtField[alist.size()]); - } - - private static void getFields(ArrayList alist, com.fr.third.javassist.CtClass cc) { - int i, num; - if (cc == null) - return; - - try { - getFields(alist, cc.getSuperclass()); - } - catch (NotFoundException e) {} - - try { - com.fr.third.javassist.CtClass[] ifs = cc.getInterfaces(); - num = ifs.length; - for (i = 0; i < num; ++i) - getFields(alist, ifs[i]); - } - catch (NotFoundException e) {} - - CtMember.Cache memCache = ((CtClassType)cc).getMembers(); - CtMember field = memCache.fieldHead(); - CtMember tail = memCache.lastField(); - while (field != tail) { - field = field.next(); - if (!Modifier.isPrivate(field.getModifiers())) - alist.add(field); - } - } - - public CtField getField(String name, String desc) throws NotFoundException { - CtField f = getField2(name, desc); - return checkGetField(f, name, desc); - } - - private CtField checkGetField(CtField f, String name, String desc) - throws NotFoundException - { - if (f == null) { - String msg = "field: " + name; - if (desc != null) - msg += " type " + desc; - - throw new NotFoundException(msg + " in " + getName()); - } - else - return f; - } - - CtField getField2(String name, String desc) { - CtField df = getDeclaredField2(name, desc); - if (df != null) - return df; - - try { - com.fr.third.javassist.CtClass[] ifs = getInterfaces(); - int num = ifs.length; - for (int i = 0; i < num; ++i) { - CtField f = ifs[i].getField2(name, desc); - if (f != null) - return f; - } - - com.fr.third.javassist.CtClass s = getSuperclass(); - if (s != null) - return s.getField2(name, desc); - } - catch (NotFoundException e) {} - return null; - } - - public CtField[] getDeclaredFields() { - CtMember.Cache memCache = getMembers(); - CtMember field = memCache.fieldHead(); - CtMember tail = memCache.lastField(); - int num = CtMember.Cache.count(field, tail); - CtField[] cfs = new CtField[num]; - int i = 0; - while (field != tail) { - field = field.next(); - cfs[i++] = (CtField)field; - } - - return cfs; - } - - public CtField getDeclaredField(String name) throws NotFoundException { - return getDeclaredField(name, null); - } - - public CtField getDeclaredField(String name, String desc) throws NotFoundException { - CtField f = getDeclaredField2(name, desc); - return checkGetField(f, name, desc); - } - - private CtField getDeclaredField2(String name, String desc) { - CtMember.Cache memCache = getMembers(); - CtMember field = memCache.fieldHead(); - CtMember tail = memCache.lastField(); - while (field != tail) { - field = field.next(); - if (field.getName().equals(name) - && (desc == null || desc.equals(field.getSignature()))) - return (CtField)field; - } - - return null; - } - - public com.fr.third.javassist.CtBehavior[] getDeclaredBehaviors() { - CtMember.Cache memCache = getMembers(); - CtMember cons = memCache.consHead(); - CtMember consTail = memCache.lastCons(); - int cnum = CtMember.Cache.count(cons, consTail); - CtMember mth = memCache.methodHead(); - CtMember mthTail = memCache.lastMethod(); - int mnum = CtMember.Cache.count(mth, mthTail); - - com.fr.third.javassist.CtBehavior[] cb = new com.fr.third.javassist.CtBehavior[cnum + mnum]; - int i = 0; - while (cons != consTail) { - cons = cons.next(); - cb[i++] = (com.fr.third.javassist.CtBehavior)cons; - } - - while (mth != mthTail) { - mth = mth.next(); - cb[i++] = (CtBehavior)mth; - } - - return cb; - } - - public CtConstructor[] getConstructors() { - CtMember.Cache memCache = getMembers(); - CtMember cons = memCache.consHead(); - CtMember consTail = memCache.lastCons(); - - int n = 0; - CtMember mem = cons; - while (mem != consTail) { - mem = mem.next(); - if (isPubCons((CtConstructor)mem)) - n++; - } - - CtConstructor[] result = new CtConstructor[n]; - int i = 0; - mem = cons; - while (mem != consTail) { - mem = mem.next(); - CtConstructor cc = (CtConstructor)mem; - if (isPubCons(cc)) - result[i++] = cc; - } - - return result; - } - - private static boolean isPubCons(CtConstructor cons) { - return !Modifier.isPrivate(cons.getModifiers()) - && cons.isConstructor(); - } - - public CtConstructor getConstructor(String desc) - throws NotFoundException - { - CtMember.Cache memCache = getMembers(); - CtMember cons = memCache.consHead(); - CtMember consTail = memCache.lastCons(); - - while (cons != consTail) { - cons = cons.next(); - CtConstructor cc = (CtConstructor)cons; - if (cc.getMethodInfo2().getDescriptor().equals(desc) - && cc.isConstructor()) - return cc; - } - - return super.getConstructor(desc); - } - - public CtConstructor[] getDeclaredConstructors() { - CtMember.Cache memCache = getMembers(); - CtMember cons = memCache.consHead(); - CtMember consTail = memCache.lastCons(); - - int n = 0; - CtMember mem = cons; - while (mem != consTail) { - mem = mem.next(); - CtConstructor cc = (CtConstructor)mem; - if (cc.isConstructor()) - n++; - } - - CtConstructor[] result = new CtConstructor[n]; - int i = 0; - mem = cons; - while (mem != consTail) { - mem = mem.next(); - CtConstructor cc = (CtConstructor)mem; - if (cc.isConstructor()) - result[i++] = cc; - } - - return result; - } - - public CtConstructor getClassInitializer() { - CtMember.Cache memCache = getMembers(); - CtMember cons = memCache.consHead(); - CtMember consTail = memCache.lastCons(); - - while (cons != consTail) { - cons = cons.next(); - CtConstructor cc = (CtConstructor)cons; - if (cc.isClassInitializer()) - return cc; - } - - return null; - } - - public CtMethod[] getMethods() { - HashMap h = new HashMap(); - getMethods0(h, this); - return (CtMethod[])h.values().toArray(new CtMethod[h.size()]); - } - - private static void getMethods0(HashMap h, com.fr.third.javassist.CtClass cc) { - try { - com.fr.third.javassist.CtClass[] ifs = cc.getInterfaces(); - int size = ifs.length; - for (int i = 0; i < size; ++i) - getMethods0(h, ifs[i]); - } - catch (NotFoundException e) {} - - try { - com.fr.third.javassist.CtClass s = cc.getSuperclass(); - if (s != null) - getMethods0(h, s); - } - catch (NotFoundException e) {} - - if (cc instanceof CtClassType) { - CtMember.Cache memCache = ((CtClassType)cc).getMembers(); - CtMember mth = memCache.methodHead(); - CtMember mthTail = memCache.lastMethod(); - - while (mth != mthTail) { - mth = mth.next(); - if (!Modifier.isPrivate(mth.getModifiers())) - h.put(((CtMethod)mth).getStringRep(), mth); - } - } - } - - public CtMethod getMethod(String name, String desc) - throws NotFoundException - { - CtMethod m = getMethod0(this, name, desc); - if (m != null) - return m; - else - throw new NotFoundException(name + "(..) is not found in " - + getName()); - } - - private static CtMethod getMethod0(com.fr.third.javassist.CtClass cc, - String name, String desc) { - if (cc instanceof CtClassType) { - CtMember.Cache memCache = ((CtClassType)cc).getMembers(); - CtMember mth = memCache.methodHead(); - CtMember mthTail = memCache.lastMethod(); - - while (mth != mthTail) { - mth = mth.next(); - if (mth.getName().equals(name) - && ((CtMethod)mth).getMethodInfo2().getDescriptor().equals(desc)) - return (CtMethod)mth; - } - } - - try { - com.fr.third.javassist.CtClass s = cc.getSuperclass(); - if (s != null) { - CtMethod m = getMethod0(s, name, desc); - if (m != null) - return m; - } - } - catch (NotFoundException e) {} - - try { - com.fr.third.javassist.CtClass[] ifs = cc.getInterfaces(); - int size = ifs.length; - for (int i = 0; i < size; ++i) { - CtMethod m = getMethod0(ifs[i], name, desc); - if (m != null) - return m; - } - } - catch (NotFoundException e) {} - return null; - } - - public CtMethod[] getDeclaredMethods() { - CtMember.Cache memCache = getMembers(); - CtMember mth = memCache.methodHead(); - CtMember mthTail = memCache.lastMethod(); - int num = CtMember.Cache.count(mth, mthTail); - CtMethod[] cms = new CtMethod[num]; - int i = 0; - while (mth != mthTail) { - mth = mth.next(); - cms[i++] = (CtMethod)mth; - } - - return cms; - } - - public CtMethod getDeclaredMethod(String name) throws NotFoundException { - CtMember.Cache memCache = getMembers(); - CtMember mth = memCache.methodHead(); - CtMember mthTail = memCache.lastMethod(); - while (mth != mthTail) { - mth = mth.next(); - if (mth.getName().equals(name)) - return (CtMethod)mth; - } - - throw new NotFoundException(name + "(..) is not found in " - + getName()); - } - - public CtMethod getDeclaredMethod(String name, com.fr.third.javassist.CtClass[] params) - throws NotFoundException - { - String desc = Descriptor.ofParameters(params); - CtMember.Cache memCache = getMembers(); - CtMember mth = memCache.methodHead(); - CtMember mthTail = memCache.lastMethod(); - - while (mth != mthTail) { - mth = mth.next(); - if (mth.getName().equals(name) - && ((CtMethod)mth).getMethodInfo2().getDescriptor().startsWith(desc)) - return (CtMethod)mth; - } - - throw new NotFoundException(name + "(..) is not found in " - + getName()); - } - - public void addField(CtField f, String init) - throws com.fr.third.javassist.CannotCompileException - { - addField(f, CtField.Initializer.byExpr(init)); - } - - public void addField(CtField f, CtField.Initializer init) - throws com.fr.third.javassist.CannotCompileException - { - checkModify(); - if (f.getDeclaringClass() != this) - throw new com.fr.third.javassist.CannotCompileException("cannot add"); - - if (init == null) - init = f.getInit(); - - if (init != null) { - init.check(f.getSignature()); - int mod = f.getModifiers(); - if (Modifier.isStatic(mod) && Modifier.isFinal(mod)) - try { - ConstPool cp = getClassFile2().getConstPool(); - int index = init.getConstantValue(cp, f.getType()); - if (index != 0) { - f.getFieldInfo2().addAttribute(new ConstantAttribute(cp, index)); - init = null; - } - } - catch (NotFoundException e) {} - } - - getMembers().addField(f); - getClassFile2().addField(f.getFieldInfo2()); - - if (init != null) { - FieldInitLink fil = new FieldInitLink(f, init); - FieldInitLink link = fieldInitializers; - if (link == null) - fieldInitializers = fil; - else { - while (link.next != null) - link = link.next; - - link.next = fil; - } - } - } - - public void removeField(CtField f) throws NotFoundException { - checkModify(); - FieldInfo fi = f.getFieldInfo2(); - ClassFile cf = getClassFile2(); - if (cf.getFields().remove(fi)) { - getMembers().remove(f); - gcConstPool = true; - } - else - throw new NotFoundException(f.toString()); - } - - public CtConstructor makeClassInitializer() - throws com.fr.third.javassist.CannotCompileException - { - CtConstructor clinit = getClassInitializer(); - if (clinit != null) - return clinit; - - checkModify(); - ClassFile cf = getClassFile2(); - Bytecode code = new Bytecode(cf.getConstPool(), 0, 0); - modifyClassConstructor(cf, code, 0, 0); - return getClassInitializer(); - } - - public void addConstructor(CtConstructor c) - throws com.fr.third.javassist.CannotCompileException - { - checkModify(); - if (c.getDeclaringClass() != this) - throw new com.fr.third.javassist.CannotCompileException("cannot add"); - - getMembers().addConstructor(c); - getClassFile2().addMethod(c.getMethodInfo2()); - } - - public void removeConstructor(CtConstructor m) throws NotFoundException { - checkModify(); - MethodInfo mi = m.getMethodInfo2(); - ClassFile cf = getClassFile2(); - if (cf.getMethods().remove(mi)) { - getMembers().remove(m); - gcConstPool = true; - } - else - throw new NotFoundException(m.toString()); - } - - public void addMethod(CtMethod m) throws com.fr.third.javassist.CannotCompileException { - checkModify(); - if (m.getDeclaringClass() != this) - throw new com.fr.third.javassist.CannotCompileException("bad declaring class"); - - int mod = m.getModifiers(); - if ((getModifiers() & Modifier.INTERFACE) != 0) { - m.setModifiers(mod | Modifier.PUBLIC); - if ((mod & Modifier.ABSTRACT) == 0) - throw new com.fr.third.javassist.CannotCompileException( - "an interface method must be abstract: " + m.toString()); - } - - getMembers().addMethod(m); - getClassFile2().addMethod(m.getMethodInfo2()); - if ((mod & Modifier.ABSTRACT) != 0) - setModifiers(getModifiers() | Modifier.ABSTRACT); - } - - public void removeMethod(CtMethod m) throws NotFoundException { - checkModify(); - MethodInfo mi = m.getMethodInfo2(); - ClassFile cf = getClassFile2(); - if (cf.getMethods().remove(mi)) { - getMembers().remove(m); - gcConstPool = true; - } - else - throw new NotFoundException(m.toString()); - } - - public byte[] getAttribute(String name) { - AttributeInfo ai = getClassFile2().getAttribute(name); - if (ai == null) - return null; - else - return ai.get(); - } - - public void setAttribute(String name, byte[] data) { - checkModify(); - ClassFile cf = getClassFile2(); - cf.addAttribute(new AttributeInfo(cf.getConstPool(), name, data)); - } - - public void instrument(CodeConverter converter) - throws com.fr.third.javassist.CannotCompileException - { - checkModify(); - ClassFile cf = getClassFile2(); - ConstPool cp = cf.getConstPool(); - List list = cf.getMethods(); - int n = list.size(); - for (int i = 0; i < n; ++i) { - MethodInfo minfo = (MethodInfo)list.get(i); - converter.doit(this, minfo, cp); - } - } - - public void instrument(ExprEditor editor) - throws com.fr.third.javassist.CannotCompileException - { - checkModify(); - ClassFile cf = getClassFile2(); - List list = cf.getMethods(); - int n = list.size(); - for (int i = 0; i < n; ++i) { - MethodInfo minfo = (MethodInfo)list.get(i); - editor.doit(this, minfo); - } - } - - /** - * @see com.fr.third.javassist.CtClass#prune() - * @see com.fr.third.javassist.CtClass#stopPruning(boolean) - */ - public void prune() { - if (wasPruned) - return; - - wasPruned = wasFrozen = true; - getClassFile2().prune(); - } - - public void rebuildClassFile() { gcConstPool = true; } - - public void toBytecode(DataOutputStream out) - throws com.fr.third.javassist.CannotCompileException, IOException - { - try { - if (isModified()) { - checkPruned("toBytecode"); - ClassFile cf = getClassFile2(); - if (gcConstPool) { - cf.compact(); - gcConstPool = false; - } - - modifyClassConstructor(cf); - modifyConstructors(cf); - if (debugDump != null) - dumpClassFile(cf); - - cf.write(out); - out.flush(); - fieldInitializers = null; - if (doPruning) { - // to save memory - cf.prune(); - wasPruned = true; - } - } - else { - classPool.writeClassfile(getName(), out); - // to save memory - // classfile = null; - } - - getCount = 0; - wasFrozen = true; - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - catch (IOException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - private void dumpClassFile(ClassFile cf) throws IOException { - DataOutputStream dump = makeFileOutput(debugDump); - try { - cf.write(dump); - } - finally { - dump.close(); - } - } - - /* See also checkModified() - */ - private void checkPruned(String method) { - if (wasPruned) - throw new RuntimeException(method + "(): " + getName() - + " was pruned."); - } - - public boolean stopPruning(boolean stop) { - boolean prev = !doPruning; - doPruning = !stop; - return prev; - } - - private void modifyClassConstructor(ClassFile cf) - throws com.fr.third.javassist.CannotCompileException, NotFoundException - { - if (fieldInitializers == null) - return; - - Bytecode code = new Bytecode(cf.getConstPool(), 0, 0); - Javac jv = new Javac(code, this); - int stacksize = 0; - boolean doInit = false; - for (FieldInitLink fi = fieldInitializers; fi != null; fi = fi.next) { - CtField f = fi.field; - if (Modifier.isStatic(f.getModifiers())) { - doInit = true; - int s = fi.init.compileIfStatic(f.getType(), f.getName(), - code, jv); - if (stacksize < s) - stacksize = s; - } - } - - if (doInit) // need an initializer for static fileds. - modifyClassConstructor(cf, code, stacksize, 0); - } - - private void modifyClassConstructor(ClassFile cf, Bytecode code, - int stacksize, int localsize) - throws com.fr.third.javassist.CannotCompileException - { - MethodInfo m = cf.getStaticInitializer(); - if (m == null) { - code.add(Bytecode.RETURN); - code.setMaxStack(stacksize); - code.setMaxLocals(localsize); - m = new MethodInfo(cf.getConstPool(), "", "()V"); - m.setAccessFlags(AccessFlag.STATIC); - m.setCodeAttribute(code.toCodeAttribute()); - cf.addMethod(m); - CtMember.Cache cache = hasMemberCache(); - if (cache != null) - cache.addConstructor(new CtConstructor(m, this)); - } - else { - CodeAttribute codeAttr = m.getCodeAttribute(); - if (codeAttr == null) - throw new com.fr.third.javassist.CannotCompileException("empty "); - - try { - CodeIterator it = codeAttr.iterator(); - int pos = it.insertEx(code.get()); - it.insert(code.getExceptionTable(), pos); - int maxstack = codeAttr.getMaxStack(); - if (maxstack < stacksize) - codeAttr.setMaxStack(stacksize); - - int maxlocals = codeAttr.getMaxLocals(); - if (maxlocals < localsize) - codeAttr.setMaxLocals(localsize); - } - catch (BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - try { - m.rebuildStackMapIf6(classPool, cf); - } - catch (BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - private void modifyConstructors(ClassFile cf) - throws com.fr.third.javassist.CannotCompileException, NotFoundException - { - if (fieldInitializers == null) - return; - - ConstPool cp = cf.getConstPool(); - List list = cf.getMethods(); - int n = list.size(); - for (int i = 0; i < n; ++i) { - MethodInfo minfo = (MethodInfo)list.get(i); - if (minfo.isConstructor()) { - CodeAttribute codeAttr = minfo.getCodeAttribute(); - if (codeAttr != null) - try { - Bytecode init = new Bytecode(cp, 0, - codeAttr.getMaxLocals()); - com.fr.third.javassist.CtClass[] params - = Descriptor.getParameterTypes( - minfo.getDescriptor(), - classPool); - int stacksize = makeFieldInitializer(init, params); - insertAuxInitializer(codeAttr, init, stacksize); - minfo.rebuildStackMapIf6(classPool, cf); - } - catch (BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - } - } - - private static void insertAuxInitializer(CodeAttribute codeAttr, - Bytecode initializer, - int stacksize) - throws BadBytecode - { - CodeIterator it = codeAttr.iterator(); - int index = it.skipSuperConstructor(); - if (index < 0) { - index = it.skipThisConstructor(); - if (index >= 0) - return; // this() is called. - - // Neither this() or super() is called. - } - - int pos = it.insertEx(initializer.get()); - it.insert(initializer.getExceptionTable(), pos); - int maxstack = codeAttr.getMaxStack(); - if (maxstack < stacksize) - codeAttr.setMaxStack(stacksize); - } - - private int makeFieldInitializer(Bytecode code, com.fr.third.javassist.CtClass[] parameters) - throws com.fr.third.javassist.CannotCompileException, NotFoundException - { - int stacksize = 0; - Javac jv = new Javac(code, this); - try { - jv.recordParams(parameters, false); - } - catch (CompileError e) { - throw new CannotCompileException(e); - } - - for (FieldInitLink fi = fieldInitializers; fi != null; fi = fi.next) { - CtField f = fi.field; - if (!Modifier.isStatic(f.getModifiers())) { - int s = fi.init.compile(f.getType(), f.getName(), code, - parameters, jv); - if (stacksize < s) - stacksize = s; - } - } - - return stacksize; - } - - // Methods used by CtNewWrappedMethod - - Hashtable getHiddenMethods() { - if (hiddenMethods == null) - hiddenMethods = new Hashtable(); - - return hiddenMethods; - } - - int getUniqueNumber() { return uniqueNumberSeed++; } - - public String makeUniqueName(String prefix) { - HashMap table = new HashMap(); - makeMemberList(table); - Set keys = table.keySet(); - String[] methods = new String[keys.size()]; - keys.toArray(methods); - - if (notFindInArray(prefix, methods)) - return prefix; - - int i = 100; - String name; - do { - if (i > 999) - throw new RuntimeException("too many unique name"); - - name = prefix + i++; - } while (!notFindInArray(name, methods)); - return name; - } - - private static boolean notFindInArray(String prefix, String[] values) { - int len = values.length; - for (int i = 0; i < len; i++) - if (values[i].startsWith(prefix)) - return false; - - return true; - } - - private void makeMemberList(HashMap table) { - int mod = getModifiers(); - if (Modifier.isAbstract(mod) || Modifier.isInterface(mod)) - try { - com.fr.third.javassist.CtClass[] ifs = getInterfaces(); - int size = ifs.length; - for (int i = 0; i < size; i++) { - com.fr.third.javassist.CtClass ic =ifs[i]; - if (ic != null && ic instanceof CtClassType) - ((CtClassType)ic).makeMemberList(table); - } - } - catch (NotFoundException e) {} - - try { - CtClass s = getSuperclass(); - if (s != null && s instanceof CtClassType) - ((CtClassType)s).makeMemberList(table); - } - catch (NotFoundException e) {} - - List list = getClassFile2().getMethods(); - int n = list.size(); - for (int i = 0; i < n; i++) { - MethodInfo minfo = (MethodInfo)list.get(i); - table.put(minfo.getName(), this); - } - - list = getClassFile2().getFields(); - n = list.size(); - for (int i = 0; i < n; i++) { - FieldInfo finfo = (FieldInfo)list.get(i); - table.put(finfo.getName(), this); - } - } -} - -class FieldInitLink { - FieldInitLink next; - CtField field; - CtField.Initializer init; - - FieldInitLink(CtField f, CtField.Initializer i) { - next = null; - field = f; - init = i; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CtConstructor.java b/fine-javassist/src/main/java/com/fr/third/javassist/CtConstructor.java deleted file mode 100644 index d2f25353d..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CtConstructor.java +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.compiler.Javac; -import com.fr.third.javassist.compiler.CompileError; - -/** - * An instance of CtConstructor represents a constructor. - * It may represent a static constructor - * (class initializer). To distinguish a constructor and a class - * initializer, call isClassInitializer(). - * - *

See the super class CtBehavior as well since - * a number of useful methods are in CtBehavior. - * - * @see com.fr.third.javassist.CtClass#getDeclaredConstructors() - * @see com.fr.third.javassist.CtClass#getClassInitializer() - * @see CtNewConstructor - */ -public final class CtConstructor extends CtBehavior { - protected CtConstructor(com.fr.third.javassist.bytecode.MethodInfo minfo, com.fr.third.javassist.CtClass declaring) { - super(declaring, minfo); - } - - /** - * Creates a constructor with no constructor body. - * The created constructor - * must be added to a class with CtClass.addConstructor(). - * - *

The created constructor does not include a constructor body, - * which must be specified with setBody(). - * - * @param declaring the class to which the created method is added. - * @param parameters a list of the parameter types - * - * @see com.fr.third.javassist.CtClass#addConstructor(CtConstructor) - * @see CtConstructor#setBody(String) - * @see CtConstructor#setBody(CtConstructor, com.fr.third.javassist.ClassMap) - */ - public CtConstructor(com.fr.third.javassist.CtClass[] parameters, com.fr.third.javassist.CtClass declaring) { - this((com.fr.third.javassist.bytecode.MethodInfo)null, declaring); - com.fr.third.javassist.bytecode.ConstPool cp = declaring.getClassFile2().getConstPool(); - String desc = com.fr.third.javassist.bytecode.Descriptor.ofConstructor(parameters); - methodInfo = new com.fr.third.javassist.bytecode.MethodInfo(cp, "", desc); - setModifiers(Modifier.PUBLIC); - } - - /** - * Creates a copy of a CtConstructor object. - * The created constructor must be - * added to a class with CtClass.addConstructor(). - * - *

All occurrences of class names in the created constructor - * are replaced with names specified by - * map if map is not null. - * - *

By default, all the occurrences of the names of the class - * declaring src and the superclass are replaced - * with the name of the class and the superclass that - * the created constructor is added to. - * This is done whichever map is null or not. - * To prevent this replacement, call ClassMap.fix() - * or put() to explicitly specify replacement. - * - *

Note: if the .class notation (for example, - * String.class) is included in an expression, the - * Javac compiler may produce a helper method. - * Since this constructor never - * copies this helper method, the programmers have the responsiblity of - * copying it. Otherwise, use Class.forName() in the - * expression. - * - * @param src the source method. - * @param declaring the class to which the created method is added. - * @param map the hashtable associating original class names - * with substituted names. - * It can be null. - * - * @see com.fr.third.javassist.CtClass#addConstructor(CtConstructor) - * @see com.fr.third.javassist.ClassMap#fix(String) - */ - public CtConstructor(CtConstructor src, com.fr.third.javassist.CtClass declaring, com.fr.third.javassist.ClassMap map) - throws com.fr.third.javassist.CannotCompileException - { - this((com.fr.third.javassist.bytecode.MethodInfo)null, declaring); - copy(src, true, map); - } - - /** - * Returns true if this object represents a constructor. - */ - public boolean isConstructor() { - return methodInfo.isConstructor(); - } - - /** - * Returns true if this object represents a static initializer. - */ - public boolean isClassInitializer() { - return methodInfo.isStaticInitializer(); - } - - /** - * Returns the constructor name followed by parameter types - * such as javassist.CtConstructor(CtClass[],CtClass). - * - * @since 3.5 - */ - public String getLongName() { - return getDeclaringClass().getName() - + (isConstructor() ? com.fr.third.javassist.bytecode.Descriptor.toString(getSignature()) - : ("." + com.fr.third.javassist.bytecode.MethodInfo.nameClinit + "()")); - } - - /** - * Obtains the name of this constructor. - * It is the same as the simple name of the class declaring this - * constructor. If this object represents a class initializer, - * then this method returns "<clinit>". - */ - public String getName() { - if (methodInfo.isStaticInitializer()) - return com.fr.third.javassist.bytecode.MethodInfo.nameClinit; - else - return declaringClass.getSimpleName(); - } - - /** - * Returns true if the constructor (or static initializer) - * is the default one. This method returns true if the constructor - * takes some arguments but it does not perform anything except - * calling super() (the no-argument constructor of - * the super class). - */ - public boolean isEmpty() { - com.fr.third.javassist.bytecode.CodeAttribute ca = getMethodInfo2().getCodeAttribute(); - if (ca == null) - return false; // native or abstract?? - // they are not allowed, though. - - com.fr.third.javassist.bytecode.ConstPool cp = ca.getConstPool(); - com.fr.third.javassist.bytecode.CodeIterator it = ca.iterator(); - try { - int pos, desc; - int op0 = it.byteAt(it.next()); - return op0 == com.fr.third.javassist.bytecode.Opcode.RETURN // empty static initializer - || (op0 == com.fr.third.javassist.bytecode.Opcode.ALOAD_0 - && it.byteAt(pos = it.next()) == com.fr.third.javassist.bytecode.Opcode.INVOKESPECIAL - && (desc = cp.isConstructor(getSuperclassName(), - it.u16bitAt(pos + 1))) != 0 - && "()V".equals(cp.getUtf8Info(desc)) - && it.byteAt(it.next()) == com.fr.third.javassist.bytecode.Opcode.RETURN - && !it.hasNext()); - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) {} - return false; - } - - private String getSuperclassName() { - com.fr.third.javassist.bytecode.ClassFile cf = declaringClass.getClassFile2(); - return cf.getSuperclass(); - } - - /** - * Returns true if this constructor calls a constructor - * of the super class. This method returns false if it - * calls another constructor of this class by this(). - */ - public boolean callsSuper() throws com.fr.third.javassist.CannotCompileException { - com.fr.third.javassist.bytecode.CodeAttribute codeAttr = methodInfo.getCodeAttribute(); - if (codeAttr != null) { - com.fr.third.javassist.bytecode.CodeIterator it = codeAttr.iterator(); - try { - int index = it.skipSuperConstructor(); - return index >= 0; - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - return false; - } - - /** - * Sets a constructor body. - * - * @param src the source code representing the constructor body. - * It must be a single statement or block. - * If it is null, the substituted - * constructor body does nothing except calling - * super(). - */ - public void setBody(String src) throws com.fr.third.javassist.CannotCompileException { - if (src == null) - if (isClassInitializer()) - src = ";"; - else - src = "super();"; - - super.setBody(src); - } - - /** - * Copies a constructor body from another constructor. - * - *

All occurrences of the class names in the copied body - * are replaced with the names specified by - * map if map is not null. - * - * @param src the method that the body is copied from. - * @param map the hashtable associating original class names - * with substituted names. - * It can be null. - */ - public void setBody(CtConstructor src, com.fr.third.javassist.ClassMap map) - throws com.fr.third.javassist.CannotCompileException - { - setBody0(src.declaringClass, src.methodInfo, - declaringClass, methodInfo, map); - } - - /** - * Inserts bytecode just after another constructor in the super class - * or this class is called. - * It does not work if this object represents a class initializer. - * - * @param src the source code representing the inserted bytecode. - * It must be a single statement or block. - */ - public void insertBeforeBody(String src) throws com.fr.third.javassist.CannotCompileException { - com.fr.third.javassist.CtClass cc = declaringClass; - cc.checkModify(); - if (isClassInitializer()) - throw new com.fr.third.javassist.CannotCompileException("class initializer"); - - com.fr.third.javassist.bytecode.CodeAttribute ca = methodInfo.getCodeAttribute(); - com.fr.third.javassist.bytecode.CodeIterator iterator = ca.iterator(); - com.fr.third.javassist.bytecode.Bytecode b = new com.fr.third.javassist.bytecode.Bytecode(methodInfo.getConstPool(), - ca.getMaxStack(), ca.getMaxLocals()); - b.setStackDepth(ca.getMaxStack()); - Javac jv = new Javac(b, cc); - try { - jv.recordParams(getParameterTypes(), false); - jv.compileStmnt(src); - ca.setMaxStack(b.getMaxStack()); - ca.setMaxLocals(b.getMaxLocals()); - iterator.skipConstructor(); - int pos = iterator.insertEx(b.get()); - iterator.insert(b.getExceptionTable(), pos); - methodInfo.rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2()); - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - catch (CompileError e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - /* This method is called by addCatch() in CtBehavior. - * super() and this() must not be in a try statement. - */ - int getStartPosOfBody(com.fr.third.javassist.bytecode.CodeAttribute ca) throws com.fr.third.javassist.CannotCompileException { - com.fr.third.javassist.bytecode.CodeIterator ci = ca.iterator(); - try { - ci.skipConstructor(); - return ci.next(); - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - /** - * Makes a copy of this constructor and converts it into a method. - * The signature of the mehtod is the same as the that of this constructor. - * The return type is void. The resulting method must be - * appended to the class specified by declaring. - * If this constructor is a static initializer, the resulting method takes - * no parameter. - * - *

An occurrence of another constructor call this() - * or a super constructor call super() is - * eliminated from the resulting method. - * - *

The immediate super class of the class declaring this constructor - * must be also a super class of the class declaring the resulting method. - * If the constructor accesses a field, the class declaring the resulting method - * must also declare a field with the same name and type. - * - * @param name the name of the resulting method. - * @param declaring the class declaring the resulting method. - */ - public CtMethod toMethod(String name, com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - return toMethod(name, declaring, null); - } - - /** - * Makes a copy of this constructor and converts it into a method. - * The signature of the method is the same as the that of this constructor. - * The return type is void. The resulting method must be - * appended to the class specified by declaring. - * If this constructor is a static initializer, the resulting method takes - * no parameter. - * - *

An occurrence of another constructor call this() - * or a super constructor call super() is - * eliminated from the resulting method. - * - *

The immediate super class of the class declaring this constructor - * must be also a super class of the class declaring the resulting method - * (this is obviously true if the second parameter declaring is - * the same as the class declaring this constructor). - * If the constructor accesses a field, the class declaring the resulting method - * must also declare a field with the same name and type. - * - * @param name the name of the resulting method. - * @param declaring the class declaring the resulting method. - * It is normally the same as the class declaring this - * constructor. - * @param map the hash table associating original class names - * with substituted names. The original class names will be - * replaced while making a copy. - * map can be null. - */ - public CtMethod toMethod(String name, CtClass declaring, ClassMap map) - throws com.fr.third.javassist.CannotCompileException - { - CtMethod method = new CtMethod(null, declaring); - method.copy(this, false, map); - if (isConstructor()) { - com.fr.third.javassist.bytecode.MethodInfo minfo = method.getMethodInfo2(); - com.fr.third.javassist.bytecode.CodeAttribute ca = minfo.getCodeAttribute(); - if (ca != null) { - removeConsCall(ca); - try { - methodInfo.rebuildStackMapIf6(declaring.getClassPool(), - declaring.getClassFile2()); - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - } - - method.setName(name); - return method; - } - - private static void removeConsCall(CodeAttribute ca) - throws com.fr.third.javassist.CannotCompileException - { - com.fr.third.javassist.bytecode.CodeIterator iterator = ca.iterator(); - try { - int pos = iterator.skipConstructor(); - if (pos >= 0) { - int mref = iterator.u16bitAt(pos + 1); - String desc = ca.getConstPool().getMethodrefType(mref); - int num = com.fr.third.javassist.bytecode.Descriptor.numOfParameters(desc) + 1; - if (num > 3) - pos = iterator.insertGapAt(pos, num - 3, false).position; - - iterator.writeByte(com.fr.third.javassist.bytecode.Opcode.POP, pos++); // this - iterator.writeByte(com.fr.third.javassist.bytecode.Opcode.NOP, pos); - iterator.writeByte(com.fr.third.javassist.bytecode.Opcode.NOP, pos + 1); - com.fr.third.javassist.bytecode.Descriptor.Iterator it = new com.fr.third.javassist.bytecode.Descriptor.Iterator(desc); - while (true) { - it.next(); - if (it.isParameter()) - iterator.writeByte(it.is2byte() ? com.fr.third.javassist.bytecode.Opcode.POP2 : com.fr.third.javassist.bytecode.Opcode.POP, - pos++); - else - break; - } - } - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new CannotCompileException(e); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CtField.java b/fine-javassist/src/main/java/com/fr/third/javassist/CtField.java deleted file mode 100644 index 235294992..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CtField.java +++ /dev/null @@ -1,1414 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.compiler.Javac; -import com.fr.third.javassist.compiler.SymbolTable; -import com.fr.third.javassist.compiler.CompileError; -import com.fr.third.javassist.compiler.ast.ASTree; -import com.fr.third.javassist.compiler.ast.IntConst; -import com.fr.third.javassist.compiler.ast.DoubleConst; -import com.fr.third.javassist.compiler.ast.StringL; - -/** - * An instance of CtField represents a field. - * - * @see com.fr.third.javassist.CtClass#getDeclaredFields() - */ -public class CtField extends CtMember { - static final String javaLangString = "java.lang.String"; - - protected com.fr.third.javassist.bytecode.FieldInfo fieldInfo; - - /** - * Creates a CtField object. - * The created field must be added to a class - * with CtClass.addField(). - * An initial value of the field is specified - * by a CtField.Initializer object. - * - *

If getter and setter methods are needed, - * call CtNewMethod.getter() and - * CtNewMethod.setter(). - * - * @param type field type - * @param name field name - * @param declaring the class to which the field will be added. - * - * @see com.fr.third.javassist.CtClass#addField(CtField) - * @see CtNewMethod#getter(String,CtField) - * @see CtNewMethod#setter(String,CtField) - * @see CtField.Initializer - */ - public CtField(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - this(com.fr.third.javassist.bytecode.Descriptor.of(type), name, declaring); - } - - /** - * Creates a copy of the given field. - * The created field must be added to a class - * with CtClass.addField(). - * An initial value of the field is specified - * by a CtField.Initializer object. - * - *

If getter and setter methods are needed, - * call CtNewMethod.getter() and - * CtNewMethod.setter(). - * - * @param src the original field - * @param declaring the class to which the field will be added. - * @see CtNewMethod#getter(String,CtField) - * @see CtNewMethod#setter(String,CtField) - * @see CtField.Initializer - */ - public CtField(CtField src, com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - this(src.fieldInfo.getDescriptor(), src.fieldInfo.getName(), - declaring); - java.util.ListIterator iterator - = src.fieldInfo.getAttributes().listIterator(); - com.fr.third.javassist.bytecode.FieldInfo fi = fieldInfo; - fi.setAccessFlags(src.fieldInfo.getAccessFlags()); - com.fr.third.javassist.bytecode.ConstPool cp = fi.getConstPool(); - while (iterator.hasNext()) { - com.fr.third.javassist.bytecode.AttributeInfo ainfo = (com.fr.third.javassist.bytecode.AttributeInfo)iterator.next(); - fi.addAttribute(ainfo.copy(cp, null)); - } - } - - private CtField(String typeDesc, String name, com.fr.third.javassist.CtClass clazz) - throws com.fr.third.javassist.CannotCompileException - { - super(clazz); - com.fr.third.javassist.bytecode.ClassFile cf = clazz.getClassFile2(); - if (cf == null) - throw new com.fr.third.javassist.CannotCompileException("bad declaring class: " - + clazz.getName()); - - fieldInfo = new com.fr.third.javassist.bytecode.FieldInfo(cf.getConstPool(), name, typeDesc); - } - - CtField(com.fr.third.javassist.bytecode.FieldInfo fi, com.fr.third.javassist.CtClass clazz) { - super(clazz); - fieldInfo = fi; - } - - /** - * Returns a String representation of the object. - */ - public String toString() { - return getDeclaringClass().getName() + "." + getName() - + ":" + fieldInfo.getDescriptor(); - } - - protected void extendToString(StringBuffer buffer) { - buffer.append(' '); - buffer.append(getName()); - buffer.append(' '); - buffer.append(fieldInfo.getDescriptor()); - } - - /* Javac.CtFieldWithInit overrides. - */ - protected ASTree getInitAST() { return null; } - - /* Called by CtClassType.addField(). - */ - Initializer getInit() { - ASTree tree = getInitAST(); - if (tree == null) - return null; - else - return Initializer.byExpr(tree); - } - - /** - * Compiles the given source code and creates a field. - * Examples of the source code are: - * - *

    -     * "public String name;"
    -     * "public int k = 3;"
- * - *

Note that the source code ends with ';' - * (semicolon). - * - * @param src the source text. - * @param declaring the class to which the created field is added. - */ - public static CtField make(String src, com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - Javac compiler = new Javac(declaring); - try { - CtMember obj = compiler.compile(src); - if (obj instanceof CtField) - return (CtField)obj; // an instance of Javac.CtFieldWithInit - } - catch (CompileError e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - - throw new com.fr.third.javassist.CannotCompileException("not a field"); - } - - /** - * Returns the FieldInfo representing the field in the class file. - */ - public com.fr.third.javassist.bytecode.FieldInfo getFieldInfo() { - declaringClass.checkModify(); - return fieldInfo; - } - - /** - * Returns the FieldInfo representing the field in the class - * file (read only). - * Normal applications do not need calling this method. Use - * getFieldInfo(). - * - *

The FieldInfo object obtained by this method - * is read only. Changes to this object might not be reflected - * on a class file generated by toBytecode(), - * toClass(), etc in CtClass. - * - *

This method is available even if the CtClass - * containing this field is frozen. However, if the class is - * frozen, the FieldInfo might be also pruned. - * - * @see #getFieldInfo() - * @see com.fr.third.javassist.CtClass#isFrozen() - * @see com.fr.third.javassist.CtClass#prune() - */ - public com.fr.third.javassist.bytecode.FieldInfo getFieldInfo2() { return fieldInfo; } - - /** - * Returns the class declaring the field. - */ - public com.fr.third.javassist.CtClass getDeclaringClass() { - // this is redundant but for javadoc. - return super.getDeclaringClass(); - } - - /** - * Returns the name of the field. - */ - public String getName() { - return fieldInfo.getName(); - } - - /** - * Changes the name of the field. - */ - public void setName(String newName) { - declaringClass.checkModify(); - fieldInfo.setName(newName); - } - - /** - * Returns the encoded modifiers of the field. - * - * @see Modifier - */ - public int getModifiers() { - return com.fr.third.javassist.bytecode.AccessFlag.toModifier(fieldInfo.getAccessFlags()); - } - - /** - * Sets the encoded modifiers of the field. - * - * @see Modifier - */ - public void setModifiers(int mod) { - declaringClass.checkModify(); - fieldInfo.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.of(mod)); - } - - /** - * Returns true if the class has the specified annotation class. - * - * @param clz the annotation class. - * @return true if the annotation is found, otherwise false. - * @since 3.11 - */ - public boolean hasAnnotation(Class clz) { - com.fr.third.javassist.bytecode.FieldInfo fi = getFieldInfo2(); - com.fr.third.javassist.bytecode.AnnotationsAttribute ainfo = (com.fr.third.javassist.bytecode.AnnotationsAttribute) - fi.getAttribute(com.fr.third.javassist.bytecode.AnnotationsAttribute.invisibleTag); - com.fr.third.javassist.bytecode.AnnotationsAttribute ainfo2 = (com.fr.third.javassist.bytecode.AnnotationsAttribute) - fi.getAttribute(com.fr.third.javassist.bytecode.AnnotationsAttribute.visibleTag); - return com.fr.third.javassist.CtClassType.hasAnnotationType(clz, getDeclaringClass().getClassPool(), - ainfo, ainfo2); - } - - /** - * Returns the annotation if the class has the specified annotation class. - * For example, if an annotation @Author is associated - * with this field, an Author object is returned. - * The member values can be obtained by calling methods on - * the Author object. - * - * @param clz the annotation class. - * @return the annotation if found, otherwise null. - * @since 3.11 - */ - public Object getAnnotation(Class clz) throws ClassNotFoundException { - com.fr.third.javassist.bytecode.FieldInfo fi = getFieldInfo2(); - com.fr.third.javassist.bytecode.AnnotationsAttribute ainfo = (com.fr.third.javassist.bytecode.AnnotationsAttribute) - fi.getAttribute(com.fr.third.javassist.bytecode.AnnotationsAttribute.invisibleTag); - com.fr.third.javassist.bytecode.AnnotationsAttribute ainfo2 = (com.fr.third.javassist.bytecode.AnnotationsAttribute) - fi.getAttribute(com.fr.third.javassist.bytecode.AnnotationsAttribute.visibleTag); - return com.fr.third.javassist.CtClassType.getAnnotationType(clz, getDeclaringClass().getClassPool(), - ainfo, ainfo2); - } - - /** - * Returns the annotations associated with this field. - * - * @return an array of annotation-type objects. - * @see #getAvailableAnnotations() - * @since 3.1 - */ - public Object[] getAnnotations() throws ClassNotFoundException { - return getAnnotations(false); - } - - /** - * Returns the annotations associated with this field. - * If any annotations are not on the classpath, they are not included - * in the returned array. - * - * @return an array of annotation-type objects. - * @see #getAnnotations() - * @since 3.3 - */ - public Object[] getAvailableAnnotations(){ - try { - return getAnnotations(true); - } - catch (ClassNotFoundException e) { - throw new RuntimeException("Unexpected exception", e); - } - } - - private Object[] getAnnotations(boolean ignoreNotFound) throws ClassNotFoundException { - com.fr.third.javassist.bytecode.FieldInfo fi = getFieldInfo2(); - com.fr.third.javassist.bytecode.AnnotationsAttribute ainfo = (com.fr.third.javassist.bytecode.AnnotationsAttribute) - fi.getAttribute(com.fr.third.javassist.bytecode.AnnotationsAttribute.invisibleTag); - com.fr.third.javassist.bytecode.AnnotationsAttribute ainfo2 = (com.fr.third.javassist.bytecode.AnnotationsAttribute) - fi.getAttribute(com.fr.third.javassist.bytecode.AnnotationsAttribute.visibleTag); - return com.fr.third.javassist.CtClassType.toAnnotationType(ignoreNotFound, getDeclaringClass().getClassPool(), - ainfo, ainfo2); - } - - /** - * Returns the character string representing the type of the field. - * The field signature is represented by a character string - * called a field descriptor, which is defined in the JVM specification. - * If two fields have the same type, - * getSignature() returns the same string. - * - *

Note that the returned string is not the type signature - * contained in the SignatureAttirbute. It is - * a descriptor. - * - * @see com.fr.third.javassist.bytecode.Descriptor - * @see #getGenericSignature() - */ - public String getSignature() { - return fieldInfo.getDescriptor(); - } - - /** - * Returns the generic signature of the field. - * It represents a type including type variables. - * - * @see com.fr.third.javassist.bytecode.SignatureAttribute#toFieldSignature(String) - * @since 3.17 - */ - public String getGenericSignature() { - com.fr.third.javassist.bytecode.SignatureAttribute sa - = (com.fr.third.javassist.bytecode.SignatureAttribute)fieldInfo.getAttribute(com.fr.third.javassist.bytecode.SignatureAttribute.tag); - return sa == null ? null : sa.getSignature(); - } - - /** - * Set the generic signature of the field. - * It represents a type including type variables. - * See {@link com.fr.third.javassist.CtClass#setGenericSignature(String)} - * for a code sample. - * - * @param sig a new generic signature. - * @see com.fr.third.javassist.bytecode.SignatureAttribute.ObjectType#encode() - * @since 3.17 - */ - public void setGenericSignature(String sig) { - declaringClass.checkModify(); - fieldInfo.addAttribute(new com.fr.third.javassist.bytecode.SignatureAttribute(fieldInfo.getConstPool(), sig)); - } - - /** - * Returns the type of the field. - */ - public com.fr.third.javassist.CtClass getType() throws NotFoundException { - return com.fr.third.javassist.bytecode.Descriptor.toCtClass(fieldInfo.getDescriptor(), - declaringClass.getClassPool()); - } - - /** - * Sets the type of the field. - */ - public void setType(com.fr.third.javassist.CtClass clazz) { - declaringClass.checkModify(); - fieldInfo.setDescriptor(com.fr.third.javassist.bytecode.Descriptor.of(clazz)); - } - - /** - * Returns the value of this field if it is a constant field. - * This method works only if the field type is a primitive type - * or String type. Otherwise, it returns null. - * A constant field is static and final. - * - * @return a Integer, Long, Float, - * Double, Boolean, - * or String object - * representing the constant value. - * null if it is not a constant field - * or if the field type is not a primitive type - * or String. - */ - public Object getConstantValue() { - // When this method is modified, - // see also getConstantFieldValue() in TypeChecker. - - int index = fieldInfo.getConstantValue(); - if (index == 0) - return null; - - com.fr.third.javassist.bytecode.ConstPool cp = fieldInfo.getConstPool(); - switch (cp.getTag(index)) { - case com.fr.third.javassist.bytecode.ConstPool.CONST_Long : - return new Long(cp.getLongInfo(index)); - case com.fr.third.javassist.bytecode.ConstPool.CONST_Float : - return new Float(cp.getFloatInfo(index)); - case com.fr.third.javassist.bytecode.ConstPool.CONST_Double : - return new Double(cp.getDoubleInfo(index)); - case com.fr.third.javassist.bytecode.ConstPool.CONST_Integer : - int value = cp.getIntegerInfo(index); - // "Z" means boolean type. - if ("Z".equals(fieldInfo.getDescriptor())) - return new Boolean(value != 0); - else - return new Integer(value); - case com.fr.third.javassist.bytecode.ConstPool.CONST_String : - return cp.getStringInfo(index); - default : - throw new RuntimeException("bad tag: " + cp.getTag(index) - + " at " + index); - } - } - - /** - * Obtains an attribute with the given name. - * If that attribute is not found in the class file, this - * method returns null. - * - *

Note that an attribute is a data block specified by - * the class file format. - * See {@link com.fr.third.javassist.bytecode.AttributeInfo}. - * - * @param name attribute name - */ - public byte[] getAttribute(String name) { - com.fr.third.javassist.bytecode.AttributeInfo ai = fieldInfo.getAttribute(name); - if (ai == null) - return null; - else - return ai.get(); - } - - /** - * Adds an attribute. The attribute is saved in the class file. - * - *

Note that an attribute is a data block specified by - * the class file format. - * See {@link com.fr.third.javassist.bytecode.AttributeInfo}. - * - * @param name attribute name - * @param data attribute value - */ - public void setAttribute(String name, byte[] data) { - declaringClass.checkModify(); - fieldInfo.addAttribute(new com.fr.third.javassist.bytecode.AttributeInfo(fieldInfo.getConstPool(), - name, data)); - } - - // inner classes - - /** - * Instances of this class specify how to initialize a field. - * Initializer is passed to - * CtClass.addField() with a CtField. - * - *

This class cannot be instantiated with the new operator. - * Factory methods such as byParameter() and - * byNew - * must be used for the instantiation. They create a new instance with - * the given parameters and return it. - * - * @see com.fr.third.javassist.CtClass#addField(CtField,CtField.Initializer) - */ - public static abstract class Initializer { - /** - * Makes an initializer that assigns a constant integer value. - * The field must be integer, short, char, or byte type. - */ - public static Initializer constant(int i) { - return new IntInitializer(i); - } - - /** - * Makes an initializer that assigns a constant boolean value. - * The field must be boolean type. - */ - public static Initializer constant(boolean b) { - return new IntInitializer(b ? 1 : 0); - } - - /** - * Makes an initializer that assigns a constant long value. - * The field must be long type. - */ - public static Initializer constant(long l) { - return new LongInitializer(l); - } - - /** - * Makes an initializer that assigns a constant float value. - * The field must be float type. - */ - public static Initializer constant(float l) { - return new FloatInitializer(l); - } - - /** - * Makes an initializer that assigns a constant double value. - * The field must be double type. - */ - public static Initializer constant(double d) { - return new DoubleInitializer(d); - } - - /** - * Makes an initializer that assigns a constant string value. - * The field must be java.lang.String type. - */ - public static Initializer constant(String s) { - return new StringInitializer(s); - } - - /** - * Makes an initializer using a constructor parameter. - * - *

The initial value is the - * N-th parameter given to the constructor of the object including - * the field. If the constructor takes less than N parameters, - * the field is not initialized. - * If the field is static, it is never initialized. - * - * @param nth the n-th (>= 0) parameter is used as - * the initial value. - * If nth is 0, then the first parameter is - * used. - */ - public static Initializer byParameter(int nth) { - ParamInitializer i = new ParamInitializer(); - i.nthParam = nth; - return i; - } - - /** - * Makes an initializer creating a new object. - * - *

This initializer creates a new object and uses it as the initial - * value of the field. The constructor of the created object receives - * the parameter: - * - *

    Object obj - the object including the field.
    - *
- * - *

If the initialized field is static, then the constructor does - * not receive any parameters. - * - * @param objectType the class instantiated for the initial value. - */ - public static Initializer byNew(com.fr.third.javassist.CtClass objectType) { - NewInitializer i = new NewInitializer(); - i.objectType = objectType; - i.stringParams = null; - i.withConstructorParams = false; - return i; - } - - /** - * Makes an initializer creating a new object. - * - *

This initializer creates a new object and uses it as the initial - * value of the field. The constructor of the created object receives - * the parameters: - * - *

    Object obj - the object including the field.
    - * String[] strs - the character strings specified - * by stringParams
    - *
- * - *

If the initialized field is static, then the constructor - * receives only strs. - * - * @param objectType the class instantiated for the initial value. - * @param stringParams the array of strings passed to the - * constructor. - */ - public static Initializer byNew(com.fr.third.javassist.CtClass objectType, - String[] stringParams) { - NewInitializer i = new NewInitializer(); - i.objectType = objectType; - i.stringParams = stringParams; - i.withConstructorParams = false; - return i; - } - - /** - * Makes an initializer creating a new object. - * - *

This initializer creates a new object and uses it as the initial - * value of the field. The constructor of the created object receives - * the parameters: - * - *

    Object obj - the object including the field.
    - * Object[] args - the parameters passed to the - * constructor of the object including the - * filed. - *
- * - *

If the initialized field is static, then the constructor does - * not receive any parameters. - * - * @param objectType the class instantiated for the initial value. - * - * @see CtField.Initializer#byNewArray(com.fr.third.javassist.CtClass,int) - * @see CtField.Initializer#byNewArray(com.fr.third.javassist.CtClass,int[]) - */ - public static Initializer byNewWithParams(com.fr.third.javassist.CtClass objectType) { - NewInitializer i = new NewInitializer(); - i.objectType = objectType; - i.stringParams = null; - i.withConstructorParams = true; - return i; - } - - /** - * Makes an initializer creating a new object. - * - *

This initializer creates a new object and uses it as the initial - * value of the field. The constructor of the created object receives - * the parameters: - * - *

    Object obj - the object including the field.
    - * String[] strs - the character strings specified - * by stringParams
    - * Object[] args - the parameters passed to the - * constructor of the object including the - * filed. - *
- * - *

If the initialized field is static, then the constructor receives - * only strs. - * - * @param objectType the class instantiated for the initial value. - * @param stringParams the array of strings passed to the - * constructor. - */ - public static Initializer byNewWithParams(com.fr.third.javassist.CtClass objectType, - String[] stringParams) { - NewInitializer i = new NewInitializer(); - i.objectType = objectType; - i.stringParams = stringParams; - i.withConstructorParams = true; - return i; - } - - /** - * Makes an initializer calling a static method. - * - *

This initializer calls a static method and uses the returned - * value as the initial value of the field. - * The called method receives the parameters: - * - *

    Object obj - the object including the field.
    - *
- * - *

If the initialized field is static, then the method does - * not receive any parameters. - * - *

The type of the returned value must be the same as the field - * type. - * - * @param methodClass the class that the static method is - * declared in. - * @param methodName the name of the satic method. - */ - public static Initializer byCall(com.fr.third.javassist.CtClass methodClass, - String methodName) { - MethodInitializer i = new MethodInitializer(); - i.objectType = methodClass; - i.methodName = methodName; - i.stringParams = null; - i.withConstructorParams = false; - return i; - } - - /** - * Makes an initializer calling a static method. - * - *

This initializer calls a static method and uses the returned - * value as the initial value of the field. The called method - * receives the parameters: - * - *

    Object obj - the object including the field.
    - * String[] strs - the character strings specified - * by stringParams
    - *
- * - *

If the initialized field is static, then the method - * receive only strs. - * - *

The type of the returned value must be the same as the field - * type. - * - * @param methodClass the class that the static method is - * declared in. - * @param methodName the name of the satic method. - * @param stringParams the array of strings passed to the - * static method. - */ - public static Initializer byCall(com.fr.third.javassist.CtClass methodClass, - String methodName, - String[] stringParams) { - MethodInitializer i = new MethodInitializer(); - i.objectType = methodClass; - i.methodName = methodName; - i.stringParams = stringParams; - i.withConstructorParams = false; - return i; - } - - /** - * Makes an initializer calling a static method. - * - *

This initializer calls a static method and uses the returned - * value as the initial value of the field. The called method - * receives the parameters: - * - *

    Object obj - the object including the field.
    - * Object[] args - the parameters passed to the - * constructor of the object including the - * filed. - *
- * - *

If the initialized field is static, then the method does - * not receive any parameters. - * - *

The type of the returned value must be the same as the field - * type. - * - * @param methodClass the class that the static method is - * declared in. - * @param methodName the name of the satic method. - */ - public static Initializer byCallWithParams(com.fr.third.javassist.CtClass methodClass, - String methodName) { - MethodInitializer i = new MethodInitializer(); - i.objectType = methodClass; - i.methodName = methodName; - i.stringParams = null; - i.withConstructorParams = true; - return i; - } - - /** - * Makes an initializer calling a static method. - * - *

This initializer calls a static method and uses the returned - * value as the initial value of the field. The called method - * receives the parameters: - * - *

    Object obj - the object including the field.
    - * String[] strs - the character strings specified - * by stringParams
    - * Object[] args - the parameters passed to the - * constructor of the object including the - * filed. - *
- * - *

If the initialized field is static, then the method - * receive only strs. - * - *

The type of the returned value must be the same as the field - * type. - * - * @param methodClass the class that the static method is - * declared in. - * @param methodName the name of the satic method. - * @param stringParams the array of strings passed to the - * static method. - */ - public static Initializer byCallWithParams(com.fr.third.javassist.CtClass methodClass, - String methodName, String[] stringParams) { - MethodInitializer i = new MethodInitializer(); - i.objectType = methodClass; - i.methodName = methodName; - i.stringParams = stringParams; - i.withConstructorParams = true; - return i; - } - - /** - * Makes an initializer creating a new array. - * - * @param type the type of the array. - * @param size the size of the array. - * @throws NotFoundException if the type of the array components - * is not found. - */ - public static Initializer byNewArray(com.fr.third.javassist.CtClass type, int size) - throws NotFoundException - { - return new ArrayInitializer(type.getComponentType(), size); - } - - /** - * Makes an initializer creating a new multi-dimensional array. - * - * @param type the type of the array. - * @param sizes an int array of the size in every - * dimension. - * The first element is the size in the first - * dimension. The second is in the second, etc. - */ - public static Initializer byNewArray(com.fr.third.javassist.CtClass type, int[] sizes) { - return new MultiArrayInitializer(type, sizes); - } - - /** - * Makes an initializer. - * - * @param source initializer expression. - */ - public static Initializer byExpr(String source) { - return new CodeInitializer(source); - } - - static Initializer byExpr(ASTree source) { - return new PtreeInitializer(source); - } - - // Check whether this initializer is valid for the field type. - // If it is invaild, this method throws an exception. - void check(String desc) throws com.fr.third.javassist.CannotCompileException {} - - // produce codes for initialization - abstract int compile(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - com.fr.third.javassist.CtClass[] parameters, Javac drv) - throws com.fr.third.javassist.CannotCompileException; - - // produce codes for initialization - abstract int compileIfStatic(com.fr.third.javassist.CtClass type, String name, - com.fr.third.javassist.bytecode.Bytecode code, Javac drv) throws com.fr.third.javassist.CannotCompileException; - - // returns the index of CONSTANT_Integer_info etc - // if the value is constant. Otherwise, 0. - int getConstantValue(com.fr.third.javassist.bytecode.ConstPool cp, com.fr.third.javassist.CtClass type) { return 0; } - } - - static abstract class CodeInitializer0 extends Initializer { - abstract void compileExpr(Javac drv) throws CompileError; - - int compile(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - com.fr.third.javassist.CtClass[] parameters, Javac drv) - throws com.fr.third.javassist.CannotCompileException - { - try { - code.addAload(0); - compileExpr(drv); - code.addPutfield(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return code.getMaxStack(); - } - catch (CompileError e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - int compileIfStatic(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - Javac drv) throws com.fr.third.javassist.CannotCompileException - { - try { - compileExpr(drv); - code.addPutstatic(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return code.getMaxStack(); - } - catch (CompileError e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - int getConstantValue2(com.fr.third.javassist.bytecode.ConstPool cp, com.fr.third.javassist.CtClass type, ASTree tree) { - if (type.isPrimitive()) { - if (tree instanceof IntConst) { - long value = ((IntConst)tree).get(); - if (type == com.fr.third.javassist.CtClass.doubleType) - return cp.addDoubleInfo((double)value); - else if (type == com.fr.third.javassist.CtClass.floatType) - return cp.addFloatInfo((float)value); - else if (type == com.fr.third.javassist.CtClass.longType) - return cp.addLongInfo(value); - else if (type != com.fr.third.javassist.CtClass.voidType) - return cp.addIntegerInfo((int)value); - } - else if (tree instanceof DoubleConst) { - double value = ((DoubleConst)tree).get(); - if (type == com.fr.third.javassist.CtClass.floatType) - return cp.addFloatInfo((float)value); - else if (type == com.fr.third.javassist.CtClass.doubleType) - return cp.addDoubleInfo(value); - } - } - else if (tree instanceof StringL - && type.getName().equals(javaLangString)) - return cp.addStringInfo(((StringL)tree).get()); - - return 0; - } - } - - static class CodeInitializer extends CodeInitializer0 { - private String expression; - - CodeInitializer(String expr) { expression = expr; } - - void compileExpr(Javac drv) throws CompileError { - drv.compileExpr(expression); - } - - int getConstantValue(com.fr.third.javassist.bytecode.ConstPool cp, com.fr.third.javassist.CtClass type) { - try { - ASTree t = Javac.parseExpr(expression, new SymbolTable()); - return getConstantValue2(cp, type, t); - } - catch (CompileError e) { - return 0; - } - } - } - - static class PtreeInitializer extends CodeInitializer0 { - private ASTree expression; - - PtreeInitializer(ASTree expr) { expression = expr; } - - void compileExpr(Javac drv) throws CompileError { - drv.compileExpr(expression); - } - - int getConstantValue(com.fr.third.javassist.bytecode.ConstPool cp, com.fr.third.javassist.CtClass type) { - return getConstantValue2(cp, type, expression); - } - } - - /** - * A field initialized with a parameter passed to the constructor - * of the class containing that field. - */ - static class ParamInitializer extends Initializer { - int nthParam; - - ParamInitializer() {} - - int compile(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - com.fr.third.javassist.CtClass[] parameters, Javac drv) - throws com.fr.third.javassist.CannotCompileException - { - if (parameters != null && nthParam < parameters.length) { - code.addAload(0); - int nth = nthParamToLocal(nthParam, parameters, false); - int s = code.addLoad(nth, type) + 1; - code.addPutfield(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return s; // stack size - } - else - return 0; // do not initialize - } - - /** - * Computes the index of the local variable that the n-th parameter - * is assigned to. - * - * @param nth n-th parameter - * @param params list of parameter types - * @param isStatic true if the method is static. - */ - static int nthParamToLocal(int nth, com.fr.third.javassist.CtClass[] params, - boolean isStatic) { - com.fr.third.javassist.CtClass longType = com.fr.third.javassist.CtClass.longType; - com.fr.third.javassist.CtClass doubleType = com.fr.third.javassist.CtClass.doubleType; - int k; - if (isStatic) - k = 0; - else - k = 1; // 0 is THIS. - - for (int i = 0; i < nth; ++i) { - com.fr.third.javassist.CtClass type = params[i]; - if (type == longType || type == doubleType) - k += 2; - else - ++k; - } - - return k; - } - - int compileIfStatic(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - Javac drv) throws com.fr.third.javassist.CannotCompileException - { - return 0; - } - } - - /** - * A field initialized with an object created by the new operator. - */ - static class NewInitializer extends Initializer { - com.fr.third.javassist.CtClass objectType; - String[] stringParams; - boolean withConstructorParams; - - NewInitializer() {} - - /** - * Produces codes in which a new object is created and assigned to - * the field as the initial value. - */ - int compile(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - com.fr.third.javassist.CtClass[] parameters, Javac drv) - throws com.fr.third.javassist.CannotCompileException - { - int stacksize; - - code.addAload(0); - code.addNew(objectType); - code.add(com.fr.third.javassist.bytecode.Bytecode.DUP); - code.addAload(0); - - if (stringParams == null) - stacksize = 4; - else - stacksize = compileStringParameter(code) + 4; - - if (withConstructorParams) - stacksize += CtNewWrappedMethod.compileParameterList(code, - parameters, 1); - - code.addInvokespecial(objectType, "", getDescriptor()); - code.addPutfield(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return stacksize; - } - - private String getDescriptor() { - final String desc3 - = "(Ljava/lang/Object;[Ljava/lang/String;[Ljava/lang/Object;)V"; - - if (stringParams == null) - if (withConstructorParams) - return "(Ljava/lang/Object;[Ljava/lang/Object;)V"; - else - return "(Ljava/lang/Object;)V"; - else - if (withConstructorParams) - return desc3; - else - return "(Ljava/lang/Object;[Ljava/lang/String;)V"; - } - - /** - * Produces codes for a static field. - */ - int compileIfStatic(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - Javac drv) throws com.fr.third.javassist.CannotCompileException - { - String desc; - - code.addNew(objectType); - code.add(com.fr.third.javassist.bytecode.Bytecode.DUP); - - int stacksize = 2; - if (stringParams == null) - desc = "()V"; - else { - desc = "([Ljava/lang/String;)V"; - stacksize += compileStringParameter(code); - } - - code.addInvokespecial(objectType, "", desc); - code.addPutstatic(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return stacksize; - } - - protected final int compileStringParameter(com.fr.third.javassist.bytecode.Bytecode code) - throws com.fr.third.javassist.CannotCompileException - { - int nparam = stringParams.length; - code.addIconst(nparam); - code.addAnewarray(javaLangString); - for (int j = 0; j < nparam; ++j) { - code.add(com.fr.third.javassist.bytecode.Bytecode.DUP); // dup - code.addIconst(j); // iconst_ - code.addLdc(stringParams[j]); // ldc ... - code.add(com.fr.third.javassist.bytecode.Bytecode.AASTORE); // aastore - } - - return 4; - } - - } - - /** - * A field initialized with the result of a static method call. - */ - static class MethodInitializer extends NewInitializer { - String methodName; - // the method class is specified by objectType. - - MethodInitializer() {} - - /** - * Produces codes in which a new object is created and assigned to - * the field as the initial value. - */ - int compile(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - com.fr.third.javassist.CtClass[] parameters, Javac drv) - throws com.fr.third.javassist.CannotCompileException - { - int stacksize; - - code.addAload(0); - code.addAload(0); - - if (stringParams == null) - stacksize = 2; - else - stacksize = compileStringParameter(code) + 2; - - if (withConstructorParams) - stacksize += CtNewWrappedMethod.compileParameterList(code, - parameters, 1); - - String typeDesc = com.fr.third.javassist.bytecode.Descriptor.of(type); - String mDesc = getDescriptor() + typeDesc; - code.addInvokestatic(objectType, methodName, mDesc); - code.addPutfield(com.fr.third.javassist.bytecode.Bytecode.THIS, name, typeDesc); - return stacksize; - } - - private String getDescriptor() { - final String desc3 - = "(Ljava/lang/Object;[Ljava/lang/String;[Ljava/lang/Object;)"; - - if (stringParams == null) - if (withConstructorParams) - return "(Ljava/lang/Object;[Ljava/lang/Object;)"; - else - return "(Ljava/lang/Object;)"; - else - if (withConstructorParams) - return desc3; - else - return "(Ljava/lang/Object;[Ljava/lang/String;)"; - } - - /** - * Produces codes for a static field. - */ - int compileIfStatic(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - Javac drv) throws com.fr.third.javassist.CannotCompileException - { - String desc; - - int stacksize = 1; - if (stringParams == null) - desc = "()"; - else { - desc = "([Ljava/lang/String;)"; - stacksize += compileStringParameter(code); - } - - String typeDesc = com.fr.third.javassist.bytecode.Descriptor.of(type); - code.addInvokestatic(objectType, methodName, desc + typeDesc); - code.addPutstatic(com.fr.third.javassist.bytecode.Bytecode.THIS, name, typeDesc); - return stacksize; - } - } - - static class IntInitializer extends Initializer { - int value; - - IntInitializer(int v) { value = v; } - - void check(String desc) throws com.fr.third.javassist.CannotCompileException { - char c = desc.charAt(0); - if (c != 'I' && c != 'S' && c != 'B' && c != 'C' && c != 'Z') - throw new com.fr.third.javassist.CannotCompileException("type mismatch"); - } - - int compile(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - com.fr.third.javassist.CtClass[] parameters, Javac drv) - throws com.fr.third.javassist.CannotCompileException - { - code.addAload(0); - code.addIconst(value); - code.addPutfield(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return 2; // stack size - } - - int compileIfStatic(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - Javac drv) throws com.fr.third.javassist.CannotCompileException - { - code.addIconst(value); - code.addPutstatic(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return 1; // stack size - } - - int getConstantValue(com.fr.third.javassist.bytecode.ConstPool cp, com.fr.third.javassist.CtClass type) { - return cp.addIntegerInfo(value); - } - } - - static class LongInitializer extends Initializer { - long value; - - LongInitializer(long v) { value = v; } - - void check(String desc) throws com.fr.third.javassist.CannotCompileException { - if (!desc.equals("J")) - throw new com.fr.third.javassist.CannotCompileException("type mismatch"); - } - - int compile(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - com.fr.third.javassist.CtClass[] parameters, Javac drv) - throws com.fr.third.javassist.CannotCompileException - { - code.addAload(0); - code.addLdc2w(value); - code.addPutfield(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return 3; // stack size - } - - int compileIfStatic(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - Javac drv) throws com.fr.third.javassist.CannotCompileException - { - code.addLdc2w(value); - code.addPutstatic(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return 2; // stack size - } - - int getConstantValue(com.fr.third.javassist.bytecode.ConstPool cp, com.fr.third.javassist.CtClass type) { - if (type == com.fr.third.javassist.CtClass.longType) - return cp.addLongInfo(value); - else - return 0; - } - } - - static class FloatInitializer extends Initializer { - float value; - - FloatInitializer(float v) { value = v; } - - void check(String desc) throws com.fr.third.javassist.CannotCompileException { - if (!desc.equals("F")) - throw new com.fr.third.javassist.CannotCompileException("type mismatch"); - } - - int compile(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - com.fr.third.javassist.CtClass[] parameters, Javac drv) - throws com.fr.third.javassist.CannotCompileException - { - code.addAload(0); - code.addFconst(value); - code.addPutfield(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return 3; // stack size - } - - int compileIfStatic(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - Javac drv) throws com.fr.third.javassist.CannotCompileException - { - code.addFconst(value); - code.addPutstatic(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return 2; // stack size - } - - int getConstantValue(com.fr.third.javassist.bytecode.ConstPool cp, com.fr.third.javassist.CtClass type) { - if (type == com.fr.third.javassist.CtClass.floatType) - return cp.addFloatInfo(value); - else - return 0; - } - } - - static class DoubleInitializer extends Initializer { - double value; - - DoubleInitializer(double v) { value = v; } - - void check(String desc) throws com.fr.third.javassist.CannotCompileException { - if (!desc.equals("D")) - throw new com.fr.third.javassist.CannotCompileException("type mismatch"); - } - - int compile(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - com.fr.third.javassist.CtClass[] parameters, Javac drv) - throws com.fr.third.javassist.CannotCompileException - { - code.addAload(0); - code.addLdc2w(value); - code.addPutfield(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return 3; // stack size - } - - int compileIfStatic(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - Javac drv) throws com.fr.third.javassist.CannotCompileException - { - code.addLdc2w(value); - code.addPutstatic(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return 2; // stack size - } - - int getConstantValue(com.fr.third.javassist.bytecode.ConstPool cp, com.fr.third.javassist.CtClass type) { - if (type == com.fr.third.javassist.CtClass.doubleType) - return cp.addDoubleInfo(value); - else - return 0; - } - } - - static class StringInitializer extends Initializer { - String value; - - StringInitializer(String v) { value = v; } - - int compile(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - com.fr.third.javassist.CtClass[] parameters, Javac drv) - throws com.fr.third.javassist.CannotCompileException - { - code.addAload(0); - code.addLdc(value); - code.addPutfield(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return 2; // stack size - } - - int compileIfStatic(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - Javac drv) throws com.fr.third.javassist.CannotCompileException - { - code.addLdc(value); - code.addPutstatic(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return 1; // stack size - } - - int getConstantValue(ConstPool cp, com.fr.third.javassist.CtClass type) { - if (type.getName().equals(javaLangString)) - return cp.addStringInfo(value); - else - return 0; - } - } - - static class ArrayInitializer extends Initializer { - com.fr.third.javassist.CtClass type; - int size; - - ArrayInitializer(com.fr.third.javassist.CtClass t, int s) { type = t; size = s; } - - private void addNewarray(com.fr.third.javassist.bytecode.Bytecode code) { - if (type.isPrimitive()) - code.addNewarray(((CtPrimitiveType)type).getArrayType(), - size); - else - code.addAnewarray(type, size); - } - - int compile(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - com.fr.third.javassist.CtClass[] parameters, Javac drv) - throws com.fr.third.javassist.CannotCompileException - { - code.addAload(0); - addNewarray(code); - code.addPutfield(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return 2; // stack size - } - - int compileIfStatic(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - Javac drv) throws com.fr.third.javassist.CannotCompileException - { - addNewarray(code); - code.addPutstatic(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return 1; // stack size - } - } - - static class MultiArrayInitializer extends Initializer { - com.fr.third.javassist.CtClass type; - int[] dim; - - MultiArrayInitializer(com.fr.third.javassist.CtClass t, int[] d) { type = t; dim = d; } - - void check(String desc) throws com.fr.third.javassist.CannotCompileException { - if (desc.charAt(0) != '[') - throw new com.fr.third.javassist.CannotCompileException("type mismatch"); - } - - int compile(com.fr.third.javassist.CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - com.fr.third.javassist.CtClass[] parameters, Javac drv) - throws com.fr.third.javassist.CannotCompileException - { - code.addAload(0); - int s = code.addMultiNewarray(type, dim); - code.addPutfield(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return s + 1; // stack size - } - - int compileIfStatic(CtClass type, String name, com.fr.third.javassist.bytecode.Bytecode code, - Javac drv) throws CannotCompileException - { - int s = code.addMultiNewarray(type, dim); - code.addPutstatic(com.fr.third.javassist.bytecode.Bytecode.THIS, name, com.fr.third.javassist.bytecode.Descriptor.of(type)); - return s; // stack size - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CtMember.java b/fine-javassist/src/main/java/com/fr/third/javassist/CtMember.java deleted file mode 100644 index 094510c57..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CtMember.java +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import com.fr.third.javassist.bytecode.AttributeInfo; -import com.fr.third.javassist.bytecode.SignatureAttribute; - -/** - * An instance of CtMember represents a field, a constructor, - * or a method. - */ -public abstract class CtMember { - CtMember next; // for internal use - protected com.fr.third.javassist.CtClass declaringClass; - - /* Make a circular link of CtMembers declared in the - * same class so that they are garbage-collected together - * at the same time. - */ - static class Cache extends CtMember { - protected void extendToString(StringBuffer buffer) {} - public boolean hasAnnotation(Class clz) { return false; } - public Object getAnnotation(Class clz) - throws ClassNotFoundException { return null; } - public Object[] getAnnotations() - throws ClassNotFoundException { return null; } - public byte[] getAttribute(String name) { return null; } - public Object[] getAvailableAnnotations() { return null; } - public int getModifiers() { return 0; } - public String getName() { return null; } - public String getSignature() { return null; } - public void setAttribute(String name, byte[] data) {} - public void setModifiers(int mod) {} - public String getGenericSignature() { return null; } - public void setGenericSignature(String sig) {} - - private CtMember methodTail; - private CtMember consTail; // constructor tail - private CtMember fieldTail; - - Cache(com.fr.third.javassist.CtClassType decl) { - super(decl); - methodTail = this; - consTail = this; - fieldTail = this; - fieldTail.next = this; - } - - CtMember methodHead() { return this; } - CtMember lastMethod() { return methodTail; } - CtMember consHead() { return methodTail; } // may include a static initializer - CtMember lastCons() { return consTail; } - CtMember fieldHead() { return consTail; } - CtMember lastField() { return fieldTail; } - - void addMethod(CtMember method) { - method.next = methodTail.next; - methodTail.next = method; - if (methodTail == consTail) { - consTail = method; - if (methodTail == fieldTail) - fieldTail = method; - } - - methodTail = method; - } - - /* Both constructors and a class initializer. - */ - void addConstructor(CtMember cons) { - cons.next = consTail.next; - consTail.next = cons; - if (consTail == fieldTail) - fieldTail = cons; - - consTail = cons; - } - - void addField(CtMember field) { - field.next = this; // or fieldTail.next - fieldTail.next = field; - fieldTail = field; - } - - static int count(CtMember head, CtMember tail) { - int n = 0; - while (head != tail) { - n++; - head = head.next; - } - - return n; - } - - void remove(CtMember mem) { - CtMember m = this; - CtMember node; - while ((node = m.next) != this) { - if (node == mem) { - m.next = node.next; - if (node == methodTail) - methodTail = m; - - if (node == consTail) - consTail = m; - - if (node == fieldTail) - fieldTail = m; - - break; - } - else - m = m.next; - } - } - } - - protected CtMember(com.fr.third.javassist.CtClass clazz) { - declaringClass = clazz; - next = null; - } - - final CtMember next() { return next; } - - /** - * This method is invoked when setName() or replaceClassName() - * in CtClass is called. - * - * @see CtMethod#nameReplaced() - */ - void nameReplaced() {} - - public String toString() { - StringBuffer buffer = new StringBuffer(getClass().getName()); - buffer.append("@"); - buffer.append(Integer.toHexString(hashCode())); - buffer.append("["); - buffer.append(Modifier.toString(getModifiers())); - extendToString(buffer); - buffer.append("]"); - return buffer.toString(); - } - - /** - * Invoked by {@link #toString()} to add to the buffer and provide the - * complete value. Subclasses should invoke this method, adding a - * space before each token. The modifiers for the member are - * provided first; subclasses should provide additional data such - * as return type, field or method name, etc. - */ - protected abstract void extendToString(StringBuffer buffer); - - /** - * Returns the class that declares this member. - */ - public com.fr.third.javassist.CtClass getDeclaringClass() { return declaringClass; } - - /** - * Returns true if this member is accessible from the given class. - */ - public boolean visibleFrom(com.fr.third.javassist.CtClass clazz) { - int mod = getModifiers(); - if (Modifier.isPublic(mod)) - return true; - else if (Modifier.isPrivate(mod)) - return clazz == declaringClass; - else { // package or protected - String declName = declaringClass.getPackageName(); - String fromName = clazz.getPackageName(); - boolean visible; - if (declName == null) - visible = fromName == null; - else - visible = declName.equals(fromName); - - if (!visible && Modifier.isProtected(mod)) - return clazz.subclassOf(declaringClass); - - return visible; - } - } - - /** - * Obtains the modifiers of the member. - * - * @return modifiers encoded with - * javassist.Modifier. - * @see Modifier - */ - public abstract int getModifiers(); - - /** - * Sets the encoded modifiers of the member. - * - * @see Modifier - */ - public abstract void setModifiers(int mod); - - /** - * Returns true if the class has the specified annotation class. - * - * @param clz the annotation class. - * @return true if the annotation is found, otherwise false. - * @since 3.11 - */ - public abstract boolean hasAnnotation(Class clz); - - /** - * Returns the annotation if the class has the specified annotation class. - * For example, if an annotation @Author is associated - * with this member, an Author object is returned. - * The member values can be obtained by calling methods on - * the Author object. - * - * @param clz the annotation class. - * @return the annotation if found, otherwise null. - * @since 3.11 - */ - public abstract Object getAnnotation(Class clz) throws ClassNotFoundException; - - /** - * Returns the annotations associated with this member. - * For example, if an annotation @Author is associated - * with this member, the returned array contains an Author - * object. The member values can be obtained by calling methods on - * the Author object. - * - * @return an array of annotation-type objects. - * @see com.fr.third.javassist.CtClass#getAnnotations() - */ - public abstract Object[] getAnnotations() throws ClassNotFoundException; - - /** - * Returns the annotations associated with this member. - * This method is equivalent to getAnnotations() - * except that, if any annotations are not on the classpath, - * they are not included in the returned array. - * - * @return an array of annotation-type objects. - * @see #getAnnotations() - * @see com.fr.third.javassist.CtClass#getAvailableAnnotations() - * @since 3.3 - */ - public abstract Object[] getAvailableAnnotations(); - - /** - * Obtains the name of the member. - * - *

As for constructor names, see getName() - * in CtConstructor. - * - * @see CtConstructor#getName() - */ - public abstract String getName(); - - /** - * Returns the character string representing the signature of the member. - * If two members have the same signature (parameter types etc.), - * getSignature() returns the same string. - */ - public abstract String getSignature(); - - /** - * Returns the generic signature of the member. - * - * @see SignatureAttribute#toFieldSignature(String) - * @see SignatureAttribute#toMethodSignature(String) - * @see com.fr.third.javassist.CtClass#getGenericSignature() - * @since 3.17 - */ - public abstract String getGenericSignature(); - - /** - * Sets the generic signature of the member. - * - * @param sig a new generic signature. - * @see SignatureAttribute.ObjectType#encode() - * @see SignatureAttribute.MethodSignature#encode() - * @see CtClass#setGenericSignature(String) - * @since 3.17 - */ - public abstract void setGenericSignature(String sig); - - /** - * Obtains a user-defined attribute with the given name. - * If that attribute is not found in the class file, this - * method returns null. - * - *

Note that an attribute is a data block specified by - * the class file format. - * See {@link AttributeInfo}. - * - * @param name attribute name - */ - public abstract byte[] getAttribute(String name); - - /** - * Adds a user-defined attribute. The attribute is saved in the class file. - * - *

Note that an attribute is a data block specified by - * the class file format. - * See {@link AttributeInfo}. - * - * @param name attribute name - * @param data attribute value - */ - public abstract void setAttribute(String name, byte[] data); -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CtMethod.java b/fine-javassist/src/main/java/com/fr/third/javassist/CtMethod.java deleted file mode 100644 index 1c7625c73..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CtMethod.java +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import com.fr.third.javassist.bytecode.CodeAttribute; - -/** - * An instance of CtMethod represents a method. - * - *

See the super class CtBehavior since - * a number of useful methods are in CtBehavior. - * A number of useful factory methods are in CtNewMethod. - * - * @see com.fr.third.javassist.CtClass#getDeclaredMethods() - * @see CtNewMethod - */ -public final class CtMethod extends CtBehavior { - protected String cachedStringRep; - - /** - * @see #make(com.fr.third.javassist.bytecode.MethodInfo minfo, com.fr.third.javassist.CtClass declaring) - */ - CtMethod(com.fr.third.javassist.bytecode.MethodInfo minfo, com.fr.third.javassist.CtClass declaring) { - super(declaring, minfo); - cachedStringRep = null; - } - - /** - * Creates a public abstract method. The created method must be - * added to a class with CtClass.addMethod(). - * - * @param declaring the class to which the created method is added. - * @param returnType the type of the returned value - * @param mname the method name - * @param parameters a list of the parameter types - * - * @see com.fr.third.javassist.CtClass#addMethod(CtMethod) - */ - public CtMethod(com.fr.third.javassist.CtClass returnType, String mname, - com.fr.third.javassist.CtClass[] parameters, com.fr.third.javassist.CtClass declaring) { - this(null, declaring); - com.fr.third.javassist.bytecode.ConstPool cp = declaring.getClassFile2().getConstPool(); - String desc = com.fr.third.javassist.bytecode.Descriptor.ofMethod(returnType, parameters); - methodInfo = new com.fr.third.javassist.bytecode.MethodInfo(cp, mname, desc); - setModifiers(Modifier.PUBLIC | Modifier.ABSTRACT); - } - - /** - * Creates a copy of a CtMethod object. - * The created method must be - * added to a class with CtClass.addMethod(). - * - *

All occurrences of class names in the created method - * are replaced with names specified by - * map if map is not null. - * - *

For example, suppose that a method at() is as - * follows: - * - *

    public X at(int i) {
    -     *     return (X)super.elementAt(i);
    -     * }
- * - *

(X is a class name.) If map substitutes - * String for X, then the created method is: - * - *

    public String at(int i) {
    -     *     return (String)super.elementAt(i);
    -     * }
- * - *

By default, all the occurrences of the names of the class - * declaring at() and the superclass are replaced - * with the name of the class and the superclass that the - * created method is added to. - * This is done whichever map is null or not. - * To prevent this replacement, call ClassMap.fix() - * or put() to explicitly specify replacement. - * - *

Note: if the .class notation (for example, - * String.class) is included in an expression, the - * Javac compiler may produce a helper method. - * Since this constructor never - * copies this helper method, the programmers have the responsiblity of - * copying it. Otherwise, use Class.forName() in the - * expression. - * - * @param src the source method. - * @param declaring the class to which the created method is added. - * @param map the hashtable associating original class names - * with substituted names. - * It can be null. - * - * @see com.fr.third.javassist.CtClass#addMethod(CtMethod) - * @see com.fr.third.javassist.ClassMap#fix(String) - */ - public CtMethod(CtMethod src, com.fr.third.javassist.CtClass declaring, com.fr.third.javassist.ClassMap map) - throws com.fr.third.javassist.CannotCompileException - { - this(null, declaring); - copy(src, false, map); - } - - /** - * Compiles the given source code and creates a method. - * This method simply delegates to make() in - * CtNewMethod. See it for more details. - * CtNewMethod has a number of useful factory methods. - * - * @param src the source text. - * @param declaring the class to which the created method is added. - * @see CtNewMethod#make(String, com.fr.third.javassist.CtClass) - */ - public static CtMethod make(String src, com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - return CtNewMethod.make(src, declaring); - } - - /** - * Creates a method from a MethodInfo object. - * - * @param declaring the class declaring the method. - * @throws com.fr.third.javassist.CannotCompileException if the the MethodInfo - * object and the declaring class have different - * ConstPool objects - * @since 3.6 - */ - public static CtMethod make(com.fr.third.javassist.bytecode.MethodInfo minfo, com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - if (declaring.getClassFile2().getConstPool() != minfo.getConstPool()) - throw new com.fr.third.javassist.CannotCompileException("bad declaring class"); - - return new CtMethod(minfo, declaring); - } - - /** - * Returns a hash code value for the method. - * If two methods have the same name and signature, then - * the hash codes for the two methods are equal. - */ - public int hashCode() { - return getStringRep().hashCode(); - } - - /** - * This method is invoked when setName() or replaceClassName() - * in CtClass is called. - */ - void nameReplaced() { - cachedStringRep = null; - } - - /* This method is also called by CtClassType.getMethods0(). - */ - final String getStringRep() { - if (cachedStringRep == null) - cachedStringRep = methodInfo.getName() - + com.fr.third.javassist.bytecode.Descriptor.getParamDescriptor(methodInfo.getDescriptor()); - - return cachedStringRep; - } - - /** - * Indicates whether obj has the same name and the - * same signature as this method. - */ - public boolean equals(Object obj) { - return obj != null && obj instanceof CtMethod - && ((CtMethod)obj).getStringRep().equals(getStringRep()); - } - - /** - * Returns the method name followed by parameter types - * such as javassist.CtMethod.setBody(String). - * - * @since 3.5 - */ - public String getLongName() { - return getDeclaringClass().getName() + "." - + getName() + com.fr.third.javassist.bytecode.Descriptor.toString(getSignature()); - } - - /** - * Obtains the name of this method. - */ - public String getName() { - return methodInfo.getName(); - } - - /** - * Changes the name of this method. - */ - public void setName(String newname) { - declaringClass.checkModify(); - methodInfo.setName(newname); - } - - /** - * Obtains the type of the returned value. - */ - public com.fr.third.javassist.CtClass getReturnType() throws NotFoundException { - return getReturnType0(); - } - - /** - * Returns true if the method body is empty, that is, {}. - * It also returns true if the method is an abstract method. - */ - public boolean isEmpty() { - com.fr.third.javassist.bytecode.CodeAttribute ca = getMethodInfo2().getCodeAttribute(); - if (ca == null) // abstract or native - return (getModifiers() & Modifier.ABSTRACT) != 0; - - com.fr.third.javassist.bytecode.CodeIterator it = ca.iterator(); - try { - return it.hasNext() && it.byteAt(it.next()) == com.fr.third.javassist.bytecode.Opcode.RETURN - && !it.hasNext(); - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) {} - return false; - } - - /** - * Copies a method body from another method. - * If this method is abstract, the abstract modifier is removed - * after the method body is copied. - * - *

All occurrences of the class names in the copied method body - * are replaced with the names specified by - * map if map is not null. - * - * @param src the method that the body is copied from. - * @param map the hashtable associating original class names - * with substituted names. - * It can be null. - */ - public void setBody(CtMethod src, ClassMap map) - throws com.fr.third.javassist.CannotCompileException - { - setBody0(src.declaringClass, src.methodInfo, - declaringClass, methodInfo, map); - } - - /** - * Replace a method body with a new method body wrapping the - * given method. - * - * @param mbody the wrapped method - * @param constParam the constant parameter given to - * the wrapped method - * (maybe null). - * - * @see CtNewMethod#wrapped(com.fr.third.javassist.CtClass,String, com.fr.third.javassist.CtClass[], com.fr.third.javassist.CtClass[],CtMethod,CtMethod.ConstParameter, com.fr.third.javassist.CtClass) - */ - public void setWrappedBody(CtMethod mbody, ConstParameter constParam) - throws com.fr.third.javassist.CannotCompileException - { - declaringClass.checkModify(); - - com.fr.third.javassist.CtClass clazz = getDeclaringClass(); - com.fr.third.javassist.CtClass[] params; - com.fr.third.javassist.CtClass retType; - try { - params = getParameterTypes(); - retType = getReturnType(); - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - - com.fr.third.javassist.bytecode.Bytecode code = CtNewWrappedMethod.makeBody(clazz, - clazz.getClassFile2(), - mbody, - params, retType, - constParam); - CodeAttribute cattr = code.toCodeAttribute(); - methodInfo.setCodeAttribute(cattr); - methodInfo.setAccessFlags(methodInfo.getAccessFlags() - & ~com.fr.third.javassist.bytecode.AccessFlag.ABSTRACT); - // rebuilding a stack map table is not needed. - } - - // inner classes - - /** - * Instances of this class represent a constant parameter. - * They are used to specify the parameter given to the methods - * created by CtNewMethod.wrapped(). - * - * @see CtMethod#setWrappedBody(CtMethod,CtMethod.ConstParameter) - * @see CtNewMethod#wrapped(com.fr.third.javassist.CtClass,String, com.fr.third.javassist.CtClass[], com.fr.third.javassist.CtClass[],CtMethod,CtMethod.ConstParameter, com.fr.third.javassist.CtClass) - * @see CtNewConstructor#make(com.fr.third.javassist.CtClass[], com.fr.third.javassist.CtClass[],int,CtMethod,CtMethod.ConstParameter, CtClass) - */ - public static class ConstParameter { - /** - * Makes an integer constant. - * - * @param i the constant value. - */ - public static ConstParameter integer(int i) { - return new IntConstParameter(i); - } - - /** - * Makes a long integer constant. - * - * @param i the constant value. - */ - public static ConstParameter integer(long i) { - return new LongConstParameter(i); - } - - /** - * Makes an String constant. - * - * @param s the constant value. - */ - public static ConstParameter string(String s) { - return new StringConstParameter(s); - } - - ConstParameter() {} - - /** - * @return the size of the stack consumption. - */ - int compile(com.fr.third.javassist.bytecode.Bytecode code) throws com.fr.third.javassist.CannotCompileException { - return 0; - } - - String descriptor() { - return defaultDescriptor(); - } - - /** - * @see CtNewWrappedMethod - */ - static String defaultDescriptor() { - return "([Ljava/lang/Object;)Ljava/lang/Object;"; - } - - /** - * Returns the descriptor for constructors. - * - * @see CtNewWrappedConstructor - */ - String constDescriptor() { - return defaultConstDescriptor(); - } - - /** - * Returns the default descriptor for constructors. - */ - static String defaultConstDescriptor() { - return "([Ljava/lang/Object;)V"; - } - } - - static class IntConstParameter extends ConstParameter { - int param; - - IntConstParameter(int i) { - param = i; - } - - int compile(com.fr.third.javassist.bytecode.Bytecode code) throws com.fr.third.javassist.CannotCompileException { - code.addIconst(param); - return 1; - } - - String descriptor() { - return "([Ljava/lang/Object;I)Ljava/lang/Object;"; - } - - String constDescriptor() { - return "([Ljava/lang/Object;I)V"; - } - } - - static class LongConstParameter extends ConstParameter { - long param; - - LongConstParameter(long l) { - param = l; - } - - int compile(com.fr.third.javassist.bytecode.Bytecode code) throws com.fr.third.javassist.CannotCompileException { - code.addLconst(param); - return 2; - } - - String descriptor() { - return "([Ljava/lang/Object;J)Ljava/lang/Object;"; - } - - String constDescriptor() { - return "([Ljava/lang/Object;J)V"; - } - } - - static class StringConstParameter extends ConstParameter { - String param; - - StringConstParameter(String s) { - param = s; - } - - int compile(com.fr.third.javassist.bytecode.Bytecode code) throws CannotCompileException { - code.addLdc(param); - return 1; - } - - String descriptor() { - return "([Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;"; - } - - String constDescriptor() { - return "([Ljava/lang/Object;Ljava/lang/String;)V"; - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CtNewClass.java b/fine-javassist/src/main/java/com/fr/third/javassist/CtNewClass.java deleted file mode 100644 index ca7a54ba2..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CtNewClass.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import java.io.DataOutputStream; -import java.io.IOException; - -import com.fr.third.javassist.bytecode.ClassFile; - -class CtNewClass extends com.fr.third.javassist.CtClassType { - /* true if the class is an interface. - */ - protected boolean hasConstructor; - - CtNewClass(String name, ClassPool cp, - boolean isInterface, com.fr.third.javassist.CtClass superclass) { - super(name, cp); - wasChanged = true; - String superName; - if (isInterface || superclass == null) - superName = null; - else - superName = superclass.getName(); - - classfile = new ClassFile(isInterface, name, superName); - if (isInterface && superclass != null) - classfile.setInterfaces(new String[] { superclass.getName() }); - - setModifiers(Modifier.setPublic(getModifiers())); - hasConstructor = isInterface; - } - - protected void extendToString(StringBuffer buffer) { - if (hasConstructor) - buffer.append("hasConstructor "); - - super.extendToString(buffer); - } - - public void addConstructor(com.fr.third.javassist.CtConstructor c) - throws com.fr.third.javassist.CannotCompileException - { - hasConstructor = true; - super.addConstructor(c); - } - - public void toBytecode(DataOutputStream out) - throws com.fr.third.javassist.CannotCompileException, IOException - { - if (!hasConstructor) - try { - inheritAllConstructors(); - hasConstructor = true; - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - - super.toBytecode(out); - } - - /** - * Adds constructors inhrited from the super class. - * - *

After this method is called, the class inherits all the - * constructors from the super class. The added constructor - * calls the super's constructor with the same signature. - */ - public void inheritAllConstructors() - throws com.fr.third.javassist.CannotCompileException, NotFoundException - { - com.fr.third.javassist.CtClass superclazz; - com.fr.third.javassist.CtConstructor[] cs; - - superclazz = getSuperclass(); - cs = superclazz.getDeclaredConstructors(); - - int n = 0; - for (int i = 0; i < cs.length; ++i) { - com.fr.third.javassist.CtConstructor c = cs[i]; - int mod = c.getModifiers(); - if (isInheritable(mod, superclazz)) { - CtConstructor cons - = CtNewConstructor.make(c.getParameterTypes(), - c.getExceptionTypes(), this); - cons.setModifiers(mod & (Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE)); - addConstructor(cons); - ++n; - } - } - - if (n < 1) - throw new CannotCompileException( - "no inheritable constructor in " + superclazz.getName()); - - } - - private boolean isInheritable(int mod, CtClass superclazz) { - if (Modifier.isPrivate(mod)) - return false; - - if (Modifier.isPackage(mod)) { - String pname = getPackageName(); - String pname2 = superclazz.getPackageName(); - if (pname == null) - return pname2 == null; - else - return pname.equals(pname2); - } - - return true; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CtNewConstructor.java b/fine-javassist/src/main/java/com/fr/third/javassist/CtNewConstructor.java deleted file mode 100644 index 80ec234fd..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CtNewConstructor.java +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.compiler.Javac; -import com.fr.third.javassist.compiler.CompileError; -import com.fr.third.javassist.CtMethod.ConstParameter; - -/** - * A collection of static methods for creating a CtConstructor. - * An instance of this class does not make any sense. - * - *

A class initializer (static constructor) cannot be created by the - * methods in this class. Call makeClassInitializer() in - * CtClass and append code snippet to the body of the class - * initializer obtained by makeClassInitializer(). - * - * @see com.fr.third.javassist.CtClass#addConstructor(com.fr.third.javassist.CtConstructor) - * @see com.fr.third.javassist.CtClass#makeClassInitializer() - */ -public class CtNewConstructor { - /** - * Specifies that no parameters are passed to a super-class' - * constructor. That is, the default constructor is invoked. - */ - public static final int PASS_NONE = 0; // call super() - - /** - * Specifies that parameters are converted into an array of - * Object and passed to a super-class' - * constructor. - */ - public static final int PASS_ARRAY = 1; // an array of parameters - - /** - * Specifies that parameters are passed as is - * to a super-class' constructor. The signature of that - * constructor must be the same as that of the created constructor. - */ - public static final int PASS_PARAMS = 2; - - /** - * Compiles the given source code and creates a constructor. - * The source code must include not only the constructor body - * but the whole declaration. - * - * @param src the source text. - * @param declaring the class to which the created constructor is added. - */ - public static com.fr.third.javassist.CtConstructor make(String src, com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - Javac compiler = new Javac(declaring); - try { - CtMember obj = compiler.compile(src); - if (obj instanceof com.fr.third.javassist.CtConstructor) { - // a stack map table has been already created. - return (com.fr.third.javassist.CtConstructor)obj; - } - } - catch (CompileError e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - - throw new com.fr.third.javassist.CannotCompileException("not a constructor"); - } - - /** - * Creates a public constructor. - * - * @param parameters a list of the parameter types. - * @param exceptions a list of the exception types. - * @param body the source text of the constructor body. - * It must be a block surrounded by {}. - * If it is null, the substituted - * constructor body does nothing except calling - * super(). - * @param declaring the class to which the created method is added. - */ - public static com.fr.third.javassist.CtConstructor make(com.fr.third.javassist.CtClass[] parameters, - com.fr.third.javassist.CtClass[] exceptions, - String body, com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - try { - com.fr.third.javassist.CtConstructor cc = new com.fr.third.javassist.CtConstructor(parameters, declaring); - cc.setExceptionTypes(exceptions); - cc.setBody(body); - return cc; - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - /** - * Creates a copy of a constructor. - * This is a convenience method for calling - * {@link com.fr.third.javassist.CtConstructor#CtConstructor(com.fr.third.javassist.CtConstructor, com.fr.third.javassist.CtClass, com.fr.third.javassist.ClassMap) this constructor}. - * See the description of the constructor for particular behavior of the copying. - * - * @param c the copied constructor. - * @param declaring the class to which the created method is added. - * @param map the hash table associating original class names - * with substituted names. - * It can be null. - * - * @see com.fr.third.javassist.CtConstructor#CtConstructor(com.fr.third.javassist.CtConstructor, com.fr.third.javassist.CtClass, com.fr.third.javassist.ClassMap) - */ - public static com.fr.third.javassist.CtConstructor copy(com.fr.third.javassist.CtConstructor c, com.fr.third.javassist.CtClass declaring, - ClassMap map) throws com.fr.third.javassist.CannotCompileException { - return new com.fr.third.javassist.CtConstructor(c, declaring, map); - } - - /** - * Creates a default (public) constructor. - * - *

The created constructor takes no parameter. It calls - * super(). - */ - public static com.fr.third.javassist.CtConstructor defaultConstructor(com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - com.fr.third.javassist.CtConstructor cons = new com.fr.third.javassist.CtConstructor((com.fr.third.javassist.CtClass[])null, declaring); - - ConstPool cp = declaring.getClassFile2().getConstPool(); - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(cp, 1, 1); - code.addAload(0); - try { - code.addInvokespecial(declaring.getSuperclass(), - "", "()V"); - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - - code.add(com.fr.third.javassist.bytecode.Bytecode.RETURN); - - // no need to construct a stack map table. - cons.getMethodInfo2().setCodeAttribute(code.toCodeAttribute()); - return cons; - } - - /** - * Creates a public constructor that only calls a constructor - * in the super class. The created constructor receives parameters - * specified by parameters but calls the super's - * constructor without those parameters (that is, it calls the default - * constructor). - * - *

The parameters passed to the created constructor should be - * used for field initialization. CtField.Initializer - * objects implicitly insert initialization code in constructor - * bodies. - * - * @param parameters parameter types - * @param exceptions exception types - * @param declaring the class to which the created constructor - * is added. - * @see CtField.Initializer#byParameter(int) - */ - public static com.fr.third.javassist.CtConstructor skeleton(com.fr.third.javassist.CtClass[] parameters, - com.fr.third.javassist.CtClass[] exceptions, com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - return make(parameters, exceptions, PASS_NONE, - null, null, declaring); - } - - /** - * Creates a public constructor that only calls a constructor - * in the super class. The created constructor receives parameters - * specified by parameters and calls the super's - * constructor with those parameters. - * - * @param parameters parameter types - * @param exceptions exception types - * @param declaring the class to which the created constructor - * is added. - */ - public static com.fr.third.javassist.CtConstructor make(com.fr.third.javassist.CtClass[] parameters, - com.fr.third.javassist.CtClass[] exceptions, com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - return make(parameters, exceptions, PASS_PARAMS, - null, null, declaring); - } - - /** - * Creates a public constructor. - * - *

If howto is PASS_PARAMS, - * the created constructor calls the super's constructor with the - * same signature. The superclass must contain - * a constructor taking the same set of parameters as the created one. - * - *

If howto is PASS_NONE, - * the created constructor calls the super's default constructor. - * The superclass must contain a constructor taking no parameters. - * - *

If howto is PASS_ARRAY, - * the created constructor calls the super's constructor - * with the given parameters in the form of an array of - * Object. The signature of the super's constructor - * must be: - * - *

    constructor(Object[] params, <type> cvalue) - *
- * - *

Here, cvalue is the constant value specified - * by cparam. - * - *

If cparam is null, the signature - * must be: - * - *

    constructor(Object[] params)
- * - *

If body is not null, a copy of that method is - * embedded in the body of the created constructor. - * The embedded method is executed after - * the super's constructor is called and the values of fields are - * initialized. Note that body must not - * be a constructor but a method. - * - *

Since the embedded method is wrapped - * in parameter-conversion code - * as in CtNewMethod.wrapped(), - * the constructor parameters are - * passed in the form of an array of Object. - * The method specified by body must have the - * signature shown below: - * - *

    Object method(Object[] params, <type> cvalue) - *
- * - *

If cparam is null, the signature - * must be: - * - *

    Object method(Object[] params)
- * - *

Although the type of the returned value is Object, - * the value must be always null. - * - *

Example: - * - *

    ClassPool pool = ... ;
    -     * CtClass xclass = pool.makeClass("X");
    -     * CtMethod method = pool.getMethod("Sample", "m");
    -     * xclass.setSuperclass(pool.get("Y"));
    -     * CtClass[] argTypes = { CtClass.intType };
    -     * ConstParameter cparam = ConstParameter.string("test");
    -     * CtConstructor c = CtNewConstructor.make(argTypes, null,
    -     *                                  PASS_PARAMS, method, cparam, xclass);
    -     * xclass.addConstructor(c);
- * - *

where the class Sample is as follows: - * - *

    public class Sample {
    -     *     public Object m(Object[] args, String msg) {
    -     *         System.out.println(msg);
    -     *         return null;
    -     *     }
    -     * }
- * - *

This program produces the following class: - * - *

    public class X extends Y {
    -     *     public X(int p0) {
    -     *         super(p0);
    -     *         String msg = "test";
    -     *         Object[] args = new Object[] { p0 };
    -     *         // begin of copied body
    -     *         System.out.println(msg);
    -     *         Object result = null;
    -     *         // end
    -     *     }
    -     * }
- * - * @param parameters a list of the parameter types - * @param exceptions a list of the exceptions - * @param howto how to pass parameters to the super-class' - * constructor (PASS_NONE, - * PASS_ARRAY, - * or PASS_PARAMS) - * @param body appended body (may be null). - * It must be not a constructor but a method. - * @param cparam constant parameter (may be null.) - * @param declaring the class to which the created constructor - * is added. - * - * @see CtNewMethod#wrapped(com.fr.third.javassist.CtClass,String, com.fr.third.javassist.CtClass[], com.fr.third.javassist.CtClass[], com.fr.third.javassist.CtMethod, ConstParameter, com.fr.third.javassist.CtClass) - */ - public static CtConstructor make(com.fr.third.javassist.CtClass[] parameters, - com.fr.third.javassist.CtClass[] exceptions, int howto, - CtMethod body, ConstParameter cparam, - CtClass declaring) - throws CannotCompileException - { - return CtNewWrappedConstructor.wrapped(parameters, exceptions, - howto, body, cparam, declaring); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CtNewMethod.java b/fine-javassist/src/main/java/com/fr/third/javassist/CtNewMethod.java deleted file mode 100644 index fd47b4a5a..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CtNewMethod.java +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.compiler.Javac; -import com.fr.third.javassist.compiler.CompileError; -import com.fr.third.javassist.CtMethod.ConstParameter; - -/** - * A collection of static methods for creating a CtMethod. - * An instance of this class does not make any sense. - * - * @see com.fr.third.javassist.CtClass#addMethod(com.fr.third.javassist.CtMethod) - */ -public class CtNewMethod { - - /** - * Compiles the given source code and creates a method. - * The source code must include not only the method body - * but the whole declaration, for example, - * - *
    "public Object id(Object obj) { return obj; }"
- * - * @param src the source text. - * @param declaring the class to which the created method is added. - */ - public static com.fr.third.javassist.CtMethod make(String src, com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - return make(src, declaring, null, null); - } - - /** - * Compiles the given source code and creates a method. - * The source code must include not only the method body - * but the whole declaration, for example, - * - *
    "public Object id(Object obj) { return obj; }"
- * - *

If the source code includes $proceed(), then - * it is compiled into a method call on the specified object. - * - * @param src the source text. - * @param declaring the class to which the created method is added. - * @param delegateObj the source text specifying the object - * that is called on by $proceed(). - * @param delegateMethod the name of the method - * that is called by $proceed(). - */ - public static com.fr.third.javassist.CtMethod make(String src, com.fr.third.javassist.CtClass declaring, - String delegateObj, String delegateMethod) - throws com.fr.third.javassist.CannotCompileException - { - Javac compiler = new Javac(declaring); - try { - if (delegateMethod != null) - compiler.recordProceed(delegateObj, delegateMethod); - - CtMember obj = compiler.compile(src); - if (obj instanceof com.fr.third.javassist.CtMethod) - return (com.fr.third.javassist.CtMethod)obj; - } - catch (CompileError e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - - throw new com.fr.third.javassist.CannotCompileException("not a method"); - } - - /** - * Creates a public (non-static) method. The created method cannot - * be changed to a static method later. - * - * @param returnType the type of the returned value. - * @param mname the method name. - * @param parameters a list of the parameter types. - * @param exceptions a list of the exception types. - * @param body the source text of the method body. - * It must be a block surrounded by {}. - * If it is null, the created method - * does nothing except returning zero or null. - * @param declaring the class to which the created method is added. - * @see #make(int, com.fr.third.javassist.CtClass, String, com.fr.third.javassist.CtClass[], com.fr.third.javassist.CtClass[], String, com.fr.third.javassist.CtClass) - */ - public static com.fr.third.javassist.CtMethod make(com.fr.third.javassist.CtClass returnType, - String mname, com.fr.third.javassist.CtClass[] parameters, - com.fr.third.javassist.CtClass[] exceptions, - String body, com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - return make(Modifier.PUBLIC, returnType, mname, parameters, exceptions, - body, declaring); - } - - /** - * Creates a method. modifiers can contain - * Modifier.STATIC. - * - * @param modifiers access modifiers. - * @param returnType the type of the returned value. - * @param mname the method name. - * @param parameters a list of the parameter types. - * @param exceptions a list of the exception types. - * @param body the source text of the method body. - * It must be a block surrounded by {}. - * If it is null, the created method - * does nothing except returning zero or null. - * @param declaring the class to which the created method is added. - * - * @see Modifier - */ - public static com.fr.third.javassist.CtMethod make(int modifiers, com.fr.third.javassist.CtClass returnType, - String mname, com.fr.third.javassist.CtClass[] parameters, - com.fr.third.javassist.CtClass[] exceptions, - String body, com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - try { - com.fr.third.javassist.CtMethod cm - = new com.fr.third.javassist.CtMethod(returnType, mname, parameters, declaring); - cm.setModifiers(modifiers); - cm.setExceptionTypes(exceptions); - cm.setBody(body); - return cm; - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - /** - * Creates a copy of a method. This method is provided for creating - * a new method based on an existing method. - * This is a convenience method for calling - * {@link com.fr.third.javassist.CtMethod#CtMethod(com.fr.third.javassist.CtMethod, com.fr.third.javassist.CtClass, com.fr.third.javassist.ClassMap) this constructor}. - * See the description of the constructor for particular behavior of the copying. - * - * @param src the source method. - * @param declaring the class to which the created method is added. - * @param map the hash table associating original class names - * with substituted names. - * It can be null. - * - * @see com.fr.third.javassist.CtMethod#CtMethod(com.fr.third.javassist.CtMethod, com.fr.third.javassist.CtClass, com.fr.third.javassist.ClassMap) - */ - public static com.fr.third.javassist.CtMethod copy(com.fr.third.javassist.CtMethod src, com.fr.third.javassist.CtClass declaring, - com.fr.third.javassist.ClassMap map) throws com.fr.third.javassist.CannotCompileException { - return new com.fr.third.javassist.CtMethod(src, declaring, map); - } - - /** - * Creates a copy of a method with a new name. - * This method is provided for creating - * a new method based on an existing method. - * This is a convenience method for calling - * {@link com.fr.third.javassist.CtMethod#CtMethod(com.fr.third.javassist.CtMethod, com.fr.third.javassist.CtClass, com.fr.third.javassist.ClassMap) this constructor}. - * See the description of the constructor for particular behavior of the copying. - * - * @param src the source method. - * @param name the name of the created method. - * @param declaring the class to which the created method is added. - * @param map the hash table associating original class names - * with substituted names. - * It can be null. - * - * @see com.fr.third.javassist.CtMethod#CtMethod(com.fr.third.javassist.CtMethod, com.fr.third.javassist.CtClass, com.fr.third.javassist.ClassMap) - */ - public static com.fr.third.javassist.CtMethod copy(com.fr.third.javassist.CtMethod src, String name, com.fr.third.javassist.CtClass declaring, - ClassMap map) throws com.fr.third.javassist.CannotCompileException { - com.fr.third.javassist.CtMethod cm = new com.fr.third.javassist.CtMethod(src, declaring, map); - cm.setName(name); - return cm; - } - - /** - * Creates a public abstract method. - * - * @param returnType the type of the returned value - * @param mname the method name - * @param parameters a list of the parameter types - * @param exceptions a list of the exception types - * @param declaring the class to which the created method is added. - * - * @see com.fr.third.javassist.CtMethod#CtMethod(com.fr.third.javassist.CtClass,String, com.fr.third.javassist.CtClass[], com.fr.third.javassist.CtClass) - */ - public static com.fr.third.javassist.CtMethod abstractMethod(com.fr.third.javassist.CtClass returnType, - String mname, - com.fr.third.javassist.CtClass[] parameters, - com.fr.third.javassist.CtClass[] exceptions, - com.fr.third.javassist.CtClass declaring) - throws NotFoundException - { - com.fr.third.javassist.CtMethod cm = new com.fr.third.javassist.CtMethod(returnType, mname, parameters, declaring); - cm.setExceptionTypes(exceptions); - return cm; - } - - /** - * Creates a public getter method. The getter method returns the value - * of the specified field in the class to which this method is added. - * The created method is initially not static even if the field is - * static. Change the modifiers if the method should be static. - * - * @param methodName the name of the getter - * @param field the field accessed. - */ - public static com.fr.third.javassist.CtMethod getter(String methodName, com.fr.third.javassist.CtField field) - throws com.fr.third.javassist.CannotCompileException - { - com.fr.third.javassist.bytecode.FieldInfo finfo = field.getFieldInfo2(); - String fieldType = finfo.getDescriptor(); - String desc = "()" + fieldType; - com.fr.third.javassist.bytecode.ConstPool cp = finfo.getConstPool(); - com.fr.third.javassist.bytecode.MethodInfo minfo = new com.fr.third.javassist.bytecode.MethodInfo(cp, methodName, desc); - minfo.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.PUBLIC); - - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(cp, 2, 1); - try { - String fieldName = finfo.getName(); - if ((finfo.getAccessFlags() & com.fr.third.javassist.bytecode.AccessFlag.STATIC) == 0) { - code.addAload(0); - code.addGetfield(com.fr.third.javassist.bytecode.Bytecode.THIS, fieldName, fieldType); - } - else - code.addGetstatic(com.fr.third.javassist.bytecode.Bytecode.THIS, fieldName, fieldType); - - code.addReturn(field.getType()); - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - - minfo.setCodeAttribute(code.toCodeAttribute()); - com.fr.third.javassist.CtClass cc = field.getDeclaringClass(); - // a stack map is not needed. - return new com.fr.third.javassist.CtMethod(minfo, cc); - } - - /** - * Creates a public setter method. The setter method assigns the - * value of the first parameter to the specified field - * in the class to which this method is added. - * The created method is not static even if the field is - * static. You may not change it to be static - * by setModifiers() in CtBehavior. - * - * @param methodName the name of the setter - * @param field the field accessed. - */ - public static com.fr.third.javassist.CtMethod setter(String methodName, CtField field) - throws com.fr.third.javassist.CannotCompileException - { - com.fr.third.javassist.bytecode.FieldInfo finfo = field.getFieldInfo2(); - String fieldType = finfo.getDescriptor(); - String desc = "(" + fieldType + ")V"; - com.fr.third.javassist.bytecode.ConstPool cp = finfo.getConstPool(); - com.fr.third.javassist.bytecode.MethodInfo minfo = new com.fr.third.javassist.bytecode.MethodInfo(cp, methodName, desc); - minfo.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.PUBLIC); - - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(cp, 3, 3); - try { - String fieldName = finfo.getName(); - if ((finfo.getAccessFlags() & com.fr.third.javassist.bytecode.AccessFlag.STATIC) == 0) { - code.addAload(0); - code.addLoad(1, field.getType()); - code.addPutfield(com.fr.third.javassist.bytecode.Bytecode.THIS, fieldName, fieldType); - } - else { - code.addLoad(1, field.getType()); - code.addPutstatic(com.fr.third.javassist.bytecode.Bytecode.THIS, fieldName, fieldType); - } - - code.addReturn(null); - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - - minfo.setCodeAttribute(code.toCodeAttribute()); - com.fr.third.javassist.CtClass cc = field.getDeclaringClass(); - // a stack map is not needed. - return new com.fr.third.javassist.CtMethod(minfo, cc); - } - - /** - * Creates a method forwarding to a delegate in - * a super class. The created method calls a method specified - * by delegate with all the parameters passed to the - * created method. If the delegate method returns a value, - * the created method returns that value to the caller. - * The delegate method must be declared in a super class. - * - *

The following method is an example of the created method. - * - *

    int f(int p, int q) {
    -     *     return super.f(p, q);
    -     * }
- * - *

The name of the created method can be changed by - * setName(). - * - * @param delegate the method that the created method forwards to. - * @param declaring the class to which the created method is - * added. - */ - public static com.fr.third.javassist.CtMethod delegator(com.fr.third.javassist.CtMethod delegate, com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - try { - return delegator0(delegate, declaring); - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - private static com.fr.third.javassist.CtMethod delegator0(com.fr.third.javassist.CtMethod delegate, com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException, NotFoundException - { - com.fr.third.javassist.bytecode.MethodInfo deleInfo = delegate.getMethodInfo2(); - String methodName = deleInfo.getName(); - String desc = deleInfo.getDescriptor(); - ConstPool cp = declaring.getClassFile2().getConstPool(); - com.fr.third.javassist.bytecode.MethodInfo minfo = new com.fr.third.javassist.bytecode.MethodInfo(cp, methodName, desc); - minfo.setAccessFlags(deleInfo.getAccessFlags()); - - com.fr.third.javassist.bytecode.ExceptionsAttribute eattr = deleInfo.getExceptionsAttribute(); - if (eattr != null) - minfo.setExceptionsAttribute( - (com.fr.third.javassist.bytecode.ExceptionsAttribute)eattr.copy(cp, null)); - - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(cp, 0, 0); - boolean isStatic = Modifier.isStatic(delegate.getModifiers()); - com.fr.third.javassist.CtClass deleClass = delegate.getDeclaringClass(); - com.fr.third.javassist.CtClass[] params = delegate.getParameterTypes(); - int s; - if (isStatic) { - s = code.addLoadParameters(params, 0); - code.addInvokestatic(deleClass, methodName, desc); - } - else { - code.addLoad(0, deleClass); - s = code.addLoadParameters(params, 1); - code.addInvokespecial(deleClass, methodName, desc); - } - - code.addReturn(delegate.getReturnType()); - code.setMaxLocals(++s); - code.setMaxStack(s < 2 ? 2 : s); // for a 2-word return value - minfo.setCodeAttribute(code.toCodeAttribute()); - // a stack map is not needed. - return new com.fr.third.javassist.CtMethod(minfo, declaring); - } - - /** - * Creates a wrapped method. The wrapped method receives parameters - * in the form of an array of Object. - * - *

The body of the created method is a copy of the body of the method - * specified by body. However, it is wrapped in - * parameter-conversion code. - * - *

The method specified by body must have this singature: - * - *

    Object method(Object[] params, <type> cvalue) - *
- * - *

The type of the cvalue depends on - * constParam. - * If constParam is null, the signature - * must be: - * - *

    Object method(Object[] params)
- * - *

The method body copied from body is wrapped in - * parameter-conversion code, which converts parameters specified by - * parameterTypes into an array of Object. - * The returned value is also converted from the Object - * type to the type specified by returnType. Thus, - * the resulting method body is as follows: - * - *

    Object[] params = new Object[] { p0, p1, ... };
    -     * <type> cvalue = <constant-value>;
    -     *  ... copied method body ...
    -     * Object result = <returned value>
    -     * return (<returnType>)result;
    -     * 
- * - *

The variables p0, p2, ... represent - * formal parameters of the created method. - * The value of cvalue is specified by - * constParam. - * - *

If the type of a parameter or a returned value is a primitive - * type, then the value is converted into a wrapper object such as - * java.lang.Integer. If the type of the returned value - * is void, the returned value is discarded. - * - *

Example: - * - *

    ClassPool pool = ... ;
    -     * CtClass vec = pool.makeClass("intVector");
    -     * vec.setSuperclass(pool.get("java.util.Vector"));
    -     * CtMethod addMethod = pool.getMethod("Sample", "add0");
    -     *
    -     * CtClass[] argTypes = { CtClass.intType };
    -     * CtMethod m = CtNewMethod.wrapped(CtClass.voidType, "add", argTypes,
    -     *                                  null, addMethod, null, vec);
    -     * vec.addMethod(m);
- * - *

where the class Sample is as follows: - * - *

    public class Sample extends java.util.Vector {
    -     *     public Object add0(Object[] args) {
    -     *         super.addElement(args[0]);
    -     *         return null;
    -     *     }
    -     * }
- * - *

This program produces a class intVector: - * - *

    public class intVector extends java.util.Vector {
    -     *     public void add(int p0) {
    -     *         Object[] args = new Object[] { p0 };
    -     *         // begin of the copied body
    -     *         super.addElement(args[0]);
    -     *         Object result = null;
    -     *         // end
    -     *     }
    -     * }
- * - *

Note that the type of the parameter to add() depends - * only on the value of argTypes passed to - * CtNewMethod.wrapped(). Thus, it is easy to - * modify this program to produce a - * StringVector class, which is a vector containing - * only String objects, and other vector classes. - * - * @param returnType the type of the returned value. - * @param mname the method name. - * @param parameterTypes a list of the parameter types. - * @param exceptionTypes a list of the exception types. - * @param body the method body - * (must not be a static method). - * @param constParam the constant parameter - * (maybe null). - * @param declaring the class to which the created method is - * added. - */ - public static com.fr.third.javassist.CtMethod wrapped(com.fr.third.javassist.CtClass returnType, - String mname, - com.fr.third.javassist.CtClass[] parameterTypes, - com.fr.third.javassist.CtClass[] exceptionTypes, - CtMethod body, ConstParameter constParam, - CtClass declaring) - throws CannotCompileException - { - return CtNewWrappedMethod.wrapped(returnType, mname, parameterTypes, - exceptionTypes, body, constParam, declaring); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CtNewNestedClass.java b/fine-javassist/src/main/java/com/fr/third/javassist/CtNewNestedClass.java deleted file mode 100644 index 3c211d58f..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CtNewNestedClass.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import com.fr.third.javassist.bytecode.ClassFile; -import com.fr.third.javassist.bytecode.AccessFlag; -import com.fr.third.javassist.bytecode.InnerClassesAttribute; - -/** - * A newly created public nested class. - */ -class CtNewNestedClass extends com.fr.third.javassist.CtNewClass { - CtNewNestedClass(String realName, ClassPool cp, boolean isInterface, - com.fr.third.javassist.CtClass superclass) { - super(realName, cp, isInterface, superclass); - } - - /** - * This method does not change the STATIC bit. The original value is kept. - */ - public void setModifiers(int mod) { - mod = mod & ~Modifier.STATIC; - super.setModifiers(mod); - updateInnerEntry(mod, getName(), this, true); - } - - private static void updateInnerEntry(int mod, String name, com.fr.third.javassist.CtClass clazz, boolean outer) { - ClassFile cf = clazz.getClassFile2(); - InnerClassesAttribute ica = (InnerClassesAttribute)cf.getAttribute( - InnerClassesAttribute.tag); - if (ica == null) - return; - - int n = ica.tableLength(); - for (int i = 0; i < n; i++) - if (name.equals(ica.innerClass(i))) { - int acc = ica.accessFlags(i) & AccessFlag.STATIC; - ica.setAccessFlags(i, mod | acc); - String outName = ica.outerClass(i); - if (outName != null && outer) - try { - CtClass parent = clazz.getClassPool().get(outName); - updateInnerEntry(mod, name, parent, false); - } - catch (NotFoundException e) { - throw new RuntimeException("cannot find the declaring class: " - + outName); - } - - break; - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CtNewWrappedConstructor.java b/fine-javassist/src/main/java/com/fr/third/javassist/CtNewWrappedConstructor.java deleted file mode 100644 index 49802cdd2..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CtNewWrappedConstructor.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import com.fr.third.javassist.bytecode.ClassFile; -import com.fr.third.javassist.CtMethod.ConstParameter; - -class CtNewWrappedConstructor extends CtNewWrappedMethod { - private static final int PASS_NONE = com.fr.third.javassist.CtNewConstructor.PASS_NONE; - // private static final int PASS_ARRAY = CtNewConstructor.PASS_ARRAY; - private static final int PASS_PARAMS = CtNewConstructor.PASS_PARAMS; - - public static com.fr.third.javassist.CtConstructor wrapped(com.fr.third.javassist.CtClass[] parameterTypes, - com.fr.third.javassist.CtClass[] exceptionTypes, - int howToCallSuper, - com.fr.third.javassist.CtMethod body, - ConstParameter constParam, - com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - try { - com.fr.third.javassist.CtConstructor cons = new CtConstructor(parameterTypes, declaring); - cons.setExceptionTypes(exceptionTypes); - com.fr.third.javassist.bytecode.Bytecode code = makeBody(declaring, declaring.getClassFile2(), - howToCallSuper, body, - parameterTypes, constParam); - cons.getMethodInfo2().setCodeAttribute(code.toCodeAttribute()); - // a stack map table is not needed. - return cons; - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - protected static com.fr.third.javassist.bytecode.Bytecode makeBody(com.fr.third.javassist.CtClass declaring, ClassFile classfile, - int howToCallSuper, - CtMethod wrappedBody, - com.fr.third.javassist.CtClass[] parameters, - ConstParameter cparam) - throws CannotCompileException - { - int stacksize, stacksize2; - - int superclazz = classfile.getSuperclassId(); - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(classfile.getConstPool(), 0, 0); - code.setMaxLocals(false, parameters, 0); - code.addAload(0); - if (howToCallSuper == PASS_NONE) { - stacksize = 1; - code.addInvokespecial(superclazz, "", "()V"); - } - else if (howToCallSuper == PASS_PARAMS) { - stacksize = code.addLoadParameters(parameters, 1) + 1; - code.addInvokespecial(superclazz, "", - com.fr.third.javassist.bytecode.Descriptor.ofConstructor(parameters)); - } - else { - stacksize = compileParameterList(code, parameters, 1); - String desc; - if (cparam == null) { - stacksize2 = 2; - desc = ConstParameter.defaultConstDescriptor(); - } - else { - stacksize2 = cparam.compile(code) + 2; - desc = cparam.constDescriptor(); - } - - if (stacksize < stacksize2) - stacksize = stacksize2; - - code.addInvokespecial(superclazz, "", desc); - } - - if (wrappedBody == null) - code.add(com.fr.third.javassist.bytecode.Bytecode.RETURN); - else { - stacksize2 = makeBody0(declaring, classfile, wrappedBody, - false, parameters, CtClass.voidType, - cparam, code); - if (stacksize < stacksize2) - stacksize = stacksize2; - } - - code.setMaxStack(stacksize); - return code; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CtNewWrappedMethod.java b/fine-javassist/src/main/java/com/fr/third/javassist/CtNewWrappedMethod.java deleted file mode 100644 index 89ebe27c0..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CtNewWrappedMethod.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import com.fr.third.javassist.bytecode.SyntheticAttribute; -import com.fr.third.javassist.compiler.JvstCodeGen; -import java.util.Hashtable; -import com.fr.third.javassist.CtMethod.ConstParameter; - -class CtNewWrappedMethod { - - private static final String addedWrappedMethod = "_added_m$"; - - public static com.fr.third.javassist.CtMethod wrapped(com.fr.third.javassist.CtClass returnType, String mname, - com.fr.third.javassist.CtClass[] parameterTypes, - com.fr.third.javassist.CtClass[] exceptionTypes, - com.fr.third.javassist.CtMethod body, ConstParameter constParam, - com.fr.third.javassist.CtClass declaring) - throws com.fr.third.javassist.CannotCompileException - { - com.fr.third.javassist.CtMethod mt = new com.fr.third.javassist.CtMethod(returnType, mname, parameterTypes, - declaring); - mt.setModifiers(body.getModifiers()); - try { - mt.setExceptionTypes(exceptionTypes); - } - catch (NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - - com.fr.third.javassist.bytecode.Bytecode code = makeBody(declaring, declaring.getClassFile2(), body, - parameterTypes, returnType, constParam); - com.fr.third.javassist.bytecode.MethodInfo minfo = mt.getMethodInfo2(); - minfo.setCodeAttribute(code.toCodeAttribute()); - // a stack map has been already created. - return mt; - } - - static com.fr.third.javassist.bytecode.Bytecode makeBody(com.fr.third.javassist.CtClass clazz, com.fr.third.javassist.bytecode.ClassFile classfile, - com.fr.third.javassist.CtMethod wrappedBody, - com.fr.third.javassist.CtClass[] parameters, - com.fr.third.javassist.CtClass returnType, - ConstParameter cparam) - throws com.fr.third.javassist.CannotCompileException - { - boolean isStatic = Modifier.isStatic(wrappedBody.getModifiers()); - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(classfile.getConstPool(), 0, 0); - int stacksize = makeBody0(clazz, classfile, wrappedBody, isStatic, - parameters, returnType, cparam, code); - code.setMaxStack(stacksize); - code.setMaxLocals(isStatic, parameters, 0); - return code; - } - - /* The generated method body does not need a stack map table - * because it does not contain a branch instruction. - */ - protected static int makeBody0(com.fr.third.javassist.CtClass clazz, com.fr.third.javassist.bytecode.ClassFile classfile, - com.fr.third.javassist.CtMethod wrappedBody, - boolean isStatic, com.fr.third.javassist.CtClass[] parameters, - com.fr.third.javassist.CtClass returnType, ConstParameter cparam, - com.fr.third.javassist.bytecode.Bytecode code) - throws com.fr.third.javassist.CannotCompileException - { - if (!(clazz instanceof com.fr.third.javassist.CtClassType)) - throw new com.fr.third.javassist.CannotCompileException("bad declaring class" - + clazz.getName()); - - if (!isStatic) - code.addAload(0); - - int stacksize = compileParameterList(code, parameters, - (isStatic ? 0 : 1)); - int stacksize2; - String desc; - if (cparam == null) { - stacksize2 = 0; - desc = ConstParameter.defaultDescriptor(); - } - else { - stacksize2 = cparam.compile(code); - desc = cparam.descriptor(); - } - - checkSignature(wrappedBody, desc); - - String bodyname; - try { - bodyname = addBodyMethod((com.fr.third.javassist.CtClassType)clazz, classfile, - wrappedBody); - /* if an exception is thrown below, the method added above - * should be removed. (future work :<) - */ - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - - if (isStatic) - code.addInvokestatic(com.fr.third.javassist.bytecode.Bytecode.THIS, bodyname, desc); - else - code.addInvokespecial(com.fr.third.javassist.bytecode.Bytecode.THIS, bodyname, desc); - - compileReturn(code, returnType); // consumes 2 stack entries - - if (stacksize < stacksize2 + 2) - stacksize = stacksize2 + 2; - - return stacksize; - } - - private static void checkSignature(com.fr.third.javassist.CtMethod wrappedBody, - String descriptor) - throws com.fr.third.javassist.CannotCompileException - { - if (!descriptor.equals(wrappedBody.getMethodInfo2().getDescriptor())) - throw new com.fr.third.javassist.CannotCompileException( - "wrapped method with a bad signature: " - + wrappedBody.getDeclaringClass().getName() - + '.' + wrappedBody.getName()); - } - - private static String addBodyMethod(com.fr.third.javassist.CtClassType clazz, - com.fr.third.javassist.bytecode.ClassFile classfile, - com.fr.third.javassist.CtMethod src) - throws com.fr.third.javassist.bytecode.BadBytecode, CannotCompileException - { - Hashtable bodies = clazz.getHiddenMethods(); - String bodyname = (String)bodies.get(src); - if (bodyname == null) { - do { - bodyname = addedWrappedMethod + clazz.getUniqueNumber(); - } while (classfile.getMethod(bodyname) != null); - com.fr.third.javassist.ClassMap map = new ClassMap(); - map.put(src.getDeclaringClass().getName(), clazz.getName()); - com.fr.third.javassist.bytecode.MethodInfo body = new com.fr.third.javassist.bytecode.MethodInfo(classfile.getConstPool(), - bodyname, src.getMethodInfo2(), - map); - int acc = body.getAccessFlags(); - body.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.setPrivate(acc)); - body.addAttribute(new SyntheticAttribute(classfile.getConstPool())); - // a stack map is copied. rebuilding it is not needed. - classfile.addMethod(body); - bodies.put(src, bodyname); - CtMember.Cache cache = clazz.hasMemberCache(); - if (cache != null) - cache.addMethod(new CtMethod(body, clazz)); - } - - return bodyname; - } - - /* compileParameterList() returns the stack size used - * by the produced code. - * - * @param regno the index of the local variable in which - * the first argument is received. - * (0: static method, 1: regular method.) - */ - static int compileParameterList(com.fr.third.javassist.bytecode.Bytecode code, - com.fr.third.javassist.CtClass[] params, int regno) { - return JvstCodeGen.compileParameterList(code, params, regno); - } - - /* - * The produced codes cosume 1 or 2 stack entries. - */ - private static void compileReturn(com.fr.third.javassist.bytecode.Bytecode code, com.fr.third.javassist.CtClass type) { - if (type.isPrimitive()) { - CtPrimitiveType pt = (CtPrimitiveType)type; - if (pt != CtClass.voidType) { - String wrapper = pt.getWrapperName(); - code.addCheckcast(wrapper); - code.addInvokevirtual(wrapper, pt.getGetMethodName(), - pt.getGetMethodDescriptor()); - } - - code.addOpcode(pt.getReturnOp()); - } - else { - code.addCheckcast(type); - code.addOpcode(com.fr.third.javassist.bytecode.Bytecode.ARETURN); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/CtPrimitiveType.java b/fine-javassist/src/main/java/com/fr/third/javassist/CtPrimitiveType.java deleted file mode 100644 index 43e66cb8d..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/CtPrimitiveType.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -/** - * An instance of CtPrimitiveType represents a primitive type. - * It is obtained from CtClass. - */ -public final class CtPrimitiveType extends CtClass { - private char descriptor; - private String wrapperName; - private String getMethodName; - private String mDescriptor; - private int returnOp; - private int arrayType; - private int dataSize; - - CtPrimitiveType(String name, char desc, String wrapper, - String methodName, String mDesc, int opcode, int atype, - int size) { - super(name); - descriptor = desc; - wrapperName = wrapper; - getMethodName = methodName; - mDescriptor = mDesc; - returnOp = opcode; - arrayType = atype; - dataSize = size; - } - - /** - * Returns true if this object represents a primitive - * Java type: boolean, byte, char, short, int, long, float, double, - * or void. - */ - public boolean isPrimitive() { return true; } - - /** - * Returns the modifiers for this type. - * For decoding, use javassist.Modifier. - * - * @see Modifier - */ - public int getModifiers() { - return Modifier.PUBLIC | Modifier.FINAL; - } - - /** - * Returns the descriptor representing this type. - * For example, if the type is int, then the descriptor is I. - */ - public char getDescriptor() { return descriptor; } - - /** - * Returns the name of the wrapper class. - * For example, if the type is int, then the wrapper class is - * java.lang.Integer. - */ - public String getWrapperName() { return wrapperName; } - - /** - * Returns the name of the method for retrieving the value - * from the wrapper object. - * For example, if the type is int, then the method name is - * intValue. - */ - public String getGetMethodName() { return getMethodName; } - - /** - * Returns the descriptor of the method for retrieving the value - * from the wrapper object. - * For example, if the type is int, then the method descriptor is - * ()I. - */ - public String getGetMethodDescriptor() { return mDescriptor; } - - /** - * Returns the opcode for returning a value of the type. - * For example, if the type is int, then the returned opcode is - * javassit.bytecode.Opcode.IRETURN. - */ - public int getReturnOp() { return returnOp; } - - /** - * Returns the array-type code representing the type. - * It is used for the newarray instruction. - * For example, if the type is int, then this method returns - * javassit.bytecode.Opcode.T_INT. - */ - public int getArrayType() { return arrayType; } - - /** - * Returns the data size of the primitive type. - * If the type is long or double, this method returns 2. - * Otherwise, it returns 1. - */ - public int getDataSize() { return dataSize; } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/Loader.java b/fine-javassist/src/main/java/com/fr/third/javassist/Loader.java deleted file mode 100644 index 7d9c81137..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/Loader.java +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import java.io.*; -import java.util.Hashtable; -import java.util.Vector; -import java.security.ProtectionDomain; - -/** - * The class loader for Javassist. - * - *

This is a sample class loader using ClassPool. - * Unlike a regular class loader, this class loader obtains bytecode - * from a ClassPool. - * - *

Note that Javassist can be used without this class loader; programmers - * can define their own versions of class loader. They can run - * a program even without any user-defined class loader if that program - * is statically translated with Javassist. - * This class loader is just provided as a utility class. - * - *

Suppose that an instance of MyTranslator implementing - * the interface Translator is responsible for modifying - * class files. - * The startup program of an application using MyTranslator - * should be something like this: - * - *

    - * import javassist.*;
    - *
    - * public class Main {
    - *   public static void main(String[] args) throws Throwable {
    - *     MyTranslator myTrans = new MyTranslator();
    - *     ClassPool cp = ClassPool.getDefault();
    - *     Loader cl = new Loader(cp);
    - *     cl.addTranslator(cp, myTrans);
    - *     cl.run("MyApp", args);
    - *   }
    - * }
    - * 
- * - *

Class MyApp is the main program of the application. - * - *

This program should be executed as follows: - * - *

    - * % java Main arg1 arg2...
    - * 
- * - *

It modifies the class MyApp with a MyTranslator - * object before the JVM loads it. - * Then it calls main() in MyApp with arguments - * arg1, arg2, ... - * - *

This program execution is equivalent to: - * - *

    - * % java MyApp arg1 arg2...
    - * 
- * - *

except that classes are translated by MyTranslator - * at load time. - * - *

If only a particular class must be modified when it is loaded, - * the startup program can be simpler; MyTranslator is - * unnecessary. For example, if only a class test.Rectangle - * is modified, the main() method above will be the following: - * - *

    - * ClassPool cp = ClassPool.getDefault();
    - * Loader cl = new Loader(cp);
    - * CtClass ct = cp.get("test.Rectangle");
    - * ct.setSuperclass(cp.get("test.Point"));
    - * cl.run("MyApp", args);
- * - *

This program changes the super class of the test.Rectangle - * class. - * - *

Note 1: - * - *

This class loader does not allow the users to intercept the loading - * of java.* and javax.* classes (and - * sun.*, org.xml.*, ...) unless - * Loader.doDelegation is false. This is because - * the JVM prohibits a user class loader from loading a system class. - * Also see Note 2. - * If this behavior is not appropriate, a subclass of Loader - * must be defined and loadClassByDelegation() must be overridden. - * - *

Note 2: - * - *

If classes are loaded with different class loaders, they belong to - * separate name spaces. If class C is loaded by a class - * loader CL, all classes that the class C - * refers to are also loaded by CL. However, if CL - * delegates the loading of the class C to CL', - * then those classes that the class C refers to - * are loaded by a parent class loader CL' - * instead of CL. - * - *

If an object of class C is assigned - * to a variable of class C belonging to a different name - * space, then a ClassCastException is thrown. - * - *

Because of the fact above, this loader delegates only the loading of - * javassist.Loader - * and classes included in package java.* and - * javax.* to the parent class - * loader. Other classes are directly loaded by this loader. - * - *

For example, suppose that java.lang.String would be loaded - * by this loader while java.io.File is loaded by the parent - * class loader. If the constructor of java.io.File is called - * with an instance of java.lang.String, then it may throw - * an exception since it accepts an instance of only the - * java.lang.String loaded by the parent class loader. - * - * @see com.fr.third.javassist.ClassPool - * @see Translator - */ -public class Loader extends ClassLoader { - private Hashtable notDefinedHere; // must be atomic. - private Vector notDefinedPackages; // must be atomic. - private com.fr.third.javassist.ClassPool source; - private Translator translator; - private ProtectionDomain domain; - - /** - * Specifies the algorithm of class loading. - * - *

This class loader uses the parent class loader for - * java.* and javax.* classes. - * If this variable doDelegation - * is false, this class loader does not delegate those - * classes to the parent class loader. - * - *

The default value is true. - */ - public boolean doDelegation = true; - - /** - * Creates a new class loader. - */ - public Loader() { - this(null); - } - - /** - * Creates a new class loader. - * - * @param cp the source of class files. - */ - public Loader(com.fr.third.javassist.ClassPool cp) { - init(cp); - } - - /** - * Creates a new class loader - * using the specified parent class loader for delegation. - * - * @param parent the parent class loader. - * @param cp the source of class files. - */ - public Loader(ClassLoader parent, com.fr.third.javassist.ClassPool cp) { - super(parent); - init(cp); - } - - private void init(com.fr.third.javassist.ClassPool cp) { - notDefinedHere = new Hashtable(); - notDefinedPackages = new Vector(); - source = cp; - translator = null; - domain = null; - delegateLoadingOf("javassist.Loader"); - } - - /** - * Records a class so that the loading of that class is delegated - * to the parent class loader. - * - *

If the given class name ends with . (dot), then - * that name is interpreted as a package name. All the classes - * in that package and the sub packages are delegated. - */ - public void delegateLoadingOf(String classname) { - if (classname.endsWith(".")) - notDefinedPackages.addElement(classname); - else - notDefinedHere.put(classname, this); - } - - /** - * Sets the protection domain for the classes handled by this class - * loader. Without registering an appropriate protection domain, - * the program loaded by this loader will not work with a security - * manager or a signed jar file. - */ - public void setDomain(ProtectionDomain d) { - domain = d; - } - - /** - * Sets the soruce ClassPool. - */ - public void setClassPool(com.fr.third.javassist.ClassPool cp) { - source = cp; - } - - /** - * Adds a translator, which is called whenever a class is loaded. - * - * @param cp the ClassPool object for obtaining - * a class file. - * @param t a translator. - * @throws NotFoundException if t.start() throws an exception. - * @throws com.fr.third.javassist.CannotCompileException if t.start() throws an exception. - */ - public void addTranslator(ClassPool cp, Translator t) - throws NotFoundException, CannotCompileException { - source = cp; - translator = t; - t.start(cp); - } - - /** - * Loads a class with an instance of Loader - * and calls main() of that class. - * - *

This method calls run(). - * - * @param args command line parameters. - *

    - * args[0] is the class name to be loaded. - *
    args[1..n] are parameters passed - * to the target main(). - *
- * - * @see Loader#run(String[]) - */ - public static void main(String[] args) throws Throwable { - Loader cl = new Loader(); - cl.run(args); - } - - /** - * Loads a class and calls main() in that class. - * - * @param args command line parameters. - *
    - * args[0] is the class name to be loaded. - *
    args[1..n] are parameters passed - * to the target main(). - *
- */ - public void run(String[] args) throws Throwable { - int n = args.length - 1; - if (n >= 0) { - String[] args2 = new String[n]; - for (int i = 0; i < n; ++i) - args2[i] = args[i + 1]; - - run(args[0], args2); - } - } - - /** - * Loads a class and calls main() in that class. - * - * @param classname the loaded class. - * @param args parameters passed to main(). - */ - public void run(String classname, String[] args) throws Throwable { - Class c = loadClass(classname); - try { - c.getDeclaredMethod("main", new Class[] { String[].class }).invoke( - null, - new Object[] { args }); - } - catch (java.lang.reflect.InvocationTargetException e) { - throw e.getTargetException(); - } - } - - /** - * Requests the class loader to load a class. - */ - protected Class loadClass(String name, boolean resolve) - throws ClassFormatError, ClassNotFoundException { - name = name.intern(); - synchronized (name) { - Class c = findLoadedClass(name); - if (c == null) - c = loadClassByDelegation(name); - - if (c == null) - c = findClass(name); - - if (c == null) - c = delegateToParent(name); - - if (resolve) - resolveClass(c); - - return c; - } - } - - /** - * Finds the specified class using ClassPath. - * If the source throws an exception, this returns null. - * - *

This method can be overridden by a subclass of - * Loader. Note that the overridden method must not throw - * an exception when it just fails to find a class file. - * - * @return null if the specified class could not be found. - * @throws ClassNotFoundException if an exception is thrown while - * obtaining a class file. - */ - protected Class findClass(String name) throws ClassNotFoundException { - byte[] classfile; - try { - if (source != null) { - if (translator != null) - translator.onLoad(source, name); - - try { - classfile = source.get(name).toBytecode(); - } - catch (NotFoundException e) { - return null; - } - } - else { - String jarname = "/" + name.replace('.', '/') + ".class"; - InputStream in = this.getClass().getResourceAsStream(jarname); - if (in == null) - return null; - - classfile = com.fr.third.javassist.ClassPoolTail.readStream(in); - } - } - catch (Exception e) { - throw new ClassNotFoundException( - "caught an exception while obtaining a class file for " - + name, e); - } - - int i = name.lastIndexOf('.'); - if (i != -1) { - String pname = name.substring(0, i); - if (getPackage(pname) == null) - try { - definePackage( - pname, null, null, null, null, null, null, null); - } - catch (IllegalArgumentException e) { - // ignore. maybe the package object for the same - // name has been created just right away. - } - } - - if (domain == null) - return defineClass(name, classfile, 0, classfile.length); - else - return defineClass(name, classfile, 0, classfile.length, domain); - } - - protected Class loadClassByDelegation(String name) - throws ClassNotFoundException - { - /* The swing components must be loaded by a system - * class loader. - * javax.swing.UIManager loads a (concrete) subclass - * of LookAndFeel by a system class loader and cast - * an instance of the class to LookAndFeel for - * (maybe) a security reason. To avoid failure of - * type conversion, LookAndFeel must not be loaded - * by this class loader. - */ - - Class c = null; - if (doDelegation) - if (name.startsWith("java.") - || name.startsWith("javax.") - || name.startsWith("sun.") - || name.startsWith("com.sun.") - || name.startsWith("org.w3c.") - || name.startsWith("org.xml.") - || notDelegated(name)) - c = delegateToParent(name); - - return c; - } - - private boolean notDelegated(String name) { - if (notDefinedHere.get(name) != null) - return true; - - int n = notDefinedPackages.size(); - for (int i = 0; i < n; ++i) - if (name.startsWith((String)notDefinedPackages.elementAt(i))) - return true; - - return false; - } - - protected Class delegateToParent(String classname) - throws ClassNotFoundException - { - ClassLoader cl = getParent(); - if (cl != null) - return cl.loadClass(classname); - else - return findSystemClass(classname); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/LoaderClassPath.java b/fine-javassist/src/main/java/com/fr/third/javassist/LoaderClassPath.java deleted file mode 100644 index cfb6a37a0..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/LoaderClassPath.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import java.io.InputStream; -import java.net.URL; -import java.lang.ref.WeakReference; - -/** - * A class search-path representing a class loader. - * - *

It is used for obtaining a class file from the given - * class loader by getResourceAsStream(). - * The LoaderClassPath refers to the class loader through - * WeakReference. If the class loader is garbage collected, - * the other search pathes are examined. - * - *

The given class loader must have both getResourceAsStream() - * and getResource(). - * - * @author Bill Burke - * @author Shigeru Chiba - * - * @see com.fr.third.javassist.ClassPool#insertClassPath(com.fr.third.javassist.ClassPath) - * @see ClassPool#appendClassPath(com.fr.third.javassist.ClassPath) - * @see ClassClassPath - */ -public class LoaderClassPath implements ClassPath { - private WeakReference clref; - - /** - * Creates a search path representing a class loader. - */ - public LoaderClassPath(ClassLoader cl) { - clref = new WeakReference(cl); - } - - public String toString() { - Object cl = null; - if (clref != null) - cl = clref.get(); - - return cl == null ? "" : cl.toString(); - } - - /** - * Obtains a class file from the class loader. - * This method calls getResourceAsStream(String) - * on the class loader. - */ - public InputStream openClassfile(String classname) { - String cname = classname.replace('.', '/') + ".class"; - ClassLoader cl = (ClassLoader)clref.get(); - if (cl == null) - return null; // not found - else - return cl.getResourceAsStream(cname); - } - - /** - * Obtains the URL of the specified class file. - * This method calls getResource(String) - * on the class loader. - * - * @return null if the class file could not be found. - */ - public URL find(String classname) { - String cname = classname.replace('.', '/') + ".class"; - ClassLoader cl = (ClassLoader)clref.get(); - if (cl == null) - return null; // not found - else - return cl.getResource(cname); - } - - /** - * Closes this class path. - */ - public void close() { - clref = null; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/Modifier.java b/fine-javassist/src/main/java/com/fr/third/javassist/Modifier.java deleted file mode 100644 index eddf230e8..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/Modifier.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import com.fr.third.javassist.bytecode.AccessFlag; - -/** - * The Modifier class provides static methods and constants to decode - * class and member access modifiers. The constant values are equivalent - * to the corresponding values in javassist.bytecode.AccessFlag. - * - *

All the methods/constants in this class are compatible with - * ones in java.lang.reflect.Modifier. - * - * @see CtClass#getModifiers() - */ -public class Modifier { - public static final int PUBLIC = AccessFlag.PUBLIC; - public static final int PRIVATE = AccessFlag.PRIVATE; - public static final int PROTECTED = AccessFlag.PROTECTED; - public static final int STATIC = AccessFlag.STATIC; - public static final int FINAL = AccessFlag.FINAL; - public static final int SYNCHRONIZED = AccessFlag.SYNCHRONIZED; - public static final int VOLATILE = AccessFlag.VOLATILE; - public static final int VARARGS = AccessFlag.VARARGS; - public static final int TRANSIENT = AccessFlag.TRANSIENT; - public static final int NATIVE = AccessFlag.NATIVE; - public static final int INTERFACE = AccessFlag.INTERFACE; - public static final int ABSTRACT = AccessFlag.ABSTRACT; - public static final int STRICT = AccessFlag.STRICT; - public static final int ANNOTATION = AccessFlag.ANNOTATION; - public static final int ENUM = AccessFlag.ENUM; - - /** - * Returns true if the modifiers include the public - * modifier. - */ - public static boolean isPublic(int mod) { - return (mod & PUBLIC) != 0; - } - - /** - * Returns true if the modifiers include the private - * modifier. - */ - public static boolean isPrivate(int mod) { - return (mod & PRIVATE) != 0; - } - - /** - * Returns true if the modifiers include the protected - * modifier. - */ - public static boolean isProtected(int mod) { - return (mod & PROTECTED) != 0; - } - - /** - * Returns true if the modifiers do not include either - * public, protected, or private. - */ - public static boolean isPackage(int mod) { - return (mod & (PUBLIC | PRIVATE | PROTECTED)) == 0; - } - - /** - * Returns true if the modifiers include the static - * modifier. - */ - public static boolean isStatic(int mod) { - return (mod & STATIC) != 0; - } - - /** - * Returns true if the modifiers include the final - * modifier. - */ - public static boolean isFinal(int mod) { - return (mod & FINAL) != 0; - } - - /** - * Returns true if the modifiers include the synchronized - * modifier. - */ - public static boolean isSynchronized(int mod) { - return (mod & SYNCHRONIZED) != 0; - } - - /** - * Returns true if the modifiers include the volatile - * modifier. - */ - public static boolean isVolatile(int mod) { - return (mod & VOLATILE) != 0; - } - - /** - * Returns true if the modifiers include the transient - * modifier. - */ - public static boolean isTransient(int mod) { - return (mod & TRANSIENT) != 0; - } - - /** - * Returns true if the modifiers include the native - * modifier. - */ - public static boolean isNative(int mod) { - return (mod & NATIVE) != 0; - } - - /** - * Returns true if the modifiers include the interface - * modifier. - */ - public static boolean isInterface(int mod) { - return (mod & INTERFACE) != 0; - } - - /** - * Returns true if the modifiers include the annotation - * modifier. - * - * @since 3.2 - */ - public static boolean isAnnotation(int mod) { - return (mod & ANNOTATION) != 0; - } - - /** - * Returns true if the modifiers include the enum - * modifier. - * - * @since 3.2 - */ - public static boolean isEnum(int mod) { - return (mod & ENUM) != 0; - } - - /** - * Returns true if the modifiers include the abstract - * modifier. - */ - public static boolean isAbstract(int mod) { - return (mod & ABSTRACT) != 0; - } - - /** - * Returns true if the modifiers include the strictfp - * modifier. - */ - public static boolean isStrict(int mod) { - return (mod & STRICT) != 0; - } - - /** - * Truns the public bit on. The protected and private bits are - * cleared. - */ - public static int setPublic(int mod) { - return (mod & ~(PRIVATE | PROTECTED)) | PUBLIC; - } - - /** - * Truns the protected bit on. The protected and public bits are - * cleared. - */ - public static int setProtected(int mod) { - return (mod & ~(PRIVATE | PUBLIC)) | PROTECTED; - } - - /** - * Truns the private bit on. The protected and private bits are - * cleared. - */ - public static int setPrivate(int mod) { - return (mod & ~(PROTECTED | PUBLIC)) | PRIVATE; - } - - /** - * Clears the public, protected, and private bits. - */ - public static int setPackage(int mod) { - return (mod & ~(PROTECTED | PUBLIC | PRIVATE)); - } - - /** - * Clears a specified bit in mod. - */ - public static int clear(int mod, int clearBit) { - return mod & ~clearBit; - } - - /** - * Return a string describing the access modifier flags in - * the specified modifier. - * - * @param mod modifier flags. - */ - public static String toString(int mod) { - return java.lang.reflect.Modifier.toString(mod); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/NotFoundException.java b/fine-javassist/src/main/java/com/fr/third/javassist/NotFoundException.java deleted file mode 100644 index dbd9aafa5..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/NotFoundException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -/** - * Signals that something could not be found. - */ -public class NotFoundException extends Exception { - public NotFoundException(String msg) { - super(msg); - } - - public NotFoundException(String msg, Exception e) { - super(msg + " because of " + e.toString()); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/SerialVersionUID.java b/fine-javassist/src/main/java/com/fr/third/javassist/SerialVersionUID.java deleted file mode 100644 index 1f4eb1faa..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/SerialVersionUID.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import java.io.*; -import java.lang.reflect.Modifier; - -import com.fr.third.javassist.bytecode.ClassFile; - -import java.util.*; -import java.security.*; - -/** - * Utility for calculating serialVersionUIDs for Serializable classes. - * - * @author Bob Lee (crazybob@crazybob.org) - * @author modified by Shigeru Chiba - */ -public class SerialVersionUID { - - /** - * Adds serialVersionUID if one does not already exist. Call this before - * modifying a class to maintain serialization compatability. - */ - public static void setSerialVersionUID(com.fr.third.javassist.CtClass clazz) - throws com.fr.third.javassist.CannotCompileException, com.fr.third.javassist.NotFoundException - { - // check for pre-existing field. - try { - clazz.getDeclaredField("serialVersionUID"); - return; - } - catch (com.fr.third.javassist.NotFoundException e) {} - - // check if the class is serializable. - if (!isSerializable(clazz)) - return; - - // add field with default value. - com.fr.third.javassist.CtField field = new com.fr.third.javassist.CtField(com.fr.third.javassist.CtClass.longType, "serialVersionUID", - clazz); - field.setModifiers(Modifier.PRIVATE | Modifier.STATIC | - Modifier.FINAL); - clazz.addField(field, calculateDefault(clazz) + "L"); - } - - /** - * Does the class implement Serializable? - */ - private static boolean isSerializable(com.fr.third.javassist.CtClass clazz) - throws NotFoundException - { - ClassPool pool = clazz.getClassPool(); - return clazz.subtypeOf(pool.get("java.io.Serializable")); - } - - /** - * Calculate default value. See Java Serialization Specification, Stream - * Unique Identifiers. - */ - static long calculateDefault(com.fr.third.javassist.CtClass clazz) - throws com.fr.third.javassist.CannotCompileException - { - try { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(bout); - ClassFile classFile = clazz.getClassFile(); - - // class name. - String javaName = javaName(clazz); - out.writeUTF(javaName); - - com.fr.third.javassist.CtMethod[] methods = clazz.getDeclaredMethods(); - - // class modifiers. - int classMods = clazz.getModifiers(); - if ((classMods & Modifier.INTERFACE) != 0) - if (methods.length > 0) - classMods = classMods | Modifier.ABSTRACT; - else - classMods = classMods & ~Modifier.ABSTRACT; - - out.writeInt(classMods); - - // interfaces. - String[] interfaces = classFile.getInterfaces(); - for (int i = 0; i < interfaces.length; i++) - interfaces[i] = javaName(interfaces[i]); - - Arrays.sort(interfaces); - for (int i = 0; i < interfaces.length; i++) - out.writeUTF(interfaces[i]); - - // fields. - com.fr.third.javassist.CtField[] fields = clazz.getDeclaredFields(); - Arrays.sort(fields, new Comparator() { - public int compare(Object o1, Object o2) { - com.fr.third.javassist.CtField field1 = (com.fr.third.javassist.CtField)o1; - com.fr.third.javassist.CtField field2 = (com.fr.third.javassist.CtField)o2; - return field1.getName().compareTo(field2.getName()); - } - }); - - for (int i = 0; i < fields.length; i++) { - com.fr.third.javassist.CtField field = (CtField) fields[i]; - int mods = field.getModifiers(); - if (((mods & Modifier.PRIVATE) == 0) || - ((mods & (Modifier.STATIC | Modifier.TRANSIENT)) == 0)) { - out.writeUTF(field.getName()); - out.writeInt(mods); - out.writeUTF(field.getFieldInfo2().getDescriptor()); - } - } - - // static initializer. - if (classFile.getStaticInitializer() != null) { - out.writeUTF(""); - out.writeInt(Modifier.STATIC); - out.writeUTF("()V"); - } - - // constructors. - com.fr.third.javassist.CtConstructor[] constructors = clazz.getDeclaredConstructors(); - Arrays.sort(constructors, new Comparator() { - public int compare(Object o1, Object o2) { - com.fr.third.javassist.CtConstructor c1 = (com.fr.third.javassist.CtConstructor)o1; - com.fr.third.javassist.CtConstructor c2 = (com.fr.third.javassist.CtConstructor)o2; - return c1.getMethodInfo2().getDescriptor().compareTo( - c2.getMethodInfo2().getDescriptor()); - } - }); - - for (int i = 0; i < constructors.length; i++) { - CtConstructor constructor = constructors[i]; - int mods = constructor.getModifiers(); - if ((mods & Modifier.PRIVATE) == 0) { - out.writeUTF(""); - out.writeInt(mods); - out.writeUTF(constructor.getMethodInfo2() - .getDescriptor().replace('/', '.')); - } - } - - // methods. - Arrays.sort(methods, new Comparator() { - public int compare(Object o1, Object o2) { - com.fr.third.javassist.CtMethod m1 = (com.fr.third.javassist.CtMethod)o1; - com.fr.third.javassist.CtMethod m2 = (com.fr.third.javassist.CtMethod)o2; - int value = m1.getName().compareTo(m2.getName()); - if (value == 0) - value = m1.getMethodInfo2().getDescriptor() - .compareTo(m2.getMethodInfo2().getDescriptor()); - - return value; - } - }); - - for (int i = 0; i < methods.length; i++) { - CtMethod method = methods[i]; - int mods = method.getModifiers() - & (Modifier.PUBLIC | Modifier.PRIVATE - | Modifier.PROTECTED | Modifier.STATIC - | Modifier.FINAL | Modifier.SYNCHRONIZED - | Modifier.NATIVE | Modifier.ABSTRACT | Modifier.STRICT); - if ((mods & Modifier.PRIVATE) == 0) { - out.writeUTF(method.getName()); - out.writeInt(mods); - out.writeUTF(method.getMethodInfo2() - .getDescriptor().replace('/', '.')); - } - } - - // calculate hash. - out.flush(); - MessageDigest digest = MessageDigest.getInstance("SHA"); - byte[] digested = digest.digest(bout.toByteArray()); - long hash = 0; - for (int i = Math.min(digested.length, 8) - 1; i >= 0; i--) - hash = (hash << 8) | (digested[i] & 0xFF); - - return hash; - } - catch (IOException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - catch (NoSuchAlgorithmException e) { - throw new CannotCompileException(e); - } - } - - private static String javaName(CtClass clazz) { - return com.fr.third.javassist.bytecode.Descriptor.toJavaName(com.fr.third.javassist.bytecode.Descriptor.toJvmName(clazz)); - } - - private static String javaName(String name) { - return com.fr.third.javassist.bytecode.Descriptor.toJavaName(com.fr.third.javassist.bytecode.Descriptor.toJvmName(name)); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/Translator.java b/fine-javassist/src/main/java/com/fr/third/javassist/Translator.java deleted file mode 100644 index 049b7cc05..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/Translator.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -/** - * An observer of Loader. - * The users can define a class implementing this - * interface and attach an instance of that class to a - * Loader object so that it can translate a class file - * when the class file is loaded into the JVM. - * - * @see com.fr.third.javassist.Loader#addTranslator(com.fr.third.javassist.ClassPool, Translator) - */ -public interface Translator { - /** - * Is invoked by a Loader for initialization - * when the object is attached to the Loader object. - * This method can be used for getting (for caching) some - * CtClass objects that will be accessed - * in onLoad() in Translator. - * - * @param pool the ClassPool that this translator - * should use. - * @see com.fr.third.javassist.Loader - * @throws com.fr.third.javassist.NotFoundException if a CtClass cannot be found. - * @throws com.fr.third.javassist.CannotCompileException if the initialization by this method - * fails. - */ - void start(com.fr.third.javassist.ClassPool pool) - throws com.fr.third.javassist.NotFoundException, com.fr.third.javassist.CannotCompileException; - - /** - * Is invoked by a Loader for notifying that - * a class is loaded. The Loader calls - * - *

    -     * pool.get(classname).toBytecode()
- * - * to read the class file after onLoad() returns. - * - *

classname may be the name of a class - * that has not been created yet. - * If so, onLoad() must create that class so that - * the Loader can read it after onLoad() - * returns. - * - * @param pool the ClassPool that this translator - * should use. - * @param classname the name of the class being loaded. - * @see Loader - * @throws com.fr.third.javassist.NotFoundException if a CtClass cannot be found. - * @throws com.fr.third.javassist.CannotCompileException if the code transformation - * by this method fails. - */ - void onLoad(ClassPool pool, String classname) - throws NotFoundException, CannotCompileException; -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/URLClassPath.java b/fine-javassist/src/main/java/com/fr/third/javassist/URLClassPath.java deleted file mode 100644 index f83979e93..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/URLClassPath.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist; - -import java.io.*; -import java.net.*; - -/** - * A class search-path specified with URL (http). - * - * @see com.fr.third.javassist.ClassPath - * @see com.fr.third.javassist.ClassPool#insertClassPath(com.fr.third.javassist.ClassPath) - * @see ClassPool#appendClassPath(com.fr.third.javassist.ClassPath) - */ -public class URLClassPath implements ClassPath { - protected String hostname; - protected int port; - protected String directory; - protected String packageName; - - /** - * Creates a search path specified with URL (http). - * - *

This search path is used only if a requested - * class name starts with the name specified by packageName. - * If packageName is "org.javassist." and a requested class is - * "org.javassist.test.Main", then the given URL is used for loading that class. - * The URLClassPath obtains a class file from: - * - *

    http://www.javassist.org:80/java/classes/org/javassist/test/Main.class
    -     * 
- * - *

Here, we assume that host is "www.javassist.org", - * port is 80, and directory is "/java/classes/". - * - *

If packageName is null, the URL is used - * for loading any class. - * - * @param host host name - * @param port port number - * @param directory directory name ending with "/". - * It can be "/" (root directory). - * It must start with "/". - * @param packageName package name. It must end with "." (dot). - */ - public URLClassPath(String host, int port, - String directory, String packageName) { - hostname = host; - this.port = port; - this.directory = directory; - this.packageName = packageName; - } - - public String toString() { - return hostname + ":" + port + directory; - } - - /** - * Opens a class file with http. - * - * @return null if the class file could not be found. - */ - public InputStream openClassfile(String classname) { - try { - URLConnection con = openClassfile0(classname); - if (con != null) - return con.getInputStream(); - } - catch (IOException e) {} - return null; // not found - } - - private URLConnection openClassfile0(String classname) throws IOException { - if (packageName == null || classname.startsWith(packageName)) { - String jarname - = directory + classname.replace('.', '/') + ".class"; - return fetchClass0(hostname, port, jarname); - } - else - return null; // not found - } - - /** - * Returns the URL. - * - * @return null if the class file could not be obtained. - */ - public URL find(String classname) { - try { - URLConnection con = openClassfile0(classname); - InputStream is = con.getInputStream(); - if (is != null) { - is.close(); - return con.getURL(); - } - } - catch (IOException e) {} - return null; - } - - /** - * Closes this class path. - */ - public void close() {} - - /** - * Reads a class file on an http server. - * - * @param host host name - * @param port port number - * @param directory directory name ending with "/". - * It can be "/" (root directory). - * It must start with "/". - * @param classname fully-qualified class name - */ - public static byte[] fetchClass(String host, int port, - String directory, String classname) - throws IOException - { - byte[] b; - URLConnection con = fetchClass0(host, port, - directory + classname.replace('.', '/') + ".class"); - int size = con.getContentLength(); - InputStream s = con.getInputStream(); - try { - if (size <= 0) - b = com.fr.third.javassist.ClassPoolTail.readStream(s); - else { - b = new byte[size]; - int len = 0; - do { - int n = s.read(b, len, size - len); - if (n < 0) - throw new IOException("the stream was closed: " - + classname); - - len += n; - } while (len < size); - } - } - finally { - s.close(); - } - - return b; - } - - private static URLConnection fetchClass0(String host, int port, - String filename) - throws IOException - { - URL url; - try { - url = new URL("http", host, port, filename); - } - catch (MalformedURLException e) { - // should never reache here. - throw new IOException("invalid URL?"); - } - - URLConnection con = url.openConnection(); - con.connect(); - return con; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/AccessFlag.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/AccessFlag.java deleted file mode 100644 index 1977da7bc..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/AccessFlag.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -/** - * A support class providing static methods and constants - * for access modifiers such as public, rivate, ... - */ -public class AccessFlag { - public static final int PUBLIC = 0x0001; - public static final int PRIVATE = 0x0002; - public static final int PROTECTED = 0x0004; - public static final int STATIC = 0x0008; - public static final int FINAL = 0x0010; - public static final int SYNCHRONIZED = 0x0020; - public static final int VOLATILE = 0x0040; - public static final int BRIDGE = 0x0040; // for method_info - public static final int TRANSIENT = 0x0080; - public static final int VARARGS = 0x0080; // for method_info - public static final int NATIVE = 0x0100; - public static final int INTERFACE = 0x0200; - public static final int ABSTRACT = 0x0400; - public static final int STRICT = 0x0800; - public static final int SYNTHETIC = 0x1000; - public static final int ANNOTATION = 0x2000; - public static final int ENUM = 0x4000; - - public static final int SUPER = 0x0020; - - // Note: 0x0020 is assigned to both ACC_SUPER and ACC_SYNCHRONIZED - // although java.lang.reflect.Modifier does not recognize ACC_SUPER. - - /** - * Truns the public bit on. The protected and private bits are - * cleared. - */ - public static int setPublic(int accflags) { - return (accflags & ~(PRIVATE | PROTECTED)) | PUBLIC; - } - - /** - * Truns the protected bit on. The protected and public bits are - * cleared. - */ - public static int setProtected(int accflags) { - return (accflags & ~(PRIVATE | PUBLIC)) | PROTECTED; - } - - /** - * Truns the private bit on. The protected and private bits are - * cleared. - */ - public static int setPrivate(int accflags) { - return (accflags & ~(PROTECTED | PUBLIC)) | PRIVATE; - } - - /** - * Clears the public, protected, and private bits. - */ - public static int setPackage(int accflags) { - return (accflags & ~(PROTECTED | PUBLIC | PRIVATE)); - } - - /** - * Returns true if the access flags include the public bit. - */ - public static boolean isPublic(int accflags) { - return (accflags & PUBLIC) != 0; - } - - /** - * Returns true if the access flags include the protected bit. - */ - public static boolean isProtected(int accflags) { - return (accflags & PROTECTED) != 0; - } - - /** - * Returns true if the access flags include the private bit. - */ - public static boolean isPrivate(int accflags) { - return (accflags & PRIVATE) != 0; - } - - /** - * Returns true if the access flags include neither public, protected, - * or private. - */ - public static boolean isPackage(int accflags) { - return (accflags & (PROTECTED | PUBLIC | PRIVATE)) == 0; - } - - /** - * Clears a specified bit in accflags. - */ - public static int clear(int accflags, int clearBit) { - return accflags & ~clearBit; - } - - /** - * Converts a javassist.Modifier into - * a javassist.bytecode.AccessFlag. - * - * @param modifier javassist.Modifier - */ - public static int of(int modifier) { - return modifier; - } - - /** - * Converts a javassist.bytecode.AccessFlag - * into a javassist.Modifier. - * - * @param accflags javassist.bytecode.Accessflag - */ - public static int toModifier(int accflags) { - return accflags; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/AnnotationDefaultAttribute.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/AnnotationDefaultAttribute.java deleted file mode 100644 index 563f460d3..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/AnnotationDefaultAttribute.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.bytecode.annotation.Annotation; -import com.fr.third.javassist.bytecode.annotation.AnnotationsWriter; -import com.fr.third.javassist.bytecode.annotation.MemberValue; - -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.IOException; -import java.util.Map; - -/** - * A class representing AnnotationDefault_attribute. - * - *

For example, if you declare the following annotation type: - * - *

    - * @interface Author {
    - *   String name() default "Shakespeare";
    - *   int age() default 99;
    - * }
    - * 
- * - *

The defautl values of name and age - * are stored as annotation default attributes in Author.class. - * The following code snippet obtains the default value of name: - * - *

    - * ClassPool pool = ...
    - * CtClass cc = pool.get("Author");
    - * CtMethod cm = cc.getDeclaredMethod("age");
    - * MethodInfo minfo = cm.getMethodInfo();
    - * AnnotationDefaultAttribute ada
    - *         = (AnnotationDefaultAttribute)
    - *           minfo.getAttribute(AnnotationDefaultAttribute.tag);
    - * MemberValue value = ada.getDefaultValue());    // default value of age
    - * 
- * - *

If the following statement is executed after the code above, - * the default value of age is set to 80: - * - *

    - * ada.setDefaultValue(new IntegerMemberValue(minfo.getConstPool(), 80));
    - * 
- * - * @see com.fr.third.javassist.bytecode.AnnotationsAttribute - * @see MemberValue - */ - -public class AnnotationDefaultAttribute extends com.fr.third.javassist.bytecode.AttributeInfo { - /** - * The name of the AnnotationDefault attribute. - */ - public static final String tag = "AnnotationDefault"; - - /** - * Constructs an AnnotationDefault_attribute. - * - * @param cp constant pool - * @param info the contents of this attribute. It does not - * include attribute_name_index or - * attribute_length. - */ - public AnnotationDefaultAttribute(com.fr.third.javassist.bytecode.ConstPool cp, byte[] info) { - super(cp, tag, info); - } - - /** - * Constructs an empty AnnotationDefault_attribute. - * The default value can be set by setDefaultValue(). - * - * @param cp constant pool - * @see #setDefaultValue(MemberValue) - */ - public AnnotationDefaultAttribute(com.fr.third.javassist.bytecode.ConstPool cp) { - this(cp, new byte[] { 0, 0 }); - } - - /** - * @param n the attribute name. - */ - AnnotationDefaultAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int n, DataInputStream in) - throws IOException - { - super(cp, n, in); - } - - /** - * Copies this attribute and returns a new copy. - */ - public AttributeInfo copy(com.fr.third.javassist.bytecode.ConstPool newCp, Map classnames) { - com.fr.third.javassist.bytecode.AnnotationsAttribute.Copier copier - = new com.fr.third.javassist.bytecode.AnnotationsAttribute.Copier(info, constPool, newCp, classnames); - try { - copier.memberValue(0); - return new AnnotationDefaultAttribute(newCp, copier.close()); - } - catch (Exception e) { - throw new RuntimeException(e.toString()); - } - } - - /** - * Obtains the default value represented by this attribute. - */ - public MemberValue getDefaultValue() - { - try { - return new AnnotationsAttribute.Parser(info, constPool) - .parseMemberValue(); - } - catch (Exception e) { - throw new RuntimeException(e.toString()); - } - } - - /** - * Changes the default value represented by this attribute. - * - * @param value the new value. - * @see Annotation#createMemberValue(ConstPool, CtClass) - */ - public void setDefaultValue(MemberValue value) { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - AnnotationsWriter writer = new AnnotationsWriter(output, constPool); - try { - value.write(writer); - writer.close(); - } - catch (IOException e) { - throw new RuntimeException(e); // should never reach here. - } - - set(output.toByteArray()); - - } - - /** - * Returns a string representation of this object. - */ - public String toString() { - return getDefaultValue().toString(); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/AnnotationsAttribute.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/AnnotationsAttribute.java deleted file mode 100644 index 739c32f1a..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/AnnotationsAttribute.java +++ /dev/null @@ -1,703 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.util.Map; -import java.util.HashMap; -import java.io.IOException; -import java.io.DataInputStream; -import java.io.ByteArrayOutputStream; - -import com.fr.third.javassist.bytecode.annotation.ClassMemberValue; - -/** - * A class representing - * RuntimeVisibleAnnotations_attribute and - * RuntimeInvisibleAnnotations_attribute. - * - *

To obtain an AnnotationAttribute object, invoke - * getAttribute(AnnotationsAttribute.visibleTag) - * in ClassFile, MethodInfo, - * or FieldInfo. The obtained attribute is a - * runtime visible annotations attribute. - * If the parameter is - * AnnotationAttribute.invisibleTag, then the obtained - * attribute is a runtime invisible one. - * - *

For example, - * - *

    - * import javassist.bytecode.annotation.Annotation;
    - *    :
    - * CtMethod m = ... ;
    - * MethodInfo minfo = m.getMethodInfo();
    - * AnnotationsAttribute attr = (AnnotationsAttribute)
    - *         minfo.getAttribute(AnnotationsAttribute.invisibleTag);
    - * Annotation an = attr.getAnnotation("Author");
    - * String s = ((StringMemberValue)an.getMemberValue("name")).getValue();
    - * System.out.println("@Author(name=" + s + ")");
    - * 
- * - *

This code snippet retrieves an annotation of the type Author - * from the MethodInfo object specified by minfo. - * Then, it prints the value of name in Author. - * - *

If the annotation type Author is annotated by a meta annotation: - * - *

    - * @Retention(RetentionPolicy.RUNTIME)
    - * 
- * - *

Then Author is visible at runtime. Therefore, the third - * statement of the code snippet above must be changed into: - * - *

    - * AnnotationsAttribute attr = (AnnotationsAttribute)
    - *         minfo.getAttribute(AnnotationsAttribute.visibleTag);
    - * 
- * - *

The attribute tag must be visibleTag instead of - * invisibleTag. - * - *

If the member value of an annotation is not specified, the default value - * is used as that member value. If so, getMemberValue() in - * Annotation returns null - * since the default value is not included in the - * AnnotationsAttribute. It is included in the - * AnnotationDefaultAttribute of the method declared in the - * annotation type. - * - *

If you want to record a new AnnotationAttribute object, execute the - * following snippet: - * - *

    - * ClassFile cf = ... ;
    - * ConstPool cp = cf.getConstPool();
    - * AnnotationsAttribute attr
    - *     = new AnnotationsAttribute(cp, AnnotationsAttribute.visibleTag);
    - * Annotation a = new Annotation("Author", cp);
    - * a.addMemberValue("name", new StringMemberValue("Chiba", cp));
    - * attr.setAnnotation(a);
    - * cf.addAttribute(attr);
    - * cf.setVersionToJava5();
    - * 
- * - *

The last statement is necessary if the class file was produced by - * Javassist or JDK 1.4. Otherwise, it is not necessary. - * - * @see AnnotationDefaultAttribute - * @see com.fr.third.javassist.bytecode.annotation.Annotation - */ -public class AnnotationsAttribute extends com.fr.third.javassist.bytecode.AttributeInfo { - /** - * The name of the RuntimeVisibleAnnotations attribute. - */ - public static final String visibleTag = "RuntimeVisibleAnnotations"; - - /** - * The name of the RuntimeInvisibleAnnotations attribute. - */ - public static final String invisibleTag = "RuntimeInvisibleAnnotations"; - - /** - * Constructs a Runtime(In)VisibleAnnotations_attribute. - * - * @param cp constant pool - * @param attrname attribute name (visibleTag or - * invisibleTag). - * @param info the contents of this attribute. It does not - * include attribute_name_index or - * attribute_length. - */ - public AnnotationsAttribute(com.fr.third.javassist.bytecode.ConstPool cp, String attrname, byte[] info) { - super(cp, attrname, info); - } - - /** - * Constructs an empty - * Runtime(In)VisibleAnnotations_attribute. - * A new annotation can be later added to the created attribute - * by setAnnotations(). - * - * @param cp constant pool - * @param attrname attribute name (visibleTag or - * invisibleTag). - * @see #setAnnotations(com.fr.third.javassist.bytecode.annotation.Annotation[]) - */ - public AnnotationsAttribute(com.fr.third.javassist.bytecode.ConstPool cp, String attrname) { - this(cp, attrname, new byte[] { 0, 0 }); - } - - /** - * @param n the attribute name. - */ - AnnotationsAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int n, DataInputStream in) - throws IOException - { - super(cp, n, in); - } - - /** - * Returns num_annotations. - */ - public int numAnnotations() { - return com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, 0); - } - - /** - * Copies this attribute and returns a new copy. - */ - public AttributeInfo copy(com.fr.third.javassist.bytecode.ConstPool newCp, Map classnames) { - Copier copier = new Copier(info, constPool, newCp, classnames); - try { - copier.annotationArray(); - return new AnnotationsAttribute(newCp, getName(), copier.close()); - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * Parses the annotations and returns a data structure representing - * the annotation with the specified type. See also - * getAnnotations() as to the returned data structure. - * - * @param type the annotation type. - * @return null if the specified annotation type is not included. - * @see #getAnnotations() - */ - public com.fr.third.javassist.bytecode.annotation.Annotation getAnnotation(String type) { - com.fr.third.javassist.bytecode.annotation.Annotation[] annotations = getAnnotations(); - for (int i = 0; i < annotations.length; i++) { - if (annotations[i].getTypeName().equals(type)) - return annotations[i]; - } - - return null; - } - - /** - * Adds an annotation. If there is an annotation with the same type, - * it is removed before the new annotation is added. - * - * @param annotation the added annotation. - */ - public void addAnnotation(com.fr.third.javassist.bytecode.annotation.Annotation annotation) { - String type = annotation.getTypeName(); - com.fr.third.javassist.bytecode.annotation.Annotation[] annotations = getAnnotations(); - for (int i = 0; i < annotations.length; i++) { - if (annotations[i].getTypeName().equals(type)) { - annotations[i] = annotation; - setAnnotations(annotations); - return; - } - } - - com.fr.third.javassist.bytecode.annotation.Annotation[] newlist = new com.fr.third.javassist.bytecode.annotation.Annotation[annotations.length + 1]; - System.arraycopy(annotations, 0, newlist, 0, annotations.length); - newlist[annotations.length] = annotation; - setAnnotations(newlist); - } - - /** - * Parses the annotations and returns a data structure representing - * that parsed annotations. Note that changes of the node values of the - * returned tree are not reflected on the annotations represented by - * this object unless the tree is copied back to this object by - * setAnnotations(). - * - * @see #setAnnotations(com.fr.third.javassist.bytecode.annotation.Annotation[]) - */ - public com.fr.third.javassist.bytecode.annotation.Annotation[] getAnnotations() { - try { - return new Parser(info, constPool).parseAnnotations(); - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * Changes the annotations represented by this object according to - * the given array of Annotation objects. - * - * @param annotations the data structure representing the - * new annotations. - */ - public void setAnnotations(com.fr.third.javassist.bytecode.annotation.Annotation[] annotations) { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - com.fr.third.javassist.bytecode.annotation.AnnotationsWriter writer = new com.fr.third.javassist.bytecode.annotation.AnnotationsWriter(output, constPool); - try { - int n = annotations.length; - writer.numAnnotations(n); - for (int i = 0; i < n; ++i) - annotations[i].write(writer); - - writer.close(); - } - catch (IOException e) { - throw new RuntimeException(e); // should never reach here. - } - - set(output.toByteArray()); - } - - /** - * Changes the annotations. A call to this method is equivalent to: - *

    setAnnotations(new Annotation[] { annotation })
- * - * @param annotation the data structure representing - * the new annotation. - */ - public void setAnnotation(com.fr.third.javassist.bytecode.annotation.Annotation annotation) { - setAnnotations(new com.fr.third.javassist.bytecode.annotation.Annotation[] { annotation }); - } - - /** - * @param oldname a JVM class name. - * @param newname a JVM class name. - */ - void renameClass(String oldname, String newname) { - HashMap map = new HashMap(); - map.put(oldname, newname); - renameClass(map); - } - - void renameClass(Map classnames) { - Renamer renamer = new Renamer(info, getConstPool(), classnames); - try { - renamer.annotationArray(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - void getRefClasses(Map classnames) { renameClass(classnames); } - - /** - * Returns a string representation of this object. - */ - public String toString() { - com.fr.third.javassist.bytecode.annotation.Annotation[] a = getAnnotations(); - StringBuilder sbuf = new StringBuilder(); - int i = 0; - while (i < a.length) { - sbuf.append(a[i++].toString()); - if (i != a.length) - sbuf.append(", "); - } - - return sbuf.toString(); - } - - static class Walker { - byte[] info; - - Walker(byte[] attrInfo) { - info = attrInfo; - } - - final void parameters() throws Exception { - int numParam = info[0] & 0xff; - parameters(numParam, 1); - } - - void parameters(int numParam, int pos) throws Exception { - for (int i = 0; i < numParam; ++i) - pos = annotationArray(pos); - } - - final void annotationArray() throws Exception { - annotationArray(0); - } - - final int annotationArray(int pos) throws Exception { - int num = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos); - return annotationArray(pos + 2, num); - } - - int annotationArray(int pos, int num) throws Exception { - for (int i = 0; i < num; ++i) - pos = annotation(pos); - - return pos; - } - - final int annotation(int pos) throws Exception { - int type = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos); - int numPairs = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos + 2); - return annotation(pos + 4, type, numPairs); - } - - int annotation(int pos, int type, int numPairs) throws Exception { - for (int j = 0; j < numPairs; ++j) - pos = memberValuePair(pos); - - return pos; - } - - final int memberValuePair(int pos) throws Exception { - int nameIndex = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos); - return memberValuePair(pos + 2, nameIndex); - } - - int memberValuePair(int pos, int nameIndex) throws Exception { - return memberValue(pos); - } - - final int memberValue(int pos) throws Exception { - int tag = info[pos] & 0xff; - if (tag == 'e') { - int typeNameIndex = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos + 1); - int constNameIndex = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos + 3); - enumMemberValue(pos, typeNameIndex, constNameIndex); - return pos + 5; - } - else if (tag == 'c') { - int index = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos + 1); - classMemberValue(pos, index); - return pos + 3; - } - else if (tag == '@') - return annotationMemberValue(pos + 1); - else if (tag == '[') { - int num = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos + 1); - return arrayMemberValue(pos + 3, num); - } - else { // primitive types or String. - int index = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos + 1); - constValueMember(tag, index); - return pos + 3; - } - } - - void constValueMember(int tag, int index) throws Exception {} - - void enumMemberValue(int pos, int typeNameIndex, int constNameIndex) - throws Exception { - } - - void classMemberValue(int pos, int index) throws Exception {} - - int annotationMemberValue(int pos) throws Exception { - return annotation(pos); - } - - int arrayMemberValue(int pos, int num) throws Exception { - for (int i = 0; i < num; ++i) { - pos = memberValue(pos); - } - - return pos; - } - } - - static class Renamer extends Walker { - com.fr.third.javassist.bytecode.ConstPool cpool; - Map classnames; - - /** - * Constructs a renamer. It renames some class names - * into the new names specified by map. - * - * @param info the annotations attribute. - * @param cp the constant pool. - * @param map pairs of replaced and substituted class names. - * It can be null. - */ - Renamer(byte[] info, com.fr.third.javassist.bytecode.ConstPool cp, Map map) { - super(info); - cpool = cp; - classnames = map; - } - - int annotation(int pos, int type, int numPairs) throws Exception { - renameType(pos - 4, type); - return super.annotation(pos, type, numPairs); - } - - void enumMemberValue(int pos, int typeNameIndex, int constNameIndex) - throws Exception - { - renameType(pos + 1, typeNameIndex); - super.enumMemberValue(pos, typeNameIndex, constNameIndex); - } - - void classMemberValue(int pos, int index) throws Exception { - renameType(pos + 1, index); - super.classMemberValue(pos, index); - } - - private void renameType(int pos, int index) { - String name = cpool.getUtf8Info(index); - String newName = com.fr.third.javassist.bytecode.Descriptor.rename(name, classnames); - if (!name.equals(newName)) { - int index2 = cpool.addUtf8Info(newName); - ByteArray.write16bit(index2, info, pos); - } - } - } - - static class Copier extends Walker { - ByteArrayOutputStream output; - com.fr.third.javassist.bytecode.annotation.AnnotationsWriter writer; - com.fr.third.javassist.bytecode.ConstPool srcPool, destPool; - Map classnames; - - /** - * Constructs a copier. This copier renames some class names - * into the new names specified by map when it copies - * an annotation attribute. - * - * @param info the source attribute. - * @param src the constant pool of the source class. - * @param dest the constant pool of the destination class. - * @param map pairs of replaced and substituted class names. - * It can be null. - */ - Copier(byte[] info, com.fr.third.javassist.bytecode.ConstPool src, com.fr.third.javassist.bytecode.ConstPool dest, Map map) { - super(info); - output = new ByteArrayOutputStream(); - writer = new com.fr.third.javassist.bytecode.annotation.AnnotationsWriter(output, dest); - srcPool = src; - destPool = dest; - classnames = map; - } - - byte[] close() throws IOException { - writer.close(); - return output.toByteArray(); - } - - void parameters(int numParam, int pos) throws Exception { - writer.numParameters(numParam); - super.parameters(numParam, pos); - } - - int annotationArray(int pos, int num) throws Exception { - writer.numAnnotations(num); - return super.annotationArray(pos, num); - } - - int annotation(int pos, int type, int numPairs) throws Exception { - writer.annotation(copyType(type), numPairs); - return super.annotation(pos, type, numPairs); - } - - int memberValuePair(int pos, int nameIndex) throws Exception { - writer.memberValuePair(copy(nameIndex)); - return super.memberValuePair(pos, nameIndex); - } - - void constValueMember(int tag, int index) throws Exception { - writer.constValueIndex(tag, copy(index)); - super.constValueMember(tag, index); - } - - void enumMemberValue(int pos, int typeNameIndex, int constNameIndex) - throws Exception - { - writer.enumConstValue(copyType(typeNameIndex), copy(constNameIndex)); - super.enumMemberValue(pos, typeNameIndex, constNameIndex); - } - - void classMemberValue(int pos, int index) throws Exception { - writer.classInfoIndex(copyType(index)); - super.classMemberValue(pos, index); - } - - int annotationMemberValue(int pos) throws Exception { - writer.annotationValue(); - return super.annotationMemberValue(pos); - } - - int arrayMemberValue(int pos, int num) throws Exception { - writer.arrayValue(num); - return super.arrayMemberValue(pos, num); - } - - /** - * Copies a constant pool entry into the destination constant pool - * and returns the index of the copied entry. - * - * @param srcIndex the index of the copied entry into the source - * constant pool. - * @return the index of the copied item into the destination - * constant pool. - */ - int copy(int srcIndex) { - return srcPool.copy(srcIndex, destPool, classnames); - } - - /** - * Copies a constant pool entry into the destination constant pool - * and returns the index of the copied entry. That entry must be - * a Utf8Info representing a class name in the L; form. - * - * @param srcIndex the index of the copied entry into the source - * constant pool. - * @return the index of the copied item into the destination - * constant pool. - */ - int copyType(int srcIndex) { - String name = srcPool.getUtf8Info(srcIndex); - String newName = Descriptor.rename(name, classnames); - return destPool.addUtf8Info(newName); - } - } - - static class Parser extends Walker { - com.fr.third.javassist.bytecode.ConstPool pool; - com.fr.third.javassist.bytecode.annotation.Annotation[][] allParams; // all parameters - com.fr.third.javassist.bytecode.annotation.Annotation[] allAnno; // all annotations - com.fr.third.javassist.bytecode.annotation.Annotation currentAnno; // current annotation - com.fr.third.javassist.bytecode.annotation.MemberValue currentMember; // current member - - /** - * Constructs a parser. This parser constructs a parse tree of - * the annotations. - * - * @param info the attribute. - * @param src the constant pool. - */ - Parser(byte[] info, com.fr.third.javassist.bytecode.ConstPool cp) { - super(info); - pool = cp; - } - - com.fr.third.javassist.bytecode.annotation.Annotation[][] parseParameters() throws Exception { - parameters(); - return allParams; - } - - com.fr.third.javassist.bytecode.annotation.Annotation[] parseAnnotations() throws Exception { - annotationArray(); - return allAnno; - } - - com.fr.third.javassist.bytecode.annotation.MemberValue parseMemberValue() throws Exception { - memberValue(0); - return currentMember; - } - - void parameters(int numParam, int pos) throws Exception { - com.fr.third.javassist.bytecode.annotation.Annotation[][] params = new com.fr.third.javassist.bytecode.annotation.Annotation[numParam][]; - for (int i = 0; i < numParam; ++i) { - pos = annotationArray(pos); - params[i] = allAnno; - } - - allParams = params; - } - - int annotationArray(int pos, int num) throws Exception { - com.fr.third.javassist.bytecode.annotation.Annotation[] array = new com.fr.third.javassist.bytecode.annotation.Annotation[num]; - for (int i = 0; i < num; ++i) { - pos = annotation(pos); - array[i] = currentAnno; - } - - allAnno = array; - return pos; - } - - int annotation(int pos, int type, int numPairs) throws Exception { - currentAnno = new com.fr.third.javassist.bytecode.annotation.Annotation(type, pool); - return super.annotation(pos, type, numPairs); - } - - int memberValuePair(int pos, int nameIndex) throws Exception { - pos = super.memberValuePair(pos, nameIndex); - currentAnno.addMemberValue(nameIndex, currentMember); - return pos; - } - - void constValueMember(int tag, int index) throws Exception { - com.fr.third.javassist.bytecode.annotation.MemberValue m; - ConstPool cp = pool; - switch (tag) { - case 'B' : - m = new com.fr.third.javassist.bytecode.annotation.ByteMemberValue(index, cp); - break; - case 'C' : - m = new com.fr.third.javassist.bytecode.annotation.CharMemberValue(index, cp); - break; - case 'D' : - m = new com.fr.third.javassist.bytecode.annotation.DoubleMemberValue(index, cp); - break; - case 'F' : - m = new com.fr.third.javassist.bytecode.annotation.FloatMemberValue(index, cp); - break; - case 'I' : - m = new com.fr.third.javassist.bytecode.annotation.IntegerMemberValue(index, cp); - break; - case 'J' : - m = new com.fr.third.javassist.bytecode.annotation.LongMemberValue(index, cp); - break; - case 'S' : - m = new com.fr.third.javassist.bytecode.annotation.ShortMemberValue(index, cp); - break; - case 'Z' : - m = new com.fr.third.javassist.bytecode.annotation.BooleanMemberValue(index, cp); - break; - case 's' : - m = new com.fr.third.javassist.bytecode.annotation.StringMemberValue(index, cp); - break; - default : - throw new RuntimeException("unknown tag:" + tag); - } - - currentMember = m; - super.constValueMember(tag, index); - } - - void enumMemberValue(int pos, int typeNameIndex, int constNameIndex) - throws Exception - { - currentMember = new com.fr.third.javassist.bytecode.annotation.EnumMemberValue(typeNameIndex, - constNameIndex, pool); - super.enumMemberValue(pos, typeNameIndex, constNameIndex); - } - - void classMemberValue(int pos, int index) throws Exception { - currentMember = new ClassMemberValue(index, pool); - super.classMemberValue(pos, index); - } - - int annotationMemberValue(int pos) throws Exception { - com.fr.third.javassist.bytecode.annotation.Annotation anno = currentAnno; - pos = super.annotationMemberValue(pos); - currentMember = new com.fr.third.javassist.bytecode.annotation.AnnotationMemberValue(currentAnno, pool); - currentAnno = anno; - return pos; - } - - int arrayMemberValue(int pos, int num) throws Exception { - com.fr.third.javassist.bytecode.annotation.ArrayMemberValue amv = new com.fr.third.javassist.bytecode.annotation.ArrayMemberValue(pool); - com.fr.third.javassist.bytecode.annotation.MemberValue[] elements = new com.fr.third.javassist.bytecode.annotation.MemberValue[num]; - for (int i = 0; i < num; ++i) { - pos = memberValue(pos); - elements[i] = currentMember; - } - - amv.setValue(elements); - currentMember = amv; - return pos; - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/AttributeInfo.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/AttributeInfo.java deleted file mode 100644 index 2a1858fe3..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/AttributeInfo.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.Map; -import java.util.ArrayList; -import java.util.ListIterator; -import java.util.List; -import java.util.Iterator; - -// Note: if you define a new subclass of AttributeInfo, then -// update AttributeInfo.read(), .copy(), and (maybe) write(). - -/** - * attribute_info structure. - */ -public class AttributeInfo { - protected com.fr.third.javassist.bytecode.ConstPool constPool; - int name; - byte[] info; - - protected AttributeInfo(com.fr.third.javassist.bytecode.ConstPool cp, int attrname, byte[] attrinfo) { - constPool = cp; - name = attrname; - info = attrinfo; - } - - protected AttributeInfo(com.fr.third.javassist.bytecode.ConstPool cp, String attrname) { - this(cp, attrname, (byte[])null); - } - - /** - * Constructs an attribute_info structure. - * - * @param cp constant pool table - * @param attrname attribute name - * @param attrinfo info field - * of attribute_info structure. - */ - public AttributeInfo(com.fr.third.javassist.bytecode.ConstPool cp, String attrname, byte[] attrinfo) { - this(cp, cp.addUtf8Info(attrname), attrinfo); - } - - protected AttributeInfo(com.fr.third.javassist.bytecode.ConstPool cp, int n, DataInputStream in) - throws IOException - { - constPool = cp; - name = n; - int len = in.readInt(); - info = new byte[len]; - if (len > 0) - in.readFully(info); - } - - static AttributeInfo read(com.fr.third.javassist.bytecode.ConstPool cp, DataInputStream in) - throws IOException - { - int name = in.readUnsignedShort(); - String nameStr = cp.getUtf8Info(name); - if (nameStr.charAt(0) < 'L') { - if (nameStr.equals(AnnotationDefaultAttribute.tag)) - return new AnnotationDefaultAttribute(cp, name, in); - else if (nameStr.equals(BootstrapMethodsAttribute.tag)) - return new BootstrapMethodsAttribute(cp, name, in); - else if (nameStr.equals(CodeAttribute.tag)) - return new CodeAttribute(cp, name, in); - else if (nameStr.equals(ConstantAttribute.tag)) - return new ConstantAttribute(cp, name, in); - else if (nameStr.equals(DeprecatedAttribute.tag)) - return new DeprecatedAttribute(cp, name, in); - else if (nameStr.equals(EnclosingMethodAttribute.tag)) - return new EnclosingMethodAttribute(cp, name, in); - else if (nameStr.equals(ExceptionsAttribute.tag)) - return new ExceptionsAttribute(cp, name, in); - else if (nameStr.equals(InnerClassesAttribute.tag)) - return new InnerClassesAttribute(cp, name, in); - } - else { - /* Note that the names of Annotations attributes begin with 'R'. - */ - if (nameStr.equals(LineNumberAttribute.tag)) - return new LineNumberAttribute(cp, name, in); - else if (nameStr.equals(LocalVariableAttribute.tag)) - return new LocalVariableAttribute(cp, name, in); - else if (nameStr.equals(LocalVariableTypeAttribute.tag)) - return new LocalVariableTypeAttribute(cp, name, in); - else if (nameStr.equals(AnnotationsAttribute.visibleTag) - || nameStr.equals(AnnotationsAttribute.invisibleTag)) { - // RuntimeVisibleAnnotations or RuntimeInvisibleAnnotations - return new AnnotationsAttribute(cp, name, in); - } - else if (nameStr.equals(ParameterAnnotationsAttribute.visibleTag) - || nameStr.equals(ParameterAnnotationsAttribute.invisibleTag)) - return new ParameterAnnotationsAttribute(cp, name, in); - else if (nameStr.equals(SignatureAttribute.tag)) - return new SignatureAttribute(cp, name, in); - else if (nameStr.equals(SourceFileAttribute.tag)) - return new SourceFileAttribute(cp, name, in); - else if (nameStr.equals(SyntheticAttribute.tag)) - return new SyntheticAttribute(cp, name, in); - else if (nameStr.equals(com.fr.third.javassist.bytecode.StackMap.tag)) - return new StackMap(cp, name, in); - else if (nameStr.equals(StackMapTable.tag)) - return new StackMapTable(cp, name, in); - } - - return new AttributeInfo(cp, name, in); - } - - /** - * Returns an attribute name. - */ - public String getName() { - return constPool.getUtf8Info(name); - } - - /** - * Returns a constant pool table. - */ - public com.fr.third.javassist.bytecode.ConstPool getConstPool() { return constPool; } - - /** - * Returns the length of this attribute_info - * structure. - * The returned value is attribute_length + 6. - */ - public int length() { - return info.length + 6; - } - - /** - * Returns the info field - * of this attribute_info structure. - * - *

This method is not available if the object is an instance - * of CodeAttribute. - */ - public byte[] get() { return info; } - - /** - * Sets the info field - * of this attribute_info structure. - * - *

This method is not available if the object is an instance - * of CodeAttribute. - */ - public void set(byte[] newinfo) { info = newinfo; } - - /** - * Makes a copy. Class names are replaced according to the - * given Map object. - * - * @param newCp the constant pool table used by the new copy. - * @param classnames pairs of replaced and substituted - * class names. - */ - public AttributeInfo copy(com.fr.third.javassist.bytecode.ConstPool newCp, Map classnames) { - int s = info.length; - byte[] srcInfo = info; - byte[] newInfo = new byte[s]; - for (int i = 0; i < s; ++i) - newInfo[i] = srcInfo[i]; - - return new AttributeInfo(newCp, getName(), newInfo); - } - - void write(DataOutputStream out) throws IOException { - out.writeShort(name); - out.writeInt(info.length); - if (info.length > 0) - out.write(info); - } - - static int getLength(ArrayList list) { - int size = 0; - int n = list.size(); - for (int i = 0; i < n; ++i) { - AttributeInfo attr = (AttributeInfo)list.get(i); - size += attr.length(); - } - - return size; - } - - static AttributeInfo lookup(ArrayList list, String name) { - if (list == null) - return null; - - ListIterator iterator = list.listIterator(); - while (iterator.hasNext()) { - AttributeInfo ai = (AttributeInfo)iterator.next(); - if (ai.getName().equals(name)) - return ai; - } - - return null; // no such attribute - } - - static synchronized void remove(ArrayList list, String name) { - if (list == null) - return; - - ListIterator iterator = list.listIterator(); - while (iterator.hasNext()) { - AttributeInfo ai = (AttributeInfo)iterator.next(); - if (ai.getName().equals(name)) - iterator.remove(); - } - } - - static void writeAll(ArrayList list, DataOutputStream out) - throws IOException - { - if (list == null) - return; - - int n = list.size(); - for (int i = 0; i < n; ++i) { - AttributeInfo attr = (AttributeInfo)list.get(i); - attr.write(out); - } - } - - static ArrayList copyAll(ArrayList list, ConstPool cp) { - if (list == null) - return null; - - ArrayList newList = new ArrayList(); - int n = list.size(); - for (int i = 0; i < n; ++i) { - AttributeInfo attr = (AttributeInfo)list.get(i); - newList.add(attr.copy(cp, null)); - } - - return newList; - } - - /* The following two methods are used to implement - * ClassFile.renameClass(). - * Only CodeAttribute, LocalVariableAttribute, - * AnnotationsAttribute, and SignatureAttribute - * override these methods. - */ - void renameClass(String oldname, String newname) {} - void renameClass(Map classnames) {} - - static void renameClass(List attributes, String oldname, String newname) { - Iterator iterator = attributes.iterator(); - while (iterator.hasNext()) { - AttributeInfo ai = (AttributeInfo)iterator.next(); - ai.renameClass(oldname, newname); - } - } - - static void renameClass(List attributes, Map classnames) { - Iterator iterator = attributes.iterator(); - while (iterator.hasNext()) { - AttributeInfo ai = (AttributeInfo)iterator.next(); - ai.renameClass(classnames); - } - } - - void getRefClasses(Map classnames) {} - - static void getRefClasses(List attributes, Map classnames) { - Iterator iterator = attributes.iterator(); - while (iterator.hasNext()) { - AttributeInfo ai = (AttributeInfo)iterator.next(); - ai.getRefClasses(classnames); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/BadBytecode.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/BadBytecode.java deleted file mode 100644 index a14ec04ab..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/BadBytecode.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -/** - * Signals that a bad bytecode sequence has been found. - */ -public class BadBytecode extends Exception { - public BadBytecode(int opcode) { - super("bytecode " + opcode); - } - - public BadBytecode(String msg) { - super(msg); - } - - public BadBytecode(String msg, Throwable cause) { - super(msg, cause); - } - - public BadBytecode(MethodInfo minfo, Throwable cause) { - super(minfo.toString() + " in " - + minfo.getConstPool().getClassName() - + ": " + cause.getMessage(), cause); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/BootstrapMethodsAttribute.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/BootstrapMethodsAttribute.java deleted file mode 100644 index a2579083e..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/BootstrapMethodsAttribute.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.IOException; -import java.util.Map; - -public class BootstrapMethodsAttribute extends com.fr.third.javassist.bytecode.AttributeInfo { - /** - * The name of this attribute "BootstrapMethods". - */ - public static final String tag = "BootstrapMethods"; - - /** - * An element of bootstrap_methods. - */ - public static class BootstrapMethod { - /** - * Constructs an element of bootstrap_methods. - * - * @param method bootstrap_method_ref. - * @param args bootstrap_arguments. - */ - public BootstrapMethod(int method, int[] args) { - methodRef = method; - arguments = args; - } - - /** - * bootstrap_method_ref. - * The value at this index must be a CONSTANT_MethodHandle_info. - */ - public int methodRef; - - /** - * bootstrap_arguments. - */ - public int[] arguments; - } - - BootstrapMethodsAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int n, DataInputStream in) - throws IOException - { - super(cp, n, in); - } - - /** - * Constructs a BootstrapMethods attribute. - * - * @param cp a constant pool table. - * @param methods the contents. - */ - public BootstrapMethodsAttribute(com.fr.third.javassist.bytecode.ConstPool cp, BootstrapMethod[] methods) { - super(cp, tag); - int size = 2; - for (int i = 0; i < methods.length; i++) - size += 4 + methods[i].arguments.length * 2; - - byte[] data = new byte[size]; - com.fr.third.javassist.bytecode.ByteArray.write16bit(methods.length, data, 0); // num_bootstrap_methods - int pos = 2; - for (int i = 0; i < methods.length; i++) { - com.fr.third.javassist.bytecode.ByteArray.write16bit(methods[i].methodRef, data, pos); - com.fr.third.javassist.bytecode.ByteArray.write16bit(methods[i].arguments.length, data, pos + 2); - int[] args = methods[i].arguments; - pos += 4; - for (int k = 0; k < args.length; k++) { - com.fr.third.javassist.bytecode.ByteArray.write16bit(args[k], data, pos); - pos += 2; - } - } - - set(data); - } - - /** - * Obtains bootstrap_methods in this attribute. - * - * @return an array of BootstrapMethod. Since it - * is a fresh copy, modifying the returned array does not - * affect the original contents of this attribute. - */ - public BootstrapMethod[] getMethods() { - byte[] data = this.get(); - int num = com.fr.third.javassist.bytecode.ByteArray.readU16bit(data, 0); - BootstrapMethod[] methods = new BootstrapMethod[num]; - int pos = 2; - for (int i = 0; i < num; i++) { - int ref = com.fr.third.javassist.bytecode.ByteArray.readU16bit(data, pos); - int len = com.fr.third.javassist.bytecode.ByteArray.readU16bit(data, pos + 2); - int[] args = new int[len]; - pos += 4; - for (int k = 0; k < len; k++) { - args[k] = ByteArray.readU16bit(data, pos); - pos += 2; - } - - methods[i] = new BootstrapMethod(ref, args); - } - - return methods; - } - - /** - * Makes a copy. Class names are replaced according to the - * given Map object. - * - * @param newCp the constant pool table used by the new copy. - * @param classnames pairs of replaced and substituted - * class names. - */ - public AttributeInfo copy(com.fr.third.javassist.bytecode.ConstPool newCp, Map classnames) { - BootstrapMethod[] methods = getMethods(); - ConstPool thisCp = getConstPool(); - for (int i = 0; i < methods.length; i++) { - BootstrapMethod m = methods[i]; - m.methodRef = thisCp.copy(m.methodRef, newCp, classnames); - for (int k = 0; k < m.arguments.length; k++) - m.arguments[k] = thisCp.copy(m.arguments[k], newCp, classnames); - } - - return new BootstrapMethodsAttribute(newCp, methods); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ByteArray.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ByteArray.java deleted file mode 100644 index 3a21f14c1..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ByteArray.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -/** - * A collection of static methods for reading and writing a byte array. - */ -public class ByteArray { - /** - * Reads an unsigned 16bit integer at the index. - */ - public static int readU16bit(byte[] code, int index) { - return ((code[index] & 0xff) << 8) | (code[index + 1] & 0xff); - } - - /** - * Reads a signed 16bit integer at the index. - */ - public static int readS16bit(byte[] code, int index) { - return (code[index] << 8) | (code[index + 1] & 0xff); - } - - /** - * Writes a 16bit integer at the index. - */ - public static void write16bit(int value, byte[] code, int index) { - code[index] = (byte)(value >>> 8); - code[index + 1] = (byte)value; - } - - /** - * Reads a 32bit integer at the index. - */ - public static int read32bit(byte[] code, int index) { - return (code[index] << 24) | ((code[index + 1] & 0xff) << 16) - | ((code[index + 2] & 0xff) << 8) | (code[index + 3] & 0xff); - } - - /** - * Writes a 32bit integer at the index. - */ - public static void write32bit(int value, byte[] code, int index) { - code[index] = (byte)(value >>> 24); - code[index + 1] = (byte)(value >>> 16); - code[index + 2] = (byte)(value >>> 8); - code[index + 3] = (byte)value; - } - - /** - * Copies a 32bit integer. - * - * @param src the source byte array. - * @param isrc the index into the source byte array. - * @param dest the destination byte array. - * @param idest the index into the destination byte array. - */ - static void copy32bit(byte[] src, int isrc, byte[] dest, int idest) { - dest[idest] = src[isrc]; - dest[idest + 1] = src[isrc + 1]; - dest[idest + 2] = src[isrc + 2]; - dest[idest + 3] = src[isrc + 3]; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ByteStream.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ByteStream.java deleted file mode 100644 index 557358cc9..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ByteStream.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.OutputStream; -import java.io.IOException; - -final class ByteStream extends OutputStream { - private byte[] buf; - private int count; - - public ByteStream() { this(32); } - - public ByteStream(int size) { - buf = new byte[size]; - count = 0; - } - - public int getPos() { return count; } - public int size() { return count; } - - public void writeBlank(int len) { - enlarge(len); - count += len; - } - - public void write(byte[] data) { - write(data, 0, data.length); - } - - public void write(byte[] data, int off, int len) { - enlarge(len); - System.arraycopy(data, off, buf, count, len); - count += len; - } - - public void write(int b) { - enlarge(1); - int oldCount = count; - buf[oldCount] = (byte)b; - count = oldCount + 1; - } - - public void writeShort(int s) { - enlarge(2); - int oldCount = count; - buf[oldCount] = (byte)(s >>> 8); - buf[oldCount + 1] = (byte)s; - count = oldCount + 2; - } - - public void writeInt(int i) { - enlarge(4); - int oldCount = count; - buf[oldCount] = (byte)(i >>> 24); - buf[oldCount + 1] = (byte)(i >>> 16); - buf[oldCount + 2] = (byte)(i >>> 8); - buf[oldCount + 3] = (byte)i; - count = oldCount + 4; - } - - public void writeLong(long i) { - enlarge(8); - int oldCount = count; - buf[oldCount] = (byte)(i >>> 56); - buf[oldCount + 1] = (byte)(i >>> 48); - buf[oldCount + 2] = (byte)(i >>> 40); - buf[oldCount + 3] = (byte)(i >>> 32); - buf[oldCount + 4] = (byte)(i >>> 24); - buf[oldCount + 5] = (byte)(i >>> 16); - buf[oldCount + 6] = (byte)(i >>> 8); - buf[oldCount + 7] = (byte)i; - count = oldCount + 8; - } - - public void writeFloat(float v) { - writeInt(Float.floatToIntBits(v)); - } - - public void writeDouble(double v) { - writeLong(Double.doubleToLongBits(v)); - } - - public void writeUTF(String s) { - int sLen = s.length(); - int pos = count; - enlarge(sLen + 2); - - byte[] buffer = buf; - buffer[pos++] = (byte)(sLen >>> 8); - buffer[pos++] = (byte)sLen; - for (int i = 0; i < sLen; ++i) { - char c = s.charAt(i); - if (0x01 <= c && c <= 0x7f) - buffer[pos++] = (byte)c; - else { - writeUTF2(s, sLen, i); - return; - } - } - - count = pos; - } - - private void writeUTF2(String s, int sLen, int offset) { - int size = sLen; - for (int i = offset; i < sLen; i++) { - int c = s.charAt(i); - if (c > 0x7ff) - size += 2; // 3 bytes code - else if (c == 0 || c > 0x7f) - ++size; // 2 bytes code - } - - if (size > 65535) - throw new RuntimeException( - "encoded string too long: " + sLen + size + " bytes"); - - enlarge(size + 2); - int pos = count; - byte[] buffer = buf; - buffer[pos] = (byte)(size >>> 8); - buffer[pos + 1] = (byte)size; - pos += 2 + offset; - for (int j = offset; j < sLen; ++j) { - int c = s.charAt(j); - if (0x01 <= c && c <= 0x7f) - buffer[pos++] = (byte) c; - else if (c > 0x07ff) { - buffer[pos] = (byte)(0xe0 | ((c >> 12) & 0x0f)); - buffer[pos + 1] = (byte)(0x80 | ((c >> 6) & 0x3f)); - buffer[pos + 2] = (byte)(0x80 | (c & 0x3f)); - pos += 3; - } - else { - buffer[pos] = (byte)(0xc0 | ((c >> 6) & 0x1f)); - buffer[pos + 1] = (byte)(0x80 | (c & 0x3f)); - pos += 2; - } - } - - count = pos; - } - - public void write(int pos, int value) { - buf[pos] = (byte)value; - } - - public void writeShort(int pos, int value) { - buf[pos] = (byte)(value >>> 8); - buf[pos + 1] = (byte)value; - } - - public void writeInt(int pos, int value) { - buf[pos] = (byte)(value >>> 24); - buf[pos + 1] = (byte)(value >>> 16); - buf[pos + 2] = (byte)(value >>> 8); - buf[pos + 3] = (byte)value; - } - - public byte[] toByteArray() { - byte[] buf2 = new byte[count]; - System.arraycopy(buf, 0, buf2, 0, count); - return buf2; - } - - public void writeTo(OutputStream out) throws IOException { - out.write(buf, 0, count); - } - - public void enlarge(int delta) { - int newCount = count + delta; - if (newCount > buf.length) { - int newLen = buf.length << 1; - byte[] newBuf = new byte[newLen > newCount ? newLen : newCount]; - System.arraycopy(buf, 0, newBuf, 0, count); - buf = newBuf; - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/Bytecode.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/Bytecode.java deleted file mode 100644 index 914e3c026..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/Bytecode.java +++ /dev/null @@ -1,1430 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CtPrimitiveType; - -class ByteVector implements Cloneable { - private byte[] buffer; - private int size; - - public ByteVector() { - buffer = new byte[64]; - size = 0; - } - - public Object clone() throws CloneNotSupportedException { - ByteVector bv = (ByteVector)super.clone(); - bv.buffer = (byte[])buffer.clone(); - return bv; - } - - public final int getSize() { return size; } - - public final byte[] copy() { - byte[] b = new byte[size]; - System.arraycopy(buffer, 0, b, 0, size); - return b; - } - - public int read(int offset) { - if (offset < 0 || size <= offset) - throw new ArrayIndexOutOfBoundsException(offset); - - return buffer[offset]; - } - - public void write(int offset, int value) { - if (offset < 0 || size <= offset) - throw new ArrayIndexOutOfBoundsException(offset); - - buffer[offset] = (byte)value; - } - - public void add(int code) { - addGap(1); - buffer[size - 1] = (byte)code; - } - - public void add(int b1, int b2) { - addGap(2); - buffer[size - 2] = (byte)b1; - buffer[size - 1] = (byte)b2; - } - - public void add(int b1, int b2, int b3, int b4) { - addGap(4); - buffer[size - 4] = (byte)b1; - buffer[size - 3] = (byte)b2; - buffer[size - 2] = (byte)b3; - buffer[size - 1] = (byte)b4; - } - - public void addGap(int length) { - if (size + length > buffer.length) { - int newSize = size << 1; - if (newSize < size + length) - newSize = size + length; - - byte[] newBuf = new byte[newSize]; - System.arraycopy(buffer, 0, newBuf, 0, size); - buffer = newBuf; - } - - size += length; - } -} - -/** - * A utility class for producing a bytecode sequence. - * - *

A Bytecode object is an unbounded array - * containing bytecode. For example, - * - *

    ConstPool cp = ...;    // constant pool table
    - * Bytecode b = new Bytecode(cp, 1, 0);
    - * b.addIconst(3);
    - * b.addReturn(CtClass.intType);
    - * CodeAttribute ca = b.toCodeAttribute();
- * - *

This program produces a Code attribute including a bytecode - * sequence: - * - *

    iconst_3
    - * ireturn
- * - * @see ConstPool - * @see CodeAttribute - */ -public class Bytecode extends ByteVector implements Cloneable, com.fr.third.javassist.bytecode.Opcode { - /** - * Represents the CtClass file using the - * constant pool table given to this Bytecode object. - */ - public static final CtClass THIS = ConstPool.THIS; - - ConstPool constPool; - int maxStack, maxLocals; - ExceptionTable tryblocks; - private int stackDepth; - - /** - * Constructs a Bytecode object with an empty bytecode - * sequence. - * - *

The parameters stacksize and localvars - * specify initial values - * of max_stack and max_locals. - * They can be changed later. - * - * @param cp constant pool table. - * @param stacksize max_stack. - * @param localvars max_locals. - */ - public Bytecode(ConstPool cp, int stacksize, int localvars) { - constPool = cp; - maxStack = stacksize; - maxLocals = localvars; - tryblocks = new ExceptionTable(cp); - stackDepth = 0; - } - - /** - * Constructs a Bytecode object with an empty bytecode - * sequence. The initial values of max_stack and - * max_locals are zero. - * - * @param cp constant pool table. - * @see Bytecode#setMaxStack(int) - * @see Bytecode#setMaxLocals(int) - */ - public Bytecode(ConstPool cp) { - this(cp, 0, 0); - } - - /** - * Creates and returns a copy of this object. - * The constant pool object is shared between this object - * and the cloned object. - */ - public Object clone() { - try { - Bytecode bc = (Bytecode)super.clone(); - bc.tryblocks = (ExceptionTable)tryblocks.clone(); - return bc; - } - catch (CloneNotSupportedException cnse) { - throw new RuntimeException(cnse); - } - } - - /** - * Gets a constant pool table. - */ - public ConstPool getConstPool() { return constPool; } - - /** - * Returns exception_table. - */ - public ExceptionTable getExceptionTable() { return tryblocks; } - - /** - * Converts to a CodeAttribute. - */ - public CodeAttribute toCodeAttribute() { - return new CodeAttribute(constPool, maxStack, maxLocals, - get(), tryblocks); - } - - /** - * Returns the length of the bytecode sequence. - */ - public int length() { - return getSize(); - } - - /** - * Returns the produced bytecode sequence. - */ - public byte[] get() { - return copy(); - } - - /** - * Gets max_stack. - */ - public int getMaxStack() { return maxStack; } - - /** - * Sets max_stack. - * - *

This value may be automatically updated when an instruction - * is appended. A Bytecode object maintains the current - * stack depth whenever an instruction is added - * by addOpcode(). For example, if DUP is appended, - * the current stack depth is increased by one. If the new stack - * depth is more than max_stack, then it is assigned - * to max_stack. However, if branch instructions are - * appended, the current stack depth may not be correctly maintained. - * - * @see #addOpcode(int) - */ - public void setMaxStack(int size) { - maxStack = size; - } - - /** - * Gets max_locals. - */ - public int getMaxLocals() { return maxLocals; } - - /** - * Sets max_locals. - */ - public void setMaxLocals(int size) { - maxLocals = size; - } - - /** - * Sets max_locals. - * - *

This computes the number of local variables - * used to pass method parameters and sets max_locals - * to that number plus locals. - * - * @param isStatic true if params must be - * interpreted as parameters to a static method. - * @param params parameter types. - * @param locals the number of local variables excluding - * ones used to pass parameters. - */ - public void setMaxLocals(boolean isStatic, CtClass[] params, - int locals) { - if (!isStatic) - ++locals; - - if (params != null) { - CtClass doubleType = CtClass.doubleType; - CtClass longType = CtClass.longType; - int n = params.length; - for (int i = 0; i < n; ++i) { - CtClass type = params[i]; - if (type == doubleType || type == longType) - locals += 2; - else - ++locals; - } - } - - maxLocals = locals; - } - - /** - * Increments max_locals. - */ - public void incMaxLocals(int diff) { - maxLocals += diff; - } - - /** - * Adds a new entry of exception_table. - */ - public void addExceptionHandler(int start, int end, - int handler, CtClass type) { - addExceptionHandler(start, end, handler, - constPool.addClassInfo(type)); - } - - /** - * Adds a new entry of exception_table. - * - * @param type the fully-qualified name of a throwable class. - */ - public void addExceptionHandler(int start, int end, - int handler, String type) { - addExceptionHandler(start, end, handler, - constPool.addClassInfo(type)); - } - - /** - * Adds a new entry of exception_table. - */ - public void addExceptionHandler(int start, int end, - int handler, int type) { - tryblocks.add(start, end, handler, type); - } - - /** - * Returns the length of bytecode sequence - * that have been added so far. - */ - public int currentPc() { - return getSize(); - } - - /** - * Reads a signed 8bit value at the offset from the beginning of the - * bytecode sequence. - * - * @throws ArrayIndexOutOfBoundsException if offset is invalid. - */ - public int read(int offset) { - return super.read(offset); - } - - /** - * Reads a signed 16bit value at the offset from the beginning of the - * bytecode sequence. - */ - public int read16bit(int offset) { - int v1 = read(offset); - int v2 = read(offset + 1); - return (v1 << 8) + (v2 & 0xff); - } - - /** - * Reads a signed 32bit value at the offset from the beginning of the - * bytecode sequence. - */ - public int read32bit(int offset) { - int v1 = read16bit(offset); - int v2 = read16bit(offset + 2); - return (v1 << 16) + (v2 & 0xffff); - } - - /** - * Writes an 8bit value at the offset from the beginning of the - * bytecode sequence. - * - * @throws ArrayIndexOutOfBoundsException if offset is invalid. - */ - public void write(int offset, int value) { - super.write(offset, value); - } - - /** - * Writes an 16bit value at the offset from the beginning of the - * bytecode sequence. - */ - public void write16bit(int offset, int value) { - write(offset, value >> 8); - write(offset + 1, value); - } - - /** - * Writes an 32bit value at the offset from the beginning of the - * bytecode sequence. - */ - public void write32bit(int offset, int value) { - write16bit(offset, value >> 16); - write16bit(offset + 2, value); - } - - /** - * Appends an 8bit value to the end of the bytecode sequence. - */ - public void add(int code) { - super.add(code); - } - - /** - * Appends a 32bit value to the end of the bytecode sequence. - */ - public void add32bit(int value) { - add(value >> 24, value >> 16, value >> 8, value); - } - - /** - * Appends the length-byte gap to the end of the bytecode sequence. - * - * @param length the gap length in byte. - */ - public void addGap(int length) { - super.addGap(length); - } - - /** - * Appends an 8bit opcode to the end of the bytecode sequence. - * The current stack depth is updated. - * max_stack is updated if the current stack depth - * is the deepest so far. - * - *

Note: some instructions such as INVOKEVIRTUAL does not - * update the current stack depth since the increment depends - * on the method signature. - * growStack() must be explicitly called. - */ - public void addOpcode(int code) { - add(code); - growStack(STACK_GROW[code]); - } - - /** - * Increases the current stack depth. - * It also updates max_stack if the current stack depth - * is the deepest so far. - * - * @param diff the number added to the current stack depth. - */ - public void growStack(int diff) { - setStackDepth(stackDepth + diff); - } - - /** - * Returns the current stack depth. - */ - public int getStackDepth() { return stackDepth; } - - /** - * Sets the current stack depth. - * It also updates max_stack if the current stack depth - * is the deepest so far. - * - * @param depth new value. - */ - public void setStackDepth(int depth) { - stackDepth = depth; - if (stackDepth > maxStack) - maxStack = stackDepth; - } - - /** - * Appends a 16bit value to the end of the bytecode sequence. - * It never changes the current stack depth. - */ - public void addIndex(int index) { - add(index >> 8, index); - } - - /** - * Appends ALOAD or (WIDE) ALOAD_<n> - * - * @param n an index into the local variable array. - */ - public void addAload(int n) { - if (n < 4) - addOpcode(42 + n); // aload_ - else if (n < 0x100) { - addOpcode(ALOAD); // aload - add(n); - } - else { - addOpcode(WIDE); - addOpcode(ALOAD); - addIndex(n); - } - } - - /** - * Appends ASTORE or (WIDE) ASTORE_<n> - * - * @param n an index into the local variable array. - */ - public void addAstore(int n) { - if (n < 4) - addOpcode(75 + n); // astore_ - else if (n < 0x100) { - addOpcode(ASTORE); // astore - add(n); - } - else { - addOpcode(WIDE); - addOpcode(ASTORE); - addIndex(n); - } - } - - /** - * Appends ICONST or ICONST_<n> - * - * @param n the pushed integer constant. - */ - public void addIconst(int n) { - if (n < 6 && -2 < n) - addOpcode(3 + n); // iconst_ -1..5 - else if (n <= 127 && -128 <= n) { - addOpcode(16); // bipush - add(n); - } - else if (n <= 32767 && -32768 <= n) { - addOpcode(17); // sipush - add(n >> 8); - add(n); - } - else - addLdc(constPool.addIntegerInfo(n)); - } - - /** - * Appends an instruction for pushing zero or null on the stack. - * If the type is void, this method does not append any instruction. - * - * @param type the type of the zero value (or null). - */ - public void addConstZero(CtClass type) { - if (type.isPrimitive()) { - if (type == CtClass.longType) - addOpcode(LCONST_0); - else if (type == CtClass.floatType) - addOpcode(FCONST_0); - else if (type == CtClass.doubleType) - addOpcode(DCONST_0); - else if (type == CtClass.voidType) - throw new RuntimeException("void type?"); - else - addOpcode(ICONST_0); - } - else - addOpcode(ACONST_NULL); - } - - /** - * Appends ILOAD or (WIDE) ILOAD_<n> - * - * @param n an index into the local variable array. - */ - public void addIload(int n) { - if (n < 4) - addOpcode(26 + n); // iload_ - else if (n < 0x100) { - addOpcode(ILOAD); // iload - add(n); - } - else { - addOpcode(WIDE); - addOpcode(ILOAD); - addIndex(n); - } - } - - /** - * Appends ISTORE or (WIDE) ISTORE_<n> - * - * @param n an index into the local variable array. - */ - public void addIstore(int n) { - if (n < 4) - addOpcode(59 + n); // istore_ - else if (n < 0x100) { - addOpcode(ISTORE); // istore - add(n); - } - else { - addOpcode(WIDE); - addOpcode(ISTORE); - addIndex(n); - } - } - - /** - * Appends LCONST or LCONST_<n> - * - * @param n the pushed long integer constant. - */ - public void addLconst(long n) { - if (n == 0 || n == 1) - addOpcode(9 + (int)n); // lconst_ - else - addLdc2w(n); - } - - /** - * Appends LLOAD or (WIDE) LLOAD_<n> - * - * @param n an index into the local variable array. - */ - public void addLload(int n) { - if (n < 4) - addOpcode(30 + n); // lload_ - else if (n < 0x100) { - addOpcode(LLOAD); // lload - add(n); - } - else { - addOpcode(WIDE); - addOpcode(LLOAD); - addIndex(n); - } - } - - /** - * Appends LSTORE or LSTORE_<n> - * - * @param n an index into the local variable array. - */ - public void addLstore(int n) { - if (n < 4) - addOpcode(63 + n); // lstore_ - else if (n < 0x100) { - addOpcode(LSTORE); // lstore - add(n); - } - else { - addOpcode(WIDE); - addOpcode(LSTORE); - addIndex(n); - } - } - - /** - * Appends DCONST or DCONST_<n> - * - * @param d the pushed double constant. - */ - public void addDconst(double d) { - if (d == 0.0 || d == 1.0) - addOpcode(14 + (int)d); // dconst_ - else - addLdc2w(d); - } - - /** - * Appends DLOAD or (WIDE) DLOAD_<n> - * - * @param n an index into the local variable array. - */ - public void addDload(int n) { - if (n < 4) - addOpcode(38 + n); // dload_ - else if (n < 0x100) { - addOpcode(DLOAD); // dload - add(n); - } - else { - addOpcode(WIDE); - addOpcode(DLOAD); - addIndex(n); - } - } - - /** - * Appends DSTORE or (WIDE) DSTORE_<n> - * - * @param n an index into the local variable array. - */ - public void addDstore(int n) { - if (n < 4) - addOpcode(71 + n); // dstore_ - else if (n < 0x100) { - addOpcode(DSTORE); // dstore - add(n); - } - else { - addOpcode(WIDE); - addOpcode(DSTORE); - addIndex(n); - } - } - - /** - * Appends FCONST or FCONST_<n> - * - * @param f the pushed float constant. - */ - public void addFconst(float f) { - if (f == 0.0f || f == 1.0f || f == 2.0f) - addOpcode(11 + (int)f); // fconst_ - else - addLdc(constPool.addFloatInfo(f)); - } - - /** - * Appends FLOAD or (WIDE) FLOAD_<n> - * - * @param n an index into the local variable array. - */ - public void addFload(int n) { - if (n < 4) - addOpcode(34 + n); // fload_ - else if (n < 0x100) { - addOpcode(FLOAD); // fload - add(n); - } - else { - addOpcode(WIDE); - addOpcode(FLOAD); - addIndex(n); - } - } - - /** - * Appends FSTORE or FSTORE_<n> - * - * @param n an index into the local variable array. - */ - public void addFstore(int n) { - if (n < 4) - addOpcode(67 + n); // fstore_ - else if (n < 0x100) { - addOpcode(FSTORE); // fstore - add(n); - } - else { - addOpcode(WIDE); - addOpcode(FSTORE); - addIndex(n); - } - } - - /** - * Appends an instruction for loading a value from the - * local variable at the index n. - * - * @param n the index. - * @param type the type of the loaded value. - * @return the size of the value (1 or 2 word). - */ - public int addLoad(int n, CtClass type) { - if (type.isPrimitive()) { - if (type == CtClass.booleanType || type == CtClass.charType - || type == CtClass.byteType || type == CtClass.shortType - || type == CtClass.intType) - addIload(n); - else if (type == CtClass.longType) { - addLload(n); - return 2; - } - else if(type == CtClass.floatType) - addFload(n); - else if(type == CtClass.doubleType) { - addDload(n); - return 2; - } - else - throw new RuntimeException("void type?"); - } - else - addAload(n); - - return 1; - } - - /** - * Appends an instruction for storing a value into the - * local variable at the index n. - * - * @param n the index. - * @param type the type of the stored value. - * @return 2 if the type is long or double. Otherwise 1. - */ - public int addStore(int n, CtClass type) { - if (type.isPrimitive()) { - if (type == CtClass.booleanType || type == CtClass.charType - || type == CtClass.byteType || type == CtClass.shortType - || type == CtClass.intType) - addIstore(n); - else if (type == CtClass.longType) { - addLstore(n); - return 2; - } - else if (type == CtClass.floatType) - addFstore(n); - else if (type == CtClass.doubleType) { - addDstore(n); - return 2; - } - else - throw new RuntimeException("void type?"); - } - else - addAstore(n); - - return 1; - } - - /** - * Appends instructions for loading all the parameters onto the - * operand stack. - * - * @param offset the index of the first parameter. It is 0 - * if the method is static. Otherwise, it is 1. - */ - public int addLoadParameters(CtClass[] params, int offset) { - int stacksize = 0; - if (params != null) { - int n = params.length; - for (int i = 0; i < n; ++i) - stacksize += addLoad(stacksize + offset, params[i]); - } - - return stacksize; - } - - /** - * Appends CHECKCAST. - * - * @param c the type. - */ - public void addCheckcast(CtClass c) { - addOpcode(CHECKCAST); - addIndex(constPool.addClassInfo(c)); - } - - /** - * Appends CHECKCAST. - * - * @param classname a fully-qualified class name. - */ - public void addCheckcast(String classname) { - addOpcode(CHECKCAST); - addIndex(constPool.addClassInfo(classname)); - } - - /** - * Appends INSTANCEOF. - * - * @param classname the class name. - */ - public void addInstanceof(String classname) { - addOpcode(INSTANCEOF); - addIndex(constPool.addClassInfo(classname)); - } - - /** - * Appends GETFIELD. - * - * @param c the class. - * @param name the field name. - * @param type the descriptor of the field type. - * - * @see Descriptor#of(CtClass) - */ - public void addGetfield(CtClass c, String name, String type) { - add(GETFIELD); - int ci = constPool.addClassInfo(c); - addIndex(constPool.addFieldrefInfo(ci, name, type)); - growStack(Descriptor.dataSize(type) - 1); - } - - /** - * Appends GETFIELD. - * - * @param c the fully-qualified class name. - * @param name the field name. - * @param type the descriptor of the field type. - * - * @see Descriptor#of(CtClass) - */ - public void addGetfield(String c, String name, String type) { - add(GETFIELD); - int ci = constPool.addClassInfo(c); - addIndex(constPool.addFieldrefInfo(ci, name, type)); - growStack(Descriptor.dataSize(type) - 1); - } - - /** - * Appends GETSTATIC. - * - * @param c the class - * @param name the field name - * @param type the descriptor of the field type. - * - * @see Descriptor#of(CtClass) - */ - public void addGetstatic(CtClass c, String name, String type) { - add(GETSTATIC); - int ci = constPool.addClassInfo(c); - addIndex(constPool.addFieldrefInfo(ci, name, type)); - growStack(Descriptor.dataSize(type)); - } - - /** - * Appends GETSTATIC. - * - * @param c the fully-qualified class name - * @param name the field name - * @param type the descriptor of the field type. - * - * @see Descriptor#of(CtClass) - */ - public void addGetstatic(String c, String name, String type) { - add(GETSTATIC); - int ci = constPool.addClassInfo(c); - addIndex(constPool.addFieldrefInfo(ci, name, type)); - growStack(Descriptor.dataSize(type)); - } - - /** - * Appends INVOKESPECIAL. - * - * @param clazz the target class. - * @param name the method name. - * @param returnType the return type. - * @param paramTypes the parameter types. - */ - public void addInvokespecial(CtClass clazz, String name, - CtClass returnType, CtClass[] paramTypes) { - String desc = Descriptor.ofMethod(returnType, paramTypes); - addInvokespecial(clazz, name, desc); - } - - /** - * Appends INVOKESPECIAL. - * - * @param clazz the target class. - * @param name the method name - * @param desc the descriptor of the method signature. - * - * @see Descriptor#ofMethod(CtClass,CtClass[]) - * @see Descriptor#ofConstructor(CtClass[]) - */ - public void addInvokespecial(CtClass clazz, String name, String desc) { - addInvokespecial(constPool.addClassInfo(clazz), name, desc); - } - - /** - * Appends INVOKESPECIAL. - * - * @param clazz the fully-qualified class name. - * @param name the method name - * @param desc the descriptor of the method signature. - * - * @see Descriptor#ofMethod(CtClass,CtClass[]) - * @see Descriptor#ofConstructor(CtClass[]) - */ - public void addInvokespecial(String clazz, String name, String desc) { - addInvokespecial(constPool.addClassInfo(clazz), name, desc); - } - - /** - * Appends INVOKESPECIAL. - * - * @param clazz the index of CONSTANT_Class_info - * structure. - * @param name the method name - * @param desc the descriptor of the method signature. - * - * @see Descriptor#ofMethod(CtClass,CtClass[]) - * @see Descriptor#ofConstructor(CtClass[]) - */ - public void addInvokespecial(int clazz, String name, String desc) { - add(INVOKESPECIAL); - addIndex(constPool.addMethodrefInfo(clazz, name, desc)); - growStack(Descriptor.dataSize(desc) - 1); - } - - /** - * Appends INVOKESTATIC. - * - * @param clazz the target class. - * @param name the method name - * @param returnType the return type. - * @param paramTypes the parameter types. - */ - public void addInvokestatic(CtClass clazz, String name, - CtClass returnType, CtClass[] paramTypes) { - String desc = Descriptor.ofMethod(returnType, paramTypes); - addInvokestatic(clazz, name, desc); - } - - /** - * Appends INVOKESTATIC. - * - * @param clazz the target class. - * @param name the method name - * @param desc the descriptor of the method signature. - * - * @see Descriptor#ofMethod(CtClass,CtClass[]) - */ - public void addInvokestatic(CtClass clazz, String name, String desc) { - addInvokestatic(constPool.addClassInfo(clazz), name, desc); - } - - /** - * Appends INVOKESTATIC. - * - * @param classname the fully-qualified class name. - * @param name the method name - * @param desc the descriptor of the method signature. - * - * @see Descriptor#ofMethod(CtClass,CtClass[]) - */ - public void addInvokestatic(String classname, String name, String desc) { - addInvokestatic(constPool.addClassInfo(classname), name, desc); - } - - /** - * Appends INVOKESTATIC. - * - * @param clazz the index of CONSTANT_Class_info - * structure. - * @param name the method name - * @param desc the descriptor of the method signature. - * - * @see Descriptor#ofMethod(CtClass,CtClass[]) - */ - public void addInvokestatic(int clazz, String name, String desc) { - add(INVOKESTATIC); - addIndex(constPool.addMethodrefInfo(clazz, name, desc)); - growStack(Descriptor.dataSize(desc)); - } - - /** - * Appends INVOKEVIRTUAL. - * - *

The specified method must not be an inherited method. - * It must be directly declared in the class specified - * in clazz. - * - * @param clazz the target class. - * @param name the method name - * @param returnType the return type. - * @param paramTypes the parameter types. - */ - public void addInvokevirtual(CtClass clazz, String name, - CtClass returnType, CtClass[] paramTypes) { - String desc = Descriptor.ofMethod(returnType, paramTypes); - addInvokevirtual(clazz, name, desc); - } - - /** - * Appends INVOKEVIRTUAL. - * - *

The specified method must not be an inherited method. - * It must be directly declared in the class specified - * in clazz. - * - * @param clazz the target class. - * @param name the method name - * @param desc the descriptor of the method signature. - * - * @see Descriptor#ofMethod(CtClass,CtClass[]) - */ - public void addInvokevirtual(CtClass clazz, String name, String desc) { - addInvokevirtual(constPool.addClassInfo(clazz), name, desc); - } - - /** - * Appends INVOKEVIRTUAL. - * - *

The specified method must not be an inherited method. - * It must be directly declared in the class specified - * in classname. - * - * @param classname the fully-qualified class name. - * @param name the method name - * @param desc the descriptor of the method signature. - * - * @see Descriptor#ofMethod(CtClass,CtClass[]) - */ - public void addInvokevirtual(String classname, String name, String desc) { - addInvokevirtual(constPool.addClassInfo(classname), name, desc); - } - - /** - * Appends INVOKEVIRTUAL. - * - *

The specified method must not be an inherited method. - * It must be directly declared in the class specified - * by clazz. - * - * @param clazz the index of CONSTANT_Class_info - * structure. - * @param name the method name - * @param desc the descriptor of the method signature. - * - * @see Descriptor#ofMethod(CtClass,CtClass[]) - */ - public void addInvokevirtual(int clazz, String name, String desc) { - add(INVOKEVIRTUAL); - addIndex(constPool.addMethodrefInfo(clazz, name, desc)); - growStack(Descriptor.dataSize(desc) - 1); - } - - /** - * Appends INVOKEINTERFACE. - * - * @param clazz the target class. - * @param name the method name - * @param returnType the return type. - * @param paramTypes the parameter types. - * @param count the count operand of the instruction. - */ - public void addInvokeinterface(CtClass clazz, String name, - CtClass returnType, CtClass[] paramTypes, - int count) { - String desc = Descriptor.ofMethod(returnType, paramTypes); - addInvokeinterface(clazz, name, desc, count); - } - - /** - * Appends INVOKEINTERFACE. - * - * @param clazz the target class. - * @param name the method name - * @param desc the descriptor of the method signature. - * @param count the count operand of the instruction. - * - * @see Descriptor#ofMethod(CtClass,CtClass[]) - */ - public void addInvokeinterface(CtClass clazz, String name, - String desc, int count) { - addInvokeinterface(constPool.addClassInfo(clazz), name, desc, - count); - } - - /** - * Appends INVOKEINTERFACE. - * - * @param classname the fully-qualified class name. - * @param name the method name - * @param desc the descriptor of the method signature. - * @param count the count operand of the instruction. - * - * @see Descriptor#ofMethod(CtClass,CtClass[]) - */ - public void addInvokeinterface(String classname, String name, - String desc, int count) { - addInvokeinterface(constPool.addClassInfo(classname), name, desc, - count); - } - - /** - * Appends INVOKEINTERFACE. - * - * @param clazz the index of CONSTANT_Class_info - * structure. - * @param name the method name - * @param desc the descriptor of the method signature. - * @param count the count operand of the instruction. - * - * @see Descriptor#ofMethod(CtClass,CtClass[]) - */ - public void addInvokeinterface(int clazz, String name, - String desc, int count) { - add(INVOKEINTERFACE); - addIndex(constPool.addInterfaceMethodrefInfo(clazz, name, desc)); - add(count); - add(0); - growStack(Descriptor.dataSize(desc) - 1); - } - - /** - * Appends INVOKEDYNAMIC. - * - * @param bootstrap an index into the bootstrap_methods array - * of the bootstrap method table. - * @param name the method name. - * @param desc the method descriptor. - * @see Descriptor#ofMethod(CtClass,CtClass[]) - * @since 3.17 - */ - public void addInvokedynamic(int bootstrap, String name, String desc) { - int nt = constPool.addNameAndTypeInfo(name, desc); - int dyn = constPool.addInvokeDynamicInfo(bootstrap, nt); - add(INVOKEDYNAMIC); - addIndex(dyn); - add(0, 0); - growStack(Descriptor.dataSize(desc)); // assume ConstPool#REF_invokeStatic - } - - /** - * Appends LDC or LDC_W. The pushed item is a String - * object. - * - * @param s the character string pushed by LDC or LDC_W. - */ - public void addLdc(String s) { - addLdc(constPool.addStringInfo(s)); - } - - /** - * Appends LDC or LDC_W. - * - * @param i index into the constant pool. - */ - public void addLdc(int i) { - if (i > 0xFF) { - addOpcode(LDC_W); - addIndex(i); - } - else { - addOpcode(LDC); - add(i); - } - } - - /** - * Appends LDC2_W. The pushed item is a long value. - */ - public void addLdc2w(long l) { - addOpcode(LDC2_W); - addIndex(constPool.addLongInfo(l)); - } - - /** - * Appends LDC2_W. The pushed item is a double value. - */ - public void addLdc2w(double d) { - addOpcode(LDC2_W); - addIndex(constPool.addDoubleInfo(d)); - } - - /** - * Appends NEW. - * - * @param clazz the class of the created instance. - */ - public void addNew(CtClass clazz) { - addOpcode(NEW); - addIndex(constPool.addClassInfo(clazz)); - } - - /** - * Appends NEW. - * - * @param classname the fully-qualified class name. - */ - public void addNew(String classname) { - addOpcode(NEW); - addIndex(constPool.addClassInfo(classname)); - } - - /** - * Appends ANEWARRAY. - * - * @param classname the qualified class name of the element type. - */ - public void addAnewarray(String classname) { - addOpcode(ANEWARRAY); - addIndex(constPool.addClassInfo(classname)); - } - - /** - * Appends ICONST and ANEWARRAY. - * - * @param clazz the elememnt type. - * @param length the array length. - */ - public void addAnewarray(CtClass clazz, int length) { - addIconst(length); - addOpcode(ANEWARRAY); - addIndex(constPool.addClassInfo(clazz)); - } - - /** - * Appends NEWARRAY for primitive types. - * - * @param atype T_BOOLEAN, T_CHAR, ... - * @see Opcode - */ - public void addNewarray(int atype, int length) { - addIconst(length); - addOpcode(NEWARRAY); - add(atype); - } - - /** - * Appends MULTINEWARRAY. - * - * @param clazz the array type. - * @param dimensions the sizes of all dimensions. - * @return the length of dimensions. - */ - public int addMultiNewarray(CtClass clazz, int[] dimensions) { - int len = dimensions.length; - for (int i = 0; i < len; ++i) - addIconst(dimensions[i]); - - growStack(len); - return addMultiNewarray(clazz, len); - } - - /** - * Appends MULTINEWARRAY. The size of every dimension must have been - * already pushed on the stack. - * - * @param clazz the array type. - * @param dim the number of the dimensions. - * @return the value of dim. - */ - public int addMultiNewarray(CtClass clazz, int dim) { - add(MULTIANEWARRAY); - addIndex(constPool.addClassInfo(clazz)); - add(dim); - growStack(1 - dim); - return dim; - } - - /** - * Appends MULTINEWARRAY. - * - * @param desc the type descriptor of the created array. - * @param dim dimensions. - * @return the value of dim. - */ - public int addMultiNewarray(String desc, int dim) { - add(MULTIANEWARRAY); - addIndex(constPool.addClassInfo(desc)); - add(dim); - growStack(1 - dim); - return dim; - } - - /** - * Appends PUTFIELD. - * - * @param c the target class. - * @param name the field name. - * @param desc the descriptor of the field type. - */ - public void addPutfield(CtClass c, String name, String desc) { - addPutfield0(c, null, name, desc); - } - - /** - * Appends PUTFIELD. - * - * @param classname the fully-qualified name of the target class. - * @param name the field name. - * @param desc the descriptor of the field type. - */ - public void addPutfield(String classname, String name, String desc) { - // if classnaem is null, the target class is THIS. - addPutfield0(null, classname, name, desc); - } - - private void addPutfield0(CtClass target, String classname, - String name, String desc) { - add(PUTFIELD); - // target is null if it represents THIS. - int ci = classname == null ? constPool.addClassInfo(target) - : constPool.addClassInfo(classname); - addIndex(constPool.addFieldrefInfo(ci, name, desc)); - growStack(-1 - Descriptor.dataSize(desc)); - } - - /** - * Appends PUTSTATIC. - * - * @param c the target class. - * @param name the field name. - * @param desc the descriptor of the field type. - */ - public void addPutstatic(CtClass c, String name, String desc) { - addPutstatic0(c, null, name, desc); - } - - /** - * Appends PUTSTATIC. - * - * @param classname the fully-qualified name of the target class. - * @param fieldName the field name. - * @param desc the descriptor of the field type. - */ - public void addPutstatic(String classname, String fieldName, String desc) { - // if classname is null, the target class is THIS. - addPutstatic0(null, classname, fieldName, desc); - } - - private void addPutstatic0(CtClass target, String classname, - String fieldName, String desc) { - add(PUTSTATIC); - // target is null if it represents THIS. - int ci = classname == null ? constPool.addClassInfo(target) - : constPool.addClassInfo(classname); - addIndex(constPool.addFieldrefInfo(ci, fieldName, desc)); - growStack(-Descriptor.dataSize(desc)); - } - - /** - * Appends ARETURN, IRETURN, .., or RETURN. - * - * @param type the return type. - */ - public void addReturn(CtClass type) { - if (type == null) - addOpcode(RETURN); - else if (type.isPrimitive()) { - CtPrimitiveType ptype = (CtPrimitiveType)type; - addOpcode(ptype.getReturnOp()); - } - else - addOpcode(ARETURN); - } - - /** - * Appends RET. - * - * @param var local variable - */ - public void addRet(int var) { - if (var < 0x100) { - addOpcode(RET); - add(var); - } - else { - addOpcode(WIDE); - addOpcode(RET); - addIndex(var); - } - } - - /** - * Appends instructions for executing - * java.lang.System.println(message). - * - * @param message printed message. - */ - public void addPrintln(String message) { - addGetstatic("java.lang.System", "err", "Ljava/io/PrintStream;"); - addLdc(message); - addInvokevirtual("java.io.PrintStream", - "println", "(Ljava/lang/String;)V"); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ClassFile.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ClassFile.java deleted file mode 100644 index d7f90a5cb..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ClassFile.java +++ /dev/null @@ -1,909 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import com.fr.third.javassist.CannotCompileException; -import com.fr.third.javassist.CtClass; - -/** - * ClassFile represents a Java .class file, which - * consists of a constant pool, methods, fields, and attributes. - * - * @see CtClass#getClassFile() - */ -public final class ClassFile { - int major, minor; // version number - ConstPool constPool; - int thisClass; - int accessFlags; - int superClass; - int[] interfaces; - ArrayList fields; - ArrayList methods; - ArrayList attributes; - String thisclassname; // not JVM-internal name - String[] cachedInterfaces; - String cachedSuperclass; - - /** - * The major version number of class files - * for JDK 1.1. - */ - public static final int JAVA_1 = 45; - - /** - * The major version number of class files - * for JDK 1.2. - */ - public static final int JAVA_2 = 46; - - /** - * The major version number of class files - * for JDK 1.3. - */ - public static final int JAVA_3 = 47; - - /** - * The major version number of class files - * for JDK 1.4. - */ - public static final int JAVA_4 = 48; - - /** - * The major version number of class files - * for JDK 1.5. - */ - public static final int JAVA_5 = 49; - - /** - * The major version number of class files - * for JDK 1.6. - */ - public static final int JAVA_6 = 50; - - /** - * The major version number of class files - * for JDK 1.7. - */ - public static final int JAVA_7 = 51; - - /** - * The major version number of class files - * for JDK 1.8. - */ - public static final int JAVA_8 = 52; - - /** - * The major version number of class files created - * from scratch. The default value is 47 (JDK 1.3). - * It is 49 (JDK 1.5) - * if the JVM supports java.lang.StringBuilder. - * It is 50 (JDK 1.6) - * if the JVM supports java.util.zip.DeflaterInputStream. - * It is 51 (JDK 1.7) - * if the JVM supports java.lang.invoke.CallSite. - */ - public static int MAJOR_VERSION = JAVA_3; - - static { - try { - Class.forName("java.lang.StringBuilder"); - MAJOR_VERSION = JAVA_5; - Class.forName("java.util.zip.DeflaterInputStream"); - MAJOR_VERSION = JAVA_6; - Class.forName("java.lang.invoke.CallSite"); - MAJOR_VERSION = JAVA_7; - } - catch (Throwable t) {} - } - - /** - * Constructs a class file from a byte stream. - */ - public ClassFile(DataInputStream in) throws IOException { - read(in); - } - - /** - * Constructs a class file including no members. - * - * @param isInterface - * true if this is an interface. false if this is a class. - * @param classname - * a fully-qualified class name - * @param superclass - * a fully-qualified super class name - */ - public ClassFile(boolean isInterface, String classname, String superclass) { - major = MAJOR_VERSION; - minor = 0; // JDK 1.3 or later - constPool = new ConstPool(classname); - thisClass = constPool.getThisClassInfo(); - if (isInterface) - accessFlags = AccessFlag.INTERFACE | AccessFlag.ABSTRACT; - else - accessFlags = AccessFlag.SUPER; - - initSuperclass(superclass); - interfaces = null; - fields = new ArrayList(); - methods = new ArrayList(); - thisclassname = classname; - - attributes = new ArrayList(); - attributes.add(new SourceFileAttribute(constPool, - getSourcefileName(thisclassname))); - } - - private void initSuperclass(String superclass) { - if (superclass != null) { - this.superClass = constPool.addClassInfo(superclass); - cachedSuperclass = superclass; - } - else { - this.superClass = constPool.addClassInfo("java.lang.Object"); - cachedSuperclass = "java.lang.Object"; - } - } - - private static String getSourcefileName(String qname) { - int index = qname.lastIndexOf('.'); - if (index >= 0) - qname = qname.substring(index + 1); - - return qname + ".java"; - } - - /** - * Eliminates dead constant pool items. If a method or a field is removed, - * the constant pool items used by that method/field become dead items. This - * method recreates a constant pool. - */ - public void compact() { - ConstPool cp = compact0(); - ArrayList list = methods; - int n = list.size(); - for (int i = 0; i < n; ++i) { - MethodInfo minfo = (MethodInfo)list.get(i); - minfo.compact(cp); - } - - list = fields; - n = list.size(); - for (int i = 0; i < n; ++i) { - FieldInfo finfo = (FieldInfo)list.get(i); - finfo.compact(cp); - } - - attributes = AttributeInfo.copyAll(attributes, cp); - constPool = cp; - } - - private ConstPool compact0() { - ConstPool cp = new ConstPool(thisclassname); - thisClass = cp.getThisClassInfo(); - String sc = getSuperclass(); - if (sc != null) - superClass = cp.addClassInfo(getSuperclass()); - - if (interfaces != null) { - int n = interfaces.length; - for (int i = 0; i < n; ++i) - interfaces[i] - = cp.addClassInfo(constPool.getClassInfo(interfaces[i])); - } - - return cp; - } - - /** - * Discards all attributes, associated with both the class file and the - * members such as a code attribute and exceptions attribute. The unused - * constant pool entries are also discarded (a new packed constant pool is - * constructed). - */ - public void prune() { - ConstPool cp = compact0(); - ArrayList newAttributes = new ArrayList(); - AttributeInfo invisibleAnnotations - = getAttribute(AnnotationsAttribute.invisibleTag); - if (invisibleAnnotations != null) { - invisibleAnnotations = invisibleAnnotations.copy(cp, null); - newAttributes.add(invisibleAnnotations); - } - - AttributeInfo visibleAnnotations - = getAttribute(AnnotationsAttribute.visibleTag); - if (visibleAnnotations != null) { - visibleAnnotations = visibleAnnotations.copy(cp, null); - newAttributes.add(visibleAnnotations); - } - - AttributeInfo signature - = getAttribute(SignatureAttribute.tag); - if (signature != null) { - signature = signature.copy(cp, null); - newAttributes.add(signature); - } - - ArrayList list = methods; - int n = list.size(); - for (int i = 0; i < n; ++i) { - MethodInfo minfo = (MethodInfo)list.get(i); - minfo.prune(cp); - } - - list = fields; - n = list.size(); - for (int i = 0; i < n; ++i) { - FieldInfo finfo = (FieldInfo)list.get(i); - finfo.prune(cp); - } - - attributes = newAttributes; - constPool = cp; - } - - /** - * Returns a constant pool table. - */ - public ConstPool getConstPool() { - return constPool; - } - - /** - * Returns true if this is an interface. - */ - public boolean isInterface() { - return (accessFlags & AccessFlag.INTERFACE) != 0; - } - - /** - * Returns true if this is a final class or interface. - */ - public boolean isFinal() { - return (accessFlags & AccessFlag.FINAL) != 0; - } - - /** - * Returns true if this is an abstract class or an interface. - */ - public boolean isAbstract() { - return (accessFlags & AccessFlag.ABSTRACT) != 0; - } - - /** - * Returns access flags. - * - * @see AccessFlag - */ - public int getAccessFlags() { - return accessFlags; - } - - /** - * Changes access flags. - * - * @see AccessFlag - */ - public void setAccessFlags(int acc) { - if ((acc & AccessFlag.INTERFACE) == 0) - acc |= AccessFlag.SUPER; - - accessFlags = acc; - } - - /** - * Returns access and property flags of this nested class. - * This method returns -1 if the class is not a nested class. - * - *

The returned value is obtained from inner_class_access_flags - * of the entry representing this nested class itself - * in InnerClasses_attribute>. - */ - public int getInnerAccessFlags() { - InnerClassesAttribute ica - = (InnerClassesAttribute)getAttribute(InnerClassesAttribute.tag); - if (ica == null) - return -1; - - String name = getName(); - int n = ica.tableLength(); - for (int i = 0; i < n; ++i) - if (name.equals(ica.innerClass(i))) - return ica.accessFlags(i); - - return -1; - } - - /** - * Returns the class name. - */ - public String getName() { - return thisclassname; - } - - /** - * Sets the class name. This method substitutes the new name for all - * occurrences of the old class name in the class file. - */ - public void setName(String name) { - renameClass(thisclassname, name); - } - - /** - * Returns the super class name. - */ - public String getSuperclass() { - if (cachedSuperclass == null) - cachedSuperclass = constPool.getClassInfo(superClass); - - return cachedSuperclass; - } - - /** - * Returns the index of the constant pool entry representing the super - * class. - */ - public int getSuperclassId() { - return superClass; - } - - /** - * Sets the super class. - * - *

- * The new super class should inherit from the old super class. - * This method modifies constructors so that they call constructors declared - * in the new super class. - */ - public void setSuperclass(String superclass) throws CannotCompileException { - if (superclass == null) - superclass = "java.lang.Object"; - - try { - this.superClass = constPool.addClassInfo(superclass); - ArrayList list = methods; - int n = list.size(); - for (int i = 0; i < n; ++i) { - MethodInfo minfo = (MethodInfo)list.get(i); - minfo.setSuperclass(superclass); - } - } - catch (BadBytecode e) { - throw new CannotCompileException(e); - } - cachedSuperclass = superclass; - } - - /** - * Replaces all occurrences of a class name in the class file. - * - *

- * If class X is substituted for class Y in the class file, X and Y must - * have the same signature. If Y provides a method m(), X must provide it - * even if X inherits m() from the super class. If this fact is not - * guaranteed, the bytecode verifier may cause an error. - * - * @param oldname - * the replaced class name - * @param newname - * the substituted class name - */ - public final void renameClass(String oldname, String newname) { - ArrayList list; - int n; - - if (oldname.equals(newname)) - return; - - if (oldname.equals(thisclassname)) - thisclassname = newname; - - oldname = Descriptor.toJvmName(oldname); - newname = Descriptor.toJvmName(newname); - constPool.renameClass(oldname, newname); - - AttributeInfo.renameClass(attributes, oldname, newname); - list = methods; - n = list.size(); - for (int i = 0; i < n; ++i) { - MethodInfo minfo = (MethodInfo)list.get(i); - String desc = minfo.getDescriptor(); - minfo.setDescriptor(Descriptor.rename(desc, oldname, newname)); - AttributeInfo.renameClass(minfo.getAttributes(), oldname, newname); - } - - list = fields; - n = list.size(); - for (int i = 0; i < n; ++i) { - FieldInfo finfo = (FieldInfo)list.get(i); - String desc = finfo.getDescriptor(); - finfo.setDescriptor(Descriptor.rename(desc, oldname, newname)); - AttributeInfo.renameClass(finfo.getAttributes(), oldname, newname); - } - } - - /** - * Replaces all occurrences of several class names in the class file. - * - * @param classnames - * specifies which class name is replaced with which new name. - * Class names must be described with the JVM-internal - * representation like java/lang/Object. - * @see #renameClass(String,String) - */ - public final void renameClass(Map classnames) { - String jvmNewThisName = (String)classnames.get(Descriptor - .toJvmName(thisclassname)); - if (jvmNewThisName != null) - thisclassname = Descriptor.toJavaName(jvmNewThisName); - - constPool.renameClass(classnames); - - AttributeInfo.renameClass(attributes, classnames); - ArrayList list = methods; - int n = list.size(); - for (int i = 0; i < n; ++i) { - MethodInfo minfo = (MethodInfo)list.get(i); - String desc = minfo.getDescriptor(); - minfo.setDescriptor(Descriptor.rename(desc, classnames)); - AttributeInfo.renameClass(minfo.getAttributes(), classnames); - } - - list = fields; - n = list.size(); - for (int i = 0; i < n; ++i) { - FieldInfo finfo = (FieldInfo)list.get(i); - String desc = finfo.getDescriptor(); - finfo.setDescriptor(Descriptor.rename(desc, classnames)); - AttributeInfo.renameClass(finfo.getAttributes(), classnames); - } - } - - /** - * Internal-use only. - * CtClass.getRefClasses() calls this method. - */ - public final void getRefClasses(Map classnames) { - constPool.renameClass(classnames); - - AttributeInfo.getRefClasses(attributes, classnames); - ArrayList list = methods; - int n = list.size(); - for (int i = 0; i < n; ++i) { - MethodInfo minfo = (MethodInfo)list.get(i); - String desc = minfo.getDescriptor(); - Descriptor.rename(desc, classnames); - AttributeInfo.getRefClasses(minfo.getAttributes(), classnames); - } - - list = fields; - n = list.size(); - for (int i = 0; i < n; ++i) { - FieldInfo finfo = (FieldInfo)list.get(i); - String desc = finfo.getDescriptor(); - Descriptor.rename(desc, classnames); - AttributeInfo.getRefClasses(finfo.getAttributes(), classnames); - } - } - - /** - * Returns the names of the interfaces implemented by the class. - * The returned array is read only. - */ - public String[] getInterfaces() { - if (cachedInterfaces != null) - return cachedInterfaces; - - String[] rtn = null; - if (interfaces == null) - rtn = new String[0]; - else { - int n = interfaces.length; - String[] list = new String[n]; - for (int i = 0; i < n; ++i) - list[i] = constPool.getClassInfo(interfaces[i]); - - rtn = list; - } - - cachedInterfaces = rtn; - return rtn; - } - - /** - * Sets the interfaces. - * - * @param nameList - * the names of the interfaces. - */ - public void setInterfaces(String[] nameList) { - cachedInterfaces = null; - if (nameList != null) { - int n = nameList.length; - interfaces = new int[n]; - for (int i = 0; i < n; ++i) - interfaces[i] = constPool.addClassInfo(nameList[i]); - } - } - - /** - * Appends an interface to the interfaces implemented by the class. - */ - public void addInterface(String name) { - cachedInterfaces = null; - int info = constPool.addClassInfo(name); - if (interfaces == null) { - interfaces = new int[1]; - interfaces[0] = info; - } - else { - int n = interfaces.length; - int[] newarray = new int[n + 1]; - System.arraycopy(interfaces, 0, newarray, 0, n); - newarray[n] = info; - interfaces = newarray; - } - } - - /** - * Returns all the fields declared in the class. - * - * @return a list of FieldInfo. - * @see FieldInfo - */ - public List getFields() { - return fields; - } - - /** - * Appends a field to the class. - * - * @throws DuplicateMemberException when the field is already included. - */ - public void addField(FieldInfo finfo) throws DuplicateMemberException { - testExistingField(finfo.getName(), finfo.getDescriptor()); - fields.add(finfo); - } - - /** - * Just appends a field to the class. - * It does not check field duplication. - * Use this method only when minimizing performance overheads - * is seriously required. - * - * @since 3.13 - */ - public final void addField2(FieldInfo finfo) { - fields.add(finfo); - } - - private void testExistingField(String name, String descriptor) - throws DuplicateMemberException { - ListIterator it = fields.listIterator(0); - while (it.hasNext()) { - FieldInfo minfo = (FieldInfo)it.next(); - if (minfo.getName().equals(name)) - throw new DuplicateMemberException("duplicate field: " + name); - } - } - - /** - * Returns all the methods declared in the class. - * - * @return a list of MethodInfo. - * @see MethodInfo - */ - public List getMethods() { - return methods; - } - - /** - * Returns the method with the specified name. If there are multiple methods - * with that name, this method returns one of them. - * - * @return null if no such method is found. - */ - public MethodInfo getMethod(String name) { - ArrayList list = methods; - int n = list.size(); - for (int i = 0; i < n; ++i) { - MethodInfo minfo = (MethodInfo)list.get(i); - if (minfo.getName().equals(name)) - return minfo; - } - - return null; - } - - /** - * Returns a static initializer (class initializer), or null if it does not - * exist. - */ - public MethodInfo getStaticInitializer() { - return getMethod(MethodInfo.nameClinit); - } - - /** - * Appends a method to the class. - * If there is a bridge method with the same name and signature, - * then the bridge method is removed before a new method is added. - * - * @throws DuplicateMemberException when the method is already included. - */ - public void addMethod(MethodInfo minfo) throws DuplicateMemberException { - testExistingMethod(minfo); - methods.add(minfo); - } - - /** - * Just appends a method to the class. - * It does not check method duplication or remove a bridge method. - * Use this method only when minimizing performance overheads - * is seriously required. - * - * @since 3.13 - */ - public final void addMethod2(MethodInfo minfo) { - methods.add(minfo); - } - - private void testExistingMethod(MethodInfo newMinfo) - throws DuplicateMemberException - { - String name = newMinfo.getName(); - String descriptor = newMinfo.getDescriptor(); - ListIterator it = methods.listIterator(0); - while (it.hasNext()) - if (isDuplicated(newMinfo, name, descriptor, (MethodInfo)it.next(), it)) - throw new DuplicateMemberException("duplicate method: " + name - + " in " + this.getName()); - } - - private static boolean isDuplicated(MethodInfo newMethod, String newName, - String newDesc, MethodInfo minfo, - ListIterator it) - { - if (!minfo.getName().equals(newName)) - return false; - - String desc = minfo.getDescriptor(); - if (!Descriptor.eqParamTypes(desc, newDesc)) - return false; - - if (desc.equals(newDesc)) { - if (notBridgeMethod(minfo)) - return true; - else { - // if the bridge method with the same signature - // already exists, replace it. - it.remove(); - return false; - } - } - else - return false; - // return notBridgeMethod(minfo) && notBridgeMethod(newMethod); - } - - /* For a bridge method, see Sec. 15.12.4.5 of JLS 3rd Ed. - */ - private static boolean notBridgeMethod(MethodInfo minfo) { - return (minfo.getAccessFlags() & AccessFlag.BRIDGE) == 0; - } - - /** - * Returns all the attributes. The returned List object - * is shared with this object. If you add a new attribute to the list, - * the attribute is also added to the classs file represented by this - * object. If you remove an attribute from the list, it is also removed - * from the class file. - * - * @return a list of AttributeInfo objects. - * @see AttributeInfo - */ - public List getAttributes() { - return attributes; - } - - /** - * Returns the attribute with the specified name. If there are multiple - * attributes with that name, this method returns either of them. It - * returns null if the specified attributed is not found. - * - * @param name attribute name - * @see #getAttributes() - */ - public AttributeInfo getAttribute(String name) { - ArrayList list = attributes; - int n = list.size(); - for (int i = 0; i < n; ++i) { - AttributeInfo ai = (AttributeInfo)list.get(i); - if (ai.getName().equals(name)) - return ai; - } - - return null; - } - - /** - * Appends an attribute. If there is already an attribute with the same - * name, the new one substitutes for it. - * - * @see #getAttributes() - */ - public void addAttribute(AttributeInfo info) { - AttributeInfo.remove(attributes, info.getName()); - attributes.add(info); - } - - /** - * Returns the source file containing this class. - * - * @return null if this information is not available. - */ - public String getSourceFile() { - SourceFileAttribute sf - = (SourceFileAttribute)getAttribute(SourceFileAttribute.tag); - if (sf == null) - return null; - else - return sf.getFileName(); - } - - private void read(DataInputStream in) throws IOException { - int i, n; - int magic = in.readInt(); - if (magic != 0xCAFEBABE) - throw new IOException("bad magic number: " + Integer.toHexString(magic)); - - minor = in.readUnsignedShort(); - major = in.readUnsignedShort(); - constPool = new ConstPool(in); - accessFlags = in.readUnsignedShort(); - thisClass = in.readUnsignedShort(); - constPool.setThisClassInfo(thisClass); - superClass = in.readUnsignedShort(); - n = in.readUnsignedShort(); - if (n == 0) - interfaces = null; - else { - interfaces = new int[n]; - for (i = 0; i < n; ++i) - interfaces[i] = in.readUnsignedShort(); - } - - ConstPool cp = constPool; - n = in.readUnsignedShort(); - fields = new ArrayList(); - for (i = 0; i < n; ++i) - addField2(new FieldInfo(cp, in)); - - n = in.readUnsignedShort(); - methods = new ArrayList(); - for (i = 0; i < n; ++i) - addMethod2(new MethodInfo(cp, in)); - - attributes = new ArrayList(); - n = in.readUnsignedShort(); - for (i = 0; i < n; ++i) - addAttribute(AttributeInfo.read(cp, in)); - - thisclassname = constPool.getClassInfo(thisClass); - } - - /** - * Writes a class file represented by this object into an output stream. - */ - public void write(DataOutputStream out) throws IOException { - int i, n; - - out.writeInt(0xCAFEBABE); // magic - out.writeShort(minor); // minor version - out.writeShort(major); // major version - constPool.write(out); // constant pool - out.writeShort(accessFlags); - out.writeShort(thisClass); - out.writeShort(superClass); - - if (interfaces == null) - n = 0; - else - n = interfaces.length; - - out.writeShort(n); - for (i = 0; i < n; ++i) - out.writeShort(interfaces[i]); - - ArrayList list = fields; - n = list.size(); - out.writeShort(n); - for (i = 0; i < n; ++i) { - FieldInfo finfo = (FieldInfo)list.get(i); - finfo.write(out); - } - - list = methods; - n = list.size(); - out.writeShort(n); - for (i = 0; i < n; ++i) { - MethodInfo minfo = (MethodInfo)list.get(i); - minfo.write(out); - } - - out.writeShort(attributes.size()); - AttributeInfo.writeAll(attributes, out); - } - - /** - * Get the Major version. - * - * @return the major version - */ - public int getMajorVersion() { - return major; - } - - /** - * Set the major version. - * - * @param major - * the major version - */ - public void setMajorVersion(int major) { - this.major = major; - } - - /** - * Get the minor version. - * - * @return the minor version - */ - public int getMinorVersion() { - return minor; - } - - /** - * Set the minor version. - * - * @param minor - * the minor version - */ - public void setMinorVersion(int minor) { - this.minor = minor; - } - - /** - * Sets the major and minor version to Java 5. - * - * If the major version is older than 49, Java 5 - * extensions such as annotations are ignored - * by the JVM. - */ - public void setVersionToJava5() { - this.major = 49; - this.minor = 0; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ClassFilePrinter.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ClassFilePrinter.java deleted file mode 100644 index ae1a7671b..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ClassFilePrinter.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.PrintWriter; -import com.fr.third.javassist.Modifier; - -import java.util.List; - -/** - * A utility class for priting the contents of a class file. - * It prints a constant pool table, fields, and methods in a - * human readable representation. - */ -public class ClassFilePrinter { - /** - * Prints the contents of a class file to the standard output stream. - */ - public static void print(com.fr.third.javassist.bytecode.ClassFile cf) { - print(cf, new PrintWriter(System.out, true)); - } - - /** - * Prints the contents of a class file. - */ - public static void print(ClassFile cf, PrintWriter out) { - List list; - int n; - - /* 0x0020 (SYNCHRONIZED) means ACC_SUPER if the modifiers - * are of a class. - */ - int mod - = com.fr.third.javassist.bytecode.AccessFlag.toModifier(cf.getAccessFlags() - & ~com.fr.third.javassist.bytecode.AccessFlag.SYNCHRONIZED); - out.println("major: " + cf.major + ", minor: " + cf.minor - + " modifiers: " + Integer.toHexString(cf.getAccessFlags())); - out.println(Modifier.toString(mod) + " class " - + cf.getName() + " extends " + cf.getSuperclass()); - - String[] infs = cf.getInterfaces(); - if (infs != null && infs.length > 0) { - out.print(" implements "); - out.print(infs[0]); - for (int i = 1; i < infs.length; ++i) - out.print(", " + infs[i]); - - out.println(); - } - - out.println(); - list = cf.getFields(); - n = list.size(); - for (int i = 0; i < n; ++i) { - com.fr.third.javassist.bytecode.FieldInfo finfo = (FieldInfo)list.get(i); - int acc = finfo.getAccessFlags(); - out.println(Modifier.toString(com.fr.third.javassist.bytecode.AccessFlag.toModifier(acc)) - + " " + finfo.getName() + "\t" - + finfo.getDescriptor()); - printAttributes(finfo.getAttributes(), out, 'f'); - } - - out.println(); - list = cf.getMethods(); - n = list.size(); - for (int i = 0; i < n; ++i) { - com.fr.third.javassist.bytecode.MethodInfo minfo = (MethodInfo)list.get(i); - int acc = minfo.getAccessFlags(); - out.println(Modifier.toString(AccessFlag.toModifier(acc)) - + " " + minfo.getName() + "\t" - + minfo.getDescriptor()); - printAttributes(minfo.getAttributes(), out, 'm'); - out.println(); - } - - out.println(); - printAttributes(cf.getAttributes(), out, 'c'); - } - - static void printAttributes(List list, PrintWriter out, char kind) { - if (list == null) - return; - - int n = list.size(); - for (int i = 0; i < n; ++i) { - com.fr.third.javassist.bytecode.AttributeInfo ai = (AttributeInfo)list.get(i); - if (ai instanceof com.fr.third.javassist.bytecode.CodeAttribute) { - com.fr.third.javassist.bytecode.CodeAttribute ca = (CodeAttribute)ai; - out.println("attribute: " + ai.getName() + ": " - + ai.getClass().getName()); - out.println("max stack " + ca.getMaxStack() - + ", max locals " + ca.getMaxLocals() - + ", " + ca.getExceptionTable().size() - + " catch blocks"); - out.println(""); - printAttributes(ca.getAttributes(), out, kind); - out.println(""); - } - else if (ai instanceof AnnotationsAttribute) { - out.println("annnotation: " + ai.toString()); - } - else if (ai instanceof ParameterAnnotationsAttribute) { - out.println("parameter annnotations: " + ai.toString()); - } - else if (ai instanceof com.fr.third.javassist.bytecode.StackMapTable) { - out.println(""); - com.fr.third.javassist.bytecode.StackMapTable.Printer.print((StackMapTable)ai, out); - out.println(""); - } - else if (ai instanceof com.fr.third.javassist.bytecode.StackMap) { - out.println(""); - ((StackMap)ai).print(out); - out.println(""); - } - else if (ai instanceof SignatureAttribute) { - SignatureAttribute sa = (SignatureAttribute)ai; - String sig = sa.getSignature(); - out.println("signature: " + sig); - try { - String s; - if (kind == 'c') - s = SignatureAttribute.toClassSignature(sig).toString(); - else if (kind == 'm') - s = SignatureAttribute.toMethodSignature(sig).toString(); - else - s = SignatureAttribute.toFieldSignature(sig).toString(); - - out.println(" " + s); - } - catch (BadBytecode e) { - out.println(" syntax error"); - } - } - else - out.println("attribute: " + ai.getName() - + " (" + ai.get().length + " byte): " - + ai.getClass().getName()); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ClassFileWriter.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ClassFileWriter.java deleted file mode 100644 index 2d7fa0d69..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ClassFileWriter.java +++ /dev/null @@ -1,782 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.OutputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * A quick class-file writer. This is useful when a generated - * class file is simple and the code generation should be fast. - * - *

Example: - * - *

- * ClassFileWriter cfw = new ClassFileWriter(ClassFile.JAVA_4, 0);
- * ConstPoolWriter cpw = cfw.getConstPool();
- *
- * FieldWriter fw = cfw.getFieldWriter();
- * fw.add(AccessFlag.PUBLIC, "value", "I", null);
- * fw.add(AccessFlag.PUBLIC, "value2", "J", null);
- *
- * int thisClass = cpw.addClassInfo("sample/Test");
- * int superClass = cpw.addClassInfo("java/lang/Object");
- *
- * MethodWriter mw = cfw.getMethodWriter();
- *
- * mw.begin(AccessFlag.PUBLIC, MethodInfo.nameInit, "()V", null, null);
- * mw.add(Opcode.ALOAD_0);
- * mw.add(Opcode.INVOKESPECIAL);
- * int signature = cpw.addNameAndTypeInfo(MethodInfo.nameInit, "()V");
- * mw.add16(cpw.addMethodrefInfo(superClass, signature));
- * mw.add(Opcode.RETURN);
- * mw.codeEnd(1, 1);
- * mw.end(null, null);
- *
- * mw.begin(AccessFlag.PUBLIC, "one", "()I", null, null);
- * mw.add(Opcode.ICONST_1);
- * mw.add(Opcode.IRETURN);
- * mw.codeEnd(1, 1);
- * mw.end(null, null);
- *
- * byte[] classfile = cfw.end(AccessFlag.PUBLIC, thisClass, superClass,
- *                            null, null);
- * 
- * - *

The code above generates the following class: - * - *

- * package sample;
- * public class Test {
- *     public int value;
- *     public long value2;
- *     public Test() { super(); }
- *     public one() { return 1; }
- * }
- * 
- * - * @since 3.13 - */ -public class ClassFileWriter { - private com.fr.third.javassist.bytecode.ByteStream output; - private ConstPoolWriter constPool; - private FieldWriter fields; - private MethodWriter methods; - int thisClass, superClass; - - /** - * Constructs a class file writer. - * - * @param major the major version ({@link com.fr.third.javassist.bytecode.ClassFile#JAVA_4}, {@link ClassFile#JAVA_5}, ...). - * @param minor the minor version (0 for JDK 1.3 and later). - */ - public ClassFileWriter(int major, int minor) { - output = new com.fr.third.javassist.bytecode.ByteStream(512); - output.writeInt(0xCAFEBABE); // magic - output.writeShort(minor); - output.writeShort(major); - constPool = new ConstPoolWriter(output); - fields = new FieldWriter(constPool); - methods = new MethodWriter(constPool); - - } - - /** - * Returns a constant pool. - */ - public ConstPoolWriter getConstPool() { return constPool; } - - /** - * Returns a filed writer. - */ - public FieldWriter getFieldWriter() { return fields; } - - /** - * Returns a method writer. - */ - public MethodWriter getMethodWriter() { return methods; } - - /** - * Ends writing and returns the contents of the class file. - * - * @param accessFlags access flags. - * @param thisClass this class. an index indicating its CONSTANT_Class_info. - * @param superClass super class. an index indicating its CONSTANT_Class_info. - * @param interfaces implemented interfaces. - * index numbers indicating their ClassInfo. - * It may be null. - * @param aw attributes of the class file. May be null. - * - * @see com.fr.third.javassist.bytecode.AccessFlag - */ - public byte[] end(int accessFlags, int thisClass, int superClass, - int[] interfaces, AttributeWriter aw) { - constPool.end(); - output.writeShort(accessFlags); - output.writeShort(thisClass); - output.writeShort(superClass); - if (interfaces == null) - output.writeShort(0); - else { - int n = interfaces.length; - output.writeShort(n); - for (int i = 0; i < n; i++) - output.writeShort(interfaces[i]); - } - - output.enlarge(fields.dataSize() + methods.dataSize() + 6); - try { - output.writeShort(fields.size()); - fields.write(output); - - output.writeShort(methods.size()); - methods.write(output); - } - catch (IOException e) {} - - writeAttribute(output, aw, 0); - return output.toByteArray(); - } - - /** - * Ends writing and writes the contents of the class file into the - * given output stream. - * - * @param accessFlags access flags. - * @param thisClass this class. an index indicating its CONSTANT_Class_info. - * @param superClass super class. an index indicating its CONSTANT_Class_info. - * @param interfaces implemented interfaces. - * index numbers indicating their CONSTATNT_Class_info. - * It may be null. - * @param aw attributes of the class file. May be null. - * - * @see com.fr.third.javassist.bytecode.AccessFlag - */ - public void end(DataOutputStream out, - int accessFlags, int thisClass, int superClass, - int[] interfaces, AttributeWriter aw) - throws IOException - { - constPool.end(); - output.writeTo(out); - out.writeShort(accessFlags); - out.writeShort(thisClass); - out.writeShort(superClass); - if (interfaces == null) - out.writeShort(0); - else { - int n = interfaces.length; - out.writeShort(n); - for (int i = 0; i < n; i++) - out.writeShort(interfaces[i]); - } - - out.writeShort(fields.size()); - fields.write(out); - - out.writeShort(methods.size()); - methods.write(out); - if (aw == null) - out.writeShort(0); - else { - out.writeShort(aw.size()); - aw.write(out); - } - } - - /** - * This writes attributes. - * - *

For example, the following object writes a synthetic attribute: - * - *

-     * ConstPoolWriter cpw = ...;
-     * final int tag = cpw.addUtf8Info("Synthetic");
-     * AttributeWriter aw = new AttributeWriter() {
-     *     public int size() {
-     *         return 1;
-     *     }
-     *     public void write(DataOutputStream out) throws java.io.IOException {
-     *         out.writeShort(tag);
-     *         out.writeInt(0);
-     *     }
-     * };
-     * 
- */ - public static interface AttributeWriter { - /** - * Returns the number of attributes that this writer will - * write. - */ - public int size(); - - /** - * Writes all the contents of the attributes. The binary representation - * of the contents is an array of attribute_info. - */ - public void write(DataOutputStream out) throws IOException; - } - - static void writeAttribute(com.fr.third.javassist.bytecode.ByteStream bs, AttributeWriter aw, int attrCount) { - if (aw == null) { - bs.writeShort(attrCount); - return; - } - - bs.writeShort(aw.size() + attrCount); - DataOutputStream dos = new DataOutputStream(bs); - try { - aw.write(dos); - dos.flush(); - } - catch (IOException e) {} - } - - /** - * Field. - */ - public static final class FieldWriter { - protected com.fr.third.javassist.bytecode.ByteStream output; - protected ConstPoolWriter constPool; - private int fieldCount; - - FieldWriter(ConstPoolWriter cp) { - output = new com.fr.third.javassist.bytecode.ByteStream(128); - constPool = cp; - fieldCount = 0; - } - - /** - * Adds a new field. - * - * @param accessFlags access flags. - * @param name the field name. - * @param descriptor the field type. - * @param aw the attributes of the field. may be null. - * @see com.fr.third.javassist.bytecode.AccessFlag - */ - public void add(int accessFlags, String name, String descriptor, AttributeWriter aw) { - int nameIndex = constPool.addUtf8Info(name); - int descIndex = constPool.addUtf8Info(descriptor); - add(accessFlags, nameIndex, descIndex, aw); - } - - /** - * Adds a new field. - * - * @param accessFlags access flags. - * @param name the field name. an index indicating its CONSTANT_Utf8_info. - * @param descriptor the field type. an index indicating its CONSTANT_Utf8_info. - * @param aw the attributes of the field. may be null. - * @see com.fr.third.javassist.bytecode.AccessFlag - */ - public void add(int accessFlags, int name, int descriptor, AttributeWriter aw) { - ++fieldCount; - output.writeShort(accessFlags); - output.writeShort(name); - output.writeShort(descriptor); - writeAttribute(output, aw, 0); - } - - int size() { return fieldCount; } - - int dataSize() { return output.size(); } - - /** - * Writes the added fields. - */ - void write(OutputStream out) throws IOException { - output.writeTo(out); - } - } - - /** - * Method. - */ - public static final class MethodWriter { - protected com.fr.third.javassist.bytecode.ByteStream output; - protected ConstPoolWriter constPool; - private int methodCount; - protected int codeIndex; - protected int throwsIndex; - protected int stackIndex; - - private int startPos; - private boolean isAbstract; - private int catchPos; - private int catchCount; - - MethodWriter(ConstPoolWriter cp) { - output = new com.fr.third.javassist.bytecode.ByteStream(256); - constPool = cp; - methodCount = 0; - codeIndex = 0; - throwsIndex = 0; - stackIndex = 0; - } - - /** - * Starts Adding a new method. - * - * @param accessFlags access flags. - * @param name the method name. - * @param descriptor the method signature. - * @param exceptions throws clause. It may be null. - * The class names must be the JVM-internal - * representations like java/lang/Exception. - * @param aw attributes to the Method_info. - */ - public void begin(int accessFlags, String name, String descriptor, - String[] exceptions, AttributeWriter aw) { - int nameIndex = constPool.addUtf8Info(name); - int descIndex = constPool.addUtf8Info(descriptor); - int[] intfs; - if (exceptions == null) - intfs = null; - else - intfs = constPool.addClassInfo(exceptions); - - begin(accessFlags, nameIndex, descIndex, intfs, aw); - } - - /** - * Starts adding a new method. - * - * @param accessFlags access flags. - * @param name the method name. an index indicating its CONSTANT_Utf8_info. - * @param descriptor the field type. an index indicating its CONSTANT_Utf8_info. - * @param exceptions throws clause. indexes indicating CONSTANT_Class_infos. - * It may be null. - * @param aw attributes to the Method_info. - */ - public void begin(int accessFlags, int name, int descriptor, int[] exceptions, AttributeWriter aw) { - ++methodCount; - output.writeShort(accessFlags); - output.writeShort(name); - output.writeShort(descriptor); - isAbstract = (accessFlags & AccessFlag.ABSTRACT) != 0; - - int attrCount = isAbstract ? 0 : 1; - if (exceptions != null) - ++attrCount; - - writeAttribute(output, aw, attrCount); - - if (exceptions != null) - writeThrows(exceptions); - - if (!isAbstract) { - if (codeIndex == 0) - codeIndex = constPool.addUtf8Info(CodeAttribute.tag); - - startPos = output.getPos(); - output.writeShort(codeIndex); - output.writeBlank(12); // attribute_length, maxStack, maxLocals, code_lenth - } - - catchPos = -1; - catchCount = 0; - } - - private void writeThrows(int[] exceptions) { - if (throwsIndex == 0) - throwsIndex = constPool.addUtf8Info(ExceptionsAttribute.tag); - - output.writeShort(throwsIndex); - output.writeInt(exceptions.length * 2 + 2); - output.writeShort(exceptions.length); - for (int i = 0; i < exceptions.length; i++) - output.writeShort(exceptions[i]); - } - - /** - * Appends an 8bit value of bytecode. - * - * @see com.fr.third.javassist.bytecode.Opcode - */ - public void add(int b) { - output.write(b); - } - - /** - * Appends a 16bit value of bytecode. - */ - public void add16(int b) { - output.writeShort(b); - } - - /** - * Appends a 32bit value of bytecode. - */ - public void add32(int b) { - output.writeInt(b); - } - - /** - * Appends a invokevirtual, inovkespecial, or invokestatic bytecode. - * - * @see Opcode - */ - public void addInvoke(int opcode, String targetClass, String methodName, - String descriptor) { - int target = constPool.addClassInfo(targetClass); - int nt = constPool.addNameAndTypeInfo(methodName, descriptor); - int method = constPool.addMethodrefInfo(target, nt); - add(opcode); - add16(method); - } - - /** - * Ends appending bytecode. - */ - public void codeEnd(int maxStack, int maxLocals) { - if (!isAbstract) { - output.writeShort(startPos + 6, maxStack); - output.writeShort(startPos + 8, maxLocals); - output.writeInt(startPos + 10, output.getPos() - startPos - 14); // code_length - catchPos = output.getPos(); - catchCount = 0; - output.writeShort(0); // number of catch clauses - } - } - - /** - * Appends an exception_table entry to the - * Code_attribute. This method is available - * only after the codeEnd method is called. - * - * @param catchType an index indicating a CONSTANT_Class_info. - */ - public void addCatch(int startPc, int endPc, int handlerPc, int catchType) { - ++catchCount; - output.writeShort(startPc); - output.writeShort(endPc); - output.writeShort(handlerPc); - output.writeShort(catchType); - } - - /** - * Ends adding a new method. The add method must be - * called before the end method is called. - * - * @param smap a stack map table. may be null. - * @param aw attributes to the Code_attribute. - * may be null. - */ - public void end(com.fr.third.javassist.bytecode.StackMapTable.Writer smap, AttributeWriter aw) { - if (isAbstract) - return; - - // exception_table_length - output.writeShort(catchPos, catchCount); - - int attrCount = smap == null ? 0 : 1; - writeAttribute(output, aw, attrCount); - - if (smap != null) { - if (stackIndex == 0) - stackIndex = constPool.addUtf8Info(StackMapTable.tag); - - output.writeShort(stackIndex); - byte[] data = smap.toByteArray(); - output.writeInt(data.length); - output.write(data); - } - - // Code attribute_length - output.writeInt(startPos + 2, output.getPos() - startPos - 6); - } - - int size() { return methodCount; } - - int dataSize() { return output.size(); } - - /** - * Writes the added methods. - */ - void write(OutputStream out) throws IOException { - output.writeTo(out); - } - } - - /** - * Constant Pool. - */ - public static final class ConstPoolWriter { - com.fr.third.javassist.bytecode.ByteStream output; - protected int startPos; - protected int num; - - ConstPoolWriter(com.fr.third.javassist.bytecode.ByteStream out) { - output = out; - startPos = out.getPos(); - num = 1; - output.writeShort(1); // number of entries - } - - /** - * Makes CONSTANT_Class_info objects for each class name. - * - * @return an array of indexes indicating CONSTANT_Class_infos. - */ - public int[] addClassInfo(String[] classNames) { - int n = classNames.length; - int[] result = new int[n]; - for (int i = 0; i < n; i++) - result[i] = addClassInfo(classNames[i]); - - return result; - } - - /** - * Adds a new CONSTANT_Class_info structure. - * - *

This also adds a CONSTANT_Utf8_info structure - * for storing the class name. - * - * @param jvmname the JVM-internal representation of a class name. - * e.g. java/lang/Object. - * @return the index of the added entry. - */ - public int addClassInfo(String jvmname) { - int utf8 = addUtf8Info(jvmname); - output.write(com.fr.third.javassist.bytecode.ClassInfo.tag); - output.writeShort(utf8); - return num++; - } - - /** - * Adds a new CONSTANT_Class_info structure. - * - * @param name name_index - * @return the index of the added entry. - */ - public int addClassInfo(int name) { - output.write(com.fr.third.javassist.bytecode.ClassInfo.tag); - output.writeShort(name); - return num++; - } - - /** - * Adds a new CONSTANT_NameAndType_info structure. - * - * @param name name_index - * @param type descriptor_index - * @return the index of the added entry. - */ - public int addNameAndTypeInfo(String name, String type) { - return addNameAndTypeInfo(addUtf8Info(name), addUtf8Info(type)); - } - - /** - * Adds a new CONSTANT_NameAndType_info structure. - * - * @param name name_index - * @param type descriptor_index - * @return the index of the added entry. - */ - public int addNameAndTypeInfo(int name, int type) { - output.write(com.fr.third.javassist.bytecode.NameAndTypeInfo.tag); - output.writeShort(name); - output.writeShort(type); - return num++; - } - - /** - * Adds a new CONSTANT_Fieldref_info structure. - * - * @param classInfo class_index - * @param nameAndTypeInfo name_and_type_index. - * @return the index of the added entry. - */ - public int addFieldrefInfo(int classInfo, int nameAndTypeInfo) { - output.write(com.fr.third.javassist.bytecode.FieldrefInfo.tag); - output.writeShort(classInfo); - output.writeShort(nameAndTypeInfo); - return num++; - } - - /** - * Adds a new CONSTANT_Methodref_info structure. - * - * @param classInfo class_index - * @param nameAndTypeInfo name_and_type_index. - * @return the index of the added entry. - */ - public int addMethodrefInfo(int classInfo, int nameAndTypeInfo) { - output.write(com.fr.third.javassist.bytecode.MethodrefInfo.tag); - output.writeShort(classInfo); - output.writeShort(nameAndTypeInfo); - return num++; - } - - /** - * Adds a new CONSTANT_InterfaceMethodref_info - * structure. - * - * @param classInfo class_index - * @param nameAndTypeInfo name_and_type_index. - * @return the index of the added entry. - */ - public int addInterfaceMethodrefInfo(int classInfo, - int nameAndTypeInfo) { - output.write(com.fr.third.javassist.bytecode.InterfaceMethodrefInfo.tag); - output.writeShort(classInfo); - output.writeShort(nameAndTypeInfo); - return num++; - } - - /** - * Adds a new CONSTANT_MethodHandle_info - * structure. - * - * @param kind reference_kind - * such as {@link ConstPool#REF_invokeStatic REF_invokeStatic}. - * @param index reference_index. - * @return the index of the added entry. - * - * @since 3.17.1 - */ - public int addMethodHandleInfo(int kind, int index) { - output.write(com.fr.third.javassist.bytecode.MethodHandleInfo.tag); - output.write(kind); - output.writeShort(index); - return num++; - } - - /** - * Adds a new CONSTANT_MethodType_info - * structure. - * - * @param desc descriptor_index. - * @return the index of the added entry. - * - * @since 3.17.1 - */ - public int addMethodTypeInfo(int desc) { - output.write(com.fr.third.javassist.bytecode.MethodTypeInfo.tag); - output.writeShort(desc); - return num++; - } - - /** - * Adds a new CONSTANT_InvokeDynamic_info - * structure. - * - * @param bootstrap bootstrap_method_attr_index. - * @param nameAndTypeInfo name_and_type_index. - * @return the index of the added entry. - * - * @since 3.17.1 - */ - public int addInvokeDynamicInfo(int bootstrap, - int nameAndTypeInfo) { - output.write(com.fr.third.javassist.bytecode.InvokeDynamicInfo.tag); - output.writeShort(bootstrap); - output.writeShort(nameAndTypeInfo); - return num++; - } - - /** - * Adds a new CONSTANT_String_info - * structure. - * - *

This also adds a new CONSTANT_Utf8_info - * structure. - * - * @return the index of the added entry. - */ - public int addStringInfo(String str) { - int utf8 = addUtf8Info(str); - output.write(com.fr.third.javassist.bytecode.StringInfo.tag); - output.writeShort(utf8); - return num++; - } - - /** - * Adds a new CONSTANT_Integer_info - * structure. - * - * @return the index of the added entry. - */ - public int addIntegerInfo(int i) { - output.write(com.fr.third.javassist.bytecode.IntegerInfo.tag); - output.writeInt(i); - return num++; - } - - /** - * Adds a new CONSTANT_Float_info - * structure. - * - * @return the index of the added entry. - */ - public int addFloatInfo(float f) { - output.write(com.fr.third.javassist.bytecode.FloatInfo.tag); - output.writeFloat(f); - return num++; - } - - /** - * Adds a new CONSTANT_Long_info - * structure. - * - * @return the index of the added entry. - */ - public int addLongInfo(long l) { - output.write(com.fr.third.javassist.bytecode.LongInfo.tag); - output.writeLong(l); - int n = num; - num += 2; - return n; - } - - /** - * Adds a new CONSTANT_Double_info - * structure. - * - * @return the index of the added entry. - */ - public int addDoubleInfo(double d) { - output.write(com.fr.third.javassist.bytecode.DoubleInfo.tag); - output.writeDouble(d); - int n = num; - num += 2; - return n; - } - - /** - * Adds a new CONSTANT_Utf8_info - * structure. - * - * @return the index of the added entry. - */ - public int addUtf8Info(String utf8) { - output.write(com.fr.third.javassist.bytecode.Utf8Info.tag); - output.writeUTF(utf8); - return num++; - } - - /** - * Writes the contents of this class pool. - */ - void end() { - output.writeShort(startPos, num); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/CodeAnalyzer.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/CodeAnalyzer.java deleted file mode 100644 index 0047135e1..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/CodeAnalyzer.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -/** - * Utility for computing max_stack. - */ -class CodeAnalyzer implements Opcode { - private ConstPool constPool; - private CodeAttribute codeAttr; - - public CodeAnalyzer(CodeAttribute ca) { - codeAttr = ca; - constPool = ca.getConstPool(); - } - - public int computeMaxStack() - throws com.fr.third.javassist.bytecode.BadBytecode - { - /* d = stack[i] - * d == 0: not visited - * d > 0: the depth is d - 1 after executing the bytecode at i. - * d < 0: not visited. the initial depth (before execution) is 1 - d. - */ - CodeIterator ci = codeAttr.iterator(); - int length = ci.getCodeLength(); - int[] stack = new int[length]; - constPool = codeAttr.getConstPool(); - initStack(stack, codeAttr); - boolean repeat; - do { - repeat = false; - for (int i = 0; i < length; ++i) - if (stack[i] < 0) { - repeat = true; - visitBytecode(ci, stack, i); - } - } while (repeat); - - int maxStack = 1; - for (int i = 0; i < length; ++i) - if (stack[i] > maxStack) - maxStack = stack[i]; - - return maxStack - 1; // the base is 1. - } - - private void initStack(int[] stack, CodeAttribute ca) { - stack[0] = -1; - ExceptionTable et = ca.getExceptionTable(); - if (et != null) { - int size = et.size(); - for (int i = 0; i < size; ++i) - stack[et.handlerPc(i)] = -2; // an exception is on stack - } - } - - private void visitBytecode(CodeIterator ci, int[] stack, int index) - throws com.fr.third.javassist.bytecode.BadBytecode - { - int codeLength = stack.length; - ci.move(index); - int stackDepth = -stack[index]; - int[] jsrDepth = new int[1]; - jsrDepth[0] = -1; - while (ci.hasNext()) { - index = ci.next(); - stack[index] = stackDepth; - int op = ci.byteAt(index); - stackDepth = visitInst(op, ci, index, stackDepth); - if (stackDepth < 1) - throw new com.fr.third.javassist.bytecode.BadBytecode("stack underflow at " + index); - - if (processBranch(op, ci, index, codeLength, stack, stackDepth, jsrDepth)) - break; - - if (isEnd(op)) // return, ireturn, athrow, ... - break; - - if (op == JSR || op == JSR_W) - --stackDepth; - } - } - - private boolean processBranch(int opcode, CodeIterator ci, int index, - int codeLength, int[] stack, int stackDepth, int[] jsrDepth) - throws com.fr.third.javassist.bytecode.BadBytecode - { - if ((IFEQ <= opcode && opcode <= IF_ACMPNE) - || opcode == IFNULL || opcode == IFNONNULL) { - int target = index + ci.s16bitAt(index + 1); - checkTarget(index, target, codeLength, stack, stackDepth); - } - else { - int target, index2; - switch (opcode) { - case GOTO : - target = index + ci.s16bitAt(index + 1); - checkTarget(index, target, codeLength, stack, stackDepth); - return true; - case GOTO_W : - target = index + ci.s32bitAt(index + 1); - checkTarget(index, target, codeLength, stack, stackDepth); - return true; - case JSR : - case JSR_W : - if (opcode == JSR) - target = index + ci.s16bitAt(index + 1); - else - target = index + ci.s32bitAt(index + 1); - - checkTarget(index, target, codeLength, stack, stackDepth); - /* - * It is unknown which RET comes back to this JSR. - * So we assume that if the stack depth at one JSR instruction - * is N, then it is also N at other JSRs and N - 1 at all RET - * instructions. Note that STACK_GROW[JSR] is 1 since it pushes - * a return address on the operand stack. - */ - if (jsrDepth[0] < 0) { - jsrDepth[0] = stackDepth; - return false; - } - else if (stackDepth == jsrDepth[0]) - return false; - else - throw new com.fr.third.javassist.bytecode.BadBytecode( - "sorry, cannot compute this data flow due to JSR: " - + stackDepth + "," + jsrDepth[0]); - case RET : - if (jsrDepth[0] < 0) { - jsrDepth[0] = stackDepth + 1; - return false; - } - else if (stackDepth + 1 == jsrDepth[0]) - return true; - else - throw new com.fr.third.javassist.bytecode.BadBytecode( - "sorry, cannot compute this data flow due to RET: " - + stackDepth + "," + jsrDepth[0]); - case LOOKUPSWITCH : - case TABLESWITCH : - index2 = (index & ~3) + 4; - target = index + ci.s32bitAt(index2); - checkTarget(index, target, codeLength, stack, stackDepth); - if (opcode == LOOKUPSWITCH) { - int npairs = ci.s32bitAt(index2 + 4); - index2 += 12; - for (int i = 0; i < npairs; ++i) { - target = index + ci.s32bitAt(index2); - checkTarget(index, target, codeLength, - stack, stackDepth); - index2 += 8; - } - } - else { - int low = ci.s32bitAt(index2 + 4); - int high = ci.s32bitAt(index2 + 8); - int n = high - low + 1; - index2 += 12; - for (int i = 0; i < n; ++i) { - target = index + ci.s32bitAt(index2); - checkTarget(index, target, codeLength, - stack, stackDepth); - index2 += 4; - } - } - - return true; // always branch. - } - } - - return false; // may not branch. - } - - private void checkTarget(int opIndex, int target, int codeLength, - int[] stack, int stackDepth) - throws com.fr.third.javassist.bytecode.BadBytecode - { - if (target < 0 || codeLength <= target) - throw new com.fr.third.javassist.bytecode.BadBytecode("bad branch offset at " + opIndex); - - int d = stack[target]; - if (d == 0) - stack[target] = -stackDepth; - else if (d != stackDepth && d != -stackDepth) - throw new com.fr.third.javassist.bytecode.BadBytecode("verification error (" + stackDepth + - "," + d + ") at " + opIndex); - } - - private static boolean isEnd(int opcode) { - return (IRETURN <= opcode && opcode <= RETURN) || opcode == ATHROW; - } - - /** - * Visits an instruction. - */ - private int visitInst(int op, CodeIterator ci, int index, int stack) - throws BadBytecode - { - String desc; - switch (op) { - case GETFIELD : - stack += getFieldSize(ci, index) - 1; - break; - case PUTFIELD : - stack -= getFieldSize(ci, index) + 1; - break; - case GETSTATIC : - stack += getFieldSize(ci, index); - break; - case PUTSTATIC : - stack -= getFieldSize(ci, index); - break; - case INVOKEVIRTUAL : - case INVOKESPECIAL : - desc = constPool.getMethodrefType(ci.u16bitAt(index + 1)); - stack += com.fr.third.javassist.bytecode.Descriptor.dataSize(desc) - 1; - break; - case INVOKESTATIC : - desc = constPool.getMethodrefType(ci.u16bitAt(index + 1)); - stack += com.fr.third.javassist.bytecode.Descriptor.dataSize(desc); - break; - case INVOKEINTERFACE : - desc = constPool.getInterfaceMethodrefType( - ci.u16bitAt(index + 1)); - stack += com.fr.third.javassist.bytecode.Descriptor.dataSize(desc) - 1; - break; - case INVOKEDYNAMIC : - desc = constPool.getInvokeDynamicType(ci.u16bitAt(index + 1)); - stack += com.fr.third.javassist.bytecode.Descriptor.dataSize(desc); // assume CosntPool#REF_invokeStatic - break; - case ATHROW : - stack = 1; // the stack becomes empty (1 means no values). - break; - case MULTIANEWARRAY : - stack += 1 - ci.byteAt(index + 3); - break; - case WIDE : - op = ci.byteAt(index + 1); - // don't break here. - default : - stack += STACK_GROW[op]; - } - - return stack; - } - - private int getFieldSize(CodeIterator ci, int index) { - String desc = constPool.getFieldrefType(ci.u16bitAt(index + 1)); - return Descriptor.dataSize(desc); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/CodeAttribute.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/CodeAttribute.java deleted file mode 100644 index b349189a1..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/CodeAttribute.java +++ /dev/null @@ -1,594 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; - -/** - * Code_attribute. - * - *

To browse the code field of - * a Code_attribute structure, - * use CodeIterator. - * - * @see com.fr.third.javassist.bytecode.CodeIterator - * @see #iterator() - */ -public class CodeAttribute extends com.fr.third.javassist.bytecode.AttributeInfo implements Opcode { - /** - * The name of this attribute "Code". - */ - public static final String tag = "Code"; - - // code[] is stored in AttributeInfo.info. - - private int maxStack; - private int maxLocals; - private ExceptionTable exceptions; - private ArrayList attributes; - - /** - * Constructs a Code_attribute. - * - * @param cp constant pool table - * @param stack max_stack - * @param locals max_locals - * @param code code[] - * @param etable exception_table[] - */ - public CodeAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int stack, int locals, byte[] code, - ExceptionTable etable) - { - super(cp, tag); - maxStack = stack; - maxLocals = locals; - info = code; - exceptions = etable; - attributes = new ArrayList(); - } - - /** - * Constructs a copy of Code_attribute. - * Specified class names are replaced during the copy. - * - * @param cp constant pool table. - * @param src source Code attribute. - * @param classnames pairs of replaced and substituted - * class names. - */ - private CodeAttribute(com.fr.third.javassist.bytecode.ConstPool cp, CodeAttribute src, Map classnames) - throws com.fr.third.javassist.bytecode.BadBytecode - { - super(cp, tag); - - maxStack = src.getMaxStack(); - maxLocals = src.getMaxLocals(); - exceptions = src.getExceptionTable().copy(cp, classnames); - attributes = new ArrayList(); - List src_attr = src.getAttributes(); - int num = src_attr.size(); - for (int i = 0; i < num; ++i) { - com.fr.third.javassist.bytecode.AttributeInfo ai = (com.fr.third.javassist.bytecode.AttributeInfo)src_attr.get(i); - attributes.add(ai.copy(cp, classnames)); - } - - info = src.copyCode(cp, classnames, exceptions, this); - } - - CodeAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int name_id, DataInputStream in) - throws IOException - { - super(cp, name_id, (byte[])null); - int attr_len = in.readInt(); - - maxStack = in.readUnsignedShort(); - maxLocals = in.readUnsignedShort(); - - int code_len = in.readInt(); - info = new byte[code_len]; - in.readFully(info); - - exceptions = new ExceptionTable(cp, in); - - attributes = new ArrayList(); - int num = in.readUnsignedShort(); - for (int i = 0; i < num; ++i) - attributes.add(com.fr.third.javassist.bytecode.AttributeInfo.read(cp, in)); - } - - /** - * Makes a copy. Class names are replaced according to the - * given Map object. - * - * @param newCp the constant pool table used by the new copy. - * @param classnames pairs of replaced and substituted - * class names. - * @exception RuntimeCopyException if a BadBytecode - * exception is thrown, it is - * converted into - * RuntimeCopyException. - * - * @return CodeAttribute object. - */ - public com.fr.third.javassist.bytecode.AttributeInfo copy(com.fr.third.javassist.bytecode.ConstPool newCp, Map classnames) - throws RuntimeCopyException - { - try { - return new CodeAttribute(newCp, this, classnames); - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new RuntimeCopyException("bad bytecode. fatal?"); - } - } - - /** - * An exception that may be thrown by copy() - * in CodeAttribute. - */ - public static class RuntimeCopyException extends RuntimeException { - /** - * Constructs an exception. - */ - public RuntimeCopyException(String s) { - super(s); - } - } - - /** - * Returns the length of this attribute_info - * structure. - * The returned value is attribute_length + 6. - */ - public int length() { - return 18 + info.length + exceptions.size() * 8 - + com.fr.third.javassist.bytecode.AttributeInfo.getLength(attributes); - } - - void write(DataOutputStream out) throws IOException { - out.writeShort(name); // attribute_name_index - out.writeInt(length() - 6); // attribute_length - out.writeShort(maxStack); // max_stack - out.writeShort(maxLocals); // max_locals - out.writeInt(info.length); // code_length - out.write(info); // code - exceptions.write(out); - out.writeShort(attributes.size()); // attributes_count - com.fr.third.javassist.bytecode.AttributeInfo.writeAll(attributes, out); // attributes - } - - /** - * This method is not available. - * - * @throws java.lang.UnsupportedOperationException always thrown. - */ - public byte[] get() { - throw new UnsupportedOperationException("CodeAttribute.get()"); - } - - /** - * This method is not available. - * - * @throws java.lang.UnsupportedOperationException always thrown. - */ - public void set(byte[] newinfo) { - throw new UnsupportedOperationException("CodeAttribute.set()"); - } - - void renameClass(String oldname, String newname) { - com.fr.third.javassist.bytecode.AttributeInfo.renameClass(attributes, oldname, newname); - } - - void renameClass(Map classnames) { - com.fr.third.javassist.bytecode.AttributeInfo.renameClass(attributes, classnames); - } - - void getRefClasses(Map classnames) { - com.fr.third.javassist.bytecode.AttributeInfo.getRefClasses(attributes, classnames); - } - - /** - * Returns the name of the class declaring the method including - * this code attribute. - */ - public String getDeclaringClass() { - com.fr.third.javassist.bytecode.ConstPool cp = getConstPool(); - return cp.getClassName(); - } - - /** - * Returns max_stack. - */ - public int getMaxStack() { - return maxStack; - } - - /** - * Sets max_stack. - */ - public void setMaxStack(int value) { - maxStack = value; - } - - /** - * Computes the maximum stack size and sets max_stack - * to the computed size. - * - * @throws com.fr.third.javassist.bytecode.BadBytecode if this method fails in computing. - * @return the newly computed value of max_stack - */ - public int computeMaxStack() throws com.fr.third.javassist.bytecode.BadBytecode { - maxStack = new com.fr.third.javassist.bytecode.CodeAnalyzer(this).computeMaxStack(); - return maxStack; - } - - /** - * Returns max_locals. - */ - public int getMaxLocals() { - return maxLocals; - } - - /** - * Sets max_locals. - */ - public void setMaxLocals(int value) { - maxLocals = value; - } - - /** - * Returns code_length. - */ - public int getCodeLength() { - return info.length; - } - - /** - * Returns code[]. - */ - public byte[] getCode() { - return info; - } - - /** - * Sets code[]. - */ - void setCode(byte[] newinfo) { super.set(newinfo); } - - /** - * Makes a new iterator for reading this code attribute. - */ - public com.fr.third.javassist.bytecode.CodeIterator iterator() { - return new com.fr.third.javassist.bytecode.CodeIterator(this); - } - - /** - * Returns exception_table[]. - */ - public ExceptionTable getExceptionTable() { return exceptions; } - - /** - * Returns attributes[]. - * It returns a list of AttributeInfo. - * A new element can be added to the returned list - * and an existing element can be removed from the list. - * - * @see com.fr.third.javassist.bytecode.AttributeInfo - */ - public List getAttributes() { return attributes; } - - /** - * Returns the attribute with the specified name. - * If it is not found, this method returns null. - * - * @param name attribute name - * @return an AttributeInfo object or null. - */ - public com.fr.third.javassist.bytecode.AttributeInfo getAttribute(String name) { - return com.fr.third.javassist.bytecode.AttributeInfo.lookup(attributes, name); - } - - /** - * Adds a stack map table. If another copy of stack map table - * is already contained, the old one is removed. - * - * @param smt the stack map table added to this code attribute. - * If it is null, a new stack map is not added. - * Only the old stack map is removed. - */ - public void setAttribute(StackMapTable smt) { - com.fr.third.javassist.bytecode.AttributeInfo.remove(attributes, StackMapTable.tag); - if (smt != null) - attributes.add(smt); - } - - /** - * Adds a stack map table for J2ME (CLDC). If another copy of stack map table - * is already contained, the old one is removed. - * - * @param sm the stack map table added to this code attribute. - * If it is null, a new stack map is not added. - * Only the old stack map is removed. - * @since 3.12 - */ - public void setAttribute(com.fr.third.javassist.bytecode.StackMap sm) { - AttributeInfo.remove(attributes, com.fr.third.javassist.bytecode.StackMap.tag); - if (sm != null) - attributes.add(sm); - } - - /** - * Copies code. - */ - private byte[] copyCode(com.fr.third.javassist.bytecode.ConstPool destCp, Map classnames, - ExceptionTable etable, CodeAttribute destCa) - throws com.fr.third.javassist.bytecode.BadBytecode - { - int len = getCodeLength(); - byte[] newCode = new byte[len]; - destCa.info = newCode; - LdcEntry ldc = copyCode(this.info, 0, len, this.getConstPool(), - newCode, destCp, classnames); - return LdcEntry.doit(newCode, ldc, etable, destCa); - } - - private static LdcEntry copyCode(byte[] code, int beginPos, int endPos, - com.fr.third.javassist.bytecode.ConstPool srcCp, byte[] newcode, - com.fr.third.javassist.bytecode.ConstPool destCp, Map classnameMap) - throws com.fr.third.javassist.bytecode.BadBytecode - { - int i2, index; - LdcEntry ldcEntry = null; - - for (int i = beginPos; i < endPos; i = i2) { - i2 = com.fr.third.javassist.bytecode.CodeIterator.nextOpcode(code, i); - byte c = code[i]; - newcode[i] = c; - switch (c & 0xff) { - case LDC_W : - case LDC2_W : - case GETSTATIC : - case PUTSTATIC : - case GETFIELD : - case PUTFIELD : - case INVOKEVIRTUAL : - case INVOKESPECIAL : - case INVOKESTATIC : - case NEW : - case ANEWARRAY : - case CHECKCAST : - case INSTANCEOF : - copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp, - classnameMap); - break; - case LDC : - index = code[i + 1] & 0xff; - index = srcCp.copy(index, destCp, classnameMap); - if (index < 0x100) - newcode[i + 1] = (byte)index; - else { - newcode[i] = NOP; - newcode[i + 1] = NOP; - LdcEntry ldc = new LdcEntry(); - ldc.where = i; - ldc.index = index; - ldc.next = ldcEntry; - ldcEntry = ldc; - } - break; - case INVOKEINTERFACE : - copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp, - classnameMap); - newcode[i + 3] = code[i + 3]; - newcode[i + 4] = code[i + 4]; - break; - case INVOKEDYNAMIC : - copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp, - classnameMap); - newcode[i + 3] = 0; - newcode[i + 4] = 0; - break; - case MULTIANEWARRAY : - copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp, - classnameMap); - newcode[i + 3] = code[i + 3]; - break; - default : - while (++i < i2) - newcode[i] = code[i]; - - break; - } - } - - return ldcEntry; - } - - private static void copyConstPoolInfo(int i, byte[] code, com.fr.third.javassist.bytecode.ConstPool srcCp, - byte[] newcode, ConstPool destCp, - Map classnameMap) { - int index = ((code[i] & 0xff) << 8) | (code[i + 1] & 0xff); - index = srcCp.copy(index, destCp, classnameMap); - newcode[i] = (byte)(index >> 8); - newcode[i + 1] = (byte)index; - } - - static class LdcEntry { - LdcEntry next; - int where; - int index; - - static byte[] doit(byte[] code, LdcEntry ldc, ExceptionTable etable, - CodeAttribute ca) - throws com.fr.third.javassist.bytecode.BadBytecode - { - if (ldc != null) - code = com.fr.third.javassist.bytecode.CodeIterator.changeLdcToLdcW(code, etable, ca, ldc); - - /* The original code was the following: - - while (ldc != null) { - int where = ldc.where; - code = CodeIterator.insertGapCore0(code, where, 1, false, etable, ca); - code[where] = (byte)Opcode.LDC_W; - ByteArray.write16bit(ldc.index, code, where + 1); - ldc = ldc.next; - } - - But this code does not support a large method > 32KB. - */ - - return code; - } - } - - /** - * Changes the index numbers of the local variables - * to append a new parameter. - * This method does not update LocalVariableAttribute, - * LocalVariableTypeAttribute, - * StackMapTable, or StackMap. - * These attributes must be explicitly updated. - * - * @param where the index of the new parameter. - * @param size the type size of the new parameter (1 or 2). - * - * @see LocalVariableAttribute#shiftIndex(int, int) - * @see LocalVariableTypeAttribute#shiftIndex(int, int) - * @see StackMapTable#insertLocal(int, int, int) - * @see StackMap#insertLocal(int, int, int) - */ - public void insertLocalVar(int where, int size) throws com.fr.third.javassist.bytecode.BadBytecode { - com.fr.third.javassist.bytecode.CodeIterator ci = iterator(); - while (ci.hasNext()) - shiftIndex(ci, where, size); - - setMaxLocals(getMaxLocals() + size); - } - - /** - * @param lessThan If the index of the local variable is - * less than this value, it does not change. - * Otherwise, the index is increased. - * @param delta the indexes of the local variables are - * increased by this value. - */ - private static void shiftIndex(com.fr.third.javassist.bytecode.CodeIterator ci, int lessThan, int delta) throws com.fr.third.javassist.bytecode.BadBytecode { - int index = ci.next(); - int opcode = ci.byteAt(index); - if (opcode < ILOAD) - return; - else if (opcode < IASTORE) { - if (opcode < ILOAD_0) { - // iload, lload, fload, dload, aload - shiftIndex8(ci, index, opcode, lessThan, delta); - } - else if (opcode < IALOAD) { - // iload_0, ..., aload_3 - shiftIndex0(ci, index, opcode, lessThan, delta, ILOAD_0, ILOAD); - } - else if (opcode < ISTORE) - return; - else if (opcode < ISTORE_0) { - // istore, lstore, ... - shiftIndex8(ci, index, opcode, lessThan, delta); - } - else { - // istore_0, ..., astore_3 - shiftIndex0(ci, index, opcode, lessThan, delta, ISTORE_0, ISTORE); - } - } - else if (opcode == IINC) { - int var = ci.byteAt(index + 1); - if (var < lessThan) - return; - - var += delta; - if (var < 0x100) - ci.writeByte(var, index + 1); - else { - int plus = (byte)ci.byteAt(index + 2); - int pos = ci.insertExGap(3); - ci.writeByte(WIDE, pos - 3); - ci.writeByte(IINC, pos - 2); - ci.write16bit(var, pos - 1); - ci.write16bit(plus, pos + 1); - } - } - else if (opcode == RET) - shiftIndex8(ci, index, opcode, lessThan, delta); - else if (opcode == WIDE) { - int var = ci.u16bitAt(index + 2); - if (var < lessThan) - return; - - var += delta; - ci.write16bit(var, index + 2); - } - } - - private static void shiftIndex8(com.fr.third.javassist.bytecode.CodeIterator ci, int index, int opcode, - int lessThan, int delta) - throws com.fr.third.javassist.bytecode.BadBytecode - { - int var = ci.byteAt(index + 1); - if (var < lessThan) - return; - - var += delta; - if (var < 0x100) - ci.writeByte(var, index + 1); - else { - int pos = ci.insertExGap(2); - ci.writeByte(WIDE, pos - 2); - ci.writeByte(opcode, pos - 1); - ci.write16bit(var, pos); - } - } - - private static void shiftIndex0(CodeIterator ci, int index, int opcode, - int lessThan, int delta, - int opcode_i_0, int opcode_i) - throws BadBytecode - { - int var = (opcode - opcode_i_0) % 4; - if (var < lessThan) - return; - - var += delta; - if (var < 4) - ci.writeByte(opcode + delta, index); - else { - opcode = (opcode - opcode_i_0) / 4 + opcode_i; - if (var < 0x100) { - int pos = ci.insertExGap(1); - ci.writeByte(opcode, pos - 1); - ci.writeByte(var, pos); - } - else { - int pos = ci.insertExGap(3); - ci.writeByte(WIDE, pos - 1); - ci.writeByte(opcode, pos); - ci.write16bit(var, pos + 1); - } - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/CodeIterator.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/CodeIterator.java deleted file mode 100644 index a36ecb54d..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/CodeIterator.java +++ /dev/null @@ -1,1599 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.util.ArrayList; - -/** - * An iterator for editing a code attribute. - * - *

To directly read or edit a bytecode sequence, call {@link #byteAt(int)}, {@link #s16bitAt(int)}, - * {@link #writeByte(int, int)}, {@link #write16bit(int, int)}, and other methods. - * For example, if method refers to a CtMethod object, - * the following code substitutes the NOP instruction for the first - * instruction of the method: - * - *

- * CodeAttribute ca = method.getMethodInfo().getCodeAttribute();
- * CodeIterator ci = ca.iterator();
- * ci.writeByte(Opcode.NOP, 0);
- * - *

To visit every instruction, call {@link #next()} on a CodeIterator. - * It returns the index of the first byte of the next instruction. - * - *

If there are multiple CodeIterators referring to the - * same Code_attribute, then inserting a gap by one - * CodeIterator will break the other - * CodeIterator. - * - *

This iterator does not provide remove(). - * If a piece of code in a Code_attribute is unnecessary, - * it should be overwritten with NOP. - * - * @see CodeAttribute#iterator() - */ -public class CodeIterator implements Opcode { - protected CodeAttribute codeAttr; - protected byte[] bytecode; - protected int endPos; - protected int currentPos; - protected int mark; - - protected CodeIterator(CodeAttribute ca) { - codeAttr = ca; - bytecode = ca.getCode(); - begin(); - } - - /** - * Moves to the first instruction. - */ - public void begin() { - currentPos = mark = 0; - endPos = getCodeLength(); - } - - /** - * Moves to the given index. - * - *

The index of the next instruction is set to the given index. - * The successive call to next() - * returns the index that has been given to move(). - * - *

Note that the index is into the byte array returned by - * get().getCode(). - * - * @see CodeAttribute#getCode() - */ - public void move(int index) { - currentPos = index; - } - - /** - * Sets a mark to the bytecode at the given index. - * The mark can be used to track the position of that bytecode - * when code blocks are inserted. - * If a code block is inclusively inserted at the position of the - * bytecode, the mark is set to the inserted code block. - * - * @see #getMark() - * @since 3.11 - */ - public void setMark(int index) { - mark = index; - } - - /** - * Gets the index of the position of the mark set by - * setMark. - * - * @return the index of the position. - * @see #setMark(int) - * @since 3.11 - */ - public int getMark() { return mark; } - - /** - * Returns a Code attribute read with this iterator. - */ - public CodeAttribute get() { - return codeAttr; - } - - /** - * Returns code_length of Code_attribute. - */ - public int getCodeLength() { - return bytecode.length; - } - - /** - * Returns the unsigned 8bit value at the given index. - */ - public int byteAt(int index) { return bytecode[index] & 0xff; } - - /** - * Writes an 8bit value at the given index. - */ - public void writeByte(int value, int index) { - bytecode[index] = (byte)value; - } - - /** - * Returns the unsigned 16bit value at the given index. - */ - public int u16bitAt(int index) { - return com.fr.third.javassist.bytecode.ByteArray.readU16bit(bytecode, index); - } - - /** - * Returns the signed 16bit value at the given index. - */ - public int s16bitAt(int index) { - return com.fr.third.javassist.bytecode.ByteArray.readS16bit(bytecode, index); - } - - /** - * Writes a 16 bit integer at the index. - */ - public void write16bit(int value, int index) { - com.fr.third.javassist.bytecode.ByteArray.write16bit(value, bytecode, index); - } - - /** - * Returns the signed 32bit value at the given index. - */ - public int s32bitAt(int index) { - return com.fr.third.javassist.bytecode.ByteArray.read32bit(bytecode, index); - } - - /** - * Writes a 32bit integer at the index. - */ - public void write32bit(int value, int index) { - com.fr.third.javassist.bytecode.ByteArray.write32bit(value, bytecode, index); - } - - /** - * Writes a byte array at the index. - * - * @param code may be a zero-length array. - */ - public void write(byte[] code, int index) { - int len = code.length; - for (int j = 0; j < len; ++j) - bytecode[index++] = code[j]; - } - - /** - * Returns true if there is more instructions. - */ - public boolean hasNext() { return currentPos < endPos; } - - /** - * Returns the index of the next instruction - * (not the operand following the current opcode). - * - *

Note that the index is into the byte array returned by - * get().getCode(). - * - * @see CodeAttribute#getCode() - * @see CodeIterator#byteAt(int) - */ - public int next() throws com.fr.third.javassist.bytecode.BadBytecode { - int pos = currentPos; - currentPos = nextOpcode(bytecode, pos); - return pos; - } - - /** - * Obtains the value that the next call - * to next() will return. - * - *

This method is side-effects free. - * Successive calls to lookAhead() return the - * same value until next() is called. - */ - public int lookAhead() { - return currentPos; - } - - /** - * Moves to the instruction for - * either super() or this(). - * - *

This method skips all the instructions for computing arguments - * to super() or this(), which should be - * placed at the beginning of a constructor body. - * - *

This method returns the index of INVOKESPECIAL instruction - * executing super() or this(). - * A successive call to next() returns the - * index of the next instruction following that INVOKESPECIAL. - * - *

This method works only for a constructor. - * - * @return the index of the INVOKESPECIAL instruction, or -1 - * if a constructor invocation is not found. - */ - public int skipConstructor() throws com.fr.third.javassist.bytecode.BadBytecode { - return skipSuperConstructor0(-1); - } - - /** - * Moves to the instruction for super(). - * - *

This method skips all the instructions for computing arguments to - * super(), which should be - * placed at the beginning of a constructor body. - * - *

This method returns the index of INVOKESPECIAL instruction - * executing super(). - * A successive call to next() returns the - * index of the next instruction following that INVOKESPECIAL. - * - *

This method works only for a constructor. - * - * @return the index of the INVOKESPECIAL instruction, or -1 - * if a super constructor invocation is not found - * but this() is found. - */ - public int skipSuperConstructor() throws com.fr.third.javassist.bytecode.BadBytecode { - return skipSuperConstructor0(0); - } - - /** - * Moves to the instruction for this(). - * - *

This method skips all the instructions for computing arguments to - * this(), which should be - * placed at the beginning of a constructor body. - * - *

This method returns the index of INVOKESPECIAL instruction - * executing this(). - * A successive call to next() returns the - * index of the next instruction following that INVOKESPECIAL. - * - *

This method works only for a constructor. - * - * @return the index of the INVOKESPECIAL instruction, or -1 - * if a explicit constructor invocation is not found - * but super() is found. - */ - public int skipThisConstructor() throws com.fr.third.javassist.bytecode.BadBytecode { - return skipSuperConstructor0(1); - } - - /* skipSuper 1: this(), 0: super(), -1: both. - */ - private int skipSuperConstructor0(int skipThis) throws com.fr.third.javassist.bytecode.BadBytecode { - begin(); - ConstPool cp = codeAttr.getConstPool(); - String thisClassName = codeAttr.getDeclaringClass(); - int nested = 0; - while (hasNext()) { - int index = next(); - int c = byteAt(index); - if (c == NEW) - ++nested; - else if (c == INVOKESPECIAL) { - int mref = com.fr.third.javassist.bytecode.ByteArray.readU16bit(bytecode, index + 1); - if (cp.getMethodrefName(mref).equals(MethodInfo.nameInit)) - if (--nested < 0) { - if (skipThis < 0) - return index; - - String cname = cp.getMethodrefClassName(mref); - if (cname.equals(thisClassName) == (skipThis > 0)) - return index; - else - break; - } - } - } - - begin(); - return -1; - } - - /** - * Inserts the given bytecode sequence - * before the next instruction that would be returned by - * next() (not before the instruction returned - * by the last call to next()). - * Branch offsets and the exception table are also updated. - * - *

If the next instruction is at the beginning of a block statement, - * then the bytecode is inserted within that block. - * - *

An extra gap may be inserted at the end of the inserted - * bytecode sequence for adjusting alignment if the code attribute - * includes LOOKUPSWITCH or TABLESWITCH. - * - * @param code inserted bytecode sequence. - * @return the index indicating the first byte of the - * inserted byte sequence. - */ - public int insert(byte[] code) - throws com.fr.third.javassist.bytecode.BadBytecode - { - return insert0(currentPos, code, false); - } - - /** - * Inserts the given bytecode sequence - * before the instruction at the given index pos. - * Branch offsets and the exception table are also updated. - * - *

If the instruction at the given index is at the beginning - * of a block statement, - * then the bytecode is inserted within that block. - * - *

An extra gap may be inserted at the end of the inserted - * bytecode sequence for adjusting alignment if the code attribute - * includes LOOKUPSWITCH or TABLESWITCH. - * - *

The index at which the byte sequence is actually inserted - * might be different from pos since some other bytes might be - * inserted at other positions (e.g. to change GOTO - * to GOTO_W). - * - * @param pos the index at which a byte sequence is inserted. - * @param code inserted bytecode sequence. - */ - public void insert(int pos, byte[] code) throws com.fr.third.javassist.bytecode.BadBytecode { - insert0(pos, code, false); - } - - /** - * Inserts the given bytecode sequence - * before the instruction at the given index pos. - * Branch offsets and the exception table are also updated. - * - *

If the instruction at the given index is at the beginning - * of a block statement, - * then the bytecode is inserted within that block. - * - *

An extra gap may be inserted at the end of the inserted - * bytecode sequence for adjusting alignment if the code attribute - * includes LOOKUPSWITCH or TABLESWITCH. - * - * @param pos the index at which a byte sequence is inserted. - * @param code inserted bytecode sequence. - * @return the index indicating the first byte of the - * inserted byte sequence, which might be - * different from pos. - * @since 3.11 - */ - public int insertAt(int pos, byte[] code) throws com.fr.third.javassist.bytecode.BadBytecode { - return insert0(pos, code, false); - } - - /** - * Inserts the given bytecode sequence exclusively - * before the next instruction that would be returned by - * next() (not before the instruction returned - * by tha last call to next()). - * Branch offsets and the exception table are also updated. - * - *

If the next instruction is at the beginning of a block statement, - * then the bytecode is excluded from that block. - * - *

An extra gap may be inserted at the end of the inserted - * bytecode sequence for adjusting alignment if the code attribute - * includes LOOKUPSWITCH or TABLESWITCH. - * - * @param code inserted bytecode sequence. - * @return the index indicating the first byte of the - * inserted byte sequence. - */ - public int insertEx(byte[] code) - throws com.fr.third.javassist.bytecode.BadBytecode - { - return insert0(currentPos, code, true); - } - - /** - * Inserts the given bytecode sequence exclusively - * before the instruction at the given index pos. - * Branch offsets and the exception table are also updated. - * - *

If the instruction at the given index is at the beginning - * of a block statement, - * then the bytecode is excluded from that block. - * - *

An extra gap may be inserted at the end of the inserted - * bytecode sequence for adjusting alignment if the code attribute - * includes LOOKUPSWITCH or TABLESWITCH. - * - *

The index at which the byte sequence is actually inserted - * might be different from pos since some other bytes might be - * inserted at other positions (e.g. to change GOTO - * to GOTO_W). - * - * @param pos the index at which a byte sequence is inserted. - * @param code inserted bytecode sequence. - */ - public void insertEx(int pos, byte[] code) throws com.fr.third.javassist.bytecode.BadBytecode { - insert0(pos, code, true); - } - - /** - * Inserts the given bytecode sequence exclusively - * before the instruction at the given index pos. - * Branch offsets and the exception table are also updated. - * - *

If the instruction at the given index is at the beginning - * of a block statement, - * then the bytecode is excluded from that block. - * - *

An extra gap may be inserted at the end of the inserted - * bytecode sequence for adjusting alignment if the code attribute - * includes LOOKUPSWITCH or TABLESWITCH. - * - * @param pos the index at which a byte sequence is inserted. - * @param code inserted bytecode sequence. - * @return the index indicating the first byte of the - * inserted byte sequence, which might be - * different from pos. - * @since 3.11 - */ - public int insertExAt(int pos, byte[] code) throws com.fr.third.javassist.bytecode.BadBytecode { - return insert0(pos, code, true); - } - - /** - * @return the index indicating the first byte of the - * inserted byte sequence. - */ - private int insert0(int pos, byte[] code, boolean exclusive) - throws com.fr.third.javassist.bytecode.BadBytecode - { - int len = code.length; - if (len <= 0) - return pos; - - // currentPos will change. - pos = insertGapAt(pos, len, exclusive).position; - - int p = pos; - for (int j = 0; j < len; ++j) - bytecode[p++] = code[j]; - - return pos; - } - - /** - * Inserts a gap - * before the next instruction that would be returned by - * next() (not before the instruction returned - * by the last call to next()). - * Branch offsets and the exception table are also updated. - * The inserted gap is filled with NOP. The gap length may be - * extended to a multiple of 4. - * - *

If the next instruction is at the beginning of a block statement, - * then the gap is inserted within that block. - * - * @param length gap length - * @return the index indicating the first byte of the inserted gap. - */ - public int insertGap(int length) throws com.fr.third.javassist.bytecode.BadBytecode { - return insertGapAt(currentPos, length, false).position; - } - - /** - * Inserts a gap in front of the instruction at the given - * index pos. - * Branch offsets and the exception table are also updated. - * The inserted gap is filled with NOP. The gap length may be - * extended to a multiple of 4. - * - *

If the instruction at the given index is at the beginning - * of a block statement, - * then the gap is inserted within that block. - * - * @param pos the index at which a gap is inserted. - * @param length gap length. - * @return the length of the inserted gap. - * It might be bigger than length. - */ - public int insertGap(int pos, int length) throws com.fr.third.javassist.bytecode.BadBytecode { - return insertGapAt(pos, length, false).length; - } - - /** - * Inserts an exclusive gap - * before the next instruction that would be returned by - * next() (not before the instruction returned - * by the last call to next()). - * Branch offsets and the exception table are also updated. - * The inserted gap is filled with NOP. The gap length may be - * extended to a multiple of 4. - * - *

If the next instruction is at the beginning of a block statement, - * then the gap is excluded from that block. - * - * @param length gap length - * @return the index indicating the first byte of the inserted gap. - */ - public int insertExGap(int length) throws com.fr.third.javassist.bytecode.BadBytecode { - return insertGapAt(currentPos, length, true).position; - } - - /** - * Inserts an exclusive gap in front of the instruction at the given - * index pos. - * Branch offsets and the exception table are also updated. - * The inserted gap is filled with NOP. The gap length may be - * extended to a multiple of 4. - * - *

If the instruction at the given index is at the beginning - * of a block statement, - * then the gap is excluded from that block. - * - * @param pos the index at which a gap is inserted. - * @param length gap length. - * @return the length of the inserted gap. - * It might be bigger than length. - */ - public int insertExGap(int pos, int length) throws com.fr.third.javassist.bytecode.BadBytecode { - return insertGapAt(pos, length, true).length; - } - - /** - * An inserted gap. - * - * @since 3.11 - */ - public static class Gap { - /** - * The position of the gap. - */ - public int position; - - /** - * The length of the gap. - */ - public int length; - } - - /** - * Inserts an inclusive or exclusive gap in front of the instruction - * at the given index pos. - * Branch offsets and the exception table in the method body - * are also updated. The inserted gap is filled with NOP. - * The gap length may be extended to a multiple of 4. - * - *

Suppose that the instruction at the given index is at the - * beginning of a block statement. If the gap is inclusive, - * then it is included within that block. If the gap is exclusive, - * then it is excluded from that block. - * - *

The index at which the gap is actually inserted - * might be different from pos since some other bytes might be - * inserted at other positions (e.g. to change GOTO - * to GOTO_W). The index is available from the Gap - * object returned by this method. - * - *

Suppose that the gap is inserted at the position of - * the next instruction that would be returned by - * next() (not the last instruction returned - * by the last call to next()). The next - * instruction returned by next() after the gap is - * inserted is still the same instruction. It is not NOP - * at the first byte of the inserted gap. - * - * @param pos the index at which a gap is inserted. - * @param length gap length. - * @param exclusive true if exclusive, otherwise false. - * @return the position and the length of the inserted gap. - * @since 3.11 - */ - public Gap insertGapAt(int pos, int length, boolean exclusive) - throws com.fr.third.javassist.bytecode.BadBytecode - { - /** - * cursorPos indicates the next bytecode whichever exclusive is - * true or false. - */ - Gap gap = new Gap(); - if (length <= 0) { - gap.position = pos; - gap.length = 0; - return gap; - } - - byte[] c; - int length2; - if (bytecode.length + length > Short.MAX_VALUE) { - // currentPos might change after calling insertGapCore0w(). - c = insertGapCore0w(bytecode, pos, length, exclusive, - get().getExceptionTable(), codeAttr, gap); - pos = gap.position; - length2 = length; // == gap.length - } - else { - int cur = currentPos; - c = insertGapCore0(bytecode, pos, length, exclusive, - get().getExceptionTable(), codeAttr); - // insertGapCore0() never changes pos. - length2 = c.length - bytecode.length; - gap.position = pos; - gap.length = length2; - if (cur >= pos) - currentPos = cur + length2; - - if (mark > pos || (mark == pos && exclusive)) - mark += length2; - } - - codeAttr.setCode(c); - bytecode = c; - endPos = getCodeLength(); - updateCursors(pos, length2); - return gap; - } - - /** - * Is called when a gap is inserted. The default implementation is empty. - * A subclass can override this method so that cursors will be updated. - * - * @param pos the position where a gap is inserted. - * @param length the length of the gap. - */ - protected void updateCursors(int pos, int length) { - // empty - } - - /** - * Copies and inserts the entries in the given exception table - * at the beginning of the exception table in the code attribute - * edited by this object. - * - * @param offset the value added to the code positions included - * in the entries. - */ - public void insert(ExceptionTable et, int offset) { - codeAttr.getExceptionTable().add(0, et, offset); - } - - /** - * Appends the given bytecode sequence at the end. - * - * @param code the bytecode appended. - * @return the position of the first byte of the appended bytecode. - */ - public int append(byte[] code) { - int size = getCodeLength(); - int len = code.length; - if (len <= 0) - return size; - - appendGap(len); - byte[] dest = bytecode; - for (int i = 0; i < len; ++i) - dest[i + size] = code[i]; - - return size; - } - - /** - * Appends a gap at the end of the bytecode sequence. - * - * @param gapLength gap length - */ - public void appendGap(int gapLength) { - byte[] code = bytecode; - int codeLength = code.length; - byte[] newcode = new byte[codeLength + gapLength]; - - int i; - for (i = 0; i < codeLength; ++i) - newcode[i] = code[i]; - - for (i = codeLength; i < codeLength + gapLength; ++i) - newcode[i] = NOP; - - codeAttr.setCode(newcode); - bytecode = newcode; - endPos = getCodeLength(); - } - - /** - * Copies and appends the entries in the given exception table - * at the end of the exception table in the code attribute - * edited by this object. - * - * @param offset the value added to the code positions included - * in the entries. - */ - public void append(ExceptionTable et, int offset) { - ExceptionTable table = codeAttr.getExceptionTable(); - table.add(table.size(), et, offset); - } - - /* opcodeLegth is used for implementing nextOpcode(). - */ - private static final int opcodeLength[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 3, - 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 0, 0, 1, 1, 1, 1, 1, 1, 3, 3, - 3, 3, 3, 3, 3, 5, 5, 3, 2, 3, 1, 1, 3, 3, 1, 1, 0, 4, 3, 3, - 5, 5 - }; - // 0 .. LOOKUPSWITCH, TABLESWITCH, WIDE - - /** - * Calculates the index of the next opcode. - */ - static int nextOpcode(byte[] code, int index) - throws com.fr.third.javassist.bytecode.BadBytecode - { - int opcode; - try { - opcode = code[index] & 0xff; - } - catch (IndexOutOfBoundsException e) { - throw new com.fr.third.javassist.bytecode.BadBytecode("invalid opcode address"); - } - - try { - int len = opcodeLength[opcode]; - if (len > 0) - return index + len; - else if (opcode == WIDE) - if (code[index + 1] == (byte)IINC) // WIDE IINC - return index + 6; - else - return index + 4; // WIDE ... - else { - int index2 = (index & ~3) + 8; - if (opcode == LOOKUPSWITCH) { - int npairs = com.fr.third.javassist.bytecode.ByteArray.read32bit(code, index2); - return index2 + npairs * 8 + 4; - } - else if (opcode == TABLESWITCH) { - int low = com.fr.third.javassist.bytecode.ByteArray.read32bit(code, index2); - int high = com.fr.third.javassist.bytecode.ByteArray.read32bit(code, index2 + 4); - return index2 + (high - low + 1) * 4 + 8; - } - // else - // throw new BadBytecode(opcode); - } - } - catch (IndexOutOfBoundsException e) { - } - - // opcode is UNUSED or an IndexOutOfBoundsException was thrown. - throw new com.fr.third.javassist.bytecode.BadBytecode(opcode); - } - - // methods for implementing insertGap(). - - static class AlignmentException extends Exception {} - - /** - * insertGapCore0() inserts a gap (some NOPs). - * It cannot handle a long code sequence more than 32K. All branch offsets must be - * signed 16bits. - * - * If "where" is the beginning of a block statement and exclusive is false, - * then the inserted gap is also included in the block statement. - * "where" must indicate the first byte of an opcode. - * The inserted gap is filled with NOP. gapLength may be extended to - * a multiple of 4. - * - * This method was also called from CodeAttribute.LdcEntry.doit(). - * - * @param where It must indicate the first byte of an opcode. - */ - static byte[] insertGapCore0(byte[] code, int where, int gapLength, - boolean exclusive, ExceptionTable etable, CodeAttribute ca) - throws com.fr.third.javassist.bytecode.BadBytecode - { - if (gapLength <= 0) - return code; - - try { - return insertGapCore1(code, where, gapLength, exclusive, etable, ca); - } - catch (AlignmentException e) { - try { - return insertGapCore1(code, where, (gapLength + 3) & ~3, - exclusive, etable, ca); - } - catch (AlignmentException e2) { - throw new RuntimeException("fatal error?"); - } - } - } - - private static byte[] insertGapCore1(byte[] code, int where, int gapLength, - boolean exclusive, ExceptionTable etable, - CodeAttribute ca) - throws com.fr.third.javassist.bytecode.BadBytecode, AlignmentException - { - int codeLength = code.length; - byte[] newcode = new byte[codeLength + gapLength]; - insertGap2(code, where, gapLength, codeLength, newcode, exclusive); - etable.shiftPc(where, gapLength, exclusive); - LineNumberAttribute na - = (LineNumberAttribute)ca.getAttribute(LineNumberAttribute.tag); - if (na != null) - na.shiftPc(where, gapLength, exclusive); - - LocalVariableAttribute va = (LocalVariableAttribute)ca.getAttribute( - LocalVariableAttribute.tag); - if (va != null) - va.shiftPc(where, gapLength, exclusive); - - LocalVariableAttribute vta - = (LocalVariableAttribute)ca.getAttribute( - LocalVariableAttribute.typeTag); - if (vta != null) - vta.shiftPc(where, gapLength, exclusive); - - StackMapTable smt = (StackMapTable)ca.getAttribute(StackMapTable.tag); - if (smt != null) - smt.shiftPc(where, gapLength, exclusive); - - com.fr.third.javassist.bytecode.StackMap sm = (com.fr.third.javassist.bytecode.StackMap)ca.getAttribute(com.fr.third.javassist.bytecode.StackMap.tag); - if (sm != null) - sm.shiftPc(where, gapLength, exclusive); - - return newcode; - } - - private static void insertGap2(byte[] code, int where, int gapLength, - int endPos, byte[] newcode, boolean exclusive) - throws com.fr.third.javassist.bytecode.BadBytecode, AlignmentException - { - int nextPos; - int i = 0; - int j = 0; - for (; i < endPos; i = nextPos) { - if (i == where) { - int j2 = j + gapLength; - while (j < j2) - newcode[j++] = NOP; - } - - nextPos = nextOpcode(code, i); - int inst = code[i] & 0xff; - // if, if_icmp, if_acmp, goto, jsr - if ((153 <= inst && inst <= 168) - || inst == IFNULL || inst == IFNONNULL) { - /* 2bytes *signed* offset */ - int offset = (code[i + 1] << 8) | (code[i + 2] & 0xff); - offset = newOffset(i, offset, where, gapLength, exclusive); - newcode[j] = code[i]; - com.fr.third.javassist.bytecode.ByteArray.write16bit(offset, newcode, j + 1); - j += 3; - } - else if (inst == GOTO_W || inst == JSR_W) { - /* 4bytes offset */ - int offset = com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i + 1); - offset = newOffset(i, offset, where, gapLength, exclusive); - newcode[j++] = code[i]; - com.fr.third.javassist.bytecode.ByteArray.write32bit(offset, newcode, j); - j += 4; - } - else if (inst == TABLESWITCH) { - if (i != j && (gapLength & 3) != 0) - throw new AlignmentException(); - - int i2 = (i & ~3) + 4; // 0-3 byte padding - // IBM JVM 1.4.2 cannot run the following code: - // int i0 = i; - // while (i0 < i2) - // newcode[j++] = code[i0++]; - // So extracting this code into an external method. - // see JIRA JASSIST-74. - j = copyGapBytes(newcode, j, code, i, i2); - - int defaultbyte = newOffset(i, com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i2), - where, gapLength, exclusive); - com.fr.third.javassist.bytecode.ByteArray.write32bit(defaultbyte, newcode, j); - int lowbyte = com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i2 + 4); - com.fr.third.javassist.bytecode.ByteArray.write32bit(lowbyte, newcode, j + 4); - int highbyte = com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i2 + 8); - com.fr.third.javassist.bytecode.ByteArray.write32bit(highbyte, newcode, j + 8); - j += 12; - int i0 = i2 + 12; - i2 = i0 + (highbyte - lowbyte + 1) * 4; - while (i0 < i2) { - int offset = newOffset(i, com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i0), - where, gapLength, exclusive); - com.fr.third.javassist.bytecode.ByteArray.write32bit(offset, newcode, j); - j += 4; - i0 += 4; - } - } - else if (inst == LOOKUPSWITCH) { - if (i != j && (gapLength & 3) != 0) - throw new AlignmentException(); - - int i2 = (i & ~3) + 4; // 0-3 byte padding - - // IBM JVM 1.4.2 cannot run the following code: - // int i0 = i; - // while (i0 < i2) - // newcode[j++] = code[i0++]; - // So extracting this code into an external method. - // see JIRA JASSIST-74. - j = copyGapBytes(newcode, j, code, i, i2); - - int defaultbyte = newOffset(i, com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i2), - where, gapLength, exclusive); - com.fr.third.javassist.bytecode.ByteArray.write32bit(defaultbyte, newcode, j); - int npairs = com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i2 + 4); - com.fr.third.javassist.bytecode.ByteArray.write32bit(npairs, newcode, j + 4); - j += 8; - int i0 = i2 + 8; - i2 = i0 + npairs * 8; - while (i0 < i2) { - com.fr.third.javassist.bytecode.ByteArray.copy32bit(code, i0, newcode, j); - int offset = newOffset(i, - com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i0 + 4), - where, gapLength, exclusive); - com.fr.third.javassist.bytecode.ByteArray.write32bit(offset, newcode, j + 4); - j += 8; - i0 += 8; - } - } - else - while (i < nextPos) - newcode[j++] = code[i++]; - } - } - - - private static int copyGapBytes(byte[] newcode, int j, byte[] code, int i, int iEnd) { - switch (iEnd - i) { - case 4: - newcode[j++] = code[i++]; - case 3: - newcode[j++] = code[i++]; - case 2: - newcode[j++] = code[i++]; - case 1: - newcode[j++] = code[i++]; - default: - } - - return j; - } - - private static int newOffset(int i, int offset, int where, - int gapLength, boolean exclusive) { - int target = i + offset; - if (i < where) { - if (where < target || (exclusive && where == target)) - offset += gapLength; - } - else if (i == where) { - // This code is different from the code in Branch#shiftOffset(). - // see JASSIST-124. - if (target < where) - offset -= gapLength; - } - else - if (target < where || (!exclusive && where == target)) - offset -= gapLength; - - return offset; - } - - static class Pointers { - int cursor; - int mark0, mark; - ExceptionTable etable; - LineNumberAttribute line; - LocalVariableAttribute vars, types; - StackMapTable stack; - com.fr.third.javassist.bytecode.StackMap stack2; - - Pointers(int cur, int m, int m0, ExceptionTable et, CodeAttribute ca) { - cursor = cur; - mark = m; - mark0 = m0; - etable = et; // non null - line = (LineNumberAttribute)ca.getAttribute(LineNumberAttribute.tag); - vars = (LocalVariableAttribute)ca.getAttribute(LocalVariableAttribute.tag); - types = (LocalVariableAttribute)ca.getAttribute(LocalVariableAttribute.typeTag); - stack = (StackMapTable)ca.getAttribute(StackMapTable.tag); - stack2 = (com.fr.third.javassist.bytecode.StackMap)ca.getAttribute(StackMap.tag); - } - - void shiftPc(int where, int gapLength, boolean exclusive) throws com.fr.third.javassist.bytecode.BadBytecode { - if (where < cursor || (where == cursor && exclusive)) - cursor += gapLength; - - if (where < mark || (where == mark && exclusive)) - mark += gapLength; - - if (where < mark0 || (where == mark0 && exclusive)) - mark0 += gapLength; - - etable.shiftPc(where, gapLength, exclusive); - if (line != null) - line.shiftPc(where, gapLength, exclusive); - - if (vars != null) - vars.shiftPc(where, gapLength, exclusive); - - if (types != null) - types.shiftPc(where, gapLength, exclusive); - - if (stack != null) - stack.shiftPc(where, gapLength, exclusive); - - if (stack2 != null) - stack2.shiftPc(where, gapLength, exclusive); - } - - void shiftForSwitch(int where, int gapLength) throws com.fr.third.javassist.bytecode.BadBytecode { - if (stack != null) - stack.shiftForSwitch(where, gapLength); - - if (stack2 != null) - stack2.shiftForSwitch(where, gapLength); - } - } - - /* - * This method is called from CodeAttribute.LdcEntry.doit(). - */ - static byte[] changeLdcToLdcW(byte[] code, ExceptionTable etable, - CodeAttribute ca, CodeAttribute.LdcEntry ldcs) - throws com.fr.third.javassist.bytecode.BadBytecode - { - Pointers pointers = new Pointers(0, 0, 0, etable, ca); - ArrayList jumps = makeJumpList(code, code.length, pointers); - while (ldcs != null) { - addLdcW(ldcs, jumps); - ldcs = ldcs.next; - } - - byte[] r = insertGap2w(code, 0, 0, false, jumps, pointers); - return r; - } - - private static void addLdcW(CodeAttribute.LdcEntry ldcs, ArrayList jumps) { - int where = ldcs.where; - LdcW ldcw = new LdcW(where, ldcs.index); - int s = jumps.size(); - for (int i = 0; i < s; i++) - if (where < ((Branch)jumps.get(i)).orgPos) { - jumps.add(i, ldcw); - return; - } - - jumps.add(ldcw); - } - - /* - * insertGapCore0w() can handle a long code sequence more than 32K. - * It guarantees that the length of the inserted gap (NOPs) is equal to - * gapLength. No other NOPs except some NOPs following TABLESWITCH or - * LOOKUPSWITCH will not be inserted. - * - * Note: currentPos might be moved. - * - * @param where It must indicate the first byte of an opcode. - * @param newWhere It contains the updated index of the position where a gap - * is inserted and the length of the gap. - * It must not be null. - */ - private byte[] insertGapCore0w(byte[] code, int where, int gapLength, boolean exclusive, - ExceptionTable etable, CodeAttribute ca, Gap newWhere) - throws com.fr.third.javassist.bytecode.BadBytecode - { - if (gapLength <= 0) - return code; - - Pointers pointers = new Pointers(currentPos, mark, where, etable, ca); - ArrayList jumps = makeJumpList(code, code.length, pointers); - byte[] r = insertGap2w(code, where, gapLength, exclusive, jumps, pointers); - currentPos = pointers.cursor; - mark = pointers.mark; - int where2 = pointers.mark0; - if (where2 == currentPos && !exclusive) - currentPos += gapLength; - - if (exclusive) - where2 -= gapLength; - - newWhere.position = where2; - newWhere.length = gapLength; - return r; - } - - private static byte[] insertGap2w(byte[] code, int where, int gapLength, - boolean exclusive, ArrayList jumps, Pointers ptrs) - throws com.fr.third.javassist.bytecode.BadBytecode - { - int n = jumps.size(); - if (gapLength > 0) { - ptrs.shiftPc(where, gapLength, exclusive); - for (int i = 0; i < n; i++) - ((Branch)jumps.get(i)).shift(where, gapLength, exclusive); - } - - boolean unstable = true; - do { - while (unstable) { - unstable = false; - for (int i = 0; i < n; i++) { - Branch b = (Branch)jumps.get(i); - if (b.expanded()) { - unstable = true; - int p = b.pos; - int delta = b.deltaSize(); - ptrs.shiftPc(p, delta, false); - for (int j = 0; j < n; j++) - ((Branch)jumps.get(j)).shift(p, delta, false); - } - } - } - - for (int i = 0; i < n; i++) { - Branch b = (Branch)jumps.get(i); - int diff = b.gapChanged(); - if (diff > 0) { - unstable = true; - int p = b.pos; - ptrs.shiftPc(p, diff, false); - for (int j = 0; j < n; j++) - ((Branch)jumps.get(j)).shift(p, diff, false); - } - } - } while (unstable); - - return makeExapndedCode(code, jumps, where, gapLength); - } - - private static ArrayList makeJumpList(byte[] code, int endPos, Pointers ptrs) - throws com.fr.third.javassist.bytecode.BadBytecode - { - ArrayList jumps = new ArrayList(); - int nextPos; - for (int i = 0; i < endPos; i = nextPos) { - nextPos = nextOpcode(code, i); - int inst = code[i] & 0xff; - // if, if_icmp, if_acmp, goto, jsr - if ((153 <= inst && inst <= 168) - || inst == IFNULL || inst == IFNONNULL) { - /* 2bytes *signed* offset */ - int offset = (code[i + 1] << 8) | (code[i + 2] & 0xff); - Branch b; - if (inst == GOTO || inst == JSR) - b = new Jump16(i, offset); - else - b = new If16(i, offset); - - jumps.add(b); - } - else if (inst == GOTO_W || inst == JSR_W) { - /* 4bytes offset */ - int offset = com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i + 1); - jumps.add(new Jump32(i, offset)); - } - else if (inst == TABLESWITCH) { - int i2 = (i & ~3) + 4; // 0-3 byte padding - int defaultbyte = com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i2); - int lowbyte = com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i2 + 4); - int highbyte = com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i2 + 8); - int i0 = i2 + 12; - int size = highbyte - lowbyte + 1; - int[] offsets = new int[size]; - for (int j = 0; j < size; j++) { - offsets[j] = com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i0); - i0 += 4; - } - - jumps.add(new Table(i, defaultbyte, lowbyte, highbyte, offsets, ptrs)); - } - else if (inst == LOOKUPSWITCH) { - int i2 = (i & ~3) + 4; // 0-3 byte padding - int defaultbyte = com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i2); - int npairs = com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i2 + 4); - int i0 = i2 + 8; - int[] matches = new int[npairs]; - int[] offsets = new int[npairs]; - for (int j = 0; j < npairs; j++) { - matches[j] = com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i0); - offsets[j] = com.fr.third.javassist.bytecode.ByteArray.read32bit(code, i0 + 4); - i0 += 8; - } - - jumps.add(new Lookup(i, defaultbyte, matches, offsets, ptrs)); - } - } - - return jumps; - } - - private static byte[] makeExapndedCode(byte[] code, ArrayList jumps, - int where, int gapLength) - throws com.fr.third.javassist.bytecode.BadBytecode - { - int n = jumps.size(); - int size = code.length + gapLength; - for (int i = 0; i < n; i++) { - Branch b = (Branch)jumps.get(i); - size += b.deltaSize(); - } - - byte[] newcode = new byte[size]; - int src = 0, dest = 0, bindex = 0; - int len = code.length; - Branch b; - int bpos; - if (0 < n) { - b = (Branch)jumps.get(0); - bpos = b.orgPos; - } - else { - b = null; - bpos = len; // src will be never equal to bpos - } - - while (src < len) { - if (src == where) { - int pos2 = dest + gapLength; - while (dest < pos2) - newcode[dest++] = NOP; - } - - if (src != bpos) - newcode[dest++] = code[src++]; - else { - int s = b.write(src, code, dest, newcode); - src += s; - dest += s + b.deltaSize(); - if (++bindex < n) { - b = (Branch)jumps.get(bindex); - bpos = b.orgPos; - } - else { - b = null; - bpos = len; - } - } - } - - return newcode; - } - - static abstract class Branch { - int pos, orgPos; - Branch(int p) { pos = orgPos = p; } - void shift(int where, int gapLength, boolean exclusive) { - if (where < pos || (where == pos && exclusive)) - pos += gapLength; - } - - static int shiftOffset(int i, int offset, int where, - int gapLength, boolean exclusive) { - int target = i + offset; - if (i < where) { - if (where < target || (exclusive && where == target)) - offset += gapLength; - } - else if (i == where) { - // This code is different from the code in CodeIterator#newOffset(). - // see JASSIST-124. - if (target < where && exclusive) - offset -= gapLength; - else if (where < target && !exclusive) - offset += gapLength; - } - else - if (target < where || (!exclusive && where == target)) - offset -= gapLength; - - return offset; - } - - boolean expanded() { return false; } - int gapChanged() { return 0; } - int deltaSize() { return 0; } // newSize - oldSize - - // This returns the original instruction size. - abstract int write(int srcPos, byte[] code, int destPos, byte[] newcode) throws com.fr.third.javassist.bytecode.BadBytecode; - } - - /* used by changeLdcToLdcW() and CodeAttribute.LdcEntry. - */ - static class LdcW extends Branch { - int index; - boolean state; - LdcW(int p, int i) { - super(p); - index = i; - state = true; - } - - boolean expanded() { - if (state) { - state = false; - return true; - } - else - return false; - } - - int deltaSize() { return 1; } - - int write(int srcPos, byte[] code, int destPos, byte[] newcode) { - newcode[destPos] = LDC_W; - com.fr.third.javassist.bytecode.ByteArray.write16bit(index, newcode, destPos + 1); - return 2; - } - } - - static abstract class Branch16 extends Branch { - int offset; - int state; - static final int BIT16 = 0; - static final int EXPAND = 1; - static final int BIT32 = 2; - - Branch16(int p, int off) { - super(p); - offset = off; - state = BIT16; - } - - void shift(int where, int gapLength, boolean exclusive) { - offset = shiftOffset(pos, offset, where, gapLength, exclusive); - super.shift(where, gapLength, exclusive); - if (state == BIT16) - if (offset < Short.MIN_VALUE || Short.MAX_VALUE < offset) - state = EXPAND; - } - - boolean expanded() { - if (state == EXPAND) { - state = BIT32; - return true; - } - else - return false; - } - - abstract int deltaSize(); - abstract void write32(int src, byte[] code, int dest, byte[] newcode); - - int write(int src, byte[] code, int dest, byte[] newcode) { - if (state == BIT32) - write32(src, code, dest, newcode); - else { - newcode[dest] = code[src]; - com.fr.third.javassist.bytecode.ByteArray.write16bit(offset, newcode, dest + 1); - } - - return 3; - } - } - - // GOTO or JSR - static class Jump16 extends Branch16 { - Jump16(int p, int off) { - super(p, off); - } - - int deltaSize() { - return state == BIT32 ? 2 : 0; - } - - void write32(int src, byte[] code, int dest, byte[] newcode) { - newcode[dest] = (byte)(((code[src] & 0xff) == GOTO) ? GOTO_W : JSR_W); - com.fr.third.javassist.bytecode.ByteArray.write32bit(offset, newcode, dest + 1); - } - } - - // if, if_icmp, or if_acmp - static class If16 extends Branch16 { - If16(int p, int off) { - super(p, off); - } - - int deltaSize() { - return state == BIT32 ? 5 : 0; - } - - void write32(int src, byte[] code, int dest, byte[] newcode) { - newcode[dest] = (byte)opcode(code[src] & 0xff); - newcode[dest + 1] = 0; - newcode[dest + 2] = 8; // branch_offset = 8 - newcode[dest + 3] = (byte)GOTO_W; - com.fr.third.javassist.bytecode.ByteArray.write32bit(offset - 3, newcode, dest + 4); - } - - int opcode(int op) { - if (op == IFNULL) - return IFNONNULL; - else if (op == IFNONNULL) - return IFNULL; - else { - if (((op - IFEQ) & 1) == 0) - return op + 1; - else - return op - 1; - } - } - } - - static class Jump32 extends Branch { - int offset; - - Jump32(int p, int off) { - super(p); - offset = off; - } - - void shift(int where, int gapLength, boolean exclusive) { - offset = shiftOffset(pos, offset, where, gapLength, exclusive); - super.shift(where, gapLength, exclusive); - } - - int write(int src, byte[] code, int dest, byte[] newcode) { - newcode[dest] = code[src]; - com.fr.third.javassist.bytecode.ByteArray.write32bit(offset, newcode, dest + 1); - return 5; - } - } - - static abstract class Switcher extends Branch { - int gap, defaultByte; - int[] offsets; - Pointers pointers; - - Switcher(int pos, int defaultByte, int[] offsets, Pointers ptrs) { - super(pos); - this.gap = 3 - (pos & 3); - this.defaultByte = defaultByte; - this.offsets = offsets; - this.pointers = ptrs; - } - - void shift(int where, int gapLength, boolean exclusive) { - int p = pos; - defaultByte = shiftOffset(p, defaultByte, where, gapLength, exclusive); - int num = offsets.length; - for (int i = 0; i < num; i++) - offsets[i] = shiftOffset(p, offsets[i], where, gapLength, exclusive); - - super.shift(where, gapLength, exclusive); - } - - int gapChanged() { - int newGap = 3 - (pos & 3); - if (newGap > gap) { - int diff = newGap - gap; - gap = newGap; - return diff; - } - - return 0; - } - - int deltaSize() { - return gap - (3 - (orgPos & 3)); - } - - int write(int src, byte[] code, int dest, byte[] newcode) throws com.fr.third.javassist.bytecode.BadBytecode { - int padding = 3 - (pos & 3); - int nops = gap - padding; - int bytecodeSize = 5 + (3 - (orgPos & 3)) + tableSize(); - if (nops > 0) - adjustOffsets(bytecodeSize, nops); - - newcode[dest++] = code[src]; - while (padding-- > 0) - newcode[dest++] = 0; - - com.fr.third.javassist.bytecode.ByteArray.write32bit(defaultByte, newcode, dest); - int size = write2(dest + 4, newcode); - dest += size + 4; - while (nops-- > 0) - newcode[dest++] = NOP; - - return 5 + (3 - (orgPos & 3)) + size; - } - - abstract int write2(int dest, byte[] newcode); - abstract int tableSize(); - - /* If the new bytecode size is shorter than the original, some NOPs - * are appended after this branch instruction (tableswitch or - * lookupswitch) to fill the gap. - * This method changes a branch offset to point to the first NOP - * if the offset originally points to the bytecode next to this - * branch instruction. Otherwise, the bytecode would contain - * dead code. It complicates the generation of StackMap and - * StackMapTable. - */ - void adjustOffsets(int size, int nops) throws BadBytecode { - pointers.shiftForSwitch(pos + size, nops); - if (defaultByte == size) - defaultByte -= nops; - - for (int i = 0; i < offsets.length; i++) - if (offsets[i] == size) - offsets[i] -= nops; - } - } - - static class Table extends Switcher { - int low, high; - - Table(int pos, int defaultByte, int low, int high, int[] offsets, Pointers ptrs) { - super(pos, defaultByte, offsets, ptrs); - this.low = low; - this.high = high; - } - - int write2(int dest, byte[] newcode) { - com.fr.third.javassist.bytecode.ByteArray.write32bit(low, newcode, dest); - com.fr.third.javassist.bytecode.ByteArray.write32bit(high, newcode, dest + 4); - int n = offsets.length; - dest += 8; - for (int i = 0; i < n; i++) { - com.fr.third.javassist.bytecode.ByteArray.write32bit(offsets[i], newcode, dest); - dest += 4; - } - - return 8 + 4 * n; - } - - int tableSize() { return 8 + 4 * offsets.length; } - } - - static class Lookup extends Switcher { - int[] matches; - - Lookup(int pos, int defaultByte, int[] matches, int[] offsets, Pointers ptrs) { - super(pos, defaultByte, offsets, ptrs); - this.matches = matches; - } - - int write2(int dest, byte[] newcode) { - int n = matches.length; - com.fr.third.javassist.bytecode.ByteArray.write32bit(n, newcode, dest); - dest += 4; - for (int i = 0; i < n; i++) { - com.fr.third.javassist.bytecode.ByteArray.write32bit(matches[i], newcode, dest); - ByteArray.write32bit(offsets[i], newcode, dest + 4); - dest += 8; - } - - return 4 + 8 * n; - } - - int tableSize() { return 4 + 8 * matches.length; } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ConstPool.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ConstPool.java deleted file mode 100644 index 704674f01..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ConstPool.java +++ /dev/null @@ -1,1991 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.ByteArrayOutputStream; -import java.io.PrintWriter; -import java.io.IOException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.CtClass; - -/** - * Constant pool table. - */ -public final class ConstPool { - LongVector items; - int numOfItems; - int thisClassInfo; - HashMap itemsCache; - - /** - * CONSTANT_Class - */ - public static final int CONST_Class = ClassInfo.tag; - - /** - * CONSTANT_Fieldref - */ - public static final int CONST_Fieldref = FieldrefInfo.tag; - - /** - * CONSTANT_Methodref - */ - public static final int CONST_Methodref = MethodrefInfo.tag; - - /** - * CONSTANT_InterfaceMethodref - */ - public static final int CONST_InterfaceMethodref - = InterfaceMethodrefInfo.tag; - - /** - * CONSTANT_String - */ - public static final int CONST_String = StringInfo.tag; - - /** - * CONSTANT_Integer - */ - public static final int CONST_Integer = IntegerInfo.tag; - - /** - * CONSTANT_Float - */ - public static final int CONST_Float = FloatInfo.tag; - - /** - * CONSTANT_Long - */ - public static final int CONST_Long = LongInfo.tag; - - /** - * CONSTANT_Double - */ - public static final int CONST_Double = DoubleInfo.tag; - - /** - * CONSTANT_NameAndType - */ - public static final int CONST_NameAndType = NameAndTypeInfo.tag; - - /** - * CONSTANT_Utf8 - */ - public static final int CONST_Utf8 = Utf8Info.tag; - - /** - * Cosnt_MethodHandle - */ - public static final int CONST_MethodHandle = MethodHandleInfo.tag; - - /** - * Represents the class using this constant pool table. - */ - public static final CtClass THIS = null; - - /** - * reference_kind of CONSTANT_MethodHandle_info. - */ - public static final int REF_getField = 1; - - /** - * reference_kind of CONSTANT_MethodHandle_info. - */ - public static final int REF_getStatic = 2; - - /** - * reference_kind of CONSTANT_MethodHandle_info. - */ - public static final int REF_putField = 3; - - /** - * reference_kind of CONSTANT_MethodHandle_info. - */ - public static final int REF_putStatic = 4; - - /** - * reference_kind of CONSTANT_MethodHandle_info. - */ - public static final int REF_invokeVirtual = 5; - - /** - * reference_kind of CONSTANT_MethodHandle_info. - */ - public static final int REF_invokeStatic = 6; - - /** - * reference_kind of CONSTANT_MethodHandle_info. - */ - public static final int REF_invokeSpecial = 7; - - /** - * reference_kind of CONSTANT_MethodHandle_info. - */ - public static final int REF_newInvokeSpecial = 8; - - /** - * reference_kind of CONSTANT_MethodHandle_info. - */ - public static final int REF_invokeInterface = 9; - - /** - * Constructs a constant pool table. - * - * @param thisclass the name of the class using this constant - * pool table - */ - public ConstPool(String thisclass) { - items = new LongVector(); - itemsCache = null; - numOfItems = 0; - addItem0(null); // index 0 is reserved by the JVM. - thisClassInfo = addClassInfo(thisclass); - } - - /** - * Constructs a constant pool table from the given byte stream. - * - * @param in byte stream. - */ - public ConstPool(DataInputStream in) throws IOException { - itemsCache = null; - thisClassInfo = 0; - /* read() initializes items and numOfItems, and do addItem(null). - */ - read(in); - } - - void prune() { - itemsCache = null; - } - - /** - * Returns the number of entries in this table. - */ - public int getSize() { - return numOfItems; - } - - /** - * Returns the name of the class using this constant pool table. - */ - public String getClassName() { - return getClassInfo(thisClassInfo); - } - - /** - * Returns the index of CONSTANT_Class_info structure - * specifying the class using this constant pool table. - */ - public int getThisClassInfo() { - return thisClassInfo; - } - - void setThisClassInfo(int i) { - thisClassInfo = i; - } - - ConstInfo getItem(int n) { - return items.elementAt(n); - } - - /** - * Returns the tag field of the constant pool table - * entry at the given index. - */ - public int getTag(int index) { - return getItem(index).getTag(); - } - - /** - * Reads CONSTANT_Class_info structure - * at the given index. - * - * @return a fully-qualified class or interface name specified - * by name_index. If the type is an array - * type, this method returns an encoded name like - * [Ljava.lang.Object; (note that the separators - * are not slashes but dots). - * @see ClassPool#getCtClass(String) - */ - public String getClassInfo(int index) { - ClassInfo c = (ClassInfo)getItem(index); - if (c == null) - return null; - else - return Descriptor.toJavaName(getUtf8Info(c.name)); - } - - /** - * Reads CONSTANT_Class_info structure - * at the given index. - * - * @return the descriptor of the type specified - * by name_index. - * @see ClassPool#getCtClass(String) - * @since 3.15 - */ - public String getClassInfoByDescriptor(int index) { - ClassInfo c = (ClassInfo)getItem(index); - if (c == null) - return null; - else { - String className = getUtf8Info(c.name); - if (className.charAt(0) == '[') - return className; - else - return Descriptor.of(className); - } - } - - /** - * Reads the name_index field of the - * CONSTANT_NameAndType_info structure - * at the given index. - */ - public int getNameAndTypeName(int index) { - NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index); - return ntinfo.memberName; - } - - /** - * Reads the descriptor_index field of the - * CONSTANT_NameAndType_info structure - * at the given index. - */ - public int getNameAndTypeDescriptor(int index) { - NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index); - return ntinfo.typeDescriptor; - } - - /** - * Reads the class_index field of the - * CONSTANT_Fieldref_info, - * CONSTANT_Methodref_info, - * or CONSTANT_Interfaceref_info, - * structure at the given index. - * - * @since 3.6 - */ - public int getMemberClass(int index) { - MemberrefInfo minfo = (MemberrefInfo)getItem(index); - return minfo.classIndex; - } - - /** - * Reads the name_and_type_index field of the - * CONSTANT_Fieldref_info, - * CONSTANT_Methodref_info, - * or CONSTANT_Interfaceref_info, - * structure at the given index. - * - * @since 3.6 - */ - public int getMemberNameAndType(int index) { - MemberrefInfo minfo = (MemberrefInfo)getItem(index); - return minfo.nameAndTypeIndex; - } - - /** - * Reads the class_index field of the - * CONSTANT_Fieldref_info structure - * at the given index. - */ - public int getFieldrefClass(int index) { - FieldrefInfo finfo = (FieldrefInfo)getItem(index); - return finfo.classIndex; - } - - /** - * Reads the class_index field of the - * CONSTANT_Fieldref_info structure - * at the given index. - * - * @return the name of the class at that class_index. - */ - public String getFieldrefClassName(int index) { - FieldrefInfo f = (FieldrefInfo)getItem(index); - if (f == null) - return null; - else - return getClassInfo(f.classIndex); - } - - /** - * Reads the name_and_type_index field of the - * CONSTANT_Fieldref_info structure - * at the given index. - */ - public int getFieldrefNameAndType(int index) { - FieldrefInfo finfo = (FieldrefInfo)getItem(index); - return finfo.nameAndTypeIndex; - } - - /** - * Reads the name_index field of the - * CONSTANT_NameAndType_info structure - * indirectly specified by the given index. - * - * @param index an index to a CONSTANT_Fieldref_info. - * @return the name of the field. - */ - public String getFieldrefName(int index) { - FieldrefInfo f = (FieldrefInfo)getItem(index); - if (f == null) - return null; - else { - NameAndTypeInfo n = (NameAndTypeInfo)getItem(f.nameAndTypeIndex); - if(n == null) - return null; - else - return getUtf8Info(n.memberName); - } - } - - /** - * Reads the descriptor_index field of the - * CONSTANT_NameAndType_info structure - * indirectly specified by the given index. - * - * @param index an index to a CONSTANT_Fieldref_info. - * @return the type descriptor of the field. - */ - public String getFieldrefType(int index) { - FieldrefInfo f = (FieldrefInfo)getItem(index); - if (f == null) - return null; - else { - NameAndTypeInfo n = (NameAndTypeInfo)getItem(f.nameAndTypeIndex); - if(n == null) - return null; - else - return getUtf8Info(n.typeDescriptor); - } - } - - /** - * Reads the class_index field of the - * CONSTANT_Methodref_info structure - * at the given index. - */ - public int getMethodrefClass(int index) { - MethodrefInfo minfo = (MethodrefInfo)getItem(index); - return minfo.classIndex; - } - - /** - * Reads the class_index field of the - * CONSTANT_Methodref_info structure - * at the given index. - * - * @return the name of the class at that class_index. - */ - public String getMethodrefClassName(int index) { - MethodrefInfo minfo = (MethodrefInfo)getItem(index); - if (minfo == null) - return null; - else - return getClassInfo(minfo.classIndex); - } - - /** - * Reads the name_and_type_index field of the - * CONSTANT_Methodref_info structure - * at the given index. - */ - public int getMethodrefNameAndType(int index) { - MethodrefInfo minfo = (MethodrefInfo)getItem(index); - return minfo.nameAndTypeIndex; - } - - /** - * Reads the name_index field of the - * CONSTANT_NameAndType_info structure - * indirectly specified by the given index. - * - * @param index an index to a CONSTANT_Methodref_info. - * @return the name of the method. - */ - public String getMethodrefName(int index) { - MethodrefInfo minfo = (MethodrefInfo)getItem(index); - if (minfo == null) - return null; - else { - NameAndTypeInfo n - = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); - if(n == null) - return null; - else - return getUtf8Info(n.memberName); - } - } - - /** - * Reads the descriptor_index field of the - * CONSTANT_NameAndType_info structure - * indirectly specified by the given index. - * - * @param index an index to a CONSTANT_Methodref_info. - * @return the descriptor of the method. - */ - public String getMethodrefType(int index) { - MethodrefInfo minfo = (MethodrefInfo)getItem(index); - if (minfo == null) - return null; - else { - NameAndTypeInfo n - = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); - if(n == null) - return null; - else - return getUtf8Info(n.typeDescriptor); - } - } - - /** - * Reads the class_index field of the - * CONSTANT_InterfaceMethodref_info structure - * at the given index. - */ - public int getInterfaceMethodrefClass(int index) { - InterfaceMethodrefInfo minfo - = (InterfaceMethodrefInfo)getItem(index); - return minfo.classIndex; - } - - /** - * Reads the class_index field of the - * CONSTANT_InterfaceMethodref_info structure - * at the given index. - * - * @return the name of the class at that class_index. - */ - public String getInterfaceMethodrefClassName(int index) { - InterfaceMethodrefInfo minfo - = (InterfaceMethodrefInfo)getItem(index); - return getClassInfo(minfo.classIndex); - } - - /** - * Reads the name_and_type_index field of the - * CONSTANT_InterfaceMethodref_info structure - * at the given index. - */ - public int getInterfaceMethodrefNameAndType(int index) { - InterfaceMethodrefInfo minfo - = (InterfaceMethodrefInfo)getItem(index); - return minfo.nameAndTypeIndex; - } - - /** - * Reads the name_index field of the - * CONSTANT_NameAndType_info structure - * indirectly specified by the given index. - * - * @param index an index to - * a CONSTANT_InterfaceMethodref_info. - * @return the name of the method. - */ - public String getInterfaceMethodrefName(int index) { - InterfaceMethodrefInfo minfo - = (InterfaceMethodrefInfo)getItem(index); - if (minfo == null) - return null; - else { - NameAndTypeInfo n - = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); - if(n == null) - return null; - else - return getUtf8Info(n.memberName); - } - } - - /** - * Reads the descriptor_index field of the - * CONSTANT_NameAndType_info structure - * indirectly specified by the given index. - * - * @param index an index to - * a CONSTANT_InterfaceMethodref_info. - * @return the descriptor of the method. - */ - public String getInterfaceMethodrefType(int index) { - InterfaceMethodrefInfo minfo - = (InterfaceMethodrefInfo)getItem(index); - if (minfo == null) - return null; - else { - NameAndTypeInfo n - = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); - if(n == null) - return null; - else - return getUtf8Info(n.typeDescriptor); - } - } - /** - * Reads CONSTANT_Integer_info, _Float_info, - * _Long_info, _Double_info, or - * _String_info structure. - * These are used with the LDC instruction. - * - * @return a String value or a wrapped primitive-type - * value. - */ - public Object getLdcValue(int index) { - ConstInfo constInfo = this.getItem(index); - Object value = null; - if (constInfo instanceof StringInfo) - value = this.getStringInfo(index); - else if (constInfo instanceof FloatInfo) - value = new Float(getFloatInfo(index)); - else if (constInfo instanceof IntegerInfo) - value = new Integer(getIntegerInfo(index)); - else if (constInfo instanceof LongInfo) - value = new Long(getLongInfo(index)); - else if (constInfo instanceof DoubleInfo) - value = new Double(getDoubleInfo(index)); - else - value = null; - - return value; - } - - /** - * Reads CONSTANT_Integer_info structure - * at the given index. - * - * @return the value specified by this entry. - */ - public int getIntegerInfo(int index) { - IntegerInfo i = (IntegerInfo)getItem(index); - return i.value; - } - - /** - * Reads CONSTANT_Float_info structure - * at the given index. - * - * @return the value specified by this entry. - */ - public float getFloatInfo(int index) { - FloatInfo i = (FloatInfo)getItem(index); - return i.value; - } - - /** - * Reads CONSTANT_Long_info structure - * at the given index. - * - * @return the value specified by this entry. - */ - public long getLongInfo(int index) { - LongInfo i = (LongInfo)getItem(index); - return i.value; - } - - /** - * Reads CONSTANT_Double_info structure - * at the given index. - * - * @return the value specified by this entry. - */ - public double getDoubleInfo(int index) { - DoubleInfo i = (DoubleInfo)getItem(index); - return i.value; - } - - /** - * Reads CONSTANT_String_info structure - * at the given index. - * - * @return the string specified by string_index. - */ - public String getStringInfo(int index) { - StringInfo si = (StringInfo)getItem(index); - return getUtf8Info(si.string); - } - - /** - * Reads CONSTANT_utf8_info structure - * at the given index. - * - * @return the string specified by this entry. - */ - public String getUtf8Info(int index) { - Utf8Info utf = (Utf8Info)getItem(index); - return utf.string; - } - - /** - * Reads the reference_kind field of the - * CONSTANT_MethodHandle_info structure - * at the given index. - * - * @see #REF_getField - * @see #REF_getStatic - * @see #REF_invokeInterface - * @see #REF_invokeSpecial - * @see #REF_invokeStatic - * @see #REF_invokeVirtual - * @see #REF_newInvokeSpecial - * @see #REF_putField - * @see #REF_putStatic - * @since 3.17 - */ - public int getMethodHandleKind(int index) { - MethodHandleInfo mhinfo = (MethodHandleInfo)getItem(index); - return mhinfo.refKind; - } - - /** - * Reads the reference_index field of the - * CONSTANT_MethodHandle_info structure - * at the given index. - * - * @since 3.17 - */ - public int getMethodHandleIndex(int index) { - MethodHandleInfo mhinfo = (MethodHandleInfo)getItem(index); - return mhinfo.refIndex; - } - - /** - * Reads the descriptor_index field of the - * CONSTANT_MethodType_info structure - * at the given index. - * - * @since 3.17 - */ - public int getMethodTypeInfo(int index) { - MethodTypeInfo mtinfo = (MethodTypeInfo)getItem(index); - return mtinfo.descriptor; - } - - /** - * Reads the bootstrap_method_attr_index field of the - * CONSTANT_InvokeDynamic_info structure - * at the given index. - * - * @since 3.17 - */ - public int getInvokeDynamicBootstrap(int index) { - InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index); - return iv.bootstrap; - } - - /** - * Reads the name_and_type_index field of the - * CONSTANT_InvokeDynamic_info structure - * at the given index. - * - * @since 3.17 - */ - public int getInvokeDynamicNameAndType(int index) { - InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index); - return iv.nameAndType; - } - - /** - * Reads the descriptor_index field of the - * CONSTANT_NameAndType_info structure - * indirectly specified by the given index. - * - * @param index an index to a CONSTANT_InvokeDynamic_info. - * @return the descriptor of the method. - * @since 3.17 - */ - public String getInvokeDynamicType(int index) { - InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index); - if (iv == null) - return null; - else { - NameAndTypeInfo n = (NameAndTypeInfo)getItem(iv.nameAndType); - if(n == null) - return null; - else - return getUtf8Info(n.typeDescriptor); - } - } - - /** - * Determines whether CONSTANT_Methodref_info - * structure at the given index represents the constructor - * of the given class. - * - * @return the descriptor_index specifying - * the type descriptor of the that constructor. - * If it is not that constructor, - * isConstructor() returns 0. - */ - public int isConstructor(String classname, int index) { - return isMember(classname, MethodInfo.nameInit, index); - } - - /** - * Determines whether CONSTANT_Methodref_info, - * CONSTANT_Fieldref_info, or - * CONSTANT_InterfaceMethodref_info structure - * at the given index represents the member with the specified - * name and declaring class. - * - * @param classname the class declaring the member - * @param membername the member name - * @param index the index into the constant pool table - * - * @return the descriptor_index specifying - * the type descriptor of that member. - * If it is not that member, - * isMember() returns 0. - */ - public int isMember(String classname, String membername, int index) { - MemberrefInfo minfo = (MemberrefInfo)getItem(index); - if (getClassInfo(minfo.classIndex).equals(classname)) { - NameAndTypeInfo ntinfo - = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); - if (getUtf8Info(ntinfo.memberName).equals(membername)) - return ntinfo.typeDescriptor; - } - - return 0; // false - } - - /** - * Determines whether CONSTANT_Methodref_info, - * CONSTANT_Fieldref_info, or - * CONSTANT_InterfaceMethodref_info structure - * at the given index has the name and the descriptor - * given as the arguments. - * - * @param membername the member name - * @param desc the descriptor of the member. - * @param index the index into the constant pool table - * - * @return the name of the target class specified by - * the ..._info structure - * at index. - * Otherwise, null if that structure does not - * match the given member name and descriptor. - */ - public String eqMember(String membername, String desc, int index) { - MemberrefInfo minfo = (MemberrefInfo)getItem(index); - NameAndTypeInfo ntinfo - = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); - if (getUtf8Info(ntinfo.memberName).equals(membername) - && getUtf8Info(ntinfo.typeDescriptor).equals(desc)) - return getClassInfo(minfo.classIndex); - else - return null; // false - } - - private int addItem0(ConstInfo info) { - items.addElement(info); - return numOfItems++; - } - - private int addItem(ConstInfo info) { - if (itemsCache == null) - itemsCache = makeItemsCache(items); - - ConstInfo found = (ConstInfo)itemsCache.get(info); - if (found != null) - return found.index; - else { - items.addElement(info); - itemsCache.put(info, info); - return numOfItems++; - } - } - - /** - * Copies the n-th item in this ConstPool object into the destination - * ConstPool object. - * The class names that the item refers to are renamed according - * to the given map. - * - * @param n the n-th item - * @param dest destination constant pool table - * @param classnames the map or null. - * @return the index of the copied item into the destination ClassPool. - */ - public int copy(int n, ConstPool dest, Map classnames) { - if (n == 0) - return 0; - - ConstInfo info = getItem(n); - return info.copy(this, dest, classnames); - } - - int addConstInfoPadding() { - return addItem0(new ConstInfoPadding(numOfItems)); - } - - /** - * Adds a new CONSTANT_Class_info structure. - * - *

This also adds a CONSTANT_Utf8_info structure - * for storing the class name. - * - * @return the index of the added entry. - */ - public int addClassInfo(CtClass c) { - if (c == THIS) - return thisClassInfo; - else if (!c.isArray()) - return addClassInfo(c.getName()); - else { - // an array type is recorded in the hashtable with - // the key "[L;" instead of "". - // - // note: toJvmName(toJvmName(c)) is equal to toJvmName(c). - - return addClassInfo(Descriptor.toJvmName(c)); - } - } - - /** - * Adds a new CONSTANT_Class_info structure. - * - *

This also adds a CONSTANT_Utf8_info structure - * for storing the class name. - * - * @param qname a fully-qualified class name - * (or the JVM-internal representation of that name). - * @return the index of the added entry. - */ - public int addClassInfo(String qname) { - int utf8 = addUtf8Info(Descriptor.toJvmName(qname)); - return addItem(new ClassInfo(utf8, numOfItems)); - } - - /** - * Adds a new CONSTANT_NameAndType_info structure. - * - *

This also adds CONSTANT_Utf8_info structures. - * - * @param name name_index - * @param type descriptor_index - * @return the index of the added entry. - */ - public int addNameAndTypeInfo(String name, String type) { - return addNameAndTypeInfo(addUtf8Info(name), addUtf8Info(type)); - } - - /** - * Adds a new CONSTANT_NameAndType_info structure. - * - * @param name name_index - * @param type descriptor_index - * @return the index of the added entry. - */ - public int addNameAndTypeInfo(int name, int type) { - return addItem(new NameAndTypeInfo(name, type, numOfItems)); - } - - /** - * Adds a new CONSTANT_Fieldref_info structure. - * - *

This also adds a new CONSTANT_NameAndType_info - * structure. - * - * @param classInfo class_index - * @param name name_index - * of CONSTANT_NameAndType_info. - * @param type descriptor_index - * of CONSTANT_NameAndType_info. - * @return the index of the added entry. - */ - public int addFieldrefInfo(int classInfo, String name, String type) { - int nt = addNameAndTypeInfo(name, type); - return addFieldrefInfo(classInfo, nt); - } - - /** - * Adds a new CONSTANT_Fieldref_info structure. - * - * @param classInfo class_index - * @param nameAndTypeInfo name_and_type_index. - * @return the index of the added entry. - */ - public int addFieldrefInfo(int classInfo, int nameAndTypeInfo) { - return addItem(new FieldrefInfo(classInfo, nameAndTypeInfo, numOfItems)); - } - - /** - * Adds a new CONSTANT_Methodref_info structure. - * - *

This also adds a new CONSTANT_NameAndType_info - * structure. - * - * @param classInfo class_index - * @param name name_index - * of CONSTANT_NameAndType_info. - * @param type descriptor_index - * of CONSTANT_NameAndType_info. - * @return the index of the added entry. - */ - public int addMethodrefInfo(int classInfo, String name, String type) { - int nt = addNameAndTypeInfo(name, type); - return addMethodrefInfo(classInfo, nt); - } - - /** - * Adds a new CONSTANT_Methodref_info structure. - * - * @param classInfo class_index - * @param nameAndTypeInfo name_and_type_index. - * @return the index of the added entry. - */ - public int addMethodrefInfo(int classInfo, int nameAndTypeInfo) { - return addItem(new MethodrefInfo(classInfo, nameAndTypeInfo, numOfItems)); - } - - /** - * Adds a new CONSTANT_InterfaceMethodref_info - * structure. - * - *

This also adds a new CONSTANT_NameAndType_info - * structure. - * - * @param classInfo class_index - * @param name name_index - * of CONSTANT_NameAndType_info. - * @param type descriptor_index - * of CONSTANT_NameAndType_info. - * @return the index of the added entry. - */ - public int addInterfaceMethodrefInfo(int classInfo, String name, - String type) { - int nt = addNameAndTypeInfo(name, type); - return addInterfaceMethodrefInfo(classInfo, nt); - } - - /** - * Adds a new CONSTANT_InterfaceMethodref_info - * structure. - * - * @param classInfo class_index - * @param nameAndTypeInfo name_and_type_index. - * @return the index of the added entry. - */ - public int addInterfaceMethodrefInfo(int classInfo, - int nameAndTypeInfo) { - return addItem(new InterfaceMethodrefInfo(classInfo, nameAndTypeInfo, - numOfItems)); - } - - /** - * Adds a new CONSTANT_String_info - * structure. - * - *

This also adds a new CONSTANT_Utf8_info - * structure. - * - * @return the index of the added entry. - */ - public int addStringInfo(String str) { - int utf = addUtf8Info(str); - return addItem(new StringInfo(utf, numOfItems)); - } - - /** - * Adds a new CONSTANT_Integer_info - * structure. - * - * @return the index of the added entry. - */ - public int addIntegerInfo(int i) { - return addItem(new IntegerInfo(i, numOfItems)); - } - - /** - * Adds a new CONSTANT_Float_info - * structure. - * - * @return the index of the added entry. - */ - public int addFloatInfo(float f) { - return addItem(new FloatInfo(f, numOfItems)); - } - - /** - * Adds a new CONSTANT_Long_info - * structure. - * - * @return the index of the added entry. - */ - public int addLongInfo(long l) { - int i = addItem(new LongInfo(l, numOfItems)); - if (i == numOfItems - 1) // if not existing - addConstInfoPadding(); - - return i; - } - - /** - * Adds a new CONSTANT_Double_info - * structure. - * - * @return the index of the added entry. - */ - public int addDoubleInfo(double d) { - int i = addItem(new DoubleInfo(d, numOfItems)); - if (i == numOfItems - 1) // if not existing - addConstInfoPadding(); - - return i; - } - - /** - * Adds a new CONSTANT_Utf8_info - * structure. - * - * @return the index of the added entry. - */ - public int addUtf8Info(String utf8) { - return addItem(new Utf8Info(utf8, numOfItems)); - } - - /** - * Adds a new CONSTANT_MethodHandle_info - * structure. - * - * @param kind reference_kind - * such as {@link #REF_invokeStatic REF_invokeStatic}. - * @param index reference_index. - * @return the index of the added entry. - * - * @since 3.17 - */ - public int addMethodHandleInfo(int kind, int index) { - return addItem(new MethodHandleInfo(kind, index, numOfItems)); - } - - /** - * Adds a new CONSTANT_MethodType_info - * structure. - * - * @param desc descriptor_index. - * @return the index of the added entry. - * - * @since 3.17 - */ - public int addMethodTypeInfo(int desc) { - return addItem(new MethodTypeInfo(desc, numOfItems)); - } - - /** - * Adds a new CONSTANT_InvokeDynamic_info - * structure. - * - * @param bootstrap bootstrap_method_attr_index. - * @param nameAndType name_and_type_index. - * @return the index of the added entry. - * - * @since 3.17 - */ - public int addInvokeDynamicInfo(int bootstrap, int nameAndType) { - return addItem(new InvokeDynamicInfo(bootstrap, nameAndType, numOfItems)); - } - - /** - * Get all the class names. - * - * @return a set of class names (String objects). - */ - public Set getClassNames() { - HashSet result = new HashSet(); - LongVector v = items; - int size = numOfItems; - for (int i = 1; i < size; ++i) { - String className = v.elementAt(i).getClassName(this); - if (className != null) - result.add(className); - } - return result; - } - - /** - * Replaces all occurrences of a class name. - * - * @param oldName the replaced name (JVM-internal representation). - * @param newName the substituted name (JVM-internal representation). - */ - public void renameClass(String oldName, String newName) { - LongVector v = items; - int size = numOfItems; - for (int i = 1; i < size; ++i) { - ConstInfo ci = v.elementAt(i); - ci.renameClass(this, oldName, newName, itemsCache); - } - } - - /** - * Replaces all occurrences of class names. - * - * @param classnames specifies pairs of replaced and substituted - * name. - */ - public void renameClass(Map classnames) { - LongVector v = items; - int size = numOfItems; - for (int i = 1; i < size; ++i) { - ConstInfo ci = v.elementAt(i); - ci.renameClass(this, classnames, itemsCache); - } - } - - private void read(DataInputStream in) throws IOException { - int n = in.readUnsignedShort(); - - items = new LongVector(n); - numOfItems = 0; - addItem0(null); // index 0 is reserved by the JVM. - - while (--n > 0) { // index 0 is reserved by JVM - int tag = readOne(in); - if ((tag == LongInfo.tag) || (tag == DoubleInfo.tag)) { - addConstInfoPadding(); - --n; - } - } - } - - private static HashMap makeItemsCache(LongVector items) { - HashMap cache = new HashMap(); - int i = 1; - while (true) { - ConstInfo info = items.elementAt(i++); - if (info == null) - break; - else - cache.put(info, info); - } - - return cache; - } - - private int readOne(DataInputStream in) throws IOException { - ConstInfo info; - int tag = in.readUnsignedByte(); - switch (tag) { - case Utf8Info.tag : // 1 - info = new Utf8Info(in, numOfItems); - break; - case IntegerInfo.tag : // 3 - info = new IntegerInfo(in, numOfItems); - break; - case FloatInfo.tag : // 4 - info = new FloatInfo(in, numOfItems); - break; - case LongInfo.tag : // 5 - info = new LongInfo(in, numOfItems); - break; - case DoubleInfo.tag : // 6 - info = new DoubleInfo(in, numOfItems); - break; - case ClassInfo.tag : // 7 - info = new ClassInfo(in, numOfItems); - break; - case StringInfo.tag : // 8 - info = new StringInfo(in, numOfItems); - break; - case FieldrefInfo.tag : // 9 - info = new FieldrefInfo(in, numOfItems); - break; - case MethodrefInfo.tag : // 10 - info = new MethodrefInfo(in, numOfItems); - break; - case InterfaceMethodrefInfo.tag : // 11 - info = new InterfaceMethodrefInfo(in, numOfItems); - break; - case NameAndTypeInfo.tag : // 12 - info = new NameAndTypeInfo(in, numOfItems); - break; - case MethodHandleInfo.tag : // 15 - info = new MethodHandleInfo(in, numOfItems); - break; - case MethodTypeInfo.tag : // 16 - info = new MethodTypeInfo(in, numOfItems); - break; - case InvokeDynamicInfo.tag : // 18 - info = new InvokeDynamicInfo(in, numOfItems); - break; - default : - throw new IOException("invalid constant type: " + tag + " at " + numOfItems); - } - - addItem0(info); - return tag; - } - - /** - * Writes the contents of the constant pool table. - */ - public void write(DataOutputStream out) throws IOException { - out.writeShort(numOfItems); - LongVector v = items; - int size = numOfItems; - for (int i = 1; i < size; ++i) - v.elementAt(i).write(out); - } - - /** - * Prints the contents of the constant pool table. - */ - public void print() { - print(new PrintWriter(System.out, true)); - } - - /** - * Prints the contents of the constant pool table. - */ - public void print(PrintWriter out) { - int size = numOfItems; - for (int i = 1; i < size; ++i) { - out.print(i); - out.print(" "); - items.elementAt(i).print(out); - } - } -} - -abstract class ConstInfo { - int index; - - public ConstInfo(int i) { index = i; } - - public abstract int getTag(); - - public String getClassName(ConstPool cp) { return null; } - public void renameClass(ConstPool cp, String oldName, String newName, HashMap cache) {} - public void renameClass(ConstPool cp, Map classnames, HashMap cache) {} - public abstract int copy(ConstPool src, ConstPool dest, Map classnames); - // ** classnames is a mapping between JVM names. - - public abstract void write(DataOutputStream out) throws IOException; - public abstract void print(PrintWriter out); - - public String toString() { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - PrintWriter out = new PrintWriter(bout); - print(out); - return bout.toString(); - } -} - -/* padding following DoubleInfo or LongInfo. - */ -class ConstInfoPadding extends ConstInfo { - public ConstInfoPadding(int i) { super(i); } - - public int getTag() { return 0; } - - public int copy(ConstPool src, ConstPool dest, Map map) { - return dest.addConstInfoPadding(); - } - - public void write(DataOutputStream out) throws IOException {} - - public void print(PrintWriter out) { - out.println("padding"); - } -} - -class ClassInfo extends ConstInfo { - static final int tag = 7; - int name; - - public ClassInfo(int className, int index) { - super(index); - name = className; - } - - public ClassInfo(DataInputStream in, int index) throws IOException { - super(index); - name = in.readUnsignedShort(); - } - - public int hashCode() { return name; } - - public boolean equals(Object obj) { - return obj instanceof ClassInfo && ((ClassInfo)obj).name == name; - } - - public int getTag() { return tag; } - - public String getClassName(ConstPool cp) { - return cp.getUtf8Info(name); - } - - public void renameClass(ConstPool cp, String oldName, String newName, HashMap cache) { - String nameStr = cp.getUtf8Info(name); - String newNameStr = null; - if (nameStr.equals(oldName)) - newNameStr = newName; - else if (nameStr.charAt(0) == '[') { - String s = Descriptor.rename(nameStr, oldName, newName); - if (nameStr != s) - newNameStr = s; - } - - if (newNameStr != null) - if (cache == null) - name = cp.addUtf8Info(newNameStr); - else { - cache.remove(this); - name = cp.addUtf8Info(newNameStr); - cache.put(this, this); - } - } - - public void renameClass(ConstPool cp, Map map, HashMap cache) { - String oldName = cp.getUtf8Info(name); - String newName = null; - if (oldName.charAt(0) == '[') { - String s = Descriptor.rename(oldName, map); - if (oldName != s) - newName = s; - } - else { - String s = (String)map.get(oldName); - if (s != null && !s.equals(oldName)) - newName = s; - } - - if (newName != null) { - if (cache == null) - name = cp.addUtf8Info(newName); - else { - cache.remove(this); - name = cp.addUtf8Info(newName); - cache.put(this, this); - } - } - } - - public int copy(ConstPool src, ConstPool dest, Map map) { - String classname = src.getUtf8Info(name); - if (map != null) { - String newname = (String)map.get(classname); - if (newname != null) - classname = newname; - } - - return dest.addClassInfo(classname); - } - - public void write(DataOutputStream out) throws IOException { - out.writeByte(tag); - out.writeShort(name); - } - - public void print(PrintWriter out) { - out.print("Class #"); - out.println(name); - } -} - -class NameAndTypeInfo extends ConstInfo { - static final int tag = 12; - int memberName; - int typeDescriptor; - - public NameAndTypeInfo(int name, int type, int index) { - super(index); - memberName = name; - typeDescriptor = type; - } - - public NameAndTypeInfo(DataInputStream in, int index) throws IOException { - super(index); - memberName = in.readUnsignedShort(); - typeDescriptor = in.readUnsignedShort(); - } - - public int hashCode() { return (memberName << 16) ^ typeDescriptor; } - - public boolean equals(Object obj) { - if (obj instanceof NameAndTypeInfo) { - NameAndTypeInfo nti = (NameAndTypeInfo)obj; - return nti.memberName == memberName && nti.typeDescriptor == typeDescriptor; - } - else - return false; - } - - public int getTag() { return tag; } - - public void renameClass(ConstPool cp, String oldName, String newName, HashMap cache) { - String type = cp.getUtf8Info(typeDescriptor); - String type2 = Descriptor.rename(type, oldName, newName); - if (type != type2) - if (cache == null) - typeDescriptor = cp.addUtf8Info(type2); - else { - cache.remove(this); - typeDescriptor = cp.addUtf8Info(type2); - cache.put(this, this); - } - } - - public void renameClass(ConstPool cp, Map map, HashMap cache) { - String type = cp.getUtf8Info(typeDescriptor); - String type2 = Descriptor.rename(type, map); - if (type != type2) - if (cache == null) - typeDescriptor = cp.addUtf8Info(type2); - else { - cache.remove(this); - typeDescriptor = cp.addUtf8Info(type2); - cache.put(this, this); - } - } - - public int copy(ConstPool src, ConstPool dest, Map map) { - String mname = src.getUtf8Info(memberName); - String tdesc = src.getUtf8Info(typeDescriptor); - tdesc = Descriptor.rename(tdesc, map); - return dest.addNameAndTypeInfo(dest.addUtf8Info(mname), - dest.addUtf8Info(tdesc)); - } - - public void write(DataOutputStream out) throws IOException { - out.writeByte(tag); - out.writeShort(memberName); - out.writeShort(typeDescriptor); - } - - public void print(PrintWriter out) { - out.print("NameAndType #"); - out.print(memberName); - out.print(", type #"); - out.println(typeDescriptor); - } -} - -abstract class MemberrefInfo extends ConstInfo { - int classIndex; - int nameAndTypeIndex; - - public MemberrefInfo(int cindex, int ntindex, int thisIndex) { - super(thisIndex); - classIndex = cindex; - nameAndTypeIndex = ntindex; - } - - public MemberrefInfo(DataInputStream in, int thisIndex) throws IOException { - super(thisIndex); - classIndex = in.readUnsignedShort(); - nameAndTypeIndex = in.readUnsignedShort(); - } - - public int hashCode() { return (classIndex << 16) ^ nameAndTypeIndex; } - - public boolean equals(Object obj) { - if (obj instanceof MemberrefInfo) { - MemberrefInfo mri = (MemberrefInfo)obj; - return mri.classIndex == classIndex && mri.nameAndTypeIndex == nameAndTypeIndex - && mri.getClass() == this.getClass(); - } - else - return false; - } - - public int copy(ConstPool src, ConstPool dest, Map map) { - int classIndex2 = src.getItem(classIndex).copy(src, dest, map); - int ntIndex2 = src.getItem(nameAndTypeIndex).copy(src, dest, map); - return copy2(dest, classIndex2, ntIndex2); - } - - abstract protected int copy2(ConstPool dest, int cindex, int ntindex); - - public void write(DataOutputStream out) throws IOException { - out.writeByte(getTag()); - out.writeShort(classIndex); - out.writeShort(nameAndTypeIndex); - } - - public void print(PrintWriter out) { - out.print(getTagName() + " #"); - out.print(classIndex); - out.print(", name&type #"); - out.println(nameAndTypeIndex); - } - - public abstract String getTagName(); -} - -class FieldrefInfo extends MemberrefInfo { - static final int tag = 9; - - public FieldrefInfo(int cindex, int ntindex, int thisIndex) { - super(cindex, ntindex, thisIndex); - } - - public FieldrefInfo(DataInputStream in, int thisIndex) throws IOException { - super(in, thisIndex); - } - - public int getTag() { return tag; } - - public String getTagName() { return "Field"; } - - protected int copy2(ConstPool dest, int cindex, int ntindex) { - return dest.addFieldrefInfo(cindex, ntindex); - } -} - -class MethodrefInfo extends MemberrefInfo { - static final int tag = 10; - - public MethodrefInfo(int cindex, int ntindex, int thisIndex) { - super(cindex, ntindex, thisIndex); - } - - public MethodrefInfo(DataInputStream in, int thisIndex) throws IOException { - super(in, thisIndex); - } - - public int getTag() { return tag; } - - public String getTagName() { return "Method"; } - - protected int copy2(ConstPool dest, int cindex, int ntindex) { - return dest.addMethodrefInfo(cindex, ntindex); - } -} - -class InterfaceMethodrefInfo extends MemberrefInfo { - static final int tag = 11; - - public InterfaceMethodrefInfo(int cindex, int ntindex, int thisIndex) { - super(cindex, ntindex, thisIndex); - } - - public InterfaceMethodrefInfo(DataInputStream in, int thisIndex) throws IOException { - super(in, thisIndex); - } - - public int getTag() { return tag; } - - public String getTagName() { return "Interface"; } - - protected int copy2(ConstPool dest, int cindex, int ntindex) { - return dest.addInterfaceMethodrefInfo(cindex, ntindex); - } -} - -class StringInfo extends ConstInfo { - static final int tag = 8; - int string; - - public StringInfo(int str, int index) { - super(index); - string = str; - } - - public StringInfo(DataInputStream in, int index) throws IOException { - super(index); - string = in.readUnsignedShort(); - } - - public int hashCode() { return string; } - - public boolean equals(Object obj) { - return obj instanceof StringInfo && ((StringInfo)obj).string == string; - } - - public int getTag() { return tag; } - - public int copy(ConstPool src, ConstPool dest, Map map) { - return dest.addStringInfo(src.getUtf8Info(string)); - } - - public void write(DataOutputStream out) throws IOException { - out.writeByte(tag); - out.writeShort(string); - } - - public void print(PrintWriter out) { - out.print("String #"); - out.println(string); - } -} - -class IntegerInfo extends ConstInfo { - static final int tag = 3; - int value; - - public IntegerInfo(int v, int index) { - super(index); - value = v; - } - - public IntegerInfo(DataInputStream in, int index) throws IOException { - super(index); - value = in.readInt(); - } - - public int hashCode() { return value; } - - public boolean equals(Object obj) { - return obj instanceof IntegerInfo && ((IntegerInfo)obj).value == value; - } - - public int getTag() { return tag; } - - public int copy(ConstPool src, ConstPool dest, Map map) { - return dest.addIntegerInfo(value); - } - - public void write(DataOutputStream out) throws IOException { - out.writeByte(tag); - out.writeInt(value); - } - - public void print(PrintWriter out) { - out.print("Integer "); - out.println(value); - } -} - -class FloatInfo extends ConstInfo { - static final int tag = 4; - float value; - - public FloatInfo(float f, int index) { - super(index); - value = f; - } - - public FloatInfo(DataInputStream in, int index) throws IOException { - super(index); - value = in.readFloat(); - } - - public int hashCode() { return Float.floatToIntBits(value); } - - public boolean equals(Object obj) { - return obj instanceof FloatInfo && ((FloatInfo)obj).value == value; - } - - public int getTag() { return tag; } - - public int copy(ConstPool src, ConstPool dest, Map map) { - return dest.addFloatInfo(value); - } - - public void write(DataOutputStream out) throws IOException { - out.writeByte(tag); - out.writeFloat(value); - } - - public void print(PrintWriter out) { - out.print("Float "); - out.println(value); - } -} - -class LongInfo extends ConstInfo { - static final int tag = 5; - long value; - - public LongInfo(long l, int index) { - super(index); - value = l; - } - - public LongInfo(DataInputStream in, int index) throws IOException { - super(index); - value = in.readLong(); - } - - public int hashCode() { return (int)(value ^ (value >>> 32)); } - - public boolean equals(Object obj) { - return obj instanceof LongInfo && ((LongInfo)obj).value == value; - } - - public int getTag() { return tag; } - - public int copy(ConstPool src, ConstPool dest, Map map) { - return dest.addLongInfo(value); - } - - public void write(DataOutputStream out) throws IOException { - out.writeByte(tag); - out.writeLong(value); - } - - public void print(PrintWriter out) { - out.print("Long "); - out.println(value); - } -} - -class DoubleInfo extends ConstInfo { - static final int tag = 6; - double value; - - public DoubleInfo(double d, int index) { - super(index); - value = d; - } - - public DoubleInfo(DataInputStream in, int index) throws IOException { - super(index); - value = in.readDouble(); - } - - public int hashCode() { - long v = Double.doubleToLongBits(value); - return (int)(v ^ (v >>> 32)); - } - - public boolean equals(Object obj) { - return obj instanceof DoubleInfo && ((DoubleInfo)obj).value == value; - } - - public int getTag() { return tag; } - - public int copy(ConstPool src, ConstPool dest, Map map) { - return dest.addDoubleInfo(value); - } - - public void write(DataOutputStream out) throws IOException { - out.writeByte(tag); - out.writeDouble(value); - } - - public void print(PrintWriter out) { - out.print("Double "); - out.println(value); - } -} - -class Utf8Info extends ConstInfo { - static final int tag = 1; - String string; - - public Utf8Info(String utf8, int index) { - super(index); - string = utf8; - } - - public Utf8Info(DataInputStream in, int index) throws IOException { - super(index); - string = in.readUTF(); - } - - public int hashCode() { - return string.hashCode(); - } - - public boolean equals(Object obj) { - return obj instanceof Utf8Info && ((Utf8Info)obj).string.equals(string); - } - - public int getTag() { return tag; } - - public int copy(ConstPool src, ConstPool dest, Map map) { - return dest.addUtf8Info(string); - } - - public void write(DataOutputStream out) throws IOException { - out.writeByte(tag); - out.writeUTF(string); - } - - public void print(PrintWriter out) { - out.print("UTF8 \""); - out.print(string); - out.println("\""); - } -} - -class MethodHandleInfo extends ConstInfo { - static final int tag = 15; - int refKind, refIndex; - - public MethodHandleInfo(int kind, int referenceIndex, int index) { - super(index); - refKind = kind; - refIndex = referenceIndex; - } - - public MethodHandleInfo(DataInputStream in, int index) throws IOException { - super(index); - refKind = in.readUnsignedByte(); - refIndex = in.readUnsignedShort(); - } - - public int hashCode() { return (refKind << 16) ^ refIndex; } - - public boolean equals(Object obj) { - if (obj instanceof MethodHandleInfo) { - MethodHandleInfo mh = (MethodHandleInfo)obj; - return mh.refKind == refKind && mh.refIndex == refIndex; - } - else - return false; - } - - public int getTag() { return tag; } - - public int copy(ConstPool src, ConstPool dest, Map map) { - return dest.addMethodHandleInfo(refKind, - src.getItem(refIndex).copy(src, dest, map)); - } - - public void write(DataOutputStream out) throws IOException { - out.writeByte(tag); - out.writeByte(refKind); - out.writeShort(refIndex); - } - - public void print(PrintWriter out) { - out.print("MethodHandle #"); - out.print(refKind); - out.print(", index #"); - out.println(refIndex); - } -} - -class MethodTypeInfo extends ConstInfo { - static final int tag = 16; - int descriptor; - - public MethodTypeInfo(int desc, int index) { - super(index); - descriptor = desc; - } - - public MethodTypeInfo(DataInputStream in, int index) throws IOException { - super(index); - descriptor = in.readUnsignedShort(); - } - - public int hashCode() { return descriptor; } - - public boolean equals(Object obj) { - if (obj instanceof MethodTypeInfo) - return ((MethodTypeInfo)obj).descriptor == descriptor; - else - return false; - } - - public int getTag() { return tag; } - - public void renameClass(ConstPool cp, String oldName, String newName, HashMap cache) { - String desc = cp.getUtf8Info(descriptor); - String desc2 = Descriptor.rename(desc, oldName, newName); - if (desc != desc2) - if (cache == null) - descriptor = cp.addUtf8Info(desc2); - else { - cache.remove(this); - descriptor = cp.addUtf8Info(desc2); - cache.put(this, this); - } - } - - public void renameClass(ConstPool cp, Map map, HashMap cache) { - String desc = cp.getUtf8Info(descriptor); - String desc2 = Descriptor.rename(desc, map); - if (desc != desc2) - if (cache == null) - descriptor = cp.addUtf8Info(desc2); - else { - cache.remove(this); - descriptor = cp.addUtf8Info(desc2); - cache.put(this, this); - } - } - - public int copy(ConstPool src, ConstPool dest, Map map) { - String desc = src.getUtf8Info(descriptor); - desc = Descriptor.rename(desc, map); - return dest.addMethodTypeInfo(dest.addUtf8Info(desc)); - } - - public void write(DataOutputStream out) throws IOException { - out.writeByte(tag); - out.writeShort(descriptor); - } - - public void print(PrintWriter out) { - out.print("MethodType #"); - out.println(descriptor); - } -} - -class InvokeDynamicInfo extends ConstInfo { - static final int tag = 18; - int bootstrap, nameAndType; - - public InvokeDynamicInfo(int bootstrapMethod, int ntIndex, int index) { - super(index); - bootstrap = bootstrapMethod; - nameAndType = ntIndex; - } - - public InvokeDynamicInfo(DataInputStream in, int index) throws IOException { - super(index); - bootstrap = in.readUnsignedShort(); - nameAndType = in.readUnsignedShort(); - } - - public int hashCode() { return (bootstrap << 16) ^ nameAndType; } - - public boolean equals(Object obj) { - if (obj instanceof InvokeDynamicInfo) { - InvokeDynamicInfo iv = (InvokeDynamicInfo)obj; - return iv.bootstrap == bootstrap && iv.nameAndType == nameAndType; - } - else - return false; - } - - public int getTag() { return tag; } - - public int copy(ConstPool src, ConstPool dest, Map map) { - return dest.addInvokeDynamicInfo(bootstrap, - src.getItem(nameAndType).copy(src, dest, map)); - } - - public void write(DataOutputStream out) throws IOException { - out.writeByte(tag); - out.writeShort(bootstrap); - out.writeShort(nameAndType); - } - - public void print(PrintWriter out) { - out.print("InvokeDynamic #"); - out.print(bootstrap); - out.print(", name&type #"); - out.println(nameAndType); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ConstantAttribute.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ConstantAttribute.java deleted file mode 100644 index 3efa3825a..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ConstantAttribute.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.util.Map; -import java.io.IOException; - -/** - * ConstantValue_attribute. - */ -public class ConstantAttribute extends com.fr.third.javassist.bytecode.AttributeInfo { - /** - * The name of this attribute "ConstantValue". - */ - public static final String tag = "ConstantValue"; - - ConstantAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int n, DataInputStream in) - throws IOException - { - super(cp, n, in); - } - - /** - * Constructs a ConstantValue attribute. - * - * @param cp a constant pool table. - * @param index constantvalue_index - * of ConstantValue_attribute. - */ - public ConstantAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int index) { - super(cp, tag); - byte[] bvalue = new byte[2]; - bvalue[0] = (byte)(index >>> 8); - bvalue[1] = (byte)index; - set(bvalue); - } - - /** - * Returns constantvalue_index. - */ - public int getConstantValue() { - return ByteArray.readU16bit(get(), 0); - } - - /** - * Makes a copy. Class names are replaced according to the - * given Map object. - * - * @param newCp the constant pool table used by the new copy. - * @param classnames pairs of replaced and substituted - * class names. - */ - public AttributeInfo copy(ConstPool newCp, Map classnames) { - int index = getConstPool().copy(getConstantValue(), newCp, - classnames); - return new ConstantAttribute(newCp, index); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/DeprecatedAttribute.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/DeprecatedAttribute.java deleted file mode 100644 index 3c9f08aa3..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/DeprecatedAttribute.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.IOException; -import java.util.Map; - -/** - * Deprecated_attribute. - */ -public class DeprecatedAttribute extends com.fr.third.javassist.bytecode.AttributeInfo { - /** - * The name of this attribute "Deprecated". - */ - public static final String tag = "Deprecated"; - - DeprecatedAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int n, DataInputStream in) - throws IOException - { - super(cp, n, in); - } - - /** - * Constructs a Deprecated attribute. - * - * @param cp a constant pool table. - */ - public DeprecatedAttribute(com.fr.third.javassist.bytecode.ConstPool cp) { - super(cp, tag, new byte[0]); - } - - /** - * Makes a copy. - * - * @param newCp the constant pool table used by the new copy. - * @param classnames should be null. - */ - public AttributeInfo copy(ConstPool newCp, Map classnames) { - return new DeprecatedAttribute(newCp); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/Descriptor.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/Descriptor.java deleted file mode 100644 index ce4ca36e5..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/Descriptor.java +++ /dev/null @@ -1,872 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CtPrimitiveType; -import com.fr.third.javassist.NotFoundException; -import java.util.Map; - -/** - * A support class for dealing with descriptors. - * - *

See chapter 4.3 in "The Java Virtual Machine Specification (2nd ed.)" - */ -public class Descriptor { - /** - * Converts a class name into the internal representation used in - * the JVM. - * - *

Note that toJvmName(toJvmName(s)) is equivalent - * to toJvmName(s). - */ - public static String toJvmName(String classname) { - return classname.replace('.', '/'); - } - - /** - * Converts a class name from the internal representation used in - * the JVM to the normal one used in Java. - * This method does not deal with an array type name such as - * "[Ljava/lang/Object;" and "[I;". For such names, use - * toClassName(). - * - * @see #toClassName(String) - */ - public static String toJavaName(String classname) { - return classname.replace('/', '.'); - } - - /** - * Returns the internal representation of the class name in the - * JVM. - */ - public static String toJvmName(CtClass clazz) { - if (clazz.isArray()) - return of(clazz); - else - return toJvmName(clazz.getName()); - } - - /** - * Converts to a Java class name from a descriptor. - * - * @param descriptor type descriptor. - */ - public static String toClassName(String descriptor) { - int arrayDim = 0; - int i = 0; - char c = descriptor.charAt(0); - while (c == '[') { - ++arrayDim; - c = descriptor.charAt(++i); - } - - String name; - if (c == 'L') { - int i2 = descriptor.indexOf(';', i++); - name = descriptor.substring(i, i2).replace('/', '.'); - i = i2; - } - else if (c == 'V') - name = "void"; - else if (c == 'I') - name = "int"; - else if (c == 'B') - name = "byte"; - else if (c == 'J') - name = "long"; - else if (c == 'D') - name = "double"; - else if (c == 'F') - name = "float"; - else if (c == 'C') - name = "char"; - else if (c == 'S') - name = "short"; - else if (c == 'Z') - name = "boolean"; - else - throw new RuntimeException("bad descriptor: " + descriptor); - - if (i + 1 != descriptor.length()) - throw new RuntimeException("multiple descriptors?: " + descriptor); - - if (arrayDim == 0) - return name; - else { - StringBuffer sbuf = new StringBuffer(name); - do { - sbuf.append("[]"); - } while (--arrayDim > 0); - - return sbuf.toString(); - } - } - - /** - * Converts to a descriptor from a Java class name - */ - public static String of(String classname) { - if (classname.equals("void")) - return "V"; - else if (classname.equals("int")) - return "I"; - else if (classname.equals("byte")) - return "B"; - else if (classname.equals("long")) - return "J"; - else if (classname.equals("double")) - return "D"; - else if (classname.equals("float")) - return "F"; - else if (classname.equals("char")) - return "C"; - else if (classname.equals("short")) - return "S"; - else if (classname.equals("boolean")) - return "Z"; - else - return "L" + toJvmName(classname) + ";"; - } - - /** - * Substitutes a class name - * in the given descriptor string. - * - * @param desc descriptor string - * @param oldname replaced JVM class name - * @param newname substituted JVM class name - * - * @see Descriptor#toJvmName(String) - */ - public static String rename(String desc, String oldname, String newname) { - if (desc.indexOf(oldname) < 0) - return desc; - - StringBuffer newdesc = new StringBuffer(); - int head = 0; - int i = 0; - for (;;) { - int j = desc.indexOf('L', i); - if (j < 0) - break; - else if (desc.startsWith(oldname, j + 1) - && desc.charAt(j + oldname.length() + 1) == ';') { - newdesc.append(desc.substring(head, j)); - newdesc.append('L'); - newdesc.append(newname); - newdesc.append(';'); - head = i = j + oldname.length() + 2; - } - else { - i = desc.indexOf(';', j) + 1; - if (i < 1) - break; // ';' was not found. - } - } - - if (head == 0) - return desc; - else { - int len = desc.length(); - if (head < len) - newdesc.append(desc.substring(head, len)); - - return newdesc.toString(); - } - } - - /** - * Substitutes class names in the given descriptor string - * according to the given map. - * - * @param map a map between replaced and substituted - * JVM class names. - * @see Descriptor#toJvmName(String) - */ - public static String rename(String desc, Map map) { - if (map == null) - return desc; - - StringBuffer newdesc = new StringBuffer(); - int head = 0; - int i = 0; - for (;;) { - int j = desc.indexOf('L', i); - if (j < 0) - break; - - int k = desc.indexOf(';', j); - if (k < 0) - break; - - i = k + 1; - String name = desc.substring(j + 1, k); - String name2 = (String)map.get(name); - if (name2 != null) { - newdesc.append(desc.substring(head, j)); - newdesc.append('L'); - newdesc.append(name2); - newdesc.append(';'); - head = i; - } - } - - if (head == 0) - return desc; - else { - int len = desc.length(); - if (head < len) - newdesc.append(desc.substring(head, len)); - - return newdesc.toString(); - } - } - - /** - * Returns the descriptor representing the given type. - */ - public static String of(CtClass type) { - StringBuffer sbuf = new StringBuffer(); - toDescriptor(sbuf, type); - return sbuf.toString(); - } - - private static void toDescriptor(StringBuffer desc, CtClass type) { - if (type.isArray()) { - desc.append('['); - try { - toDescriptor(desc, type.getComponentType()); - } - catch (NotFoundException e) { - desc.append('L'); - String name = type.getName(); - desc.append(toJvmName(name.substring(0, name.length() - 2))); - desc.append(';'); - } - } - else if (type.isPrimitive()) { - CtPrimitiveType pt = (CtPrimitiveType)type; - desc.append(pt.getDescriptor()); - } - else { // class type - desc.append('L'); - desc.append(type.getName().replace('.', '/')); - desc.append(';'); - } - } - - /** - * Returns the descriptor representing a constructor receiving - * the given parameter types. - * - * @param paramTypes parameter types - */ - public static String ofConstructor(CtClass[] paramTypes) { - return ofMethod(CtClass.voidType, paramTypes); - } - - /** - * Returns the descriptor representing a method that receives - * the given parameter types and returns the given type. - * - * @param returnType return type - * @param paramTypes parameter types - */ - public static String ofMethod(CtClass returnType, CtClass[] paramTypes) { - StringBuffer desc = new StringBuffer(); - desc.append('('); - if (paramTypes != null) { - int n = paramTypes.length; - for (int i = 0; i < n; ++i) - toDescriptor(desc, paramTypes[i]); - } - - desc.append(')'); - if (returnType != null) - toDescriptor(desc, returnType); - - return desc.toString(); - } - - /** - * Returns the descriptor representing a list of parameter types. - * For example, if the given parameter types are two int, - * then this method returns "(II)". - * - * @param paramTypes parameter types - */ - public static String ofParameters(CtClass[] paramTypes) { - return ofMethod(null, paramTypes); - } - - /** - * Appends a parameter type to the parameter list represented - * by the given descriptor. - * - *

classname must not be an array type. - * - * @param classname parameter type (not primitive type) - * @param desc descriptor - */ - public static String appendParameter(String classname, String desc) { - int i = desc.indexOf(')'); - if (i < 0) - return desc; - else { - StringBuffer newdesc = new StringBuffer(); - newdesc.append(desc.substring(0, i)); - newdesc.append('L'); - newdesc.append(classname.replace('.', '/')); - newdesc.append(';'); - newdesc.append(desc.substring(i)); - return newdesc.toString(); - } - } - - /** - * Inserts a parameter type at the beginning of the parameter - * list represented - * by the given descriptor. - * - *

classname must not be an array type. - * - * @param classname parameter type (not primitive type) - * @param desc descriptor - */ - public static String insertParameter(String classname, String desc) { - if (desc.charAt(0) != '(') - return desc; - else - return "(L" + classname.replace('.', '/') + ';' - + desc.substring(1); - } - - /** - * Appends a parameter type to the parameter list represented - * by the given descriptor. The appended parameter becomes - * the last parameter. - * - * @param type the type of the appended parameter. - * @param descriptor the original descriptor. - */ - public static String appendParameter(CtClass type, String descriptor) { - int i = descriptor.indexOf(')'); - if (i < 0) - return descriptor; - else { - StringBuffer newdesc = new StringBuffer(); - newdesc.append(descriptor.substring(0, i)); - toDescriptor(newdesc, type); - newdesc.append(descriptor.substring(i)); - return newdesc.toString(); - } - } - - /** - * Inserts a parameter type at the beginning of the parameter - * list represented - * by the given descriptor. - * - * @param type the type of the inserted parameter. - * @param descriptor the descriptor of the method. - */ - public static String insertParameter(CtClass type, - String descriptor) { - if (descriptor.charAt(0) != '(') - return descriptor; - else - return "(" + of(type) + descriptor.substring(1); - } - - /** - * Changes the return type included in the given descriptor. - * - *

classname must not be an array type. - * - * @param classname return type - * @param desc descriptor - */ - public static String changeReturnType(String classname, String desc) { - int i = desc.indexOf(')'); - if (i < 0) - return desc; - else { - StringBuffer newdesc = new StringBuffer(); - newdesc.append(desc.substring(0, i + 1)); - newdesc.append('L'); - newdesc.append(classname.replace('.', '/')); - newdesc.append(';'); - return newdesc.toString(); - } - } - - /** - * Returns the CtClass objects representing the parameter - * types specified by the given descriptor. - * - * @param desc descriptor - * @param cp the class pool used for obtaining - * a CtClass object. - */ - public static CtClass[] getParameterTypes(String desc, ClassPool cp) - throws NotFoundException - { - if (desc.charAt(0) != '(') - return null; - else { - int num = numOfParameters(desc); - CtClass[] args = new CtClass[num]; - int n = 0; - int i = 1; - do { - i = toCtClass(cp, desc, i, args, n++); - } while (i > 0); - return args; - } - } - - /** - * Returns true if the list of the parameter types of desc1 is equal to - * that of desc2. - * For example, "(II)V" and "(II)I" are equal. - */ - public static boolean eqParamTypes(String desc1, String desc2) { - if (desc1.charAt(0) != '(') - return false; - - for (int i = 0; true; ++i) { - char c = desc1.charAt(i); - if (c != desc2.charAt(i)) - return false; - - if (c == ')') - return true; - } - } - - /** - * Returns the signature of the given descriptor. The signature does - * not include the return type. For example, the signature of "(I)V" - * is "(I)". - */ - public static String getParamDescriptor(String decl) { - return decl.substring(0, decl.indexOf(')') + 1); - } - - /** - * Returns the CtClass object representing the return - * type specified by the given descriptor. - * - * @param desc descriptor - * @param cp the class pool used for obtaining - * a CtClass object. - */ - public static CtClass getReturnType(String desc, ClassPool cp) - throws NotFoundException - { - int i = desc.indexOf(')'); - if (i < 0) - return null; - else { - CtClass[] type = new CtClass[1]; - toCtClass(cp, desc, i + 1, type, 0); - return type[0]; - } - } - - /** - * Returns the number of the prameters included in the given - * descriptor. - * - * @param desc descriptor - */ - public static int numOfParameters(String desc) { - int n = 0; - int i = 1; - for (;;) { - char c = desc.charAt(i); - if (c == ')') - break; - - while (c == '[') - c = desc.charAt(++i); - - if (c == 'L') { - i = desc.indexOf(';', i) + 1; - if (i <= 0) - throw new IndexOutOfBoundsException("bad descriptor"); - } - else - ++i; - - ++n; - } - - return n; - } - - /** - * Returns a CtClass object representing the type - * specified by the given descriptor. - * - *

This method works even if the package-class separator is - * not / but . (period). For example, - * it accepts Ljava.lang.Object; - * as well as Ljava/lang/Object;. - * - * @param desc descriptor. - * @param cp the class pool used for obtaining - * a CtClass object. - */ - public static CtClass toCtClass(String desc, ClassPool cp) - throws NotFoundException - { - CtClass[] clazz = new CtClass[1]; - int res = toCtClass(cp, desc, 0, clazz, 0); - if (res >= 0) - return clazz[0]; - else { - // maybe, you forgot to surround the class name with - // L and ;. It violates the protocol, but I'm tolerant... - return cp.get(desc.replace('/', '.')); - } - } - - private static int toCtClass(ClassPool cp, String desc, int i, - CtClass[] args, int n) - throws NotFoundException - { - int i2; - String name; - - int arrayDim = 0; - char c = desc.charAt(i); - while (c == '[') { - ++arrayDim; - c = desc.charAt(++i); - } - - if (c == 'L') { - i2 = desc.indexOf(';', ++i); - name = desc.substring(i, i2++).replace('/', '.'); - } - else { - CtClass type = toPrimitiveClass(c); - if (type == null) - return -1; // error - - i2 = i + 1; - if (arrayDim == 0) { - args[n] = type; - return i2; // neither an array type or a class type - } - else - name = type.getName(); - } - - if (arrayDim > 0) { - StringBuffer sbuf = new StringBuffer(name); - while (arrayDim-- > 0) - sbuf.append("[]"); - - name = sbuf.toString(); - } - - args[n] = cp.get(name); - return i2; - } - - static CtClass toPrimitiveClass(char c) { - CtClass type = null; - switch (c) { - case 'Z' : - type = CtClass.booleanType; - break; - case 'C' : - type = CtClass.charType; - break; - case 'B' : - type = CtClass.byteType; - break; - case 'S' : - type = CtClass.shortType; - break; - case 'I' : - type = CtClass.intType; - break; - case 'J' : - type = CtClass.longType; - break; - case 'F' : - type = CtClass.floatType; - break; - case 'D' : - type = CtClass.doubleType; - break; - case 'V' : - type = CtClass.voidType; - break; - } - - return type; - } - - /** - * Computes the dimension of the array represented by the given - * descriptor. For example, if the descriptor is "[[I", - * then this method returns 2. - * - * @param desc the descriptor. - * @return 0 if the descriptor does not represent an array type. - */ - public static int arrayDimension(String desc) { - int dim = 0; - while (desc.charAt(dim) == '[') - ++dim; - - return dim; - } - - /** - * Returns the descriptor of the type of the array component. - * For example, if the given descriptor is - * "[[Ljava/lang/String;" and the given dimension is 2, - * then this method returns "Ljava/lang/String;". - * - * @param desc the descriptor. - * @param dim the array dimension. - */ - public static String toArrayComponent(String desc, int dim) { - return desc.substring(dim); - } - - /** - * Computes the data size specified by the given descriptor. - * For example, if the descriptor is "D", this method returns 2. - * - *

If the descriptor represents a method type, this method returns - * (the size of the returned value) - (the sum of the data sizes - * of all the parameters). For example, if the descriptor is - * "(I)D", then this method returns 1 (= 2 - 1). - * - * @param desc descriptor - */ - public static int dataSize(String desc) { - return dataSize(desc, true); - } - - /** - * Computes the data size of parameters. - * If one of the parameters is double type, the size of that parameter - * is 2 words. For example, if the given descriptor is - * "(IJ)D", then this method returns 3. The size of the - * return type is not computed. - * - * @param desc a method descriptor. - */ - public static int paramSize(String desc) { - return -dataSize(desc, false); - } - - private static int dataSize(String desc, boolean withRet) { - int n = 0; - char c = desc.charAt(0); - if (c == '(') { - int i = 1; - for (;;) { - c = desc.charAt(i); - if (c == ')') { - c = desc.charAt(i + 1); - break; - } - - boolean array = false; - while (c == '[') { - array = true; - c = desc.charAt(++i); - } - - if (c == 'L') { - i = desc.indexOf(';', i) + 1; - if (i <= 0) - throw new IndexOutOfBoundsException("bad descriptor"); - } - else - ++i; - - if (!array && (c == 'J' || c == 'D')) - n -= 2; - else - --n; - } - } - - if (withRet) - if (c == 'J' || c == 'D') - n += 2; - else if (c != 'V') - ++n; - - return n; - } - - /** - * Returns a human-readable representation of the - * given descriptor. For example, Ljava/lang/Object; - * is converted into java.lang.Object. - * (I[I)V is converted into (int, int[]) - * (the return type is ignored). - */ - public static String toString(String desc) { - return PrettyPrinter.toString(desc); - } - - static class PrettyPrinter { - static String toString(String desc) { - StringBuffer sbuf = new StringBuffer(); - if (desc.charAt(0) == '(') { - int pos = 1; - sbuf.append('('); - while (desc.charAt(pos) != ')') { - if (pos > 1) - sbuf.append(','); - - pos = readType(sbuf, pos, desc); - } - - sbuf.append(')'); - } - else - readType(sbuf, 0, desc); - - return sbuf.toString(); - } - - static int readType(StringBuffer sbuf, int pos, String desc) { - char c = desc.charAt(pos); - int arrayDim = 0; - while (c == '[') { - arrayDim++; - c = desc.charAt(++pos); - } - - if (c == 'L') - while (true) { - c = desc.charAt(++pos); - if (c == ';') - break; - - if (c == '/') - c = '.'; - - sbuf.append(c); - } - else { - CtClass t = toPrimitiveClass(c); - sbuf.append(t.getName()); - } - - while (arrayDim-- > 0) - sbuf.append("[]"); - - return pos + 1; - } - } - - /** - * An Iterator over a descriptor. - */ - public static class Iterator { - private String desc; - private int index, curPos; - private boolean param; - - /** - * Constructs an iterator. - * - * @param s descriptor. - */ - public Iterator(String s) { - desc = s; - index = curPos = 0; - param = false; - } - - /** - * Returns true if the iteration has more elements. - */ - public boolean hasNext() { - return index < desc.length(); - } - - /** - * Returns true if the current element is a parameter type. - */ - public boolean isParameter() { return param; } - - /** - * Returns the first character of the current element. - */ - public char currentChar() { return desc.charAt(curPos); } - - /** - * Returns true if the current element is double or long type. - */ - public boolean is2byte() { - char c = currentChar(); - return c == 'D' || c == 'J'; - } - - /** - * Returns the position of the next type character. - * That type character becomes a new current element. - */ - public int next() { - int nextPos = index; - char c = desc.charAt(nextPos); - if (c == '(') { - ++index; - c = desc.charAt(++nextPos); - param = true; - } - - if (c == ')') { - ++index; - c = desc.charAt(++nextPos); - param = false; - } - - while (c == '[') - c = desc.charAt(++nextPos); - - if (c == 'L') { - nextPos = desc.indexOf(';', nextPos) + 1; - if (nextPos <= 0) - throw new IndexOutOfBoundsException("bad descriptor"); - } - else - ++nextPos; - - curPos = index; - index = nextPos; - return curPos; - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/DuplicateMemberException.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/DuplicateMemberException.java deleted file mode 100644 index b4225d8ec..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/DuplicateMemberException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import com.fr.third.javassist.CannotCompileException; - -/** - * An exception thrown when adding a duplicate member is requested. - * - * @see com.fr.third.javassist.bytecode.ClassFile#addMethod(MethodInfo) - * @see ClassFile#addField(FieldInfo) - */ -public class DuplicateMemberException extends CannotCompileException { - public DuplicateMemberException(String msg) { - super(msg); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/EnclosingMethodAttribute.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/EnclosingMethodAttribute.java deleted file mode 100644 index 89b66bbdf..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/EnclosingMethodAttribute.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.IOException; -import java.util.Map; - -/** - * EnclosingMethod_attribute. - */ -public class EnclosingMethodAttribute extends com.fr.third.javassist.bytecode.AttributeInfo { - /** - * The name of this attribute "EnclosingMethod". - */ - public static final String tag = "EnclosingMethod"; - - EnclosingMethodAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int n, DataInputStream in) - throws IOException - { - super(cp, n, in); - } - - /** - * Constructs an EnclosingMethod attribute. - * - * @param cp a constant pool table. - * @param className the name of the innermost enclosing class. - * @param methodName the name of the enclosing method. - * @param methodDesc the descriptor of the enclosing method. - */ - public EnclosingMethodAttribute(com.fr.third.javassist.bytecode.ConstPool cp, String className, - String methodName, String methodDesc) { - super(cp, tag); - int ci = cp.addClassInfo(className); - int ni = cp.addNameAndTypeInfo(methodName, methodDesc); - byte[] bvalue = new byte[4]; - bvalue[0] = (byte)(ci >>> 8); - bvalue[1] = (byte)ci; - bvalue[2] = (byte)(ni >>> 8); - bvalue[3] = (byte)ni; - set(bvalue); - } - - /** - * Constructs an EnclosingMethod attribute. - * The value of method_index is set to 0. - * - * @param cp a constant pool table. - * @param className the name of the innermost enclosing class. - */ - public EnclosingMethodAttribute(com.fr.third.javassist.bytecode.ConstPool cp, String className) { - super(cp, tag); - int ci = cp.addClassInfo(className); - int ni = 0; - byte[] bvalue = new byte[4]; - bvalue[0] = (byte)(ci >>> 8); - bvalue[1] = (byte)ci; - bvalue[2] = (byte)(ni >>> 8); - bvalue[3] = (byte)ni; - set(bvalue); - } - - /** - * Returns the value of class_index. - */ - public int classIndex() { - return com.fr.third.javassist.bytecode.ByteArray.readU16bit(get(), 0); - } - - /** - * Returns the value of method_index. - */ - public int methodIndex() { - return ByteArray.readU16bit(get(), 2); - } - - /** - * Returns the name of the class specified by class_index. - */ - public String className() { - return getConstPool().getClassInfo(classIndex()); - } - - /** - * Returns the method name specified by method_index. - */ - public String methodName() { - com.fr.third.javassist.bytecode.ConstPool cp = getConstPool(); - int mi = methodIndex(); - int ni = cp.getNameAndTypeName(mi); - return cp.getUtf8Info(ni); - } - - /** - * Returns the method descriptor specified by method_index. - */ - public String methodDescriptor() { - com.fr.third.javassist.bytecode.ConstPool cp = getConstPool(); - int mi = methodIndex(); - int ti = cp.getNameAndTypeDescriptor(mi); - return cp.getUtf8Info(ti); - } - - /** - * Makes a copy. Class names are replaced according to the - * given Map object. - * - * @param newCp the constant pool table used by the new copy. - * @param classnames pairs of replaced and substituted - * class names. - */ - public AttributeInfo copy(ConstPool newCp, Map classnames) { - if (methodIndex() == 0) - return new EnclosingMethodAttribute(newCp, className()); - else - return new EnclosingMethodAttribute(newCp, className(), - methodName(), methodDescriptor()); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ExceptionTable.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ExceptionTable.java deleted file mode 100644 index dd29f4ff3..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ExceptionTable.java +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Map; - -class ExceptionTableEntry { - int startPc; - int endPc; - int handlerPc; - int catchType; - - ExceptionTableEntry(int start, int end, int handle, int type) { - startPc = start; - endPc = end; - handlerPc = handle; - catchType = type; - } -} - -/** - * exception_table[] of Code_attribute. - */ -public class ExceptionTable implements Cloneable { - private com.fr.third.javassist.bytecode.ConstPool constPool; - private ArrayList entries; - - /** - * Constructs an exception_table[]. - * - * @param cp constant pool table. - */ - public ExceptionTable(com.fr.third.javassist.bytecode.ConstPool cp) { - constPool = cp; - entries = new ArrayList(); - } - - ExceptionTable(com.fr.third.javassist.bytecode.ConstPool cp, DataInputStream in) throws IOException { - constPool = cp; - int length = in.readUnsignedShort(); - ArrayList list = new ArrayList(length); - for (int i = 0; i < length; ++i) { - int start = in.readUnsignedShort(); - int end = in.readUnsignedShort(); - int handle = in.readUnsignedShort(); - int type = in.readUnsignedShort(); - list.add(new ExceptionTableEntry(start, end, handle, type)); - } - - entries = list; - } - - /** - * Creates and returns a copy of this object. - * The constant pool object is shared between this object - * and the cloned object. - */ - public Object clone() throws CloneNotSupportedException { - ExceptionTable r = (ExceptionTable)super.clone(); - r.entries = new ArrayList(entries); - return r; - } - - /** - * Returns exception_table_length, which is the number - * of entries in the exception_table[]. - */ - public int size() { - return entries.size(); - } - - /** - * Returns startPc of the n-th entry. - * - * @param nth the n-th (>= 0). - */ - public int startPc(int nth) { - ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth); - return e.startPc; - } - - /** - * Sets startPc of the n-th entry. - * - * @param nth the n-th (>= 0). - * @param value new value. - */ - public void setStartPc(int nth, int value) { - ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth); - e.startPc = value; - } - - /** - * Returns endPc of the n-th entry. - * - * @param nth the n-th (>= 0). - */ - public int endPc(int nth) { - ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth); - return e.endPc; - } - - /** - * Sets endPc of the n-th entry. - * - * @param nth the n-th (>= 0). - * @param value new value. - */ - public void setEndPc(int nth, int value) { - ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth); - e.endPc = value; - } - - /** - * Returns handlerPc of the n-th entry. - * - * @param nth the n-th (>= 0). - */ - public int handlerPc(int nth) { - ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth); - return e.handlerPc; - } - - /** - * Sets handlerPc of the n-th entry. - * - * @param nth the n-th (>= 0). - * @param value new value. - */ - public void setHandlerPc(int nth, int value) { - ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth); - e.handlerPc = value; - } - - /** - * Returns catchType of the n-th entry. - * - * @param nth the n-th (>= 0). - * @return an index into the constant_pool table, - * or zero if this exception handler is for all exceptions. - */ - public int catchType(int nth) { - ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth); - return e.catchType; - } - - /** - * Sets catchType of the n-th entry. - * - * @param nth the n-th (>= 0). - * @param value new value. - */ - public void setCatchType(int nth, int value) { - ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth); - e.catchType = value; - } - - /** - * Copies the given exception table at the specified position - * in the table. - * - * @param index index (>= 0) at which the entry is to be inserted. - * @param offset the offset added to the code position. - */ - public void add(int index, ExceptionTable table, int offset) { - int len = table.size(); - while (--len >= 0) { - ExceptionTableEntry e - = (ExceptionTableEntry)table.entries.get(len); - add(index, e.startPc + offset, e.endPc + offset, - e.handlerPc + offset, e.catchType); - } - } - - /** - * Adds a new entry at the specified position in the table. - * - * @param index index (>= 0) at which the entry is to be inserted. - * @param start startPc - * @param end endPc - * @param handler handlerPc - * @param type catchType - */ - public void add(int index, int start, int end, int handler, int type) { - if (start < end) - entries.add(index, - new ExceptionTableEntry(start, end, handler, type)); - } - - /** - * Appends a new entry at the end of the table. - * - * @param start startPc - * @param end endPc - * @param handler handlerPc - * @param type catchType - */ - public void add(int start, int end, int handler, int type) { - if (start < end) - entries.add(new ExceptionTableEntry(start, end, handler, type)); - } - - /** - * Removes the entry at the specified position in the table. - * - * @param index the index of the removed entry. - */ - public void remove(int index) { - entries.remove(index); - } - - /** - * Makes a copy of this exception_table[]. - * Class names are replaced according to the - * given Map object. - * - * @param newCp the constant pool table used by the new copy. - * @param classnames pairs of replaced and substituted - * class names. - */ - public ExceptionTable copy(com.fr.third.javassist.bytecode.ConstPool newCp, Map classnames) { - ExceptionTable et = new ExceptionTable(newCp); - ConstPool srcCp = constPool; - int len = size(); - for (int i = 0; i < len; ++i) { - ExceptionTableEntry e = (ExceptionTableEntry)entries.get(i); - int type = srcCp.copy(e.catchType, newCp, classnames); - et.add(e.startPc, e.endPc, e.handlerPc, type); - } - - return et; - } - - void shiftPc(int where, int gapLength, boolean exclusive) { - int len = size(); - for (int i = 0; i < len; ++i) { - ExceptionTableEntry e = (ExceptionTableEntry)entries.get(i); - e.startPc = shiftPc(e.startPc, where, gapLength, exclusive); - e.endPc = shiftPc(e.endPc, where, gapLength, exclusive); - e.handlerPc = shiftPc(e.handlerPc, where, gapLength, exclusive); - } - } - - private static int shiftPc(int pc, int where, int gapLength, - boolean exclusive) { - if (pc > where || (exclusive && pc == where)) - pc += gapLength; - - return pc; - } - - void write(DataOutputStream out) throws IOException { - int len = size(); - out.writeShort(len); // exception_table_length - for (int i = 0; i < len; ++i) { - ExceptionTableEntry e = (ExceptionTableEntry)entries.get(i); - out.writeShort(e.startPc); - out.writeShort(e.endPc); - out.writeShort(e.handlerPc); - out.writeShort(e.catchType); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ExceptionsAttribute.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ExceptionsAttribute.java deleted file mode 100644 index a7a8fc78a..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ExceptionsAttribute.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.IOException; -import java.util.Map; - -/** - * Exceptions_attribute. - */ -public class ExceptionsAttribute extends com.fr.third.javassist.bytecode.AttributeInfo { - /** - * The name of this attribute "Exceptions". - */ - public static final String tag = "Exceptions"; - - ExceptionsAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int n, DataInputStream in) - throws IOException - { - super(cp, n, in); - } - - /** - * Constructs a copy of an exceptions attribute. - * - * @param cp constant pool table. - * @param src source attribute. - */ - private ExceptionsAttribute(com.fr.third.javassist.bytecode.ConstPool cp, ExceptionsAttribute src, - Map classnames) { - super(cp, tag); - copyFrom(src, classnames); - } - - /** - * Constructs a new exceptions attribute. - * - * @param cp constant pool table. - */ - public ExceptionsAttribute(com.fr.third.javassist.bytecode.ConstPool cp) { - super(cp, tag); - byte[] data = new byte[2]; - data[0] = data[1] = 0; // empty - this.info = data; - } - - /** - * Makes a copy. Class names are replaced according to the - * given Map object. - * - * @param newCp the constant pool table used by the new copy. - * @param classnames pairs of replaced and substituted - * class names. It can be null. - */ - public AttributeInfo copy(com.fr.third.javassist.bytecode.ConstPool newCp, Map classnames) { - return new ExceptionsAttribute(newCp, this, classnames); - } - - /** - * Copies the contents from a source attribute. - * Specified class names are replaced during the copy. - * - * @param srcAttr source Exceptions attribute - * @param classnames pairs of replaced and substituted - * class names. - */ - private void copyFrom(ExceptionsAttribute srcAttr, Map classnames) { - com.fr.third.javassist.bytecode.ConstPool srcCp = srcAttr.constPool; - ConstPool destCp = this.constPool; - byte[] src = srcAttr.info; - int num = src.length; - byte[] dest = new byte[num]; - dest[0] = src[0]; - dest[1] = src[1]; // the number of elements. - for (int i = 2; i < num; i += 2) { - int index = com.fr.third.javassist.bytecode.ByteArray.readU16bit(src, i); - com.fr.third.javassist.bytecode.ByteArray.write16bit(srcCp.copy(index, destCp, classnames), - dest, i); - } - - this.info = dest; - } - - /** - * Returns exception_index_table[]. - */ - public int[] getExceptionIndexes() { - byte[] blist = info; - int n = blist.length; - if (n <= 2) - return null; - - int[] elist = new int[n / 2 - 1]; - int k = 0; - for (int j = 2; j < n; j += 2) - elist[k++] = ((blist[j] & 0xff) << 8) | (blist[j + 1] & 0xff); - - return elist; - } - - /** - * Returns the names of exceptions that the method may throw. - */ - public String[] getExceptions() { - byte[] blist = info; - int n = blist.length; - if (n <= 2) - return null; - - String[] elist = new String[n / 2 - 1]; - int k = 0; - for (int j = 2; j < n; j += 2) { - int index = ((blist[j] & 0xff) << 8) | (blist[j + 1] & 0xff); - elist[k++] = constPool.getClassInfo(index); - } - - return elist; - } - - /** - * Sets exception_index_table[]. - */ - public void setExceptionIndexes(int[] elist) { - int n = elist.length; - byte[] blist = new byte[n * 2 + 2]; - com.fr.third.javassist.bytecode.ByteArray.write16bit(n, blist, 0); - for (int i = 0; i < n; ++i) - com.fr.third.javassist.bytecode.ByteArray.write16bit(elist[i], blist, i * 2 + 2); - - info = blist; - } - - /** - * Sets the names of exceptions that the method may throw. - */ - public void setExceptions(String[] elist) { - int n = elist.length; - byte[] blist = new byte[n * 2 + 2]; - com.fr.third.javassist.bytecode.ByteArray.write16bit(n, blist, 0); - for (int i = 0; i < n; ++i) - ByteArray.write16bit(constPool.addClassInfo(elist[i]), - blist, i * 2 + 2); - - info = blist; - } - - /** - * Returns number_of_exceptions. - */ - public int tableLength() { return info.length / 2 - 1; } - - /** - * Returns the value of exception_index_table[nth]. - */ - public int getException(int nth) { - int index = nth * 2 + 2; // nth >= 0 - return ((info[index] & 0xff) << 8) | (info[index + 1] & 0xff); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/FieldInfo.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/FieldInfo.java deleted file mode 100644 index ee86d17f2..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/FieldInfo.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import com.fr.third.javassist.CtField; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.List; -import java.util.ArrayList; - -/** - * field_info structure. - * - * @see CtField#getFieldInfo() - */ -public final class FieldInfo { - com.fr.third.javassist.bytecode.ConstPool constPool; - int accessFlags; - int name; - String cachedName; - String cachedType; - int descriptor; - ArrayList attribute; // may be null. - - private FieldInfo(com.fr.third.javassist.bytecode.ConstPool cp) { - constPool = cp; - accessFlags = 0; - attribute = null; - } - - /** - * Constructs a field_info structure. - * - * @param cp a constant pool table - * @param fieldName field name - * @param desc field descriptor - * - * @see Descriptor - */ - public FieldInfo(com.fr.third.javassist.bytecode.ConstPool cp, String fieldName, String desc) { - this(cp); - name = cp.addUtf8Info(fieldName); - cachedName = fieldName; - descriptor = cp.addUtf8Info(desc); - } - - FieldInfo(com.fr.third.javassist.bytecode.ConstPool cp, DataInputStream in) throws IOException { - this(cp); - read(in); - } - - /** - * Returns a string representation of the object. - */ - public String toString() { - return getName() + " " + getDescriptor(); - } - - /** - * Copies all constant pool items to a given new constant pool - * and replaces the original items with the new ones. - * This is used for garbage collecting the items of removed fields - * and methods. - * - * @param cp the destination - */ - void compact(com.fr.third.javassist.bytecode.ConstPool cp) { - name = cp.addUtf8Info(getName()); - descriptor = cp.addUtf8Info(getDescriptor()); - attribute = AttributeInfo.copyAll(attribute, cp); - constPool = cp; - } - - void prune(com.fr.third.javassist.bytecode.ConstPool cp) { - ArrayList newAttributes = new ArrayList(); - AttributeInfo invisibleAnnotations - = getAttribute(AnnotationsAttribute.invisibleTag); - if (invisibleAnnotations != null) { - invisibleAnnotations = invisibleAnnotations.copy(cp, null); - newAttributes.add(invisibleAnnotations); - } - - AttributeInfo visibleAnnotations - = getAttribute(AnnotationsAttribute.visibleTag); - if (visibleAnnotations != null) { - visibleAnnotations = visibleAnnotations.copy(cp, null); - newAttributes.add(visibleAnnotations); - } - - AttributeInfo signature - = getAttribute(SignatureAttribute.tag); - if (signature != null) { - signature = signature.copy(cp, null); - newAttributes.add(signature); - } - - int index = getConstantValue(); - if (index != 0) { - index = constPool.copy(index, cp, null); - newAttributes.add(new ConstantAttribute(cp, index)); - } - - attribute = newAttributes; - name = cp.addUtf8Info(getName()); - descriptor = cp.addUtf8Info(getDescriptor()); - constPool = cp; - } - - /** - * Returns the constant pool table used - * by this field_info. - */ - public ConstPool getConstPool() { - return constPool; - } - - /** - * Returns the field name. - */ - public String getName() { - if (cachedName == null) - cachedName = constPool.getUtf8Info(name); - - return cachedName; - } - - /** - * Sets the field name. - */ - public void setName(String newName) { - name = constPool.addUtf8Info(newName); - cachedName = newName; - } - - /** - * Returns the access flags. - * - * @see AccessFlag - */ - public int getAccessFlags() { - return accessFlags; - } - - /** - * Sets the access flags. - * - * @see AccessFlag - */ - public void setAccessFlags(int acc) { - accessFlags = acc; - } - - /** - * Returns the field descriptor. - * - * @see Descriptor - */ - public String getDescriptor() { - return constPool.getUtf8Info(descriptor); - } - - /** - * Sets the field descriptor. - * - * @see Descriptor - */ - public void setDescriptor(String desc) { - if (!desc.equals(getDescriptor())) - descriptor = constPool.addUtf8Info(desc); - } - - /** - * Finds a ConstantValue attribute and returns the index into - * the constant_pool table. - * - * @return 0 if a ConstantValue attribute is not found. - */ - public int getConstantValue() { - if ((accessFlags & AccessFlag.STATIC) == 0) - return 0; - - ConstantAttribute attr - = (ConstantAttribute)getAttribute(ConstantAttribute.tag); - if (attr == null) - return 0; - else - return attr.getConstantValue(); - } - - /** - * Returns all the attributes. The returned List object - * is shared with this object. If you add a new attribute to the list, - * the attribute is also added to the field represented by this - * object. If you remove an attribute from the list, it is also removed - * from the field. - * - * @return a list of AttributeInfo objects. - * @see AttributeInfo - */ - public List getAttributes() { - if (attribute == null) - attribute = new ArrayList(); - - return attribute; - } - - /** - * Returns the attribute with the specified name. - * It returns null if the specified attribute is not found. - * - * @param name attribute name - * @see #getAttributes() - */ - public AttributeInfo getAttribute(String name) { - return AttributeInfo.lookup(attribute, name); - } - - /** - * Appends an attribute. If there is already an attribute with - * the same name, the new one substitutes for it. - * - * @see #getAttributes() - */ - public void addAttribute(AttributeInfo info) { - if (attribute == null) - attribute = new ArrayList(); - - AttributeInfo.remove(attribute, info.getName()); - attribute.add(info); - } - - private void read(DataInputStream in) throws IOException { - accessFlags = in.readUnsignedShort(); - name = in.readUnsignedShort(); - descriptor = in.readUnsignedShort(); - int n = in.readUnsignedShort(); - attribute = new ArrayList(); - for (int i = 0; i < n; ++i) - attribute.add(AttributeInfo.read(constPool, in)); - } - - void write(DataOutputStream out) throws IOException { - out.writeShort(accessFlags); - out.writeShort(name); - out.writeShort(descriptor); - if (attribute == null) - out.writeShort(0); - else { - out.writeShort(attribute.size()); - AttributeInfo.writeAll(attribute, out); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/InnerClassesAttribute.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/InnerClassesAttribute.java deleted file mode 100644 index d174e206c..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/InnerClassesAttribute.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.util.Map; -import java.io.IOException; - -/** - * InnerClasses_attribute. - */ -public class InnerClassesAttribute extends com.fr.third.javassist.bytecode.AttributeInfo { - /** - * The name of this attribute "InnerClasses". - */ - public static final String tag = "InnerClasses"; - - InnerClassesAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int n, DataInputStream in) - throws IOException - { - super(cp, n, in); - } - - private InnerClassesAttribute(com.fr.third.javassist.bytecode.ConstPool cp, byte[] info) { - super(cp, tag, info); - } - - /** - * Constructs an empty InnerClasses attribute. - * - * @see #append(String, String, String, int) - */ - public InnerClassesAttribute(com.fr.third.javassist.bytecode.ConstPool cp) { - super(cp, tag, new byte[2]); - com.fr.third.javassist.bytecode.ByteArray.write16bit(0, get(), 0); - } - - /** - * Returns number_of_classes. - */ - public int tableLength() { return com.fr.third.javassist.bytecode.ByteArray.readU16bit(get(), 0); } - - /** - * Returns classes[nth].inner_class_info_index. - */ - public int innerClassIndex(int nth) { - return com.fr.third.javassist.bytecode.ByteArray.readU16bit(get(), nth * 8 + 2); - } - - /** - * Returns the class name indicated - * by classes[nth].inner_class_info_index. - * - * @return null or the class name. - */ - public String innerClass(int nth) { - int i = innerClassIndex(nth); - if (i == 0) - return null; - else - return constPool.getClassInfo(i); - } - - /** - * Sets classes[nth].inner_class_info_index to - * the given index. - */ - public void setInnerClassIndex(int nth, int index) { - com.fr.third.javassist.bytecode.ByteArray.write16bit(index, get(), nth * 8 + 2); - } - - /** - * Returns classes[nth].outer_class_info_index. - */ - public int outerClassIndex(int nth) { - return com.fr.third.javassist.bytecode.ByteArray.readU16bit(get(), nth * 8 + 4); - } - - /** - * Returns the class name indicated - * by classes[nth].outer_class_info_index. - * - * @return null or the class name. - */ - public String outerClass(int nth) { - int i = outerClassIndex(nth); - if (i == 0) - return null; - else - return constPool.getClassInfo(i); - } - - /** - * Sets classes[nth].outer_class_info_index to - * the given index. - */ - public void setOuterClassIndex(int nth, int index) { - com.fr.third.javassist.bytecode.ByteArray.write16bit(index, get(), nth * 8 + 4); - } - - /** - * Returns classes[nth].inner_name_index. - */ - public int innerNameIndex(int nth) { - return com.fr.third.javassist.bytecode.ByteArray.readU16bit(get(), nth * 8 + 6); - } - - /** - * Returns the simple class name indicated - * by classes[nth].inner_name_index. - * - * @return null or the class name. - */ - public String innerName(int nth) { - int i = innerNameIndex(nth); - if (i == 0) - return null; - else - return constPool.getUtf8Info(i); - } - - /** - * Sets classes[nth].inner_name_index to - * the given index. - */ - public void setInnerNameIndex(int nth, int index) { - com.fr.third.javassist.bytecode.ByteArray.write16bit(index, get(), nth * 8 + 6); - } - - /** - * Returns classes[nth].inner_class_access_flags. - */ - public int accessFlags(int nth) { - return com.fr.third.javassist.bytecode.ByteArray.readU16bit(get(), nth * 8 + 8); - } - - /** - * Sets classes[nth].inner_class_access_flags to - * the given index. - */ - public void setAccessFlags(int nth, int flags) { - com.fr.third.javassist.bytecode.ByteArray.write16bit(flags, get(), nth * 8 + 8); - } - - /** - * Appends a new entry. - * - * @param inner inner_class_info_index - * @param outer outer_class_info_index - * @param name inner_name_index - * @param flags inner_class_access_flags - */ - public void append(String inner, String outer, String name, int flags) { - int i = constPool.addClassInfo(inner); - int o = constPool.addClassInfo(outer); - int n = constPool.addUtf8Info(name); - append(i, o, n, flags); - } - - /** - * Appends a new entry. - * - * @param inner inner_class_info_index - * @param outer outer_class_info_index - * @param name inner_name_index - * @param flags inner_class_access_flags - */ - public void append(int inner, int outer, int name, int flags) { - byte[] data = get(); - int len = data.length; - byte[] newData = new byte[len + 8]; - for (int i = 2; i < len; ++i) - newData[i] = data[i]; - - int n = com.fr.third.javassist.bytecode.ByteArray.readU16bit(data, 0); - com.fr.third.javassist.bytecode.ByteArray.write16bit(n + 1, newData, 0); - - com.fr.third.javassist.bytecode.ByteArray.write16bit(inner, newData, len); - com.fr.third.javassist.bytecode.ByteArray.write16bit(outer, newData, len + 2); - com.fr.third.javassist.bytecode.ByteArray.write16bit(name, newData, len + 4); - com.fr.third.javassist.bytecode.ByteArray.write16bit(flags, newData, len + 6); - - set(newData); - } - - /** - * Makes a copy. Class names are replaced according to the - * given Map object. - * - * @param newCp the constant pool table used by the new copy. - * @param classnames pairs of replaced and substituted - * class names. - */ - public AttributeInfo copy(com.fr.third.javassist.bytecode.ConstPool newCp, Map classnames) { - byte[] src = get(); - byte[] dest = new byte[src.length]; - ConstPool cp = getConstPool(); - InnerClassesAttribute attr = new InnerClassesAttribute(newCp, dest); - int n = com.fr.third.javassist.bytecode.ByteArray.readU16bit(src, 0); - com.fr.third.javassist.bytecode.ByteArray.write16bit(n, dest, 0); - int j = 2; - for (int i = 0; i < n; ++i) { - int innerClass = com.fr.third.javassist.bytecode.ByteArray.readU16bit(src, j); - int outerClass = com.fr.third.javassist.bytecode.ByteArray.readU16bit(src, j + 2); - int innerName = com.fr.third.javassist.bytecode.ByteArray.readU16bit(src, j + 4); - int innerAccess = com.fr.third.javassist.bytecode.ByteArray.readU16bit(src, j + 6); - - if (innerClass != 0) - innerClass = cp.copy(innerClass, newCp, classnames); - - com.fr.third.javassist.bytecode.ByteArray.write16bit(innerClass, dest, j); - - if (outerClass != 0) - outerClass = cp.copy(outerClass, newCp, classnames); - - com.fr.third.javassist.bytecode.ByteArray.write16bit(outerClass, dest, j + 2); - - if (innerName != 0) - innerName = cp.copy(innerName, newCp, classnames); - - com.fr.third.javassist.bytecode.ByteArray.write16bit(innerName, dest, j + 4); - ByteArray.write16bit(innerAccess, dest, j + 6); - j += 8; - } - - return attr; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/InstructionPrinter.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/InstructionPrinter.java deleted file mode 100644 index 07cc146ee..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/InstructionPrinter.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.bytecode; - -import java.io.PrintStream; - -import com.fr.third.javassist.CtMethod; - -/** - * Simple utility class for printing the bytecode instructions of a method. - * - * @author Jason T. Greene - */ -public class InstructionPrinter implements Opcode { - - private final static String opcodes[] = Mnemonic.OPCODE; - private final PrintStream stream; - - /** - * Constructs a InstructionPrinter object. - */ - public InstructionPrinter(PrintStream stream) { - this.stream = stream; - } - - /** - * Prints the bytecode instructions of a given method. - */ - public static void print(CtMethod method, PrintStream stream) { - (new InstructionPrinter(stream)).print(method); - } - - /** - * Prints the bytecode instructions of a given method. - */ - public void print(CtMethod method) { - MethodInfo info = method.getMethodInfo2(); - com.fr.third.javassist.bytecode.ConstPool pool = info.getConstPool(); - CodeAttribute code = info.getCodeAttribute(); - if (code == null) - return; - - com.fr.third.javassist.bytecode.CodeIterator iterator = code.iterator(); - while (iterator.hasNext()) { - int pos; - try { - pos = iterator.next(); - } catch (BadBytecode e) { - throw new RuntimeException(e); - } - - stream.println(pos + ": " + instructionString(iterator, pos, pool)); - } - } - - /** - * Gets a string representation of the bytecode instruction at the specified - * position. - */ - public static String instructionString(com.fr.third.javassist.bytecode.CodeIterator iter, int pos, com.fr.third.javassist.bytecode.ConstPool pool) { - int opcode = iter.byteAt(pos); - - if (opcode > opcodes.length || opcode < 0) - throw new IllegalArgumentException("Invalid opcode, opcode: " + opcode + " pos: "+ pos); - - String opstring = opcodes[opcode]; - switch (opcode) { - case BIPUSH: - return opstring + " " + iter.byteAt(pos + 1); - case SIPUSH: - return opstring + " " + iter.s16bitAt(pos + 1); - case LDC: - return opstring + " " + ldc(pool, iter.byteAt(pos + 1)); - case LDC_W : - case LDC2_W : - return opstring + " " + ldc(pool, iter.u16bitAt(pos + 1)); - case ILOAD: - case LLOAD: - case FLOAD: - case DLOAD: - case ALOAD: - case ISTORE: - case LSTORE: - case FSTORE: - case DSTORE: - case ASTORE: - return opstring + " " + iter.byteAt(pos + 1); - case IFEQ: - case IFGE: - case IFGT: - case IFLE: - case IFLT: - case IFNE: - case IFNONNULL: - case IFNULL: - case IF_ACMPEQ: - case IF_ACMPNE: - case IF_ICMPEQ: - case IF_ICMPGE: - case IF_ICMPGT: - case IF_ICMPLE: - case IF_ICMPLT: - case IF_ICMPNE: - return opstring + " " + (iter.s16bitAt(pos + 1) + pos); - case IINC: - return opstring + " " + iter.byteAt(pos + 1); - case GOTO: - case JSR: - return opstring + " " + (iter.s16bitAt(pos + 1) + pos); - case RET: - return opstring + " " + iter.byteAt(pos + 1); - case TABLESWITCH: - return tableSwitch(iter, pos); - case LOOKUPSWITCH: - return lookupSwitch(iter, pos); - case GETSTATIC: - case PUTSTATIC: - case GETFIELD: - case PUTFIELD: - return opstring + " " + fieldInfo(pool, iter.u16bitAt(pos + 1)); - case INVOKEVIRTUAL: - case INVOKESPECIAL: - case INVOKESTATIC: - return opstring + " " + methodInfo(pool, iter.u16bitAt(pos + 1)); - case INVOKEINTERFACE: - return opstring + " " + interfaceMethodInfo(pool, iter.u16bitAt(pos + 1)); - case INVOKEDYNAMIC: - return opstring + " " + iter.u16bitAt(pos + 1); - case NEW: - return opstring + " " + classInfo(pool, iter.u16bitAt(pos + 1)); - case NEWARRAY: - return opstring + " " + arrayInfo(iter.byteAt(pos + 1)); - case ANEWARRAY: - case CHECKCAST: - return opstring + " " + classInfo(pool, iter.u16bitAt(pos + 1)); - case WIDE: - return wide(iter, pos); - case MULTIANEWARRAY: - return opstring + " " + classInfo(pool, iter.u16bitAt(pos + 1)); - case GOTO_W: - case JSR_W: - return opstring + " " + (iter.s32bitAt(pos + 1)+ pos); - default: - return opstring; - } - } - - - private static String wide(com.fr.third.javassist.bytecode.CodeIterator iter, int pos) { - int opcode = iter.byteAt(pos + 1); - int index = iter.u16bitAt(pos + 2); - switch (opcode) { - case ILOAD: - case LLOAD: - case FLOAD: - case DLOAD: - case ALOAD: - case ISTORE: - case LSTORE: - case FSTORE: - case DSTORE: - case ASTORE: - case IINC: - case RET: - return opcodes[opcode] + " " + index; - default: - throw new RuntimeException("Invalid WIDE operand"); - } - } - - - private static String arrayInfo(int type) { - switch (type) { - case T_BOOLEAN: - return "boolean"; - case T_CHAR: - return "char"; - case T_BYTE: - return "byte"; - case T_SHORT: - return "short"; - case T_INT: - return "int"; - case T_LONG: - return "long"; - case T_FLOAT: - return "float"; - case T_DOUBLE: - return "double"; - default: - throw new RuntimeException("Invalid array type"); - } - } - - - private static String classInfo(com.fr.third.javassist.bytecode.ConstPool pool, int index) { - return "#" + index + " = Class " + pool.getClassInfo(index); - } - - - private static String interfaceMethodInfo(com.fr.third.javassist.bytecode.ConstPool pool, int index) { - return "#" + index + " = Method " - + pool.getInterfaceMethodrefClassName(index) + "." - + pool.getInterfaceMethodrefName(index) + "(" - + pool.getInterfaceMethodrefType(index) + ")"; - } - - private static String methodInfo(com.fr.third.javassist.bytecode.ConstPool pool, int index) { - return "#" + index + " = Method " - + pool.getMethodrefClassName(index) + "." - + pool.getMethodrefName(index) + "(" - + pool.getMethodrefType(index) + ")"; - } - - - private static String fieldInfo(com.fr.third.javassist.bytecode.ConstPool pool, int index) { - return "#" + index + " = Field " - + pool.getFieldrefClassName(index) + "." - + pool.getFieldrefName(index) + "(" - + pool.getFieldrefType(index) + ")"; - } - - - private static String lookupSwitch(com.fr.third.javassist.bytecode.CodeIterator iter, int pos) { - StringBuffer buffer = new StringBuffer("lookupswitch {\n"); - int index = (pos & ~3) + 4; - // default - buffer.append("\t\tdefault: ").append(pos + iter.s32bitAt(index)).append("\n"); - int npairs = iter.s32bitAt(index += 4); - int end = npairs * 8 + (index += 4); - - for (; index < end; index += 8) { - int match = iter.s32bitAt(index); - int target = iter.s32bitAt(index + 4) + pos; - buffer.append("\t\t").append(match).append(": ").append(target).append("\n"); - } - - buffer.setCharAt(buffer.length() - 1, '}'); - return buffer.toString(); - } - - - private static String tableSwitch(CodeIterator iter, int pos) { - StringBuffer buffer = new StringBuffer("tableswitch {\n"); - int index = (pos & ~3) + 4; - // default - buffer.append("\t\tdefault: ").append(pos + iter.s32bitAt(index)).append("\n"); - int low = iter.s32bitAt(index += 4); - int high = iter.s32bitAt(index += 4); - int end = (high - low + 1) * 4 + (index += 4); - - // Offset table - for (int key = low; index < end; index += 4, key++) { - int target = iter.s32bitAt(index) + pos; - buffer.append("\t\t").append(key).append(": ").append(target).append("\n"); - } - - buffer.setCharAt(buffer.length() - 1, '}'); - return buffer.toString(); - } - - - private static String ldc(com.fr.third.javassist.bytecode.ConstPool pool, int index) { - int tag = pool.getTag(index); - switch (tag) { - case com.fr.third.javassist.bytecode.ConstPool.CONST_String: - return "#" + index + " = \"" + pool.getStringInfo(index) + "\""; - case com.fr.third.javassist.bytecode.ConstPool.CONST_Integer: - return "#" + index + " = int " + pool.getIntegerInfo(index); - case com.fr.third.javassist.bytecode.ConstPool.CONST_Float: - return "#" + index + " = float " + pool.getFloatInfo(index); - case com.fr.third.javassist.bytecode.ConstPool.CONST_Long: - return "#" + index + " = long " + pool.getLongInfo(index); - case com.fr.third.javassist.bytecode.ConstPool.CONST_Double: - return "#" + index + " = int " + pool.getDoubleInfo(index); - case ConstPool.CONST_Class: - return classInfo(pool, index); - default: - throw new RuntimeException("bad LDC: " + tag); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/LineNumberAttribute.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/LineNumberAttribute.java deleted file mode 100644 index 3cc24bd3c..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/LineNumberAttribute.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.IOException; -import java.util.Map; - -/** - * LineNumberTable_attribute. - */ -public class LineNumberAttribute extends com.fr.third.javassist.bytecode.AttributeInfo { - /** - * The name of this attribute "LineNumberTable". - */ - public static final String tag = "LineNumberTable"; - - LineNumberAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int n, DataInputStream in) - throws IOException - { - super(cp, n, in); - } - - private LineNumberAttribute(com.fr.third.javassist.bytecode.ConstPool cp, byte[] i) { - super(cp, tag, i); - } - - /** - * Returns line_number_table_length. - * This represents the number of entries in the table. - */ - public int tableLength() { - return com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, 0); - } - - /** - * Returns line_number_table[i].start_pc. - * This represents the index into the code array at which the code - * for a new line in the original source file begins. - * - * @param i the i-th entry. - */ - public int startPc(int i) { - return com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, i * 4 + 2); - } - - /** - * Returns line_number_table[i].line_number. - * This represents the corresponding line number in the original - * source file. - * - * @param i the i-th entry. - */ - public int lineNumber(int i) { - return com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, i * 4 + 4); - } - - /** - * Returns the line number corresponding to the specified bytecode. - * - * @param pc the index into the code array. - */ - public int toLineNumber(int pc) { - int n = tableLength(); - int i = 0; - for (; i < n; ++i) - if (pc < startPc(i)) - if (i == 0) - return lineNumber(0); - else - break; - - return lineNumber(i - 1); - } - - /** - * Returns the index into the code array at which the code for - * the specified line begins. - * - * @param line the line number. - * @return -1 if the specified line is not found. - */ - public int toStartPc(int line) { - int n = tableLength(); - for (int i = 0; i < n; ++i) - if (line == lineNumber(i)) - return startPc(i); - - return -1; - } - - /** - * Used as a return type of toNearPc(). - */ - static public class Pc { - /** - * The index into the code array. - */ - public int index; - /** - * The line number. - */ - public int line; - } - - /** - * Returns the index into the code array at which the code for - * the specified line (or the nearest line after the specified one) - * begins. - * - * @param line the line number. - * @return a pair of the index and the line number of the - * bytecode at that index. - */ - public Pc toNearPc(int line) { - int n = tableLength(); - int nearPc = 0; - int distance = 0; - if (n > 0) { - distance = lineNumber(0) - line; - nearPc = startPc(0); - } - - for (int i = 1; i < n; ++i) { - int d = lineNumber(i) - line; - if ((d < 0 && d > distance) - || (d >= 0 && (d < distance || distance < 0))) { - distance = d; - nearPc = startPc(i); - } - } - - Pc res = new Pc(); - res.index = nearPc; - res.line = line + distance; - return res; - } - - /** - * Makes a copy. - * - * @param newCp the constant pool table used by the new copy. - * @param classnames should be null. - */ - public AttributeInfo copy(ConstPool newCp, Map classnames) { - byte[] src = info; - int num = src.length; - byte[] dest = new byte[num]; - for (int i = 0; i < num; ++i) - dest[i] = src[i]; - - LineNumberAttribute attr = new LineNumberAttribute(newCp, dest); - return attr; - } - - /** - * Adjusts start_pc if bytecode is inserted in a method body. - */ - void shiftPc(int where, int gapLength, boolean exclusive) { - int n = tableLength(); - for (int i = 0; i < n; ++i) { - int pos = i * 4 + 2; - int pc = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos); - if (pc > where || (exclusive && pc == where)) - ByteArray.write16bit(pc + gapLength, info, pos); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/LocalVariableAttribute.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/LocalVariableAttribute.java deleted file mode 100644 index cccbebfb1..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/LocalVariableAttribute.java +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.IOException; -import java.util.Map; - -/** - * LocalVariableTable_attribute. - */ -public class LocalVariableAttribute extends com.fr.third.javassist.bytecode.AttributeInfo { - /** - * The name of this attribute "LocalVariableTable". - */ - public static final String tag = "LocalVariableTable"; - - /** - * The name of the attribute "LocalVariableTypeTable". - */ - public static final String typeTag = "LocalVariableTypeTable"; - - /** - * Constructs an empty LocalVariableTable. - */ - public LocalVariableAttribute(com.fr.third.javassist.bytecode.ConstPool cp) { - super(cp, tag, new byte[2]); - com.fr.third.javassist.bytecode.ByteArray.write16bit(0, info, 0); - } - - /** - * Constructs an empty LocalVariableTable. - * - * @param name the attribute name. - * LocalVariableAttribute.tag or - * LocalVariableAttribute.typeTag. - * @see #tag - * @see #typeTag - * @since 3.1 - * @deprecated - */ - public LocalVariableAttribute(com.fr.third.javassist.bytecode.ConstPool cp, String name) { - super(cp, name, new byte[2]); - com.fr.third.javassist.bytecode.ByteArray.write16bit(0, info, 0); - } - - LocalVariableAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int n, DataInputStream in) - throws IOException - { - super(cp, n, in); - } - - LocalVariableAttribute(com.fr.third.javassist.bytecode.ConstPool cp, String name, byte[] i) { - super(cp, name, i); - } - - /** - * Appends a new entry to local_variable_table. - * - * @param startPc start_pc - * @param length length - * @param nameIndex name_index - * @param descriptorIndex descriptor_index - * @param index index - */ - public void addEntry(int startPc, int length, int nameIndex, - int descriptorIndex, int index) { - int size = info.length; - byte[] newInfo = new byte[size + 10]; - com.fr.third.javassist.bytecode.ByteArray.write16bit(tableLength() + 1, newInfo, 0); - for (int i = 2; i < size; ++i) - newInfo[i] = info[i]; - - com.fr.third.javassist.bytecode.ByteArray.write16bit(startPc, newInfo, size); - com.fr.third.javassist.bytecode.ByteArray.write16bit(length, newInfo, size + 2); - com.fr.third.javassist.bytecode.ByteArray.write16bit(nameIndex, newInfo, size + 4); - com.fr.third.javassist.bytecode.ByteArray.write16bit(descriptorIndex, newInfo, size + 6); - com.fr.third.javassist.bytecode.ByteArray.write16bit(index, newInfo, size + 8); - info = newInfo; - } - - void renameClass(String oldname, String newname) { - com.fr.third.javassist.bytecode.ConstPool cp = getConstPool(); - int n = tableLength(); - for (int i = 0; i < n; ++i) { - int pos = i * 10 + 2; - int index = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos + 6); - if (index != 0) { - String desc = cp.getUtf8Info(index); - desc = renameEntry(desc, oldname, newname); - com.fr.third.javassist.bytecode.ByteArray.write16bit(cp.addUtf8Info(desc), info, pos + 6); - } - } - } - - String renameEntry(String desc, String oldname, String newname) { - return com.fr.third.javassist.bytecode.Descriptor.rename(desc, oldname, newname); - } - - void renameClass(Map classnames) { - com.fr.third.javassist.bytecode.ConstPool cp = getConstPool(); - int n = tableLength(); - for (int i = 0; i < n; ++i) { - int pos = i * 10 + 2; - int index = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos + 6); - if (index != 0) { - String desc = cp.getUtf8Info(index); - desc = renameEntry(desc, classnames); - com.fr.third.javassist.bytecode.ByteArray.write16bit(cp.addUtf8Info(desc), info, pos + 6); - } - } - } - - String renameEntry(String desc, Map classnames) { - return com.fr.third.javassist.bytecode.Descriptor.rename(desc, classnames); - } - - /** - * For each local_variable_table[i].index, - * this method increases index by delta. - * - * @param lessThan the index does not change if it - * is less than this value. - */ - public void shiftIndex(int lessThan, int delta) { - int size = info.length; - for (int i = 2; i < size; i += 10){ - int org = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, i + 8); - if (org >= lessThan) - com.fr.third.javassist.bytecode.ByteArray.write16bit(org + delta, info, i + 8); - } - } - - /** - * Returns local_variable_table_length. - * This represents the number of entries in the table. - */ - public int tableLength() { - return com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, 0); - } - - /** - * Returns local_variable_table[i].start_pc. - * This represents the index into the code array from which the local - * variable is effective. - * - * @param i the i-th entry. - */ - public int startPc(int i) { - return com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, i * 10 + 2); - } - - /** - * Returns local_variable_table[i].length. - * This represents the length of the code region in which the local - * variable is effective. - * - * @param i the i-th entry. - */ - public int codeLength(int i) { - return com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, i * 10 + 4); - } - - /** - * Adjusts start_pc and length if bytecode is inserted in a method body. - */ - void shiftPc(int where, int gapLength, boolean exclusive) { - int n = tableLength(); - for (int i = 0; i < n; ++i) { - int pos = i * 10 + 2; - int pc = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos); - int len = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos + 2); - - /* if pc == 0, then the local variable is a method parameter. - */ - if (pc > where || (exclusive && pc == where && pc != 0)) - com.fr.third.javassist.bytecode.ByteArray.write16bit(pc + gapLength, info, pos); - else if (pc + len > where || (exclusive && pc + len == where)) - com.fr.third.javassist.bytecode.ByteArray.write16bit(len + gapLength, info, pos + 2); - } - } - - /** - * Returns the value of local_variable_table[i].name_index. - * This represents the name of the local variable. - * - * @param i the i-th entry. - */ - public int nameIndex(int i) { - return com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, i * 10 + 6); - } - - /** - * Returns the name of the local variable - * specified by local_variable_table[i].name_index. - * - * @param i the i-th entry. - */ - public String variableName(int i) { - return getConstPool().getUtf8Info(nameIndex(i)); - } - - /** - * Returns the value of - * local_variable_table[i].descriptor_index. - * This represents the type descriptor of the local variable. - *

- * If this attribute represents a LocalVariableTypeTable attribute, - * this method returns the value of - * local_variable_type_table[i].signature_index. - * It represents the type of the local variable. - * - * @param i the i-th entry. - */ - public int descriptorIndex(int i) { - return com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, i * 10 + 8); - } - - /** - * This method is equivalent to descriptorIndex(). - * If this attribute represents a LocalVariableTypeTable attribute, - * this method should be used instead of descriptorIndex() - * since the method name is more appropriate. - * - * @param i the i-th entry. - * @see #descriptorIndex(int) - * @see com.fr.third.javassist.bytecode.SignatureAttribute#toFieldSignature(String) - */ - public int signatureIndex(int i) { - return descriptorIndex(i); - } - - /** - * Returns the type descriptor of the local variable - * specified by local_variable_table[i].descriptor_index. - *

- * If this attribute represents a LocalVariableTypeTable attribute, - * this method returns the type signature of the local variable - * specified by local_variable_type_table[i].signature_index. - * - * @param i the i-th entry. - */ - public String descriptor(int i) { - return getConstPool().getUtf8Info(descriptorIndex(i)); - } - - /** - * This method is equivalent to descriptor(). - * If this attribute represents a LocalVariableTypeTable attribute, - * this method should be used instead of descriptor() - * since the method name is more appropriate. - * - *

To parse the string, call toFieldSignature(String) - * in SignatureAttribute. - * - * @param i the i-th entry. - * @see #descriptor(int) - * @see SignatureAttribute#toFieldSignature(String) - */ - public String signature(int i) { - return descriptor(i); - } - - /** - * Returns local_variable_table[i].index. - * This represents the index of the local variable. - * - * @param i the i-th entry. - */ - public int index(int i) { - return com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, i * 10 + 10); - } - - /** - * Makes a copy. - * - * @param newCp the constant pool table used by the new copy. - * @param classnames should be null. - */ - public AttributeInfo copy(com.fr.third.javassist.bytecode.ConstPool newCp, Map classnames) { - byte[] src = get(); - byte[] dest = new byte[src.length]; - com.fr.third.javassist.bytecode.ConstPool cp = getConstPool(); - LocalVariableAttribute attr = makeThisAttr(newCp, dest); - int n = com.fr.third.javassist.bytecode.ByteArray.readU16bit(src, 0); - com.fr.third.javassist.bytecode.ByteArray.write16bit(n, dest, 0); - int j = 2; - for (int i = 0; i < n; ++i) { - int start = com.fr.third.javassist.bytecode.ByteArray.readU16bit(src, j); - int len = com.fr.third.javassist.bytecode.ByteArray.readU16bit(src, j + 2); - int name = com.fr.third.javassist.bytecode.ByteArray.readU16bit(src, j + 4); - int type = com.fr.third.javassist.bytecode.ByteArray.readU16bit(src, j + 6); - int index = com.fr.third.javassist.bytecode.ByteArray.readU16bit(src, j + 8); - - com.fr.third.javassist.bytecode.ByteArray.write16bit(start, dest, j); - com.fr.third.javassist.bytecode.ByteArray.write16bit(len, dest, j + 2); - if (name != 0) - name = cp.copy(name, newCp, null); - - com.fr.third.javassist.bytecode.ByteArray.write16bit(name, dest, j + 4); - - if (type != 0) { - String sig = cp.getUtf8Info(type); - sig = Descriptor.rename(sig, classnames); - type = newCp.addUtf8Info(sig); - } - - com.fr.third.javassist.bytecode.ByteArray.write16bit(type, dest, j + 6); - ByteArray.write16bit(index, dest, j + 8); - j += 10; - } - - return attr; - } - - // LocalVariableTypeAttribute overrides this method. - LocalVariableAttribute makeThisAttr(ConstPool cp, byte[] dest) { - return new LocalVariableAttribute(cp, tag, dest); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/LocalVariableTypeAttribute.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/LocalVariableTypeAttribute.java deleted file mode 100644 index fdeb9f7c0..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/LocalVariableTypeAttribute.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.IOException; -import java.util.Map; - -/** - * LocalVariableTypeTable_attribute. - * - * @since 3.11 - */ -public class LocalVariableTypeAttribute extends com.fr.third.javassist.bytecode.LocalVariableAttribute { - /** - * The name of the attribute "LocalVariableTypeTable". - */ - public static final String tag = com.fr.third.javassist.bytecode.LocalVariableAttribute.typeTag; - - /** - * Constructs an empty LocalVariableTypeTable. - */ - public LocalVariableTypeAttribute(com.fr.third.javassist.bytecode.ConstPool cp) { - super(cp, tag, new byte[2]); - ByteArray.write16bit(0, info, 0); - } - - LocalVariableTypeAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int n, DataInputStream in) - throws IOException - { - super(cp, n, in); - } - - private LocalVariableTypeAttribute(com.fr.third.javassist.bytecode.ConstPool cp, byte[] dest) { - super(cp, tag, dest); - } - - String renameEntry(String desc, String oldname, String newname) { - return com.fr.third.javassist.bytecode.SignatureAttribute.renameClass(desc, oldname, newname); - } - - String renameEntry(String desc, Map classnames) { - return SignatureAttribute.renameClass(desc, classnames); - } - - LocalVariableAttribute makeThisAttr(ConstPool cp, byte[] dest) { - return new LocalVariableTypeAttribute(cp, dest); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/LongVector.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/LongVector.java deleted file mode 100644 index 2bf45f182..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/LongVector.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -final class LongVector { - static final int ASIZE = 128; - static final int ABITS = 7; // ASIZE = 2^ABITS - static final int VSIZE = 8; - private com.fr.third.javassist.bytecode.ConstInfo[][] objects; - private int elements; - - public LongVector() { - objects = new com.fr.third.javassist.bytecode.ConstInfo[VSIZE][]; - elements = 0; - } - - public LongVector(int initialSize) { - int vsize = ((initialSize >> ABITS) & ~(VSIZE - 1)) + VSIZE; - objects = new com.fr.third.javassist.bytecode.ConstInfo[vsize][]; - elements = 0; - } - - public int size() { return elements; } - - public int capacity() { return objects.length * ASIZE; } - - public com.fr.third.javassist.bytecode.ConstInfo elementAt(int i) { - if (i < 0 || elements <= i) - return null; - - return objects[i >> ABITS][i & (ASIZE - 1)]; - } - - public void addElement(com.fr.third.javassist.bytecode.ConstInfo value) { - int nth = elements >> ABITS; - int offset = elements & (ASIZE - 1); - int len = objects.length; - if (nth >= len) { - com.fr.third.javassist.bytecode.ConstInfo[][] newObj = new com.fr.third.javassist.bytecode.ConstInfo[len + VSIZE][]; - System.arraycopy(objects, 0, newObj, 0, len); - objects = newObj; - } - - if (objects[nth] == null) - objects[nth] = new com.fr.third.javassist.bytecode.ConstInfo[ASIZE]; - - objects[nth][offset] = value; - elements++; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/MethodInfo.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/MethodInfo.java deleted file mode 100644 index 7c723cedb..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/MethodInfo.java +++ /dev/null @@ -1,551 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.CtConstructor; -import com.fr.third.javassist.CtMethod; -import com.fr.third.javassist.bytecode.stackmap.MapMaker; - -/** - * method_info structure. - * - *

The bytecode sequence of the method is represented - * by a CodeAttribute object. - * - * @see #getCodeAttribute() - * @see CodeAttribute - * @see CtMethod#getMethodInfo() - * @see CtConstructor#getMethodInfo() - */ -public class MethodInfo { - com.fr.third.javassist.bytecode.ConstPool constPool; - int accessFlags; - int name; - String cachedName; - int descriptor; - ArrayList attribute; // may be null - - /** - * If this value is true, Javassist maintains a StackMap attribute - * generated by the preverify tool of J2ME (CLDC). The initial - * value of this field is false. - */ - public static boolean doPreverify = false; - - /** - * The name of constructors: <init>. - */ - public static final String nameInit = ""; - - /** - * The name of class initializer (static initializer): - * <clinit>. - */ - public static final String nameClinit = ""; - - private MethodInfo(com.fr.third.javassist.bytecode.ConstPool cp) { - constPool = cp; - attribute = null; - } - - /** - * Constructs a method_info structure. The initial value of - * access_flags is zero. - * - * @param cp - * a constant pool table - * @param methodname - * method name - * @param desc - * method descriptor - * @see com.fr.third.javassist.bytecode.Descriptor - */ - public MethodInfo(com.fr.third.javassist.bytecode.ConstPool cp, String methodname, String desc) { - this(cp); - accessFlags = 0; - name = cp.addUtf8Info(methodname); - cachedName = methodname; - descriptor = constPool.addUtf8Info(desc); - } - - MethodInfo(com.fr.third.javassist.bytecode.ConstPool cp, DataInputStream in) throws IOException { - this(cp); - read(in); - } - - /** - * Constructs a copy of method_info structure. Class names - * appearing in the source method_info are renamed according - * to classnameMap. - * - *

- * Note: only Code and Exceptions attributes - * are copied from the source. The other attributes are ignored. - * - * @param cp - * a constant pool table - * @param methodname - * a method name - * @param src - * a source method_info - * @param classnameMap - * specifies pairs of replaced and substituted name. - * @see com.fr.third.javassist.bytecode.Descriptor - */ - public MethodInfo(com.fr.third.javassist.bytecode.ConstPool cp, String methodname, MethodInfo src, - Map classnameMap) throws BadBytecode { - this(cp); - read(src, methodname, classnameMap); - } - - /** - * Returns a string representation of the object. - */ - public String toString() { - return getName() + " " + getDescriptor(); - } - - /** - * Copies all constant pool items to a given new constant pool - * and replaces the original items with the new ones. - * This is used for garbage collecting the items of removed fields - * and methods. - * - * @param cp the destination - */ - void compact(com.fr.third.javassist.bytecode.ConstPool cp) { - name = cp.addUtf8Info(getName()); - descriptor = cp.addUtf8Info(getDescriptor()); - attribute = AttributeInfo.copyAll(attribute, cp); - constPool = cp; - } - - void prune(com.fr.third.javassist.bytecode.ConstPool cp) { - ArrayList newAttributes = new ArrayList(); - - AttributeInfo invisibleAnnotations - = getAttribute(AnnotationsAttribute.invisibleTag); - if (invisibleAnnotations != null) { - invisibleAnnotations = invisibleAnnotations.copy(cp, null); - newAttributes.add(invisibleAnnotations); - } - - AttributeInfo visibleAnnotations - = getAttribute(AnnotationsAttribute.visibleTag); - if (visibleAnnotations != null) { - visibleAnnotations = visibleAnnotations.copy(cp, null); - newAttributes.add(visibleAnnotations); - } - - AttributeInfo parameterInvisibleAnnotations - = getAttribute(ParameterAnnotationsAttribute.invisibleTag); - if (parameterInvisibleAnnotations != null) { - parameterInvisibleAnnotations = parameterInvisibleAnnotations.copy(cp, null); - newAttributes.add(parameterInvisibleAnnotations); - } - - AttributeInfo parameterVisibleAnnotations - = getAttribute(ParameterAnnotationsAttribute.visibleTag); - if (parameterVisibleAnnotations != null) { - parameterVisibleAnnotations = parameterVisibleAnnotations.copy(cp, null); - newAttributes.add(parameterVisibleAnnotations); - } - - AnnotationDefaultAttribute defaultAttribute - = (AnnotationDefaultAttribute) getAttribute(AnnotationDefaultAttribute.tag); - if (defaultAttribute != null) - newAttributes.add(defaultAttribute); - - ExceptionsAttribute ea = getExceptionsAttribute(); - if (ea != null) - newAttributes.add(ea); - - AttributeInfo signature - = getAttribute(SignatureAttribute.tag); - if (signature != null) { - signature = signature.copy(cp, null); - newAttributes.add(signature); - } - - attribute = newAttributes; - name = cp.addUtf8Info(getName()); - descriptor = cp.addUtf8Info(getDescriptor()); - constPool = cp; - } - - /** - * Returns a method name. - */ - public String getName() { - if (cachedName == null) - cachedName = constPool.getUtf8Info(name); - - return cachedName; - } - - /** - * Sets a method name. - */ - public void setName(String newName) { - name = constPool.addUtf8Info(newName); - cachedName = newName; - } - - /** - * Returns true if this is not a constructor or a class initializer (static - * initializer). - */ - public boolean isMethod() { - String n = getName(); - return !n.equals(nameInit) && !n.equals(nameClinit); - } - - /** - * Returns a constant pool table used by this method. - */ - public com.fr.third.javassist.bytecode.ConstPool getConstPool() { - return constPool; - } - - /** - * Returns true if this is a constructor. - */ - public boolean isConstructor() { - return getName().equals(nameInit); - } - - /** - * Returns true if this is a class initializer (static initializer). - */ - public boolean isStaticInitializer() { - return getName().equals(nameClinit); - } - - /** - * Returns access flags. - * - * @see com.fr.third.javassist.bytecode.AccessFlag - */ - public int getAccessFlags() { - return accessFlags; - } - - /** - * Sets access flags. - * - * @see AccessFlag - */ - public void setAccessFlags(int acc) { - accessFlags = acc; - } - - /** - * Returns a method descriptor. - * - * @see com.fr.third.javassist.bytecode.Descriptor - */ - public String getDescriptor() { - return constPool.getUtf8Info(descriptor); - } - - /** - * Sets a method descriptor. - * - * @see com.fr.third.javassist.bytecode.Descriptor - */ - public void setDescriptor(String desc) { - if (!desc.equals(getDescriptor())) - descriptor = constPool.addUtf8Info(desc); - } - - /** - * Returns all the attributes. The returned List object - * is shared with this object. If you add a new attribute to the list, - * the attribute is also added to the method represented by this - * object. If you remove an attribute from the list, it is also removed - * from the method. - * - * @return a list of AttributeInfo objects. - * @see AttributeInfo - */ - public List getAttributes() { - if (attribute == null) - attribute = new ArrayList(); - - return attribute; - } - - /** - * Returns the attribute with the specified name. If it is not found, this - * method returns null. - * - * @param name attribute name - * @return an AttributeInfo object or null. - * @see #getAttributes() - */ - public AttributeInfo getAttribute(String name) { - return AttributeInfo.lookup(attribute, name); - } - - /** - * Appends an attribute. If there is already an attribute with the same - * name, the new one substitutes for it. - * - * @see #getAttributes() - */ - public void addAttribute(AttributeInfo info) { - if (attribute == null) - attribute = new ArrayList(); - - AttributeInfo.remove(attribute, info.getName()); - attribute.add(info); - } - - /** - * Returns an Exceptions attribute. - * - * @return an Exceptions attribute or null if it is not specified. - */ - public ExceptionsAttribute getExceptionsAttribute() { - AttributeInfo info = AttributeInfo.lookup(attribute, - ExceptionsAttribute.tag); - return (ExceptionsAttribute)info; - } - - /** - * Returns a Code attribute. - * - * @return a Code attribute or null if it is not specified. - */ - public CodeAttribute getCodeAttribute() { - AttributeInfo info = AttributeInfo.lookup(attribute, CodeAttribute.tag); - return (CodeAttribute)info; - } - - /** - * Removes an Exception attribute. - */ - public void removeExceptionsAttribute() { - AttributeInfo.remove(attribute, ExceptionsAttribute.tag); - } - - /** - * Adds an Exception attribute. - * - *

- * The added attribute must share the same constant pool table as this - * method_info structure. - */ - public void setExceptionsAttribute(ExceptionsAttribute cattr) { - removeExceptionsAttribute(); - if (attribute == null) - attribute = new ArrayList(); - - attribute.add(cattr); - } - - /** - * Removes a Code attribute. - */ - public void removeCodeAttribute() { - AttributeInfo.remove(attribute, CodeAttribute.tag); - } - - /** - * Adds a Code attribute. - * - *

- * The added attribute must share the same constant pool table as this - * method_info structure. - */ - public void setCodeAttribute(CodeAttribute cattr) { - removeCodeAttribute(); - if (attribute == null) - attribute = new ArrayList(); - - attribute.add(cattr); - } - - /** - * Rebuilds a stack map table if the class file is for Java 6 - * or later. Java 5 or older Java VMs do not recognize a stack - * map table. If doPreverify is true, this method - * also rebuilds a stack map for J2ME (CLDC). - * - * @param pool used for making type hierarchy. - * @param cf rebuild if this class file is for Java 6 or later. - * @see #rebuildStackMap(ClassPool) - * @see #rebuildStackMapForME(ClassPool) - * @see #doPreverify - * @since 3.6 - */ - public void rebuildStackMapIf6(ClassPool pool, com.fr.third.javassist.bytecode.ClassFile cf) - throws BadBytecode - { - if (cf.getMajorVersion() >= ClassFile.JAVA_6) - rebuildStackMap(pool); - - if (doPreverify) - rebuildStackMapForME(pool); - } - - /** - * Rebuilds a stack map table. If no stack map table is included, - * a new one is created. If this MethodInfo does not - * include a code attribute, nothing happens. - * - * @param pool used for making type hierarchy. - * @see StackMapTable - * @since 3.6 - */ - public void rebuildStackMap(ClassPool pool) throws BadBytecode { - CodeAttribute ca = getCodeAttribute(); - if (ca != null) { - StackMapTable smt = MapMaker.make(pool, this); - ca.setAttribute(smt); - } - } - - /** - * Rebuilds a stack map table for J2ME (CLDC). If no stack map table is included, - * a new one is created. If this MethodInfo does not - * include a code attribute, nothing happens. - * - * @param pool used for making type hierarchy. - * @see com.fr.third.javassist.bytecode.StackMap - * @since 3.12 - */ - public void rebuildStackMapForME(ClassPool pool) throws BadBytecode { - CodeAttribute ca = getCodeAttribute(); - if (ca != null) { - StackMap sm = MapMaker.make2(pool, this); - ca.setAttribute(sm); - } - } - - /** - * Returns the line number of the source line corresponding to the specified - * bytecode contained in this method. - * - * @param pos - * the position of the bytecode (>= 0). an index into the code - * array. - * @return -1 if this information is not available. - */ - public int getLineNumber(int pos) { - CodeAttribute ca = getCodeAttribute(); - if (ca == null) - return -1; - - LineNumberAttribute ainfo = (LineNumberAttribute)ca - .getAttribute(LineNumberAttribute.tag); - if (ainfo == null) - return -1; - - return ainfo.toLineNumber(pos); - } - - /** - * Changes a super constructor called by this constructor. - * - *

- * This method modifies a call to super(), which should be - * at the head of a constructor body, so that a constructor in a different - * super class is called. This method does not change actual parameters. - * Hence the new super class must have a constructor with the same signature - * as the original one. - * - *

- * This method should be called when the super class of the class declaring - * this method is changed. - * - *

- * This method does not perform anything unless this MethodInfo - * represents a constructor. - * - * @param superclass - * the new super class - */ - public void setSuperclass(String superclass) throws BadBytecode { - if (!isConstructor()) - return; - - CodeAttribute ca = getCodeAttribute(); - byte[] code = ca.getCode(); - CodeIterator iterator = ca.iterator(); - int pos = iterator.skipSuperConstructor(); - if (pos >= 0) { // not this() - com.fr.third.javassist.bytecode.ConstPool cp = constPool; - int mref = com.fr.third.javassist.bytecode.ByteArray.readU16bit(code, pos + 1); - int nt = cp.getMethodrefNameAndType(mref); - int sc = cp.addClassInfo(superclass); - int mref2 = cp.addMethodrefInfo(sc, nt); - ByteArray.write16bit(mref2, code, pos + 1); - } - } - - private void read(MethodInfo src, String methodname, Map classnames) - throws BadBytecode { - com.fr.third.javassist.bytecode.ConstPool destCp = constPool; - accessFlags = src.accessFlags; - name = destCp.addUtf8Info(methodname); - cachedName = methodname; - ConstPool srcCp = src.constPool; - String desc = srcCp.getUtf8Info(src.descriptor); - String desc2 = Descriptor.rename(desc, classnames); - descriptor = destCp.addUtf8Info(desc2); - - attribute = new ArrayList(); - ExceptionsAttribute eattr = src.getExceptionsAttribute(); - if (eattr != null) - attribute.add(eattr.copy(destCp, classnames)); - - CodeAttribute cattr = src.getCodeAttribute(); - if (cattr != null) - attribute.add(cattr.copy(destCp, classnames)); - } - - private void read(DataInputStream in) throws IOException { - accessFlags = in.readUnsignedShort(); - name = in.readUnsignedShort(); - descriptor = in.readUnsignedShort(); - int n = in.readUnsignedShort(); - attribute = new ArrayList(); - for (int i = 0; i < n; ++i) - attribute.add(AttributeInfo.read(constPool, in)); - } - - void write(DataOutputStream out) throws IOException { - out.writeShort(accessFlags); - out.writeShort(name); - out.writeShort(descriptor); - - if (attribute == null) - out.writeShort(0); - else { - out.writeShort(attribute.size()); - AttributeInfo.writeAll(attribute, out); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/Mnemonic.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/Mnemonic.java deleted file mode 100644 index 9356e15b7..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/Mnemonic.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -/** - * JVM Instruction Names. - * - *

This interface has been separated from javassist.bytecode.Opcode - * because typical bytecode translators do not use mnemonics. If this - * interface were merged with Opcode, extra memory would be unnecessary - * consumed. - * - * @see Opcode - */ -public interface Mnemonic { - - /** - * The instruction names (mnemonics) sorted by the opcode. - * The length of this array is 202 (jsr_w=201). - */ - String[] OPCODE = { - "nop", /* 0*/ - "aconst_null", /* 1*/ - "iconst_m1", /* 2*/ - "iconst_0", /* 3*/ - "iconst_1", /* 4*/ - "iconst_2", /* 5*/ - "iconst_3", /* 6*/ - "iconst_4", /* 7*/ - "iconst_5", /* 8*/ - "lconst_0", /* 9*/ - "lconst_1", /* 10*/ - "fconst_0", /* 11*/ - "fconst_1", /* 12*/ - "fconst_2", /* 13*/ - "dconst_0", /* 14*/ - "dconst_1", /* 15*/ - "bipush", /* 16*/ - "sipush", /* 17*/ - "ldc", /* 18*/ - "ldc_w", /* 19*/ - "ldc2_w", /* 20*/ - "iload", /* 21*/ - "lload", /* 22*/ - "fload", /* 23*/ - "dload", /* 24*/ - "aload", /* 25*/ - "iload_0", /* 26*/ - "iload_1", /* 27*/ - "iload_2", /* 28*/ - "iload_3", /* 29*/ - "lload_0", /* 30*/ - "lload_1", /* 31*/ - "lload_2", /* 32*/ - "lload_3", /* 33*/ - "fload_0", /* 34*/ - "fload_1", /* 35*/ - "fload_2", /* 36*/ - "fload_3", /* 37*/ - "dload_0", /* 38*/ - "dload_1", /* 39*/ - "dload_2", /* 40*/ - "dload_3", /* 41*/ - "aload_0", /* 42*/ - "aload_1", /* 43*/ - "aload_2", /* 44*/ - "aload_3", /* 45*/ - "iaload", /* 46*/ - "laload", /* 47*/ - "faload", /* 48*/ - "daload", /* 49*/ - "aaload", /* 50*/ - "baload", /* 51*/ - "caload", /* 52*/ - "saload", /* 53*/ - "istore", /* 54*/ - "lstore", /* 55*/ - "fstore", /* 56*/ - "dstore", /* 57*/ - "astore", /* 58*/ - "istore_0", /* 59*/ - "istore_1", /* 60*/ - "istore_2", /* 61*/ - "istore_3", /* 62*/ - "lstore_0", /* 63*/ - "lstore_1", /* 64*/ - "lstore_2", /* 65*/ - "lstore_3", /* 66*/ - "fstore_0", /* 67*/ - "fstore_1", /* 68*/ - "fstore_2", /* 69*/ - "fstore_3", /* 70*/ - "dstore_0", /* 71*/ - "dstore_1", /* 72*/ - "dstore_2", /* 73*/ - "dstore_3", /* 74*/ - "astore_0", /* 75*/ - "astore_1", /* 76*/ - "astore_2", /* 77*/ - "astore_3", /* 78*/ - "iastore", /* 79*/ - "lastore", /* 80*/ - "fastore", /* 81*/ - "dastore", /* 82*/ - "aastore", /* 83*/ - "bastore", /* 84*/ - "castore", /* 85*/ - "sastore", /* 86*/ - "pop", /* 87*/ - "pop2", /* 88*/ - "dup", /* 89*/ - "dup_x1", /* 90*/ - "dup_x2", /* 91*/ - "dup2", /* 92*/ - "dup2_x1", /* 93*/ - "dup2_x2", /* 94*/ - "swap", /* 95*/ - "iadd", /* 96*/ - "ladd", /* 97*/ - "fadd", /* 98*/ - "dadd", /* 99*/ - "isub", /* 100*/ - "lsub", /* 101*/ - "fsub", /* 102*/ - "dsub", /* 103*/ - "imul", /* 104*/ - "lmul", /* 105*/ - "fmul", /* 106*/ - "dmul", /* 107*/ - "idiv", /* 108*/ - "ldiv", /* 109*/ - "fdiv", /* 110*/ - "ddiv", /* 111*/ - "irem", /* 112*/ - "lrem", /* 113*/ - "frem", /* 114*/ - "drem", /* 115*/ - "ineg", /* 116*/ - "lneg", /* 117*/ - "fneg", /* 118*/ - "dneg", /* 119*/ - "ishl", /* 120*/ - "lshl", /* 121*/ - "ishr", /* 122*/ - "lshr", /* 123*/ - "iushr", /* 124*/ - "lushr", /* 125*/ - "iand", /* 126*/ - "land", /* 127*/ - "ior", /* 128*/ - "lor", /* 129*/ - "ixor", /* 130*/ - "lxor", /* 131*/ - "iinc", /* 132*/ - "i2l", /* 133*/ - "i2f", /* 134*/ - "i2d", /* 135*/ - "l2i", /* 136*/ - "l2f", /* 137*/ - "l2d", /* 138*/ - "f2i", /* 139*/ - "f2l", /* 140*/ - "f2d", /* 141*/ - "d2i", /* 142*/ - "d2l", /* 143*/ - "d2f", /* 144*/ - "i2b", /* 145*/ - "i2c", /* 146*/ - "i2s", /* 147*/ - "lcmp", /* 148*/ - "fcmpl", /* 149*/ - "fcmpg", /* 150*/ - "dcmpl", /* 151*/ - "dcmpg", /* 152*/ - "ifeq", /* 153*/ - "ifne", /* 154*/ - "iflt", /* 155*/ - "ifge", /* 156*/ - "ifgt", /* 157*/ - "ifle", /* 158*/ - "if_icmpeq", /* 159*/ - "if_icmpne", /* 160*/ - "if_icmplt", /* 161*/ - "if_icmpge", /* 162*/ - "if_icmpgt", /* 163*/ - "if_icmple", /* 164*/ - "if_acmpeq", /* 165*/ - "if_acmpne", /* 166*/ - "goto", /* 167*/ - "jsr", /* 168*/ - "ret", /* 169*/ - "tableswitch", /* 170*/ - "lookupswitch", /* 171*/ - "ireturn", /* 172*/ - "lreturn", /* 173*/ - "freturn", /* 174*/ - "dreturn", /* 175*/ - "areturn", /* 176*/ - "return", /* 177*/ - "getstatic", /* 178*/ - "putstatic", /* 179*/ - "getfield", /* 180*/ - "putfield", /* 181*/ - "invokevirtual", /* 182*/ - "invokespecial", /* 183*/ - "invokestatic", /* 184*/ - "invokeinterface", /* 185*/ - "invokedynamic", /* 186 */ - "new", /* 187*/ - "newarray", /* 188*/ - "anewarray", /* 189*/ - "arraylength", /* 190*/ - "athrow", /* 191*/ - "checkcast", /* 192*/ - "instanceof", /* 193*/ - "monitorenter", /* 194*/ - "monitorexit", /* 195*/ - "wide", /* 196*/ - "multianewarray", /* 197*/ - "ifnull", /* 198*/ - "ifnonnull", /* 199*/ - "goto_w", /* 200*/ - "jsr_w" /* 201*/ - }; -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/Opcode.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/Opcode.java deleted file mode 100644 index 058c79e70..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/Opcode.java +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -/** - * JVM Instruction Set. - * - *

This interface defines opcodes and - * array types for the NEWARRAY instruction. - * - * @see Mnemonic - */ -public interface Opcode { - /* Opcodes */ - - int AALOAD = 50; - int AASTORE = 83; - int ACONST_NULL = 1; - int ALOAD = 25; - int ALOAD_0 = 42; - int ALOAD_1 = 43; - int ALOAD_2 = 44; - int ALOAD_3 = 45; - int ANEWARRAY = 189; - int ARETURN = 176; - int ARRAYLENGTH = 190; - int ASTORE = 58; - int ASTORE_0 = 75; - int ASTORE_1 = 76; - int ASTORE_2 = 77; - int ASTORE_3 = 78; - int ATHROW = 191; - int BALOAD = 51; - int BASTORE = 84; - int BIPUSH = 16; - int CALOAD = 52; - int CASTORE = 85; - int CHECKCAST = 192; - int D2F = 144; - int D2I = 142; - int D2L = 143; - int DADD = 99; - int DALOAD = 49; - int DASTORE = 82; - int DCMPG = 152; - int DCMPL = 151; - int DCONST_0 = 14; - int DCONST_1 = 15; - int DDIV = 111; - int DLOAD = 24; - int DLOAD_0 = 38; - int DLOAD_1 = 39; - int DLOAD_2 = 40; - int DLOAD_3 = 41; - int DMUL = 107; - int DNEG = 119; - int DREM = 115; - int DRETURN = 175; - int DSTORE = 57; - int DSTORE_0 = 71; - int DSTORE_1 = 72; - int DSTORE_2 = 73; - int DSTORE_3 = 74; - int DSUB = 103; - int DUP = 89; - int DUP2 = 92; - int DUP2_X1 = 93; - int DUP2_X2 = 94; - int DUP_X1 = 90; - int DUP_X2 = 91; - int F2D = 141; - int F2I = 139; - int F2L = 140; - int FADD = 98; - int FALOAD = 48; - int FASTORE = 81; - int FCMPG = 150; - int FCMPL = 149; - int FCONST_0 = 11; - int FCONST_1 = 12; - int FCONST_2 = 13; - int FDIV = 110; - int FLOAD = 23; - int FLOAD_0 = 34; - int FLOAD_1 = 35; - int FLOAD_2 = 36; - int FLOAD_3 = 37; - int FMUL = 106; - int FNEG = 118; - int FREM = 114; - int FRETURN = 174; - int FSTORE = 56; - int FSTORE_0 = 67; - int FSTORE_1 = 68; - int FSTORE_2 = 69; - int FSTORE_3 = 70; - int FSUB = 102; - int GETFIELD = 180; - int GETSTATIC = 178; - int GOTO = 167; - int GOTO_W = 200; - int I2B = 145; - int I2C = 146; - int I2D = 135; - int I2F = 134; - int I2L = 133; - int I2S = 147; - int IADD = 96; - int IALOAD = 46; - int IAND = 126; - int IASTORE = 79; - 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 ICONST_M1 = 2; - int IDIV = 108; - int IFEQ = 153; - int IFGE = 156; - int IFGT = 157; - int IFLE = 158; - int IFLT = 155; - int IFNE = 154; - int IFNONNULL = 199; - int IFNULL = 198; - int IF_ACMPEQ = 165; - int IF_ACMPNE = 166; - int IF_ICMPEQ = 159; - int IF_ICMPGE = 162; - int IF_ICMPGT = 163; - int IF_ICMPLE = 164; - int IF_ICMPLT = 161; - int IF_ICMPNE = 160; - int IINC = 132; - int ILOAD = 21; - int ILOAD_0 = 26; - int ILOAD_1 = 27; - int ILOAD_2 = 28; - int ILOAD_3 = 29; - int IMUL = 104; - int INEG = 116; - int INSTANCEOF = 193; - int INVOKEDYNAMIC = 186; - int INVOKEINTERFACE = 185; - int INVOKESPECIAL = 183; - int INVOKESTATIC = 184; - int INVOKEVIRTUAL = 182; - int IOR = 128; - int IREM = 112; - int IRETURN = 172; - int ISHL = 120; - int ISHR = 122; - int ISTORE = 54; - int ISTORE_0 = 59; - int ISTORE_1 = 60; - int ISTORE_2 = 61; - int ISTORE_3 = 62; - int ISUB = 100; - int IUSHR = 124; - int IXOR = 130; - int JSR = 168; - int JSR_W = 201; - int L2D = 138; - int L2F = 137; - int L2I = 136; - int LADD = 97; - int LALOAD = 47; - int LAND = 127; - int LASTORE = 80; - int LCMP = 148; - int LCONST_0 = 9; - int LCONST_1 = 10; - int LDC = 18; - int LDC2_W = 20; - int LDC_W = 19; - int LDIV = 109; - int LLOAD = 22; - int LLOAD_0 = 30; - int LLOAD_1 = 31; - int LLOAD_2 = 32; - int LLOAD_3 = 33; - int LMUL = 105; - int LNEG = 117; - int LOOKUPSWITCH = 171; - int LOR = 129; - int LREM = 113; - int LRETURN = 173; - int LSHL = 121; - int LSHR = 123; - int LSTORE = 55; - int LSTORE_0 = 63; - int LSTORE_1 = 64; - int LSTORE_2 = 65; - int LSTORE_3 = 66; - int LSUB = 101; - int LUSHR = 125; - int LXOR = 131; - int MONITORENTER = 194; - int MONITOREXIT = 195; - int MULTIANEWARRAY = 197; - int NEW = 187; - int NEWARRAY = 188; - int NOP = 0; - int POP = 87; - int POP2 = 88; - int PUTFIELD = 181; - int PUTSTATIC = 179; - int RET = 169; - int RETURN = 177; - int SALOAD = 53; - int SASTORE = 86; - int SIPUSH = 17; - int SWAP = 95; - int TABLESWITCH = 170; - int WIDE = 196; - - /* array-type code for the newarray instruction */ - - 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; - - /* how many values are pushed on the operand stack. */ - int[] STACK_GROW = { - 0, // nop, 0 - 1, // aconst_null, 1 - 1, // iconst_m1, 2 - 1, // iconst_0, 3 - 1, // iconst_1, 4 - 1, // iconst_2, 5 - 1, // iconst_3, 6 - 1, // iconst_4, 7 - 1, // iconst_5, 8 - 2, // lconst_0, 9 - 2, // lconst_1, 10 - 1, // fconst_0, 11 - 1, // fconst_1, 12 - 1, // fconst_2, 13 - 2, // dconst_0, 14 - 2, // dconst_1, 15 - 1, // bipush, 16 - 1, // sipush, 17 - 1, // ldc, 18 - 1, // ldc_w, 19 - 2, // ldc2_w, 20 - 1, // iload, 21 - 2, // lload, 22 - 1, // fload, 23 - 2, // dload, 24 - 1, // aload, 25 - 1, // iload_0, 26 - 1, // iload_1, 27 - 1, // iload_2, 28 - 1, // iload_3, 29 - 2, // lload_0, 30 - 2, // lload_1, 31 - 2, // lload_2, 32 - 2, // lload_3, 33 - 1, // fload_0, 34 - 1, // fload_1, 35 - 1, // fload_2, 36 - 1, // fload_3, 37 - 2, // dload_0, 38 - 2, // dload_1, 39 - 2, // dload_2, 40 - 2, // dload_3, 41 - 1, // aload_0, 42 - 1, // aload_1, 43 - 1, // aload_2, 44 - 1, // aload_3, 45 - -1, // iaload, 46 - 0, // laload, 47 - -1, // faload, 48 - 0, // daload, 49 - -1, // aaload, 50 - -1, // baload, 51 - -1, // caload, 52 - -1, // saload, 53 - -1, // istore, 54 - -2, // lstore, 55 - -1, // fstore, 56 - -2, // dstore, 57 - -1, // astore, 58 - -1, // istore_0, 59 - -1, // istore_1, 60 - -1, // istore_2, 61 - -1, // istore_3, 62 - -2, // lstore_0, 63 - -2, // lstore_1, 64 - -2, // lstore_2, 65 - -2, // lstore_3, 66 - -1, // fstore_0, 67 - -1, // fstore_1, 68 - -1, // fstore_2, 69 - -1, // fstore_3, 70 - -2, // dstore_0, 71 - -2, // dstore_1, 72 - -2, // dstore_2, 73 - -2, // dstore_3, 74 - -1, // astore_0, 75 - -1, // astore_1, 76 - -1, // astore_2, 77 - -1, // astore_3, 78 - -3, // iastore, 79 - -4, // lastore, 80 - -3, // fastore, 81 - -4, // dastore, 82 - -3, // aastore, 83 - -3, // bastore, 84 - -3, // castore, 85 - -3, // sastore, 86 - -1, // pop, 87 - -2, // pop2, 88 - 1, // dup, 89 - 1, // dup_x1, 90 - 1, // dup_x2, 91 - 2, // dup2, 92 - 2, // dup2_x1, 93 - 2, // dup2_x2, 94 - 0, // swap, 95 - -1, // iadd, 96 - -2, // ladd, 97 - -1, // fadd, 98 - -2, // dadd, 99 - -1, // isub, 100 - -2, // lsub, 101 - -1, // fsub, 102 - -2, // dsub, 103 - -1, // imul, 104 - -2, // lmul, 105 - -1, // fmul, 106 - -2, // dmul, 107 - -1, // idiv, 108 - -2, // ldiv, 109 - -1, // fdiv, 110 - -2, // ddiv, 111 - -1, // irem, 112 - -2, // lrem, 113 - -1, // frem, 114 - -2, // drem, 115 - 0, // ineg, 116 - 0, // lneg, 117 - 0, // fneg, 118 - 0, // dneg, 119 - -1, // ishl, 120 - -1, // lshl, 121 - -1, // ishr, 122 - -1, // lshr, 123 - -1, // iushr, 124 - -1, // lushr, 125 - -1, // iand, 126 - -2, // land, 127 - -1, // ior, 128 - -2, // lor, 129 - -1, // ixor, 130 - -2, // lxor, 131 - 0, // iinc, 132 - 1, // i2l, 133 - 0, // i2f, 134 - 1, // i2d, 135 - -1, // l2i, 136 - -1, // l2f, 137 - 0, // l2d, 138 - 0, // f2i, 139 - 1, // f2l, 140 - 1, // f2d, 141 - -1, // d2i, 142 - 0, // d2l, 143 - -1, // d2f, 144 - 0, // i2b, 145 - 0, // i2c, 146 - 0, // i2s, 147 - -3, // lcmp, 148 - -1, // fcmpl, 149 - -1, // fcmpg, 150 - -3, // dcmpl, 151 - -3, // dcmpg, 152 - -1, // ifeq, 153 - -1, // ifne, 154 - -1, // iflt, 155 - -1, // ifge, 156 - -1, // ifgt, 157 - -1, // ifle, 158 - -2, // if_icmpeq, 159 - -2, // if_icmpne, 160 - -2, // if_icmplt, 161 - -2, // if_icmpge, 162 - -2, // if_icmpgt, 163 - -2, // if_icmple, 164 - -2, // if_acmpeq, 165 - -2, // if_acmpne, 166 - 0, // goto, 167 - 1, // jsr, 168 - 0, // ret, 169 - -1, // tableswitch, 170 - -1, // lookupswitch, 171 - -1, // ireturn, 172 - -2, // lreturn, 173 - -1, // freturn, 174 - -2, // dreturn, 175 - -1, // areturn, 176 - 0, // return, 177 - 0, // getstatic, 178 depends on the type - 0, // putstatic, 179 depends on the type - 0, // getfield, 180 depends on the type - 0, // putfield, 181 depends on the type - 0, // invokevirtual, 182 depends on the type - 0, // invokespecial, 183 depends on the type - 0, // invokestatic, 184 depends on the type - 0, // invokeinterface, 185 depends on the type - 0, // invokedynaimc, 186 depends on the type - 1, // new, 187 - 0, // newarray, 188 - 0, // anewarray, 189 - 0, // arraylength, 190 - -1, // athrow, 191 stack is cleared - 0, // checkcast, 192 - 0, // instanceof, 193 - -1, // monitorenter, 194 - -1, // monitorexit, 195 - 0, // wide, 196 depends on the following opcode - 0, // multianewarray, 197 depends on the dimensions - -1, // ifnull, 198 - -1, // ifnonnull, 199 - 0, // goto_w, 200 - 1 // jsr_w, 201 - }; -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ParameterAnnotationsAttribute.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ParameterAnnotationsAttribute.java deleted file mode 100644 index 5a98872e4..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/ParameterAnnotationsAttribute.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.util.HashMap; -import java.util.Map; -import java.io.IOException; -import java.io.DataInputStream; -import java.io.ByteArrayOutputStream; - -import com.fr.third.javassist.bytecode.annotation.Annotation; -import com.fr.third.javassist.bytecode.AnnotationsAttribute.Copier; -import com.fr.third.javassist.bytecode.AnnotationsAttribute.Parser; -import com.fr.third.javassist.bytecode.AnnotationsAttribute.Renamer; - -/** - * A class representing RuntimeVisibleAnnotations_attribute and - * RuntimeInvisibleAnnotations_attribute. - * - *

To obtain an ParameterAnnotationAttribute object, invoke - * getAttribute(ParameterAnnotationsAttribute.invisibleTag) - * in MethodInfo. - * The obtained attribute is a - * runtime invisible annotations attribute. - * If the parameter is - * ParameterAnnotationAttribute.visibleTag, then the obtained - * attribute is a runtime visible one. - */ -public class ParameterAnnotationsAttribute extends com.fr.third.javassist.bytecode.AttributeInfo { - /** - * The name of the RuntimeVisibleParameterAnnotations - * attribute. - */ - public static final String visibleTag - = "RuntimeVisibleParameterAnnotations"; - - /** - * The name of the RuntimeInvisibleParameterAnnotations - * attribute. - */ - public static final String invisibleTag - = "RuntimeInvisibleParameterAnnotations"; - /** - * Constructs - * a Runtime(In)VisibleParameterAnnotations_attribute. - * - * @param cp constant pool - * @param attrname attribute name (visibleTag or - * invisibleTag). - * @param info the contents of this attribute. It does not - * include attribute_name_index or - * attribute_length. - */ - public ParameterAnnotationsAttribute(com.fr.third.javassist.bytecode.ConstPool cp, String attrname, - byte[] info) { - super(cp, attrname, info); - } - - /** - * Constructs an empty - * Runtime(In)VisibleParameterAnnotations_attribute. - * A new annotation can be later added to the created attribute - * by setAnnotations(). - * - * @param cp constant pool - * @param attrname attribute name (visibleTag or - * invisibleTag). - * @see #setAnnotations(com.fr.third.javassist.bytecode.annotation.Annotation[][]) - */ - public ParameterAnnotationsAttribute(com.fr.third.javassist.bytecode.ConstPool cp, String attrname) { - this(cp, attrname, new byte[] { 0 }); - } - - /** - * @param n the attribute name. - */ - ParameterAnnotationsAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int n, DataInputStream in) - throws IOException - { - super(cp, n, in); - } - - /** - * Returns num_parameters. - */ - public int numParameters() { - return info[0] & 0xff; - } - - /** - * Copies this attribute and returns a new copy. - */ - public AttributeInfo copy(ConstPool newCp, Map classnames) { - Copier copier = new Copier(info, constPool, newCp, classnames); - try { - copier.parameters(); - return new ParameterAnnotationsAttribute(newCp, getName(), - copier.close()); - } - catch (Exception e) { - throw new RuntimeException(e.toString()); - } - } - - /** - * Parses the annotations and returns a data structure representing - * that parsed annotations. Note that changes of the node values of the - * returned tree are not reflected on the annotations represented by - * this object unless the tree is copied back to this object by - * setAnnotations(). - * - * @return Each element of the returned array represents an array of - * annotations that are associated with each method parameter. - * - * @see #setAnnotations(com.fr.third.javassist.bytecode.annotation.Annotation[][]) - */ - public com.fr.third.javassist.bytecode.annotation.Annotation[][] getAnnotations() { - try { - return new Parser(info, constPool).parseParameters(); - } - catch (Exception e) { - throw new RuntimeException(e.toString()); - } - } - - /** - * Changes the annotations represented by this object according to - * the given array of Annotation objects. - * - * @param params the data structure representing the - * new annotations. Every element of this array - * is an array of Annotation and - * it represens annotations of each method parameter. - */ - public void setAnnotations(com.fr.third.javassist.bytecode.annotation.Annotation[][] params) { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - com.fr.third.javassist.bytecode.annotation.AnnotationsWriter writer = new com.fr.third.javassist.bytecode.annotation.AnnotationsWriter(output, constPool); - try { - int n = params.length; - writer.numParameters(n); - for (int i = 0; i < n; ++i) { - com.fr.third.javassist.bytecode.annotation.Annotation[] anno = params[i]; - writer.numAnnotations(anno.length); - for (int j = 0; j < anno.length; ++j) - anno[j].write(writer); - } - - writer.close(); - } - catch (IOException e) { - throw new RuntimeException(e); // should never reach here. - } - - set(output.toByteArray()); - } - - /** - * @param oldname a JVM class name. - * @param newname a JVM class name. - */ - void renameClass(String oldname, String newname) { - HashMap map = new HashMap(); - map.put(oldname, newname); - renameClass(map); - } - - void renameClass(Map classnames) { - Renamer renamer = new Renamer(info, getConstPool(), classnames); - try { - renamer.parameters(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - void getRefClasses(Map classnames) { renameClass(classnames); } - - /** - * Returns a string representation of this object. - */ - public String toString() { - com.fr.third.javassist.bytecode.annotation.Annotation[][] aa = getAnnotations(); - StringBuilder sbuf = new StringBuilder(); - int k = 0; - while (k < aa.length) { - Annotation[] a = aa[k++]; - int i = 0; - while (i < a.length) { - sbuf.append(a[i++].toString()); - if (i != a.length) - sbuf.append(" "); - } - - if (k != aa.length) - sbuf.append(", "); - } - - return sbuf.toString(); - - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/SignatureAttribute.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/SignatureAttribute.java deleted file mode 100644 index 48449a2ca..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/SignatureAttribute.java +++ /dev/null @@ -1,1170 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.IOException; -import java.util.Map; -import java.util.ArrayList; -import com.fr.third.javassist.CtClass; - -/** - * Signature_attribute. - */ -public class SignatureAttribute extends com.fr.third.javassist.bytecode.AttributeInfo { - /** - * The name of this attribute "Signature". - */ - public static final String tag = "Signature"; - - SignatureAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int n, DataInputStream in) - throws IOException - { - super(cp, n, in); - } - - /** - * Constructs a Signature attribute. - * - * @param cp a constant pool table. - * @param signature the signature represented by this attribute. - */ - public SignatureAttribute(com.fr.third.javassist.bytecode.ConstPool cp, String signature) { - super(cp, tag); - int index = cp.addUtf8Info(signature); - byte[] bvalue = new byte[2]; - bvalue[0] = (byte)(index >>> 8); - bvalue[1] = (byte)index; - set(bvalue); - } - - /** - * Returns the generic signature indicated by signature_index. - * - * @see #toClassSignature(String) - * @see #toMethodSignature(String) - * @see #toFieldSignature(String) - */ - public String getSignature() { - return getConstPool().getUtf8Info(com.fr.third.javassist.bytecode.ByteArray.readU16bit(get(), 0)); - } - - /** - * Sets signature_index to the index of the given generic signature, - * which is added to a constant pool. - * - * @param sig new signature. - * @since 3.11 - */ - public void setSignature(String sig) { - int index = getConstPool().addUtf8Info(sig); - ByteArray.write16bit(index, info, 0); - } - - /** - * Makes a copy. Class names are replaced according to the - * given Map object. - * - * @param newCp the constant pool table used by the new copy. - * @param classnames pairs of replaced and substituted - * class names. - */ - public AttributeInfo copy(ConstPool newCp, Map classnames) { - return new SignatureAttribute(newCp, getSignature()); - } - - void renameClass(String oldname, String newname) { - String sig = renameClass(getSignature(), oldname, newname); - setSignature(sig); - } - - void renameClass(Map classnames) { - String sig = renameClass(getSignature(), classnames); - setSignature(sig); - } - - static String renameClass(String desc, String oldname, String newname) { - Map map = new java.util.HashMap(); - map.put(oldname, newname); - return renameClass(desc, map); - } - - static String renameClass(String desc, Map map) { - if (map == null) - return desc; - - StringBuilder newdesc = new StringBuilder(); - int head = 0; - int i = 0; - for (;;) { - int j = desc.indexOf('L', i); - if (j < 0) - break; - - StringBuilder nameBuf = new StringBuilder(); - int k = j; - char c; - try { - while ((c = desc.charAt(++k)) != ';') { - nameBuf.append(c); - if (c == '<') { - while ((c = desc.charAt(++k)) != '>') - nameBuf.append(c); - - nameBuf.append(c); - } - } - } - catch (IndexOutOfBoundsException e) { break; } - i = k + 1; - String name = nameBuf.toString(); - String name2 = (String)map.get(name); - if (name2 != null) { - newdesc.append(desc.substring(head, j)); - newdesc.append('L'); - newdesc.append(name2); - newdesc.append(c); - head = i; - } - } - - if (head == 0) - return desc; - else { - int len = desc.length(); - if (head < len) - newdesc.append(desc.substring(head, len)); - - return newdesc.toString(); - } - } - - private static boolean isNamePart(int c) { - return c != ';' && c != '<'; - } - - static private class Cursor { - int position = 0; - - int indexOf(String s, int ch) throws com.fr.third.javassist.bytecode.BadBytecode { - int i = s.indexOf(ch, position); - if (i < 0) - throw error(s); - else { - position = i + 1; - return i; - } - } - } - - /** - * Class signature. - */ - public static class ClassSignature { - TypeParameter[] params; - ClassType superClass; - ClassType[] interfaces; - - /** - * Constructs a class signature. - * - * @param params type parameters. - * @param superClass the super class. - * @param interfaces the interface types. - */ - public ClassSignature(TypeParameter[] params, ClassType superClass, ClassType[] interfaces) { - this.params = params == null ? new TypeParameter[0] : params; - this.superClass = superClass == null ? ClassType.OBJECT : superClass; - this.interfaces = interfaces == null ? new ClassType[0] : interfaces; - } - - /** - * Constructs a class signature. - * - * @param p type parameters. - */ - public ClassSignature(TypeParameter[] p) { - this(p, null, null); - } - - /** - * Returns the type parameters. - * - * @return a zero-length array if the type parameters are not specified. - */ - public TypeParameter[] getParameters() { - return params; - } - - /** - * Returns the super class. - */ - public ClassType getSuperClass() { return superClass; } - - /** - * Returns the super interfaces. - * - * @return a zero-length array if the super interfaces are not specified. - */ - public ClassType[] getInterfaces() { return interfaces; } - - /** - * Returns the string representation. - */ - public String toString() { - StringBuffer sbuf = new StringBuffer(); - - TypeParameter.toString(sbuf, params); - sbuf.append(" extends ").append(superClass); - if (interfaces.length > 0) { - sbuf.append(" implements "); - Type.toString(sbuf, interfaces); - } - - return sbuf.toString(); - } - - /** - * Returns the encoded string representing the method type signature. - */ - public String encode() { - StringBuffer sbuf = new StringBuffer(); - if (params.length > 0) { - sbuf.append('<'); - for (int i = 0; i < params.length; i++) - params[i].encode(sbuf); - - sbuf.append('>'); - } - - superClass.encode(sbuf); - for (int i = 0; i < interfaces.length; i++) - interfaces[i].encode(sbuf); - - return sbuf.toString(); - } - } - - /** - * Method type signature. - */ - public static class MethodSignature { - TypeParameter[] typeParams; - Type[] params; - Type retType; - ObjectType[] exceptions; - - /** - * Constructs a method type signature. Any parameter can be null - * to represent void or nothing. - * - * @param tp type parameters. - * @param params parameter types. - * @param ret a return type, or null if the return type is void. - * @param ex exception types. - */ - public MethodSignature(TypeParameter[] tp, Type[] params, Type ret, ObjectType[] ex) { - typeParams = tp == null ? new TypeParameter[0] : tp; - this.params = params == null ? new Type[0] : params; - retType = ret == null ? new BaseType("void") : ret; - exceptions = ex == null ? new ObjectType[0] : ex; - } - - /** - * Returns the formal type parameters. - * - * @return a zero-length array if the type parameters are not specified. - */ - public TypeParameter[] getTypeParameters() { return typeParams; } - - /** - * Returns the types of the formal parameters. - * - * @return a zero-length array if no formal parameter is taken. - */ - public Type[] getParameterTypes() { return params; } - - /** - * Returns the type of the returned value. - */ - public Type getReturnType() { return retType; } - - /** - * Returns the types of the exceptions that may be thrown. - * - * @return a zero-length array if exceptions are never thrown or - * the exception types are not parameterized types or type variables. - */ - public ObjectType[] getExceptionTypes() { return exceptions; } - - /** - * Returns the string representation. - */ - public String toString() { - StringBuffer sbuf = new StringBuffer(); - - TypeParameter.toString(sbuf, typeParams); - sbuf.append(" ("); - Type.toString(sbuf, params); - sbuf.append(") "); - sbuf.append(retType); - if (exceptions.length > 0) { - sbuf.append(" throws "); - Type.toString(sbuf, exceptions); - } - - return sbuf.toString(); - } - - /** - * Returns the encoded string representing the method type signature. - */ - public String encode() { - StringBuffer sbuf = new StringBuffer(); - if (typeParams.length > 0) { - sbuf.append('<'); - for (int i = 0; i < typeParams.length; i++) - typeParams[i].encode(sbuf); - - sbuf.append('>'); - } - - sbuf.append('('); - for (int i = 0; i < params.length; i++) - params[i].encode(sbuf); - - sbuf.append(')'); - retType.encode(sbuf); - if (exceptions.length > 0) - for (int i = 0; i < exceptions.length; i++) { - sbuf.append('^'); - exceptions[i].encode(sbuf); - } - - return sbuf.toString(); - } - } - - /** - * Formal type parameters. - * - * @see TypeArgument - */ - public static class TypeParameter { - String name; - ObjectType superClass; - ObjectType[] superInterfaces; - - TypeParameter(String sig, int nb, int ne, ObjectType sc, ObjectType[] si) { - name = sig.substring(nb, ne); - superClass = sc; - superInterfaces = si; - } - - /** - * Constructs a TypeParameter representing a type parametre - * like <T extends ... >. - * - * @param name parameter name. - * @param superClass an upper bound class-type (or null). - * @param superInterfaces an upper bound interface-type (or null). - */ - public TypeParameter(String name, ObjectType superClass, ObjectType[] superInterfaces) { - this.name = name; - this.superClass = superClass; - if (superInterfaces == null) - this.superInterfaces = new ObjectType[0]; - else - this.superInterfaces = superInterfaces; - } - - /** - * Constructs a TypeParameter representing a type parameter - * like <T>. - * - * @param name parameter name. - */ - public TypeParameter(String name) { - this(name, null, null); - } - - /** - * Returns the name of the type parameter. - */ - public String getName() { - return name; - } - - /** - * Returns the class bound of this parameter. - */ - public ObjectType getClassBound() { return superClass; } - - /** - * Returns the interface bound of this parameter. - * - * @return a zero-length array if the interface bound is not specified. - */ - public ObjectType[] getInterfaceBound() { return superInterfaces; } - - /** - * Returns the string representation. - */ - public String toString() { - StringBuffer sbuf = new StringBuffer(getName()); - if (superClass != null) - sbuf.append(" extends ").append(superClass.toString()); - - int len = superInterfaces.length; - if (len > 0) { - for (int i = 0; i < len; i++) { - if (i > 0 || superClass != null) - sbuf.append(" & "); - else - sbuf.append(" extends "); - - sbuf.append(superInterfaces[i].toString()); - } - } - - return sbuf.toString(); - } - - static void toString(StringBuffer sbuf, TypeParameter[] tp) { - sbuf.append('<'); - for (int i = 0; i < tp.length; i++) { - if (i > 0) - sbuf.append(", "); - - sbuf.append(tp[i]); - } - - sbuf.append('>'); - } - - void encode(StringBuffer sb) { - sb.append(name); - if (superClass == null) - sb.append(":Ljava/lang/Object;"); - else { - sb.append(':'); - superClass.encode(sb); - } - - for (int i = 0; i < superInterfaces.length; i++) { - sb.append(':'); - superInterfaces[i].encode(sb); - } - } - } - - /** - * Type argument. - * - * @see TypeParameter - */ - public static class TypeArgument { - ObjectType arg; - char wildcard; - - TypeArgument(ObjectType a, char w) { - arg = a; - wildcard = w; - } - - /** - * Constructs a TypeArgument. - * A type argument is <String>, <int[]>, - * or a type variable <T>, etc. - * - * @param t a class type, an array type, or a type variable. - */ - public TypeArgument(ObjectType t) { - this(t, ' '); - } - - /** - * Constructs a TypeArgument representing <?>. - */ - public TypeArgument() { - this(null, '*'); - } - - /** - * A factory method constructing a TypeArgument with an upper bound. - * It represents <? extends ... > - * - * @param t an upper bound type. - */ - public static TypeArgument subclassOf(ObjectType t) { - return new TypeArgument(t, '+'); - } - - /** - * A factory method constructing a TypeArgument with an lower bound. - * It represents <? super ... > - * - * @param t an lower bbound type. - */ - public static TypeArgument superOf(ObjectType t) { - return new TypeArgument(t, '-'); - } - - /** - * Returns the kind of this type argument. - * - * @return ' ' (not-wildcard), '*' (wildcard), '+' (wildcard with - * upper bound), or '-' (wildcard with lower bound). - */ - public char getKind() { return wildcard; } - - /** - * Returns true if this type argument is a wildcard type - * such as ?, ? extends String, or ? super Integer. - */ - public boolean isWildcard() { return wildcard != ' '; } - - /** - * Returns the type represented by this argument - * if the argument is not a wildcard type. Otherwise, this method - * returns the upper bound (if the kind is '+'), - * the lower bound (if the kind is '-'), or null (if the upper or lower - * bound is not specified). - */ - public ObjectType getType() { return arg; } - - /** - * Returns the string representation. - */ - public String toString() { - if (wildcard == '*') - return "?"; - - String type = arg.toString(); - if (wildcard == ' ') - return type; - else if (wildcard == '+') - return "? extends " + type; - else - return "? super " + type; - } - - static void encode(StringBuffer sb, TypeArgument[] args) { - sb.append('<'); - for (int i = 0; i < args.length; i++) { - TypeArgument ta = args[i]; - if (ta.isWildcard()) - sb.append(ta.wildcard); - - if (ta.getType() != null) - ta.getType().encode(sb); - } - - sb.append('>'); - } - } - - /** - * Primitive types and object types. - */ - public static abstract class Type { - abstract void encode(StringBuffer sb); - static void toString(StringBuffer sbuf, Type[] ts) { - for (int i = 0; i < ts.length; i++) { - if (i > 0) - sbuf.append(", "); - - sbuf.append(ts[i]); - } - } - - /** - * Returns the type name in the JVM internal style. - * For example, if the type is a nested class {@code foo.Bar.Baz}, - * then {@code foo.Bar$Baz} is returned. - */ - public String jvmTypeName() { return toString(); } - } - - /** - * Primitive types. - */ - public static class BaseType extends Type { - char descriptor; - BaseType(char c) { descriptor = c; } - - /** - * Constructs a BaseType. - * - * @param typeName void, int, ... - */ - public BaseType(String typeName) { - this(com.fr.third.javassist.bytecode.Descriptor.of(typeName).charAt(0)); - } - - /** - * Returns the descriptor representing this primitive type. - * - * @see com.fr.third.javassist.bytecode.Descriptor - */ - public char getDescriptor() { return descriptor; } - - /** - * Returns the CtClass representing this - * primitive type. - */ - public CtClass getCtlass() { - return com.fr.third.javassist.bytecode.Descriptor.toPrimitiveClass(descriptor); - } - - /** - * Returns the string representation. - */ - public String toString() { - return Descriptor.toClassName(Character.toString(descriptor)); - } - - void encode(StringBuffer sb) { - sb.append(descriptor); - } - } - - /** - * Class types, array types, and type variables. - * This class is also used for representing a field type. - */ - public static abstract class ObjectType extends Type { - /** - * Returns the encoded string representing the object type signature. - */ - public String encode() { - StringBuffer sb = new StringBuffer(); - encode(sb); - return sb.toString(); - } - } - - /** - * Class types. - */ - public static class ClassType extends ObjectType { - String name; - TypeArgument[] arguments; - - static ClassType make(String s, int b, int e, - TypeArgument[] targs, ClassType parent) { - if (parent == null) - return new ClassType(s, b, e, targs); - else - return new NestedClassType(s, b, e, targs, parent); - } - - ClassType(String signature, int begin, int end, TypeArgument[] targs) { - name = signature.substring(begin, end).replace('/', '.'); - arguments = targs; - } - - /** - * A class type representing java.lang.Object. - */ - public static ClassType OBJECT = new ClassType("java.lang.Object", null); - - /** - * Constructs a ClassType. It represents - * the name of a non-nested class. - * - * @param className a fully qualified class name. - * @param args type arguments or null. - */ - public ClassType(String className, TypeArgument[] args) { - name = className; - arguments = args; - } - - /** - * Constructs a ClassType. It represents - * the name of a non-nested class. - * - * @param className a fully qualified class name. - */ - public ClassType(String className) { - this(className, null); - } - - /** - * Returns the class name. - */ - public String getName() { - return name; - } - - /** - * Returns the type arguments. - * - * @return null if no type arguments are given to this class. - */ - public TypeArgument[] getTypeArguments() { return arguments; } - - /** - * If this class is a member of another class, returns the - * class in which this class is declared. - * - * @return null if this class is not a member of another class. - */ - public ClassType getDeclaringClass() { return null; } - - /** - * Returns the string representation. - */ - public String toString() { - StringBuffer sbuf = new StringBuffer(); - ClassType parent = getDeclaringClass(); - if (parent != null) - sbuf.append(parent.toString()).append('.'); - - sbuf.append(name); - if (arguments != null) { - sbuf.append('<'); - int n = arguments.length; - for (int i = 0; i < n; i++) { - if (i > 0) - sbuf.append(", "); - - sbuf.append(arguments[i].toString()); - } - - sbuf.append('>'); - } - - return sbuf.toString(); - } - - /** - * Returns the type name in the JVM internal style. - * For example, if the type is a nested class {@code foo.Bar.Baz}, - * then {@code foo.Bar$Baz} is returned. - */ - public String jvmTypeName() { - StringBuffer sbuf = new StringBuffer(); - ClassType parent = getDeclaringClass(); - if (parent != null) - sbuf.append(parent.jvmTypeName()).append('$'); - - sbuf.append(name); - if (arguments != null) { - sbuf.append('<'); - int n = arguments.length; - for (int i = 0; i < n; i++) { - if (i > 0) - sbuf.append(", "); - - sbuf.append(arguments[i].toString()); - } - - sbuf.append('>'); - } - - return sbuf.toString(); - } - - void encode(StringBuffer sb) { - sb.append('L'); - encode2(sb); - sb.append(';'); - } - - void encode2(StringBuffer sb) { - ClassType parent = getDeclaringClass(); - if (parent != null) { - parent.encode2(sb); - sb.append('$'); - } - - sb.append(name.replace('.', '/')); - if (arguments != null) - TypeArgument.encode(sb, arguments); - } - } - - /** - * Nested class types. - */ - public static class NestedClassType extends ClassType { - ClassType parent; - NestedClassType(String s, int b, int e, - TypeArgument[] targs, ClassType p) { - super(s, b, e, targs); - parent = p; - } - - /** - * Constructs a NestedClassType. - * - * @param parent the class surrounding this class type. - * @param className a simple class name. It does not include - * a package name or a parent's class name. - * @param args type parameters or null. - */ - public NestedClassType(ClassType parent, String className, TypeArgument[] args) { - super(className, args); - this.parent = parent; - } - - /** - * Returns the class that declares this nested class. - * This nested class is a member of that declaring class. - */ - public ClassType getDeclaringClass() { return parent; } - } - - /** - * Array types. - */ - public static class ArrayType extends ObjectType { - int dim; - Type componentType; - - /** - * Constructs an ArrayType. - * - * @param d dimension. - * @param comp the component type. - */ - public ArrayType(int d, Type comp) { - dim = d; - componentType = comp; - } - - /** - * Returns the dimension of the array. - */ - public int getDimension() { return dim; } - - /** - * Returns the component type. - */ - public Type getComponentType() { - return componentType; - } - - /** - * Returns the string representation. - */ - public String toString() { - StringBuffer sbuf = new StringBuffer(componentType.toString()); - for (int i = 0; i < dim; i++) - sbuf.append("[]"); - - return sbuf.toString(); - } - - void encode(StringBuffer sb) { - for (int i = 0; i < dim; i++) - sb.append('['); - - componentType.encode(sb); - } - } - - /** - * Type variables. - */ - public static class TypeVariable extends ObjectType { - String name; - - TypeVariable(String sig, int begin, int end) { - name = sig.substring(begin, end); - } - - /** - * Constructs a TypeVariable. - * - * @param name the name of a type variable. - */ - public TypeVariable(String name) { - this.name = name; - } - - /** - * Returns the variable name. - */ - public String getName() { - return name; - } - - /** - * Returns the string representation. - */ - public String toString() { - return name; - } - - void encode(StringBuffer sb) { - sb.append('T').append(name).append(';'); - } - } - - /** - * Parses the given signature string as a class signature. - * - * @param sig the signature obtained from the SignatureAttribute - * of a ClassFile. - * @return a tree-like data structure representing a class signature. It provides - * convenient accessor methods. - * @throws com.fr.third.javassist.bytecode.BadBytecode thrown when a syntactical error is found. - * @see #getSignature() - * @since 3.5 - */ - public static ClassSignature toClassSignature(String sig) throws com.fr.third.javassist.bytecode.BadBytecode { - try { - return parseSig(sig); - } - catch (IndexOutOfBoundsException e) { - throw error(sig); - } - } - - /** - * Parses the given signature string as a method type signature. - * - * @param sig the signature obtained from the SignatureAttribute - * of a MethodInfo. - * @return @return a tree-like data structure representing a method signature. It provides - * convenient accessor methods. - * @throws com.fr.third.javassist.bytecode.BadBytecode thrown when a syntactical error is found. - * @see #getSignature() - * @since 3.5 - */ - public static MethodSignature toMethodSignature(String sig) throws com.fr.third.javassist.bytecode.BadBytecode { - try { - return parseMethodSig(sig); - } - catch (IndexOutOfBoundsException e) { - throw error(sig); - } - } - - /** - * Parses the given signature string as a field type signature. - * - * @param sig the signature string obtained from the SignatureAttribute - * of a FieldInfo. - * @return the field type signature. - * @throws com.fr.third.javassist.bytecode.BadBytecode thrown when a syntactical error is found. - * @see #getSignature() - * @since 3.5 - */ - public static ObjectType toFieldSignature(String sig) throws com.fr.third.javassist.bytecode.BadBytecode { - try { - return parseObjectType(sig, new Cursor(), false); - } - catch (IndexOutOfBoundsException e) { - throw error(sig); - } - } - - /** - * Parses the given signature string as a type signature. - * The type signature is either the field type signature or a base type - * descriptor including void type. - * - * @throws com.fr.third.javassist.bytecode.BadBytecode thrown when a syntactical error is found. - * @since 3.18 - */ - public static Type toTypeSignature(String sig) throws com.fr.third.javassist.bytecode.BadBytecode { - try { - return parseType(sig, new Cursor()); - } - catch (IndexOutOfBoundsException e) { - throw error(sig); - } - } - - private static ClassSignature parseSig(String sig) - throws com.fr.third.javassist.bytecode.BadBytecode, IndexOutOfBoundsException - { - Cursor cur = new Cursor(); - TypeParameter[] tp = parseTypeParams(sig, cur); - ClassType superClass = parseClassType(sig, cur); - int sigLen = sig.length(); - ArrayList ifArray = new ArrayList(); - while (cur.position < sigLen && sig.charAt(cur.position) == 'L') - ifArray.add(parseClassType(sig, cur)); - - ClassType[] ifs - = (ClassType[])ifArray.toArray(new ClassType[ifArray.size()]); - return new ClassSignature(tp, superClass, ifs); - } - - private static MethodSignature parseMethodSig(String sig) - throws com.fr.third.javassist.bytecode.BadBytecode - { - Cursor cur = new Cursor(); - TypeParameter[] tp = parseTypeParams(sig, cur); - if (sig.charAt(cur.position++) != '(') - throw error(sig); - - ArrayList params = new ArrayList(); - while (sig.charAt(cur.position) != ')') { - Type t = parseType(sig, cur); - params.add(t); - } - - cur.position++; - Type ret = parseType(sig, cur); - int sigLen = sig.length(); - ArrayList exceptions = new ArrayList(); - while (cur.position < sigLen && sig.charAt(cur.position) == '^') { - cur.position++; - ObjectType t = parseObjectType(sig, cur, false); - if (t instanceof ArrayType) - throw error(sig); - - exceptions.add(t); - } - - Type[] p = (Type[])params.toArray(new Type[params.size()]); - ObjectType[] ex = (ObjectType[])exceptions.toArray(new ObjectType[exceptions.size()]); - return new MethodSignature(tp, p, ret, ex); - } - - private static TypeParameter[] parseTypeParams(String sig, Cursor cur) - throws com.fr.third.javassist.bytecode.BadBytecode - { - ArrayList typeParam = new ArrayList(); - if (sig.charAt(cur.position) == '<') { - cur.position++; - while (sig.charAt(cur.position) != '>') { - int nameBegin = cur.position; - int nameEnd = cur.indexOf(sig, ':'); - ObjectType classBound = parseObjectType(sig, cur, true); - ArrayList ifBound = new ArrayList(); - while (sig.charAt(cur.position) == ':') { - cur.position++; - ObjectType t = parseObjectType(sig, cur, false); - ifBound.add(t); - } - - TypeParameter p = new TypeParameter(sig, nameBegin, nameEnd, - classBound, (ObjectType[])ifBound.toArray(new ObjectType[ifBound.size()])); - typeParam.add(p); - } - - cur.position++; - } - - return (TypeParameter[])typeParam.toArray(new TypeParameter[typeParam.size()]); - } - - private static ObjectType parseObjectType(String sig, Cursor c, boolean dontThrow) - throws com.fr.third.javassist.bytecode.BadBytecode - { - int i; - int begin = c.position; - switch (sig.charAt(begin)) { - case 'L' : - return parseClassType2(sig, c, null); - case 'T' : - i = c.indexOf(sig, ';'); - return new TypeVariable(sig, begin + 1, i); - case '[' : - return parseArray(sig, c); - default : - if (dontThrow) - return null; - else - throw error(sig); - } - } - - private static ClassType parseClassType(String sig, Cursor c) - throws com.fr.third.javassist.bytecode.BadBytecode - { - if (sig.charAt(c.position) == 'L') - return parseClassType2(sig, c, null); - else - throw error(sig); - } - - private static ClassType parseClassType2(String sig, Cursor c, ClassType parent) - throws com.fr.third.javassist.bytecode.BadBytecode - { - int start = ++c.position; - char t; - do { - t = sig.charAt(c.position++); - } while (t != '$' && t != '<' && t != ';'); - int end = c.position - 1; - TypeArgument[] targs; - if (t == '<') { - targs = parseTypeArgs(sig, c); - t = sig.charAt(c.position++); - } - else - targs = null; - - ClassType thisClass = ClassType.make(sig, start, end, targs, parent); - if (t == '$' || t == '.') { - c.position--; - return parseClassType2(sig, c, thisClass); - } - else - return thisClass; - } - - private static TypeArgument[] parseTypeArgs(String sig, Cursor c) throws com.fr.third.javassist.bytecode.BadBytecode { - ArrayList args = new ArrayList(); - char t; - while ((t = sig.charAt(c.position++)) != '>') { - TypeArgument ta; - if (t == '*' ) - ta = new TypeArgument(null, '*'); - else { - if (t != '+' && t != '-') { - t = ' '; - c.position--; - } - - ta = new TypeArgument(parseObjectType(sig, c, false), t); - } - - args.add(ta); - } - - return (TypeArgument[])args.toArray(new TypeArgument[args.size()]); - } - - private static ObjectType parseArray(String sig, Cursor c) throws com.fr.third.javassist.bytecode.BadBytecode { - int dim = 1; - while (sig.charAt(++c.position) == '[') - dim++; - - return new ArrayType(dim, parseType(sig, c)); - } - - private static Type parseType(String sig, Cursor c) throws com.fr.third.javassist.bytecode.BadBytecode { - Type t = parseObjectType(sig, c, true); - if (t == null) - t = new BaseType(sig.charAt(c.position++)); - - return t; - } - - private static com.fr.third.javassist.bytecode.BadBytecode error(String sig) { - return new BadBytecode("bad signature: " + sig); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/SourceFileAttribute.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/SourceFileAttribute.java deleted file mode 100644 index abf1401b8..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/SourceFileAttribute.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.IOException; -import java.util.Map; - -/** - * SourceFile_attribute. - */ -public class SourceFileAttribute extends com.fr.third.javassist.bytecode.AttributeInfo { - /** - * The name of this attribute "SourceFile". - */ - public static final String tag = "SourceFile"; - - SourceFileAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int n, DataInputStream in) - throws IOException - { - super(cp, n, in); - } - - /** - * Constructs a SourceFile attribute. - * - * @param cp a constant pool table. - * @param filename the name of the source file. - */ - public SourceFileAttribute(com.fr.third.javassist.bytecode.ConstPool cp, String filename) { - super(cp, tag); - int index = cp.addUtf8Info(filename); - byte[] bvalue = new byte[2]; - bvalue[0] = (byte)(index >>> 8); - bvalue[1] = (byte)index; - set(bvalue); - } - - /** - * Returns the file name indicated by sourcefile_index. - */ - public String getFileName() { - return getConstPool().getUtf8Info(ByteArray.readU16bit(get(), 0)); - } - - /** - * Makes a copy. Class names are replaced according to the - * given Map object. - * - * @param newCp the constant pool table used by the new copy. - * @param classnames pairs of replaced and substituted - * class names. - */ - public AttributeInfo copy(ConstPool newCp, Map classnames) { - return new SourceFileAttribute(newCp, getFileName()); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/StackMap.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/StackMap.java deleted file mode 100644 index 686df1b5c..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/StackMap.java +++ /dev/null @@ -1,575 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.IOException; -import java.util.Map; - -import com.fr.third.javassist.CannotCompileException; -import com.fr.third.javassist.CtBehavior; -import com.fr.third.javassist.CtClass; - -/** - * Another stack_map attribute defined in CLDC 1.1 for J2ME. - * - *

This is an entry in the attributes table of a Code attribute. - * It was introduced by J2ME CLDC 1.1 (JSR 139) for pre-verification. - * - *

According to the CLDC specification, the sizes of some fields are not 16bit - * but 32bit if the code size is more than 64K or the number of the local variables - * is more than 64K. However, for the J2ME CLDC technology, they are always 16bit. - * The implementation of the StackMap class assumes they are 16bit. - * - * @see MethodInfo#doPreverify - * @see StackMapTable - * @since 3.12 - */ -public class StackMap extends AttributeInfo { - /** - * The name of this attribute "StackMap". - */ - public static final String tag = "StackMap"; - - - /** - * Constructs a stack_map attribute. - */ - StackMap(ConstPool cp, byte[] newInfo) { - super(cp, tag, newInfo); - } - - StackMap(ConstPool cp, int name_id, DataInputStream in) - throws IOException - { - super(cp, name_id, in); - } - - /** - * Returns number_of_entries. - */ - public int numOfEntries() { - return ByteArray.readU16bit(info, 0); - } - - /** - * Top_variable_info.tag. - */ - public static final int TOP = 0; - - /** - * Integer_variable_info.tag. - */ - public static final int INTEGER = 1; - - /** - * Float_variable_info.tag. - */ - public static final int FLOAT = 2; - - /** - * Double_variable_info.tag. - */ - public static final int DOUBLE = 3; - - /** - * Long_variable_info.tag. - */ - public static final int LONG = 4; - - /** - * Null_variable_info.tag. - */ - public static final int NULL = 5; - - /** - * UninitializedThis_variable_info.tag. - */ - public static final int THIS = 6; - - /** - * Object_variable_info.tag. - */ - public static final int OBJECT = 7; - - /** - * Uninitialized_variable_info.tag. - */ - public static final int UNINIT = 8; - - /** - * Makes a copy. - */ - public AttributeInfo copy(ConstPool newCp, Map classnames) { - Copier copier = new Copier(this, newCp, classnames); - copier.visit(); - return copier.getStackMap(); - } - - /** - * A code walker for a StackMap attribute. - */ - public static class Walker { - byte[] info; - - /** - * Constructs a walker. - */ - public Walker(StackMap sm) { - info = sm.get(); - } - - /** - * Visits each entry of the stack map frames. - */ - public void visit() { - int num = ByteArray.readU16bit(info, 0); - int pos = 2; - for (int i = 0; i < num; i++) { - int offset = ByteArray.readU16bit(info, pos); - int numLoc = ByteArray.readU16bit(info, pos + 2); - pos = locals(pos + 4, offset, numLoc); - int numStack = ByteArray.readU16bit(info, pos); - pos = stack(pos + 2, offset, numStack); - } - } - - /** - * Invoked when locals of stack_map_frame - * is visited. - */ - public int locals(int pos, int offset, int num) { - return typeInfoArray(pos, offset, num, true); - } - - /** - * Invoked when stack of stack_map_frame - * is visited. - */ - public int stack(int pos, int offset, int num) { - return typeInfoArray(pos, offset, num, false); - } - - /** - * Invoked when an array of verification_type_info is - * visited. - * - * @param num the number of elements. - * @param isLocals true if this array is for locals. - * false if it is for stack. - */ - public int typeInfoArray(int pos, int offset, int num, boolean isLocals) { - for (int k = 0; k < num; k++) - pos = typeInfoArray2(k, pos); - - return pos; - } - - int typeInfoArray2(int k, int pos) { - byte tag = info[pos]; - if (tag == OBJECT) { - int clazz = ByteArray.readU16bit(info, pos + 1); - objectVariable(pos, clazz); - pos += 3; - } - else if (tag == UNINIT) { - int offsetOfNew = ByteArray.readU16bit(info, pos + 1); - uninitialized(pos, offsetOfNew); - pos += 3; - } - else { - typeInfo(pos, tag); - pos++; - } - - return pos; - } - - /** - * Invoked when an element of verification_type_info - * (except Object_variable_info and - * Uninitialized_variable_info) is visited. - */ - public void typeInfo(int pos, byte tag) {} - - /** - * Invoked when an element of type Object_variable_info - * is visited. - */ - public void objectVariable(int pos, int clazz) {} - - /** - * Invoked when an element of type Uninitialized_variable_info - * is visited. - */ - public void uninitialized(int pos, int offset) {} - } - - static class Copier extends Walker { - byte[] dest; - ConstPool srcCp, destCp; - Map classnames; - - Copier(StackMap map, ConstPool newCp, Map classnames) { - super(map); - srcCp = map.getConstPool(); - dest = new byte[info.length]; - destCp = newCp; - this.classnames = classnames; - } - - public void visit() { - int num = ByteArray.readU16bit(info, 0); - ByteArray.write16bit(num, dest, 0); - super.visit(); - } - - public int locals(int pos, int offset, int num) { - ByteArray.write16bit(offset, dest, pos - 4); - return super.locals(pos, offset, num); - } - - public int typeInfoArray(int pos, int offset, int num, boolean isLocals) { - ByteArray.write16bit(num, dest, pos - 2); - return super.typeInfoArray(pos, offset, num, isLocals); - } - - public void typeInfo(int pos, byte tag) { - dest[pos] = tag; - } - - public void objectVariable(int pos, int clazz) { - dest[pos] = OBJECT; - int newClazz = srcCp.copy(clazz, destCp, classnames); - ByteArray.write16bit(newClazz, dest, pos + 1); - } - - public void uninitialized(int pos, int offset) { - dest[pos] = UNINIT; - ByteArray.write16bit(offset, dest, pos + 1); - } - - public StackMap getStackMap() { - return new StackMap(destCp, dest); - } - } - - /** - * Updates this stack map table when a new local variable is inserted - * for a new parameter. - * - * @param index the index of the added local variable. - * @param tag the type tag of that local variable. - * It is available by StackMapTable.typeTagOf(char). - * @param classInfo the index of the CONSTANT_Class_info structure - * in a constant pool table. This should be zero unless the tag - * is ITEM_Object. - * - * @see CtBehavior#addParameter(CtClass) - * @see StackMapTable#typeTagOf(char) - * @see ConstPool - */ - public void insertLocal(int index, int tag, int classInfo) - throws BadBytecode - { - byte[] data = new InsertLocal(this, index, tag, classInfo).doit(); - this.set(data); - } - - static class SimpleCopy extends Walker { - Writer writer; - - SimpleCopy(StackMap map) { - super(map); - writer = new Writer(); - } - - byte[] doit() { - visit(); - return writer.toByteArray(); - } - - public void visit() { - int num = ByteArray.readU16bit(info, 0); - writer.write16bit(num); - super.visit(); - } - - public int locals(int pos, int offset, int num) { - writer.write16bit(offset); - return super.locals(pos, offset, num); - } - - public int typeInfoArray(int pos, int offset, int num, boolean isLocals) { - writer.write16bit(num); - return super.typeInfoArray(pos, offset, num, isLocals); - } - - public void typeInfo(int pos, byte tag) { - writer.writeVerifyTypeInfo(tag, 0); - } - - public void objectVariable(int pos, int clazz) { - writer.writeVerifyTypeInfo(OBJECT, clazz); - } - - public void uninitialized(int pos, int offset) { - writer.writeVerifyTypeInfo(UNINIT, offset); - } - } - - static class InsertLocal extends SimpleCopy { - private int varIndex; - private int varTag, varData; - - InsertLocal(StackMap map, int varIndex, int varTag, int varData) { - super(map); - this.varIndex = varIndex; - this.varTag = varTag; - this.varData = varData; - } - - public int typeInfoArray(int pos, int offset, int num, boolean isLocals) { - if (!isLocals || num < varIndex) - return super.typeInfoArray(pos, offset, num, isLocals); - - writer.write16bit(num + 1); - for (int k = 0; k < num; k++) { - if (k == varIndex) - writeVarTypeInfo(); - - pos = typeInfoArray2(k, pos); - } - - if (num == varIndex) - writeVarTypeInfo(); - - return pos; - } - - private void writeVarTypeInfo() { - if (varTag == OBJECT) - writer.writeVerifyTypeInfo(OBJECT, varData); - else if (varTag == UNINIT) - writer.writeVerifyTypeInfo(UNINIT, varData); - else - writer.writeVerifyTypeInfo(varTag, 0); - } - } - - void shiftPc(int where, int gapSize, boolean exclusive) - throws BadBytecode - { - new Shifter(this, where, gapSize, exclusive).visit(); - } - - static class Shifter extends Walker { - private int where, gap; - private boolean exclusive; - - public Shifter(StackMap smt, int where, int gap, boolean exclusive) { - super(smt); - this.where = where; - this.gap = gap; - this.exclusive = exclusive; - } - - public int locals(int pos, int offset, int num) { - if (exclusive ? where <= offset : where < offset) - ByteArray.write16bit(offset + gap, info, pos - 4); - - return super.locals(pos, offset, num); - } - - public void uninitialized(int pos, int offset) { - if (where <= offset) - ByteArray.write16bit(offset + gap, info, pos + 1); - } - } - - /** - * @see CodeIterator.Switcher#adjustOffsets(int, int) - */ - void shiftForSwitch(int where, int gapSize) throws BadBytecode { - new SwitchShifter(this, where, gapSize).visit(); - } - - static class SwitchShifter extends Walker { - private int where, gap; - - public SwitchShifter(StackMap smt, int where, int gap) { - super(smt); - this.where = where; - this.gap = gap; - } - - public int locals(int pos, int offset, int num) { - if (where == pos + offset) - ByteArray.write16bit(offset - gap, info, pos - 4); - else if (where == pos) - ByteArray.write16bit(offset + gap, info, pos - 4); - - return super.locals(pos, offset, num); - } - } - - /** - * Undocumented method. Do not use; internal-use only. - * - *

This method is for javassist.convert.TransformNew. - * It is called to update the stack map when - * the NEW opcode (and the following DUP) is removed. - * - * @param where the position of the removed NEW opcode. - */ - public void removeNew(int where) throws CannotCompileException { - byte[] data = new NewRemover(this, where).doit(); - this.set(data); - } - - static class NewRemover extends SimpleCopy { - int posOfNew; - - NewRemover(StackMap map, int where) { - super(map); - posOfNew = where; - } - - public int stack(int pos, int offset, int num) { - return stackTypeInfoArray(pos, offset, num); - } - - private int stackTypeInfoArray(int pos, int offset, int num) { - int p = pos; - int count = 0; - for (int k = 0; k < num; k++) { - byte tag = info[p]; - if (tag == OBJECT) - p += 3; - else if (tag == UNINIT) { - int offsetOfNew = ByteArray.readU16bit(info, p + 1); - if (offsetOfNew == posOfNew) - count++; - - p += 3; - } - else - p++; - } - - writer.write16bit(num - count); - for (int k = 0; k < num; k++) { - byte tag = info[pos]; - if (tag == OBJECT) { - int clazz = ByteArray.readU16bit(info, pos + 1); - objectVariable(pos, clazz); - pos += 3; - } - else if (tag == UNINIT) { - int offsetOfNew = ByteArray.readU16bit(info, pos + 1); - if (offsetOfNew != posOfNew) - uninitialized(pos, offsetOfNew); - - pos += 3; - } - else { - typeInfo(pos, tag); - pos++; - } - } - - return pos; - } - } - - /** - * Prints this stack map. - */ - public void print(java.io.PrintWriter out) { - new Printer(this, out).print(); - } - - static class Printer extends Walker { - private java.io.PrintWriter writer; - - public Printer(StackMap map, java.io.PrintWriter out) { - super(map); - writer = out; - } - - public void print() { - int num = ByteArray.readU16bit(info, 0); - writer.println(num + " entries"); - visit(); - } - - public int locals(int pos, int offset, int num) { - writer.println(" * offset " + offset); - return super.locals(pos, offset, num); - } - } - - /** - * Internal use only. - */ - public static class Writer { - // see javassist.bytecode.stackmap.MapMaker - - private ByteArrayOutputStream output; - - /** - * Constructs a writer. - */ - public Writer() { - output = new ByteArrayOutputStream(); - } - - /** - * Converts the written data into a byte array. - */ - public byte[] toByteArray() { - return output.toByteArray(); - } - - /** - * Converts to a StackMap attribute. - */ - public StackMap toStackMap(ConstPool cp) { - return new StackMap(cp, output.toByteArray()); - } - - /** - * Writes a union verification_type_info value. - * - * @param data cpool_index or offset. - */ - public void writeVerifyTypeInfo(int tag, int data) { - output.write(tag); - if (tag == StackMap.OBJECT || tag == StackMap.UNINIT) - write16bit(data); - } - - /** - * Writes a 16bit value. - */ - public void write16bit(int value) { - output.write((value >>> 8) & 0xff); - output.write(value & 0xff); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/StackMapTable.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/StackMapTable.java deleted file mode 100644 index d4fc3dbfb..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/StackMapTable.java +++ /dev/null @@ -1,1051 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.ByteArrayOutputStream; -import java.io.PrintWriter; -import java.io.IOException; -import java.util.Map; -import com.fr.third.javassist.CannotCompileException; -import com.fr.third.javassist.CtBehavior; -import com.fr.third.javassist.CtClass; - -/** - * stack_map attribute. - * - *

This is an entry in the attributes table of a Code attribute. - * It was introduced by J2SE 6 for the verification by - * typechecking. - * - * @see StackMap - * @since 3.4 - */ -public class StackMapTable extends com.fr.third.javassist.bytecode.AttributeInfo { - /** - * The name of this attribute "StackMapTable". - */ - public static final String tag = "StackMapTable"; - - /** - * Constructs a stack_map attribute. - */ - StackMapTable(com.fr.third.javassist.bytecode.ConstPool cp, byte[] newInfo) { - super(cp, tag, newInfo); - } - - StackMapTable(com.fr.third.javassist.bytecode.ConstPool cp, int name_id, DataInputStream in) - throws IOException - { - super(cp, name_id, in); - } - - /** - * Makes a copy. - * - * @exception RuntimeCopyException if a BadBytecode - * exception is thrown while copying, - * it is converted into - * RuntimeCopyException. - * - */ - public AttributeInfo copy(com.fr.third.javassist.bytecode.ConstPool newCp, Map classnames) - throws RuntimeCopyException - { - try { - return new StackMapTable(newCp, - new Copier(this.constPool, info, newCp, classnames).doit()); - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new RuntimeCopyException("bad bytecode. fatal?"); - } - } - - /** - * An exception that may be thrown by copy() - * in StackMapTable. - */ - public static class RuntimeCopyException extends RuntimeException { - /** - * Constructs an exception. - */ - public RuntimeCopyException(String s) { - super(s); - } - } - - void write(DataOutputStream out) throws IOException { - super.write(out); - } - - /** - * Top_variable_info.tag. - */ - public static final int TOP = 0; - - /** - * Integer_variable_info.tag. - */ - public static final int INTEGER = 1; - - /** - * Float_variable_info.tag. - */ - public static final int FLOAT = 2; - - /** - * Double_variable_info.tag. - */ - public static final int DOUBLE = 3; - - /** - * Long_variable_info.tag. - */ - public static final int LONG = 4; - - /** - * Null_variable_info.tag. - */ - public static final int NULL = 5; - - /** - * UninitializedThis_variable_info.tag. - */ - public static final int THIS = 6; - - /** - * Object_variable_info.tag. - */ - public static final int OBJECT = 7; - - /** - * Uninitialized_variable_info.tag. - */ - public static final int UNINIT = 8; - - /** - * A code walker for a StackMapTable attribute. - */ - public static class Walker { - byte[] info; - int numOfEntries; - - /** - * Constructs a walker. - * - * @param smt the StackMapTable that this walker - * walks around. - */ - public Walker(StackMapTable smt) { - this(smt.get()); - } - - /** - * Constructs a walker. - * - * @param data the info field of the - * attribute_info structure. - * It can be obtained by get() - * in the AttributeInfo class. - */ - public Walker(byte[] data) { - info = data; - numOfEntries = com.fr.third.javassist.bytecode.ByteArray.readU16bit(data, 0); - } - - /** - * Returns the number of the entries. - */ - public final int size() { return numOfEntries; } - - /** - * Visits each entry of the stack map frames. - */ - public void parse() throws com.fr.third.javassist.bytecode.BadBytecode { - int n = numOfEntries; - int pos = 2; - for (int i = 0; i < n; i++) - pos = stackMapFrames(pos, i); - } - - /** - * Invoked when the next entry of the stack map frames is visited. - * - * @param pos the position of the frame in the info - * field of attribute_info structure. - * @param nth the frame is the N-th - * (0, 1st, 2nd, 3rd, 4th, ...) entry. - * @return the position of the next frame. - */ - int stackMapFrames(int pos, int nth) throws com.fr.third.javassist.bytecode.BadBytecode { - int type = info[pos] & 0xff; - if (type < 64) { - sameFrame(pos, type); - pos++; - } - else if (type < 128) - pos = sameLocals(pos, type); - else if (type < 247) - throw new com.fr.third.javassist.bytecode.BadBytecode("bad frame_type in StackMapTable"); - else if (type == 247) // SAME_LOCALS_1_STACK_ITEM_EXTENDED - pos = sameLocals(pos, type); - else if (type < 251) { - int offset = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos + 1); - chopFrame(pos, offset, 251 - type); - pos += 3; - } - else if (type == 251) { // SAME_FRAME_EXTENDED - int offset = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos + 1); - sameFrame(pos, offset); - pos += 3; - } - else if (type < 255) - pos = appendFrame(pos, type); - else // FULL_FRAME - pos = fullFrame(pos); - - return pos; - } - - /** - * Invoked if the visited frame is a same_frame or - * a same_frame_extended. - * - * @param pos the position of this frame in the info - * field of attribute_info structure. - * @param offsetDelta - */ - public void sameFrame(int pos, int offsetDelta) throws com.fr.third.javassist.bytecode.BadBytecode {} - - private int sameLocals(int pos, int type) throws com.fr.third.javassist.bytecode.BadBytecode { - int top = pos; - int offset; - if (type < 128) - offset = type - 64; - else { // type == 247 - offset = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos + 1); - pos += 2; - } - - int tag = info[pos + 1] & 0xff; - int data = 0; - if (tag == OBJECT || tag == UNINIT) { - data = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos + 2); - objectOrUninitialized(tag, data, pos + 2); - pos += 2; - } - - sameLocals(top, offset, tag, data); - return pos + 2; - } - - /** - * Invoked if the visited frame is a same_locals_1_stack_item_frame - * or a same_locals_1_stack_item_frame_extended. - * - * @param pos the position. - * @param offsetDelta - * @param stackTag stack[0].tag. - * @param stackData stack[0].cpool_index - * if the tag is OBJECT, - * or stack[0].offset - * if the tag is UNINIT. - */ - public void sameLocals(int pos, int offsetDelta, int stackTag, int stackData) - throws com.fr.third.javassist.bytecode.BadBytecode {} - - /** - * Invoked if the visited frame is a chop_frame. - * - * @param pos the position. - * @param offsetDelta - * @param k the k last locals are absent. - */ - public void chopFrame(int pos, int offsetDelta, int k) throws com.fr.third.javassist.bytecode.BadBytecode {} - - private int appendFrame(int pos, int type) throws com.fr.third.javassist.bytecode.BadBytecode { - int k = type - 251; - int offset = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos + 1); - int[] tags = new int[k]; - int[] data = new int[k]; - int p = pos + 3; - for (int i = 0; i < k; i++) { - int tag = info[p] & 0xff; - tags[i] = tag; - if (tag == OBJECT || tag == UNINIT) { - data[i] = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, p + 1); - objectOrUninitialized(tag, data[i], p + 1); - p += 3; - } - else { - data[i] = 0; - p++; - } - } - - appendFrame(pos, offset, tags, data); - return p; - } - - /** - * Invoked if the visited frame is a append_frame. - * - * @param pos the position. - * @param offsetDelta - * @param tags locals[i].tag. - * @param data locals[i].cpool_index - * or locals[i].offset. - */ - public void appendFrame(int pos, int offsetDelta, int[] tags, int[] data) - throws com.fr.third.javassist.bytecode.BadBytecode {} - - private int fullFrame(int pos) throws com.fr.third.javassist.bytecode.BadBytecode { - int offset = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos + 1); - int numOfLocals = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos + 3); - int[] localsTags = new int[numOfLocals]; - int[] localsData = new int[numOfLocals]; - int p = verifyTypeInfo(pos + 5, numOfLocals, localsTags, localsData); - int numOfItems = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, p); - int[] itemsTags = new int[numOfItems]; - int[] itemsData = new int[numOfItems]; - p = verifyTypeInfo(p + 2, numOfItems, itemsTags, itemsData); - fullFrame(pos, offset, localsTags, localsData, itemsTags, itemsData); - return p; - } - - /** - * Invoked if the visited frame is full_frame. - * - * @param pos the position. - * @param offsetDelta - * @param localTags locals[i].tag - * @param localData locals[i].cpool_index - * or locals[i].offset - * @param stackTags stack[i].tag - * @param stackData stack[i].cpool_index - * or stack[i].offset - */ - public void fullFrame(int pos, int offsetDelta, int[] localTags, int[] localData, - int[] stackTags, int[] stackData) - throws com.fr.third.javassist.bytecode.BadBytecode {} - - private int verifyTypeInfo(int pos, int n, int[] tags, int[] data) { - for (int i = 0; i < n; i++) { - int tag = info[pos++] & 0xff; - tags[i] = tag; - if (tag == OBJECT || tag == UNINIT) { - data[i] = com.fr.third.javassist.bytecode.ByteArray.readU16bit(info, pos); - objectOrUninitialized(tag, data[i], pos); - pos += 2; - } - } - - return pos; - } - - /** - * Invoked if Object_variable_info - * or Uninitialized_variable_info is visited. - * - * @param tag OBJECT or UNINIT. - * @param data the value of cpool_index or offset. - * @param pos the position of cpool_index or offset. - */ - public void objectOrUninitialized(int tag, int data, int pos) {} - } - - static class SimpleCopy extends Walker { - private Writer writer; - - public SimpleCopy(byte[] data) { - super(data); - writer = new Writer(data.length); - } - - public byte[] doit() throws com.fr.third.javassist.bytecode.BadBytecode { - parse(); - return writer.toByteArray(); - } - - public void sameFrame(int pos, int offsetDelta) { - writer.sameFrame(offsetDelta); - } - - public void sameLocals(int pos, int offsetDelta, int stackTag, int stackData) { - writer.sameLocals(offsetDelta, stackTag, copyData(stackTag, stackData)); - } - - public void chopFrame(int pos, int offsetDelta, int k) { - writer.chopFrame(offsetDelta, k); - } - - public void appendFrame(int pos, int offsetDelta, int[] tags, int[] data) { - writer.appendFrame(offsetDelta, tags, copyData(tags, data)); - } - - public void fullFrame(int pos, int offsetDelta, int[] localTags, int[] localData, - int[] stackTags, int[] stackData) { - writer.fullFrame(offsetDelta, localTags, copyData(localTags, localData), - stackTags, copyData(stackTags, stackData)); - } - - protected int copyData(int tag, int data) { - return data; - } - - protected int[] copyData(int[] tags, int[] data) { - return data; - } - } - - static class Copier extends SimpleCopy { - private com.fr.third.javassist.bytecode.ConstPool srcPool, destPool; - private Map classnames; - - public Copier(com.fr.third.javassist.bytecode.ConstPool src, byte[] data, com.fr.third.javassist.bytecode.ConstPool dest, Map names) { - super(data); - srcPool = src; - destPool = dest; - classnames = names; - } - - protected int copyData(int tag, int data) { - if (tag == OBJECT) - return srcPool.copy(data, destPool, classnames); - else - return data; - } - - protected int[] copyData(int[] tags, int[] data) { - int[] newData = new int[data.length]; - for (int i = 0; i < data.length; i++) - if (tags[i] == OBJECT) - newData[i] = srcPool.copy(data[i], destPool, classnames); - else - newData[i] = data[i]; - - return newData; - } - } - - /** - * Updates this stack map table when a new local variable is inserted - * for a new parameter. - * - * @param index the index of the added local variable. - * @param tag the type tag of that local variable. - * @param classInfo the index of the CONSTANT_Class_info structure - * in a constant pool table. This should be zero unless the tag - * is ITEM_Object. - * - * @see CtBehavior#addParameter(CtClass) - * @see #typeTagOf(char) - * @see com.fr.third.javassist.bytecode.ConstPool - */ - public void insertLocal(int index, int tag, int classInfo) - throws com.fr.third.javassist.bytecode.BadBytecode - { - byte[] data = new InsertLocal(this.get(), index, tag, classInfo).doit(); - this.set(data); - } - - /** - * Returns the tag of the type specified by the - * descriptor. This method returns INTEGER - * unless the descriptor is either D (double), F (float), - * J (long), L (class type), or [ (array). - * - * @param descriptor the type descriptor. - * @see Descriptor - */ - public static int typeTagOf(char descriptor) { - switch (descriptor) { - case 'D' : - return DOUBLE; - case 'F' : - return FLOAT; - case 'J' : - return LONG; - case 'L' : - case '[' : - return OBJECT; - // case 'V' : - default : - return INTEGER; - } - } - - /* This implementation assumes that a local variable initially - * holding a parameter value is never changed to be a different - * type. - * - */ - static class InsertLocal extends SimpleCopy { - private int varIndex; - private int varTag, varData; - - public InsertLocal(byte[] data, int varIndex, int varTag, int varData) { - super(data); - this.varIndex = varIndex; - this.varTag = varTag; - this.varData = varData; - } - - public void fullFrame(int pos, int offsetDelta, int[] localTags, int[] localData, - int[] stackTags, int[] stackData) { - int len = localTags.length; - if (len < varIndex) { - super.fullFrame(pos, offsetDelta, localTags, localData, stackTags, stackData); - return; - } - - int typeSize = (varTag == LONG || varTag == DOUBLE) ? 2 : 1; - int[] localTags2 = new int[len + typeSize]; - int[] localData2 = new int[len + typeSize]; - int index = varIndex; - int j = 0; - for (int i = 0; i < len; i++) { - if (j == index) - j += typeSize; - - localTags2[j] = localTags[i]; - localData2[j++] = localData[i]; - } - - localTags2[index] = varTag; - localData2[index] = varData; - if (typeSize > 1) { - localTags2[index + 1] = TOP; - localData2[index + 1] = 0; - } - - super.fullFrame(pos, offsetDelta, localTags2, localData2, stackTags, stackData); - } - } - - /** - * A writer of stack map tables. - */ - public static class Writer { - ByteArrayOutputStream output; - int numOfEntries; - - /** - * Constructs a writer. - * @param size the initial buffer size. - */ - public Writer(int size) { - output = new ByteArrayOutputStream(size); - numOfEntries = 0; - output.write(0); // u2 number_of_entries - output.write(0); - } - - /** - * Returns the stack map table written out. - */ - public byte[] toByteArray() { - byte[] b = output.toByteArray(); - com.fr.third.javassist.bytecode.ByteArray.write16bit(numOfEntries, b, 0); - return b; - } - - /** - * Constructs and a return a stack map table containing - * the written stack map entries. - * - * @param cp the constant pool used to write - * the stack map entries. - */ - public StackMapTable toStackMapTable(ConstPool cp) { - return new StackMapTable(cp, toByteArray()); - } - - /** - * Writes a same_frame or a same_frame_extended. - */ - public void sameFrame(int offsetDelta) { - numOfEntries++; - if (offsetDelta < 64) - output.write(offsetDelta); - else { - output.write(251); // SAME_FRAME_EXTENDED - write16(offsetDelta); - } - } - - /** - * Writes a same_locals_1_stack_item - * or a same_locals_1_stack_item_extended. - * - * @param tag stack[0].tag. - * @param data stack[0].cpool_index - * if the tag is OBJECT, - * or stack[0].offset - * if the tag is UNINIT. - * Otherwise, this parameter is not used. - */ - public void sameLocals(int offsetDelta, int tag, int data) { - numOfEntries++; - if (offsetDelta < 64) - output.write(offsetDelta + 64); - else { - output.write(247); // SAME_LOCALS_1_STACK_ITEM_EXTENDED - write16(offsetDelta); - } - - writeTypeInfo(tag, data); - } - - /** - * Writes a chop_frame. - * - * @param k the number of absent locals. 1, 2, or 3. - */ - public void chopFrame(int offsetDelta, int k) { - numOfEntries++; - output.write(251 - k); - write16(offsetDelta); - } - - /** - * Writes a append_frame. The number of the appended - * locals is specified by the length of tags. - * - * @param tags locals[].tag. - * The length of this array must be - * either 1, 2, or 3. - * @param data locals[].cpool_index - * if the tag is OBJECT, - * or locals[].offset - * if the tag is UNINIT. - * Otherwise, this parameter is not used. - */ - public void appendFrame(int offsetDelta, int[] tags, int[] data) { - numOfEntries++; - int k = tags.length; // k is 1, 2, or 3 - output.write(k + 251); - write16(offsetDelta); - for (int i = 0; i < k; i++) - writeTypeInfo(tags[i], data[i]); - } - - /** - * Writes a full_frame. - * number_of_locals and number_of_stack_items - * are specified by the the length of localTags and - * stackTags. - * - * @param localTags locals[].tag. - * @param localData locals[].cpool_index - * if the tag is OBJECT, - * or locals[].offset - * if the tag is UNINIT. - * Otherwise, this parameter is not used. - * @param stackTags stack[].tag. - * @param stackData stack[].cpool_index - * if the tag is OBJECT, - * or stack[].offset - * if the tag is UNINIT. - * Otherwise, this parameter is not used. - */ - public void fullFrame(int offsetDelta, int[] localTags, int[] localData, - int[] stackTags, int[] stackData) { - numOfEntries++; - output.write(255); // FULL_FRAME - write16(offsetDelta); - int n = localTags.length; - write16(n); - for (int i = 0; i < n; i++) - writeTypeInfo(localTags[i], localData[i]); - - n = stackTags.length; - write16(n); - for (int i = 0; i < n; i++) - writeTypeInfo(stackTags[i], stackData[i]); - } - - private void writeTypeInfo(int tag, int data) { - output.write(tag); - if (tag == OBJECT || tag == UNINIT) - write16(data); - } - - private void write16(int value) { - output.write((value >>> 8) & 0xff); - output.write(value & 0xff); - } - } - - /** - * Prints the stack table map. - */ - public void println(PrintWriter w) { - Printer.print(this, w); - } - - /** - * Prints the stack table map. - * - * @param ps a print stream such as System.out. - */ - public void println(java.io.PrintStream ps) { - Printer.print(this, new java.io.PrintWriter(ps, true)); - } - - static class Printer extends Walker { - private PrintWriter writer; - private int offset; - - /** - * Prints the stack table map. - */ - public static void print(StackMapTable smt, PrintWriter writer) { - try { - new Printer(smt.get(), writer).parse(); - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - writer.println(e.getMessage()); - } - } - - Printer(byte[] data, PrintWriter pw) { - super(data); - writer = pw; - offset = -1; - } - - public void sameFrame(int pos, int offsetDelta) { - offset += offsetDelta + 1; - writer.println(offset + " same frame: " + offsetDelta); - } - - public void sameLocals(int pos, int offsetDelta, int stackTag, int stackData) { - offset += offsetDelta + 1; - writer.println(offset + " same locals: " + offsetDelta); - printTypeInfo(stackTag, stackData); - } - - public void chopFrame(int pos, int offsetDelta, int k) { - offset += offsetDelta + 1; - writer.println(offset + " chop frame: " + offsetDelta + ", " + k + " last locals"); - } - - public void appendFrame(int pos, int offsetDelta, int[] tags, int[] data) { - offset += offsetDelta + 1; - writer.println(offset + " append frame: " + offsetDelta); - for (int i = 0; i < tags.length; i++) - printTypeInfo(tags[i], data[i]); - } - - public void fullFrame(int pos, int offsetDelta, int[] localTags, int[] localData, - int[] stackTags, int[] stackData) { - offset += offsetDelta + 1; - writer.println(offset + " full frame: " + offsetDelta); - writer.println("[locals]"); - for (int i = 0; i < localTags.length; i++) - printTypeInfo(localTags[i], localData[i]); - - writer.println("[stack]"); - for (int i = 0; i < stackTags.length; i++) - printTypeInfo(stackTags[i], stackData[i]); - } - - private void printTypeInfo(int tag, int data) { - String msg = null; - switch (tag) { - case TOP : - msg = "top"; - break; - case INTEGER : - msg = "integer"; - break; - case FLOAT : - msg = "float"; - break; - case DOUBLE : - msg = "double"; - break; - case LONG : - msg = "long"; - break; - case NULL : - msg = "null"; - break; - case THIS : - msg = "this"; - break; - case OBJECT : - msg = "object (cpool_index " + data + ")"; - break; - case UNINIT : - msg = "uninitialized (offset " + data + ")"; - break; - } - - writer.print(" "); - writer.println(msg); - } - } - - void shiftPc(int where, int gapSize, boolean exclusive) - throws com.fr.third.javassist.bytecode.BadBytecode - { - new OffsetShifter(this, where, gapSize).parse(); - new Shifter(this, where, gapSize, exclusive).doit(); - } - - static class OffsetShifter extends Walker { - int where, gap; - - public OffsetShifter(StackMapTable smt, int where, int gap) { - super(smt); - this.where = where; - this.gap = gap; - } - - public void objectOrUninitialized(int tag, int data, int pos) { - if (tag == UNINIT) - if (where <= data) - com.fr.third.javassist.bytecode.ByteArray.write16bit(data + gap, info, pos); - } - } - - static class Shifter extends Walker { - private StackMapTable stackMap; - int where, gap; - int position; - byte[] updatedInfo; - boolean exclusive; - - public Shifter(StackMapTable smt, int where, int gap, boolean exclusive) { - super(smt); - stackMap = smt; - this.where = where; - this.gap = gap; - this.position = 0; - this.updatedInfo = null; - this.exclusive = exclusive; - } - - public void doit() throws com.fr.third.javassist.bytecode.BadBytecode { - parse(); - if (updatedInfo != null) - stackMap.set(updatedInfo); - } - - public void sameFrame(int pos, int offsetDelta) { - update(pos, offsetDelta, 0, 251); - } - - public void sameLocals(int pos, int offsetDelta, int stackTag, int stackData) { - update(pos, offsetDelta, 64, 247); - } - - void update(int pos, int offsetDelta, int base, int entry) { - int oldPos = position; - position = oldPos + offsetDelta + (oldPos == 0 ? 0 : 1); - boolean match; - if (exclusive) - match = oldPos < where && where <= position; - else - match = oldPos <= where && where < position; - - if (match) { - int newDelta = offsetDelta + gap; - position += gap; - if (newDelta < 64) - info[pos] = (byte)(newDelta + base); - else if (offsetDelta < 64) { - byte[] newinfo = insertGap(info, pos, 2); - newinfo[pos] = (byte)entry; - com.fr.third.javassist.bytecode.ByteArray.write16bit(newDelta, newinfo, pos + 1); - updatedInfo = newinfo; - } - else - com.fr.third.javassist.bytecode.ByteArray.write16bit(newDelta, info, pos + 1); - } - } - - static byte[] insertGap(byte[] info, int where, int gap) { - int len = info.length; - byte[] newinfo = new byte[len + gap]; - for (int i = 0; i < len; i++) - newinfo[i + (i < where ? 0 : gap)] = info[i]; - - return newinfo; - } - - public void chopFrame(int pos, int offsetDelta, int k) { - update(pos, offsetDelta); - } - - public void appendFrame(int pos, int offsetDelta, int[] tags, int[] data) { - update(pos, offsetDelta); - } - - public void fullFrame(int pos, int offsetDelta, int[] localTags, int[] localData, - int[] stackTags, int[] stackData) { - update(pos, offsetDelta); - } - - void update(int pos, int offsetDelta) { - int oldPos = position; - position = oldPos + offsetDelta + (oldPos == 0 ? 0 : 1); - boolean match; - if (exclusive) - match = oldPos < where && where <= position; - else - match = oldPos <= where && where < position; - - if (match) { - int newDelta = offsetDelta + gap; - com.fr.third.javassist.bytecode.ByteArray.write16bit(newDelta, info, pos + 1); - position += gap; - } - } - } - - /** - * @see CodeIterator.Switcher#adjustOffsets(int, int) - */ - void shiftForSwitch(int where, int gapSize) throws com.fr.third.javassist.bytecode.BadBytecode { - new SwitchShifter(this, where, gapSize).doit(); - } - - static class SwitchShifter extends Shifter { - SwitchShifter(StackMapTable smt, int where, int gap) { - super(smt, where, gap, false); - } - - void update(int pos, int offsetDelta, int base, int entry) { - int oldPos = position; - position = oldPos + offsetDelta + (oldPos == 0 ? 0 : 1); - int newDelta = offsetDelta; - if (where == position) - newDelta = offsetDelta - gap; - else if (where == oldPos) - newDelta = offsetDelta + gap; - else - return; - - if (offsetDelta < 64) - if (newDelta < 64) - info[pos] = (byte)(newDelta + base); - else { - byte[] newinfo = insertGap(info, pos, 2); - newinfo[pos] = (byte)entry; - com.fr.third.javassist.bytecode.ByteArray.write16bit(newDelta, newinfo, pos + 1); - updatedInfo = newinfo; - } - else - if (newDelta < 64) { - byte[] newinfo = deleteGap(info, pos, 2); - newinfo[pos] = (byte)(newDelta + base); - updatedInfo = newinfo; - } - else - com.fr.third.javassist.bytecode.ByteArray.write16bit(newDelta, info, pos + 1); - } - - static byte[] deleteGap(byte[] info, int where, int gap) { - where += gap; - int len = info.length; - byte[] newinfo = new byte[len - gap]; - for (int i = 0; i < len; i++) - newinfo[i - (i < where ? 0 : gap)] = info[i]; - - return newinfo; - } - - void update(int pos, int offsetDelta) { - int oldPos = position; - position = oldPos + offsetDelta + (oldPos == 0 ? 0 : 1); - int newDelta = offsetDelta; - if (where == position) - newDelta = offsetDelta - gap; - else if (where == oldPos) - newDelta = offsetDelta + gap; - else - return; - - ByteArray.write16bit(newDelta, info, pos + 1); - } - } - - /** - * Undocumented method. Do not use; internal-use only. - * - *

This method is for javassist.convert.TransformNew. - * It is called to update the stack map table when - * the NEW opcode (and the following DUP) is removed. - * - * @param where the position of the removed NEW opcode. - */ - public void removeNew(int where) throws CannotCompileException { - try { - byte[] data = new NewRemover(this.get(), where).doit(); - this.set(data); - } - catch (BadBytecode e) { - throw new CannotCompileException("bad stack map table", e); - } - } - - static class NewRemover extends SimpleCopy { - int posOfNew; - - public NewRemover(byte[] data, int pos) { - super(data); - posOfNew = pos; - } - - public void sameLocals(int pos, int offsetDelta, int stackTag, int stackData) { - if (stackTag == UNINIT && stackData == posOfNew) - super.sameFrame(pos, offsetDelta); - else - super.sameLocals(pos, offsetDelta, stackTag, stackData); - } - - public void fullFrame(int pos, int offsetDelta, int[] localTags, int[] localData, - int[] stackTags, int[] stackData) { - int n = stackTags.length - 1; - for (int i = 0; i < n; i++) - if (stackTags[i] == UNINIT && stackData[i] == posOfNew - && stackTags[i + 1] == UNINIT && stackData[i + 1] == posOfNew) { - n++; - int[] stackTags2 = new int[n - 2]; - int[] stackData2 = new int[n - 2]; - int k = 0; - for (int j = 0; j < n; j++) - if (j == i) - j++; - else { - stackTags2[k] = stackTags[j]; - stackData2[k++] = stackData[j]; - } - - stackTags = stackTags2; - stackData = stackData2; - break; - } - - super.fullFrame(pos, offsetDelta, localTags, localData, stackTags, stackData); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/SyntheticAttribute.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/SyntheticAttribute.java deleted file mode 100644 index 1d5829417..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/SyntheticAttribute.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode; - -import java.io.DataInputStream; -import java.io.IOException; -import java.util.Map; - -/** - * Synthetic_attribute. - */ -public class SyntheticAttribute extends com.fr.third.javassist.bytecode.AttributeInfo { - /** - * The name of this attribute "Synthetic". - */ - public static final String tag = "Synthetic"; - - SyntheticAttribute(com.fr.third.javassist.bytecode.ConstPool cp, int n, DataInputStream in) - throws IOException - { - super(cp, n, in); - } - - /** - * Constructs a Synthetic attribute. - * - * @param cp a constant pool table. - */ - public SyntheticAttribute(com.fr.third.javassist.bytecode.ConstPool cp) { - super(cp, tag, new byte[0]); - } - - /** - * Makes a copy. - * - * @param newCp the constant pool table used by the new copy. - * @param classnames should be null. - */ - public AttributeInfo copy(ConstPool newCp, Map classnames) { - return new SyntheticAttribute(newCp); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Analyzer.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Analyzer.java deleted file mode 100644 index 6a14a57b5..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Analyzer.java +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.bytecode.analysis; - -import java.util.Iterator; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CtMethod; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.bytecode.AccessFlag; -import com.fr.third.javassist.bytecode.BadBytecode; -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.bytecode.CodeIterator; -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.bytecode.Descriptor; -import com.fr.third.javassist.bytecode.ExceptionTable; -import com.fr.third.javassist.bytecode.MethodInfo; -import com.fr.third.javassist.bytecode.Opcode; - -/** - * A data-flow analyzer that determines the type state of the stack and local - * variable table at every reachable instruction in a method. During analysis, - * bytecode verification is performed in a similar manner to that described - * in the JVM specification. - * - *

Example:

- * - *
- * // Method to analyze
- * public Object doSomething(int x) {
- *     Number n;
- *     if (x < 5) {
- *        n = new Double(0);
- *     } else {
- *        n = new Long(0);
- *     }
- *
- *     return n;
- * }
- *
- * // Which compiles to:
- * // 0:   iload_1
- * // 1:   iconst_5
- * // 2:   if_icmpge   17
- * // 5:   new #18; //class java/lang/Double
- * // 8:   dup
- * // 9:   dconst_0
- * // 10:  invokespecial   #44; //Method java/lang/Double."":(D)V
- * // 13:  astore_2
- * // 14:  goto    26
- * // 17:  new #16; //class java/lang/Long
- * // 20:  dup
- * // 21:  lconst_1
- * // 22:  invokespecial   #47; //Method java/lang/Long."":(J)V
- * // 25:  astore_2
- * // 26:  aload_2
- * // 27:  areturn
- *
- * public void analyzeIt(CtClass clazz, MethodInfo method) {
- *     Analyzer analyzer = new Analyzer();
- *     Frame[] frames = analyzer.analyze(clazz, method);
- *     frames[0].getLocal(0).getCtClass(); // returns clazz;
- *     frames[0].getLocal(1).getCtClass(); // returns java.lang.String
- *     frames[1].peek(); // returns Type.INTEGER
- *     frames[27].peek().getCtClass(); // returns java.lang.Number
- * }
- * 
- * - * @see FramePrinter - * @author Jason T. Greene - */ -public class Analyzer implements Opcode { - private final SubroutineScanner scanner = new SubroutineScanner(); - private CtClass clazz; - private ExceptionInfo[] exceptions; - private com.fr.third.javassist.bytecode.analysis.Frame[] frames; - private Subroutine[] subroutines; - - private static class ExceptionInfo { - private int end; - private int handler; - private int start; - private com.fr.third.javassist.bytecode.analysis.Type type; - - private ExceptionInfo(int start, int end, int handler, com.fr.third.javassist.bytecode.analysis.Type type) { - this.start = start; - this.end = end; - this.handler = handler; - this.type = type; - } - } - - /** - * Performs data-flow analysis on a method and returns an array, indexed by - * instruction position, containing the starting frame state of all reachable - * instructions. Non-reachable code, and illegal code offsets are represented - * as a null in the frame state array. This can be used to detect dead code. - * - * If the method does not contain code (it is either native or abstract), null - * is returned. - * - * @param clazz the declaring class of the method - * @param method the method to analyze - * @return an array, indexed by instruction position, of the starting frame state, - * or null if this method doesn't have code - * @throws BadBytecode if the bytecode does not comply with the JVM specification - */ - public com.fr.third.javassist.bytecode.analysis.Frame[] analyze(CtClass clazz, MethodInfo method) throws BadBytecode { - this.clazz = clazz; - CodeAttribute codeAttribute = method.getCodeAttribute(); - // Native or Abstract - if (codeAttribute == null) - return null; - - int maxLocals = codeAttribute.getMaxLocals(); - int maxStack = codeAttribute.getMaxStack(); - int codeLength = codeAttribute.getCodeLength(); - - CodeIterator iter = codeAttribute.iterator(); - IntQueue queue = new IntQueue(); - - exceptions = buildExceptionInfo(method); - subroutines = scanner.scan(method); - - Executor executor = new Executor(clazz.getClassPool(), method.getConstPool()); - frames = new com.fr.third.javassist.bytecode.analysis.Frame[codeLength]; - frames[iter.lookAhead()] = firstFrame(method, maxLocals, maxStack); - queue.add(iter.next()); - while (!queue.isEmpty()) { - analyzeNextEntry(method, iter, queue, executor); - } - - return frames; - } - - /** - * Performs data-flow analysis on a method and returns an array, indexed by - * instruction position, containing the starting frame state of all reachable - * instructions. Non-reachable code, and illegal code offsets are represented - * as a null in the frame state array. This can be used to detect dead code. - * - * If the method does not contain code (it is either native or abstract), null - * is returned. - * - * @param method the method to analyze - * @return an array, indexed by instruction position, of the starting frame state, - * or null if this method doesn't have code - * @throws BadBytecode if the bytecode does not comply with the JVM specification - */ - public com.fr.third.javassist.bytecode.analysis.Frame[] analyze(CtMethod method) throws BadBytecode { - return analyze(method.getDeclaringClass(), method.getMethodInfo2()); - } - - private void analyzeNextEntry(MethodInfo method, CodeIterator iter, - IntQueue queue, Executor executor) throws BadBytecode { - int pos = queue.take(); - iter.move(pos); - iter.next(); - - com.fr.third.javassist.bytecode.analysis.Frame frame = frames[pos].copy(); - Subroutine subroutine = subroutines[pos]; - - try { - executor.execute(method, pos, iter, frame, subroutine); - } catch (RuntimeException e) { - throw new BadBytecode(e.getMessage() + "[pos = " + pos + "]", e); - } - - int opcode = iter.byteAt(pos); - - if (opcode == TABLESWITCH) { - mergeTableSwitch(queue, pos, iter, frame); - } else if (opcode == LOOKUPSWITCH) { - mergeLookupSwitch(queue, pos, iter, frame); - } else if (opcode == RET) { - mergeRet(queue, iter, pos, frame, subroutine); - } else if (com.fr.third.javassist.bytecode.analysis.Util.isJumpInstruction(opcode)) { - int target = com.fr.third.javassist.bytecode.analysis.Util.getJumpTarget(pos, iter); - - if (com.fr.third.javassist.bytecode.analysis.Util.isJsr(opcode)) { - // Merge the state before the jsr into the next instruction - mergeJsr(queue, frames[pos], subroutines[target], pos, lookAhead(iter, pos)); - } else if (! com.fr.third.javassist.bytecode.analysis.Util.isGoto(opcode)) { - merge(queue, frame, lookAhead(iter, pos)); - } - - merge(queue, frame, target); - } else if (opcode != ATHROW && ! Util.isReturn(opcode)) { - // Can advance to next instruction - merge(queue, frame, lookAhead(iter, pos)); - } - - // Merge all exceptions that are reachable from this instruction. - // The redundancy is intentional, since the state must be based - // on the current instruction frame. - mergeExceptionHandlers(queue, method, pos, frame); - } - - private ExceptionInfo[] buildExceptionInfo(MethodInfo method) { - ConstPool constPool = method.getConstPool(); - ClassPool classes = clazz.getClassPool(); - - ExceptionTable table = method.getCodeAttribute().getExceptionTable(); - ExceptionInfo[] exceptions = new ExceptionInfo[table.size()]; - for (int i = 0; i < table.size(); i++) { - int index = table.catchType(i); - com.fr.third.javassist.bytecode.analysis.Type type; - try { - type = index == 0 ? com.fr.third.javassist.bytecode.analysis.Type.THROWABLE : com.fr.third.javassist.bytecode.analysis.Type.get(classes.get(constPool.getClassInfo(index))); - } catch (NotFoundException e) { - throw new IllegalStateException(e.getMessage()); - } - - exceptions[i] = new ExceptionInfo(table.startPc(i), table.endPc(i), table.handlerPc(i), type); - } - - return exceptions; - } - - private com.fr.third.javassist.bytecode.analysis.Frame firstFrame(MethodInfo method, int maxLocals, int maxStack) { - int pos = 0; - - com.fr.third.javassist.bytecode.analysis.Frame first = new com.fr.third.javassist.bytecode.analysis.Frame(maxLocals, maxStack); - if ((method.getAccessFlags() & AccessFlag.STATIC) == 0) { - first.setLocal(pos++, com.fr.third.javassist.bytecode.analysis.Type.get(clazz)); - } - - CtClass[] parameters; - try { - parameters = Descriptor.getParameterTypes(method.getDescriptor(), clazz.getClassPool()); - } catch (NotFoundException e) { - throw new RuntimeException(e); - } - - for (int i = 0; i < parameters.length; i++) { - com.fr.third.javassist.bytecode.analysis.Type type = zeroExtend(com.fr.third.javassist.bytecode.analysis.Type.get(parameters[i])); - first.setLocal(pos++, type); - if (type.getSize() == 2) - first.setLocal(pos++, com.fr.third.javassist.bytecode.analysis.Type.TOP); - } - - return first; - } - - private int getNext(CodeIterator iter, int of, int restore) throws BadBytecode { - iter.move(of); - iter.next(); - int next = iter.lookAhead(); - iter.move(restore); - iter.next(); - - return next; - } - - private int lookAhead(CodeIterator iter, int pos) throws BadBytecode { - if (! iter.hasNext()) - throw new BadBytecode("Execution falls off end! [pos = " + pos + "]"); - - return iter.lookAhead(); - } - - - private void merge(IntQueue queue, com.fr.third.javassist.bytecode.analysis.Frame frame, int target) { - com.fr.third.javassist.bytecode.analysis.Frame old = frames[target]; - boolean changed; - - if (old == null) { - frames[target] = frame.copy(); - changed = true; - } else { - changed = old.merge(frame); - } - - if (changed) { - queue.add(target); - } - } - - private void mergeExceptionHandlers(IntQueue queue, MethodInfo method, int pos, com.fr.third.javassist.bytecode.analysis.Frame frame) { - for (int i = 0; i < exceptions.length; i++) { - ExceptionInfo exception = exceptions[i]; - - // Start is inclusive, while end is exclusive! - if (pos >= exception.start && pos < exception.end) { - com.fr.third.javassist.bytecode.analysis.Frame newFrame = frame.copy(); - newFrame.clearStack(); - newFrame.push(exception.type); - merge(queue, newFrame, exception.handler); - } - } - } - - private void mergeJsr(IntQueue queue, com.fr.third.javassist.bytecode.analysis.Frame frame, Subroutine sub, int pos, int next) throws BadBytecode { - if (sub == null) - throw new BadBytecode("No subroutine at jsr target! [pos = " + pos + "]"); - - com.fr.third.javassist.bytecode.analysis.Frame old = frames[next]; - boolean changed = false; - - if (old == null) { - old = frames[next] = frame.copy(); - changed = true; - } else { - for (int i = 0; i < frame.localsLength(); i++) { - // Skip everything accessed by a subroutine, mergeRet must handle this - if (!sub.isAccessed(i)) { - com.fr.third.javassist.bytecode.analysis.Type oldType = old.getLocal(i); - com.fr.third.javassist.bytecode.analysis.Type newType = frame.getLocal(i); - if (oldType == null) { - old.setLocal(i, newType); - changed = true; - continue; - } - - newType = oldType.merge(newType); - // Always set the type, in case a multi-type switched to a standard type. - old.setLocal(i, newType); - if (!newType.equals(oldType) || newType.popChanged()) - changed = true; - } - } - } - - if (! old.isJsrMerged()) { - old.setJsrMerged(true); - changed = true; - } - - if (changed && old.isRetMerged()) - queue.add(next); - - } - - private void mergeLookupSwitch(IntQueue queue, int pos, CodeIterator iter, com.fr.third.javassist.bytecode.analysis.Frame frame) throws BadBytecode { - int index = (pos & ~3) + 4; - // default - merge(queue, frame, pos + iter.s32bitAt(index)); - int npairs = iter.s32bitAt(index += 4); - int end = npairs * 8 + (index += 4); - - // skip "match" - for (index += 4; index < end; index += 8) { - int target = iter.s32bitAt(index) + pos; - merge(queue, frame, target); - } - } - - private void mergeRet(IntQueue queue, CodeIterator iter, int pos, com.fr.third.javassist.bytecode.analysis.Frame frame, Subroutine subroutine) throws BadBytecode { - if (subroutine == null) - throw new BadBytecode("Ret on no subroutine! [pos = " + pos + "]"); - - Iterator callerIter = subroutine.callers().iterator(); - while (callerIter.hasNext()) { - int caller = ((Integer) callerIter.next()).intValue(); - int returnLoc = getNext(iter, caller, pos); - boolean changed = false; - - com.fr.third.javassist.bytecode.analysis.Frame old = frames[returnLoc]; - if (old == null) { - old = frames[returnLoc] = frame.copyStack(); - changed = true; - } else { - changed = old.mergeStack(frame); - } - - for (Iterator i = subroutine.accessed().iterator(); i.hasNext(); ) { - int index = ((Integer)i.next()).intValue(); - com.fr.third.javassist.bytecode.analysis.Type oldType = old.getLocal(index); - com.fr.third.javassist.bytecode.analysis.Type newType = frame.getLocal(index); - if (oldType != newType) { - old.setLocal(index, newType); - changed = true; - } - } - - if (! old.isRetMerged()) { - old.setRetMerged(true); - changed = true; - } - - if (changed && old.isJsrMerged()) - queue.add(returnLoc); - } - } - - - private void mergeTableSwitch(IntQueue queue, int pos, CodeIterator iter, Frame frame) throws BadBytecode { - // Skip 4 byte alignment padding - int index = (pos & ~3) + 4; - // default - merge(queue, frame, pos + iter.s32bitAt(index)); - int low = iter.s32bitAt(index += 4); - int high = iter.s32bitAt(index += 4); - int end = (high - low + 1) * 4 + (index += 4); - - // Offset table - for (; index < end; index += 4) { - int target = iter.s32bitAt(index) + pos; - merge(queue, frame, target); - } - } - - private com.fr.third.javassist.bytecode.analysis.Type zeroExtend(com.fr.third.javassist.bytecode.analysis.Type type) { - if (type == com.fr.third.javassist.bytecode.analysis.Type.SHORT || type == com.fr.third.javassist.bytecode.analysis.Type.BYTE || type == com.fr.third.javassist.bytecode.analysis.Type.CHAR || type == com.fr.third.javassist.bytecode.analysis.Type.BOOLEAN) - return Type.INTEGER; - - return type; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/ControlFlow.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/ControlFlow.java deleted file mode 100644 index f8f16f990..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/ControlFlow.java +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.analysis; - -import java.util.ArrayList; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CtMethod; -import com.fr.third.javassist.bytecode.BadBytecode; -import com.fr.third.javassist.bytecode.MethodInfo; -import com.fr.third.javassist.bytecode.stackmap.BasicBlock; - -/** - * Represents the control flow graph of a given method. - * - *

To obtain the control flow graph, do the following:

- * - *
CtMethod m = ...
- * ControlFlow cf = new ControlFlow(m);
- * Block[] blocks = cf.basicBlocks();
- * 
- * - *

blocks is an array of basic blocks in - * that method body.

- * - * @see CtMethod - * @see Block - * @see com.fr.third.javassist.bytecode.analysis.Frame - * @see com.fr.third.javassist.bytecode.analysis.Analyzer - * @author Shigeru Chiba - * @since 3.16 - */ -public class ControlFlow { - private CtClass clazz; - private MethodInfo methodInfo; - private Block[] basicBlocks; - private com.fr.third.javassist.bytecode.analysis.Frame[] frames; - - /** - * Constructs a control-flow analyzer for the given method. - */ - public ControlFlow(CtMethod method) throws BadBytecode { - this(method.getDeclaringClass(), method.getMethodInfo2()); - } - - /** - * Constructs a control-flow analyzer. - */ - public ControlFlow(CtClass ctclazz, MethodInfo minfo) throws BadBytecode { - clazz = ctclazz; - methodInfo = minfo; - frames = null; - basicBlocks = (Block[])new BasicBlock.Maker() { - protected BasicBlock makeBlock(int pos) { - return new Block(pos, methodInfo); - } - protected BasicBlock[] makeArray(int size) { - return new Block[size]; - } - }.make(minfo); - int size = basicBlocks.length; - int[] counters = new int[size]; - for (int i = 0; i < size; i++) { - Block b = basicBlocks[i]; - b.index = i; - b.entrances = new Block[b.incomings()]; - counters[i] = 0; - } - - for (int i = 0; i < size; i++) { - Block b = basicBlocks[i]; - for (int k = 0; k < b.exits(); k++) { - Block e = b.exit(k); - e.entrances[counters[e.index]++] = b; - } - - ControlFlow.Catcher[] catchers = b.catchers(); - for (int k = 0; k < catchers.length; k++) { - Block catchBlock = catchers[k].node; - catchBlock.entrances[counters[catchBlock.index]++] = b; - } - } - } - - /** - * Returns all the basic blocks in the method body. - */ - public Block[] basicBlocks() { - return basicBlocks; - } - - /** - * Returns the types of the local variables and stack frame entries - * available at the given position. If the byte at the position is - * not the first byte of an instruction, then this method returns - * null. - * - * @param pos the position. - */ - public Frame frameAt(int pos) throws BadBytecode { - if (frames == null) - frames = new Analyzer().analyze(clazz, methodInfo); - - return frames[pos]; - } - - /** - * Constructs a dominator tree. This method returns an array of - * the tree nodes. The first element of the array is the root - * of the tree. - * - *

The order of the elements is the same as that - * of the elements in the Block array returned - * by the basicBlocks - * method. If a Block object is at the i-th position - * in the Block array, then - * the Node object referring to that - * Block object is at the i-th position in the - * array returned by this method. - * For every array element node, its index in the - * array is equivalent to node.block().index(). - * - * @return an array of the tree nodes, or null if the method is abstract. - * @see Node#block() - * @see Block#index() - */ - public Node[] dominatorTree() { - int size = basicBlocks.length; - if (size == 0) - return null; - - Node[] nodes = new Node[size]; - boolean[] visited = new boolean[size]; - int[] distance = new int[size]; - for (int i = 0; i < size; i++) { - nodes[i] = new Node(basicBlocks[i]); - visited[i] = false; - } - - Access access = new Access(nodes) { - BasicBlock[] exits(Node n) { return n.block.getExit(); } - BasicBlock[] entrances(Node n) { return n.block.entrances; } - }; - nodes[0].makeDepth1stTree(null, visited, 0, distance, access); - do { - for (int i = 0; i < size; i++) - visited[i] = false; - } while (nodes[0].makeDominatorTree(visited, distance, access)); - Node.setChildren(nodes); - return nodes; - } - - /** - * Constructs a post dominator tree. This method returns an array of - * the tree nodes. Note that the tree has multiple roots. - * The parent of the root nodes is null. - * - *

The order of the elements is the same as that - * of the elements in the Block array returned - * by the basicBlocks - * method. If a Block object is at the i-th position - * in the Block array, then - * the Node object referring to that - * Block object is at the i-th position in the - * array returned by this method. - * For every array element node, its index in the - * array is equivalent to node.block().index(). - * - * @return an array of the tree nodes, or null if the method is abstract. - * @see Node#block() - * @see Block#index() - */ - public Node[] postDominatorTree() { - int size = basicBlocks.length; - if (size == 0) - return null; - - Node[] nodes = new Node[size]; - boolean[] visited = new boolean[size]; - int[] distance = new int[size]; - for (int i = 0; i < size; i++) { - nodes[i] = new Node(basicBlocks[i]); - visited[i] = false; - } - - Access access = new Access(nodes) { - BasicBlock[] exits(Node n) { return n.block.entrances; } - BasicBlock[] entrances(Node n) { return n.block.getExit(); } - }; - - int counter = 0; - for (int i = 0; i < size; i++) - if (nodes[i].block.exits() == 0) - counter = nodes[i].makeDepth1stTree(null, visited, counter, distance, access); - - boolean changed; - do { - for (int i = 0; i < size; i++) - visited[i] = false; - - changed = false; - for (int i = 0; i < size; i++) - if (nodes[i].block.exits() == 0) - if (nodes[i].makeDominatorTree(visited, distance, access)) - changed = true; - } while (changed); - - Node.setChildren(nodes); - return nodes; - } - - /** - * Basic block. - * It is a sequence of contiguous instructions that do not contain - * jump/branch instructions except the last one. - * Since Java6 or later does not allow JSR, - * we deal with JSR as a non-branch instruction. - */ - public static class Block extends BasicBlock { - /** - * A field that can be freely used for storing extra data. - * A client program of this control-flow analyzer can append - * an additional attribute to a Block object. - * The Javassist library never accesses this field. - */ - public Object clientData = null; - - int index; - MethodInfo method; - Block[] entrances; - - Block(int pos, MethodInfo minfo) { - super(pos); - method = minfo; - } - - protected void toString2(StringBuffer sbuf) { - super.toString2(sbuf); - sbuf.append(", incoming{"); - for (int i = 0; i < entrances.length; i++) - sbuf.append(entrances[i].position).append(", "); - - sbuf.append("}"); - } - - BasicBlock[] getExit() { return exit; } - - /** - * Returns the position of this block in the array of - * basic blocks that the basicBlocks method - * returns. - * - * @see #basicBlocks() - */ - public int index() { return index; } - - /** - * Returns the position of the first instruction - * in this block. - */ - public int position() { return position; } - - /** - * Returns the length of this block. - */ - public int length() { return length; } - - /** - * Returns the number of the control paths entering this block. - */ - public int incomings() { return incoming; } - - /** - * Returns the block that the control may jump into this block from. - */ - public Block incoming(int n) { - return entrances[n]; - } - - /** - * Return the number of the blocks that may be executed - * after this block. - */ - public int exits() { return exit == null ? 0 : exit.length; } - - /** - * Returns the n-th block that may be executed after this - * block. - * - * @param n an index in the array of exit blocks. - */ - public Block exit(int n) { return (Block)exit[n]; } - - /** - * Returns catch clauses that will catch an exception thrown - * in this block. - */ - public Catcher[] catchers() { - ArrayList catchers = new ArrayList(); - BasicBlock.Catch c = toCatch; - while (c != null) { - catchers.add(new Catcher(c)); - c = c.next; - } - - return (Catcher[])catchers.toArray(new Catcher[catchers.size()]); - } - } - - static abstract class Access { - Node[] all; - Access(Node[] nodes) { all = nodes; } - Node node(BasicBlock b) { return all[((Block)b).index]; } - abstract BasicBlock[] exits(Node n); - abstract BasicBlock[] entrances(Node n); - } - - /** - * A node of (post) dominator trees. - */ - public static class Node { - private Block block; - private Node parent; - private Node[] children; - - Node(Block b) { - block = b; - parent = null; - } - - /** - * Returns a String representation. - */ - public String toString() { - StringBuffer sbuf = new StringBuffer(); - sbuf.append("Node[pos=").append(block().position()); - sbuf.append(", parent="); - sbuf.append(parent == null ? "*" : Integer.toString(parent.block().position())); - sbuf.append(", children{"); - for (int i = 0; i < children.length; i++) - sbuf.append(children[i].block().position()).append(", "); - - sbuf.append("}]"); - return sbuf.toString(); - } - - /** - * Returns the basic block indicated by this node. - */ - public Block block() { return block; } - - /** - * Returns the parent of this node. - */ - public Node parent() { return parent; } - - /** - * Returns the number of the children of this node. - */ - public int children() { return children.length; } - - /** - * Returns the n-th child of this node. - * - * @param n an index in the array of children. - */ - public Node child(int n) { return children[n]; } - - /* - * After executing this method, distance[] represents the post order of the tree nodes. - * It also represents distances from the root; a bigger number represents a shorter - * distance. parent is set to its parent in the depth first spanning tree. - */ - int makeDepth1stTree(Node caller, boolean[] visited, int counter, int[] distance, Access access) { - int index = block.index; - if (visited[index]) - return counter; - - visited[index] = true; - parent = caller; - BasicBlock[] exits = access.exits(this); - if (exits != null) - for (int i = 0; i < exits.length; i++) { - Node n = access.node(exits[i]); - counter = n.makeDepth1stTree(this, visited, counter, distance, access); - } - - distance[index] = counter++; - return counter; - } - - boolean makeDominatorTree(boolean[] visited, int[] distance, Access access) { - int index = block.index; - if (visited[index]) - return false; - - visited[index] = true; - boolean changed = false; - BasicBlock[] exits = access.exits(this); - if (exits != null) - for (int i = 0; i < exits.length; i++) { - Node n = access.node(exits[i]); - if (n.makeDominatorTree(visited, distance, access)) - changed = true; - } - - BasicBlock[] entrances = access.entrances(this); - if (entrances != null) - for (int i = 0; i < entrances.length; i++) { - if (parent != null) { - Node n = getAncestor(parent, access.node(entrances[i]), distance); - if (n != parent) { - parent = n; - changed = true; - } - } - } - - return changed; - } - - private static Node getAncestor(Node n1, Node n2, int[] distance) { - while (n1 != n2) { - if (distance[n1.block.index] < distance[n2.block.index]) - n1 = n1.parent; - else - n2 = n2.parent; - - if (n1 == null || n2 == null) - return null; - } - - return n1; - } - - private static void setChildren(Node[] all) { - int size = all.length; - int[] nchildren = new int[size]; - for (int i = 0; i < size; i++) - nchildren[i] = 0; - - for (int i = 0; i < size; i++) { - Node p = all[i].parent; - if (p != null) - nchildren[p.block.index]++; - } - - for (int i = 0; i < size; i++) - all[i].children = new Node[nchildren[i]]; - - for (int i = 0; i < size; i++) - nchildren[i] = 0; - - for (int i = 0; i < size; i++) { - Node n = all[i]; - Node p = n.parent; - if (p != null) - p.children[nchildren[p.block.index]++] = n; - } - } - } - - /** - * Represents a catch clause. - */ - public static class Catcher { - private Block node; - private int typeIndex; - - Catcher(BasicBlock.Catch c) { - node = (Block)c.body; - typeIndex = c.typeIndex; - } - - /** - * Returns the first block of the catch clause. - */ - public Block block() { return node; } - - /** - * Returns the name of the exception type that - * this catch clause catches. - */ - public String type() { - if (typeIndex == 0) - return "java.lang.Throwable"; - else - return node.method.getConstPool().getClassInfo(typeIndex); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Executor.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Executor.java deleted file mode 100644 index f717ca669..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Executor.java +++ /dev/null @@ -1,1047 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.bytecode.analysis; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.bytecode.BadBytecode; -import com.fr.third.javassist.bytecode.CodeIterator; -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.bytecode.Descriptor; -import com.fr.third.javassist.bytecode.MethodInfo; -import com.fr.third.javassist.bytecode.Opcode; - -/** - * Executor is responsible for modeling the effects of a JVM instruction on a frame. - * - * @author Jason T. Greene - */ -public class Executor implements Opcode { - private final ConstPool constPool; - private final ClassPool classPool; - private final com.fr.third.javassist.bytecode.analysis.Type STRING_TYPE; - private final com.fr.third.javassist.bytecode.analysis.Type CLASS_TYPE; - private final com.fr.third.javassist.bytecode.analysis.Type THROWABLE_TYPE; - private int lastPos; - - public Executor(ClassPool classPool, ConstPool constPool) { - this.constPool = constPool; - this.classPool = classPool; - - try { - STRING_TYPE = getType("java.lang.String"); - CLASS_TYPE = getType("java.lang.Class"); - THROWABLE_TYPE = getType("java.lang.Throwable"); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - - /** - * Execute the instruction, modeling the effects on the specified frame and subroutine. - * If a subroutine is passed, the access flags will be modified if this instruction accesses - * the local variable table. - * - * @param method the method containing the instruction - * @param pos the position of the instruction in the method - * @param iter the code iterator used to find the instruction - * @param frame the frame to modify to represent the result of the instruction - * @param subroutine the optional subroutine this instruction belongs to. - * @throws BadBytecode if the bytecode violates the jvm spec - */ - public void execute(MethodInfo method, int pos, CodeIterator iter, com.fr.third.javassist.bytecode.analysis.Frame frame, Subroutine subroutine) throws BadBytecode { - this.lastPos = pos; - int opcode = iter.byteAt(pos); - - - // Declared opcode in order - switch (opcode) { - case NOP: - break; - case ACONST_NULL: - frame.push(com.fr.third.javassist.bytecode.analysis.Type.UNINIT); - break; - case ICONST_M1: - case ICONST_0: - case ICONST_1: - case ICONST_2: - case ICONST_3: - case ICONST_4: - case ICONST_5: - frame.push(com.fr.third.javassist.bytecode.analysis.Type.INTEGER); - break; - case LCONST_0: - case LCONST_1: - frame.push(com.fr.third.javassist.bytecode.analysis.Type.LONG); - frame.push(com.fr.third.javassist.bytecode.analysis.Type.TOP); - break; - case FCONST_0: - case FCONST_1: - case FCONST_2: - frame.push(com.fr.third.javassist.bytecode.analysis.Type.FLOAT); - break; - case DCONST_0: - case DCONST_1: - frame.push(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE); - frame.push(com.fr.third.javassist.bytecode.analysis.Type.TOP); - break; - case BIPUSH: - case SIPUSH: - frame.push(com.fr.third.javassist.bytecode.analysis.Type.INTEGER); - break; - case LDC: - evalLDC(iter.byteAt(pos + 1), frame); - break; - case LDC_W : - case LDC2_W : - evalLDC(iter.u16bitAt(pos + 1), frame); - break; - case ILOAD: - evalLoad(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, iter.byteAt(pos + 1), frame, subroutine); - break; - case LLOAD: - evalLoad(com.fr.third.javassist.bytecode.analysis.Type.LONG, iter.byteAt(pos + 1), frame, subroutine); - break; - case FLOAD: - evalLoad(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, iter.byteAt(pos + 1), frame, subroutine); - break; - case DLOAD: - evalLoad(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, iter.byteAt(pos + 1), frame, subroutine); - break; - case ALOAD: - evalLoad(com.fr.third.javassist.bytecode.analysis.Type.OBJECT, iter.byteAt(pos + 1), frame, subroutine); - break; - case ILOAD_0: - case ILOAD_1: - case ILOAD_2: - case ILOAD_3: - evalLoad(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, opcode - ILOAD_0, frame, subroutine); - break; - case LLOAD_0: - case LLOAD_1: - case LLOAD_2: - case LLOAD_3: - evalLoad(com.fr.third.javassist.bytecode.analysis.Type.LONG, opcode - LLOAD_0, frame, subroutine); - break; - case FLOAD_0: - case FLOAD_1: - case FLOAD_2: - case FLOAD_3: - evalLoad(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, opcode - FLOAD_0, frame, subroutine); - break; - case DLOAD_0: - case DLOAD_1: - case DLOAD_2: - case DLOAD_3: - evalLoad(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, opcode - DLOAD_0, frame, subroutine); - break; - case ALOAD_0: - case ALOAD_1: - case ALOAD_2: - case ALOAD_3: - evalLoad(com.fr.third.javassist.bytecode.analysis.Type.OBJECT, opcode - ALOAD_0, frame, subroutine); - break; - case IALOAD: - evalArrayLoad(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case LALOAD: - evalArrayLoad(com.fr.third.javassist.bytecode.analysis.Type.LONG, frame); - break; - case FALOAD: - evalArrayLoad(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, frame); - break; - case DALOAD: - evalArrayLoad(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, frame); - break; - case AALOAD: - evalArrayLoad(com.fr.third.javassist.bytecode.analysis.Type.OBJECT, frame); - break; - case BALOAD: - case CALOAD: - case SALOAD: - evalArrayLoad(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case ISTORE: - evalStore(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, iter.byteAt(pos + 1), frame, subroutine); - break; - case LSTORE: - evalStore(com.fr.third.javassist.bytecode.analysis.Type.LONG, iter.byteAt(pos + 1), frame, subroutine); - break; - case FSTORE: - evalStore(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, iter.byteAt(pos + 1), frame, subroutine); - break; - case DSTORE: - evalStore(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, iter.byteAt(pos + 1), frame, subroutine); - break; - case ASTORE: - evalStore(com.fr.third.javassist.bytecode.analysis.Type.OBJECT, iter.byteAt(pos + 1), frame, subroutine); - break; - case ISTORE_0: - case ISTORE_1: - case ISTORE_2: - case ISTORE_3: - evalStore(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, opcode - ISTORE_0, frame, subroutine); - break; - case LSTORE_0: - case LSTORE_1: - case LSTORE_2: - case LSTORE_3: - evalStore(com.fr.third.javassist.bytecode.analysis.Type.LONG, opcode - LSTORE_0, frame, subroutine); - break; - case FSTORE_0: - case FSTORE_1: - case FSTORE_2: - case FSTORE_3: - evalStore(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, opcode - FSTORE_0, frame, subroutine); - break; - case DSTORE_0: - case DSTORE_1: - case DSTORE_2: - case DSTORE_3: - evalStore(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, opcode - DSTORE_0, frame, subroutine); - break; - case ASTORE_0: - case ASTORE_1: - case ASTORE_2: - case ASTORE_3: - evalStore(com.fr.third.javassist.bytecode.analysis.Type.OBJECT, opcode - ASTORE_0, frame, subroutine); - break; - case IASTORE: - evalArrayStore(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case LASTORE: - evalArrayStore(com.fr.third.javassist.bytecode.analysis.Type.LONG, frame); - break; - case FASTORE: - evalArrayStore(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, frame); - break; - case DASTORE: - evalArrayStore(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, frame); - break; - case AASTORE: - evalArrayStore(com.fr.third.javassist.bytecode.analysis.Type.OBJECT, frame); - break; - case BASTORE: - case CASTORE: - case SASTORE: - evalArrayStore(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case POP: - if (frame.pop() == com.fr.third.javassist.bytecode.analysis.Type.TOP) - throw new BadBytecode("POP can not be used with a category 2 value, pos = " + pos); - break; - case POP2: - frame.pop(); - frame.pop(); - break; - case DUP: { - com.fr.third.javassist.bytecode.analysis.Type type = frame.peek(); - if (type == com.fr.third.javassist.bytecode.analysis.Type.TOP) - throw new BadBytecode("DUP can not be used with a category 2 value, pos = " + pos); - - frame.push(frame.peek()); - break; - } - case DUP_X1: - case DUP_X2: { - com.fr.third.javassist.bytecode.analysis.Type type = frame.peek(); - if (type == com.fr.third.javassist.bytecode.analysis.Type.TOP) - throw new BadBytecode("DUP can not be used with a category 2 value, pos = " + pos); - int end = frame.getTopIndex(); - int insert = end - (opcode - DUP_X1) - 1; - frame.push(type); - - while (end > insert) { - frame.setStack(end, frame.getStack(end - 1)); - end--; - } - frame.setStack(insert, type); - break; - } - case DUP2: - frame.push(frame.getStack(frame.getTopIndex() - 1)); - frame.push(frame.getStack(frame.getTopIndex() - 1)); - break; - case DUP2_X1: - case DUP2_X2: { - int end = frame.getTopIndex(); - int insert = end - (opcode - DUP2_X1) - 1; - com.fr.third.javassist.bytecode.analysis.Type type1 = frame.getStack(frame.getTopIndex() - 1); - com.fr.third.javassist.bytecode.analysis.Type type2 = frame.peek(); - frame.push(type1); - frame.push(type2); - while (end > insert) { - frame.setStack(end, frame.getStack(end - 2)); - end--; - } - frame.setStack(insert, type2); - frame.setStack(insert - 1, type1); - break; - } - case SWAP: { - com.fr.third.javassist.bytecode.analysis.Type type1 = frame.pop(); - com.fr.third.javassist.bytecode.analysis.Type type2 = frame.pop(); - if (type1.getSize() == 2 || type2.getSize() == 2) - throw new BadBytecode("Swap can not be used with category 2 values, pos = " + pos); - frame.push(type1); - frame.push(type2); - break; - } - - // Math - case IADD: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case LADD: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.LONG, frame); - break; - case FADD: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, frame); - break; - case DADD: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, frame); - break; - case ISUB: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case LSUB: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.LONG, frame); - break; - case FSUB: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, frame); - break; - case DSUB: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, frame); - break; - case IMUL: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case LMUL: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.LONG, frame); - break; - case FMUL: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, frame); - break; - case DMUL: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, frame); - break; - case IDIV: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case LDIV: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.LONG, frame); - break; - case FDIV: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, frame); - break; - case DDIV: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, frame); - break; - case IREM: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case LREM: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.LONG, frame); - break; - case FREM: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, frame); - break; - case DREM: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, frame); - break; - - // Unary - case INEG: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, simplePeek(frame)); - break; - case LNEG: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.LONG, simplePeek(frame)); - break; - case FNEG: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, simplePeek(frame)); - break; - case DNEG: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, simplePeek(frame)); - break; - - // Shifts - case ISHL: - evalShift(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case LSHL: - evalShift(com.fr.third.javassist.bytecode.analysis.Type.LONG, frame); - break; - case ISHR: - evalShift(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case LSHR: - evalShift(com.fr.third.javassist.bytecode.analysis.Type.LONG, frame); - break; - case IUSHR: - evalShift(com.fr.third.javassist.bytecode.analysis.Type.INTEGER,frame); - break; - case LUSHR: - evalShift(com.fr.third.javassist.bytecode.analysis.Type.LONG, frame); - break; - - // Bitwise Math - case IAND: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case LAND: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.LONG, frame); - break; - case IOR: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case LOR: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.LONG, frame); - break; - case IXOR: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case LXOR: - evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type.LONG, frame); - break; - - case IINC: { - int index = iter.byteAt(pos + 1); - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame.getLocal(index)); - access(index, com.fr.third.javassist.bytecode.analysis.Type.INTEGER, subroutine); - break; - } - - // Conversion - case I2L: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, simplePop(frame)); - simplePush(com.fr.third.javassist.bytecode.analysis.Type.LONG, frame); - break; - case I2F: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, simplePop(frame)); - simplePush(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, frame); - break; - case I2D: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, simplePop(frame)); - simplePush(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, frame); - break; - case L2I: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.LONG, simplePop(frame)); - simplePush(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case L2F: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.LONG, simplePop(frame)); - simplePush(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, frame); - break; - case L2D: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.LONG, simplePop(frame)); - simplePush(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, frame); - break; - case F2I: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, simplePop(frame)); - simplePush(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case F2L: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, simplePop(frame)); - simplePush(com.fr.third.javassist.bytecode.analysis.Type.LONG, frame); - break; - case F2D: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, simplePop(frame)); - simplePush(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, frame); - break; - case D2I: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, simplePop(frame)); - simplePush(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame); - break; - case D2L: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, simplePop(frame)); - simplePush(com.fr.third.javassist.bytecode.analysis.Type.LONG, frame); - break; - case D2F: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, simplePop(frame)); - simplePush(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, frame); - break; - case I2B: - case I2C: - case I2S: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame.peek()); - break; - case LCMP: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.LONG, simplePop(frame)); - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.LONG, simplePop(frame)); - frame.push(com.fr.third.javassist.bytecode.analysis.Type.INTEGER); - break; - case FCMPL: - case FCMPG: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, simplePop(frame)); - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, simplePop(frame)); - frame.push(com.fr.third.javassist.bytecode.analysis.Type.INTEGER); - break; - case DCMPL: - case DCMPG: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, simplePop(frame)); - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, simplePop(frame)); - frame.push(com.fr.third.javassist.bytecode.analysis.Type.INTEGER); - break; - - // Control flow - case IFEQ: - case IFNE: - case IFLT: - case IFGE: - case IFGT: - case IFLE: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, simplePop(frame)); - break; - case IF_ICMPEQ: - case IF_ICMPNE: - case IF_ICMPLT: - case IF_ICMPGE: - case IF_ICMPGT: - case IF_ICMPLE: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, simplePop(frame)); - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, simplePop(frame)); - break; - case IF_ACMPEQ: - case IF_ACMPNE: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.OBJECT, simplePop(frame)); - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.OBJECT, simplePop(frame)); - break; - case GOTO: - break; - case JSR: - frame.push(com.fr.third.javassist.bytecode.analysis.Type.RETURN_ADDRESS); - break; - case RET: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.RETURN_ADDRESS, frame.getLocal(iter.byteAt(pos + 1))); - break; - case TABLESWITCH: - case LOOKUPSWITCH: - case IRETURN: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, simplePop(frame)); - break; - case LRETURN: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.LONG, simplePop(frame)); - break; - case FRETURN: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, simplePop(frame)); - break; - case DRETURN: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, simplePop(frame)); - break; - case ARETURN: - try { - CtClass returnType = Descriptor.getReturnType(method.getDescriptor(), classPool); - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.get(returnType), simplePop(frame)); - } catch (NotFoundException e) { - throw new RuntimeException(e); - } - break; - case RETURN: - break; - case GETSTATIC: - evalGetField(opcode, iter.u16bitAt(pos + 1), frame); - break; - case PUTSTATIC: - evalPutField(opcode, iter.u16bitAt(pos + 1), frame); - break; - case GETFIELD: - evalGetField(opcode, iter.u16bitAt(pos + 1), frame); - break; - case PUTFIELD: - evalPutField(opcode, iter.u16bitAt(pos + 1), frame); - break; - case INVOKEVIRTUAL: - case INVOKESPECIAL: - case INVOKESTATIC: - evalInvokeMethod(opcode, iter.u16bitAt(pos + 1), frame); - break; - case INVOKEINTERFACE: - evalInvokeIntfMethod(opcode, iter.u16bitAt(pos + 1), frame); - break; - case INVOKEDYNAMIC: - evalInvokeDynamic(opcode, iter.u16bitAt(pos + 1), frame); - break; - case NEW: - frame.push(resolveClassInfo(constPool.getClassInfo(iter.u16bitAt(pos + 1)))); - break; - case NEWARRAY: - evalNewArray(pos, iter, frame); - break; - case ANEWARRAY: - evalNewObjectArray(pos, iter, frame); - break; - case ARRAYLENGTH: { - com.fr.third.javassist.bytecode.analysis.Type array = simplePop(frame); - if (! array.isArray() && array != com.fr.third.javassist.bytecode.analysis.Type.UNINIT) - throw new BadBytecode("Array length passed a non-array [pos = " + pos + "]: " + array); - frame.push(com.fr.third.javassist.bytecode.analysis.Type.INTEGER); - break; - } - case ATHROW: - verifyAssignable(THROWABLE_TYPE, simplePop(frame)); - break; - case CHECKCAST: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.OBJECT, simplePop(frame)); - frame.push(typeFromDesc(constPool.getClassInfoByDescriptor(iter.u16bitAt(pos + 1)))); - break; - case INSTANCEOF: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.OBJECT, simplePop(frame)); - frame.push(com.fr.third.javassist.bytecode.analysis.Type.INTEGER); - break; - case MONITORENTER: - case MONITOREXIT: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.OBJECT, simplePop(frame)); - break; - case WIDE: - evalWide(pos, iter, frame, subroutine); - break; - case MULTIANEWARRAY: - evalNewObjectArray(pos, iter, frame); - break; - case IFNULL: - case IFNONNULL: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.OBJECT, simplePop(frame)); - break; - case GOTO_W: - break; - case JSR_W: - frame.push(com.fr.third.javassist.bytecode.analysis.Type.RETURN_ADDRESS); - break; - } - } - - private com.fr.third.javassist.bytecode.analysis.Type zeroExtend(com.fr.third.javassist.bytecode.analysis.Type type) { - if (type == com.fr.third.javassist.bytecode.analysis.Type.SHORT || type == com.fr.third.javassist.bytecode.analysis.Type.BYTE || type == com.fr.third.javassist.bytecode.analysis.Type.CHAR || type == com.fr.third.javassist.bytecode.analysis.Type.BOOLEAN) - return com.fr.third.javassist.bytecode.analysis.Type.INTEGER; - - return type; - } - - private void evalArrayLoad(com.fr.third.javassist.bytecode.analysis.Type expectedComponent, com.fr.third.javassist.bytecode.analysis.Frame frame) throws BadBytecode { - com.fr.third.javassist.bytecode.analysis.Type index = frame.pop(); - com.fr.third.javassist.bytecode.analysis.Type array = frame.pop(); - - // Special case, an array defined by aconst_null - // TODO - we might need to be more inteligent about this - if (array == com.fr.third.javassist.bytecode.analysis.Type.UNINIT) { - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, index); - if (expectedComponent == com.fr.third.javassist.bytecode.analysis.Type.OBJECT) { - simplePush(com.fr.third.javassist.bytecode.analysis.Type.UNINIT, frame); - } else { - simplePush(expectedComponent, frame); - } - return; - } - - com.fr.third.javassist.bytecode.analysis.Type component = array.getComponent(); - - if (component == null) - throw new BadBytecode("Not an array! [pos = " + lastPos + "]: " + component); - - component = zeroExtend(component); - - verifyAssignable(expectedComponent, component); - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, index); - simplePush(component, frame); - } - - private void evalArrayStore(com.fr.third.javassist.bytecode.analysis.Type expectedComponent, com.fr.third.javassist.bytecode.analysis.Frame frame) throws BadBytecode { - com.fr.third.javassist.bytecode.analysis.Type value = simplePop(frame); - com.fr.third.javassist.bytecode.analysis.Type index = frame.pop(); - com.fr.third.javassist.bytecode.analysis.Type array = frame.pop(); - - if (array == com.fr.third.javassist.bytecode.analysis.Type.UNINIT) { - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, index); - return; - } - - com.fr.third.javassist.bytecode.analysis.Type component = array.getComponent(); - - if (component == null) - throw new BadBytecode("Not an array! [pos = " + lastPos + "]: " + component); - - component = zeroExtend(component); - - verifyAssignable(expectedComponent, component); - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, index); - - // This intentionally only checks for Object on aastore - // downconverting of an array (no casts) - // e.g. Object[] blah = new String[]; - // blah[2] = (Object) "test"; - // blah[3] = new Integer(); // compiler doesnt catch it (has legal bytecode), - // // but will throw arraystoreexception - if (expectedComponent == com.fr.third.javassist.bytecode.analysis.Type.OBJECT) { - verifyAssignable(expectedComponent, value); - } else { - verifyAssignable(component, value); - } - } - - private void evalBinaryMath(com.fr.third.javassist.bytecode.analysis.Type expected, com.fr.third.javassist.bytecode.analysis.Frame frame) throws BadBytecode { - com.fr.third.javassist.bytecode.analysis.Type value2 = simplePop(frame); - com.fr.third.javassist.bytecode.analysis.Type value1 = simplePop(frame); - - verifyAssignable(expected, value2); - verifyAssignable(expected, value1); - simplePush(value1, frame); - } - - private void evalGetField(int opcode, int index, com.fr.third.javassist.bytecode.analysis.Frame frame) throws BadBytecode { - String desc = constPool.getFieldrefType(index); - com.fr.third.javassist.bytecode.analysis.Type type = zeroExtend(typeFromDesc(desc)); - - if (opcode == GETFIELD) { - com.fr.third.javassist.bytecode.analysis.Type objectType = resolveClassInfo(constPool.getFieldrefClassName(index)); - verifyAssignable(objectType, simplePop(frame)); - } - - simplePush(type, frame); - } - - private void evalInvokeIntfMethod(int opcode, int index, com.fr.third.javassist.bytecode.analysis.Frame frame) throws BadBytecode { - String desc = constPool.getInterfaceMethodrefType(index); - com.fr.third.javassist.bytecode.analysis.Type[] types = paramTypesFromDesc(desc); - int i = types.length; - - while (i > 0) - verifyAssignable(zeroExtend(types[--i]), simplePop(frame)); - - String classInfo = constPool.getInterfaceMethodrefClassName(index); - com.fr.third.javassist.bytecode.analysis.Type objectType = resolveClassInfo(classInfo); - verifyAssignable(objectType, simplePop(frame)); - - com.fr.third.javassist.bytecode.analysis.Type returnType = returnTypeFromDesc(desc); - if (returnType != com.fr.third.javassist.bytecode.analysis.Type.VOID) - simplePush(zeroExtend(returnType), frame); - } - - private void evalInvokeMethod(int opcode, int index, com.fr.third.javassist.bytecode.analysis.Frame frame) throws BadBytecode { - String desc = constPool.getMethodrefType(index); - com.fr.third.javassist.bytecode.analysis.Type[] types = paramTypesFromDesc(desc); - int i = types.length; - - while (i > 0) - verifyAssignable(zeroExtend(types[--i]), simplePop(frame)); - - if (opcode != INVOKESTATIC) { - com.fr.third.javassist.bytecode.analysis.Type objectType = resolveClassInfo(constPool.getMethodrefClassName(index)); - verifyAssignable(objectType, simplePop(frame)); - } - - com.fr.third.javassist.bytecode.analysis.Type returnType = returnTypeFromDesc(desc); - if (returnType != com.fr.third.javassist.bytecode.analysis.Type.VOID) - simplePush(zeroExtend(returnType), frame); - } - - private void evalInvokeDynamic(int opcode, int index, com.fr.third.javassist.bytecode.analysis.Frame frame) throws BadBytecode { - String desc = constPool.getInvokeDynamicType(index); - com.fr.third.javassist.bytecode.analysis.Type[] types = paramTypesFromDesc(desc); - int i = types.length; - - while (i > 0) - verifyAssignable(zeroExtend(types[--i]), simplePop(frame)); - - // simplePop(frame); // assume CosntPool#REF_invokeStatic - - com.fr.third.javassist.bytecode.analysis.Type returnType = returnTypeFromDesc(desc); - if (returnType != com.fr.third.javassist.bytecode.analysis.Type.VOID) - simplePush(zeroExtend(returnType), frame); - } - - private void evalLDC(int index, com.fr.third.javassist.bytecode.analysis.Frame frame) throws BadBytecode { - int tag = constPool.getTag(index); - com.fr.third.javassist.bytecode.analysis.Type type; - switch (tag) { - case ConstPool.CONST_String: - type = STRING_TYPE; - break; - case ConstPool.CONST_Integer: - type = com.fr.third.javassist.bytecode.analysis.Type.INTEGER; - break; - case ConstPool.CONST_Float: - type = com.fr.third.javassist.bytecode.analysis.Type.FLOAT; - break; - case ConstPool.CONST_Long: - type = com.fr.third.javassist.bytecode.analysis.Type.LONG; - break; - case ConstPool.CONST_Double: - type = com.fr.third.javassist.bytecode.analysis.Type.DOUBLE; - break; - case ConstPool.CONST_Class: - type = CLASS_TYPE; - break; - default: - throw new BadBytecode("bad LDC [pos = " + lastPos + "]: " + tag); - } - - simplePush(type, frame); - } - - private void evalLoad(com.fr.third.javassist.bytecode.analysis.Type expected, int index, com.fr.third.javassist.bytecode.analysis.Frame frame, Subroutine subroutine) throws BadBytecode { - com.fr.third.javassist.bytecode.analysis.Type type = frame.getLocal(index); - - verifyAssignable(expected, type); - - simplePush(type, frame); - access(index, type, subroutine); - } - - private void evalNewArray(int pos, CodeIterator iter, com.fr.third.javassist.bytecode.analysis.Frame frame) throws BadBytecode { - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, simplePop(frame)); - com.fr.third.javassist.bytecode.analysis.Type type = null; - int typeInfo = iter.byteAt(pos + 1); - switch (typeInfo) { - case T_BOOLEAN: - type = getType("boolean[]"); - break; - case T_CHAR: - type = getType("char[]"); - break; - case T_BYTE: - type = getType("byte[]"); - break; - case T_SHORT: - type = getType("short[]"); - break; - case T_INT: - type = getType("int[]"); - break; - case T_LONG: - type = getType("long[]"); - break; - case T_FLOAT: - type = getType("float[]"); - break; - case T_DOUBLE: - type = getType("double[]"); - break; - default: - throw new BadBytecode("Invalid array type [pos = " + pos + "]: " + typeInfo); - - } - - frame.push(type); - } - - private void evalNewObjectArray(int pos, CodeIterator iter, com.fr.third.javassist.bytecode.analysis.Frame frame) throws BadBytecode { - // Convert to x[] format - com.fr.third.javassist.bytecode.analysis.Type type = resolveClassInfo(constPool.getClassInfo(iter.u16bitAt(pos + 1))); - String name = type.getCtClass().getName(); - int opcode = iter.byteAt(pos); - int dimensions; - - if (opcode == MULTIANEWARRAY) { - dimensions = iter.byteAt(pos + 3); - } else { - name = name + "[]"; - dimensions = 1; - } - - while (dimensions-- > 0) { - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, simplePop(frame)); - } - - simplePush(getType(name), frame); - } - - private void evalPutField(int opcode, int index, com.fr.third.javassist.bytecode.analysis.Frame frame) throws BadBytecode { - String desc = constPool.getFieldrefType(index); - com.fr.third.javassist.bytecode.analysis.Type type = zeroExtend(typeFromDesc(desc)); - - verifyAssignable(type, simplePop(frame)); - - if (opcode == PUTFIELD) { - com.fr.third.javassist.bytecode.analysis.Type objectType = resolveClassInfo(constPool.getFieldrefClassName(index)); - verifyAssignable(objectType, simplePop(frame)); - } - } - - private void evalShift(com.fr.third.javassist.bytecode.analysis.Type expected, com.fr.third.javassist.bytecode.analysis.Frame frame) throws BadBytecode { - com.fr.third.javassist.bytecode.analysis.Type value2 = simplePop(frame); - com.fr.third.javassist.bytecode.analysis.Type value1 = simplePop(frame); - - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, value2); - verifyAssignable(expected, value1); - simplePush(value1, frame); - } - - private void evalStore(com.fr.third.javassist.bytecode.analysis.Type expected, int index, com.fr.third.javassist.bytecode.analysis.Frame frame, Subroutine subroutine) throws BadBytecode { - com.fr.third.javassist.bytecode.analysis.Type type = simplePop(frame); - - // RETURN_ADDRESS is allowed by ASTORE - if (! (expected == com.fr.third.javassist.bytecode.analysis.Type.OBJECT && type == com.fr.third.javassist.bytecode.analysis.Type.RETURN_ADDRESS)) - verifyAssignable(expected, type); - simpleSetLocal(index, type, frame); - access(index, type, subroutine); - } - - private void evalWide(int pos, CodeIterator iter, com.fr.third.javassist.bytecode.analysis.Frame frame, Subroutine subroutine) throws BadBytecode { - int opcode = iter.byteAt(pos + 1); - int index = iter.u16bitAt(pos + 2); - switch (opcode) { - case ILOAD: - evalLoad(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, index, frame, subroutine); - break; - case LLOAD: - evalLoad(com.fr.third.javassist.bytecode.analysis.Type.LONG, index, frame, subroutine); - break; - case FLOAD: - evalLoad(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, index, frame, subroutine); - break; - case DLOAD: - evalLoad(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, index, frame, subroutine); - break; - case ALOAD: - evalLoad(com.fr.third.javassist.bytecode.analysis.Type.OBJECT, index, frame, subroutine); - break; - case ISTORE: - evalStore(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, index, frame, subroutine); - break; - case LSTORE: - evalStore(com.fr.third.javassist.bytecode.analysis.Type.LONG, index, frame, subroutine); - break; - case FSTORE: - evalStore(com.fr.third.javassist.bytecode.analysis.Type.FLOAT, index, frame, subroutine); - break; - case DSTORE: - evalStore(com.fr.third.javassist.bytecode.analysis.Type.DOUBLE, index, frame, subroutine); - break; - case ASTORE: - evalStore(com.fr.third.javassist.bytecode.analysis.Type.OBJECT, index, frame, subroutine); - break; - case IINC: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.INTEGER, frame.getLocal(index)); - break; - case RET: - verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type.RETURN_ADDRESS, frame.getLocal(index)); - break; - default: - throw new BadBytecode("Invalid WIDE operand [pos = " + pos + "]: " + opcode); - } - - } - - private com.fr.third.javassist.bytecode.analysis.Type getType(String name) throws BadBytecode { - try { - return com.fr.third.javassist.bytecode.analysis.Type.get(classPool.get(name)); - } catch (NotFoundException e) { - throw new BadBytecode("Could not find class [pos = " + lastPos + "]: " + name); - } - } - - private com.fr.third.javassist.bytecode.analysis.Type[] paramTypesFromDesc(String desc) throws BadBytecode { - CtClass classes[] = null; - try { - classes = Descriptor.getParameterTypes(desc, classPool); - } catch (NotFoundException e) { - throw new BadBytecode("Could not find class in descriptor [pos = " + lastPos + "]: " + e.getMessage()); - } - - if (classes == null) - throw new BadBytecode("Could not obtain parameters for descriptor [pos = " + lastPos + "]: " + desc); - - com.fr.third.javassist.bytecode.analysis.Type[] types = new com.fr.third.javassist.bytecode.analysis.Type[classes.length]; - for (int i = 0; i < types.length; i++) - types[i] = com.fr.third.javassist.bytecode.analysis.Type.get(classes[i]); - - return types; - } - - private com.fr.third.javassist.bytecode.analysis.Type returnTypeFromDesc(String desc) throws BadBytecode { - CtClass clazz = null; - try { - clazz = Descriptor.getReturnType(desc, classPool); - } catch (NotFoundException e) { - throw new BadBytecode("Could not find class in descriptor [pos = " + lastPos + "]: " + e.getMessage()); - } - - if (clazz == null) - throw new BadBytecode("Could not obtain return type for descriptor [pos = " + lastPos + "]: " + desc); - - return com.fr.third.javassist.bytecode.analysis.Type.get(clazz); - } - - private com.fr.third.javassist.bytecode.analysis.Type simplePeek(com.fr.third.javassist.bytecode.analysis.Frame frame) { - com.fr.third.javassist.bytecode.analysis.Type type = frame.peek(); - return (type == com.fr.third.javassist.bytecode.analysis.Type.TOP) ? frame.getStack(frame.getTopIndex() - 1) : type; - } - - private com.fr.third.javassist.bytecode.analysis.Type simplePop(com.fr.third.javassist.bytecode.analysis.Frame frame) { - com.fr.third.javassist.bytecode.analysis.Type type = frame.pop(); - return (type == com.fr.third.javassist.bytecode.analysis.Type.TOP) ? frame.pop() : type; - } - - private void simplePush(com.fr.third.javassist.bytecode.analysis.Type type, com.fr.third.javassist.bytecode.analysis.Frame frame) { - frame.push(type); - if (type.getSize() == 2) - frame.push(com.fr.third.javassist.bytecode.analysis.Type.TOP); - } - - private void access(int index, com.fr.third.javassist.bytecode.analysis.Type type, Subroutine subroutine) { - if (subroutine == null) - return; - subroutine.access(index); - if (type.getSize() == 2) - subroutine.access(index + 1); - } - - private void simpleSetLocal(int index, com.fr.third.javassist.bytecode.analysis.Type type, Frame frame) { - frame.setLocal(index, type); - if (type.getSize() == 2) - frame.setLocal(index + 1, com.fr.third.javassist.bytecode.analysis.Type.TOP); - } - - private com.fr.third.javassist.bytecode.analysis.Type resolveClassInfo(String info) throws BadBytecode { - CtClass clazz = null; - try { - if (info.charAt(0) == '[') { - clazz = Descriptor.toCtClass(info, classPool); - } else { - clazz = classPool.get(info); - } - - } catch (NotFoundException e) { - throw new BadBytecode("Could not find class in descriptor [pos = " + lastPos + "]: " + e.getMessage()); - } - - if (clazz == null) - throw new BadBytecode("Could not obtain type for descriptor [pos = " + lastPos + "]: " + info); - - return com.fr.third.javassist.bytecode.analysis.Type.get(clazz); - } - - private com.fr.third.javassist.bytecode.analysis.Type typeFromDesc(String desc) throws BadBytecode { - CtClass clazz = null; - try { - clazz = Descriptor.toCtClass(desc, classPool); - } catch (NotFoundException e) { - throw new BadBytecode("Could not find class in descriptor [pos = " + lastPos + "]: " + e.getMessage()); - } - - if (clazz == null) - throw new BadBytecode("Could not obtain type for descriptor [pos = " + lastPos + "]: " + desc); - - return com.fr.third.javassist.bytecode.analysis.Type.get(clazz); - } - - private void verifyAssignable(com.fr.third.javassist.bytecode.analysis.Type expected, Type type) throws BadBytecode { - if (! expected.isAssignableFrom(type)) - throw new BadBytecode("Expected type: " + expected + " Got: " + type + " [pos = " + lastPos + "]"); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Frame.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Frame.java deleted file mode 100644 index 036730880..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Frame.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.bytecode.analysis; - - -/** - * Represents the stack frame and local variable table at a particular point in time. - * - * @author Jason T. Greene - */ -public class Frame { - private com.fr.third.javassist.bytecode.analysis.Type[] locals; - private com.fr.third.javassist.bytecode.analysis.Type[] stack; - private int top; - private boolean jsrMerged; - private boolean retMerged; - - /** - * Create a new frame with the specified local variable table size, and max stack size - * - * @param locals the number of local variable table entries - * @param stack the maximum stack size - */ - public Frame(int locals, int stack) { - this.locals = new com.fr.third.javassist.bytecode.analysis.Type[locals]; - this.stack = new com.fr.third.javassist.bytecode.analysis.Type[stack]; - } - - /** - * Returns the local varaible table entry at index. - * - * @param index the position in the table - * @return the type if one exists, or null if the position is empty - */ - public com.fr.third.javassist.bytecode.analysis.Type getLocal(int index) { - return locals[index]; - } - - /** - * Sets the local variable table entry at index to a type. - * - * @param index the position in the table - * @param type the type to set at the position - */ - public void setLocal(int index, com.fr.third.javassist.bytecode.analysis.Type type) { - locals[index] = type; - } - - - /** - * Returns the type on the stack at the specified index. - * - * @param index the position on the stack - * @return the type of the stack position - */ - public com.fr.third.javassist.bytecode.analysis.Type getStack(int index) { - return stack[index]; - } - - /** - * Sets the type of the stack position - * - * @param index the position on the stack - * @param type the type to set - */ - public void setStack(int index, com.fr.third.javassist.bytecode.analysis.Type type) { - stack[index] = type; - } - - /** - * Empties the stack - */ - public void clearStack() { - top = 0; - } - - /** - * Gets the index of the type sitting at the top of the stack. - * This is not to be confused with a length operation which - * would return the number of elements, not the position of - * the last element. - * - * @return the position of the element at the top of the stack - */ - public int getTopIndex() { - return top - 1; - } - - /** - * Returns the number of local variable table entries, specified - * at construction. - * - * @return the number of local variable table entries - */ - public int localsLength() { - return locals.length; - } - - /** - * Gets the top of the stack without altering it - * - * @return the top of the stack - */ - public com.fr.third.javassist.bytecode.analysis.Type peek() { - if (top < 1) - throw new IndexOutOfBoundsException("Stack is empty"); - - return stack[top - 1]; - } - - /** - * Alters the stack to contain one less element and return it. - * - * @return the element popped from the stack - */ - public com.fr.third.javassist.bytecode.analysis.Type pop() { - if (top < 1) - throw new IndexOutOfBoundsException("Stack is empty"); - return stack[--top]; - } - - /** - * Alters the stack by placing the passed type on the top - * - * @param type the type to add to the top - */ - public void push(com.fr.third.javassist.bytecode.analysis.Type type) { - stack[top++] = type; - } - - - /** - * Makes a shallow copy of this frame, i.e. the type instances will - * remain the same. - * - * @return the shallow copy - */ - public Frame copy() { - Frame frame = new Frame(locals.length, stack.length); - System.arraycopy(locals, 0, frame.locals, 0, locals.length); - System.arraycopy(stack, 0, frame.stack, 0, stack.length); - frame.top = top; - return frame; - } - - /** - * Makes a shallow copy of the stack portion of this frame. The local - * variable table size will be copied, but its contents will be empty. - * - * @return the shallow copy of the stack - */ - public Frame copyStack() { - Frame frame = new Frame(locals.length, stack.length); - System.arraycopy(stack, 0, frame.stack, 0, stack.length); - frame.top = top; - return frame; - } - - /** - * Merges all types on the stack of this frame instance with that of the specified frame. - * The local variable table is left untouched. - * - * @param frame the frame to merge the stack from - * @return true if any changes where made - */ - public boolean mergeStack(Frame frame) { - boolean changed = false; - if (top != frame.top) - throw new RuntimeException("Operand stacks could not be merged, they are different sizes!"); - - for (int i = 0; i < top; i++) { - if (stack[i] != null) { - com.fr.third.javassist.bytecode.analysis.Type prev = stack[i]; - com.fr.third.javassist.bytecode.analysis.Type merged = prev.merge(frame.stack[i]); - if (merged == com.fr.third.javassist.bytecode.analysis.Type.BOGUS) - throw new RuntimeException("Operand stacks could not be merged due to differing primitive types: pos = " + i); - - stack[i] = merged; - // always replace the instance in case a multi-interface type changes to a normal Type - if ((! merged.equals(prev)) || merged.popChanged()) { - changed = true; - } - } - } - - return changed; - } - - /** - * Merges all types on the stack and local variable table of this frame with that of the specified - * type. - * - * @param frame the frame to merge with - * @return true if any changes to this frame where made by this merge - */ - public boolean merge(Frame frame) { - boolean changed = false; - - // Local variable table - for (int i = 0; i < locals.length; i++) { - if (locals[i] != null) { - com.fr.third.javassist.bytecode.analysis.Type prev = locals[i]; - Type merged = prev.merge(frame.locals[i]); - // always replace the instance in case a multi-interface type changes to a normal Type - locals[i] = merged; - if (! merged.equals(prev) || merged.popChanged()) { - changed = true; - } - } else if (frame.locals[i] != null) { - locals[i] = frame.locals[i]; - changed = true; - } - } - - changed |= mergeStack(frame); - return changed; - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("locals = ["); - for (int i = 0; i < locals.length; i++) { - buffer.append(locals[i] == null ? "empty" : locals[i].toString()); - if (i < locals.length - 1) - buffer.append(", "); - } - buffer.append("] stack = ["); - for (int i = 0; i < top; i++) { - buffer.append(stack[i]); - if (i < top - 1) - buffer.append(", "); - } - buffer.append("]"); - - return buffer.toString(); - } - - /** - * Whether or not state from the source JSR instruction has been merged - * - * @return true if JSR state has been merged - */ - boolean isJsrMerged() { - return jsrMerged; - } - - /** - * Sets whether of not the state from the source JSR instruction has been merged - * - * @param jsrMerged true if merged, otherwise false - */ - void setJsrMerged(boolean jsrMerged) { - this.jsrMerged = jsrMerged; - } - - /** - * Whether or not state from the RET instruction, of the subroutine that was jumped - * to has been merged. - * - * @return true if RET state has been merged - */ - boolean isRetMerged() { - return retMerged; - } - - /** - * Sets whether or not state from the RET instruction, of the subroutine that was jumped - * to has been merged. - * - * @param retMerged true if RET state has been merged - */ - void setRetMerged(boolean retMerged) { - this.retMerged = retMerged; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/FramePrinter.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/FramePrinter.java deleted file mode 100644 index 87e79b99b..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/FramePrinter.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.bytecode.analysis; - -import java.io.PrintStream; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CtMethod; -import com.fr.third.javassist.Modifier; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.bytecode.BadBytecode; -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.bytecode.CodeIterator; -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.bytecode.Descriptor; -import com.fr.third.javassist.bytecode.InstructionPrinter; -import com.fr.third.javassist.bytecode.MethodInfo; - -/** - * A utility class for printing a merged view of the frame state and the - * instructions of a method. - * - * @author Jason T. Greene - */ -public final class FramePrinter { - private final PrintStream stream; - - /** - * Constructs a bytecode printer. - */ - public FramePrinter(PrintStream stream) { - this.stream = stream; - } - - /** - * Prints all the methods declared in the given class. - */ - public static void print(CtClass clazz, PrintStream stream) { - (new FramePrinter(stream)).print(clazz); - } - - /** - * Prints all the methods declared in the given class. - */ - public void print(CtClass clazz) { - CtMethod[] methods = clazz.getDeclaredMethods(); - for (int i = 0; i < methods.length; i++) { - print(methods[i]); - } - } - - private String getMethodString(CtMethod method) { - try { - return Modifier.toString(method.getModifiers()) + " " - + method.getReturnType().getName() + " " + method.getName() - + Descriptor.toString(method.getSignature()) + ";"; - } catch (NotFoundException e) { - throw new RuntimeException(e); - } - } - - /** - * Prints the instructions and the frame states of the given method. - */ - public void print(CtMethod method) { - stream.println("\n" + getMethodString(method)); - MethodInfo info = method.getMethodInfo2(); - ConstPool pool = info.getConstPool(); - CodeAttribute code = info.getCodeAttribute(); - if (code == null) - return; - - com.fr.third.javassist.bytecode.analysis.Frame[] frames; - try { - frames = (new Analyzer()).analyze(method.getDeclaringClass(), info); - } catch (BadBytecode e) { - throw new RuntimeException(e); - } - - int spacing = String.valueOf(code.getCodeLength()).length(); - - CodeIterator iterator = code.iterator(); - while (iterator.hasNext()) { - int pos; - try { - pos = iterator.next(); - } catch (BadBytecode e) { - throw new RuntimeException(e); - } - - stream.println(pos + ": " + InstructionPrinter.instructionString(iterator, pos, pool)); - - addSpacing(spacing + 3); - com.fr.third.javassist.bytecode.analysis.Frame frame = frames[pos]; - if (frame == null) { - stream.println("--DEAD CODE--"); - continue; - } - printStack(frame); - - addSpacing(spacing + 3); - printLocals(frame); - } - - } - - private void printStack(com.fr.third.javassist.bytecode.analysis.Frame frame) { - stream.print("stack ["); - int top = frame.getTopIndex(); - for (int i = 0; i <= top; i++) { - if (i > 0) - stream.print(", "); - com.fr.third.javassist.bytecode.analysis.Type type = frame.getStack(i); - stream.print(type); - } - stream.println("]"); - } - - private void printLocals(Frame frame) { - stream.print("locals ["); - int length = frame.localsLength(); - for (int i = 0; i < length; i++) { - if (i > 0) - stream.print(", "); - Type type = frame.getLocal(i); - stream.print(type == null ? "empty" : type.toString()); - } - stream.println("]"); - } - - private void addSpacing(int count) { - while (count-- > 0) - stream.print(' '); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/IntQueue.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/IntQueue.java deleted file mode 100644 index 955cca0ea..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/IntQueue.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.bytecode.analysis; - -import java.util.NoSuchElementException; - -class IntQueue { - private static class Entry { - private IntQueue.Entry next; - private int value; - private Entry(int value) { - this.value = value; - } - } - private IntQueue.Entry head; - - private IntQueue.Entry tail; - - void add(int value) { - IntQueue.Entry entry = new Entry(value); - if (tail != null) - tail.next = entry; - tail = entry; - - if (head == null) - head = entry; - } - - boolean isEmpty() { - return head == null; - } - - int take() { - if (head == null) - throw new NoSuchElementException(); - - int value = head.value; - head = head.next; - if (head == null) - tail = null; - - return value; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/MultiArrayType.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/MultiArrayType.java deleted file mode 100644 index c638341e6..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/MultiArrayType.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.bytecode.analysis; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.NotFoundException; - -/** - * Represents an array of {@link com.fr.third.javassist.bytecode.analysis.MultiType} instances. - * - * @author Jason T. Greene - */ -public class MultiArrayType extends com.fr.third.javassist.bytecode.analysis.Type { - private com.fr.third.javassist.bytecode.analysis.MultiType component; - private int dims; - - public MultiArrayType(MultiType component, int dims) { - super(null); - this.component = component; - this.dims = dims; - } - - public CtClass getCtClass() { - CtClass clazz = component.getCtClass(); - if (clazz == null) - return null; - - ClassPool pool = clazz.getClassPool(); - if (pool == null) - pool = ClassPool.getDefault(); - - String name = arrayName(clazz.getName(), dims); - - try { - return pool.get(name); - } catch (NotFoundException e) { - throw new RuntimeException(e); - } - } - - boolean popChanged() { - return component.popChanged(); - } - - public int getDimensions() { - return dims; - } - - public com.fr.third.javassist.bytecode.analysis.Type getComponent() { - return dims == 1 ? (com.fr.third.javassist.bytecode.analysis.Type)component : new MultiArrayType(component, dims - 1); - } - - public int getSize() { - return 1; - } - - public boolean isArray() { - return true; - } - - public boolean isAssignableFrom(com.fr.third.javassist.bytecode.analysis.Type type) { - throw new UnsupportedOperationException("Not implemented"); - } - - public boolean isReference() { - return true; - } - - public boolean isAssignableTo(com.fr.third.javassist.bytecode.analysis.Type type) { - if (eq(type.getCtClass(), com.fr.third.javassist.bytecode.analysis.Type.OBJECT.getCtClass())) - return true; - - if (eq(type.getCtClass(), com.fr.third.javassist.bytecode.analysis.Type.CLONEABLE.getCtClass())) - return true; - - if (eq(type.getCtClass(), com.fr.third.javassist.bytecode.analysis.Type.SERIALIZABLE.getCtClass())) - return true; - - if (! type.isArray()) - return false; - - com.fr.third.javassist.bytecode.analysis.Type typeRoot = getRootComponent(type); - int typeDims = type.getDimensions(); - - if (typeDims > dims) - return false; - - if (typeDims < dims) { - if (eq(typeRoot.getCtClass(), com.fr.third.javassist.bytecode.analysis.Type.OBJECT.getCtClass())) - return true; - - if (eq(typeRoot.getCtClass(), com.fr.third.javassist.bytecode.analysis.Type.CLONEABLE.getCtClass())) - return true; - - if (eq(typeRoot.getCtClass(), Type.SERIALIZABLE.getCtClass())) - return true; - - return false; - } - - return component.isAssignableTo(typeRoot); - } - - public boolean equals(Object o) { - if (! (o instanceof MultiArrayType)) - return false; - MultiArrayType multi = (MultiArrayType)o; - - return component.equals(multi.component) && dims == multi.dims; - } - - public String toString() { - // follows the same detailed formating scheme as component - return arrayName(component.toString(), dims); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/MultiType.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/MultiType.java deleted file mode 100644 index da553b6e2..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/MultiType.java +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.bytecode.analysis; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import com.fr.third.javassist.CtClass; - -/** - * MultiType represents an unresolved type. Whenever two Type - * instances are merged, if they share more than one super type (either an - * interface or a superclass), then a MultiType is used to - * represent the possible super types. The goal of a MultiType - * is to reduce the set of possible types down to a single resolved type. This - * is done by eliminating non-assignable types from the typeset when the - * MultiType is passed as an argument to - * {@link com.fr.third.javassist.bytecode.analysis.Type#isAssignableFrom(com.fr.third.javassist.bytecode.analysis.Type)}, as well as removing non-intersecting - * types during a merge. - * - * Note: Currently the MultiType instance is reused as much - * as possible so that updates are visible from all frames. In addition, all - * MultiType merge paths are also updated. This is somewhat - * hackish, but it appears to handle most scenarios. - * - * @author Jason T. Greene - */ - -/* TODO - A better, but more involved, approach would be to track the instruction - * offset that resulted in the creation of this type, and - * whenever the typeset changes, to force a merge on that position. This - * would require creating a new MultiType instance every time the typeset - * changes, and somehow communicating assignment changes to the Analyzer - */ -public class MultiType extends com.fr.third.javassist.bytecode.analysis.Type { - private Map interfaces; - private com.fr.third.javassist.bytecode.analysis.Type resolved; - private com.fr.third.javassist.bytecode.analysis.Type potentialClass; - private MultiType mergeSource; - private boolean changed = false; - - public MultiType(Map interfaces) { - this(interfaces, null); - } - - public MultiType(Map interfaces, com.fr.third.javassist.bytecode.analysis.Type potentialClass) { - super(null); - this.interfaces = interfaces; - this.potentialClass = potentialClass; - } - - /** - * Gets the class that corresponds with this type. If this information - * is not yet known, java.lang.Object will be returned. - */ - public CtClass getCtClass() { - if (resolved != null) - return resolved.getCtClass(); - - return com.fr.third.javassist.bytecode.analysis.Type.OBJECT.getCtClass(); - } - - /** - * Always returns null since this type is never used for an array. - */ - public com.fr.third.javassist.bytecode.analysis.Type getComponent() { - return null; - } - - /** - * Always returns 1, since this type is a reference. - */ - public int getSize() { - return 1; - } - - /** - * Always reutnrs false since this type is never used for an array - */ - public boolean isArray() { - return false; - } - - /** - * Returns true if the internal state has changed. - */ - boolean popChanged() { - boolean changed = this.changed; - this.changed = false; - return changed; - } - - public boolean isAssignableFrom(com.fr.third.javassist.bytecode.analysis.Type type) { - throw new UnsupportedOperationException("Not implemented"); - } - - public boolean isAssignableTo(com.fr.third.javassist.bytecode.analysis.Type type) { - if (resolved != null) - return type.isAssignableFrom(resolved); - - if (com.fr.third.javassist.bytecode.analysis.Type.OBJECT.equals(type)) - return true; - - if (potentialClass != null && !type.isAssignableFrom(potentialClass)) - potentialClass = null; - - Map map = mergeMultiAndSingle(this, type); - - if (map.size() == 1 && potentialClass == null) { - // Update previous merge paths to the same resolved type - resolved = com.fr.third.javassist.bytecode.analysis.Type.get((CtClass)map.values().iterator().next()); - propogateResolved(); - - return true; - } - - // Keep all previous merge paths up to date - if (map.size() >= 1) { - interfaces = map; - propogateState(); - - return true; - } - - if (potentialClass != null) { - resolved = potentialClass; - propogateResolved(); - - return true; - } - - return false; - } - - private void propogateState() { - MultiType source = mergeSource; - while (source != null) { - source.interfaces = interfaces; - source.potentialClass = potentialClass; - source = source.mergeSource; - } - } - - private void propogateResolved() { - MultiType source = mergeSource; - while (source != null) { - source.resolved = resolved; - source = source.mergeSource; - } - } - - /** - * Always returns true, since this type is always a reference. - * - * @return true - */ - public boolean isReference() { - return true; - } - - private Map getAllMultiInterfaces(MultiType type) { - Map map = new HashMap(); - - Iterator iter = type.interfaces.values().iterator(); - while (iter.hasNext()) { - CtClass intf = (CtClass)iter.next(); - map.put(intf.getName(), intf); - getAllInterfaces(intf, map); - } - - return map; - } - - - private Map mergeMultiInterfaces(MultiType type1, MultiType type2) { - Map map1 = getAllMultiInterfaces(type1); - Map map2 = getAllMultiInterfaces(type2); - - return findCommonInterfaces(map1, map2); - } - - private Map mergeMultiAndSingle(MultiType multi, com.fr.third.javassist.bytecode.analysis.Type single) { - Map map1 = getAllMultiInterfaces(multi); - Map map2 = getAllInterfaces(single.getCtClass(), null); - - return findCommonInterfaces(map1, map2); - } - - private boolean inMergeSource(MultiType source) { - while (source != null) { - if (source == this) - return true; - - source = source.mergeSource; - } - - return false; - } - - public com.fr.third.javassist.bytecode.analysis.Type merge(com.fr.third.javassist.bytecode.analysis.Type type) { - if (this == type) - return this; - - if (type == UNINIT) - return this; - - if (type == BOGUS) - return BOGUS; - - if (type == null) - return this; - - if (resolved != null) - return resolved.merge(type); - - if (potentialClass != null) { - com.fr.third.javassist.bytecode.analysis.Type mergePotential = potentialClass.merge(type); - if (! mergePotential.equals(potentialClass) || mergePotential.popChanged()) { - potentialClass = com.fr.third.javassist.bytecode.analysis.Type.OBJECT.equals(mergePotential) ? null : mergePotential; - changed = true; - } - } - - Map merged; - - if (type instanceof MultiType) { - MultiType multi = (MultiType)type; - - if (multi.resolved != null) { - merged = mergeMultiAndSingle(this, multi.resolved); - } else { - merged = mergeMultiInterfaces(multi, this); - if (! inMergeSource(multi)) - mergeSource = multi; - } - } else { - merged = mergeMultiAndSingle(this, type); - } - - // Keep all previous merge paths up to date - if (merged.size() > 1 || (merged.size() == 1 && potentialClass != null)) { - // Check for changes - if (merged.size() != interfaces.size()) { - changed = true; - } else if (changed == false){ - Iterator iter = merged.keySet().iterator(); - while (iter.hasNext()) - if (! interfaces.containsKey(iter.next())) - changed = true; - } - - interfaces = merged; - propogateState(); - - return this; - } - - if (merged.size() == 1) { - resolved = Type.get((CtClass) merged.values().iterator().next()); - } else if (potentialClass != null){ - resolved = potentialClass; - } else { - resolved = OBJECT; - } - - propogateResolved(); - - return resolved; - } - - public boolean equals(Object o) { - if (! (o instanceof MultiType)) - return false; - - MultiType multi = (MultiType) o; - if (resolved != null) - return resolved.equals(multi.resolved); - else if (multi.resolved != null) - return false; - - return interfaces.keySet().equals(multi.interfaces.keySet()); - } - - public String toString() { - if (resolved != null) - return resolved.toString(); - - StringBuffer buffer = new StringBuffer("{"); - Iterator iter = interfaces.keySet().iterator(); - while (iter.hasNext()) { - buffer.append(iter.next()); - buffer.append(", "); - } - buffer.setLength(buffer.length() - 2); - if (potentialClass != null) - buffer.append(", *").append(potentialClass.toString()); - buffer.append("}"); - return buffer.toString(); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Subroutine.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Subroutine.java deleted file mode 100644 index ec25ed3f4..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Subroutine.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.bytecode.analysis; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * Represents a nested method subroutine (marked by JSR and RET). - * - * @author Jason T. Greene - */ -public class Subroutine { - //private Set callers = new HashSet(); - private List callers = new ArrayList(); - private Set access = new HashSet(); - private int start; - - public Subroutine(int start, int caller) { - this.start = start; - callers.add(new Integer(caller)); - } - - public void addCaller(int caller) { - callers.add(new Integer(caller)); - } - - public int start() { - return start; - } - - public void access(int index) { - access.add(new Integer(index)); - } - - public boolean isAccessed(int index) { - return access.contains(new Integer(index)); - } - - public Collection accessed() { - return access; - } - - public Collection callers() { - return callers; - } - - public String toString() { - return "start = " + start + " callers = " + callers.toString(); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/SubroutineScanner.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/SubroutineScanner.java deleted file mode 100644 index a8f9f1e62..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/SubroutineScanner.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.bytecode.analysis; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import com.fr.third.javassist.bytecode.BadBytecode; -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.bytecode.CodeIterator; -import com.fr.third.javassist.bytecode.ExceptionTable; -import com.fr.third.javassist.bytecode.MethodInfo; -import com.fr.third.javassist.bytecode.Opcode; - -/** - * Discovers the subroutines in a method, and tracks all callers. - * - * @author Jason T. Greene - */ -public class SubroutineScanner implements Opcode { - - private com.fr.third.javassist.bytecode.analysis.Subroutine[] subroutines; - Map subTable = new HashMap(); - Set done = new HashSet(); - - - public com.fr.third.javassist.bytecode.analysis.Subroutine[] scan(MethodInfo method) throws BadBytecode { - CodeAttribute code = method.getCodeAttribute(); - CodeIterator iter = code.iterator(); - - subroutines = new com.fr.third.javassist.bytecode.analysis.Subroutine[code.getCodeLength()]; - subTable.clear(); - done.clear(); - - scan(0, iter, null); - - ExceptionTable exceptions = code.getExceptionTable(); - for (int i = 0; i < exceptions.size(); i++) { - int handler = exceptions.handlerPc(i); - // If an exception is thrown in subroutine, the handler - // is part of the same subroutine. - scan(handler, iter, subroutines[exceptions.startPc(i)]); - } - - return subroutines; - } - - private void scan(int pos, CodeIterator iter, com.fr.third.javassist.bytecode.analysis.Subroutine sub) throws BadBytecode { - // Skip already processed blocks - if (done.contains(new Integer(pos))) - return; - - done.add(new Integer(pos)); - - int old = iter.lookAhead(); - iter.move(pos); - - boolean next; - do { - pos = iter.next(); - next = scanOp(pos, iter, sub) && iter.hasNext(); - } while (next); - - iter.move(old); - } - - private boolean scanOp(int pos, CodeIterator iter, com.fr.third.javassist.bytecode.analysis.Subroutine sub) throws BadBytecode { - subroutines[pos] = sub; - - int opcode = iter.byteAt(pos); - - if (opcode == TABLESWITCH) { - scanTableSwitch(pos, iter, sub); - - return false; - } - - if (opcode == LOOKUPSWITCH) { - scanLookupSwitch(pos, iter, sub); - - return false; - } - - // All forms of return and throw end current code flow - if (com.fr.third.javassist.bytecode.analysis.Util.isReturn(opcode) || opcode == RET || opcode == ATHROW) - return false; - - if (com.fr.third.javassist.bytecode.analysis.Util.isJumpInstruction(opcode)) { - int target = com.fr.third.javassist.bytecode.analysis.Util.getJumpTarget(pos, iter); - if (opcode == JSR || opcode == JSR_W) { - com.fr.third.javassist.bytecode.analysis.Subroutine s = (com.fr.third.javassist.bytecode.analysis.Subroutine) subTable.get(new Integer(target)); - if (s == null) { - s = new com.fr.third.javassist.bytecode.analysis.Subroutine(target, pos); - subTable.put(new Integer(target), s); - scan(target, iter, s); - } else { - s.addCaller(pos); - } - } else { - scan(target, iter, sub); - - // GOTO ends current code flow - if (Util.isGoto(opcode)) - return false; - } - } - - return true; - } - - private void scanLookupSwitch(int pos, CodeIterator iter, com.fr.third.javassist.bytecode.analysis.Subroutine sub) throws BadBytecode { - int index = (pos & ~3) + 4; - // default - scan(pos + iter.s32bitAt(index), iter, sub); - int npairs = iter.s32bitAt(index += 4); - int end = npairs * 8 + (index += 4); - - // skip "match" - for (index += 4; index < end; index += 8) { - int target = iter.s32bitAt(index) + pos; - scan(target, iter, sub); - } - } - - private void scanTableSwitch(int pos, CodeIterator iter, Subroutine sub) throws BadBytecode { - // Skip 4 byte alignment padding - int index = (pos & ~3) + 4; - // default - scan(pos + iter.s32bitAt(index), iter, sub); - int low = iter.s32bitAt(index += 4); - int high = iter.s32bitAt(index += 4); - int end = (high - low + 1) * 4 + (index += 4); - - // Offset table - for (; index < end; index += 4) { - int target = iter.s32bitAt(index) + pos; - scan(target, iter, sub); - } - } - - -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Type.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Type.java deleted file mode 100644 index df6e381d6..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Type.java +++ /dev/null @@ -1,593 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.bytecode.analysis; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.Map; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.NotFoundException; - -/** - * Represents a JVM type in data-flow analysis. This abstraction is necessary since - * a JVM type not only includes all normal Java types, but also a few special types - * that are used by the JVM internally. See the static field types on this class for - * more info on these special types. - * - * All primitive and special types reuse the same instance, so identity comparison can - * be used when examining them. Normal java types must use {@link #equals(Object)} to - * compare type instances. - * - * In most cases, applications which consume this API, only need to call {@link #getCtClass()} - * to obtain the needed type information. - * - * @author Jason T. Greene - */ -public class Type { - private final CtClass clazz; - private final boolean special; - - private static final Map prims = new IdentityHashMap(); - /** Represents the double primitive type */ - public static final Type DOUBLE = new Type(CtClass.doubleType); - /** Represents the boolean primitive type */ - public static final Type BOOLEAN = new Type(CtClass.booleanType); - /** Represents the long primitive type */ - public static final Type LONG = new Type(CtClass.longType); - /** Represents the char primitive type */ - public static final Type CHAR = new Type(CtClass.charType); - /** Represents the byte primitive type */ - public static final Type BYTE = new Type(CtClass.byteType); - /** Represents the short primitive type */ - public static final Type SHORT = new Type(CtClass.shortType); - /** Represents the integer primitive type */ - public static final Type INTEGER = new Type(CtClass.intType); - /** Represents the float primitive type */ - public static final Type FLOAT = new Type(CtClass.floatType); - /** Represents the void primitive type */ - public static final Type VOID = new Type(CtClass.voidType); - - /** - * Represents an unknown, or null type. This occurs when aconst_null is used. - * It is important not to treat this type as java.lang.Object, since a null can - * be assigned to any reference type. The analyzer will replace these with - * an actual known type if it can be determined by a merged path with known type - * information. If this type is encountered on a frame then it is guaranteed to - * be null, and the type information is simply not available. Any attempts to - * infer the type, without further information from the compiler would be a guess. - */ - public static final Type UNINIT = new Type(null); - - /** - * Represents an internal JVM return address, which is used by the RET - * instruction to return to a JSR that invoked the subroutine. - */ - public static final Type RETURN_ADDRESS = new Type(null, true); - - /** A placeholder used by the analyzer for the second word position of a double-word type */ - public static final Type TOP = new Type(null, true); - - /** - * Represents a non-accessible value. Code cannot access the value this type - * represents. It occurs when bytecode reuses a local variable table - * position with non-mergable types. An example would be compiled code which - * uses the same position for a primitive type in one branch, and a reference type - * in another branch. - */ - public static final Type BOGUS = new Type(null, true); - - /** Represents the java.lang.Object reference type */ - public static final Type OBJECT = lookupType("java.lang.Object"); - /** Represents the java.io.Serializable reference type */ - public static final Type SERIALIZABLE = lookupType("java.io.Serializable"); - /** Represents the java.lang.Coneable reference type */ - public static final Type CLONEABLE = lookupType("java.lang.Cloneable"); - /** Represents the java.lang.Throwable reference type */ - public static final Type THROWABLE = lookupType("java.lang.Throwable"); - - static { - prims.put(CtClass.doubleType, DOUBLE); - prims.put(CtClass.longType, LONG); - prims.put(CtClass.charType, CHAR); - prims.put(CtClass.shortType, SHORT); - prims.put(CtClass.intType, INTEGER); - prims.put(CtClass.floatType, FLOAT); - prims.put(CtClass.byteType, BYTE); - prims.put(CtClass.booleanType, BOOLEAN); - prims.put(CtClass.voidType, VOID); - - } - - /** - * Obtain the Type for a given class. If the class is a primitive, - * the the unique type instance for the primitive will be returned. - * Otherwise a new Type instance representing the class is returned. - * - * @param clazz The java class - * @return a type instance for this class - */ - public static Type get(CtClass clazz) { - Type type = (Type)prims.get(clazz); - return type != null ? type : new Type(clazz); - } - - private static Type lookupType(String name) { - try { - return new Type(ClassPool.getDefault().get(name)); - } catch (NotFoundException e) { - throw new RuntimeException(e); - } - } - - Type(CtClass clazz) { - this(clazz, false); - } - - private Type(CtClass clazz, boolean special) { - this.clazz = clazz; - this.special = special; - } - - // Used to indicate a merge internally triggered a change - boolean popChanged() { - return false; - } - - /** - * Gets the word size of this type. Double-word types, such as long and double - * will occupy two positions on the local variable table or stack. - * - * @return the number of words needed to hold this type - */ - public int getSize() { - return clazz == CtClass.doubleType || clazz == CtClass.longType || this == TOP ? 2 : 1; - } - - /** - * Returns the class this type represents. If the type is special, null will be returned. - * - * @return the class for this type, or null if special - */ - public CtClass getCtClass() { - return clazz; - } - - /** - * Returns whether or not this type is a normal java reference, i.e. it is or extends java.lang.Object. - * - * @return true if a java reference, false if a primitive or special - */ - public boolean isReference() { - return !special && (clazz == null || !clazz.isPrimitive()); - } - - /** - * Returns whether or not the type is special. A special type is one that is either used - * for internal tracking, or is only used internally by the JVM. - * - * @return true if special, false if not - */ - public boolean isSpecial() { - return special; - } - - /** - * Returns whether or not this type is an array. - * - * @return true if an array, false if not - */ - public boolean isArray() { - return clazz != null && clazz.isArray(); - } - - /** - * Returns the number of dimensions of this array. If the type is not an - * array zero is returned. - * - * @return zero if not an array, otherwise the number of array dimensions. - */ - public int getDimensions() { - if (!isArray()) return 0; - - String name = clazz.getName(); - int pos = name.length() - 1; - int count = 0; - while (name.charAt(pos) == ']' ) { - pos -= 2; - count++; - } - - return count; - } - - /** - * Returns the array component if this type is an array. If the type - * is not an array null is returned. - * - * @return the array component if an array, otherwise null - */ - public Type getComponent() { - if (this.clazz == null || !this.clazz.isArray()) - return null; - - CtClass component; - try { - component = this.clazz.getComponentType(); - } catch (NotFoundException e) { - throw new RuntimeException(e); - } - - Type type = (Type)prims.get(component); - return (type != null) ? type : new Type(component); - } - - /** - * Determines whether this type is assignable, to the passed type. - * A type is assignable to another if it is either the same type, or - * a sub-type. - * - * @param type the type to test assignability to - * @return true if this is assignable to type, otherwise false - */ - public boolean isAssignableFrom(Type type) { - if (this == type) - return true; - - if ((type == UNINIT && isReference()) || this == UNINIT && type.isReference()) - return true; - - if (type instanceof MultiType) - return ((MultiType)type).isAssignableTo(this); - - if (type instanceof MultiArrayType) - return ((MultiArrayType)type).isAssignableTo(this); - - - // Primitives and Special types must be identical - if (clazz == null || clazz.isPrimitive()) - return false; - - try { - return type.clazz.subtypeOf(clazz); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * Finds the common base type, or interface which both this and the specified - * type can be assigned. If there is more than one possible answer, then a {@link MultiType}, - * or a {@link MultiArrayType} is returned. Multi-types have special rules, - * and successive merges and assignment tests on them will alter their internal state, - * as well as other multi-types they have been merged with. This method is used by - * the data-flow analyzer to merge the type state from multiple branches. - * - * @param type the type to merge with - * @return the merged type - */ - public Type merge(Type type) { - if (type == this) - return this; - if (type == null) - return this; - if (type == Type.UNINIT) - return this; - if (this == Type.UNINIT) - return type; - - // Unequal primitives and special types can not be merged - if (! type.isReference() || ! this.isReference()) - return BOGUS; - - // Centralize merging of multi-interface types - if (type instanceof MultiType) - return type.merge(this); - - if (type.isArray() && this.isArray()) - return mergeArray(type); - - try { - return mergeClasses(type); - } catch (NotFoundException e) { - throw new RuntimeException(e); - } - } - - Type getRootComponent(Type type) { - while (type.isArray()) - type = type.getComponent(); - - return type; - } - - private Type createArray(Type rootComponent, int dims) { - if (rootComponent instanceof MultiType) - return new MultiArrayType((MultiType) rootComponent, dims); - - String name = arrayName(rootComponent.clazz.getName(), dims); - - Type type; - try { - type = Type.get(getClassPool(rootComponent).get(name)); - } catch (NotFoundException e) { - throw new RuntimeException(e); - } - - return type; - } - - String arrayName(String component, int dims) { - // Using char[] since we have no StringBuilder in JDK4, and StringBuffer is slow. - // Although, this is more efficient even if we did have one. - int i = component.length(); - int size = i + dims * 2; - char[] string = new char[size]; - component.getChars(0, i, string, 0); - while (i < size) { - string[i++] = '['; - string[i++] = ']'; - } - component = new String(string); - return component; - } - - private ClassPool getClassPool(Type rootComponent) { - ClassPool pool = rootComponent.clazz.getClassPool(); - return pool != null ? pool : ClassPool.getDefault(); - } - - private Type mergeArray(Type type) { - Type typeRoot = getRootComponent(type); - Type thisRoot = getRootComponent(this); - int typeDims = type.getDimensions(); - int thisDims = this.getDimensions(); - - // Array commponents can be merged when the dimensions are equal - if (typeDims == thisDims) { - Type mergedComponent = thisRoot.merge(typeRoot); - - // If the components can not be merged (a primitive component mixed with a different type) - // then Object is the common type. - if (mergedComponent == Type.BOGUS) - return Type.OBJECT; - - return createArray(mergedComponent, thisDims); - } - - Type targetRoot; - int targetDims; - - if (typeDims < thisDims) { - targetRoot = typeRoot; - targetDims = typeDims; - } else { - targetRoot = thisRoot; - targetDims = thisDims; - } - - // Special case, arrays are cloneable and serializable, so prefer them when dimensions differ - if (eq(CLONEABLE.clazz, targetRoot.clazz) || eq(SERIALIZABLE.clazz, targetRoot.clazz)) - return createArray(targetRoot, targetDims); - - return createArray(OBJECT, targetDims); - } - - private static CtClass findCommonSuperClass(CtClass one, CtClass two) throws NotFoundException { - CtClass deep = one; - CtClass shallow = two; - CtClass backupShallow = shallow; - CtClass backupDeep = deep; - - // Phase 1 - Find the deepest hierarchy, set deep and shallow correctly - for (;;) { - // In case we get lucky, and find a match early - if (eq(deep, shallow) && deep.getSuperclass() != null) - return deep; - - CtClass deepSuper = deep.getSuperclass(); - CtClass shallowSuper = shallow.getSuperclass(); - - if (shallowSuper == null) { - // right, now reset shallow - shallow = backupShallow; - break; - } - - if (deepSuper == null) { - // wrong, swap them, since deep is now useless, its our tmp before we swap it - deep = backupDeep; - backupDeep = backupShallow; - backupShallow = deep; - - deep = shallow; - shallow = backupShallow; - break; - } - - deep = deepSuper; - shallow = shallowSuper; - } - - // Phase 2 - Move deepBackup up by (deep end - deep) - for (;;) { - deep = deep.getSuperclass(); - if (deep == null) - break; - - backupDeep = backupDeep.getSuperclass(); - } - - deep = backupDeep; - - // Phase 3 - The hierarchy positions are now aligned - // The common super class is easy to find now - while (!eq(deep, shallow)) { - deep = deep.getSuperclass(); - shallow = shallow.getSuperclass(); - } - - return deep; - } - - private Type mergeClasses(Type type) throws NotFoundException { - CtClass superClass = findCommonSuperClass(this.clazz, type.clazz); - - // If its Object, then try and find a common interface(s) - if (superClass.getSuperclass() == null) { - Map interfaces = findCommonInterfaces(type); - if (interfaces.size() == 1) - return new Type((CtClass) interfaces.values().iterator().next()); - if (interfaces.size() > 1) - return new MultiType(interfaces); - - // Only Object is in common - return new Type(superClass); - } - - // Check for a common interface that is not on the found supertype - Map commonDeclared = findExclusiveDeclaredInterfaces(type, superClass); - if (commonDeclared.size() > 0) { - return new MultiType(commonDeclared, new Type(superClass)); - } - - return new Type(superClass); - } - - private Map findCommonInterfaces(Type type) { - Map typeMap = getAllInterfaces(type.clazz, null); - Map thisMap = getAllInterfaces(this.clazz, null); - - return findCommonInterfaces(typeMap, thisMap); - } - - private Map findExclusiveDeclaredInterfaces(Type type, CtClass exclude) { - Map typeMap = getDeclaredInterfaces(type.clazz, null); - Map thisMap = getDeclaredInterfaces(this.clazz, null); - Map excludeMap = getAllInterfaces(exclude, null); - - Iterator i = excludeMap.keySet().iterator(); - while (i.hasNext()) { - Object intf = i.next(); - typeMap.remove(intf); - thisMap.remove(intf); - } - - return findCommonInterfaces(typeMap, thisMap); - } - - - Map findCommonInterfaces(Map typeMap, Map alterMap) { - Iterator i = alterMap.keySet().iterator(); - while (i.hasNext()) { - if (! typeMap.containsKey(i.next())) - i.remove(); - } - - // Reduce to subinterfaces - // This does not need to be recursive since we make a copy, - // and that copy contains all super types for the whole hierarchy - i = new ArrayList(alterMap.values()).iterator(); - while (i.hasNext()) { - CtClass intf = (CtClass) i.next(); - CtClass[] interfaces; - try { - interfaces = intf.getInterfaces(); - } catch (NotFoundException e) { - throw new RuntimeException(e); - } - - for (int c = 0; c < interfaces.length; c++) - alterMap.remove(interfaces[c].getName()); - } - - return alterMap; - } - - Map getAllInterfaces(CtClass clazz, Map map) { - if (map == null) - map = new HashMap(); - - if (clazz.isInterface()) - map.put(clazz.getName(), clazz); - do { - try { - CtClass[] interfaces = clazz.getInterfaces(); - for (int i = 0; i < interfaces.length; i++) { - CtClass intf = interfaces[i]; - map.put(intf.getName(), intf); - getAllInterfaces(intf, map); - } - - clazz = clazz.getSuperclass(); - } catch (NotFoundException e) { - throw new RuntimeException(e); - } - } while (clazz != null); - - return map; - } - - Map getDeclaredInterfaces(CtClass clazz, Map map) { - if (map == null) - map = new HashMap(); - - if (clazz.isInterface()) - map.put(clazz.getName(), clazz); - - CtClass[] interfaces; - try { - interfaces = clazz.getInterfaces(); - } catch (NotFoundException e) { - throw new RuntimeException(e); - } - - for (int i = 0; i < interfaces.length; i++) { - CtClass intf = interfaces[i]; - map.put(intf.getName(), intf); - getDeclaredInterfaces(intf, map); - } - - return map; - } - - public boolean equals(Object o) { - if (! (o instanceof Type)) - return false; - - return o.getClass() == getClass() && eq(clazz, ((Type)o).clazz); - } - - static boolean eq(CtClass one, CtClass two) { - return one == two || (one != null && two != null && one.getName().equals(two.getName())); - } - - public String toString() { - if (this == BOGUS) - return "BOGUS"; - if (this == UNINIT) - return "UNINIT"; - if (this == RETURN_ADDRESS) - return "RETURN ADDRESS"; - if (this == TOP) - return "TOP"; - - return clazz == null ? "null" : clazz.getName(); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Util.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Util.java deleted file mode 100644 index 7c962e43c..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/Util.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.bytecode.analysis; - -import com.fr.third.javassist.bytecode.CodeIterator; -import com.fr.third.javassist.bytecode.Opcode; - -/** - * A set of common utility methods. - * - * @author Jason T. Greene - */ -public class Util implements Opcode { - public static int getJumpTarget(int pos, CodeIterator iter) { - int opcode = iter.byteAt(pos); - pos += (opcode == JSR_W || opcode == GOTO_W) ? iter.s32bitAt(pos + 1) : iter.s16bitAt(pos + 1); - return pos; - } - - public static boolean isJumpInstruction(int opcode) { - return (opcode >= IFEQ && opcode <= JSR) || opcode == IFNULL || opcode == IFNONNULL || opcode == JSR_W || opcode == GOTO_W; - } - - public static boolean isGoto(int opcode) { - return opcode == GOTO || opcode == GOTO_W; - } - - public static boolean isJsr(int opcode) { - return opcode == JSR || opcode == JSR_W; - } - - public static boolean isReturn(int opcode) { - return (opcode >= IRETURN && opcode <= RETURN); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/package.html b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/package.html deleted file mode 100644 index ec39a4736..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/analysis/package.html +++ /dev/null @@ -1,20 +0,0 @@ - - -Bytecode Analysis API. - -

This package provides an API for performing data-flow analysis on a method's bytecode. -This allows the user to determine the type state of the stack and local variable table -at the start of every instruction. In addition this API can be used to validate -bytecode, find dead bytecode, and identify unnecessary checkcasts. -Look at ControlFlow class first for details. - -

The users of this package must know the specifications of -class file and Java bytecode. For more details, read this book: - -

    Tim Lindholm and Frank Yellin, -"The Java Virtual Machine Specification 2nd Ed.", -Addison-Wesley, 1999. -
- - - diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/Annotation.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/Annotation.java deleted file mode 100644 index 730cb8dfd..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/Annotation.java +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 2004 Bill Burke. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.annotation; - -import com.fr.third.javassist.bytecode.AnnotationDefaultAttribute; -import com.fr.third.javassist.bytecode.AnnotationsAttribute; -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.bytecode.Descriptor; -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CtMethod; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.bytecode.ParameterAnnotationsAttribute; - -import java.io.IOException; -import java.util.LinkedHashMap; -import java.util.Set; -import java.util.Iterator; - -/** - * The annotation structure. - * - *

An instance of this class is returned by - * getAnnotations() in AnnotationsAttribute - * or in ParameterAnnotationsAttribute. - * - * @see AnnotationsAttribute#getAnnotations() - * @see ParameterAnnotationsAttribute#getAnnotations() - * @see MemberValue - * @see MemberValueVisitor - * @see AnnotationsWriter - * - * @author Bill Burke - * @author Shigeru Chiba - * @author Adrian Brock - */ -public class Annotation { - static class Pair { - int name; - MemberValue value; - } - - ConstPool pool; - int typeIndex; - LinkedHashMap members; // this sould be LinkedHashMap - // but it is not supported by JDK 1.3. - - /** - * Constructs an annotation including no members. A member can be - * later added to the created annotation by addMemberValue(). - * - * @param type the index into the constant pool table. - * the entry at that index must be the - * CONSTANT_Utf8_Info structure - * repreenting the name of the annotation interface type. - * @param cp the constant pool table. - * - * @see #addMemberValue(String, MemberValue) - */ - public Annotation(int type, ConstPool cp) { - pool = cp; - typeIndex = type; - members = null; - } - - /** - * Constructs an annotation including no members. A member can be - * later added to the created annotation by addMemberValue(). - * - * @param typeName the name of the annotation interface type. - * @param cp the constant pool table. - * - * @see #addMemberValue(String, MemberValue) - */ - public Annotation(String typeName, ConstPool cp) { - this(cp.addUtf8Info(Descriptor.of(typeName)), cp); - } - - /** - * Constructs an annotation that can be accessed through the interface - * represented by clazz. The values of the members are - * not specified. - * - * @param cp the constant pool table. - * @param clazz the interface. - * @throws NotFoundException when the clazz is not found - */ - public Annotation(ConstPool cp, CtClass clazz) - throws NotFoundException - { - // todo Enums are not supported right now. - this(cp.addUtf8Info(Descriptor.of(clazz.getName())), cp); - - if (!clazz.isInterface()) - throw new RuntimeException( - "Only interfaces are allowed for Annotation creation."); - - CtMethod methods[] = clazz.getDeclaredMethods(); - if (methods.length > 0) { - members = new LinkedHashMap(); - } - - for (int i = 0; i < methods.length; i++) { - CtClass returnType = methods[i].getReturnType(); - addMemberValue(methods[i].getName(), - createMemberValue(cp, returnType)); - - } - } - - /** - * Makes an instance of MemberValue. - * - * @param cp the constant pool table. - * @param type the type of the member. - * @return the member value - * @throws NotFoundException when the type is not found - */ - public static MemberValue createMemberValue(ConstPool cp, CtClass type) - throws NotFoundException - { - if (type == CtClass.booleanType) - return new BooleanMemberValue(cp); - else if (type == CtClass.byteType) - return new ByteMemberValue(cp); - else if (type == CtClass.charType) - return new CharMemberValue(cp); - else if (type == CtClass.shortType) - return new ShortMemberValue(cp); - else if (type == CtClass.intType) - return new IntegerMemberValue(cp); - else if (type == CtClass.longType) - return new LongMemberValue(cp); - else if (type == CtClass.floatType) - return new FloatMemberValue(cp); - else if (type == CtClass.doubleType) - return new DoubleMemberValue(cp); - else if (type.getName().equals("java.lang.Class")) - return new ClassMemberValue(cp); - else if (type.getName().equals("java.lang.String")) - return new StringMemberValue(cp); - else if (type.isArray()) { - CtClass arrayType = type.getComponentType(); - MemberValue member = createMemberValue(cp, arrayType); - return new ArrayMemberValue(member, cp); - } - else if (type.isInterface()) { - Annotation info = new Annotation(cp, type); - return new AnnotationMemberValue(info, cp); - } - else { - // treat as enum. I know this is not typed, - // but JBoss has an Annotation Compiler for JDK 1.4 - // and I want it to work with that. - Bill Burke - EnumMemberValue emv = new EnumMemberValue(cp); - emv.setType(type.getName()); - return emv; - } - } - - /** - * Adds a new member. - * - * @param nameIndex the index into the constant pool table. - * The entry at that index must be - * a CONSTANT_Utf8_info structure. - * structure representing the member name. - * @param value the member value. - */ - public void addMemberValue(int nameIndex, MemberValue value) { - Pair p = new Pair(); - p.name = nameIndex; - p.value = value; - addMemberValue(p); - } - - /** - * Adds a new member. - * - * @param name the member name. - * @param value the member value. - */ - public void addMemberValue(String name, MemberValue value) { - Pair p = new Pair(); - p.name = pool.addUtf8Info(name); - p.value = value; - if (members == null) - members = new LinkedHashMap(); - - members.put(name, p); - } - - private void addMemberValue(Pair pair) { - String name = pool.getUtf8Info(pair.name); - if (members == null) - members = new LinkedHashMap(); - - members.put(name, pair); - } - - /** - * Returns a string representation of the annotation. - */ - public String toString() { - StringBuffer buf = new StringBuffer("@"); - buf.append(getTypeName()); - if (members != null) { - buf.append("("); - Iterator mit = members.keySet().iterator(); - while (mit.hasNext()) { - String name = (String)mit.next(); - buf.append(name).append("=").append(getMemberValue(name)); - if (mit.hasNext()) - buf.append(", "); - } - buf.append(")"); - } - - return buf.toString(); - } - - /** - * Obtains the name of the annotation type. - * - * @return the type name - */ - public String getTypeName() { - return Descriptor.toClassName(pool.getUtf8Info(typeIndex)); - } - - /** - * Obtains all the member names. - * - * @return null if no members are defined. - */ - public Set getMemberNames() { - if (members == null) - return null; - else - return members.keySet(); - } - - /** - * Obtains the member value with the given name. - * - *

If this annotation does not have a value for the - * specified member, - * this method returns null. It does not return a - * MemberValue with the default value. - * The default value can be obtained from the annotation type. - * - * @param name the member name - * @return null if the member cannot be found or if the value is - * the default value. - * - * @see AnnotationDefaultAttribute - */ - public MemberValue getMemberValue(String name) { - if (members == null) - return null; - else { - Pair p = (Pair)members.get(name); - if (p == null) - return null; - else - return p.value; - } - } - - /** - * Constructs an annotation-type object representing this annotation. - * For example, if this annotation represents @Author, - * this method returns an Author object. - * - * @param cl class loader for loading an annotation type. - * @param cp class pool for obtaining class files. - * @return the annotation - * @throws ClassNotFoundException if the class cannot found. - * @throws NoSuchClassError if the class linkage fails. - */ - public Object toAnnotationType(ClassLoader cl, ClassPool cp) - throws ClassNotFoundException, NoSuchClassError - { - return AnnotationImpl.make(cl, - MemberValue.loadClass(cl, getTypeName()), - cp, this); - } - - /** - * Writes this annotation. - * - * @param writer the output. - * @throws IOException for an error during the write - */ - public void write(AnnotationsWriter writer) throws IOException { - String typeName = pool.getUtf8Info(typeIndex); - if (members == null) { - writer.annotation(typeName, 0); - return; - } - - writer.annotation(typeName, members.size()); - Iterator it = members.values().iterator(); - while (it.hasNext()) { - Pair pair = (Pair)it.next(); - writer.memberValuePair(pair.name); - pair.value.write(writer); - } - } - - /** - * Returns true if the given object represents the same annotation - * as this object. The equality test checks the member values. - */ - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || obj instanceof Annotation == false) - return false; - - Annotation other = (Annotation) obj; - - if (getTypeName().equals(other.getTypeName()) == false) - return false; - - LinkedHashMap otherMembers = other.members; - if (members == otherMembers) - return true; - else if (members == null) - return otherMembers == null; - else - if (otherMembers == null) - return false; - else - return members.equals(otherMembers); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/AnnotationImpl.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/AnnotationImpl.java deleted file mode 100644 index da1832a9a..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/AnnotationImpl.java +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.annotation; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.bytecode.AnnotationDefaultAttribute; -import com.fr.third.javassist.bytecode.ClassFile; -import com.fr.third.javassist.bytecode.MethodInfo; - -/** - * Internal-use only. This is a helper class internally used for implementing - * toAnnotationType() in Annotation. - * - * @author Shigeru Chiba - * @author Bill Burke - * @author Adrian Brock - */ -public class AnnotationImpl implements InvocationHandler { - private static final String JDK_ANNOTATION_CLASS_NAME = "java.lang.annotation.Annotation"; - private static Method JDK_ANNOTATION_TYPE_METHOD = null; - - private com.fr.third.javassist.bytecode.annotation.Annotation annotation; - private ClassPool pool; - private ClassLoader classLoader; - private transient Class annotationType; - private transient int cachedHashCode = Integer.MIN_VALUE; - - static { - // Try to resolve the JDK annotation type method - try { - Class clazz = Class.forName(JDK_ANNOTATION_CLASS_NAME); - JDK_ANNOTATION_TYPE_METHOD = clazz.getMethod("annotationType", (Class[])null); - } - catch (Exception ignored) { - // Probably not JDK5+ - } - } - - /** - * Constructs an annotation object. - * - * @param cl class loader for obtaining annotation types. - * @param clazz the annotation type. - * @param cp class pool for containing an annotation - * type (or null). - * @param anon the annotation. - * @return the annotation - */ - public static Object make(ClassLoader cl, Class clazz, ClassPool cp, - com.fr.third.javassist.bytecode.annotation.Annotation anon) { - AnnotationImpl handler = new AnnotationImpl(anon, cp, cl); - return Proxy.newProxyInstance(cl, new Class[] { clazz }, handler); - } - - private AnnotationImpl(com.fr.third.javassist.bytecode.annotation.Annotation a, ClassPool cp, ClassLoader loader) { - annotation = a; - pool = cp; - classLoader = loader; - } - - /** - * Obtains the name of the annotation type. - * - * @return the type name - */ - public String getTypeName() { - return annotation.getTypeName(); - } - - /** - * Get the annotation type - * - * @return the annotation class - * @throws NoClassDefFoundError when the class could not loaded - */ - private Class getAnnotationType() { - if (annotationType == null) { - String typeName = annotation.getTypeName(); - try { - annotationType = classLoader.loadClass(typeName); - } - catch (ClassNotFoundException e) { - NoClassDefFoundError error = new NoClassDefFoundError("Error loading annotation class: " + typeName); - error.setStackTrace(e.getStackTrace()); - throw error; - } - } - return annotationType; - } - - /** - * Obtains the internal data structure representing the annotation. - * - * @return the annotation - */ - public Annotation getAnnotation() { - return annotation; - } - - /** - * Executes a method invocation on a proxy instance. - * The implementations of toString(), equals(), - * and hashCode() are directly supplied by the - * AnnotationImpl. The annotationType() method - * is also available on the proxy instance. - */ - public Object invoke(Object proxy, Method method, Object[] args) - throws Throwable - { - String name = method.getName(); - if (Object.class == method.getDeclaringClass()) { - if ("equals".equals(name)) { - Object obj = args[0]; - return new Boolean(checkEquals(obj)); - } - else if ("toString".equals(name)) - return annotation.toString(); - else if ("hashCode".equals(name)) - return new Integer(hashCode()); - } - else if ("annotationType".equals(name) - && method.getParameterTypes().length == 0) - return getAnnotationType(); - - com.fr.third.javassist.bytecode.annotation.MemberValue mv = annotation.getMemberValue(name); - if (mv == null) - return getDefault(name, method); - else - return mv.getValue(classLoader, pool, method); - } - - private Object getDefault(String name, Method method) - throws ClassNotFoundException, RuntimeException - { - String classname = annotation.getTypeName(); - if (pool != null) { - try { - CtClass cc = pool.get(classname); - ClassFile cf = cc.getClassFile2(); - MethodInfo minfo = cf.getMethod(name); - if (minfo != null) { - AnnotationDefaultAttribute ainfo - = (AnnotationDefaultAttribute) - minfo.getAttribute(AnnotationDefaultAttribute.tag); - if (ainfo != null) { - com.fr.third.javassist.bytecode.annotation.MemberValue mv = ainfo.getDefaultValue(); - return mv.getValue(classLoader, pool, method); - } - } - } - catch (NotFoundException e) { - throw new RuntimeException("cannot find a class file: " - + classname); - } - } - - throw new RuntimeException("no default value: " + classname + "." - + name + "()"); - } - - /** - * Returns a hash code value for this object. - */ - public int hashCode() { - if (cachedHashCode == Integer.MIN_VALUE) { - int hashCode = 0; - - // Load the annotation class - getAnnotationType(); - - Method[] methods = annotationType.getDeclaredMethods(); - for (int i = 0; i < methods.length; ++ i) { - String name = methods[i].getName(); - int valueHashCode = 0; - - // Get the value - com.fr.third.javassist.bytecode.annotation.MemberValue mv = annotation.getMemberValue(name); - Object value = null; - try { - if (mv != null) - value = mv.getValue(classLoader, pool, methods[i]); - if (value == null) - value = getDefault(name, methods[i]); - } - catch (RuntimeException e) { - throw e; - } - catch (Exception e) { - throw new RuntimeException("Error retrieving value " + name + " for annotation " + annotation.getTypeName(), e); - } - - // Calculate the hash code - if (value != null) { - if (value.getClass().isArray()) - valueHashCode = arrayHashCode(value); - else - valueHashCode = value.hashCode(); - } - hashCode += 127 * name.hashCode() ^ valueHashCode; - } - - cachedHashCode = hashCode; - } - return cachedHashCode; - } - - /** - * Check that another annotation equals ourselves. - * - * @param obj the other annotation - * @return the true when equals false otherwise - * @throws Exception for any problem - */ - private boolean checkEquals(Object obj) throws Exception { - if (obj == null) - return false; - - // Optimization when the other is one of ourselves - if (obj instanceof Proxy) { - InvocationHandler ih = Proxy.getInvocationHandler(obj); - if (ih instanceof AnnotationImpl) { - AnnotationImpl other = (AnnotationImpl) ih; - return annotation.equals(other.annotation); - } - } - - Class otherAnnotationType = (Class) JDK_ANNOTATION_TYPE_METHOD.invoke(obj, (Object[])null); - if (getAnnotationType().equals(otherAnnotationType) == false) - return false; - - Method[] methods = annotationType.getDeclaredMethods(); - for (int i = 0; i < methods.length; ++ i) { - String name = methods[i].getName(); - - // Get the value - MemberValue mv = annotation.getMemberValue(name); - Object value = null; - Object otherValue = null; - try { - if (mv != null) - value = mv.getValue(classLoader, pool, methods[i]); - if (value == null) - value = getDefault(name, methods[i]); - otherValue = methods[i].invoke(obj, (Object[])null); - } - catch (RuntimeException e) { - throw e; - } - catch (Exception e) { - throw new RuntimeException("Error retrieving value " + name + " for annotation " + annotation.getTypeName(), e); - } - - if (value == null && otherValue != null) - return false; - if (value != null && value.equals(otherValue) == false) - return false; - } - - return true; - } - - /** - * Calculates the hashCode of an array using the same - * algorithm as java.util.Arrays.hashCode() - * - * @param object the object - * @return the hashCode - */ - private static int arrayHashCode(Object object) - { - if (object == null) - return 0; - - int result = 1; - - Object[] array = (Object[]) object; - for (int i = 0; i < array.length; ++i) { - int elementHashCode = 0; - if (array[i] != null) - elementHashCode = array[i].hashCode(); - result = 31 * result + elementHashCode; - } - return result; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/AnnotationMemberValue.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/AnnotationMemberValue.java deleted file mode 100644 index 654a5e1ec..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/AnnotationMemberValue.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 2004 Bill Burke. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.bytecode.annotation; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.bytecode.ConstPool; - -import java.io.IOException; -import java.lang.reflect.Method; - -/** - * Nested annotation. - * - * @author Bill Burke - * @author Shigeru Chiba - */ -public class AnnotationMemberValue extends MemberValue { - com.fr.third.javassist.bytecode.annotation.Annotation value; - - /** - * Constructs an annotation member. The initial value is not specified. - */ - public AnnotationMemberValue(ConstPool cp) { - this(null, cp); - } - - /** - * Constructs an annotation member. The initial value is specified by - * the first parameter. - */ - public AnnotationMemberValue(com.fr.third.javassist.bytecode.annotation.Annotation a, ConstPool cp) { - super('@', cp); - value = a; - } - - Object getValue(ClassLoader cl, ClassPool cp, Method m) - throws ClassNotFoundException - { - return AnnotationImpl.make(cl, getType(cl), cp, value); - } - - Class getType(ClassLoader cl) throws ClassNotFoundException { - if (value == null) - throw new ClassNotFoundException("no type specified"); - else - return loadClass(cl, value.getTypeName()); - } - - /** - * Obtains the value. - */ - public com.fr.third.javassist.bytecode.annotation.Annotation getValue() { - return value; - } - - /** - * Sets the value of this member. - */ - public void setValue(Annotation newValue) { - value = newValue; - } - - /** - * Obtains the string representation of this object. - */ - public String toString() { - return value.toString(); - } - - /** - * Writes the value. - */ - public void write(AnnotationsWriter writer) throws IOException { - writer.annotationValue(); - value.write(writer); - } - - /** - * Accepts a visitor. - */ - public void accept(MemberValueVisitor visitor) { - visitor.visitAnnotationMemberValue(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/AnnotationsWriter.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/AnnotationsWriter.java deleted file mode 100644 index a11f0aeb1..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/AnnotationsWriter.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.annotation; - -import java.io.*; - -import com.fr.third.javassist.bytecode.AnnotationsAttribute; -import com.fr.third.javassist.bytecode.ByteArray; -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.bytecode.ParameterAnnotationsAttribute; - -/** - * A convenience class for constructing a - * ..Annotations_attribute. - * See the source code of the AnnotationsAttribute.Copier class. - * - *

The following code snippet is an example of use of this class: - * - *

    - * ConstPool pool = ...;
    - * output = new ByteArrayOutputStream();
    - * writer = new AnnotationsWriter(output, pool);
    - *
    - * writer.numAnnotations(1);
    - * writer.annotation("Author", 2);
    - * writer.memberValuePair("name");
    - * writer.constValueIndex("chiba");
    - * writer.memberValuePair("address");
    - * writer.constValueIndex("tokyo");
    - *
    - * writer.close();
    - * byte[] attribute_info = output.toByteArray();
    - * AnnotationsAttribute anno
    - *     = new AnnotationsAttribute(pool, AnnotationsAttribute.visibleTag,
    - *                                attribute_info);
    - * 
- * - *

The code snippet above generates the annotation attribute - * corresponding to this annotation: - * - *

    - *  @Author(name = "chiba", address = "tokyo")
    - * 
- * - * @see AnnotationsAttribute - * @see ParameterAnnotationsAttribute - */ -public class AnnotationsWriter { - private OutputStream output; - private ConstPool pool; - - /** - * Constructs with the given output stream. - * - * @param os the output stream. - * @param cp the constant pool. - */ - public AnnotationsWriter(OutputStream os, ConstPool cp) { - output = os; - pool = cp; - } - - /** - * Obtains the constant pool given to the constructor. - */ - public ConstPool getConstPool() { - return pool; - } - - /** - * Closes the output stream. - * - */ - public void close() throws IOException { - output.close(); - } - - /** - * Writes num_parameters in - * Runtime(In)VisibleParameterAnnotations_attribute. - * This method must be followed by num calls to - * numAnnotations(). - */ - public void numParameters(int num) throws IOException { - output.write(num); - } - - /** - * Writes num_annotations in - * Runtime(In)VisibleAnnotations_attribute. - * This method must be followed by num calls to - * annotation(). - */ - public void numAnnotations(int num) throws IOException { - write16bit(num); - } - - /** - * Writes annotation. - * This method must be followed by numMemberValuePairs - * calls to memberValuePair(). - * - * @param type the annotation interface name. - * @param numMemberValuePairs num_member_value_pairs - * in annotation. - */ - public void annotation(String type, int numMemberValuePairs) - throws IOException - { - annotation(pool.addUtf8Info(type), numMemberValuePairs); - } - - /** - * Writes annotation. - * This method must be followed by numMemberValuePairs - * calls to memberValuePair(). - * - * @param typeIndex type_index in annotation. - * @param numMemberValuePairs num_member_value_pairs - * in annotation. - */ - public void annotation(int typeIndex, int numMemberValuePairs) - throws IOException - { - write16bit(typeIndex); - write16bit(numMemberValuePairs); - } - - /** - * Writes an element of a member_value_pairs array - * in annotation. - * This method must be followed by a - * call to constValueIndex(), enumConstValue(), - * etc. - * - * @param memberName the name of the annotation type member. - */ - public void memberValuePair(String memberName) throws IOException { - memberValuePair(pool.addUtf8Info(memberName)); - } - - /** - * Writes an element of a member_value_pairs array - * in annotation. - * This method must be followed by a - * call to constValueIndex(), enumConstValue(), - * etc. - * - * @param memberNameIndex member_name_index - * in member_value_pairs array. - */ - public void memberValuePair(int memberNameIndex) throws IOException { - write16bit(memberNameIndex); - } - - /** - * Writes tag and const_value_index - * in member_value. - * - * @param value the constant value. - */ - public void constValueIndex(boolean value) throws IOException { - constValueIndex('Z', pool.addIntegerInfo(value ? 1 : 0)); - } - - /** - * Writes tag and const_value_index - * in member_value. - * - * @param value the constant value. - */ - public void constValueIndex(byte value) throws IOException { - constValueIndex('B', pool.addIntegerInfo(value)); - } - - /** - * Writes tag and const_value_index - * in member_value. - * - * @param value the constant value. - */ - public void constValueIndex(char value) throws IOException { - constValueIndex('C', pool.addIntegerInfo(value)); - } - - /** - * Writes tag and const_value_index - * in member_value. - * - * @param value the constant value. - */ - public void constValueIndex(short value) throws IOException { - constValueIndex('S', pool.addIntegerInfo(value)); - } - - /** - * Writes tag and const_value_index - * in member_value. - * - * @param value the constant value. - */ - public void constValueIndex(int value) throws IOException { - constValueIndex('I', pool.addIntegerInfo(value)); - } - - /** - * Writes tag and const_value_index - * in member_value. - * - * @param value the constant value. - */ - public void constValueIndex(long value) throws IOException { - constValueIndex('J', pool.addLongInfo(value)); - } - - /** - * Writes tag and const_value_index - * in member_value. - * - * @param value the constant value. - */ - public void constValueIndex(float value) throws IOException { - constValueIndex('F', pool.addFloatInfo(value)); - } - - /** - * Writes tag and const_value_index - * in member_value. - * - * @param value the constant value. - */ - public void constValueIndex(double value) throws IOException { - constValueIndex('D', pool.addDoubleInfo(value)); - } - - /** - * Writes tag and const_value_index - * in member_value. - * - * @param value the constant value. - */ - public void constValueIndex(String value) throws IOException { - constValueIndex('s', pool.addUtf8Info(value)); - } - - /** - * Writes tag and const_value_index - * in member_value. - * - * @param tag tag in member_value. - * @param index const_value_index - * in member_value. - */ - public void constValueIndex(int tag, int index) - throws IOException - { - output.write(tag); - write16bit(index); - } - - /** - * Writes tag and enum_const_value - * in member_value. - * - * @param typeName the type name of the enum constant. - * @param constName the simple name of the enum constant. - */ - public void enumConstValue(String typeName, String constName) - throws IOException - { - enumConstValue(pool.addUtf8Info(typeName), - pool.addUtf8Info(constName)); - } - - /** - * Writes tag and enum_const_value - * in member_value. - * - * @param typeNameIndex type_name_index - * in member_value. - * @param constNameIndex const_name_index - * in member_value. - */ - public void enumConstValue(int typeNameIndex, int constNameIndex) - throws IOException - { - output.write('e'); - write16bit(typeNameIndex); - write16bit(constNameIndex); - } - - /** - * Writes tag and class_info_index - * in member_value. - * - * @param name the class name. - */ - public void classInfoIndex(String name) throws IOException { - classInfoIndex(pool.addUtf8Info(name)); - } - - /** - * Writes tag and class_info_index - * in member_value. - * - * @param index class_info_index - */ - public void classInfoIndex(int index) throws IOException { - output.write('c'); - write16bit(index); - } - - /** - * Writes tag and annotation_value - * in member_value. - * This method must be followed by a call to annotation(). - */ - public void annotationValue() throws IOException { - output.write('@'); - } - - /** - * Writes tag and array_value - * in member_value. - * This method must be followed by numValues calls - * to constValueIndex(), enumConstValue(), - * etc. - * - * @param numValues num_values - * in array_value. - */ - public void arrayValue(int numValues) throws IOException { - output.write('['); - write16bit(numValues); - } - - private void write16bit(int value) throws IOException { - byte[] buf = new byte[2]; - ByteArray.write16bit(value, buf, 0); - output.write(buf); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/ArrayMemberValue.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/ArrayMemberValue.java deleted file mode 100644 index e3acd284b..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/ArrayMemberValue.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 2004 Bill Burke. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.bytecode.annotation; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.bytecode.ConstPool; - -import java.io.IOException; -import java.lang.reflect.Array; -import java.lang.reflect.Method; - -/** - * Array member. - * - * @author Bill Burke - * @author Shigeru Chiba - */ -public class ArrayMemberValue extends com.fr.third.javassist.bytecode.annotation.MemberValue { - com.fr.third.javassist.bytecode.annotation.MemberValue type; - com.fr.third.javassist.bytecode.annotation.MemberValue[] values; - - /** - * Constructs an array. The initial value or type are not specified. - */ - public ArrayMemberValue(ConstPool cp) { - super('[', cp); - type = null; - values = null; - } - - /** - * Constructs an array. The initial value is not specified. - * - * @param t the type of the array elements. - */ - public ArrayMemberValue(com.fr.third.javassist.bytecode.annotation.MemberValue t, ConstPool cp) { - super('[', cp); - type = t; - values = null; - } - - Object getValue(ClassLoader cl, ClassPool cp, Method method) - throws ClassNotFoundException - { - if (values == null) - throw new ClassNotFoundException( - "no array elements found: " + method.getName()); - - int size = values.length; - Class clazz; - if (type == null) { - clazz = method.getReturnType().getComponentType(); - if (clazz == null || size > 0) - throw new ClassNotFoundException("broken array type: " - + method.getName()); - } - else - clazz = type.getType(cl); - - Object a = Array.newInstance(clazz, size); - for (int i = 0; i < size; i++) - Array.set(a, i, values[i].getValue(cl, cp, method)); - - return a; - } - - Class getType(ClassLoader cl) throws ClassNotFoundException { - if (type == null) - throw new ClassNotFoundException("no array type specified"); - - Object a = Array.newInstance(type.getType(cl), 0); - return a.getClass(); - } - - /** - * Obtains the type of the elements. - * - * @return null if the type is not specified. - */ - public com.fr.third.javassist.bytecode.annotation.MemberValue getType() { - return type; - } - - /** - * Obtains the elements of the array. - */ - public com.fr.third.javassist.bytecode.annotation.MemberValue[] getValue() { - return values; - } - - /** - * Sets the elements of the array. - */ - public void setValue(MemberValue[] elements) { - values = elements; - if (elements != null && elements.length > 0) - type = elements[0]; - } - - /** - * Obtains the string representation of this object. - */ - public String toString() { - StringBuffer buf = new StringBuffer("{"); - if (values != null) { - for (int i = 0; i < values.length; i++) { - buf.append(values[i].toString()); - if (i + 1 < values.length) - buf.append(", "); - } - } - - buf.append("}"); - return buf.toString(); - } - - /** - * Writes the value. - */ - public void write(AnnotationsWriter writer) throws IOException { - int num = values.length; - writer.arrayValue(num); - for (int i = 0; i < num; ++i) - values[i].write(writer); - } - - /** - * Accepts a visitor. - */ - public void accept(MemberValueVisitor visitor) { - visitor.visitArrayMemberValue(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/BooleanMemberValue.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/BooleanMemberValue.java deleted file mode 100644 index 92bd49158..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/BooleanMemberValue.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 2004 Bill Burke. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.bytecode.annotation; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.bytecode.ConstPool; - -import java.io.IOException; -import java.lang.reflect.Method; - -/** - * Boolean constant value. - * - * @author Bill Burke - * @author Shigeru Chiba - */ -public class BooleanMemberValue extends MemberValue { - int valueIndex; - - /** - * Constructs a boolean constant value. The initial value is specified - * by the constant pool entry at the given index. - * - * @param index the index of a CONSTANT_Integer_info structure. - */ - public BooleanMemberValue(int index, ConstPool cp) { - super('Z', cp); - this.valueIndex = index; - } - - /** - * Constructs a boolean constant value. - * - * @param b the initial value. - */ - public BooleanMemberValue(boolean b, ConstPool cp) { - super('Z', cp); - setValue(b); - } - - /** - * Constructs a boolean constant value. The initial value is false. - */ - public BooleanMemberValue(ConstPool cp) { - super('Z', cp); - setValue(false); - } - - Object getValue(ClassLoader cl, ClassPool cp, Method m) { - return new Boolean(getValue()); - } - - Class getType(ClassLoader cl) { - return boolean.class; - } - - /** - * Obtains the value of the member. - */ - public boolean getValue() { - return cp.getIntegerInfo(valueIndex) != 0; - } - - /** - * Sets the value of the member. - */ - public void setValue(boolean newValue) { - valueIndex = cp.addIntegerInfo(newValue ? 1 : 0); - } - - /** - * Obtains the string representation of this object. - */ - public String toString() { - return getValue() ? "true" : "false"; - } - - /** - * Writes the value. - */ - public void write(AnnotationsWriter writer) throws IOException { - writer.constValueIndex(getValue()); - } - - /** - * Accepts a visitor. - */ - public void accept(MemberValueVisitor visitor) { - visitor.visitBooleanMemberValue(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/ByteMemberValue.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/ByteMemberValue.java deleted file mode 100644 index eac9f1634..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/ByteMemberValue.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 2004 Bill Burke. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.bytecode.annotation; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.bytecode.ConstPool; - -import java.io.IOException; -import java.lang.reflect.Method; - -/** - * Byte constant value. - * - * @author Bill Burke - * @author Shigeru Chiba - */ -public class ByteMemberValue extends MemberValue { - int valueIndex; - - /** - * Constructs a byte constant value. The initial value is specified - * by the constant pool entry at the given index. - * - * @param index the index of a CONSTANT_Integer_info structure. - */ - public ByteMemberValue(int index, ConstPool cp) { - super('B', cp); - this.valueIndex = index; - } - - /** - * Constructs a byte constant value. - * - * @param b the initial value. - */ - public ByteMemberValue(byte b, ConstPool cp) { - super('B', cp); - setValue(b); - } - - /** - * Constructs a byte constant value. The initial value is 0. - */ - public ByteMemberValue(ConstPool cp) { - super('B', cp); - setValue((byte)0); - } - - Object getValue(ClassLoader cl, ClassPool cp, Method m) { - return new Byte(getValue()); - } - - Class getType(ClassLoader cl) { - return byte.class; - } - - /** - * Obtains the value of the member. - */ - public byte getValue() { - return (byte)cp.getIntegerInfo(valueIndex); - } - - /** - * Sets the value of the member. - */ - public void setValue(byte newValue) { - valueIndex = cp.addIntegerInfo(newValue); - } - - /** - * Obtains the string representation of this object. - */ - public String toString() { - return Byte.toString(getValue()); - } - - /** - * Writes the value. - */ - public void write(AnnotationsWriter writer) throws IOException { - writer.constValueIndex(getValue()); - } - - /** - * Accepts a visitor. - */ - public void accept(MemberValueVisitor visitor) { - visitor.visitByteMemberValue(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/CharMemberValue.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/CharMemberValue.java deleted file mode 100644 index c17b901ac..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/CharMemberValue.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 2004 Bill Burke. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.annotation; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.bytecode.ConstPool; - -import java.io.IOException; -import java.lang.reflect.Method; - -/** - * Char constant value. - * - * @author Bill Burke - * @author Shigeru Chiba - */ -public class CharMemberValue extends MemberValue { - int valueIndex; - - /** - * Constructs a char constant value. The initial value is specified - * by the constant pool entry at the given index. - * - * @param index the index of a CONSTANT_Integer_info structure. - */ - public CharMemberValue(int index, ConstPool cp) { - super('C', cp); - this.valueIndex = index; - } - - /** - * Constructs a char constant value. - * - * @param c the initial value. - */ - public CharMemberValue(char c, ConstPool cp) { - super('C', cp); - setValue(c); - } - - /** - * Constructs a char constant value. The initial value is '\0'. - */ - public CharMemberValue(ConstPool cp) { - super('C', cp); - setValue('\0'); - } - - Object getValue(ClassLoader cl, ClassPool cp, Method m) { - return new Character(getValue()); - } - - Class getType(ClassLoader cl) { - return char.class; - } - - /** - * Obtains the value of the member. - */ - public char getValue() { - return (char)cp.getIntegerInfo(valueIndex); - } - - /** - * Sets the value of the member. - */ - public void setValue(char newValue) { - valueIndex = cp.addIntegerInfo(newValue); - } - - /** - * Obtains the string representation of this object. - */ - public String toString() { - return Character.toString(getValue()); - } - - /** - * Writes the value. - */ - public void write(AnnotationsWriter writer) throws IOException { - writer.constValueIndex(getValue()); - } - - /** - * Accepts a visitor. - */ - public void accept(MemberValueVisitor visitor) { - visitor.visitCharMemberValue(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/ClassMemberValue.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/ClassMemberValue.java deleted file mode 100644 index 35deae092..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/ClassMemberValue.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 2004 Bill Burke. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.annotation; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.bytecode.BadBytecode; -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.bytecode.Descriptor; -import com.fr.third.javassist.bytecode.SignatureAttribute; - -import java.io.IOException; -import java.lang.reflect.Method; - -/** - * Class value. - * - * @author Bill Burke - * @author Shigeru Chiba - */ -public class ClassMemberValue extends MemberValue { - int valueIndex; - - /** - * Constructs a class value. The initial value is specified - * by the constant pool entry at the given index. - * - * @param index the index of a CONSTANT_Utf8_info structure. - */ - public ClassMemberValue(int index, ConstPool cp) { - super('c', cp); - this.valueIndex = index; - } - - /** - * Constructs a class value. - * - * @param className the initial value. - */ - public ClassMemberValue(String className, ConstPool cp) { - super('c', cp); - setValue(className); - } - - /** - * Constructs a class value. - * The initial value is java.lang.Class. - */ - public ClassMemberValue(ConstPool cp) { - super('c', cp); - setValue("java.lang.Class"); - } - - Object getValue(ClassLoader cl, ClassPool cp, Method m) - throws ClassNotFoundException { - final String classname = getValue(); - if (classname.equals("void")) - return void.class; - else if (classname.equals("int")) - return int.class; - else if (classname.equals("byte")) - return byte.class; - else if (classname.equals("long")) - return long.class; - else if (classname.equals("double")) - return double.class; - else if (classname.equals("float")) - return float.class; - else if (classname.equals("char")) - return char.class; - else if (classname.equals("short")) - return short.class; - else if (classname.equals("boolean")) - return boolean.class; - else - return loadClass(cl, classname); - } - - Class getType(ClassLoader cl) throws ClassNotFoundException { - return loadClass(cl, "java.lang.Class"); - } - - /** - * Obtains the value of the member. - * - * @return fully-qualified class name. - */ - public String getValue() { - String v = cp.getUtf8Info(valueIndex); - try { - return SignatureAttribute.toTypeSignature(v).jvmTypeName(); - } catch (BadBytecode e) { - throw new RuntimeException(e); - } - } - - /** - * Sets the value of the member. - * - * @param newClassName fully-qualified class name. - */ - public void setValue(String newClassName) { - String setTo = Descriptor.of(newClassName); - valueIndex = cp.addUtf8Info(setTo); - } - - /** - * Obtains the string representation of this object. - */ - public String toString() { - return getValue().replace('$', '.') + ".class"; - } - - /** - * Writes the value. - */ - public void write(AnnotationsWriter writer) throws IOException { - writer.classInfoIndex(cp.getUtf8Info(valueIndex)); - } - - /** - * Accepts a visitor. - */ - public void accept(MemberValueVisitor visitor) { - visitor.visitClassMemberValue(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/DoubleMemberValue.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/DoubleMemberValue.java deleted file mode 100644 index cb212af90..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/DoubleMemberValue.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 2004 Bill Burke. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.annotation; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.bytecode.ConstPool; - -import java.io.IOException; -import java.lang.reflect.Method; - -/** - * Double floating-point number constant value. - * - * @author Bill Burke - * @author Shigeru Chiba - * @version $Revision: 1.7 $ - */ -public class DoubleMemberValue extends MemberValue { - int valueIndex; - - /** - * Constructs a double constant value. The initial value is specified - * by the constant pool entry at the given index. - * - * @param index the index of a CONSTANT_Double_info structure. - */ - public DoubleMemberValue(int index, ConstPool cp) { - super('D', cp); - this.valueIndex = index; - } - - /** - * Constructs a double constant value. - * - * @param d the initial value. - */ - public DoubleMemberValue(double d, ConstPool cp) { - super('D', cp); - setValue(d); - } - - /** - * Constructs a double constant value. The initial value is 0.0. - */ - public DoubleMemberValue(ConstPool cp) { - super('D', cp); - setValue(0.0); - } - - Object getValue(ClassLoader cl, ClassPool cp, Method m) { - return new Double(getValue()); - } - - Class getType(ClassLoader cl) { - return double.class; - } - - /** - * Obtains the value of the member. - */ - public double getValue() { - return cp.getDoubleInfo(valueIndex); - } - - /** - * Sets the value of the member. - */ - public void setValue(double newValue) { - valueIndex = cp.addDoubleInfo(newValue); - } - - /** - * Obtains the string representation of this object. - */ - public String toString() { - return Double.toString(getValue()); - } - - /** - * Writes the value. - */ - public void write(AnnotationsWriter writer) throws IOException { - writer.constValueIndex(getValue()); - } - - /** - * Accepts a visitor. - */ - public void accept(MemberValueVisitor visitor) { - visitor.visitDoubleMemberValue(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/EnumMemberValue.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/EnumMemberValue.java deleted file mode 100644 index 5c2fbafe4..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/EnumMemberValue.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 2004 Bill Burke. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.annotation; - -import java.io.IOException; -import java.lang.reflect.Method; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.bytecode.Descriptor; - -/** - * Enum constant value. - * - * @author Bill Burke - * @author Shigeru Chiba - */ -public class EnumMemberValue extends MemberValue { - int typeIndex, valueIndex; - - /** - * Constructs an enum constant value. The initial value is specified - * by the constant pool entries at the given indexes. - * - * @param type the index of a CONSTANT_Utf8_info structure - * representing the enum type. - * @param value the index of a CONSTANT_Utf8_info structure. - * representing the enum value. - */ - public EnumMemberValue(int type, int value, ConstPool cp) { - super('e', cp); - this.typeIndex = type; - this.valueIndex = value; - } - - /** - * Constructs an enum constant value. - * The initial value is not specified. - */ - public EnumMemberValue(ConstPool cp) { - super('e', cp); - typeIndex = valueIndex = 0; - } - - Object getValue(ClassLoader cl, ClassPool cp, Method m) - throws ClassNotFoundException - { - try { - return getType(cl).getField(getValue()).get(null); - } - catch (NoSuchFieldException e) { - throw new ClassNotFoundException(getType() + "." + getValue()); - } - catch (IllegalAccessException e) { - throw new ClassNotFoundException(getType() + "." + getValue()); - } - } - - Class getType(ClassLoader cl) throws ClassNotFoundException { - return loadClass(cl, getType()); - } - - /** - * Obtains the enum type name. - * - * @return a fully-qualified type name. - */ - public String getType() { - return Descriptor.toClassName(cp.getUtf8Info(typeIndex)); - } - - /** - * Changes the enum type name. - * - * @param typename a fully-qualified type name. - */ - public void setType(String typename) { - typeIndex = cp.addUtf8Info(Descriptor.of(typename)); - } - - /** - * Obtains the name of the enum constant value. - */ - public String getValue() { - return cp.getUtf8Info(valueIndex); - } - - /** - * Changes the name of the enum constant value. - */ - public void setValue(String name) { - valueIndex = cp.addUtf8Info(name); - } - - public String toString() { - return getType() + "." + getValue(); - } - - /** - * Writes the value. - */ - public void write(AnnotationsWriter writer) throws IOException { - writer.enumConstValue(cp.getUtf8Info(typeIndex), getValue()); - } - - /** - * Accepts a visitor. - */ - public void accept(MemberValueVisitor visitor) { - visitor.visitEnumMemberValue(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/FloatMemberValue.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/FloatMemberValue.java deleted file mode 100644 index 8911fe99e..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/FloatMemberValue.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 2004 Bill Burke. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.annotation; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.bytecode.ConstPool; - -import java.io.IOException; -import java.lang.reflect.Method; - -/** - * Floating-point number constant value. - * - * @author Bill Burke - * @author Shigeru Chiba - * @version $Revision: 1.7 $ - */ -public class FloatMemberValue extends MemberValue { - int valueIndex; - - /** - * Constructs a float constant value. The initial value is specified - * by the constant pool entry at the given index. - * - * @param index the index of a CONSTANT_Float_info structure. - */ - public FloatMemberValue(int index, ConstPool cp) { - super('F', cp); - this.valueIndex = index; - } - - /** - * Constructs a float constant value. - * - * @param f the initial value. - */ - public FloatMemberValue(float f, ConstPool cp) { - super('F', cp); - setValue(f); - } - - /** - * Constructs a float constant value. The initial value is 0.0. - */ - public FloatMemberValue(ConstPool cp) { - super('F', cp); - setValue(0.0F); - } - - Object getValue(ClassLoader cl, ClassPool cp, Method m) { - return new Float(getValue()); - } - - Class getType(ClassLoader cl) { - return float.class; - } - - /** - * Obtains the value of the member. - */ - public float getValue() { - return cp.getFloatInfo(valueIndex); - } - - /** - * Sets the value of the member. - */ - public void setValue(float newValue) { - valueIndex = cp.addFloatInfo(newValue); - } - - /** - * Obtains the string representation of this object. - */ - public String toString() { - return Float.toString(getValue()); - } - - /** - * Writes the value. - */ - public void write(AnnotationsWriter writer) throws IOException { - writer.constValueIndex(getValue()); - } - - /** - * Accepts a visitor. - */ - public void accept(MemberValueVisitor visitor) { - visitor.visitFloatMemberValue(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/IntegerMemberValue.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/IntegerMemberValue.java deleted file mode 100644 index 6b5505b7a..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/IntegerMemberValue.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 2004 Bill Burke. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.annotation; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.bytecode.ConstPool; - -import java.io.IOException; -import java.lang.reflect.Method; - -/** - * Integer constant value. - * - * @author Bill Burke - * @author Shigeru Chiba - */ -public class IntegerMemberValue extends MemberValue { - int valueIndex; - - /** - * Constructs an int constant value. The initial value is specified - * by the constant pool entry at the given index. - * - * @param index the index of a CONSTANT_Integer_info structure. - */ - public IntegerMemberValue(int index, ConstPool cp) { - super('I', cp); - this.valueIndex = index; - } - - /** - * Constructs an int constant value. - * Note that this constructor receives the initial value - * as the second parameter - * unlike the corresponding constructors in the sibling classes. - * This is for making a difference from the constructor that receives - * an index into the constant pool table as the first parameter. - * Note that the index is also int type. - * - * @param value the initial value. - */ - public IntegerMemberValue(ConstPool cp, int value) { - super('I', cp); - setValue(value); - } - - /** - * Constructs an int constant value. The initial value is 0. - */ - public IntegerMemberValue(ConstPool cp) { - super('I', cp); - setValue(0); - } - - Object getValue(ClassLoader cl, ClassPool cp, Method m) { - return new Integer(getValue()); - } - - Class getType(ClassLoader cl) { - return int.class; - } - - /** - * Obtains the value of the member. - */ - public int getValue() { - return cp.getIntegerInfo(valueIndex); - } - - /** - * Sets the value of the member. - */ - public void setValue(int newValue) { - valueIndex = cp.addIntegerInfo(newValue); - } - - /** - * Obtains the string representation of this object. - */ - public String toString() { - return Integer.toString(getValue()); - } - - /** - * Writes the value. - */ - public void write(AnnotationsWriter writer) throws IOException { - writer.constValueIndex(getValue()); - } - - /** - * Accepts a visitor. - */ - public void accept(MemberValueVisitor visitor) { - visitor.visitIntegerMemberValue(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/LongMemberValue.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/LongMemberValue.java deleted file mode 100644 index 8188d02fc..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/LongMemberValue.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 2004 Bill Burke. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.annotation; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.bytecode.ConstPool; - -import java.io.IOException; -import java.lang.reflect.Method; - -/** - * Long integer constant value. - * - * @author Bill Burke - * @author Shigeru Chiba - */ -public class LongMemberValue extends MemberValue { - int valueIndex; - - /** - * Constructs a long constant value. The initial value is specified - * by the constant pool entry at the given index. - * - * @param index the index of a CONSTANT_Long_info structure. - */ - public LongMemberValue(int index, ConstPool cp) { - super('J', cp); - this.valueIndex = index; - } - - /** - * Constructs a long constant value. - * - * @param j the initial value. - */ - public LongMemberValue(long j, ConstPool cp) { - super('J', cp); - setValue(j); - } - - /** - * Constructs a long constant value. The initial value is 0. - */ - public LongMemberValue(ConstPool cp) { - super('J', cp); - setValue(0L); - } - - Object getValue(ClassLoader cl, ClassPool cp, Method m) { - return new Long(getValue()); - } - - Class getType(ClassLoader cl) { - return long.class; - } - - /** - * Obtains the value of the member. - */ - public long getValue() { - return cp.getLongInfo(valueIndex); - } - - /** - * Sets the value of the member. - */ - public void setValue(long newValue) { - valueIndex = cp.addLongInfo(newValue); - } - - /** - * Obtains the string representation of this object. - */ - public String toString() { - return Long.toString(getValue()); - } - - /** - * Writes the value. - */ - public void write(AnnotationsWriter writer) throws IOException { - writer.constValueIndex(getValue()); - } - - /** - * Accepts a visitor. - */ - public void accept(MemberValueVisitor visitor) { - visitor.visitLongMemberValue(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/MemberValue.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/MemberValue.java deleted file mode 100644 index 5ff48f133..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/MemberValue.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 2004 Bill Burke. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.annotation; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.bytecode.Descriptor; - -import java.io.IOException; -import java.lang.reflect.Method; - -/** - * The value of a member declared in an annotation. - * - * @see Annotation#getMemberValue(String) - * @author Bill Burke - * @author Shigeru Chiba - */ -public abstract class MemberValue { - ConstPool cp; - char tag; - - MemberValue(char tag, ConstPool cp) { - this.cp = cp; - this.tag = tag; - } - - /** - * Returns the value. If the value type is a primitive type, the - * returned value is boxed. - */ - abstract Object getValue(ClassLoader cl, ClassPool cp, Method m) - throws ClassNotFoundException; - - abstract Class getType(ClassLoader cl) throws ClassNotFoundException; - - static Class loadClass(ClassLoader cl, String classname) - throws ClassNotFoundException, NoSuchClassError - { - try { - return Class.forName(convertFromArray(classname), true, cl); - } - catch (LinkageError e) { - throw new NoSuchClassError(classname, e); - } - } - - private static String convertFromArray(String classname) - { - int index = classname.indexOf("[]"); - if (index != -1) { - String rawType = classname.substring(0, index); - StringBuffer sb = new StringBuffer(Descriptor.of(rawType)); - while (index != -1) { - sb.insert(0, "["); - index = classname.indexOf("[]", index + 1); - } - return sb.toString().replace('/', '.'); - } - return classname; - } - - /** - * Accepts a visitor. - */ - public abstract void accept(MemberValueVisitor visitor); - - /** - * Writes the value. - */ - public abstract void write(AnnotationsWriter w) throws IOException; -} - - diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/MemberValueVisitor.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/MemberValueVisitor.java deleted file mode 100644 index 4672c9e1c..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/MemberValueVisitor.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 2004 Bill Burke. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.annotation; - -/** - * Visitor for traversing member values included in an annotation. - * - * @see MemberValue#accept(MemberValueVisitor) - * @author Bill Burke - */ -public interface MemberValueVisitor { - public void visitAnnotationMemberValue(AnnotationMemberValue node); - public void visitArrayMemberValue(ArrayMemberValue node); - public void visitBooleanMemberValue(BooleanMemberValue node); - public void visitByteMemberValue(ByteMemberValue node); - public void visitCharMemberValue(CharMemberValue node); - public void visitDoubleMemberValue(DoubleMemberValue node); - public void visitEnumMemberValue(EnumMemberValue node); - public void visitFloatMemberValue(FloatMemberValue node); - public void visitIntegerMemberValue(IntegerMemberValue node); - public void visitLongMemberValue(LongMemberValue node); - public void visitShortMemberValue(ShortMemberValue node); - public void visitStringMemberValue(StringMemberValue node); - public void visitClassMemberValue(ClassMemberValue node); -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/NoSuchClassError.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/NoSuchClassError.java deleted file mode 100644 index 39b97ee5a..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/NoSuchClassError.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.annotation; - -/** - * Thrown if the linkage fails. - * It keeps the name of the class that caused this error. - */ -public class NoSuchClassError extends Error { - private String className; - - /** - * Constructs an exception. - */ - public NoSuchClassError(String className, Error cause) { - super(cause.toString(), cause); - this.className = className; - } - - /** - * Returns the name of the class not found. - */ - public String getClassName() { - return className; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/ShortMemberValue.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/ShortMemberValue.java deleted file mode 100644 index a26486bb7..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/ShortMemberValue.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 2004 Bill Burke. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.annotation; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.bytecode.ConstPool; - -import java.io.IOException; -import java.lang.reflect.Method; - -/** - * Short integer constant value. - * - * @author Bill Burke - * @author Shigeru Chiba - */ -public class ShortMemberValue extends MemberValue { - int valueIndex; - - /** - * Constructs a short constant value. The initial value is specified - * by the constant pool entry at the given index. - * - * @param index the index of a CONSTANT_Integer_info structure. - */ - public ShortMemberValue(int index, ConstPool cp) { - super('S', cp); - this.valueIndex = index; - } - - /** - * Constructs a short constant value. - * - * @param s the initial value. - */ - public ShortMemberValue(short s, ConstPool cp) { - super('S', cp); - setValue(s); - } - - /** - * Constructs a short constant value. The initial value is 0. - */ - public ShortMemberValue(ConstPool cp) { - super('S', cp); - setValue((short)0); - } - - Object getValue(ClassLoader cl, ClassPool cp, Method m) { - return new Short(getValue()); - } - - Class getType(ClassLoader cl) { - return short.class; - } - - /** - * Obtains the value of the member. - */ - public short getValue() { - return (short)cp.getIntegerInfo(valueIndex); - } - - /** - * Sets the value of the member. - */ - public void setValue(short newValue) { - valueIndex = cp.addIntegerInfo(newValue); - } - - /** - * Obtains the string representation of this object. - */ - public String toString() { - return Short.toString(getValue()); - } - - /** - * Writes the value. - */ - public void write(AnnotationsWriter writer) throws IOException { - writer.constValueIndex(getValue()); - } - - /** - * Accepts a visitor. - */ - public void accept(MemberValueVisitor visitor) { - visitor.visitShortMemberValue(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/StringMemberValue.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/StringMemberValue.java deleted file mode 100644 index 9bf7f1e6c..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/StringMemberValue.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 2004 Bill Burke. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.annotation; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.bytecode.ConstPool; - -import java.io.IOException; -import java.lang.reflect.Method; - -/** - * String constant value. - * - * @author Bill Burke - * @author Shigeru Chiba - */ -public class StringMemberValue extends MemberValue { - int valueIndex; - - /** - * Constructs a string constant value. The initial value is specified - * by the constant pool entry at the given index. - * - * @param index the index of a CONSTANT_Utf8_info structure. - */ - public StringMemberValue(int index, ConstPool cp) { - super('s', cp); - this.valueIndex = index; - } - - /** - * Constructs a string constant value. - * - * @param str the initial value. - */ - public StringMemberValue(String str, ConstPool cp) { - super('s', cp); - setValue(str); - } - - /** - * Constructs a string constant value. The initial value is "". - */ - public StringMemberValue(ConstPool cp) { - super('s', cp); - setValue(""); - } - - Object getValue(ClassLoader cl, ClassPool cp, Method m) { - return getValue(); - } - - Class getType(ClassLoader cl) { - return String.class; - } - - /** - * Obtains the value of the member. - */ - public String getValue() { - return cp.getUtf8Info(valueIndex); - } - - /** - * Sets the value of the member. - */ - public void setValue(String newValue) { - valueIndex = cp.addUtf8Info(newValue); - } - - /** - * Obtains the string representation of this object. - */ - public String toString() { - return "\"" + getValue() + "\""; - } - - /** - * Writes the value. - */ - public void write(AnnotationsWriter writer) throws IOException { - writer.constValueIndex(getValue()); - } - - /** - * Accepts a visitor. - */ - public void accept(MemberValueVisitor visitor) { - visitor.visitStringMemberValue(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/package.html b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/package.html deleted file mode 100644 index d0656db6c..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/annotation/package.html +++ /dev/null @@ -1,8 +0,0 @@ - - -Bytecode-level Annotations API. - -

This package provides low-level API for editing annotations attributes. - - - diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/package.html b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/package.html deleted file mode 100644 index 9da3888a2..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/package.html +++ /dev/null @@ -1,18 +0,0 @@ - - -Bytecode-level API. - -

This package provides low-level API for editing a raw class file. -It allows the users to read and modify a constant pool entry, a single -bytecode instruction, and so on. - -

The users of this package must know the specifications of -class file and Java bytecode. For more details, read this book: - -

    Tim Lindholm and Frank Yellin, -"The Java Virtual Machine Specification 2nd Ed.", -Addison-Wesley, 1999. -
- - - diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/BasicBlock.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/BasicBlock.java deleted file mode 100644 index 4e65e852b..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/BasicBlock.java +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.stackmap; - -import com.fr.third.javassist.bytecode.BadBytecode; - -import java.util.HashMap; -import java.util.ArrayList; - -/** - * A basic block is a sequence of bytecode that does not contain jump/branch - * instructions except at the last bytecode. - * Since Java7 or later does not allow JSR, this class throws an exception when - * it finds JSR. - */ -public class BasicBlock { - static class JsrBytecode extends com.fr.third.javassist.bytecode.BadBytecode { - JsrBytecode() { super("JSR"); } - } - - protected int position, length; - protected int incoming; // the number of incoming branches. - protected BasicBlock[] exit; // null if the block is a leaf. - protected boolean stop; // true if the block ends with an unconditional jump. - protected Catch toCatch; - - protected BasicBlock(int pos) { - position = pos; - length = 0; - incoming = 0; - } - - public static BasicBlock find(BasicBlock[] blocks, int pos) - throws com.fr.third.javassist.bytecode.BadBytecode - { - for (int i = 0; i < blocks.length; i++) { - int iPos = blocks[i].position; - if (iPos <= pos && pos < iPos + blocks[i].length) - return blocks[i]; - } - - throw new com.fr.third.javassist.bytecode.BadBytecode("no basic block at " + pos); - } - - public static class Catch { - public Catch next; - public BasicBlock body; - public int typeIndex; - Catch(BasicBlock b, int i, Catch c) { - body = b; - typeIndex = i; - next = c; - } - } - - public String toString() { - StringBuffer sbuf = new StringBuffer(); - String cname = this.getClass().getName(); - int i = cname.lastIndexOf('.'); - sbuf.append(i < 0 ? cname : cname.substring(i + 1)); - sbuf.append("["); - toString2(sbuf); - sbuf.append("]"); - return sbuf.toString(); - } - - protected void toString2(StringBuffer sbuf) { - sbuf.append("pos=").append(position).append(", len=") - .append(length).append(", in=").append(incoming) - .append(", exit{"); - if (exit != null) { - for (int i = 0; i < exit.length; i++) - sbuf.append(exit[i].position).append(","); - } - - sbuf.append("}, {"); - Catch th = toCatch; - while (th != null) { - sbuf.append("(").append(th.body.position).append(", ") - .append(th.typeIndex).append("), "); - th = th.next; - } - - sbuf.append("}"); - } - - /** - * A Mark indicates the position of a branch instruction - * or a branch target. - */ - static class Mark implements Comparable { - int position; - BasicBlock block; - BasicBlock[] jump; - boolean alwaysJmp; // true if an unconditional branch. - int size; // 0 unless the mark indicates RETURN etc. - Catch catcher; - - Mark(int p) { - position = p; - block = null; - jump = null; - alwaysJmp = false; - size = 0; - catcher = null; - } - - public int compareTo(Object obj) { - if (obj instanceof Mark) { - int pos = ((Mark)obj).position; - return position - pos; - } - - return -1; - } - - void setJump(BasicBlock[] bb, int s, boolean always) { - jump = bb; - size = s; - alwaysJmp = always; - } - } - - public static class Maker { - /* Override these two methods if a subclass of BasicBlock must be - * instantiated. - */ - protected BasicBlock makeBlock(int pos) { - return new BasicBlock(pos); - } - - protected BasicBlock[] makeArray(int size) { - return new BasicBlock[size]; - } - - private BasicBlock[] makeArray(BasicBlock b) { - BasicBlock[] array = makeArray(1); - array[0] = b; - return array; - } - - private BasicBlock[] makeArray(BasicBlock b1, BasicBlock b2) { - BasicBlock[] array = makeArray(2); - array[0] = b1; - array[1] = b2; - return array; - } - - public BasicBlock[] make(com.fr.third.javassist.bytecode.MethodInfo minfo) throws com.fr.third.javassist.bytecode.BadBytecode { - com.fr.third.javassist.bytecode.CodeAttribute ca = minfo.getCodeAttribute(); - if (ca == null) - return null; - - com.fr.third.javassist.bytecode.CodeIterator ci = ca.iterator(); - return make(ci, 0, ci.getCodeLength(), ca.getExceptionTable()); - } - - public BasicBlock[] make(com.fr.third.javassist.bytecode.CodeIterator ci, int begin, int end, - com.fr.third.javassist.bytecode.ExceptionTable et) - throws com.fr.third.javassist.bytecode.BadBytecode - { - HashMap marks = makeMarks(ci, begin, end, et); - BasicBlock[] bb = makeBlocks(marks); - addCatchers(bb, et); - return bb; - } - - /* Branch target - */ - private Mark makeMark(HashMap table, int pos) { - return makeMark0(table, pos, true, true); - } - - /* Branch instruction. - * size > 0 - */ - private Mark makeMark(HashMap table, int pos, BasicBlock[] jump, - int size, boolean always) { - Mark m = makeMark0(table, pos, false, false); - m.setJump(jump, size, always); - return m; - } - - private Mark makeMark0(HashMap table, int pos, - boolean isBlockBegin, boolean isTarget) { - Integer p = new Integer(pos); - Mark m = (Mark)table.get(p); - if (m == null) { - m = new Mark(pos); - table.put(p, m); - } - - if (isBlockBegin) { - if (m.block == null) - m.block = makeBlock(pos); - - if (isTarget) - m.block.incoming++; - } - - return m; - } - - private HashMap makeMarks(com.fr.third.javassist.bytecode.CodeIterator ci, int begin, int end, - com.fr.third.javassist.bytecode.ExceptionTable et) - throws com.fr.third.javassist.bytecode.BadBytecode - { - ci.begin(); - ci.move(begin); - HashMap marks = new HashMap(); - while (ci.hasNext()) { - int index = ci.next(); - if (index >= end) - break; - - int op = ci.byteAt(index); - if ((com.fr.third.javassist.bytecode.Opcode.IFEQ <= op && op <= com.fr.third.javassist.bytecode.Opcode.IF_ACMPNE) - || op == com.fr.third.javassist.bytecode.Opcode.IFNULL || op == com.fr.third.javassist.bytecode.Opcode.IFNONNULL) { - Mark to = makeMark(marks, index + ci.s16bitAt(index + 1)); - Mark next = makeMark(marks, index + 3); - makeMark(marks, index, makeArray(to.block, next.block), 3, false); - } - else if (com.fr.third.javassist.bytecode.Opcode.GOTO <= op && op <= com.fr.third.javassist.bytecode.Opcode.LOOKUPSWITCH) - switch (op) { - case com.fr.third.javassist.bytecode.Opcode.GOTO : - makeGoto(marks, index, index + ci.s16bitAt(index + 1), 3); - break; - case com.fr.third.javassist.bytecode.Opcode.JSR : - makeJsr(marks, index, index + ci.s16bitAt(index + 1), 3); - break; - case com.fr.third.javassist.bytecode.Opcode.RET : - makeMark(marks, index, null, 2, true); - break; - case com.fr.third.javassist.bytecode.Opcode.TABLESWITCH : { - int pos = (index & ~3) + 4; - int low = ci.s32bitAt(pos + 4); - int high = ci.s32bitAt(pos + 8); - int ncases = high - low + 1; - BasicBlock[] to = makeArray(ncases + 1); - to[0] = makeMark(marks, index + ci.s32bitAt(pos)).block; // default branch target - int p = pos + 12; - int n = p + ncases * 4; - int k = 1; - while (p < n) { - to[k++] = makeMark(marks, index + ci.s32bitAt(p)).block; - p += 4; - } - makeMark(marks, index, to, n - index, true); - break; } - case com.fr.third.javassist.bytecode.Opcode.LOOKUPSWITCH : { - int pos = (index & ~3) + 4; - int ncases = ci.s32bitAt(pos + 4); - BasicBlock[] to = makeArray(ncases + 1); - to[0] = makeMark(marks, index + ci.s32bitAt(pos)).block; // default branch target - int p = pos + 8 + 4; - int n = p + ncases * 8 - 4; - int k = 1; - while (p < n) { - to[k++] = makeMark(marks, index + ci.s32bitAt(p)).block; - p += 8; - } - makeMark(marks, index, to, n - index, true); - break; } - } - else if ((com.fr.third.javassist.bytecode.Opcode.IRETURN <= op && op <= com.fr.third.javassist.bytecode.Opcode.RETURN) || op == com.fr.third.javassist.bytecode.Opcode.ATHROW) - makeMark(marks, index, null, 1, true); - else if (op == com.fr.third.javassist.bytecode.Opcode.GOTO_W) - makeGoto(marks, index, index + ci.s32bitAt(index + 1), 5); - else if (op == com.fr.third.javassist.bytecode.Opcode.JSR_W) - makeJsr(marks, index, index + ci.s32bitAt(index + 1), 5); - else if (op == com.fr.third.javassist.bytecode.Opcode.WIDE && ci.byteAt(index + 1) == com.fr.third.javassist.bytecode.Opcode.RET) - makeMark(marks, index, null, 4, true); - } - - if (et != null) { - int i = et.size(); - while (--i >= 0) { - makeMark0(marks, et.startPc(i), true, false); - makeMark(marks, et.handlerPc(i)); - } - } - - return marks; - } - - private void makeGoto(HashMap marks, int pos, int target, int size) { - Mark to = makeMark(marks, target); - BasicBlock[] jumps = makeArray(to.block); - makeMark(marks, pos, jumps, size, true); - } - - /* - * We could ignore JSR since Java 7 or later does not allow it. - * See The JVM Spec. Sec. 4.10.2.5. - */ - protected void makeJsr(HashMap marks, int pos, int target, int size) throws com.fr.third.javassist.bytecode.BadBytecode { - /* - Mark to = makeMark(marks, target); - Mark next = makeMark(marks, pos + size); - BasicBlock[] jumps = makeArray(to.block, next.block); - makeMark(marks, pos, jumps, size, false); - */ - throw new JsrBytecode(); - } - - private BasicBlock[] makeBlocks(HashMap markTable) { - Mark[] marks = (Mark[])markTable.values() - .toArray(new Mark[markTable.size()]); - java.util.Arrays.sort(marks); - ArrayList blocks = new ArrayList(); - int i = 0; - BasicBlock prev; - if (marks.length > 0 && marks[0].position == 0 && marks[0].block != null) - prev = getBBlock(marks[i++]); - else - prev = makeBlock(0); - - blocks.add(prev); - while (i < marks.length) { - Mark m = marks[i++]; - BasicBlock bb = getBBlock(m); - if (bb == null) { - // the mark indicates a branch instruction - if (prev.length > 0) { - // the previous mark already has exits. - prev = makeBlock(prev.position + prev.length); - blocks.add(prev); - } - - prev.length = m.position + m.size - prev.position; - prev.exit = m.jump; - prev.stop = m.alwaysJmp; - } - else { - // the mark indicates a branch target - if (prev.length == 0) { - prev.length = m.position - prev.position; - bb.incoming++; - prev.exit = makeArray(bb); - } - else { - // the previous mark already has exits. - if (prev.position + prev.length < m.position) { - // dead code is found. - prev = makeBlock(prev.position + prev.length); - blocks.add(prev); - prev.length = m.position - prev.position; - // the incoming flow from dead code is not counted - // bb.incoming++; - prev.exit = makeArray(bb); - } - } - - blocks.add(bb); - prev = bb; - } - } - - return (BasicBlock[])blocks.toArray(makeArray(blocks.size())); - } - - private static BasicBlock getBBlock(Mark m) { - BasicBlock b = m.block; - if (b != null && m.size > 0) { - b.exit = m.jump; - b.length = m.size; - b.stop = m.alwaysJmp; - } - - return b; - } - - private void addCatchers(BasicBlock[] blocks, com.fr.third.javassist.bytecode.ExceptionTable et) - throws BadBytecode - { - if (et == null) - return; - - int i = et.size(); - while (--i >= 0) { - BasicBlock handler = find(blocks, et.handlerPc(i)); - int start = et.startPc(i); - int end = et.endPc(i); - int type = et.catchType(i); - handler.incoming--; - for (int k = 0; k < blocks.length; k++) { - BasicBlock bb = blocks[k]; - int iPos = bb.position; - if (start <= iPos && iPos < end) { - bb.toCatch = new Catch(handler, type, bb.toCatch); - handler.incoming++; - } - } - } - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/MapMaker.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/MapMaker.java deleted file mode 100644 index 3c6e80c67..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/MapMaker.java +++ /dev/null @@ -1,605 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.stackmap; - -import java.util.ArrayList; -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.bytecode.ConstPool; - -/** - * Stack map maker. - */ -public class MapMaker extends Tracer { - /* - public static void main(String[] args) throws Exception { - boolean useMain2 = args[0].equals("0"); - if (useMain2 && args.length > 1) { - main2(args); - return; - } - - for (int i = 0; i < args.length; i++) - main1(args[i]); - } - - public static void main1(String className) throws Exception { - ClassPool cp = ClassPool.getDefault(); - //javassist.CtClass cc = cp.get(className); - javassist.CtClass cc = cp.makeClass(new java.io.FileInputStream(className)); - System.out.println(className); - ClassFile cf = cc.getClassFile(); - java.util.List minfos = cf.getMethods(); - for (int i = 0; i < minfos.size(); i++) { - MethodInfo minfo = (MethodInfo)minfos.get(i); - CodeAttribute ca = minfo.getCodeAttribute(); - if (ca != null) - ca.setAttribute(make(cp, minfo)); - } - - cc.writeFile("tmp"); - } - - public static void main2(String[] args) throws Exception { - ClassPool cp = ClassPool.getDefault(); - //javassist.CtClass cc = cp.get(args[1]); - javassist.CtClass cc = cp.makeClass(new java.io.FileInputStream(args[1])); - MethodInfo minfo; - if (args[2].equals("_init_")) - minfo = cc.getDeclaredConstructors()[0].getMethodInfo(); - // minfo = cc.getClassInitializer().getMethodInfo(); - else - minfo = cc.getDeclaredMethod(args[2]).getMethodInfo(); - - CodeAttribute ca = minfo.getCodeAttribute(); - if (ca == null) { - System.out.println("abstarct method"); - return; - } - - TypedBlock[] blocks = TypedBlock.makeBlocks(minfo, ca, false); - MapMaker mm = new MapMaker(cp, minfo, ca); - mm.make(blocks, ca.getCode()); - for (int i = 0; i < blocks.length; i++) - System.out.println(blocks[i]); - } - */ - - /** - * Computes the stack map table of the given method and returns it. - * It returns null if the given method does not have to have a - * stack map table or it includes JSR. - */ - public static com.fr.third.javassist.bytecode.StackMapTable make(ClassPool classes, com.fr.third.javassist.bytecode.MethodInfo minfo) - throws com.fr.third.javassist.bytecode.BadBytecode - { - com.fr.third.javassist.bytecode.CodeAttribute ca = minfo.getCodeAttribute(); - if (ca == null) - return null; - - TypedBlock[] blocks; - try { - blocks = TypedBlock.makeBlocks(minfo, ca, true); - } - catch (BasicBlock.JsrBytecode e) { - return null; - } - - if (blocks == null) - return null; - - MapMaker mm = new MapMaker(classes, minfo, ca); - try { - mm.make(blocks, ca.getCode()); - } - catch (com.fr.third.javassist.bytecode.BadBytecode bb) { - throw new com.fr.third.javassist.bytecode.BadBytecode(minfo, bb); - } - - return mm.toStackMap(blocks); - } - - /** - * Computes the stack map table for J2ME. - * It returns null if the given method does not have to have a - * stack map table or it includes JSR. - */ - public static com.fr.third.javassist.bytecode.StackMap make2(ClassPool classes, com.fr.third.javassist.bytecode.MethodInfo minfo) - throws com.fr.third.javassist.bytecode.BadBytecode - { - com.fr.third.javassist.bytecode.CodeAttribute ca = minfo.getCodeAttribute(); - if (ca == null) - return null; - - TypedBlock[] blocks; - try { - blocks = TypedBlock.makeBlocks(minfo, ca, true); - } - catch (BasicBlock.JsrBytecode e) { - return null; - } - - if (blocks == null) - return null; - - MapMaker mm = new MapMaker(classes, minfo, ca); - try { - mm.make(blocks, ca.getCode()); - } - catch (com.fr.third.javassist.bytecode.BadBytecode bb) { - throw new com.fr.third.javassist.bytecode.BadBytecode(minfo, bb); - } - return mm.toStackMap2(minfo.getConstPool(), blocks); - } - - public MapMaker(ClassPool classes, com.fr.third.javassist.bytecode.MethodInfo minfo, com.fr.third.javassist.bytecode.CodeAttribute ca) { - super(classes, minfo.getConstPool(), - ca.getMaxStack(), ca.getMaxLocals(), - TypedBlock.getRetType(minfo.getDescriptor())); - } - - protected MapMaker(MapMaker old) { super(old); } - - /** - * Runs an analyzer (Phase 1 and 2). - */ - void make(TypedBlock[] blocks, byte[] code) - throws com.fr.third.javassist.bytecode.BadBytecode - { - make(code, blocks[0]); - findDeadCatchers(code, blocks); - try { - fixTypes(code, blocks); - } catch (NotFoundException e) { - throw new com.fr.third.javassist.bytecode.BadBytecode("failed to resolve types", e); - } - } - - // Phase 1 - - private void make(byte[] code, TypedBlock tb) - throws com.fr.third.javassist.bytecode.BadBytecode - { - copyTypeData(tb.stackTop, tb.stackTypes, stackTypes); - stackTop = tb.stackTop; - copyTypeData(tb.localsTypes.length, tb.localsTypes, localsTypes); - - traceException(code, tb.toCatch); - - int pos = tb.position; - int end = pos + tb.length; - while (pos < end) { - pos += doOpcode(pos, code); - traceException(code, tb.toCatch); - } - - if (tb.exit != null) { - for (int i = 0; i < tb.exit.length; i++) { - TypedBlock e = (TypedBlock)tb.exit[i]; - if (e.alreadySet()) - mergeMap(e, true); - else { - recordStackMap(e); - MapMaker maker = new MapMaker(this); - maker.make(code, e); - } - } - } - } - - private void traceException(byte[] code, TypedBlock.Catch handler) - throws com.fr.third.javassist.bytecode.BadBytecode - { - while (handler != null) { - TypedBlock tb = (TypedBlock)handler.body; - if (tb.alreadySet()) { - mergeMap(tb, false); - if (tb.stackTop < 1) - throw new com.fr.third.javassist.bytecode.BadBytecode("bad catch clause: " + handler.typeIndex); - - tb.stackTypes[0] = merge(toExceptionType(handler.typeIndex), - tb.stackTypes[0]); - } - else { - recordStackMap(tb, handler.typeIndex); - MapMaker maker = new MapMaker(this); - maker.make(code, tb); - } - - handler = handler.next; - } - } - - private void mergeMap(TypedBlock dest, boolean mergeStack) throws com.fr.third.javassist.bytecode.BadBytecode { - int n = localsTypes.length; - for (int i = 0; i < n; i++) - dest.localsTypes[i] = merge(validateTypeData(localsTypes, n, i), - dest.localsTypes[i]); - - if (mergeStack) { - n = stackTop; - for (int i = 0; i < n; i++) - dest.stackTypes[i] = merge(stackTypes[i], dest.stackTypes[i]); - } - } - - private TypeData merge(TypeData src, TypeData target) throws com.fr.third.javassist.bytecode.BadBytecode { - if (src == target) - return target; - else if (target instanceof TypeData.ClassName - || target instanceof TypeData.BasicType) // a parameter - return target; - else if (target instanceof TypeData.AbsTypeVar) { - ((TypeData.AbsTypeVar)target).merge(src); - return target; - } - else - throw new RuntimeException("fatal: this should never happen"); - } - - private void recordStackMap(TypedBlock target) - throws com.fr.third.javassist.bytecode.BadBytecode - { - TypeData[] tStackTypes = TypeData.make(stackTypes.length); - int st = stackTop; - recordTypeData(st, stackTypes, tStackTypes); - recordStackMap0(target, st, tStackTypes); - } - - private void recordStackMap(TypedBlock target, int exceptionType) - throws com.fr.third.javassist.bytecode.BadBytecode - { - TypeData[] tStackTypes = TypeData.make(stackTypes.length); - tStackTypes[0] = toExceptionType(exceptionType).join(); - recordStackMap0(target, 1, tStackTypes); - } - - private TypeData.ClassName toExceptionType(int exceptionType) { - String type; - if (exceptionType == 0) // for finally clauses - type= "java.lang.Throwable"; - else - type = cpool.getClassInfo(exceptionType); - - return new TypeData.ClassName(type); - } - - private void recordStackMap0(TypedBlock target, int st, TypeData[] tStackTypes) - throws com.fr.third.javassist.bytecode.BadBytecode - { - int n = localsTypes.length; - TypeData[] tLocalsTypes = TypeData.make(n); - int k = recordTypeData(n, localsTypes, tLocalsTypes); - target.setStackMap(st, tStackTypes, k, tLocalsTypes); - } - - protected static int recordTypeData(int n, TypeData[] srcTypes, TypeData[] destTypes) { - int k = -1; - for (int i = 0; i < n; i++) { - TypeData t = validateTypeData(srcTypes, n, i); - destTypes[i] = t.join(); - if (t != TOP) - k = i + 1; // t might be long or double. - } - - return k + 1; - } - - protected static void copyTypeData(int n, TypeData[] srcTypes, TypeData[] destTypes) { - for (int i = 0; i < n; i++) - destTypes[i] = srcTypes[i]; - } - - private static TypeData validateTypeData(TypeData[] data, int length, int index) { - TypeData td = data[index]; - if (td.is2WordType() && index + 1 < length) - if (data[index + 1] != TOP) - return TOP; - - return td; - } - - // Phase 1.5 - - /* - * Javac may generate an exception handler that catches only the exception - * thrown within the handler itself. It is dead code. - * See com.fr.third.javassist.JvstTest4.testJIRA195(). - */ - - private void findDeadCatchers(byte[] code, TypedBlock[] blocks) throws com.fr.third.javassist.bytecode.BadBytecode { - int len = blocks.length; - for (int i = 0; i < len; i++) { - TypedBlock block = blocks[i]; - if (!block.alreadySet()) { - fixDeadcode(code, block); - BasicBlock.Catch handler = block.toCatch; - if (handler != null) { - TypedBlock tb = (TypedBlock)handler.body; - if (!tb.alreadySet()) { - // tb is a handler that catches only the exceptions - // thrown from dead code. - recordStackMap(tb, handler.typeIndex); - fixDeadcode(code, tb); - tb.incoming = 1; - } - } - - } - } - } - - private void fixDeadcode(byte[] code, TypedBlock block) throws com.fr.third.javassist.bytecode.BadBytecode { - int pos = block.position; - int len = block.length - 3; - if (len < 0) { - // if the dead-code length is shorter than 3 bytes. - if (len == -1) - code[pos] = com.fr.third.javassist.bytecode.Bytecode.NOP; - - code[pos + block.length - 1] = (byte) com.fr.third.javassist.bytecode.Bytecode.ATHROW; - block.incoming = 1; - recordStackMap(block, 0); - return; - } - - // if block.incomping > 0, all the incoming edges are from - // other dead code blocks. So set block.incoming to 0. - block.incoming = 0; - - for (int k = 0; k < len; k++) - code[pos + k] = com.fr.third.javassist.bytecode.Bytecode.NOP; - - code[pos + len] = (byte) com.fr.third.javassist.bytecode.Bytecode.GOTO; - com.fr.third.javassist.bytecode.ByteArray.write16bit(-len, code, pos + len + 1); - } - - // Phase 2 - - /* - * This method first finds strongly connected components (SCCs) - * in a TypeData graph by Tarjan's algorithm. - * SCCs are TypeData nodes sharing the same type. - * Since SCCs are found in the topologically sorted order, - * their types are also fixed when they are found. - */ - private void fixTypes(byte[] code, TypedBlock[] blocks) throws NotFoundException, com.fr.third.javassist.bytecode.BadBytecode { - ArrayList preOrder = new ArrayList(); - int len = blocks.length; - int index = 0; - for (int i = 0; i < len; i++) { - TypedBlock block = blocks[i]; - if (block.alreadySet()) { // if block is not dead code - int n = block.localsTypes.length; - for (int j = 0; j < n; j++) - index = block.localsTypes[j].dfs(preOrder, index, classPool); - - n = block.stackTop; - for (int j = 0; j < n; j++) - index = block.stackTypes[j].dfs(preOrder, index, classPool); - } - } - } - - // Phase 3 - - public com.fr.third.javassist.bytecode.StackMapTable toStackMap(TypedBlock[] blocks) { - com.fr.third.javassist.bytecode.StackMapTable.Writer writer = new com.fr.third.javassist.bytecode.StackMapTable.Writer(32); - int n = blocks.length; - TypedBlock prev = blocks[0]; - int offsetDelta = prev.length; - if (prev.incoming > 0) { // the first instruction is a branch target. - writer.sameFrame(0); - offsetDelta--; - } - - for (int i = 1; i < n; i++) { - TypedBlock bb = blocks[i]; - if (isTarget(bb, blocks[i - 1])) { - bb.resetNumLocals(); - int diffL = stackMapDiff(prev.numLocals, prev.localsTypes, - bb.numLocals, bb.localsTypes); - toStackMapBody(writer, bb, diffL, offsetDelta, prev); - offsetDelta = bb.length - 1; - prev = bb; - } - else if (bb.incoming == 0) { - // dead code. - writer.sameFrame(offsetDelta); - offsetDelta = bb.length - 1; - prev = bb; - } - else - offsetDelta += bb.length; - } - - return writer.toStackMapTable(cpool); - } - - /** - * Returns true if cur is a branch target. - */ - private boolean isTarget(TypedBlock cur, TypedBlock prev) { - int in = cur.incoming; - if (in > 1) - return true; - else if (in < 1) - return false; - - return prev.stop; - } - - private void toStackMapBody(com.fr.third.javassist.bytecode.StackMapTable.Writer writer, TypedBlock bb, - int diffL, int offsetDelta, TypedBlock prev) { - // if diffL is -100, two TypeData arrays do not share - // any elements. - - int stackTop = bb.stackTop; - if (stackTop == 0) { - if (diffL == 0) { - writer.sameFrame(offsetDelta); - return; - } - else if (0 > diffL && diffL >= -3) { - writer.chopFrame(offsetDelta, -diffL); - return; - } - else if (0 < diffL && diffL <= 3) { - int[] data = new int[diffL]; - int[] tags = fillStackMap(bb.numLocals - prev.numLocals, - prev.numLocals, data, - bb.localsTypes); - writer.appendFrame(offsetDelta, tags, data); - return; - } - } - else if (stackTop == 1 && diffL == 0) { - TypeData td = bb.stackTypes[0]; - writer.sameLocals(offsetDelta, td.getTypeTag(), td.getTypeData(cpool)); - return; - } - else if (stackTop == 2 && diffL == 0) { - TypeData td = bb.stackTypes[0]; - if (td.is2WordType()) { - // bb.stackTypes[1] must be TOP. - writer.sameLocals(offsetDelta, td.getTypeTag(), td.getTypeData(cpool)); - return; - } - } - - int[] sdata = new int[stackTop]; - int[] stags = fillStackMap(stackTop, 0, sdata, bb.stackTypes); - int[] ldata = new int[bb.numLocals]; - int[] ltags = fillStackMap(bb.numLocals, 0, ldata, bb.localsTypes); - writer.fullFrame(offsetDelta, ltags, ldata, stags, sdata); - } - - private int[] fillStackMap(int num, int offset, int[] data, TypeData[] types) { - int realNum = diffSize(types, offset, offset + num); - com.fr.third.javassist.bytecode.ConstPool cp = cpool; - int[] tags = new int[realNum]; - int j = 0; - for (int i = 0; i < num; i++) { - TypeData td = types[offset + i]; - tags[j] = td.getTypeTag(); - data[j] = td.getTypeData(cp); - if (td.is2WordType()) - i++; - - j++; - } - - return tags; - } - - private static int stackMapDiff(int oldTdLen, TypeData[] oldTd, - int newTdLen, TypeData[] newTd) - { - int diff = newTdLen - oldTdLen; - int len; - if (diff > 0) - len = oldTdLen; - else - len = newTdLen; - - if (stackMapEq(oldTd, newTd, len)) - if (diff > 0) - return diffSize(newTd, len, newTdLen); - else - return -diffSize(oldTd, len, oldTdLen); - else - return -100; - } - - private static boolean stackMapEq(TypeData[] oldTd, TypeData[] newTd, int len) { - for (int i = 0; i < len; i++) { - if (!oldTd[i].eq(newTd[i])) - return false; - } - - return true; - } - - private static int diffSize(TypeData[] types, int offset, int len) { - int num = 0; - while (offset < len) { - TypeData td = types[offset++]; - num++; - if (td.is2WordType()) - offset++; - } - - return num; - } - - // Phase 3 for J2ME - - public com.fr.third.javassist.bytecode.StackMap toStackMap2(com.fr.third.javassist.bytecode.ConstPool cp, TypedBlock[] blocks) { - com.fr.third.javassist.bytecode.StackMap.Writer writer = new com.fr.third.javassist.bytecode.StackMap.Writer(); - int n = blocks.length; // should be > 0 - boolean[] effective = new boolean[n]; - TypedBlock prev = blocks[0]; - - // Is the first instruction a branch target? - effective[0] = prev.incoming > 0; - - int num = effective[0] ? 1 : 0; - for (int i = 1; i < n; i++) { - TypedBlock bb = blocks[i]; - if (effective[i] = isTarget(bb, blocks[i - 1])) { - bb.resetNumLocals(); - prev = bb; - num++; - } - } - - if (num == 0) - return null; - - writer.write16bit(num); - for (int i = 0; i < n; i++) - if (effective[i]) - writeStackFrame(writer, cp, blocks[i].position, blocks[i]); - - return writer.toStackMap(cp); - } - - private void writeStackFrame(com.fr.third.javassist.bytecode.StackMap.Writer writer, com.fr.third.javassist.bytecode.ConstPool cp, int offset, TypedBlock tb) { - writer.write16bit(offset); - writeVerifyTypeInfo(writer, cp, tb.localsTypes, tb.numLocals); - writeVerifyTypeInfo(writer, cp, tb.stackTypes, tb.stackTop); - } - - private void writeVerifyTypeInfo(com.fr.third.javassist.bytecode.StackMap.Writer writer, ConstPool cp, TypeData[] types, int num) { - int numDWord = 0; - for (int i = 0; i < num; i++) { - TypeData td = types[i]; - if (td != null && td.is2WordType()) { - numDWord++; - i++; - } - } - - writer.write16bit(num - numDWord); - for (int i = 0; i < num; i++) { - TypeData td = types[i]; - writer.writeVerifyTypeInfo(td.getTypeTag(), td.getTypeData(cp)); - if (td.is2WordType()) - i++; - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/Tracer.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/Tracer.java deleted file mode 100644 index 01c912234..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/Tracer.java +++ /dev/null @@ -1,933 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.stackmap; - -import com.fr.third.javassist.bytecode.ByteArray; -import com.fr.third.javassist.bytecode.Opcode; -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.bytecode.Descriptor; -import com.fr.third.javassist.bytecode.BadBytecode; -import com.fr.third.javassist.ClassPool; - -/* - * A class for performing abstract interpretation. - * See also MapMaker class. - */ - -public abstract class Tracer implements TypeTag { - protected ClassPool classPool; - protected ConstPool cpool; - protected String returnType; // used as the type of ARETURN - - protected int stackTop; - protected TypeData[] stackTypes; - protected TypeData[] localsTypes; - - public Tracer(ClassPool classes, ConstPool cp, int maxStack, int maxLocals, - String retType) { - classPool = classes; - cpool = cp; - returnType = retType; - stackTop = 0; - stackTypes = TypeData.make(maxStack); - localsTypes = TypeData.make(maxLocals); - } - - public Tracer(Tracer t) { - classPool = t.classPool; - cpool = t.cpool; - returnType = t.returnType; - stackTop = t.stackTop; - stackTypes = TypeData.make(t.stackTypes.length); - localsTypes = TypeData.make(t.localsTypes.length); - } - - /** - * Does abstract interpretation on the given bytecode instruction. - * It records whether or not a local variable (i.e. register) is accessed. - * If the instruction requires that a local variable or - * a stack element has a more specific type, this method updates the - * type of it. - * - * @param pos the position of the instruction. - * @return the size of the instruction at POS. - */ - protected int doOpcode(int pos, byte[] code) throws BadBytecode { - try { - int op = code[pos] & 0xff; - if (op < 96) - if (op < 54) - return doOpcode0_53(pos, code, op); - else - return doOpcode54_95(pos, code, op); - else - if (op < 148) - return doOpcode96_147(pos, code, op); - else - return doOpcode148_201(pos, code, op); - } - catch (ArrayIndexOutOfBoundsException e) { - throw new BadBytecode("inconsistent stack height " + e.getMessage(), e); - } - } - - protected void visitBranch(int pos, byte[] code, int offset) throws BadBytecode {} - protected void visitGoto(int pos, byte[] code, int offset) throws BadBytecode {} - protected void visitReturn(int pos, byte[] code) throws BadBytecode {} - protected void visitThrow(int pos, byte[] code) throws BadBytecode {} - - /** - * @param pos the position of TABLESWITCH - * @param code bytecode - * @param n the number of case labels - * @param offsetPos the position of the branch-target table. - * @param defaultOffset the offset to the default branch target. - */ - protected void visitTableSwitch(int pos, byte[] code, int n, - int offsetPos, int defaultOffset) throws BadBytecode {} - - /** - * @param pos the position of LOOKUPSWITCH - * @param code bytecode - * @param n the number of case labels - * @param offsetPos the position of the table of pairs of a value and a branch target. - * @param defaultOffset the offset to the default branch target. - */ - protected void visitLookupSwitch(int pos, byte[] code, int n, - int pairsPos, int defaultOffset) throws BadBytecode {} - - /** - * Invoked when the visited instruction is jsr. - * Java6 or later does not allow using RET. - */ - protected void visitJSR(int pos, byte[] code) throws BadBytecode { - /* Since JSR pushes a return address onto the operand stack, - * the stack map at the entry point of a subroutine is - * stackTypes resulting after executing the following code: - * - * stackTypes[stackTop++] = TOP; - */ - } - - /** - * Invoked when the visited instruction is ret or wide ret. - * Java6 or later does not allow using RET. - */ - protected void visitRET(int pos, byte[] code) throws BadBytecode {} - - private int doOpcode0_53(int pos, byte[] code, int op) throws BadBytecode { - int reg; - TypeData[] stackTypes = this.stackTypes; - switch (op) { - case Opcode.NOP : - break; - case Opcode.ACONST_NULL : - stackTypes[stackTop++] = new TypeData.NullType(); - break; - case Opcode.ICONST_M1 : - case Opcode.ICONST_0 : - case Opcode.ICONST_1 : - case Opcode.ICONST_2 : - case Opcode.ICONST_3 : - case Opcode.ICONST_4 : - case Opcode.ICONST_5 : - stackTypes[stackTop++] = INTEGER; - break; - case Opcode.LCONST_0 : - case Opcode.LCONST_1 : - stackTypes[stackTop++] = LONG; - stackTypes[stackTop++] = TOP; - break; - case Opcode.FCONST_0 : - case Opcode.FCONST_1 : - case Opcode.FCONST_2 : - stackTypes[stackTop++] = FLOAT; - break; - case Opcode.DCONST_0 : - case Opcode.DCONST_1 : - stackTypes[stackTop++] = DOUBLE; - stackTypes[stackTop++] = TOP; - break; - case Opcode.BIPUSH : - case Opcode.SIPUSH : - stackTypes[stackTop++] = INTEGER; - return op == Opcode.SIPUSH ? 3 : 2; - case Opcode.LDC : - doLDC(code[pos + 1] & 0xff); - return 2; - case Opcode.LDC_W : - case Opcode.LDC2_W : - doLDC(ByteArray.readU16bit(code, pos + 1)); - return 3; - case Opcode.ILOAD : - return doXLOAD(INTEGER, code, pos); - case Opcode.LLOAD : - return doXLOAD(LONG, code, pos); - case Opcode.FLOAD : - return doXLOAD(FLOAT, code, pos); - case Opcode.DLOAD : - return doXLOAD(DOUBLE, code, pos); - case Opcode.ALOAD : - return doALOAD(code[pos + 1] & 0xff); - case Opcode.ILOAD_0 : - case Opcode.ILOAD_1 : - case Opcode.ILOAD_2 : - case Opcode.ILOAD_3 : - stackTypes[stackTop++] = INTEGER; - break; - case Opcode.LLOAD_0 : - case Opcode.LLOAD_1 : - case Opcode.LLOAD_2 : - case Opcode.LLOAD_3 : - stackTypes[stackTop++] = LONG; - stackTypes[stackTop++] = TOP; - break; - case Opcode.FLOAD_0 : - case Opcode.FLOAD_1 : - case Opcode.FLOAD_2 : - case Opcode.FLOAD_3 : - stackTypes[stackTop++] = FLOAT; - break; - case Opcode.DLOAD_0 : - case Opcode.DLOAD_1 : - case Opcode.DLOAD_2 : - case Opcode.DLOAD_3 : - stackTypes[stackTop++] = DOUBLE; - stackTypes[stackTop++] = TOP; - break; - case Opcode.ALOAD_0 : - case Opcode.ALOAD_1 : - case Opcode.ALOAD_2 : - case Opcode.ALOAD_3 : - reg = op - Opcode.ALOAD_0; - stackTypes[stackTop++] = localsTypes[reg]; - break; - case Opcode.IALOAD : - stackTypes[--stackTop - 1] = INTEGER; - break; - case Opcode.LALOAD : - stackTypes[stackTop - 2] = LONG; - stackTypes[stackTop - 1] = TOP; - break; - case Opcode.FALOAD : - stackTypes[--stackTop - 1] = FLOAT; - break; - case Opcode.DALOAD : - stackTypes[stackTop - 2] = DOUBLE; - stackTypes[stackTop - 1] = TOP; - break; - case Opcode.AALOAD : { - int s = --stackTop - 1; - TypeData data = stackTypes[s]; - stackTypes[s] = TypeData.ArrayElement.make(data); - break; } - case Opcode.BALOAD : - case Opcode.CALOAD : - case Opcode.SALOAD : - stackTypes[--stackTop - 1] = INTEGER; - break; - default : - throw new RuntimeException("fatal"); - } - - return 1; - } - - private void doLDC(int index) { - TypeData[] stackTypes = this.stackTypes; - int tag = cpool.getTag(index); - if (tag == ConstPool.CONST_String) - stackTypes[stackTop++] = new TypeData.ClassName("java.lang.String"); - else if (tag == ConstPool.CONST_Integer) - stackTypes[stackTop++] = INTEGER; - else if (tag == ConstPool.CONST_Float) - stackTypes[stackTop++] = FLOAT; - else if (tag == ConstPool.CONST_Long) { - stackTypes[stackTop++] = LONG; - stackTypes[stackTop++] = TOP; - } - else if (tag == ConstPool.CONST_Double) { - stackTypes[stackTop++] = DOUBLE; - stackTypes[stackTop++] = TOP; - } - else if (tag == ConstPool.CONST_Class) - stackTypes[stackTop++] = new TypeData.ClassName("java.lang.Class"); - else - throw new RuntimeException("bad LDC: " + tag); - } - - private int doXLOAD(TypeData type, byte[] code, int pos) { - int localVar = code[pos + 1] & 0xff; - return doXLOAD(localVar, type); - } - - private int doXLOAD(int localVar, TypeData type) { - stackTypes[stackTop++] = type; - if (type.is2WordType()) - stackTypes[stackTop++] = TOP; - - return 2; - } - - private int doALOAD(int localVar) { - stackTypes[stackTop++] = localsTypes[localVar]; - return 2; - } - - private int doOpcode54_95(int pos, byte[] code, int op) throws BadBytecode { - switch (op) { - case Opcode.ISTORE : - return doXSTORE(pos, code, INTEGER); - case Opcode.LSTORE : - return doXSTORE(pos, code, LONG); - case Opcode.FSTORE : - return doXSTORE(pos, code, FLOAT); - case Opcode.DSTORE : - return doXSTORE(pos, code, DOUBLE); - case Opcode.ASTORE : - return doASTORE(code[pos + 1] & 0xff); - case Opcode.ISTORE_0 : - case Opcode.ISTORE_1 : - case Opcode.ISTORE_2 : - case Opcode.ISTORE_3 : - { int var = op - Opcode.ISTORE_0; - localsTypes[var] = INTEGER; - stackTop--; } - break; - case Opcode.LSTORE_0 : - case Opcode.LSTORE_1 : - case Opcode.LSTORE_2 : - case Opcode.LSTORE_3 : - { int var = op - Opcode.LSTORE_0; - localsTypes[var] = LONG; - localsTypes[var + 1] = TOP; - stackTop -= 2; } - break; - case Opcode.FSTORE_0 : - case Opcode.FSTORE_1 : - case Opcode.FSTORE_2 : - case Opcode.FSTORE_3 : - { int var = op - Opcode.FSTORE_0; - localsTypes[var] = FLOAT; - stackTop--; } - break; - case Opcode.DSTORE_0 : - case Opcode.DSTORE_1 : - case Opcode.DSTORE_2 : - case Opcode.DSTORE_3 : - { int var = op - Opcode.DSTORE_0; - localsTypes[var] = DOUBLE; - localsTypes[var + 1] = TOP; - stackTop -= 2; } - break; - case Opcode.ASTORE_0 : - case Opcode.ASTORE_1 : - case Opcode.ASTORE_2 : - case Opcode.ASTORE_3 : - { int var = op - Opcode.ASTORE_0; - doASTORE(var); - break; } - case Opcode.IASTORE : - case Opcode.LASTORE : - case Opcode.FASTORE : - case Opcode.DASTORE : - stackTop -= (op == Opcode.LASTORE || op == Opcode.DASTORE) ? 4 : 3; - break; - case Opcode.AASTORE : - TypeData.ArrayElement.aastore(stackTypes[stackTop - 3], - stackTypes[stackTop - 1], - classPool); - stackTop -= 3; - break; - case Opcode.BASTORE : - case Opcode.CASTORE : - case Opcode.SASTORE : - stackTop -= 3; - break; - case Opcode.POP : - stackTop--; - break; - case Opcode.POP2 : - stackTop -= 2; - break; - case Opcode.DUP : { - int sp = stackTop; - stackTypes[sp] = stackTypes[sp - 1]; - stackTop = sp + 1; - break; } - case Opcode.DUP_X1 : - case Opcode.DUP_X2 : { - int len = op - Opcode.DUP_X1 + 2; - doDUP_XX(1, len); - int sp = stackTop; - stackTypes[sp - len] = stackTypes[sp]; - stackTop = sp + 1; - break; } - case Opcode.DUP2 : - doDUP_XX(2, 2); - stackTop += 2; - break; - case Opcode.DUP2_X1 : - case Opcode.DUP2_X2 : { - int len = op - Opcode.DUP2_X1 + 3; - doDUP_XX(2, len); - int sp = stackTop; - stackTypes[sp - len] = stackTypes[sp]; - stackTypes[sp - len + 1] = stackTypes[sp + 1]; - stackTop = sp + 2; - break; } - case Opcode.SWAP : { - int sp = stackTop - 1; - TypeData t = stackTypes[sp]; - stackTypes[sp] = stackTypes[sp - 1]; - stackTypes[sp - 1] = t; - break; } - default : - throw new RuntimeException("fatal"); - } - - return 1; - } - - private int doXSTORE(int pos, byte[] code, TypeData type) { - int index = code[pos + 1] & 0xff; - return doXSTORE(index, type); - } - - private int doXSTORE(int index, TypeData type) { - stackTop--; - localsTypes[index] = type; - if (type.is2WordType()) { - stackTop--; - localsTypes[index + 1] = TOP; - } - - return 2; - } - - private int doASTORE(int index) { - stackTop--; - // implicit upcast might be done. - localsTypes[index] = stackTypes[stackTop]; - return 2; - } - - private void doDUP_XX(int delta, int len) { - TypeData types[] = stackTypes; - int sp = stackTop - 1; - int end = sp - len; - while (sp > end) { - types[sp + delta] = types[sp]; - sp--; - } - } - - private int doOpcode96_147(int pos, byte[] code, int op) { - if (op <= Opcode.LXOR) { // IADD...LXOR - stackTop += Opcode.STACK_GROW[op]; - return 1; - } - - switch (op) { - case Opcode.IINC : - // this does not call writeLocal(). - return 3; - case Opcode.I2L : - stackTypes[stackTop - 1] = LONG; - stackTypes[stackTop] = TOP; - stackTop++; - break; - case Opcode.I2F : - stackTypes[stackTop - 1] = FLOAT; - break; - case Opcode.I2D : - stackTypes[stackTop - 1] = DOUBLE; - stackTypes[stackTop] = TOP; - stackTop++; - break; - case Opcode.L2I : - stackTypes[--stackTop - 1] = INTEGER; - break; - case Opcode.L2F : - stackTypes[--stackTop - 1] = FLOAT; - break; - case Opcode.L2D : - stackTypes[stackTop - 2] = DOUBLE; - break; - case Opcode.F2I : - stackTypes[stackTop - 1] = INTEGER; - break; - case Opcode.F2L : - stackTypes[stackTop - 1] = LONG; - stackTypes[stackTop] = TOP; - stackTop++; - break; - case Opcode.F2D : - stackTypes[stackTop - 1] = DOUBLE; - stackTypes[stackTop] = TOP; - stackTop++; - break; - case Opcode.D2I : - stackTypes[--stackTop - 1] = INTEGER; - break; - case Opcode.D2L : - stackTypes[stackTop - 2] = LONG; - break; - case Opcode.D2F : - stackTypes[--stackTop - 1] = FLOAT; - break; - case Opcode.I2B : - case Opcode.I2C : - case Opcode.I2S : - break; - default : - throw new RuntimeException("fatal"); - } - - return 1; - } - - private int doOpcode148_201(int pos, byte[] code, int op) throws BadBytecode { - switch (op) { - case Opcode.LCMP : - stackTypes[stackTop - 4] = INTEGER; - stackTop -= 3; - break; - case Opcode.FCMPL : - case Opcode.FCMPG : - stackTypes[--stackTop - 1] = INTEGER; - break; - case Opcode.DCMPL : - case Opcode.DCMPG : - stackTypes[stackTop - 4] = INTEGER; - stackTop -= 3; - break; - case Opcode.IFEQ : - case Opcode.IFNE : - case Opcode.IFLT : - case Opcode.IFGE : - case Opcode.IFGT : - case Opcode.IFLE : - stackTop--; // branch - visitBranch(pos, code, ByteArray.readS16bit(code, pos + 1)); - return 3; - case Opcode.IF_ICMPEQ : - case Opcode.IF_ICMPNE : - case Opcode.IF_ICMPLT : - case Opcode.IF_ICMPGE : - case Opcode.IF_ICMPGT : - case Opcode.IF_ICMPLE : - case Opcode.IF_ACMPEQ : - case Opcode.IF_ACMPNE : - stackTop -= 2; // branch - visitBranch(pos, code, ByteArray.readS16bit(code, pos + 1)); - return 3; - case Opcode.GOTO : - visitGoto(pos, code, ByteArray.readS16bit(code, pos + 1)); - return 3; // branch - case Opcode.JSR : - visitJSR(pos, code); - return 3; // branch - case Opcode.RET : - visitRET(pos, code); - return 2; - case Opcode.TABLESWITCH : { - stackTop--; // branch - int pos2 = (pos & ~3) + 8; - int low = ByteArray.read32bit(code, pos2); - int high = ByteArray.read32bit(code, pos2 + 4); - int n = high - low + 1; - visitTableSwitch(pos, code, n, pos2 + 8, ByteArray.read32bit(code, pos2 - 4)); - return n * 4 + 16 - (pos & 3); } - case Opcode.LOOKUPSWITCH : { - stackTop--; // branch - int pos2 = (pos & ~3) + 8; - int n = ByteArray.read32bit(code, pos2); - visitLookupSwitch(pos, code, n, pos2 + 4, ByteArray.read32bit(code, pos2 - 4)); - return n * 8 + 12 - (pos & 3); } - case Opcode.IRETURN : - stackTop--; - visitReturn(pos, code); - break; - case Opcode.LRETURN : - stackTop -= 2; - visitReturn(pos, code); - break; - case Opcode.FRETURN : - stackTop--; - visitReturn(pos, code); - break; - case Opcode.DRETURN : - stackTop -= 2; - visitReturn(pos, code); - break; - case Opcode.ARETURN : - stackTypes[--stackTop].setType(returnType, classPool); - visitReturn(pos, code); - break; - case Opcode.RETURN : - visitReturn(pos, code); - break; - case Opcode.GETSTATIC : - return doGetField(pos, code, false); - case Opcode.PUTSTATIC : - return doPutField(pos, code, false); - case Opcode.GETFIELD : - return doGetField(pos, code, true); - case Opcode.PUTFIELD : - return doPutField(pos, code, true); - case Opcode.INVOKEVIRTUAL : - case Opcode.INVOKESPECIAL : - return doInvokeMethod(pos, code, true); - case Opcode.INVOKESTATIC : - return doInvokeMethod(pos, code, false); - case Opcode.INVOKEINTERFACE : - return doInvokeIntfMethod(pos, code); - case Opcode.INVOKEDYNAMIC : - return doInvokeDynamic(pos, code); - case Opcode.NEW : { - int i = ByteArray.readU16bit(code, pos + 1); - stackTypes[stackTop++] - = new TypeData.UninitData(pos, cpool.getClassInfo(i)); - return 3; } - case Opcode.NEWARRAY : - return doNEWARRAY(pos, code); - case Opcode.ANEWARRAY : { - int i = ByteArray.readU16bit(code, pos + 1); - String type = cpool.getClassInfo(i).replace('.', '/'); - if (type.charAt(0) == '[') - type = "[" + type; - else - type = "[L" + type + ";"; - - stackTypes[stackTop - 1] - = new TypeData.ClassName(type); - return 3; } - case Opcode.ARRAYLENGTH : - stackTypes[stackTop - 1].setType("[Ljava.lang.Object;", classPool); - stackTypes[stackTop - 1] = INTEGER; - break; - case Opcode.ATHROW : - stackTypes[--stackTop].setType("java.lang.Throwable", classPool); - visitThrow(pos, code); - break; - case Opcode.CHECKCAST : { - // TypeData.setType(stackTypes[stackTop - 1], "java.lang.Object", classPool); - int i = ByteArray.readU16bit(code, pos + 1); - String type = cpool.getClassInfo(i); - if (type.charAt(0) == '[') - type = type.replace('.', '/'); // getClassInfo() may return "[java.lang.Object;". - - stackTypes[stackTop - 1] = new TypeData.ClassName(type); - return 3; } - case Opcode.INSTANCEOF : - // TypeData.setType(stackTypes[stackTop - 1], "java.lang.Object", classPool); - stackTypes[stackTop - 1] = INTEGER; - return 3; - case Opcode.MONITORENTER : - case Opcode.MONITOREXIT : - stackTop--; - // TypeData.setType(stackTypes[stackTop], "java.lang.Object", classPool); - break; - case Opcode.WIDE : - return doWIDE(pos, code); - case Opcode.MULTIANEWARRAY : - return doMultiANewArray(pos, code); - case Opcode.IFNULL : - case Opcode.IFNONNULL : - stackTop--; // branch - visitBranch(pos, code, ByteArray.readS16bit(code, pos + 1)); - return 3; - case Opcode.GOTO_W : - visitGoto(pos, code, ByteArray.read32bit(code, pos + 1)); - return 5; // branch - case Opcode.JSR_W : - visitJSR(pos, code); - return 5; - } - return 1; - } - - private int doWIDE(int pos, byte[] code) throws BadBytecode { - int op = code[pos + 1] & 0xff; - switch (op) { - case Opcode.ILOAD : - doWIDE_XLOAD(pos, code, INTEGER); - break; - case Opcode.LLOAD : - doWIDE_XLOAD(pos, code, LONG); - break; - case Opcode.FLOAD : - doWIDE_XLOAD(pos, code, FLOAT); - break; - case Opcode.DLOAD : - doWIDE_XLOAD(pos, code, DOUBLE); - break; - case Opcode.ALOAD : { - int index = ByteArray.readU16bit(code, pos + 2); - doALOAD(index); - break; } - case Opcode.ISTORE : - doWIDE_STORE(pos, code, INTEGER); - break; - case Opcode.LSTORE : - doWIDE_STORE(pos, code, LONG); - break; - case Opcode.FSTORE : - doWIDE_STORE(pos, code, FLOAT); - break; - case Opcode.DSTORE : - doWIDE_STORE(pos, code, DOUBLE); - break; - case Opcode.ASTORE : { - int index = ByteArray.readU16bit(code, pos + 2); - doASTORE(index); - break; } - case Opcode.IINC : - // this does not call writeLocal(). - return 6; - case Opcode.RET : - visitRET(pos, code); - break; - default : - throw new RuntimeException("bad WIDE instruction: " + op); - } - - return 4; - } - - private void doWIDE_XLOAD(int pos, byte[] code, TypeData type) { - int index = ByteArray.readU16bit(code, pos + 2); - doXLOAD(index, type); - } - - private void doWIDE_STORE(int pos, byte[] code, TypeData type) { - int index = ByteArray.readU16bit(code, pos + 2); - doXSTORE(index, type); - } - - private int doPutField(int pos, byte[] code, boolean notStatic) throws BadBytecode { - int index = ByteArray.readU16bit(code, pos + 1); - String desc = cpool.getFieldrefType(index); - stackTop -= Descriptor.dataSize(desc); - char c = desc.charAt(0); - if (c == 'L') - stackTypes[stackTop].setType(getFieldClassName(desc, 0), classPool); - else if (c == '[') - stackTypes[stackTop].setType(desc, classPool); - - setFieldTarget(notStatic, index); - return 3; - } - - private int doGetField(int pos, byte[] code, boolean notStatic) throws BadBytecode { - int index = ByteArray.readU16bit(code, pos + 1); - setFieldTarget(notStatic, index); - String desc = cpool.getFieldrefType(index); - pushMemberType(desc); - return 3; - } - - private void setFieldTarget(boolean notStatic, int index) throws BadBytecode { - if (notStatic) { - String className = cpool.getFieldrefClassName(index); - stackTypes[--stackTop].setType(className, classPool); - } - } - - private int doNEWARRAY(int pos, byte[] code) { - int s = stackTop - 1; - String type; - switch (code[pos + 1] & 0xff) { - case Opcode.T_BOOLEAN : - type = "[Z"; - break; - case Opcode.T_CHAR : - type = "[C"; - break; - case Opcode.T_FLOAT : - type = "[F"; - break; - case Opcode.T_DOUBLE : - type = "[D"; - break; - case Opcode.T_BYTE : - type = "[B"; - break; - case Opcode.T_SHORT : - type = "[S"; - break; - case Opcode.T_INT : - type = "[I"; - break; - case Opcode.T_LONG : - type = "[J"; - break; - default : - throw new RuntimeException("bad newarray"); - } - - stackTypes[s] = new TypeData.ClassName(type); - return 2; - } - - private int doMultiANewArray(int pos, byte[] code) { - int i = ByteArray.readU16bit(code, pos + 1); - int dim = code[pos + 3] & 0xff; - stackTop -= dim - 1; - - String type = cpool.getClassInfo(i).replace('.', '/'); - stackTypes[stackTop - 1] = new TypeData.ClassName(type); - return 4; - } - - private int doInvokeMethod(int pos, byte[] code, boolean notStatic) throws BadBytecode { - int i = ByteArray.readU16bit(code, pos + 1); - String desc = cpool.getMethodrefType(i); - checkParamTypes(desc, 1); - if (notStatic) { - String className = cpool.getMethodrefClassName(i); - TypeData target = stackTypes[--stackTop]; - if (target instanceof TypeData.UninitTypeVar && target.isUninit()) - constructorCalled(target, ((TypeData.UninitTypeVar)target).offset()); - else if (target instanceof TypeData.UninitData) - constructorCalled(target, ((TypeData.UninitData)target).offset()); - - target.setType(className, classPool); - } - - pushMemberType(desc); - return 3; - } - - /* This is a constructor call on an uninitialized object. - * Sets flags of other references to that object. - * - * @param offset the offset where the object has been created. - */ - private void constructorCalled(TypeData target, int offset) { - target.constructorCalled(offset); - for (int i = 0; i < stackTop; i++) - stackTypes[i].constructorCalled(offset); - - for (int i = 0; i < localsTypes.length; i++) - localsTypes[i].constructorCalled(offset); - } - - private int doInvokeIntfMethod(int pos, byte[] code) throws BadBytecode { - int i = ByteArray.readU16bit(code, pos + 1); - String desc = cpool.getInterfaceMethodrefType(i); - checkParamTypes(desc, 1); - String className = cpool.getInterfaceMethodrefClassName(i); - stackTypes[--stackTop].setType(className, classPool); - pushMemberType(desc); - return 5; - } - - private int doInvokeDynamic(int pos, byte[] code) throws BadBytecode { - int i = ByteArray.readU16bit(code, pos + 1); - String desc = cpool.getInvokeDynamicType(i); - checkParamTypes(desc, 1); - - // assume CosntPool#REF_invokeStatic - /* TypeData target = stackTypes[--stackTop]; - if (target instanceof TypeData.UninitTypeVar && target.isUninit()) - constructorCalled((TypeData.UninitTypeVar)target); - */ - - pushMemberType(desc); - return 5; - } - - private void pushMemberType(String descriptor) { - int top = 0; - if (descriptor.charAt(0) == '(') { - top = descriptor.indexOf(')') + 1; - if (top < 1) - throw new IndexOutOfBoundsException("bad descriptor: " - + descriptor); - } - - TypeData[] types = stackTypes; - int index = stackTop; - switch (descriptor.charAt(top)) { - case '[' : - types[index] = new TypeData.ClassName(descriptor.substring(top)); - break; - case 'L' : - types[index] = new TypeData.ClassName(getFieldClassName(descriptor, top)); - break; - case 'J' : - types[index] = LONG; - types[index + 1] = TOP; - stackTop += 2; - return; - case 'F' : - types[index] = FLOAT; - break; - case 'D' : - types[index] = DOUBLE; - types[index + 1] = TOP; - stackTop += 2; - return; - case 'V' : - return; - default : // C, B, S, I, Z - types[index] = INTEGER; - break; - } - - stackTop++; - } - - private static String getFieldClassName(String desc, int index) { - return desc.substring(index + 1, desc.length() - 1).replace('/', '.'); - } - - private void checkParamTypes(String desc, int i) throws BadBytecode { - char c = desc.charAt(i); - if (c == ')') - return; - - int k = i; - boolean array = false; - while (c == '[') { - array = true; - c = desc.charAt(++k); - } - - if (c == 'L') { - k = desc.indexOf(';', k) + 1; - if (k <= 0) - throw new IndexOutOfBoundsException("bad descriptor"); - } - else - k++; - - checkParamTypes(desc, k); - if (!array && (c == 'J' || c == 'D')) - stackTop -= 2; - else - stackTop--; - - if (array) - stackTypes[stackTop].setType(desc.substring(i, k), classPool); - else if (c == 'L') - stackTypes[stackTop].setType(desc.substring(i + 1, k - 1).replace('/', '.'), - classPool); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/TypeData.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/TypeData.java deleted file mode 100644 index fe9f149af..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/TypeData.java +++ /dev/null @@ -1,786 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.stackmap; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.bytecode.Descriptor; -import com.fr.third.javassist.bytecode.StackMapTable; -import com.fr.third.javassist.bytecode.BadBytecode; - -import java.util.HashSet; -import java.util.Iterator; -import java.util.ArrayList; - -public abstract class TypeData { - /* Memo: - * array type is a subtype of Cloneable and Serializable - */ - - public static TypeData[] make(int size) { - TypeData[] array = new TypeData[size]; - for (int i = 0; i < size; i++) - array[i] = com.fr.third.javassist.bytecode.stackmap.TypeTag.TOP; - - return array; - } - - protected TypeData() {} - - /** - * Sets the type name of this object type. If the given type name is - * a subclass of the current type name, then the given name becomes - * the name of this object type. - * - * @param className dot-separated name unless the type is an array type. - */ - private static void setType(TypeData td, String className, ClassPool cp) throws BadBytecode { - td.setType(className, cp); - } - - public abstract int getTypeTag(); - public abstract int getTypeData(ConstPool cp); - - public TypeData join() { return new TypeVar(this); } - - /** - * If the type is a basic type, this method normalizes the type - * and returns a BasicType object. Otherwise, it returns null. - */ - public abstract BasicType isBasicType(); - - public abstract boolean is2WordType(); - - /** - * Returns false if getName() returns a valid type name. - */ - public boolean isNullType() { return false; } - - public boolean isUninit() { return false; } - - public abstract boolean eq(TypeData d); - - public abstract String getName(); - public abstract void setType(String s, ClassPool cp) throws BadBytecode; - - // depth-first search - public int dfs(ArrayList order, int index, ClassPool cp) - throws NotFoundException - { - return index; - } - - /** - * Returns this if it is a TypeVar or a TypeVar that this - * type depends on. Otherwise, this method returns null. - * It is used by dfs(). - */ - protected TypeVar toTypeVar() { return null; } - - // see UninitTypeVar and UninitData - public void constructorCalled(int offset) {} - - /** - * Primitive types. - */ - protected static class BasicType extends TypeData { - private String name; - private int typeTag; - - public BasicType(String type, int tag) { - name = type; - typeTag = tag; - } - - public int getTypeTag() { return typeTag; } - public int getTypeData(ConstPool cp) { return 0; } - - public TypeData join() { - if (this == com.fr.third.javassist.bytecode.stackmap.TypeTag.TOP) - return this; - else - return super.join(); - } - - public BasicType isBasicType() { return this; } - - public boolean is2WordType() { - return typeTag == StackMapTable.LONG - || typeTag == StackMapTable.DOUBLE; - } - - public boolean eq(TypeData d) { return this == d; } - - public String getName() { - return name; - } - - public void setType(String s, ClassPool cp) throws BadBytecode { - throw new BadBytecode("conflict: " + name + " and " + s); - } - - public String toString() { return name; } - } - - // a type variable - public static abstract class AbsTypeVar extends TypeData { - public AbsTypeVar() {} - public abstract void merge(TypeData t); - public int getTypeTag() { return StackMapTable.OBJECT; } - - public int getTypeData(ConstPool cp) { - return cp.addClassInfo(getName()); - } - - public boolean eq(TypeData d) { return getName().equals(d.getName()); } - } - - /* a type variable representing a class type or a basic type. - */ - public static class TypeVar extends AbsTypeVar { - protected ArrayList lowers; // lower bounds of this type. ArrayList - protected ArrayList usedBy; // reverse relations of lowers - protected ArrayList uppers; // upper bounds of this type. - protected String fixedType; - private boolean is2WordType; // cache - - public TypeVar(TypeData t) { - uppers = null; - lowers = new ArrayList(2); - usedBy = new ArrayList(2); - merge(t); - fixedType = null; - is2WordType = t.is2WordType(); - } - - public String getName() { - if (fixedType == null) - return ((TypeData)lowers.get(0)).getName(); - else - return fixedType; - } - - public BasicType isBasicType() { - if (fixedType == null) - return ((TypeData)lowers.get(0)).isBasicType(); - else - return null; - } - - public boolean is2WordType() { - if (fixedType == null) { - return is2WordType; - // return ((TypeData)lowers.get(0)).is2WordType(); - } - else - return false; - } - - public boolean isNullType() { - if (fixedType == null) - return ((TypeData)lowers.get(0)).isNullType(); - else - return false; - } - - public boolean isUninit() { - if (fixedType == null) - return ((TypeData)lowers.get(0)).isUninit(); - else - return false; - } - - public void merge(TypeData t) { - lowers.add(t); - if (t instanceof TypeVar) - ((TypeVar)t).usedBy.add(this); - } - - public int getTypeTag() { - /* If fixedType is null after calling dfs(), then this - type is NULL, Uninit, or a basic type. So call - getTypeTag() on the first element of lowers. */ - if (fixedType == null) - return ((TypeData)lowers.get(0)).getTypeTag(); - else - return super.getTypeTag(); - } - - public int getTypeData(ConstPool cp) { - if (fixedType == null) - return ((TypeData)lowers.get(0)).getTypeData(cp); - else - return super.getTypeData(cp); - } - - public void setType(String typeName, ClassPool cp) throws BadBytecode { - if (uppers == null) - uppers = new ArrayList(); - - uppers.add(typeName); - } - - protected TypeVar toTypeVar() { return this; } - - private int visited = 0; - private int smallest = 0; - private boolean inList = false; - - // depth-first serach - public int dfs(ArrayList preOrder, int index, ClassPool cp) throws NotFoundException { - if (visited > 0) - return index; // MapMaker.make() may call an already visited node. - - visited = smallest = ++index; - preOrder.add(this); - inList = true; - int n = lowers.size(); - for (int i = 0; i < n; i++) { - TypeVar child = ((TypeData)lowers.get(i)).toTypeVar(); - if (child != null) - if (child.visited == 0) { - index = child.dfs(preOrder, index, cp); - if (child.smallest < smallest) - smallest = child.smallest; - } - else if (child.inList) - if (child.visited < smallest) - smallest = child.visited; - } - - if (visited == smallest) { - ArrayList scc = new ArrayList(); // strongly connected component - TypeVar cv; - do { - cv = (TypeVar)preOrder.remove(preOrder.size() - 1); - cv.inList = false; - scc.add(cv); - } while (cv != this); - fixTypes(scc, cp); - } - - return index; - } - - private void fixTypes(ArrayList scc, ClassPool cp) throws NotFoundException { - HashSet lowersSet = new HashSet(); - boolean isBasicType = false; - TypeData kind = null; - int size = scc.size(); - for (int i = 0; i < size; i++) { - ArrayList tds = ((TypeVar)scc.get(i)).lowers; - int size2 = tds.size(); - for (int j = 0; j < size2; j++) { - TypeData d = (TypeData)tds.get(j); - BasicType bt = d.isBasicType(); - if (kind == null) { - if (bt == null) { - isBasicType = false; - kind = d; - /* If scc has only an UninitData, fixedType is kept null. - So lowerSet must be empty. If scc has not only an UninitData - but also another TypeData, an error must be thrown but this - error detection has not been implemented. */ - if (d.isUninit()) - break; - } - else { - isBasicType = true; - kind = bt; - } - } - else { - if ((bt == null && isBasicType) - || (bt != null && kind != bt)) { - isBasicType = true; - kind = com.fr.third.javassist.bytecode.stackmap.TypeTag.TOP; - break; - } - } - - if (bt == null && !d.isNullType()) - lowersSet.add(d.getName()); - } - } - - if (isBasicType) { - for (int i = 0; i < size; i++) { - TypeVar cv = (TypeVar)scc.get(i); - cv.lowers.clear(); - cv.lowers.add(kind); - is2WordType = kind.is2WordType(); - } - } - else { - String typeName = fixTypes2(scc, lowersSet, cp); - for (int i = 0; i < size; i++) { - TypeVar cv = (TypeVar)scc.get(i); - cv.fixedType = typeName; - } - } - } - - private String fixTypes2(ArrayList scc, HashSet lowersSet, ClassPool cp) throws NotFoundException { - Iterator it = lowersSet.iterator(); - if (lowersSet.size() == 0) - return null; // only NullType - else if (lowersSet.size() == 1) - return (String)it.next(); - else { - CtClass cc = cp.get((String)it.next()); - while (it.hasNext()) - cc = commonSuperClassEx(cc, cp.get((String)it.next())); - - if (cc.getSuperclass() == null || isObjectArray(cc)) - cc = fixByUppers(scc, cp, new HashSet(), cc); - - if (cc.isArray()) - return Descriptor.toJvmName(cc); - else - return cc.getName(); - } - } - - private static boolean isObjectArray(CtClass cc) throws NotFoundException { - return cc.isArray() && cc.getComponentType().getSuperclass() == null; - } - - private CtClass fixByUppers(ArrayList users, ClassPool cp, HashSet visited, CtClass type) - throws NotFoundException - { - if (users == null) - return type; - - int size = users.size(); - for (int i = 0; i < size; i++) { - TypeVar t = (TypeVar)users.get(i); - if (!visited.add(t)) - return type; - - if (t.uppers != null) { - int s = t.uppers.size(); - for (int k = 0; k < s; k++) { - CtClass cc = cp.get((String)t.uppers.get(k)); - if (cc.subtypeOf(type)) - type = cc; - } - } - - type = fixByUppers(t.usedBy, cp, visited, type); - } - - return type; - } - } - - /** - * Finds the most specific common super class of the given classes - * by considering array types. - */ - public static CtClass commonSuperClassEx(CtClass one, CtClass two) throws NotFoundException { - if (one == two) - return one; - else if (one.isArray() && two.isArray()) { - CtClass ele1 = one.getComponentType(); - CtClass ele2 = two.getComponentType(); - CtClass element = commonSuperClassEx(ele1, ele2); - if (element == ele1) - return one; - else if (element == ele2) - return two; - else - return one.getClassPool().get(element == null ? "java.lang.Object" - : element.getName() + "[]"); - } - else if (one.isPrimitive() || two.isPrimitive()) - return null; // TOP - else if (one.isArray() || two.isArray()) // but !(one.isArray() && two.isArray()) - return one.getClassPool().get("java.lang.Object"); - else - return commonSuperClass(one, two); - } - - /** - * Finds the most specific common super class of the given classes. - * This method is a copy from javassist.bytecode.analysis.Type. - */ - public static CtClass commonSuperClass(CtClass one, CtClass two) throws NotFoundException { - CtClass deep = one; - CtClass shallow = two; - CtClass backupShallow = shallow; - CtClass backupDeep = deep; - - // Phase 1 - Find the deepest hierarchy, set deep and shallow correctly - for (;;) { - // In case we get lucky, and find a match early - if (eq(deep, shallow) && deep.getSuperclass() != null) - return deep; - - CtClass deepSuper = deep.getSuperclass(); - CtClass shallowSuper = shallow.getSuperclass(); - - if (shallowSuper == null) { - // right, now reset shallow - shallow = backupShallow; - break; - } - - if (deepSuper == null) { - // wrong, swap them, since deep is now useless, its our tmp before we swap it - deep = backupDeep; - backupDeep = backupShallow; - backupShallow = deep; - - deep = shallow; - shallow = backupShallow; - break; - } - - deep = deepSuper; - shallow = shallowSuper; - } - - // Phase 2 - Move deepBackup up by (deep end - deep) - for (;;) { - deep = deep.getSuperclass(); - if (deep == null) - break; - - backupDeep = backupDeep.getSuperclass(); - } - - deep = backupDeep; - - // Phase 3 - The hierarchy positions are now aligned - // The common super class is easy to find now - while (!eq(deep, shallow)) { - deep = deep.getSuperclass(); - shallow = shallow.getSuperclass(); - } - - return deep; - } - - static boolean eq(CtClass one, CtClass two) { - return one == two || (one != null && two != null && one.getName().equals(two.getName())); - } - - public static void aastore(TypeData array, TypeData value, ClassPool cp) throws BadBytecode { - if (array instanceof AbsTypeVar) - if (!value.isNullType()) - ((AbsTypeVar)array).merge(ArrayType.make(value)); - - if (value instanceof AbsTypeVar) - if (array instanceof AbsTypeVar) - ArrayElement.make(array); // should call value.setType() later. - else if (array instanceof ClassName) { - if (!array.isNullType()) { - String type = ArrayElement.typeName(array.getName()); - value.setType(type, cp); - } - } - else - throw new BadBytecode("bad AASTORE: " + array); - } - - /* A type variable representing an array type. - * It is a decorator of another type variable. - */ - public static class ArrayType extends AbsTypeVar { - private AbsTypeVar element; - - private ArrayType(AbsTypeVar elementType) { - element = elementType; - } - - static TypeData make(TypeData element) throws BadBytecode { - if (element instanceof ArrayElement) - return ((ArrayElement)element).arrayType(); - else if (element instanceof AbsTypeVar) - return new ArrayType((AbsTypeVar)element); - else if (element instanceof ClassName) - if (!element.isNullType()) - return new ClassName(typeName(element.getName())); - - throw new BadBytecode("bad AASTORE: " + element); - } - - public void merge(TypeData t) { - try { - if (!t.isNullType()) - element.merge(ArrayElement.make(t)); - } - catch (BadBytecode e) { - // never happens - throw new RuntimeException("fatal: " + e); - } - } - - public String getName() { - return typeName(element.getName()); - } - - public AbsTypeVar elementType() { return element; } - - public BasicType isBasicType() { return null; } - public boolean is2WordType() { return false; } - - /* elementType must be a class name. Basic type names - * are not allowed. - */ - public static String typeName(String elementType) { - if (elementType.charAt(0) == '[') - return "[" + elementType; - else - return "[L" + elementType.replace('.', '/') + ";"; - } - - public void setType(String s, ClassPool cp) throws BadBytecode { - element.setType(ArrayElement.typeName(s), cp); - } - - protected TypeVar toTypeVar() { return element.toTypeVar(); } - - public int dfs(ArrayList order, int index, ClassPool cp) throws NotFoundException { - return element.dfs(order, index, cp); - } - } - - /* A type variable representing an array-element type. - * It is a decorator of another type variable. - */ - public static class ArrayElement extends AbsTypeVar { - private AbsTypeVar array; - - private ArrayElement(AbsTypeVar a) { // a is never null - array = a; - } - - public static TypeData make(TypeData array) throws BadBytecode { - if (array instanceof ArrayType) - return ((ArrayType)array).elementType(); - else if (array instanceof AbsTypeVar) - return new ArrayElement((AbsTypeVar)array); - else if (array instanceof ClassName) - if (!array.isNullType()) - return new ClassName(typeName(array.getName())); - - throw new BadBytecode("bad AASTORE: " + array); - } - - public void merge(TypeData t) { - try { - if (!t.isNullType()) - array.merge(ArrayType.make(t)); - } - catch (BadBytecode e) { - // never happens - throw new RuntimeException("fatal: " + e); - } - } - - public String getName() { - return typeName(array.getName()); - } - - public AbsTypeVar arrayType() { return array; } - - /* arrayType must be a class name. Basic type names are - * not allowed. - */ - - public BasicType isBasicType() { return null; } - - public boolean is2WordType() { return false; } - - private static String typeName(String arrayType) { - if (arrayType.length() > 1 && arrayType.charAt(0) == '[') { - char c = arrayType.charAt(1); - if (c == 'L') - return arrayType.substring(2, arrayType.length() - 1).replace('/', '.'); - else if (c == '[') - return arrayType.substring(1); - } - - return "java.lang.Object"; // the array type may be NullType - } - - public void setType(String s, ClassPool cp) throws BadBytecode { - array.setType(ArrayType.typeName(s), cp); - } - - protected TypeVar toTypeVar() { return array.toTypeVar(); } - - public int dfs(ArrayList order, int index, ClassPool cp) throws NotFoundException { - return array.dfs(order, index, cp); - } - } - - public static class UninitTypeVar extends AbsTypeVar { - protected TypeData type; // UninitData or TOP - - public UninitTypeVar(UninitData t) { type = t; } - public int getTypeTag() { return type.getTypeTag(); } - public int getTypeData(ConstPool cp) { return type.getTypeData(cp); } - public BasicType isBasicType() { return type.isBasicType(); } - public boolean is2WordType() { return type.is2WordType(); } - public boolean isUninit() { return type.isUninit(); } - public boolean eq(TypeData d) { return type.eq(d); } - public String getName() { return type.getName(); } - - protected TypeVar toTypeVar() { return null; } - public TypeData join() { return type.join(); } - - public void setType(String s, ClassPool cp) throws BadBytecode { - type.setType(s, cp); - } - - public void merge(TypeData t) { - if (!t.eq(type)) - type = TypeTag.TOP; - } - - public void constructorCalled(int offset) { - type.constructorCalled(offset); - } - - public int offset() { - if (type instanceof UninitData) - return ((UninitData)type).offset; - else // if type == TypeTag.TOP - throw new RuntimeException("not available"); - } - } - - /** - * Type data for OBJECT. - */ - public static class ClassName extends TypeData { - private String name; // dot separated. - - public ClassName(String n) { - name = n; - } - - public String getName() { - return name; - } - - public BasicType isBasicType() { return null; } - - public boolean is2WordType() { return false; } - - public int getTypeTag() { return StackMapTable.OBJECT; } - - public int getTypeData(ConstPool cp) { - return cp.addClassInfo(getName()); - } - - public boolean eq(TypeData d) { return name.equals(d.getName()); } - - public void setType(String typeName, ClassPool cp) throws BadBytecode {} - } - - /** - * Type data for NULL or OBJECT. - * The types represented by the instances of this class are - * initially NULL but will be OBJECT. - */ - public static class NullType extends ClassName { - public NullType() { - super("null-type"); // type name - } - - public int getTypeTag() { - return StackMapTable.NULL; - } - - public boolean isNullType() { return true; } - public int getTypeData(ConstPool cp) { return 0; } - } - - /** - * Type data for UNINIT. - */ - public static class UninitData extends ClassName { - int offset; - boolean initialized; - - UninitData(int offset, String className) { - super(className); - this.offset = offset; - this.initialized = false; - } - - public UninitData copy() { return new UninitData(offset, getName()); } - - public int getTypeTag() { - return StackMapTable.UNINIT; - } - - public int getTypeData(ConstPool cp) { - return offset; - } - - public TypeData join() { - if (initialized) - return new TypeVar(new ClassName(getName())); - else - return new UninitTypeVar(copy()); - } - - public boolean isUninit() { return true; } - - public boolean eq(TypeData d) { - if (d instanceof UninitData) { - UninitData ud = (UninitData)d; - return offset == ud.offset && getName().equals(ud.getName()); - } - else - return false; - } - - public String toString() { return "uninit:" + getName() + "@" + offset; } - - public int offset() { return offset; } - - public void constructorCalled(int offset) { - if (offset == this.offset) - initialized = true; - } - } - - public static class UninitThis extends UninitData { - UninitThis(String className) { - super(-1, className); - } - - public UninitData copy() { return new UninitThis(getName()); } - - public int getTypeTag() { - return StackMapTable.THIS; - } - - public int getTypeData(ConstPool cp) { - return 0; - } - - public String toString() { return "uninit:this"; } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/TypeTag.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/TypeTag.java deleted file mode 100644 index be8deda87..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/TypeTag.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.stackmap; - -import com.fr.third.javassist.bytecode.StackMapTable; - -public interface TypeTag { - String TOP_TYPE = "*top*"; - TypeData TOP = new TypeData.BasicType(TOP_TYPE, StackMapTable.TOP); - TypeData INTEGER = new TypeData.BasicType("int", StackMapTable.INTEGER); - TypeData FLOAT = new TypeData.BasicType("float", StackMapTable.FLOAT); - TypeData DOUBLE = new TypeData.BasicType("double", StackMapTable.DOUBLE); - TypeData LONG = new TypeData.BasicType("long", StackMapTable.LONG); - - // and NULL, THIS, OBJECT, UNINIT -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/TypedBlock.java b/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/TypedBlock.java deleted file mode 100644 index 4d5ce08ee..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/bytecode/stackmap/TypedBlock.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.bytecode.stackmap; - -import com.fr.third.javassist.bytecode.BadBytecode; - -public class TypedBlock extends com.fr.third.javassist.bytecode.stackmap.BasicBlock { - public int stackTop, numLocals; - // localsTypes is set to non-null when this block is first visited by a MapMaker. - // see alreadySet(). - public com.fr.third.javassist.bytecode.stackmap.TypeData[] localsTypes; - public com.fr.third.javassist.bytecode.stackmap.TypeData[] stackTypes; - - /** - * Divides the method body into basic blocks. - * The type information of the first block is initialized. - * - * @param optmize if it is true and the method does not include - * branches, this method returns null. - */ - public static TypedBlock[] makeBlocks(com.fr.third.javassist.bytecode.MethodInfo minfo, com.fr.third.javassist.bytecode.CodeAttribute ca, - boolean optimize) - throws com.fr.third.javassist.bytecode.BadBytecode - { - TypedBlock[] blocks = (TypedBlock[])new Maker().make(minfo); - if (optimize && blocks.length < 2) - if (blocks.length == 0 || blocks[0].incoming == 0) - return null; - - com.fr.third.javassist.bytecode.ConstPool pool = minfo.getConstPool(); - boolean isStatic = (minfo.getAccessFlags() & com.fr.third.javassist.bytecode.AccessFlag.STATIC) != 0; - blocks[0].initFirstBlock(ca.getMaxStack(), ca.getMaxLocals(), - pool.getClassName(), minfo.getDescriptor(), - isStatic, minfo.isConstructor()); - return blocks; - } - - protected TypedBlock(int pos) { - super(pos); - localsTypes = null; - } - - protected void toString2(StringBuffer sbuf) { - super.toString2(sbuf); - sbuf.append(",\n stack={"); - printTypes(sbuf, stackTop, stackTypes); - sbuf.append("}, locals={"); - printTypes(sbuf, numLocals, localsTypes); - sbuf.append('}'); - } - - private void printTypes(StringBuffer sbuf, int size, - com.fr.third.javassist.bytecode.stackmap.TypeData[] types) { - if (types == null) - return; - - for (int i = 0; i < size; i++) { - if (i > 0) - sbuf.append(", "); - - com.fr.third.javassist.bytecode.stackmap.TypeData td = types[i]; - sbuf.append(td == null ? "<>" : td.toString()); - } - } - - public boolean alreadySet() { - return localsTypes != null; - } - - public void setStackMap(int st, com.fr.third.javassist.bytecode.stackmap.TypeData[] stack, int nl, com.fr.third.javassist.bytecode.stackmap.TypeData[] locals) - throws com.fr.third.javassist.bytecode.BadBytecode - { - stackTop = st; - stackTypes = stack; - numLocals = nl; - localsTypes = locals; - } - - /* - * Computes the correct value of numLocals. - */ - public void resetNumLocals() { - if (localsTypes != null) { - int nl = localsTypes.length; - while (nl > 0 && localsTypes[nl - 1].isBasicType() == com.fr.third.javassist.bytecode.stackmap.TypeTag.TOP) { - if (nl > 1) { - if (localsTypes[nl - 2].is2WordType()) - break; - } - - --nl; - } - - numLocals = nl; - } - } - - public static class Maker extends com.fr.third.javassist.bytecode.stackmap.BasicBlock.Maker { - protected com.fr.third.javassist.bytecode.stackmap.BasicBlock makeBlock(int pos) { - return new TypedBlock(pos); - } - - protected BasicBlock[] makeArray(int size) { - return new TypedBlock[size]; - } - } - - /** - * Initializes the first block by the given method descriptor. - * - * @param block the first basic block that this method initializes. - * @param className a dot-separated fully qualified class name. - * For example, javassist.bytecode.stackmap.BasicBlock. - * @param methodDesc method descriptor. - * @param isStatic true if the method is a static method. - * @param isConstructor true if the method is a constructor. - */ - void initFirstBlock(int maxStack, int maxLocals, String className, - String methodDesc, boolean isStatic, boolean isConstructor) - throws com.fr.third.javassist.bytecode.BadBytecode - { - if (methodDesc.charAt(0) != '(') - throw new com.fr.third.javassist.bytecode.BadBytecode("no method descriptor: " + methodDesc); - - stackTop = 0; - stackTypes = com.fr.third.javassist.bytecode.stackmap.TypeData.make(maxStack); - com.fr.third.javassist.bytecode.stackmap.TypeData[] locals = com.fr.third.javassist.bytecode.stackmap.TypeData.make(maxLocals); - if (isConstructor) - locals[0] = new com.fr.third.javassist.bytecode.stackmap.TypeData.UninitThis(className); - else if (!isStatic) - locals[0] = new com.fr.third.javassist.bytecode.stackmap.TypeData.ClassName(className); - - int n = isStatic ? -1 : 0; - int i = 1; - try { - while ((i = descToTag(methodDesc, i, ++n, locals)) > 0) - if (locals[n].is2WordType()) - locals[++n] = com.fr.third.javassist.bytecode.stackmap.TypeTag.TOP; - } - catch (StringIndexOutOfBoundsException e) { - throw new com.fr.third.javassist.bytecode.BadBytecode("bad method descriptor: " - + methodDesc); - } - - numLocals = n; - localsTypes = locals; - } - - private static int descToTag(String desc, int i, - int n, com.fr.third.javassist.bytecode.stackmap.TypeData[] types) - throws com.fr.third.javassist.bytecode.BadBytecode - { - int i0 = i; - int arrayDim = 0; - char c = desc.charAt(i); - if (c == ')') - return 0; - - while (c == '[') { - ++arrayDim; - c = desc.charAt(++i); - } - - if (c == 'L') { - int i2 = desc.indexOf(';', ++i); - if (arrayDim > 0) - types[n] = new com.fr.third.javassist.bytecode.stackmap.TypeData.ClassName(desc.substring(i0, ++i2)); - else - types[n] = new com.fr.third.javassist.bytecode.stackmap.TypeData.ClassName(desc.substring(i0 + 1, ++i2 - 1) - .replace('/', '.')); - return i2; - } - else if (arrayDim > 0) { - types[n] = new com.fr.third.javassist.bytecode.stackmap.TypeData.ClassName(desc.substring(i0, ++i)); - return i; - } - else { - com.fr.third.javassist.bytecode.stackmap.TypeData t = toPrimitiveTag(c); - if (t == null) - throw new BadBytecode("bad method descriptor: " + desc); - - types[n] = t; - return i + 1; - } - } - - private static TypeData toPrimitiveTag(char c) { - switch (c) { - case 'Z' : - case 'C' : - case 'B' : - case 'S' : - case 'I' : - return com.fr.third.javassist.bytecode.stackmap.TypeTag.INTEGER; - case 'J' : - return com.fr.third.javassist.bytecode.stackmap.TypeTag.LONG; - case 'F' : - return com.fr.third.javassist.bytecode.stackmap.TypeTag.FLOAT; - case 'D' : - return TypeTag.DOUBLE; - case 'V' : - default : - return null; - } - } - - public static String getRetType(String desc) { - int i = desc.indexOf(')'); - if (i < 0) - return "java.lang.Object"; - - char c = desc.charAt(i + 1); - if (c == '[') - return desc.substring(i + 1); - else if (c == 'L') - return desc.substring(i + 2, desc.length() - 1).replace('/', '.'); - else - return "java.lang.Object"; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/AccessorMaker.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/AccessorMaker.java deleted file mode 100644 index d01acd789..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/AccessorMaker.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.bytecode.SyntheticAttribute; - -import java.util.HashMap; - -/** - * AccessorMaker maintains accessors to private members of an enclosing - * class. It is necessary for compiling a method in an inner class. - */ -public class AccessorMaker { - private com.fr.third.javassist.CtClass clazz; - private int uniqueNumber; - private HashMap accessors; - - static final String lastParamType = "javassist.runtime.Inner"; - - public AccessorMaker(com.fr.third.javassist.CtClass c) { - clazz = c; - uniqueNumber = 1; - accessors = new HashMap(); - } - - public String getConstructor(com.fr.third.javassist.CtClass c, String desc, com.fr.third.javassist.bytecode.MethodInfo orig) - throws com.fr.third.javassist.compiler.CompileError - { - String key = ":" + desc; - String consDesc = (String)accessors.get(key); - if (consDesc != null) - return consDesc; // already exists. - - consDesc = com.fr.third.javassist.bytecode.Descriptor.appendParameter(lastParamType, desc); - com.fr.third.javassist.bytecode.ClassFile cf = clazz.getClassFile(); // turn on the modified flag. - try { - com.fr.third.javassist.bytecode.ConstPool cp = cf.getConstPool(); - com.fr.third.javassist.ClassPool pool = clazz.getClassPool(); - com.fr.third.javassist.bytecode.MethodInfo minfo - = new com.fr.third.javassist.bytecode.MethodInfo(cp, com.fr.third.javassist.bytecode.MethodInfo.nameInit, consDesc); - minfo.setAccessFlags(0); - minfo.addAttribute(new com.fr.third.javassist.bytecode.SyntheticAttribute(cp)); - com.fr.third.javassist.bytecode.ExceptionsAttribute ea = orig.getExceptionsAttribute(); - if (ea != null) - minfo.addAttribute(ea.copy(cp, null)); - - com.fr.third.javassist.CtClass[] params = com.fr.third.javassist.bytecode.Descriptor.getParameterTypes(desc, pool); - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(cp); - code.addAload(0); - int regno = 1; - for (int i = 0; i < params.length; ++i) - regno += code.addLoad(regno, params[i]); - code.setMaxLocals(regno + 1); // the last parameter is added. - code.addInvokespecial(clazz, com.fr.third.javassist.bytecode.MethodInfo.nameInit, desc); - - code.addReturn(null); - minfo.setCodeAttribute(code.toCodeAttribute()); - cf.addMethod(minfo); - } - catch (com.fr.third.javassist.CannotCompileException e) { - throw new com.fr.third.javassist.compiler.CompileError(e); - } - catch (com.fr.third.javassist.NotFoundException e) { - throw new com.fr.third.javassist.compiler.CompileError(e); - } - - accessors.put(key, consDesc); - return consDesc; - } - - /** - * Returns the name of the method for accessing a private method. - * - * @param name the name of the private method. - * @param desc the descriptor of the private method. - * @param accDesc the descriptor of the accessor method. The first - * parameter type is clazz. - * If the private method is static, - * accDesc must be identical to desc. - * - * @param orig the method info of the private method. - * @return - */ - public String getMethodAccessor(String name, String desc, String accDesc, - com.fr.third.javassist.bytecode.MethodInfo orig) - throws com.fr.third.javassist.compiler.CompileError - { - String key = name + ":" + desc; - String accName = (String)accessors.get(key); - if (accName != null) - return accName; // already exists. - - com.fr.third.javassist.bytecode.ClassFile cf = clazz.getClassFile(); // turn on the modified flag. - accName = findAccessorName(cf); - try { - com.fr.third.javassist.bytecode.ConstPool cp = cf.getConstPool(); - com.fr.third.javassist.ClassPool pool = clazz.getClassPool(); - com.fr.third.javassist.bytecode.MethodInfo minfo - = new com.fr.third.javassist.bytecode.MethodInfo(cp, accName, accDesc); - minfo.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.STATIC); - minfo.addAttribute(new com.fr.third.javassist.bytecode.SyntheticAttribute(cp)); - com.fr.third.javassist.bytecode.ExceptionsAttribute ea = orig.getExceptionsAttribute(); - if (ea != null) - minfo.addAttribute(ea.copy(cp, null)); - - com.fr.third.javassist.CtClass[] params = com.fr.third.javassist.bytecode.Descriptor.getParameterTypes(accDesc, pool); - int regno = 0; - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(cp); - for (int i = 0; i < params.length; ++i) - regno += code.addLoad(regno, params[i]); - - code.setMaxLocals(regno); - if (desc == accDesc) - code.addInvokestatic(clazz, name, desc); - else - code.addInvokevirtual(clazz, name, desc); - - code.addReturn(com.fr.third.javassist.bytecode.Descriptor.getReturnType(desc, pool)); - minfo.setCodeAttribute(code.toCodeAttribute()); - cf.addMethod(minfo); - } - catch (com.fr.third.javassist.CannotCompileException e) { - throw new com.fr.third.javassist.compiler.CompileError(e); - } - catch (com.fr.third.javassist.NotFoundException e) { - throw new com.fr.third.javassist.compiler.CompileError(e); - } - - accessors.put(key, accName); - return accName; - } - - /** - * Returns the method_info representing the added getter. - */ - public com.fr.third.javassist.bytecode.MethodInfo getFieldGetter(com.fr.third.javassist.bytecode.FieldInfo finfo, boolean is_static) - throws com.fr.third.javassist.compiler.CompileError - { - String fieldName = finfo.getName(); - String key = fieldName + ":getter"; - Object res = accessors.get(key); - if (res != null) - return (com.fr.third.javassist.bytecode.MethodInfo)res; // already exists. - - com.fr.third.javassist.bytecode.ClassFile cf = clazz.getClassFile(); // turn on the modified flag. - String accName = findAccessorName(cf); - try { - com.fr.third.javassist.bytecode.ConstPool cp = cf.getConstPool(); - com.fr.third.javassist.ClassPool pool = clazz.getClassPool(); - String fieldType = finfo.getDescriptor(); - String accDesc; - if (is_static) - accDesc = "()" + fieldType; - else - accDesc = "(" + com.fr.third.javassist.bytecode.Descriptor.of(clazz) + ")" + fieldType; - - com.fr.third.javassist.bytecode.MethodInfo minfo = new com.fr.third.javassist.bytecode.MethodInfo(cp, accName, accDesc); - minfo.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.STATIC); - minfo.addAttribute(new com.fr.third.javassist.bytecode.SyntheticAttribute(cp)); - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(cp); - if (is_static) { - code.addGetstatic(com.fr.third.javassist.bytecode.Bytecode.THIS, fieldName, fieldType); - } - else { - code.addAload(0); - code.addGetfield(com.fr.third.javassist.bytecode.Bytecode.THIS, fieldName, fieldType); - code.setMaxLocals(1); - } - - code.addReturn(com.fr.third.javassist.bytecode.Descriptor.toCtClass(fieldType, pool)); - minfo.setCodeAttribute(code.toCodeAttribute()); - cf.addMethod(minfo); - accessors.put(key, minfo); - return minfo; - } - catch (com.fr.third.javassist.CannotCompileException e) { - throw new com.fr.third.javassist.compiler.CompileError(e); - } - catch (com.fr.third.javassist.NotFoundException e) { - throw new com.fr.third.javassist.compiler.CompileError(e); - } - } - - /** - * Returns the method_info representing the added setter. - */ - public com.fr.third.javassist.bytecode.MethodInfo getFieldSetter(com.fr.third.javassist.bytecode.FieldInfo finfo, boolean is_static) - throws com.fr.third.javassist.compiler.CompileError - { - String fieldName = finfo.getName(); - String key = fieldName + ":setter"; - Object res = accessors.get(key); - if (res != null) - return (com.fr.third.javassist.bytecode.MethodInfo)res; // already exists. - - com.fr.third.javassist.bytecode.ClassFile cf = clazz.getClassFile(); // turn on the modified flag. - String accName = findAccessorName(cf); - try { - com.fr.third.javassist.bytecode.ConstPool cp = cf.getConstPool(); - com.fr.third.javassist.ClassPool pool = clazz.getClassPool(); - String fieldType = finfo.getDescriptor(); - String accDesc; - if (is_static) - accDesc = "(" + fieldType + ")V"; - else - accDesc = "(" + com.fr.third.javassist.bytecode.Descriptor.of(clazz) + fieldType + ")V"; - - com.fr.third.javassist.bytecode.MethodInfo minfo = new com.fr.third.javassist.bytecode.MethodInfo(cp, accName, accDesc); - minfo.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.STATIC); - minfo.addAttribute(new SyntheticAttribute(cp)); - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(cp); - int reg; - if (is_static) { - reg = code.addLoad(0, com.fr.third.javassist.bytecode.Descriptor.toCtClass(fieldType, pool)); - code.addPutstatic(com.fr.third.javassist.bytecode.Bytecode.THIS, fieldName, fieldType); - } - else { - code.addAload(0); - reg = code.addLoad(1, com.fr.third.javassist.bytecode.Descriptor.toCtClass(fieldType, pool)) - + 1; - code.addPutfield(com.fr.third.javassist.bytecode.Bytecode.THIS, fieldName, fieldType); - } - - code.addReturn(null); - code.setMaxLocals(reg); - minfo.setCodeAttribute(code.toCodeAttribute()); - cf.addMethod(minfo); - accessors.put(key, minfo); - return minfo; - } - catch (com.fr.third.javassist.CannotCompileException e) { - throw new com.fr.third.javassist.compiler.CompileError(e); - } - catch (NotFoundException e) { - throw new CompileError(e); - } - } - - private String findAccessorName(com.fr.third.javassist.bytecode.ClassFile cf) { - String accName; - do { - accName = "access$" + uniqueNumber++; - } while (cf.getMethod(accName) != null); - return accName; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/CodeGen.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/CodeGen.java deleted file mode 100644 index 5a67ddbe1..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/CodeGen.java +++ /dev/null @@ -1,1923 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -import java.util.ArrayList; -import java.util.Arrays; - -import com.fr.third.javassist.bytecode.Opcode; -import com.fr.third.javassist.compiler.ast.DoubleConst; - -/* The code generator is implemeted by three files: - * CodeGen.java, MemberCodeGen.java, and JvstCodeGen. - * I just wanted to split a big file into three smaller ones. - */ - -public abstract class CodeGen extends com.fr.third.javassist.compiler.ast.Visitor implements com.fr.third.javassist.bytecode.Opcode, TokenId { - static final String javaLangObject = "java.lang.Object"; - static final String jvmJavaLangObject = "java/lang/Object"; - - static final String javaLangString = "java.lang.String"; - static final String jvmJavaLangString = "java/lang/String"; - - protected com.fr.third.javassist.bytecode.Bytecode bytecode; - private int tempVar; - TypeChecker typeChecker; - - /** - * true if the last visited node is a return statement. - */ - protected boolean hasReturned; - - /** - * Must be true if compilation is for a static method. - */ - public boolean inStaticMethod; - - protected ArrayList breakList, continueList; - - /** - * doit() in ReturnHook is called from atReturn(). - */ - protected static abstract class ReturnHook { - ReturnHook next; - - /** - * Returns true if the generated code ends with return, - * throw, or goto. - */ - protected abstract boolean doit(com.fr.third.javassist.bytecode.Bytecode b, int opcode); - - protected ReturnHook(CodeGen gen) { - next = gen.returnHooks; - gen.returnHooks = this; - } - - protected void remove(CodeGen gen) { - gen.returnHooks = next; - } - } - - protected ReturnHook returnHooks; - - /* The following fields are used by atXXX() methods - * for returning the type of the compiled expression. - */ - protected int exprType; // VOID, NULL, CLASS, BOOLEAN, INT, ... - protected int arrayDim; - protected String className; // JVM-internal representation - - public CodeGen(com.fr.third.javassist.bytecode.Bytecode b) { - bytecode = b; - tempVar = -1; - typeChecker = null; - hasReturned = false; - inStaticMethod = false; - breakList = null; - continueList = null; - returnHooks = null; - } - - public void setTypeChecker(TypeChecker checker) { - typeChecker = checker; - } - - protected static void fatal() throws CompileError { - throw new CompileError("fatal"); - } - - public static boolean is2word(int type, int dim) { - return dim == 0 && (type == DOUBLE || type == LONG); - } - - public int getMaxLocals() { return bytecode.getMaxLocals(); } - - public void setMaxLocals(int n) { - bytecode.setMaxLocals(n); - } - - protected void incMaxLocals(int size) { - bytecode.incMaxLocals(size); - } - - /** - * Returns a local variable that single or double words can be - * stored in. - */ - protected int getTempVar() { - if (tempVar < 0) { - tempVar = getMaxLocals(); - incMaxLocals(2); - } - - return tempVar; - } - - protected int getLocalVar(com.fr.third.javassist.compiler.ast.Declarator d) { - int v = d.getLocalVar(); - if (v < 0) { - v = getMaxLocals(); // delayed variable allocation. - d.setLocalVar(v); - incMaxLocals(1); - } - - return v; - } - - /** - * Returns the JVM-internal representation of this class name. - */ - protected abstract String getThisName(); - - /** - * Returns the JVM-internal representation of this super class name. - */ - protected abstract String getSuperName() throws CompileError; - - /* Converts a class name into a JVM-internal representation. - * - * It may also expand a simple class name to java.lang.*. - * For example, this converts Object into java/lang/Object. - */ - protected abstract String resolveClassName(com.fr.third.javassist.compiler.ast.ASTList name) - throws CompileError; - - /* Expands a simple class name to java.lang.*. - * For example, this converts Object into java/lang/Object. - */ - protected abstract String resolveClassName(String jvmClassName) - throws CompileError; - - /** - * @param name the JVM-internal representation. - * name is not exapnded to java.lang.*. - */ - protected static String toJvmArrayName(String name, int dim) { - if (name == null) - return null; - - if (dim == 0) - return name; - else { - StringBuffer sbuf = new StringBuffer(); - int d = dim; - while (d-- > 0) - sbuf.append('['); - - sbuf.append('L'); - sbuf.append(name); - sbuf.append(';'); - - return sbuf.toString(); - } - } - - protected static String toJvmTypeName(int type, int dim) { - char c = 'I'; - switch(type) { - case BOOLEAN : - c = 'Z'; - break; - case BYTE : - c = 'B'; - break; - case CHAR : - c = 'C'; - break; - case SHORT : - c = 'S'; - break; - case INT : - c = 'I'; - break; - case LONG : - c = 'J'; - break; - case FLOAT : - c = 'F'; - break; - case DOUBLE : - c = 'D'; - break; - case VOID : - c = 'V'; - break; - } - - StringBuffer sbuf = new StringBuffer(); - while (dim-- > 0) - sbuf.append('['); - - sbuf.append(c); - return sbuf.toString(); - } - - public void compileExpr(com.fr.third.javassist.compiler.ast.ASTree expr) throws CompileError { - doTypeCheck(expr); - expr.accept(this); - } - - public boolean compileBooleanExpr(boolean branchIf, com.fr.third.javassist.compiler.ast.ASTree expr) - throws CompileError - { - doTypeCheck(expr); - return booleanExpr(branchIf, expr); - } - - public void doTypeCheck(com.fr.third.javassist.compiler.ast.ASTree expr) throws CompileError { - if (typeChecker != null) - expr.accept(typeChecker); - } - - public void atASTList(com.fr.third.javassist.compiler.ast.ASTList n) throws CompileError { fatal(); } - - public void atPair(com.fr.third.javassist.compiler.ast.Pair n) throws CompileError { fatal(); } - - public void atSymbol(com.fr.third.javassist.compiler.ast.Symbol n) throws CompileError { fatal(); } - - public void atFieldDecl(com.fr.third.javassist.compiler.ast.FieldDecl field) throws CompileError { - field.getInit().accept(this); - } - - public void atMethodDecl(com.fr.third.javassist.compiler.ast.MethodDecl method) throws CompileError { - com.fr.third.javassist.compiler.ast.ASTList mods = method.getModifiers(); - setMaxLocals(1); - while (mods != null) { - com.fr.third.javassist.compiler.ast.Keyword k = (com.fr.third.javassist.compiler.ast.Keyword)mods.head(); - mods = mods.tail(); - if (k.get() == STATIC) { - setMaxLocals(0); - inStaticMethod = true; - } - } - - com.fr.third.javassist.compiler.ast.ASTList params = method.getParams(); - while (params != null) { - atDeclarator((com.fr.third.javassist.compiler.ast.Declarator)params.head()); - params = params.tail(); - } - - com.fr.third.javassist.compiler.ast.Stmnt s = method.getBody(); - atMethodBody(s, method.isConstructor(), - method.getReturn().getType() == VOID); - } - - /** - * @param isCons true if super() must be called. - * false if the method is a class initializer. - */ - public void atMethodBody(com.fr.third.javassist.compiler.ast.Stmnt s, boolean isCons, boolean isVoid) - throws CompileError - { - if (s == null) - return; - - if (isCons && needsSuperCall(s)) - insertDefaultSuperCall(); - - hasReturned = false; - s.accept(this); - if (!hasReturned) - if (isVoid) { - bytecode.addOpcode(com.fr.third.javassist.bytecode.Opcode.RETURN); - hasReturned = true; - } - else - throw new CompileError("no return statement"); - } - - private boolean needsSuperCall(com.fr.third.javassist.compiler.ast.Stmnt body) throws CompileError { - if (body.getOperator() == BLOCK) - body = (com.fr.third.javassist.compiler.ast.Stmnt)body.head(); - - if (body != null && body.getOperator() == EXPR) { - com.fr.third.javassist.compiler.ast.ASTree expr = body.head(); - if (expr != null && expr instanceof com.fr.third.javassist.compiler.ast.Expr - && ((com.fr.third.javassist.compiler.ast.Expr)expr).getOperator() == CALL) { - com.fr.third.javassist.compiler.ast.ASTree target = ((com.fr.third.javassist.compiler.ast.Expr)expr).head(); - if (target instanceof com.fr.third.javassist.compiler.ast.Keyword) { - int token = ((com.fr.third.javassist.compiler.ast.Keyword)target).get(); - return token != THIS && token != SUPER; - } - } - } - - return true; - } - - protected abstract void insertDefaultSuperCall() throws CompileError; - - public void atStmnt(com.fr.third.javassist.compiler.ast.Stmnt st) throws CompileError { - if (st == null) - return; // empty - - int op = st.getOperator(); - if (op == EXPR) { - com.fr.third.javassist.compiler.ast.ASTree expr = st.getLeft(); - doTypeCheck(expr); - if (expr instanceof com.fr.third.javassist.compiler.ast.AssignExpr) - atAssignExpr((com.fr.third.javassist.compiler.ast.AssignExpr)expr, false); - else if (isPlusPlusExpr(expr)) { - com.fr.third.javassist.compiler.ast.Expr e = (com.fr.third.javassist.compiler.ast.Expr)expr; - atPlusPlus(e.getOperator(), e.oprand1(), e, false); - } - else { - expr.accept(this); - if (is2word(exprType, arrayDim)) - bytecode.addOpcode(POP2); - else if (exprType != VOID) - bytecode.addOpcode(POP); - } - } - else if (op == DECL || op == BLOCK) { - com.fr.third.javassist.compiler.ast.ASTList list = st; - while (list != null) { - com.fr.third.javassist.compiler.ast.ASTree h = list.head(); - list = list.tail(); - if (h != null) - h.accept(this); - } - } - else if (op == IF) - atIfStmnt(st); - else if (op == WHILE || op == DO) - atWhileStmnt(st, op == WHILE); - else if (op == FOR) - atForStmnt(st); - else if (op == BREAK || op == CONTINUE) - atBreakStmnt(st, op == BREAK); - else if (op == TokenId.RETURN) - atReturnStmnt(st); - else if (op == THROW) - atThrowStmnt(st); - else if (op == TRY) - atTryStmnt(st); - else if (op == SWITCH) - atSwitchStmnt(st); - else if (op == SYNCHRONIZED) - atSyncStmnt(st); - else { - // LABEL, SWITCH label stament might be null?. - hasReturned = false; - throw new CompileError( - "sorry, not supported statement: TokenId " + op); - } - } - - private void atIfStmnt(com.fr.third.javassist.compiler.ast.Stmnt st) throws CompileError { - com.fr.third.javassist.compiler.ast.ASTree expr = st.head(); - com.fr.third.javassist.compiler.ast.Stmnt thenp = (com.fr.third.javassist.compiler.ast.Stmnt)st.tail().head(); - com.fr.third.javassist.compiler.ast.Stmnt elsep = (com.fr.third.javassist.compiler.ast.Stmnt)st.tail().tail().head(); - compileBooleanExpr(false, expr); - int pc = bytecode.currentPc(); - int pc2 = 0; - bytecode.addIndex(0); // correct later - - hasReturned = false; - if (thenp != null) - thenp.accept(this); - - boolean thenHasReturned = hasReturned; - hasReturned = false; - - if (elsep != null && !thenHasReturned) { - bytecode.addOpcode(com.fr.third.javassist.bytecode.Opcode.GOTO); - pc2 = bytecode.currentPc(); - bytecode.addIndex(0); - } - - bytecode.write16bit(pc, bytecode.currentPc() - pc + 1); - - if (elsep != null) { - elsep.accept(this); - if (!thenHasReturned) - bytecode.write16bit(pc2, bytecode.currentPc() - pc2 + 1); - - hasReturned = thenHasReturned && hasReturned; - } - } - - private void atWhileStmnt(com.fr.third.javassist.compiler.ast.Stmnt st, boolean notDo) throws CompileError { - ArrayList prevBreakList = breakList; - ArrayList prevContList = continueList; - breakList = new ArrayList(); - continueList = new ArrayList(); - - com.fr.third.javassist.compiler.ast.ASTree expr = st.head(); - com.fr.third.javassist.compiler.ast.Stmnt body = (com.fr.third.javassist.compiler.ast.Stmnt)st.tail(); - - int pc = 0; - if (notDo) { - bytecode.addOpcode(com.fr.third.javassist.bytecode.Opcode.GOTO); - pc = bytecode.currentPc(); - bytecode.addIndex(0); - } - - int pc2 = bytecode.currentPc(); - if (body != null) - body.accept(this); - - int pc3 = bytecode.currentPc(); - if (notDo) - bytecode.write16bit(pc, pc3 - pc + 1); - - boolean alwaysBranch = compileBooleanExpr(true, expr) && breakList.size() == 0; - bytecode.addIndex(pc2 - bytecode.currentPc() + 1); - - patchGoto(breakList, bytecode.currentPc()); - patchGoto(continueList, pc3); - continueList = prevContList; - breakList = prevBreakList; - hasReturned = alwaysBranch; - } - - protected void patchGoto(ArrayList list, int targetPc) { - int n = list.size(); - for (int i = 0; i < n; ++i) { - int pc = ((Integer)list.get(i)).intValue(); - bytecode.write16bit(pc, targetPc - pc + 1); - } - } - - private void atForStmnt(com.fr.third.javassist.compiler.ast.Stmnt st) throws CompileError { - ArrayList prevBreakList = breakList; - ArrayList prevContList = continueList; - breakList = new ArrayList(); - continueList = new ArrayList(); - - com.fr.third.javassist.compiler.ast.Stmnt init = (com.fr.third.javassist.compiler.ast.Stmnt)st.head(); - com.fr.third.javassist.compiler.ast.ASTList p = st.tail(); - com.fr.third.javassist.compiler.ast.ASTree expr = p.head(); - p = p.tail(); - com.fr.third.javassist.compiler.ast.Stmnt update = (com.fr.third.javassist.compiler.ast.Stmnt)p.head(); - com.fr.third.javassist.compiler.ast.Stmnt body = (com.fr.third.javassist.compiler.ast.Stmnt)p.tail(); - - if (init != null) - init.accept(this); - - int pc = bytecode.currentPc(); - int pc2 = 0; - if (expr != null) { - compileBooleanExpr(false, expr); - pc2 = bytecode.currentPc(); - bytecode.addIndex(0); - } - - if (body != null) - body.accept(this); - - int pc3 = bytecode.currentPc(); - if (update != null) - update.accept(this); - - bytecode.addOpcode(com.fr.third.javassist.bytecode.Opcode.GOTO); - bytecode.addIndex(pc - bytecode.currentPc() + 1); - - int pc4 = bytecode.currentPc(); - if (expr != null) - bytecode.write16bit(pc2, pc4 - pc2 + 1); - - patchGoto(breakList, pc4); - patchGoto(continueList, pc3); - continueList = prevContList; - breakList = prevBreakList; - hasReturned = false; - } - - private void atSwitchStmnt(com.fr.third.javassist.compiler.ast.Stmnt st) throws CompileError { - compileExpr(st.head()); - - ArrayList prevBreakList = breakList; - breakList = new ArrayList(); - int opcodePc = bytecode.currentPc(); - bytecode.addOpcode(LOOKUPSWITCH); - int npads = 3 - (opcodePc & 3); - while (npads-- > 0) - bytecode.add(0); - - com.fr.third.javassist.compiler.ast.Stmnt body = (com.fr.third.javassist.compiler.ast.Stmnt)st.tail(); - int npairs = 0; - for (com.fr.third.javassist.compiler.ast.ASTList list = body; list != null; list = list.tail()) - if (((com.fr.third.javassist.compiler.ast.Stmnt)list.head()).getOperator() == CASE) - ++npairs; - - // opcodePc2 is the position at which the default jump offset is. - int opcodePc2 = bytecode.currentPc(); - bytecode.addGap(4); - bytecode.add32bit(npairs); - bytecode.addGap(npairs * 8); - - long[] pairs = new long[npairs]; - int ipairs = 0; - int defaultPc = -1; - for (com.fr.third.javassist.compiler.ast.ASTList list = body; list != null; list = list.tail()) { - com.fr.third.javassist.compiler.ast.Stmnt label = (com.fr.third.javassist.compiler.ast.Stmnt)list.head(); - int op = label.getOperator(); - if (op == DEFAULT) - defaultPc = bytecode.currentPc(); - else if (op != CASE) - fatal(); - else { - pairs[ipairs++] - = ((long)computeLabel(label.head()) << 32) + - ((long)(bytecode.currentPc() - opcodePc) & 0xffffffff); - } - - hasReturned = false; - ((com.fr.third.javassist.compiler.ast.Stmnt)label.tail()).accept(this); - } - - Arrays.sort(pairs); - int pc = opcodePc2 + 8; - for (int i = 0; i < npairs; ++i) { - bytecode.write32bit(pc, (int)(pairs[i] >>> 32)); - bytecode.write32bit(pc + 4, (int)pairs[i]); - pc += 8; - } - - if (defaultPc < 0 || breakList.size() > 0) - hasReturned = false; - - int endPc = bytecode.currentPc(); - if (defaultPc < 0) - defaultPc = endPc; - - bytecode.write32bit(opcodePc2, defaultPc - opcodePc); - - patchGoto(breakList, endPc); - breakList = prevBreakList; - } - - private int computeLabel(com.fr.third.javassist.compiler.ast.ASTree expr) throws CompileError { - doTypeCheck(expr); - expr = TypeChecker.stripPlusExpr(expr); - if (expr instanceof com.fr.third.javassist.compiler.ast.IntConst) - return (int)((com.fr.third.javassist.compiler.ast.IntConst)expr).get(); - else - throw new CompileError("bad case label"); - } - - private void atBreakStmnt(com.fr.third.javassist.compiler.ast.Stmnt st, boolean notCont) - throws CompileError - { - if (st.head() != null) - throw new CompileError( - "sorry, not support labeled break or continue"); - - bytecode.addOpcode(com.fr.third.javassist.bytecode.Opcode.GOTO); - Integer pc = new Integer(bytecode.currentPc()); - bytecode.addIndex(0); - if (notCont) - breakList.add(pc); - else - continueList.add(pc); - } - - protected void atReturnStmnt(com.fr.third.javassist.compiler.ast.Stmnt st) throws CompileError { - atReturnStmnt2(st.getLeft()); - } - - protected final void atReturnStmnt2(com.fr.third.javassist.compiler.ast.ASTree result) throws CompileError { - int op; - if (result == null) - op = com.fr.third.javassist.bytecode.Opcode.RETURN; - else { - compileExpr(result); - if (arrayDim > 0) - op = ARETURN; - else { - int type = exprType; - if (type == DOUBLE) - op = DRETURN; - else if (type == FLOAT) - op = FRETURN; - else if (type == LONG) - op = LRETURN; - else if (isRefType(type)) - op = ARETURN; - else - op = IRETURN; - } - } - - for (ReturnHook har = returnHooks; har != null; har = har.next) - if (har.doit(bytecode, op)) { - hasReturned = true; - return; - } - - bytecode.addOpcode(op); - hasReturned = true; - } - - private void atThrowStmnt(com.fr.third.javassist.compiler.ast.Stmnt st) throws CompileError { - com.fr.third.javassist.compiler.ast.ASTree e = st.getLeft(); - compileExpr(e); - if (exprType != CLASS || arrayDim > 0) - throw new CompileError("bad throw statement"); - - bytecode.addOpcode(ATHROW); - hasReturned = true; - } - - /* overridden in MemberCodeGen - */ - protected void atTryStmnt(com.fr.third.javassist.compiler.ast.Stmnt st) throws CompileError { - hasReturned = false; - } - - private void atSyncStmnt(com.fr.third.javassist.compiler.ast.Stmnt st) throws CompileError { - int nbreaks = getListSize(breakList); - int ncontinues = getListSize(continueList); - - compileExpr(st.head()); - if (exprType != CLASS && arrayDim == 0) - throw new CompileError("bad type expr for synchronized block"); - - com.fr.third.javassist.bytecode.Bytecode bc = bytecode; - final int var = bc.getMaxLocals(); - bc.incMaxLocals(1); - bc.addOpcode(DUP); - bc.addAstore(var); - bc.addOpcode(MONITORENTER); - - ReturnHook rh = new ReturnHook(this) { - protected boolean doit(com.fr.third.javassist.bytecode.Bytecode b, int opcode) { - b.addAload(var); - b.addOpcode(MONITOREXIT); - return false; - } - }; - - int pc = bc.currentPc(); - com.fr.third.javassist.compiler.ast.Stmnt body = (com.fr.third.javassist.compiler.ast.Stmnt)st.tail(); - if (body != null) - body.accept(this); - - int pc2 = bc.currentPc(); - int pc3 = 0; - if (!hasReturned) { - rh.doit(bc, 0); // the 2nd arg is ignored. - bc.addOpcode(com.fr.third.javassist.bytecode.Opcode.GOTO); - pc3 = bc.currentPc(); - bc.addIndex(0); - } - - if (pc < pc2) { // if the body is not empty - int pc4 = bc.currentPc(); - rh.doit(bc, 0); // the 2nd arg is ignored. - bc.addOpcode(ATHROW); - bc.addExceptionHandler(pc, pc2, pc4, 0); - } - - if (!hasReturned) - bc.write16bit(pc3, bc.currentPc() - pc3 + 1); - - rh.remove(this); - - if (getListSize(breakList) != nbreaks - || getListSize(continueList) != ncontinues) - throw new CompileError( - "sorry, cannot break/continue in synchronized block"); - } - - private static int getListSize(ArrayList list) { - return list == null ? 0 : list.size(); - } - - private static boolean isPlusPlusExpr(com.fr.third.javassist.compiler.ast.ASTree expr) { - if (expr instanceof com.fr.third.javassist.compiler.ast.Expr) { - int op = ((com.fr.third.javassist.compiler.ast.Expr)expr).getOperator(); - return op == PLUSPLUS || op == MINUSMINUS; - } - - return false; - } - - public void atDeclarator(com.fr.third.javassist.compiler.ast.Declarator d) throws CompileError { - d.setLocalVar(getMaxLocals()); - d.setClassName(resolveClassName(d.getClassName())); - - int size; - if (is2word(d.getType(), d.getArrayDim())) - size = 2; - else - size = 1; - - incMaxLocals(size); - - /* NOTE: Array initializers has not been supported. - */ - com.fr.third.javassist.compiler.ast.ASTree init = d.getInitializer(); - if (init != null) { - doTypeCheck(init); - atVariableAssign(null, '=', null, d, init, false); - } - } - - public abstract void atNewExpr(com.fr.third.javassist.compiler.ast.NewExpr n) throws CompileError; - - public abstract void atArrayInit(com.fr.third.javassist.compiler.ast.ArrayInit init) throws CompileError; - - public void atAssignExpr(com.fr.third.javassist.compiler.ast.AssignExpr expr) throws CompileError { - atAssignExpr(expr, true); - } - - protected void atAssignExpr(com.fr.third.javassist.compiler.ast.AssignExpr expr, boolean doDup) - throws CompileError - { - // =, %=, &=, *=, /=, +=, -=, ^=, |=, <<=, >>=, >>>= - int op = expr.getOperator(); - com.fr.third.javassist.compiler.ast.ASTree left = expr.oprand1(); - com.fr.third.javassist.compiler.ast.ASTree right = expr.oprand2(); - if (left instanceof com.fr.third.javassist.compiler.ast.Variable) - atVariableAssign(expr, op, (com.fr.third.javassist.compiler.ast.Variable)left, - ((com.fr.third.javassist.compiler.ast.Variable)left).getDeclarator(), - right, doDup); - else { - if (left instanceof com.fr.third.javassist.compiler.ast.Expr) { - com.fr.third.javassist.compiler.ast.Expr e = (com.fr.third.javassist.compiler.ast.Expr)left; - if (e.getOperator() == ARRAY) { - atArrayAssign(expr, op, (com.fr.third.javassist.compiler.ast.Expr)left, right, doDup); - return; - } - } - - atFieldAssign(expr, op, left, right, doDup); - } - } - - protected static void badAssign(com.fr.third.javassist.compiler.ast.Expr expr) throws CompileError { - String msg; - if (expr == null) - msg = "incompatible type for assignment"; - else - msg = "incompatible type for " + expr.getName(); - - throw new CompileError(msg); - } - - /* op is either =, %=, &=, *=, /=, +=, -=, ^=, |=, <<=, >>=, or >>>=. - * - * expr and var can be null. - */ - private void atVariableAssign(com.fr.third.javassist.compiler.ast.Expr expr, int op, com.fr.third.javassist.compiler.ast.Variable var, - com.fr.third.javassist.compiler.ast.Declarator d, com.fr.third.javassist.compiler.ast.ASTree right, - boolean doDup) throws CompileError - { - int varType = d.getType(); - int varArray = d.getArrayDim(); - String varClass = d.getClassName(); - int varNo = getLocalVar(d); - - if (op != '=') - atVariable(var); - - // expr is null if the caller is atDeclarator(). - if (expr == null && right instanceof com.fr.third.javassist.compiler.ast.ArrayInit) - atArrayVariableAssign((com.fr.third.javassist.compiler.ast.ArrayInit)right, varType, varArray, varClass); - else - atAssignCore(expr, op, right, varType, varArray, varClass); - - if (doDup) - if (is2word(varType, varArray)) - bytecode.addOpcode(DUP2); - else - bytecode.addOpcode(DUP); - - if (varArray > 0) - bytecode.addAstore(varNo); - else if (varType == DOUBLE) - bytecode.addDstore(varNo); - else if (varType == FLOAT) - bytecode.addFstore(varNo); - else if (varType == LONG) - bytecode.addLstore(varNo); - else if (isRefType(varType)) - bytecode.addAstore(varNo); - else - bytecode.addIstore(varNo); - - exprType = varType; - arrayDim = varArray; - className = varClass; - } - - protected abstract void atArrayVariableAssign(com.fr.third.javassist.compiler.ast.ArrayInit init, - int varType, int varArray, String varClass) throws CompileError; - - private void atArrayAssign(com.fr.third.javassist.compiler.ast.Expr expr, int op, com.fr.third.javassist.compiler.ast.Expr array, - com.fr.third.javassist.compiler.ast.ASTree right, boolean doDup) throws CompileError - { - arrayAccess(array.oprand1(), array.oprand2()); - - if (op != '=') { - bytecode.addOpcode(DUP2); - bytecode.addOpcode(getArrayReadOp(exprType, arrayDim)); - } - - int aType = exprType; - int aDim = arrayDim; - String cname = className; - - atAssignCore(expr, op, right, aType, aDim, cname); - - if (doDup) - if (is2word(aType, aDim)) - bytecode.addOpcode(DUP2_X2); - else - bytecode.addOpcode(DUP_X2); - - bytecode.addOpcode(getArrayWriteOp(aType, aDim)); - exprType = aType; - arrayDim = aDim; - className = cname; - } - - protected abstract void atFieldAssign(com.fr.third.javassist.compiler.ast.Expr expr, int op, com.fr.third.javassist.compiler.ast.ASTree left, - com.fr.third.javassist.compiler.ast.ASTree right, boolean doDup) throws CompileError; - - protected void atAssignCore(com.fr.third.javassist.compiler.ast.Expr expr, int op, com.fr.third.javassist.compiler.ast.ASTree right, - int type, int dim, String cname) - throws CompileError - { - if (op == PLUS_E && dim == 0 && type == CLASS) - atStringPlusEq(expr, type, dim, cname, right); - else { - right.accept(this); - if (invalidDim(exprType, arrayDim, className, type, dim, cname, - false) || (op != '=' && dim > 0)) - badAssign(expr); - - if (op != '=') { - int token = assignOps[op - MOD_E]; - int k = lookupBinOp(token); - if (k < 0) - fatal(); - - atArithBinExpr(expr, token, k, type); - } - } - - if (op != '=' || (dim == 0 && !isRefType(type))) - atNumCastExpr(exprType, type); - - // type check should be done here. - } - - private void atStringPlusEq(com.fr.third.javassist.compiler.ast.Expr expr, int type, int dim, String cname, - com.fr.third.javassist.compiler.ast.ASTree right) - throws CompileError - { - if (!jvmJavaLangString.equals(cname)) - badAssign(expr); - - convToString(type, dim); // the value might be null. - right.accept(this); - convToString(exprType, arrayDim); - bytecode.addInvokevirtual(javaLangString, "concat", - "(Ljava/lang/String;)Ljava/lang/String;"); - exprType = CLASS; - arrayDim = 0; - className = jvmJavaLangString; - } - - private boolean invalidDim(int srcType, int srcDim, String srcClass, - int destType, int destDim, String destClass, - boolean isCast) - { - if (srcDim != destDim) - if (srcType == NULL) - return false; - else if (destDim == 0 && destType == CLASS - && jvmJavaLangObject.equals(destClass)) - return false; - else if (isCast && srcDim == 0 && srcType == CLASS - && jvmJavaLangObject.equals(srcClass)) - return false; - else - return true; - - return false; - } - - public void atCondExpr(com.fr.third.javassist.compiler.ast.CondExpr expr) throws CompileError { - booleanExpr(false, expr.condExpr()); - int pc = bytecode.currentPc(); - bytecode.addIndex(0); // correct later - expr.thenExpr().accept(this); - int dim1 = arrayDim; - bytecode.addOpcode(com.fr.third.javassist.bytecode.Opcode.GOTO); - int pc2 = bytecode.currentPc(); - bytecode.addIndex(0); - bytecode.write16bit(pc, bytecode.currentPc() - pc + 1); - expr.elseExpr().accept(this); - if (dim1 != arrayDim) - throw new CompileError("type mismatch in ?:"); - - bytecode.write16bit(pc2, bytecode.currentPc() - pc2 + 1); - } - - static final int[] binOp = { - '+', DADD, FADD, LADD, IADD, - '-', DSUB, FSUB, LSUB, ISUB, - '*', DMUL, FMUL, LMUL, IMUL, - '/', DDIV, FDIV, LDIV, IDIV, - '%', DREM, FREM, LREM, IREM, - '|', NOP, NOP, LOR, IOR, - '^', NOP, NOP, LXOR, IXOR, - '&', NOP, NOP, LAND, IAND, - LSHIFT, NOP, NOP, LSHL, ISHL, - RSHIFT, NOP, NOP, LSHR, ISHR, - ARSHIFT, NOP, NOP, LUSHR, IUSHR }; - - static int lookupBinOp(int token) { - int[] code = binOp; - int s = code.length; - for (int k = 0; k < s; k = k + 5) - if (code[k] == token) - return k; - - return -1; - } - - public void atBinExpr(com.fr.third.javassist.compiler.ast.BinExpr expr) throws CompileError { - int token = expr.getOperator(); - - /* arithmetic operators: +, -, *, /, %, |, ^, &, <<, >>, >>> - */ - int k = lookupBinOp(token); - if (k >= 0) { - expr.oprand1().accept(this); - com.fr.third.javassist.compiler.ast.ASTree right = expr.oprand2(); - if (right == null) - return; // see TypeChecker.atBinExpr(). - - int type1 = exprType; - int dim1 = arrayDim; - String cname1 = className; - right.accept(this); - if (dim1 != arrayDim) - throw new CompileError("incompatible array types"); - - if (token == '+' && dim1 == 0 - && (type1 == CLASS || exprType == CLASS)) - atStringConcatExpr(expr, type1, dim1, cname1); - else - atArithBinExpr(expr, token, k, type1); - } - else { - /* equation: &&, ||, ==, !=, <=, >=, <, > - */ - booleanExpr(true, expr); - bytecode.addIndex(7); - bytecode.addIconst(0); // false - bytecode.addOpcode(com.fr.third.javassist.bytecode.Opcode.GOTO); - bytecode.addIndex(4); - bytecode.addIconst(1); // true - } - } - - /* arrayDim values of the two oprands must be equal. - * If an oprand type is not a numeric type, this method - * throws an exception. - */ - private void atArithBinExpr(com.fr.third.javassist.compiler.ast.Expr expr, int token, - int index, int type1) throws CompileError - { - if (arrayDim != 0) - badTypes(expr); - - int type2 = exprType; - if (token == LSHIFT || token == RSHIFT || token == ARSHIFT) - if (type2 == INT || type2 == SHORT - || type2 == CHAR || type2 == BYTE) - exprType = type1; - else - badTypes(expr); - else - convertOprandTypes(type1, type2, expr); - - int p = typePrecedence(exprType); - if (p >= 0) { - int op = binOp[index + p + 1]; - if (op != NOP) { - if (p == P_INT && exprType != BOOLEAN) - exprType = INT; // type1 may be BYTE, ... - - bytecode.addOpcode(op); - return; - } - } - - badTypes(expr); - } - - private void atStringConcatExpr(com.fr.third.javassist.compiler.ast.Expr expr, int type1, int dim1, - String cname1) throws CompileError - { - int type2 = exprType; - int dim2 = arrayDim; - boolean type2Is2 = is2word(type2, dim2); - boolean type2IsString - = (type2 == CLASS && jvmJavaLangString.equals(className)); - - if (type2Is2) - convToString(type2, dim2); - - if (is2word(type1, dim1)) { - bytecode.addOpcode(DUP_X2); - bytecode.addOpcode(POP); - } - else - bytecode.addOpcode(SWAP); - - // even if type1 is String, the left operand might be null. - convToString(type1, dim1); - bytecode.addOpcode(SWAP); - - if (!type2Is2 && !type2IsString) - convToString(type2, dim2); - - bytecode.addInvokevirtual(javaLangString, "concat", - "(Ljava/lang/String;)Ljava/lang/String;"); - exprType = CLASS; - arrayDim = 0; - className = jvmJavaLangString; - } - - private void convToString(int type, int dim) throws CompileError { - final String method = "valueOf"; - - if (isRefType(type) || dim > 0) - bytecode.addInvokestatic(javaLangString, method, - "(Ljava/lang/Object;)Ljava/lang/String;"); - else if (type == DOUBLE) - bytecode.addInvokestatic(javaLangString, method, - "(D)Ljava/lang/String;"); - else if (type == FLOAT) - bytecode.addInvokestatic(javaLangString, method, - "(F)Ljava/lang/String;"); - else if (type == LONG) - bytecode.addInvokestatic(javaLangString, method, - "(J)Ljava/lang/String;"); - else if (type == BOOLEAN) - bytecode.addInvokestatic(javaLangString, method, - "(Z)Ljava/lang/String;"); - else if (type == CHAR) - bytecode.addInvokestatic(javaLangString, method, - "(C)Ljava/lang/String;"); - else if (type == VOID) - throw new CompileError("void type expression"); - else /* INT, BYTE, SHORT */ - bytecode.addInvokestatic(javaLangString, method, - "(I)Ljava/lang/String;"); - } - - /* Produces the opcode to branch if the condition is true. - * The oprand is not produced. - * - * @return true if the compiled code is GOTO (always branch). - */ - private boolean booleanExpr(boolean branchIf, com.fr.third.javassist.compiler.ast.ASTree expr) - throws CompileError - { - boolean isAndAnd; - int op = getCompOperator(expr); - if (op == EQ) { // ==, !=, ... - com.fr.third.javassist.compiler.ast.BinExpr bexpr = (com.fr.third.javassist.compiler.ast.BinExpr)expr; - int type1 = compileOprands(bexpr); - // here, arrayDim might represent the array dim. of the left oprand - // if the right oprand is NULL. - compareExpr(branchIf, bexpr.getOperator(), type1, bexpr); - } - else if (op == '!') - booleanExpr(!branchIf, ((com.fr.third.javassist.compiler.ast.Expr)expr).oprand1()); - else if ((isAndAnd = (op == ANDAND)) || op == OROR) { - com.fr.third.javassist.compiler.ast.BinExpr bexpr = (com.fr.third.javassist.compiler.ast.BinExpr)expr; - booleanExpr(!isAndAnd, bexpr.oprand1()); - int pc = bytecode.currentPc(); - bytecode.addIndex(0); // correct later - - booleanExpr(isAndAnd, bexpr.oprand2()); - bytecode.write16bit(pc, bytecode.currentPc() - pc + 3); - if (branchIf != isAndAnd) { - bytecode.addIndex(6); // skip GOTO instruction - bytecode.addOpcode(com.fr.third.javassist.bytecode.Opcode.GOTO); - } - } - else if (isAlwaysBranch(expr, branchIf)) { - bytecode.addOpcode(com.fr.third.javassist.bytecode.Opcode.GOTO); - return true; // always branch - } - else { // others - expr.accept(this); - if (exprType != BOOLEAN || arrayDim != 0) - throw new CompileError("boolean expr is required"); - - bytecode.addOpcode(branchIf ? IFNE : IFEQ); - } - - exprType = BOOLEAN; - arrayDim = 0; - return false; - } - - - private static boolean isAlwaysBranch(com.fr.third.javassist.compiler.ast.ASTree expr, boolean branchIf) { - if (expr instanceof com.fr.third.javassist.compiler.ast.Keyword) { - int t = ((com.fr.third.javassist.compiler.ast.Keyword)expr).get(); - return branchIf ? t == TRUE : t == FALSE; - } - - return false; - } - - static int getCompOperator(com.fr.third.javassist.compiler.ast.ASTree expr) throws CompileError { - if (expr instanceof com.fr.third.javassist.compiler.ast.Expr) { - com.fr.third.javassist.compiler.ast.Expr bexpr = (com.fr.third.javassist.compiler.ast.Expr)expr; - int token = bexpr.getOperator(); - if (token == '!') - return '!'; - else if ((bexpr instanceof com.fr.third.javassist.compiler.ast.BinExpr) - && token != OROR && token != ANDAND - && token != '&' && token != '|') - return EQ; // ==, !=, ... - else - return token; - } - - return ' '; // others - } - - private int compileOprands(com.fr.third.javassist.compiler.ast.BinExpr expr) throws CompileError { - expr.oprand1().accept(this); - int type1 = exprType; - int dim1 = arrayDim; - expr.oprand2().accept(this); - if (dim1 != arrayDim) - if (type1 != NULL && exprType != NULL) - throw new CompileError("incompatible array types"); - else if (exprType == NULL) - arrayDim = dim1; - - if (type1 == NULL) - return exprType; - else - return type1; - } - - private static final int ifOp[] = { EQ, IF_ICMPEQ, IF_ICMPNE, - NEQ, IF_ICMPNE, IF_ICMPEQ, - LE, IF_ICMPLE, IF_ICMPGT, - GE, IF_ICMPGE, IF_ICMPLT, - '<', IF_ICMPLT, IF_ICMPGE, - '>', IF_ICMPGT, IF_ICMPLE }; - - private static final int ifOp2[] = { EQ, IFEQ, IFNE, - NEQ, IFNE, IFEQ, - LE, IFLE, IFGT, - GE, IFGE, IFLT, - '<', IFLT, IFGE, - '>', IFGT, IFLE }; - - /* Produces the opcode to branch if the condition is true. - * The oprands are not produced. - * - * Parameter expr - compare expression ==, !=, <=, >=, <, > - */ - private void compareExpr(boolean branchIf, - int token, int type1, com.fr.third.javassist.compiler.ast.BinExpr expr) - throws CompileError - { - if (arrayDim == 0) - convertOprandTypes(type1, exprType, expr); - - int p = typePrecedence(exprType); - if (p == P_OTHER || arrayDim > 0) - if (token == EQ) - bytecode.addOpcode(branchIf ? IF_ACMPEQ : IF_ACMPNE); - else if (token == NEQ) - bytecode.addOpcode(branchIf ? IF_ACMPNE : IF_ACMPEQ); - else - badTypes(expr); - else - if (p == P_INT) { - int op[] = ifOp; - for (int i = 0; i < op.length; i += 3) - if (op[i] == token) { - bytecode.addOpcode(op[i + (branchIf ? 1 : 2)]); - return; - } - - badTypes(expr); - } - else { - if (p == P_DOUBLE) - if (token == '<' || token == LE) - bytecode.addOpcode(DCMPG); - else - bytecode.addOpcode(DCMPL); - else if (p == P_FLOAT) - if (token == '<' || token == LE) - bytecode.addOpcode(FCMPG); - else - bytecode.addOpcode(FCMPL); - else if (p == P_LONG) - bytecode.addOpcode(LCMP); // 1: >, 0: =, -1: < - else - fatal(); - - int[] op = ifOp2; - for (int i = 0; i < op.length; i += 3) - if (op[i] == token) { - bytecode.addOpcode(op[i + (branchIf ? 1 : 2)]); - return; - } - - badTypes(expr); - } - } - - protected static void badTypes(com.fr.third.javassist.compiler.ast.Expr expr) throws CompileError { - throw new CompileError("invalid types for " + expr.getName()); - } - - private static final int P_DOUBLE = 0; - private static final int P_FLOAT = 1; - private static final int P_LONG = 2; - private static final int P_INT = 3; - private static final int P_OTHER = -1; - - protected static boolean isRefType(int type) { - return type == CLASS || type == NULL; - } - - private static int typePrecedence(int type) { - if (type == DOUBLE) - return P_DOUBLE; - else if (type == FLOAT) - return P_FLOAT; - else if (type == LONG) - return P_LONG; - else if (isRefType(type)) - return P_OTHER; - else if (type == VOID) - return P_OTHER; // this is wrong, but ... - else - return P_INT; // BOOLEAN, BYTE, CHAR, SHORT, INT - } - - // used in TypeChecker. - static boolean isP_INT(int type) { - return typePrecedence(type) == P_INT; - } - - // used in TypeChecker. - static boolean rightIsStrong(int type1, int type2) { - int type1_p = typePrecedence(type1); - int type2_p = typePrecedence(type2); - return type1_p >= 0 && type2_p >= 0 && type1_p > type2_p; - } - - private static final int[] castOp = { - /* D F L I */ - /* double */ NOP, D2F, D2L, D2I, - /* float */ F2D, NOP, F2L, F2I, - /* long */ L2D, L2F, NOP, L2I, - /* other */ I2D, I2F, I2L, NOP }; - - /* do implicit type conversion. - * arrayDim values of the two oprands must be zero. - */ - private void convertOprandTypes(int type1, int type2, com.fr.third.javassist.compiler.ast.Expr expr) - throws CompileError - { - boolean rightStrong; - int type1_p = typePrecedence(type1); - int type2_p = typePrecedence(type2); - - if (type2_p < 0 && type1_p < 0) // not primitive types - return; - - if (type2_p < 0 || type1_p < 0) // either is not a primitive type - badTypes(expr); - - int op, result_type; - if (type1_p <= type2_p) { - rightStrong = false; - exprType = type1; - op = castOp[type2_p * 4 + type1_p]; - result_type = type1_p; - } - else { - rightStrong = true; - op = castOp[type1_p * 4 + type2_p]; - result_type = type2_p; - } - - if (rightStrong) { - if (result_type == P_DOUBLE || result_type == P_LONG) { - if (type1_p == P_DOUBLE || type1_p == P_LONG) - bytecode.addOpcode(DUP2_X2); - else - bytecode.addOpcode(DUP2_X1); - - bytecode.addOpcode(POP2); - bytecode.addOpcode(op); - bytecode.addOpcode(DUP2_X2); - bytecode.addOpcode(POP2); - } - else if (result_type == P_FLOAT) { - if (type1_p == P_LONG) { - bytecode.addOpcode(DUP_X2); - bytecode.addOpcode(POP); - } - else - bytecode.addOpcode(SWAP); - - bytecode.addOpcode(op); - bytecode.addOpcode(SWAP); - } - else - fatal(); - } - else if (op != NOP) - bytecode.addOpcode(op); - } - - public void atCastExpr(com.fr.third.javassist.compiler.ast.CastExpr expr) throws CompileError { - String cname = resolveClassName(expr.getClassName()); - String toClass = checkCastExpr(expr, cname); - int srcType = exprType; - exprType = expr.getType(); - arrayDim = expr.getArrayDim(); - className = cname; - if (toClass == null) - atNumCastExpr(srcType, exprType); // built-in type - else - bytecode.addCheckcast(toClass); - } - - public void atInstanceOfExpr(com.fr.third.javassist.compiler.ast.InstanceOfExpr expr) throws CompileError { - String cname = resolveClassName(expr.getClassName()); - String toClass = checkCastExpr(expr, cname); - bytecode.addInstanceof(toClass); - exprType = BOOLEAN; - arrayDim = 0; - } - - private String checkCastExpr(com.fr.third.javassist.compiler.ast.CastExpr expr, String name) - throws CompileError - { - final String msg = "invalid cast"; - com.fr.third.javassist.compiler.ast.ASTree oprand = expr.getOprand(); - int dim = expr.getArrayDim(); - int type = expr.getType(); - oprand.accept(this); - int srcType = exprType; - if (invalidDim(srcType, arrayDim, className, type, dim, name, true) - || srcType == VOID || type == VOID) - throw new CompileError(msg); - - if (type == CLASS) { - if (!isRefType(srcType)) - throw new CompileError(msg); - - return toJvmArrayName(name, dim); - } - else - if (dim > 0) - return toJvmTypeName(type, dim); - else - return null; // built-in type - } - - void atNumCastExpr(int srcType, int destType) - throws CompileError - { - if (srcType == destType) - return; - - int op, op2; - int stype = typePrecedence(srcType); - int dtype = typePrecedence(destType); - if (0 <= stype && stype < 3) - op = castOp[stype * 4 + dtype]; - else - op = NOP; - - if (destType == DOUBLE) - op2 = I2D; - else if (destType == FLOAT) - op2 = I2F; - else if (destType == LONG) - op2 = I2L; - else if (destType == SHORT) - op2 = I2S; - else if (destType == CHAR) - op2 = I2C; - else if (destType == BYTE) - op2 = I2B; - else - op2 = NOP; - - if (op != NOP) - bytecode.addOpcode(op); - - if (op == NOP || op == L2I || op == F2I || op == D2I) - if (op2 != NOP) - bytecode.addOpcode(op2); - } - - public void atExpr(com.fr.third.javassist.compiler.ast.Expr expr) throws CompileError { - // array access, member access, - // (unary) +, (unary) -, ++, --, !, ~ - - int token = expr.getOperator(); - com.fr.third.javassist.compiler.ast.ASTree oprand = expr.oprand1(); - if (token == '.') { - String member = ((com.fr.third.javassist.compiler.ast.Symbol)expr.oprand2()).get(); - if (member.equals("class")) - atClassObject(expr); // .class - else - atFieldRead(expr); - } - else if (token == MEMBER) { // field read - /* MEMBER ('#') is an extension by Javassist. - * The compiler internally uses # for compiling .class - * expressions such as "int.class". - */ - atFieldRead(expr); - } - else if (token == ARRAY) - atArrayRead(oprand, expr.oprand2()); - else if (token == PLUSPLUS || token == MINUSMINUS) - atPlusPlus(token, oprand, expr, true); - else if (token == '!') { - booleanExpr(false, expr); - bytecode.addIndex(7); - bytecode.addIconst(1); - bytecode.addOpcode(com.fr.third.javassist.bytecode.Opcode.GOTO); - bytecode.addIndex(4); - bytecode.addIconst(0); - } - else if (token == CALL) // method call - fatal(); - else { - expr.oprand1().accept(this); - int type = typePrecedence(exprType); - if (arrayDim > 0) - badType(expr); - - if (token == '-') { - if (type == P_DOUBLE) - bytecode.addOpcode(DNEG); - else if (type == P_FLOAT) - bytecode.addOpcode(FNEG); - else if (type == P_LONG) - bytecode.addOpcode(LNEG); - else if (type == P_INT) { - bytecode.addOpcode(INEG); - exprType = INT; // type may be BYTE, ... - } - else - badType(expr); - } - else if (token == '~') { - if (type == P_INT) { - bytecode.addIconst(-1); - bytecode.addOpcode(IXOR); - exprType = INT; // type may be BYTE. ... - } - else if (type == P_LONG) { - bytecode.addLconst(-1); - bytecode.addOpcode(LXOR); - } - else - badType(expr); - - } - else if (token == '+') { - if (type == P_OTHER) - badType(expr); - - // do nothing. ignore. - } - else - fatal(); - } - } - - protected static void badType(com.fr.third.javassist.compiler.ast.Expr expr) throws CompileError { - throw new CompileError("invalid type for " + expr.getName()); - } - - public abstract void atCallExpr(com.fr.third.javassist.compiler.ast.CallExpr expr) throws CompileError; - - protected abstract void atFieldRead(com.fr.third.javassist.compiler.ast.ASTree expr) throws CompileError; - - public void atClassObject(com.fr.third.javassist.compiler.ast.Expr expr) throws CompileError { - com.fr.third.javassist.compiler.ast.ASTree op1 = expr.oprand1(); - if (!(op1 instanceof com.fr.third.javassist.compiler.ast.Symbol)) - throw new CompileError("fatal error: badly parsed .class expr"); - - String cname = ((com.fr.third.javassist.compiler.ast.Symbol)op1).get(); - if (cname.startsWith("[")) { - int i = cname.indexOf("[L"); - if (i >= 0) { - String name = cname.substring(i + 2, cname.length() - 1); - String name2 = resolveClassName(name); - if (!name.equals(name2)) { - /* For example, to obtain String[].class, - * "[Ljava.lang.String;" (not "[Ljava/lang/String"!) - * must be passed to Class.forName(). - */ - name2 = MemberResolver.jvmToJavaName(name2); - StringBuffer sbuf = new StringBuffer(); - while (i-- >= 0) - sbuf.append('['); - - sbuf.append('L').append(name2).append(';'); - cname = sbuf.toString(); - } - } - } - else { - cname = resolveClassName(MemberResolver.javaToJvmName(cname)); - cname = MemberResolver.jvmToJavaName(cname); - } - - atClassObject2(cname); - exprType = CLASS; - arrayDim = 0; - className = "java/lang/Class"; - } - - /* MemberCodeGen overrides this method. - */ - protected void atClassObject2(String cname) throws CompileError { - int start = bytecode.currentPc(); - bytecode.addLdc(cname); - bytecode.addInvokestatic("java.lang.Class", "forName", - "(Ljava/lang/String;)Ljava/lang/Class;"); - int end = bytecode.currentPc(); - bytecode.addOpcode(Opcode.GOTO); - int pc = bytecode.currentPc(); - bytecode.addIndex(0); // correct later - - bytecode.addExceptionHandler(start, end, bytecode.currentPc(), - "java.lang.ClassNotFoundException"); - - /* -- the following code is for inlining a call to DotClass.fail(). - - int var = getMaxLocals(); - incMaxLocals(1); - bytecode.growStack(1); - bytecode.addAstore(var); - - bytecode.addNew("java.lang.NoClassDefFoundError"); - bytecode.addOpcode(DUP); - bytecode.addAload(var); - bytecode.addInvokevirtual("java.lang.ClassNotFoundException", - "getMessage", "()Ljava/lang/String;"); - bytecode.addInvokespecial("java.lang.NoClassDefFoundError", "", - "(Ljava/lang/String;)V"); - */ - - bytecode.growStack(1); - bytecode.addInvokestatic("javassist.runtime.DotClass", "fail", - "(Ljava/lang/ClassNotFoundException;)" - + "Ljava/lang/NoClassDefFoundError;"); - bytecode.addOpcode(ATHROW); - bytecode.write16bit(pc, bytecode.currentPc() - pc + 1); - } - - public void atArrayRead(com.fr.third.javassist.compiler.ast.ASTree array, com.fr.third.javassist.compiler.ast.ASTree index) - throws CompileError - { - arrayAccess(array, index); - bytecode.addOpcode(getArrayReadOp(exprType, arrayDim)); - } - - protected void arrayAccess(com.fr.third.javassist.compiler.ast.ASTree array, com.fr.third.javassist.compiler.ast.ASTree index) - throws CompileError - { - array.accept(this); - int type = exprType; - int dim = arrayDim; - if (dim == 0) - throw new CompileError("bad array access"); - - String cname = className; - - index.accept(this); - if (typePrecedence(exprType) != P_INT || arrayDim > 0) - throw new CompileError("bad array index"); - - exprType = type; - arrayDim = dim - 1; - className = cname; - } - - protected static int getArrayReadOp(int type, int dim) { - if (dim > 0) - return AALOAD; - - switch (type) { - case DOUBLE : - return DALOAD; - case FLOAT : - return FALOAD; - case LONG : - return LALOAD; - case INT : - return IALOAD; - case SHORT : - return SALOAD; - case CHAR : - return CALOAD; - case BYTE : - case BOOLEAN : - return BALOAD; - default : - return AALOAD; - } - } - - protected static int getArrayWriteOp(int type, int dim) { - if (dim > 0) - return AASTORE; - - switch (type) { - case DOUBLE : - return DASTORE; - case FLOAT : - return FASTORE; - case LONG : - return LASTORE; - case INT : - return IASTORE; - case SHORT : - return SASTORE; - case CHAR : - return CASTORE; - case BYTE : - case BOOLEAN : - return BASTORE; - default : - return AASTORE; - } - } - - private void atPlusPlus(int token, com.fr.third.javassist.compiler.ast.ASTree oprand, com.fr.third.javassist.compiler.ast.Expr expr, - boolean doDup) throws CompileError - { - boolean isPost = oprand == null; // ++i or i++? - if (isPost) - oprand = expr.oprand2(); - - if (oprand instanceof com.fr.third.javassist.compiler.ast.Variable) { - com.fr.third.javassist.compiler.ast.Declarator d = ((com.fr.third.javassist.compiler.ast.Variable)oprand).getDeclarator(); - int t = exprType = d.getType(); - arrayDim = d.getArrayDim(); - int var = getLocalVar(d); - if (arrayDim > 0) - badType(expr); - - if (t == DOUBLE) { - bytecode.addDload(var); - if (doDup && isPost) - bytecode.addOpcode(DUP2); - - bytecode.addDconst(1.0); - bytecode.addOpcode(token == PLUSPLUS ? DADD : DSUB); - if (doDup && !isPost) - bytecode.addOpcode(DUP2); - - bytecode.addDstore(var); - } - else if (t == LONG) { - bytecode.addLload(var); - if (doDup && isPost) - bytecode.addOpcode(DUP2); - - bytecode.addLconst((long)1); - bytecode.addOpcode(token == PLUSPLUS ? LADD : LSUB); - if (doDup && !isPost) - bytecode.addOpcode(DUP2); - - bytecode.addLstore(var); - } - else if (t == FLOAT) { - bytecode.addFload(var); - if (doDup && isPost) - bytecode.addOpcode(DUP); - - bytecode.addFconst(1.0f); - bytecode.addOpcode(token == PLUSPLUS ? FADD : FSUB); - if (doDup && !isPost) - bytecode.addOpcode(DUP); - - bytecode.addFstore(var); - } - else if (t == BYTE || t == CHAR || t == SHORT || t == INT) { - if (doDup && isPost) - bytecode.addIload(var); - - int delta = token == PLUSPLUS ? 1 : -1; - if (var > 0xff) { - bytecode.addOpcode(WIDE); - bytecode.addOpcode(IINC); - bytecode.addIndex(var); - bytecode.addIndex(delta); - } - else { - bytecode.addOpcode(IINC); - bytecode.add(var); - bytecode.add(delta); - } - - if (doDup && !isPost) - bytecode.addIload(var); - } - else - badType(expr); - } - else { - if (oprand instanceof com.fr.third.javassist.compiler.ast.Expr) { - com.fr.third.javassist.compiler.ast.Expr e = (com.fr.third.javassist.compiler.ast.Expr)oprand; - if (e.getOperator() == ARRAY) { - atArrayPlusPlus(token, isPost, e, doDup); - return; - } - } - - atFieldPlusPlus(token, isPost, oprand, expr, doDup); - } - } - - public void atArrayPlusPlus(int token, boolean isPost, - com.fr.third.javassist.compiler.ast.Expr expr, boolean doDup) throws CompileError - { - arrayAccess(expr.oprand1(), expr.oprand2()); - int t = exprType; - int dim = arrayDim; - if (dim > 0) - badType(expr); - - bytecode.addOpcode(DUP2); - bytecode.addOpcode(getArrayReadOp(t, arrayDim)); - int dup_code = is2word(t, dim) ? DUP2_X2 : DUP_X2; - atPlusPlusCore(dup_code, doDup, token, isPost, expr); - bytecode.addOpcode(getArrayWriteOp(t, dim)); - } - - protected void atPlusPlusCore(int dup_code, boolean doDup, - int token, boolean isPost, - com.fr.third.javassist.compiler.ast.Expr expr) throws CompileError - { - int t = exprType; - - if (doDup && isPost) - bytecode.addOpcode(dup_code); - - if (t == INT || t == BYTE || t == CHAR || t == SHORT) { - bytecode.addIconst(1); - bytecode.addOpcode(token == PLUSPLUS ? IADD : ISUB); - exprType = INT; - } - else if (t == LONG) { - bytecode.addLconst((long)1); - bytecode.addOpcode(token == PLUSPLUS ? LADD : LSUB); - } - else if (t == FLOAT) { - bytecode.addFconst(1.0f); - bytecode.addOpcode(token == PLUSPLUS ? FADD : FSUB); - } - else if (t == DOUBLE) { - bytecode.addDconst(1.0); - bytecode.addOpcode(token == PLUSPLUS ? DADD : DSUB); - } - else - badType(expr); - - if (doDup && !isPost) - bytecode.addOpcode(dup_code); - } - - protected abstract void atFieldPlusPlus(int token, boolean isPost, - com.fr.third.javassist.compiler.ast.ASTree oprand, com.fr.third.javassist.compiler.ast.Expr expr, boolean doDup) throws CompileError; - - public abstract void atMember(com.fr.third.javassist.compiler.ast.Member n) throws CompileError; - - public void atVariable(com.fr.third.javassist.compiler.ast.Variable v) throws CompileError { - com.fr.third.javassist.compiler.ast.Declarator d = v.getDeclarator(); - exprType = d.getType(); - arrayDim = d.getArrayDim(); - className = d.getClassName(); - int var = getLocalVar(d); - - if (arrayDim > 0) - bytecode.addAload(var); - else - switch (exprType) { - case CLASS : - bytecode.addAload(var); - break; - case LONG : - bytecode.addLload(var); - break; - case FLOAT : - bytecode.addFload(var); - break; - case DOUBLE : - bytecode.addDload(var); - break; - default : // BOOLEAN, BYTE, CHAR, SHORT, INT - bytecode.addIload(var); - break; - } - } - - public void atKeyword(com.fr.third.javassist.compiler.ast.Keyword k) throws CompileError { - arrayDim = 0; - int token = k.get(); - switch (token) { - case TRUE : - bytecode.addIconst(1); - exprType = BOOLEAN; - break; - case FALSE : - bytecode.addIconst(0); - exprType = BOOLEAN; - break; - case NULL : - bytecode.addOpcode(ACONST_NULL); - exprType = NULL; - break; - case THIS : - case SUPER : - if (inStaticMethod) - throw new CompileError("not-available: " - + (token == THIS ? "this" : "super")); - - bytecode.addAload(0); - exprType = CLASS; - if (token == THIS) - className = getThisName(); - else - className = getSuperName(); - break; - default : - fatal(); - } - } - - public void atStringL(com.fr.third.javassist.compiler.ast.StringL s) throws CompileError { - exprType = CLASS; - arrayDim = 0; - className = jvmJavaLangString; - bytecode.addLdc(s.get()); - } - - public void atIntConst(com.fr.third.javassist.compiler.ast.IntConst i) throws CompileError { - arrayDim = 0; - long value = i.get(); - int type = i.getType(); - if (type == IntConstant || type == CharConstant) { - exprType = (type == IntConstant ? INT : CHAR); - bytecode.addIconst((int)value); - } - else { - exprType = LONG; - bytecode.addLconst(value); - } - } - - public void atDoubleConst(DoubleConst d) throws CompileError { - arrayDim = 0; - if (d.getType() == DoubleConstant) { - exprType = DOUBLE; - bytecode.addDconst(d.get()); - } - else { - exprType = FLOAT; - bytecode.addFconst((float)d.get()); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/CompileError.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/CompileError.java deleted file mode 100644 index 71fb018c7..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/CompileError.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -import com.fr.third.javassist.CannotCompileException; -import com.fr.third.javassist.NotFoundException; - -public class CompileError extends Exception { - private com.fr.third.javassist.compiler.Lex lex; - private String reason; - - public CompileError(String s, com.fr.third.javassist.compiler.Lex l) { - reason = s; - lex = l; - } - - public CompileError(String s) { - reason = s; - lex = null; - } - - public CompileError(CannotCompileException e) { - this(e.getReason()); - } - - public CompileError(NotFoundException e) { - this("cannot find " + e.getMessage()); - } - - public Lex getLex() { return lex; } - - public String getMessage() { - return reason; - } - - public String toString() { - return "compile error: " + reason; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/Javac.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/Javac.java deleted file mode 100644 index 15f57d05c..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/Javac.java +++ /dev/null @@ -1,610 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CtPrimitiveType; -import com.fr.third.javassist.CtMember; -import com.fr.third.javassist.CtField; -import com.fr.third.javassist.CtBehavior; -import com.fr.third.javassist.CtMethod; -import com.fr.third.javassist.CtConstructor; -import com.fr.third.javassist.CannotCompileException; -import com.fr.third.javassist.Modifier; -import com.fr.third.javassist.bytecode.Bytecode; -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.bytecode.LocalVariableAttribute; -import com.fr.third.javassist.bytecode.BadBytecode; -import com.fr.third.javassist.bytecode.Opcode; -import com.fr.third.javassist.NotFoundException; - -import com.fr.third.javassist.compiler.ast.ASTree; - -public class Javac { - JvstCodeGen gen; - SymbolTable stable; - private Bytecode bytecode; - - public static final String param0Name = "$0"; - public static final String resultVarName = "$_"; - public static final String proceedName = "$proceed"; - - /** - * Constructs a compiler. - * - * @param thisClass the class that a compiled method/field - * belongs to. - */ - public Javac(CtClass thisClass) { - this(new Bytecode(thisClass.getClassFile2().getConstPool(), 0, 0), - thisClass); - } - - /** - * Constructs a compiler. - * The produced bytecode is stored in the Bytecode object - * specified by b. - * - * @param thisClass the class that a compiled method/field - * belongs to. - */ - public Javac(Bytecode b, CtClass thisClass) { - gen = new JvstCodeGen(b, thisClass, thisClass.getClassPool()); - stable = new SymbolTable(); - bytecode = b; - } - - /** - * Returns the produced bytecode. - */ - public Bytecode getBytecode() { return bytecode; } - - /** - * Compiles a method, constructor, or field declaration - * to a class. - * A field declaration can declare only one field. - * - *

In a method or constructor body, $0, $1, ... and $_ - * are not available. - * - * @return a CtMethod, CtConstructor, - * or CtField object. - * @see #recordProceed(String,String) - */ - public CtMember compile(String src) throws CompileError { - Parser p = new Parser(new com.fr.third.javassist.compiler.Lex(src)); - com.fr.third.javassist.compiler.ast.ASTList mem = p.parseMember1(stable); - try { - if (mem instanceof com.fr.third.javassist.compiler.ast.FieldDecl) - return compileField((com.fr.third.javassist.compiler.ast.FieldDecl)mem); - else { - CtBehavior cb = compileMethod(p, (com.fr.third.javassist.compiler.ast.MethodDecl)mem); - CtClass decl = cb.getDeclaringClass(); - cb.getMethodInfo2() - .rebuildStackMapIf6(decl.getClassPool(), - decl.getClassFile2()); - return cb; - } - } - catch (BadBytecode bb) { - throw new CompileError(bb.getMessage()); - } - catch (CannotCompileException e) { - throw new CompileError(e.getMessage()); - } - } - - public static class CtFieldWithInit extends CtField { - private com.fr.third.javassist.compiler.ast.ASTree init; - - CtFieldWithInit(CtClass type, String name, CtClass declaring) - throws CannotCompileException - { - super(type, name, declaring); - init = null; - } - - protected void setInit(com.fr.third.javassist.compiler.ast.ASTree i) { init = i; } - - protected com.fr.third.javassist.compiler.ast.ASTree getInitAST() { - return init; - } - } - - private CtField compileField(com.fr.third.javassist.compiler.ast.FieldDecl fd) - throws CompileError, CannotCompileException - { - CtFieldWithInit f; - com.fr.third.javassist.compiler.ast.Declarator d = fd.getDeclarator(); - f = new CtFieldWithInit(gen.resolver.lookupClass(d), - d.getVariable().get(), gen.getThisClass()); - f.setModifiers(MemberResolver.getModifiers(fd.getModifiers())); - if (fd.getInit() != null) - f.setInit(fd.getInit()); - - return f; - } - - private CtBehavior compileMethod(Parser p, com.fr.third.javassist.compiler.ast.MethodDecl md) - throws CompileError - { - int mod = MemberResolver.getModifiers(md.getModifiers()); - CtClass[] plist = gen.makeParamList(md); - CtClass[] tlist = gen.makeThrowsList(md); - recordParams(plist, Modifier.isStatic(mod)); - md = p.parseMethod2(stable, md); - try { - if (md.isConstructor()) { - CtConstructor cons = new CtConstructor(plist, - gen.getThisClass()); - cons.setModifiers(mod); - md.accept(gen); - cons.getMethodInfo().setCodeAttribute( - bytecode.toCodeAttribute()); - cons.setExceptionTypes(tlist); - return cons; - } - else { - com.fr.third.javassist.compiler.ast.Declarator r = md.getReturn(); - CtClass rtype = gen.resolver.lookupClass(r); - recordReturnType(rtype, false); - CtMethod method = new CtMethod(rtype, r.getVariable().get(), - plist, gen.getThisClass()); - method.setModifiers(mod); - gen.setThisMethod(method); - md.accept(gen); - if (md.getBody() != null) - method.getMethodInfo().setCodeAttribute( - bytecode.toCodeAttribute()); - else - method.setModifiers(mod | Modifier.ABSTRACT); - - method.setExceptionTypes(tlist); - return method; - } - } - catch (NotFoundException e) { - throw new CompileError(e.toString()); - } - } - - /** - * Compiles a method (or constructor) body. - * - * @src a single statement or a block. - * If null, this method produces a body returning zero or null. - */ - public Bytecode compileBody(CtBehavior method, String src) - throws CompileError - { - try { - int mod = method.getModifiers(); - recordParams(method.getParameterTypes(), Modifier.isStatic(mod)); - - CtClass rtype; - if (method instanceof CtMethod) { - gen.setThisMethod((CtMethod)method); - rtype = ((CtMethod)method).getReturnType(); - } - else - rtype = CtClass.voidType; - - recordReturnType(rtype, false); - boolean isVoid = rtype == CtClass.voidType; - - if (src == null) - makeDefaultBody(bytecode, rtype); - else { - Parser p = new Parser(new com.fr.third.javassist.compiler.Lex(src)); - SymbolTable stb = new SymbolTable(stable); - com.fr.third.javassist.compiler.ast.Stmnt s = p.parseStatement(stb); - if (p.hasMore()) - throw new CompileError( - "the method/constructor body must be surrounded by {}"); - - boolean callSuper = false; - if (method instanceof CtConstructor) - callSuper = !((CtConstructor)method).isClassInitializer(); - - gen.atMethodBody(s, callSuper, isVoid); - } - - return bytecode; - } - catch (NotFoundException e) { - throw new CompileError(e.toString()); - } - } - - private static void makeDefaultBody(Bytecode b, CtClass type) { - int op; - int value; - if (type instanceof CtPrimitiveType) { - CtPrimitiveType pt = (CtPrimitiveType)type; - op = pt.getReturnOp(); - if (op == Opcode.DRETURN) - value = Opcode.DCONST_0; - else if (op == Opcode.FRETURN) - value = Opcode.FCONST_0; - else if (op == Opcode.LRETURN) - value = Opcode.LCONST_0; - else if (op == Opcode.RETURN) - value = Opcode.NOP; - else - value = Opcode.ICONST_0; - } - else { - op = Opcode.ARETURN; - value = Opcode.ACONST_NULL; - } - - if (value != Opcode.NOP) - b.addOpcode(value); - - b.addOpcode(op); - } - - /** - * Records local variables available at the specified program counter. - * If the LocalVariableAttribute is not available, this method does not - * record any local variable. It only returns false. - * - * @param pc program counter (>= 0) - * @return false if the CodeAttribute does not include a - * LocalVariableAttribute. - */ - public boolean recordLocalVariables(CodeAttribute ca, int pc) - throws CompileError - { - LocalVariableAttribute va - = (LocalVariableAttribute) - ca.getAttribute(LocalVariableAttribute.tag); - if (va == null) - return false; - - int n = va.tableLength(); - for (int i = 0; i < n; ++i) { - int start = va.startPc(i); - int len = va.codeLength(i); - if (start <= pc && pc < start + len) - gen.recordVariable(va.descriptor(i), va.variableName(i), - va.index(i), stable); - } - - return true; - } - - /** - * Records parameter names if the LocalVariableAttribute is available. - * It returns false unless the LocalVariableAttribute is available. - * - * @param numOfLocalVars the number of local variables used - * for storing the parameters. - * @return false if the CodeAttribute does not include a - * LocalVariableAttribute. - */ - public boolean recordParamNames(CodeAttribute ca, int numOfLocalVars) - throws CompileError - { - LocalVariableAttribute va - = (LocalVariableAttribute) - ca.getAttribute(LocalVariableAttribute.tag); - if (va == null) - return false; - - int n = va.tableLength(); - for (int i = 0; i < n; ++i) { - int index = va.index(i); - if (index < numOfLocalVars) - gen.recordVariable(va.descriptor(i), va.variableName(i), - index, stable); - } - - return true; - } - - - /** - * Makes variables $0 (this), $1, $2, ..., and $args represent method - * parameters. $args represents an array of all the parameters. - * It also makes $$ available as a parameter list of method call. - * - *

This must be called before calling compileStmnt() and - * compileExpr(). The correct value of - * isStatic must be recorded before compilation. - * maxLocals is updated to include $0,... - */ - public int recordParams(CtClass[] params, boolean isStatic) - throws CompileError - { - return gen.recordParams(params, isStatic, "$", "$args", "$$", stable); - } - - /** - * Makes variables $0, $1, $2, ..., and $args represent method - * parameters. $args represents an array of all the parameters. - * It also makes $$ available as a parameter list of method call. - * $0 can represent a local variable other than THIS (variable 0). - * $class is also made available. - * - *

This must be called before calling compileStmnt() and - * compileExpr(). The correct value of - * isStatic must be recorded before compilation. - * maxLocals is updated to include $0,... - * - * @paaram use0 true if $0 is used. - * @param varNo the register number of $0 (use0 is true) - * or $1 (otherwise). - * @param target the type of $0 (it can be null if use0 is false). - * It is used as the name of the type represented - * by $class. - * @param isStatic true if the method in which the compiled bytecode - * is embedded is static. - */ - public int recordParams(String target, CtClass[] params, - boolean use0, int varNo, boolean isStatic) - throws CompileError - { - return gen.recordParams(params, isStatic, "$", "$args", "$$", - use0, varNo, target, stable); - } - - /** - * Sets maxLocals to max. - * This method tells the compiler the local variables that have been - * allocated for the rest of the code. When the compiler needs - * new local variables, the local variables at the index max, - * max + 1, ... are assigned. - * - *

This method is indirectly called by recordParams. - */ - public void setMaxLocals(int max) { - gen.setMaxLocals(max); - } - - /** - * Prepares to use cast $r, $w, $_, and $type. - * $type is made to represent the specified return type. - * It also enables to write a return statement with a return value - * for void method. - * - *

If the return type is void, ($r) does nothing. - * The type of $_ is java.lang.Object. - * - * @param type the return type. - * @param useResultVar true if $_ is used. - * @return -1 or the variable index assigned to $_. - * @see #recordType(CtClass) - */ - public int recordReturnType(CtClass type, boolean useResultVar) - throws CompileError - { - gen.recordType(type); - return gen.recordReturnType(type, "$r", - (useResultVar ? resultVarName : null), stable); - } - - /** - * Prepares to use $type. Note that recordReturnType() overwrites - * the value of $type. - * - * @param t the type represented by $type. - */ - public void recordType(CtClass t) { - gen.recordType(t); - } - - /** - * Makes the given variable available. - * - * @param type variable type - * @param name variable name - */ - public int recordVariable(CtClass type, String name) - throws CompileError - { - return gen.recordVariable(type, name, stable); - } - - /** - * Prepares to use $proceed(). - * If the return type of $proceed() is void, null is pushed on the - * stack. - * - * @param target an expression specifying the target object. - * if null, "this" is the target. - * @param method the method name. - */ - public void recordProceed(String target, String method) - throws CompileError - { - Parser p = new Parser(new com.fr.third.javassist.compiler.Lex(target)); - final com.fr.third.javassist.compiler.ast.ASTree texpr = p.parseExpression(stable); - final String m = method; - - ProceedHandler h = new ProceedHandler() { - public void doit(JvstCodeGen gen, Bytecode b, com.fr.third.javassist.compiler.ast.ASTList args) - throws CompileError - { - com.fr.third.javassist.compiler.ast.ASTree expr = new com.fr.third.javassist.compiler.ast.Member(m); - if (texpr != null) - expr = com.fr.third.javassist.compiler.ast.Expr.make('.', texpr, expr); - - expr = com.fr.third.javassist.compiler.ast.CallExpr.makeCall(expr, args); - gen.compileExpr(expr); - gen.addNullIfVoid(); - } - - public void setReturnType(JvstTypeChecker check, com.fr.third.javassist.compiler.ast.ASTList args) - throws CompileError - { - com.fr.third.javassist.compiler.ast.ASTree expr = new com.fr.third.javassist.compiler.ast.Member(m); - if (texpr != null) - expr = com.fr.third.javassist.compiler.ast.Expr.make('.', texpr, expr); - - expr = com.fr.third.javassist.compiler.ast.CallExpr.makeCall(expr, args); - expr.accept(check); - check.addNullIfVoid(); - } - }; - - gen.setProceedHandler(h, proceedName); - } - - /** - * Prepares to use $proceed() representing a static method. - * If the return type of $proceed() is void, null is pushed on the - * stack. - * - * @param targetClass the fully-qualified dot-separated name - * of the class declaring the method. - * @param method the method name. - */ - public void recordStaticProceed(String targetClass, String method) - throws CompileError - { - final String c = targetClass; - final String m = method; - - ProceedHandler h = new ProceedHandler() { - public void doit(JvstCodeGen gen, Bytecode b, com.fr.third.javassist.compiler.ast.ASTList args) - throws CompileError - { - com.fr.third.javassist.compiler.ast.Expr expr = com.fr.third.javassist.compiler.ast.Expr.make(TokenId.MEMBER, - new com.fr.third.javassist.compiler.ast.Symbol(c), new com.fr.third.javassist.compiler.ast.Member(m)); - expr = com.fr.third.javassist.compiler.ast.CallExpr.makeCall(expr, args); - gen.compileExpr(expr); - gen.addNullIfVoid(); - } - - public void setReturnType(JvstTypeChecker check, com.fr.third.javassist.compiler.ast.ASTList args) - throws CompileError - { - com.fr.third.javassist.compiler.ast.Expr expr = com.fr.third.javassist.compiler.ast.Expr.make(TokenId.MEMBER, - new com.fr.third.javassist.compiler.ast.Symbol(c), new com.fr.third.javassist.compiler.ast.Member(m)); - expr = com.fr.third.javassist.compiler.ast.CallExpr.makeCall(expr, args); - expr.accept(check); - check.addNullIfVoid(); - } - }; - - gen.setProceedHandler(h, proceedName); - } - - /** - * Prepares to use $proceed() representing a private/super's method. - * If the return type of $proceed() is void, null is pushed on the - * stack. This method is for methods invoked by INVOKESPECIAL. - * - * @param target an expression specifying the target object. - * if null, "this" is the target. - * @param classname the class name declaring the method. - * @param methodname the method name. - * @param descriptor the method descriptor. - */ - public void recordSpecialProceed(String target, String classname, - String methodname, String descriptor) - throws CompileError - { - Parser p = new Parser(new com.fr.third.javassist.compiler.Lex(target)); - final com.fr.third.javassist.compiler.ast.ASTree texpr = p.parseExpression(stable); - final String cname = classname; - final String method = methodname; - final String desc = descriptor; - - ProceedHandler h = new ProceedHandler() { - public void doit(JvstCodeGen gen, Bytecode b, com.fr.third.javassist.compiler.ast.ASTList args) - throws CompileError - { - gen.compileInvokeSpecial(texpr, cname, method, desc, args); - } - - public void setReturnType(JvstTypeChecker c, com.fr.third.javassist.compiler.ast.ASTList args) - throws CompileError - { - c.compileInvokeSpecial(texpr, cname, method, desc, args); - } - - }; - - gen.setProceedHandler(h, proceedName); - } - - /** - * Prepares to use $proceed(). - */ - public void recordProceed(ProceedHandler h) { - gen.setProceedHandler(h, proceedName); - } - - /** - * Compiles a statement (or a block). - * recordParams() must be called before invoking - * this method. - * - *

Local variables that are not declared - * in the compiled source text might not be accessible within that - * source text. Fields and method parameters ($0, $1, ..) are available. - */ - public void compileStmnt(String src) throws CompileError { - Parser p = new Parser(new com.fr.third.javassist.compiler.Lex(src)); - SymbolTable stb = new SymbolTable(stable); - while (p.hasMore()) { - com.fr.third.javassist.compiler.ast.Stmnt s = p.parseStatement(stb); - if (s != null) - s.accept(gen); - } - } - - /** - * Compiles an exression. recordParams() must be - * called before invoking this method. - * - *

Local variables are not accessible - * within the compiled source text. Fields and method parameters - * ($0, $1, ..) are available if recordParams() - * have been invoked. - */ - public void compileExpr(String src) throws CompileError { - com.fr.third.javassist.compiler.ast.ASTree e = parseExpr(src, stable); - compileExpr(e); - } - - /** - * Parsers an expression. - */ - public static com.fr.third.javassist.compiler.ast.ASTree parseExpr(String src, SymbolTable st) - throws CompileError - { - Parser p = new Parser(new Lex(src)); - return p.parseExpression(st); - } - - /** - * Compiles an exression. recordParams() must be - * called before invoking this method. - * - *

Local variables are not accessible - * within the compiled source text. Fields and method parameters - * ($0, $1, ..) are available if recordParams() - * have been invoked. - */ - public void compileExpr(ASTree e) throws CompileError { - if (e != null) - gen.compileExpr(e); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/JvstCodeGen.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/JvstCodeGen.java deleted file mode 100644 index 8a8b3a67b..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/JvstCodeGen.java +++ /dev/null @@ -1,712 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -import com.fr.third.javassist.CtPrimitiveType; -import com.fr.third.javassist.bytecode.Bytecode; -import com.fr.third.javassist.compiler.ast.ASTree; -import com.fr.third.javassist.compiler.CodeGen; -import com.fr.third.javassist.compiler.TokenId; - -/* Code generator accepting extended Java syntax for Javassist. - */ - -public class JvstCodeGen extends MemberCodeGen { - String paramArrayName = null; - String paramListName = null; - com.fr.third.javassist.CtClass[] paramTypeList = null; - private int paramVarBase = 0; // variable index for $0 or $1. - private boolean useParam0 = false; // true if $0 is used. - private String param0Type = null; // JVM name - public static final String sigName = "$sig"; - public static final String dollarTypeName = "$type"; - public static final String clazzName = "$class"; - private com.fr.third.javassist.CtClass dollarType = null; - com.fr.third.javassist.CtClass returnType = null; - String returnCastName = null; - private String returnVarName = null; // null if $_ is not used. - public static final String wrapperCastName = "$w"; - String proceedName = null; - public static final String cflowName = "$cflow"; - ProceedHandler procHandler = null; // null if not used. - - public JvstCodeGen(com.fr.third.javassist.bytecode.Bytecode b, com.fr.third.javassist.CtClass cc, com.fr.third.javassist.ClassPool cp) { - super(b, cc, cp); - setTypeChecker(new JvstTypeChecker(cc, cp, this)); - } - - /* Index of $1. - */ - private int indexOfParam1() { - return paramVarBase + (useParam0 ? 1 : 0); - } - - /* Records a ProceedHandler obejct. - * - * @param name the name of the special method call. - * it is usually $proceed. - */ - public void setProceedHandler(ProceedHandler h, String name) { - proceedName = name; - procHandler = h; - } - - /* If the type of the expression compiled last is void, - * add ACONST_NULL and change exprType, arrayDim, className. - */ - public void addNullIfVoid() { - if (exprType == TokenId.VOID) { - bytecode.addOpcode(ACONST_NULL); - exprType = TokenId.CLASS; - arrayDim = 0; - className = CodeGen.jvmJavaLangObject; - } - } - - /* To support $args, $sig, and $type. - * $args is an array of parameter list. - */ - public void atMember(com.fr.third.javassist.compiler.ast.Member mem) throws CompileError { - String name = mem.get(); - if (name.equals(paramArrayName)) { - compileParameterList(bytecode, paramTypeList, indexOfParam1()); - exprType = TokenId.CLASS; - arrayDim = 1; - className = CodeGen.jvmJavaLangObject; - } - else if (name.equals(sigName)) { - bytecode.addLdc(com.fr.third.javassist.bytecode.Descriptor.ofMethod(returnType, paramTypeList)); - bytecode.addInvokestatic("javassist/runtime/Desc", "getParams", - "(Ljava/lang/String;)[Ljava/lang/Class;"); - exprType = TokenId.CLASS; - arrayDim = 1; - className = "java/lang/Class"; - } - else if (name.equals(dollarTypeName)) { - if (dollarType == null) - throw new CompileError(dollarTypeName + " is not available"); - - bytecode.addLdc(com.fr.third.javassist.bytecode.Descriptor.of(dollarType)); - callGetType("getType"); - } - else if (name.equals(clazzName)) { - if (param0Type == null) - throw new CompileError(clazzName + " is not available"); - - bytecode.addLdc(param0Type); - callGetType("getClazz"); - } - else - super.atMember(mem); - } - - private void callGetType(String method) { - bytecode.addInvokestatic("javassist/runtime/Desc", method, - "(Ljava/lang/String;)Ljava/lang/Class;"); - exprType = TokenId.CLASS; - arrayDim = 0; - className = "java/lang/Class"; - } - - protected void atFieldAssign(com.fr.third.javassist.compiler.ast.Expr expr, int op, com.fr.third.javassist.compiler.ast.ASTree left, - com.fr.third.javassist.compiler.ast.ASTree right, boolean doDup) throws CompileError - { - if (left instanceof com.fr.third.javassist.compiler.ast.Member - && ((com.fr.third.javassist.compiler.ast.Member)left).get().equals(paramArrayName)) { - if (op != '=') - throw new CompileError("bad operator for " + paramArrayName); - - right.accept(this); - if (arrayDim != 1 || exprType != TokenId.CLASS) - throw new CompileError("invalid type for " + paramArrayName); - - atAssignParamList(paramTypeList, bytecode); - if (!doDup) - bytecode.addOpcode(POP); - } - else - super.atFieldAssign(expr, op, left, right, doDup); - } - - protected void atAssignParamList(com.fr.third.javassist.CtClass[] params, com.fr.third.javassist.bytecode.Bytecode code) - throws CompileError - { - if (params == null) - return; - - int varNo = indexOfParam1(); - int n = params.length; - for (int i = 0; i < n; ++i) { - code.addOpcode(DUP); - code.addIconst(i); - code.addOpcode(AALOAD); - compileUnwrapValue(params[i], code); - code.addStore(varNo, params[i]); - varNo += CodeGen.is2word(exprType, arrayDim) ? 2 : 1; - } - } - - public void atCastExpr(com.fr.third.javassist.compiler.ast.CastExpr expr) throws CompileError { - com.fr.third.javassist.compiler.ast.ASTList classname = expr.getClassName(); - if (classname != null && expr.getArrayDim() == 0) { - com.fr.third.javassist.compiler.ast.ASTree p = classname.head(); - if (p instanceof com.fr.third.javassist.compiler.ast.Symbol && classname.tail() == null) { - String typename = ((com.fr.third.javassist.compiler.ast.Symbol)p).get(); - if (typename.equals(returnCastName)) { - atCastToRtype(expr); - return; - } - else if (typename.equals(wrapperCastName)) { - atCastToWrapper(expr); - return; - } - } - } - - super.atCastExpr(expr); - } - - /** - * Inserts a cast operator to the return type. - * If the return type is void, this does nothing. - */ - protected void atCastToRtype(com.fr.third.javassist.compiler.ast.CastExpr expr) throws CompileError { - expr.getOprand().accept(this); - if (exprType == TokenId.VOID || CodeGen.isRefType(exprType) || arrayDim > 0) - compileUnwrapValue(returnType, bytecode); - else if (returnType instanceof com.fr.third.javassist.CtPrimitiveType) { - com.fr.third.javassist.CtPrimitiveType pt = (com.fr.third.javassist.CtPrimitiveType)returnType; - int destType = MemberResolver.descToType(pt.getDescriptor()); - atNumCastExpr(exprType, destType); - exprType = destType; - arrayDim = 0; - className = null; - } - else - throw new CompileError("invalid cast"); - } - - protected void atCastToWrapper(com.fr.third.javassist.compiler.ast.CastExpr expr) throws CompileError { - expr.getOprand().accept(this); - if (CodeGen.isRefType(exprType) || arrayDim > 0) - return; // Object type. do nothing. - - com.fr.third.javassist.CtClass clazz = resolver.lookupClass(exprType, arrayDim, className); - if (clazz instanceof com.fr.third.javassist.CtPrimitiveType) { - com.fr.third.javassist.CtPrimitiveType pt = (com.fr.third.javassist.CtPrimitiveType)clazz; - String wrapper = pt.getWrapperName(); - bytecode.addNew(wrapper); // new - bytecode.addOpcode(DUP); // dup - if (pt.getDataSize() > 1) - bytecode.addOpcode(DUP2_X2); // dup2_x2 - else - bytecode.addOpcode(DUP2_X1); // dup2_x1 - - bytecode.addOpcode(POP2); // pop2 - bytecode.addInvokespecial(wrapper, "", - "(" + pt.getDescriptor() + ")V"); - // invokespecial - exprType = TokenId.CLASS; - arrayDim = 0; - className = CodeGen.jvmJavaLangObject; - } - } - - /* Delegates to a ProcHandler object if the method call is - * $proceed(). It may process $cflow(). - */ - public void atCallExpr(com.fr.third.javassist.compiler.ast.CallExpr expr) throws CompileError { - com.fr.third.javassist.compiler.ast.ASTree method = expr.oprand1(); - if (method instanceof com.fr.third.javassist.compiler.ast.Member) { - String name = ((com.fr.third.javassist.compiler.ast.Member)method).get(); - if (procHandler != null && name.equals(proceedName)) { - procHandler.doit(this, bytecode, (com.fr.third.javassist.compiler.ast.ASTList)expr.oprand2()); - return; - } - else if (name.equals(cflowName)) { - atCflow((com.fr.third.javassist.compiler.ast.ASTList)expr.oprand2()); - return; - } - } - - super.atCallExpr(expr); - } - - /* To support $cflow(). - */ - protected void atCflow(com.fr.third.javassist.compiler.ast.ASTList cname) throws CompileError { - StringBuffer sbuf = new StringBuffer(); - if (cname == null || cname.tail() != null) - throw new CompileError("bad " + cflowName); - - makeCflowName(sbuf, cname.head()); - String name = sbuf.toString(); - Object[] names = resolver.getClassPool().lookupCflow(name); - if (names == null) - throw new CompileError("no such " + cflowName + ": " + name); - - bytecode.addGetstatic((String)names[0], (String)names[1], - "Ljavassist/runtime/Cflow;"); - bytecode.addInvokevirtual("javassist.runtime.Cflow", - "value", "()I"); - exprType = TokenId.INT; - arrayDim = 0; - className = null; - } - - /* Syntax: - * - * : $cflow '(' ')' - * : ('.' )* - */ - private static void makeCflowName(StringBuffer sbuf, com.fr.third.javassist.compiler.ast.ASTree name) - throws CompileError - { - if (name instanceof com.fr.third.javassist.compiler.ast.Symbol) { - sbuf.append(((com.fr.third.javassist.compiler.ast.Symbol)name).get()); - return; - } - else if (name instanceof com.fr.third.javassist.compiler.ast.Expr) { - com.fr.third.javassist.compiler.ast.Expr expr = (com.fr.third.javassist.compiler.ast.Expr)name; - if (expr.getOperator() == '.') { - makeCflowName(sbuf, expr.oprand1()); - sbuf.append('.'); - makeCflowName(sbuf, expr.oprand2()); - return; - } - } - - throw new CompileError("bad " + cflowName); - } - - /* To support $$. ($$) is equivalent to ($1, ..., $n). - * It can be used only as a parameter list of method call. - */ - public boolean isParamListName(com.fr.third.javassist.compiler.ast.ASTList args) { - if (paramTypeList != null - && args != null && args.tail() == null) { - com.fr.third.javassist.compiler.ast.ASTree left = args.head(); - return (left instanceof com.fr.third.javassist.compiler.ast.Member - && ((com.fr.third.javassist.compiler.ast.Member)left).get().equals(paramListName)); - } - else - return false; - } - - /* - public int getMethodArgsLength(ASTList args) { - if (!isParamListName(args)) - return super.getMethodArgsLength(args); - - return paramTypeList.length; - } - */ - - public int getMethodArgsLength(com.fr.third.javassist.compiler.ast.ASTList args) { - String pname = paramListName; - int n = 0; - while (args != null) { - com.fr.third.javassist.compiler.ast.ASTree a = args.head(); - if (a instanceof com.fr.third.javassist.compiler.ast.Member && ((com.fr.third.javassist.compiler.ast.Member)a).get().equals(pname)) { - if (paramTypeList != null) - n += paramTypeList.length; - } - else - ++n; - - args = args.tail(); - } - - return n; - } - - public void atMethodArgs(com.fr.third.javassist.compiler.ast.ASTList args, int[] types, int[] dims, - String[] cnames) throws CompileError { - com.fr.third.javassist.CtClass[] params = paramTypeList; - String pname = paramListName; - int i = 0; - while (args != null) { - com.fr.third.javassist.compiler.ast.ASTree a = args.head(); - if (a instanceof com.fr.third.javassist.compiler.ast.Member && ((com.fr.third.javassist.compiler.ast.Member)a).get().equals(pname)) { - if (params != null) { - int n = params.length; - int regno = indexOfParam1(); - for (int k = 0; k < n; ++k) { - com.fr.third.javassist.CtClass p = params[k]; - regno += bytecode.addLoad(regno, p); - setType(p); - types[i] = exprType; - dims[i] = arrayDim; - cnames[i] = className; - ++i; - } - } - } - else { - a.accept(this); - types[i] = exprType; - dims[i] = arrayDim; - cnames[i] = className; - ++i; - } - - args = args.tail(); - } - } - - /* - public void atMethodArgs(ASTList args, int[] types, int[] dims, - String[] cnames) throws CompileError { - if (!isParamListName(args)) { - super.atMethodArgs(args, types, dims, cnames); - return; - } - - CtClass[] params = paramTypeList; - if (params == null) - return; - - int n = params.length; - int regno = indexOfParam1(); - for (int i = 0; i < n; ++i) { - CtClass p = params[i]; - regno += bytecode.addLoad(regno, p); - setType(p); - types[i] = exprType; - dims[i] = arrayDim; - cnames[i] = className; - } - } - */ - - /* called by Javac#recordSpecialProceed(). - */ - void compileInvokeSpecial(com.fr.third.javassist.compiler.ast.ASTree target, String classname, - String methodname, String descriptor, - com.fr.third.javassist.compiler.ast.ASTList args) - throws CompileError - { - target.accept(this); - int nargs = getMethodArgsLength(args); - atMethodArgs(args, new int[nargs], new int[nargs], - new String[nargs]); - bytecode.addInvokespecial(classname, methodname, descriptor); - setReturnType(descriptor, false, false); - addNullIfVoid(); - } - - /* - * Makes it valid to write "return ;" for a void method. - */ - protected void atReturnStmnt(com.fr.third.javassist.compiler.ast.Stmnt st) throws CompileError { - ASTree result = st.getLeft(); - if (result != null && returnType == com.fr.third.javassist.CtClass.voidType) { - compileExpr(result); - if (CodeGen.is2word(exprType, arrayDim)) - bytecode.addOpcode(POP2); - else if (exprType != TokenId.VOID) - bytecode.addOpcode(POP); - - result = null; - } - - atReturnStmnt2(result); - } - - /** - * Makes a cast to the return type ($r) available. - * It also enables $_. - * - *

If the return type is void, ($r) does nothing. - * The type of $_ is java.lang.Object. - * - * @param resultName null if $_ is not used. - * @return -1 or the variable index assigned to $_. - */ - public int recordReturnType(com.fr.third.javassist.CtClass type, String castName, - String resultName, SymbolTable tbl) throws CompileError - { - returnType = type; - returnCastName = castName; - returnVarName = resultName; - if (resultName == null) - return -1; - else { - int varNo = getMaxLocals(); - int locals = varNo + recordVar(type, resultName, varNo, tbl); - setMaxLocals(locals); - return varNo; - } - } - - /** - * Makes $type available. - */ - public void recordType(com.fr.third.javassist.CtClass t) { - dollarType = t; - } - - /** - * Makes method parameters $0, $1, ..., $args, $$, and $class available. - * $0 is equivalent to THIS if the method is not static. Otherwise, - * if the method is static, then $0 is not available. - */ - public int recordParams(com.fr.third.javassist.CtClass[] params, boolean isStatic, - String prefix, String paramVarName, - String paramsName, SymbolTable tbl) - throws CompileError - { - return recordParams(params, isStatic, prefix, paramVarName, - paramsName, !isStatic, 0, getThisName(), tbl); - } - - /** - * Makes method parameters $0, $1, ..., $args, $$, and $class available. - * $0 is available only if use0 is true. It might not be equivalent - * to THIS. - * - * @param params the parameter types (the types of $1, $2, ..) - * @param prefix it must be "$" (the first letter of $0, $1, ...) - * @param paramVarName it must be "$args" - * @param paramsName it must be "$$" - * @param use0 true if $0 is used. - * @param paramBase the register number of $0 (use0 is true) - * or $1 (otherwise). - * @param target the class of $0. If use0 is false, target - * can be null. The value of "target" is also used - * as the name of the type represented by $class. - * @param isStatic true if the method in which the compiled bytecode - * is embedded is static. - */ - public int recordParams(com.fr.third.javassist.CtClass[] params, boolean isStatic, - String prefix, String paramVarName, - String paramsName, boolean use0, - int paramBase, String target, - SymbolTable tbl) - throws CompileError - { - int varNo; - - paramTypeList = params; - paramArrayName = paramVarName; - paramListName = paramsName; - paramVarBase = paramBase; - useParam0 = use0; - - if (target != null) - param0Type = MemberResolver.jvmToJavaName(target); - - inStaticMethod = isStatic; - varNo = paramBase; - if (use0) { - String varName = prefix + "0"; - com.fr.third.javassist.compiler.ast.Declarator decl - = new com.fr.third.javassist.compiler.ast.Declarator(TokenId.CLASS, MemberResolver.javaToJvmName(target), - 0, varNo++, new com.fr.third.javassist.compiler.ast.Symbol(varName)); - tbl.append(varName, decl); - } - - for (int i = 0; i < params.length; ++i) - varNo += recordVar(params[i], prefix + (i + 1), varNo, tbl); - - if (getMaxLocals() < varNo) - setMaxLocals(varNo); - - return varNo; - } - - /** - * Makes the given variable name available. - * - * @param type variable type - * @param varName variable name - */ - public int recordVariable(com.fr.third.javassist.CtClass type, String varName, SymbolTable tbl) - throws CompileError - { - if (varName == null) - return -1; - else { - int varNo = getMaxLocals(); - int locals = varNo + recordVar(type, varName, varNo, tbl); - setMaxLocals(locals); - return varNo; - } - } - - private int recordVar(com.fr.third.javassist.CtClass cc, String varName, int varNo, - SymbolTable tbl) throws CompileError - { - if (cc == com.fr.third.javassist.CtClass.voidType) { - exprType = TokenId.CLASS; - arrayDim = 0; - className = CodeGen.jvmJavaLangObject; - } - else - setType(cc); - - com.fr.third.javassist.compiler.ast.Declarator decl - = new com.fr.third.javassist.compiler.ast.Declarator(exprType, className, arrayDim, - varNo, new com.fr.third.javassist.compiler.ast.Symbol(varName)); - tbl.append(varName, decl); - return CodeGen.is2word(exprType, arrayDim) ? 2 : 1; - } - - /** - * Makes the given variable name available. - * - * @param typeDesc the type descriptor of the variable - * @param varName variable name - * @param varNo an index into the local variable array - */ - public void recordVariable(String typeDesc, String varName, int varNo, - SymbolTable tbl) throws CompileError - { - char c; - int dim = 0; - while ((c = typeDesc.charAt(dim)) == '[') - ++dim; - - int type = MemberResolver.descToType(c); - String cname = null; - if (type == TokenId.CLASS) { - if (dim == 0) - cname = typeDesc.substring(1, typeDesc.length() - 1); - else - cname = typeDesc.substring(dim + 1, typeDesc.length() - 1); - } - - com.fr.third.javassist.compiler.ast.Declarator decl - = new com.fr.third.javassist.compiler.ast.Declarator(type, cname, dim, varNo, new com.fr.third.javassist.compiler.ast.Symbol(varName)); - tbl.append(varName, decl); - } - - /* compileParameterList() returns the stack size used - * by the produced code. - * - * This method correctly computes the max_stack value. - * - * @param regno the index of the local variable in which - * the first argument is received. - * (0: static method, 1: regular method.) - */ - public static int compileParameterList(com.fr.third.javassist.bytecode.Bytecode code, - com.fr.third.javassist.CtClass[] params, int regno) { - if (params == null) { - code.addIconst(0); // iconst_0 - code.addAnewarray(CodeGen.javaLangObject); // anewarray Object - return 1; - } - else { - com.fr.third.javassist.CtClass[] args = new com.fr.third.javassist.CtClass[1]; - int n = params.length; - code.addIconst(n); // iconst_ - code.addAnewarray(CodeGen.javaLangObject); // anewarray Object - for (int i = 0; i < n; ++i) { - code.addOpcode(com.fr.third.javassist.bytecode.Bytecode.DUP); // dup - code.addIconst(i); // iconst_ - if (params[i].isPrimitive()) { - com.fr.third.javassist.CtPrimitiveType pt = (com.fr.third.javassist.CtPrimitiveType)params[i]; - String wrapper = pt.getWrapperName(); - code.addNew(wrapper); // new - code.addOpcode(com.fr.third.javassist.bytecode.Bytecode.DUP); // dup - int s = code.addLoad(regno, pt); // ?load - regno += s; - args[0] = pt; - code.addInvokespecial(wrapper, "", - com.fr.third.javassist.bytecode.Descriptor.ofMethod(com.fr.third.javassist.CtClass.voidType, args)); - // invokespecial - } - else { - code.addAload(regno); // aload - ++regno; - } - - code.addOpcode(com.fr.third.javassist.bytecode.Bytecode.AASTORE); // aastore - } - - return 8; - } - } - - protected void compileUnwrapValue(com.fr.third.javassist.CtClass type, Bytecode code) - throws CompileError - { - if (type == com.fr.third.javassist.CtClass.voidType) { - addNullIfVoid(); - return; - } - - if (exprType == TokenId.VOID) - throw new CompileError("invalid type for " + returnCastName); - - if (type instanceof com.fr.third.javassist.CtPrimitiveType) { - com.fr.third.javassist.CtPrimitiveType pt = (com.fr.third.javassist.CtPrimitiveType)type; - // pt is not voidType. - String wrapper = pt.getWrapperName(); - code.addCheckcast(wrapper); - code.addInvokevirtual(wrapper, pt.getGetMethodName(), - pt.getGetMethodDescriptor()); - setType(type); - } - else { - code.addCheckcast(type); - setType(type); - } - } - - /* Sets exprType, arrayDim, and className; - * If type is void, then this method does nothing. - */ - public void setType(com.fr.third.javassist.CtClass type) throws CompileError { - setType(type, 0); - } - - private void setType(com.fr.third.javassist.CtClass type, int dim) throws CompileError { - if (type.isPrimitive()) { - com.fr.third.javassist.CtPrimitiveType pt = (com.fr.third.javassist.CtPrimitiveType)type; - exprType = MemberResolver.descToType(pt.getDescriptor()); - arrayDim = dim; - className = null; - } - else if (type.isArray()) - try { - setType(type.getComponentType(), dim + 1); - } - catch (com.fr.third.javassist.NotFoundException e) { - throw new CompileError("undefined type: " + type.getName()); - } - else { - exprType = TokenId.CLASS; - arrayDim = dim; - className = MemberResolver.javaToJvmName(type.getName()); - } - } - - /* Performs implicit coercion from exprType to type. - */ - public void doNumCast(com.fr.third.javassist.CtClass type) throws CompileError { - if (arrayDim == 0 && !CodeGen.isRefType(exprType)) - if (type instanceof com.fr.third.javassist.CtPrimitiveType) { - com.fr.third.javassist.CtPrimitiveType pt = (CtPrimitiveType)type; - atNumCastExpr(exprType, - MemberResolver.descToType(pt.getDescriptor())); - } - else - throw new CompileError("type mismatch"); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/JvstTypeChecker.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/JvstTypeChecker.java deleted file mode 100644 index aea78cd8d..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/JvstTypeChecker.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.compiler.ast.ASTree; - -/* Type checker accepting extended Java syntax for Javassist. - */ - -public class JvstTypeChecker extends TypeChecker { - private com.fr.third.javassist.compiler.JvstCodeGen codeGen; - - public JvstTypeChecker(com.fr.third.javassist.CtClass cc, com.fr.third.javassist.ClassPool cp, com.fr.third.javassist.compiler.JvstCodeGen gen) { - super(cc, cp); - codeGen = gen; - } - - /* If the type of the expression compiled last is void, - * add ACONST_NULL and change exprType, arrayDim, className. - */ - public void addNullIfVoid() { - if (exprType == VOID) { - exprType = CLASS; - arrayDim = 0; - className = jvmJavaLangObject; - } - } - - /* To support $args, $sig, and $type. - * $args is an array of parameter list. - */ - public void atMember(com.fr.third.javassist.compiler.ast.Member mem) throws com.fr.third.javassist.compiler.CompileError { - String name = mem.get(); - if (name.equals(codeGen.paramArrayName)) { - exprType = CLASS; - arrayDim = 1; - className = jvmJavaLangObject; - } - else if (name.equals(com.fr.third.javassist.compiler.JvstCodeGen.sigName)) { - exprType = CLASS; - arrayDim = 1; - className = "java/lang/Class"; - } - else if (name.equals(com.fr.third.javassist.compiler.JvstCodeGen.dollarTypeName) - || name.equals(com.fr.third.javassist.compiler.JvstCodeGen.clazzName)) { - exprType = CLASS; - arrayDim = 0; - className = "java/lang/Class"; - } - else - super.atMember(mem); - } - - protected void atFieldAssign(com.fr.third.javassist.compiler.ast.Expr expr, int op, com.fr.third.javassist.compiler.ast.ASTree left, com.fr.third.javassist.compiler.ast.ASTree right) - throws com.fr.third.javassist.compiler.CompileError - { - if (left instanceof com.fr.third.javassist.compiler.ast.Member - && ((com.fr.third.javassist.compiler.ast.Member)left).get().equals(codeGen.paramArrayName)) { - right.accept(this); - com.fr.third.javassist.CtClass[] params = codeGen.paramTypeList; - if (params == null) - return; - - int n = params.length; - for (int i = 0; i < n; ++i) - compileUnwrapValue(params[i]); - } - else - super.atFieldAssign(expr, op, left, right); - } - - public void atCastExpr(com.fr.third.javassist.compiler.ast.CastExpr expr) throws com.fr.third.javassist.compiler.CompileError { - com.fr.third.javassist.compiler.ast.ASTList classname = expr.getClassName(); - if (classname != null && expr.getArrayDim() == 0) { - com.fr.third.javassist.compiler.ast.ASTree p = classname.head(); - if (p instanceof com.fr.third.javassist.compiler.ast.Symbol && classname.tail() == null) { - String typename = ((com.fr.third.javassist.compiler.ast.Symbol)p).get(); - if (typename.equals(codeGen.returnCastName)) { - atCastToRtype(expr); - return; - } - else if (typename.equals(com.fr.third.javassist.compiler.JvstCodeGen.wrapperCastName)) { - atCastToWrapper(expr); - return; - } - } - } - - super.atCastExpr(expr); - } - - /** - * Inserts a cast operator to the return type. - * If the return type is void, this does nothing. - */ - protected void atCastToRtype(com.fr.third.javassist.compiler.ast.CastExpr expr) throws com.fr.third.javassist.compiler.CompileError { - com.fr.third.javassist.CtClass returnType = codeGen.returnType; - expr.getOprand().accept(this); - if (exprType == VOID || com.fr.third.javassist.compiler.CodeGen.isRefType(exprType) || arrayDim > 0) - compileUnwrapValue(returnType); - else if (returnType instanceof com.fr.third.javassist.CtPrimitiveType) { - com.fr.third.javassist.CtPrimitiveType pt = (com.fr.third.javassist.CtPrimitiveType)returnType; - int destType = com.fr.third.javassist.compiler.MemberResolver.descToType(pt.getDescriptor()); - exprType = destType; - arrayDim = 0; - className = null; - } - } - - protected void atCastToWrapper(com.fr.third.javassist.compiler.ast.CastExpr expr) throws com.fr.third.javassist.compiler.CompileError { - expr.getOprand().accept(this); - if (CodeGen.isRefType(exprType) || arrayDim > 0) - return; // Object type. do nothing. - - com.fr.third.javassist.CtClass clazz = resolver.lookupClass(exprType, arrayDim, className); - if (clazz instanceof com.fr.third.javassist.CtPrimitiveType) { - exprType = CLASS; - arrayDim = 0; - className = jvmJavaLangObject; - } - } - - /* Delegates to a ProcHandler object if the method call is - * $proceed(). It may process $cflow(). - */ - public void atCallExpr(com.fr.third.javassist.compiler.ast.CallExpr expr) throws com.fr.third.javassist.compiler.CompileError { - com.fr.third.javassist.compiler.ast.ASTree method = expr.oprand1(); - if (method instanceof com.fr.third.javassist.compiler.ast.Member) { - String name = ((com.fr.third.javassist.compiler.ast.Member)method).get(); - if (codeGen.procHandler != null - && name.equals(codeGen.proceedName)) { - codeGen.procHandler.setReturnType(this, - (com.fr.third.javassist.compiler.ast.ASTList)expr.oprand2()); - return; - } - else if (name.equals(JvstCodeGen.cflowName)) { - atCflow((com.fr.third.javassist.compiler.ast.ASTList)expr.oprand2()); - return; - } - } - - super.atCallExpr(expr); - } - - /* To support $cflow(). - */ - protected void atCflow(com.fr.third.javassist.compiler.ast.ASTList cname) throws com.fr.third.javassist.compiler.CompileError { - exprType = INT; - arrayDim = 0; - className = null; - } - - /* To support $$. ($$) is equivalent to ($1, ..., $n). - * It can be used only as a parameter list of method call. - */ - public boolean isParamListName(com.fr.third.javassist.compiler.ast.ASTList args) { - if (codeGen.paramTypeList != null - && args != null && args.tail() == null) { - com.fr.third.javassist.compiler.ast.ASTree left = args.head(); - return (left instanceof com.fr.third.javassist.compiler.ast.Member - && ((com.fr.third.javassist.compiler.ast.Member)left).get().equals(codeGen.paramListName)); - } - else - return false; - } - - public int getMethodArgsLength(com.fr.third.javassist.compiler.ast.ASTList args) { - String pname = codeGen.paramListName; - int n = 0; - while (args != null) { - com.fr.third.javassist.compiler.ast.ASTree a = args.head(); - if (a instanceof com.fr.third.javassist.compiler.ast.Member && ((com.fr.third.javassist.compiler.ast.Member)a).get().equals(pname)) { - if (codeGen.paramTypeList != null) - n += codeGen.paramTypeList.length; - } - else - ++n; - - args = args.tail(); - } - - return n; - } - - public void atMethodArgs(com.fr.third.javassist.compiler.ast.ASTList args, int[] types, int[] dims, - String[] cnames) throws com.fr.third.javassist.compiler.CompileError { - com.fr.third.javassist.CtClass[] params = codeGen.paramTypeList; - String pname = codeGen.paramListName; - int i = 0; - while (args != null) { - com.fr.third.javassist.compiler.ast.ASTree a = args.head(); - if (a instanceof com.fr.third.javassist.compiler.ast.Member && ((com.fr.third.javassist.compiler.ast.Member)a).get().equals(pname)) { - if (params != null) { - int n = params.length; - for (int k = 0; k < n; ++k) { - com.fr.third.javassist.CtClass p = params[k]; - setType(p); - types[i] = exprType; - dims[i] = arrayDim; - cnames[i] = className; - ++i; - } - } - } - else { - a.accept(this); - types[i] = exprType; - dims[i] = arrayDim; - cnames[i] = className; - ++i; - } - - args = args.tail(); - } - } - - /* called by Javac#recordSpecialProceed(). - */ - void compileInvokeSpecial(ASTree target, String classname, - String methodname, String descriptor, - com.fr.third.javassist.compiler.ast.ASTList args) - throws com.fr.third.javassist.compiler.CompileError - { - target.accept(this); - int nargs = getMethodArgsLength(args); - atMethodArgs(args, new int[nargs], new int[nargs], - new String[nargs]); - setReturnType(descriptor); - addNullIfVoid(); - } - - protected void compileUnwrapValue(com.fr.third.javassist.CtClass type) throws com.fr.third.javassist.compiler.CompileError - { - if (type == com.fr.third.javassist.CtClass.voidType) - addNullIfVoid(); - else - setType(type); - } - - /* Sets exprType, arrayDim, and className; - * If type is void, then this method does nothing. - */ - public void setType(com.fr.third.javassist.CtClass type) throws com.fr.third.javassist.compiler.CompileError { - setType(type, 0); - } - - private void setType(com.fr.third.javassist.CtClass type, int dim) throws com.fr.third.javassist.compiler.CompileError { - if (type.isPrimitive()) { - com.fr.third.javassist.CtPrimitiveType pt = (com.fr.third.javassist.CtPrimitiveType)type; - exprType = com.fr.third.javassist.compiler.MemberResolver.descToType(pt.getDescriptor()); - arrayDim = dim; - className = null; - } - else if (type.isArray()) - try { - setType(type.getComponentType(), dim + 1); - } - catch (NotFoundException e) { - throw new CompileError("undefined type: " + type.getName()); - } - else { - exprType = CLASS; - arrayDim = dim; - className = MemberResolver.javaToJvmName(type.getName()); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/KeywordTable.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/KeywordTable.java deleted file mode 100644 index 6578fc8bb..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/KeywordTable.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -public final class KeywordTable extends java.util.HashMap { - public KeywordTable() { super(); } - - public int lookup(String name) { - Object found = get(name); - if (found == null) - return -1; - else - return ((Integer)found).intValue(); - } - - public void append(String name, int t) { - put(name, new Integer(t)); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/Lex.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/Lex.java deleted file mode 100644 index 47487249b..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/Lex.java +++ /dev/null @@ -1,551 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -class Token { - public Token next = null; - public int tokenId; - - public long longValue; - public double doubleValue; - public String textValue; -} - -public class Lex implements TokenId { - private int lastChar; - private StringBuffer textBuffer; - private Token currentToken; - private Token lookAheadTokens; - - private String input; - private int position, maxlen, lineNumber; - - /** - * Constructs a lexical analyzer. - */ - public Lex(String s) { - lastChar = -1; - textBuffer = new StringBuffer(); - currentToken = new Token(); - lookAheadTokens = null; - - input = s; - position = 0; - maxlen = s.length(); - lineNumber = 0; - } - - public int get() { - if (lookAheadTokens == null) - return get(currentToken); - else { - Token t; - currentToken = t = lookAheadTokens; - lookAheadTokens = lookAheadTokens.next; - return t.tokenId; - } - } - - /** - * Looks at the next token. - */ - public int lookAhead() { - return lookAhead(0); - } - - public int lookAhead(int i) { - Token tk = lookAheadTokens; - if (tk == null) { - lookAheadTokens = tk = currentToken; // reuse an object! - tk.next = null; - get(tk); - } - - for (; i-- > 0; tk = tk.next) - if (tk.next == null) { - Token tk2; - tk.next = tk2 = new Token(); - get(tk2); - } - - currentToken = tk; - return tk.tokenId; - } - - public String getString() { - return currentToken.textValue; - } - - public long getLong() { - return currentToken.longValue; - } - - public double getDouble() { - return currentToken.doubleValue; - } - - private int get(Token token) { - int t; - do { - t = readLine(token); - } while (t == '\n'); - token.tokenId = t; - return t; - } - - private int readLine(Token token) { - int c = getNextNonWhiteChar(); - if(c < 0) - return c; - else if(c == '\n') { - ++lineNumber; - return '\n'; - } - else if (c == '\'') - return readCharConst(token); - else if (c == '"') - return readStringL(token); - else if ('0' <= c && c <= '9') - return readNumber(c, token); - else if(c == '.'){ - c = getc(); - if ('0' <= c && c <= '9') { - StringBuffer tbuf = textBuffer; - tbuf.setLength(0); - tbuf.append('.'); - return readDouble(tbuf, c, token); - } - else{ - ungetc(c); - return readSeparator('.'); - } - } - else if (Character.isJavaIdentifierStart((char)c)) - return readIdentifier(c, token); - else - return readSeparator(c); - } - - private int getNextNonWhiteChar() { - int c; - do { - c = getc(); - if (c == '/') { - c = getc(); - if (c == '/') - do { - c = getc(); - } while (c != '\n' && c != '\r' && c != -1); - else if (c == '*') - while (true) { - c = getc(); - if (c == -1) - break; - else if (c == '*') - if ((c = getc()) == '/') { - c = ' '; - break; - } - else - ungetc(c); - } - else { - ungetc(c); - c = '/'; - } - } - } while(isBlank(c)); - return c; - } - - private int readCharConst(Token token) { - int c; - int value = 0; - while ((c = getc()) != '\'') - if (c == '\\') - value = readEscapeChar(); - else if (c < 0x20) { - if (c == '\n') - ++lineNumber; - - return BadToken; - } - else - value = c; - - token.longValue = value; - return CharConstant; - } - - private int readEscapeChar() { - int c = getc(); - if (c == 'n') - c = '\n'; - else if (c == 't') - c = '\t'; - else if (c == 'r') - c = '\r'; - else if (c == 'f') - c = '\f'; - else if (c == '\n') - ++lineNumber; - - return c; - } - - private int readStringL(Token token) { - int c; - StringBuffer tbuf = textBuffer; - tbuf.setLength(0); - for (;;) { - while ((c = getc()) != '"') { - if (c == '\\') - c = readEscapeChar(); - else if (c == '\n' || c < 0) { - ++lineNumber; - return BadToken; - } - - tbuf.append((char)c); - } - - for (;;) { - c = getc(); - if (c == '\n') - ++lineNumber; - else if (!isBlank(c)) - break; - } - - if (c != '"') { - ungetc(c); - break; - } - } - - token.textValue = tbuf.toString(); - return StringL; - } - - private int readNumber(int c, Token token) { - long value = 0; - int c2 = getc(); - if (c == '0') - if (c2 == 'X' || c2 == 'x') - for (;;) { - c = getc(); - if ('0' <= c && c <= '9') - value = value * 16 + (long)(c - '0'); - else if ('A' <= c && c <= 'F') - value = value * 16 + (long)(c - 'A' + 10); - else if ('a' <= c && c <= 'f') - value = value * 16 + (long)(c - 'a' + 10); - else { - token.longValue = value; - if (c == 'L' || c == 'l') - return LongConstant; - else { - ungetc(c); - return IntConstant; - } - } - } - else if ('0' <= c2 && c2 <= '7') { - value = c2 - '0'; - for (;;) { - c = getc(); - if ('0' <= c && c <= '7') - value = value * 8 + (long)(c - '0'); - else { - token.longValue = value; - if (c == 'L' || c == 'l') - return LongConstant; - else { - ungetc(c); - return IntConstant; - } - } - } - } - - value = c - '0'; - while ('0' <= c2 && c2 <= '9') { - value = value * 10 + c2 - '0'; - c2 = getc(); - } - - token.longValue = value; - if (c2 == 'F' || c2 == 'f') { - token.doubleValue = (double)value; - return FloatConstant; - } - else if (c2 == 'E' || c2 == 'e' - || c2 == 'D' || c2 == 'd' || c2 == '.') { - StringBuffer tbuf = textBuffer; - tbuf.setLength(0); - tbuf.append(value); - return readDouble(tbuf, c2, token); - } - else if (c2 == 'L' || c2 == 'l') - return LongConstant; - else { - ungetc(c2); - return IntConstant; - } - } - - private int readDouble(StringBuffer sbuf, int c, Token token) { - if (c != 'E' && c != 'e' && c != 'D' && c != 'd') { - sbuf.append((char)c); - for (;;) { - c = getc(); - if ('0' <= c && c <= '9') - sbuf.append((char)c); - else - break; - } - } - - if (c == 'E' || c == 'e') { - sbuf.append((char)c); - c = getc(); - if (c == '+' || c == '-') { - sbuf.append((char)c); - c = getc(); - } - - while ('0' <= c && c <= '9') { - sbuf.append((char)c); - c = getc(); - } - } - - try { - token.doubleValue = Double.parseDouble(sbuf.toString()); - } - catch (NumberFormatException e) { - return BadToken; - } - - if (c == 'F' || c == 'f') - return FloatConstant; - else { - if (c != 'D' && c != 'd') - ungetc(c); - - return DoubleConstant; - } - } - - // !"#$%&'( )*+,-./0 12345678 9:;<=>? - private static final int[] equalOps - = { NEQ, 0, 0, 0, MOD_E, AND_E, 0, 0, - 0, MUL_E, PLUS_E, 0, MINUS_E, 0, DIV_E, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, LE, EQ, GE, 0 }; - - private int readSeparator(int c) { - int c2, c3; - if ('!' <= c && c <= '?') { - int t = equalOps[c - '!']; - if (t == 0) - return c; - else { - c2 = getc(); - if (c == c2) - switch (c) { - case '=' : - return EQ; - case '+' : - return PLUSPLUS; - case '-' : - return MINUSMINUS; - case '&' : - return ANDAND; - case '<' : - c3 = getc(); - if (c3 == '=') - return LSHIFT_E; - else { - ungetc(c3); - return LSHIFT; - } - case '>' : - c3 = getc(); - if (c3 == '=') - return RSHIFT_E; - else if (c3 == '>') { - c3 = getc(); - if (c3 == '=') - return ARSHIFT_E; - else { - ungetc(c3); - return ARSHIFT; - } - } - else { - ungetc(c3); - return RSHIFT; - } - default : - break; - } - else if (c2 == '=') - return t; - } - } - else if (c == '^') { - c2 = getc(); - if (c2 == '=') - return EXOR_E; - } - else if (c == '|') { - c2 = getc(); - if (c2 == '=') - return OR_E; - else if (c2 == '|') - return OROR; - } - else - return c; - - ungetc(c2); - return c; - } - - private int readIdentifier(int c, Token token) { - StringBuffer tbuf = textBuffer; - tbuf.setLength(0); - - do { - tbuf.append((char)c); - c = getc(); - } while (Character.isJavaIdentifierPart((char)c)); - - ungetc(c); - - String name = tbuf.toString(); - int t = ktable.lookup(name); - if (t >= 0) - return t; - else { - /* tbuf.toString() is executed quickly since it does not - * need memory copy. Using a hand-written extensible - * byte-array class instead of StringBuffer is not a good idea - * for execution speed. Converting a byte array to a String - * object is very slow. Using an extensible char array - * might be OK. - */ - token.textValue = name; - return Identifier; - } - } - - private static final KeywordTable ktable = new KeywordTable(); - - static { - ktable.append("abstract", ABSTRACT); - ktable.append("boolean", BOOLEAN); - ktable.append("break", BREAK); - ktable.append("byte", BYTE); - ktable.append("case", CASE); - ktable.append("catch", CATCH); - ktable.append("char", CHAR); - ktable.append("class", CLASS); - ktable.append("const", CONST); - ktable.append("continue", CONTINUE); - ktable.append("default", DEFAULT); - ktable.append("do", DO); - ktable.append("double", DOUBLE); - ktable.append("else", ELSE); - ktable.append("extends", EXTENDS); - ktable.append("false", FALSE); - ktable.append("final", FINAL); - ktable.append("finally", FINALLY); - ktable.append("float", FLOAT); - ktable.append("for", FOR); - ktable.append("goto", GOTO); - ktable.append("if", IF); - ktable.append("implements", IMPLEMENTS); - ktable.append("import", IMPORT); - ktable.append("instanceof", INSTANCEOF); - ktable.append("int", INT); - ktable.append("interface", INTERFACE); - ktable.append("long", LONG); - ktable.append("native", NATIVE); - ktable.append("new", NEW); - ktable.append("null", NULL); - ktable.append("package", PACKAGE); - ktable.append("private", PRIVATE); - ktable.append("protected", PROTECTED); - ktable.append("public", PUBLIC); - ktable.append("return", RETURN); - ktable.append("short", SHORT); - ktable.append("static", STATIC); - ktable.append("strictfp", STRICT); - ktable.append("super", SUPER); - ktable.append("switch", SWITCH); - ktable.append("synchronized", SYNCHRONIZED); - ktable.append("this", THIS); - ktable.append("throw", THROW); - ktable.append("throws", THROWS); - ktable.append("transient", TRANSIENT); - ktable.append("true", TRUE); - ktable.append("try", TRY); - ktable.append("void", VOID); - ktable.append("volatile", VOLATILE); - ktable.append("while", WHILE); - } - - private static boolean isBlank(int c) { - return c == ' ' || c == '\t' || c == '\f' || c == '\r' - || c == '\n'; - } - - private static boolean isDigit(int c) { - return '0' <= c && c <= '9'; - } - - private void ungetc(int c) { - lastChar = c; - } - - public String getTextAround() { - int begin = position - 10; - if (begin < 0) - begin = 0; - - int end = position + 10; - if (end > maxlen) - end = maxlen; - - return input.substring(begin, end); - } - - private int getc() { - if (lastChar < 0) - if (position < maxlen) - return input.charAt(position++); - else - return -1; - else { - int c = lastChar; - lastChar = -1; - return c; - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/MemberCodeGen.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/MemberCodeGen.java deleted file mode 100644 index d384d705f..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/MemberCodeGen.java +++ /dev/null @@ -1,1147 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.compiler.ast.ASTree; - -import java.util.ArrayList; - -/* Code generator methods depending on javassist.* classes. - */ -public class MemberCodeGen extends com.fr.third.javassist.compiler.CodeGen { - protected MemberResolver resolver; - protected com.fr.third.javassist.CtClass thisClass; - protected com.fr.third.javassist.bytecode.MethodInfo thisMethod; - - protected boolean resultStatic; - - public MemberCodeGen(com.fr.third.javassist.bytecode.Bytecode b, com.fr.third.javassist.CtClass cc, com.fr.third.javassist.ClassPool cp) { - super(b); - resolver = new MemberResolver(cp); - thisClass = cc; - thisMethod = null; - } - - /** - * Returns the major version of the class file - * targeted by this compilation. - */ - public int getMajorVersion() { - com.fr.third.javassist.bytecode.ClassFile cf = thisClass.getClassFile2(); - if (cf == null) - return com.fr.third.javassist.bytecode.ClassFile.MAJOR_VERSION; // JDK 1.3 - else - return cf.getMajorVersion(); - } - - /** - * Records the currently compiled method. - */ - public void setThisMethod(com.fr.third.javassist.CtMethod m) { - thisMethod = m.getMethodInfo2(); - if (typeChecker != null) - typeChecker.setThisMethod(thisMethod); - } - - public com.fr.third.javassist.CtClass getThisClass() { return thisClass; } - - /** - * Returns the JVM-internal representation of this class name. - */ - protected String getThisName() { - return MemberResolver.javaToJvmName(thisClass.getName()); - } - - /** - * Returns the JVM-internal representation of this super class name. - */ - protected String getSuperName() throws com.fr.third.javassist.compiler.CompileError { - return MemberResolver.javaToJvmName( - MemberResolver.getSuperclass(thisClass).getName()); - } - - protected void insertDefaultSuperCall() throws com.fr.third.javassist.compiler.CompileError { - bytecode.addAload(0); - bytecode.addInvokespecial(MemberResolver.getSuperclass(thisClass), - "", "()V"); - } - - static class JsrHook extends ReturnHook { - ArrayList jsrList; - com.fr.third.javassist.compiler.CodeGen cgen; - int var; - - JsrHook(com.fr.third.javassist.compiler.CodeGen gen) { - super(gen); - jsrList = new ArrayList(); - cgen = gen; - var = -1; - } - - private int getVar(int size) { - if (var < 0) { - var = cgen.getMaxLocals(); - cgen.incMaxLocals(size); - } - - return var; - } - - private void jsrJmp(com.fr.third.javassist.bytecode.Bytecode b) { - b.addOpcode(com.fr.third.javassist.bytecode.Opcode.GOTO); - jsrList.add(new int[] {b.currentPc(), var}); - b.addIndex(0); - } - - protected boolean doit(com.fr.third.javassist.bytecode.Bytecode b, int opcode) { - switch (opcode) { - case com.fr.third.javassist.bytecode.Opcode.RETURN : - jsrJmp(b); - break; - case ARETURN : - b.addAstore(getVar(1)); - jsrJmp(b); - b.addAload(var); - break; - case IRETURN : - b.addIstore(getVar(1)); - jsrJmp(b); - b.addIload(var); - break; - case LRETURN : - b.addLstore(getVar(2)); - jsrJmp(b); - b.addLload(var); - break; - case DRETURN : - b.addDstore(getVar(2)); - jsrJmp(b); - b.addDload(var); - break; - case FRETURN : - b.addFstore(getVar(1)); - jsrJmp(b); - b.addFload(var); - break; - default : - throw new RuntimeException("fatal"); - } - - return false; - } - } - - static class JsrHook2 extends ReturnHook { - int var; - int target; - - JsrHook2(CodeGen gen, int[] retTarget) { - super(gen); - target = retTarget[0]; - var = retTarget[1]; - } - - protected boolean doit(com.fr.third.javassist.bytecode.Bytecode b, int opcode) { - switch (opcode) { - case com.fr.third.javassist.bytecode.Opcode.RETURN : - break; - case ARETURN : - b.addAstore(var); - break; - case IRETURN : - b.addIstore(var); - break; - case LRETURN : - b.addLstore(var); - break; - case DRETURN : - b.addDstore(var); - break; - case FRETURN : - b.addFstore(var); - break; - default : - throw new RuntimeException("fatal"); - } - - b.addOpcode(com.fr.third.javassist.bytecode.Opcode.GOTO); - b.addIndex(target - b.currentPc() + 3); - return true; - } - } - - protected void atTryStmnt(com.fr.third.javassist.compiler.ast.Stmnt st) throws com.fr.third.javassist.compiler.CompileError { - com.fr.third.javassist.bytecode.Bytecode bc = bytecode; - com.fr.third.javassist.compiler.ast.Stmnt body = (com.fr.third.javassist.compiler.ast.Stmnt)st.getLeft(); - if (body == null) - return; - - com.fr.third.javassist.compiler.ast.ASTList catchList = (com.fr.third.javassist.compiler.ast.ASTList)st.getRight().getLeft(); - com.fr.third.javassist.compiler.ast.Stmnt finallyBlock = (com.fr.third.javassist.compiler.ast.Stmnt)st.getRight().getRight().getLeft(); - ArrayList gotoList = new ArrayList(); - - JsrHook jsrHook = null; - if (finallyBlock != null) - jsrHook = new JsrHook(this); - - int start = bc.currentPc(); - body.accept(this); - int end = bc.currentPc(); - if (start == end) - throw new com.fr.third.javassist.compiler.CompileError("empty try block"); - - boolean tryNotReturn = !hasReturned; - if (tryNotReturn) { - bc.addOpcode(com.fr.third.javassist.bytecode.Opcode.GOTO); - gotoList.add(new Integer(bc.currentPc())); - bc.addIndex(0); // correct later - } - - int var = getMaxLocals(); - incMaxLocals(1); - while (catchList != null) { - // catch clause - com.fr.third.javassist.compiler.ast.Pair p = (com.fr.third.javassist.compiler.ast.Pair)catchList.head(); - catchList = catchList.tail(); - com.fr.third.javassist.compiler.ast.Declarator decl = (com.fr.third.javassist.compiler.ast.Declarator)p.getLeft(); - com.fr.third.javassist.compiler.ast.Stmnt block = (com.fr.third.javassist.compiler.ast.Stmnt)p.getRight(); - - decl.setLocalVar(var); - - com.fr.third.javassist.CtClass type = resolver.lookupClassByJvmName(decl.getClassName()); - decl.setClassName(MemberResolver.javaToJvmName(type.getName())); - bc.addExceptionHandler(start, end, bc.currentPc(), type); - bc.growStack(1); - bc.addAstore(var); - hasReturned = false; - if (block != null) - block.accept(this); - - if (!hasReturned) { - bc.addOpcode(com.fr.third.javassist.bytecode.Opcode.GOTO); - gotoList.add(new Integer(bc.currentPc())); - bc.addIndex(0); // correct later - tryNotReturn = true; - } - } - - if (finallyBlock != null) { - jsrHook.remove(this); - // catch (any) clause - int pcAnyCatch = bc.currentPc(); - bc.addExceptionHandler(start, pcAnyCatch, pcAnyCatch, 0); - bc.growStack(1); - bc.addAstore(var); - hasReturned = false; - finallyBlock.accept(this); - if (!hasReturned) { - bc.addAload(var); - bc.addOpcode(ATHROW); - } - - addFinally(jsrHook.jsrList, finallyBlock); - } - - int pcEnd = bc.currentPc(); - patchGoto(gotoList, pcEnd); - hasReturned = !tryNotReturn; - if (finallyBlock != null) { - if (tryNotReturn) - finallyBlock.accept(this); - } - } - - /** - * Adds a finally clause for earch return statement. - */ - private void addFinally(ArrayList returnList, com.fr.third.javassist.compiler.ast.Stmnt finallyBlock) - throws com.fr.third.javassist.compiler.CompileError - { - com.fr.third.javassist.bytecode.Bytecode bc = bytecode; - int n = returnList.size(); - for (int i = 0; i < n; ++i) { - final int[] ret = (int[])returnList.get(i); - int pc = ret[0]; - bc.write16bit(pc, bc.currentPc() - pc + 1); - ReturnHook hook = new JsrHook2(this, ret); - finallyBlock.accept(this); - hook.remove(this); - if (!hasReturned) { - bc.addOpcode(com.fr.third.javassist.bytecode.Opcode.GOTO); - bc.addIndex(pc + 3 - bc.currentPc()); - } - } - } - - public void atNewExpr(com.fr.third.javassist.compiler.ast.NewExpr expr) throws com.fr.third.javassist.compiler.CompileError { - if (expr.isArray()) - atNewArrayExpr(expr); - else { - com.fr.third.javassist.CtClass clazz = resolver.lookupClassByName(expr.getClassName()); - String cname = clazz.getName(); - com.fr.third.javassist.compiler.ast.ASTList args = expr.getArguments(); - bytecode.addNew(cname); - bytecode.addOpcode(DUP); - - atMethodCallCore(clazz, com.fr.third.javassist.bytecode.MethodInfo.nameInit, args, - false, true, -1, null); - - exprType = CLASS; - arrayDim = 0; - className = MemberResolver.javaToJvmName(cname); - } - } - - public void atNewArrayExpr(com.fr.third.javassist.compiler.ast.NewExpr expr) throws com.fr.third.javassist.compiler.CompileError { - int type = expr.getArrayType(); - com.fr.third.javassist.compiler.ast.ASTList size = expr.getArraySize(); - com.fr.third.javassist.compiler.ast.ASTList classname = expr.getClassName(); - com.fr.third.javassist.compiler.ast.ArrayInit init = expr.getInitializer(); - if (size.length() > 1) { - if (init != null) - throw new com.fr.third.javassist.compiler.CompileError( - "sorry, multi-dimensional array initializer " + - "for new is not supported"); - - atMultiNewArray(type, classname, size); - return; - } - - com.fr.third.javassist.compiler.ast.ASTree sizeExpr = size.head(); - atNewArrayExpr2(type, sizeExpr, com.fr.third.javassist.compiler.ast.Declarator.astToClassName(classname, '/'), init); - } - - private void atNewArrayExpr2(int type, com.fr.third.javassist.compiler.ast.ASTree sizeExpr, - String jvmClassname, com.fr.third.javassist.compiler.ast.ArrayInit init) throws com.fr.third.javassist.compiler.CompileError { - if (init == null) - if (sizeExpr == null) - throw new com.fr.third.javassist.compiler.CompileError("no array size"); - else - sizeExpr.accept(this); - else - if (sizeExpr == null) { - int s = init.length(); - bytecode.addIconst(s); - } - else - throw new com.fr.third.javassist.compiler.CompileError("unnecessary array size specified for new"); - - String elementClass; - if (type == CLASS) { - elementClass = resolveClassName(jvmClassname); - bytecode.addAnewarray(MemberResolver.jvmToJavaName(elementClass)); - } - else { - elementClass = null; - int atype = 0; - switch (type) { - case BOOLEAN : - atype = T_BOOLEAN; - break; - case CHAR : - atype = T_CHAR; - break; - case FLOAT : - atype = T_FLOAT; - break; - case DOUBLE : - atype = T_DOUBLE; - break; - case BYTE : - atype = T_BYTE; - break; - case SHORT : - atype = T_SHORT; - break; - case INT : - atype = T_INT; - break; - case LONG : - atype = T_LONG; - break; - default : - badNewExpr(); - break; - } - - bytecode.addOpcode(NEWARRAY); - bytecode.add(atype); - } - - if (init != null) { - int s = init.length(); - com.fr.third.javassist.compiler.ast.ASTList list = init; - for (int i = 0; i < s; i++) { - bytecode.addOpcode(DUP); - bytecode.addIconst(i); - list.head().accept(this); - if (!isRefType(type)) - atNumCastExpr(exprType, type); - - bytecode.addOpcode(getArrayWriteOp(type, 0)); - list = list.tail(); - } - } - - exprType = type; - arrayDim = 1; - className = elementClass; - } - - private static void badNewExpr() throws com.fr.third.javassist.compiler.CompileError { - throw new com.fr.third.javassist.compiler.CompileError("bad new expression"); - } - - protected void atArrayVariableAssign(com.fr.third.javassist.compiler.ast.ArrayInit init, int varType, - int varArray, String varClass) throws com.fr.third.javassist.compiler.CompileError { - atNewArrayExpr2(varType, null, varClass, init); - } - - public void atArrayInit(com.fr.third.javassist.compiler.ast.ArrayInit init) throws com.fr.third.javassist.compiler.CompileError { - throw new com.fr.third.javassist.compiler.CompileError("array initializer is not supported"); - } - - protected void atMultiNewArray(int type, com.fr.third.javassist.compiler.ast.ASTList classname, com.fr.third.javassist.compiler.ast.ASTList size) - throws com.fr.third.javassist.compiler.CompileError - { - int count, dim; - dim = size.length(); - for (count = 0; size != null; size = size.tail()) { - com.fr.third.javassist.compiler.ast.ASTree s = size.head(); - if (s == null) - break; // int[][][] a = new int[3][4][]; - - ++count; - s.accept(this); - if (exprType != INT) - throw new com.fr.third.javassist.compiler.CompileError("bad type for array size"); - } - - String desc; - exprType = type; - arrayDim = dim; - if (type == CLASS) { - className = resolveClassName(classname); - desc = toJvmArrayName(className, dim); - } - else - desc = toJvmTypeName(type, dim); - - bytecode.addMultiNewarray(desc, count); - } - - public void atCallExpr(com.fr.third.javassist.compiler.ast.CallExpr expr) throws com.fr.third.javassist.compiler.CompileError { - String mname = null; - com.fr.third.javassist.CtClass targetClass = null; - com.fr.third.javassist.compiler.ast.ASTree method = expr.oprand1(); - com.fr.third.javassist.compiler.ast.ASTList args = (com.fr.third.javassist.compiler.ast.ASTList)expr.oprand2(); - boolean isStatic = false; - boolean isSpecial = false; - int aload0pos = -1; - - MemberResolver.Method cached = expr.getMethod(); - if (method instanceof com.fr.third.javassist.compiler.ast.Member) { - mname = ((com.fr.third.javassist.compiler.ast.Member)method).get(); - targetClass = thisClass; - if (inStaticMethod || (cached != null && cached.isStatic())) - isStatic = true; // should be static - else { - aload0pos = bytecode.currentPc(); - bytecode.addAload(0); // this - } - } - else if (method instanceof com.fr.third.javassist.compiler.ast.Keyword) { // constructor - isSpecial = true; - mname = com.fr.third.javassist.bytecode.MethodInfo.nameInit; // - targetClass = thisClass; - if (inStaticMethod) - throw new com.fr.third.javassist.compiler.CompileError("a constructor cannot be static"); - else - bytecode.addAload(0); // this - - if (((com.fr.third.javassist.compiler.ast.Keyword)method).get() == SUPER) - targetClass = MemberResolver.getSuperclass(targetClass); - } - else if (method instanceof com.fr.third.javassist.compiler.ast.Expr) { - com.fr.third.javassist.compiler.ast.Expr e = (com.fr.third.javassist.compiler.ast.Expr)method; - mname = ((com.fr.third.javassist.compiler.ast.Symbol)e.oprand2()).get(); - int op = e.getOperator(); - if (op == MEMBER) { // static method - targetClass - = resolver.lookupClass(((com.fr.third.javassist.compiler.ast.Symbol)e.oprand1()).get(), false); - isStatic = true; - } - else if (op == '.') { - com.fr.third.javassist.compiler.ast.ASTree target = e.oprand1(); - if (target instanceof com.fr.third.javassist.compiler.ast.Keyword) - if (((com.fr.third.javassist.compiler.ast.Keyword)target).get() == SUPER) - isSpecial = true; - - try { - target.accept(this); - } - catch (NoFieldException nfe) { - if (nfe.getExpr() != target) - throw nfe; - - // it should be a static method. - exprType = CLASS; - arrayDim = 0; - className = nfe.getField(); // JVM-internal - isStatic = true; - } - - if (arrayDim > 0) - targetClass = resolver.lookupClass(javaLangObject, true); - else if (exprType == CLASS /* && arrayDim == 0 */) - targetClass = resolver.lookupClassByJvmName(className); - else - badMethod(); - } - else - badMethod(); - } - else - fatal(); - - atMethodCallCore(targetClass, mname, args, isStatic, isSpecial, - aload0pos, cached); - } - - private static void badMethod() throws com.fr.third.javassist.compiler.CompileError { - throw new com.fr.third.javassist.compiler.CompileError("bad method"); - } - - /* - * atMethodCallCore() is also called by doit() in NewExpr.ProceedForNew - * - * @param targetClass the class at which method lookup starts. - * @param found not null if the method look has been already done. - */ - public void atMethodCallCore(com.fr.third.javassist.CtClass targetClass, String mname, - com.fr.third.javassist.compiler.ast.ASTList args, boolean isStatic, boolean isSpecial, - int aload0pos, MemberResolver.Method found) - throws com.fr.third.javassist.compiler.CompileError - { - int nargs = getMethodArgsLength(args); - int[] types = new int[nargs]; - int[] dims = new int[nargs]; - String[] cnames = new String[nargs]; - - if (!isStatic && found != null && found.isStatic()) { - bytecode.addOpcode(POP); - isStatic = true; - } - - int stack = bytecode.getStackDepth(); - - // generate code for evaluating arguments. - atMethodArgs(args, types, dims, cnames); - - // used by invokeinterface - int count = bytecode.getStackDepth() - stack + 1; - - if (found == null) - found = resolver.lookupMethod(targetClass, thisClass, thisMethod, - mname, types, dims, cnames); - - if (found == null) { - String msg; - if (mname.equals(com.fr.third.javassist.bytecode.MethodInfo.nameInit)) - msg = "constructor not found"; - else - msg = "Method " + mname + " not found in " - + targetClass.getName(); - - throw new com.fr.third.javassist.compiler.CompileError(msg); - } - - atMethodCallCore2(targetClass, mname, isStatic, isSpecial, - aload0pos, count, found); - } - - private void atMethodCallCore2(com.fr.third.javassist.CtClass targetClass, String mname, - boolean isStatic, boolean isSpecial, - int aload0pos, int count, - MemberResolver.Method found) - throws com.fr.third.javassist.compiler.CompileError - { - com.fr.third.javassist.CtClass declClass = found.declaring; - com.fr.third.javassist.bytecode.MethodInfo minfo = found.info; - String desc = minfo.getDescriptor(); - int acc = minfo.getAccessFlags(); - - if (mname.equals(com.fr.third.javassist.bytecode.MethodInfo.nameInit)) { - isSpecial = true; - if (declClass != targetClass) - throw new com.fr.third.javassist.compiler.CompileError("no such constructor: " + targetClass.getName()); - - if (declClass != thisClass && com.fr.third.javassist.bytecode.AccessFlag.isPrivate(acc)) { - desc = getAccessibleConstructor(desc, declClass, minfo); - bytecode.addOpcode(com.fr.third.javassist.bytecode.Opcode.ACONST_NULL); // the last parameter - } - } - else if (com.fr.third.javassist.bytecode.AccessFlag.isPrivate(acc)) - if (declClass == thisClass) - isSpecial = true; - else { - isSpecial = false; - isStatic = true; - String origDesc = desc; - if ((acc & com.fr.third.javassist.bytecode.AccessFlag.STATIC) == 0) - desc = com.fr.third.javassist.bytecode.Descriptor.insertParameter(declClass.getName(), - origDesc); - - acc = com.fr.third.javassist.bytecode.AccessFlag.setPackage(acc) | com.fr.third.javassist.bytecode.AccessFlag.STATIC; - mname = getAccessiblePrivate(mname, origDesc, desc, - minfo, declClass); - } - - boolean popTarget = false; - if ((acc & com.fr.third.javassist.bytecode.AccessFlag.STATIC) != 0) { - if (!isStatic) { - /* this method is static but the target object is - on stack. It must be popped out. If aload0pos >= 0, - then the target object was pushed by aload_0. It is - overwritten by NOP. - */ - isStatic = true; - if (aload0pos >= 0) - bytecode.write(aload0pos, NOP); - else - popTarget = true; - } - - bytecode.addInvokestatic(declClass, mname, desc); - } - else if (isSpecial) // if (isSpecial && notStatic(acc)) - bytecode.addInvokespecial(declClass, mname, desc); - else { - if (!com.fr.third.javassist.Modifier.isPublic(declClass.getModifiers()) - || declClass.isInterface() != targetClass.isInterface()) - declClass = targetClass; - - if (declClass.isInterface()) - bytecode.addInvokeinterface(declClass, mname, desc, count); - else - if (isStatic) - throw new com.fr.third.javassist.compiler.CompileError(mname + " is not static"); - else - bytecode.addInvokevirtual(declClass, mname, desc); - } - - setReturnType(desc, isStatic, popTarget); - } - - /* - * Finds (or adds if necessary) a hidden accessor if the method - * is in an enclosing class. - * - * @param desc the descriptor of the method. - * @param declClass the class declaring the method. - */ - protected String getAccessiblePrivate(String methodName, String desc, - String newDesc, com.fr.third.javassist.bytecode.MethodInfo minfo, - com.fr.third.javassist.CtClass declClass) - throws com.fr.third.javassist.compiler.CompileError - { - if (isEnclosing(declClass, thisClass)) { - com.fr.third.javassist.compiler.AccessorMaker maker = declClass.getAccessorMaker(); - if (maker != null) - return maker.getMethodAccessor(methodName, desc, newDesc, - minfo); - } - - throw new com.fr.third.javassist.compiler.CompileError("Method " + methodName - + " is private"); - } - - /* - * Finds (or adds if necessary) a hidden constructor if the given - * constructor is in an enclosing class. - * - * @param desc the descriptor of the constructor. - * @param declClass the class declaring the constructor. - * @param minfo the method info of the constructor. - * @return the descriptor of the hidden constructor. - */ - protected String getAccessibleConstructor(String desc, com.fr.third.javassist.CtClass declClass, - com.fr.third.javassist.bytecode.MethodInfo minfo) - throws com.fr.third.javassist.compiler.CompileError - { - if (isEnclosing(declClass, thisClass)) { - com.fr.third.javassist.compiler.AccessorMaker maker = declClass.getAccessorMaker(); - if (maker != null) - return maker.getConstructor(declClass, desc, minfo); - } - - throw new com.fr.third.javassist.compiler.CompileError("the called constructor is private in " - + declClass.getName()); - } - - private boolean isEnclosing(com.fr.third.javassist.CtClass outer, com.fr.third.javassist.CtClass inner) { - try { - while (inner != null) { - inner = inner.getDeclaringClass(); - if (inner == outer) - return true; - } - } - catch (com.fr.third.javassist.NotFoundException e) {} - return false; - } - - public int getMethodArgsLength(com.fr.third.javassist.compiler.ast.ASTList args) { - return com.fr.third.javassist.compiler.ast.ASTList.length(args); - } - - public void atMethodArgs(com.fr.third.javassist.compiler.ast.ASTList args, int[] types, int[] dims, - String[] cnames) throws com.fr.third.javassist.compiler.CompileError { - int i = 0; - while (args != null) { - com.fr.third.javassist.compiler.ast.ASTree a = args.head(); - a.accept(this); - types[i] = exprType; - dims[i] = arrayDim; - cnames[i] = className; - ++i; - args = args.tail(); - } - } - - void setReturnType(String desc, boolean isStatic, boolean popTarget) - throws com.fr.third.javassist.compiler.CompileError - { - int i = desc.indexOf(')'); - if (i < 0) - badMethod(); - - char c = desc.charAt(++i); - int dim = 0; - while (c == '[') { - ++dim; - c = desc.charAt(++i); - } - - arrayDim = dim; - if (c == 'L') { - int j = desc.indexOf(';', i + 1); - if (j < 0) - badMethod(); - - exprType = CLASS; - className = desc.substring(i + 1, j); - } - else { - exprType = MemberResolver.descToType(c); - className = null; - } - - int etype = exprType; - if (isStatic) { - if (popTarget) { - if (is2word(etype, dim)) { - bytecode.addOpcode(DUP2_X1); - bytecode.addOpcode(POP2); - bytecode.addOpcode(POP); - } - else if (etype == VOID) - bytecode.addOpcode(POP); - else { - bytecode.addOpcode(SWAP); - bytecode.addOpcode(POP); - } - } - } - } - - protected void atFieldAssign(com.fr.third.javassist.compiler.ast.Expr expr, int op, com.fr.third.javassist.compiler.ast.ASTree left, - com.fr.third.javassist.compiler.ast.ASTree right, boolean doDup) throws com.fr.third.javassist.compiler.CompileError - { - com.fr.third.javassist.CtField f = fieldAccess(left, false); - boolean is_static = resultStatic; - if (op != '=' && !is_static) - bytecode.addOpcode(DUP); - - int fi; - if (op == '=') { - com.fr.third.javassist.bytecode.FieldInfo finfo = f.getFieldInfo2(); - setFieldType(finfo); - com.fr.third.javassist.compiler.AccessorMaker maker = isAccessibleField(f, finfo); - if (maker == null) - fi = addFieldrefInfo(f, finfo); - else - fi = 0; - } - else - fi = atFieldRead(f, is_static); - - int fType = exprType; - int fDim = arrayDim; - String cname = className; - - atAssignCore(expr, op, right, fType, fDim, cname); - - boolean is2w = is2word(fType, fDim); - if (doDup) { - int dup_code; - if (is_static) - dup_code = (is2w ? DUP2 : DUP); - else - dup_code = (is2w ? DUP2_X1 : DUP_X1); - - bytecode.addOpcode(dup_code); - } - - atFieldAssignCore(f, is_static, fi, is2w); - - exprType = fType; - arrayDim = fDim; - className = cname; - } - - /* If fi == 0, the field must be a private field in an enclosing class. - */ - private void atFieldAssignCore(com.fr.third.javassist.CtField f, boolean is_static, int fi, - boolean is2byte) throws com.fr.third.javassist.compiler.CompileError { - if (fi != 0) { - if (is_static) { - bytecode.add(PUTSTATIC); - bytecode.growStack(is2byte ? -2 : -1); - } - else { - bytecode.add(PUTFIELD); - bytecode.growStack(is2byte ? -3 : -2); - } - - bytecode.addIndex(fi); - } - else { - com.fr.third.javassist.CtClass declClass = f.getDeclaringClass(); - com.fr.third.javassist.compiler.AccessorMaker maker = declClass.getAccessorMaker(); - // make should be non null. - com.fr.third.javassist.bytecode.FieldInfo finfo = f.getFieldInfo2(); - com.fr.third.javassist.bytecode.MethodInfo minfo = maker.getFieldSetter(finfo, is_static); - bytecode.addInvokestatic(declClass, minfo.getName(), - minfo.getDescriptor()); - } - } - - /* overwritten in JvstCodeGen. - */ - public void atMember(com.fr.third.javassist.compiler.ast.Member mem) throws com.fr.third.javassist.compiler.CompileError { - atFieldRead(mem); - } - - protected void atFieldRead(com.fr.third.javassist.compiler.ast.ASTree expr) throws com.fr.third.javassist.compiler.CompileError - { - com.fr.third.javassist.CtField f = fieldAccess(expr, true); - if (f == null) { - atArrayLength(expr); - return; - } - - boolean is_static = resultStatic; - com.fr.third.javassist.compiler.ast.ASTree cexpr = TypeChecker.getConstantFieldValue(f); - if (cexpr == null) - atFieldRead(f, is_static); - else { - cexpr.accept(this); - setFieldType(f.getFieldInfo2()); - } - } - - private void atArrayLength(com.fr.third.javassist.compiler.ast.ASTree expr) throws com.fr.third.javassist.compiler.CompileError { - if (arrayDim == 0) - throw new com.fr.third.javassist.compiler.CompileError(".length applied to a non array"); - - bytecode.addOpcode(ARRAYLENGTH); - exprType = INT; - arrayDim = 0; - } - - /** - * Generates bytecode for reading a field value. - * It returns a fieldref_info index or zero if the field is a private - * one declared in an enclosing class. - */ - private int atFieldRead(com.fr.third.javassist.CtField f, boolean isStatic) throws com.fr.third.javassist.compiler.CompileError { - com.fr.third.javassist.bytecode.FieldInfo finfo = f.getFieldInfo2(); - boolean is2byte = setFieldType(finfo); - com.fr.third.javassist.compiler.AccessorMaker maker = isAccessibleField(f, finfo); - if (maker != null) { - com.fr.third.javassist.bytecode.MethodInfo minfo = maker.getFieldGetter(finfo, isStatic); - bytecode.addInvokestatic(f.getDeclaringClass(), minfo.getName(), - minfo.getDescriptor()); - return 0; - } - else { - int fi = addFieldrefInfo(f, finfo); - if (isStatic) { - bytecode.add(GETSTATIC); - bytecode.growStack(is2byte ? 2 : 1); - } - else { - bytecode.add(GETFIELD); - bytecode.growStack(is2byte ? 1 : 0); - } - - bytecode.addIndex(fi); - return fi; - } - } - - /** - * Returns null if the field is accessible. Otherwise, it throws - * an exception or it returns AccessorMaker if the field is a private - * one declared in an enclosing class. - */ - private com.fr.third.javassist.compiler.AccessorMaker isAccessibleField(com.fr.third.javassist.CtField f, com.fr.third.javassist.bytecode.FieldInfo finfo) - throws com.fr.third.javassist.compiler.CompileError - { - if (com.fr.third.javassist.bytecode.AccessFlag.isPrivate(finfo.getAccessFlags()) - && f.getDeclaringClass() != thisClass) { - com.fr.third.javassist.CtClass declClass = f.getDeclaringClass(); - if (isEnclosing(declClass, thisClass)) { - AccessorMaker maker = declClass.getAccessorMaker(); - if (maker != null) - return maker; - else - throw new com.fr.third.javassist.compiler.CompileError("fatal error. bug?"); - } - else - throw new com.fr.third.javassist.compiler.CompileError("Field " + f.getName() + " in " - + declClass.getName() + " is private."); - } - - return null; // accessible field - } - - /** - * Sets exprType, arrayDim, and className. - * - * @return true if the field type is long or double. - */ - private boolean setFieldType(com.fr.third.javassist.bytecode.FieldInfo finfo) throws com.fr.third.javassist.compiler.CompileError { - String type = finfo.getDescriptor(); - - int i = 0; - int dim = 0; - char c = type.charAt(i); - while (c == '[') { - ++dim; - c = type.charAt(++i); - } - - arrayDim = dim; - exprType = MemberResolver.descToType(c); - - if (c == 'L') - className = type.substring(i + 1, type.indexOf(';', i + 1)); - else - className = null; - - boolean is2byte = dim == 0 && (c == 'J' || c == 'D'); - return is2byte; - } - - private int addFieldrefInfo(com.fr.third.javassist.CtField f, com.fr.third.javassist.bytecode.FieldInfo finfo) { - ConstPool cp = bytecode.getConstPool(); - String cname = f.getDeclaringClass().getName(); - int ci = cp.addClassInfo(cname); - String name = finfo.getName(); - String type = finfo.getDescriptor(); - return cp.addFieldrefInfo(ci, name, type); - } - - protected void atClassObject2(String cname) throws com.fr.third.javassist.compiler.CompileError { - if (getMajorVersion() < com.fr.third.javassist.bytecode.ClassFile.JAVA_5) - super.atClassObject2(cname); - else - bytecode.addLdc(bytecode.getConstPool().addClassInfo(cname)); - } - - protected void atFieldPlusPlus(int token, boolean isPost, - com.fr.third.javassist.compiler.ast.ASTree oprand, com.fr.third.javassist.compiler.ast.Expr expr, boolean doDup) - throws com.fr.third.javassist.compiler.CompileError - { - com.fr.third.javassist.CtField f = fieldAccess(oprand, false); - boolean is_static = resultStatic; - if (!is_static) - bytecode.addOpcode(DUP); - - int fi = atFieldRead(f, is_static); - int t = exprType; - boolean is2w = is2word(t, arrayDim); - - int dup_code; - if (is_static) - dup_code = (is2w ? DUP2 : DUP); - else - dup_code = (is2w ? DUP2_X1 : DUP_X1); - - atPlusPlusCore(dup_code, doDup, token, isPost, expr); - atFieldAssignCore(f, is_static, fi, is2w); - } - - /* This method also returns a value in resultStatic. - * - * @param acceptLength true if array length is acceptable - */ - protected com.fr.third.javassist.CtField fieldAccess(ASTree expr, boolean acceptLength) - throws com.fr.third.javassist.compiler.CompileError - { - if (expr instanceof com.fr.third.javassist.compiler.ast.Member) { - String name = ((com.fr.third.javassist.compiler.ast.Member)expr).get(); - com.fr.third.javassist.CtField f = null; - try { - f = thisClass.getField(name); - } - catch (com.fr.third.javassist.NotFoundException e) { - // EXPR might be part of a static member access? - throw new NoFieldException(name, expr); - } - - boolean is_static = com.fr.third.javassist.Modifier.isStatic(f.getModifiers()); - if (!is_static) - if (inStaticMethod) - throw new com.fr.third.javassist.compiler.CompileError( - "not available in a static method: " + name); - else - bytecode.addAload(0); // this - - resultStatic = is_static; - return f; - } - else if (expr instanceof com.fr.third.javassist.compiler.ast.Expr) { - com.fr.third.javassist.compiler.ast.Expr e = (com.fr.third.javassist.compiler.ast.Expr)expr; - int op = e.getOperator(); - if (op == MEMBER) { - /* static member by # (extension by Javassist) - * For example, if int.class is parsed, the resulting tree - * is (# "java.lang.Integer" "TYPE"). - */ - com.fr.third.javassist.CtField f = resolver.lookupField(((com.fr.third.javassist.compiler.ast.Symbol)e.oprand1()).get(), - (com.fr.third.javassist.compiler.ast.Symbol)e.oprand2()); - resultStatic = true; - return f; - } - else if (op == '.') { - com.fr.third.javassist.CtField f = null; - try { - e.oprand1().accept(this); - /* Don't call lookupFieldByJvmName2(). - * The left operand of . is not a class name but - * a normal expression. - */ - if (exprType == CLASS && arrayDim == 0) - f = resolver.lookupFieldByJvmName(className, - (com.fr.third.javassist.compiler.ast.Symbol)e.oprand2()); - else if (acceptLength && arrayDim > 0 - && ((com.fr.third.javassist.compiler.ast.Symbol)e.oprand2()).get().equals("length")) - return null; // expr is an array length. - else - badLvalue(); - - boolean is_static = com.fr.third.javassist.Modifier.isStatic(f.getModifiers()); - if (is_static) - bytecode.addOpcode(POP); - - resultStatic = is_static; - return f; - } - catch (NoFieldException nfe) { - if (nfe.getExpr() != e.oprand1()) - throw nfe; - - /* EXPR should be a static field. - * If EXPR might be part of a qualified class name, - * lookupFieldByJvmName2() throws NoFieldException. - */ - com.fr.third.javassist.compiler.ast.Symbol fname = (com.fr.third.javassist.compiler.ast.Symbol)e.oprand2(); - String cname = nfe.getField(); - f = resolver.lookupFieldByJvmName2(cname, fname, expr); - resultStatic = true; - return f; - } - } - else - badLvalue(); - } - else - badLvalue(); - - resultStatic = false; - return null; // never reach - } - - private static void badLvalue() throws com.fr.third.javassist.compiler.CompileError { - throw new com.fr.third.javassist.compiler.CompileError("bad l-value"); - } - - public com.fr.third.javassist.CtClass[] makeParamList(com.fr.third.javassist.compiler.ast.MethodDecl md) throws com.fr.third.javassist.compiler.CompileError { - com.fr.third.javassist.CtClass[] params; - com.fr.third.javassist.compiler.ast.ASTList plist = md.getParams(); - if (plist == null) - params = new com.fr.third.javassist.CtClass[0]; - else { - int i = 0; - params = new com.fr.third.javassist.CtClass[plist.length()]; - while (plist != null) { - params[i++] = resolver.lookupClass((com.fr.third.javassist.compiler.ast.Declarator)plist.head()); - plist = plist.tail(); - } - } - - return params; - } - - public com.fr.third.javassist.CtClass[] makeThrowsList(com.fr.third.javassist.compiler.ast.MethodDecl md) throws com.fr.third.javassist.compiler.CompileError { - com.fr.third.javassist.CtClass[] clist; - com.fr.third.javassist.compiler.ast.ASTList list = md.getThrows(); - if (list == null) - return null; - else { - int i = 0; - clist = new CtClass[list.length()]; - while (list != null) { - clist[i++] = resolver.lookupClassByName((com.fr.third.javassist.compiler.ast.ASTList)list.head()); - list = list.tail(); - } - - return clist; - } - } - - /* Converts a class name into a JVM-internal representation. - * - * It may also expand a simple class name to java.lang.*. - * For example, this converts Object into java/lang/Object. - */ - protected String resolveClassName(com.fr.third.javassist.compiler.ast.ASTList name) throws com.fr.third.javassist.compiler.CompileError { - return resolver.resolveClassName(name); - } - - /* Expands a simple class name to java.lang.*. - * For example, this converts Object into java/lang/Object. - */ - protected String resolveClassName(String jvmName) throws CompileError { - return resolver.resolveJvmClassName(jvmName); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/MemberResolver.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/MemberResolver.java deleted file mode 100644 index a6cb4cfc4..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/MemberResolver.java +++ /dev/null @@ -1,605 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -import java.util.Hashtable; -import java.lang.ref.WeakReference; -import java.util.WeakHashMap; -import java.util.List; -import java.util.Iterator; - -import com.fr.third.javassist.Modifier; -import com.fr.third.javassist.bytecode.AccessFlag; -import com.fr.third.javassist.compiler.ast.ASTree; - -/* Code generator methods depending on javassist.* classes. - */ -public class MemberResolver implements TokenId { - private com.fr.third.javassist.ClassPool classPool; - - public MemberResolver(com.fr.third.javassist.ClassPool cp) { - classPool = cp; - } - - public com.fr.third.javassist.ClassPool getClassPool() { return classPool; } - - private static void fatal() throws com.fr.third.javassist.compiler.CompileError { - throw new com.fr.third.javassist.compiler.CompileError("fatal"); - } - - public static class Method { - public com.fr.third.javassist.CtClass declaring; - public com.fr.third.javassist.bytecode.MethodInfo info; - public int notmatch; - - public Method(com.fr.third.javassist.CtClass c, com.fr.third.javassist.bytecode.MethodInfo i, int n) { - declaring = c; - info = i; - notmatch = n; - } - - /** - * Returns true if the invoked method is static. - */ - public boolean isStatic() { - int acc = info.getAccessFlags(); - return (acc & AccessFlag.STATIC) != 0; - } - } - - public Method lookupMethod(com.fr.third.javassist.CtClass clazz, com.fr.third.javassist.CtClass currentClass, com.fr.third.javassist.bytecode.MethodInfo current, - String methodName, - int[] argTypes, int[] argDims, - String[] argClassNames) - throws com.fr.third.javassist.compiler.CompileError - { - Method maybe = null; - // to enable the creation of a recursively called method - if (current != null && clazz == currentClass) - if (current.getName().equals(methodName)) { - int res = compareSignature(current.getDescriptor(), - argTypes, argDims, argClassNames); - if (res != NO) { - Method r = new Method(clazz, current, res); - if (res == YES) - return r; - else - maybe = r; - } - } - - Method m = lookupMethod(clazz, methodName, argTypes, argDims, - argClassNames, maybe != null); - if (m != null) - return m; - else - return maybe; - } - - private Method lookupMethod(com.fr.third.javassist.CtClass clazz, String methodName, - int[] argTypes, int[] argDims, - String[] argClassNames, boolean onlyExact) - throws com.fr.third.javassist.compiler.CompileError - { - Method maybe = null; - com.fr.third.javassist.bytecode.ClassFile cf = clazz.getClassFile2(); - // If the class is an array type, the class file is null. - // If so, search the super class java.lang.Object for clone() etc. - if (cf != null) { - List list = cf.getMethods(); - int n = list.size(); - for (int i = 0; i < n; ++i) { - com.fr.third.javassist.bytecode.MethodInfo minfo = (com.fr.third.javassist.bytecode.MethodInfo)list.get(i); - if (minfo.getName().equals(methodName)) { - int res = compareSignature(minfo.getDescriptor(), - argTypes, argDims, argClassNames); - if (res != NO) { - Method r = new Method(clazz, minfo, res); - if (res == YES) - return r; - else if (maybe == null || maybe.notmatch > res) - maybe = r; - } - } - } - } - - if (onlyExact) - maybe = null; - else - onlyExact = maybe != null; - - int mod = clazz.getModifiers(); - boolean isIntf = com.fr.third.javassist.Modifier.isInterface(mod); - try { - // skip searching java.lang.Object if clazz is an interface type. - if (!isIntf) { - com.fr.third.javassist.CtClass pclazz = clazz.getSuperclass(); - if (pclazz != null) { - Method r = lookupMethod(pclazz, methodName, argTypes, - argDims, argClassNames, onlyExact); - if (r != null) - return r; - } - } - } - catch (com.fr.third.javassist.NotFoundException e) {} - - if (isIntf || com.fr.third.javassist.Modifier.isAbstract(mod)) - try { - com.fr.third.javassist.CtClass[] ifs = clazz.getInterfaces(); - int size = ifs.length; - for (int i = 0; i < size; ++i) { - Method r = lookupMethod(ifs[i], methodName, - argTypes, argDims, argClassNames, - onlyExact); - if (r != null) - return r; - } - - if (isIntf) { - // finally search java.lang.Object. - com.fr.third.javassist.CtClass pclazz = clazz.getSuperclass(); - if (pclazz != null) { - Method r = lookupMethod(pclazz, methodName, argTypes, - argDims, argClassNames, onlyExact); - if (r != null) - return r; - } - } - } - catch (com.fr.third.javassist.NotFoundException e) {} - - return maybe; - } - - private static final int YES = 0; - private static final int NO = -1; - - /* - * Returns YES if actual parameter types matches the given signature. - * - * argTypes, argDims, and argClassNames represent actual parameters. - * - * This method does not correctly implement the Java method dispatch - * algorithm. - * - * If some of the parameter types exactly match but others are subtypes of - * the corresponding type in the signature, this method returns the number - * of parameter types that do not exactly match. - */ - private int compareSignature(String desc, int[] argTypes, - int[] argDims, String[] argClassNames) - throws com.fr.third.javassist.compiler.CompileError - { - int result = YES; - int i = 1; - int nArgs = argTypes.length; - if (nArgs != com.fr.third.javassist.bytecode.Descriptor.numOfParameters(desc)) - return NO; - - int len = desc.length(); - for (int n = 0; i < len; ++n) { - char c = desc.charAt(i++); - if (c == ')') - return (n == nArgs ? result : NO); - else if (n >= nArgs) - return NO; - - int dim = 0; - while (c == '[') { - ++dim; - c = desc.charAt(i++); - } - - if (argTypes[n] == NULL) { - if (dim == 0 && c != 'L') - return NO; - - if (c == 'L') - i = desc.indexOf(';', i) + 1; - } - else if (argDims[n] != dim) { - if (!(dim == 0 && c == 'L' - && desc.startsWith("java/lang/Object;", i))) - return NO; - - // if the thread reaches here, c must be 'L'. - i = desc.indexOf(';', i) + 1; - result++; - if (i <= 0) - return NO; // invalid descriptor? - } - else if (c == 'L') { // not compare - int j = desc.indexOf(';', i); - if (j < 0 || argTypes[n] != CLASS) - return NO; - - String cname = desc.substring(i, j); - if (!cname.equals(argClassNames[n])) { - com.fr.third.javassist.CtClass clazz = lookupClassByJvmName(argClassNames[n]); - try { - if (clazz.subtypeOf(lookupClassByJvmName(cname))) - result++; - else - return NO; - } - catch (com.fr.third.javassist.NotFoundException e) { - result++; // should be NO? - } - } - - i = j + 1; - } - else { - int t = descToType(c); - int at = argTypes[n]; - if (t != at) - if (t == INT - && (at == SHORT || at == BYTE || at == CHAR)) - result++; - else - return NO; - } - } - - return NO; - } - - /** - * Only used by fieldAccess() in MemberCodeGen and TypeChecker. - * - * @param jvmClassName a JVM class name. e.g. java/lang/String - * @see #lookupClass(String, boolean) - */ - public com.fr.third.javassist.CtField lookupFieldByJvmName2(String jvmClassName, com.fr.third.javassist.compiler.ast.Symbol fieldSym, - ASTree expr) throws NoFieldException - { - String field = fieldSym.get(); - com.fr.third.javassist.CtClass cc = null; - try { - cc = lookupClass(jvmToJavaName(jvmClassName), true); - } - catch (com.fr.third.javassist.compiler.CompileError e) { - // EXPR might be part of a qualified class name. - throw new NoFieldException(jvmClassName + "/" + field, expr); - } - - try { - return cc.getField(field); - } - catch (com.fr.third.javassist.NotFoundException e) { - // maybe an inner class. - jvmClassName = javaToJvmName(cc.getName()); - throw new NoFieldException(jvmClassName + "$" + field, expr); - } - } - - /** - * @param jvmClassName a JVM class name. e.g. java/lang/String - */ - public com.fr.third.javassist.CtField lookupFieldByJvmName(String jvmClassName, com.fr.third.javassist.compiler.ast.Symbol fieldName) - throws com.fr.third.javassist.compiler.CompileError - { - return lookupField(jvmToJavaName(jvmClassName), fieldName); - } - - /** - * @param name a qualified class name. e.g. java.lang.String - */ - public com.fr.third.javassist.CtField lookupField(String className, com.fr.third.javassist.compiler.ast.Symbol fieldName) - throws com.fr.third.javassist.compiler.CompileError - { - com.fr.third.javassist.CtClass cc = lookupClass(className, false); - try { - return cc.getField(fieldName.get()); - } - catch (com.fr.third.javassist.NotFoundException e) {} - throw new com.fr.third.javassist.compiler.CompileError("no such field: " + fieldName.get()); - } - - public com.fr.third.javassist.CtClass lookupClassByName(com.fr.third.javassist.compiler.ast.ASTList name) throws com.fr.third.javassist.compiler.CompileError { - return lookupClass(com.fr.third.javassist.compiler.ast.Declarator.astToClassName(name, '.'), false); - } - - public com.fr.third.javassist.CtClass lookupClassByJvmName(String jvmName) throws com.fr.third.javassist.compiler.CompileError { - return lookupClass(jvmToJavaName(jvmName), false); - } - - public com.fr.third.javassist.CtClass lookupClass(com.fr.third.javassist.compiler.ast.Declarator decl) throws com.fr.third.javassist.compiler.CompileError { - return lookupClass(decl.getType(), decl.getArrayDim(), - decl.getClassName()); - } - - /** - * @parma classname jvm class name. - */ - public com.fr.third.javassist.CtClass lookupClass(int type, int dim, String classname) - throws com.fr.third.javassist.compiler.CompileError - { - String cname = ""; - com.fr.third.javassist.CtClass clazz; - if (type == CLASS) { - clazz = lookupClassByJvmName(classname); - if (dim > 0) - cname = clazz.getName(); - else - return clazz; - } - else - cname = getTypeName(type); - - while (dim-- > 0) - cname += "[]"; - - return lookupClass(cname, false); - } - - /* - * type cannot be CLASS - */ - static String getTypeName(int type) throws com.fr.third.javassist.compiler.CompileError { - String cname = ""; - switch (type) { - case BOOLEAN : - cname = "boolean"; - break; - case CHAR : - cname = "char"; - break; - case BYTE : - cname = "byte"; - break; - case SHORT : - cname = "short"; - break; - case INT : - cname = "int"; - break; - case LONG : - cname = "long"; - break; - case FLOAT : - cname = "float"; - break; - case DOUBLE : - cname = "double"; - break; - case VOID : - cname = "void"; - break; - default : - fatal(); - } - - return cname; - } - - /** - * @param name a qualified class name. e.g. java.lang.String - */ - public com.fr.third.javassist.CtClass lookupClass(String name, boolean notCheckInner) - throws com.fr.third.javassist.compiler.CompileError - { - Hashtable cache = getInvalidNames(); - Object found = cache.get(name); - if (found == INVALID) - throw new com.fr.third.javassist.compiler.CompileError("no such class: " + name); - else if (found != null) - try { - return classPool.get((String)found); - } - catch (com.fr.third.javassist.NotFoundException e) {} - - com.fr.third.javassist.CtClass cc = null; - try { - cc = lookupClass0(name, notCheckInner); - } - catch (com.fr.third.javassist.NotFoundException e) { - cc = searchImports(name); - } - - cache.put(name, cc.getName()); - return cc; - } - - private static final String INVALID = ""; - private static WeakHashMap invalidNamesMap = new WeakHashMap(); - private Hashtable invalidNames = null; - - // for unit tests - public static int getInvalidMapSize() { return invalidNamesMap.size(); } - - private Hashtable getInvalidNames() { - Hashtable ht = invalidNames; - if (ht == null) { - synchronized (MemberResolver.class) { - WeakReference ref = (WeakReference)invalidNamesMap.get(classPool); - if (ref != null) - ht = (Hashtable)ref.get(); - - if (ht == null) { - ht = new Hashtable(); - invalidNamesMap.put(classPool, new WeakReference(ht)); - } - } - - invalidNames = ht; - } - - return ht; - } - - private com.fr.third.javassist.CtClass searchImports(String orgName) - throws com.fr.third.javassist.compiler.CompileError - { - if (orgName.indexOf('.') < 0) { - Iterator it = classPool.getImportedPackages(); - while (it.hasNext()) { - String pac = (String)it.next(); - String fqName = pac + '.' + orgName; - try { - return classPool.get(fqName); - } - catch (com.fr.third.javassist.NotFoundException e) { - try { - if (pac.endsWith("." + orgName)) - return classPool.get(pac); - } - catch (com.fr.third.javassist.NotFoundException e2) {} - } - } - } - - getInvalidNames().put(orgName, INVALID); - throw new com.fr.third.javassist.compiler.CompileError("no such class: " + orgName); - } - - private com.fr.third.javassist.CtClass lookupClass0(String classname, boolean notCheckInner) - throws com.fr.third.javassist.NotFoundException - { - com.fr.third.javassist.CtClass cc = null; - do { - try { - cc = classPool.get(classname); - } - catch (com.fr.third.javassist.NotFoundException e) { - int i = classname.lastIndexOf('.'); - if (notCheckInner || i < 0) - throw e; - else { - StringBuffer sbuf = new StringBuffer(classname); - sbuf.setCharAt(i, '$'); - classname = sbuf.toString(); - } - } - } while (cc == null); - return cc; - } - - /* Converts a class name into a JVM-internal representation. - * - * It may also expand a simple class name to java.lang.*. - * For example, this converts Object into java/lang/Object. - */ - public String resolveClassName(com.fr.third.javassist.compiler.ast.ASTList name) throws com.fr.third.javassist.compiler.CompileError { - if (name == null) - return null; - else - return javaToJvmName(lookupClassByName(name).getName()); - } - - /* Expands a simple class name to java.lang.*. - * For example, this converts Object into java/lang/Object. - */ - public String resolveJvmClassName(String jvmName) throws com.fr.third.javassist.compiler.CompileError { - if (jvmName == null) - return null; - else - return javaToJvmName(lookupClassByJvmName(jvmName).getName()); - } - - public static com.fr.third.javassist.CtClass getSuperclass(com.fr.third.javassist.CtClass c) throws com.fr.third.javassist.compiler.CompileError { - try { - com.fr.third.javassist.CtClass sc = c.getSuperclass(); - if (sc != null) - return sc; - } - catch (com.fr.third.javassist.NotFoundException e) {} - throw new com.fr.third.javassist.compiler.CompileError("cannot find the super class of " - + c.getName()); - } - - public static String javaToJvmName(String classname) { - return classname.replace('.', '/'); - } - - public static String jvmToJavaName(String classname) { - return classname.replace('/', '.'); - } - - public static int descToType(char c) throws CompileError { - switch (c) { - case 'Z' : - return BOOLEAN; - case 'C' : - return CHAR; - case 'B' : - return BYTE; - case 'S' : - return SHORT; - case 'I' : - return INT; - case 'J' : - return LONG; - case 'F' : - return FLOAT; - case 'D' : - return DOUBLE; - case 'V' : - return VOID; - case 'L' : - case '[' : - return CLASS; - default : - fatal(); - return VOID; // never reach here - } - } - - public static int getModifiers(com.fr.third.javassist.compiler.ast.ASTList mods) { - int m = 0; - while (mods != null) { - com.fr.third.javassist.compiler.ast.Keyword k = (com.fr.third.javassist.compiler.ast.Keyword)mods.head(); - mods = mods.tail(); - switch (k.get()) { - case STATIC : - m |= com.fr.third.javassist.Modifier.STATIC; - break; - case FINAL : - m |= com.fr.third.javassist.Modifier.FINAL; - break; - case SYNCHRONIZED : - m |= com.fr.third.javassist.Modifier.SYNCHRONIZED; - break; - case ABSTRACT : - m |= com.fr.third.javassist.Modifier.ABSTRACT; - break; - case PUBLIC : - m |= com.fr.third.javassist.Modifier.PUBLIC; - break; - case PROTECTED : - m |= com.fr.third.javassist.Modifier.PROTECTED; - break; - case PRIVATE : - m |= com.fr.third.javassist.Modifier.PRIVATE; - break; - case VOLATILE : - m |= com.fr.third.javassist.Modifier.VOLATILE; - break; - case TRANSIENT : - m |= com.fr.third.javassist.Modifier.TRANSIENT; - break; - case STRICT : - m |= Modifier.STRICT; - break; - } - } - - return m; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/NoFieldException.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/NoFieldException.java deleted file mode 100644 index 13dc6a587..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/NoFieldException.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -import com.fr.third.javassist.compiler.ast.ASTree; - -public class NoFieldException extends CompileError { - private String fieldName; - private ASTree expr; - - /* NAME must be JVM-internal representation. - */ - public NoFieldException(String name, ASTree e) { - super("no such field: " + name); - fieldName = name; - expr = e; - } - - /* The returned name should be JVM-internal representation. - */ - public String getField() { return fieldName; } - - /* Returns the expression where this exception is thrown. - */ - public ASTree getExpr() { return expr; } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/Parser.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/Parser.java deleted file mode 100644 index b792c0bce..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/Parser.java +++ /dev/null @@ -1,1343 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -import com.fr.third.javassist.compiler.ast.DoubleConst; - -public final class Parser implements TokenId { - private com.fr.third.javassist.compiler.Lex lex; - - public Parser(Lex lex) { - this.lex = lex; - } - - public boolean hasMore() { return lex.lookAhead() >= 0; } - - /* member.declaration - * : method.declaration | field.declaration - */ - public com.fr.third.javassist.compiler.ast.ASTList parseMember(SymbolTable tbl) throws CompileError { - com.fr.third.javassist.compiler.ast.ASTList mem = parseMember1(tbl); - if (mem instanceof com.fr.third.javassist.compiler.ast.MethodDecl) - return parseMethod2(tbl, (com.fr.third.javassist.compiler.ast.MethodDecl)mem); - else - return mem; - } - - /* A method body is not parsed. - */ - public com.fr.third.javassist.compiler.ast.ASTList parseMember1(SymbolTable tbl) throws CompileError { - com.fr.third.javassist.compiler.ast.ASTList mods = parseMemberMods(); - com.fr.third.javassist.compiler.ast.Declarator d; - boolean isConstructor = false; - if (lex.lookAhead() == Identifier && lex.lookAhead(1) == '(') { - d = new com.fr.third.javassist.compiler.ast.Declarator(VOID, 0); - isConstructor = true; - } - else - d = parseFormalType(tbl); - - if (lex.get() != Identifier) - throw new SyntaxError(lex); - - String name; - if (isConstructor) - name = com.fr.third.javassist.compiler.ast.MethodDecl.initName; - else - name = lex.getString(); - - d.setVariable(new com.fr.third.javassist.compiler.ast.Symbol(name)); - if (isConstructor || lex.lookAhead() == '(') - return parseMethod1(tbl, isConstructor, mods, d); - else - return parseField(tbl, mods, d); - } - - /* field.declaration - * : member.modifiers - * formal.type Identifier - * [ "=" expression ] ";" - */ - private com.fr.third.javassist.compiler.ast.FieldDecl parseField(SymbolTable tbl, com.fr.third.javassist.compiler.ast.ASTList mods, - com.fr.third.javassist.compiler.ast.Declarator d) throws CompileError - { - com.fr.third.javassist.compiler.ast.ASTree expr = null; - if (lex.lookAhead() == '=') { - lex.get(); - expr = parseExpression(tbl); - } - - int c = lex.get(); - if (c == ';') - return new com.fr.third.javassist.compiler.ast.FieldDecl(mods, new com.fr.third.javassist.compiler.ast.ASTList(d, new com.fr.third.javassist.compiler.ast.ASTList(expr))); - else if (c == ',') - throw new CompileError( - "only one field can be declared in one declaration", lex); - else - throw new SyntaxError(lex); - } - - /* method.declaration - * : member.modifiers - * [ formal.type ] - * Identifier "(" [ formal.parameter ( "," formal.parameter )* ] ")" - * array.dimension - * [ THROWS class.type ( "," class.type ) ] - * ( block.statement | ";" ) - * - * Note that a method body is not parsed. - */ - private com.fr.third.javassist.compiler.ast.MethodDecl parseMethod1(SymbolTable tbl, boolean isConstructor, - com.fr.third.javassist.compiler.ast.ASTList mods, com.fr.third.javassist.compiler.ast.Declarator d) - throws CompileError - { - if (lex.get() != '(') - throw new SyntaxError(lex); - - com.fr.third.javassist.compiler.ast.ASTList parms = null; - if (lex.lookAhead() != ')') - while (true) { - parms = com.fr.third.javassist.compiler.ast.ASTList.append(parms, parseFormalParam(tbl)); - int t = lex.lookAhead(); - if (t == ',') - lex.get(); - else if (t == ')') - break; - } - - lex.get(); // ')' - d.addArrayDim(parseArrayDimension()); - if (isConstructor && d.getArrayDim() > 0) - throw new SyntaxError(lex); - - com.fr.third.javassist.compiler.ast.ASTList throwsList = null; - if (lex.lookAhead() == THROWS) { - lex.get(); - while (true) { - throwsList = com.fr.third.javassist.compiler.ast.ASTList.append(throwsList, parseClassType(tbl)); - if (lex.lookAhead() == ',') - lex.get(); - else - break; - } - } - - return new com.fr.third.javassist.compiler.ast.MethodDecl(mods, new com.fr.third.javassist.compiler.ast.ASTList(d, - com.fr.third.javassist.compiler.ast.ASTList.make(parms, throwsList, null))); - } - - /* Parses a method body. - */ - public com.fr.third.javassist.compiler.ast.MethodDecl parseMethod2(SymbolTable tbl, com.fr.third.javassist.compiler.ast.MethodDecl md) - throws CompileError - { - com.fr.third.javassist.compiler.ast.Stmnt body = null; - if (lex.lookAhead() == ';') - lex.get(); - else { - body = parseBlock(tbl); - if (body == null) - body = new com.fr.third.javassist.compiler.ast.Stmnt(BLOCK); - } - - md.sublist(4).setHead(body); - return md; - } - - /* member.modifiers - * : ( FINAL | SYNCHRONIZED | ABSTRACT - * | PUBLIC | PROTECTED | PRIVATE | STATIC - * | VOLATILE | TRANSIENT | STRICT )* - */ - private com.fr.third.javassist.compiler.ast.ASTList parseMemberMods() { - int t; - com.fr.third.javassist.compiler.ast.ASTList list = null; - while (true) { - t = lex.lookAhead(); - if (t == ABSTRACT || t == FINAL || t == PUBLIC || t == PROTECTED - || t == PRIVATE || t == SYNCHRONIZED || t == STATIC - || t == VOLATILE || t == TRANSIENT || t == STRICT) - list = new com.fr.third.javassist.compiler.ast.ASTList(new com.fr.third.javassist.compiler.ast.Keyword(lex.get()), list); - else - break; - } - - return list; - } - - /* formal.type : ( build-in-type | class.type ) array.dimension - */ - private com.fr.third.javassist.compiler.ast.Declarator parseFormalType(SymbolTable tbl) throws CompileError { - int t = lex.lookAhead(); - if (isBuiltinType(t) || t == VOID) { - lex.get(); // primitive type - int dim = parseArrayDimension(); - return new com.fr.third.javassist.compiler.ast.Declarator(t, dim); - } - else { - com.fr.third.javassist.compiler.ast.ASTList name = parseClassType(tbl); - int dim = parseArrayDimension(); - return new com.fr.third.javassist.compiler.ast.Declarator(name, dim); - } - } - - private static boolean isBuiltinType(int t) { - return (t == BOOLEAN || t == BYTE || t == CHAR || t == SHORT - || t == INT || t == LONG || t == FLOAT || t == DOUBLE); - } - - /* formal.parameter : formal.type Identifier array.dimension - */ - private com.fr.third.javassist.compiler.ast.Declarator parseFormalParam(SymbolTable tbl) - throws CompileError - { - com.fr.third.javassist.compiler.ast.Declarator d = parseFormalType(tbl); - if (lex.get() != Identifier) - throw new SyntaxError(lex); - - String name = lex.getString(); - d.setVariable(new com.fr.third.javassist.compiler.ast.Symbol(name)); - d.addArrayDim(parseArrayDimension()); - tbl.append(name, d); - return d; - } - - /* statement : [ label ":" ]* labeled.statement - * - * labeled.statement - * : block.statement - * | if.statement - * | while.statement - * | do.statement - * | for.statement - * | switch.statement - * | try.statement - * | return.statement - * | thorw.statement - * | break.statement - * | continue.statement - * | declaration.or.expression - * | ";" - * - * This method may return null (empty statement). - */ - public com.fr.third.javassist.compiler.ast.Stmnt parseStatement(SymbolTable tbl) - throws CompileError - { - int t = lex.lookAhead(); - if (t == '{') - return parseBlock(tbl); - else if (t == ';') { - lex.get(); - return new com.fr.third.javassist.compiler.ast.Stmnt(BLOCK); // empty statement - } - else if (t == Identifier && lex.lookAhead(1) == ':') { - lex.get(); // Identifier - String label = lex.getString(); - lex.get(); // ':' - return com.fr.third.javassist.compiler.ast.Stmnt.make(LABEL, new com.fr.third.javassist.compiler.ast.Symbol(label), parseStatement(tbl)); - } - else if (t == IF) - return parseIf(tbl); - else if (t == WHILE) - return parseWhile(tbl); - else if (t == DO) - return parseDo(tbl); - else if (t == FOR) - return parseFor(tbl); - else if (t == TRY) - return parseTry(tbl); - else if (t == SWITCH) - return parseSwitch(tbl); - else if (t == SYNCHRONIZED) - return parseSynchronized(tbl); - else if (t == RETURN) - return parseReturn(tbl); - else if (t == THROW) - return parseThrow(tbl); - else if (t == BREAK) - return parseBreak(tbl); - else if (t == CONTINUE) - return parseContinue(tbl); - else - return parseDeclarationOrExpression(tbl, false); - } - - /* block.statement : "{" statement* "}" - */ - private com.fr.third.javassist.compiler.ast.Stmnt parseBlock(SymbolTable tbl) throws CompileError { - if (lex.get() != '{') - throw new SyntaxError(lex); - - com.fr.third.javassist.compiler.ast.Stmnt body = null; - SymbolTable tbl2 = new SymbolTable(tbl); - while (lex.lookAhead() != '}') { - com.fr.third.javassist.compiler.ast.Stmnt s = parseStatement(tbl2); - if (s != null) - body = (com.fr.third.javassist.compiler.ast.Stmnt) com.fr.third.javassist.compiler.ast.ASTList.concat(body, new com.fr.third.javassist.compiler.ast.Stmnt(BLOCK, s)); - } - - lex.get(); // '}' - if (body == null) - return new com.fr.third.javassist.compiler.ast.Stmnt(BLOCK); // empty block - else - return body; - } - - /* if.statement : IF "(" expression ")" statement - * [ ELSE statement ] - */ - private com.fr.third.javassist.compiler.ast.Stmnt parseIf(SymbolTable tbl) throws CompileError { - int t = lex.get(); // IF - com.fr.third.javassist.compiler.ast.ASTree expr = parseParExpression(tbl); - com.fr.third.javassist.compiler.ast.Stmnt thenp = parseStatement(tbl); - com.fr.third.javassist.compiler.ast.Stmnt elsep; - if (lex.lookAhead() == ELSE) { - lex.get(); - elsep = parseStatement(tbl); - } - else - elsep = null; - - return new com.fr.third.javassist.compiler.ast.Stmnt(t, expr, new com.fr.third.javassist.compiler.ast.ASTList(thenp, new com.fr.third.javassist.compiler.ast.ASTList(elsep))); - } - - /* while.statement : WHILE "(" expression ")" statement - */ - private com.fr.third.javassist.compiler.ast.Stmnt parseWhile(SymbolTable tbl) - throws CompileError - { - int t = lex.get(); // WHILE - com.fr.third.javassist.compiler.ast.ASTree expr = parseParExpression(tbl); - com.fr.third.javassist.compiler.ast.Stmnt body = parseStatement(tbl); - return new com.fr.third.javassist.compiler.ast.Stmnt(t, expr, body); - } - - /* do.statement : DO statement WHILE "(" expression ")" ";" - */ - private com.fr.third.javassist.compiler.ast.Stmnt parseDo(SymbolTable tbl) throws CompileError { - int t = lex.get(); // DO - com.fr.third.javassist.compiler.ast.Stmnt body = parseStatement(tbl); - if (lex.get() != WHILE || lex.get() != '(') - throw new SyntaxError(lex); - - com.fr.third.javassist.compiler.ast.ASTree expr = parseExpression(tbl); - if (lex.get() != ')' || lex.get() != ';') - throw new SyntaxError(lex); - - return new com.fr.third.javassist.compiler.ast.Stmnt(t, expr, body); - } - - /* for.statement : FOR "(" decl.or.expr expression ";" expression ")" - * statement - */ - private com.fr.third.javassist.compiler.ast.Stmnt parseFor(SymbolTable tbl) throws CompileError { - com.fr.third.javassist.compiler.ast.Stmnt expr1, expr3; - com.fr.third.javassist.compiler.ast.ASTree expr2; - int t = lex.get(); // FOR - - SymbolTable tbl2 = new SymbolTable(tbl); - - if (lex.get() != '(') - throw new SyntaxError(lex); - - if (lex.lookAhead() == ';') { - lex.get(); - expr1 = null; - } - else - expr1 = parseDeclarationOrExpression(tbl2, true); - - if (lex.lookAhead() == ';') - expr2 = null; - else - expr2 = parseExpression(tbl2); - - if (lex.get() != ';') - throw new CompileError("; is missing", lex); - - if (lex.lookAhead() == ')') - expr3 = null; - else - expr3 = parseExprList(tbl2); - - if (lex.get() != ')') - throw new CompileError(") is missing", lex); - - com.fr.third.javassist.compiler.ast.Stmnt body = parseStatement(tbl2); - return new com.fr.third.javassist.compiler.ast.Stmnt(t, expr1, new com.fr.third.javassist.compiler.ast.ASTList(expr2, - new com.fr.third.javassist.compiler.ast.ASTList(expr3, body))); - } - - /* switch.statement : SWITCH "(" expression ")" "{" switch.block "}" - * - * swtich.block : ( switch.label statement* )* - * - * swtich.label : DEFAULT ":" - * | CASE const.expression ":" - */ - private com.fr.third.javassist.compiler.ast.Stmnt parseSwitch(SymbolTable tbl) throws CompileError { - int t = lex.get(); // SWITCH - com.fr.third.javassist.compiler.ast.ASTree expr = parseParExpression(tbl); - com.fr.third.javassist.compiler.ast.Stmnt body = parseSwitchBlock(tbl); - return new com.fr.third.javassist.compiler.ast.Stmnt(t, expr, body); - } - - private com.fr.third.javassist.compiler.ast.Stmnt parseSwitchBlock(SymbolTable tbl) throws CompileError { - if (lex.get() != '{') - throw new SyntaxError(lex); - - SymbolTable tbl2 = new SymbolTable(tbl); - com.fr.third.javassist.compiler.ast.Stmnt s = parseStmntOrCase(tbl2); - if (s == null) - throw new CompileError("empty switch block", lex); - - int op = s.getOperator(); - if (op != CASE && op != DEFAULT) - throw new CompileError("no case or default in a switch block", - lex); - - com.fr.third.javassist.compiler.ast.Stmnt body = new com.fr.third.javassist.compiler.ast.Stmnt(BLOCK, s); - while (lex.lookAhead() != '}') { - com.fr.third.javassist.compiler.ast.Stmnt s2 = parseStmntOrCase(tbl2); - if (s2 != null) { - int op2 = s2.getOperator(); - if (op2 == CASE || op2 == DEFAULT) { - body = (com.fr.third.javassist.compiler.ast.Stmnt) com.fr.third.javassist.compiler.ast.ASTList.concat(body, new com.fr.third.javassist.compiler.ast.Stmnt(BLOCK, s2)); - s = s2; - } - else - s = (com.fr.third.javassist.compiler.ast.Stmnt) com.fr.third.javassist.compiler.ast.ASTList.concat(s, new com.fr.third.javassist.compiler.ast.Stmnt(BLOCK, s2)); - } - } - - lex.get(); // '}' - return body; - } - - private com.fr.third.javassist.compiler.ast.Stmnt parseStmntOrCase(SymbolTable tbl) throws CompileError { - int t = lex.lookAhead(); - if (t != CASE && t != DEFAULT) - return parseStatement(tbl); - - lex.get(); - com.fr.third.javassist.compiler.ast.Stmnt s; - if (t == CASE) - s = new com.fr.third.javassist.compiler.ast.Stmnt(t, parseExpression(tbl)); - else - s = new com.fr.third.javassist.compiler.ast.Stmnt(DEFAULT); - - if (lex.get() != ':') - throw new CompileError(": is missing", lex); - - return s; - } - - /* synchronized.statement : - * SYNCHRONIZED "(" expression ")" block.statement - */ - private com.fr.third.javassist.compiler.ast.Stmnt parseSynchronized(SymbolTable tbl) throws CompileError { - int t = lex.get(); // SYNCHRONIZED - if (lex.get() != '(') - throw new SyntaxError(lex); - - com.fr.third.javassist.compiler.ast.ASTree expr = parseExpression(tbl); - if (lex.get() != ')') - throw new SyntaxError(lex); - - com.fr.third.javassist.compiler.ast.Stmnt body = parseBlock(tbl); - return new com.fr.third.javassist.compiler.ast.Stmnt(t, expr, body); - } - - /* try.statement - * : TRY block.statement - * [ CATCH "(" class.type Identifier ")" block.statement ]* - * [ FINALLY block.statement ]* - */ - private com.fr.third.javassist.compiler.ast.Stmnt parseTry(SymbolTable tbl) throws CompileError { - lex.get(); // TRY - com.fr.third.javassist.compiler.ast.Stmnt block = parseBlock(tbl); - com.fr.third.javassist.compiler.ast.ASTList catchList = null; - while (lex.lookAhead() == CATCH) { - lex.get(); // CATCH - if (lex.get() != '(') - throw new SyntaxError(lex); - - SymbolTable tbl2 = new SymbolTable(tbl); - com.fr.third.javassist.compiler.ast.Declarator d = parseFormalParam(tbl2); - if (d.getArrayDim() > 0 || d.getType() != CLASS) - throw new SyntaxError(lex); - - if (lex.get() != ')') - throw new SyntaxError(lex); - - com.fr.third.javassist.compiler.ast.Stmnt b = parseBlock(tbl2); - catchList = com.fr.third.javassist.compiler.ast.ASTList.append(catchList, new com.fr.third.javassist.compiler.ast.Pair(d, b)); - } - - com.fr.third.javassist.compiler.ast.Stmnt finallyBlock = null; - if (lex.lookAhead() == FINALLY) { - lex.get(); // FINALLY - finallyBlock = parseBlock(tbl); - } - - return com.fr.third.javassist.compiler.ast.Stmnt.make(TRY, block, catchList, finallyBlock); - } - - /* return.statement : RETURN [ expression ] ";" - */ - private com.fr.third.javassist.compiler.ast.Stmnt parseReturn(SymbolTable tbl) throws CompileError { - int t = lex.get(); // RETURN - com.fr.third.javassist.compiler.ast.Stmnt s = new com.fr.third.javassist.compiler.ast.Stmnt(t); - if (lex.lookAhead() != ';') - s.setLeft(parseExpression(tbl)); - - if (lex.get() != ';') - throw new CompileError("; is missing", lex); - - return s; - } - - /* throw.statement : THROW expression ";" - */ - private com.fr.third.javassist.compiler.ast.Stmnt parseThrow(SymbolTable tbl) throws CompileError { - int t = lex.get(); // THROW - com.fr.third.javassist.compiler.ast.ASTree expr = parseExpression(tbl); - if (lex.get() != ';') - throw new CompileError("; is missing", lex); - - return new com.fr.third.javassist.compiler.ast.Stmnt(t, expr); - } - - /* break.statement : BREAK [ Identifier ] ";" - */ - private com.fr.third.javassist.compiler.ast.Stmnt parseBreak(SymbolTable tbl) - throws CompileError - { - return parseContinue(tbl); - } - - /* continue.statement : CONTINUE [ Identifier ] ";" - */ - private com.fr.third.javassist.compiler.ast.Stmnt parseContinue(SymbolTable tbl) - throws CompileError - { - int t = lex.get(); // CONTINUE - com.fr.third.javassist.compiler.ast.Stmnt s = new com.fr.third.javassist.compiler.ast.Stmnt(t); - int t2 = lex.get(); - if (t2 == Identifier) { - s.setLeft(new com.fr.third.javassist.compiler.ast.Symbol(lex.getString())); - t2 = lex.get(); - } - - if (t2 != ';') - throw new CompileError("; is missing", lex); - - return s; - } - - /* declaration.or.expression - * : [ FINAL ] built-in-type array.dimension declarators - * | [ FINAL ] class.type array.dimension declarators - * | expression ';' - * | expr.list ';' if exprList is true - * - * Note: FINAL is currently ignored. This must be fixed - * in future. - */ - private com.fr.third.javassist.compiler.ast.Stmnt parseDeclarationOrExpression(SymbolTable tbl, - boolean exprList) - throws CompileError - { - int t = lex.lookAhead(); - while (t == FINAL) { - lex.get(); - t = lex.lookAhead(); - } - - if (isBuiltinType(t)) { - t = lex.get(); - int dim = parseArrayDimension(); - return parseDeclarators(tbl, new com.fr.third.javassist.compiler.ast.Declarator(t, dim)); - } - else if (t == Identifier) { - int i = nextIsClassType(0); - if (i >= 0) - if (lex.lookAhead(i) == Identifier) { - com.fr.third.javassist.compiler.ast.ASTList name = parseClassType(tbl); - int dim = parseArrayDimension(); - return parseDeclarators(tbl, new com.fr.third.javassist.compiler.ast.Declarator(name, dim)); - } - } - - com.fr.third.javassist.compiler.ast.Stmnt expr; - if (exprList) - expr = parseExprList(tbl); - else - expr = new com.fr.third.javassist.compiler.ast.Stmnt(EXPR, parseExpression(tbl)); - - if (lex.get() != ';') - throw new CompileError("; is missing", lex); - - return expr; - } - - /* expr.list : ( expression ',')* expression - */ - private com.fr.third.javassist.compiler.ast.Stmnt parseExprList(SymbolTable tbl) throws CompileError { - com.fr.third.javassist.compiler.ast.Stmnt expr = null; - for (;;) { - com.fr.third.javassist.compiler.ast.Stmnt e = new com.fr.third.javassist.compiler.ast.Stmnt(EXPR, parseExpression(tbl)); - expr = (com.fr.third.javassist.compiler.ast.Stmnt) com.fr.third.javassist.compiler.ast.ASTList.concat(expr, new com.fr.third.javassist.compiler.ast.Stmnt(BLOCK, e)); - if (lex.lookAhead() == ',') - lex.get(); - else - return expr; - } - } - - /* declarators : declarator [ ',' declarator ]* ';' - */ - private com.fr.third.javassist.compiler.ast.Stmnt parseDeclarators(SymbolTable tbl, com.fr.third.javassist.compiler.ast.Declarator d) - throws CompileError - { - com.fr.third.javassist.compiler.ast.Stmnt decl = null; - for (;;) { - decl = (com.fr.third.javassist.compiler.ast.Stmnt) com.fr.third.javassist.compiler.ast.ASTList.concat(decl, - new com.fr.third.javassist.compiler.ast.Stmnt(DECL, parseDeclarator(tbl, d))); - int t = lex.get(); - if (t == ';') - return decl; - else if (t != ',') - throw new CompileError("; is missing", lex); - } - } - - /* declarator : Identifier array.dimension [ '=' initializer ] - */ - private com.fr.third.javassist.compiler.ast.Declarator parseDeclarator(SymbolTable tbl, com.fr.third.javassist.compiler.ast.Declarator d) - throws CompileError - { - if (lex.get() != Identifier || d.getType() == VOID) - throw new SyntaxError(lex); - - String name = lex.getString(); - com.fr.third.javassist.compiler.ast.Symbol symbol = new com.fr.third.javassist.compiler.ast.Symbol(name); - int dim = parseArrayDimension(); - com.fr.third.javassist.compiler.ast.ASTree init = null; - if (lex.lookAhead() == '=') { - lex.get(); - init = parseInitializer(tbl); - } - - com.fr.third.javassist.compiler.ast.Declarator decl = d.make(symbol, dim, init); - tbl.append(name, decl); - return decl; - } - - /* initializer : expression | array.initializer - */ - private com.fr.third.javassist.compiler.ast.ASTree parseInitializer(SymbolTable tbl) throws CompileError { - if (lex.lookAhead() == '{') - return parseArrayInitializer(tbl); - else - return parseExpression(tbl); - } - - /* array.initializer : - * '{' (( array.initializer | expression ) ',')* '}' - */ - private com.fr.third.javassist.compiler.ast.ArrayInit parseArrayInitializer(SymbolTable tbl) - throws CompileError - { - lex.get(); // '{' - com.fr.third.javassist.compiler.ast.ASTree expr = parseExpression(tbl); - com.fr.third.javassist.compiler.ast.ArrayInit init = new com.fr.third.javassist.compiler.ast.ArrayInit(expr); - while (lex.lookAhead() == ',') { - lex.get(); - expr = parseExpression(tbl); - com.fr.third.javassist.compiler.ast.ASTList.append(init, expr); - } - - if (lex.get() != '}') - throw new SyntaxError(lex); - - return init; - } - - /* par.expression : '(' expression ')' - */ - private com.fr.third.javassist.compiler.ast.ASTree parseParExpression(SymbolTable tbl) throws CompileError { - if (lex.get() != '(') - throw new SyntaxError(lex); - - com.fr.third.javassist.compiler.ast.ASTree expr = parseExpression(tbl); - if (lex.get() != ')') - throw new SyntaxError(lex); - - return expr; - } - - /* expression : conditional.expr - * | conditional.expr assign.op expression (right-to-left) - */ - public com.fr.third.javassist.compiler.ast.ASTree parseExpression(SymbolTable tbl) throws CompileError { - com.fr.third.javassist.compiler.ast.ASTree left = parseConditionalExpr(tbl); - if (!isAssignOp(lex.lookAhead())) - return left; - - int t = lex.get(); - com.fr.third.javassist.compiler.ast.ASTree right = parseExpression(tbl); - return com.fr.third.javassist.compiler.ast.AssignExpr.makeAssign(t, left, right); - } - - private static boolean isAssignOp(int t) { - return t == '=' || t == MOD_E || t == AND_E - || t == MUL_E || t == PLUS_E || t == MINUS_E || t == DIV_E - || t == EXOR_E || t == OR_E || t == LSHIFT_E - || t == RSHIFT_E || t == ARSHIFT_E; - } - - /* conditional.expr (right-to-left) - * : logical.or.expr [ '?' expression ':' conditional.expr ] - */ - private com.fr.third.javassist.compiler.ast.ASTree parseConditionalExpr(SymbolTable tbl) throws CompileError { - com.fr.third.javassist.compiler.ast.ASTree cond = parseBinaryExpr(tbl); - if (lex.lookAhead() == '?') { - lex.get(); - com.fr.third.javassist.compiler.ast.ASTree thenExpr = parseExpression(tbl); - if (lex.get() != ':') - throw new CompileError(": is missing", lex); - - com.fr.third.javassist.compiler.ast.ASTree elseExpr = parseExpression(tbl); - return new com.fr.third.javassist.compiler.ast.CondExpr(cond, thenExpr, elseExpr); - } - else - return cond; - } - - /* logical.or.expr 10 (operator precedence) - * : logical.and.expr - * | logical.or.expr OROR logical.and.expr left-to-right - * - * logical.and.expr 9 - * : inclusive.or.expr - * | logical.and.expr ANDAND inclusive.or.expr - * - * inclusive.or.expr 8 - * : exclusive.or.expr - * | inclusive.or.expr "|" exclusive.or.expr - * - * exclusive.or.expr 7 - * : and.expr - * | exclusive.or.expr "^" and.expr - * - * and.expr 6 - * : equality.expr - * | and.expr "&" equality.expr - * - * equality.expr 5 - * : relational.expr - * | equality.expr (EQ | NEQ) relational.expr - * - * relational.expr 4 - * : shift.expr - * | relational.expr (LE | GE | "<" | ">") shift.expr - * | relational.expr INSTANCEOF class.type ("[" "]")* - * - * shift.expr 3 - * : additive.expr - * | shift.expr (LSHIFT | RSHIFT | ARSHIFT) additive.expr - * - * additive.expr 2 - * : multiply.expr - * | additive.expr ("+" | "-") multiply.expr - * - * multiply.expr 1 - * : unary.expr - * | multiply.expr ("*" | "/" | "%") unary.expr - */ - private com.fr.third.javassist.compiler.ast.ASTree parseBinaryExpr(SymbolTable tbl) throws CompileError { - com.fr.third.javassist.compiler.ast.ASTree expr = parseUnaryExpr(tbl); - for (;;) { - int t = lex.lookAhead(); - int p = getOpPrecedence(t); - if (p == 0) - return expr; - else - expr = binaryExpr2(tbl, expr, p); - } - } - - private com.fr.third.javassist.compiler.ast.ASTree parseInstanceOf(SymbolTable tbl, com.fr.third.javassist.compiler.ast.ASTree expr) - throws CompileError - { - int t = lex.lookAhead(); - if (isBuiltinType(t)) { - lex.get(); // primitive type - int dim = parseArrayDimension(); - return new com.fr.third.javassist.compiler.ast.InstanceOfExpr(t, dim, expr); - } - else { - com.fr.third.javassist.compiler.ast.ASTList name = parseClassType(tbl); - int dim = parseArrayDimension(); - return new com.fr.third.javassist.compiler.ast.InstanceOfExpr(name, dim, expr); - } - } - - private com.fr.third.javassist.compiler.ast.ASTree binaryExpr2(SymbolTable tbl, com.fr.third.javassist.compiler.ast.ASTree expr, int prec) - throws CompileError - { - int t = lex.get(); - if (t == INSTANCEOF) - return parseInstanceOf(tbl, expr); - - com.fr.third.javassist.compiler.ast.ASTree expr2 = parseUnaryExpr(tbl); - for (;;) { - int t2 = lex.lookAhead(); - int p2 = getOpPrecedence(t2); - if (p2 != 0 && prec > p2) - expr2 = binaryExpr2(tbl, expr2, p2); - else - return com.fr.third.javassist.compiler.ast.BinExpr.makeBin(t, expr, expr2); - } - } - - // !"#$%&'( )*+,-./0 12345678 9:;<=>? - private static final int[] binaryOpPrecedence - = { 0, 0, 0, 0, 1, 6, 0, 0, - 0, 1, 2, 0, 2, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4, 0, 4, 0 }; - - private int getOpPrecedence(int c) { - if ('!' <= c && c <= '?') - return binaryOpPrecedence[c - '!']; - else if (c == '^') - return 7; - else if (c == '|') - return 8; - else if (c == ANDAND) - return 9; - else if (c == OROR) - return 10; - else if (c == EQ || c == NEQ) - return 5; - else if (c == LE || c == GE || c == INSTANCEOF) - return 4; - else if (c == LSHIFT || c == RSHIFT || c == ARSHIFT) - return 3; - else - return 0; // not a binary operator - } - - /* unary.expr : "++"|"--" unary.expr - | "+"|"-" unary.expr - | "!"|"~" unary.expr - | cast.expr - | postfix.expr - - unary.expr.not.plus.minus is a unary expression starting without - "+", "-", "++", or "--". - */ - private com.fr.third.javassist.compiler.ast.ASTree parseUnaryExpr(SymbolTable tbl) throws CompileError { - int t; - switch (lex.lookAhead()) { - case '+' : - case '-' : - case PLUSPLUS : - case MINUSMINUS : - case '!' : - case '~' : - t = lex.get(); - if (t == '-') { - int t2 = lex.lookAhead(); - switch (t2) { - case LongConstant : - case IntConstant : - case CharConstant : - lex.get(); - return new com.fr.third.javassist.compiler.ast.IntConst(-lex.getLong(), t2); - case DoubleConstant : - case FloatConstant : - lex.get(); - return new com.fr.third.javassist.compiler.ast.DoubleConst(-lex.getDouble(), t2); - default : - break; - } - } - - return com.fr.third.javassist.compiler.ast.Expr.make(t, parseUnaryExpr(tbl)); - case '(' : - return parseCast(tbl); - default : - return parsePostfix(tbl); - } - } - - /* cast.expr : "(" builtin.type ("[" "]")* ")" unary.expr - | "(" class.type ("[" "]")* ")" unary.expr2 - - unary.expr2 is a unary.expr beginning with "(", NULL, StringL, - Identifier, THIS, SUPER, or NEW. - - Either "(int.class)" or "(String[].class)" is a not cast expression. - */ - private com.fr.third.javassist.compiler.ast.ASTree parseCast(SymbolTable tbl) throws CompileError { - int t = lex.lookAhead(1); - if (isBuiltinType(t) && nextIsBuiltinCast()) { - lex.get(); // '(' - lex.get(); // primitive type - int dim = parseArrayDimension(); - if (lex.get() != ')') - throw new CompileError(") is missing", lex); - - return new com.fr.third.javassist.compiler.ast.CastExpr(t, dim, parseUnaryExpr(tbl)); - } - else if (t == Identifier && nextIsClassCast()) { - lex.get(); // '(' - com.fr.third.javassist.compiler.ast.ASTList name = parseClassType(tbl); - int dim = parseArrayDimension(); - if (lex.get() != ')') - throw new CompileError(") is missing", lex); - - return new com.fr.third.javassist.compiler.ast.CastExpr(name, dim, parseUnaryExpr(tbl)); - } - else - return parsePostfix(tbl); - } - - private boolean nextIsBuiltinCast() { - int t; - int i = 2; - while ((t = lex.lookAhead(i++)) == '[') - if (lex.lookAhead(i++) != ']') - return false; - - return lex.lookAhead(i - 1) == ')'; - } - - private boolean nextIsClassCast() { - int i = nextIsClassType(1); - if (i < 0) - return false; - - int t = lex.lookAhead(i); - if (t != ')') - return false; - - t = lex.lookAhead(i + 1); - return t == '(' || t == NULL || t == StringL - || t == Identifier || t == THIS || t == SUPER || t == NEW - || t == TRUE || t == FALSE || t == LongConstant - || t == IntConstant || t == CharConstant - || t == DoubleConstant || t == FloatConstant; - } - - private int nextIsClassType(int i) { - int t; - while (lex.lookAhead(++i) == '.') - if (lex.lookAhead(++i) != Identifier) - return -1; - - while ((t = lex.lookAhead(i++)) == '[') - if (lex.lookAhead(i++) != ']') - return -1; - - return i - 1; - } - - /* array.dimension : [ "[" "]" ]* - */ - private int parseArrayDimension() throws CompileError { - int arrayDim = 0; - while (lex.lookAhead() == '[') { - ++arrayDim; - lex.get(); - if (lex.get() != ']') - throw new CompileError("] is missing", lex); - } - - return arrayDim; - } - - /* class.type : Identifier ( "." Identifier )* - */ - private com.fr.third.javassist.compiler.ast.ASTList parseClassType(SymbolTable tbl) throws CompileError { - com.fr.third.javassist.compiler.ast.ASTList list = null; - for (;;) { - if (lex.get() != Identifier) - throw new SyntaxError(lex); - - list = com.fr.third.javassist.compiler.ast.ASTList.append(list, new com.fr.third.javassist.compiler.ast.Symbol(lex.getString())); - if (lex.lookAhead() == '.') - lex.get(); - else - break; - } - - return list; - } - - /* postfix.expr : number.literal - * | primary.expr - * | method.expr - * | postfix.expr "++" | "--" - * | postfix.expr "[" array.size "]" - * | postfix.expr "." Identifier - * | postfix.expr ( "[" "]" )* "." CLASS - * | postfix.expr "#" Identifier - * - * "#" is not an operator of regular Java. It separates - * a class name and a member name in an expression for static member - * access. For example, - * java.lang.Integer.toString(3) in regular Java - * can be written like this: - * java.lang.Integer#toString(3) for this compiler. - */ - private com.fr.third.javassist.compiler.ast.ASTree parsePostfix(SymbolTable tbl) throws CompileError { - int token = lex.lookAhead(); - switch (token) { // see also parseUnaryExpr() - case LongConstant : - case IntConstant : - case CharConstant : - lex.get(); - return new com.fr.third.javassist.compiler.ast.IntConst(lex.getLong(), token); - case DoubleConstant : - case FloatConstant : - lex.get(); - return new DoubleConst(lex.getDouble(), token); - default : - break; - } - - String str; - com.fr.third.javassist.compiler.ast.ASTree index; - com.fr.third.javassist.compiler.ast.ASTree expr = parsePrimaryExpr(tbl); - int t; - while (true) { - switch (lex.lookAhead()) { - case '(' : - expr = parseMethodCall(tbl, expr); - break; - case '[' : - if (lex.lookAhead(1) == ']') { - int dim = parseArrayDimension(); - if (lex.get() != '.' || lex.get() != CLASS) - throw new SyntaxError(lex); - - expr = parseDotClass(expr, dim); - } - else { - index = parseArrayIndex(tbl); - if (index == null) - throw new SyntaxError(lex); - - expr = com.fr.third.javassist.compiler.ast.Expr.make(ARRAY, expr, index); - } - break; - case PLUSPLUS : - case MINUSMINUS : - t = lex.get(); - expr = com.fr.third.javassist.compiler.ast.Expr.make(t, null, expr); - break; - case '.' : - lex.get(); - t = lex.get(); - if (t == CLASS) { - expr = parseDotClass(expr, 0); - } - else if (t == Identifier) { - str = lex.getString(); - expr = com.fr.third.javassist.compiler.ast.Expr.make('.', expr, new com.fr.third.javassist.compiler.ast.Member(str)); - } - else - throw new CompileError("missing member name", lex); - break; - case '#' : - lex.get(); - t = lex.get(); - if (t != Identifier) - throw new CompileError("missing static member name", lex); - - str = lex.getString(); - expr = com.fr.third.javassist.compiler.ast.Expr.make(MEMBER, new com.fr.third.javassist.compiler.ast.Symbol(toClassName(expr)), - new com.fr.third.javassist.compiler.ast.Member(str)); - break; - default : - return expr; - } - } - } - - /* Parse a .class expression on a class type. For example, - * String.class => ('.' "String" "class") - * String[].class => ('.' "[LString;" "class") - */ - private com.fr.third.javassist.compiler.ast.ASTree parseDotClass(com.fr.third.javassist.compiler.ast.ASTree className, int dim) - throws CompileError - { - String cname = toClassName(className); - if (dim > 0) { - StringBuffer sbuf = new StringBuffer(); - while (dim-- > 0) - sbuf.append('['); - - sbuf.append('L').append(cname.replace('.', '/')).append(';'); - cname = sbuf.toString(); - } - - return com.fr.third.javassist.compiler.ast.Expr.make('.', new com.fr.third.javassist.compiler.ast.Symbol(cname), new com.fr.third.javassist.compiler.ast.Member("class")); - } - - /* Parses a .class expression on a built-in type. For example, - * int.class => ('#' "java.lang.Integer" "TYPE") - * int[].class => ('.' "[I", "class") - */ - private com.fr.third.javassist.compiler.ast.ASTree parseDotClass(int builtinType, int dim) - throws CompileError - { - if (dim > 0) { - String cname = CodeGen.toJvmTypeName(builtinType, dim); - return com.fr.third.javassist.compiler.ast.Expr.make('.', new com.fr.third.javassist.compiler.ast.Symbol(cname), new com.fr.third.javassist.compiler.ast.Member("class")); - } - else { - String cname; - switch(builtinType) { - case BOOLEAN : - cname = "java.lang.Boolean"; - break; - case BYTE : - cname = "java.lang.Byte"; - break; - case CHAR : - cname = "java.lang.Character"; - break; - case SHORT : - cname = "java.lang.Short"; - break; - case INT : - cname = "java.lang.Integer"; - break; - case LONG : - cname = "java.lang.Long"; - break; - case FLOAT : - cname = "java.lang.Float"; - break; - case DOUBLE : - cname = "java.lang.Double"; - break; - case VOID : - cname = "java.lang.Void"; - break; - default : - throw new CompileError("invalid builtin type: " - + builtinType); - } - - return com.fr.third.javassist.compiler.ast.Expr.make(MEMBER, new com.fr.third.javassist.compiler.ast.Symbol(cname), new com.fr.third.javassist.compiler.ast.Member("TYPE")); - } - } - - /* method.call : method.expr "(" argument.list ")" - * method.expr : THIS | SUPER | Identifier - * | postfix.expr "." Identifier - * | postfix.expr "#" Identifier - */ - private com.fr.third.javassist.compiler.ast.ASTree parseMethodCall(SymbolTable tbl, com.fr.third.javassist.compiler.ast.ASTree expr) - throws CompileError - { - if (expr instanceof com.fr.third.javassist.compiler.ast.Keyword) { - int token = ((com.fr.third.javassist.compiler.ast.Keyword)expr).get(); - if (token != THIS && token != SUPER) - throw new SyntaxError(lex); - } - else if (expr instanceof com.fr.third.javassist.compiler.ast.Symbol) // Identifier - ; - else if (expr instanceof com.fr.third.javassist.compiler.ast.Expr) { - int op = ((com.fr.third.javassist.compiler.ast.Expr)expr).getOperator(); - if (op != '.' && op != MEMBER) - throw new SyntaxError(lex); - } - - return com.fr.third.javassist.compiler.ast.CallExpr.makeCall(expr, parseArgumentList(tbl)); - } - - private String toClassName(com.fr.third.javassist.compiler.ast.ASTree name) - throws CompileError - { - StringBuffer sbuf = new StringBuffer(); - toClassName(name, sbuf); - return sbuf.toString(); - } - - private void toClassName(com.fr.third.javassist.compiler.ast.ASTree name, StringBuffer sbuf) - throws CompileError - { - if (name instanceof com.fr.third.javassist.compiler.ast.Symbol) { - sbuf.append(((com.fr.third.javassist.compiler.ast.Symbol)name).get()); - return; - } - else if (name instanceof com.fr.third.javassist.compiler.ast.Expr) { - com.fr.third.javassist.compiler.ast.Expr expr = (com.fr.third.javassist.compiler.ast.Expr)name; - if (expr.getOperator() == '.') { - toClassName(expr.oprand1(), sbuf); - sbuf.append('.'); - toClassName(expr.oprand2(), sbuf); - return; - } - } - - throw new CompileError("bad static member access", lex); - } - - /* primary.expr : THIS | SUPER | TRUE | FALSE | NULL - * | StringL - * | Identifier - * | NEW new.expr - * | "(" expression ")" - * | builtin.type ( "[" "]" )* "." CLASS - * - * Identifier represents either a local variable name, a member name, - * or a class name. - */ - private com.fr.third.javassist.compiler.ast.ASTree parsePrimaryExpr(SymbolTable tbl) throws CompileError { - int t; - String name; - com.fr.third.javassist.compiler.ast.Declarator decl; - com.fr.third.javassist.compiler.ast.ASTree expr; - - switch (t = lex.get()) { - case THIS : - case SUPER : - case TRUE : - case FALSE : - case NULL : - return new com.fr.third.javassist.compiler.ast.Keyword(t); - case Identifier : - name = lex.getString(); - decl = tbl.lookup(name); - if (decl == null) - return new com.fr.third.javassist.compiler.ast.Member(name); // this or static member - else - return new com.fr.third.javassist.compiler.ast.Variable(name, decl); // local variable - case StringL : - return new com.fr.third.javassist.compiler.ast.StringL(lex.getString()); - case NEW : - return parseNew(tbl); - case '(' : - expr = parseExpression(tbl); - if (lex.get() == ')') - return expr; - else - throw new CompileError(") is missing", lex); - default : - if (isBuiltinType(t) || t == VOID) { - int dim = parseArrayDimension(); - if (lex.get() == '.' && lex.get() == CLASS) - return parseDotClass(t, dim); - } - - throw new SyntaxError(lex); - } - } - - /* new.expr : class.type "(" argument.list ")" - * | class.type array.size [ array.initializer ] - * | primitive.type array.size [ array.initializer ] - */ - private com.fr.third.javassist.compiler.ast.NewExpr parseNew(SymbolTable tbl) throws CompileError { - com.fr.third.javassist.compiler.ast.ArrayInit init = null; - int t = lex.lookAhead(); - if (isBuiltinType(t)) { - lex.get(); - com.fr.third.javassist.compiler.ast.ASTList size = parseArraySize(tbl); - if (lex.lookAhead() == '{') - init = parseArrayInitializer(tbl); - - return new com.fr.third.javassist.compiler.ast.NewExpr(t, size, init); - } - else if (t == Identifier) { - com.fr.third.javassist.compiler.ast.ASTList name = parseClassType(tbl); - t = lex.lookAhead(); - if (t == '(') { - com.fr.third.javassist.compiler.ast.ASTList args = parseArgumentList(tbl); - return new com.fr.third.javassist.compiler.ast.NewExpr(name, args); - } - else if (t == '[') { - com.fr.third.javassist.compiler.ast.ASTList size = parseArraySize(tbl); - if (lex.lookAhead() == '{') - init = parseArrayInitializer(tbl); - - return com.fr.third.javassist.compiler.ast.NewExpr.makeObjectArray(name, size, init); - } - } - - throw new SyntaxError(lex); - } - - /* array.size : [ array.index ]* - */ - private com.fr.third.javassist.compiler.ast.ASTList parseArraySize(SymbolTable tbl) throws CompileError { - com.fr.third.javassist.compiler.ast.ASTList list = null; - while (lex.lookAhead() == '[') - list = com.fr.third.javassist.compiler.ast.ASTList.append(list, parseArrayIndex(tbl)); - - return list; - } - - /* array.index : "[" [ expression ] "]" - */ - private com.fr.third.javassist.compiler.ast.ASTree parseArrayIndex(SymbolTable tbl) throws CompileError { - lex.get(); // '[' - if (lex.lookAhead() == ']') { - lex.get(); - return null; - } - else { - com.fr.third.javassist.compiler.ast.ASTree index = parseExpression(tbl); - if (lex.get() != ']') - throw new CompileError("] is missing", lex); - - return index; - } - } - - /* argument.list : "(" [ expression [ "," expression ]* ] ")" - */ - private com.fr.third.javassist.compiler.ast.ASTList parseArgumentList(SymbolTable tbl) throws CompileError { - if (lex.get() != '(') - throw new CompileError("( is missing", lex); - - com.fr.third.javassist.compiler.ast.ASTList list = null; - if (lex.lookAhead() != ')') - for (;;) { - list = com.fr.third.javassist.compiler.ast.ASTList.append(list, parseExpression(tbl)); - if (lex.lookAhead() == ',') - lex.get(); - else - break; - } - - if (lex.get() != ')') - throw new CompileError(") is missing", lex); - - return list; - } -} - diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ProceedHandler.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ProceedHandler.java deleted file mode 100644 index 1634bc636..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ProceedHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -import com.fr.third.javassist.bytecode.Bytecode; -import com.fr.third.javassist.compiler.ast.ASTList; - -/** - * An interface to an object for implementing $proceed(). - * - * @see com.fr.third.javassist.compiler.JvstCodeGen#setProceedHandler(ProceedHandler, String) - * @see com.fr.third.javassist.compiler.JvstCodeGen#atMethodCall(Expr) - */ -public interface ProceedHandler { - void doit(JvstCodeGen gen, Bytecode b, ASTList args) throws com.fr.third.javassist.compiler.CompileError; - void setReturnType(JvstTypeChecker c, ASTList args) throws CompileError; -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/SymbolTable.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/SymbolTable.java deleted file mode 100644 index 4a2ccb4c6..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/SymbolTable.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -import java.util.HashMap; -import com.fr.third.javassist.compiler.ast.Declarator; - -public final class SymbolTable extends HashMap { - private SymbolTable parent; - - public SymbolTable() { this(null); } - - public SymbolTable(SymbolTable p) { - super(); - parent = p; - } - - public SymbolTable getParent() { return parent; } - - public Declarator lookup(String name) { - Declarator found = (Declarator)get(name); - if (found == null && parent != null) - return parent.lookup(name); - else - return found; - } - - public void append(String name, Declarator value) { - put(name, value); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/SyntaxError.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/SyntaxError.java deleted file mode 100644 index f54866cac..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/SyntaxError.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -public class SyntaxError extends CompileError { - public SyntaxError(Lex lexer) { - super("syntax error near \"" + lexer.getTextAround() + "\"", lexer); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/TokenId.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/TokenId.java deleted file mode 100644 index d39ba8733..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/TokenId.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -public interface TokenId { - int ABSTRACT = 300; - int BOOLEAN = 301; - int BREAK = 302; - int BYTE = 303; - int CASE = 304; - int CATCH = 305; - int CHAR = 306; - int CLASS = 307; - int CONST = 308; // reserved keyword - int CONTINUE = 309; - int DEFAULT = 310; - int DO = 311; - int DOUBLE = 312; - int ELSE = 313; - int EXTENDS = 314; - int FINAL = 315; - int FINALLY = 316; - int FLOAT = 317; - int FOR = 318; - int GOTO = 319; // reserved keyword - int IF = 320; - int IMPLEMENTS = 321; - int IMPORT = 322; - int INSTANCEOF = 323; - int INT = 324; - int INTERFACE = 325; - int LONG = 326; - int NATIVE = 327; - int NEW = 328; - int PACKAGE = 329; - int PRIVATE = 330; - int PROTECTED = 331; - int PUBLIC = 332; - int RETURN = 333; - int SHORT = 334; - int STATIC = 335; - int SUPER = 336; - int SWITCH = 337; - int SYNCHRONIZED = 338; - int THIS = 339; - int THROW = 340; - int THROWS = 341; - int TRANSIENT = 342; - int TRY = 343; - int VOID = 344; - int VOLATILE = 345; - int WHILE = 346; - int STRICT = 347; - - int NEQ = 350; // != - int MOD_E = 351; // %= - int AND_E = 352; // &= - int MUL_E = 353; // *= - int PLUS_E = 354; // += - int MINUS_E = 355; // -= - int DIV_E = 356; // /= - int LE = 357; // <= - int EQ = 358; // == - int GE = 359; // >= - int EXOR_E = 360; // ^= - int OR_E = 361; // |= - int PLUSPLUS = 362; // ++ - int MINUSMINUS = 363; // -- - int LSHIFT = 364; // << - int LSHIFT_E = 365; // <<= - int RSHIFT = 366; // >> - int RSHIFT_E = 367; // >>= - int OROR = 368; // || - int ANDAND = 369; // && - int ARSHIFT = 370; // >>> - int ARSHIFT_E = 371; // >>>= - - // operators from NEQ to ARSHIFT_E - String opNames[] = { "!=", "%=", "&=", "*=", "+=", "-=", "/=", - "<=", "==", ">=", "^=", "|=", "++", "--", - "<<", "<<=", ">>", ">>=", "||", "&&", ">>>", - ">>>=" }; - - // operators from MOD_E to ARSHIFT_E - int assignOps[] = { '%', '&', '*', '+', '-', '/', 0, 0, 0, - '^', '|', 0, 0, 0, LSHIFT, 0, RSHIFT, 0, 0, 0, - ARSHIFT }; - - int Identifier = 400; - int CharConstant = 401; - int IntConstant = 402; - int LongConstant = 403; - int FloatConstant = 404; - int DoubleConstant = 405; - int StringL = 406; - - int TRUE = 410; - int FALSE = 411; - int NULL = 412; - - int CALL = 'C'; // method call - int ARRAY = 'A'; // array access - int MEMBER = '#'; // static member access - - int EXPR = 'E'; // expression statement - int LABEL = 'L'; // label statement - int BLOCK = 'B'; // block statement - int DECL = 'D'; // declaration statement - - int BadToken = 500; -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/TypeChecker.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/TypeChecker.java deleted file mode 100644 index 5905c593e..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/TypeChecker.java +++ /dev/null @@ -1,1018 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CtField; -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.Modifier; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.bytecode.Opcode; -import com.fr.third.javassist.compiler.ast.DoubleConst; - -public class TypeChecker extends com.fr.third.javassist.compiler.ast.Visitor implements Opcode, com.fr.third.javassist.compiler.TokenId { - static final String javaLangObject = "java.lang.Object"; - static final String jvmJavaLangObject = "java/lang/Object"; - static final String jvmJavaLangString = "java/lang/String"; - static final String jvmJavaLangClass = "java/lang/Class"; - - /* The following fields are used by atXXX() methods - * for returning the type of the compiled expression. - */ - protected int exprType; // VOID, NULL, CLASS, BOOLEAN, INT, ... - protected int arrayDim; - protected String className; // JVM-internal representation - - protected MemberResolver resolver; - protected CtClass thisClass; - protected com.fr.third.javassist.bytecode.MethodInfo thisMethod; - - public TypeChecker(CtClass cc, ClassPool cp) { - resolver = new MemberResolver(cp); - thisClass = cc; - thisMethod = null; - } - - /* - * Converts an array of tuples of exprType, arrayDim, and className - * into a String object. - */ - protected static String argTypesToString(int[] types, int[] dims, - String[] cnames) { - StringBuffer sbuf = new StringBuffer(); - sbuf.append('('); - int n = types.length; - if (n > 0) { - int i = 0; - while (true) { - typeToString(sbuf, types[i], dims[i], cnames[i]); - if (++i < n) - sbuf.append(','); - else - break; - } - } - - sbuf.append(')'); - return sbuf.toString(); - } - - /* - * Converts a tuple of exprType, arrayDim, and className - * into a String object. - */ - protected static StringBuffer typeToString(StringBuffer sbuf, - int type, int dim, String cname) { - String s; - if (type == CLASS) - s = MemberResolver.jvmToJavaName(cname); - else if (type == NULL) - s = "Object"; - else - try { - s = MemberResolver.getTypeName(type); - } - catch (CompileError e) { - s = "?"; - } - - sbuf.append(s); - while (dim-- > 0) - sbuf.append("[]"); - - return sbuf; - } - - /** - * Records the currently compiled method. - */ - public void setThisMethod(com.fr.third.javassist.bytecode.MethodInfo m) { - thisMethod = m; - } - - protected static void fatal() throws CompileError { - throw new CompileError("fatal"); - } - - /** - * Returns the JVM-internal representation of this class name. - */ - protected String getThisName() { - return MemberResolver.javaToJvmName(thisClass.getName()); - } - - /** - * Returns the JVM-internal representation of this super class name. - */ - protected String getSuperName() throws CompileError { - return MemberResolver.javaToJvmName( - MemberResolver.getSuperclass(thisClass).getName()); - } - - /* Converts a class name into a JVM-internal representation. - * - * It may also expand a simple class name to java.lang.*. - * For example, this converts Object into java/lang/Object. - */ - protected String resolveClassName(com.fr.third.javassist.compiler.ast.ASTList name) throws CompileError { - return resolver.resolveClassName(name); - } - - /* Expands a simple class name to java.lang.*. - * For example, this converts Object into java/lang/Object. - */ - protected String resolveClassName(String jvmName) throws CompileError { - return resolver.resolveJvmClassName(jvmName); - } - - public void atNewExpr(com.fr.third.javassist.compiler.ast.NewExpr expr) throws CompileError { - if (expr.isArray()) - atNewArrayExpr(expr); - else { - CtClass clazz = resolver.lookupClassByName(expr.getClassName()); - String cname = clazz.getName(); - com.fr.third.javassist.compiler.ast.ASTList args = expr.getArguments(); - atMethodCallCore(clazz, com.fr.third.javassist.bytecode.MethodInfo.nameInit, args); - exprType = CLASS; - arrayDim = 0; - className = MemberResolver.javaToJvmName(cname); - } - } - - public void atNewArrayExpr(com.fr.third.javassist.compiler.ast.NewExpr expr) throws CompileError { - int type = expr.getArrayType(); - com.fr.third.javassist.compiler.ast.ASTList size = expr.getArraySize(); - com.fr.third.javassist.compiler.ast.ASTList classname = expr.getClassName(); - com.fr.third.javassist.compiler.ast.ASTree init = expr.getInitializer(); - if (init != null) - init.accept(this); - - if (size.length() > 1) - atMultiNewArray(type, classname, size); - else { - com.fr.third.javassist.compiler.ast.ASTree sizeExpr = size.head(); - if (sizeExpr != null) - sizeExpr.accept(this); - - exprType = type; - arrayDim = 1; - if (type == CLASS) - className = resolveClassName(classname); - else - className = null; - } - } - - public void atArrayInit(com.fr.third.javassist.compiler.ast.ArrayInit init) throws CompileError { - com.fr.third.javassist.compiler.ast.ASTList list = init; - while (list != null) { - com.fr.third.javassist.compiler.ast.ASTree h = list.head(); - list = list.tail(); - if (h != null) - h.accept(this); - } - } - - protected void atMultiNewArray(int type, com.fr.third.javassist.compiler.ast.ASTList classname, com.fr.third.javassist.compiler.ast.ASTList size) - throws CompileError - { - int count, dim; - dim = size.length(); - for (count = 0; size != null; size = size.tail()) { - com.fr.third.javassist.compiler.ast.ASTree s = size.head(); - if (s == null) - break; // int[][][] a = new int[3][4][]; - - ++count; - s.accept(this); - } - - exprType = type; - arrayDim = dim; - if (type == CLASS) - className = resolveClassName(classname); - else - className = null; - } - - public void atAssignExpr(com.fr.third.javassist.compiler.ast.AssignExpr expr) throws CompileError { - // =, %=, &=, *=, /=, +=, -=, ^=, |=, <<=, >>=, >>>= - int op = expr.getOperator(); - com.fr.third.javassist.compiler.ast.ASTree left = expr.oprand1(); - com.fr.third.javassist.compiler.ast.ASTree right = expr.oprand2(); - if (left instanceof com.fr.third.javassist.compiler.ast.Variable) - atVariableAssign(expr, op, (com.fr.third.javassist.compiler.ast.Variable)left, - ((com.fr.third.javassist.compiler.ast.Variable)left).getDeclarator(), - right); - else { - if (left instanceof com.fr.third.javassist.compiler.ast.Expr) { - com.fr.third.javassist.compiler.ast.Expr e = (com.fr.third.javassist.compiler.ast.Expr)left; - if (e.getOperator() == ARRAY) { - atArrayAssign(expr, op, (com.fr.third.javassist.compiler.ast.Expr)left, right); - return; - } - } - - atFieldAssign(expr, op, left, right); - } - } - - /* op is either =, %=, &=, *=, /=, +=, -=, ^=, |=, <<=, >>=, or >>>=. - * - * expr and var can be null. - */ - private void atVariableAssign(com.fr.third.javassist.compiler.ast.Expr expr, int op, com.fr.third.javassist.compiler.ast.Variable var, - com.fr.third.javassist.compiler.ast.Declarator d, com.fr.third.javassist.compiler.ast.ASTree right) - throws CompileError - { - int varType = d.getType(); - int varArray = d.getArrayDim(); - String varClass = d.getClassName(); - - if (op != '=') - atVariable(var); - - right.accept(this); - exprType = varType; - arrayDim = varArray; - className = varClass; - } - - private void atArrayAssign(com.fr.third.javassist.compiler.ast.Expr expr, int op, com.fr.third.javassist.compiler.ast.Expr array, - com.fr.third.javassist.compiler.ast.ASTree right) throws CompileError - { - atArrayRead(array.oprand1(), array.oprand2()); - int aType = exprType; - int aDim = arrayDim; - String cname = className; - right.accept(this); - exprType = aType; - arrayDim = aDim; - className = cname; - } - - protected void atFieldAssign(com.fr.third.javassist.compiler.ast.Expr expr, int op, com.fr.third.javassist.compiler.ast.ASTree left, com.fr.third.javassist.compiler.ast.ASTree right) - throws CompileError - { - CtField f = fieldAccess(left); - atFieldRead(f); - int fType = exprType; - int fDim = arrayDim; - String cname = className; - right.accept(this); - exprType = fType; - arrayDim = fDim; - className = cname; - } - - public void atCondExpr(com.fr.third.javassist.compiler.ast.CondExpr expr) throws CompileError { - booleanExpr(expr.condExpr()); - expr.thenExpr().accept(this); - int type1 = exprType; - int dim1 = arrayDim; - String cname1 = className; - expr.elseExpr().accept(this); - - if (dim1 == 0 && dim1 == arrayDim) - if (com.fr.third.javassist.compiler.CodeGen.rightIsStrong(type1, exprType)) - expr.setThen(new com.fr.third.javassist.compiler.ast.CastExpr(exprType, 0, expr.thenExpr())); - else if (com.fr.third.javassist.compiler.CodeGen.rightIsStrong(exprType, type1)) { - expr.setElse(new com.fr.third.javassist.compiler.ast.CastExpr(type1, 0, expr.elseExpr())); - exprType = type1; - } - } - - /* - * If atBinExpr() substitutes a new expression for the original - * binary-operator expression, it changes the operator name to '+' - * (if the original is not '+') and sets the new expression to the - * left-hand-side expression and null to the right-hand-side expression. - */ - public void atBinExpr(com.fr.third.javassist.compiler.ast.BinExpr expr) throws CompileError { - int token = expr.getOperator(); - int k = com.fr.third.javassist.compiler.CodeGen.lookupBinOp(token); - if (k >= 0) { - /* arithmetic operators: +, -, *, /, %, |, ^, &, <<, >>, >>> - */ - if (token == '+') { - com.fr.third.javassist.compiler.ast.Expr e = atPlusExpr(expr); - if (e != null) { - /* String concatenation has been translated into - * an expression using StringBuffer. - */ - e = com.fr.third.javassist.compiler.ast.CallExpr.makeCall(com.fr.third.javassist.compiler.ast.Expr.make('.', e, - new com.fr.third.javassist.compiler.ast.Member("toString")), null); - expr.setOprand1(e); - expr.setOprand2(null); // <---- look at this! - className = jvmJavaLangString; - } - } - else { - com.fr.third.javassist.compiler.ast.ASTree left = expr.oprand1(); - com.fr.third.javassist.compiler.ast.ASTree right = expr.oprand2(); - left.accept(this); - int type1 = exprType; - right.accept(this); - if (!isConstant(expr, token, left, right)) - computeBinExprType(expr, token, type1); - } - } - else { - /* equation: &&, ||, ==, !=, <=, >=, <, > - */ - booleanExpr(expr); - } - } - - /* EXPR must be a + expression. - * atPlusExpr() returns non-null if the given expression is string - * concatenation. The returned value is "new StringBuffer().append..". - */ - private com.fr.third.javassist.compiler.ast.Expr atPlusExpr(com.fr.third.javassist.compiler.ast.BinExpr expr) throws CompileError { - com.fr.third.javassist.compiler.ast.ASTree left = expr.oprand1(); - com.fr.third.javassist.compiler.ast.ASTree right = expr.oprand2(); - if (right == null) { - // this expression has been already type-checked. - // see atBinExpr() above. - left.accept(this); - return null; - } - - if (isPlusExpr(left)) { - com.fr.third.javassist.compiler.ast.Expr newExpr = atPlusExpr((com.fr.third.javassist.compiler.ast.BinExpr)left); - if (newExpr != null) { - right.accept(this); - exprType = CLASS; - arrayDim = 0; - className = "java/lang/StringBuffer"; - return makeAppendCall(newExpr, right); - } - } - else - left.accept(this); - - int type1 = exprType; - int dim1 = arrayDim; - String cname = className; - right.accept(this); - - if (isConstant(expr, '+', left, right)) - return null; - - if ((type1 == CLASS && dim1 == 0 && jvmJavaLangString.equals(cname)) - || (exprType == CLASS && arrayDim == 0 - && jvmJavaLangString.equals(className))) { - com.fr.third.javassist.compiler.ast.ASTList sbufClass = com.fr.third.javassist.compiler.ast.ASTList.make(new com.fr.third.javassist.compiler.ast.Symbol("java"), - new com.fr.third.javassist.compiler.ast.Symbol("lang"), new com.fr.third.javassist.compiler.ast.Symbol("StringBuffer")); - com.fr.third.javassist.compiler.ast.ASTree e = new com.fr.third.javassist.compiler.ast.NewExpr(sbufClass, null); - exprType = CLASS; - arrayDim = 0; - className = "java/lang/StringBuffer"; - return makeAppendCall(makeAppendCall(e, left), right); - } - else { - computeBinExprType(expr, '+', type1); - return null; - } - } - - private boolean isConstant(com.fr.third.javassist.compiler.ast.BinExpr expr, int op, com.fr.third.javassist.compiler.ast.ASTree left, - com.fr.third.javassist.compiler.ast.ASTree right) throws CompileError - { - left = stripPlusExpr(left); - right = stripPlusExpr(right); - com.fr.third.javassist.compiler.ast.ASTree newExpr = null; - if (left instanceof com.fr.third.javassist.compiler.ast.StringL && right instanceof com.fr.third.javassist.compiler.ast.StringL && op == '+') - newExpr = new com.fr.third.javassist.compiler.ast.StringL(((com.fr.third.javassist.compiler.ast.StringL)left).get() - + ((com.fr.third.javassist.compiler.ast.StringL)right).get()); - else if (left instanceof com.fr.third.javassist.compiler.ast.IntConst) - newExpr = ((com.fr.third.javassist.compiler.ast.IntConst)left).compute(op, right); - else if (left instanceof com.fr.third.javassist.compiler.ast.DoubleConst) - newExpr = ((com.fr.third.javassist.compiler.ast.DoubleConst)left).compute(op, right); - - if (newExpr == null) - return false; // not a constant expression - else { - expr.setOperator('+'); - expr.setOprand1(newExpr); - expr.setOprand2(null); - newExpr.accept(this); // for setting exprType, arrayDim, ... - return true; - } - } - - /* CodeGen.atSwitchStmnt() also calls stripPlusExpr(). - */ - static com.fr.third.javassist.compiler.ast.ASTree stripPlusExpr(com.fr.third.javassist.compiler.ast.ASTree expr) { - if (expr instanceof com.fr.third.javassist.compiler.ast.BinExpr) { - com.fr.third.javassist.compiler.ast.BinExpr e = (com.fr.third.javassist.compiler.ast.BinExpr)expr; - if (e.getOperator() == '+' && e.oprand2() == null) - return e.getLeft(); - } - else if (expr instanceof com.fr.third.javassist.compiler.ast.Expr) { // note: BinExpr extends Expr. - com.fr.third.javassist.compiler.ast.Expr e = (com.fr.third.javassist.compiler.ast.Expr)expr; - int op = e.getOperator(); - if (op == MEMBER) { - com.fr.third.javassist.compiler.ast.ASTree cexpr = getConstantFieldValue((com.fr.third.javassist.compiler.ast.Member)e.oprand2()); - if (cexpr != null) - return cexpr; - } - else if (op == '+' && e.getRight() == null) - return e.getLeft(); - } - else if (expr instanceof com.fr.third.javassist.compiler.ast.Member) { - com.fr.third.javassist.compiler.ast.ASTree cexpr = getConstantFieldValue((com.fr.third.javassist.compiler.ast.Member)expr); - if (cexpr != null) - return cexpr; - } - - return expr; - } - - /** - * If MEM is a static final field, this method returns a constant - * expression representing the value of that field. - */ - private static com.fr.third.javassist.compiler.ast.ASTree getConstantFieldValue(com.fr.third.javassist.compiler.ast.Member mem) { - return getConstantFieldValue(mem.getField()); - } - - public static com.fr.third.javassist.compiler.ast.ASTree getConstantFieldValue(CtField f) { - if (f == null) - return null; - - Object value = f.getConstantValue(); - if (value == null) - return null; - - if (value instanceof String) - return new com.fr.third.javassist.compiler.ast.StringL((String)value); - else if (value instanceof Double || value instanceof Float) { - int token = (value instanceof Double) - ? DoubleConstant : FloatConstant; - return new com.fr.third.javassist.compiler.ast.DoubleConst(((Number)value).doubleValue(), token); - } - else if (value instanceof Number) { - int token = (value instanceof Long) ? LongConstant : IntConstant; - return new com.fr.third.javassist.compiler.ast.IntConst(((Number)value).longValue(), token); - } - else if (value instanceof Boolean) - return new com.fr.third.javassist.compiler.ast.Keyword(((Boolean)value).booleanValue() - ? com.fr.third.javassist.compiler.TokenId.TRUE : TokenId.FALSE); - else - return null; - } - - private static boolean isPlusExpr(com.fr.third.javassist.compiler.ast.ASTree expr) { - if (expr instanceof com.fr.third.javassist.compiler.ast.BinExpr) { - com.fr.third.javassist.compiler.ast.BinExpr bexpr = (com.fr.third.javassist.compiler.ast.BinExpr)expr; - int token = bexpr.getOperator(); - return token == '+'; - } - - return false; - } - - private static com.fr.third.javassist.compiler.ast.Expr makeAppendCall(com.fr.third.javassist.compiler.ast.ASTree target, com.fr.third.javassist.compiler.ast.ASTree arg) { - return com.fr.third.javassist.compiler.ast.CallExpr.makeCall(com.fr.third.javassist.compiler.ast.Expr.make('.', target, new com.fr.third.javassist.compiler.ast.Member("append")), - new com.fr.third.javassist.compiler.ast.ASTList(arg)); - } - - private void computeBinExprType(com.fr.third.javassist.compiler.ast.BinExpr expr, int token, int type1) - throws CompileError - { - // arrayDim should be 0. - int type2 = exprType; - if (token == LSHIFT || token == RSHIFT || token == ARSHIFT) - exprType = type1; - else - insertCast(expr, type1, type2); - - if (com.fr.third.javassist.compiler.CodeGen.isP_INT(exprType)) - exprType = INT; // type1 may be BYTE, ... - } - - private void booleanExpr(com.fr.third.javassist.compiler.ast.ASTree expr) - throws CompileError - { - int op = com.fr.third.javassist.compiler.CodeGen.getCompOperator(expr); - if (op == EQ) { // ==, !=, ... - com.fr.third.javassist.compiler.ast.BinExpr bexpr = (com.fr.third.javassist.compiler.ast.BinExpr)expr; - bexpr.oprand1().accept(this); - int type1 = exprType; - int dim1 = arrayDim; - bexpr.oprand2().accept(this); - if (dim1 == 0 && arrayDim == 0) - insertCast(bexpr, type1, exprType); - } - else if (op == '!') - ((com.fr.third.javassist.compiler.ast.Expr)expr).oprand1().accept(this); - else if (op == ANDAND || op == OROR) { - com.fr.third.javassist.compiler.ast.BinExpr bexpr = (com.fr.third.javassist.compiler.ast.BinExpr)expr; - bexpr.oprand1().accept(this); - bexpr.oprand2().accept(this); - } - else // others - expr.accept(this); - - exprType = BOOLEAN; - arrayDim = 0; - } - - private void insertCast(com.fr.third.javassist.compiler.ast.BinExpr expr, int type1, int type2) - throws CompileError - { - if (com.fr.third.javassist.compiler.CodeGen.rightIsStrong(type1, type2)) - expr.setLeft(new com.fr.third.javassist.compiler.ast.CastExpr(type2, 0, expr.oprand1())); - else - exprType = type1; - } - - public void atCastExpr(com.fr.third.javassist.compiler.ast.CastExpr expr) throws CompileError { - String cname = resolveClassName(expr.getClassName()); - expr.getOprand().accept(this); - exprType = expr.getType(); - arrayDim = expr.getArrayDim(); - className = cname; - } - - public void atInstanceOfExpr(com.fr.third.javassist.compiler.ast.InstanceOfExpr expr) throws CompileError { - expr.getOprand().accept(this); - exprType = BOOLEAN; - arrayDim = 0; - } - - public void atExpr(com.fr.third.javassist.compiler.ast.Expr expr) throws CompileError { - // array access, member access, - // (unary) +, (unary) -, ++, --, !, ~ - - int token = expr.getOperator(); - com.fr.third.javassist.compiler.ast.ASTree oprand = expr.oprand1(); - if (token == '.') { - String member = ((com.fr.third.javassist.compiler.ast.Symbol)expr.oprand2()).get(); - if (member.equals("length")) - try { - atArrayLength(expr); - } - catch (NoFieldException nfe) { - // length might be a class or package name. - atFieldRead(expr); - } - else if (member.equals("class")) - atClassObject(expr); // .class - else - atFieldRead(expr); - } - else if (token == MEMBER) { // field read - String member = ((com.fr.third.javassist.compiler.ast.Symbol)expr.oprand2()).get(); - if (member.equals("class")) - atClassObject(expr); // .class - else - atFieldRead(expr); - } - else if (token == ARRAY) - atArrayRead(oprand, expr.oprand2()); - else if (token == PLUSPLUS || token == MINUSMINUS) - atPlusPlus(token, oprand, expr); - else if (token == '!') - booleanExpr(expr); - else if (token == CALL) // method call - fatal(); - else { - oprand.accept(this); - if (!isConstant(expr, token, oprand)) - if (token == '-' || token == '~') - if (CodeGen.isP_INT(exprType)) - exprType = INT; // type may be BYTE, ... - } - } - - private boolean isConstant(com.fr.third.javassist.compiler.ast.Expr expr, int op, com.fr.third.javassist.compiler.ast.ASTree oprand) { - oprand = stripPlusExpr(oprand); - if (oprand instanceof com.fr.third.javassist.compiler.ast.IntConst) { - com.fr.third.javassist.compiler.ast.IntConst c = (com.fr.third.javassist.compiler.ast.IntConst)oprand; - long v = c.get(); - if (op == '-') - v = -v; - else if (op == '~') - v = ~v; - else - return false; - - c.set(v); - } - else if (oprand instanceof com.fr.third.javassist.compiler.ast.DoubleConst) { - com.fr.third.javassist.compiler.ast.DoubleConst c = (com.fr.third.javassist.compiler.ast.DoubleConst)oprand; - if (op == '-') - c.set(-c.get()); - else - return false; - } - else - return false; - - expr.setOperator('+'); - return true; - } - - public void atCallExpr(com.fr.third.javassist.compiler.ast.CallExpr expr) throws CompileError { - String mname = null; - CtClass targetClass = null; - com.fr.third.javassist.compiler.ast.ASTree method = expr.oprand1(); - com.fr.third.javassist.compiler.ast.ASTList args = (com.fr.third.javassist.compiler.ast.ASTList)expr.oprand2(); - - if (method instanceof com.fr.third.javassist.compiler.ast.Member) { - mname = ((com.fr.third.javassist.compiler.ast.Member)method).get(); - targetClass = thisClass; - } - else if (method instanceof com.fr.third.javassist.compiler.ast.Keyword) { // constructor - mname = com.fr.third.javassist.bytecode.MethodInfo.nameInit; // - if (((com.fr.third.javassist.compiler.ast.Keyword)method).get() == SUPER) - targetClass = MemberResolver.getSuperclass(thisClass); - else - targetClass = thisClass; - } - else if (method instanceof com.fr.third.javassist.compiler.ast.Expr) { - com.fr.third.javassist.compiler.ast.Expr e = (com.fr.third.javassist.compiler.ast.Expr)method; - mname = ((com.fr.third.javassist.compiler.ast.Symbol)e.oprand2()).get(); - int op = e.getOperator(); - if (op == MEMBER) // static method - targetClass - = resolver.lookupClass(((com.fr.third.javassist.compiler.ast.Symbol)e.oprand1()).get(), - false); - else if (op == '.') { - com.fr.third.javassist.compiler.ast.ASTree target = e.oprand1(); - try { - target.accept(this); - } - catch (NoFieldException nfe) { - if (nfe.getExpr() != target) - throw nfe; - - // it should be a static method. - exprType = CLASS; - arrayDim = 0; - className = nfe.getField(); // JVM-internal - e.setOperator(MEMBER); - e.setOprand1(new com.fr.third.javassist.compiler.ast.Symbol(MemberResolver.jvmToJavaName( - className))); - } - - if (arrayDim > 0) - targetClass = resolver.lookupClass(javaLangObject, true); - else if (exprType == CLASS /* && arrayDim == 0 */) - targetClass = resolver.lookupClassByJvmName(className); - else - badMethod(); - } - else - badMethod(); - } - else - fatal(); - - MemberResolver.Method minfo - = atMethodCallCore(targetClass, mname, args); - expr.setMethod(minfo); - } - - private static void badMethod() throws CompileError { - throw new CompileError("bad method"); - } - - /** - * @return a pair of the class declaring the invoked method - * and the MethodInfo of that method. Never null. - */ - public MemberResolver.Method atMethodCallCore(CtClass targetClass, - String mname, com.fr.third.javassist.compiler.ast.ASTList args) - throws CompileError - { - int nargs = getMethodArgsLength(args); - int[] types = new int[nargs]; - int[] dims = new int[nargs]; - String[] cnames = new String[nargs]; - atMethodArgs(args, types, dims, cnames); - - MemberResolver.Method found - = resolver.lookupMethod(targetClass, thisClass, thisMethod, - mname, types, dims, cnames); - if (found == null) { - String clazz = targetClass.getName(); - String signature = argTypesToString(types, dims, cnames); - String msg; - if (mname.equals(com.fr.third.javassist.bytecode.MethodInfo.nameInit)) - msg = "cannot find constructor " + clazz + signature; - else - msg = mname + signature + " not found in " + clazz; - - throw new CompileError(msg); - } - - String desc = found.info.getDescriptor(); - setReturnType(desc); - return found; - } - - public int getMethodArgsLength(com.fr.third.javassist.compiler.ast.ASTList args) { - return com.fr.third.javassist.compiler.ast.ASTList.length(args); - } - - public void atMethodArgs(com.fr.third.javassist.compiler.ast.ASTList args, int[] types, int[] dims, - String[] cnames) throws CompileError { - int i = 0; - while (args != null) { - com.fr.third.javassist.compiler.ast.ASTree a = args.head(); - a.accept(this); - types[i] = exprType; - dims[i] = arrayDim; - cnames[i] = className; - ++i; - args = args.tail(); - } - } - - void setReturnType(String desc) throws CompileError { - int i = desc.indexOf(')'); - if (i < 0) - badMethod(); - - char c = desc.charAt(++i); - int dim = 0; - while (c == '[') { - ++dim; - c = desc.charAt(++i); - } - - arrayDim = dim; - if (c == 'L') { - int j = desc.indexOf(';', i + 1); - if (j < 0) - badMethod(); - - exprType = CLASS; - className = desc.substring(i + 1, j); - } - else { - exprType = MemberResolver.descToType(c); - className = null; - } - } - - private void atFieldRead(com.fr.third.javassist.compiler.ast.ASTree expr) throws CompileError { - atFieldRead(fieldAccess(expr)); - } - - private void atFieldRead(CtField f) throws CompileError { - com.fr.third.javassist.bytecode.FieldInfo finfo = f.getFieldInfo2(); - String type = finfo.getDescriptor(); - - int i = 0; - int dim = 0; - char c = type.charAt(i); - while (c == '[') { - ++dim; - c = type.charAt(++i); - } - - arrayDim = dim; - exprType = MemberResolver.descToType(c); - - if (c == 'L') - className = type.substring(i + 1, type.indexOf(';', i + 1)); - else - className = null; - } - - /* if EXPR is to access a static field, fieldAccess() translates EXPR - * into an expression using '#' (MEMBER). For example, it translates - * java.lang.Integer.TYPE into java.lang.Integer#TYPE. This translation - * speeds up type resolution by MemberCodeGen. - */ - protected CtField fieldAccess(com.fr.third.javassist.compiler.ast.ASTree expr) throws CompileError { - if (expr instanceof com.fr.third.javassist.compiler.ast.Member) { - com.fr.third.javassist.compiler.ast.Member mem = (com.fr.third.javassist.compiler.ast.Member)expr; - String name = mem.get(); - try { - CtField f = thisClass.getField(name); - if (Modifier.isStatic(f.getModifiers())) - mem.setField(f); - - return f; - } - catch (NotFoundException e) { - // EXPR might be part of a static member access? - throw new NoFieldException(name, expr); - } - } - else if (expr instanceof com.fr.third.javassist.compiler.ast.Expr) { - com.fr.third.javassist.compiler.ast.Expr e = (com.fr.third.javassist.compiler.ast.Expr)expr; - int op = e.getOperator(); - if (op == MEMBER) { - com.fr.third.javassist.compiler.ast.Member mem = (com.fr.third.javassist.compiler.ast.Member)e.oprand2(); - CtField f - = resolver.lookupField(((com.fr.third.javassist.compiler.ast.Symbol)e.oprand1()).get(), mem); - mem.setField(f); - return f; - } - else if (op == '.') { - try { - e.oprand1().accept(this); - } - catch (NoFieldException nfe) { - if (nfe.getExpr() != e.oprand1()) - throw nfe; - - /* EXPR should be a static field. - * If EXPR might be part of a qualified class name, - * lookupFieldByJvmName2() throws NoFieldException. - */ - return fieldAccess2(e, nfe.getField()); - } - - CompileError err = null; - try { - if (exprType == CLASS && arrayDim == 0) - return resolver.lookupFieldByJvmName(className, - (com.fr.third.javassist.compiler.ast.Symbol)e.oprand2()); - } - catch (CompileError ce) { - err = ce; - } - - /* If a filed name is the same name as a package's, - * a static member of a class in that package is not - * visible. For example, - * - * class Foo { - * int javassist; - * } - * - * It is impossible to add the following method: - * - * String m() { return javassist.CtClass.intType.toString(); } - * - * because javassist is a field name. However, this is - * often inconvenient, this compiler allows it. The following - * code is for that. - */ - com.fr.third.javassist.compiler.ast.ASTree oprnd1 = e.oprand1(); - if (oprnd1 instanceof com.fr.third.javassist.compiler.ast.Symbol) - return fieldAccess2(e, ((com.fr.third.javassist.compiler.ast.Symbol)oprnd1).get()); - - if (err != null) - throw err; - } - } - - throw new CompileError("bad filed access"); - } - - private CtField fieldAccess2(com.fr.third.javassist.compiler.ast.Expr e, String jvmClassName) throws CompileError { - com.fr.third.javassist.compiler.ast.Member fname = (com.fr.third.javassist.compiler.ast.Member)e.oprand2(); - CtField f = resolver.lookupFieldByJvmName2(jvmClassName, fname, e); - e.setOperator(MEMBER); - e.setOprand1(new com.fr.third.javassist.compiler.ast.Symbol(MemberResolver.jvmToJavaName(jvmClassName))); - fname.setField(f); - return f; - } - - public void atClassObject(com.fr.third.javassist.compiler.ast.Expr expr) throws CompileError { - exprType = CLASS; - arrayDim = 0; - className =jvmJavaLangClass; - } - - public void atArrayLength(com.fr.third.javassist.compiler.ast.Expr expr) throws CompileError { - expr.oprand1().accept(this); - if (arrayDim == 0) - throw new NoFieldException("length", expr); - - exprType = INT; - arrayDim = 0; - } - - public void atArrayRead(com.fr.third.javassist.compiler.ast.ASTree array, com.fr.third.javassist.compiler.ast.ASTree index) - throws CompileError - { - array.accept(this); - int type = exprType; - int dim = arrayDim; - String cname = className; - index.accept(this); - exprType = type; - arrayDim = dim - 1; - className = cname; - } - - private void atPlusPlus(int token, com.fr.third.javassist.compiler.ast.ASTree oprand, com.fr.third.javassist.compiler.ast.Expr expr) - throws CompileError - { - boolean isPost = oprand == null; // ++i or i++? - if (isPost) - oprand = expr.oprand2(); - - if (oprand instanceof com.fr.third.javassist.compiler.ast.Variable) { - com.fr.third.javassist.compiler.ast.Declarator d = ((com.fr.third.javassist.compiler.ast.Variable)oprand).getDeclarator(); - exprType = d.getType(); - arrayDim = d.getArrayDim(); - } - else { - if (oprand instanceof com.fr.third.javassist.compiler.ast.Expr) { - com.fr.third.javassist.compiler.ast.Expr e = (com.fr.third.javassist.compiler.ast.Expr)oprand; - if (e.getOperator() == ARRAY) { - atArrayRead(e.oprand1(), e.oprand2()); - // arrayDim should be 0. - int t = exprType; - if (t == INT || t == BYTE || t == CHAR || t == SHORT) - exprType = INT; - - return; - } - } - - atFieldPlusPlus(oprand); - } - } - - protected void atFieldPlusPlus(com.fr.third.javassist.compiler.ast.ASTree oprand) throws CompileError - { - CtField f = fieldAccess(oprand); - atFieldRead(f); - int t = exprType; - if (t == INT || t == BYTE || t == CHAR || t == SHORT) - exprType = INT; - } - - public void atMember(com.fr.third.javassist.compiler.ast.Member mem) throws CompileError { - atFieldRead(mem); - } - - public void atVariable(com.fr.third.javassist.compiler.ast.Variable v) throws CompileError { - com.fr.third.javassist.compiler.ast.Declarator d = v.getDeclarator(); - exprType = d.getType(); - arrayDim = d.getArrayDim(); - className = d.getClassName(); - } - - public void atKeyword(com.fr.third.javassist.compiler.ast.Keyword k) throws CompileError { - arrayDim = 0; - int token = k.get(); - switch (token) { - case TRUE : - case FALSE : - exprType = BOOLEAN; - break; - case NULL : - exprType = NULL; - break; - case THIS : - case SUPER : - exprType = CLASS; - if (token == THIS) - className = getThisName(); - else - className = getSuperName(); - break; - default : - fatal(); - } - } - - public void atStringL(com.fr.third.javassist.compiler.ast.StringL s) throws CompileError { - exprType = CLASS; - arrayDim = 0; - className = jvmJavaLangString; - } - - public void atIntConst(com.fr.third.javassist.compiler.ast.IntConst i) throws CompileError { - arrayDim = 0; - int type = i.getType(); - if (type == IntConstant || type == CharConstant) - exprType = (type == IntConstant ? INT : CHAR); - else - exprType = LONG; - } - - public void atDoubleConst(DoubleConst d) throws CompileError { - arrayDim = 0; - if (d.getType() == DoubleConstant) - exprType = DOUBLE; - else - exprType = FLOAT; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/ASTList.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/ASTList.java deleted file mode 100644 index 5a784693a..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/ASTList.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; - -/** - * A linked list. - * The right subtree must be an ASTList object or null. - */ -public class ASTList extends com.fr.third.javassist.compiler.ast.ASTree { - private com.fr.third.javassist.compiler.ast.ASTree left; - private ASTList right; - - public ASTList(com.fr.third.javassist.compiler.ast.ASTree _head, ASTList _tail) { - left = _head; - right = _tail; - } - - public ASTList(com.fr.third.javassist.compiler.ast.ASTree _head) { - left = _head; - right = null; - } - - public static ASTList make(com.fr.third.javassist.compiler.ast.ASTree e1, com.fr.third.javassist.compiler.ast.ASTree e2, com.fr.third.javassist.compiler.ast.ASTree e3) { - return new ASTList(e1, new ASTList(e2, new ASTList(e3))); - } - - public com.fr.third.javassist.compiler.ast.ASTree getLeft() { return left; } - - public com.fr.third.javassist.compiler.ast.ASTree getRight() { return right; } - - public void setLeft(com.fr.third.javassist.compiler.ast.ASTree _left) { left = _left; } - - public void setRight(com.fr.third.javassist.compiler.ast.ASTree _right) { - right = (ASTList)_right; - } - - /** - * Returns the car part of the list. - */ - public com.fr.third.javassist.compiler.ast.ASTree head() { return left; } - - public void setHead(com.fr.third.javassist.compiler.ast.ASTree _head) { - left = _head; - } - - /** - * Returns the cdr part of the list. - */ - public ASTList tail() { return right; } - - public void setTail(ASTList _tail) { - right = _tail; - } - - public void accept(Visitor v) throws CompileError { v.atASTList(this); } - - public String toString() { - StringBuffer sbuf = new StringBuffer(); - sbuf.append("(<"); - sbuf.append(getTag()); - sbuf.append('>'); - ASTList list = this; - while (list != null) { - sbuf.append(' '); - com.fr.third.javassist.compiler.ast.ASTree a = list.left; - sbuf.append(a == null ? "" : a.toString()); - list = list.right; - } - - sbuf.append(')'); - return sbuf.toString(); - } - - /** - * Returns the number of the elements in this list. - */ - public int length() { - return length(this); - } - - public static int length(ASTList list) { - if (list == null) - return 0; - - int n = 0; - while (list != null) { - list = list.right; - ++n; - } - - return n; - } - - /** - * Returns a sub list of the list. The sub list begins with the - * n-th element of the list. - * - * @param nth zero or more than zero. - */ - public ASTList sublist(int nth) { - ASTList list = this; - while (nth-- > 0) - list = list.right; - - return list; - } - - /** - * Substitutes newObj for oldObj in the - * list. - */ - public boolean subst(com.fr.third.javassist.compiler.ast.ASTree newObj, com.fr.third.javassist.compiler.ast.ASTree oldObj) { - for (ASTList list = this; list != null; list = list.right) - if (list.left == oldObj) { - list.left = newObj; - return true; - } - - return false; - } - - /** - * Appends an object to a list. - */ - public static ASTList append(ASTList a, ASTree b) { - return concat(a, new ASTList(b)); - } - - /** - * Concatenates two lists. - */ - public static ASTList concat(ASTList a, ASTList b) { - if (a == null) - return b; - else { - ASTList list = a; - while (list.right != null) - list = list.right; - - list.right = b; - return a; - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/ASTree.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/ASTree.java deleted file mode 100644 index 281054b31..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/ASTree.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import java.io.Serializable; -import com.fr.third.javassist.compiler.CompileError; - -/** - * Abstract Syntax Tree. An ASTree object represents a node of - * a binary tree. If the node is a leaf node, both getLeft() - * and getRight() returns null. - */ -public abstract class ASTree implements Serializable { - public ASTree getLeft() { return null; } - - public ASTree getRight() { return null; } - - public void setLeft(ASTree _left) {} - - public void setRight(ASTree _right) {} - - /** - * Is a method for the visitor pattern. It calls - * atXXX() on the given visitor, where - * XXX is the class name of the node object. - */ - public abstract void accept(Visitor v) throws CompileError; - - public String toString() { - StringBuffer sbuf = new StringBuffer(); - sbuf.append('<'); - sbuf.append(getTag()); - sbuf.append('>'); - return sbuf.toString(); - } - - /** - * Returns the type of this node. This method is used by - * toString(). - */ - protected String getTag() { - String name = getClass().getName(); - return name.substring(name.lastIndexOf('.') + 1); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/ArrayInit.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/ArrayInit.java deleted file mode 100644 index ab10b4ac0..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/ArrayInit.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; - -/** - * Array initializer such as { 1, 2, 3 }. - */ -public class ArrayInit extends ASTList { - public ArrayInit(ASTree firstElement) { - super(firstElement); - } - - public void accept(Visitor v) throws CompileError { v.atArrayInit(this); } - - public String getTag() { return "array"; } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/AssignExpr.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/AssignExpr.java deleted file mode 100644 index cb410b302..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/AssignExpr.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; - -/** - * Assignment expression. - */ -public class AssignExpr extends Expr { - /* operator must be either of: - * =, %=, &=, *=, +=, -=, /=, ^=, |=, <<=, >>=, >>>= - */ - - private AssignExpr(int op, com.fr.third.javassist.compiler.ast.ASTree _head, com.fr.third.javassist.compiler.ast.ASTList _tail) { - super(op, _head, _tail); - } - - public static AssignExpr makeAssign(int op, com.fr.third.javassist.compiler.ast.ASTree oprand1, - ASTree oprand2) { - return new AssignExpr(op, oprand1, new ASTList(oprand2)); - } - - public void accept(Visitor v) throws CompileError { - v.atAssignExpr(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/BinExpr.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/BinExpr.java deleted file mode 100644 index da3192f68..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/BinExpr.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; - -/** - * Binary expression. - * - *

If the operator is +, the right node might be null. - * See TypeChecker.atBinExpr(). - */ -public class BinExpr extends Expr { - /* operator must be either of: - * ||, &&, |, ^, &, ==, !=, <=, >=, <, >, - * <<, >>, >>>, +, -, *, /, % - */ - - private BinExpr(int op, com.fr.third.javassist.compiler.ast.ASTree _head, com.fr.third.javassist.compiler.ast.ASTList _tail) { - super(op, _head, _tail); - } - - public static BinExpr makeBin(int op, com.fr.third.javassist.compiler.ast.ASTree oprand1, ASTree oprand2) { - return new BinExpr(op, oprand1, new ASTList(oprand2)); - } - - public void accept(Visitor v) throws CompileError { v.atBinExpr(this); } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/CallExpr.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/CallExpr.java deleted file mode 100644 index b496eccb4..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/CallExpr.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; -import com.fr.third.javassist.compiler.TokenId; -import com.fr.third.javassist.compiler.MemberResolver; - -/** - * Method call expression. - */ -public class CallExpr extends Expr { - private MemberResolver.Method method; // cached result of lookupMethod() - - private CallExpr(com.fr.third.javassist.compiler.ast.ASTree _head, com.fr.third.javassist.compiler.ast.ASTList _tail) { - super(TokenId.CALL, _head, _tail); - method = null; - } - - public void setMethod(MemberResolver.Method m) { - method = m; - } - - public MemberResolver.Method getMethod() { - return method; - } - - public static CallExpr makeCall(com.fr.third.javassist.compiler.ast.ASTree target, ASTree args) { - return new CallExpr(target, new ASTList(args)); - } - - public void accept(Visitor v) throws CompileError { v.atCallExpr(this); } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/CastExpr.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/CastExpr.java deleted file mode 100644 index 169f66833..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/CastExpr.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.TokenId; -import com.fr.third.javassist.compiler.CompileError; - -/** - * Cast expression. - */ -public class CastExpr extends com.fr.third.javassist.compiler.ast.ASTList implements TokenId { - protected int castType; - protected int arrayDim; - - public CastExpr(com.fr.third.javassist.compiler.ast.ASTList className, int dim, com.fr.third.javassist.compiler.ast.ASTree expr) { - super(className, new com.fr.third.javassist.compiler.ast.ASTList(expr)); - castType = CLASS; - arrayDim = dim; - } - - public CastExpr(int type, int dim, com.fr.third.javassist.compiler.ast.ASTree expr) { - super(null, new com.fr.third.javassist.compiler.ast.ASTList(expr)); - castType = type; - arrayDim = dim; - } - - /* Returns CLASS, BOOLEAN, INT, or ... - */ - public int getType() { return castType; } - - public int getArrayDim() { return arrayDim; } - - public com.fr.third.javassist.compiler.ast.ASTList getClassName() { return (ASTList)getLeft(); } - - public com.fr.third.javassist.compiler.ast.ASTree getOprand() { return getRight().getLeft(); } - - public void setOprand(ASTree t) { getRight().setLeft(t); } - - public String getTag() { return "cast:" + castType + ":" + arrayDim; } - - public void accept(Visitor v) throws CompileError { v.atCastExpr(this); } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/CondExpr.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/CondExpr.java deleted file mode 100644 index 744fdf087..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/CondExpr.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; - -/** - * Conditional expression. - */ -public class CondExpr extends com.fr.third.javassist.compiler.ast.ASTList { - public CondExpr(com.fr.third.javassist.compiler.ast.ASTree cond, com.fr.third.javassist.compiler.ast.ASTree thenp, com.fr.third.javassist.compiler.ast.ASTree elsep) { - super(cond, new com.fr.third.javassist.compiler.ast.ASTList(thenp, new ASTList(elsep))); - } - - public com.fr.third.javassist.compiler.ast.ASTree condExpr() { return head(); } - - public void setCond(com.fr.third.javassist.compiler.ast.ASTree t) { setHead(t); } - - public com.fr.third.javassist.compiler.ast.ASTree thenExpr() { return tail().head(); } - - public void setThen(com.fr.third.javassist.compiler.ast.ASTree t) { tail().setHead(t); } - - public com.fr.third.javassist.compiler.ast.ASTree elseExpr() { return tail().tail().head(); } - - public void setElse(ASTree t) { tail().tail().setHead(t); } - - public String getTag() { return "?:"; } - - public void accept(Visitor v) throws CompileError { v.atCondExpr(this); } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Declarator.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Declarator.java deleted file mode 100644 index 4f52057be..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Declarator.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.TokenId; -import com.fr.third.javassist.compiler.CompileError; - -/** - * Variable declarator. - */ -public class Declarator extends com.fr.third.javassist.compiler.ast.ASTList implements TokenId { - protected int varType; - protected int arrayDim; - protected int localVar; - protected String qualifiedClass; // JVM-internal representation - - public Declarator(int type, int dim) { - super(null); - varType = type; - arrayDim = dim; - localVar = -1; - qualifiedClass = null; - } - - public Declarator(com.fr.third.javassist.compiler.ast.ASTList className, int dim) { - super(null); - varType = CLASS; - arrayDim = dim; - localVar = -1; - qualifiedClass = astToClassName(className, '/'); - } - - /* For declaring a pre-defined? local variable. - */ - public Declarator(int type, String jvmClassName, int dim, - int var, com.fr.third.javassist.compiler.ast.Symbol sym) { - super(null); - varType = type; - arrayDim = dim; - localVar = var; - qualifiedClass = jvmClassName; - setLeft(sym); - append(this, null); // initializer - } - - public Declarator make(com.fr.third.javassist.compiler.ast.Symbol sym, int dim, com.fr.third.javassist.compiler.ast.ASTree init) { - Declarator d = new Declarator(this.varType, this.arrayDim + dim); - d.qualifiedClass = this.qualifiedClass; - d.setLeft(sym); - append(d, init); - return d; - } - - /* Returns CLASS, BOOLEAN, BYTE, CHAR, SHORT, INT, LONG, FLOAT, - * or DOUBLE (or VOID) - */ - public int getType() { return varType; } - - public int getArrayDim() { return arrayDim; } - - public void addArrayDim(int d) { arrayDim += d; } - - public String getClassName() { return qualifiedClass; } - - public void setClassName(String s) { qualifiedClass = s; } - - public com.fr.third.javassist.compiler.ast.Symbol getVariable() { return (com.fr.third.javassist.compiler.ast.Symbol)getLeft(); } - - public void setVariable(com.fr.third.javassist.compiler.ast.Symbol sym) { setLeft(sym); } - - public com.fr.third.javassist.compiler.ast.ASTree getInitializer() { - com.fr.third.javassist.compiler.ast.ASTList t = tail(); - if (t != null) - return t.head(); - else - return null; - } - - public void setLocalVar(int n) { localVar = n; } - - public int getLocalVar() { return localVar; } - - public String getTag() { return "decl"; } - - public void accept(Visitor v) throws CompileError { - v.atDeclarator(this); - } - - public static String astToClassName(com.fr.third.javassist.compiler.ast.ASTList name, char sep) { - if (name == null) - return null; - - StringBuffer sbuf = new StringBuffer(); - astToClassName(sbuf, name, sep); - return sbuf.toString(); - } - - private static void astToClassName(StringBuffer sbuf, com.fr.third.javassist.compiler.ast.ASTList name, - char sep) { - for (;;) { - ASTree h = name.head(); - if (h instanceof com.fr.third.javassist.compiler.ast.Symbol) - sbuf.append(((Symbol)h).get()); - else if (h instanceof com.fr.third.javassist.compiler.ast.ASTList) - astToClassName(sbuf, (ASTList)h, sep); - - name = name.tail(); - if (name == null) - break; - - sbuf.append(sep); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/DoubleConst.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/DoubleConst.java deleted file mode 100644 index c1b1761b7..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/DoubleConst.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; -import com.fr.third.javassist.compiler.TokenId; - -/** - * Double constant. - */ -public class DoubleConst extends com.fr.third.javassist.compiler.ast.ASTree { - protected double value; - protected int type; - - public DoubleConst(double v, int tokenId) { value = v; type = tokenId; } - - public double get() { return value; } - - public void set(double v) { value = v; } - - /* Returns DoubleConstant or FloatConstant - */ - public int getType() { return type; } - - public String toString() { return Double.toString(value); } - - public void accept(Visitor v) throws CompileError { - v.atDoubleConst(this); - } - - public com.fr.third.javassist.compiler.ast.ASTree compute(int op, ASTree right) { - if (right instanceof com.fr.third.javassist.compiler.ast.IntConst) - return compute0(op, (com.fr.third.javassist.compiler.ast.IntConst)right); - else if (right instanceof DoubleConst) - return compute0(op, (DoubleConst)right); - else - return null; - } - - private DoubleConst compute0(int op, DoubleConst right) { - int newType; - if (this.type == TokenId.DoubleConstant - || right.type == TokenId.DoubleConstant) - newType = TokenId.DoubleConstant; - else - newType = TokenId.FloatConstant; - - return compute(op, this.value, right.value, newType); - } - - private DoubleConst compute0(int op, IntConst right) { - return compute(op, this.value, (double)right.value, this.type); - } - - private static DoubleConst compute(int op, double value1, double value2, - int newType) - { - double newValue; - switch (op) { - case '+' : - newValue = value1 + value2; - break; - case '-' : - newValue = value1 - value2; - break; - case '*' : - newValue = value1 * value2; - break; - case '/' : - newValue = value1 / value2; - break; - case '%' : - newValue = value1 % value2; - break; - default : - return null; - } - - return new DoubleConst(newValue, newType); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Expr.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Expr.java deleted file mode 100644 index b2d70fc13..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Expr.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.TokenId; -import com.fr.third.javassist.compiler.CompileError; - -/** - * Expression. - */ -public class Expr extends ASTList implements TokenId { - /* operator must be either of: - * (unary) +, (unary) -, ++, --, !, ~, - * ARRAY, . (dot), MEMBER (static member access). - * Otherwise, the object should be an instance of a subclass. - */ - - protected int operatorId; - - Expr(int op, ASTree _head, ASTList _tail) { - super(_head, _tail); - operatorId = op; - } - - Expr(int op, ASTree _head) { - super(_head); - operatorId = op; - } - - public static Expr make(int op, ASTree oprand1, ASTree oprand2) { - return new Expr(op, oprand1, new ASTList(oprand2)); - } - - public static Expr make(int op, ASTree oprand1) { - return new Expr(op, oprand1); - } - - public int getOperator() { return operatorId; } - - public void setOperator(int op) { operatorId = op; } - - public ASTree oprand1() { return getLeft(); } - - public void setOprand1(ASTree expr) { - setLeft(expr); - } - - public ASTree oprand2() { return getRight().getLeft(); } - - public void setOprand2(ASTree expr) { - getRight().setLeft(expr); - } - - public void accept(Visitor v) throws CompileError { v.atExpr(this); } - - public String getName() { - int id = operatorId; - if (id < 128) - return String.valueOf((char)id); - else if (NEQ <= id && id <= ARSHIFT_E) - return opNames[id - NEQ]; - else if (id == INSTANCEOF) - return "instanceof"; - else - return String.valueOf(id); - } - - protected String getTag() { - return "op:" + getName(); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/FieldDecl.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/FieldDecl.java deleted file mode 100644 index c33617f59..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/FieldDecl.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; - -public class FieldDecl extends com.fr.third.javassist.compiler.ast.ASTList { - public FieldDecl(com.fr.third.javassist.compiler.ast.ASTree _head, com.fr.third.javassist.compiler.ast.ASTList _tail) { - super(_head, _tail); - } - - public com.fr.third.javassist.compiler.ast.ASTList getModifiers() { return (ASTList)getLeft(); } - - public Declarator getDeclarator() { return (Declarator)tail().head(); } - - public com.fr.third.javassist.compiler.ast.ASTree getInit() { return (ASTree)sublist(2).head(); } - - public void accept(Visitor v) throws CompileError { - v.atFieldDecl(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/InstanceOfExpr.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/InstanceOfExpr.java deleted file mode 100644 index a127d1f63..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/InstanceOfExpr.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; - -/** - * Instanceof expression. - */ -public class InstanceOfExpr extends CastExpr { - public InstanceOfExpr(ASTList className, int dim, com.fr.third.javassist.compiler.ast.ASTree expr) { - super(className, dim, expr); - } - - public InstanceOfExpr(int type, int dim, ASTree expr) { - super(type, dim, expr); - } - - public String getTag() { - return "instanceof:" + castType + ":" + arrayDim; - } - - public void accept(Visitor v) throws CompileError { - v.atInstanceOfExpr(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/IntConst.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/IntConst.java deleted file mode 100644 index 71bfc91c2..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/IntConst.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; -import com.fr.third.javassist.compiler.TokenId; - -/** - * Integer constant. - */ -public class IntConst extends com.fr.third.javassist.compiler.ast.ASTree { - protected long value; - protected int type; - - public IntConst(long v, int tokenId) { value = v; type = tokenId; } - - public long get() { return value; } - - public void set(long v) { value = v; } - - /* Returns IntConstant, CharConstant, or LongConstant. - */ - public int getType() { return type; } - - public String toString() { return Long.toString(value); } - - public void accept(Visitor v) throws CompileError { - v.atIntConst(this); - } - - public com.fr.third.javassist.compiler.ast.ASTree compute(int op, ASTree right) { - if (right instanceof IntConst) - return compute0(op, (IntConst)right); - else if (right instanceof DoubleConst) - return compute0(op, (DoubleConst)right); - else - return null; - } - - private IntConst compute0(int op, IntConst right) { - int type1 = this.type; - int type2 = right.type; - int newType; - if (type1 == TokenId.LongConstant || type2 == TokenId.LongConstant) - newType = TokenId.LongConstant; - else if (type1 == TokenId.CharConstant - && type2 == TokenId.CharConstant) - newType = TokenId.CharConstant; - else - newType = TokenId.IntConstant; - - long value1 = this.value; - long value2 = right.value; - long newValue; - switch (op) { - case '+' : - newValue = value1 + value2; - break; - case '-' : - newValue = value1 - value2; - break; - case '*' : - newValue = value1 * value2; - break; - case '/' : - newValue = value1 / value2; - break; - case '%' : - newValue = value1 % value2; - break; - case '|' : - newValue = value1 | value2; - break; - case '^' : - newValue = value1 ^ value2; - break; - case '&' : - newValue = value1 & value2; - break; - case TokenId.LSHIFT : - newValue = value << (int)value2; - newType = type1; - break; - case TokenId.RSHIFT : - newValue = value >> (int)value2; - newType = type1; - break; - case TokenId.ARSHIFT : - newValue = value >>> (int)value2; - newType = type1; - break; - default : - return null; - } - - return new IntConst(newValue, newType); - } - - private DoubleConst compute0(int op, DoubleConst right) { - double value1 = (double)this.value; - double value2 = right.value; - double newValue; - switch (op) { - case '+' : - newValue = value1 + value2; - break; - case '-' : - newValue = value1 - value2; - break; - case '*' : - newValue = value1 * value2; - break; - case '/' : - newValue = value1 / value2; - break; - case '%' : - newValue = value1 % value2; - break; - default : - return null; - } - - return new DoubleConst(newValue, right.type); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Keyword.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Keyword.java deleted file mode 100644 index 5505b16ff..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Keyword.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; - -/** - * Keyword. - */ -public class Keyword extends ASTree { - protected int tokenId; - - public Keyword(int token) { - tokenId = token; - } - - public int get() { return tokenId; } - - public String toString() { return "id:" + tokenId; } - - public void accept(Visitor v) throws CompileError { v.atKeyword(this); } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Member.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Member.java deleted file mode 100644 index 02b716c28..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Member.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; -import com.fr.third.javassist.CtField; - -/** - * Member name. - */ -public class Member extends Symbol { - // cache maintained by fieldAccess() in TypeChecker. - // this is used to obtain the value of a static final field. - private CtField field; - - public Member(String name) { - super(name); - field = null; - } - - public void setField(CtField f) { field = f; } - - public CtField getField() { return field; } - - public void accept(Visitor v) throws CompileError { v.atMember(this); } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/MethodDecl.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/MethodDecl.java deleted file mode 100644 index a83583001..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/MethodDecl.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; - -public class MethodDecl extends com.fr.third.javassist.compiler.ast.ASTList { - public static final String initName = ""; - - public MethodDecl(ASTree _head, com.fr.third.javassist.compiler.ast.ASTList _tail) { - super(_head, _tail); - } - - public boolean isConstructor() { - Symbol sym = getReturn().getVariable(); - return sym != null && initName.equals(sym.get()); - } - - public com.fr.third.javassist.compiler.ast.ASTList getModifiers() { return (com.fr.third.javassist.compiler.ast.ASTList)getLeft(); } - - public com.fr.third.javassist.compiler.ast.Declarator getReturn() { return (Declarator)tail().head(); } - - public com.fr.third.javassist.compiler.ast.ASTList getParams() { return (com.fr.third.javassist.compiler.ast.ASTList)sublist(2).head(); } - - public com.fr.third.javassist.compiler.ast.ASTList getThrows() { return (ASTList)sublist(3).head(); } - - public com.fr.third.javassist.compiler.ast.Stmnt getBody() { return (Stmnt)sublist(4).head(); } - - public void accept(Visitor v) throws CompileError { - v.atMethodDecl(this); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/NewExpr.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/NewExpr.java deleted file mode 100644 index 8376ee3ba..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/NewExpr.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.TokenId; -import com.fr.third.javassist.compiler.CompileError; - -/** - * New Expression. - */ -public class NewExpr extends com.fr.third.javassist.compiler.ast.ASTList implements TokenId { - protected boolean newArray; - protected int arrayType; - - public NewExpr(com.fr.third.javassist.compiler.ast.ASTList className, com.fr.third.javassist.compiler.ast.ASTList args) { - super(className, new com.fr.third.javassist.compiler.ast.ASTList(args)); - newArray = false; - arrayType = CLASS; - } - - public NewExpr(int type, com.fr.third.javassist.compiler.ast.ASTList arraySize, ArrayInit init) { - super(null, new com.fr.third.javassist.compiler.ast.ASTList(arraySize)); - newArray = true; - arrayType = type; - if (init != null) - append(this, init); - } - - public static NewExpr makeObjectArray(com.fr.third.javassist.compiler.ast.ASTList className, - com.fr.third.javassist.compiler.ast.ASTList arraySize, ArrayInit init) { - NewExpr e = new NewExpr(className, arraySize); - e.newArray = true; - if (init != null) - append(e, init); - - return e; - } - - public boolean isArray() { return newArray; } - - /* TokenId.CLASS, TokenId.INT, ... - */ - public int getArrayType() { return arrayType; } - - public com.fr.third.javassist.compiler.ast.ASTList getClassName() { return (com.fr.third.javassist.compiler.ast.ASTList)getLeft(); } - - public com.fr.third.javassist.compiler.ast.ASTList getArguments() { return (com.fr.third.javassist.compiler.ast.ASTList)getRight().getLeft(); } - - public ASTList getArraySize() { return getArguments(); } - - public ArrayInit getInitializer() { - ASTree t = getRight().getRight(); - if (t == null) - return null; - else - return (ArrayInit)t.getLeft(); - } - - public void accept(Visitor v) throws CompileError { v.atNewExpr(this); } - - protected String getTag() { - return newArray ? "new[]" : "new"; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Pair.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Pair.java deleted file mode 100644 index 5d266a266..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Pair.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; - -/** - * A node of a a binary tree. This class provides concrete methods - * overriding abstract methods in ASTree. - */ -public class Pair extends ASTree { - protected ASTree left, right; - - public Pair(ASTree _left, ASTree _right) { - left = _left; - right = _right; - } - - public void accept(Visitor v) throws CompileError { v.atPair(this); } - - public String toString() { - StringBuffer sbuf = new StringBuffer(); - sbuf.append("( "); - sbuf.append(left == null ? "" : left.toString()); - sbuf.append(" . "); - sbuf.append(right == null ? "" : right.toString()); - sbuf.append(')'); - return sbuf.toString(); - } - - public ASTree getLeft() { return left; } - - public ASTree getRight() { return right; } - - public void setLeft(ASTree _left) { left = _left; } - - public void setRight(ASTree _right) { right = _right; } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Stmnt.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Stmnt.java deleted file mode 100644 index b372d25db..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Stmnt.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.TokenId; -import com.fr.third.javassist.compiler.CompileError; - -/** - * Statement. - */ -public class Stmnt extends ASTList implements TokenId { - protected int operatorId; - - public Stmnt(int op, ASTree _head, ASTList _tail) { - super(_head, _tail); - operatorId = op; - } - - public Stmnt(int op, ASTree _head) { - super(_head); - operatorId = op; - } - - public Stmnt(int op) { - this(op, null); - } - - public static Stmnt make(int op, ASTree oprand1, ASTree oprand2) { - return new Stmnt(op, oprand1, new ASTList(oprand2)); - } - - public static Stmnt make(int op, ASTree op1, ASTree op2, ASTree op3) { - return new Stmnt(op, op1, new ASTList(op2, new ASTList(op3))); - } - - public void accept(Visitor v) throws CompileError { v.atStmnt(this); } - - public int getOperator() { return operatorId; } - - protected String getTag() { - if (operatorId < 128) - return "stmnt:" + (char)operatorId; - else - return "stmnt:" + operatorId; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/StringL.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/StringL.java deleted file mode 100644 index 41e4e4fe5..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/StringL.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; - -/** - * String literal. - */ -public class StringL extends ASTree { - protected String text; - - public StringL(String t) { - text = t; - } - - public String get() { return text; } - - public String toString() { return "\"" + text + "\""; } - - public void accept(Visitor v) throws CompileError { v.atStringL(this); } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Symbol.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Symbol.java deleted file mode 100644 index 68b3eee69..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Symbol.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; - -/** - * Identifier. - */ -public class Symbol extends ASTree { - protected String identifier; - - public Symbol(String sym) { - identifier = sym; - } - - public String get() { return identifier; } - - public String toString() { return identifier; } - - public void accept(Visitor v) throws CompileError { v.atSymbol(this); } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Variable.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Variable.java deleted file mode 100644 index 88c2122fd..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Variable.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; - -/** - * Variable. - */ -public class Variable extends Symbol { - protected Declarator declarator; - - public Variable(String sym, Declarator d) { - super(sym); - declarator = d; - } - - public Declarator getDeclarator() { return declarator; } - - public String toString() { - return identifier + ":" + declarator.getType(); - } - - public void accept(Visitor v) throws CompileError { v.atVariable(this); } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Visitor.java b/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Visitor.java deleted file mode 100644 index 2e91af8a6..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/compiler/ast/Visitor.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.compiler.ast; - -import com.fr.third.javassist.compiler.CompileError; - -/** - * The visitor pattern. - * - * @see ast.ASTree#accept(Visitor) - */ -public class Visitor { - public void atASTList(ASTList n) throws CompileError {} - public void atPair(Pair n) throws CompileError {} - - public void atFieldDecl(FieldDecl n) throws CompileError {} - public void atMethodDecl(MethodDecl n) throws CompileError {} - public void atStmnt(Stmnt n) throws CompileError {} - public void atDeclarator(Declarator n) throws CompileError {} - - public void atAssignExpr(AssignExpr n) throws CompileError {} - public void atCondExpr(CondExpr n) throws CompileError {} - public void atBinExpr(BinExpr n) throws CompileError {} - public void atExpr(Expr n) throws CompileError {} - public void atCallExpr(CallExpr n) throws CompileError {} - public void atCastExpr(CastExpr n) throws CompileError {} - public void atInstanceOfExpr(InstanceOfExpr n) throws CompileError {} - public void atNewExpr(NewExpr n) throws CompileError {} - - public void atSymbol(Symbol n) throws CompileError {} - public void atMember(Member n) throws CompileError {} - public void atVariable(Variable n) throws CompileError {} - public void atKeyword(Keyword n) throws CompileError {} - public void atStringL(StringL n) throws CompileError {} - public void atIntConst(IntConst n) throws CompileError {} - public void atDoubleConst(DoubleConst n) throws CompileError {} - public void atArrayInit(ArrayInit n) throws CompileError {} -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformAccessArrayField.java b/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformAccessArrayField.java deleted file mode 100644 index 98cfb771c..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformAccessArrayField.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.convert; - -import com.fr.third.javassist.CannotCompileException; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.CodeConverter.ArrayAccessReplacementMethodNames; -import com.fr.third.javassist.bytecode.BadBytecode; -import com.fr.third.javassist.bytecode.CodeIterator; -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.bytecode.Descriptor; -import com.fr.third.javassist.bytecode.MethodInfo; -import com.fr.third.javassist.bytecode.analysis.Analyzer; -import com.fr.third.javassist.bytecode.analysis.Frame; - -/** - * A transformer which replaces array access with static method invocations. - * - * @author Kabir Khan - * @author Jason T. Greene - * @version $Revision: 1.8 $ - */ -public final class TransformAccessArrayField extends com.fr.third.javassist.convert.Transformer { - private final String methodClassname; - private final ArrayAccessReplacementMethodNames names; - private Frame[] frames; - private int offset; - - public TransformAccessArrayField(Transformer next, String methodClassname, - ArrayAccessReplacementMethodNames names) throws NotFoundException { - super(next); - this.methodClassname = methodClassname; - this.names = names; - - } - - public void initialize(ConstPool cp, CtClass clazz, MethodInfo minfo) throws CannotCompileException { - /* - * This transformer must be isolated from other transformers, since some - * of them affect the local variable and stack maximums without updating - * the code attribute to reflect the changes. This screws up the - * data-flow analyzer, since it relies on consistent code state. Even - * if the attribute values were updated correctly, we would have to - * detect it, and redo analysis, which is not cheap. Instead, we are - * better off doing all changes in initialize() before everyone else has - * a chance to muck things up. - */ - CodeIterator iterator = minfo.getCodeAttribute().iterator(); - while (iterator.hasNext()) { - try { - int pos = iterator.next(); - int c = iterator.byteAt(pos); - - if (c == AALOAD) - initFrames(clazz, minfo); - - if (c == AALOAD || c == BALOAD || c == CALOAD || c == DALOAD - || c == FALOAD || c == IALOAD || c == LALOAD - || c == SALOAD) { - pos = replace(cp, iterator, pos, c, getLoadReplacementSignature(c)); - } else if (c == AASTORE || c == BASTORE || c == CASTORE - || c == DASTORE || c == FASTORE || c == IASTORE - || c == LASTORE || c == SASTORE) { - pos = replace(cp, iterator, pos, c, getStoreReplacementSignature(c)); - } - - } catch (Exception e) { - throw new CannotCompileException(e); - } - } - } - - public void clean() { - frames = null; - offset = -1; - } - - public int transform(CtClass tclazz, int pos, CodeIterator iterator, - ConstPool cp) throws BadBytecode { - // Do nothing, see above comment - return pos; - } - - private Frame getFrame(int pos) throws BadBytecode { - return frames[pos - offset]; // Adjust pos - } - - private void initFrames(CtClass clazz, MethodInfo minfo) throws BadBytecode { - if (frames == null) { - frames = ((new Analyzer())).analyze(clazz, minfo); - offset = 0; // start tracking changes - } - } - - private int updatePos(int pos, int increment) { - if (offset > -1) - offset += increment; - - return pos + increment; - } - - private String getTopType(int pos) throws BadBytecode { - Frame frame = getFrame(pos); - if (frame == null) - return null; - - CtClass clazz = frame.peek().getCtClass(); - return clazz != null ? Descriptor.toJvmName(clazz) : null; - } - - private int replace(ConstPool cp, CodeIterator iterator, int pos, - int opcode, String signature) throws BadBytecode { - String castType = null; - String methodName = getMethodName(opcode); - if (methodName != null) { - // See if the object must be cast - if (opcode == AALOAD) { - castType = getTopType(iterator.lookAhead()); - // Do not replace an AALOAD instruction that we do not have a type for - // This happens when the state is guaranteed to be null (Type.UNINIT) - // So we don't really care about this case. - if (castType == null) - return pos; - if ("java/lang/Object".equals(castType)) - castType = null; - } - - // The gap may include extra padding - // Write a nop in case the padding pushes the instruction forward - iterator.writeByte(NOP, pos); - CodeIterator.Gap gap - = iterator.insertGapAt(pos, castType != null ? 5 : 2, false); - pos = gap.position; - int mi = cp.addClassInfo(methodClassname); - int methodref = cp.addMethodrefInfo(mi, methodName, signature); - iterator.writeByte(INVOKESTATIC, pos); - iterator.write16bit(methodref, pos + 1); - - if (castType != null) { - int index = cp.addClassInfo(castType); - iterator.writeByte(CHECKCAST, pos + 3); - iterator.write16bit(index, pos + 4); - } - - pos = updatePos(pos, gap.length); - } - - return pos; - } - - private String getMethodName(int opcode) { - String methodName = null; - switch (opcode) { - case AALOAD: - methodName = names.objectRead(); - break; - case BALOAD: - methodName = names.byteOrBooleanRead(); - break; - case CALOAD: - methodName = names.charRead(); - break; - case DALOAD: - methodName = names.doubleRead(); - break; - case FALOAD: - methodName = names.floatRead(); - break; - case IALOAD: - methodName = names.intRead(); - break; - case SALOAD: - methodName = names.shortRead(); - break; - case LALOAD: - methodName = names.longRead(); - break; - case AASTORE: - methodName = names.objectWrite(); - break; - case BASTORE: - methodName = names.byteOrBooleanWrite(); - break; - case CASTORE: - methodName = names.charWrite(); - break; - case DASTORE: - methodName = names.doubleWrite(); - break; - case FASTORE: - methodName = names.floatWrite(); - break; - case IASTORE: - methodName = names.intWrite(); - break; - case SASTORE: - methodName = names.shortWrite(); - break; - case LASTORE: - methodName = names.longWrite(); - break; - } - - if (methodName.equals("")) - methodName = null; - - return methodName; - } - - private String getLoadReplacementSignature(int opcode) throws BadBytecode { - switch (opcode) { - case AALOAD: - return "(Ljava/lang/Object;I)Ljava/lang/Object;"; - case BALOAD: - return "(Ljava/lang/Object;I)B"; - case CALOAD: - return "(Ljava/lang/Object;I)C"; - case DALOAD: - return "(Ljava/lang/Object;I)D"; - case FALOAD: - return "(Ljava/lang/Object;I)F"; - case IALOAD: - return "(Ljava/lang/Object;I)I"; - case SALOAD: - return "(Ljava/lang/Object;I)S"; - case LALOAD: - return "(Ljava/lang/Object;I)J"; - } - - throw new BadBytecode(opcode); - } - - private String getStoreReplacementSignature(int opcode) throws BadBytecode { - switch (opcode) { - case AASTORE: - return "(Ljava/lang/Object;ILjava/lang/Object;)V"; - case BASTORE: - return "(Ljava/lang/Object;IB)V"; - case CASTORE: - return "(Ljava/lang/Object;IC)V"; - case DASTORE: - return "(Ljava/lang/Object;ID)V"; - case FASTORE: - return "(Ljava/lang/Object;IF)V"; - case IASTORE: - return "(Ljava/lang/Object;II)V"; - case SASTORE: - return "(Ljava/lang/Object;IS)V"; - case LASTORE: - return "(Ljava/lang/Object;IJ)V"; - } - - throw new BadBytecode(opcode); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformAfter.java b/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformAfter.java deleted file mode 100644 index 793313803..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformAfter.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.convert; - -import com.fr.third.javassist.CtMethod; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.bytecode.CodeIterator; - -public class TransformAfter extends TransformBefore { - public TransformAfter(Transformer next, - CtMethod origMethod, CtMethod afterMethod) - throws NotFoundException - { - super(next, origMethod, afterMethod); - } - - protected int match2(int pos, CodeIterator iterator) throws com.fr.third.javassist.bytecode.BadBytecode { - iterator.move(pos); - iterator.insert(saveCode); - iterator.insert(loadCode); - int p = iterator.insertGap(3); - iterator.setMark(p); - iterator.insert(loadCode); - pos = iterator.next(); - p = iterator.getMark(); - iterator.writeByte(iterator.byteAt(pos), p); - iterator.write16bit(iterator.u16bitAt(pos + 1), p + 1); - iterator.writeByte(INVOKESTATIC, pos); - iterator.write16bit(newIndex, pos + 1); - iterator.move(p); - return iterator.next(); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformBefore.java b/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformBefore.java deleted file mode 100644 index 29eb157b3..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformBefore.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.convert; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CtMethod; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.bytecode.CodeAttribute; - -public class TransformBefore extends TransformCall { - protected CtClass[] parameterTypes; - protected int locals; - protected int maxLocals; - protected byte[] saveCode, loadCode; - - public TransformBefore(Transformer next, - CtMethod origMethod, CtMethod beforeMethod) - throws NotFoundException - { - super(next, origMethod, beforeMethod); - - // override - methodDescriptor = origMethod.getMethodInfo2().getDescriptor(); - - parameterTypes = origMethod.getParameterTypes(); - locals = 0; - maxLocals = 0; - saveCode = loadCode = null; - } - - public void initialize(com.fr.third.javassist.bytecode.ConstPool cp, CodeAttribute attr) { - super.initialize(cp, attr); - locals = 0; - maxLocals = attr.getMaxLocals(); - saveCode = loadCode = null; - } - - protected int match(int c, int pos, com.fr.third.javassist.bytecode.CodeIterator iterator, - int typedesc, com.fr.third.javassist.bytecode.ConstPool cp) throws com.fr.third.javassist.bytecode.BadBytecode - { - if (newIndex == 0) { - String desc = com.fr.third.javassist.bytecode.Descriptor.ofParameters(parameterTypes) + 'V'; - desc = com.fr.third.javassist.bytecode.Descriptor.insertParameter(classname, desc); - int nt = cp.addNameAndTypeInfo(newMethodname, desc); - int ci = cp.addClassInfo(newClassname); - newIndex = cp.addMethodrefInfo(ci, nt); - constPool = cp; - } - - if (saveCode == null) - makeCode(parameterTypes, cp); - - return match2(pos, iterator); - } - - protected int match2(int pos, com.fr.third.javassist.bytecode.CodeIterator iterator) throws com.fr.third.javassist.bytecode.BadBytecode { - iterator.move(pos); - iterator.insert(saveCode); - iterator.insert(loadCode); - int p = iterator.insertGap(3); - iterator.writeByte(INVOKESTATIC, p); - iterator.write16bit(newIndex, p + 1); - iterator.insert(loadCode); - return iterator.next(); - } - - public int extraLocals() { return locals; } - - protected void makeCode(CtClass[] paramTypes, com.fr.third.javassist.bytecode.ConstPool cp) { - com.fr.third.javassist.bytecode.Bytecode save = new com.fr.third.javassist.bytecode.Bytecode(cp, 0, 0); - com.fr.third.javassist.bytecode.Bytecode load = new com.fr.third.javassist.bytecode.Bytecode(cp, 0, 0); - - int var = maxLocals; - int len = (paramTypes == null) ? 0 : paramTypes.length; - load.addAload(var); - makeCode2(save, load, 0, len, paramTypes, var + 1); - save.addAstore(var); - - saveCode = save.get(); - loadCode = load.get(); - } - - private void makeCode2(com.fr.third.javassist.bytecode.Bytecode save, com.fr.third.javassist.bytecode.Bytecode load, - int i, int n, CtClass[] paramTypes, int var) - { - if (i < n) { - int size = load.addLoad(var, paramTypes[i]); - makeCode2(save, load, i + 1, n, paramTypes, var + size); - save.addStore(var, paramTypes[i]); - } - else - locals = var - maxLocals; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformCall.java b/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformCall.java deleted file mode 100644 index b0f8b5f83..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformCall.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.convert; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CtMethod; -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.Modifier; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.bytecode.CodeAttribute; - -public class TransformCall extends com.fr.third.javassist.convert.Transformer { - protected String classname, methodname, methodDescriptor; - protected String newClassname, newMethodname; - protected boolean newMethodIsPrivate; - - /* cache */ - protected int newIndex; - protected com.fr.third.javassist.bytecode.ConstPool constPool; - - public TransformCall(com.fr.third.javassist.convert.Transformer next, CtMethod origMethod, - CtMethod substMethod) - { - this(next, origMethod.getName(), substMethod); - classname = origMethod.getDeclaringClass().getName(); - } - - public TransformCall(Transformer next, String oldMethodName, - CtMethod substMethod) - { - super(next); - methodname = oldMethodName; - methodDescriptor = substMethod.getMethodInfo2().getDescriptor(); - classname = newClassname = substMethod.getDeclaringClass().getName(); - newMethodname = substMethod.getName(); - constPool = null; - newMethodIsPrivate = Modifier.isPrivate(substMethod.getModifiers()); - } - - public void initialize(com.fr.third.javassist.bytecode.ConstPool cp, CodeAttribute attr) { - if (constPool != cp) - newIndex = 0; - } - - /** - * Modify INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC and INVOKEVIRTUAL - * so that a different method is invoked. The class name in the operand - * of these instructions might be a subclass of the target class specified - * by classname. This method transforms the instruction - * in that case unless the subclass overrides the target method. - */ - public int transform(CtClass clazz, int pos, com.fr.third.javassist.bytecode.CodeIterator iterator, - com.fr.third.javassist.bytecode.ConstPool cp) throws com.fr.third.javassist.bytecode.BadBytecode - { - int c = iterator.byteAt(pos); - if (c == INVOKEINTERFACE || c == INVOKESPECIAL - || c == INVOKESTATIC || c == INVOKEVIRTUAL) { - int index = iterator.u16bitAt(pos + 1); - String cname = cp.eqMember(methodname, methodDescriptor, index); - if (cname != null && matchClass(cname, clazz.getClassPool())) { - int ntinfo = cp.getMemberNameAndType(index); - pos = match(c, pos, iterator, - cp.getNameAndTypeDescriptor(ntinfo), cp); - } - } - - return pos; - } - - private boolean matchClass(String name, ClassPool pool) { - if (classname.equals(name)) - return true; - - try { - CtClass clazz = pool.get(name); - CtClass declClazz = pool.get(classname); - if (clazz.subtypeOf(declClazz)) - try { - CtMethod m = clazz.getMethod(methodname, methodDescriptor); - return m.getDeclaringClass().getName().equals(classname); - } - catch (NotFoundException e) { - // maybe the original method has been removed. - return true; - } - } - catch (NotFoundException e) { - return false; - } - - return false; - } - - protected int match(int c, int pos, com.fr.third.javassist.bytecode.CodeIterator iterator, - int typedesc, com.fr.third.javassist.bytecode.ConstPool cp) throws com.fr.third.javassist.bytecode.BadBytecode - { - if (newIndex == 0) { - int nt = cp.addNameAndTypeInfo(cp.addUtf8Info(newMethodname), - typedesc); - int ci = cp.addClassInfo(newClassname); - if (c == INVOKEINTERFACE) - newIndex = cp.addInterfaceMethodrefInfo(ci, nt); - else { - if (newMethodIsPrivate && c == INVOKEVIRTUAL) - iterator.writeByte(INVOKESPECIAL, pos); - - newIndex = cp.addMethodrefInfo(ci, nt); - } - - constPool = cp; - } - - iterator.write16bit(newIndex, pos + 1); - return pos; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformFieldAccess.java b/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformFieldAccess.java deleted file mode 100644 index 4e9eaec43..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformFieldAccess.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.convert; - -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CtField; -import com.fr.third.javassist.Modifier; - -final public class TransformFieldAccess extends com.fr.third.javassist.convert.Transformer { - private String newClassname, newFieldname; - private String fieldname; - private CtClass fieldClass; - private boolean isPrivate; - - /* cache */ - private int newIndex; - private com.fr.third.javassist.bytecode.ConstPool constPool; - - public TransformFieldAccess(Transformer next, CtField field, - String newClassname, String newFieldname) - { - super(next); - this.fieldClass = field.getDeclaringClass(); - this.fieldname = field.getName(); - this.isPrivate = Modifier.isPrivate(field.getModifiers()); - this.newClassname = newClassname; - this.newFieldname = newFieldname; - this.constPool = null; - } - - public void initialize(com.fr.third.javassist.bytecode.ConstPool cp, CodeAttribute attr) { - if (constPool != cp) - newIndex = 0; - } - - /** - * Modify GETFIELD, GETSTATIC, PUTFIELD, and PUTSTATIC so that - * a different field is accessed. The new field must be declared - * in a superclass of the class in which the original field is - * declared. - */ - public int transform(CtClass clazz, int pos, - com.fr.third.javassist.bytecode.CodeIterator iterator, com.fr.third.javassist.bytecode.ConstPool cp) - { - int c = iterator.byteAt(pos); - if (c == GETFIELD || c == GETSTATIC - || c == PUTFIELD || c == PUTSTATIC) { - int index = iterator.u16bitAt(pos + 1); - String typedesc - = TransformReadField.isField(clazz.getClassPool(), cp, - fieldClass, fieldname, isPrivate, index); - if (typedesc != null) { - if (newIndex == 0) { - int nt = cp.addNameAndTypeInfo(newFieldname, - typedesc); - newIndex = cp.addFieldrefInfo( - cp.addClassInfo(newClassname), nt); - constPool = cp; - } - - iterator.write16bit(newIndex, pos + 1); - } - } - - return pos; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformNew.java b/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformNew.java deleted file mode 100644 index 4583a3638..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformNew.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.convert; - -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CannotCompileException; - -final public class TransformNew extends com.fr.third.javassist.convert.Transformer { - private int nested; - private String classname, trapClass, trapMethod; - - public TransformNew(Transformer next, - String classname, String trapClass, String trapMethod) { - super(next); - this.classname = classname; - this.trapClass = trapClass; - this.trapMethod = trapMethod; - } - - public void initialize(com.fr.third.javassist.bytecode.ConstPool cp, CodeAttribute attr) { - nested = 0; - } - - /** - * Replace a sequence of - * NEW classname - * DUP - * ... - * INVOKESPECIAL - * with - * NOP - * NOP - * ... - * INVOKESTATIC trapMethod in trapClass - */ - public int transform(CtClass clazz, int pos, com.fr.third.javassist.bytecode.CodeIterator iterator, - com.fr.third.javassist.bytecode.ConstPool cp) throws CannotCompileException - { - int index; - int c = iterator.byteAt(pos); - if (c == NEW) { - index = iterator.u16bitAt(pos + 1); - if (cp.getClassInfo(index).equals(classname)) { - if (iterator.byteAt(pos + 3) != DUP) - throw new CannotCompileException( - "NEW followed by no DUP was found"); - - iterator.writeByte(NOP, pos); - iterator.writeByte(NOP, pos + 1); - iterator.writeByte(NOP, pos + 2); - iterator.writeByte(NOP, pos + 3); - ++nested; - - com.fr.third.javassist.bytecode.StackMapTable smt - = (com.fr.third.javassist.bytecode.StackMapTable)iterator.get().getAttribute(com.fr.third.javassist.bytecode.StackMapTable.tag); - if (smt != null) - smt.removeNew(pos); - - com.fr.third.javassist.bytecode.StackMap sm - = (com.fr.third.javassist.bytecode.StackMap)iterator.get().getAttribute(com.fr.third.javassist.bytecode.StackMap.tag); - if (sm != null) - sm.removeNew(pos); - } - } - else if (c == INVOKESPECIAL) { - index = iterator.u16bitAt(pos + 1); - int typedesc = cp.isConstructor(classname, index); - if (typedesc != 0 && nested > 0) { - int methodref = computeMethodref(typedesc, cp); - iterator.writeByte(INVOKESTATIC, pos); - iterator.write16bit(methodref, pos + 1); - --nested; - } - } - - return pos; - } - - private int computeMethodref(int typedesc, com.fr.third.javassist.bytecode.ConstPool cp) { - int classIndex = cp.addClassInfo(trapClass); - int mnameIndex = cp.addUtf8Info(trapMethod); - typedesc = cp.addUtf8Info( - com.fr.third.javassist.bytecode.Descriptor.changeReturnType(classname, - cp.getUtf8Info(typedesc))); - return cp.addMethodrefInfo(classIndex, - cp.addNameAndTypeInfo(mnameIndex, typedesc)); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformNewClass.java b/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformNewClass.java deleted file mode 100644 index f6ce9be48..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformNewClass.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.convert; - -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CannotCompileException; - -final public class TransformNewClass extends com.fr.third.javassist.convert.Transformer { - private int nested; - private String classname, newClassName; - private int newClassIndex, newMethodNTIndex, newMethodIndex; - - public TransformNewClass(Transformer next, - String classname, String newClassName) { - super(next); - this.classname = classname; - this.newClassName = newClassName; - } - - public void initialize(com.fr.third.javassist.bytecode.ConstPool cp, CodeAttribute attr) { - nested = 0; - newClassIndex = newMethodNTIndex = newMethodIndex = 0; - } - - /** - * Modifies a sequence of - * NEW classname - * DUP - * ... - * INVOKESPECIAL classname:method - */ - public int transform(CtClass clazz, int pos, com.fr.third.javassist.bytecode.CodeIterator iterator, - com.fr.third.javassist.bytecode.ConstPool cp) throws CannotCompileException - { - int index; - int c = iterator.byteAt(pos); - if (c == NEW) { - index = iterator.u16bitAt(pos + 1); - if (cp.getClassInfo(index).equals(classname)) { - if (iterator.byteAt(pos + 3) != DUP) - throw new CannotCompileException( - "NEW followed by no DUP was found"); - - if (newClassIndex == 0) - newClassIndex = cp.addClassInfo(newClassName); - - iterator.write16bit(newClassIndex, pos + 1); - ++nested; - } - } - else if (c == INVOKESPECIAL) { - index = iterator.u16bitAt(pos + 1); - int typedesc = cp.isConstructor(classname, index); - if (typedesc != 0 && nested > 0) { - int nt = cp.getMethodrefNameAndType(index); - if (newMethodNTIndex != nt) { - newMethodNTIndex = nt; - newMethodIndex = cp.addMethodrefInfo(newClassIndex, nt); - } - - iterator.write16bit(newMethodIndex, pos + 1); - --nested; - } - } - - return pos; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformReadField.java b/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformReadField.java deleted file mode 100644 index e5b2d6c4c..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformReadField.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.convert; - -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CtField; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.Modifier; - -public class TransformReadField extends com.fr.third.javassist.convert.Transformer { - protected String fieldname; - protected CtClass fieldClass; - protected boolean isPrivate; - protected String methodClassname, methodName; - - public TransformReadField(Transformer next, CtField field, - String methodClassname, String methodName) - { - super(next); - this.fieldClass = field.getDeclaringClass(); - this.fieldname = field.getName(); - this.methodClassname = methodClassname; - this.methodName = methodName; - this.isPrivate = Modifier.isPrivate(field.getModifiers()); - } - - static String isField(ClassPool pool, com.fr.third.javassist.bytecode.ConstPool cp, CtClass fclass, - String fname, boolean is_private, int index) { - if (!cp.getFieldrefName(index).equals(fname)) - return null; - - try { - CtClass c = pool.get(cp.getFieldrefClassName(index)); - if (c == fclass || (!is_private && isFieldInSuper(c, fclass, fname))) - return cp.getFieldrefType(index); - } - catch (NotFoundException e) {} - return null; - } - - static boolean isFieldInSuper(CtClass clazz, CtClass fclass, String fname) { - if (!clazz.subclassOf(fclass)) - return false; - - try { - CtField f = clazz.getField(fname); - return f.getDeclaringClass() == fclass; - } - catch (NotFoundException e) {} - return false; - } - - public int transform(CtClass tclazz, int pos, com.fr.third.javassist.bytecode.CodeIterator iterator, - ConstPool cp) throws com.fr.third.javassist.bytecode.BadBytecode - { - int c = iterator.byteAt(pos); - if (c == GETFIELD || c == GETSTATIC) { - int index = iterator.u16bitAt(pos + 1); - String typedesc = isField(tclazz.getClassPool(), cp, - fieldClass, fieldname, isPrivate, index); - if (typedesc != null) { - if (c == GETSTATIC) { - iterator.move(pos); - pos = iterator.insertGap(1); // insertGap() may insert 4 bytes. - iterator.writeByte(ACONST_NULL, pos); - pos = iterator.next(); - } - - String type = "(Ljava/lang/Object;)" + typedesc; - int mi = cp.addClassInfo(methodClassname); - int methodref = cp.addMethodrefInfo(mi, methodName, type); - iterator.writeByte(INVOKESTATIC, pos); - iterator.write16bit(methodref, pos + 1); - return pos; - } - } - - return pos; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformWriteField.java b/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformWriteField.java deleted file mode 100644 index ed7868d26..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/convert/TransformWriteField.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.convert; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CtField; -import com.fr.third.javassist.bytecode.CodeAttribute; - -final public class TransformWriteField extends TransformReadField { - public TransformWriteField(Transformer next, CtField field, - String methodClassname, String methodName) - { - super(next, field, methodClassname, methodName); - } - - public int transform(CtClass tclazz, int pos, com.fr.third.javassist.bytecode.CodeIterator iterator, - com.fr.third.javassist.bytecode.ConstPool cp) throws com.fr.third.javassist.bytecode.BadBytecode - { - int c = iterator.byteAt(pos); - if (c == PUTFIELD || c == PUTSTATIC) { - int index = iterator.u16bitAt(pos + 1); - String typedesc = isField(tclazz.getClassPool(), cp, - fieldClass, fieldname, isPrivate, index); - if (typedesc != null) { - if (c == PUTSTATIC) { - CodeAttribute ca = iterator.get(); - iterator.move(pos); - char c0 = typedesc.charAt(0); - if (c0 == 'J' || c0 == 'D') { // long or double - // insertGap() may insert 4 bytes. - pos = iterator.insertGap(3); - iterator.writeByte(ACONST_NULL, pos); - iterator.writeByte(DUP_X2, pos + 1); - iterator.writeByte(POP, pos + 2); - ca.setMaxStack(ca.getMaxStack() + 2); - } - else { - // insertGap() may insert 4 bytes. - pos = iterator.insertGap(2); - iterator.writeByte(ACONST_NULL, pos); - iterator.writeByte(SWAP, pos + 1); - ca.setMaxStack(ca.getMaxStack() + 1); - } - - pos = iterator.next(); - } - - int mi = cp.addClassInfo(methodClassname); - String type = "(Ljava/lang/Object;" + typedesc + ")V"; - int methodref = cp.addMethodrefInfo(mi, methodName, type); - iterator.writeByte(INVOKESTATIC, pos); - iterator.write16bit(methodref, pos + 1); - } - } - - return pos; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/convert/Transformer.java b/fine-javassist/src/main/java/com/fr/third/javassist/convert/Transformer.java deleted file mode 100644 index fb2e2c6e1..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/convert/Transformer.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.convert; - -import com.fr.third.javassist.CannotCompileException; -import com.fr.third.javassist.CodeConverter; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.bytecode.BadBytecode; -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.bytecode.CodeIterator; -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.bytecode.MethodInfo; -import com.fr.third.javassist.bytecode.Opcode; - -/** - * Transformer and its subclasses are used for executing - * code transformation specified by CodeConverter. - * - * @see CodeConverter - */ -public abstract class Transformer implements Opcode { - private Transformer next; - - public Transformer(Transformer t) { - next = t; - } - - public Transformer getNext() { return next; } - - public void initialize(ConstPool cp, CodeAttribute attr) {} - - public void initialize(ConstPool cp, CtClass clazz, MethodInfo minfo) throws CannotCompileException { - initialize(cp, minfo.getCodeAttribute()); - } - - public void clean() {} - - public abstract int transform(CtClass clazz, int pos, CodeIterator it, - ConstPool cp) throws CannotCompileException, BadBytecode; - - public int extraLocals() { return 0; } - - public int extraStack() { return 0; } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/expr/Cast.java b/fine-javassist/src/main/java/com/fr/third/javassist/expr/Cast.java deleted file mode 100644 index b175e9b69..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/expr/Cast.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.expr; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.compiler.CompileError; -import com.fr.third.javassist.compiler.ast.ASTList; - -/** - * Explicit type cast. - */ -public class Cast extends Expr { - /** - * Undocumented constructor. Do not use; internal-use only. - */ - protected Cast(int pos, com.fr.third.javassist.bytecode.CodeIterator i, com.fr.third.javassist.CtClass declaring, com.fr.third.javassist.bytecode.MethodInfo m) { - super(pos, i, declaring, m); - } - - /** - * Returns the method or constructor containing the type cast - * expression represented by this object. - */ - public com.fr.third.javassist.CtBehavior where() { return super.where(); } - - /** - * Returns the line number of the source line containing the - * type-cast expression. - * - * @return -1 if this information is not available. - */ - public int getLineNumber() { - return super.getLineNumber(); - } - - /** - * Returns the source file containing the type-cast expression. - * - * @return null if this information is not available. - */ - public String getFileName() { - return super.getFileName(); - } - - /** - * Returns the CtClass object representing - * the type specified by the cast. - */ - public com.fr.third.javassist.CtClass getType() throws com.fr.third.javassist.NotFoundException { - com.fr.third.javassist.bytecode.ConstPool cp = getConstPool(); - int pos = currentPos; - int index = iterator.u16bitAt(pos + 1); - String name = cp.getClassInfo(index); - return thisClass.getClassPool().getCtClass(name); - } - - /** - * Returns the list of exceptions that the expression may throw. - * This list includes both the exceptions that the try-catch statements - * including the expression can catch and the exceptions that - * the throws declaration allows the method to throw. - */ - public com.fr.third.javassist.CtClass[] mayThrow() { - return super.mayThrow(); - } - - /** - * Replaces the explicit cast operator with the bytecode derived from - * the given source text. - * - *

$0 is available but the value is null. - * - * @param statement a Java statement except try-catch. - */ - public void replace(String statement) throws com.fr.third.javassist.CannotCompileException { - thisClass.getClassFile(); // to call checkModify(). - com.fr.third.javassist.bytecode.ConstPool constPool = getConstPool(); - int pos = currentPos; - int index = iterator.u16bitAt(pos + 1); - - com.fr.third.javassist.compiler.Javac jc = new com.fr.third.javassist.compiler.Javac(thisClass); - com.fr.third.javassist.ClassPool cp = thisClass.getClassPool(); - CodeAttribute ca = iterator.get(); - - try { - com.fr.third.javassist.CtClass[] params - = new com.fr.third.javassist.CtClass[] { cp.get(javaLangObject) }; - com.fr.third.javassist.CtClass retType = getType(); - - int paramVar = ca.getMaxLocals(); - jc.recordParams(javaLangObject, params, true, paramVar, - withinStatic()); - int retVar = jc.recordReturnType(retType, true); - jc.recordProceed(new ProceedForCast(index, retType)); - - /* Is $_ included in the source code? - */ - checkResultValue(retType, statement); - - com.fr.third.javassist.bytecode.Bytecode bytecode = jc.getBytecode(); - storeStack(params, true, paramVar, bytecode); - jc.recordLocalVariables(ca, pos); - - bytecode.addConstZero(retType); - bytecode.addStore(retVar, retType); // initialize $_ - - jc.compileStmnt(statement); - bytecode.addLoad(retVar, retType); - - replace0(pos, bytecode, 3); - } - catch (com.fr.third.javassist.compiler.CompileError e) { throw new com.fr.third.javassist.CannotCompileException(e); } - catch (com.fr.third.javassist.NotFoundException e) { throw new com.fr.third.javassist.CannotCompileException(e); } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException("broken method"); - } - } - - /* $proceed(Object obj) - */ - static class ProceedForCast implements com.fr.third.javassist.compiler.ProceedHandler { - int index; - com.fr.third.javassist.CtClass retType; - - ProceedForCast(int i, CtClass t) { - index = i; - retType = t; - } - - public void doit(com.fr.third.javassist.compiler.JvstCodeGen gen, com.fr.third.javassist.bytecode.Bytecode bytecode, ASTList args) - throws com.fr.third.javassist.compiler.CompileError - { - if (gen.getMethodArgsLength(args) != 1) - throw new com.fr.third.javassist.compiler.CompileError(com.fr.third.javassist.compiler.Javac.proceedName - + "() cannot take more than one parameter " - + "for cast"); - - gen.atMethodArgs(args, new int[1], new int[1], new String[1]); - bytecode.addOpcode(com.fr.third.javassist.bytecode.Opcode.CHECKCAST); - bytecode.addIndex(index); - gen.setType(retType); - } - - public void setReturnType(com.fr.third.javassist.compiler.JvstTypeChecker c, ASTList args) - throws CompileError - { - c.atMethodArgs(args, new int[1], new int[1], new String[1]); - c.setType(retType); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/expr/ConstructorCall.java b/fine-javassist/src/main/java/com/fr/third/javassist/expr/ConstructorCall.java deleted file mode 100644 index 6d916b2a1..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/expr/ConstructorCall.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.expr; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CtConstructor; -import com.fr.third.javassist.CtMethod; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.bytecode.CodeIterator; -import com.fr.third.javassist.bytecode.MethodInfo; - -/** - * Constructor call such as this() and super() - * within a constructor body. - * - * @see NewExpr - */ -public class ConstructorCall extends MethodCall { - /** - * Undocumented constructor. Do not use; internal-use only. - */ - protected ConstructorCall(int pos, CodeIterator i, CtClass decl, MethodInfo m) { - super(pos, i, decl, m); - } - - /** - * Returns "super" or ""this". - */ - public String getMethodName() { - return isSuper() ? "super" : "this"; - } - - /** - * Always throws a NotFoundException. - * - * @see #getConstructor() - */ - public CtMethod getMethod() throws NotFoundException { - throw new NotFoundException("this is a constructor call. Call getConstructor()."); - } - - /** - * Returns the called constructor. - */ - public CtConstructor getConstructor() throws NotFoundException { - return getCtClass().getConstructor(getSignature()); - } - - /** - * Returns true if the called constructor is not this() - * but super() (a constructor declared in the super class). - */ - public boolean isSuper() { - return super.isSuper(); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/expr/Expr.java b/fine-javassist/src/main/java/com/fr/third/javassist/expr/Expr.java deleted file mode 100644 index 40f743804..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/expr/Expr.java +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.expr; - -import com.fr.third.javassist.CannotCompileException; -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.CtBehavior; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CtConstructor; -import com.fr.third.javassist.CtPrimitiveType; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.bytecode.AccessFlag; -import com.fr.third.javassist.bytecode.BadBytecode; -import com.fr.third.javassist.bytecode.Bytecode; -import com.fr.third.javassist.bytecode.ClassFile; -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.bytecode.CodeIterator; -import com.fr.third.javassist.bytecode.ConstPool; -import com.fr.third.javassist.bytecode.ExceptionTable; -import com.fr.third.javassist.bytecode.ExceptionsAttribute; -import com.fr.third.javassist.bytecode.MethodInfo; -import com.fr.third.javassist.bytecode.Opcode; -import com.fr.third.javassist.compiler.Javac; - -import java.util.Iterator; -import java.util.LinkedList; - -/** - * Expression. - */ -public abstract class Expr implements Opcode { - int currentPos; - CodeIterator iterator; - CtClass thisClass; - MethodInfo thisMethod; - boolean edited; - int maxLocals, maxStack; - - static final String javaLangObject = "java.lang.Object"; - - /** - * Undocumented constructor. Do not use; internal-use only. - */ - protected Expr(int pos, CodeIterator i, CtClass declaring, MethodInfo m) { - currentPos = pos; - iterator = i; - thisClass = declaring; - thisMethod = m; - } - - /** - * Returns the class that declares the method enclosing - * this expression. - * - * @since 3.7 - */ - public CtClass getEnclosingClass() { return thisClass; } - - protected final ConstPool getConstPool() { - return thisMethod.getConstPool(); - } - - protected final boolean edited() { - return edited; - } - - protected final int locals() { - return maxLocals; - } - - protected final int stack() { - return maxStack; - } - - /** - * Returns true if this method is static. - */ - protected final boolean withinStatic() { - return (thisMethod.getAccessFlags() & AccessFlag.STATIC) != 0; - } - - /** - * Returns the constructor or method containing the expression. - */ - public CtBehavior where() { - MethodInfo mi = thisMethod; - CtBehavior[] cb = thisClass.getDeclaredBehaviors(); - for (int i = cb.length - 1; i >= 0; --i) - if (cb[i].getMethodInfo2() == mi) - return cb[i]; - - CtConstructor init = thisClass.getClassInitializer(); - if (init != null && init.getMethodInfo2() == mi) - return init; - - /* getDeclaredBehaviors() returns a list of methods/constructors. - * Although the list is cached in a CtClass object, it might be - * recreated for some reason. Thus, the member name and the signature - * must be also checked. - */ - for (int i = cb.length - 1; i >= 0; --i) { - if (thisMethod.getName().equals(cb[i].getMethodInfo2().getName()) - && thisMethod.getDescriptor() - .equals(cb[i].getMethodInfo2().getDescriptor())) { - return cb[i]; - } - } - - throw new RuntimeException("fatal: not found"); - } - - /** - * Returns the list of exceptions that the expression may throw. This list - * includes both the exceptions that the try-catch statements including the - * expression can catch and the exceptions that the throws declaration - * allows the method to throw. - */ - public CtClass[] mayThrow() { - ClassPool pool = thisClass.getClassPool(); - ConstPool cp = thisMethod.getConstPool(); - LinkedList list = new LinkedList(); - try { - CodeAttribute ca = thisMethod.getCodeAttribute(); - ExceptionTable et = ca.getExceptionTable(); - int pos = currentPos; - int n = et.size(); - for (int i = 0; i < n; ++i) - if (et.startPc(i) <= pos && pos < et.endPc(i)) { - int t = et.catchType(i); - if (t > 0) - try { - addClass(list, pool.get(cp.getClassInfo(t))); - } - catch (NotFoundException e) { - } - } - } - catch (NullPointerException e) { - } - - ExceptionsAttribute ea = thisMethod.getExceptionsAttribute(); - if (ea != null) { - String[] exceptions = ea.getExceptions(); - if (exceptions != null) { - int n = exceptions.length; - for (int i = 0; i < n; ++i) - try { - addClass(list, pool.get(exceptions[i])); - } - catch (NotFoundException e) { - } - } - } - - return (CtClass[])list.toArray(new CtClass[list.size()]); - } - - private static void addClass(LinkedList list, CtClass c) { - Iterator it = list.iterator(); - while (it.hasNext()) - if (it.next() == c) - return; - - list.add(c); - } - - /** - * Returns the index of the bytecode corresponding to the expression. It is - * the index into the byte array containing the Java bytecode that - * implements the method. - */ - public int indexOfBytecode() { - return currentPos; - } - - /** - * Returns the line number of the source line containing the expression. - * - * @return -1 if this information is not available. - */ - public int getLineNumber() { - return thisMethod.getLineNumber(currentPos); - } - - /** - * Returns the source file containing the expression. - * - * @return null if this information is not available. - */ - public String getFileName() { - ClassFile cf = thisClass.getClassFile2(); - if (cf == null) - return null; - else - return cf.getSourceFile(); - } - - static final boolean checkResultValue(CtClass retType, String prog) - throws CannotCompileException { - /* - * Is $_ included in the source code? - */ - boolean hasIt = (prog.indexOf(Javac.resultVarName) >= 0); - if (!hasIt && retType != CtClass.voidType) - throw new CannotCompileException( - "the resulting value is not stored in " - + Javac.resultVarName); - - return hasIt; - } - - /* - * If isStaticCall is true, null is assigned to $0. So $0 must be declared - * by calling Javac.recordParams(). - * - * After executing this method, the current stack depth might be less than - * 0. - */ - static final void storeStack(CtClass[] params, boolean isStaticCall, - int regno, Bytecode bytecode) { - storeStack0(0, params.length, params, regno + 1, bytecode); - if (isStaticCall) - bytecode.addOpcode(ACONST_NULL); - - bytecode.addAstore(regno); - } - - private static void storeStack0(int i, int n, CtClass[] params, int regno, - Bytecode bytecode) { - if (i >= n) - return; - else { - CtClass c = params[i]; - int size; - if (c instanceof CtPrimitiveType) - size = ((CtPrimitiveType)c).getDataSize(); - else - size = 1; - - storeStack0(i + 1, n, params, regno + size, bytecode); - bytecode.addStore(regno, c); - } - } - - // The implementation of replace() should call thisClass.checkModify() - // so that isModify() will return true. Otherwise, thisClass.classfile - // might be released during compilation and the compiler might generate - // bytecode with a wrong copy of ConstPool. - - /** - * Replaces this expression with the bytecode derived from - * the given source text. - * - * @param statement a Java statement except try-catch. - */ - public abstract void replace(String statement) throws CannotCompileException; - - /** - * Replaces this expression with the bytecode derived from - * the given source text and ExprEditor. - * - * @param statement a Java statement except try-catch. - * @param recursive if not null, the substituted bytecode - * is recursively processed by the given - * ExprEditor. - * @since 3.1 - */ - public void replace(String statement, ExprEditor recursive) - throws CannotCompileException - { - replace(statement); - if (recursive != null) - runEditor(recursive, iterator); - } - - protected void replace0(int pos, Bytecode bytecode, int size) - throws BadBytecode { - byte[] code = bytecode.get(); - edited = true; - int gap = code.length - size; - for (int i = 0; i < size; ++i) - iterator.writeByte(NOP, pos + i); - - if (gap > 0) - pos = iterator.insertGapAt(pos, gap, false).position; - - iterator.write(code, pos); - iterator.insert(bytecode.getExceptionTable(), pos); - maxLocals = bytecode.getMaxLocals(); - maxStack = bytecode.getMaxStack(); - } - - protected void runEditor(ExprEditor ed, CodeIterator oldIterator) - throws CannotCompileException - { - CodeAttribute codeAttr = oldIterator.get(); - int orgLocals = codeAttr.getMaxLocals(); - int orgStack = codeAttr.getMaxStack(); - int newLocals = locals(); - codeAttr.setMaxStack(stack()); - codeAttr.setMaxLocals(newLocals); - ExprEditor.LoopContext context - = new ExprEditor.LoopContext(newLocals); - int size = oldIterator.getCodeLength(); - int endPos = oldIterator.lookAhead(); - oldIterator.move(currentPos); - if (ed.doit(thisClass, thisMethod, context, oldIterator, endPos)) - edited = true; - - oldIterator.move(endPos + oldIterator.getCodeLength() - size); - codeAttr.setMaxLocals(orgLocals); - codeAttr.setMaxStack(orgStack); - maxLocals = context.maxLocals; - maxStack += context.maxStack; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/expr/ExprEditor.java b/fine-javassist/src/main/java/com/fr/third/javassist/expr/ExprEditor.java deleted file mode 100644 index 7583805b6..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/expr/ExprEditor.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.expr; - -import com.fr.third.javassist.CodeConverter; -import com.fr.third.javassist.CtConstructor; -import com.fr.third.javassist.CtMethod; -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CannotCompileException; - -/** - * A translator of method bodies. - * - *

The users can define a subclass of this class to customize how to - * modify a method body. The overall architecture is similar to the - * strategy pattern. - * - *

If instrument() is called in - * CtMethod, the method body is scanned from the beginning - * to the end. - * Whenever an expression, such as a method call and a new - * expression (object creation), - * is found, edit() is called in ExprEdit. - * edit() can inspect and modify the given expression. - * The modification is reflected on the original method body. If - * edit() does nothing, the original method body is not - * changed. - * - *

The following code is an example: - * - *

    - * CtMethod cm = ...;
    - * cm.instrument(new ExprEditor() {
    - *     public void edit(MethodCall m) throws CannotCompileException {
    - *         if (m.getClassName().equals("Point")) {
    - *             System.out.println(m.getMethodName() + " line: "
    - *                                + m.getLineNumber());
    - *     }
    - * });
    - * 
- * - *

This code inspects all method calls appearing in the method represented - * by cm and it prints the names and the line numbers of the - * methods declared in class Point. This code does not modify - * the body of the method represented by cm. If the method - * body must be modified, call replace() - * in MethodCall. - * - * @see CtClass#instrument(ExprEditor) - * @see CtMethod#instrument(ExprEditor) - * @see CtConstructor#instrument(ExprEditor) - * @see MethodCall - * @see com.fr.third.javassist.expr.NewExpr - * @see FieldAccess - * - * @see CodeConverter - */ -public class ExprEditor { - /** - * Default constructor. It does nothing. - */ - public ExprEditor() {} - - /** - * Undocumented method. Do not use; internal-use only. - */ - public boolean doit(CtClass clazz, com.fr.third.javassist.bytecode.MethodInfo minfo) - throws CannotCompileException - { - CodeAttribute codeAttr = minfo.getCodeAttribute(); - if (codeAttr == null) - return false; - - com.fr.third.javassist.bytecode.CodeIterator iterator = codeAttr.iterator(); - boolean edited = false; - LoopContext context = new LoopContext(codeAttr.getMaxLocals()); - - while (iterator.hasNext()) - if (loopBody(iterator, clazz, minfo, context)) - edited = true; - - com.fr.third.javassist.bytecode.ExceptionTable et = codeAttr.getExceptionTable(); - int n = et.size(); - for (int i = 0; i < n; ++i) { - com.fr.third.javassist.expr.Handler h = new com.fr.third.javassist.expr.Handler(et, i, iterator, clazz, minfo); - edit(h); - if (h.edited()) { - edited = true; - context.updateMax(h.locals(), h.stack()); - } - } - - // codeAttr might be modified by other partiess - // so I check the current value of max-locals. - if (codeAttr.getMaxLocals() < context.maxLocals) - codeAttr.setMaxLocals(context.maxLocals); - - codeAttr.setMaxStack(codeAttr.getMaxStack() + context.maxStack); - try { - if (edited) - minfo.rebuildStackMapIf6(clazz.getClassPool(), - clazz.getClassFile2()); - } - catch (com.fr.third.javassist.bytecode.BadBytecode b) { - throw new CannotCompileException(b.getMessage(), b); - } - - return edited; - } - - /** - * Visits each bytecode in the given range. - */ - boolean doit(CtClass clazz, com.fr.third.javassist.bytecode.MethodInfo minfo, LoopContext context, - com.fr.third.javassist.bytecode.CodeIterator iterator, int endPos) - throws CannotCompileException - { - boolean edited = false; - while (iterator.hasNext() && iterator.lookAhead() < endPos) { - int size = iterator.getCodeLength(); - if (loopBody(iterator, clazz, minfo, context)) { - edited = true; - int size2 = iterator.getCodeLength(); - if (size != size2) // the body was modified. - endPos += size2 - size; - } - } - - return edited; - } - - final static class NewOp { - NewOp next; - int pos; - String type; - - NewOp(NewOp n, int p, String t) { - next = n; - pos = p; - type = t; - } - } - - final static class LoopContext { - NewOp newList; - int maxLocals; - int maxStack; - - LoopContext(int locals) { - maxLocals = locals; - maxStack = 0; - newList = null; - } - - void updateMax(int locals, int stack) { - if (maxLocals < locals) - maxLocals = locals; - - if (maxStack < stack) - maxStack = stack; - } - } - - final boolean loopBody(com.fr.third.javassist.bytecode.CodeIterator iterator, CtClass clazz, - com.fr.third.javassist.bytecode.MethodInfo minfo, LoopContext context) - throws CannotCompileException - { - try { - Expr expr = null; - int pos = iterator.next(); - int c = iterator.byteAt(pos); - - if (c < com.fr.third.javassist.bytecode.Opcode.GETSTATIC) // c < 178 - /* skip */; - else if (c < com.fr.third.javassist.bytecode.Opcode.NEWARRAY) { // c < 188 - if (c == com.fr.third.javassist.bytecode.Opcode.INVOKESTATIC - || c == com.fr.third.javassist.bytecode.Opcode.INVOKEINTERFACE - || c == com.fr.third.javassist.bytecode.Opcode.INVOKEVIRTUAL) { - expr = new MethodCall(pos, iterator, clazz, minfo); - edit((MethodCall)expr); - } - else if (c == com.fr.third.javassist.bytecode.Opcode.GETFIELD || c == com.fr.third.javassist.bytecode.Opcode.GETSTATIC - || c == com.fr.third.javassist.bytecode.Opcode.PUTFIELD - || c == com.fr.third.javassist.bytecode.Opcode.PUTSTATIC) { - expr = new FieldAccess(pos, iterator, clazz, minfo, c); - edit((FieldAccess)expr); - } - else if (c == com.fr.third.javassist.bytecode.Opcode.NEW) { - int index = iterator.u16bitAt(pos + 1); - context.newList = new NewOp(context.newList, pos, - minfo.getConstPool().getClassInfo(index)); - } - else if (c == com.fr.third.javassist.bytecode.Opcode.INVOKESPECIAL) { - NewOp newList = context.newList; - if (newList != null - && minfo.getConstPool().isConstructor(newList.type, - iterator.u16bitAt(pos + 1)) > 0) { - expr = new com.fr.third.javassist.expr.NewExpr(pos, iterator, clazz, minfo, - newList.type, newList.pos); - edit((com.fr.third.javassist.expr.NewExpr)expr); - context.newList = newList.next; - } - else { - MethodCall mcall = new MethodCall(pos, iterator, clazz, minfo); - if (mcall.getMethodName().equals(com.fr.third.javassist.bytecode.MethodInfo.nameInit)) { - ConstructorCall ccall = new ConstructorCall(pos, iterator, clazz, minfo); - expr = ccall; - edit(ccall); - } - else { - expr = mcall; - edit(mcall); - } - } - } - } - else { // c >= 188 - if (c == com.fr.third.javassist.bytecode.Opcode.NEWARRAY || c == com.fr.third.javassist.bytecode.Opcode.ANEWARRAY - || c == com.fr.third.javassist.bytecode.Opcode.MULTIANEWARRAY) { - expr = new com.fr.third.javassist.expr.NewArray(pos, iterator, clazz, minfo, c); - edit((com.fr.third.javassist.expr.NewArray)expr); - } - else if (c == com.fr.third.javassist.bytecode.Opcode.INSTANCEOF) { - expr = new Instanceof(pos, iterator, clazz, minfo); - edit((Instanceof)expr); - } - else if (c == com.fr.third.javassist.bytecode.Opcode.CHECKCAST) { - expr = new com.fr.third.javassist.expr.Cast(pos, iterator, clazz, minfo); - edit((com.fr.third.javassist.expr.Cast)expr); - } - } - - if (expr != null && expr.edited()) { - context.updateMax(expr.locals(), expr.stack()); - return true; - } - else - return false; - } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new CannotCompileException(e); - } - } - - /** - * Edits a new expression (overridable). - * The default implementation performs nothing. - * - * @param e the new expression creating an object. - */ - public void edit(com.fr.third.javassist.expr.NewExpr e) throws CannotCompileException {} - - /** - * Edits an expression for array creation (overridable). - * The default implementation performs nothing. - * - * @param a the new expression for creating an array. - * @throws CannotCompileException - */ - public void edit(NewArray a) throws CannotCompileException {} - - /** - * Edits a method call (overridable). - * - * The default implementation performs nothing. - */ - public void edit(MethodCall m) throws CannotCompileException {} - - /** - * Edits a constructor call (overridable). - * The constructor call is either - * super() or this() - * included in a constructor body. - * - * The default implementation performs nothing. - * - * @see #edit(NewExpr) - */ - public void edit(ConstructorCall c) throws CannotCompileException {} - - /** - * Edits a field-access expression (overridable). - * Field access means both read and write. - * The default implementation performs nothing. - */ - public void edit(FieldAccess f) throws CannotCompileException {} - - /** - * Edits an instanceof expression (overridable). - * The default implementation performs nothing. - */ - public void edit(Instanceof i) throws CannotCompileException {} - - /** - * Edits an expression for explicit type casting (overridable). - * The default implementation performs nothing. - */ - public void edit(Cast c) throws CannotCompileException {} - - /** - * Edits a catch clause (overridable). - * The default implementation performs nothing. - */ - public void edit(Handler h) throws CannotCompileException {} -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/expr/FieldAccess.java b/fine-javassist/src/main/java/com/fr/third/javassist/expr/FieldAccess.java deleted file mode 100644 index 2f73987ca..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/expr/FieldAccess.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.expr; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.compiler.CompileError; -import com.fr.third.javassist.compiler.ast.ASTList; - -/** - * Expression for accessing a field. - */ -public class FieldAccess extends Expr { - int opcode; - - protected FieldAccess(int pos, com.fr.third.javassist.bytecode.CodeIterator i, com.fr.third.javassist.CtClass declaring, - com.fr.third.javassist.bytecode.MethodInfo m, int op) { - super(pos, i, declaring, m); - opcode = op; - } - - /** - * Returns the method or constructor containing the field-access - * expression represented by this object. - */ - public com.fr.third.javassist.CtBehavior where() { return super.where(); } - - /** - * Returns the line number of the source line containing the - * field access. - * - * @return -1 if this information is not available. - */ - public int getLineNumber() { - return super.getLineNumber(); - } - - /** - * Returns the source file containing the field access. - * - * @return null if this information is not available. - */ - public String getFileName() { - return super.getFileName(); - } - - /** - * Returns true if the field is static. - */ - public boolean isStatic() { - return isStatic(opcode); - } - - static boolean isStatic(int c) { - return c == com.fr.third.javassist.bytecode.Opcode.GETSTATIC || c == com.fr.third.javassist.bytecode.Opcode.PUTSTATIC; - } - - /** - * Returns true if the field is read. - */ - public boolean isReader() { - return opcode == com.fr.third.javassist.bytecode.Opcode.GETFIELD || opcode == com.fr.third.javassist.bytecode.Opcode.GETSTATIC; - } - - /** - * Returns true if the field is written in. - */ - public boolean isWriter() { - return opcode == com.fr.third.javassist.bytecode.Opcode.PUTFIELD || opcode == com.fr.third.javassist.bytecode.Opcode.PUTSTATIC; - } - - /** - * Returns the class in which the field is declared. - */ - private com.fr.third.javassist.CtClass getCtClass() throws com.fr.third.javassist.NotFoundException { - return thisClass.getClassPool().get(getClassName()); - } - - /** - * Returns the name of the class in which the field is declared. - */ - public String getClassName() { - int index = iterator.u16bitAt(currentPos + 1); - return getConstPool().getFieldrefClassName(index); - } - - /** - * Returns the name of the field. - */ - public String getFieldName() { - int index = iterator.u16bitAt(currentPos + 1); - return getConstPool().getFieldrefName(index); - } - - /** - * Returns the field accessed by this expression. - */ - public com.fr.third.javassist.CtField getField() throws com.fr.third.javassist.NotFoundException { - com.fr.third.javassist.CtClass cc = getCtClass(); - int index = iterator.u16bitAt(currentPos + 1); - com.fr.third.javassist.bytecode.ConstPool cp = getConstPool(); - return cc.getField(cp.getFieldrefName(index), cp.getFieldrefType(index)); - } - - /** - * Returns the list of exceptions that the expression may throw. - * This list includes both the exceptions that the try-catch statements - * including the expression can catch and the exceptions that - * the throws declaration allows the method to throw. - */ - public com.fr.third.javassist.CtClass[] mayThrow() { - return super.mayThrow(); - } - - /** - * Returns the signature of the field type. - * The signature is represented by a character string - * called field descriptor, which is defined in the JVM specification. - * - * @see com.fr.third.javassist.bytecode.Descriptor#toCtClass(String, com.fr.third.javassist.ClassPool) - * @since 3.1 - */ - public String getSignature() { - int index = iterator.u16bitAt(currentPos + 1); - return getConstPool().getFieldrefType(index); - } - - /** - * Replaces the method call with the bytecode derived from - * the given source text. - * - *

$0 is available even if the called method is static. - * If the field access is writing, $_ is available but the value - * of $_ is ignored. - * - * @param statement a Java statement except try-catch. - */ - public void replace(String statement) throws com.fr.third.javassist.CannotCompileException { - thisClass.getClassFile(); // to call checkModify(). - com.fr.third.javassist.bytecode.ConstPool constPool = getConstPool(); - int pos = currentPos; - int index = iterator.u16bitAt(pos + 1); - - com.fr.third.javassist.compiler.Javac jc = new com.fr.third.javassist.compiler.Javac(thisClass); - CodeAttribute ca = iterator.get(); - try { - com.fr.third.javassist.CtClass[] params; - com.fr.third.javassist.CtClass retType; - com.fr.third.javassist.CtClass fieldType - = com.fr.third.javassist.bytecode.Descriptor.toCtClass(constPool.getFieldrefType(index), - thisClass.getClassPool()); - boolean read = isReader(); - if (read) { - params = new com.fr.third.javassist.CtClass[0]; - retType = fieldType; - } - else { - params = new com.fr.third.javassist.CtClass[1]; - params[0] = fieldType; - retType = com.fr.third.javassist.CtClass.voidType; - } - - int paramVar = ca.getMaxLocals(); - jc.recordParams(constPool.getFieldrefClassName(index), params, - true, paramVar, withinStatic()); - - /* Is $_ included in the source code? - */ - boolean included = checkResultValue(retType, statement); - if (read) - included = true; - - int retVar = jc.recordReturnType(retType, included); - if (read) - jc.recordProceed(new ProceedForRead(retType, opcode, - index, paramVar)); - else { - // because $type is not the return type... - jc.recordType(fieldType); - jc.recordProceed(new ProceedForWrite(params[0], opcode, - index, paramVar)); - } - - com.fr.third.javassist.bytecode.Bytecode bytecode = jc.getBytecode(); - storeStack(params, isStatic(), paramVar, bytecode); - jc.recordLocalVariables(ca, pos); - - if (included) - if (retType == com.fr.third.javassist.CtClass.voidType) { - bytecode.addOpcode(ACONST_NULL); - bytecode.addAstore(retVar); - } - else { - bytecode.addConstZero(retType); - bytecode.addStore(retVar, retType); // initialize $_ - } - - jc.compileStmnt(statement); - if (read) - bytecode.addLoad(retVar, retType); - - replace0(pos, bytecode, 3); - } - catch (com.fr.third.javassist.compiler.CompileError e) { throw new com.fr.third.javassist.CannotCompileException(e); } - catch (com.fr.third.javassist.NotFoundException e) { throw new com.fr.third.javassist.CannotCompileException(e); } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException("broken method"); - } - } - - /* $proceed() - */ - static class ProceedForRead implements com.fr.third.javassist.compiler.ProceedHandler { - com.fr.third.javassist.CtClass fieldType; - int opcode; - int targetVar, index; - - ProceedForRead(com.fr.third.javassist.CtClass type, int op, int i, int var) { - fieldType = type; - targetVar = var; - opcode = op; - index = i; - } - - public void doit(com.fr.third.javassist.compiler.JvstCodeGen gen, com.fr.third.javassist.bytecode.Bytecode bytecode, ASTList args) - throws com.fr.third.javassist.compiler.CompileError - { - if (args != null && !gen.isParamListName(args)) - throw new com.fr.third.javassist.compiler.CompileError(com.fr.third.javassist.compiler.Javac.proceedName - + "() cannot take a parameter for field reading"); - - int stack; - if (isStatic(opcode)) - stack = 0; - else { - stack = -1; - bytecode.addAload(targetVar); - } - - if (fieldType instanceof com.fr.third.javassist.CtPrimitiveType) - stack += ((com.fr.third.javassist.CtPrimitiveType)fieldType).getDataSize(); - else - ++stack; - - bytecode.add(opcode); - bytecode.addIndex(index); - bytecode.growStack(stack); - gen.setType(fieldType); - } - - public void setReturnType(com.fr.third.javassist.compiler.JvstTypeChecker c, ASTList args) - throws com.fr.third.javassist.compiler.CompileError - { - c.setType(fieldType); - } - } - - /* void $proceed() - * the return type is not the field type but void. - */ - static class ProceedForWrite implements com.fr.third.javassist.compiler.ProceedHandler { - com.fr.third.javassist.CtClass fieldType; - int opcode; - int targetVar, index; - - ProceedForWrite(com.fr.third.javassist.CtClass type, int op, int i, int var) { - fieldType = type; - targetVar = var; - opcode = op; - index = i; - } - - public void doit(com.fr.third.javassist.compiler.JvstCodeGen gen, com.fr.third.javassist.bytecode.Bytecode bytecode, ASTList args) - throws com.fr.third.javassist.compiler.CompileError - { - if (gen.getMethodArgsLength(args) != 1) - throw new com.fr.third.javassist.compiler.CompileError(com.fr.third.javassist.compiler.Javac.proceedName - + "() cannot take more than one parameter " - + "for field writing"); - - int stack; - if (isStatic(opcode)) - stack = 0; - else { - stack = -1; - bytecode.addAload(targetVar); - } - - gen.atMethodArgs(args, new int[1], new int[1], new String[1]); - gen.doNumCast(fieldType); - if (fieldType instanceof com.fr.third.javassist.CtPrimitiveType) - stack -= ((com.fr.third.javassist.CtPrimitiveType)fieldType).getDataSize(); - else - --stack; - - bytecode.add(opcode); - bytecode.addIndex(index); - bytecode.growStack(stack); - gen.setType(com.fr.third.javassist.CtClass.voidType); - gen.addNullIfVoid(); - } - - public void setReturnType(com.fr.third.javassist.compiler.JvstTypeChecker c, ASTList args) - throws CompileError - { - c.atMethodArgs(args, new int[1], new int[1], new String[1]); - c.setType(CtClass.voidType); - c.addNullIfVoid(); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/expr/Handler.java b/fine-javassist/src/main/java/com/fr/third/javassist/expr/Handler.java deleted file mode 100644 index 8fd34f0f1..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/expr/Handler.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.expr; - -import com.fr.third.javassist.CannotCompileException; -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.compiler.CompileError; - -/** - * A catch clause or a finally block. - */ -public class Handler extends Expr { - private static String EXCEPTION_NAME = "$1"; - private com.fr.third.javassist.bytecode.ExceptionTable etable; - private int index; - - /** - * Undocumented constructor. Do not use; internal-use only. - */ - protected Handler(com.fr.third.javassist.bytecode.ExceptionTable et, int nth, - com.fr.third.javassist.bytecode.CodeIterator it, com.fr.third.javassist.CtClass declaring, com.fr.third.javassist.bytecode.MethodInfo m) { - super(et.handlerPc(nth), it, declaring, m); - etable = et; - index = nth; - } - - /** - * Returns the method or constructor containing the catch clause. - */ - public com.fr.third.javassist.CtBehavior where() { return super.where(); } - - /** - * Returns the source line number of the catch clause. - * - * @return -1 if this information is not available. - */ - public int getLineNumber() { - return super.getLineNumber(); - } - - /** - * Returns the source file containing the catch clause. - * - * @return null if this information is not available. - */ - public String getFileName() { - return super.getFileName(); - } - - /** - * Returns the list of exceptions that the catch clause may throw. - */ - public com.fr.third.javassist.CtClass[] mayThrow() { - return super.mayThrow(); - } - - /** - * Returns the type handled by the catch clause. - * If this is a finally block, null is returned. - */ - public com.fr.third.javassist.CtClass getType() throws com.fr.third.javassist.NotFoundException { - int type = etable.catchType(index); - if (type == 0) - return null; - else { - com.fr.third.javassist.bytecode.ConstPool cp = getConstPool(); - String name = cp.getClassInfo(type); - return thisClass.getClassPool().getCtClass(name); - } - } - - /** - * Returns true if this is a finally block. - */ - public boolean isFinally() { - return etable.catchType(index) == 0; - } - - /** - * This method has not been implemented yet. - * - * @param statement a Java statement except try-catch. - */ - public void replace(String statement) throws com.fr.third.javassist.CannotCompileException { - throw new RuntimeException("not implemented yet"); - } - - /** - * Inserts bytecode at the beginning of the catch clause. - * The caught exception is stored in $1. - * - * @param src the source code representing the inserted bytecode. - * It must be a single statement or block. - */ - public void insertBefore(String src) throws com.fr.third.javassist.CannotCompileException { - edited = true; - - com.fr.third.javassist.bytecode.ConstPool cp = getConstPool(); - CodeAttribute ca = iterator.get(); - com.fr.third.javassist.compiler.Javac jv = new com.fr.third.javassist.compiler.Javac(thisClass); - com.fr.third.javassist.bytecode.Bytecode b = jv.getBytecode(); - b.setStackDepth(1); - b.setMaxLocals(ca.getMaxLocals()); - - try { - com.fr.third.javassist.CtClass type = getType(); - int var = jv.recordVariable(type, EXCEPTION_NAME); - jv.recordReturnType(type, false); - b.addAstore(var); - jv.compileStmnt(src); - b.addAload(var); - - int oldHandler = etable.handlerPc(index); - b.addOpcode(com.fr.third.javassist.bytecode.Opcode.GOTO); - b.addIndex(oldHandler - iterator.getCodeLength() - - b.currentPc() + 1); - - maxStack = b.getMaxStack(); - maxLocals = b.getMaxLocals(); - - int pos = iterator.append(b.get()); - iterator.append(b.getExceptionTable(), pos); - etable.setHandlerPc(index, pos); - } - catch (com.fr.third.javassist.NotFoundException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - catch (CompileError e) { - throw new CannotCompileException(e); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/expr/Instanceof.java b/fine-javassist/src/main/java/com/fr/third/javassist/expr/Instanceof.java deleted file mode 100644 index e2b293f3e..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/expr/Instanceof.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.expr; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.compiler.CompileError; -import com.fr.third.javassist.compiler.ast.ASTList; - -/** - * Instanceof operator. - */ -public class Instanceof extends Expr { - /** - * Undocumented constructor. Do not use; internal-use only. - */ - protected Instanceof(int pos, com.fr.third.javassist.bytecode.CodeIterator i, com.fr.third.javassist.CtClass declaring, - com.fr.third.javassist.bytecode.MethodInfo m) { - super(pos, i, declaring, m); - } - - /** - * Returns the method or constructor containing the instanceof - * expression represented by this object. - */ - public com.fr.third.javassist.CtBehavior where() { return super.where(); } - - /** - * Returns the line number of the source line containing the - * instanceof expression. - * - * @return -1 if this information is not available. - */ - public int getLineNumber() { - return super.getLineNumber(); - } - - /** - * Returns the source file containing the - * instanceof expression. - * - * @return null if this information is not available. - */ - public String getFileName() { - return super.getFileName(); - } - - /** - * Returns the CtClass object representing - * the type name on the right hand side - * of the instanceof operator. - */ - public com.fr.third.javassist.CtClass getType() throws com.fr.third.javassist.NotFoundException { - com.fr.third.javassist.bytecode.ConstPool cp = getConstPool(); - int pos = currentPos; - int index = iterator.u16bitAt(pos + 1); - String name = cp.getClassInfo(index); - return thisClass.getClassPool().getCtClass(name); - } - - /** - * Returns the list of exceptions that the expression may throw. - * This list includes both the exceptions that the try-catch statements - * including the expression can catch and the exceptions that - * the throws declaration allows the method to throw. - */ - public com.fr.third.javassist.CtClass[] mayThrow() { - return super.mayThrow(); - } - - /** - * Replaces the instanceof operator with the bytecode derived from - * the given source text. - * - *

$0 is available but the value is null. - * - * @param statement a Java statement except try-catch. - */ - public void replace(String statement) throws com.fr.third.javassist.CannotCompileException { - thisClass.getClassFile(); // to call checkModify(). - com.fr.third.javassist.bytecode.ConstPool constPool = getConstPool(); - int pos = currentPos; - int index = iterator.u16bitAt(pos + 1); - - com.fr.third.javassist.compiler.Javac jc = new com.fr.third.javassist.compiler.Javac(thisClass); - com.fr.third.javassist.ClassPool cp = thisClass.getClassPool(); - CodeAttribute ca = iterator.get(); - - try { - com.fr.third.javassist.CtClass[] params - = new com.fr.third.javassist.CtClass[] { cp.get(javaLangObject) }; - com.fr.third.javassist.CtClass retType = com.fr.third.javassist.CtClass.booleanType; - - int paramVar = ca.getMaxLocals(); - jc.recordParams(javaLangObject, params, true, paramVar, - withinStatic()); - int retVar = jc.recordReturnType(retType, true); - jc.recordProceed(new ProceedForInstanceof(index)); - - // because $type is not the return type... - jc.recordType(getType()); - - /* Is $_ included in the source code? - */ - checkResultValue(retType, statement); - - com.fr.third.javassist.bytecode.Bytecode bytecode = jc.getBytecode(); - storeStack(params, true, paramVar, bytecode); - jc.recordLocalVariables(ca, pos); - - bytecode.addConstZero(retType); - bytecode.addStore(retVar, retType); // initialize $_ - - jc.compileStmnt(statement); - bytecode.addLoad(retVar, retType); - - replace0(pos, bytecode, 3); - } - catch (com.fr.third.javassist.compiler.CompileError e) { throw new com.fr.third.javassist.CannotCompileException(e); } - catch (com.fr.third.javassist.NotFoundException e) { throw new com.fr.third.javassist.CannotCompileException(e); } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException("broken method"); - } - } - - /* boolean $proceed(Object obj) - */ - static class ProceedForInstanceof implements com.fr.third.javassist.compiler.ProceedHandler { - int index; - - ProceedForInstanceof(int i) { - index = i; - } - - public void doit(com.fr.third.javassist.compiler.JvstCodeGen gen, com.fr.third.javassist.bytecode.Bytecode bytecode, ASTList args) - throws com.fr.third.javassist.compiler.CompileError - { - if (gen.getMethodArgsLength(args) != 1) - throw new com.fr.third.javassist.compiler.CompileError(com.fr.third.javassist.compiler.Javac.proceedName - + "() cannot take more than one parameter " - + "for instanceof"); - - gen.atMethodArgs(args, new int[1], new int[1], new String[1]); - bytecode.addOpcode(com.fr.third.javassist.bytecode.Opcode.INSTANCEOF); - bytecode.addIndex(index); - gen.setType(com.fr.third.javassist.CtClass.booleanType); - } - - public void setReturnType(com.fr.third.javassist.compiler.JvstTypeChecker c, ASTList args) - throws CompileError - { - c.atMethodArgs(args, new int[1], new int[1], new String[1]); - c.setType(CtClass.booleanType); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/expr/MethodCall.java b/fine-javassist/src/main/java/com/fr/third/javassist/expr/MethodCall.java deleted file mode 100644 index f6b26c95b..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/expr/MethodCall.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.expr; - -import com.fr.third.javassist.CannotCompileException; -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.compiler.CompileError; - -/** - * Method invocation (caller-side expression). - */ -public class MethodCall extends Expr { - /** - * Undocumented constructor. Do not use; internal-use only. - */ - protected MethodCall(int pos, com.fr.third.javassist.bytecode.CodeIterator i, com.fr.third.javassist.CtClass declaring, - com.fr.third.javassist.bytecode.MethodInfo m) { - super(pos, i, declaring, m); - } - - private int getNameAndType(com.fr.third.javassist.bytecode.ConstPool cp) { - int pos = currentPos; - int c = iterator.byteAt(pos); - int index = iterator.u16bitAt(pos + 1); - - if (c == INVOKEINTERFACE) - return cp.getInterfaceMethodrefNameAndType(index); - else - return cp.getMethodrefNameAndType(index); - } - - /** - * Returns the method or constructor containing the method-call - * expression represented by this object. - */ - public com.fr.third.javassist.CtBehavior where() { return super.where(); } - - /** - * Returns the line number of the source line containing the - * method call. - * - * @return -1 if this information is not available. - */ - public int getLineNumber() { - return super.getLineNumber(); - } - - /** - * Returns the source file containing the method call. - * - * @return null if this information is not available. - */ - public String getFileName() { - return super.getFileName(); - } - - /** - * Returns the class of the target object, - * which the method is called on. - */ - protected com.fr.third.javassist.CtClass getCtClass() throws com.fr.third.javassist.NotFoundException { - return thisClass.getClassPool().get(getClassName()); - } - - /** - * Returns the class name of the target object, - * which the method is called on. - */ - public String getClassName() { - String cname; - - com.fr.third.javassist.bytecode.ConstPool cp = getConstPool(); - int pos = currentPos; - int c = iterator.byteAt(pos); - int index = iterator.u16bitAt(pos + 1); - - if (c == INVOKEINTERFACE) - cname = cp.getInterfaceMethodrefClassName(index); - else - cname = cp.getMethodrefClassName(index); - - if (cname.charAt(0) == '[') - cname = com.fr.third.javassist.bytecode.Descriptor.toClassName(cname); - - return cname; - } - - /** - * Returns the name of the called method. - */ - public String getMethodName() { - com.fr.third.javassist.bytecode.ConstPool cp = getConstPool(); - int nt = getNameAndType(cp); - return cp.getUtf8Info(cp.getNameAndTypeName(nt)); - } - - /** - * Returns the called method. - */ - public com.fr.third.javassist.CtMethod getMethod() throws com.fr.third.javassist.NotFoundException { - return getCtClass().getMethod(getMethodName(), getSignature()); - } - - /** - * Returns the method signature (the parameter types - * and the return type). - * The method signature is represented by a character string - * called method descriptor, which is defined in the JVM specification. - * - * @see com.fr.third.javassist.CtBehavior#getSignature() - * @see com.fr.third.javassist.bytecode.Descriptor - * @since 3.1 - */ - public String getSignature() { - com.fr.third.javassist.bytecode.ConstPool cp = getConstPool(); - int nt = getNameAndType(cp); - return cp.getUtf8Info(cp.getNameAndTypeDescriptor(nt)); - } - - /** - * Returns the list of exceptions that the expression may throw. - * This list includes both the exceptions that the try-catch statements - * including the expression can catch and the exceptions that - * the throws declaration allows the method to throw. - */ - public com.fr.third.javassist.CtClass[] mayThrow() { - return super.mayThrow(); - } - - /** - * Returns true if the called method is of a superclass of the current - * class. - */ - public boolean isSuper() { - return iterator.byteAt(currentPos) == INVOKESPECIAL - && !where().getDeclaringClass().getName().equals(getClassName()); - } - - /* - * Returns the parameter types of the called method. - - public CtClass[] getParameterTypes() throws NotFoundException { - return Descriptor.getParameterTypes(getMethodDesc(), - thisClass.getClassPool()); - } - */ - - /* - * Returns the return type of the called method. - - public CtClass getReturnType() throws NotFoundException { - return Descriptor.getReturnType(getMethodDesc(), - thisClass.getClassPool()); - } - */ - - /** - * Replaces the method call with the bytecode derived from - * the given source text. - * - *

$0 is available even if the called method is static. - * - * @param statement a Java statement except try-catch. - */ - public void replace(String statement) throws com.fr.third.javassist.CannotCompileException { - thisClass.getClassFile(); // to call checkModify(). - com.fr.third.javassist.bytecode.ConstPool constPool = getConstPool(); - int pos = currentPos; - int index = iterator.u16bitAt(pos + 1); - - String classname, methodname, signature; - int opcodeSize; - int c = iterator.byteAt(pos); - if (c == INVOKEINTERFACE) { - opcodeSize = 5; - classname = constPool.getInterfaceMethodrefClassName(index); - methodname = constPool.getInterfaceMethodrefName(index); - signature = constPool.getInterfaceMethodrefType(index); - } - else if (c == INVOKESTATIC - || c == INVOKESPECIAL || c == INVOKEVIRTUAL) { - opcodeSize = 3; - classname = constPool.getMethodrefClassName(index); - methodname = constPool.getMethodrefName(index); - signature = constPool.getMethodrefType(index); - } - else - throw new com.fr.third.javassist.CannotCompileException("not method invocation"); - - com.fr.third.javassist.compiler.Javac jc = new com.fr.third.javassist.compiler.Javac(thisClass); - com.fr.third.javassist.ClassPool cp = thisClass.getClassPool(); - CodeAttribute ca = iterator.get(); - try { - com.fr.third.javassist.CtClass[] params = com.fr.third.javassist.bytecode.Descriptor.getParameterTypes(signature, cp); - com.fr.third.javassist.CtClass retType = com.fr.third.javassist.bytecode.Descriptor.getReturnType(signature, cp); - int paramVar = ca.getMaxLocals(); - jc.recordParams(classname, params, - true, paramVar, withinStatic()); - int retVar = jc.recordReturnType(retType, true); - if (c == INVOKESTATIC) - jc.recordStaticProceed(classname, methodname); - else if (c == INVOKESPECIAL) - jc.recordSpecialProceed(com.fr.third.javassist.compiler.Javac.param0Name, classname, - methodname, signature); - else - jc.recordProceed(com.fr.third.javassist.compiler.Javac.param0Name, methodname); - - /* Is $_ included in the source code? - */ - checkResultValue(retType, statement); - - com.fr.third.javassist.bytecode.Bytecode bytecode = jc.getBytecode(); - storeStack(params, c == INVOKESTATIC, paramVar, bytecode); - jc.recordLocalVariables(ca, pos); - - if (retType != com.fr.third.javassist.CtClass.voidType) { - bytecode.addConstZero(retType); - bytecode.addStore(retVar, retType); // initialize $_ - } - - jc.compileStmnt(statement); - if (retType != com.fr.third.javassist.CtClass.voidType) - bytecode.addLoad(retVar, retType); - - replace0(pos, bytecode, opcodeSize); - } - catch (CompileError e) { throw new com.fr.third.javassist.CannotCompileException(e); } - catch (com.fr.third.javassist.NotFoundException e) { throw new com.fr.third.javassist.CannotCompileException(e); } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new CannotCompileException("broken method"); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/expr/NewArray.java b/fine-javassist/src/main/java/com/fr/third/javassist/expr/NewArray.java deleted file mode 100644 index 83a362c5c..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/expr/NewArray.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.expr; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.compiler.CompileError; -import com.fr.third.javassist.compiler.ast.ASTList; - -/** - * Array creation. - * - *

This class does not provide methods for obtaining the initial - * values of array elements. - */ -public class NewArray extends Expr { - int opcode; - - protected NewArray(int pos, com.fr.third.javassist.bytecode.CodeIterator i, com.fr.third.javassist.CtClass declaring, - com.fr.third.javassist.bytecode.MethodInfo m, int op) { - super(pos, i, declaring, m); - opcode = op; - } - - /** - * Returns the method or constructor containing the array creation - * represented by this object. - */ - public com.fr.third.javassist.CtBehavior where() { return super.where(); } - - /** - * Returns the line number of the source line containing the - * array creation. - * - * @return -1 if this information is not available. - */ - public int getLineNumber() { - return super.getLineNumber(); - } - - /** - * Returns the source file containing the array creation. - * - * @return null if this information is not available. - */ - public String getFileName() { - return super.getFileName(); - } - - /** - * Returns the list of exceptions that the expression may throw. - * This list includes both the exceptions that the try-catch statements - * including the expression can catch and the exceptions that - * the throws declaration allows the method to throw. - */ - public com.fr.third.javassist.CtClass[] mayThrow() { - return super.mayThrow(); - } - - /** - * Returns the type of array components. If the created array is - * a two-dimensional array of int, - * the type returned by this method is - * not int[] but int. - */ - public com.fr.third.javassist.CtClass getComponentType() throws com.fr.third.javassist.NotFoundException { - if (opcode == com.fr.third.javassist.bytecode.Opcode.NEWARRAY) { - int atype = iterator.byteAt(currentPos + 1); - return getPrimitiveType(atype); - } - else if (opcode == com.fr.third.javassist.bytecode.Opcode.ANEWARRAY - || opcode == com.fr.third.javassist.bytecode.Opcode.MULTIANEWARRAY) { - int index = iterator.u16bitAt(currentPos + 1); - String desc = getConstPool().getClassInfo(index); - int dim = com.fr.third.javassist.bytecode.Descriptor.arrayDimension(desc); - desc = com.fr.third.javassist.bytecode.Descriptor.toArrayComponent(desc, dim); - return com.fr.third.javassist.bytecode.Descriptor.toCtClass(desc, thisClass.getClassPool()); - } - else - throw new RuntimeException("bad opcode: " + opcode); - } - - com.fr.third.javassist.CtClass getPrimitiveType(int atype) { - switch (atype) { - case com.fr.third.javassist.bytecode.Opcode.T_BOOLEAN : - return com.fr.third.javassist.CtClass.booleanType; - case com.fr.third.javassist.bytecode.Opcode.T_CHAR : - return com.fr.third.javassist.CtClass.charType; - case com.fr.third.javassist.bytecode.Opcode.T_FLOAT : - return com.fr.third.javassist.CtClass.floatType; - case com.fr.third.javassist.bytecode.Opcode.T_DOUBLE : - return com.fr.third.javassist.CtClass.doubleType; - case com.fr.third.javassist.bytecode.Opcode.T_BYTE : - return com.fr.third.javassist.CtClass.byteType; - case com.fr.third.javassist.bytecode.Opcode.T_SHORT : - return com.fr.third.javassist.CtClass.shortType; - case com.fr.third.javassist.bytecode.Opcode.T_INT : - return com.fr.third.javassist.CtClass.intType; - case com.fr.third.javassist.bytecode.Opcode.T_LONG : - return com.fr.third.javassist.CtClass.longType; - default : - throw new RuntimeException("bad atype: " + atype); - } - } - - /** - * Returns the dimension of the created array. - */ - public int getDimension() { - if (opcode == com.fr.third.javassist.bytecode.Opcode.NEWARRAY) - return 1; - else if (opcode == com.fr.third.javassist.bytecode.Opcode.ANEWARRAY - || opcode == com.fr.third.javassist.bytecode.Opcode.MULTIANEWARRAY) { - int index = iterator.u16bitAt(currentPos + 1); - String desc = getConstPool().getClassInfo(index); - return com.fr.third.javassist.bytecode.Descriptor.arrayDimension(desc) - + (opcode == com.fr.third.javassist.bytecode.Opcode.ANEWARRAY ? 1 : 0); - } - else - throw new RuntimeException("bad opcode: " + opcode); - } - - /** - * Returns the number of dimensions of arrays to be created. - * If the opcode is multianewarray, this method returns the second - * operand. Otherwise, it returns 1. - */ - public int getCreatedDimensions() { - if (opcode == com.fr.third.javassist.bytecode.Opcode.MULTIANEWARRAY) - return iterator.byteAt(currentPos + 3); - else - return 1; - } - - /** - * Replaces the array creation with the bytecode derived from - * the given source text. - * - *

$0 is available even if the called method is static. - * If the field access is writing, $_ is available but the value - * of $_ is ignored. - * - * @param statement a Java statement except try-catch. - */ - public void replace(String statement) throws com.fr.third.javassist.CannotCompileException { - try { - replace2(statement); - } - catch (com.fr.third.javassist.compiler.CompileError e) { throw new com.fr.third.javassist.CannotCompileException(e); } - catch (com.fr.third.javassist.NotFoundException e) { throw new com.fr.third.javassist.CannotCompileException(e); } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException("broken method"); - } - } - - private void replace2(String statement) - throws com.fr.third.javassist.compiler.CompileError, com.fr.third.javassist.NotFoundException, com.fr.third.javassist.bytecode.BadBytecode, - com.fr.third.javassist.CannotCompileException - { - thisClass.getClassFile(); // to call checkModify(). - com.fr.third.javassist.bytecode.ConstPool constPool = getConstPool(); - int pos = currentPos; - com.fr.third.javassist.CtClass retType; - int codeLength; - int index = 0; - int dim = 1; - String desc; - if (opcode == com.fr.third.javassist.bytecode.Opcode.NEWARRAY) { - index = iterator.byteAt(currentPos + 1); // atype - com.fr.third.javassist.CtPrimitiveType cpt = (com.fr.third.javassist.CtPrimitiveType)getPrimitiveType(index); - desc = "[" + cpt.getDescriptor(); - codeLength = 2; - } - else if (opcode == com.fr.third.javassist.bytecode.Opcode.ANEWARRAY) { - index = iterator.u16bitAt(pos + 1); - desc = constPool.getClassInfo(index); - if (desc.startsWith("[")) - desc = "[" + desc; - else - desc = "[L" + desc + ";"; - - codeLength = 3; - } - else if (opcode == com.fr.third.javassist.bytecode.Opcode.MULTIANEWARRAY) { - index = iterator.u16bitAt(currentPos + 1); - desc = constPool.getClassInfo(index); - dim = iterator.byteAt(currentPos + 3); - codeLength = 4; - } - else - throw new RuntimeException("bad opcode: " + opcode); - - retType = com.fr.third.javassist.bytecode.Descriptor.toCtClass(desc, thisClass.getClassPool()); - - com.fr.third.javassist.compiler.Javac jc = new com.fr.third.javassist.compiler.Javac(thisClass); - CodeAttribute ca = iterator.get(); - - com.fr.third.javassist.CtClass[] params = new com.fr.third.javassist.CtClass[dim]; - for (int i = 0; i < dim; ++i) - params[i] = com.fr.third.javassist.CtClass.intType; - - int paramVar = ca.getMaxLocals(); - jc.recordParams(javaLangObject, params, - true, paramVar, withinStatic()); - - /* Is $_ included in the source code? - */ - checkResultValue(retType, statement); - int retVar = jc.recordReturnType(retType, true); - jc.recordProceed(new ProceedForArray(retType, opcode, index, dim)); - - com.fr.third.javassist.bytecode.Bytecode bytecode = jc.getBytecode(); - storeStack(params, true, paramVar, bytecode); - jc.recordLocalVariables(ca, pos); - - bytecode.addOpcode(ACONST_NULL); // initialize $_ - bytecode.addAstore(retVar); - - jc.compileStmnt(statement); - bytecode.addAload(retVar); - - replace0(pos, bytecode, codeLength); - } - - /* $proceed( ..) - */ - static class ProceedForArray implements com.fr.third.javassist.compiler.ProceedHandler { - com.fr.third.javassist.CtClass arrayType; - int opcode; - int index, dimension; - - ProceedForArray(CtClass type, int op, int i, int dim) { - arrayType = type; - opcode = op; - index = i; - dimension = dim; - } - - public void doit(com.fr.third.javassist.compiler.JvstCodeGen gen, com.fr.third.javassist.bytecode.Bytecode bytecode, ASTList args) - throws com.fr.third.javassist.compiler.CompileError - { - int num = gen.getMethodArgsLength(args); - if (num != dimension) - throw new com.fr.third.javassist.compiler.CompileError(com.fr.third.javassist.compiler.Javac.proceedName - + "() with a wrong number of parameters"); - - gen.atMethodArgs(args, new int[num], - new int[num], new String[num]); - bytecode.addOpcode(opcode); - if (opcode == com.fr.third.javassist.bytecode.Opcode.ANEWARRAY) - bytecode.addIndex(index); - else if (opcode == com.fr.third.javassist.bytecode.Opcode.NEWARRAY) - bytecode.add(index); - else /* if (opcode == Opcode.MULTIANEWARRAY) */ { - bytecode.addIndex(index); - bytecode.add(dimension); - bytecode.growStack(1 - dimension); - } - - gen.setType(arrayType); - } - - public void setReturnType(com.fr.third.javassist.compiler.JvstTypeChecker c, ASTList args) - throws CompileError - { - c.setType(arrayType); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/expr/NewExpr.java b/fine-javassist/src/main/java/com/fr/third/javassist/expr/NewExpr.java deleted file mode 100644 index ec31e40da..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/expr/NewExpr.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.expr; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.bytecode.CodeAttribute; -import com.fr.third.javassist.compiler.CompileError; -import com.fr.third.javassist.compiler.ast.ASTList; - -/** - * Object creation (new expression). - */ -public class NewExpr extends Expr { - String newTypeName; - int newPos; - - /** - * Undocumented constructor. Do not use; internal-use only. - */ - protected NewExpr(int pos, com.fr.third.javassist.bytecode.CodeIterator i, com.fr.third.javassist.CtClass declaring, - com.fr.third.javassist.bytecode.MethodInfo m, String type, int np) { - super(pos, i, declaring, m); - newTypeName = type; - newPos = np; - } - - /* - * Not used - * - private int getNameAndType(ConstPool cp) { - int pos = currentPos; - int c = iterator.byteAt(pos); - int index = iterator.u16bitAt(pos + 1); - - if (c == INVOKEINTERFACE) - return cp.getInterfaceMethodrefNameAndType(index); - else - return cp.getMethodrefNameAndType(index); - } */ - - /** - * Returns the method or constructor containing the new - * expression represented by this object. - */ - public com.fr.third.javassist.CtBehavior where() { return super.where(); } - - /** - * Returns the line number of the source line containing the - * new expression. - * - * @return -1 if this information is not available. - */ - public int getLineNumber() { - return super.getLineNumber(); - } - - /** - * Returns the source file containing the new expression. - * - * @return null if this information is not available. - */ - public String getFileName() { - return super.getFileName(); - } - - /** - * Returns the class of the created object. - */ - private com.fr.third.javassist.CtClass getCtClass() throws com.fr.third.javassist.NotFoundException { - return thisClass.getClassPool().get(newTypeName); - } - - /** - * Returns the class name of the created object. - */ - public String getClassName() { - return newTypeName; - } - - /** - * Get the signature of the constructor - * - * The signature is represented by a character string - * called method descriptor, which is defined in the JVM specification. - * - * @see com.fr.third.javassist.CtBehavior#getSignature() - * @see com.fr.third.javassist.bytecode.Descriptor - * @return the signature - */ - public String getSignature() { - com.fr.third.javassist.bytecode.ConstPool constPool = getConstPool(); - int methodIndex = iterator.u16bitAt(currentPos + 1); // constructor - return constPool.getMethodrefType(methodIndex); - } - - /** - * Returns the constructor called for creating the object. - */ - public com.fr.third.javassist.CtConstructor getConstructor() throws com.fr.third.javassist.NotFoundException { - com.fr.third.javassist.bytecode.ConstPool cp = getConstPool(); - int index = iterator.u16bitAt(currentPos + 1); - String desc = cp.getMethodrefType(index); - return getCtClass().getConstructor(desc); - } - - /** - * Returns the list of exceptions that the expression may throw. - * This list includes both the exceptions that the try-catch statements - * including the expression can catch and the exceptions that - * the throws declaration allows the method to throw. - */ - public com.fr.third.javassist.CtClass[] mayThrow() { - return super.mayThrow(); - } - - /* - * Returns the parameter types of the constructor. - - public CtClass[] getParameterTypes() throws NotFoundException { - ConstPool cp = getConstPool(); - int index = iterator.u16bitAt(currentPos + 1); - String desc = cp.getMethodrefType(index); - return Descriptor.getParameterTypes(desc, thisClass.getClassPool()); - } - */ - - private int canReplace() throws com.fr.third.javassist.CannotCompileException { - int op = iterator.byteAt(newPos + 3); - if (op == com.fr.third.javassist.bytecode.Opcode.DUP) - return 4; - else if (op == com.fr.third.javassist.bytecode.Opcode.DUP_X1 - && iterator.byteAt(newPos + 4) == com.fr.third.javassist.bytecode.Opcode.SWAP) - return 5; - else - return 3; // for Eclipse. The generated code may include no DUP. - // throw new CannotCompileException( - // "sorry, cannot edit NEW followed by no DUP"); - } - - /** - * Replaces the new expression with the bytecode derived from - * the given source text. - * - *

$0 is available but the value is null. - * - * @param statement a Java statement except try-catch. - */ - public void replace(String statement) throws com.fr.third.javassist.CannotCompileException { - thisClass.getClassFile(); // to call checkModify(). - - final int bytecodeSize = 3; - int pos = newPos; - - int newIndex = iterator.u16bitAt(pos + 1); - - /* delete the preceding NEW and DUP (or DUP_X1, SWAP) instructions. - */ - int codeSize = canReplace(); - int end = pos + codeSize; - for (int i = pos; i < end; ++i) - iterator.writeByte(NOP, i); - - com.fr.third.javassist.bytecode.ConstPool constPool = getConstPool(); - pos = currentPos; - int methodIndex = iterator.u16bitAt(pos + 1); // constructor - - String signature = constPool.getMethodrefType(methodIndex); - - com.fr.third.javassist.compiler.Javac jc = new com.fr.third.javassist.compiler.Javac(thisClass); - com.fr.third.javassist.ClassPool cp = thisClass.getClassPool(); - CodeAttribute ca = iterator.get(); - try { - com.fr.third.javassist.CtClass[] params = com.fr.third.javassist.bytecode.Descriptor.getParameterTypes(signature, cp); - com.fr.third.javassist.CtClass newType = cp.get(newTypeName); - int paramVar = ca.getMaxLocals(); - jc.recordParams(newTypeName, params, - true, paramVar, withinStatic()); - int retVar = jc.recordReturnType(newType, true); - jc.recordProceed(new ProceedForNew(newType, newIndex, - methodIndex)); - - /* Is $_ included in the source code? - */ - checkResultValue(newType, statement); - - com.fr.third.javassist.bytecode.Bytecode bytecode = jc.getBytecode(); - storeStack(params, true, paramVar, bytecode); - jc.recordLocalVariables(ca, pos); - - bytecode.addConstZero(newType); - bytecode.addStore(retVar, newType); // initialize $_ - - jc.compileStmnt(statement); - if (codeSize > 3) // if the original code includes DUP. - bytecode.addAload(retVar); - - replace0(pos, bytecode, bytecodeSize); - } - catch (com.fr.third.javassist.compiler.CompileError e) { throw new com.fr.third.javassist.CannotCompileException(e); } - catch (com.fr.third.javassist.NotFoundException e) { throw new com.fr.third.javassist.CannotCompileException(e); } - catch (com.fr.third.javassist.bytecode.BadBytecode e) { - throw new com.fr.third.javassist.CannotCompileException("broken method"); - } - } - - static class ProceedForNew implements com.fr.third.javassist.compiler.ProceedHandler { - com.fr.third.javassist.CtClass newType; - int newIndex, methodIndex; - - ProceedForNew(CtClass nt, int ni, int mi) { - newType = nt; - newIndex = ni; - methodIndex = mi; - } - - public void doit(com.fr.third.javassist.compiler.JvstCodeGen gen, com.fr.third.javassist.bytecode.Bytecode bytecode, ASTList args) - throws com.fr.third.javassist.compiler.CompileError - { - bytecode.addOpcode(NEW); - bytecode.addIndex(newIndex); - bytecode.addOpcode(DUP); - gen.atMethodCallCore(newType, com.fr.third.javassist.bytecode.MethodInfo.nameInit, args, - false, true, -1, null); - gen.setType(newType); - } - - public void setReturnType(com.fr.third.javassist.compiler.JvstTypeChecker c, ASTList args) - throws CompileError - { - c.atMethodCallCore(newType, com.fr.third.javassist.bytecode.MethodInfo.nameInit, args); - c.setType(newType); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/expr/package.html b/fine-javassist/src/main/java/com/fr/third/javassist/expr/package.html deleted file mode 100644 index 12a2c6376..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/expr/package.html +++ /dev/null @@ -1,8 +0,0 @@ - - - -

This package contains the classes for modifying a method body. -See ExprEditor (expression editor) for more details. - - - diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/package.html b/fine-javassist/src/main/java/com/fr/third/javassist/package.html deleted file mode 100644 index f5b66b98f..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/package.html +++ /dev/null @@ -1,22 +0,0 @@ - - -The Javassist Core API. - -

Javassist (Java programming assistant) makes bytecode -engineering simple. It is a class library for editing -bytecode in Java; it enables Java programs to define a new class at -runtime and to modify a given class file when the JVM loads it. - -

The most significant class of this package is CtClass. -See the description of this class first. - -

To know the version number of this package, type the following command: - -

    -java -jar javassist.jar
    -
- -

It prints the version number on the console. - - - diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/runtime/Cflow.java b/fine-javassist/src/main/java/com/fr/third/javassist/runtime/Cflow.java deleted file mode 100644 index 89ee4802e..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/runtime/Cflow.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.runtime; - -import com.fr.third.javassist.CtBehavior; - -/** - * A support class for implementing $cflow. - * This support class is required at runtime - * only if $cflow is used. - * - * @see CtBehavior#useCflow(String) - */ -public class Cflow extends ThreadLocal { - private static class Depth { - private int depth; - Depth() { depth = 0; } - int get() { return depth; } - void inc() { ++depth; } - void dec() { --depth; } - } - - protected synchronized Object initialValue() { - return new Depth(); - } - - /** - * Increments the counter. - */ - public void enter() { ((Depth)get()).inc(); } - - /** - * Decrements the counter. - */ - public void exit() { ((Depth)get()).dec(); } - - /** - * Returns the value of the counter. - */ - public int value() { return ((Depth)get()).get(); } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/runtime/Desc.java b/fine-javassist/src/main/java/com/fr/third/javassist/runtime/Desc.java deleted file mode 100644 index 2f7ec883e..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/runtime/Desc.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.runtime; - -/** - * A support class for implementing $sig and - * $type. - * This support class is required at runtime - * only if $sig or $type is used. - */ -public class Desc { - - /** - * Specifies how a java.lang.Class object is loaded. - * - *

If true, it is loaded by: - *

    Thread.currentThread().getContextClassLoader().loadClass()
- *

If false, it is loaded by Class.forName(). - * The default value is false. - */ - public static boolean useContextClassLoader = false; - - private static Class getClassObject(String name) - throws ClassNotFoundException - { - if (useContextClassLoader) - return Class.forName(name, true, Thread.currentThread().getContextClassLoader()); - else - return Class.forName(name); - } - - /** - * Interprets the given class name. - * It is used for implementing $class. - */ - public static Class getClazz(String name) { - try { - return getClassObject(name); - } - catch (ClassNotFoundException e) { - throw new RuntimeException( - "$class: internal error, could not find class '" + name - + "' (Desc.useContextClassLoader: " - + Boolean.toString(useContextClassLoader) + ")", e); - } - } - - /** - * Interprets the given type descriptor representing a method - * signature. It is used for implementing $sig. - */ - public static Class[] getParams(String desc) { - if (desc.charAt(0) != '(') - throw new RuntimeException("$sig: internal error"); - - return getType(desc, desc.length(), 1, 0); - } - - /** - * Interprets the given type descriptor. - * It is used for implementing $type. - */ - public static Class getType(String desc) { - Class[] result = getType(desc, desc.length(), 0, 0); - if (result == null || result.length != 1) - throw new RuntimeException("$type: internal error"); - - return result[0]; - } - - private static Class[] getType(String desc, int descLen, - int start, int num) { - Class clazz; - if (start >= descLen) - return new Class[num]; - - char c = desc.charAt(start); - switch (c) { - case 'Z' : - clazz = Boolean.TYPE; - break; - case 'C' : - clazz = Character.TYPE; - break; - case 'B' : - clazz = Byte.TYPE; - break; - case 'S' : - clazz = Short.TYPE; - break; - case 'I' : - clazz = Integer.TYPE; - break; - case 'J' : - clazz = Long.TYPE; - break; - case 'F' : - clazz = Float.TYPE; - break; - case 'D' : - clazz = Double.TYPE; - break; - case 'V' : - clazz = Void.TYPE; - break; - case 'L' : - case '[' : - return getClassType(desc, descLen, start, num); - default : - return new Class[num]; - } - - Class[] result = getType(desc, descLen, start + 1, num + 1); - result[num] = clazz; - return result; - } - - private static Class[] getClassType(String desc, int descLen, - int start, int num) { - int end = start; - while (desc.charAt(end) == '[') - ++end; - - if (desc.charAt(end) == 'L') { - end = desc.indexOf(';', end); - if (end < 0) - throw new IndexOutOfBoundsException("bad descriptor"); - } - - String cname; - if (desc.charAt(start) == 'L') - cname = desc.substring(start + 1, end); - else - cname = desc.substring(start, end + 1); - - Class[] result = getType(desc, descLen, end + 1, num + 1); - try { - result[num] = getClassObject(cname.replace('/', '.')); - } - catch (ClassNotFoundException e) { - // "new RuntimeException(e)" is not available in JDK 1.3. - throw new RuntimeException(e.getMessage()); - } - - return result; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/runtime/DotClass.java b/fine-javassist/src/main/java/com/fr/third/javassist/runtime/DotClass.java deleted file mode 100644 index 1619c6e93..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/runtime/DotClass.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.runtime; - -/** - * A support class for implementing .class notation. - * This is required at runtime - * only if .class notation is used in source code given - * to the Javassist compiler. - */ -public class DotClass { - public static NoClassDefFoundError fail(ClassNotFoundException e) { - return new NoClassDefFoundError(e.getMessage()); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/runtime/Inner.java b/fine-javassist/src/main/java/com/fr/third/javassist/runtime/Inner.java deleted file mode 100644 index 237371d2e..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/runtime/Inner.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.runtime; - -/** - * A support class for compiling a method declared in an inner class. - * This support class is required at runtime - * only if the method calls a private constructor in the enclosing class. - */ -public class Inner { -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/runtime/package.html b/fine-javassist/src/main/java/com/fr/third/javassist/runtime/package.html deleted file mode 100644 index 313648f6e..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/runtime/package.html +++ /dev/null @@ -1,12 +0,0 @@ - - -Runtime support classes required by modified bytecode. - -

This package includes support classes that may be required by -classes modified with Javassist. Note that most of the modified -classes do not require these support classes. See the documentation -of every support class to know which kind of modification needs -a support class. - - - diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPool.java b/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPool.java deleted file mode 100644 index 8756a2409..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPool.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.scopedpool; - -import java.lang.ref.WeakReference; -import java.security.ProtectionDomain; -import java.util.Iterator; -import java.util.Map; -import com.fr.third.javassist.CannotCompileException; -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.LoaderClassPath; -import com.fr.third.javassist.NotFoundException; - -/** - * A scoped class pool. - * - * @author Bill Burke - * @author Adrian Brock - * @author Kabir Khan - * @version $Revision: 1.8 $ - */ -public class ScopedClassPool extends ClassPool { - protected ScopedClassPoolRepository repository; - - protected WeakReference classLoader; - - protected LoaderClassPath classPath; - - protected SoftValueHashMap softcache = new SoftValueHashMap(); - - boolean isBootstrapCl = true; - - static { - ClassPool.doPruning = false; - ClassPool.releaseUnmodifiedClassFile = false; - } - - /** - * Create a new ScopedClassPool. - * - * @param cl - * the classloader - * @param src - * the original class pool - * @param repository - * the repository - *@deprecated - */ - protected ScopedClassPool(ClassLoader cl, ClassPool src, - ScopedClassPoolRepository repository) { - this(cl, src, repository, false); - } - - /** - * Create a new ScopedClassPool. - * - * @param cl - * the classloader - * @param src - * the original class pool - * @param repository - * the repository - * @param isTemp - * Whether this is a temporary pool used to resolve references - */ - protected ScopedClassPool(ClassLoader cl, ClassPool src, ScopedClassPoolRepository repository, boolean isTemp) - { - super(src); - this.repository = repository; - this.classLoader = new WeakReference(cl); - if (cl != null) { - classPath = new LoaderClassPath(cl); - this.insertClassPath(classPath); - } - childFirstLookup = true; - if (!isTemp && cl == null) - { - isBootstrapCl = true; - } - } - - /** - * Get the class loader - * - * @return the class loader - */ - public ClassLoader getClassLoader() { - ClassLoader cl = getClassLoader0(); - if (cl == null && !isBootstrapCl) - { - throw new IllegalStateException( - "ClassLoader has been garbage collected"); - } - return cl; - } - - protected ClassLoader getClassLoader0() { - return (ClassLoader)classLoader.get(); - } - - /** - * Close the class pool - */ - public void close() { - this.removeClassPath(classPath); - classPath.close(); - classes.clear(); - softcache.clear(); - } - - /** - * Flush a class - * - * @param classname - * the class to flush - */ - public synchronized void flushClass(String classname) { - classes.remove(classname); - softcache.remove(classname); - } - - /** - * Soften a class - * - * @param clazz - * the class - */ - public synchronized void soften(CtClass clazz) { - if (repository.isPrune()) - clazz.prune(); - classes.remove(clazz.getName()); - softcache.put(clazz.getName(), clazz); - } - - /** - * Whether the classloader is loader - * - * @return false always - */ - public boolean isUnloadedClassLoader() { - return false; - } - - /** - * Get the cached class - * - * @param classname - * the class name - * @return the class - */ - protected CtClass getCached(String classname) { - CtClass clazz = getCachedLocally(classname); - if (clazz == null) { - boolean isLocal = false; - - ClassLoader dcl = getClassLoader0(); - if (dcl != null) { - final int lastIndex = classname.lastIndexOf('$'); - String classResourceName = null; - if (lastIndex < 0) { - classResourceName = classname.replaceAll("[\\.]", "/") - + ".class"; - } - else { - classResourceName = classname.substring(0, lastIndex) - .replaceAll("[\\.]", "/") - + classname.substring(lastIndex) + ".class"; - } - - isLocal = dcl.getResource(classResourceName) != null; - } - - if (!isLocal) { - Map registeredCLs = repository.getRegisteredCLs(); - synchronized (registeredCLs) { - Iterator it = registeredCLs.values().iterator(); - while (it.hasNext()) { - ScopedClassPool pool = (ScopedClassPool)it.next(); - if (pool.isUnloadedClassLoader()) { - repository.unregisterClassLoader(pool - .getClassLoader()); - continue; - } - - clazz = pool.getCachedLocally(classname); - if (clazz != null) { - return clazz; - } - } - } - } - } - // *NOTE* NEED TO TEST WHEN SUPERCLASS IS IN ANOTHER UCL!!!!!! - return clazz; - } - - /** - * Cache a class - * - * @param classname - * the class name - * @param c - * the ctClass - * @param dynamic - * whether the class is dynamically generated - */ - protected void cacheCtClass(String classname, CtClass c, boolean dynamic) { - if (dynamic) { - super.cacheCtClass(classname, c, dynamic); - } - else { - if (repository.isPrune()) - c.prune(); - softcache.put(classname, c); - } - } - - /** - * Lock a class into the cache - * - * @param c - * the class - */ - public void lockInCache(CtClass c) { - super.cacheCtClass(c.getName(), c, false); - } - - /** - * Whether the class is cached in this pooled - * - * @param classname - * the class name - * @return the cached class - */ - protected CtClass getCachedLocally(String classname) { - CtClass cached = (CtClass)classes.get(classname); - if (cached != null) - return cached; - synchronized (softcache) { - return (CtClass)softcache.get(classname); - } - } - - /** - * Get any local copy of the class - * - * @param classname - * the class name - * @return the class - * @throws NotFoundException - * when the class is not found - */ - public synchronized CtClass getLocally(String classname) - throws NotFoundException { - softcache.remove(classname); - CtClass clazz = (CtClass)classes.get(classname); - if (clazz == null) { - clazz = createCtClass(classname, true); - if (clazz == null) - throw new NotFoundException(classname); - super.cacheCtClass(classname, clazz, false); - } - - return clazz; - } - - /** - * Convert a javassist class to a java class - * - * @param ct - * the javassist class - * @param loader - * the loader - * @throws CannotCompileException - * for any error - */ - public Class toClass(CtClass ct, ClassLoader loader, ProtectionDomain domain) - throws CannotCompileException { - // We need to pass up the classloader stored in this pool, as the - // default implementation uses the Thread context cl. - // In the case of JSP's in Tomcat, - // org.apache.jasper.servlet.JasperLoader will be stored here, while - // it's parent - // org.jboss.web.tomcat.tc5.WebCtxLoader$ENCLoader is used as the Thread - // context cl. The invocation class needs to - // be generated in the JasperLoader classloader since in the case of - // method invocations, the package name will be - // the same as for the class generated from the jsp, i.e. - // org.apache.jsp. For classes belonging to org.apache.jsp, - // JasperLoader does NOT delegate to its parent if it cannot find them. - lockInCache(ct); - return super.toClass(ct, getClassLoader0(), domain); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPoolFactory.java b/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPoolFactory.java deleted file mode 100644 index 43987d51c..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPoolFactory.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.scopedpool; - -import com.fr.third.javassist.ClassPool; - -/** - * A factory interface. - * - * @author Kabir Khan - * @version $Revision: 1.4 $ - */ -public interface ScopedClassPoolFactory { - /** - * Makes an instance. - */ - com.fr.third.javassist.scopedpool.ScopedClassPool create(ClassLoader cl, ClassPool src, - ScopedClassPoolRepository repository); - - /** - * Makes an instance. - */ - ScopedClassPool create(ClassPool src, - ScopedClassPoolRepository repository); -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPoolFactoryImpl.java b/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPoolFactoryImpl.java deleted file mode 100644 index 0fad68639..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPoolFactoryImpl.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.scopedpool; - -import com.fr.third.javassist.ClassPool; - -/** - * An implementation of factory. - * - * @author Kabir Khan - * @version $Revision: 1.5 $ - */ -public class ScopedClassPoolFactoryImpl implements ScopedClassPoolFactory { - /** - * Makes an instance. - */ - public com.fr.third.javassist.scopedpool.ScopedClassPool create(ClassLoader cl, ClassPool src, - com.fr.third.javassist.scopedpool.ScopedClassPoolRepository repository) { - return new com.fr.third.javassist.scopedpool.ScopedClassPool(cl, src, repository, false); - } - - /** - * Makes an instance. - */ - public com.fr.third.javassist.scopedpool.ScopedClassPool create(ClassPool src, - ScopedClassPoolRepository repository) { - return new ScopedClassPool(null, src, repository, true); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPoolRepository.java b/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPoolRepository.java deleted file mode 100644 index 0324a7d1b..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPoolRepository.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.scopedpool; - -import java.util.Map; - -import com.fr.third.javassist.ClassPool; - -/** - * An interface to ScopedClassPoolRepositoryImpl. - * - * @author Kabir Khan - * @version $Revision: 1.4 $ - */ -public interface ScopedClassPoolRepository { - /** - * Records a factory. - */ - void setClassPoolFactory(com.fr.third.javassist.scopedpool.ScopedClassPoolFactory factory); - - /** - * Obtains the recorded factory. - */ - ScopedClassPoolFactory getClassPoolFactory(); - - /** - * Returns whether or not the class pool is pruned. - * - * @return the prune. - */ - boolean isPrune(); - - /** - * Sets the prune flag. - * - * @param prune a new value. - */ - void setPrune(boolean prune); - - /** - * Create a scoped classpool. - * - * @param cl the classloader. - * @param src the original classpool. - * @return the classpool. - */ - ScopedClassPool createScopedClassPool(ClassLoader cl, ClassPool src); - - /** - * Finds a scoped classpool registered under the passed in classloader. - * - * @param cl the classloader. - * @return the classpool. - */ - ClassPool findClassPool(ClassLoader cl); - - /** - * Register a classloader. - * - * @param ucl the classloader. - * @return the classpool. - */ - ClassPool registerClassLoader(ClassLoader ucl); - - /** - * Get the registered classloaders. - * - * @return the registered classloaders. - */ - Map getRegisteredCLs(); - - /** - * This method will check to see if a register classloader has been - * undeployed (as in JBoss). - */ - void clearUnregisteredClassLoaders(); - - /** - * Unregisters a classpool and unregisters its classloader. - * - * @param cl the classloader the pool is stored under. - */ - void unregisterClassLoader(ClassLoader cl); -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPoolRepositoryImpl.java b/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPoolRepositoryImpl.java deleted file mode 100644 index 498dfc77f..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/ScopedClassPoolRepositoryImpl.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.scopedpool; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.Map; -import java.util.WeakHashMap; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.LoaderClassPath; - -/** - * An implementation of ScopedClassPoolRepository. - * It is an singleton. - * - * @author Kabir Khan - * @version $Revision: 1.4 $ - */ -public class ScopedClassPoolRepositoryImpl implements com.fr.third.javassist.scopedpool.ScopedClassPoolRepository { - /** The instance */ - private static final ScopedClassPoolRepositoryImpl instance = new ScopedClassPoolRepositoryImpl(); - - /** Whether to prune */ - private boolean prune = true; - - /** Whether to prune when added to the classpool's cache */ - boolean pruneWhenCached; - - /** The registered classloaders */ - protected Map registeredCLs = Collections - .synchronizedMap(new WeakHashMap()); - - /** The default class pool */ - protected ClassPool classpool; - - /** The factory for creating class pools */ - protected com.fr.third.javassist.scopedpool.ScopedClassPoolFactory factory = new ScopedClassPoolFactoryImpl(); - - /** - * Get the instance. - * - * @return the instance. - */ - public static com.fr.third.javassist.scopedpool.ScopedClassPoolRepository getInstance() { - return instance; - } - - /** - * Singleton. - */ - private ScopedClassPoolRepositoryImpl() { - classpool = ClassPool.getDefault(); - // FIXME This doesn't look correct - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - classpool.insertClassPath(new LoaderClassPath(cl)); - } - - /** - * Returns the value of the prune attribute. - * - * @return the prune. - */ - public boolean isPrune() { - return prune; - } - - /** - * Set the prune attribute. - * - * @param prune a new value. - */ - public void setPrune(boolean prune) { - this.prune = prune; - } - - /** - * Create a scoped classpool. - * - * @param cl the classloader. - * @param src the original classpool. - * @return the classpool - */ - public com.fr.third.javassist.scopedpool.ScopedClassPool createScopedClassPool(ClassLoader cl, ClassPool src) { - return factory.create(cl, src, this); - } - - public ClassPool findClassPool(ClassLoader cl) { - if (cl == null) - return registerClassLoader(ClassLoader.getSystemClassLoader()); - - return registerClassLoader(cl); - } - - /** - * Register a classloader. - * - * @param ucl the classloader. - * @return the classpool - */ - public ClassPool registerClassLoader(ClassLoader ucl) { - synchronized (registeredCLs) { - // FIXME: Probably want to take this method out later - // so that AOP framework can be independent of JMX - // This is in here so that we can remove a UCL from the ClassPool as - // a - // ClassPool.classpath - if (registeredCLs.containsKey(ucl)) { - return (ClassPool)registeredCLs.get(ucl); - } - com.fr.third.javassist.scopedpool.ScopedClassPool pool = createScopedClassPool(ucl, classpool); - registeredCLs.put(ucl, pool); - return pool; - } - } - - /** - * Get the registered classloaders. - */ - public Map getRegisteredCLs() { - clearUnregisteredClassLoaders(); - return registeredCLs; - } - - /** - * This method will check to see if a register classloader has been - * undeployed (as in JBoss) - */ - public void clearUnregisteredClassLoaders() { - ArrayList toUnregister = null; - synchronized (registeredCLs) { - Iterator it = registeredCLs.values().iterator(); - while (it.hasNext()) { - com.fr.third.javassist.scopedpool.ScopedClassPool pool = (com.fr.third.javassist.scopedpool.ScopedClassPool)it.next(); - if (pool.isUnloadedClassLoader()) { - it.remove(); - ClassLoader cl = pool.getClassLoader(); - if (cl != null) { - if (toUnregister == null) { - toUnregister = new ArrayList(); - } - toUnregister.add(cl); - } - } - } - if (toUnregister != null) { - for (int i = 0; i < toUnregister.size(); i++) { - unregisterClassLoader((ClassLoader)toUnregister.get(i)); - } - } - } - } - - public void unregisterClassLoader(ClassLoader cl) { - synchronized (registeredCLs) { - com.fr.third.javassist.scopedpool.ScopedClassPool pool = (ScopedClassPool)registeredCLs.remove(cl); - if (pool != null) - pool.close(); - } - } - - public void insertDelegate(ScopedClassPoolRepository delegate) { - // Noop - this is the end - } - - public void setClassPoolFactory(com.fr.third.javassist.scopedpool.ScopedClassPoolFactory factory) { - this.factory = factory; - } - - public ScopedClassPoolFactory getClassPoolFactory() { - return factory; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/SoftValueHashMap.java b/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/SoftValueHashMap.java deleted file mode 100644 index d4532ce2f..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/SoftValueHashMap.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.scopedpool; - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; -import java.util.AbstractMap; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -/** - * This Map will remove entries when the value in the map has been cleaned from - * garbage collection - * - * @version $Revision: 1.4 $ - * @author Bill Burke - */ -public class SoftValueHashMap extends AbstractMap implements Map { - private static class SoftValueRef extends SoftReference { - public Object key; - - private SoftValueRef(Object key, Object val, ReferenceQueue q) { - super(val, q); - this.key = key; - } - - private static SoftValueRef create(Object key, Object val, - ReferenceQueue q) { - if (val == null) - return null; - else - return new SoftValueRef(key, val, q); - } - - } - - /** - * Returns a set of the mappings contained in this hash table. - */ - public Set entrySet() { - processQueue(); - return hash.entrySet(); - } - - /* Hash table mapping WeakKeys to values */ - private Map hash; - - /* Reference queue for cleared WeakKeys */ - private ReferenceQueue queue = new ReferenceQueue(); - - /* - * Remove all invalidated entries from the map, that is, remove all entries - * whose values have been discarded. - */ - private void processQueue() { - SoftValueRef ref; - while ((ref = (SoftValueRef)queue.poll()) != null) { - if (ref == (SoftValueRef)hash.get(ref.key)) { - // only remove if it is the *exact* same WeakValueRef - // - hash.remove(ref.key); - } - } - } - - /* -- Constructors -- */ - - /** - * Constructs a new, empty WeakHashMap with the given initial - * capacity and the given load factor. - * - * @param initialCapacity - * The initial capacity of the WeakHashMap - * - * @param loadFactor - * The load factor of the WeakHashMap - * - * @throws IllegalArgumentException - * If the initial capacity is less than zero, or if the load - * factor is nonpositive - */ - public SoftValueHashMap(int initialCapacity, float loadFactor) { - hash = new HashMap(initialCapacity, loadFactor); - } - - /** - * Constructs a new, empty WeakHashMap with the given initial - * capacity and the default load factor, which is 0.75. - * - * @param initialCapacity - * The initial capacity of the WeakHashMap - * - * @throws IllegalArgumentException - * If the initial capacity is less than zero - */ - public SoftValueHashMap(int initialCapacity) { - hash = new HashMap(initialCapacity); - } - - /** - * Constructs a new, empty WeakHashMap with the default - * initial capacity and the default load factor, which is 0.75. - */ - public SoftValueHashMap() { - hash = new HashMap(); - } - - /** - * Constructs a new WeakHashMap with the same mappings as the - * specified Map. The WeakHashMap is created with - * an initial capacity of twice the number of mappings in the specified map - * or 11 (whichever is greater), and a default load factor, which is - * 0.75. - * - * @param t the map whose mappings are to be placed in this map. - */ - public SoftValueHashMap(Map t) { - this(Math.max(2 * t.size(), 11), 0.75f); - putAll(t); - } - - /* -- Simple queries -- */ - - /** - * Returns the number of key-value mappings in this map. Note: - * In contrast with most implementations of the - * Map interface, the time required by this operation is - * linear in the size of the map. - */ - public int size() { - processQueue(); - return hash.size(); - } - - /** - * Returns true if this map contains no key-value mappings. - */ - public boolean isEmpty() { - processQueue(); - return hash.isEmpty(); - } - - /** - * Returns true if this map contains a mapping for the - * specified key. - * - * @param key - * The key whose presence in this map is to be tested. - */ - public boolean containsKey(Object key) { - processQueue(); - return hash.containsKey(key); - } - - /* -- Lookup and modification operations -- */ - - /** - * Returns the value to which this map maps the specified key. - * If this map does not contain a value for this key, then return - * null. - * - * @param key - * The key whose associated value, if any, is to be returned. - */ - public Object get(Object key) { - processQueue(); - SoftReference ref = (SoftReference)hash.get(key); - if (ref != null) - return ref.get(); - return null; - } - - /** - * Updates this map so that the given key maps to the given - * value. If the map previously contained a mapping for - * key then that mapping is replaced and the previous value - * is returned. - * - * @param key - * The key that is to be mapped to the given value - * @param value - * The value to which the given key is to be - * mapped - * - * @return The previous value to which this key was mapped, or - * null if if there was no mapping for the key - */ - public Object put(Object key, Object value) { - processQueue(); - Object rtn = hash.put(key, SoftValueRef.create(key, value, queue)); - if (rtn != null) - rtn = ((SoftReference)rtn).get(); - return rtn; - } - - /** - * Removes the mapping for the given key from this map, if - * present. - * - * @param key - * The key whose mapping is to be removed. - * - * @return The value to which this key was mapped, or null if - * there was no mapping for the key. - */ - public Object remove(Object key) { - processQueue(); - return hash.remove(key); - } - - /** - * Removes all mappings from this map. - */ - public void clear() { - processQueue(); - hash.clear(); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/package.html b/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/package.html deleted file mode 100644 index 946e5e18d..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/scopedpool/package.html +++ /dev/null @@ -1,7 +0,0 @@ - - -

A custom class pool for several JBoss products. -It is not part of Javassist. -

- - diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/Dump.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/Dump.java deleted file mode 100644 index 92c29b312..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/Dump.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools; - -import java.io.*; -import com.fr.third.javassist.bytecode.ClassFile; -import com.fr.third.javassist.bytecode.ClassFilePrinter; - -/** - * Dump is a tool for viewing the class definition in the given - * class file. Unlike the JDK javap tool, Dump works even if - * the class file is broken. - * - *

For example, - *

    % java javassist.tools.Dump foo.class
- * - *

prints the contents of the constant pool and the list of methods - * and fields. - */ -public class Dump { - private Dump() {} - - /** - * Main method. - * - * @param args args[0] is the class file name. - */ - public static void main(String[] args) throws Exception { - if (args.length != 1) { - System.err.println("Usage: java Dump "); - return; - } - - DataInputStream in = new DataInputStream( - new FileInputStream(args[0])); - ClassFile w = new ClassFile(in); - PrintWriter out = new PrintWriter(System.out, true); - out.println("*** constant pool ***"); - w.getConstPool().print(out); - out.println(); - out.println("*** members ***"); - ClassFilePrinter.print(w, out); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/framedump.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/framedump.java deleted file mode 100644 index 6b4879d72..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/framedump.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.tools; - -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.bytecode.analysis.FramePrinter; - -/** - * framedump is a tool for viewing a merged combination of the instructions and frame state - * of all methods in a class. - * - *

For example, - *

    % java javassist.tools.framedump foo.class
- */ -public class framedump { - private framedump() {} - - /** - * Main method. - * - * @param args args[0] is the class file name. - */ - public static void main(String[] args) throws Exception { - if (args.length != 1) { - System.err.println("Usage: java javassist.tools.framedump "); - return; - } - - ClassPool pool = ClassPool.getDefault(); - CtClass clazz = pool.get(args[0]); - System.out.println("Frame Dump of " + clazz.getName() + ":"); - FramePrinter.print(clazz, System.out); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/package.html b/fine-javassist/src/main/java/com/fr/third/javassist/tools/package.html deleted file mode 100644 index bee6208da..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/package.html +++ /dev/null @@ -1,6 +0,0 @@ - - -Covenient tools. - - - diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/CannotCreateException.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/CannotCreateException.java deleted file mode 100644 index de396e75e..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/CannotCreateException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.reflect; - -/** - * Signals that ClassMetaobject.newInstance() fails. - */ -public class CannotCreateException extends Exception { - public CannotCreateException(String s) { - super(s); - } - - public CannotCreateException(Exception e) { - super("by " + e.toString()); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/CannotInvokeException.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/CannotInvokeException.java deleted file mode 100644 index 668e3a8e0..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/CannotInvokeException.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.reflect; - -import java.lang.reflect.InvocationTargetException; -import java.lang.IllegalAccessException; - -/** - * Thrown when method invocation using the reflection API has thrown - * an exception. - * - * @see Metaobject#trapMethodcall(int, Object[]) - * @see ClassMetaobject#trapMethodcall(int, Object[]) - * @see ClassMetaobject#invoke(Object, int, Object[]) - */ -public class CannotInvokeException extends RuntimeException { - - private Throwable err = null; - - /** - * Returns the cause of this exception. It may return null. - */ - public Throwable getReason() { return err; } - - /** - * Constructs a CannotInvokeException with an error message. - */ - public CannotInvokeException(String reason) { - super(reason); - } - - /** - * Constructs a CannotInvokeException with an InvocationTargetException. - */ - public CannotInvokeException(InvocationTargetException e) { - super("by " + e.getTargetException().toString()); - err = e.getTargetException(); - } - - /** - * Constructs a CannotInvokeException with an IllegalAccessException. - */ - public CannotInvokeException(IllegalAccessException e) { - super("by " + e.toString()); - err = e; - } - - /** - * Constructs a CannotInvokeException with an ClassNotFoundException. - */ - public CannotInvokeException(ClassNotFoundException e) { - super("by " + e.toString()); - err = e; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/CannotReflectException.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/CannotReflectException.java deleted file mode 100644 index f890f5089..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/CannotReflectException.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.reflect; - -import com.fr.third.javassist.CannotCompileException; - -/** - * Thrown by makeReflective() in Reflection - * when there is an attempt to reflect - * a class that is either an interface or a subclass of - * either ClassMetaobject or Metaobject. - * - * @author Brett Randall - * @see Reflection#makeReflective(CtClass,CtClass,CtClass) - * @see CannotCompileException - */ -public class CannotReflectException extends CannotCompileException { - public CannotReflectException(String msg) { - super(msg); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/ClassMetaobject.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/ClassMetaobject.java deleted file mode 100644 index 1bd815c3b..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/ClassMetaobject.java +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.reflect; - -import java.lang.reflect.*; -import java.util.Arrays; -import java.io.Serializable; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -/** - * A runtime class metaobject. - * - *

A ClassMetaobject is created for every - * class of reflective objects. It can be used to hold values - * shared among the reflective objects of the same class. - * - *

To obtain a class metaobject, calls _getClass() - * on a reflective object. For example, - * - *

    ClassMetaobject cm = ((Metalevel)reflectiveObject)._getClass();
    - * 
- * - * @see com.fr.third.javassist.tools.reflect.Metaobject - * @see Metalevel - */ -public class ClassMetaobject implements Serializable { - /** - * The base-level methods controlled by a metaobject - * are renamed so that they begin with - * methodPrefix "_m_". - */ - static final String methodPrefix = "_m_"; - static final int methodPrefixLen = 3; - - private Class javaClass; - private Constructor[] constructors; - private Method[] methods; - - /** - * Specifies how a java.lang.Class object is loaded. - * - *

If true, it is loaded by: - *

    Thread.currentThread().getContextClassLoader().loadClass()
- *

If false, it is loaded by Class.forName(). - * The default value is false. - */ - public static boolean useContextClassLoader = false; - - /** - * Constructs a ClassMetaobject. - * - * @param params params[0] is the name of the class - * of the reflective objects. - */ - public ClassMetaobject(String[] params) - { - try { - javaClass = getClassObject(params[0]); - } - catch (ClassNotFoundException e) { - throw new RuntimeException("not found: " + params[0] - + ", useContextClassLoader: " - + Boolean.toString(useContextClassLoader), e); - } - - constructors = javaClass.getConstructors(); - methods = null; - } - - private void writeObject(ObjectOutputStream out) throws IOException { - out.writeUTF(javaClass.getName()); - } - - private void readObject(ObjectInputStream in) - throws IOException, ClassNotFoundException - { - javaClass = getClassObject(in.readUTF()); - constructors = javaClass.getConstructors(); - methods = null; - } - - private Class getClassObject(String name) throws ClassNotFoundException { - if (useContextClassLoader) - return Thread.currentThread().getContextClassLoader() - .loadClass(name); - else - return Class.forName(name); - } - - /** - * Obtains the java.lang.Class representing this class. - */ - public final Class getJavaClass() { - return javaClass; - } - - /** - * Obtains the name of this class. - */ - public final String getName() { - return javaClass.getName(); - } - - /** - * Returns true if obj is an instance of this class. - */ - public final boolean isInstance(Object obj) { - return javaClass.isInstance(obj); - } - - /** - * Creates a new instance of the class. - * - * @param args the arguments passed to the constructor. - */ - public final Object newInstance(Object[] args) - throws CannotCreateException - { - int n = constructors.length; - for (int i = 0; i < n; ++i) { - try { - return constructors[i].newInstance(args); - } - catch (IllegalArgumentException e) { - // try again - } - catch (InstantiationException e) { - throw new CannotCreateException(e); - } - catch (IllegalAccessException e) { - throw new CannotCreateException(e); - } - catch (InvocationTargetException e) { - throw new CannotCreateException(e); - } - } - - throw new CannotCreateException("no constructor matches"); - } - - /** - * Is invoked when static fields of the base-level - * class are read and the runtime system intercepts it. - * This method simply returns the value of the field. - * - *

Every subclass of this class should redefine this method. - */ - public Object trapFieldRead(String name) { - Class jc = getJavaClass(); - try { - return jc.getField(name).get(null); - } - catch (NoSuchFieldException e) { - throw new RuntimeException(e.toString()); - } - catch (IllegalAccessException e) { - throw new RuntimeException(e.toString()); - } - } - - /** - * Is invoked when static fields of the base-level - * class are modified and the runtime system intercepts it. - * This method simply sets the field to the given value. - * - *

Every subclass of this class should redefine this method. - */ - public void trapFieldWrite(String name, Object value) { - Class jc = getJavaClass(); - try { - jc.getField(name).set(null, value); - } - catch (NoSuchFieldException e) { - throw new RuntimeException(e.toString()); - } - catch (IllegalAccessException e) { - throw new RuntimeException(e.toString()); - } - } - - /** - * Invokes a method whose name begins with - * methodPrefix "_m_" and the identifier. - * - * @exception CannotInvokeException if the invocation fails. - */ - static public Object invoke(Object target, int identifier, Object[] args) - throws Throwable - { - Method[] allmethods = target.getClass().getMethods(); - int n = allmethods.length; - String head = methodPrefix + identifier; - for (int i = 0; i < n; ++i) - if (allmethods[i].getName().startsWith(head)) { - try { - return allmethods[i].invoke(target, args); - } catch (java.lang.reflect.InvocationTargetException e) { - throw e.getTargetException(); - } catch (java.lang.IllegalAccessException e) { - throw new CannotInvokeException(e); - } - } - - throw new CannotInvokeException("cannot find a method"); - } - - /** - * Is invoked when static methods of the base-level - * class are called and the runtime system intercepts it. - * This method simply executes the intercepted method invocation - * with the original parameters and returns the resulting value. - * - *

Every subclass of this class should redefine this method. - */ - public Object trapMethodcall(int identifier, Object[] args) - throws Throwable - { - try { - Method[] m = getReflectiveMethods(); - return m[identifier].invoke(null, args); - } - catch (java.lang.reflect.InvocationTargetException e) { - throw e.getTargetException(); - } - catch (java.lang.IllegalAccessException e) { - throw new CannotInvokeException(e); - } - } - - /** - * Returns an array of the methods defined on the given reflective - * object. This method is for the internal use only. - */ - public final Method[] getReflectiveMethods() { - if (methods != null) - return methods; - - Class baseclass = getJavaClass(); - Method[] allmethods = baseclass.getDeclaredMethods(); - int n = allmethods.length; - int[] index = new int[n]; - int max = 0; - for (int i = 0; i < n; ++i) { - Method m = allmethods[i]; - String mname = m.getName(); - if (mname.startsWith(methodPrefix)) { - int k = 0; - for (int j = methodPrefixLen;; ++j) { - char c = mname.charAt(j); - if ('0' <= c && c <= '9') - k = k * 10 + c - '0'; - else - break; - } - - index[i] = ++k; - if (k > max) - max = k; - } - } - - methods = new Method[max]; - for (int i = 0; i < n; ++i) - if (index[i] > 0) - methods[index[i] - 1] = allmethods[i]; - - return methods; - } - - /** - * Returns the java.lang.reflect.Method object representing - * the method specified by identifier. - * - *

Note that the actual method returned will be have an altered, - * reflective name i.e. _m_2_... - * - * @param identifier the identifier index - * given to trapMethodcall() etc. - * @see Metaobject#trapMethodcall(int,Object[]) - * @see #trapMethodcall(int,Object[]) - */ - public final Method getMethod(int identifier) { - return getReflectiveMethods()[identifier]; - } - - /** - * Returns the name of the method specified - * by identifier. - */ - public final String getMethodName(int identifier) { - String mname = getReflectiveMethods()[identifier].getName(); - int j = ClassMetaobject.methodPrefixLen; - for (;;) { - char c = mname.charAt(j++); - if (c < '0' || '9' < c) - break; - } - - return mname.substring(j); - } - - /** - * Returns an array of Class objects representing the - * formal parameter types of the method specified - * by identifier. - */ - public final Class[] getParameterTypes(int identifier) { - return getReflectiveMethods()[identifier].getParameterTypes(); - } - - /** - * Returns a Class objects representing the - * return type of the method specified by identifier. - */ - public final Class getReturnType(int identifier) { - return getReflectiveMethods()[identifier].getReturnType(); - } - - /** - * Returns the identifier index of the method, as identified by its - * original name. - * - *

This method is useful, in conjuction with - * ClassMetaobject#getMethod(), to obtain a quick reference - * to the original method in the reflected class (i.e. not the proxy - * method), using the original name of the method. - * - *

Written by Brett Randall and Shigeru Chiba. - * - * @param originalName The original name of the reflected method - * @param argTypes array of Class specifying the method signature - * @return the identifier index of the original method - * @throws NoSuchMethodException if the method does not exist - * - * @see ClassMetaobject#getMethod(int) - */ - public final int getMethodIndex(String originalName, Class[] argTypes) - throws NoSuchMethodException - { - Method[] mthds = getReflectiveMethods(); - for (int i = 0; i < mthds.length; i++) { - if (mthds[i] == null) - continue; - - // check name and parameter types match - if (getMethodName(i).equals(originalName) - && Arrays.equals(argTypes, mthds[i].getParameterTypes())) - return i; - } - - throw new NoSuchMethodException("Method " + originalName - + " not found"); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Compiler.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Compiler.java deleted file mode 100644 index 5c637b438..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Compiler.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.reflect; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.ClassPool; -import java.io.PrintStream; - -class CompiledClass { - public String classname; - public String metaobject; - public String classobject; -} - -/** - * A bytecode translator for reflection. - * - *

This translator directly modifies class files on a local disk so that - * the classes represented by those class files are reflective. - * After the modification, the class files can be run with the standard JVM - * without javassist.tools.reflect.Loader - * or any other user-defined class loader. - * - *

The modified class files are given as the command-line parameters, - * which are a sequence of fully-qualified class names followed by options: - * - *

-m classname : specifies the class of the - * metaobjects associated with instances of the class followed by - * this option. The default is javassit.reflect.Metaobject. - * - *

-c classname : specifies the class of the - * class metaobjects associated with instances of the class followed by - * this option. The default is javassit.reflect.ClassMetaobject. - * - *

If a class name is not followed by any options, the class indicated - * by that class name is not reflective. - * - *

For example, - *

    % java Compiler Dog -m MetaDog -c CMetaDog Cat -m MetaCat Cow
    - * 
- * - *

modifies class files Dog.class, Cat.class, - * and Cow.class. - * The metaobject of a Dog object is a MetaDog object and the class - * metaobject is a CMetaDog object. - * The metaobject of a Cat object is a MetaCat object but - * the class metaobject is a default one. - * Cow objects are not reflective. - * - *

Note that if the super class is also made reflective, it must be done - * before the sub class. - * - * @see Metaobject - * @see ClassMetaobject - * @see Reflection - */ -public class Compiler { - - public static void main(String[] args) throws Exception { - if (args.length == 0) { - help(System.err); - return; - } - - CompiledClass[] entries = new CompiledClass[args.length]; - int n = parse(args, entries); - - if (n < 1) { - System.err.println("bad parameter."); - return; - } - - processClasses(entries, n); - } - - private static void processClasses(CompiledClass[] entries, int n) - throws Exception - { - Reflection implementor = new Reflection(); - ClassPool pool = ClassPool.getDefault(); - implementor.start(pool); - - for (int i = 0; i < n; ++i) { - CtClass c = pool.get(entries[i].classname); - if (entries[i].metaobject != null - || entries[i].classobject != null) { - String metaobj, classobj; - - if (entries[i].metaobject == null) - metaobj = "javassist.tools.reflect.Metaobject"; - else - metaobj = entries[i].metaobject; - - if (entries[i].classobject == null) - classobj = "javassist.tools.reflect.ClassMetaobject"; - else - classobj = entries[i].classobject; - - if (!implementor.makeReflective(c, pool.get(metaobj), - pool.get(classobj))) - System.err.println("Warning: " + c.getName() - + " is reflective. It was not changed."); - - System.err.println(c.getName() + ": " + metaobj + ", " - + classobj); - } - else - System.err.println(c.getName() + ": not reflective"); - } - - for (int i = 0; i < n; ++i) { - implementor.onLoad(pool, entries[i].classname); - pool.get(entries[i].classname).writeFile(); - } - } - - private static int parse(String[] args, CompiledClass[] result) { - int n = -1; - for (int i = 0; i < args.length; ++i) { - String a = args[i]; - if (a.equals("-m")) - if (n < 0 || i + 1 > args.length) - return -1; - else - result[n].metaobject = args[++i]; - else if (a.equals("-c")) - if (n < 0 || i + 1 > args.length) - return -1; - else - result[n].classobject = args[++i]; - else if (a.charAt(0) == '-') - return -1; - else { - CompiledClass cc = new CompiledClass(); - cc.classname = a; - cc.metaobject = null; - cc.classobject = null; - result[++n] = cc; - } - } - - return n + 1; - } - - private static void help(PrintStream out) { - out.println("Usage: java javassist.tools.reflect.Compiler"); - out.println(" ( [-m ] [-c ])+"); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Loader.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Loader.java deleted file mode 100644 index dd69f10ce..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Loader.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.reflect; - -import com.fr.third.javassist.CannotCompileException; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.ClassPool; - -/** - * A class loader for reflection. - * - *

To run a program, say MyApp, - * including a reflective class, - * you must write a start-up program as follows: - * - *

    - * public class Main {
    - *   public static void main(String[] args) throws Throwable {
    - *     javassist.tools.reflect.Loader cl
    - *         = (javassist.tools.reflect.Loader)Main.class.getClassLoader();
    - *     cl.makeReflective("Person", "MyMetaobject",
    - *                       "javassist.tools.reflect.ClassMetaobject");
    - *     cl.run("MyApp", args);
    - *   }
    - * }
    - * 
- * - *

Then run this program as follows: - * - *

    % java javassist.tools.reflect.Loader Main arg1, ...
- * - *

This command runs Main.main() with arg1, ... - * and Main.main() runs MyApp.main() with - * arg1, ... - * The Person class is modified - * to be a reflective class. Method calls on a Person - * object are intercepted by an instance of MyMetaobject. - * - *

Also, you can run MyApp in a slightly different way: - * - *

    - * public class Main2 {
    - *   public static void main(String[] args) throws Throwable {
    - *     javassist.tools.reflect.Loader cl = new javassist.tools.reflect.Loader();
    - *     cl.makeReflective("Person", "MyMetaobject",
    - *                       "javassist.tools.reflect.ClassMetaobject");
    - *     cl.run("MyApp", args);
    - *   }
    - * }
    - * 
- * - *

This program is run as follows: - * - *

    % java Main2 arg1, ...
- * - *

The difference from the former one is that the class Main - * is loaded by javassist.tools.reflect.Loader whereas the class - * Main2 is not. Thus, Main belongs - * to the same name space (security domain) as MyApp - * whereas Main2 does not; Main2 belongs - * to the same name space as javassist.tools.reflect.Loader. - * For more details, - * see the notes in the manual page of javassist.Loader. - * - *

The class Main2 is equivalent to this class: - * - *

    - * public class Main3 {
    - *   public static void main(String[] args) throws Throwable {
    - *     Reflection reflection = new Reflection();
    - *     javassist.Loader cl
    - *         = new javassist.Loader(ClassPool.getDefault(reflection));
    - *     reflection.makeReflective("Person", "MyMetaobject",
    - *                               "javassist.tools.reflect.ClassMetaobject");
    - *     cl.run("MyApp", args);
    - *   }
    - * }
    - * 
- * - *

Note: - * - *

javassist.tools.reflect.Loader does not make a class reflective - * if that class is in a java.* or - * javax.* pacakge because of the specifications - * on the class loading algorithm of Java. The JVM does not allow to - * load such a system class with a user class loader. - * - *

To avoid this limitation, those classes should be statically - * modified with javassist.tools.reflect.Compiler and the original - * class files should be replaced. - * - * @see Reflection - * @see Compiler - * @see com.fr.third.javassist.Loader - */ -public class Loader extends com.fr.third.javassist.Loader { - protected Reflection reflection; - - /** - * Loads a class with an instance of Loader - * and calls main() in that class. - * - * @param args command line parameters. - *

    - * args[0] is the class name to be loaded. - *
    args[1..n] are parameters passed - * to the target main(). - *
- */ - public static void main(String[] args) throws Throwable { - Loader cl = new Loader(); - cl.run(args); - } - - /** - * Constructs a new class loader. - */ - public Loader() throws CannotCompileException, NotFoundException { - super(); - delegateLoadingOf("javassist.tools.reflect.Loader"); - - reflection = new Reflection(); - ClassPool pool = ClassPool.getDefault(); - addTranslator(pool, reflection); - } - - /** - * Produces a reflective class. - * If the super class is also made reflective, it must be done - * before the sub class. - * - * @param clazz the reflective class. - * @param metaobject the class of metaobjects. - * It must be a subclass of - * Metaobject. - * @param metaclass the class of the class metaobject. - * It must be a subclass of - * ClassMetaobject. - * @return false if the class is already reflective. - * - * @see Metaobject - * @see ClassMetaobject - */ - public boolean makeReflective(String clazz, - String metaobject, String metaclass) - throws CannotCompileException, NotFoundException - { - return reflection.makeReflective(clazz, metaobject, metaclass); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Metalevel.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Metalevel.java deleted file mode 100644 index 7c65544fe..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Metalevel.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.reflect; - -/** - * An interface to access a metaobject and a class metaobject. - * This interface is implicitly implemented by the reflective - * class. - */ -public interface Metalevel { - /** - * Obtains the class metaobject associated with this object. - */ - ClassMetaobject _getClass(); - - /** - * Obtains the metaobject associated with this object. - */ - Metaobject _getMetaobject(); - - /** - * Changes the metaobject associated with this object. - */ - void _setMetaobject(Metaobject m); -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Metaobject.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Metaobject.java deleted file mode 100644 index 455e63245..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Metaobject.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.reflect; - -import java.lang.reflect.Method; -import java.io.Serializable; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -/** - * A runtime metaobject. - * - *

A Metaobject is created for - * every object at the base level. A different reflective object is - * associated with a different metaobject. - * - *

The metaobject intercepts method calls - * on the reflective object at the base-level. To change the behavior - * of the method calls, a subclass of Metaobject - * should be defined. - * - *

To obtain a metaobject, calls _getMetaobject() - * on a reflective object. For example, - * - *

    Metaobject m = ((Metalevel)reflectiveObject)._getMetaobject();
    - * 
- * - * @see ClassMetaobject - * @see com.fr.third.javassist.tools.reflect.Metalevel - */ -public class Metaobject implements Serializable { - protected ClassMetaobject classmetaobject; - protected com.fr.third.javassist.tools.reflect.Metalevel baseobject; - protected Method[] methods; - - /** - * Constructs a Metaobject. The metaobject is - * constructed before the constructor is called on the base-level - * object. - * - * @param self the object that this metaobject is associated with. - * @param args the parameters passed to the constructor of - * self. - */ - public Metaobject(Object self, Object[] args) { - baseobject = (com.fr.third.javassist.tools.reflect.Metalevel)self; - classmetaobject = baseobject._getClass(); - methods = classmetaobject.getReflectiveMethods(); - } - - /** - * Constructs a Metaobject without initialization. - * If calling this constructor, a subclass should be responsible - * for initialization. - */ - protected Metaobject() { - baseobject = null; - classmetaobject = null; - methods = null; - } - - private void writeObject(ObjectOutputStream out) throws IOException { - out.writeObject(baseobject); - } - - private void readObject(ObjectInputStream in) - throws IOException, ClassNotFoundException - { - baseobject = (com.fr.third.javassist.tools.reflect.Metalevel)in.readObject(); - classmetaobject = baseobject._getClass(); - methods = classmetaobject.getReflectiveMethods(); - } - - /** - * Obtains the class metaobject associated with this metaobject. - * - * @see ClassMetaobject - */ - public final ClassMetaobject getClassMetaobject() { - return classmetaobject; - } - - /** - * Obtains the object controlled by this metaobject. - */ - public final Object getObject() { - return baseobject; - } - - /** - * Changes the object controlled by this metaobject. - * - * @param self the object - */ - public final void setObject(Object self) { - baseobject = (Metalevel)self; - classmetaobject = baseobject._getClass(); - methods = classmetaobject.getReflectiveMethods(); - - // call _setMetaobject() after the metaobject is settled. - baseobject._setMetaobject(this); - } - - /** - * Returns the name of the method specified - * by identifier. - */ - public final String getMethodName(int identifier) { - String mname = methods[identifier].getName(); - int j = ClassMetaobject.methodPrefixLen; - for (;;) { - char c = mname.charAt(j++); - if (c < '0' || '9' < c) - break; - } - - return mname.substring(j); - } - - /** - * Returns an array of Class objects representing the - * formal parameter types of the method specified - * by identifier. - */ - public final Class[] getParameterTypes(int identifier) { - return methods[identifier].getParameterTypes(); - } - - /** - * Returns a Class objects representing the - * return type of the method specified by identifier. - */ - public final Class getReturnType(int identifier) { - return methods[identifier].getReturnType(); - } - - /** - * Is invoked when public fields of the base-level - * class are read and the runtime system intercepts it. - * This method simply returns the value of the field. - * - *

Every subclass of this class should redefine this method. - */ - public Object trapFieldRead(String name) { - Class jc = getClassMetaobject().getJavaClass(); - try { - return jc.getField(name).get(getObject()); - } - catch (NoSuchFieldException e) { - throw new RuntimeException(e.toString()); - } - catch (IllegalAccessException e) { - throw new RuntimeException(e.toString()); - } - } - - /** - * Is invoked when public fields of the base-level - * class are modified and the runtime system intercepts it. - * This method simply sets the field to the given value. - * - *

Every subclass of this class should redefine this method. - */ - public void trapFieldWrite(String name, Object value) { - Class jc = getClassMetaobject().getJavaClass(); - try { - jc.getField(name).set(getObject(), value); - } - catch (NoSuchFieldException e) { - throw new RuntimeException(e.toString()); - } - catch (IllegalAccessException e) { - throw new RuntimeException(e.toString()); - } - } - - /** - * Is invoked when base-level method invocation is intercepted. - * This method simply executes the intercepted method invocation - * with the original parameters and returns the resulting value. - * - *

Every subclass of this class should redefine this method. - * - *

Note: this method is not invoked if the base-level method - * is invoked by a constructor in the super class. For example, - * - *

    abstract class A {
    -     *   abstract void initialize();
    -     *   A() {
    -     *       initialize();    // not intercepted
    -     *   }
    -     * }
    -     *
    -     * class B extends A {
    -     *   void initialize() { System.out.println("initialize()"); }
    -     *   B() {
    -     *       super();
    -     *       initialize();    // intercepted
    -     *   }
    -     * }
- * - *

if an instance of B is created, - * the invocation of initialize() in B is intercepted only once. - * The first invocation by the constructor in A is not intercepted. - * This is because the link between a base-level object and a - * metaobject is not created until the execution of a - * constructor of the super class finishes. - */ - public Object trapMethodcall(int identifier, Object[] args) - throws Throwable - { - try { - return methods[identifier].invoke(getObject(), args); - } - catch (java.lang.reflect.InvocationTargetException e) { - throw e.getTargetException(); - } - catch (java.lang.IllegalAccessException e) { - throw new CannotInvokeException(e); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Reflection.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Reflection.java deleted file mode 100644 index a61904b99..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Reflection.java +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.reflect; - -import java.util.Iterator; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.CtMethod.ConstParameter; -import com.fr.third.javassist.bytecode.ClassFile; -import com.fr.third.javassist.bytecode.BadBytecode; -import com.fr.third.javassist.bytecode.MethodInfo; - -/** - * The class implementing the behavioral reflection mechanism. - * - *

If a class is reflective, - * then all the method invocations on every - * instance of that class are intercepted by the runtime - * metaobject controlling that instance. The methods inherited from the - * super classes are also intercepted except final methods. To intercept - * a final method in a super class, that super class must be also reflective. - * - *

To do this, the original class file representing a reflective class: - * - *

    - * class Person {
    - *   public int f(int i) { return i + 1; }
    - *   public int value;
    - * }
    - * 
- * - *

is modified so that it represents a class: - * - *

    - * class Person implements Metalevel {
    - *   public int _original_f(int i) { return i + 1; }
    - *   public int f(int i) { delegate to the metaobject }
    - *
    - *   public int value;
    - *   public int _r_value() { read "value" }
    - *   public void _w_value(int v) { write "value" }
    - *
    - *   public ClassMetaobject _getClass() { return a class metaobject }
    - *   public Metaobject _getMetaobject() { return a metaobject }
    - *   public void _setMetaobject(Metaobject m) { change a metaobject }
    - * }
    - * 
- * - * @see ClassMetaobject - * @see Metaobject - * @see Loader - * @see Compiler - */ -public class Reflection implements com.fr.third.javassist.Translator { - - static final String classobjectField = "_classobject"; - static final String classobjectAccessor = "_getClass"; - static final String metaobjectField = "_metaobject"; - static final String metaobjectGetter = "_getMetaobject"; - static final String metaobjectSetter = "_setMetaobject"; - static final String readPrefix = "_r_"; - static final String writePrefix = "_w_"; - - static final String metaobjectClassName = "javassist.tools.reflect.Metaobject"; - static final String classMetaobjectClassName - = "javassist.tools.reflect.ClassMetaobject"; - - protected com.fr.third.javassist.CtMethod trapMethod, trapStaticMethod; - protected com.fr.third.javassist.CtMethod trapRead, trapWrite; - protected com.fr.third.javassist.CtClass[] readParam; - - protected com.fr.third.javassist.ClassPool classPool; - protected com.fr.third.javassist.CodeConverter converter; - - private boolean isExcluded(String name) { - return name.startsWith(ClassMetaobject.methodPrefix) - || name.equals(classobjectAccessor) - || name.equals(metaobjectSetter) - || name.equals(metaobjectGetter) - || name.startsWith(readPrefix) - || name.startsWith(writePrefix); - } - - /** - * Constructs a new Reflection object. - */ - public Reflection() { - classPool = null; - converter = new com.fr.third.javassist.CodeConverter(); - } - - /** - * Initializes the object. - */ - public void start(com.fr.third.javassist.ClassPool pool) throws com.fr.third.javassist.NotFoundException { - classPool = pool; - final String msg - = "javassist.tools.reflect.Sample is not found or broken."; - try { - com.fr.third.javassist.CtClass c = classPool.get("javassist.tools.reflect.Sample"); - rebuildClassFile(c.getClassFile()); - trapMethod = c.getDeclaredMethod("trap"); - trapStaticMethod = c.getDeclaredMethod("trapStatic"); - trapRead = c.getDeclaredMethod("trapRead"); - trapWrite = c.getDeclaredMethod("trapWrite"); - readParam - = new com.fr.third.javassist.CtClass[] { classPool.get("java.lang.Object") }; - } - catch (com.fr.third.javassist.NotFoundException e) { - throw new RuntimeException(msg); - } catch (BadBytecode e) { - throw new RuntimeException(msg); - } - } - - /** - * Inserts hooks for intercepting accesses to the fields declared - * in reflective classes. - */ - public void onLoad(com.fr.third.javassist.ClassPool pool, String classname) - throws com.fr.third.javassist.CannotCompileException, com.fr.third.javassist.NotFoundException - { - com.fr.third.javassist.CtClass clazz = pool.get(classname); - clazz.instrument(converter); - } - - /** - * Produces a reflective class. - * If the super class is also made reflective, it must be done - * before the sub class. - * - * @param classname the name of the reflective class - * @param metaobject the class name of metaobjects. - * @param metaclass the class name of the class metaobject. - * @return false if the class is already reflective. - * - * @see Metaobject - * @see ClassMetaobject - */ - public boolean makeReflective(String classname, - String metaobject, String metaclass) - throws com.fr.third.javassist.CannotCompileException, com.fr.third.javassist.NotFoundException - { - return makeReflective(classPool.get(classname), - classPool.get(metaobject), - classPool.get(metaclass)); - } - - /** - * Produces a reflective class. - * If the super class is also made reflective, it must be done - * before the sub class. - * - * @param clazz the reflective class. - * @param metaobject the class of metaobjects. - * It must be a subclass of - * Metaobject. - * @param metaclass the class of the class metaobject. - * It must be a subclass of - * ClassMetaobject. - * @return false if the class is already reflective. - * - * @see Metaobject - * @see ClassMetaobject - */ - public boolean makeReflective(Class clazz, - Class metaobject, Class metaclass) - throws com.fr.third.javassist.CannotCompileException, com.fr.third.javassist.NotFoundException - { - return makeReflective(clazz.getName(), metaobject.getName(), - metaclass.getName()); - } - - /** - * Produces a reflective class. It modifies the given - * CtClass object and makes it reflective. - * If the super class is also made reflective, it must be done - * before the sub class. - * - * @param clazz the reflective class. - * @param metaobject the class of metaobjects. - * It must be a subclass of - * Metaobject. - * @param metaclass the class of the class metaobject. - * It must be a subclass of - * ClassMetaobject. - * @return false if the class is already reflective. - * - * @see Metaobject - * @see ClassMetaobject - */ - public boolean makeReflective(com.fr.third.javassist.CtClass clazz, - com.fr.third.javassist.CtClass metaobject, com.fr.third.javassist.CtClass metaclass) - throws com.fr.third.javassist.CannotCompileException, CannotReflectException, - com.fr.third.javassist.NotFoundException - { - if (clazz.isInterface()) - throw new CannotReflectException( - "Cannot reflect an interface: " + clazz.getName()); - - if (clazz.subclassOf(classPool.get(classMetaobjectClassName))) - throw new CannotReflectException( - "Cannot reflect a subclass of ClassMetaobject: " - + clazz.getName()); - - if (clazz.subclassOf(classPool.get(metaobjectClassName))) - throw new CannotReflectException( - "Cannot reflect a subclass of Metaobject: " - + clazz.getName()); - - registerReflectiveClass(clazz); - return modifyClassfile(clazz, metaobject, metaclass); - } - - /** - * Registers a reflective class. The field accesses to the instances - * of this class are instrumented. - */ - private void registerReflectiveClass(com.fr.third.javassist.CtClass clazz) { - com.fr.third.javassist.CtField[] fs = clazz.getDeclaredFields(); - for (int i = 0; i < fs.length; ++i) { - com.fr.third.javassist.CtField f = fs[i]; - int mod = f.getModifiers(); - if ((mod & com.fr.third.javassist.Modifier.PUBLIC) != 0 && (mod & com.fr.third.javassist.Modifier.FINAL) == 0) { - String name = f.getName(); - converter.replaceFieldRead(f, clazz, readPrefix + name); - converter.replaceFieldWrite(f, clazz, writePrefix + name); - } - } - } - - private boolean modifyClassfile(com.fr.third.javassist.CtClass clazz, com.fr.third.javassist.CtClass metaobject, - com.fr.third.javassist.CtClass metaclass) - throws com.fr.third.javassist.CannotCompileException, com.fr.third.javassist.NotFoundException - { - if (clazz.getAttribute("Reflective") != null) - return false; // this is already reflective. - else - clazz.setAttribute("Reflective", new byte[0]); - - com.fr.third.javassist.CtClass mlevel = classPool.get("javassist.tools.reflect.Metalevel"); - boolean addMeta = !clazz.subtypeOf(mlevel); - if (addMeta) - clazz.addInterface(mlevel); - - processMethods(clazz, addMeta); - processFields(clazz); - - com.fr.third.javassist.CtField f; - if (addMeta) { - f = new com.fr.third.javassist.CtField(classPool.get("javassist.tools.reflect.Metaobject"), - metaobjectField, clazz); - f.setModifiers(com.fr.third.javassist.Modifier.PROTECTED); - clazz.addField(f, com.fr.third.javassist.CtField.Initializer.byNewWithParams(metaobject)); - - clazz.addMethod(com.fr.third.javassist.CtNewMethod.getter(metaobjectGetter, f)); - clazz.addMethod(com.fr.third.javassist.CtNewMethod.setter(metaobjectSetter, f)); - } - - f = new com.fr.third.javassist.CtField(classPool.get("javassist.tools.reflect.ClassMetaobject"), - classobjectField, clazz); - f.setModifiers(com.fr.third.javassist.Modifier.PRIVATE | com.fr.third.javassist.Modifier.STATIC); - clazz.addField(f, com.fr.third.javassist.CtField.Initializer.byNew(metaclass, - new String[] { clazz.getName() })); - - clazz.addMethod(com.fr.third.javassist.CtNewMethod.getter(classobjectAccessor, f)); - return true; - } - - private void processMethods(com.fr.third.javassist.CtClass clazz, boolean dontSearch) - throws com.fr.third.javassist.CannotCompileException, com.fr.third.javassist.NotFoundException - { - com.fr.third.javassist.CtMethod[] ms = clazz.getMethods(); - for (int i = 0; i < ms.length; ++i) { - com.fr.third.javassist.CtMethod m = ms[i]; - int mod = m.getModifiers(); - if (com.fr.third.javassist.Modifier.isPublic(mod) && !com.fr.third.javassist.Modifier.isAbstract(mod)) - processMethods0(mod, clazz, m, i, dontSearch); - } - } - - private void processMethods0(int mod, com.fr.third.javassist.CtClass clazz, - com.fr.third.javassist.CtMethod m, int identifier, boolean dontSearch) - throws com.fr.third.javassist.CannotCompileException, com.fr.third.javassist.NotFoundException - { - com.fr.third.javassist.CtMethod body; - String name = m.getName(); - - if (isExcluded(name)) // internally-used method inherited - return; // from a reflective class. - - com.fr.third.javassist.CtMethod m2; - if (m.getDeclaringClass() == clazz) { - if (com.fr.third.javassist.Modifier.isNative(mod)) - return; - - m2 = m; - if (com.fr.third.javassist.Modifier.isFinal(mod)) { - mod &= ~com.fr.third.javassist.Modifier.FINAL; - m2.setModifiers(mod); - } - } - else { - if (com.fr.third.javassist.Modifier.isFinal(mod)) - return; - - mod &= ~com.fr.third.javassist.Modifier.NATIVE; - m2 = com.fr.third.javassist.CtNewMethod.delegator(findOriginal(m, dontSearch), clazz); - m2.setModifiers(mod); - clazz.addMethod(m2); - } - - m2.setName(ClassMetaobject.methodPrefix + identifier - + "_" + name); - - if (com.fr.third.javassist.Modifier.isStatic(mod)) - body = trapStaticMethod; - else - body = trapMethod; - - com.fr.third.javassist.CtMethod wmethod - = com.fr.third.javassist.CtNewMethod.wrapped(m.getReturnType(), name, - m.getParameterTypes(), m.getExceptionTypes(), - body, ConstParameter.integer(identifier), - clazz); - wmethod.setModifiers(mod); - clazz.addMethod(wmethod); - } - - private com.fr.third.javassist.CtMethod findOriginal(com.fr.third.javassist.CtMethod m, boolean dontSearch) - throws com.fr.third.javassist.NotFoundException - { - if (dontSearch) - return m; - - String name = m.getName(); - com.fr.third.javassist.CtMethod[] ms = m.getDeclaringClass().getDeclaredMethods(); - for (int i = 0; i < ms.length; ++i) { - String orgName = ms[i].getName(); - if (orgName.endsWith(name) - && orgName.startsWith(ClassMetaobject.methodPrefix) - && ms[i].getSignature().equals(m.getSignature())) - return ms[i]; - } - - return m; - } - - private void processFields(com.fr.third.javassist.CtClass clazz) - throws com.fr.third.javassist.CannotCompileException, com.fr.third.javassist.NotFoundException - { - com.fr.third.javassist.CtField[] fs = clazz.getDeclaredFields(); - for (int i = 0; i < fs.length; ++i) { - com.fr.third.javassist.CtField f = fs[i]; - int mod = f.getModifiers(); - if ((mod & com.fr.third.javassist.Modifier.PUBLIC) != 0 && (mod & com.fr.third.javassist.Modifier.FINAL) == 0) { - mod |= com.fr.third.javassist.Modifier.STATIC; - String name = f.getName(); - com.fr.third.javassist.CtClass ftype = f.getType(); - com.fr.third.javassist.CtMethod wmethod - = com.fr.third.javassist.CtNewMethod.wrapped(ftype, readPrefix + name, - readParam, null, trapRead, - ConstParameter.string(name), - clazz); - wmethod.setModifiers(mod); - clazz.addMethod(wmethod); - com.fr.third.javassist.CtClass[] writeParam = new com.fr.third.javassist.CtClass[2]; - writeParam[0] = classPool.get("java.lang.Object"); - writeParam[1] = ftype; - wmethod = com.fr.third.javassist.CtNewMethod.wrapped(CtClass.voidType, - writePrefix + name, - writeParam, null, trapWrite, - ConstParameter.string(name), clazz); - wmethod.setModifiers(mod); - clazz.addMethod(wmethod); - } - } - } - - public void rebuildClassFile(ClassFile cf) throws BadBytecode { - if (ClassFile.MAJOR_VERSION < ClassFile.JAVA_6) - return; - - Iterator methods = cf.getMethods().iterator(); - while (methods.hasNext()) { - MethodInfo mi = (MethodInfo)methods.next(); - mi.rebuildStackMap(classPool); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Sample.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Sample.java deleted file mode 100644 index a75ccc631..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/Sample.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.reflect; - -/** - * A template used for defining a reflective class. - */ -public class Sample { - private Metaobject _metaobject; - private static ClassMetaobject _classobject; - - public Object trap(Object[] args, int identifier) throws Throwable { - Metaobject mobj; - mobj = _metaobject; - if (mobj == null) - return ClassMetaobject.invoke(this, identifier, args); - else - return mobj.trapMethodcall(identifier, args); - } - - public static Object trapStatic(Object[] args, int identifier) - throws Throwable - { - return _classobject.trapMethodcall(identifier, args); - } - - public static Object trapRead(Object[] args, String name) { - if (args[0] == null) - return _classobject.trapFieldRead(name); - else - return ((Metalevel)args[0])._getMetaobject().trapFieldRead(name); - } - - public static Object trapWrite(Object[] args, String name) { - Metalevel base = (Metalevel)args[0]; - if (base == null) - _classobject.trapFieldWrite(name, args[1]); - else - base._getMetaobject().trapFieldWrite(name, args[1]); - - return null; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/package.html b/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/package.html deleted file mode 100644 index 10a419644..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/reflect/package.html +++ /dev/null @@ -1,35 +0,0 @@ - - -Runtime Behavioral Reflection. - -

(also recently known as interceptors or AOP?) - -

This package enables a metaobject to trap method calls and field -accesses on a regular Java object. It provides a class -Reflection, which is a main module for implementing -runtime behavioral reflection. -It also provides -a class Loader and Compiler -as utilities for dynamically or statically -translating a regular class into a reflective class. - -

An instance of the reflective class is associated with -a runtime metaobject and a runtime class metaobject, which control -the behavior of that instance. -The runtime -metaobject is created for every (base-level) instance but the -runtime class metaobject is created for every (base-level) class. -Metaobject is the root class of the runtime -metaobject and ClassMetaobject is the root class -of the runtime class metaobject. - -

This package is provided as a sample implementation of the -reflection mechanism with Javassist. All the programs in this package -uses only the regular Javassist API; they never call any hidden -methods. - -

The most significant class in this package is Reflection. -See the description of this class first. - - - diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/AppletServer.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/AppletServer.java deleted file mode 100644 index 99403b1dc..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/AppletServer.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.rmi; - -import java.io.*; - -import com.fr.third.javassist.tools.web.BadHttpRequest; -import com.fr.third.javassist.CannotCompileException; -import com.fr.third.javassist.NotFoundException; -import com.fr.third.javassist.ClassPool; -import java.lang.reflect.Method; -import java.util.Hashtable; -import java.util.Vector; - -/** - * An AppletServer object is a web server that an ObjectImporter - * communicates with. It makes the objects specified by - * exportObject() remotely accessible from applets. - * If the classes of the exported objects are requested by the client-side - * JVM, this web server sends proxy classes for the requested classes. - * - * @see ObjectImporter - */ -public class AppletServer extends com.fr.third.javassist.tools.web.Webserver { - private StubGenerator stubGen; - private Hashtable exportedNames; - private Vector exportedObjects; - - private static final byte[] okHeader - = "HTTP/1.0 200 OK\r\n\r\n".getBytes(); - - /** - * Constructs a web server. - * - * @param port port number - */ - public AppletServer(String port) - throws IOException, NotFoundException, CannotCompileException - { - this(Integer.parseInt(port)); - } - - /** - * Constructs a web server. - * - * @param port port number - */ - public AppletServer(int port) - throws IOException, NotFoundException, CannotCompileException - { - this(ClassPool.getDefault(), new StubGenerator(), port); - } - - /** - * Constructs a web server. - * - * @param port port number - * @param src the source of classs files. - */ - public AppletServer(int port, ClassPool src) - throws IOException, NotFoundException, CannotCompileException - { - this(new ClassPool(src), new StubGenerator(), port); - } - - private AppletServer(ClassPool loader, StubGenerator gen, int port) - throws IOException, NotFoundException, CannotCompileException - { - super(port); - exportedNames = new Hashtable(); - exportedObjects = new Vector(); - stubGen = gen; - addTranslator(loader, gen); - } - - /** - * Begins the HTTP service. - */ - public void run() { - super.run(); - } - - /** - * Exports an object. - * This method produces the bytecode of the proxy class used - * to access the exported object. A remote applet can load - * the proxy class and call a method on the exported object. - * - * @param name the name used for looking the object up. - * @param obj the exported object. - * @return the object identifier - * - * @see ObjectImporter#lookupObject(String) - */ - public synchronized int exportObject(String name, Object obj) - throws CannotCompileException - { - Class clazz = obj.getClass(); - ExportedObject eo = new ExportedObject(); - eo.object = obj; - eo.methods = clazz.getMethods(); - exportedObjects.addElement(eo); - eo.identifier = exportedObjects.size() - 1; - if (name != null) - exportedNames.put(name, eo); - - try { - stubGen.makeProxyClass(clazz); - } - catch (NotFoundException e) { - throw new CannotCompileException(e); - } - - return eo.identifier; - } - - /** - * Processes a request from a web browser (an ObjectImporter). - */ - public void doReply(InputStream in, OutputStream out, String cmd) - throws IOException, BadHttpRequest - { - if (cmd.startsWith("POST /rmi ")) - processRMI(in, out); - else if (cmd.startsWith("POST /lookup ")) - lookupName(cmd, in, out); - else - super.doReply(in, out, cmd); - } - - private void processRMI(InputStream ins, OutputStream outs) - throws IOException - { - ObjectInputStream in = new ObjectInputStream(ins); - - int objectId = in.readInt(); - int methodId = in.readInt(); - Exception err = null; - Object rvalue = null; - try { - ExportedObject eo - = (ExportedObject)exportedObjects.elementAt(objectId); - Object[] args = readParameters(in); - rvalue = convertRvalue(eo.methods[methodId].invoke(eo.object, - args)); - } - catch(Exception e) { - err = e; - logging2(e.toString()); - } - - outs.write(okHeader); - ObjectOutputStream out = new ObjectOutputStream(outs); - if (err != null) { - out.writeBoolean(false); - out.writeUTF(err.toString()); - } - else - try { - out.writeBoolean(true); - out.writeObject(rvalue); - } - catch (NotSerializableException e) { - logging2(e.toString()); - } - catch (InvalidClassException e) { - logging2(e.toString()); - } - - out.flush(); - out.close(); - in.close(); - } - - private Object[] readParameters(ObjectInputStream in) - throws IOException, ClassNotFoundException - { - int n = in.readInt(); - Object[] args = new Object[n]; - for (int i = 0; i < n; ++i) { - Object a = in.readObject(); - if (a instanceof com.fr.third.javassist.tools.rmi.RemoteRef) { - com.fr.third.javassist.tools.rmi.RemoteRef ref = (com.fr.third.javassist.tools.rmi.RemoteRef)a; - ExportedObject eo - = (ExportedObject)exportedObjects.elementAt(ref.oid); - a = eo.object; - } - - args[i] = a; - } - - return args; - } - - private Object convertRvalue(Object rvalue) - throws CannotCompileException - { - if (rvalue == null) - return null; // the return type is void. - - String classname = rvalue.getClass().getName(); - if (stubGen.isProxyClass(classname)) - return new RemoteRef(exportObject(null, rvalue), classname); - else - return rvalue; - } - - private void lookupName(String cmd, InputStream ins, OutputStream outs) - throws IOException - { - ObjectInputStream in = new ObjectInputStream(ins); - String name = DataInputStream.readUTF(in); - ExportedObject found = (ExportedObject)exportedNames.get(name); - outs.write(okHeader); - ObjectOutputStream out = new ObjectOutputStream(outs); - if (found == null) { - logging2(name + "not found."); - out.writeInt(-1); // error code - out.writeUTF("error"); - } - else { - logging2(name); - out.writeInt(found.identifier); - out.writeUTF(found.object.getClass().getName()); - } - - out.flush(); - out.close(); - in.close(); - } -} - -class ExportedObject { - public int identifier; - public Object object; - public Method[] methods; -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/ObjectImporter.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/ObjectImporter.java deleted file mode 100644 index 79481461a..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/ObjectImporter.java +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.rmi; - -import com.fr.third.javassist.tools.web.Viewer; - -import java.io.*; -import java.net.*; -import java.applet.Applet; -import java.lang.reflect.*; - -/** - * The object importer enables applets to call a method on a remote - * object running on the Webserver (the main class of this - * package). - * - *

To access the remote - * object, the applet first calls lookupObject() and - * obtains a proxy object, which is a reference to that object. - * The class name of the proxy object is identical to that of - * the remote object. - * The proxy object provides the same set of methods as the remote object. - * If one of the methods is invoked on the proxy object, - * the invocation is delegated to the remote object. - * From the viewpoint of the applet, therefore, the two objects are - * identical. The applet can access the object on the server - * with the regular Java syntax without concern about the actual - * location. - * - *

The methods remotely called by the applet must be public. - * This is true even if the applet's class and the remote object's classs - * belong to the same package. - * - *

If class X is a class of remote objects, a subclass of X must be - * also a class of remote objects. On the other hand, this restriction - * is not applied to the superclass of X. The class X does not have to - * contain a constructor taking no arguments. - * - *

The parameters to a remote method is passed in the call-by-value - * manner. Thus all the parameter classes must implement - * java.io.Serializable. However, if the parameter is the - * proxy object, the reference to the remote object instead of a copy of - * the object is passed to the method. - * - *

Because of the limitations of the current implementation, - *

    - *
  • The parameter objects cannot contain the proxy - * object as a field value. - *
  • If class C is of the remote object, then - * the applet cannot instantiate C locally or remotely. - *
- * - *

All the exceptions thrown by the remote object are converted - * into RemoteException. Since this exception is a subclass - * of RuntimeException, the caller method does not need - * to catch the exception. However, good programs should catch - * the RuntimeException. - * - * @see AppletServer - * @see RemoteException - * @see Viewer - */ -public class ObjectImporter implements java.io.Serializable { - private final byte[] endofline = { 0x0d, 0x0a }; - private String servername, orgServername; - private int port, orgPort; - - protected byte[] lookupCommand = "POST /lookup HTTP/1.0".getBytes(); - protected byte[] rmiCommand = "POST /rmi HTTP/1.0".getBytes(); - - /** - * Constructs an object importer. - * - *

Remote objects are imported from the web server that the given - * applet has been loaded from. - * - * @param applet the applet loaded from the Webserver. - */ - public ObjectImporter(Applet applet) { - URL codebase = applet.getCodeBase(); - orgServername = servername = codebase.getHost(); - orgPort = port = codebase.getPort(); - } - - /** - * Constructs an object importer. - * - *

If you run a program with javassist.tools.web.Viewer, - * you can construct an object importer as follows: - * - *

    -     * Viewer v = (Viewer)this.getClass().getClassLoader();
    -     * ObjectImporter oi = new ObjectImporter(v.getServer(), v.getPort());
    -     * 
- * - * @see Viewer - */ - public ObjectImporter(String servername, int port) { - this.orgServername = this.servername = servername; - this.orgPort = this.port = port; - } - - /** - * Finds the object exported by a server with the specified name. - * If the object is not found, this method returns null. - * - * @param name the name of the exported object. - * @return the proxy object or null. - */ - public Object getObject(String name) { - try { - return lookupObject(name); - } - catch (ObjectNotFoundException e) { - return null; - } - } - - /** - * Sets an http proxy server. After this method is called, the object - * importer connects a server through the http proxy server. - */ - public void setHttpProxy(String host, int port) { - String proxyHeader = "POST http://" + orgServername + ":" + orgPort; - String cmd = proxyHeader + "/lookup HTTP/1.0"; - lookupCommand = cmd.getBytes(); - cmd = proxyHeader + "/rmi HTTP/1.0"; - rmiCommand = cmd.getBytes(); - this.servername = host; - this.port = port; - } - - /** - * Finds the object exported by the server with the specified name. - * It sends a POST request to the server (via an http proxy server - * if needed). - * - * @param name the name of the exported object. - * @return the proxy object. - */ - public Object lookupObject(String name) throws ObjectNotFoundException - { - try { - Socket sock = new Socket(servername, port); - OutputStream out = sock.getOutputStream(); - out.write(lookupCommand); - out.write(endofline); - out.write(endofline); - - ObjectOutputStream dout = new ObjectOutputStream(out); - dout.writeUTF(name); - dout.flush(); - - InputStream in = new BufferedInputStream(sock.getInputStream()); - skipHeader(in); - ObjectInputStream din = new ObjectInputStream(in); - int n = din.readInt(); - String classname = din.readUTF(); - din.close(); - dout.close(); - sock.close(); - - if (n >= 0) - return createProxy(n, classname); - } - catch (Exception e) { - e.printStackTrace(); - throw new ObjectNotFoundException(name, e); - } - - throw new ObjectNotFoundException(name); - } - - private static final Class[] proxyConstructorParamTypes - = new Class[] { ObjectImporter.class, int.class }; - - private Object createProxy(int oid, String classname) throws Exception { - Class c = Class.forName(classname); - Constructor cons = c.getConstructor(proxyConstructorParamTypes); - return cons.newInstance(new Object[] { this, new Integer(oid) }); - } - - /** - * Calls a method on a remote object. - * It sends a POST request to the server (via an http proxy server - * if needed). - * - *

This method is called by only proxy objects. - */ - public Object call(int objectid, int methodid, Object[] args) - throws RemoteException - { - boolean result; - Object rvalue; - String errmsg; - - try { - /* This method establishes a raw tcp connection for sending - * a POST message. Thus the object cannot communicate a - * remote object beyond a fire wall. To avoid this problem, - * the connection should be established with a mechanism - * collaborating a proxy server. Unfortunately, java.lang.URL - * does not seem to provide such a mechanism. - * - * You might think that using HttpURLConnection is a better - * way than constructing a raw tcp connection. Unfortunately, - * URL.openConnection() does not return an HttpURLConnection - * object in Netscape's JVM. It returns a - * netscape.net.URLConnection object. - * - * lookupObject() has the same problem. - */ - Socket sock = new Socket(servername, port); - OutputStream out = new BufferedOutputStream( - sock.getOutputStream()); - out.write(rmiCommand); - out.write(endofline); - out.write(endofline); - - ObjectOutputStream dout = new ObjectOutputStream(out); - dout.writeInt(objectid); - dout.writeInt(methodid); - writeParameters(dout, args); - dout.flush(); - - InputStream ins = new BufferedInputStream(sock.getInputStream()); - skipHeader(ins); - ObjectInputStream din = new ObjectInputStream(ins); - result = din.readBoolean(); - rvalue = null; - errmsg = null; - if (result) - rvalue = din.readObject(); - else - errmsg = din.readUTF(); - - din.close(); - dout.close(); - sock.close(); - - if (rvalue instanceof com.fr.third.javassist.tools.rmi.RemoteRef) { - com.fr.third.javassist.tools.rmi.RemoteRef ref = (com.fr.third.javassist.tools.rmi.RemoteRef)rvalue; - rvalue = createProxy(ref.oid, ref.classname); - } - } - catch (ClassNotFoundException e) { - throw new RemoteException(e); - } - catch (IOException e) { - throw new RemoteException(e); - } - catch (Exception e) { - throw new RemoteException(e); - } - - if (result) - return rvalue; - else - throw new RemoteException(errmsg); - } - - private void skipHeader(InputStream in) throws IOException { - int len; - do { - int c; - len = 0; - while ((c = in.read()) >= 0 && c != 0x0d) - ++len; - - in.read(); /* skip 0x0a (LF) */ - } while (len > 0); - } - - private void writeParameters(ObjectOutputStream dout, Object[] params) - throws IOException - { - int n = params.length; - dout.writeInt(n); - for (int i = 0; i < n; ++i) - if (params[i] instanceof com.fr.third.javassist.tools.rmi.Proxy) { - com.fr.third.javassist.tools.rmi.Proxy p = (Proxy)params[i]; - dout.writeObject(new RemoteRef(p._getObjectId())); - } - else - dout.writeObject(params[i]); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/ObjectNotFoundException.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/ObjectNotFoundException.java deleted file mode 100644 index 35830ce05..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/ObjectNotFoundException.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.rmi; - -public class ObjectNotFoundException extends Exception { - public ObjectNotFoundException(String name) { - super(name + " is not exported"); - } - - public ObjectNotFoundException(String name, Exception e) { - super(name + " because of " + e.toString()); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/Proxy.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/Proxy.java deleted file mode 100644 index baac3472c..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/Proxy.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.rmi; - -/** - * An interface implemented by proxy classes. - * - * @see StubGenerator - */ -public interface Proxy { - int _getObjectId(); -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/RemoteException.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/RemoteException.java deleted file mode 100644 index b7dc9aeae..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/RemoteException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.rmi; - -/** - * RemoteException represents any exception thrown - * during remote method invocation. - */ -public class RemoteException extends RuntimeException { - public RemoteException(String msg) { - super(msg); - } - - public RemoteException(Exception e) { - super("by " + e.toString()); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/RemoteRef.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/RemoteRef.java deleted file mode 100644 index 8ec9c041d..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/RemoteRef.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.rmi; - -/** - * Remote reference. This class is internally used for sending a remote - * reference through a network stream. - */ -public class RemoteRef implements java.io.Serializable { - public int oid; - public String classname; - - public RemoteRef(int i) { - oid = i; - classname = null; - } - - public RemoteRef(int i, String name) { - oid = i; - classname = name; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/Sample.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/Sample.java deleted file mode 100644 index ea1d9d3e8..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/Sample.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.rmi; - -/** - * A template used for defining a proxy class. - * The class file of this class is read by the StubGenerator - * class. - */ -public class Sample { - private ObjectImporter importer; - private int objectId; - - public Object forward(Object[] args, int identifier) { - return importer.call(objectId, identifier, args); - } - - public static Object forwardStatic(Object[] args, int identifier) - throws RemoteException - { - throw new RemoteException("cannot call a static method."); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/StubGenerator.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/StubGenerator.java deleted file mode 100644 index d4d5164b5..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/StubGenerator.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.rmi; - -import com.fr.third.javassist.CtNewConstructor; - -import java.lang.reflect.Method; -import java.util.Hashtable; -import com.fr.third.javassist.CtMethod.ConstParameter; - -/** - * A stub-code generator. It is used for producing a proxy class. - * - *

The proxy class for class A is as follows: - * - *

    public class A implements Proxy, Serializable {
    - *   private ObjectImporter importer;
    - *   private int objectId;
    - *   public int _getObjectId() { return objectId; }
    - *   public A(ObjectImporter oi, int id) {
    - *     importer = oi; objectId = id;
    - *   }
    - *
    - *   ... the same methods that the original class A declares ...
    - * }
- * - *

Instances of the proxy class is created by an - * ObjectImporter object. - */ -public class StubGenerator implements com.fr.third.javassist.Translator { - private static final String fieldImporter = "importer"; - private static final String fieldObjectId = "objectId"; - private static final String accessorObjectId = "_getObjectId"; - private static final String sampleClass = "javassist.tools.rmi.Sample"; - - private com.fr.third.javassist.ClassPool classPool; - private Hashtable proxyClasses; - private com.fr.third.javassist.CtMethod forwardMethod; - private com.fr.third.javassist.CtMethod forwardStaticMethod; - - private com.fr.third.javassist.CtClass[] proxyConstructorParamTypes; - private com.fr.third.javassist.CtClass[] interfacesForProxy; - private com.fr.third.javassist.CtClass[] exceptionForProxy; - - /** - * Constructs a stub-code generator. - */ - public StubGenerator() { - proxyClasses = new Hashtable(); - } - - /** - * Initializes the object. - * This is a method declared in javassist.Translator. - * - * @see com.fr.third.javassist.Translator#start(com.fr.third.javassist.ClassPool) - */ - public void start(com.fr.third.javassist.ClassPool pool) throws com.fr.third.javassist.NotFoundException { - classPool = pool; - com.fr.third.javassist.CtClass c = pool.get(sampleClass); - forwardMethod = c.getDeclaredMethod("forward"); - forwardStaticMethod = c.getDeclaredMethod("forwardStatic"); - - proxyConstructorParamTypes - = pool.get(new String[] { "javassist.tools.rmi.ObjectImporter", - "int" }); - interfacesForProxy - = pool.get(new String[] { "java.io.Serializable", - "javassist.tools.rmi.Proxy" }); - exceptionForProxy - = new com.fr.third.javassist.CtClass[] { pool.get("javassist.tools.rmi.RemoteException") }; - } - - /** - * Does nothing. - * This is a method declared in javassist.Translator. - * @see com.fr.third.javassist.Translator#onLoad(com.fr.third.javassist.ClassPool,String) - */ - public void onLoad(com.fr.third.javassist.ClassPool pool, String classname) {} - - /** - * Returns true if the specified class is a proxy class - * recorded by makeProxyClass(). - * - * @param name a fully-qualified class name - */ - public boolean isProxyClass(String name) { - return proxyClasses.get(name) != null; - } - - /** - * Makes a proxy class. The produced class is substituted - * for the original class. - * - * @param clazz the class referenced - * through the proxy class. - * @return false if the proxy class - * has been already produced. - */ - public synchronized boolean makeProxyClass(Class clazz) - throws com.fr.third.javassist.CannotCompileException, com.fr.third.javassist.NotFoundException - { - String classname = clazz.getName(); - if (proxyClasses.get(classname) != null) - return false; - else { - com.fr.third.javassist.CtClass ctclazz = produceProxyClass(classPool.get(classname), - clazz); - proxyClasses.put(classname, ctclazz); - modifySuperclass(ctclazz); - return true; - } - } - - private com.fr.third.javassist.CtClass produceProxyClass(com.fr.third.javassist.CtClass orgclass, Class orgRtClass) - throws com.fr.third.javassist.CannotCompileException, com.fr.third.javassist.NotFoundException - { - int modify = orgclass.getModifiers(); - if (com.fr.third.javassist.Modifier.isAbstract(modify) || com.fr.third.javassist.Modifier.isNative(modify) - || !com.fr.third.javassist.Modifier.isPublic(modify)) - throw new com.fr.third.javassist.CannotCompileException(orgclass.getName() - + " must be public, non-native, and non-abstract."); - - com.fr.third.javassist.CtClass proxy = classPool.makeClass(orgclass.getName(), - orgclass.getSuperclass()); - - proxy.setInterfaces(interfacesForProxy); - - com.fr.third.javassist.CtField f - = new com.fr.third.javassist.CtField(classPool.get("javassist.tools.rmi.ObjectImporter"), - fieldImporter, proxy); - f.setModifiers(com.fr.third.javassist.Modifier.PRIVATE); - proxy.addField(f, com.fr.third.javassist.CtField.Initializer.byParameter(0)); - - f = new com.fr.third.javassist.CtField(com.fr.third.javassist.CtClass.intType, fieldObjectId, proxy); - f.setModifiers(com.fr.third.javassist.Modifier.PRIVATE); - proxy.addField(f, com.fr.third.javassist.CtField.Initializer.byParameter(1)); - - proxy.addMethod(com.fr.third.javassist.CtNewMethod.getter(accessorObjectId, f)); - - proxy.addConstructor(com.fr.third.javassist.CtNewConstructor.defaultConstructor(proxy)); - com.fr.third.javassist.CtConstructor cons - = com.fr.third.javassist.CtNewConstructor.skeleton(proxyConstructorParamTypes, - null, proxy); - proxy.addConstructor(cons); - - try { - addMethods(proxy, orgRtClass.getMethods()); - return proxy; - } - catch (SecurityException e) { - throw new com.fr.third.javassist.CannotCompileException(e); - } - } - - private com.fr.third.javassist.CtClass toCtClass(Class rtclass) throws com.fr.third.javassist.NotFoundException { - String name; - if (!rtclass.isArray()) - name = rtclass.getName(); - else { - StringBuffer sbuf = new StringBuffer(); - do { - sbuf.append("[]"); - rtclass = rtclass.getComponentType(); - } while(rtclass.isArray()); - sbuf.insert(0, rtclass.getName()); - name = sbuf.toString(); - } - - return classPool.get(name); - } - - private com.fr.third.javassist.CtClass[] toCtClass(Class[] rtclasses) throws com.fr.third.javassist.NotFoundException { - int n = rtclasses.length; - com.fr.third.javassist.CtClass[] ctclasses = new com.fr.third.javassist.CtClass[n]; - for (int i = 0; i < n; ++i) - ctclasses[i] = toCtClass(rtclasses[i]); - - return ctclasses; - } - - /* ms must not be an array of CtMethod. To invoke a method ms[i] - * on a server, a client must send i to the server. - */ - private void addMethods(com.fr.third.javassist.CtClass proxy, Method[] ms) - throws com.fr.third.javassist.CannotCompileException, com.fr.third.javassist.NotFoundException - { - com.fr.third.javassist.CtMethod wmethod; - for (int i = 0; i < ms.length; ++i) { - Method m = ms[i]; - int mod = m.getModifiers(); - if (m.getDeclaringClass() != Object.class - && !com.fr.third.javassist.Modifier.isFinal(mod)) - if (com.fr.third.javassist.Modifier.isPublic(mod)) { - com.fr.third.javassist.CtMethod body; - if (com.fr.third.javassist.Modifier.isStatic(mod)) - body = forwardStaticMethod; - else - body = forwardMethod; - - wmethod - = com.fr.third.javassist.CtNewMethod.wrapped(toCtClass(m.getReturnType()), - m.getName(), - toCtClass(m.getParameterTypes()), - exceptionForProxy, - body, - ConstParameter.integer(i), - proxy); - wmethod.setModifiers(mod); - proxy.addMethod(wmethod); - } - else if (!com.fr.third.javassist.Modifier.isProtected(mod) - && !com.fr.third.javassist.Modifier.isPrivate(mod)) - // if package method - throw new com.fr.third.javassist.CannotCompileException( - "the methods must be public, protected, or private."); - } - } - - /** - * Adds a default constructor to the super classes. - */ - private void modifySuperclass(com.fr.third.javassist.CtClass orgclass) - throws com.fr.third.javassist.CannotCompileException, com.fr.third.javassist.NotFoundException - { - com.fr.third.javassist.CtClass superclazz; - for (;; orgclass = superclazz) { - superclazz = orgclass.getSuperclass(); - if (superclazz == null) - break; - - try { - superclazz.getDeclaredConstructor(null); - break; // the constructor with no arguments is found. - } - catch (com.fr.third.javassist.NotFoundException e) { - } - - superclazz.addConstructor( - CtNewConstructor.defaultConstructor(superclazz)); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/package.html b/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/package.html deleted file mode 100644 index 5432a9487..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/rmi/package.html +++ /dev/null @@ -1,16 +0,0 @@ - - -Sample implementation of remote method invocation. - -

This package enables applets to access remote objects -running on the web server with regular Java syntax. -It is provided as a sample implementation with Javassist. -All the programs in this package uses only the regular -Javassist API; they never call any hidden methods. - -

The most significant class of this package is -ObjectImporter. -See the description of this class first. - - - diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/web/BadHttpRequest.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/web/BadHttpRequest.java deleted file mode 100644 index 2457dc6d7..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/web/BadHttpRequest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.web; - -/** - * Thrown when receiving an invalid HTTP request. - */ -public class BadHttpRequest extends Exception { - private Exception e; - - public BadHttpRequest() { e = null; } - - public BadHttpRequest(Exception _e) { e = _e; } - - public String toString() { - if (e == null) - return super.toString(); - else - return e.toString(); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/web/Viewer.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/web/Viewer.java deleted file mode 100644 index bffe9a842..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/web/Viewer.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.web; - -import java.io.*; -import java.net.*; - -/** - * A sample applet viewer. - * - *

This is a sort of applet viewer that can run any program even if - * the main class is not a subclass of Applet. - * This viewwer first calls main() in the main class. - * - *

To run, you should type: - * - *

    % java javassist.tools.web.Viewer host port Main arg1, ...
- * - *

This command calls Main.main() with arg1,... - * All classes including Main are fetched from - * a server http://host:port. - * Only the class file for Viewer must exist - * on a local file system at the client side; even other - * javassist.* classes are not needed at the client side. - * Viewer uses only Java core API classes. - * - *

Note: since a Viewer object is a class loader, - * a program loaded by this object can call a method in Viewer. - * For example, you can write something like this: - * - *

    - * Viewer v = (Viewer)this.getClass().getClassLoader();
    - * String port = v.getPort();
    - * 
- * - */ -public class Viewer extends ClassLoader { - private String server; - private int port; - - /** - * Starts a program. - */ - public static void main(String[] args) throws Throwable { - if (args.length >= 3) { - Viewer cl = new Viewer(args[0], Integer.parseInt(args[1])); - String[] args2 = new String[args.length - 3]; - System.arraycopy(args, 3, args2, 0, args.length - 3); - cl.run(args[2], args2); - } - else - System.err.println( - "Usage: java javassist.tools.web.Viewer class [args ...]"); - } - - /** - * Constructs a viewer. - * - * @param host server name - * @param p port number - */ - public Viewer(String host, int p) { - server = host; - port = p; - } - - /** - * Returns the server name. - */ - public String getServer() { return server; } - - /** - * Returns the port number. - */ - public int getPort() { return port; } - - /** - * Invokes main() in the class specified by classname. - * - * @param classname executed class - * @param args the arguments passed to main(). - */ - public void run(String classname, String[] args) - throws Throwable - { - Class c = loadClass(classname); - try { - c.getDeclaredMethod("main", new Class[] { String[].class }) - .invoke(null, new Object[] { args }); - } - catch (java.lang.reflect.InvocationTargetException e) { - throw e.getTargetException(); - } - } - - /** - * Requests the class loader to load a class. - */ - protected synchronized Class loadClass(String name, boolean resolve) - throws ClassNotFoundException - { - Class c = findLoadedClass(name); - if (c == null) - c = findClass(name); - - if (c == null) - throw new ClassNotFoundException(name); - - if (resolve) - resolveClass(c); - - return c; - } - - /** - * Finds the specified class. The implementation in this class - * fetches the class from the http server. If the class is - * either java.*, javax.*, or - * Viewer, then it is loaded by the parent class - * loader. - * - *

This method can be overridden by a subclass of - * Viewer. - */ - protected Class findClass(String name) throws ClassNotFoundException { - Class c = null; - if (name.startsWith("java.") || name.startsWith("javax.") - || name.equals("javassist.tools.web.Viewer")) - c = findSystemClass(name); - - if (c == null) - try { - byte[] b = fetchClass(name); - if (b != null) - c = defineClass(name, b, 0, b.length); - } - catch (Exception e) { - } - - return c; - } - - /** - * Fetches the class file of the specified class from the http - * server. - */ - protected byte[] fetchClass(String classname) throws Exception - { - byte[] b; - URL url = new URL("http", server, port, - "/" + classname.replace('.', '/') + ".class"); - URLConnection con = url.openConnection(); - con.connect(); - int size = con.getContentLength(); - InputStream s = con.getInputStream(); - if (size <= 0) - b = readStream(s); - else { - b = new byte[size]; - int len = 0; - do { - int n = s.read(b, len, size - len); - if (n < 0) { - s.close(); - throw new IOException("the stream was closed: " - + classname); - } - len += n; - } while (len < size); - } - - s.close(); - return b; - } - - private byte[] readStream(InputStream fin) throws IOException { - byte[] buf = new byte[4096]; - int size = 0; - int len = 0; - do { - size += len; - if (buf.length - size <= 0) { - byte[] newbuf = new byte[buf.length * 2]; - System.arraycopy(buf, 0, newbuf, 0, size); - buf = newbuf; - } - - len = fin.read(buf, size, buf.length - size); - } while (len >= 0); - - byte[] result = new byte[size]; - System.arraycopy(buf, 0, result, 0, size); - return result; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/web/Webserver.java b/fine-javassist/src/main/java/com/fr/third/javassist/tools/web/Webserver.java deleted file mode 100644 index 75af34208..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/web/Webserver.java +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.tools.web; - -import java.net.*; -import java.io.*; -import java.util.Date; - -import com.fr.third.javassist.CtClass; - -/** - * A web server for running sample programs. - * - *

This enables a Java program to instrument class files loaded by - * web browsers for applets. Since the (standard) security manager - * does not allow an applet to create and use a class loader, - * instrumenting class files must be done by this web server. - * - *

Note: although this class is included in the Javassist API, - * it is provided as a sample implementation of the web server using - * Javassist. Especially, there might be security flaws in this server. - * Please use this with YOUR OWN RISK. - */ -public class Webserver { - private ServerSocket socket; - private com.fr.third.javassist.ClassPool classPool; - protected com.fr.third.javassist.Translator translator; - - private final static byte[] endofline = { 0x0d, 0x0a }; - - private final static int typeHtml = 1; - private final static int typeClass = 2; - private final static int typeGif = 3; - private final static int typeJpeg = 4; - private final static int typeText = 5; - - /** - * If this field is not null, the class files taken from - * ClassPool are written out under the directory - * specified by this field. The directory name must not end - * with a directory separator. - */ - public String debugDir = null; - - /** - * The top directory of html (and .gif, .class, ...) files. - * It must end with the directory separator such as "/". - * (For portability, "/" should be used as the directory separator. - * Javassist automatically translates "/" into a platform-dependent - * character.) - * If this field is null, the top directory is the current one where - * the JVM is running. - * - *

If the given URL indicates a class file and the class file - * is not found under the directory specified by this variable, - * then Class.getResourceAsStream() is called - * for searching the Java class paths. - */ - public String htmlfileBase = null; - - /** - * Starts a web server. - * The port number is specified by the first argument. - */ - public static void main(String[] args) throws IOException { - if (args.length == 1) { - Webserver web = new Webserver(args[0]); - web.run(); - } - else - System.err.println( - "Usage: java javassist.tools.web.Webserver "); - } - - /** - * Constructs a web server. - * - * @param port port number - */ - public Webserver(String port) throws IOException { - this(Integer.parseInt(port)); - } - - /** - * Constructs a web server. - * - * @param port port number - */ - public Webserver(int port) throws IOException { - socket = new ServerSocket(port); - classPool = null; - translator = null; - } - - /** - * Requests the web server to use the specified - * ClassPool object for obtaining a class file. - */ - public void setClassPool(com.fr.third.javassist.ClassPool loader) { - classPool = loader; - } - - /** - * Adds a translator, which is called whenever a client requests - * a class file. - * - * @param cp the ClassPool object for obtaining - * a class file. - * @param t a translator. - */ - public void addTranslator(com.fr.third.javassist.ClassPool cp, com.fr.third.javassist.Translator t) - throws com.fr.third.javassist.NotFoundException, com.fr.third.javassist.CannotCompileException - { - classPool = cp; - translator = t; - t.start(classPool); - } - - /** - * Closes the socket. - */ - public void end() throws IOException { - socket.close(); - } - - /** - * Prints a log message. - */ - public void logging(String msg) { - System.out.println(msg); - } - - /** - * Prints a log message. - */ - public void logging(String msg1, String msg2) { - System.out.print(msg1); - System.out.print(" "); - System.out.println(msg2); - } - - /** - * Prints a log message. - */ - public void logging(String msg1, String msg2, String msg3) { - System.out.print(msg1); - System.out.print(" "); - System.out.print(msg2); - System.out.print(" "); - System.out.println(msg3); - } - - /** - * Prints a log message with indentation. - */ - public void logging2(String msg) { - System.out.print(" "); - System.out.println(msg); - } - - /** - * Begins the HTTP service. - */ - public void run() { - System.err.println("ready to service..."); - for (;;) - try { - ServiceThread th = new ServiceThread(this, socket.accept()); - th.start(); - } - catch (IOException e) { - logging(e.toString()); - } - } - - final void process(Socket clnt) throws IOException { - InputStream in = new BufferedInputStream(clnt.getInputStream()); - String cmd = readLine(in); - logging(clnt.getInetAddress().getHostName(), - new Date().toString(), cmd); - while (skipLine(in) > 0){ - } - - OutputStream out = new BufferedOutputStream(clnt.getOutputStream()); - try { - doReply(in, out, cmd); - } - catch (BadHttpRequest e) { - replyError(out, e); - } - - out.flush(); - in.close(); - out.close(); - clnt.close(); - } - - private String readLine(InputStream in) throws IOException { - StringBuffer buf = new StringBuffer(); - int c; - while ((c = in.read()) >= 0 && c != 0x0d) - buf.append((char)c); - - in.read(); /* skip 0x0a (LF) */ - return buf.toString(); - } - - private int skipLine(InputStream in) throws IOException { - int c; - int len = 0; - while ((c = in.read()) >= 0 && c != 0x0d) - ++len; - - in.read(); /* skip 0x0a (LF) */ - return len; - } - - /** - * Proceses a HTTP request from a client. - * - * @param out the output stream to a client - * @param cmd the command received from a client - */ - public void doReply(InputStream in, OutputStream out, String cmd) - throws IOException, BadHttpRequest - { - int len; - int fileType; - String filename, urlName; - - if (cmd.startsWith("GET /")) - filename = urlName = cmd.substring(5, cmd.indexOf(' ', 5)); - else - throw new BadHttpRequest(); - - if (filename.endsWith(".class")) - fileType = typeClass; - else if (filename.endsWith(".html") || filename.endsWith(".htm")) - fileType = typeHtml; - else if (filename.endsWith(".gif")) - fileType = typeGif; - else if (filename.endsWith(".jpg")) - fileType = typeJpeg; - else - fileType = typeText; // or textUnknown - - len = filename.length(); - if (fileType == typeClass - && letUsersSendClassfile(out, filename, len)) - return; - - checkFilename(filename, len); - if (htmlfileBase != null) - filename = htmlfileBase + filename; - - if (File.separatorChar != '/') - filename = filename.replace('/', File.separatorChar); - - File file = new File(filename); - if (file.canRead()) { - sendHeader(out, file.length(), fileType); - FileInputStream fin = new FileInputStream(file); - byte[] filebuffer = new byte[4096]; - for (;;) { - len = fin.read(filebuffer); - if (len <= 0) - break; - else - out.write(filebuffer, 0, len); - } - - fin.close(); - return; - } - - // If the file is not found under the html-file directory, - // then Class.getResourceAsStream() is tried. - - if (fileType == typeClass) { - InputStream fin - = getClass().getResourceAsStream("/" + urlName); - if (fin != null) { - ByteArrayOutputStream barray = new ByteArrayOutputStream(); - byte[] filebuffer = new byte[4096]; - for (;;) { - len = fin.read(filebuffer); - if (len <= 0) - break; - else - barray.write(filebuffer, 0, len); - } - - byte[] classfile = barray.toByteArray(); - sendHeader(out, classfile.length, typeClass); - out.write(classfile); - fin.close(); - return; - } - } - - throw new BadHttpRequest(); - } - - private void checkFilename(String filename, int len) - throws BadHttpRequest - { - for (int i = 0; i < len; ++i) { - char c = filename.charAt(i); - if (!Character.isJavaIdentifierPart(c) && c != '.' && c != '/') - throw new BadHttpRequest(); - } - - if (filename.indexOf("src") >= 0) - throw new BadHttpRequest(); - } - - private boolean letUsersSendClassfile(OutputStream out, - String filename, int length) - throws IOException, BadHttpRequest - { - if (classPool == null) - return false; - - byte[] classfile; - String classname - = filename.substring(0, length - 6).replace('/', '.'); - try { - if (translator != null) - translator.onLoad(classPool, classname); - - CtClass c = classPool.get(classname); - classfile = c.toBytecode(); - if (debugDir != null) - c.writeFile(debugDir); - } - catch (Exception e) { - throw new BadHttpRequest(e); - } - - sendHeader(out, classfile.length, typeClass); - out.write(classfile); - return true; - } - - private void sendHeader(OutputStream out, long dataLength, int filetype) - throws IOException - { - out.write("HTTP/1.0 200 OK".getBytes()); - out.write(endofline); - out.write("Content-Length: ".getBytes()); - out.write(Long.toString(dataLength).getBytes()); - out.write(endofline); - if (filetype == typeClass) - out.write("Content-Type: application/octet-stream".getBytes()); - else if (filetype == typeHtml) - out.write("Content-Type: text/html".getBytes()); - else if (filetype == typeGif) - out.write("Content-Type: image/gif".getBytes()); - else if (filetype == typeJpeg) - out.write("Content-Type: image/jpg".getBytes()); - else if (filetype == typeText) - out.write("Content-Type: text/plain".getBytes()); - - out.write(endofline); - out.write(endofline); - } - - private void replyError(OutputStream out, BadHttpRequest e) - throws IOException - { - logging2("bad request: " + e.toString()); - out.write("HTTP/1.0 400 Bad Request".getBytes()); - out.write(endofline); - out.write(endofline); - out.write("

Bad Request

".getBytes()); - } -} - -class ServiceThread extends Thread { - Webserver web; - Socket sock; - - public ServiceThread(Webserver w, Socket s) { - web = w; - sock = s; - } - - public void run() { - try { - web.process(sock); - } - catch (IOException e) { - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/tools/web/package.html b/fine-javassist/src/main/java/com/fr/third/javassist/tools/web/package.html deleted file mode 100644 index 0c7fb4535..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/tools/web/package.html +++ /dev/null @@ -1,7 +0,0 @@ - - -Simple web server for running sample code. - -

Note: The new definition of the reloaded class must declare - * the same set of methods and fields as the original definition. The - * schema change between the original and new definitions is not allowed - * by the JPDA. - * - *

To use this class, the JVM must be launched with the following - * command line options: - * - *

    - *

    For Java 1.4,
    - *

    java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000
    - *

    For Java 5,
    - *

    java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
    - *
- * - *

Note that 8000 is the port number used by HotSwapper. - * Any port number can be specified. Since HotSwapper does not - * launch another JVM for running a target application, this port number - * is used only for inter-thread communication. - * - *

Furthermore, JAVA_HOME/lib/tools.jar must be included - * in the class path. - * - *

Using HotSwapper is easy. See the following example: - * - *

    - * CtClass clazz = ...
    - * byte[] classFile = clazz.toBytecode();
    - * HotSwapper hs = new HostSwapper(8000);  // 8000 is a port number.
    - * hs.reload("Test", classFile);
    - * 
- * - *

reload() - * first unload the Test class and load a new version of - * the Test class. - * classFile is a byte array containing the new contents of - * the class file for the Test class. The developers can - * repatedly call reload() on the same HotSwapper - * object so that they can reload a number of classes. - * - * @since 3.1 - */ -public class HotSwapper { - private VirtualMachine jvm; - private MethodEntryRequest request; - private Map newClassFiles; - - private Trigger trigger; - - private static final String HOST_NAME = "localhost"; - private static final String TRIGGER_NAME = Trigger.class.getName(); - - /** - * Connects to the JVM. - * - * @param port the port number used for the connection to the JVM. - */ - public HotSwapper(int port) - throws IOException, IllegalConnectorArgumentsException - { - this(Integer.toString(port)); - } - - /** - * Connects to the JVM. - * - * @param port the port number used for the connection to the JVM. - */ - public HotSwapper(String port) - throws IOException, IllegalConnectorArgumentsException - { - jvm = null; - request = null; - newClassFiles = null; - trigger = new Trigger(); - AttachingConnector connector - = (AttachingConnector)findConnector("com.sun.jdi.SocketAttach"); - - Map arguments = connector.defaultArguments(); - ((Connector.Argument)arguments.get("hostname")).setValue(HOST_NAME); - ((Connector.Argument)arguments.get("port")).setValue(port); - jvm = connector.attach(arguments); - EventRequestManager manager = jvm.eventRequestManager(); - request = methodEntryRequests(manager, TRIGGER_NAME); - } - - private Connector findConnector(String connector) throws IOException { - List connectors = Bootstrap.virtualMachineManager().allConnectors(); - Iterator iter = connectors.iterator(); - while (iter.hasNext()) { - Connector con = (Connector)iter.next(); - if (con.name().equals(connector)) { - return con; - } - } - - throw new IOException("Not found: " + connector); - } - - private static MethodEntryRequest methodEntryRequests( - EventRequestManager manager, - String classpattern) { - MethodEntryRequest mereq = manager.createMethodEntryRequest(); - mereq.addClassFilter(classpattern); - mereq.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); - return mereq; - } - - /* Stops triggering a hotswapper when reload() is called. - */ - private void deleteEventRequest(EventRequestManager manager, - MethodEntryRequest request) { - manager.deleteEventRequest(request); - } - - /** - * Reloads a class. - * - * @param className the fully-qualified class name. - * @param classFile the contents of the class file. - */ - public void reload(String className, byte[] classFile) { - ReferenceType classtype = toRefType(className); - Map map = new HashMap(); - map.put(classtype, classFile); - reload2(map, className); - } - - /** - * Reloads a class. - * - * @param classFiles a map between fully-qualified class names - * and class files. The type of the class names - * is String and the type of the - * class files is byte[]. - */ - public void reload(Map classFiles) { - Set set = classFiles.entrySet(); - Iterator it = set.iterator(); - Map map = new HashMap(); - String className = null; - while (it.hasNext()) { - Map.Entry e = (Map.Entry)it.next(); - className = (String)e.getKey(); - map.put(toRefType(className), e.getValue()); - } - - if (className != null) - reload2(map, className + " etc."); - } - - private ReferenceType toRefType(String className) { - List list = jvm.classesByName(className); - if (list == null || list.isEmpty()) - throw new RuntimeException("no such class: " + className); - else - return (ReferenceType)list.get(0); - } - - private void reload2(Map map, String msg) { - synchronized (trigger) { - startDaemon(); - newClassFiles = map; - request.enable(); - trigger.doSwap(); - request.disable(); - Map ncf = newClassFiles; - if (ncf != null) { - newClassFiles = null; - throw new RuntimeException("failed to reload: " + msg); - } - } - } - - private void startDaemon() { - new Thread() { - private void errorMsg(Throwable e) { - System.err.print("Exception in thread \"HotSwap\" "); - e.printStackTrace(System.err); - } - - public void run() { - EventSet events = null; - try { - events = waitEvent(); - EventIterator iter = events.eventIterator(); - while (iter.hasNext()) { - Event event = iter.nextEvent(); - if (event instanceof MethodEntryEvent) { - hotswap(); - break; - } - } - } - catch (Throwable e) { - errorMsg(e); - } - try { - if (events != null) - events.resume(); - } - catch (Throwable e) { - errorMsg(e); - } - } - }.start(); - } - - EventSet waitEvent() throws InterruptedException { - EventQueue queue = jvm.eventQueue(); - return queue.remove(); - } - - void hotswap() { - Map map = newClassFiles; - jvm.redefineClasses(map); - newClassFiles = null; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/util/package.html b/fine-javassist/src/main/java/com/fr/third/javassist/util/package.html deleted file mode 100644 index 349d99620..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/util/package.html +++ /dev/null @@ -1,5 +0,0 @@ - - -Utility classes. - - diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/FactoryHelper.java b/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/FactoryHelper.java deleted file mode 100644 index b75bbec57..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/FactoryHelper.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.util.proxy; - -import java.lang.reflect.Method; -import java.io.BufferedOutputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.security.ProtectionDomain; - -import com.fr.third.javassist.CannotCompileException; -import com.fr.third.javassist.bytecode.ClassFile; - -/** - * A helper class for implementing ProxyFactory. - * The users of ProxyFactory do not have to see this class. - * - * @see ProxyFactory - */ -public class FactoryHelper { - private static java.lang.reflect.Method defineClass1, defineClass2; - - static { - try { - Class cl = Class.forName("java.lang.ClassLoader"); - defineClass1 = SecurityActions.getDeclaredMethod( - cl, - "defineClass", - new Class[] { String.class, byte[].class, - int.class, int.class }); - - defineClass2 = SecurityActions.getDeclaredMethod( - cl, - "defineClass", - new Class[] { String.class, byte[].class, - int.class, int.class, ProtectionDomain.class }); - } - catch (Exception e) { - throw new RuntimeException("cannot initialize"); - } - } - - /** - * Returns an index for accessing arrays in this class. - * - * @throws RuntimeException if a given type is not a primitive type. - */ - public static final int typeIndex(Class type) { - Class[] list = primitiveTypes; - int n = list.length; - for (int i = 0; i < n; i++) - if (list[i] == type) - return i; - - throw new RuntimeException("bad type:" + type.getName()); - } - - /** - * Class objects representing primitive types. - */ - public static final Class[] primitiveTypes = { - Boolean.TYPE, Byte.TYPE, Character.TYPE, Short.TYPE, Integer.TYPE, - Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE - }; - - /** - * The fully-qualified names of wrapper classes for primitive types. - */ - public static final String[] wrapperTypes = { - "java.lang.Boolean", "java.lang.Byte", "java.lang.Character", - "java.lang.Short", "java.lang.Integer", "java.lang.Long", - "java.lang.Float", "java.lang.Double", "java.lang.Void" - }; - - /** - * The descriptors of the constructors of wrapper classes. - */ - public static final String[] wrapperDesc = { - "(Z)V", "(B)V", "(C)V", "(S)V", "(I)V", "(J)V", - "(F)V", "(D)V" - }; - - /** - * The names of methods for obtaining a primitive value - * from a wrapper object. For example, intValue() - * is such a method for obtaining an integer value from a - * java.lang.Integer object. - */ - public static final String[] unwarpMethods = { - "booleanValue", "byteValue", "charValue", "shortValue", - "intValue", "longValue", "floatValue", "doubleValue" - }; - - /** - * The descriptors of the unwrapping methods contained - * in unwrapMethods. - */ - public static final String[] unwrapDesc = { - "()Z", "()B", "()C", "()S", "()I", "()J", "()F", "()D" - }; - - /** - * The data size of primitive types. long - * and double are 2; the others are 1. - */ - public static final int[] dataSize = { - 1, 1, 1, 1, 1, 2, 1, 2 - }; - - /** - * Loads a class file by a given class loader. - * This method uses a default protection domain for the class - * but it may not work with a security manager or a sigend jar file. - * - * @see #toClass(ClassFile,ClassLoader,ProtectionDomain) - */ - public static Class toClass(ClassFile cf, ClassLoader loader) - throws CannotCompileException - { - return toClass(cf, loader, null); - } - - /** - * Loads a class file by a given class loader. - * - * @param domain if it is null, a default domain is used. - * @since 3.3 - */ - public static Class toClass(ClassFile cf, ClassLoader loader, ProtectionDomain domain) - throws CannotCompileException - { - try { - byte[] b = toBytecode(cf); - Method method; - Object[] args; - if (domain == null) { - method = defineClass1; - args = new Object[] { cf.getName(), b, new Integer(0), - new Integer(b.length) }; - } - else { - method = defineClass2; - args = new Object[] { cf.getName(), b, new Integer(0), - new Integer(b.length), domain }; - } - - return toClass2(method, loader, args); - } - catch (RuntimeException e) { - throw e; - } - catch (java.lang.reflect.InvocationTargetException e) { - throw new CannotCompileException(e.getTargetException()); - } - catch (Exception e) { - throw new CannotCompileException(e); - } - } - - private static synchronized Class toClass2(Method method, - ClassLoader loader, Object[] args) - throws Exception - { - SecurityActions.setAccessible(method, true); - Class clazz = (Class)method.invoke(loader, args); - SecurityActions.setAccessible(method, false); - return clazz; - } - - private static byte[] toBytecode(ClassFile cf) throws IOException { - ByteArrayOutputStream barray = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(barray); - try { - cf.write(out); - } - finally { - out.close(); - } - - return barray.toByteArray(); - } - - /** - * Writes a class file. - */ - public static void writeFile(ClassFile cf, String directoryName) - throws CannotCompileException { - try { - writeFile0(cf, directoryName); - } - catch (IOException e) { - throw new CannotCompileException(e); - } - } - - private static void writeFile0(ClassFile cf, String directoryName) - throws CannotCompileException, IOException { - String classname = cf.getName(); - String filename = directoryName + File.separatorChar - + classname.replace('.', File.separatorChar) + ".class"; - int pos = filename.lastIndexOf(File.separatorChar); - if (pos > 0) { - String dir = filename.substring(0, pos); - if (!dir.equals(".")) - new File(dir).mkdirs(); - } - - DataOutputStream out = new DataOutputStream(new BufferedOutputStream( - new FileOutputStream(filename))); - try { - cf.write(out); - } - catch (IOException e) { - throw e; - } - finally { - out.close(); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/MethodFilter.java b/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/MethodFilter.java deleted file mode 100644 index 67055ee3f..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/MethodFilter.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.util.proxy; - -import java.lang.reflect.Method; - -/** - * Selector of the methods implemented by a handler. - * - * @see ProxyFactory#setFilter(MethodFilter) - */ -public interface MethodFilter { - /** - * Returns true if the given method is implemented by a handler. - */ - boolean isHandled(Method m); -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/MethodHandler.java b/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/MethodHandler.java deleted file mode 100644 index 6b52e7083..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/MethodHandler.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.util.proxy; - -import java.lang.reflect.Method; - -/** - * The interface implemented by the invocation handler of a proxy - * instance. - * - * @see Proxy#setHandler(MethodHandler) - */ -public interface MethodHandler { - /** - * Is called when a method is invoked on a proxy instance associated - * with this handler. This method must process that method invocation. - * - * @param self the proxy instance. - * @param thisMethod the overridden method declared in the super - * class or interface. - * @param proceed the forwarder method for invoking the overridden - * method. It is null if the overridden method is - * abstract or declared in the interface. - * @param args an array of objects containing the values of - * the arguments passed in the method invocation - * on the proxy instance. If a parameter type is - * a primitive type, the type of the array element - * is a wrapper class. - * @return the resulting value of the method invocation. - * - * @throws Throwable if the method invocation fails. - */ - Object invoke(Object self, Method thisMethod, Method proceed, - Object[] args) throws Throwable; -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/Proxy.java b/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/Proxy.java deleted file mode 100644 index ec6519817..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/Proxy.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.util.proxy; - -/** - * The interface implemented by proxy classes. - * This interface only provides a setter method. - * To obtain a handler, call {@link ProxyFactory#getHandler(Proxy)}. - * - * @see ProxyFactory - * @since 3.16 - */ -public interface Proxy { - /** - * Sets a handler. It can be used for changing handlers - * during runtime. - */ - void setHandler(MethodHandler mi); -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/ProxyFactory.java b/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/ProxyFactory.java deleted file mode 100644 index e5ee06071..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/ProxyFactory.java +++ /dev/null @@ -1,1445 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.util.proxy; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Constructor; -import java.lang.reflect.Member; -import java.lang.reflect.Modifier; -import java.security.ProtectionDomain; -import java.util.*; -import java.lang.ref.WeakReference; - -import com.fr.third.javassist.CannotCompileException; -import com.fr.third.javassist.bytecode.CodeAttribute; - -/* - * This class is implemented only with the lower-level API of Javassist. - * This design decision is for maximizing performance. - */ - -/** - * Factory of dynamic proxy classes. - * - *

This factory generates a class that extends the given super class and implements - * the given interfaces. The calls of the methods inherited from the super class are - * forwarded and then invoke() is called on the method handler - * associated with instances of the generated class. The calls of the methods from - * the interfaces are also forwarded to the method handler. - * - *

For example, if the following code is executed, - * - *

    - * ProxyFactory f = new ProxyFactory();
    - * f.setSuperclass(Foo.class);
    - * f.setFilter(new MethodFilter() {
    - *     public boolean isHandled(Method m) {
    - *         // ignore finalize()
    - *         return !m.getName().equals("finalize");
    - *     }
    - * });
    - * Class c = f.createClass();
    - * MethodHandler mi = new MethodHandler() {
    - *     public Object invoke(Object self, Method m, Method proceed,
    - *                          Object[] args) throws Throwable {
    - *         System.out.println("Name: " + m.getName());
    - *         return proceed.invoke(self, args);  // execute the original method.
    - *     }
    - * };
    - * Foo foo = (Foo)c.newInstance();
    - * ((Proxy)foo).setHandler(mi);
    - * 
- * - *

Here, Method is java.lang.reflect.Method.

- * - *

Then, the following method call will be forwarded to MethodHandler - * mi and prints a message before executing the originally called method - * bar() in Foo. - * - *

    - * foo.bar();
    - * 
- * - *

The last three lines of the code shown above can be replaced with a call to - * the helper method create, which generates a proxy class, instantiates - * it, and sets the method handler of the instance: - * - *

    - *     :
    - * Foo foo = (Foo)f.create(new Class[0], new Object[0], mi);
    - * 
- * - *

To change the method handler during runtime, - * execute the following code: - * - *

    - * MethodHandler mi = ... ;    // alternative handler
    - * ((Proxy)foo).setHandler(mi);
    - * 
- * - *

If setHandler is never called for a proxy instance then it will - * employ the default handler which proceeds by invoking the original method. - * The behaviour of the default handler is identical to the following - * handler: - * - *

    - * class EmptyHandler implements MethodHandler {
    - *     public Object invoke(Object self, Method m,
    - *                          Method proceed, Object[] args) throws Exception {
    - *         return proceed.invoke(self, args);
    - *     }
    - * }
    - * 
- * - *

A proxy factory caches and reuses proxy classes by default. It is possible to reset - * this default globally by setting static field {@link ProxyFactory#useCache} to false. - * Caching may also be configured for a specific factory by calling instance method - * {@link ProxyFactory#setUseCache(boolean)}. It is strongly recommended that new clients - * of class ProxyFactory enable caching. Failure to do so may lead to exhaustion of - * the heap memory area used to store classes. - * - *

Caching is automatically disabled for any given proxy factory if deprecated instance - * method {@link ProxyFactory#setHandler(MethodHandler)} is called. This method was - * used to specify a default handler which newly created proxy classes should install - * when they create their instances. It is only retained to provide backward compatibility - * with previous releases of javassist. Unfortunately,this legacy behaviour makes caching - * and reuse of proxy classes impossible. The current programming model expects javassist - * clients to set the handler of a proxy instance explicitly by calling method - * {@link com.fr.third.javassist.util.proxy.Proxy#setHandler(MethodHandler)} as shown in the sample code above. New - * clients are strongly recommended to use this model rather than calling - * {@link ProxyFactory#setHandler(MethodHandler)}. - * - *

A proxy object generated by ProxyFactory is serializable - * if its super class or any of its interfaces implement java.io.Serializable. - * However, a serialized proxy object may not be compatible with future releases. - * The serialization support should be used for short-term storage or RMI. - * - *

For compatibility with older releases serialization of proxy objects is implemented by - * adding a writeReplace method to the proxy class. This allows a proxy to be serialized - * to a conventional {@link java.io.ObjectOutputStream} and deserialized from a corresponding - * {@link java.io.ObjectInputStream}. However this method suffers from several problems, the most - * notable one being that it fails to serialize state inherited from the proxy's superclass. - *

- * An alternative method of serializing proxy objects is available which fixes these problems. It - * requires inhibiting generation of the writeReplace method and instead using instances of - * {@link ProxyObjectOutputStream} and {@link ProxyObjectInputStream} - * (which are subclasses of {@link java.io.ObjectOutputStream} and {@link java.io.ObjectInputStream}) - * to serialize and deserialize, respectively, the proxy. These streams recognise javassist proxies and ensure - * that they are serialized and deserialized without the need for the proxy class to implement special methods - * such as writeReplace. Generation of the writeReplace method can be disabled globally by setting static field - * {@link ProxyFactory#useWriteReplace} to false. Alternatively, it may be - * configured per factory by calling instance method {@link ProxyFactory#setUseWriteReplace(boolean)}. - * - * @see MethodHandler - * @since 3.1 - * @author Muga Nishizawa - * @author Shigeru Chiba - * @author Andrew Dinn - */ -public class ProxyFactory { - private Class superClass; - private Class[] interfaces; - private com.fr.third.javassist.util.proxy.MethodFilter methodFilter; - private MethodHandler handler; // retained for legacy usage - private List signatureMethods; - private boolean hasGetHandler; - private byte[] signature; - private String classname; - private String basename; - private String superName; - private Class thisClass; - /** - * per factory setting initialised from current setting for useCache but able to be reset before each create call - */ - private boolean factoryUseCache; - /** - * per factory setting initialised from current setting for useWriteReplace but able to be reset before each create call - */ - private boolean factoryWriteReplace; - - - /** - * If the value of this variable is not null, the class file of - * the generated proxy class is written under the directory specified - * by this variable. For example, if the value is - * ".", then the class file is written under the current - * directory. This method is for debugging. - * - *

The default value is null. - */ - public String writeDirectory; - - private static final Class OBJECT_TYPE = Object.class; - - private static final String HOLDER = "_methods_"; - private static final String HOLDER_TYPE = "[Ljava/lang/reflect/Method;"; - private static final String FILTER_SIGNATURE_FIELD = "_filter_signature"; - private static final String FILTER_SIGNATURE_TYPE = "[B"; - private static final String HANDLER = "handler"; - private static final String NULL_INTERCEPTOR_HOLDER = "javassist.util.proxy.RuntimeSupport"; - private static final String DEFAULT_INTERCEPTOR = "default_interceptor"; - private static final String HANDLER_TYPE - = 'L' + MethodHandler.class.getName().replace('.', '/') + ';'; - private static final String HANDLER_SETTER = "setHandler"; - private static final String HANDLER_SETTER_TYPE = "(" + HANDLER_TYPE + ")V"; - - private static final String HANDLER_GETTER = "getHandler"; - private static final String HANDLER_GETTER_TYPE = "()" + HANDLER_TYPE; - - private static final String SERIAL_VERSION_UID_FIELD = "serialVersionUID"; - private static final String SERIAL_VERSION_UID_TYPE = "J"; - private static final long SERIAL_VERSION_UID_VALUE = -1L; - - /** - * If true, a generated proxy class is cached and it will be reused - * when generating the proxy class with the same properties is requested. - * The default value is true. - * - * Note that this value merely specifies the initial setting employed by any newly created - * proxy factory. The factory setting may be overwritten by calling factory instance method - * {@link #setUseCache(boolean)} - * - * @since 3.4 - */ - public static volatile boolean useCache = true; - - /** - * If true, a generated proxy class will implement method writeReplace enabling - * serialization of its proxies to a conventional ObjectOutputStream. this (default) - * setting retains the old javassist behaviour which has the advantage that it - * retains compatibility with older releases and requires no extra work on the part - * of the client performing the serialization. However, it has the disadvantage that - * state inherited from the superclasses of the proxy is lost during serialization. - * if false then serialization/deserialization of the proxy instances will preserve - * all fields. However, serialization must be performed via a {@link ProxyObjectOutputStream} - * and deserialization must be via {@link ProxyObjectInputStream}. Any attempt to serialize - * proxies whose class was created with useWriteReplace set to false via a normal - * {@link java.io.ObjectOutputStream} will fail. - * - * Note that this value merely specifies the initial setting employed by any newly created - * proxy factory. The factory setting may be overwritten by calling factory instance method - * {@link #setUseWriteReplace(boolean)} - * - * @since 3.4 - */ - public static volatile boolean useWriteReplace = true; - - /* - * methods allowing individual factory settings for factoryUseCache and factoryWriteReplace to be reset - */ - - /** - * test whether this factory uses the proxy cache - * @return true if this factory uses the proxy cache otherwise false - */ - public boolean isUseCache() - { - return factoryUseCache; - } - - /** - * configure whether this factory should use the proxy cache - * @param useCache true if this factory should use the proxy cache and false if it should not use the cache - * @throws RuntimeException if a default interceptor has been set for the factory - */ - public void setUseCache(boolean useCache) - { - // we cannot allow caching to be used if the factory is configured to install a default interceptor - // field into generated classes - if (handler != null && useCache) { - throw new RuntimeException("caching cannot be enabled if the factory default interceptor has been set"); - } - factoryUseCache = useCache; - } - - /** - * test whether this factory installs a writeReplace method in created classes - * @return true if this factory installs a writeReplace method in created classes otherwise false - */ - public boolean isUseWriteReplace() - { - return factoryWriteReplace; - } - - /** - * configure whether this factory should add a writeReplace method to created classes - * @param useWriteReplace true if this factory should add a writeReplace method to created classes and false if it - * should not add a writeReplace method - */ - public void setUseWriteReplace(boolean useWriteReplace) - { - factoryWriteReplace = useWriteReplace; - } - - private static WeakHashMap proxyCache = new WeakHashMap(); - - /** - * determine if a class is a javassist proxy class - * @param cl - * @return true if the class is a javassist proxy class otherwise false - */ - public static boolean isProxyClass(Class cl) - { - // all proxies implement Proxy or ProxyObject. nothing else should. - return (com.fr.third.javassist.util.proxy.Proxy.class.isAssignableFrom(cl)); - } - - /** - * used to store details of a specific proxy class in the second tier of the proxy cache. this entry - * will be located in a hashmap keyed by the unique identifying name of the proxy class. the hashmap is - * located in a weak hashmap keyed by the classloader common to all proxy classes in the second tier map. - */ - static class ProxyDetails { - /** - * the unique signature of any method filter whose behaviour will be met by this class. each bit in - * the byte array is set if the filter redirects the corresponding super or interface method and clear - * if it does not redirect it. - */ - byte[] signature; - /** - * a hexadecimal string representation of the signature bit sequence. this string also forms part - * of the proxy class name. - */ - WeakReference proxyClass; - /** - * a flag which is true this class employs writeReplace to perform serialization of its instances - * and false if serialization must employ of a ProxyObjectOutputStream and ProxyObjectInputStream - */ - boolean isUseWriteReplace; - - ProxyDetails(byte[] signature, Class proxyClass, boolean isUseWriteReplace) - { - this.signature = signature; - this.proxyClass = new WeakReference(proxyClass); - this.isUseWriteReplace = isUseWriteReplace; - } - } - - /** - * Constructs a factory of proxy class. - */ - public ProxyFactory() { - superClass = null; - interfaces = null; - methodFilter = null; - handler = null; - signature = null; - signatureMethods = null; - hasGetHandler = false; - thisClass = null; - writeDirectory = null; - factoryUseCache = useCache; - factoryWriteReplace = useWriteReplace; - } - - /** - * Sets the super class of a proxy class. - */ - public void setSuperclass(Class clazz) { - superClass = clazz; - // force recompute of signature - signature = null; - } - - /** - * Obtains the super class set by setSuperclass(). - * - * @since 3.4 - */ - public Class getSuperclass() { return superClass; } - - /** - * Sets the interfaces of a proxy class. - */ - public void setInterfaces(Class[] ifs) { - interfaces = ifs; - // force recompute of signature - signature = null; - } - - /** - * Obtains the interfaces set by setInterfaces. - * - * @since 3.4 - */ - public Class[] getInterfaces() { return interfaces; } - - /** - * Sets a filter that selects the methods that will be controlled by a handler. - */ - public void setFilter(com.fr.third.javassist.util.proxy.MethodFilter mf) { - methodFilter = mf; - // force recompute of signature - signature = null; - } - - /** - * Generates a proxy class using the current filter. - */ - public Class createClass() { - if (signature == null) { - computeSignature(methodFilter); - } - return createClass1(); - } - - /** - * Generates a proxy class using the supplied filter. - */ - public Class createClass(com.fr.third.javassist.util.proxy.MethodFilter filter) { - computeSignature(filter); - return createClass1(); - } - - /** - * Generates a proxy class with a specific signature. - * access is package local so ProxyObjectInputStream can use this - * @param signature - * @return - */ - Class createClass(byte[] signature) - { - installSignature(signature); - return createClass1(); - } - - private Class createClass1() { - if (thisClass == null) { - ClassLoader cl = getClassLoader(); - synchronized (proxyCache) { - if (factoryUseCache) - createClass2(cl); - else - createClass3(cl); - } - } - - // don't retain any unwanted references - Class result = thisClass; - thisClass = null; - - return result; - } - - private static char[] hexDigits = - { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - - public String getKey(Class superClass, Class[] interfaces, byte[] signature, boolean useWriteReplace) - { - StringBuffer sbuf = new StringBuffer(); - if (superClass != null){ - sbuf.append(superClass.getName()); - } - sbuf.append(":"); - for (int i = 0; i < interfaces.length; i++) { - sbuf.append(interfaces[i].getName()); - sbuf.append(":"); - } - for (int i = 0; i < signature.length; i++) { - byte b = signature[i]; - int lo = b & 0xf; - int hi = (b >> 4) & 0xf; - sbuf.append(hexDigits[lo]); - sbuf.append(hexDigits[hi]); - } - if (useWriteReplace) { - sbuf.append(":w"); - } - - return sbuf.toString(); - } - - private void createClass2(ClassLoader cl) { - String key = getKey(superClass, interfaces, signature, factoryWriteReplace); - /* - * Excessive concurrency causes a large memory footprint and slows the - * execution speed down (with JDK 1.5). Thus, we use a jumbo lock for - * reducing concrrency. - */ - // synchronized (proxyCache) { - HashMap cacheForTheLoader = (HashMap)proxyCache.get(cl); - ProxyDetails details; - if (cacheForTheLoader == null) { - cacheForTheLoader = new HashMap(); - proxyCache.put(cl, cacheForTheLoader); - } - details = (ProxyDetails)cacheForTheLoader.get(key); - if (details != null) { - WeakReference reference = details.proxyClass; - thisClass = (Class)reference.get(); - if (thisClass != null) { - return; - } - } - createClass3(cl); - details = new ProxyDetails(signature, thisClass, factoryWriteReplace); - cacheForTheLoader.put(key, details); - // } - } - - private void createClass3(ClassLoader cl) { - // we need a new class so we need a new class name - allocateClassName(); - - try { - com.fr.third.javassist.bytecode.ClassFile cf = make(); - if (writeDirectory != null) - FactoryHelper.writeFile(cf, writeDirectory); - - thisClass = FactoryHelper.toClass(cf, cl, getDomain()); - setField(FILTER_SIGNATURE_FIELD, signature); - // legacy behaviour : we only set the default interceptor static field if we are not using the cache - if (!factoryUseCache) { - setField(DEFAULT_INTERCEPTOR, handler); - } - } - catch (CannotCompileException e) { - throw new RuntimeException(e.getMessage(), e); - } - - } - - private void setField(String fieldName, Object value) { - if (thisClass != null && value != null) - try { - Field f = thisClass.getField(fieldName); - SecurityActions.setAccessible(f, true); - f.set(null, value); - SecurityActions.setAccessible(f, false); - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - - static byte[] getFilterSignature(Class clazz) { - return (byte[])getField(clazz, FILTER_SIGNATURE_FIELD); - } - - private static Object getField(Class clazz, String fieldName) { - try { - Field f = clazz.getField(fieldName); - f.setAccessible(true); - Object value = f.get(null); - f.setAccessible(false); - return value; - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * Obtains the method handler of the given proxy object. - * - * @param p a proxy object. - * @return the method handler. - * @since 3.16 - */ - public static MethodHandler getHandler(com.fr.third.javassist.util.proxy.Proxy p) { - try { - Field f = p.getClass().getDeclaredField(HANDLER); - f.setAccessible(true); - Object value = f.get(p); - f.setAccessible(false); - return (MethodHandler)value; - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * A provider of class loaders. - * - * @see #classLoaderProvider - * @since 3.4 - */ - public static interface ClassLoaderProvider { - /** - * Returns a class loader. - * - * @param pf a proxy factory that is going to obtain a class loader. - */ - public ClassLoader get(ProxyFactory pf); - } - - /** - * A provider used by createClass() for obtaining - * a class loader. - * get() on this ClassLoaderProvider object - * is called to obtain a class loader. - * - *

The value of this field can be updated for changing the default - * implementation. - * - *

Example: - *

    -     * ProxyFactory.classLoaderProvider = new ProxyFactory.ClassLoaderProvider() {
    -     *     public ClassLoader get(ProxyFactory pf) {
    -     *         return Thread.currentThread().getContextClassLoader();
    -     *     }
    -     * };
    -     * 
- * - * @since 3.4 - */ - public static ClassLoaderProvider classLoaderProvider - = new ClassLoaderProvider() { - public ClassLoader get(ProxyFactory pf) { - return pf.getClassLoader0(); - } - }; - - protected ClassLoader getClassLoader() { - return classLoaderProvider.get(this); - } - - protected ClassLoader getClassLoader0() { - ClassLoader loader = null; - if (superClass != null && !superClass.getName().equals("java.lang.Object")) - loader = superClass.getClassLoader(); - else if (interfaces != null && interfaces.length > 0) - loader = interfaces[0].getClassLoader(); - - if (loader == null) { - loader = getClass().getClassLoader(); - // In case javassist is in the endorsed dir - if (loader == null) { - loader = Thread.currentThread().getContextClassLoader(); - if (loader == null) - loader = ClassLoader.getSystemClassLoader(); - } - } - - return loader; - } - - protected ProtectionDomain getDomain() { - Class clazz; - if (superClass != null && !superClass.getName().equals("java.lang.Object")) - clazz = superClass; - else if (interfaces != null && interfaces.length > 0) - clazz = interfaces[0]; - else - clazz = this.getClass(); - - return clazz.getProtectionDomain(); - } - - /** - * Creates a proxy class and returns an instance of that class. - * - * @param paramTypes parameter types for a constructor. - * @param args arguments passed to a constructor. - * @param mh the method handler for the proxy class. - * @since 3.4 - */ - public Object create(Class[] paramTypes, Object[] args, MethodHandler mh) - throws NoSuchMethodException, IllegalArgumentException, - InstantiationException, IllegalAccessException, InvocationTargetException - { - Object obj = create(paramTypes, args); - ((com.fr.third.javassist.util.proxy.Proxy)obj).setHandler(mh); - return obj; - } - - /** - * Creates a proxy class and returns an instance of that class. - * - * @param paramTypes parameter types for a constructor. - * @param args arguments passed to a constructor. - */ - public Object create(Class[] paramTypes, Object[] args) - throws NoSuchMethodException, IllegalArgumentException, - InstantiationException, IllegalAccessException, InvocationTargetException - { - Class c = createClass(); - Constructor cons = c.getConstructor(paramTypes); - return cons.newInstance(args); - } - - /** - * Sets the default invocation handler. This invocation handler is shared - * among all the instances of a proxy class unless another is explicitly - * specified. - * @deprecated since 3.12 - * use of this method is incompatible with proxy class caching. - * instead clients should call method {@link com.fr.third.javassist.util.proxy.Proxy#setHandler(MethodHandler)} to set the handler - * for each newly created proxy instance. - * calling this method will automatically disable caching of classes created by the proxy factory. - */ - public void setHandler(MethodHandler mi) { - // if we were using the cache and the handler is non-null then we must stop caching - if (factoryUseCache && mi != null) { - factoryUseCache = false; - // clear any currently held class so we don't try to reuse it or set its handler field - thisClass = null; - } - handler = mi; - // this retains the behaviour of the old code which resets any class we were holding on to - // this is probably not what is wanted - setField(DEFAULT_INTERCEPTOR, handler); - } - - /** - * A unique class name generator. - */ - public static interface UniqueName { - /** - * Returns a unique class name. - * - * @param classname the super class name of the proxy class. - */ - String get(String classname); - } - - /** - * A unique class name generator. - * Replacing this generator changes the algorithm to generate a - * unique name. The get method does not have to be - * a synchronized method since the access to this field - * is mutually exclusive and thus thread safe. - */ - public static UniqueName nameGenerator = new UniqueName() { - private final String sep = "_$$_jvst" + Integer.toHexString(this.hashCode() & 0xfff) + "_"; - private int counter = 0; - - public String get(String classname) { - return classname + sep + Integer.toHexString(counter++); - } - }; - - private static String makeProxyName(String classname) { - synchronized (nameGenerator) { - return nameGenerator.get(classname); - } - } - - private com.fr.third.javassist.bytecode.ClassFile make() throws CannotCompileException { - com.fr.third.javassist.bytecode.ClassFile cf = new com.fr.third.javassist.bytecode.ClassFile(false, classname, superName); - cf.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.PUBLIC); - setInterfaces(cf, interfaces, hasGetHandler ? Proxy.class : ProxyObject.class); - com.fr.third.javassist.bytecode.ConstPool pool = cf.getConstPool(); - - // legacy: we only add the static field for the default interceptor if caching is disabled - if (!factoryUseCache) { - com.fr.third.javassist.bytecode.FieldInfo finfo = new com.fr.third.javassist.bytecode.FieldInfo(pool, DEFAULT_INTERCEPTOR, HANDLER_TYPE); - finfo.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.PUBLIC | com.fr.third.javassist.bytecode.AccessFlag.STATIC); - cf.addField(finfo); - } - - // handler is per instance - com.fr.third.javassist.bytecode.FieldInfo finfo2 = new com.fr.third.javassist.bytecode.FieldInfo(pool, HANDLER, HANDLER_TYPE); - finfo2.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.PRIVATE); - cf.addField(finfo2); - - // filter signature is per class - com.fr.third.javassist.bytecode.FieldInfo finfo3 = new com.fr.third.javassist.bytecode.FieldInfo(pool, FILTER_SIGNATURE_FIELD, FILTER_SIGNATURE_TYPE); - finfo3.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.PUBLIC | com.fr.third.javassist.bytecode.AccessFlag.STATIC); - cf.addField(finfo3); - - // the proxy class serial uid must always be a fixed value - com.fr.third.javassist.bytecode.FieldInfo finfo4 = new com.fr.third.javassist.bytecode.FieldInfo(pool, SERIAL_VERSION_UID_FIELD, SERIAL_VERSION_UID_TYPE); - finfo4.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.PUBLIC | com.fr.third.javassist.bytecode.AccessFlag.STATIC| com.fr.third.javassist.bytecode.AccessFlag.FINAL); - cf.addField(finfo4); - - // HashMap allMethods = getMethods(superClass, interfaces); - // int size = allMethods.size(); - makeConstructors(classname, cf, pool, classname); - - ArrayList forwarders = new ArrayList(); - int s = overrideMethods(cf, pool, classname, forwarders); - addClassInitializer(cf, pool, classname, s, forwarders); - addSetter(classname, cf, pool); - if (!hasGetHandler) - addGetter(classname, cf, pool); - - if (factoryWriteReplace) { - try { - cf.addMethod(makeWriteReplace(pool)); - } - catch (com.fr.third.javassist.bytecode.DuplicateMemberException e) { - // writeReplace() is already declared in the super class/interfaces. - } - } - - thisClass = null; - return cf; - } - - private void checkClassAndSuperName() { - if (interfaces == null) - interfaces = new Class[0]; - - if (superClass == null) { - superClass = OBJECT_TYPE; - superName = superClass.getName(); - basename = interfaces.length == 0 ? superName - : interfaces[0].getName(); - } else { - superName = superClass.getName(); - basename = superName; - } - - if (Modifier.isFinal(superClass.getModifiers())) - throw new RuntimeException(superName + " is final"); - - if (basename.startsWith("java.")) - basename = "org.javassist.tmp." + basename; - } - - private void allocateClassName() { - classname = makeProxyName(basename); - } - - private static Comparator sorter = new Comparator() { - - public int compare(Object o1, Object o2) { - Map.Entry e1 = (Map.Entry)o1; - Map.Entry e2 = (Map.Entry)o2; - String key1 = (String)e1.getKey(); - String key2 = (String)e2.getKey(); - return key1.compareTo(key2); - } - }; - - private void makeSortedMethodList() { - checkClassAndSuperName(); - - hasGetHandler = false; // getMethods() may set this to true. - HashMap allMethods = getMethods(superClass, interfaces); - signatureMethods = new ArrayList(allMethods.entrySet()); - Collections.sort(signatureMethods, sorter); - } - - private void computeSignature(MethodFilter filter) // throws CannotCompileException - { - makeSortedMethodList(); - - int l = signatureMethods.size(); - int maxBytes = ((l + 7) >> 3); - signature = new byte[maxBytes]; - for (int idx = 0; idx < l; idx++) - { - Map.Entry e = (Map.Entry)signatureMethods.get(idx); - Method m = (Method)e.getValue(); - int mod = m.getModifiers(); - if (!Modifier.isFinal(mod) && !Modifier.isStatic(mod) - && isVisible(mod, basename, m) && (filter == null || filter.isHandled(m))) { - setBit(signature, idx); - } - } - } - - private void installSignature(byte[] signature) // throws CannotCompileException - { - makeSortedMethodList(); - - int l = signatureMethods.size(); - int maxBytes = ((l + 7) >> 3); - if (signature.length != maxBytes) { - throw new RuntimeException("invalid filter signature length for deserialized proxy class"); - } - - this.signature = signature; - } - - private boolean testBit(byte[] signature, int idx) { - int byteIdx = idx >> 3; - if (byteIdx > signature.length) { - return false; - } else { - int bitIdx = idx & 0x7; - int mask = 0x1 << bitIdx; - int sigByte = signature[byteIdx]; - return ((sigByte & mask) != 0); - } - } - - private void setBit(byte[] signature, int idx) { - int byteIdx = idx >> 3; - if (byteIdx < signature.length) { - int bitIdx = idx & 0x7; - int mask = 0x1 << bitIdx; - int sigByte = signature[byteIdx]; - signature[byteIdx] = (byte)(sigByte | mask); - } - } - - private static void setInterfaces(com.fr.third.javassist.bytecode.ClassFile cf, Class[] interfaces, Class proxyClass) { - String setterIntf = proxyClass.getName(); - String[] list; - if (interfaces == null || interfaces.length == 0) - list = new String[] { setterIntf }; - else { - list = new String[interfaces.length + 1]; - for (int i = 0; i < interfaces.length; i++) - list[i] = interfaces[i].getName(); - - list[interfaces.length] = setterIntf; - } - - cf.setInterfaces(list); - } - - private static void addClassInitializer(com.fr.third.javassist.bytecode.ClassFile cf, com.fr.third.javassist.bytecode.ConstPool cp, - String classname, int size, ArrayList forwarders) - throws CannotCompileException - { - com.fr.third.javassist.bytecode.FieldInfo finfo = new com.fr.third.javassist.bytecode.FieldInfo(cp, HOLDER, HOLDER_TYPE); - finfo.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.PRIVATE | com.fr.third.javassist.bytecode.AccessFlag.STATIC); - cf.addField(finfo); - com.fr.third.javassist.bytecode.MethodInfo minfo = new com.fr.third.javassist.bytecode.MethodInfo(cp, "", "()V"); - minfo.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.STATIC); - setThrows(minfo, cp, new Class[] { ClassNotFoundException.class }); - - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(cp, 0, 2); - code.addIconst(size * 2); - code.addAnewarray("java.lang.reflect.Method"); - final int varArray = 0; - code.addAstore(varArray); - - // forName() must be called here. Otherwise, the class might be - // invisible. - code.addLdc(classname); - code.addInvokestatic("java.lang.Class", - "forName", "(Ljava/lang/String;)Ljava/lang/Class;"); - final int varClass = 1; - code.addAstore(varClass); - - Iterator it = forwarders.iterator(); - while (it.hasNext()) { - Find2MethodsArgs args = (Find2MethodsArgs)it.next(); - callFind2Methods(code, args.methodName, args.delegatorName, - args.origIndex, args.descriptor, varClass, varArray); - } - - code.addAload(varArray); - code.addPutstatic(classname, HOLDER, HOLDER_TYPE); - - code.addLconst(SERIAL_VERSION_UID_VALUE); - code.addPutstatic(classname, SERIAL_VERSION_UID_FIELD, SERIAL_VERSION_UID_TYPE); - code.addOpcode(com.fr.third.javassist.bytecode.Bytecode.RETURN); - minfo.setCodeAttribute(code.toCodeAttribute()); - cf.addMethod(minfo); - } - - /** - * @param thisMethod might be null. - */ - private static void callFind2Methods(com.fr.third.javassist.bytecode.Bytecode code, String superMethod, String thisMethod, - int index, String desc, int classVar, int arrayVar) { - String findClass = RuntimeSupport.class.getName(); - String findDesc - = "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V"; - - code.addAload(classVar); - code.addLdc(superMethod); - if (thisMethod == null) - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.ACONST_NULL); - else - code.addLdc(thisMethod); - - code.addIconst(index); - code.addLdc(desc); - code.addAload(arrayVar); - code.addInvokestatic(findClass, "find2Methods", findDesc); - } - - private static void addSetter(String classname, com.fr.third.javassist.bytecode.ClassFile cf, com.fr.third.javassist.bytecode.ConstPool cp) - throws CannotCompileException - { - com.fr.third.javassist.bytecode.MethodInfo minfo = new com.fr.third.javassist.bytecode.MethodInfo(cp, HANDLER_SETTER, - HANDLER_SETTER_TYPE); - minfo.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.PUBLIC); - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(cp, 2, 2); - code.addAload(0); - code.addAload(1); - code.addPutfield(classname, HANDLER, HANDLER_TYPE); - code.addOpcode(com.fr.third.javassist.bytecode.Bytecode.RETURN); - minfo.setCodeAttribute(code.toCodeAttribute()); - cf.addMethod(minfo); - } - - private static void addGetter(String classname, com.fr.third.javassist.bytecode.ClassFile cf, com.fr.third.javassist.bytecode.ConstPool cp) - throws CannotCompileException - { - com.fr.third.javassist.bytecode.MethodInfo minfo = new com.fr.third.javassist.bytecode.MethodInfo(cp, HANDLER_GETTER, - HANDLER_GETTER_TYPE); - minfo.setAccessFlags(com.fr.third.javassist.bytecode.AccessFlag.PUBLIC); - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(cp, 1, 1); - code.addAload(0); - code.addGetfield(classname, HANDLER, HANDLER_TYPE); - code.addOpcode(com.fr.third.javassist.bytecode.Bytecode.ARETURN); - minfo.setCodeAttribute(code.toCodeAttribute()); - cf.addMethod(minfo); - } - - private int overrideMethods(com.fr.third.javassist.bytecode.ClassFile cf, com.fr.third.javassist.bytecode.ConstPool cp, String className, ArrayList forwarders) - throws CannotCompileException - { - String prefix = makeUniqueName("_d", signatureMethods); - Iterator it = signatureMethods.iterator(); - int index = 0; - while (it.hasNext()) { - Map.Entry e = (Map.Entry)it.next(); - String key = (String)e.getKey(); - Method meth = (Method)e.getValue(); - if (com.fr.third.javassist.bytecode.ClassFile.MAJOR_VERSION < com.fr.third.javassist.bytecode.ClassFile.JAVA_5 || !isBridge(meth)) - if (testBit(signature, index)) { - override(className, meth, prefix, index, - keyToDesc(key, meth), cf, cp, forwarders); - } - - index++; - } - - return index; - } - - private static boolean isBridge(Method m) { - return m.isBridge(); - } - - private void override(String thisClassname, Method meth, String prefix, - int index, String desc, com.fr.third.javassist.bytecode.ClassFile cf, com.fr.third.javassist.bytecode.ConstPool cp, ArrayList forwarders) - throws CannotCompileException - { - Class declClass = meth.getDeclaringClass(); - String delegatorName = prefix + index + meth.getName(); - if (Modifier.isAbstract(meth.getModifiers())) - delegatorName = null; - else { - com.fr.third.javassist.bytecode.MethodInfo delegator - = makeDelegator(meth, desc, cp, declClass, delegatorName); - // delegator is not a bridge method. See Sec. 15.12.4.5 of JLS 3rd Ed. - delegator.setAccessFlags(delegator.getAccessFlags() & ~com.fr.third.javassist.bytecode.AccessFlag.BRIDGE); - cf.addMethod(delegator); - } - - com.fr.third.javassist.bytecode.MethodInfo forwarder - = makeForwarder(thisClassname, meth, desc, cp, declClass, - delegatorName, index, forwarders); - cf.addMethod(forwarder); - } - - private void makeConstructors(String thisClassName, com.fr.third.javassist.bytecode.ClassFile cf, - com.fr.third.javassist.bytecode.ConstPool cp, String classname) throws CannotCompileException - { - Constructor[] cons = SecurityActions.getDeclaredConstructors(superClass); - // legacy: if we are not caching then we need to initialise the default handler - boolean doHandlerInit = !factoryUseCache; - for (int i = 0; i < cons.length; i++) { - Constructor c = cons[i]; - int mod = c.getModifiers(); - if (!Modifier.isFinal(mod) && !Modifier.isPrivate(mod) - && isVisible(mod, basename, c)) { - com.fr.third.javassist.bytecode.MethodInfo m = makeConstructor(thisClassName, c, cp, superClass, doHandlerInit); - cf.addMethod(m); - } - } - } - - private static String makeUniqueName(String name, List sortedMethods) { - if (makeUniqueName0(name, sortedMethods.iterator())) - return name; - - for (int i = 100; i < 999; i++) { - String s = name + i; - if (makeUniqueName0(s, sortedMethods.iterator())) - return s; - } - - throw new RuntimeException("cannot make a unique method name"); - } - - private static boolean makeUniqueName0(String name, Iterator it) { - while (it.hasNext()) { - Map.Entry e = (Map.Entry)it.next(); - String key = (String)e.getKey(); - if (key.startsWith(name)) - return false; - } - - return true; - } - - /** - * Returns true if the method is visible from the package. - * - * @param mod the modifiers of the method. - */ - private static boolean isVisible(int mod, String from, Member meth) { - if ((mod & Modifier.PRIVATE) != 0) - return false; - else if ((mod & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0) - return true; - else { - String p = getPackageName(from); - String q = getPackageName(meth.getDeclaringClass().getName()); - if (p == null) - return q == null; - else - return p.equals(q); - } - } - - private static String getPackageName(String name) { - int i = name.lastIndexOf('.'); - if (i < 0) - return null; - else - return name.substring(0, i); - } - - /* getMethods() may set hasGetHandler to true. - */ - private HashMap getMethods(Class superClass, Class[] interfaceTypes) { - HashMap hash = new HashMap(); - HashSet set = new HashSet(); - for (int i = 0; i < interfaceTypes.length; i++) - getMethods(hash, interfaceTypes[i], set); - - getMethods(hash, superClass, set); - return hash; - } - - private void getMethods(HashMap hash, Class clazz, Set visitedClasses) { - // This both speeds up scanning by avoiding duplicate interfaces and is needed to - // ensure that superinterfaces are always scanned before subinterfaces. - if (!visitedClasses.add(clazz)) - return; - - Class[] ifs = clazz.getInterfaces(); - for (int i = 0; i < ifs.length; i++) - getMethods(hash, ifs[i], visitedClasses); - - Class parent = clazz.getSuperclass(); - if (parent != null) - getMethods(hash, parent, visitedClasses); - - /* Java 5 or later allows covariant return types. - * It also allows contra-variant parameter types - * if a super class is a generics with concrete type arguments - * such as Foo. So the method-overriding rule is complex. - */ - Method[] methods = SecurityActions.getDeclaredMethods(clazz); - for (int i = 0; i < methods.length; i++) - if (!Modifier.isPrivate(methods[i].getModifiers())) { - Method m = methods[i]; - String key = m.getName() + ':' + RuntimeSupport.makeDescriptor(m); // see keyToDesc(). - if (key.startsWith(HANDLER_GETTER_KEY)) - hasGetHandler = true; - - // JIRA JASSIST-85 - // put the method to the cache, retrieve previous definition (if any) - Method oldMethod = (Method)hash.put(key, methods[i]); - - // check if visibility has been reduced - if (null != oldMethod && Modifier.isPublic(oldMethod.getModifiers()) - && !Modifier.isPublic(methods[i].getModifiers()) ) { - // we tried to overwrite a public definition with a non-public definition, - // use the old definition instead. - hash.put(key, oldMethod); - } - } - } - - private static final String HANDLER_GETTER_KEY - = HANDLER_GETTER + ":()"; - - private static String keyToDesc(String key, Method m) { - return key.substring(key.indexOf(':') + 1); - } - - private static com.fr.third.javassist.bytecode.MethodInfo makeConstructor(String thisClassName, Constructor cons, - com.fr.third.javassist.bytecode.ConstPool cp, Class superClass, boolean doHandlerInit) { - String desc = RuntimeSupport.makeDescriptor(cons.getParameterTypes(), - Void.TYPE); - com.fr.third.javassist.bytecode.MethodInfo minfo = new com.fr.third.javassist.bytecode.MethodInfo(cp, "", desc); - minfo.setAccessFlags(Modifier.PUBLIC); // cons.getModifiers() & ~Modifier.NATIVE - setThrows(minfo, cp, cons.getExceptionTypes()); - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(cp, 0, 0); - - // legacy: if we are not using caching then we initialise the instance's handler - // from the class's static default interceptor and skip the next few instructions if - // it is non-null - if (doHandlerInit) { - code.addAload(0); - code.addGetstatic(thisClassName, DEFAULT_INTERCEPTOR, HANDLER_TYPE); - code.addPutfield(thisClassName, HANDLER, HANDLER_TYPE); - code.addGetstatic(thisClassName, DEFAULT_INTERCEPTOR, HANDLER_TYPE); - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.IFNONNULL); - code.addIndex(10); - } - // if caching is enabled then we don't have a handler to initialise so this else branch will install - // the handler located in the static field of class RuntimeSupport. - code.addAload(0); - code.addGetstatic(NULL_INTERCEPTOR_HOLDER, DEFAULT_INTERCEPTOR, HANDLER_TYPE); - code.addPutfield(thisClassName, HANDLER, HANDLER_TYPE); - int pc = code.currentPc(); - - code.addAload(0); - int s = addLoadParameters(code, cons.getParameterTypes(), 1); - code.addInvokespecial(superClass.getName(), "", desc); - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.RETURN); - code.setMaxLocals(s + 1); - com.fr.third.javassist.bytecode.CodeAttribute ca = code.toCodeAttribute(); - minfo.setCodeAttribute(ca); - - com.fr.third.javassist.bytecode.StackMapTable.Writer writer = new com.fr.third.javassist.bytecode.StackMapTable.Writer(32); - writer.sameFrame(pc); - ca.setAttribute(writer.toStackMapTable(cp)); - return minfo; - } - - private static com.fr.third.javassist.bytecode.MethodInfo makeDelegator(Method meth, String desc, - com.fr.third.javassist.bytecode.ConstPool cp, Class declClass, String delegatorName) { - com.fr.third.javassist.bytecode.MethodInfo delegator = new com.fr.third.javassist.bytecode.MethodInfo(cp, delegatorName, desc); - delegator.setAccessFlags(Modifier.FINAL | Modifier.PUBLIC - | (meth.getModifiers() & ~(Modifier.PRIVATE - | Modifier.PROTECTED - | Modifier.ABSTRACT - | Modifier.NATIVE - | Modifier.SYNCHRONIZED))); - setThrows(delegator, cp, meth); - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(cp, 0, 0); - code.addAload(0); - int s = addLoadParameters(code, meth.getParameterTypes(), 1); - code.addInvokespecial(declClass.getName(), meth.getName(), desc); - addReturn(code, meth.getReturnType()); - code.setMaxLocals(++s); - delegator.setCodeAttribute(code.toCodeAttribute()); - return delegator; - } - - /** - * @param delegatorName null if the original method is abstract. - */ - private static com.fr.third.javassist.bytecode.MethodInfo makeForwarder(String thisClassName, - Method meth, String desc, com.fr.third.javassist.bytecode.ConstPool cp, - Class declClass, String delegatorName, int index, - ArrayList forwarders) { - com.fr.third.javassist.bytecode.MethodInfo forwarder = new com.fr.third.javassist.bytecode.MethodInfo(cp, meth.getName(), desc); - forwarder.setAccessFlags(Modifier.FINAL - | (meth.getModifiers() & ~(Modifier.ABSTRACT - | Modifier.NATIVE - | Modifier.SYNCHRONIZED))); - setThrows(forwarder, cp, meth); - int args = com.fr.third.javassist.bytecode.Descriptor.paramSize(desc); - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(cp, 0, args + 2); - /* - * static { - * methods[index * 2] - * = RuntimeSupport.findSuperMethod(this, , ); - * methods[index * 2 + 1] - * = RuntimeSupport.findMethod(this, , ); - * or = null // the original method is abstract. - * } - * : - * return ($r)handler.invoke(this, methods[index * 2], - * methods[index * 2 + 1], $args); - */ - int origIndex = index * 2; - int delIndex = index * 2 + 1; - int arrayVar = args + 1; - code.addGetstatic(thisClassName, HOLDER, HOLDER_TYPE); - code.addAstore(arrayVar); - - forwarders.add(new Find2MethodsArgs(meth.getName(), delegatorName, desc, origIndex)); - - code.addAload(0); - code.addGetfield(thisClassName, HANDLER, HANDLER_TYPE); - code.addAload(0); - - code.addAload(arrayVar); - code.addIconst(origIndex); - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.AALOAD); - - code.addAload(arrayVar); - code.addIconst(delIndex); - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.AALOAD); - - makeParameterList(code, meth.getParameterTypes()); - code.addInvokeinterface(MethodHandler.class.getName(), "invoke", - "(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;", - 5); - Class retType = meth.getReturnType(); - addUnwrapper(code, retType); - addReturn(code, retType); - - CodeAttribute ca = code.toCodeAttribute(); - forwarder.setCodeAttribute(ca); - return forwarder; - } - - static class Find2MethodsArgs { - String methodName, delegatorName, descriptor; - int origIndex; - - Find2MethodsArgs(String mname, String dname, String desc, int index) { - methodName = mname; - delegatorName = dname; - descriptor = desc; - origIndex = index; - } - } - - private static void setThrows(com.fr.third.javassist.bytecode.MethodInfo minfo, com.fr.third.javassist.bytecode.ConstPool cp, Method orig) { - Class[] exceptions = orig.getExceptionTypes(); - setThrows(minfo, cp, exceptions); - } - - private static void setThrows(com.fr.third.javassist.bytecode.MethodInfo minfo, com.fr.third.javassist.bytecode.ConstPool cp, - Class[] exceptions) { - if (exceptions.length == 0) - return; - - String[] list = new String[exceptions.length]; - for (int i = 0; i < exceptions.length; i++) - list[i] = exceptions[i].getName(); - - com.fr.third.javassist.bytecode.ExceptionsAttribute ea = new com.fr.third.javassist.bytecode.ExceptionsAttribute(cp); - ea.setExceptions(list); - minfo.setExceptionsAttribute(ea); - } - - private static int addLoadParameters(com.fr.third.javassist.bytecode.Bytecode code, Class[] params, - int offset) { - int stacksize = 0; - int n = params.length; - for (int i = 0; i < n; ++i) - stacksize += addLoad(code, stacksize + offset, params[i]); - - return stacksize; - } - - private static int addLoad(com.fr.third.javassist.bytecode.Bytecode code, int n, Class type) { - if (type.isPrimitive()) { - if (type == Long.TYPE) { - code.addLload(n); - return 2; - } - else if (type == Float.TYPE) - code.addFload(n); - else if (type == Double.TYPE) { - code.addDload(n); - return 2; - } - else - code.addIload(n); - } - else - code.addAload(n); - - return 1; - } - - private static int addReturn(com.fr.third.javassist.bytecode.Bytecode code, Class type) { - if (type.isPrimitive()) { - if (type == Long.TYPE) { - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.LRETURN); - return 2; - } - else if (type == Float.TYPE) - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.FRETURN); - else if (type == Double.TYPE) { - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.DRETURN); - return 2; - } - else if (type == Void.TYPE) { - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.RETURN); - return 0; - } - else - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.IRETURN); - } - else - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.ARETURN); - - return 1; - } - - private static void makeParameterList(com.fr.third.javassist.bytecode.Bytecode code, Class[] params) { - int regno = 1; - int n = params.length; - code.addIconst(n); - code.addAnewarray("java/lang/Object"); - for (int i = 0; i < n; i++) { - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.DUP); - code.addIconst(i); - Class type = params[i]; - if (type.isPrimitive()) - regno = makeWrapper(code, type, regno); - else { - code.addAload(regno); - regno++; - } - - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.AASTORE); - } - } - - private static int makeWrapper(com.fr.third.javassist.bytecode.Bytecode code, Class type, int regno) { - int index = FactoryHelper.typeIndex(type); - String wrapper = FactoryHelper.wrapperTypes[index]; - code.addNew(wrapper); - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.DUP); - addLoad(code, regno, type); - code.addInvokespecial(wrapper, "", - FactoryHelper.wrapperDesc[index]); - return regno + FactoryHelper.dataSize[index]; - } - - private static void addUnwrapper(com.fr.third.javassist.bytecode.Bytecode code, Class type) { - if (type.isPrimitive()) { - if (type == Void.TYPE) - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.POP); - else { - int index = FactoryHelper.typeIndex(type); - String wrapper = FactoryHelper.wrapperTypes[index]; - code.addCheckcast(wrapper); - code.addInvokevirtual(wrapper, - FactoryHelper.unwarpMethods[index], - FactoryHelper.unwrapDesc[index]); - } - } - else - code.addCheckcast(type.getName()); - } - - private static com.fr.third.javassist.bytecode.MethodInfo makeWriteReplace(com.fr.third.javassist.bytecode.ConstPool cp) { - com.fr.third.javassist.bytecode.MethodInfo minfo = new com.fr.third.javassist.bytecode.MethodInfo(cp, "writeReplace", "()Ljava/lang/Object;"); - String[] list = new String[1]; - list[0] = "java.io.ObjectStreamException"; - com.fr.third.javassist.bytecode.ExceptionsAttribute ea = new com.fr.third.javassist.bytecode.ExceptionsAttribute(cp); - ea.setExceptions(list); - minfo.setExceptionsAttribute(ea); - com.fr.third.javassist.bytecode.Bytecode code = new com.fr.third.javassist.bytecode.Bytecode(cp, 0, 1); - code.addAload(0); - code.addInvokestatic("javassist.util.proxy.RuntimeSupport", - "makeSerializedProxy", - "(Ljava/lang/Object;)Ljavassist/util/proxy/SerializedProxy;"); - code.addOpcode(com.fr.third.javassist.bytecode.Opcode.ARETURN); - minfo.setCodeAttribute(code.toCodeAttribute()); - return minfo; - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/ProxyObject.java b/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/ProxyObject.java deleted file mode 100644 index adb80d77c..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/ProxyObject.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.util.proxy; - -/** - * The interface implemented by proxy classes. - * This interface is available only if the super class of the proxy object - * does not have a getHandler() method. If the super class - * has getHandler, then Proxy interface is - * available. - * - * @see ProxyFactory - * @see com.fr.third.javassist.util.proxy.Proxy - */ -public interface ProxyObject extends com.fr.third.javassist.util.proxy.Proxy { - /** - * Sets a handler. It can be used for changing handlers - * during runtime. - */ - void setHandler(MethodHandler mi); - - /** - * Get the handler. - * This can be used to access the underlying MethodHandler - * or to serialize it properly. - * - * @see ProxyFactory#getHandler(Proxy) - */ - MethodHandler getHandler(); -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/ProxyObjectInputStream.java b/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/ProxyObjectInputStream.java deleted file mode 100644 index 58ed73e70..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/ProxyObjectInputStream.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.util.proxy; - -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectStreamClass; - -/** - * An input stream class which knows how to deserialize proxies created via {@link com.fr.third.javassist.util.proxy.ProxyFactory} and - * serializedo via a {@link ProxyObjectOutputStream}. It must be used when deserialising proxies created - * from a proxy factory configured with {@link com.fr.third.javassist.util.proxy.ProxyFactory#useWriteReplace} set to false. - * - * @author Andrew Dinn - */ -public class ProxyObjectInputStream extends ObjectInputStream -{ - /** - * create an input stream which can be used to deserialize an object graph which includes proxies created - * using class ProxyFactory. the classloader used to resolve proxy superclass and interface names - * read from the input stream will default to the current thread's context class loader or the system - * classloader if the context class loader is null. - * @param in - * @throws java.io.StreamCorruptedException whenever ObjectInputStream would also do so - * @throws IOException whenever ObjectInputStream would also do so - * @throws SecurityException whenever ObjectInputStream would also do so - * @throws NullPointerException if in is null - */ - public ProxyObjectInputStream(InputStream in) throws IOException - { - super(in); - loader = Thread.currentThread().getContextClassLoader(); - if (loader == null) { - loader = ClassLoader.getSystemClassLoader(); - } - } - - /** - * Reset the loader to be - * @param loader - */ - public void setClassLoader(ClassLoader loader) - { - if (loader != null) { - this.loader = loader; - } else { - loader = ClassLoader.getSystemClassLoader(); - } - } - - protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { - boolean isProxy = readBoolean(); - if (isProxy) { - String name = (String)readObject(); - Class superClass = loader.loadClass(name); - int length = readInt(); - Class[] interfaces = new Class[length]; - for (int i = 0; i < length; i++) { - name = (String)readObject(); - interfaces[i] = loader.loadClass(name); - } - length = readInt(); - byte[] signature = new byte[length]; - read(signature); - com.fr.third.javassist.util.proxy.ProxyFactory factory = new ProxyFactory(); - // we must always use the cache and never use writeReplace when using - // ProxyObjectOutputStream and ProxyObjectInputStream - factory.setUseCache(true); - factory.setUseWriteReplace(false); - factory.setSuperclass(superClass); - factory.setInterfaces(interfaces); - Class proxyClass = factory.createClass(signature); - return ObjectStreamClass.lookup(proxyClass); - } else { - return super.readClassDescriptor(); - } - } - - /** - * the loader to use to resolve classes for proxy superclass and interface names read - * from the stream. defaults to the context class loader of the thread which creates - * the input stream or the system class loader if the context class loader is null. - */ - private ClassLoader loader; -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/ProxyObjectOutputStream.java b/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/ProxyObjectOutputStream.java deleted file mode 100644 index a2ab4e1a9..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/ProxyObjectOutputStream.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.util.proxy; - -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.io.ObjectStreamClass; -import java.io.OutputStream; - -/** - * An input stream class which knows how to serialize proxies created via {@link com.fr.third.javassist.util.proxy.ProxyFactory}. It must - * be used when serialising proxies created from a proxy factory configured with - * {@link com.fr.third.javassist.util.proxy.ProxyFactory#useWriteReplace} set to false. Subsequent deserialization of the serialized data - * must employ a {@link ProxyObjectInputStream} - * - * @author Andrew Dinn - */ -public class ProxyObjectOutputStream extends ObjectOutputStream -{ - /** - * create an output stream which can be used to serialize an object graph which includes proxies created - * using class ProxyFactory - * @param out - * @throws IOException whenever ObjectOutputStream would also do so - * @throws SecurityException whenever ObjectOutputStream would also do so - * @throws NullPointerException if out is null - */ - public ProxyObjectOutputStream(OutputStream out) throws IOException - { - super(out); - } - - protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException { - Class cl = desc.forClass(); - if (com.fr.third.javassist.util.proxy.ProxyFactory.isProxyClass(cl)) { - writeBoolean(true); - Class superClass = cl.getSuperclass(); - Class[] interfaces = cl.getInterfaces(); - byte[] signature = ProxyFactory.getFilterSignature(cl); - String name = superClass.getName(); - writeObject(name); - // we don't write the marker interface ProxyObject - writeInt(interfaces.length - 1); - for (int i = 0; i < interfaces.length; i++) { - Class interfaze = interfaces[i]; - if (interfaze != ProxyObject.class && interfaze != Proxy.class) { - name = interfaces[i].getName(); - writeObject(name); - } - } - writeInt(signature.length); - write(signature); - } else { - writeBoolean(false); - super.writeClassDescriptor(desc); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/RuntimeSupport.java b/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/RuntimeSupport.java deleted file mode 100644 index 834687e82..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/RuntimeSupport.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.util.proxy; - -import java.lang.reflect.Method; -import java.io.Serializable; - -/** - * Runtime support routines that the classes generated by ProxyFactory use. - * - * @see com.fr.third.javassist.util.proxy.ProxyFactory - */ -public class RuntimeSupport { - /** - * A method handler that only executes a method. - */ - public static com.fr.third.javassist.util.proxy.MethodHandler default_interceptor = new DefaultMethodHandler(); - - static class DefaultMethodHandler implements com.fr.third.javassist.util.proxy.MethodHandler, Serializable { - public Object invoke(Object self, Method m, - Method proceed, Object[] args) - throws Exception - { - return proceed.invoke(self, args); - } - }; - - /** - * Finds two methods specified by the parameters and stores them - * into the given array. - * - * @throws RuntimeException if the methods are not found. - * @see com.fr.third.javassist.util.proxy.ProxyFactory - */ - public static void find2Methods(Class clazz, String superMethod, - String thisMethod, int index, - String desc, java.lang.reflect.Method[] methods) - { - methods[index + 1] = thisMethod == null ? null - : findMethod(clazz, thisMethod, desc); - methods[index] = findSuperClassMethod(clazz, superMethod, desc); - } - - /** - * Finds two methods specified by the parameters and stores them - * into the given array. - * - *

Added back for JBoss Seam. See JASSIST-206.

- * - * @throws RuntimeException if the methods are not found. - * @see com.fr.third.javassist.util.proxy.ProxyFactory - * @deprecated replaced by {@link #find2Methods(Class, String, String, int, String, Method[])} - */ - public static void find2Methods(Object self, String superMethod, - String thisMethod, int index, - String desc, java.lang.reflect.Method[] methods) - { - methods[index + 1] = thisMethod == null ? null - : findMethod(self, thisMethod, desc); - methods[index] = findSuperMethod(self, superMethod, desc); - } - - /** - * Finds a method with the given name and descriptor. - * It searches only the class of self. - * - *

Added back for JBoss Seam. See JASSIST-206.

- * - * @throws RuntimeException if the method is not found. - * @deprecated replaced by {@link #findMethod(Class, String, String)} - */ - public static Method findMethod(Object self, String name, String desc) { - Method m = findMethod2(self.getClass(), name, desc); - if (m == null) - error(self.getClass(), name, desc); - - return m; - } - - /** - * Finds a method with the given name and descriptor. - * It searches only the class of self. - * - * @throws RuntimeException if the method is not found. - */ - public static Method findMethod(Class clazz, String name, String desc) { - Method m = findMethod2(clazz, name, desc); - if (m == null) - error(clazz, name, desc); - - return m; - } - - /** - * Finds a method that has the given name and descriptor and is declared - * in the super class. - * - * @throws RuntimeException if the method is not found. - */ - public static Method findSuperMethod(Object self, String name, String desc) { - // for JBoss Seam. See JASSIST-183. - Class clazz = self.getClass(); - return findSuperClassMethod(clazz, name, desc); - } - - /** - * Finds a method that has the given name and descriptor and is declared - * in the super class. - * - * @throws RuntimeException if the method is not found. - */ - public static Method findSuperClassMethod(Class clazz, String name, String desc) { - Method m = findSuperMethod2(clazz.getSuperclass(), name, desc); - if (m == null) - m = searchInterfaces(clazz, name, desc); - - if (m == null) - error(clazz, name, desc); - - return m; - } - - private static void error(Class clazz, String name, String desc) { - throw new RuntimeException("not found " + name + ":" + desc - + " in " + clazz.getName()); - } - - private static Method findSuperMethod2(Class clazz, String name, String desc) { - Method m = findMethod2(clazz, name, desc); - if (m != null) - return m; - - Class superClass = clazz.getSuperclass(); - if (superClass != null) { - m = findSuperMethod2(superClass, name, desc); - if (m != null) - return m; - } - - return searchInterfaces(clazz, name, desc); - } - - private static Method searchInterfaces(Class clazz, String name, String desc) { - Method m = null; - Class[] interfaces = clazz.getInterfaces(); - for (int i = 0; i < interfaces.length; i++) { - m = findSuperMethod2(interfaces[i], name, desc); - if (m != null) - return m; - } - - return m; - } - - private static Method findMethod2(Class clazz, String name, String desc) { - Method[] methods = SecurityActions.getDeclaredMethods(clazz); - int n = methods.length; - for (int i = 0; i < n; i++) - if (methods[i].getName().equals(name) - && makeDescriptor(methods[i]).equals(desc)) - return methods[i]; - - return null; - } - - /** - * Makes a descriptor for a given method. - */ - public static String makeDescriptor(Method m) { - Class[] params = m.getParameterTypes(); - return makeDescriptor(params, m.getReturnType()); - } - - /** - * Makes a descriptor for a given method. - * - * @param params parameter types. - * @param retType return type. - */ - public static String makeDescriptor(Class[] params, Class retType) { - StringBuffer sbuf = new StringBuffer(); - sbuf.append('('); - for (int i = 0; i < params.length; i++) - makeDesc(sbuf, params[i]); - - sbuf.append(')'); - if (retType != null) - makeDesc(sbuf, retType); - - return sbuf.toString(); - } - - /** - * Makes a descriptor for a given method. - * - * @param params the descriptor of parameter types. - * @param retType return type. - */ - public static String makeDescriptor(String params, Class retType) { - StringBuffer sbuf = new StringBuffer(params); - makeDesc(sbuf, retType); - return sbuf.toString(); - } - - private static void makeDesc(StringBuffer sbuf, Class type) { - if (type.isArray()) { - sbuf.append('['); - makeDesc(sbuf, type.getComponentType()); - } - else if (type.isPrimitive()) { - if (type == Void.TYPE) - sbuf.append('V'); - else if (type == Integer.TYPE) - sbuf.append('I'); - else if (type == Byte.TYPE) - sbuf.append('B'); - else if (type == Long.TYPE) - sbuf.append('J'); - else if (type == Double.TYPE) - sbuf.append('D'); - else if (type == Float.TYPE) - sbuf.append('F'); - else if (type == Character.TYPE) - sbuf.append('C'); - else if (type == Short.TYPE) - sbuf.append('S'); - else if (type == Boolean.TYPE) - sbuf.append('Z'); - else - throw new RuntimeException("bad type: " + type.getName()); - } - else - sbuf.append('L').append(type.getName().replace('.', '/')) - .append(';'); - } - - /** - * Converts a proxy object to an object that is writable to an - * object stream. This method is called by writeReplace() - * in a proxy class. - * - * @since 3.4 - */ - public static SerializedProxy makeSerializedProxy(Object proxy) - throws java.io.InvalidClassException - { - Class clazz = proxy.getClass(); - - MethodHandler methodHandler = null; - if (proxy instanceof com.fr.third.javassist.util.proxy.ProxyObject) - methodHandler = ((ProxyObject)proxy).getHandler(); - else if (proxy instanceof com.fr.third.javassist.util.proxy.Proxy) - methodHandler = com.fr.third.javassist.util.proxy.ProxyFactory.getHandler((Proxy)proxy); - - return new SerializedProxy(clazz, ProxyFactory.getFilterSignature(clazz), methodHandler); - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/SecurityActions.java b/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/SecurityActions.java deleted file mode 100644 index 27e89ee8b..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/SecurityActions.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ -package com.fr.third.javassist.util.proxy; - -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; - -class SecurityActions { - static Method[] getDeclaredMethods(final Class clazz) { - if (System.getSecurityManager() == null) - return clazz.getDeclaredMethods(); - else { - return (Method[]) AccessController - .doPrivileged(new PrivilegedAction() { - public Object run() { - return clazz.getDeclaredMethods(); - } - }); - } - } - - static Constructor[] getDeclaredConstructors(final Class clazz) { - if (System.getSecurityManager() == null) - return clazz.getDeclaredConstructors(); - else { - return (Constructor[]) AccessController - .doPrivileged(new PrivilegedAction() { - public Object run() { - return clazz.getDeclaredConstructors(); - } - }); - } - } - - static Method getDeclaredMethod(final Class clazz, final String name, - final Class[] types) throws NoSuchMethodException { - if (System.getSecurityManager() == null) - return clazz.getDeclaredMethod(name, types); - else { - try { - return (Method) AccessController - .doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - return clazz.getDeclaredMethod(name, types); - } - }); - } - catch (PrivilegedActionException e) { - if (e.getCause() instanceof NoSuchMethodException) - throw (NoSuchMethodException) e.getCause(); - - throw new RuntimeException(e.getCause()); - } - } - } - - static Constructor getDeclaredConstructor(final Class clazz, - final Class[] types) - throws NoSuchMethodException - { - if (System.getSecurityManager() == null) - return clazz.getDeclaredConstructor(types); - else { - try { - return (Constructor) AccessController - .doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - return clazz.getDeclaredConstructor(types); - } - }); - } - catch (PrivilegedActionException e) { - if (e.getCause() instanceof NoSuchMethodException) - throw (NoSuchMethodException) e.getCause(); - - throw new RuntimeException(e.getCause()); - } - } - } - - static void setAccessible(final AccessibleObject ao, - final boolean accessible) { - if (System.getSecurityManager() == null) - ao.setAccessible(accessible); - else { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ao.setAccessible(accessible); - return null; - } - }); - } - } - - static void set(final Field fld, final Object target, final Object value) - throws IllegalAccessException - { - if (System.getSecurityManager() == null) - fld.set(target, value); - else { - try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - fld.set(target, value); - return null; - } - }); - } - catch (PrivilegedActionException e) { - if (e.getCause() instanceof NoSuchMethodException) - throw (IllegalAccessException) e.getCause(); - - throw new RuntimeException(e.getCause()); - } - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/SerializedProxy.java b/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/SerializedProxy.java deleted file mode 100644 index 6eb986503..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/SerializedProxy.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.util.proxy; - -import java.io.Serializable; -import java.io.ObjectStreamException; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; - -/** - * A proxy object is converted into an instance of this class - * when it is written to an output stream. - * - * @see RuntimeSupport#makeSerializedProxy(Object) - */ -class SerializedProxy implements Serializable { - private String superClass; - private String[] interfaces; - private byte[] filterSignature; - private com.fr.third.javassist.util.proxy.MethodHandler handler; - - SerializedProxy(Class proxy, byte[] sig, MethodHandler h) { - filterSignature = sig; - handler = h; - superClass = proxy.getSuperclass().getName(); - Class[] infs = proxy.getInterfaces(); - int n = infs.length; - interfaces = new String[n - 1]; - String setterInf = ProxyObject.class.getName(); - String setterInf2 = com.fr.third.javassist.util.proxy.Proxy.class.getName(); - for (int i = 0; i < n; i++) { - String name = infs[i].getName(); - if (!name.equals(setterInf) && !name.equals(setterInf2)) - interfaces[i] = name; - } - } - - /** - * Load class. - * - * @param className the class name - * @return loaded class - * @throws ClassNotFoundException for any error - */ - protected Class loadClass(final String className) throws ClassNotFoundException { - try { - return (Class)AccessController.doPrivileged(new PrivilegedExceptionAction(){ - public Object run() throws Exception{ - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - return Class.forName(className, true, cl); - } - }); - } - catch (PrivilegedActionException pae) { - throw new RuntimeException("cannot load the class: " + className, pae.getException()); - } - } - - Object readResolve() throws ObjectStreamException { - try { - int n = interfaces.length; - Class[] infs = new Class[n]; - for (int i = 0; i < n; i++) - infs[i] = loadClass(interfaces[i]); - - com.fr.third.javassist.util.proxy.ProxyFactory f = new ProxyFactory(); - f.setSuperclass(loadClass(superClass)); - f.setInterfaces(infs); - com.fr.third.javassist.util.proxy.Proxy proxy = (Proxy)f.createClass(filterSignature).newInstance(); - proxy.setHandler(handler); - return proxy; - } - catch (ClassNotFoundException e) { - throw new java.io.InvalidClassException(e.getMessage()); - } - catch (InstantiationException e2) { - throw new java.io.InvalidObjectException(e2.getMessage()); - } - catch (IllegalAccessException e3) { - throw new java.io.InvalidClassException(e3.getMessage()); - } - } -} diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/package.html b/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/package.html deleted file mode 100644 index 6c77804d7..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/util/proxy/package.html +++ /dev/null @@ -1,6 +0,0 @@ - - -Dynamic proxy (similar to Enhancer of cglib). -See ProxyFactory for more details. - - diff --git a/fine-transmittable-thread-local/pom.xml b/fine-transmittable-thread-local/pom.xml deleted file mode 100644 index d75a1146a..000000000 --- a/fine-transmittable-thread-local/pom.xml +++ /dev/null @@ -1,36 +0,0 @@ - - 4.0.0 - - - com.fr.third - step8 - ${revision} - ../base-third-project/base-third-step8 - - - fine-transmittable-thread-local - ${revision} - - - - - - com.fr.third - fine-javassist - ${revision} - - - - - - diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TransmittableThreadLocal.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TransmittableThreadLocal.java deleted file mode 100644 index 5ce678ed0..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TransmittableThreadLocal.java +++ /dev/null @@ -1,752 +0,0 @@ -package com.fr.third.alibaba.ttl; - -import com.fr.third.alibaba.ttl.threadpool.TtlExecutors; -import com.fr.third.alibaba.ttl.threadpool.TtlForkJoinPoolHelper; -import com.fr.third.alibaba.ttl.threadpool.agent.TtlAgent; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.WeakHashMap; -import java.util.concurrent.Callable; -import java.util.function.Supplier; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * {@link TransmittableThreadLocal} can transmit value from the thread of submitting task to the thread of executing task. - *

- * Note:
- * {@link TransmittableThreadLocal} extends {@link InheritableThreadLocal}, - * so {@link TransmittableThreadLocal} first is a {@link InheritableThreadLocal}.
- * If the inheritable ability from {@link InheritableThreadLocal} has potential leaking problem, - * you can disable the inheritable ability: - *

- * ❶ by wrapping thread factory using method - * {@link TtlExecutors#getDisableInheritableThreadFactory(java.util.concurrent.ThreadFactory)} / - * {@link TtlForkJoinPoolHelper#getDefaultDisableInheritableForkJoinWorkerThreadFactory()} - * for thread pooling components({@link java.util.concurrent.ThreadPoolExecutor}, {@link java.util.concurrent.ForkJoinPool}). - * Inheritable feature in thread pooling components should never happen, - * because threads in thread pooling components is pre-created and pooled, these threads is neutral for biz logic/data. - *
- * You can turn on "disable inheritable for thread pool" by {@link TtlAgent} - * so as to wrap thread factory for thread pooling components ({@link java.util.concurrent.ThreadPoolExecutor}, - * {@link java.util.concurrent.ForkJoinPool}) automatically and transparently. - *

- * ❷ or by overriding method {@link #childValue(Object)}. - * Whether the value should be inheritable or not can be controlled by the data owner, - * disable it carefully when data owner have a clear idea. - *

 {@code TransmittableThreadLocal transmittableThreadLocal = new TransmittableThreadLocal() {
- *     protected String childValue(String parentValue) {
- *         return initialValue();
- *     }
- * }}
- *

- * More discussion about "disable the inheritable ability" - * see - * issue #100: disable Inheritable when it's not necessary and buggy. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @author Yang Fang (snoop dot fy at gmail dot com) - * @see TtlRunnable - * @see TtlCallable - * @see TtlExecutors - * @see TtlExecutors#getTtlExecutor(java.util.concurrent.Executor) - * @see TtlExecutors#getTtlExecutorService(java.util.concurrent.ExecutorService) - * @see TtlExecutors#getTtlScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) - * @see TtlExecutors#getDefaultDisableInheritableThreadFactory() - * @see TtlExecutors#getDisableInheritableThreadFactory(java.util.concurrent.ThreadFactory) - * @see TtlForkJoinPoolHelper - * @see TtlForkJoinPoolHelper#getDefaultDisableInheritableForkJoinWorkerThreadFactory() - * @see TtlForkJoinPoolHelper#getDisableInheritableForkJoinWorkerThreadFactory(java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory) - * @see TtlAgent - * @since 0.10.0 - */ -public class TransmittableThreadLocal extends InheritableThreadLocal implements TtlCopier { - private static final Logger logger = Logger.getLogger(TransmittableThreadLocal.class.getName()); - - private final boolean disableIgnoreNullValueSemantics; - - /** - * Default constructor. - *

- * Create a {@link TransmittableThreadLocal} instance with "Ignore-Null-Value Semantics". - * About "Ignore-Null-Value Semantics": - *

- *

    - *
  1. If value is {@code null}(check by {@link #get()} method), do NOT transmit this {@code ThreadLocal}.
  2. - *
  3. If set {@code null} value, also remove value(invoke {@link #remove()} method).
  4. - *
- *

- * This is a pragmatic design decision: - *

    - *
  1. use explicit value type rather than {@code null} to biz intent.
  2. - *
  3. more safe(avoid {@code NPE}) and gc friendly.
  4. - *
- *

- * So it's not recommended to use {@code null} value. - *

- * But the behavior of "Ignore-Null-Value Semantics" is NOT compatible with - * {@link ThreadLocal} and {@link InheritableThreadLocal}, - * you can disable this behavior/semantics via using constructor {@link #TransmittableThreadLocal(boolean)} - * and set parameter {@code disableIgnoreNullValueSemantics} instead. - *

- * More info see Issue #157. - * - * @see #TransmittableThreadLocal(boolean) - */ - public TransmittableThreadLocal() { - this(false); - } - - /** - * Constructor, create a {@link TransmittableThreadLocal} with parameter {@code disableIgnoreNullValueSemantics} - * to control "Ignore-Null-Value Semantics". - * - * @param disableIgnoreNullValueSemantics disable "Ignore-Null-Value Semantics" - * @see #TransmittableThreadLocal() - * @since 2.11.3 - */ - public TransmittableThreadLocal(boolean disableIgnoreNullValueSemantics) { - this.disableIgnoreNullValueSemantics = disableIgnoreNullValueSemantics; - } - - /** - * Computes the value for this transmittable thread-local variable - * as a function of the source thread's value at the time the task - * Object is created. - *

- * This method is called from {@link TtlRunnable} or - * {@link TtlCallable} when it create, before the task is started. - *

- * This method merely returns reference of its source thread value(the shadow copy), - * and should be overridden if a different behavior is desired. - * - * @since 1.0.0 - */ - public T copy(T parentValue) { - return parentValue; - } - - /** - * Callback method before task object({@link TtlRunnable}/{@link TtlCallable}) execute. - *

- * Default behavior is to do nothing, and should be overridden - * if a different behavior is desired. - *

- * Do not throw any exception, just ignored. - * - * @since 1.2.0 - */ - protected void beforeExecute() { - } - - /** - * Callback method after task object({@link TtlRunnable}/{@link TtlCallable}) execute. - *

- * Default behavior is to do nothing, and should be overridden - * if a different behavior is desired. - *

- * Do not throw any exception, just ignored. - * - * @since 1.2.0 - */ - protected void afterExecute() { - } - - /** - * see {@link InheritableThreadLocal#get()} - */ - @Override - public final T get() { - T value = super.get(); - if (disableIgnoreNullValueSemantics || null != value) addThisToHolder(); - return value; - } - - /** - * see {@link InheritableThreadLocal#set} - */ - @Override - public final void set(T value) { - if (!disableIgnoreNullValueSemantics && null == value) { - // may set null to remove value - remove(); - } else { - super.set(value); - addThisToHolder(); - } - } - - /** - * see {@link InheritableThreadLocal#remove()} - */ - @Override - public final void remove() { - removeThisFromHolder(); - super.remove(); - } - - private void superRemove() { - super.remove(); - } - - private T copyValue() { - return copy(get()); - } - - // Note about the holder: - // 1. holder self is a InheritableThreadLocal(a *ThreadLocal*). - // 2. The type of value in the holder is WeakHashMap, ?>. - // 2.1 but the WeakHashMap is used as a *Set*: - // - the value of WeakHashMap is *always null, - // - and be never used. - // 2.2 WeakHashMap support *null* value. - private static InheritableThreadLocal, ?>> holder = - new InheritableThreadLocal, ?>>() { - @Override - protected WeakHashMap, ?> initialValue() { - return new WeakHashMap, Object>(); - } - - @Override - protected WeakHashMap, ?> childValue(WeakHashMap, ?> parentValue) { - return new WeakHashMap, Object>(parentValue); - } - }; - - @SuppressWarnings("unchecked") - private void addThisToHolder() { - if (!holder.get().containsKey(this)) { - holder.get().put((TransmittableThreadLocal) this, null); // WeakHashMap supports null value. - } - } - - private void removeThisFromHolder() { - holder.get().remove(this); - } - - private static void doExecuteCallback(boolean isBefore) { - for (TransmittableThreadLocal threadLocal : holder.get().keySet()) { - try { - if (isBefore) threadLocal.beforeExecute(); - else threadLocal.afterExecute(); - } catch (Throwable t) { - if (logger.isLoggable(Level.WARNING)) { - logger.log(Level.WARNING, "TTL exception when " + (isBefore ? "beforeExecute" : "afterExecute") + ", cause: " + t.toString(), t); - } - } - } - } - - /** - * Debug only method! - */ - static void dump( String title) { - if (title != null && title.length() > 0) { - System.out.printf("Start TransmittableThreadLocal[%s] Dump...%n", title); - } else { - System.out.println("Start TransmittableThreadLocal Dump..."); - } - - for (TransmittableThreadLocal threadLocal : holder.get().keySet()) { - System.out.println(threadLocal.get()); - } - System.out.println("TransmittableThreadLocal Dump end!"); - } - - /** - * Debug only method! - */ - static void dump() { - dump(null); - } - - /** - * {@link Transmitter} transmit all {@link TransmittableThreadLocal} - * and registered {@link ThreadLocal}(registered by {@link Transmitter#registerThreadLocal}) - * values of the current thread to other thread by static methods - * {@link #capture()} => {@link #replay(Object)} => {@link #restore(Object)} (aka {@code CRR} operation). - *

- * {@link Transmitter} is internal manipulation api for framework/middleware integration; - * In general, you will never use it in the biz/application code! - * - *

Framework/Middleware integration to TTL transmittance

- * Below is the example code: - * - *

-     * ///////////////////////////////////////////////////////////////////////////
-     * // in thread A, capture all TransmittableThreadLocal values of thread A
-     * ///////////////////////////////////////////////////////////////////////////
-     *
-     * Object captured = Transmitter.capture(); // (1)
-     *
-     * ///////////////////////////////////////////////////////////////////////////
-     * // in thread B
-     * ///////////////////////////////////////////////////////////////////////////
-     *
-     * // replay all TransmittableThreadLocal values from thread A
-     * Object backup = Transmitter.replay(captured); // (2)
-     * try {
-     *     // your biz logic, run with the TransmittableThreadLocal values of thread B
-     *     System.out.println("Hello");
-     *     // ...
-     *     return "World";
-     * } finally {
-     *     // restore the TransmittableThreadLocal of thread B when replay
-     *     Transmitter.restore(backup); (3)
-     * }
-     * 
- *

- * see the implementation code of {@link TtlRunnable} and {@link TtlCallable} for more actual code sample. - *

- * Of course, {@link #replay(Object)} and {@link #restore(Object)} operation can be simplified by util methods - * {@link #runCallableWithCaptured(Object, Callable)} or {@link #runSupplierWithCaptured(Object, Supplier)} - * and the adorable {@code Java 8 lambda syntax}. - *

- * Below is the example code: - * - *


-     * ///////////////////////////////////////////////////////////////////////////
-     * // in thread A, capture all TransmittableThreadLocal values of thread A
-     * ///////////////////////////////////////////////////////////////////////////
-     *
-     * Object captured = Transmitter.capture(); // (1)
-     *
-     * ///////////////////////////////////////////////////////////////////////////
-     * // in thread B
-     * ///////////////////////////////////////////////////////////////////////////
-     *
-     * String result = runSupplierWithCaptured(captured, () -> {
-     *      // your biz logic, run with the TransmittableThreadLocal values of thread A
-     *      System.out.println("Hello");
-     *      ...
-     *      return "World";
-     * }); // (2) + (3)
-     * 
- *

- * The reason of providing 2 util methods is the different {@code throws Exception} type - * so as to satisfy your biz logic({@code lambda}): - *

    - *
  1. {@link #runCallableWithCaptured(Object, Callable)}: {@code throws Exception}
  2. - *
  3. {@link #runSupplierWithCaptured(Object, Supplier)}: No {@code throws}
  4. - *
- *

- * If you need the different {@code throws Exception} type, - * you can define your own util method(function interface({@code lambda})) with your own {@code throws Exception} type. - * - *

ThreadLocal Integration

- * If you can not rewrite the existed code which use {@link ThreadLocal} to {@link TransmittableThreadLocal}, - * register the {@link ThreadLocal} instances via the methods - * {@link #registerThreadLocal(ThreadLocal, TtlCopier)}/{@link #registerThreadLocalWithShadowCopier(ThreadLocal)} - * to enhance the Transmittable ability for the existed {@link ThreadLocal} instances. - *

- * Below is the example code: - * - *


-     * // the value of this ThreadLocal instance will be transmitted after registered
-     * Transmitter.registerThreadLocal(aThreadLocal, copyLambda);
-     *
-     * // Then the value of this ThreadLocal instance will not be transmitted after unregistered
-     * Transmitter.unregisterThreadLocal(aThreadLocal);
-     * 
- * - * Caution:
- * If the registered {@link ThreadLocal} instance is not {@link InheritableThreadLocal}, - * the instance can NOT {@code inherit} value from parent thread(aka. the inheritable ability)! - * - * @author Yang Fang (snoop dot fy at gmail dot com) - * @author Jerry Lee (oldratlee at gmail dot com) - * @see TtlRunnable - * @see TtlCallable - * @since 2.3.0 - */ - public static class Transmitter { - /** - * Capture all {@link TransmittableThreadLocal} and registered {@link ThreadLocal} values in the current thread. - * - * @return the captured {@link TransmittableThreadLocal} values - * @since 2.3.0 - */ - - public static Object capture() { - return new Snapshot(captureTtlValues(), captureThreadLocalValues()); - } - - private static HashMap, Object> captureTtlValues() { - HashMap, Object> ttl2Value = new HashMap, Object>(); - for (TransmittableThreadLocal threadLocal : holder.get().keySet()) { - ttl2Value.put(threadLocal, threadLocal.copyValue()); - } - return ttl2Value; - } - - private static HashMap, Object> captureThreadLocalValues() { - final HashMap, Object> threadLocal2Value = new HashMap, Object>(); - for (Map.Entry, TtlCopier> entry : threadLocalHolder.entrySet()) { - final ThreadLocal threadLocal = entry.getKey(); - final TtlCopier copier = entry.getValue(); - - threadLocal2Value.put(threadLocal, copier.copy(threadLocal.get())); - } - return threadLocal2Value; - } - - /** - * Replay the captured {@link TransmittableThreadLocal} and registered {@link ThreadLocal} values from {@link #capture()}, - * and return the backup {@link TransmittableThreadLocal} values in the current thread before replay. - * - * @param captured captured {@link TransmittableThreadLocal} values from other thread from {@link #capture()} - * @return the backup {@link TransmittableThreadLocal} values before replay - * @see #capture() - * @since 2.3.0 - */ - - public static Object replay(Object captured) { - final Snapshot capturedSnapshot = (Snapshot) captured; - return new Snapshot(replayTtlValues(capturedSnapshot.ttl2Value), replayThreadLocalValues(capturedSnapshot.threadLocal2Value)); - } - - - private static HashMap, Object> replayTtlValues(HashMap, Object> captured) { - HashMap, Object> backup = new HashMap, Object>(); - - for (final Iterator> iterator = holder.get().keySet().iterator(); iterator.hasNext(); ) { - TransmittableThreadLocal threadLocal = iterator.next(); - - // backup - backup.put(threadLocal, threadLocal.get()); - - // clear the TTL values that is not in captured - // avoid the extra TTL values after replay when run task - if (!captured.containsKey(threadLocal)) { - iterator.remove(); - threadLocal.superRemove(); - } - } - - // set TTL values to captured - setTtlValuesTo(captured); - - // call beforeExecute callback - doExecuteCallback(true); - - return backup; - } - - private static HashMap, Object> replayThreadLocalValues(HashMap, Object> captured) { - final HashMap, Object> backup = new HashMap, Object>(); - - for (Map.Entry, Object> entry : captured.entrySet()) { - final ThreadLocal threadLocal = entry.getKey(); - backup.put(threadLocal, threadLocal.get()); - - final Object value = entry.getValue(); - if (value == threadLocalClearMark) threadLocal.remove(); - else threadLocal.set(value); - } - - return backup; - } - - /** - * Clear all {@link TransmittableThreadLocal} and registered {@link ThreadLocal} values in the current thread, - * and return the backup {@link TransmittableThreadLocal} values in the current thread before clear. - * - * @return the backup {@link TransmittableThreadLocal} values before clear - * @since 2.9.0 - */ - - public static Object clear() { - final HashMap, Object> ttl2Value = new HashMap, Object>(); - - final HashMap, Object> threadLocal2Value = new HashMap, Object>(); - for (Map.Entry, TtlCopier> entry : threadLocalHolder.entrySet()) { - final ThreadLocal threadLocal = entry.getKey(); - threadLocal2Value.put(threadLocal, threadLocalClearMark); - } - - return replay(new Snapshot(ttl2Value, threadLocal2Value)); - } - - /** - * Restore the backup {@link TransmittableThreadLocal} and - * registered {@link ThreadLocal} values from {@link #replay(Object)}/{@link #clear()}. - * - * @param backup the backup {@link TransmittableThreadLocal} values from {@link #replay(Object)}/{@link #clear()} - * @see #replay(Object) - * @see #clear() - * @since 2.3.0 - */ - public static void restore(Object backup) { - final Snapshot backupSnapshot = (Snapshot) backup; - restoreTtlValues(backupSnapshot.ttl2Value); - restoreThreadLocalValues(backupSnapshot.threadLocal2Value); - } - - private static void restoreTtlValues(HashMap, Object> backup) { - // call afterExecute callback - doExecuteCallback(false); - - for (final Iterator> iterator = holder.get().keySet().iterator(); iterator.hasNext(); ) { - TransmittableThreadLocal threadLocal = iterator.next(); - - // clear the TTL values that is not in backup - // avoid the extra TTL values after restore - if (!backup.containsKey(threadLocal)) { - iterator.remove(); - threadLocal.superRemove(); - } - } - - // restore TTL values - setTtlValuesTo(backup); - } - - private static void setTtlValuesTo(HashMap, Object> ttlValues) { - for (Map.Entry, Object> entry : ttlValues.entrySet()) { - TransmittableThreadLocal threadLocal = entry.getKey(); - threadLocal.set(entry.getValue()); - } - } - - private static void restoreThreadLocalValues(HashMap, Object> backup) { - for (Map.Entry, Object> entry : backup.entrySet()) { - final ThreadLocal threadLocal = entry.getKey(); - threadLocal.set(entry.getValue()); - } - } - - private static class Snapshot { - final HashMap, Object> ttl2Value; - final HashMap, Object> threadLocal2Value; - - private Snapshot(HashMap, Object> ttl2Value, HashMap, Object> threadLocal2Value) { - this.ttl2Value = ttl2Value; - this.threadLocal2Value = threadLocal2Value; - } - } - - /** - * Util method for simplifying {@link #replay(Object)} and {@link #restore(Object)} operation. - * - * @param captured captured {@link TransmittableThreadLocal} values from other thread from {@link #capture()} - * @param bizLogic biz logic - * @param the return type of biz logic - * @return the return value of biz logic - * @see #capture() - * @see #replay(Object) - * @see #restore(Object) - * @since 2.3.1 - */ - public static R runSupplierWithCaptured(Object captured, Supplier bizLogic) { - Object backup = replay(captured); - try { - return bizLogic.get(); - } finally { - restore(backup); - } - } - - /** - * Util method for simplifying {@link #clear()} and {@link #restore(Object)} operation. - * - * @param bizLogic biz logic - * @param the return type of biz logic - * @return the return value of biz logic - * @see #clear() - * @see #restore(Object) - * @since 2.9.0 - */ - public static R runSupplierWithClear(Supplier bizLogic) { - Object backup = clear(); - try { - return bizLogic.get(); - } finally { - restore(backup); - } - } - - /** - * Util method for simplifying {@link #replay(Object)} and {@link #restore(Object)} operation. - * - * @param captured captured {@link TransmittableThreadLocal} values from other thread from {@link #capture()} - * @param bizLogic biz logic - * @param the return type of biz logic - * @return the return value of biz logic - * @throws Exception exception threw by biz logic - * @see #capture() - * @see #replay(Object) - * @see #restore(Object) - * @since 2.3.1 - */ - public static R runCallableWithCaptured(Object captured, Callable bizLogic) throws Exception { - Object backup = replay(captured); - try { - return bizLogic.call(); - } finally { - restore(backup); - } - } - - /** - * Util method for simplifying {@link #clear()} and {@link #restore(Object)} operation. - * - * @param bizLogic biz logic - * @param the return type of biz logic - * @return the return value of biz logic - * @throws Exception exception threw by biz logic - * @see #clear() - * @see #restore(Object) - * @since 2.9.0 - */ - public static R runCallableWithClear(Callable bizLogic) throws Exception { - Object backup = clear(); - try { - return bizLogic.call(); - } finally { - restore(backup); - } - } - - private static volatile WeakHashMap, TtlCopier> threadLocalHolder = new WeakHashMap, TtlCopier>(); - private static final Object threadLocalHolderUpdateLock = new Object(); - private static final Object threadLocalClearMark = new Object(); - - /** - * Register the {@link ThreadLocal}(including subclass {@link InheritableThreadLocal}) instances - * to enhance the Transmittable ability for the existed {@link ThreadLocal} instances. - *

- * If the registered {@link ThreadLocal} instance is {@link TransmittableThreadLocal} just ignores and return {@code true}. - * since a {@link TransmittableThreadLocal} instance itself has the {@code Transmittable} ability, - * it is unnecessary to register a {@link TransmittableThreadLocal} instance. - * - * @param threadLocal the {@link ThreadLocal} instance that to enhance the Transmittable ability - * @param copier the {@link TtlCopier} - * @return {@code true} if register the {@link ThreadLocal} instance and set {@code copier}, otherwise {@code false} - * @see #registerThreadLocal(ThreadLocal, TtlCopier, boolean) - * @since 2.11.0 - */ - public static boolean registerThreadLocal(ThreadLocal threadLocal, TtlCopier copier) { - return registerThreadLocal(threadLocal, copier, false); - } - - /** - * Register the {@link ThreadLocal}(including subclass {@link InheritableThreadLocal}) instances - * to enhance the Transmittable ability for the existed {@link ThreadLocal} instances. - *

- * Use the shadow copier(transmit the reference directly), - * and should use {@link #registerThreadLocal(ThreadLocal, TtlCopier)} to pass a {@link TtlCopier} explicitly - * if a different behavior is desired. - *

- * If the registered {@link ThreadLocal} instance is {@link TransmittableThreadLocal} just ignores and return {@code true}. - * since a {@link TransmittableThreadLocal} instance itself has the {@code Transmittable} ability, - * it is unnecessary to register a {@link TransmittableThreadLocal} instance. - * - * @param threadLocal the {@link ThreadLocal} instance that to enhance the Transmittable ability - * @return {@code true} if register the {@link ThreadLocal} instance and set {@code copier}, otherwise {@code false} - * @see #registerThreadLocal(ThreadLocal, TtlCopier) - * @see #registerThreadLocal(ThreadLocal, TtlCopier, boolean) - * @since 2.11.0 - */ - @SuppressWarnings("unchecked") - public static boolean registerThreadLocalWithShadowCopier(ThreadLocal threadLocal) { - return registerThreadLocal(threadLocal, (TtlCopier) shadowCopier, false); - } - - /** - * Register the {@link ThreadLocal}(including subclass {@link InheritableThreadLocal}) instances - * to enhance the Transmittable ability for the existed {@link ThreadLocal} instances. - *

- * If the registered {@link ThreadLocal} instance is {@link TransmittableThreadLocal} just ignores and return {@code true}. - * since a {@link TransmittableThreadLocal} instance itself has the {@code Transmittable} ability, - * it is unnecessary to register a {@link TransmittableThreadLocal} instance. - * - * @param threadLocal the {@link ThreadLocal} instance that to enhance the Transmittable ability - * @param copier the {@link TtlCopier} - * @param force if {@code true}, update {@code copier} to {@link ThreadLocal} instance - * when a {@link ThreadLocal} instance is already registered; otherwise, ignore. - * @return {@code true} if register the {@link ThreadLocal} instance and set {@code copier}, otherwise {@code false} - * @see #registerThreadLocal(ThreadLocal, TtlCopier) - * @since 2.11.0 - */ - @SuppressWarnings("unchecked") - public static boolean registerThreadLocal(ThreadLocal threadLocal, TtlCopier copier, boolean force) { - if (threadLocal instanceof TransmittableThreadLocal) { - logger.warning("register a TransmittableThreadLocal instance, this is unnecessary!"); - return true; - } - - synchronized (threadLocalHolderUpdateLock) { - if (!force && threadLocalHolder.containsKey(threadLocal)) return false; - - WeakHashMap, TtlCopier> newHolder = new WeakHashMap, TtlCopier>(threadLocalHolder); - newHolder.put((ThreadLocal) threadLocal, (TtlCopier) copier); - threadLocalHolder = newHolder; - return true; - } - } - - /** - * Register the {@link ThreadLocal}(including subclass {@link InheritableThreadLocal}) instances - * to enhance the Transmittable ability for the existed {@link ThreadLocal} instances. - *

- * Use the shadow copier(transmit the reference directly), - * and should use {@link #registerThreadLocal(ThreadLocal, TtlCopier, boolean)} to pass a {@link TtlCopier} explicitly - * if a different behavior is desired. - *

- * If the registered {@link ThreadLocal} instance is {@link TransmittableThreadLocal} just ignores and return {@code true}. - * since a {@link TransmittableThreadLocal} instance itself has the {@code Transmittable} ability, - * it is unnecessary to register a {@link TransmittableThreadLocal} instance. - * - * @param threadLocal the {@link ThreadLocal} instance that to enhance the Transmittable ability - * @param force if {@code true}, update {@code copier} to {@link ThreadLocal} instance - * when a {@link ThreadLocal} instance is already registered; otherwise, ignore. - * @return {@code true} if register the {@link ThreadLocal} instance and set {@code copier}, otherwise {@code false} - * @see #registerThreadLocal(ThreadLocal, TtlCopier) - * @see #registerThreadLocal(ThreadLocal, TtlCopier, boolean) - * @since 2.11.0 - */ - @SuppressWarnings("unchecked") - public static boolean registerThreadLocalWithShadowCopier(ThreadLocal threadLocal, boolean force) { - return registerThreadLocal(threadLocal, (TtlCopier) shadowCopier, force); - } - - /** - * Unregister the {@link ThreadLocal} instances - * to remove the Transmittable ability for the {@link ThreadLocal} instances. - *

- * If the {@link ThreadLocal} instance is {@link TransmittableThreadLocal} just ignores and return {@code true}. - * - * @see #registerThreadLocal(ThreadLocal, TtlCopier) - * @see #registerThreadLocalWithShadowCopier(ThreadLocal) - * @since 2.11.0 - */ - public static boolean unregisterThreadLocal(ThreadLocal threadLocal) { - if (threadLocal instanceof TransmittableThreadLocal) { - logger.warning("unregister a TransmittableThreadLocal instance, this is unnecessary!"); - return true; - } - - synchronized (threadLocalHolderUpdateLock) { - if (!threadLocalHolder.containsKey(threadLocal)) return false; - - WeakHashMap, TtlCopier> newHolder = new WeakHashMap, TtlCopier>(threadLocalHolder); - newHolder.remove(threadLocal); - threadLocalHolder = newHolder; - return true; - } - } - - private static final TtlCopier shadowCopier = new TtlCopier() { - @Override - public Object copy(Object parentValue) { - return parentValue; - } - }; - - private Transmitter() { - throw new InstantiationError("Must not instantiate this class"); - } - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlCallable.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlCallable.java deleted file mode 100644 index cb2c4b12d..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlCallable.java +++ /dev/null @@ -1,260 +0,0 @@ -package com.fr.third.alibaba.ttl; - -import com.fr.third.alibaba.ttl.spi.TtlAttachments; -import com.fr.third.alibaba.ttl.spi.TtlAttachmentsDelegate; -import com.fr.third.alibaba.ttl.spi.TtlEnhanced; -import com.fr.third.alibaba.ttl.spi.TtlWrapper; -import com.fr.third.alibaba.ttl.threadpool.TtlExecutors; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.atomic.AtomicReference; - -import static com.fr.third.alibaba.ttl.TransmittableThreadLocal.Transmitter.*; - -/** - * {@link TtlCallable} decorate {@link Callable}, so as to get {@link TransmittableThreadLocal} - * and transmit it to the time of {@link Callable} execution, needed when use {@link Callable} to thread pool. - *

- * Use factory method {@link #get(Callable)} to get decorated instance. - *

- * Other TTL Wrapper for common {@code Functional Interface} see {@link TtlWrappers}. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see TtlExecutors - * @see TtlWrappers - * @see java.util.concurrent.Executor - * @see java.util.concurrent.ExecutorService - * @see java.util.concurrent.ThreadPoolExecutor - * @see java.util.concurrent.ScheduledThreadPoolExecutor - * @see java.util.concurrent.Executors - * @see java.util.concurrent.CompletionService - * @see java.util.concurrent.ExecutorCompletionService - * @since 0.9.0 - */ -public final class TtlCallable implements Callable, TtlWrapper>, TtlEnhanced, TtlAttachments { - private final AtomicReference capturedRef; - private final Callable callable; - private final boolean releaseTtlValueReferenceAfterCall; - - private TtlCallable(Callable callable, boolean releaseTtlValueReferenceAfterCall) { - this.capturedRef = new AtomicReference(capture()); - this.callable = callable; - this.releaseTtlValueReferenceAfterCall = releaseTtlValueReferenceAfterCall; - } - - /** - * wrap method {@link Callable#call()}. - */ - @Override - public V call() throws Exception { - Object captured = capturedRef.get(); - if (captured == null || releaseTtlValueReferenceAfterCall && !capturedRef.compareAndSet(captured, null)) { - throw new IllegalStateException("TTL value reference is released after call!"); - } - - Object backup = replay(captured); - try { - return callable.call(); - } finally { - restore(backup); - } - } - - /** - * return the original/underneath {@link Callable}. - */ - - public Callable getCallable() { - return unwrap(); - } - - /** - * unwrap to the original/underneath {@link Callable}. - * - * @see TtlUnwrap#unwrap(Object) - * @since 2.11.4 - */ - - @Override - public Callable unwrap() { - return callable; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - TtlCallable that = (TtlCallable) o; - - return callable.equals(that.callable); - } - - @Override - public int hashCode() { - return callable.hashCode(); - } - - @Override - public String toString() { - return this.getClass().getName() + " - " + callable.toString(); - } - - /** - * Factory method, wrap input {@link Callable} to {@link TtlCallable}. - *

- * This method is idempotent. - * - * @param callable input {@link Callable} - * @return Wrapped {@link Callable} - */ - - public static TtlCallable get( Callable callable) { - return get(callable, false); - } - - - /** - * Factory method, wrap input {@link Callable} to {@link TtlCallable}. - *

- * This method is idempotent. - * - * @param callable input {@link Callable} - * @param releaseTtlValueReferenceAfterCall release TTL value reference after run, avoid memory leak even if {@link TtlRunnable} is referred. - * @return Wrapped {@link Callable} - */ - - public static TtlCallable get( Callable callable, boolean releaseTtlValueReferenceAfterCall) { - return get(callable, releaseTtlValueReferenceAfterCall, false); - } - - /** - * Factory method, wrap input {@link Callable} to {@link TtlCallable}. - *

- * This method is idempotent. - * - * @param callable input {@link Callable} - * @param releaseTtlValueReferenceAfterCall release TTL value reference after run, avoid memory leak even if {@link TtlRunnable} is referred. - * @param idempotent is idempotent or not. {@code true} will cover up bugs! DO NOT set, only when you know why. - * @return Wrapped {@link Callable} - */ - - public static TtlCallable get( Callable callable, boolean releaseTtlValueReferenceAfterCall, boolean idempotent) { - if (null == callable) return null; - - if (callable instanceof TtlEnhanced) { - // avoid redundant decoration, and ensure idempotency - if (idempotent) return (TtlCallable) callable; - else throw new IllegalStateException("Already TtlCallable!"); - } - return new TtlCallable(callable, releaseTtlValueReferenceAfterCall); - } - - /** - * wrap input {@link Callable} Collection to {@link TtlCallable} Collection. - * - * @param tasks task to be wrapped - * @return Wrapped {@link Callable} - */ - - public static List> gets( Collection> tasks) { - return gets(tasks, false, false); - } - - /** - * wrap input {@link Callable} Collection to {@link TtlCallable} Collection. - * - * @param tasks task to be wrapped - * @param releaseTtlValueReferenceAfterCall release TTL value reference after run, avoid memory leak even if {@link TtlRunnable} is referred. - * @return Wrapped {@link Callable} - */ - - public static List> gets( Collection> tasks, boolean releaseTtlValueReferenceAfterCall) { - return gets(tasks, releaseTtlValueReferenceAfterCall, false); - } - - /** - * wrap input {@link Callable} Collection to {@link TtlCallable} Collection. - * - * @param tasks task to be wrapped - * @param releaseTtlValueReferenceAfterCall release TTL value reference after run, avoid memory leak even if {@link TtlRunnable} is referred. - * @param idempotent is idempotent or not. {@code true} will cover up bugs! DO NOT set, only when you know why. - * @return Wrapped {@link Callable} - */ - - public static List> gets( Collection> tasks, boolean releaseTtlValueReferenceAfterCall, boolean idempotent) { - if (null == tasks) return Collections.emptyList(); - - List> copy = new ArrayList>(); - for (Callable task : tasks) { - copy.add(TtlCallable.get(task, releaseTtlValueReferenceAfterCall, idempotent)); - } - return copy; - } - - /** - * Unwrap {@link TtlCallable} to the original/underneath one. - *

- * this method is {@code null}-safe, when input {@code Callable} parameter is {@code null}, return {@code null}; - * if input {@code Callable} parameter is not a {@link TtlCallable} just return input {@code Callable}. - *

- * so {@code TtlCallable.unwrap(TtlCallable.get(callable))} will always return the same input {@code callable} object. - * - * @see #get(Callable) - * @since 2.10.2 - */ - - public static Callable unwrap( Callable callable) { - if (!(callable instanceof TtlCallable)) return callable; - else return ((TtlCallable) callable).getCallable(); - } - - /** - * Unwrap {@link TtlCallable} to the original/underneath one. - *

- * Invoke {@link #unwrap(Callable)} for each element in input collection. - *

- * This method is {@code null}-safe, when input {@code Callable} parameter is {@code null}, return a empty list. - * - * @see #gets(Collection) - * @see #unwrap(Callable) - * @since 2.10.2 - */ - - public static List> unwraps( Collection> tasks) { - if (null == tasks) return Collections.emptyList(); - - List> copy = new ArrayList>(); - for (Callable task : tasks) { - if (!(task instanceof TtlCallable)) copy.add(task); - else copy.add(((TtlCallable) task).getCallable()); - } - return copy; - } - - private final TtlAttachmentsDelegate ttlAttachment = new TtlAttachmentsDelegate(); - - /** - * see {@link TtlAttachments#setTtlAttachment(String, Object)} - * - * @since 2.11.0 - */ - @Override - public void setTtlAttachment(String key, Object value) { - ttlAttachment.setTtlAttachment(key, value); - } - - /** - * see {@link TtlAttachments#getTtlAttachment(String)} - * - * @since 2.11.0 - */ - @Override - public T getTtlAttachment(String key) { - return ttlAttachment.getTtlAttachment(key); - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlCopier.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlCopier.java deleted file mode 100644 index 6135a2531..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlCopier.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.fr.third.alibaba.ttl; - -/** - * TtlCopier creates the value when {@link TransmittableThreadLocal.Transmitter#capture()}, - * use the created value when {@link TransmittableThreadLocal.Transmitter#replay(Object)} - * - * @see TransmittableThreadLocal.Transmitter - * @see TransmittableThreadLocal.Transmitter#capture() - * @author Jerry Lee (oldratlee at gmail dot com) - * @since 2.11.0 - */ -@FunctionalInterface -public interface TtlCopier { - /** - * Computes the value for {@link TransmittableThreadLocal} - * or registered {@link ThreadLocal}(registered by {@link TransmittableThreadLocal.Transmitter#registerThreadLocal}) - * as a function of the source thread's value at the time the task - * Object is created. - *

- * This method is called from {@link TtlRunnable} or - * {@link TtlCallable} when it create, before the task is started - * (aka. called when {@link TransmittableThreadLocal.Transmitter#capture()}). - * - * @see TransmittableThreadLocal.Transmitter#registerThreadLocal(ThreadLocal, TtlCopier) - * @see TransmittableThreadLocal.Transmitter#registerThreadLocalWithShadowCopier(ThreadLocal) - * @see TransmittableThreadLocal.Transmitter#unregisterThreadLocal - */ - T copy(T parentValue); -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlEnhanced.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlEnhanced.java deleted file mode 100644 index b4fca536d..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlEnhanced.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.fr.third.alibaba.ttl; - -import com.fr.third.alibaba.ttl.spi.TtlAttachments; - - -/** - * @see TtlAttachments - * @deprecated Use {@link com.fr.third.alibaba.ttl.spi.TtlEnhanced} instead. - */ -@Deprecated - -// [ERROR] The class name com.fr.third.alibaba.ttl.TtlEnhanced shadows -// the simple name of implemented interface com.fr.third.alibaba.ttl.spi.TtlEnhanced [com.fr.third.alibaba.ttl.TtlEnhanced] -public interface TtlEnhanced extends com.fr.third.alibaba.ttl.spi.TtlEnhanced { -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlRecursiveAction.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlRecursiveAction.java deleted file mode 100644 index 4b0b392a1..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlRecursiveAction.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.fr.third.alibaba.ttl; - -import com.fr.third.alibaba.ttl.spi.TtlEnhanced; -import com.fr.third.alibaba.ttl.threadpool.TtlForkJoinPoolHelper; -import com.fr.third.alibaba.ttl.threadpool.agent.TtlAgent; - -import java.util.concurrent.ForkJoinTask; - -import static com.fr.third.alibaba.ttl.TransmittableThreadLocal.Transmitter.*; - -/** - * A recursive resultless {@link ForkJoinTask} enhanced by {@link TransmittableThreadLocal}. - *

- * Recommend to use {@link TtlAgent}; - * Specially for {@code Java 8} {@link java.util.stream.Stream} and {@link java.util.concurrent.CompletableFuture}, - * these async task are executed by {@link java.util.concurrent.ForkJoinPool} via {@link ForkJoinTask} at the bottom. - * - * @author LNAmp - * @see java.util.concurrent.RecursiveAction - * @see TtlForkJoinPoolHelper - * @see TtlAgent - * @since 2.4.0 - */ -public abstract class TtlRecursiveAction extends ForkJoinTask implements TtlEnhanced { - - private static final long serialVersionUID = -5753568484583412377L; - - private final Object captured = capture(); - - protected TtlRecursiveAction() { - } - - /** - * The main computation performed by this task. - */ - protected abstract void compute(); - - /** - * see {@link ForkJoinTask#getRawResult()} - */ - public final Void getRawResult() { - return null; - } - - /** - * see {@link ForkJoinTask#setRawResult(Object)} - */ - protected final void setRawResult(Void mustBeNull) { - } - - /** - * Implements execution conventions for RecursiveActions. - */ - protected final boolean exec() { - Object backup = replay(captured); - try { - compute(); - return true; - } finally { - restore(backup); - } - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlRecursiveTask.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlRecursiveTask.java deleted file mode 100644 index 6869c9aba..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlRecursiveTask.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.fr.third.alibaba.ttl; - -import com.fr.third.alibaba.ttl.spi.TtlEnhanced; -import com.fr.third.alibaba.ttl.threadpool.TtlForkJoinPoolHelper; -import com.fr.third.alibaba.ttl.threadpool.agent.TtlAgent; - -import java.util.concurrent.ForkJoinTask; - -import static com.fr.third.alibaba.ttl.TransmittableThreadLocal.Transmitter.*; - -/** - * A recursive result-bearing {@link ForkJoinTask} enhanced by {@link TransmittableThreadLocal}. - *

- * Recommend to use {@link TtlAgent}; - * Specially for {@code Java 8} {@link java.util.stream.Stream} and {@link java.util.concurrent.CompletableFuture}, - * these async task are executed by {@link java.util.concurrent.ForkJoinPool} via {@link ForkJoinTask} at the bottom. - * - * @author LNAmp - * @see java.util.concurrent.RecursiveTask - * @see TtlForkJoinPoolHelper - * @see TtlAgent - * @since 2.4.0 - */ -public abstract class TtlRecursiveTask extends ForkJoinTask implements TtlEnhanced { - - private static final long serialVersionUID = 1814679366926362436L; - - private final Object captured = capture(); - - protected TtlRecursiveTask() { - } - - /** - * The result of the computation. - */ - V result; - - /** - * The main computation performed by this task. - * - * @return the result of the computation - */ - protected abstract V compute(); - - /** - * see {@link ForkJoinTask#getRawResult()} - */ - public final V getRawResult() { - return result; - } - - /** - * see {@link ForkJoinTask#setRawResult(Object)} - */ - protected final void setRawResult(V value) { - result = value; - } - - /** - * Implements execution conventions for RecursiveTask. - */ - protected final boolean exec() { - Object backup = replay(captured); - try { - result = compute(); - return true; - } finally { - restore(backup); - } - } - -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlRunnable.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlRunnable.java deleted file mode 100644 index cc581bfd1..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlRunnable.java +++ /dev/null @@ -1,260 +0,0 @@ -package com.fr.third.alibaba.ttl; - -import com.fr.third.alibaba.ttl.spi.TtlAttachments; -import com.fr.third.alibaba.ttl.spi.TtlAttachmentsDelegate; -import com.fr.third.alibaba.ttl.spi.TtlEnhanced; -import com.fr.third.alibaba.ttl.spi.TtlWrapper; -import com.fr.third.alibaba.ttl.threadpool.TtlExecutors; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicReference; - -import static com.fr.third.alibaba.ttl.TransmittableThreadLocal.Transmitter.*; - -/** - * {@link TtlRunnable} decorate {@link Runnable}, so as to get {@link TransmittableThreadLocal} - * and transmit it to the time of {@link Runnable} execution, needed when use {@link Runnable} to thread pool. - *

- * Use factory methods {@link #get} / {@link #gets} to create instance. - *

- * Other TTL Wrapper for common {@code Functional Interface} see {@link TtlWrappers}. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see TtlExecutors - * @see TtlWrappers - * @see java.util.concurrent.Executor - * @see java.util.concurrent.ExecutorService - * @see java.util.concurrent.ThreadPoolExecutor - * @see java.util.concurrent.ScheduledThreadPoolExecutor - * @see java.util.concurrent.Executors - * @since 0.9.0 - */ -public final class TtlRunnable implements Runnable, TtlWrapper, TtlEnhanced, TtlAttachments { - private final AtomicReference capturedRef; - private final Runnable runnable; - private final boolean releaseTtlValueReferenceAfterRun; - - private TtlRunnable(Runnable runnable, boolean releaseTtlValueReferenceAfterRun) { - this.capturedRef = new AtomicReference(capture()); - this.runnable = runnable; - this.releaseTtlValueReferenceAfterRun = releaseTtlValueReferenceAfterRun; - } - - /** - * wrap method {@link Runnable#run()}. - */ - @Override - public void run() { - Object captured = capturedRef.get(); - if (captured == null || releaseTtlValueReferenceAfterRun && !capturedRef.compareAndSet(captured, null)) { - throw new IllegalStateException("TTL value reference is released after run!"); - } - - Object backup = replay(captured); - try { - runnable.run(); - } finally { - restore(backup); - } - } - - /** - * return original/unwrapped {@link Runnable}. - */ - - public Runnable getRunnable() { - return unwrap(); - } - - /** - * unwrap to original/unwrapped {@link Runnable}. - * - * @see TtlUnwrap#unwrap(Object) - * @since 2.11.4 - */ - - @Override - public Runnable unwrap() { - return runnable; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - TtlRunnable that = (TtlRunnable) o; - - return runnable.equals(that.runnable); - } - - @Override - public int hashCode() { - return runnable.hashCode(); - } - - @Override - public String toString() { - return this.getClass().getName() + " - " + runnable.toString(); - } - - /** - * Factory method, wrap input {@link Runnable} to {@link TtlRunnable}. - * - * @param runnable input {@link Runnable}. if input is {@code null}, return {@code null}. - * @return Wrapped {@link Runnable} - * @throws IllegalStateException when input is {@link TtlRunnable} already. - */ - - public static TtlRunnable get( Runnable runnable) { - return get(runnable, false, false); - } - - /** - * Factory method, wrap input {@link Runnable} to {@link TtlRunnable}. - * - * @param runnable input {@link Runnable}. if input is {@code null}, return {@code null}. - * @param releaseTtlValueReferenceAfterRun release TTL value reference after run, avoid memory leak even if {@link TtlRunnable} is referred. - * @return Wrapped {@link Runnable} - * @throws IllegalStateException when input is {@link TtlRunnable} already. - */ - - public static TtlRunnable get( Runnable runnable, boolean releaseTtlValueReferenceAfterRun) { - return get(runnable, releaseTtlValueReferenceAfterRun, false); - } - - /** - * Factory method, wrap input {@link Runnable} to {@link TtlRunnable}. - * - * @param runnable input {@link Runnable}. if input is {@code null}, return {@code null}. - * @param releaseTtlValueReferenceAfterRun release TTL value reference after run, avoid memory leak even if {@link TtlRunnable} is referred. - * @param idempotent is idempotent mode or not. if {@code true}, just return input {@link Runnable} when it's {@link TtlRunnable}, - * otherwise throw {@link IllegalStateException}. - * Caution: {@code true} will cover up bugs! DO NOT set, only when you know why. - * @return Wrapped {@link Runnable} - * @throws IllegalStateException when input is {@link TtlRunnable} already and not idempotent. - */ - - public static TtlRunnable get( Runnable runnable, boolean releaseTtlValueReferenceAfterRun, boolean idempotent) { - if (null == runnable) return null; - - if (runnable instanceof TtlEnhanced) { - // avoid redundant decoration, and ensure idempotency - if (idempotent) return (TtlRunnable) runnable; - else throw new IllegalStateException("Already TtlRunnable!"); - } - return new TtlRunnable(runnable, releaseTtlValueReferenceAfterRun); - } - - /** - * wrap input {@link Runnable} Collection to {@link TtlRunnable} Collection. - * - * @param tasks task to be wrapped. if input is {@code null}, return {@code null}. - * @return wrapped tasks - * @throws IllegalStateException when input is {@link TtlRunnable} already. - */ - - public static List gets( Collection tasks) { - return gets(tasks, false, false); - } - - /** - * wrap input {@link Runnable} Collection to {@link TtlRunnable} Collection. - * - * @param tasks task to be wrapped. if input is {@code null}, return {@code null}. - * @param releaseTtlValueReferenceAfterRun release TTL value reference after run, avoid memory leak even if {@link TtlRunnable} is referred. - * @return wrapped tasks - * @throws IllegalStateException when input is {@link TtlRunnable} already. - */ - - public static List gets( Collection tasks, boolean releaseTtlValueReferenceAfterRun) { - return gets(tasks, releaseTtlValueReferenceAfterRun, false); - } - - /** - * wrap input {@link Runnable} Collection to {@link TtlRunnable} Collection. - * - * @param tasks task to be wrapped. if input is {@code null}, return {@code null}. - * @param releaseTtlValueReferenceAfterRun release TTL value reference after run, avoid memory leak even if {@link TtlRunnable} is referred. - * @param idempotent is idempotent mode or not. if {@code true}, just return input {@link Runnable} when it's {@link TtlRunnable}, - * otherwise throw {@link IllegalStateException}. - * Caution: {@code true} will cover up bugs! DO NOT set, only when you know why. - * @return wrapped tasks - * @throws IllegalStateException when input is {@link TtlRunnable} already and not idempotent. - */ - - public static List gets( Collection tasks, boolean releaseTtlValueReferenceAfterRun, boolean idempotent) { - if (null == tasks) return Collections.emptyList(); - - List copy = new ArrayList(); - for (Runnable task : tasks) { - copy.add(TtlRunnable.get(task, releaseTtlValueReferenceAfterRun, idempotent)); - } - return copy; - } - - /** - * Unwrap {@link TtlRunnable} to the original/underneath one. - *

- * this method is {@code null}-safe, when input {@code Runnable} parameter is {@code null}, return {@code null}; - * if input {@code Runnable} parameter is not a {@link TtlRunnable} just return input {@code Runnable}. - *

- * so {@code TtlRunnable.unwrap(TtlRunnable.get(runnable))} will always return the same input {@code runnable} object. - * - * @see #get(Runnable) - * @since 2.10.2 - */ - - public static Runnable unwrap( Runnable runnable) { - if (!(runnable instanceof TtlRunnable)) return runnable; - else return ((TtlRunnable) runnable).getRunnable(); - } - - /** - * Unwrap {@link TtlRunnable} to the original/underneath one for collection. - *

- * Invoke {@link #unwrap(Runnable)} for each element in input collection. - *

- * This method is {@code null}-safe, when input {@code Runnable} parameter is {@code null}, return a empty list. - * - * @see #gets(Collection) - * @see #unwrap(Runnable) - * @since 2.10.2 - */ - - public static List unwraps( Collection tasks) { - if (null == tasks) return Collections.emptyList(); - - List copy = new ArrayList(); - for (Runnable task : tasks) { - if (!(task instanceof TtlRunnable)) copy.add(task); - else copy.add(((TtlRunnable) task).getRunnable()); - } - return copy; - } - - private final TtlAttachmentsDelegate ttlAttachment = new TtlAttachmentsDelegate(); - - /** - * see {@link TtlAttachments#setTtlAttachment(String, Object)} - * - * @since 2.11.0 - */ - @Override - public void setTtlAttachment(String key, Object value) { - ttlAttachment.setTtlAttachment(key, value); - } - - /** - * see {@link TtlAttachments#getTtlAttachment(String)} - * - * @since 2.11.0 - */ - @Override - public T getTtlAttachment(String key) { - return ttlAttachment.getTtlAttachment(key); - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlTimerTask.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlTimerTask.java deleted file mode 100644 index 2e3699a0a..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlTimerTask.java +++ /dev/null @@ -1,193 +0,0 @@ -package com.fr.third.alibaba.ttl; - -import com.fr.third.alibaba.ttl.spi.TtlEnhanced; -import com.fr.third.alibaba.ttl.spi.TtlWrapper; -import com.fr.third.alibaba.ttl.threadpool.agent.TtlAgent; - - - -import java.util.*; -import java.util.concurrent.atomic.AtomicReference; - -import static com.fr.third.alibaba.ttl.TransmittableThreadLocal.Transmitter.*; - -/** - * {@link TtlTimerTask} decorate {@link TimerTask}, so as to get {@link TransmittableThreadLocal} - * and transmit it to the time of {@link TtlTimerTask} execution, needed when use {@link TtlTimerTask} to {@link java.util.TimerTask}. - *

- * Use factory method {@link #get(TimerTask)} to create instance. - *

- * NOTE: - * The {@link TtlTimerTask} make the method {@link TimerTask#scheduledExecutionTime()} in - * the origin {@link TimerTask} lose effectiveness! Use {@link TtlAgent} instead. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see java.util.Timer - * @see TimerTask - * @see Alibaba Java Coding Guidelines - Concurrency - Item 10: [Mandatory] Run multiple TimeTask by using ScheduledExecutorService rather than Timer because Timer will kill all running threads in case of failing to catch exceptions. - * @see TtlAgent - * @since 0.9.1 - * @deprecated Use {@link TtlRunnable}, {@link java.util.concurrent.ScheduledExecutorService} instead of {@link java.util.Timer}, {@link java.util.TimerTask}. - */ -@Deprecated -public final class TtlTimerTask extends TimerTask implements TtlWrapper, com.fr.third.alibaba.ttl.spi.TtlEnhanced { - private final AtomicReference capturedRef; - private final TimerTask timerTask; - private final boolean releaseTtlValueReferenceAfterRun; - - private TtlTimerTask(TimerTask timerTask, boolean releaseTtlValueReferenceAfterRun) { - this.capturedRef = new AtomicReference(capture()); - this.timerTask = timerTask; - this.releaseTtlValueReferenceAfterRun = releaseTtlValueReferenceAfterRun; - } - - /** - * wrap method {@link TimerTask#run()}. - */ - @Override - public void run() { - Object captured = capturedRef.get(); - if (captured == null || releaseTtlValueReferenceAfterRun && !capturedRef.compareAndSet(captured, null)) { - throw new IllegalStateException("TTL value reference is released after run!"); - } - - Object backup = replay(captured); - try { - timerTask.run(); - } finally { - restore(backup); - } - } - - @Override - public boolean cancel() { - timerTask.cancel(); - return super.cancel(); - } - - /** - * return original/unwrapped {@link TimerTask}. - */ - - public TimerTask getTimerTask() { - return unwrap(); - } - - /** - * unwrap to original/unwrapped {@link TimerTask}. - * - * @see TtlUnwrap#unwrap(Object) - * @since 2.11.4 - */ - - @Override - public TimerTask unwrap() { - return timerTask; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - TtlTimerTask that = (TtlTimerTask) o; - - return timerTask.equals(that.timerTask); - } - - @Override - public int hashCode() { - return timerTask != null ? timerTask.hashCode() : 0; - } - - @Override - public String toString() { - return this.getClass().getName() + " - " + timerTask.toString(); - } - - /** - * Factory method, wrap input {@link TimerTask} to {@link TtlTimerTask}. - *

- * This method is idempotent. - * - * @param timerTask input {@link TimerTask} - * @return Wrapped {@link TimerTask} - */ - - public static TtlTimerTask get( TimerTask timerTask) { - return get(timerTask, false, false); - } - - /** - * Factory method, wrap input {@link TimerTask} to {@link TtlTimerTask}. - *

- * This method is idempotent. - * - * @param timerTask input {@link TimerTask} - * @param releaseTtlValueReferenceAfterRun release TTL value reference after run, avoid memory leak even if {@link TtlTimerTask} is referred. - * @return Wrapped {@link TimerTask} - */ - - public static TtlTimerTask get( TimerTask timerTask, boolean releaseTtlValueReferenceAfterRun) { - return get(timerTask, releaseTtlValueReferenceAfterRun, false); - } - - /** - * Factory method, wrap input {@link TimerTask} to {@link TtlTimerTask}. - *

- * This method is idempotent. - * - * @param timerTask input {@link TimerTask} - * @param releaseTtlValueReferenceAfterRun release TTL value reference after run, avoid memory leak even if {@link TtlTimerTask} is referred. - * @param idempotent is idempotent or not. {@code true} will cover up bugs! DO NOT set, only when you know why. - * @return Wrapped {@link TimerTask} - */ - - public static TtlTimerTask get( TimerTask timerTask, boolean releaseTtlValueReferenceAfterRun, boolean idempotent) { - if (null == timerTask) return null; - - if (timerTask instanceof TtlEnhanced) { - // avoid redundant decoration, and ensure idempotency - if (idempotent) return (TtlTimerTask) timerTask; - else throw new IllegalStateException("Already TtlTimerTask!"); - } - return new TtlTimerTask(timerTask, releaseTtlValueReferenceAfterRun); - } - - /** - * Unwrap {@link TtlTimerTask} to the original/underneath one. - *

- * this method is {@code null}-safe, when input {@code TimerTask} parameter is {@code null}, return {@code null}; - * if input {@code TimerTask} parameter is not a {@link TtlTimerTask} just return input {@code TimerTask}. - * - * @see #get(TimerTask) - * @since 2.10.2 - */ - - public static TimerTask unwrap( TimerTask timerTask) { - if (!(timerTask instanceof TtlTimerTask)) return timerTask; - else return ((TtlTimerTask) timerTask).getTimerTask(); - } - - /** - * Unwrap {@link TtlTimerTask} to the original/underneath one. - *

- * Invoke {@link #unwrap(TimerTask)} for each element in input collection. - *

- * This method is {@code null}-safe, when input {@code TimerTask} parameter is {@code null}, return a empty list. - * - * @see #unwrap(TimerTask) - * @since 2.10.2 - */ - - public static List unwraps( Collection tasks) { - if (null == tasks) return Collections.emptyList(); - - List copy = new ArrayList(); - for (TimerTask task : tasks) { - if (!(task instanceof TtlTimerTask)) copy.add(task); - else copy.add(((TtlTimerTask) task).getTimerTask()); - } - return copy; - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlUnwrap.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlUnwrap.java deleted file mode 100644 index db8866bdc..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlUnwrap.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.fr.third.alibaba.ttl; - -import com.fr.third.alibaba.ttl.spi.TtlWrapper; -import com.fr.third.alibaba.ttl.threadpool.TtlExecutors; -import com.fr.third.alibaba.ttl.threadpool.TtlForkJoinPoolHelper; - - -import java.util.concurrent.Callable; - -/** - * Util methods for TTL Wrapper: unwrap TTL Wrapper and check TTL Wrapper. - *

- * Note: - * all methods is {@code null}-safe, when input parameter is {@code null}, return {@code null}. - *

- * Implementation Note: - * The util methods in this class should have been inside {@link TtlWrappers}.
- * But for {@code Java 6} support, it's required splitting the util methods - * which involved {@code Java 8} from {@link TtlWrappers}. - * In order to avoid loading {@code Java 8} class (eg: {@link java.util.function.Consumer}, {@link java.util.function.Supplier}), - * when invoking any methods of {@link TtlWrappers}. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see TtlWrappers - * @see TtlWrapper - * @see TtlRunnable - * @see TtlCallable - * @since 2.11.4 - */ -public class TtlUnwrap { - /** - * Generic unwrap method, unwrap {@code TtlWrapper} to the original/underneath one. - *

- * this method is {@code null}-safe, when input {@code BiFunction} parameter is {@code null}, return {@code null}; - * if input parameter is not a {@code TtlWrapper} just return input. - *

- * so {@code unwrap} will always return the same input object. - * - * @see TtlWrappers#wrap(java.util.function.Supplier) - * @see TtlWrappers#wrap(java.util.function.Consumer) - * @see TtlWrappers#wrap(java.util.function.BiConsumer) - * @see TtlWrappers#wrap(java.util.function.Function) - * @see TtlWrappers#wrap(java.util.function.BiFunction) - * @see TtlRunnable#unwrap(Runnable) - * @see TtlCallable#unwrap(Callable) - * @see TtlExecutors#unwrap(java.util.concurrent.Executor) - * @see TtlExecutors#unwrap(java.util.concurrent.ThreadFactory) - * @see TtlForkJoinPoolHelper#unwrap(java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory) - * @since 2.11.4 - */ - - @SuppressWarnings("unchecked") - public static T unwrap( T obj) { - if (!isWrapper(obj)) return obj; - else return ((TtlWrapper) obj).unwrap(); - } - - /** - * check the input object is a {@code TtlWrapper} or not. - * - * @since 2.11.4 - */ - public static boolean isWrapper( T obj) { - return obj instanceof TtlWrapper; - } - - private TtlUnwrap() { - throw new InstantiationError("Must not instantiate this class"); - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlWrappers.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlWrappers.java deleted file mode 100644 index 79ceddbc0..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/TtlWrappers.java +++ /dev/null @@ -1,342 +0,0 @@ -package com.fr.third.alibaba.ttl; - -import com.fr.third.alibaba.ttl.spi.TtlEnhanced; -import com.fr.third.alibaba.ttl.spi.TtlWrapper; - - - -import java.util.function.*; - -import static com.fr.third.alibaba.ttl.TransmittableThreadLocal.Transmitter.*; - -/** - * Util methods for TTL Wrapper: wrap common {@code Functional Interface}. - *

- * Note: - *

    - *
  • all methods is {@code null}-safe, when input parameter is {@code null}, return {@code null}.
  • - *
  • all wrap method skip wrap (aka. just return input parameter), when input parameter is already wrapped.
  • - *
- * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see TtlRunnable - * @see TtlCallable - * @see TtlUnwrap - * @see TtlWrapper - * @since 2.11.4 - */ -public class TtlWrappers { - /** - * wrap input {@link Supplier} to TTL wrapper. - * - * @param supplier input {@link Supplier} - * @return Wrapped {@link Supplier} - * @see TtlUnwrap#unwrap(Object) - * @since 2.11.4 - */ - - public static Supplier wrap( Supplier supplier) { - if (supplier == null) return null; - else if (supplier instanceof TtlEnhanced) return supplier; - else return new TtlSupplier(supplier); - } - - private static class TtlSupplier implements Supplier, TtlWrapper>, TtlEnhanced { - final Supplier supplier; - final Object captured; - - TtlSupplier(Supplier supplier) { - this.supplier = supplier; - this.captured = capture(); - } - - @Override - public T get() { - final Object backup = replay(captured); - try { - return supplier.get(); - } finally { - restore(backup); - } - } - - - @Override - public Supplier unwrap() { - return supplier; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - TtlSupplier that = (TtlSupplier) o; - - return supplier.equals(that.supplier); - } - - @Override - public int hashCode() { - return supplier.hashCode(); - } - - @Override - public String toString() { - return this.getClass().getName() + " - " + supplier.toString(); - } - } - - - /** - * wrap input {@link Consumer} to TTL wrapper. - * - * @param consumer input {@link Consumer} - * @return Wrapped {@link Consumer} - * @see TtlUnwrap#unwrap(Object) - * @since 2.11.4 - */ - - public static Consumer wrap( Consumer consumer) { - if (consumer == null) return null; - else if (consumer instanceof TtlEnhanced) return consumer; - else return new TtlConsumer(consumer); - } - - private static class TtlConsumer implements Consumer, TtlWrapper>, TtlEnhanced { - final Consumer consumer; - final Object captured; - - TtlConsumer(Consumer consumer) { - this.consumer = consumer; - this.captured = capture(); - } - - @Override - public void accept(T t) { - final Object backup = replay(captured); - try { - consumer.accept(t); - } finally { - restore(backup); - } - } - - - @Override - public Consumer unwrap() { - return consumer; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - TtlConsumer that = (TtlConsumer) o; - - return consumer.equals(that.consumer); - } - - @Override - public int hashCode() { - return consumer.hashCode(); - } - - @Override - public String toString() { - return this.getClass().getName() + " - " + consumer.toString(); - } - } - - - /** - * wrap input {@link BiConsumer} to TTL wrapper. - * - * @param consumer input {@link BiConsumer} - * @return Wrapped {@link BiConsumer} - * @see TtlUnwrap#unwrap(Object) - * @since 2.11.4 - */ - - public static BiConsumer wrap( BiConsumer consumer) { - if (consumer == null) return null; - else if (consumer instanceof TtlEnhanced) return consumer; - else return new TtlBiConsumer(consumer); - } - - private static class TtlBiConsumer implements BiConsumer, TtlWrapper>, TtlEnhanced { - final BiConsumer consumer; - final Object captured; - - TtlBiConsumer(BiConsumer consumer) { - this.consumer = consumer; - this.captured = capture(); - } - - @Override - public void accept(T t, U u) { - final Object backup = replay(captured); - try { - consumer.accept(t, u); - } finally { - restore(backup); - } - } - - - @Override - public BiConsumer unwrap() { - return consumer; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - TtlBiConsumer that = (TtlBiConsumer) o; - - return consumer.equals(that.consumer); - } - - @Override - public int hashCode() { - return consumer.hashCode(); - } - - @Override - public String toString() { - return this.getClass().getName() + " - " + consumer.toString(); - } - } - - - /** - * wrap input {@link Function} to TTL wrapper. - * - * @param fn input {@link Function} - * @return Wrapped {@link Function} - * @see TtlUnwrap#unwrap(Object) - * @since 2.11.4 - */ - - public static Function wrap( Function fn) { - if (fn == null) return null; - else if (fn instanceof TtlEnhanced) return fn; - else return new TtlFunction(fn); - } - - private static class TtlFunction implements Function, TtlWrapper>, TtlEnhanced { - final Function fn; - final Object captured; - - TtlFunction(Function fn) { - this.fn = fn; - this.captured = capture(); - } - - @Override - public R apply(T t) { - final Object backup = replay(captured); - try { - return fn.apply(t); - } finally { - restore(backup); - } - } - - - @Override - public Function unwrap() { - return fn; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - TtlFunction that = (TtlFunction) o; - - return fn.equals(that.fn); - } - - @Override - public int hashCode() { - return fn.hashCode(); - } - - @Override - public String toString() { - return this.getClass().getName() + " - " + fn.toString(); - } - } - - - /** - * wrap input {@link BiFunction} to TTL wrapper. - * - * @param fn input {@link BiFunction} - * @return Wrapped {@link BiFunction} - * @see TtlUnwrap#unwrap(Object) - * @since 2.11.4 - */ - - public static BiFunction wrap( BiFunction fn) { - if (fn == null) return null; - else if (fn instanceof TtlEnhanced) return fn; - else return new TtlBiFunction(fn); - } - - private static class TtlBiFunction implements BiFunction, TtlWrapper>, TtlEnhanced { - final BiFunction fn; - final Object captured; - - TtlBiFunction(BiFunction fn) { - this.fn = fn; - this.captured = capture(); - } - - @Override - public R apply(T t, U u) { - final Object backup = replay(captured); - try { - return fn.apply(t, u); - } finally { - restore(backup); - } - } - - - @Override - public BiFunction unwrap() { - return fn; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - TtlBiFunction that = (TtlBiFunction) o; - - return fn.equals(that.fn); - } - - @Override - public int hashCode() { - return fn.hashCode(); - } - - @Override - public String toString() { - return this.getClass().getName() + " - " + fn.toString(); - } - } - - - private TtlWrappers() { - throw new InstantiationError("Must not instantiate this class"); - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/package-info.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/package-info.java deleted file mode 100644 index d842d0a01..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ -/** - * TTL API. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see com.fr.third.alibaba.ttl.TransmittableThreadLocal - * @see com.fr.third.alibaba.ttl.TtlRunnable - * @see com.fr.third.alibaba.ttl.TtlCallable - */ -package com.fr.third.alibaba.ttl; diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/TtlAttachments.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/TtlAttachments.java deleted file mode 100644 index 73f527710..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/TtlAttachments.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.fr.third.alibaba.ttl.spi; - -import com.fr.third.alibaba.ttl.TtlCallable; -import com.fr.third.alibaba.ttl.TtlRunnable; - -/** - * The TTL attachments for TTL tasks, eg: {@link TtlRunnable}, {@link TtlCallable}. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @since 2.11.0 - */ -public interface TtlAttachments extends TtlEnhanced { - /** - * set the TTL attachments for TTL tasks - * - * @param key attachment key - * @param value attachment value - * @since 2.11.0 - */ - void setTtlAttachment(String key, Object value); - - /** - * get the TTL attachment for TTL tasks - * - * @param key attachment key - * @since 2.11.0 - */ - T getTtlAttachment(String key); - - /** - * The attachment key of TTL task, weather this task is a auto wrapper task. - *

- * so the value of this attachment is a {@code boolean}. - * - * @since 2.11.0 - */ - String KEY_IS_AUTO_WRAPPER = "ttl.is.auto.wrapper"; -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/TtlAttachmentsDelegate.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/TtlAttachmentsDelegate.java deleted file mode 100644 index 9df5d2f85..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/TtlAttachmentsDelegate.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.fr.third.alibaba.ttl.spi; - -import com.fr.third.alibaba.ttl.TtlCallable; -import com.fr.third.alibaba.ttl.TtlRunnable; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * {@link TtlAttachments} delegate/implementation. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see TtlRunnable - * @see TtlCallable - * @since 2.11.0 - */ -public class TtlAttachmentsDelegate implements TtlAttachments { - private final ConcurrentMap attachments = new ConcurrentHashMap(); - - @Override - public void setTtlAttachment(String key, Object value) { - attachments.put(key, value); - } - - @Override - @SuppressWarnings("unchecked") - public T getTtlAttachment(String key) { - return (T) attachments.get(key); - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/TtlEnhanced.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/TtlEnhanced.java deleted file mode 100644 index 2fe90b789..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/TtlEnhanced.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.fr.third.alibaba.ttl.spi; - -import com.fr.third.alibaba.ttl.TtlCallable; -import com.fr.third.alibaba.ttl.TtlRecursiveAction; -import com.fr.third.alibaba.ttl.TtlRecursiveTask; -import com.fr.third.alibaba.ttl.TtlRunnable; - -/** - * a Ttl marker/tag interface, for ttl enhanced class, for example {@code TTL wrapper} like {@link TtlRunnable}, {@link TtlCallable}. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see TtlRunnable - * @see TtlCallable - * @see TtlRecursiveAction - * @see TtlRecursiveTask - * @see TtlAttachments - * @since 2.11.0 - */ -public interface TtlEnhanced { -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/TtlWrapper.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/TtlWrapper.java deleted file mode 100644 index 47da24daf..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/TtlWrapper.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.fr.third.alibaba.ttl.spi; - -import com.fr.third.alibaba.ttl.TtlUnwrap; - -/** - * Ttl Wrapper interface. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see TtlUnwrap#unwrap - * @since 2.11.4 - */ -public interface TtlWrapper extends TtlEnhanced { - /** - * unwrap {@link TtlWrapper} to the original/underneath one. - *

- * this method is {@code null}-safe, when input {@code BiFunction} parameter is {@code null}, return {@code null}; - * if input parameter is not a {@code TtlWrapper} just return input. - *

- * so {@code unwrap} will always return the same input object. - * - * @see TtlUnwrap#unwrap(Object) - */ - - T unwrap(); -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/package-info.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/package-info.java deleted file mode 100644 index 50919ee22..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/spi/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ -/** - * TTL SPI - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see com.fr.third.alibaba.ttl.spi.TtlEnhanced - * @see com.fr.third.alibaba.ttl.spi.TtlAttachments - * @since 2.11.0 - */ -package com.fr.third.alibaba.ttl.spi; diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/DisableInheritableForkJoinWorkerThreadFactory.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/DisableInheritableForkJoinWorkerThreadFactory.java deleted file mode 100644 index 3e5655e57..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/DisableInheritableForkJoinWorkerThreadFactory.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool; - -import com.fr.third.alibaba.ttl.spi.TtlWrapper; - -import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory; - -/** - * Disable inheritable {@link ForkJoinWorkerThreadFactory}. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @since 2.10.1 - */ -public interface DisableInheritableForkJoinWorkerThreadFactory extends ForkJoinWorkerThreadFactory, TtlWrapper { - /** - * Unwrap {@link DisableInheritableThreadFactory} to the original/underneath one. - */ - @Override - - ForkJoinWorkerThreadFactory unwrap(); -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/DisableInheritableForkJoinWorkerThreadFactoryWrapper.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/DisableInheritableForkJoinWorkerThreadFactoryWrapper.java deleted file mode 100644 index 4a5b11d63..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/DisableInheritableForkJoinWorkerThreadFactoryWrapper.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool; - - -import java.util.concurrent.ForkJoinPool; -import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory; -import java.util.concurrent.ForkJoinWorkerThread; - -import static com.fr.third.alibaba.ttl.TransmittableThreadLocal.Transmitter.clear; -import static com.fr.third.alibaba.ttl.TransmittableThreadLocal.Transmitter.restore; - -/** - * @author Jerry Lee (oldratlee at gmail dot com) - * @since 2.10.1 - */ -class DisableInheritableForkJoinWorkerThreadFactoryWrapper implements DisableInheritableForkJoinWorkerThreadFactory { - private final ForkJoinWorkerThreadFactory threadFactory; - - DisableInheritableForkJoinWorkerThreadFactoryWrapper(ForkJoinWorkerThreadFactory threadFactory) { - this.threadFactory = threadFactory; - } - - @Override - public ForkJoinWorkerThread newThread(ForkJoinPool pool) { - final Object backup = clear(); - try { - return threadFactory.newThread(pool); - } finally { - restore(backup); - } - } - - @Override - public ForkJoinWorkerThreadFactory unwrap() { - return threadFactory; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - DisableInheritableForkJoinWorkerThreadFactoryWrapper that = (DisableInheritableForkJoinWorkerThreadFactoryWrapper) o; - - return threadFactory.equals(that.threadFactory); - } - - @Override - public int hashCode() { - return threadFactory.hashCode(); - } - - @Override - public String toString() { - return this.getClass().getName() + " - " + threadFactory.toString(); - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/DisableInheritableThreadFactory.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/DisableInheritableThreadFactory.java deleted file mode 100644 index 6b25fe898..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/DisableInheritableThreadFactory.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool; - -import com.fr.third.alibaba.ttl.spi.TtlWrapper; - -import java.util.concurrent.ThreadFactory; - -/** - * Disable inheritable {@link ThreadFactory}. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see ThreadFactory - * @since 2.10.0 - */ -public interface DisableInheritableThreadFactory extends ThreadFactory, TtlWrapper { - /** - * Unwrap {@link DisableInheritableThreadFactory} to the original/underneath one. - */ - @Override - - ThreadFactory unwrap(); -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/DisableInheritableThreadFactoryWrapper.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/DisableInheritableThreadFactoryWrapper.java deleted file mode 100644 index 95f76b978..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/DisableInheritableThreadFactoryWrapper.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool; - - -import java.util.concurrent.ThreadFactory; - -import static com.fr.third.alibaba.ttl.TransmittableThreadLocal.Transmitter.clear; -import static com.fr.third.alibaba.ttl.TransmittableThreadLocal.Transmitter.restore; - -/** - * @author Jerry Lee (oldratlee at gmail dot com) - * @since 2.10.0 - */ -class DisableInheritableThreadFactoryWrapper implements DisableInheritableThreadFactory { - private final ThreadFactory threadFactory; - - DisableInheritableThreadFactoryWrapper(ThreadFactory threadFactory) { - this.threadFactory = threadFactory; - } - - @Override - public Thread newThread(Runnable r) { - final Object backup = clear(); - try { - return threadFactory.newThread(r); - } finally { - restore(backup); - } - } - - - @Override - public ThreadFactory unwrap() { - return threadFactory; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - DisableInheritableThreadFactoryWrapper that = (DisableInheritableThreadFactoryWrapper) o; - - return threadFactory.equals(that.threadFactory); - } - - @Override - public int hashCode() { - return threadFactory.hashCode(); - } - - @Override - public String toString() { - return this.getClass().getName() + " - " + threadFactory.toString(); - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/ExecutorServiceTtlWrapper.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/ExecutorServiceTtlWrapper.java deleted file mode 100644 index b415395b1..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/ExecutorServiceTtlWrapper.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool; - -import com.fr.third.alibaba.ttl.TransmittableThreadLocal; -import com.fr.third.alibaba.ttl.TtlCallable; -import com.fr.third.alibaba.ttl.TtlRunnable; -import com.fr.third.alibaba.ttl.spi.TtlEnhanced; - -import java.util.Collection; -import java.util.List; -import java.util.concurrent.*; - -/** - * {@link TransmittableThreadLocal} Wrapper of {@link ExecutorService}, - * transmit the {@link TransmittableThreadLocal} from the task submit time of {@link Runnable} or {@link Callable} - * to the execution time of {@link Runnable} or {@link Callable}. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @since 0.9.0 - */ -class ExecutorServiceTtlWrapper extends ExecutorTtlWrapper implements ExecutorService, TtlEnhanced { - private final ExecutorService executorService; - - ExecutorServiceTtlWrapper(ExecutorService executorService) { - super(executorService); - this.executorService = executorService; - } - - @Override - public void shutdown() { - executorService.shutdown(); - } - - - @Override - public List shutdownNow() { - return executorService.shutdownNow(); - } - - @Override - public boolean isShutdown() { - return executorService.isShutdown(); - } - - @Override - public boolean isTerminated() { - return executorService.isTerminated(); - } - - @Override - public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { - return executorService.awaitTermination(timeout, unit); - } - - - @Override - public Future submit(Callable task) { - return executorService.submit(TtlCallable.get(task)); - } - - - @Override - public Future submit(Runnable task, T result) { - return executorService.submit(TtlRunnable.get(task), result); - } - - - @Override - public Future submit(Runnable task) { - return executorService.submit(TtlRunnable.get(task)); - } - - - @Override - public List> invokeAll(Collection> tasks) throws InterruptedException { - return executorService.invokeAll(TtlCallable.gets(tasks)); - } - - - @Override - public List> invokeAll(Collection> tasks, long timeout, TimeUnit unit) throws InterruptedException { - return executorService.invokeAll(TtlCallable.gets(tasks), timeout, unit); - } - - - @Override - public T invokeAny(Collection> tasks) throws InterruptedException, ExecutionException { - return executorService.invokeAny(TtlCallable.gets(tasks)); - } - - @Override - public T invokeAny(Collection> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return executorService.invokeAny(TtlCallable.gets(tasks), timeout, unit); - } - - - @Override - public ExecutorService unwrap() { - return executorService; - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/ExecutorTtlWrapper.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/ExecutorTtlWrapper.java deleted file mode 100644 index ffb3309d7..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/ExecutorTtlWrapper.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool; - -import com.fr.third.alibaba.ttl.TransmittableThreadLocal; -import com.fr.third.alibaba.ttl.TtlRunnable; -import com.fr.third.alibaba.ttl.spi.TtlEnhanced; -import com.fr.third.alibaba.ttl.spi.TtlWrapper; - -import java.util.concurrent.Executor; - -/** - * {@link TransmittableThreadLocal} Wrapper of {@link Executor}, - * transmit the {@link TransmittableThreadLocal} from the task submit time of {@link Runnable} - * to the execution time of {@link Runnable}. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @since 0.9.0 - */ -class ExecutorTtlWrapper implements Executor, TtlWrapper, TtlEnhanced { - private final Executor executor; - - ExecutorTtlWrapper(Executor executor) { - this.executor = executor; - } - - @Override - public void execute(Runnable command) { - executor.execute(TtlRunnable.get(command)); - } - - @Override - - public Executor unwrap() { - return executor; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - ExecutorTtlWrapper that = (ExecutorTtlWrapper) o; - - return executor.equals(that.executor); - } - - @Override - public int hashCode() { - return executor.hashCode(); - } - - @Override - public String toString() { - return this.getClass().getName() + " - " + executor.toString(); - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/ScheduledExecutorServiceTtlWrapper.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/ScheduledExecutorServiceTtlWrapper.java deleted file mode 100644 index a26b67fcb..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/ScheduledExecutorServiceTtlWrapper.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool; - -import com.fr.third.alibaba.ttl.TransmittableThreadLocal; -import com.fr.third.alibaba.ttl.TtlCallable; -import com.fr.third.alibaba.ttl.TtlRunnable; -import com.fr.third.alibaba.ttl.spi.TtlEnhanced; - - -import java.util.concurrent.Callable; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -/** - * {@link TransmittableThreadLocal} Wrapper of {@link ScheduledExecutorService}, - * transmit the {@link TransmittableThreadLocal} from the task submit time of {@link Runnable} or {@link Callable} - * to the execution time of {@link Runnable} or {@link Callable}. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @since 0.9.0 - */ - -class ScheduledExecutorServiceTtlWrapper extends ExecutorServiceTtlWrapper implements ScheduledExecutorService, TtlEnhanced { - final ScheduledExecutorService scheduledExecutorService; - - public ScheduledExecutorServiceTtlWrapper(ScheduledExecutorService scheduledExecutorService) { - super(scheduledExecutorService); - this.scheduledExecutorService = scheduledExecutorService; - } - - - @Override - public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) { - return scheduledExecutorService.schedule(TtlRunnable.get(command), delay, unit); - } - - - @Override - public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) { - return scheduledExecutorService.schedule(TtlCallable.get(callable), delay, unit); - } - - - @Override - public ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { - return scheduledExecutorService.scheduleAtFixedRate(TtlRunnable.get(command), initialDelay, period, unit); - } - - - @Override - public ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { - return scheduledExecutorService.scheduleWithFixedDelay(TtlRunnable.get(command), initialDelay, delay, unit); - } - - @Override - - public ScheduledExecutorService unwrap() { - return scheduledExecutorService; - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/TtlExecutors.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/TtlExecutors.java deleted file mode 100644 index 7d05f0df3..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/TtlExecutors.java +++ /dev/null @@ -1,170 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool; - -import com.fr.third.alibaba.ttl.TransmittableThreadLocal; -import com.fr.third.alibaba.ttl.spi.TtlEnhanced; -import com.fr.third.alibaba.ttl.threadpool.agent.TtlAgent; - -import java.util.concurrent.*; - -/** - * Util methods for TTL wrapper of jdk executors. - * - *

    - *
  1. Factory methods to get TTL wrapper from jdk executors.
  2. - *
  3. unwrap/check methods for TTL wrapper of jdk executors.
  4. - *
  5. wrap/unwrap/check methods to disable Inheritable for {@link ThreadFactory}.
  6. - *
- *

- * Note: - *

    - *
  • all method is {@code null}-safe, when input {@code executor} parameter is {@code null}, return {@code null}.
  • - *
  • skip wrap/decoration thread pool/{@code executor}(aka. just return input {@code executor}) - * when ttl agent is loaded, Or when input {@code executor} is already wrapped/decorated.
  • - *
- * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see java.util.concurrent.Executor - * @see java.util.concurrent.ExecutorService - * @see java.util.concurrent.ThreadPoolExecutor - * @see java.util.concurrent.ScheduledThreadPoolExecutor - * @see java.util.concurrent.Executors - * @see java.util.concurrent.CompletionService - * @see java.util.concurrent.ExecutorCompletionService - * @see ThreadFactory - * @see Executors#defaultThreadFactory() - * @since 0.9.0 - */ -public final class TtlExecutors { - /** - * {@link TransmittableThreadLocal} Wrapper of {@link Executor}, - * transmit the {@link TransmittableThreadLocal} from the task submit time of {@link Runnable} - * to the execution time of {@link Runnable}. - */ - - public static Executor getTtlExecutor( Executor executor) { - if (TtlAgent.isTtlAgentLoaded() || null == executor || executor instanceof TtlEnhanced) { - return executor; - } - return new ExecutorTtlWrapper(executor); - } - - /** - * {@link TransmittableThreadLocal} Wrapper of {@link ExecutorService}, - * transmit the {@link TransmittableThreadLocal} from the task submit time of {@link Runnable} or {@link java.util.concurrent.Callable} - * to the execution time of {@link Runnable} or {@link java.util.concurrent.Callable}. - */ - - public static ExecutorService getTtlExecutorService( ExecutorService executorService) { - if (TtlAgent.isTtlAgentLoaded() || executorService == null || executorService instanceof TtlEnhanced) { - return executorService; - } - return new ExecutorServiceTtlWrapper(executorService); - } - - /** - * {@link TransmittableThreadLocal} Wrapper of {@link ScheduledExecutorService}, - * transmit the {@link TransmittableThreadLocal} from the task submit time of {@link Runnable} or {@link java.util.concurrent.Callable} - * to the execution time of {@link Runnable} or {@link java.util.concurrent.Callable}. - */ - - public static ScheduledExecutorService getTtlScheduledExecutorService( ScheduledExecutorService scheduledExecutorService) { - if (TtlAgent.isTtlAgentLoaded() || scheduledExecutorService == null || scheduledExecutorService instanceof TtlEnhanced) { - return scheduledExecutorService; - } - return new ScheduledExecutorServiceTtlWrapper(scheduledExecutorService); - } - - /** - * check the executor is TTL wrapper executor or not. - *

- * if the parameter executor is TTL wrapper, return {@code true}, otherwise {@code false}. - *

- * NOTE: if input executor is {@code null}, return {@code false}. - * - * @param executor input executor - * @param Executor type - * @see #getTtlExecutor(Executor) - * @see #getTtlExecutorService(ExecutorService) - * @see #getTtlScheduledExecutorService(ScheduledExecutorService) - * @see #unwrap(Executor) - * @since 2.8.0 - */ - public static boolean isTtlWrapper( T executor) { - return executor instanceof TtlEnhanced; - } - - /** - * Unwrap TTL wrapper executor to the original/underneath one. - *

- * if the parameter executor is TTL wrapper, return the original/underneath executor; - * otherwise, just return the input parameter executor. - *

- * NOTE: if input executor is {@code null}, return {@code null}. - * - * @param executor input executor - * @param Executor type - * @see #getTtlExecutor(Executor) - * @see #getTtlExecutorService(ExecutorService) - * @see #getTtlScheduledExecutorService(ScheduledExecutorService) - * @see #isTtlWrapper(Executor) - * @since 2.8.0 - */ - - @SuppressWarnings("unchecked") - public static T unwrap( T executor) { - if (!isTtlWrapper(executor)) return executor; - - return (T) ((ExecutorTtlWrapper) executor).unwrap(); - } - - /** - * Wrapper of {@link ThreadFactory}, disable inheritable. - * - * @param threadFactory input thread factory - * @see DisableInheritableThreadFactory - * @since 2.10.0 - */ - - public static ThreadFactory getDisableInheritableThreadFactory( ThreadFactory threadFactory) { - if (threadFactory == null || isDisableInheritableThreadFactory(threadFactory)) return threadFactory; - - return new DisableInheritableThreadFactoryWrapper(threadFactory); - } - - /** - * Wrapper of {@link Executors#defaultThreadFactory()}, disable inheritable. - * - * @see #getDisableInheritableThreadFactory(ThreadFactory) - * @since 2.10.0 - */ - - public static ThreadFactory getDefaultDisableInheritableThreadFactory() { - return getDisableInheritableThreadFactory(Executors.defaultThreadFactory()); - } - - /** - * check the {@link ThreadFactory} is {@link DisableInheritableThreadFactory} or not. - * - * @see DisableInheritableThreadFactory - * @since 2.10.0 - */ - public static boolean isDisableInheritableThreadFactory( ThreadFactory threadFactory) { - return threadFactory instanceof DisableInheritableThreadFactory; - } - - /** - * Unwrap {@link DisableInheritableThreadFactory} to the original/underneath one. - * - * @see DisableInheritableThreadFactory - * @since 2.10.0 - */ - - public static ThreadFactory unwrap( ThreadFactory threadFactory) { - if (!isDisableInheritableThreadFactory(threadFactory)) return threadFactory; - - return ((DisableInheritableThreadFactory) threadFactory).unwrap(); - } - - private TtlExecutors() { - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/TtlForkJoinPoolHelper.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/TtlForkJoinPoolHelper.java deleted file mode 100644 index dd9bd8104..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/TtlForkJoinPoolHelper.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool; - - -import java.util.concurrent.ForkJoinPool; -import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory; - -/** - * Util methods to wrap/unwrap/check methods to disable Inheritable for {@link ForkJoinWorkerThreadFactory}. - *

- * Note: - *

- * all method is {@code null}-safe, when input parameter(eg: {@link ForkJoinWorkerThreadFactory}) is {@code null}, return {@code null}. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see ForkJoinPool - * @see ForkJoinWorkerThreadFactory - * @see ForkJoinPool#defaultForkJoinWorkerThreadFactory - * @since 2.10.1 - */ -public class TtlForkJoinPoolHelper { - /** - * Wrapper of {@link ForkJoinWorkerThreadFactory}, disable inheritable. - * - * @param threadFactory input thread factory - * @see DisableInheritableForkJoinWorkerThreadFactory - * @since 2.10.1 - */ - - public static ForkJoinWorkerThreadFactory getDisableInheritableForkJoinWorkerThreadFactory( ForkJoinWorkerThreadFactory threadFactory) { - if (threadFactory == null || isDisableInheritableForkJoinWorkerThreadFactory(threadFactory)) - return threadFactory; - - return new DisableInheritableForkJoinWorkerThreadFactoryWrapper(threadFactory); - } - - /** - * Wrapper of {@link ForkJoinPool#defaultForkJoinWorkerThreadFactory}, disable inheritable. - * - * @see #getDisableInheritableForkJoinWorkerThreadFactory(ForkJoinWorkerThreadFactory) - * @since 2.10.1 - */ - - public static ForkJoinWorkerThreadFactory getDefaultDisableInheritableForkJoinWorkerThreadFactory() { - return getDisableInheritableForkJoinWorkerThreadFactory(ForkJoinPool.defaultForkJoinWorkerThreadFactory); - } - - /** - * check the {@link ForkJoinWorkerThreadFactory} is {@link DisableInheritableForkJoinWorkerThreadFactory} or not. - * - * @see DisableInheritableForkJoinWorkerThreadFactory - * @since 2.10.1 - */ - public static boolean isDisableInheritableForkJoinWorkerThreadFactory( ForkJoinWorkerThreadFactory threadFactory) { - return threadFactory instanceof DisableInheritableForkJoinWorkerThreadFactory; - } - - /** - * Unwrap {@link DisableInheritableForkJoinWorkerThreadFactory} to the original/underneath one. - * - * @see DisableInheritableForkJoinWorkerThreadFactory - * @since 2.10.1 - */ - - public static ForkJoinWorkerThreadFactory unwrap( ForkJoinWorkerThreadFactory threadFactory) { - if (!isDisableInheritableForkJoinWorkerThreadFactory(threadFactory)) return threadFactory; - - return ((DisableInheritableForkJoinWorkerThreadFactory) threadFactory).unwrap(); - } - - private TtlForkJoinPoolHelper() { - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/TtlUtils.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/TtlUtils.java deleted file mode 100644 index 6f7d9830c..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/TtlUtils.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool; - -import com.fr.third.alibaba.ttl.TtlRunnable; -import com.fr.third.alibaba.ttl.spi.TtlAttachments; -import com.fr.third.alibaba.ttl.spi.TtlEnhanced; - -import static com.fr.third.alibaba.ttl.TransmittableThreadLocal.Transmitter.capture; - - -public class TtlUtils { - public static Object doCaptureWhenNotTtlEnhanced( Object obj) { - if (obj instanceof TtlEnhanced) return null; - else return capture(); - } - - public static void setAutoWrapperAttachment( Object ttlAttachment) { - if (notTtlAttachments(ttlAttachment)) return; - ((TtlAttachments) ttlAttachment).setTtlAttachment(TtlAttachments.KEY_IS_AUTO_WRAPPER, true); - } - - - public static Runnable unwrapIfIsAutoWrapper( Runnable runnable) { - if (isAutoWrapper(runnable)) return TtlRunnable.unwrap(runnable); - else return runnable; - } - - private static boolean notTtlAttachments( Object ttlAttachment) { - return !(ttlAttachment instanceof TtlAttachments); - } - - private static boolean isAutoWrapper( Runnable ttlAttachments) { - if (notTtlAttachments(ttlAttachments)) return false; - - final Boolean value = ((TtlAttachments) ttlAttachments).getTtlAttachment(TtlAttachments.KEY_IS_AUTO_WRAPPER); - if (value == null) return false; - - return value; - } -} \ No newline at end of file diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/TtlAgent.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/TtlAgent.java deleted file mode 100644 index cd3740a07..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/TtlAgent.java +++ /dev/null @@ -1,239 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool.agent; - -import com.fr.third.alibaba.ttl.TransmittableThreadLocal; -import com.fr.third.alibaba.ttl.threadpool.agent.internal.logging.Logger; -import com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.JavassistTransformlet; -import com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.impl.TtlExecutorTransformlet; -import com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.impl.TtlForkJoinTransformlet; -import com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.impl.TtlTimerTaskTransformlet; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.instrument.Instrumentation; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; - -/** - * TTL Java Agent. - *

- * The configuration/arguments for agent see the javadoc of {@link #premain(String, Instrumentation)} - *

- * NOTE:
- * Since {@code v2.6.0}, TTL agent jar will auto add self to {@code boot classpath}. - * But you should NOT modify the downloaded TTL jar file name in the maven repo(eg: {@code transmittable-thread-local-2.x.x.jar}).
- * if you modified the downloaded TTL agent jar file name(eg: {@code ttl-foo-name-changed.jar}), - * you must add TTL agent jar to {@code boot classpath} manually - * by java option {@code -Xbootclasspath/a:path/to/ttl-foo-name-changed.jar}. - *

- * The implementation of auto adding self agent jar to {@code boot classpath} use - * the {@code Boot-Class-Path} property of manifest file({@code META-INF/MANIFEST.MF}) in the TTL Java Agent Jar: - *

- *
- *
Boot-Class-Path
- *
- * A list of paths to be searched by the bootstrap class loader. Paths represent directories or libraries (commonly referred to as JAR or zip libraries on many platforms). - * These paths are searched by the bootstrap class loader after the platform specific mechanisms of locating a class have failed. Paths are searched in the order listed. - *
- *
- *
- *

- * More info about {@code Boot-Class-Path} see - * The mechanism for instrumentation. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see TransmittableThreadLocal - * @see Instrumentation - * @see The mechanism for instrumentation - * @see JAR File Specification - JAR Manifest - * @see Working with Manifest Files - The Java™ TutorialsHide - * @since 0.9.0 - */ -public final class TtlAgent { - /** - * Entrance method of TTL Java Agent. - * - *

TTL Agent configuration

- * Configure TTL agent via agent arguments, format is {@code k1:v1,k2:v2}. Below is available configuration keys. - * - *

Disable inheritable for thread pool

- *

- * Enable "disable inheritable" for thread pool, config by key {@code ttl.agent.disable.inheritable.for.thread.pool}. - * When no configuration for this key, default does not enabled. Since version {@code 2.10.1}. - * - *

    - *
  • rewrite the {@link java.util.concurrent.ThreadFactory} constructor parameter - * of {@link java.util.concurrent.ThreadPoolExecutor} - * to {@link DisableInheritableThreadFactory} - * by util method {@link TtlExecutors#getDisableInheritableThreadFactory(java.util.concurrent.ThreadFactory)}. - *
  • - *
  • rewrite the {@link java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory} constructor parameter - * of {@link java.util.concurrent.ForkJoinPool} - * to {@link DisableInheritableForkJoinWorkerThreadFactory} - * by util method {@link TtlForkJoinPoolHelper#getDisableInheritableForkJoinWorkerThreadFactory(java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory)}. - *
  • - *
- * More info about "disable inheritable" see {@link TransmittableThreadLocal}. - *

- * Configuration example:
- * {@code -javaagent:/path/to/transmittable-thread-local-2.x.x.jar=ttl.agent.disable.inheritable.for.thread.pool:true} - * - *

The log configuration

- * The log of TTL Java Agent is config by key {@code ttl.agent.logger}. Since version {@code 2.6.0}. - * - *
    - *
  • {@code ttl.agent.logger : STDERR}
    - * only log to {@code stderr} when error. - * This is default, when no/unrecognized configuration for key {@code ttl.agent.logger}.
  • - *
  • {@code ttl.agent.logger : STDOUT}
    - * Log to {@code stdout}, more info than {@code ttl.agent.logger:STDERR}; This is needed when developing.
  • - *
- *

- * configuration example: - *

    - *
  • {@code -javaagent:/path/to/transmittable-thread-local-2.x.x.jar}
  • - *
  • {@code -javaagent:/path/to/transmittable-thread-local-2.x.x.jar=ttl.agent.logger:STDOUT}
  • - *
- * - *

Enable/disable TimerTask class decoration

- * Enable/disable TimerTask class decoration is config by key {@code ttl.agent.enable.timer.task}. - * Since version {@code 2.7.0}. - *

- * When no configuration for this key, default is enabled.
- * Note: Since version {@code 2.11.2} the default value is {@code true}(enable TimerTask class decoration); - * Before version {@code 2.11.1} default value is {@code false}. - *

- * Configuration example: - *

    - *
  • {@code -javaagent:/path/to/transmittable-thread-local-2.x.x.jar=ttl.agent.enable.timer.task:false}
  • - *
  • {@code -javaagent:/path/to/transmittable-thread-local-2.x.x.jar=ttl.agent.enable.timer.task:true}
  • - *
- * - *

Multi key configuration example

- * {@code -javaagent:/path/to/transmittable-thread-local-2.x.x.jar=ttl.agent.logger:STDOUT,ttl.agent.disable.inheritable.for.thread.pool:true} - * - * @see java.util.concurrent.ThreadPoolExecutor - * @see java.util.concurrent.ScheduledThreadPoolExecutor - * @see java.util.concurrent.ForkJoinPool - * @see java.util.TimerTask - * @see Logger - * @see Logger#TTL_AGENT_LOGGER_KEY - * @see Logger#STDERR - * @see Logger#STDOUT - */ - public static void premain(String agentArgs, Instrumentation inst) { - kvs = splitCommaColonStringToKV(agentArgs); - - Logger.setLoggerImplType(getLogImplTypeFromAgentArgs(kvs)); - final Logger logger = Logger.getLogger(TtlAgent.class); - - try { - logger.info("[TtlAgent.premain] begin, agentArgs: " + agentArgs + ", Instrumentation: " + inst); - final boolean disableInheritableForThreadPool = isDisableInheritableForThreadPool(); - - final List transformletList = new ArrayList(); - transformletList.add(new TtlExecutorTransformlet(disableInheritableForThreadPool)); - transformletList.add(new TtlForkJoinTransformlet(disableInheritableForThreadPool)); - if (isEnableTimerTask()) transformletList.add(new TtlTimerTaskTransformlet()); - - final ClassFileTransformer transformer = new TtlTransformer(transformletList); - inst.addTransformer(transformer, true); - logger.info("[TtlAgent.premain] addTransformer " + transformer.getClass() + " success"); - - logger.info("[TtlAgent.premain] end"); - - ttlAgentLoaded = true; - } catch (Exception e) { - String msg = "Fail to load TtlAgent , cause: " + e.toString(); - logger.log(Level.SEVERE, msg, e); - throw new IllegalStateException(msg, e); - } - } - - private static String getLogImplTypeFromAgentArgs(final Map kvs) { - return kvs.get(Logger.TTL_AGENT_LOGGER_KEY); - } - - private static volatile Map kvs; - - private static volatile boolean ttlAgentLoaded = false; - - /** - * Whether TTL agent is loaded. - * - * @since 2.9.0 - */ - public static boolean isTtlAgentLoaded() { - return ttlAgentLoaded; - } - - private static final String TTL_AGENT_ENABLE_TIMER_TASK_KEY = "ttl.agent.enable.timer.task"; - - private static final String TTL_AGENT_DISABLE_INHERITABLE_FOR_THREAD_POOL = "ttl.agent.disable.inheritable.for.thread.pool"; - - /** - * Whether disable inheritable for thread pool is enhanced by ttl agent, check {@link #isTtlAgentLoaded()} first. - * - * @see TtlExecutors#getDefaultDisableInheritableThreadFactory() - * @see TtlExecutors#getDisableInheritableThreadFactory(java.util.concurrent.ThreadFactory) - * @see DisableInheritableThreadFactory - * @see TtlForkJoinPoolHelper#getDefaultDisableInheritableForkJoinWorkerThreadFactory() - * @see TtlForkJoinPoolHelper#getDisableInheritableForkJoinWorkerThreadFactory(java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory) - * @see DisableInheritableForkJoinWorkerThreadFactory - * @since 2.10.1 - */ - public static boolean isDisableInheritableForThreadPool() { - return isOptionSetOrFalse(kvs, TTL_AGENT_DISABLE_INHERITABLE_FOR_THREAD_POOL); - } - - /** - * Whether timer task is enhanced by ttl agent, check {@link #isTtlAgentLoaded()} first. - * - * @since 2.10.1 - */ - public static boolean isEnableTimerTask() { - return isOptionSetOrTrue(kvs, TTL_AGENT_ENABLE_TIMER_TASK_KEY); - } - - private static boolean isOptionSetOrFalse( final Map kvs, String key) { - return isOptionSetOrFalse(kvs, key, false); - } - - private static boolean isOptionSetOrTrue( final Map kvs, String key) { - return isOptionSetOrFalse(kvs, key, true); - } - - private static boolean isOptionSetOrFalse( final Map kvs, String key, boolean defaultValue) { - if (null == kvs) return defaultValue; - - final boolean hasEnableKey = kvs.containsKey(key); - if (!hasEnableKey) return defaultValue; - - return !"false".equalsIgnoreCase(kvs.get(key)); - } - - /** - * Split to {@code json} like String({@code "k1:v1,k2:v2"}) to KV map({@code "k1"->"v1", "k2"->"v2"}). - */ - - static Map splitCommaColonStringToKV( String commaColonString) { - Map ret = new HashMap(); - if (commaColonString == null || commaColonString.trim().length() == 0) return ret; - - final String[] splitKvArray = commaColonString.trim().split("\\s*,\\s*"); - for (String kvString : splitKvArray) { - final String[] kv = kvString.trim().split("\\s*:\\s*"); - if (kv.length == 0) continue; - - if (kv.length == 1) ret.put(kv[0], ""); - else ret.put(kv[0], kv[1]); - } - - return ret; - } - - private TtlAgent() { - throw new InstantiationError("Must not instantiate this class"); - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/TtlTransformer.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/TtlTransformer.java deleted file mode 100644 index a38628bb8..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/TtlTransformer.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool.agent; - -import com.fr.third.alibaba.ttl.threadpool.agent.internal.logging.Logger; -import com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.ClassInfo; -import com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.JavassistTransformlet; - - -import java.lang.instrument.ClassFileTransformer; -import java.security.ProtectionDomain; -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Level; - -/** - * TTL {@link ClassFileTransformer} of Java Agent - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see ClassFileTransformer - * @see The mechanism for instrumentation - * @since 0.9.0 - */ -public class TtlTransformer implements ClassFileTransformer { - private static final Logger logger = Logger.getLogger(TtlTransformer.class); - - /** - * "null if no transform is performed", - * see {@code @return} of {@link ClassFileTransformer#transform(ClassLoader, String, Class, ProtectionDomain, byte[])} - */ - - // [ERROR] com.fr.third.alibaba.ttl.threadpool.agent.TtlTransformer.transform(ClassLoader, String, Class, ProtectionDomain, byte[]) - // may expose internal representation by returning TtlTransformer.NO_TRANSFORM - // the value is null, so there is NO "EI_EXPOSE_REP" problem actually. - private static final byte[] NO_TRANSFORM = null; - - private final List transformletList = new ArrayList(); - - TtlTransformer(List transformletList) { - for (JavassistTransformlet transformlet : transformletList) { - this.transformletList.add(transformlet); - logger.info("[TtlTransformer] add Transformlet " + transformlet.getClass() + " success"); - } - } - - @Override - public final byte[] transform( final ClassLoader loader, final String classFile, final Class classBeingRedefined, - final ProtectionDomain protectionDomain, final byte[] classFileBuffer) { - try { - // Lambda has no class file, no need to transform, just return. - if (classFile == null) return NO_TRANSFORM; - - final String className = toClassName(classFile); - - ClassInfo classInfo = new ClassInfo(className, classFileBuffer, loader); - - for (JavassistTransformlet transformlet : transformletList) { - transformlet.doTransform(classInfo); - if (classInfo.isModified()) return classInfo.getCtClass().toBytecode(); - } - } catch (Throwable t) { - String msg = "Fail to transform class " + classFile + ", cause: " + t.toString(); - logger.log(Level.SEVERE, msg, t); - throw new IllegalStateException(msg, t); - } - - return NO_TRANSFORM; - } - - private static String toClassName(final String classFile) { - return classFile.replace('/', '.'); - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/logging/Logger.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/logging/Logger.java deleted file mode 100644 index 74a11957b..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/logging/Logger.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool.agent.internal.logging; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.logging.Level; - -/** - * logger adaptor for ttl java agent, internal use for ttl usage only! - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @since 2.6.0 - */ -public abstract class Logger { - public static final String TTL_AGENT_LOGGER_KEY = "ttl.agent.logger"; - public static final String STDOUT = "STDOUT"; - public static final String STDERR = "STDERR"; - - private static volatile int loggerImplType = -1; - - public static void setLoggerImplType(String type) { - if (loggerImplType != -1) { - throw new IllegalStateException("TTL logger implementation type is already set! type = " + loggerImplType); - } - - if (STDERR.equalsIgnoreCase(type)) loggerImplType = 0; - else if (STDOUT.equalsIgnoreCase(type)) loggerImplType = 1; - else loggerImplType = 0; - } - - public static Logger getLogger(Class clazz) { - if (loggerImplType == -1) throw new IllegalStateException("TTL logger implementation type is NOT set!"); - - switch (loggerImplType) { - case 1: - return new StdOutLogger(clazz); - default: - return new StdErrorLogger(clazz); - } - } - - final Class logClass; - - private Logger(Class logClass) { - this.logClass = logClass; - } - - public void info(String msg) { - log(Level.INFO, msg, null); - } - - public abstract void log(Level level, String msg, Throwable thrown); - - private static class StdErrorLogger extends Logger { - StdErrorLogger(Class clazz) { - super(clazz); - } - - @Override - public void log(Level level, String msg, Throwable thrown) { - if (level == Level.SEVERE) { - final String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()); - System.err.printf("%s %s [%s] %s: %s%n", time, level, Thread.currentThread().getName(), logClass.getSimpleName(), msg); - if (thrown != null) thrown.printStackTrace(); - } - } - } - - private static class StdOutLogger extends Logger { - StdOutLogger(Class clazz) { - super(clazz); - } - - @Override - public void log(Level level, String msg, Throwable thrown) { - final String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()); - System.out.printf("%s %s [%s] %s: %s%n", time, level, Thread.currentThread().getName(), logClass.getSimpleName(), msg); - if (thrown != null) thrown.printStackTrace(System.out); - } - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/ClassInfo.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/ClassInfo.java deleted file mode 100644 index e65c6673e..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/ClassInfo.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet; - -import com.fr.third.javassist.CtClass; -import com.fr.third.javassist.ClassPool; -import com.fr.third.javassist.LoaderClassPath; -import com.fr.third.javassist.NotFoundException; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; - -/** - * @author Jerry Lee (oldratlee at gmail dot com) - * @since 2.11.0 - */ -public class ClassInfo { - private final String className; - private final byte[] classFileBuffer; - private final ClassLoader loader; - private static Set paths = new CopyOnWriteArraySet<>(); - - // SuppressFBWarnings for classFileBuffer parameter: - // [ERROR] new com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.ClassInfo(String, byte[], ClassLoader) - // may expose internal representation by storing an externally mutable object - // into ClassInfo.classFileBuffer - public ClassInfo(String className, byte[] classFileBuffer, ClassLoader loader) { - this.className = className; - this.classFileBuffer = classFileBuffer; - this.loader = loader; - } - - - public String getClassName() { - return className; - } - - private CtClass ctClass; - - - public CtClass getCtClass() throws IOException { - if (ctClass != null) return ctClass; - - final ClassPool classPool = new ClassPool(true); - if (loader == null) { - classPool.appendClassPath(new LoaderClassPath(ClassLoader.getSystemClassLoader())); - } else { - classPool.appendClassPath(new LoaderClassPath(loader)); - } - for (String path: paths) { - try { - classPool.appendClassPath(path); - } catch (NotFoundException e) { - e.printStackTrace(); - } - } - final CtClass clazz = classPool.makeClass(new ByteArrayInputStream(classFileBuffer), false); - clazz.defrost(); - - this.ctClass = clazz; - return clazz; - } - - private boolean modified = false; - - public boolean isModified() { - return modified; - } - - public void setModified() { - this.modified = true; - } - - public static void addPath(String path) { - paths.add(path); - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/JavassistTransformlet.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/JavassistTransformlet.java deleted file mode 100644 index eca3e756d..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/JavassistTransformlet.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet; - -import com.fr.third.javassist.CannotCompileException; -import com.fr.third.javassist.NotFoundException; - -import java.io.IOException; - -/** - * TTL {@code Transformlet} by {@code Javassist}. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @since 2.5.1 - */ -public interface JavassistTransformlet { - void doTransform(ClassInfo classInfo) throws IOException, NotFoundException, CannotCompileException; -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/impl/TtlExecutorTransformlet.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/impl/TtlExecutorTransformlet.java deleted file mode 100644 index 1d6a9a566..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/impl/TtlExecutorTransformlet.java +++ /dev/null @@ -1,160 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.impl; - -import com.fr.third.alibaba.ttl.threadpool.agent.internal.logging.Logger; -import com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.ClassInfo; -import com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.JavassistTransformlet; -import com.fr.third.javassist.*; - -import java.io.IOException; -import java.lang.reflect.Modifier; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Callable; - -/** - * TTL {@link JavassistTransformlet} for {@link java.util.concurrent.Executor}. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @author wuwen5 (wuwen.55 at aliyun dot com) - * @see java.util.concurrent.Executor - * @see java.util.concurrent.ExecutorService - * @see java.util.concurrent.ThreadPoolExecutor - * @see java.util.concurrent.ScheduledThreadPoolExecutor - * @see java.util.concurrent.Executors - * @since 2.5.1 - */ -public class TtlExecutorTransformlet implements JavassistTransformlet { - private static final Logger logger = Logger.getLogger(TtlExecutorTransformlet.class); - - private static Set EXECUTOR_CLASS_NAMES = new HashSet(); - private static final Map PARAM_TYPE_NAME_TO_DECORATE_METHOD_CLASS = new HashMap(); - - private static final String THREAD_POOL_EXECUTOR_CLASS_NAME = "java.util.concurrent.ThreadPoolExecutor"; - private static final String RUNNABLE_CLASS_NAME = "java.lang.Runnable"; - - static { - EXECUTOR_CLASS_NAMES.add(THREAD_POOL_EXECUTOR_CLASS_NAME); - EXECUTOR_CLASS_NAMES.add("java.util.concurrent.ScheduledThreadPoolExecutor"); - - PARAM_TYPE_NAME_TO_DECORATE_METHOD_CLASS.put(RUNNABLE_CLASS_NAME, "com.fr.third.alibaba.ttl.TtlRunnable"); - PARAM_TYPE_NAME_TO_DECORATE_METHOD_CLASS.put("java.util.concurrent.Callable", "com.fr.third.alibaba.ttl.TtlCallable"); - } - - private static final String THREAD_FACTORY_CLASS_NAME = "java.util.concurrent.ThreadFactory"; - - private final boolean disableInheritableForThreadPool; - - public TtlExecutorTransformlet(boolean disableInheritableForThreadPool) { - this.disableInheritableForThreadPool = disableInheritableForThreadPool; - } - - @Override - public void doTransform(final ClassInfo classInfo) throws IOException, NotFoundException, CannotCompileException { - if (EXECUTOR_CLASS_NAMES.contains(classInfo.getClassName())) { - final CtClass clazz = classInfo.getCtClass(); - - for (CtMethod method : clazz.getDeclaredMethods()) { - updateSubmitMethodsOfExecutorClass_decorateToTtlWrapperAndSetAutoWrapperAttachment(method); - } - - if (disableInheritableForThreadPool) updateConstructorDisableInheritable(clazz); - - classInfo.setModified(); - } else { - final CtClass clazz = classInfo.getCtClass(); - - if (clazz.isPrimitive() || clazz.isArray() || clazz.isInterface() || clazz.isAnnotation()) { - return; - } - if (!clazz.subclassOf(clazz.getClassPool().get(THREAD_POOL_EXECUTOR_CLASS_NAME))) return; - - logger.info("Transforming class " + classInfo.getClassName()); - - final boolean modified = updateBeforeAndAfterExecuteMethodOfExecutorSubclass(clazz); - if (modified) classInfo.setModified(); - } - } - - /** - * @see TtlRunnable#get(Runnable, boolean, boolean) - * @see TtlCallable#get(Callable, boolean, boolean) - * @see com.fr.third.alibaba.ttl.threadpool.TtlUtils#setAutoWrapperAttachment(Object) - */ - // [ERROR] Format string should use %n rather than \n - private void updateSubmitMethodsOfExecutorClass_decorateToTtlWrapperAndSetAutoWrapperAttachment(final CtMethod method) throws NotFoundException, CannotCompileException { - final int modifiers = method.getModifiers(); - if (!Modifier.isPublic(modifiers) || Modifier.isStatic(modifiers)) return; - - CtClass[] parameterTypes = method.getParameterTypes(); - StringBuilder insertCode = new StringBuilder(); - for (int i = 0; i < parameterTypes.length; i++) { - final String paramTypeName = parameterTypes[i].getName(); - if (PARAM_TYPE_NAME_TO_DECORATE_METHOD_CLASS.containsKey(paramTypeName)) { - String code = String.format( - // decorate to TTL wrapper, - // and then set AutoWrapper attachment/Tag - "$%d = %s.get($%d, false, true);" - + "\ncom.fr.third.alibaba.ttl.threadpool.TtlUtils.setAutoWrapperAttachment($% 0) method.insertBefore(insertCode.toString()); - } - - /** - * @see TtlExecutors#getDisableInheritableThreadFactory(java.util.concurrent.ThreadFactory) - */ - private void updateConstructorDisableInheritable(final CtClass clazz) throws NotFoundException, CannotCompileException { - for (CtConstructor constructor : clazz.getDeclaredConstructors()) { - final CtClass[] parameterTypes = constructor.getParameterTypes(); - final StringBuilder insertCode = new StringBuilder(); - for (int i = 0; i < parameterTypes.length; i++) { - final String paramTypeName = parameterTypes[i].getName(); - if (THREAD_FACTORY_CLASS_NAME.equals(paramTypeName)) { - String code = String.format("$%d = com.fr.third.alibaba.ttl.threadpool.TtlExecutors.getDisableInheritableThreadFactory($% 0) constructor.insertBefore(insertCode.toString()); - } - } - - /** - * @see com.fr.third.alibaba.ttl.threadpool.TtlUtils#unwrapIfIsAutoWrapper(Runnable) - */ - private boolean updateBeforeAndAfterExecuteMethodOfExecutorSubclass(final CtClass clazz) throws NotFoundException, CannotCompileException { - final CtClass runnableClass = clazz.getClassPool().get(RUNNABLE_CLASS_NAME); - final CtClass threadClass = clazz.getClassPool().get("java.lang.Thread"); - final CtClass throwableClass = clazz.getClassPool().get("java.lang.Throwable"); - boolean modified = false; - - try { - final CtMethod beforeExecute = clazz.getDeclaredMethod("beforeExecute", new CtClass[]{threadClass, runnableClass}); - // unwrap runnable if IsAutoWrapper - String code = "$2 = com.fr.third.alibaba.ttl.threadpool.TtlUtils.unwrapIfIsAutoWrapper($2);"; - logger.info("insert code before method " + Utils.signatureOfMethod(beforeExecute) + " of class " + beforeExecute.getDeclaringClass().getName() + ": " + code); - beforeExecute.insertBefore(code); - modified = true; - } catch (NotFoundException e) { - // clazz does not override beforeExecute method, do nothing. - } - - try { - final CtMethod afterExecute = clazz.getDeclaredMethod("afterExecute", new CtClass[]{runnableClass, throwableClass}); - // unwrap runnable if IsAutoWrapper - String code = "$1 = com.fr.third.alibaba.ttl.threadpool.TtlUtils.unwrapIfIsAutoWrapper($1);"; - logger.info("insert code before method " + Utils.signatureOfMethod(afterExecute) + " of class " + afterExecute.getDeclaringClass().getName() + ": " + code); - afterExecute.insertBefore(code); - modified = true; - } catch (NotFoundException e) { - // clazz does not override afterExecute method, do nothing. - } - - return modified; - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/impl/TtlForkJoinTransformlet.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/impl/TtlForkJoinTransformlet.java deleted file mode 100644 index e20e3401f..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/impl/TtlForkJoinTransformlet.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.impl; - -import com.fr.third.alibaba.ttl.threadpool.agent.internal.logging.Logger; -import com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.ClassInfo; -import com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.JavassistTransformlet; -import com.fr.third.javassist.*; - -import java.io.IOException; - -/** - * TTL {@link JavassistTransformlet} for {@link java.util.concurrent.ForkJoinTask}. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @author wuwen5 (wuwen.55 at aliyun dot com) - * @see java.util.concurrent.ForkJoinPool - * @see java.util.concurrent.ForkJoinTask - * @since 2.5.1 - */ -public class TtlForkJoinTransformlet implements JavassistTransformlet { - private static final Logger logger = Logger.getLogger(TtlForkJoinTransformlet.class); - - private static final String FORK_JOIN_TASK_CLASS_NAME = "java.util.concurrent.ForkJoinTask"; - private static final String FORK_JOIN_POOL_CLASS_NAME = "java.util.concurrent.ForkJoinPool"; - private static final String FORK_JOIN_WORKER_THREAD_FACTORY_CLASS_NAME = "java.util.concurrent.ForkJoinPool$ForkJoinWorkerThreadFactory"; - - private final boolean disableInheritableForThreadPool; - - public TtlForkJoinTransformlet(boolean disableInheritableForThreadPool) { - this.disableInheritableForThreadPool = disableInheritableForThreadPool; - } - - @Override - public void doTransform(final ClassInfo classInfo) throws IOException, NotFoundException, CannotCompileException { - if (FORK_JOIN_TASK_CLASS_NAME.equals(classInfo.getClassName())) { - updateForkJoinTaskClass(classInfo.getCtClass()); - classInfo.setModified(); - } else if (disableInheritableForThreadPool && FORK_JOIN_POOL_CLASS_NAME.equals(classInfo.getClassName())) { - updateConstructorDisableInheritable(classInfo.getCtClass()); - classInfo.setModified(); - } - } - - /** - * @see com.fr.third.alibaba.ttl.threadpool.TtlUtils#doCaptureWhenNotTtlEnhanced(java.lang.Object) - */ - private void updateForkJoinTaskClass(final CtClass clazz) throws CannotCompileException, NotFoundException { - final String className = clazz.getName(); - - // add new field - final String capturedFieldName = "captured$field$added$by$ttl"; - final CtField capturedField = CtField.make("private final Object " + capturedFieldName + ";", clazz); - clazz.addField(capturedField, "com.fr.third.alibaba.ttl.threadpool.TtlUtils.doCaptureWhenNotTtlEnhanced(this);"); - logger.info("add new field " + capturedFieldName + " to class " + className); - - final CtMethod doExecMethod = clazz.getDeclaredMethod("doExec", new CtClass[0]); - final String doExec_renamed_method_name = Utils.renamedMethodNameByTtl(doExecMethod); - - final String beforeCode = "if (this instanceof " + "com.fr.third.alibaba.ttl.spi.TtlEnhanced" + ") {\n" + // if the class is already TTL enhanced(eg: com.fr.third.alibaba.ttl.TtlRecursiveTask) - " return " + doExec_renamed_method_name + "($$);\n" + // return directly/do nothing - "}\n" + - "Object backup = com.fr.third.alibaba.ttl.TransmittableThreadLocal.Transmitter.replay(" + capturedFieldName + ");"; - - final String finallyCode = "com.fr.third.alibaba.ttl.TransmittableThreadLocal.Transmitter.restore(backup);"; - - Utils.doTryFinallyForMethod(doExecMethod, doExec_renamed_method_name, beforeCode, finallyCode); - } - - private void updateConstructorDisableInheritable(final CtClass clazz) throws NotFoundException, CannotCompileException { - for (CtConstructor constructor : clazz.getDeclaredConstructors()) { - final CtClass[] parameterTypes = constructor.getParameterTypes(); - final StringBuilder insertCode = new StringBuilder(); - for (int i = 0; i < parameterTypes.length; i++) { - final String paramTypeName = parameterTypes[i].getName(); - if (FORK_JOIN_WORKER_THREAD_FACTORY_CLASS_NAME.equals(paramTypeName)) { - String code = String.format("$%d = com.fr.third.alibaba.ttl.threadpool.TtlForkJoinPoolHelper.getDisableInheritableForkJoinWorkerThreadFactory($% 0) constructor.insertBefore(insertCode.toString()); - } - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/impl/TtlTimerTaskTransformlet.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/impl/TtlTimerTaskTransformlet.java deleted file mode 100644 index 016457db4..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/impl/TtlTimerTaskTransformlet.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.impl; - -import com.fr.third.alibaba.ttl.threadpool.agent.internal.logging.Logger; -import com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.ClassInfo; -import com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.JavassistTransformlet; -import com.fr.third.javassist.*; - -import java.io.IOException; - -/** - * TTL {@link JavassistTransformlet} for {@link java.util.TimerTask}. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @author wuwen5 (wuwen.55 at aliyun dot com) - * @see java.util.TimerTask - * @see java.util.Timer - * @since 2.7.0 - */ -public class TtlTimerTaskTransformlet implements JavassistTransformlet { - private static final Logger logger = Logger.getLogger(TtlTimerTaskTransformlet.class); - - private static final String TIMER_TASK_CLASS_NAME = "java.util.TimerTask"; - private static final String RUN_METHOD_NAME = "run"; - - @Override - public void doTransform(final ClassInfo classInfo) throws IOException, NotFoundException, CannotCompileException { - if (TIMER_TASK_CLASS_NAME.equals(classInfo.getClassName())) return; // No need transform TimerTask class - - final CtClass clazz = classInfo.getCtClass(); - - if (clazz.isPrimitive() || clazz.isArray() || clazz.isInterface() || clazz.isAnnotation()) { - return; - } - // class contains method `void run()` ? - try { - final CtMethod runMethod = clazz.getDeclaredMethod(RUN_METHOD_NAME, new CtClass[0]); - if (!CtClass.voidType.equals(runMethod.getReturnType())) return; - } catch (NotFoundException e) { - return; - } - if (!clazz.subclassOf(clazz.getClassPool().get(TIMER_TASK_CLASS_NAME))) return; - - logger.info("Transforming class " + classInfo.getClassName()); - - updateTimerTaskClass(clazz); - classInfo.setModified(); - } - - /** - * @see com.fr.third.alibaba.ttl.threadpool.TtlUtils#doCaptureWhenNotTtlEnhanced(java.lang.Object) - */ - private void updateTimerTaskClass(final CtClass clazz) throws CannotCompileException, NotFoundException { - final String className = clazz.getName(); - - // add new field - final String capturedFieldName = "captured$field$added$by$ttl"; - final CtField capturedField = CtField.make("private final Object " + capturedFieldName + ";", clazz); - clazz.addField(capturedField, "com.fr.third.alibaba.ttl.threadpool.TtlUtils.doCaptureWhenNotTtlEnhanced(this);"); - logger.info("add new field " + capturedFieldName + " to class " + className); - - final CtMethod runMethod = clazz.getDeclaredMethod(RUN_METHOD_NAME, new CtClass[0]); - - final String beforeCode = "Object backup = com.fr.third.alibaba.ttl.TransmittableThreadLocal.Transmitter.replay(" + capturedFieldName + ");"; - final String finallyCode = "com.fr.third.alibaba.ttl.TransmittableThreadLocal.Transmitter.restore(backup);"; - - Utils.doTryFinallyForMethod(runMethod, beforeCode, finallyCode); - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/impl/Utils.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/impl/Utils.java deleted file mode 100644 index 0d1635cc0..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/impl/Utils.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.impl; - -import com.fr.third.alibaba.ttl.threadpool.agent.internal.logging.Logger; -import com.fr.third.javassist.*; - -import java.lang.reflect.Modifier; - -/** - * @author Jerry Lee (oldratlee at gmail dot com) - * @since 2.6.0 - */ -public class Utils { - private static final Logger logger = Logger.getLogger(Utils.class); - - /** - * String like {@code public ScheduledFuture scheduleAtFixedRate(Runnable, long, long, TimeUnit)} - * for {@link java.util.concurrent.ScheduledThreadPoolExecutor#scheduleAtFixedRate}. - * - * @param method method object - * @return method signature string - */ - - static String signatureOfMethod(final CtBehavior method) throws NotFoundException { - final StringBuilder stringBuilder = new StringBuilder(); - - stringBuilder.append(Modifier.toString(method.getModifiers())); - if (method instanceof CtMethod) { - final String returnType = ((CtMethod) method).getReturnType().getSimpleName(); - stringBuilder.append(" ").append(returnType); - } - stringBuilder.append(" ").append(method.getName()).append("("); - - final CtClass[] parameterTypes = method.getParameterTypes(); - for (int i = 0; i < parameterTypes.length; i++) { - CtClass parameterType = parameterTypes[i]; - if (i != 0) stringBuilder.append(", "); - stringBuilder.append(parameterType.getSimpleName()); - } - - stringBuilder.append(")"); - return stringBuilder.toString(); - } - - - static String renamedMethodNameByTtl(CtMethod method) { - return "original$" + method.getName() + "$method$renamed$by$ttl"; - } - - static void doTryFinallyForMethod(CtMethod method, String beforeCode, String finallyCode) throws CannotCompileException, NotFoundException { - doTryFinallyForMethod(method, renamedMethodNameByTtl(method), beforeCode, finallyCode); - } - - static void doTryFinallyForMethod(CtMethod method, String renamedMethodName, String beforeCode, String finallyCode) throws CannotCompileException, NotFoundException { - final CtClass clazz = method.getDeclaringClass(); - final CtMethod newMethod = CtNewMethod.copy(method, clazz, null); - - // rename original method, and set to private method(avoid reflect out renamed method unexpectedly) - method.setName(renamedMethodName); - method.setModifiers(method.getModifiers() - & ~Modifier.PUBLIC /* remove public */ - & ~Modifier.PROTECTED /* remove protected */ - | Modifier.PRIVATE /* add private */); - - final String returnOp; - if (method.getReturnType() == CtClass.voidType) { - returnOp = ""; - } else { - returnOp = "return "; - } - // set new method implementation - final String code = "{\n" + - beforeCode + "\n" + - "try {\n" + - " " + returnOp + renamedMethodName + "($$);\n" + - "} finally {\n" + - " " + finallyCode + "\n" + - "} }"; - newMethod.setBody(code); - clazz.addMethod(newMethod); - logger.info("insert code around method " + signatureOfMethod(newMethod) + " of class " + clazz.getName() + ": " + code); - } -} diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/package-info.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/package-info.java deleted file mode 100644 index 0705dc7db..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/internal/transformlet/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * TTL {@code Transformlet} implementations by {@code Javassist}. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet.JavassistTransformlet - */ -package com.fr.third.alibaba.ttl.threadpool.agent.internal.transformlet; diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/package-info.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/package-info.java deleted file mode 100644 index ef60e8f6f..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/agent/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * TTL Agent. - * - * @author Jerry Lee (oldratlee at gmail dot com) - * @see com.fr.third.alibaba.ttl.threadpool.agent.TtlAgent - * @see The mechanism for instrumentation - * - * 此包中的不允许直接使用ttl中其他代码 - */ -package com.fr.third.alibaba.ttl.threadpool.agent; diff --git a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/package-info.java b/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/package-info.java deleted file mode 100644 index ee37492d5..000000000 --- a/fine-transmittable-thread-local/src/main/java/com/fr/third/alibaba/ttl/threadpool/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Thread pool wrap/decoration utils. - * - * @author Jerry Lee (oldratlee at gmail dot com) - */ -package com.fr.third.alibaba.ttl.threadpool; From 9338d415f94163ff51e322ae2064019e18b91c06 Mon Sep 17 00:00:00 2001 From: "Cloud.Liu" Date: Tue, 11 May 2021 20:24:28 +0800 Subject: [PATCH 3/3] =?UTF-8?q?REPORT-51412=20fix:=20third=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=8C=85=E6=BC=8F=E6=94=B9pom?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- base-third-project/base-third-step3/pom.xml | 1 - base-third-project/base-third-step8/pom.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/base-third-project/base-third-step3/pom.xml b/base-third-project/base-third-step3/pom.xml index e8da71e05..578c8b59f 100644 --- a/base-third-project/base-third-step3/pom.xml +++ b/base-third-project/base-third-step3/pom.xml @@ -16,7 +16,6 @@ ../../fine-itext - ../../fine-javassist ../../fine-jedis ../../fine-jboss-logging diff --git a/base-third-project/base-third-step8/pom.xml b/base-third-project/base-third-step8/pom.xml index af1c0c7cc..7590473d7 100644 --- a/base-third-project/base-third-step8/pom.xml +++ b/base-third-project/base-third-step8/pom.xml @@ -16,7 +16,6 @@ ../../fine-ehcache - ../../fine-transmittable-thread-local

This package provides a simple web server for sample packages. - - diff --git a/fine-javassist/src/main/java/com/fr/third/javassist/util/HotSwapper.java b/fine-javassist/src/main/java/com/fr/third/javassist/util/HotSwapper.java deleted file mode 100644 index 4c4da8111..000000000 --- a/fine-javassist/src/main/java/com/fr/third/javassist/util/HotSwapper.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Javassist, a Java-bytecode translator toolkit. - * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. Alternatively, the contents of this file may be used under - * the terms of the GNU Lesser General Public License Version 2.1 or later, - * or the Apache License Version 2.0. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - */ - -package com.fr.third.javassist.util; - -import com.sun.jdi.*; -import com.sun.jdi.connect.*; -import com.sun.jdi.event.*; -import com.sun.jdi.request.*; -import java.io.*; -import java.util.*; - -class Trigger { - void doSwap() {} -} - -/** - * A utility class for dynamically reloading a class by - * the Java Platform Debugger Architecture (JPDA), or HotSwap. - * It works only with JDK 1.4 and later. - * - *