From 663631f0456fcc245dd835889f86541d75161c53 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 28 Aug 2014 20:52:43 +0400 Subject: java-decompiler: post-import cleanup (classes moved) --- .../java/decompiler/code/CodeConstants.java | 371 +++++++ .../java/decompiler/code/ConstantsUtil.java | 519 +++++++++ .../java/decompiler/code/ExceptionHandler.java | 62 ++ .../java/decompiler/code/ExceptionTable.java | 57 + .../decompiler/code/FullInstructionSequence.java | 38 + .../java/decompiler/code/IfInstruction.java | 36 + .../java/decompiler/code/Instruction.java | 124 +++ .../java/decompiler/code/InstructionSequence.java | 219 ++++ .../java/decompiler/code/JumpInstruction.java | 41 + .../decompiler/code/SimpleInstructionSequence.java | 39 + .../java/decompiler/code/SwitchInstruction.java | 93 ++ .../java/decompiler/code/cfg/BasicBlock.java | 265 +++++ .../java/decompiler/code/cfg/ControlFlowGraph.java | 887 ++++++++++++++++ .../decompiler/code/cfg/ExceptionRangeCFG.java | 128 +++ .../java/decompiler/code/instructions/AALOAD.java | 7 + .../java/decompiler/code/instructions/AASTORE.java | 7 + .../decompiler/code/instructions/ACONST_NULL.java | 7 + .../java/decompiler/code/instructions/ALOAD.java | 43 + .../decompiler/code/instructions/ANEWARRAY.java | 19 + .../java/decompiler/code/instructions/ARETURN.java | 7 + .../decompiler/code/instructions/ARRAYLENGTH.java | 7 + .../java/decompiler/code/instructions/ASTORE.java | 42 + .../java/decompiler/code/instructions/ATHROW.java | 7 + .../java/decompiler/code/instructions/BALOAD.java | 7 + .../java/decompiler/code/instructions/BASTORE.java | 7 + .../java/decompiler/code/instructions/BIPUSH.java | 30 + .../java/decompiler/code/instructions/CALOAD.java | 7 + .../java/decompiler/code/instructions/CASTORE.java | 7 + .../decompiler/code/instructions/CHECKCAST.java | 20 + .../java/decompiler/code/instructions/D2F.java | 7 + .../java/decompiler/code/instructions/D2I.java | 7 + .../java/decompiler/code/instructions/D2L.java | 7 + .../java/decompiler/code/instructions/DADD.java | 7 + .../java/decompiler/code/instructions/DALOAD.java | 7 + .../java/decompiler/code/instructions/DASTORE.java | 7 + .../java/decompiler/code/instructions/DCMPG.java | 7 + .../java/decompiler/code/instructions/DCMPL.java | 7 + .../decompiler/code/instructions/DCONST_0.java | 7 + .../decompiler/code/instructions/DCONST_1.java | 7 + .../java/decompiler/code/instructions/DDIV.java | 7 + .../java/decompiler/code/instructions/DLOAD.java | 42 + .../java/decompiler/code/instructions/DMUL.java | 7 + .../java/decompiler/code/instructions/DNEG.java | 7 + .../java/decompiler/code/instructions/DREM.java | 7 + .../java/decompiler/code/instructions/DRETURN.java | 7 + .../java/decompiler/code/instructions/DSTORE.java | 41 + .../java/decompiler/code/instructions/DSUB.java | 7 + .../java/decompiler/code/instructions/DUP.java | 7 + .../java/decompiler/code/instructions/DUP2.java | 7 + .../java/decompiler/code/instructions/DUP2_X1.java | 7 + .../java/decompiler/code/instructions/DUP2_X2.java | 7 + .../java/decompiler/code/instructions/DUP_X1.java | 7 + .../java/decompiler/code/instructions/DUP_X2.java | 7 + .../java/decompiler/code/instructions/F2D.java | 7 + .../java/decompiler/code/instructions/F2I.java | 7 + .../java/decompiler/code/instructions/F2L.java | 7 + .../java/decompiler/code/instructions/FADD.java | 7 + .../java/decompiler/code/instructions/FALOAD.java | 7 + .../java/decompiler/code/instructions/FASTORE.java | 7 + .../java/decompiler/code/instructions/FCMPG.java | 7 + .../java/decompiler/code/instructions/FCMPL.java | 7 + .../decompiler/code/instructions/FCONST_0.java | 7 + .../decompiler/code/instructions/FCONST_1.java | 7 + .../decompiler/code/instructions/FCONST_2.java | 7 + .../java/decompiler/code/instructions/FDIV.java | 7 + .../java/decompiler/code/instructions/FLOAD.java | 42 + .../java/decompiler/code/instructions/FMUL.java | 7 + .../java/decompiler/code/instructions/FNEG.java | 7 + .../java/decompiler/code/instructions/FREM.java | 7 + .../java/decompiler/code/instructions/FRETURN.java | 7 + .../java/decompiler/code/instructions/FSTORE.java | 41 + .../java/decompiler/code/instructions/FSUB.java | 7 + .../decompiler/code/instructions/GETFIELD.java | 18 + .../decompiler/code/instructions/GETSTATIC.java | 19 + .../java/decompiler/code/instructions/GOTO.java | 30 + .../java/decompiler/code/instructions/GOTO_W.java | 19 + .../java/decompiler/code/instructions/I2B.java | 7 + .../java/decompiler/code/instructions/I2C.java | 7 + .../java/decompiler/code/instructions/I2D.java | 7 + .../java/decompiler/code/instructions/I2F.java | 7 + .../java/decompiler/code/instructions/I2L.java | 7 + .../java/decompiler/code/instructions/I2S.java | 7 + .../java/decompiler/code/instructions/IADD.java | 7 + .../java/decompiler/code/instructions/IALOAD.java | 7 + .../java/decompiler/code/instructions/IAND.java | 7 + .../java/decompiler/code/instructions/IASTORE.java | 7 + .../java/decompiler/code/instructions/IDIV.java | 7 + .../java/decompiler/code/instructions/IFEQ.java | 19 + .../java/decompiler/code/instructions/IFGE.java | 19 + .../java/decompiler/code/instructions/IFGT.java | 19 + .../java/decompiler/code/instructions/IFLE.java | 19 + .../java/decompiler/code/instructions/IFLT.java | 19 + .../java/decompiler/code/instructions/IFNE.java | 19 + .../decompiler/code/instructions/IFNONNULL.java | 19 + .../java/decompiler/code/instructions/IFNULL.java | 19 + .../decompiler/code/instructions/IF_ACMPEQ.java | 20 + .../decompiler/code/instructions/IF_ACMPNE.java | 19 + .../decompiler/code/instructions/IF_ICMPEQ.java | 19 + .../decompiler/code/instructions/IF_ICMPGE.java | 19 + .../decompiler/code/instructions/IF_ICMPGT.java | 19 + .../decompiler/code/instructions/IF_ICMPLE.java | 19 + .../decompiler/code/instructions/IF_ICMPLT.java | 19 + .../decompiler/code/instructions/IF_ICMPNE.java | 19 + .../java/decompiler/code/instructions/IINC.java | 28 + .../java/decompiler/code/instructions/ILOAD.java | 38 + .../java/decompiler/code/instructions/IMUL.java | 7 + .../java/decompiler/code/instructions/INEG.java | 7 + .../decompiler/code/instructions/INSTANCEOF.java | 19 + .../code/instructions/INVOKEINTERFACE.java | 21 + .../code/instructions/INVOKESPECIAL.java | 19 + .../decompiler/code/instructions/INVOKESTATIC.java | 19 + .../code/instructions/INVOKEVIRTUAL.java | 19 + .../java/decompiler/code/instructions/IOR.java | 7 + .../java/decompiler/code/instructions/IREM.java | 7 + .../java/decompiler/code/instructions/IRETURN.java | 7 + .../java/decompiler/code/instructions/ISHL.java | 7 + .../java/decompiler/code/instructions/ISHR.java | 7 + .../java/decompiler/code/instructions/ISTORE.java | 38 + .../java/decompiler/code/instructions/ISUB.java | 7 + .../java/decompiler/code/instructions/IUSHR.java | 7 + .../java/decompiler/code/instructions/IXOR.java | 7 + .../java/decompiler/code/instructions/JSR.java | 30 + .../java/decompiler/code/instructions/JSR_W.java | 19 + .../java/decompiler/code/instructions/L2D.java | 7 + .../java/decompiler/code/instructions/L2F.java | 7 + .../java/decompiler/code/instructions/L2I.java | 7 + .../java/decompiler/code/instructions/LADD.java | 7 + .../java/decompiler/code/instructions/LALOAD.java | 7 + .../java/decompiler/code/instructions/LAND.java | 7 + .../java/decompiler/code/instructions/LASTORE.java | 7 + .../java/decompiler/code/instructions/LCMP.java | 7 + .../decompiler/code/instructions/LCONST_0.java | 7 + .../decompiler/code/instructions/LCONST_1.java | 7 + .../java/decompiler/code/instructions/LDC.java | 19 + .../java/decompiler/code/instructions/LDC2_W.java | 19 + .../java/decompiler/code/instructions/LDC_W.java | 19 + .../java/decompiler/code/instructions/LDIV.java | 7 + .../java/decompiler/code/instructions/LLOAD.java | 38 + .../java/decompiler/code/instructions/LMUL.java | 7 + .../java/decompiler/code/instructions/LNEG.java | 7 + .../decompiler/code/instructions/LOOKUPSWITCH.java | 28 + .../java/decompiler/code/instructions/LOR.java | 7 + .../java/decompiler/code/instructions/LREM.java | 7 + .../java/decompiler/code/instructions/LRETURN.java | 7 + .../java/decompiler/code/instructions/LSHL.java | 7 + .../java/decompiler/code/instructions/LSHR.java | 7 + .../java/decompiler/code/instructions/LSTORE.java | 38 + .../java/decompiler/code/instructions/LSUB.java | 7 + .../java/decompiler/code/instructions/LUSHR.java | 7 + .../java/decompiler/code/instructions/LXOR.java | 7 + .../decompiler/code/instructions/MONITORENTER.java | 7 + .../decompiler/code/instructions/MONITOREXIT.java | 7 + .../code/instructions/MULTIANEWARRAY.java | 20 + .../java/decompiler/code/instructions/NEW.java | 19 + .../decompiler/code/instructions/NEWARRAY.java | 19 + .../java/decompiler/code/instructions/NOP.java | 7 + .../java/decompiler/code/instructions/POP.java | 7 + .../java/decompiler/code/instructions/POP2.java | 7 + .../decompiler/code/instructions/PUTFIELD.java | 19 + .../decompiler/code/instructions/PUTSTATIC.java | 19 + .../java/decompiler/code/instructions/RET.java | 26 + .../java/decompiler/code/instructions/RETURN.java | 7 + .../java/decompiler/code/instructions/SALOAD.java | 7 + .../java/decompiler/code/instructions/SASTORE.java | 7 + .../java/decompiler/code/instructions/SIPUSH.java | 19 + .../java/decompiler/code/instructions/SWAP.java | 7 + .../decompiler/code/instructions/TABLESWITCH.java | 29 + .../decompiler/code/instructions/XXXUNUSEDXXX.java | 7 + .../code/interpreter/InstructionImpact.java | 468 +++++++++ .../java/decompiler/code/interpreter/Util.java | 265 +++++ .../decompiler/code/optinstructions/ALOAD.java | 56 + .../decompiler/code/optinstructions/ANEWARRAY.java | 33 + .../decompiler/code/optinstructions/ASTORE.java | 56 + .../decompiler/code/optinstructions/BIPUSH.java | 44 + .../decompiler/code/optinstructions/CHECKCAST.java | 34 + .../decompiler/code/optinstructions/DLOAD.java | 56 + .../decompiler/code/optinstructions/DSTORE.java | 55 + .../decompiler/code/optinstructions/FLOAD.java | 56 + .../decompiler/code/optinstructions/FSTORE.java | 55 + .../decompiler/code/optinstructions/GETFIELD.java | 32 + .../decompiler/code/optinstructions/GETSTATIC.java | 33 + .../java/decompiler/code/optinstructions/GOTO.java | 44 + .../decompiler/code/optinstructions/GOTO_W.java | 33 + .../java/decompiler/code/optinstructions/IINC.java | 42 + .../decompiler/code/optinstructions/ILOAD.java | 52 + .../code/optinstructions/INSTANCEOF.java | 33 + .../code/optinstructions/INVOKEDYNAMIC.java | 20 + .../code/optinstructions/INVOKEINTERFACE.java | 35 + .../code/optinstructions/INVOKESPECIAL.java | 33 + .../code/optinstructions/INVOKESTATIC.java | 33 + .../code/optinstructions/INVOKEVIRTUAL.java | 33 + .../decompiler/code/optinstructions/ISTORE.java | 52 + .../java/decompiler/code/optinstructions/JSR.java | 44 + .../decompiler/code/optinstructions/JSR_W.java | 33 + .../java/decompiler/code/optinstructions/LDC.java | 33 + .../decompiler/code/optinstructions/LDC2_W.java | 33 + .../decompiler/code/optinstructions/LDC_W.java | 33 + .../decompiler/code/optinstructions/LLOAD.java | 52 + .../code/optinstructions/LOOKUPSWITCH.java | 42 + .../decompiler/code/optinstructions/LSTORE.java | 52 + .../code/optinstructions/MULTIANEWARRAY.java | 34 + .../java/decompiler/code/optinstructions/NEW.java | 33 + .../decompiler/code/optinstructions/NEWARRAY.java | 33 + .../decompiler/code/optinstructions/PUTFIELD.java | 33 + .../decompiler/code/optinstructions/PUTSTATIC.java | 33 + .../java/decompiler/code/optinstructions/RET.java | 40 + .../decompiler/code/optinstructions/SIPUSH.java | 33 + .../code/optinstructions/TABLESWITCH.java | 43 + .../java/decompiler/main/AssertProcessor.java | 321 ++++++ .../decompiler/main/ClassReference14Processor.java | 309 ++++++ .../java/decompiler/main/ClassWriter.java | 1107 ++++++++++++++++++++ .../java/decompiler/main/ClassesProcessor.java | 449 ++++++++ .../java/decompiler/main/DecompilerContext.java | 197 ++++ .../java/decompiler/main/EnumProcessor.java | 159 +++ .../jetbrains/java/decompiler/main/Fernflower.java | 110 ++ .../java/decompiler/main/InitializerProcessor.java | 321 ++++++ .../main/collectors/CounterContainer.java | 37 + .../main/collectors/ImportCollector.java | 157 +++ .../main/collectors/VarNamesCollector.java | 50 + .../main/decompiler/ConsoleDecompiler.java | 323 ++++++ .../decompiler/main/decompiler/IdeDecompiler.java | 54 + .../decompiler/main/decompiler/WebDecompiler.java | 78 ++ .../main/decompiler/helper/PrintStreamLogger.java | 83 ++ .../decompiler/main/extern/IBytecodeProvider.java | 23 + .../decompiler/main/extern/IDecompilatSaver.java | 39 + .../decompiler/main/extern/IFernflowerLogger.java | 56 + .../main/extern/IFernflowerPreferences.java | 57 + .../decompiler/main/extern/IIdentifierRenamer.java | 20 + .../java/decompiler/main/rels/ClassWrapper.java | 216 ++++ .../java/decompiler/main/rels/LambdaProcessor.java | 138 +++ .../main/rels/MethodProcessorThread.java | 274 +++++ .../java/decompiler/main/rels/MethodWrapper.java | 62 ++ .../decompiler/main/rels/NestedClassProcessor.java | 1020 ++++++++++++++++++ .../decompiler/main/rels/NestedMemberAccess.java | 457 ++++++++ .../decompiler/modules/code/DeadCodeHelper.java | 438 ++++++++ .../modules/decompiler/ClearStructHelper.java | 41 + .../modules/decompiler/ConcatenationHelper.java | 213 ++++ .../decompiler/modules/decompiler/DecHelper.java | 217 ++++ .../decompiler/modules/decompiler/DomHelper.java | 720 +++++++++++++ .../modules/decompiler/EliminateLoopsHelper.java | 214 ++++ .../decompiler/modules/decompiler/ExitHelper.java | 348 ++++++ .../modules/decompiler/ExprProcessor.java | 886 ++++++++++++++++ .../modules/decompiler/ExprentStack.java | 46 + .../modules/decompiler/FinallyProcessor.java | 1031 ++++++++++++++++++ .../modules/decompiler/IdeaNotNullHelper.java | 320 ++++++ .../decompiler/modules/decompiler/IfHelper.java | 731 +++++++++++++ .../decompiler/InlineSingleBlockHelper.java | 223 ++++ .../decompiler/modules/decompiler/LabelHelper.java | 521 +++++++++ .../modules/decompiler/LoopExtractHelper.java | 209 ++++ .../modules/decompiler/LowBreakHelper.java | 207 ++++ .../decompiler/modules/decompiler/MergeHelper.java | 416 ++++++++ .../modules/decompiler/PPandMMHelper.java | 153 +++ .../modules/decompiler/PrimitiveExprsList.java | 47 + .../decompiler/SecondaryFunctionsHelper.java | 428 ++++++++ .../modules/decompiler/SequenceHelper.java | 326 ++++++ .../modules/decompiler/SimplifyExprentsHelper.java | 863 +++++++++++++++ .../modules/decompiler/StackVarsProcessor.java | 716 +++++++++++++ .../decompiler/modules/decompiler/StatEdge.java | 103 ++ .../decompiler/StrongConnectivityHelper.java | 204 ++++ .../decompiler/decompose/DominatorEngine.java | 127 +++ .../decompose/DominatorTreeExceptionFilter.java | 188 ++++ .../decompose/FastExtendedPostdominanceHelper.java | 362 +++++++ .../decompose/GenericDominatorEngine.java | 150 +++ .../modules/decompiler/decompose/IGraph.java | 26 + .../modules/decompiler/decompose/IGraphNode.java | 23 + .../deobfuscator/ExceptionDeobfuscator.java | 324 ++++++ .../deobfuscator/IrreducibleCFGDeobfuscator.java | 238 +++++ .../modules/decompiler/exps/AnnotationExprent.java | 111 ++ .../modules/decompiler/exps/ArrayExprent.java | 125 +++ .../modules/decompiler/exps/AssertExprent.java | 51 + .../modules/decompiler/exps/AssignmentExprent.java | 195 ++++ .../modules/decompiler/exps/ConstExprent.java | 369 +++++++ .../modules/decompiler/exps/ExitExprent.java | 149 +++ .../modules/decompiler/exps/Exprent.java | 134 +++ .../modules/decompiler/exps/FieldExprent.java | 195 ++++ .../modules/decompiler/exps/FunctionExprent.java | 585 +++++++++++ .../modules/decompiler/exps/IfExprent.java | 146 +++ .../modules/decompiler/exps/InvocationExprent.java | 504 +++++++++ .../modules/decompiler/exps/MonitorExprent.java | 82 ++ .../modules/decompiler/exps/NewExprent.java | 512 +++++++++ .../modules/decompiler/exps/SwitchExprent.java | 113 ++ .../modules/decompiler/exps/VarExprent.java | 198 ++++ .../modules/decompiler/sforms/DirectGraph.java | 136 +++ .../modules/decompiler/sforms/DirectNode.java | 68 ++ .../decompiler/sforms/FlattenStatementsHelper.java | 562 ++++++++++ .../decompiler/sforms/SSAConstructorSparseEx.java | 514 +++++++++ .../decompiler/sforms/SSAUConstructorSparseEx.java | 833 +++++++++++++++ .../decompiler/stats/BasicBlockStatement.java | 95 ++ .../decompiler/stats/CatchAllStatement.java | 233 ++++ .../modules/decompiler/stats/CatchStatement.java | 206 ++++ .../modules/decompiler/stats/DoStatement.java | 221 ++++ .../modules/decompiler/stats/GeneralStatement.java | 75 ++ .../modules/decompiler/stats/IfStatement.java | 404 +++++++ .../modules/decompiler/stats/RootStatement.java | 49 + .../decompiler/stats/SequenceStatement.java | 144 +++ .../modules/decompiler/stats/Statement.java | 871 +++++++++++++++ .../modules/decompiler/stats/SwitchStatement.java | 370 +++++++ .../decompiler/stats/SynchronizedStatement.java | 154 +++ .../modules/decompiler/vars/CheckTypesResult.java | 57 + .../decompiler/vars/VarDefinitionHelper.java | 358 +++++++ .../modules/decompiler/vars/VarProcessor.java | 135 +++ .../modules/decompiler/vars/VarTypeProcessor.java | 273 +++++ .../modules/decompiler/vars/VarVersionEdge.java | 56 + .../modules/decompiler/vars/VarVersionNode.java | 80 ++ .../modules/decompiler/vars/VarVersionPaar.java | 65 ++ .../modules/decompiler/vars/VarVersionsGraph.java | 172 +++ .../decompiler/vars/VarVersionsProcessor.java | 340 ++++++ .../modules/renamer/ClassWrapperNode.java | 41 + .../modules/renamer/ConverterHelper.java | 127 +++ .../modules/renamer/IdentifierConverter.java | 447 ++++++++ .../modules/renamer/PoolInterceptor.java | 36 + .../java/decompiler/struct/ContextUnit.java | 210 ++++ .../java/decompiler/struct/IDecompiledData.java | 23 + .../java/decompiler/struct/ISaveClass.java | 30 + .../java/decompiler/struct/StructClass.java | 352 +++++++ .../java/decompiler/struct/StructContext.java | 211 ++++ .../java/decompiler/struct/StructField.java | 109 ++ .../java/decompiler/struct/StructMethod.java | 560 ++++++++++ .../struct/attr/StructAnnDefaultAttribute.java | 40 + .../struct/attr/StructAnnotationAttribute.java | 187 ++++ .../attr/StructAnnotationParameterAttribute.java | 57 + .../struct/attr/StructAnnotationTypeAttribute.java | 188 ++++ .../attr/StructBootstrapMethodsAttribute.java | 62 ++ .../struct/attr/StructConstantValueAttribute.java | 34 + .../attr/StructEnclosingMethodAttribute.java | 57 + .../struct/attr/StructExceptionsAttribute.java | 78 ++ .../struct/attr/StructGeneralAttribute.java | 145 +++ .../attr/StructGenericSignatureAttribute.java | 34 + .../struct/attr/StructInnerClassesAttribute.java | 73 ++ .../attr/StructLocalVariableTableAttribute.java | 47 + .../decompiler/struct/consts/ConstantPool.java | 316 ++++++ .../decompiler/struct/consts/LinkConstant.java | 159 +++ .../decompiler/struct/consts/PooledConstant.java | 116 ++ .../struct/consts/PrimitiveConstant.java | 126 +++ .../decompiler/struct/consts/VariableTypeEnum.java | 47 + .../java/decompiler/struct/gen/DataPoint.java | 98 ++ .../decompiler/struct/gen/FieldDescriptor.java | 58 + .../decompiler/struct/gen/MethodDescriptor.java | 102 ++ .../java/decompiler/struct/gen/VarType.java | 410 ++++++++ .../gen/generics/GenericClassDescriptor.java | 30 + .../gen/generics/GenericFieldDescriptor.java | 21 + .../struct/gen/generics/GenericMain.java | 229 ++++ .../gen/generics/GenericMethodDescriptor.java | 32 + .../struct/gen/generics/GenericType.java | 270 +++++ .../java/decompiler/struct/lazy/LazyLoader.java | 186 ++++ .../java/decompiler/util/DataInputFullStream.java | 50 + .../java/decompiler/util/FastFixedSetFactory.java | 363 +++++++ .../java/decompiler/util/FastSetFactory.java | 486 +++++++++ .../java/decompiler/util/FastSparseSetFactory.java | 549 ++++++++++ .../java/decompiler/util/InterpreterUtil.java | 157 +++ .../jetbrains/java/decompiler/util/ListStack.java | 101 ++ .../java/decompiler/util/SFormsFastMap.java | 232 ++++ .../java/decompiler/util/SFormsFastMapDirect.java | 411 ++++++++ .../java/decompiler/util/SFormsFastMapOld.java | 270 +++++ .../java/decompiler/util/VBStyleCollection.java | 204 ++++ 355 files changed, 42422 insertions(+) create mode 100644 src/org/jetbrains/java/decompiler/code/CodeConstants.java create mode 100644 src/org/jetbrains/java/decompiler/code/ConstantsUtil.java create mode 100644 src/org/jetbrains/java/decompiler/code/ExceptionHandler.java create mode 100644 src/org/jetbrains/java/decompiler/code/ExceptionTable.java create mode 100644 src/org/jetbrains/java/decompiler/code/FullInstructionSequence.java create mode 100644 src/org/jetbrains/java/decompiler/code/IfInstruction.java create mode 100644 src/org/jetbrains/java/decompiler/code/Instruction.java create mode 100644 src/org/jetbrains/java/decompiler/code/InstructionSequence.java create mode 100644 src/org/jetbrains/java/decompiler/code/JumpInstruction.java create mode 100644 src/org/jetbrains/java/decompiler/code/SimpleInstructionSequence.java create mode 100644 src/org/jetbrains/java/decompiler/code/SwitchInstruction.java create mode 100644 src/org/jetbrains/java/decompiler/code/cfg/BasicBlock.java create mode 100644 src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java create mode 100644 src/org/jetbrains/java/decompiler/code/cfg/ExceptionRangeCFG.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/AALOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/AASTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/ACONST_NULL.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/ALOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/ANEWARRAY.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/ARETURN.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/ARRAYLENGTH.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/ASTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/ATHROW.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/BALOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/BASTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/BIPUSH.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/CALOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/CASTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/CHECKCAST.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/D2F.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/D2I.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/D2L.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DADD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DALOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DASTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DCMPG.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DCMPL.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DCONST_0.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DCONST_1.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DDIV.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DLOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DMUL.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DNEG.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DREM.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DRETURN.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DSTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DSUB.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DUP.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DUP2.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DUP2_X1.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DUP2_X2.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DUP_X1.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/DUP_X2.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/F2D.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/F2I.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/F2L.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/FADD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/FALOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/FASTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/FCMPG.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/FCMPL.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/FCONST_0.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/FCONST_1.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/FCONST_2.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/FDIV.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/FLOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/FMUL.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/FNEG.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/FREM.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/FRETURN.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/FSTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/FSUB.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/GETFIELD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/GETSTATIC.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/GOTO.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/GOTO_W.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/I2B.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/I2C.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/I2D.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/I2F.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/I2L.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/I2S.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IADD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IALOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IAND.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IASTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IDIV.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IFEQ.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IFGE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IFGT.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IFLE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IFLT.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IFNE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IFNONNULL.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IFNULL.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IF_ACMPEQ.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IF_ACMPNE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPEQ.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPGE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPGT.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPLE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPLT.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPNE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IINC.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/ILOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IMUL.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/INEG.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/INSTANCEOF.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/INVOKEINTERFACE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/INVOKESPECIAL.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/INVOKESTATIC.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/INVOKEVIRTUAL.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IOR.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IREM.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IRETURN.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/ISHL.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/ISHR.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/ISTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/ISUB.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IUSHR.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/IXOR.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/JSR.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/JSR_W.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/L2D.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/L2F.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/L2I.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LADD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LALOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LAND.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LASTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LCMP.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LCONST_0.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LCONST_1.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LDC.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LDC2_W.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LDC_W.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LDIV.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LLOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LMUL.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LNEG.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LOOKUPSWITCH.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LOR.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LREM.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LRETURN.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LSHL.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LSHR.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LSTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LSUB.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LUSHR.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/LXOR.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/MONITORENTER.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/MONITOREXIT.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/MULTIANEWARRAY.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/NEW.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/NEWARRAY.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/NOP.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/POP.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/POP2.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/PUTFIELD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/PUTSTATIC.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/RET.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/RETURN.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/SALOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/SASTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/SIPUSH.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/SWAP.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/TABLESWITCH.java create mode 100644 src/org/jetbrains/java/decompiler/code/instructions/XXXUNUSEDXXX.java create mode 100644 src/org/jetbrains/java/decompiler/code/interpreter/InstructionImpact.java create mode 100644 src/org/jetbrains/java/decompiler/code/interpreter/Util.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/ALOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/ANEWARRAY.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/ASTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/BIPUSH.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/CHECKCAST.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/DLOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/DSTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/FLOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/FSTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/GETFIELD.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/GETSTATIC.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/GOTO.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/GOTO_W.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/IINC.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/ILOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/INSTANCEOF.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/INVOKEDYNAMIC.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/INVOKEINTERFACE.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/INVOKESPECIAL.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/INVOKESTATIC.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/INVOKEVIRTUAL.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/ISTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/JSR.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/JSR_W.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/LDC.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/LDC2_W.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/LDC_W.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/LLOAD.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/LOOKUPSWITCH.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/LSTORE.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/MULTIANEWARRAY.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/NEW.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/NEWARRAY.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/PUTFIELD.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/PUTSTATIC.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/RET.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/SIPUSH.java create mode 100644 src/org/jetbrains/java/decompiler/code/optinstructions/TABLESWITCH.java create mode 100644 src/org/jetbrains/java/decompiler/main/AssertProcessor.java create mode 100644 src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java create mode 100644 src/org/jetbrains/java/decompiler/main/ClassWriter.java create mode 100644 src/org/jetbrains/java/decompiler/main/ClassesProcessor.java create mode 100644 src/org/jetbrains/java/decompiler/main/DecompilerContext.java create mode 100644 src/org/jetbrains/java/decompiler/main/EnumProcessor.java create mode 100644 src/org/jetbrains/java/decompiler/main/Fernflower.java create mode 100644 src/org/jetbrains/java/decompiler/main/InitializerProcessor.java create mode 100644 src/org/jetbrains/java/decompiler/main/collectors/CounterContainer.java create mode 100644 src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java create mode 100644 src/org/jetbrains/java/decompiler/main/collectors/VarNamesCollector.java create mode 100644 src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java create mode 100644 src/org/jetbrains/java/decompiler/main/decompiler/IdeDecompiler.java create mode 100644 src/org/jetbrains/java/decompiler/main/decompiler/WebDecompiler.java create mode 100644 src/org/jetbrains/java/decompiler/main/decompiler/helper/PrintStreamLogger.java create mode 100644 src/org/jetbrains/java/decompiler/main/extern/IBytecodeProvider.java create mode 100644 src/org/jetbrains/java/decompiler/main/extern/IDecompilatSaver.java create mode 100644 src/org/jetbrains/java/decompiler/main/extern/IFernflowerLogger.java create mode 100644 src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java create mode 100644 src/org/jetbrains/java/decompiler/main/extern/IIdentifierRenamer.java create mode 100644 src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java create mode 100644 src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java create mode 100644 src/org/jetbrains/java/decompiler/main/rels/MethodProcessorThread.java create mode 100644 src/org/jetbrains/java/decompiler/main/rels/MethodWrapper.java create mode 100644 src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java create mode 100644 src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java create mode 100644 src/org/jetbrains/java/decompiler/modules/code/DeadCodeHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/ClearStructHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/DecHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/EliminateLoopsHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/ExitHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/ExprentStack.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/IdeaNotNullHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/InlineSingleBlockHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/LabelHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/LoopExtractHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/LowBreakHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/MergeHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/PrimitiveExprsList.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/SequenceHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/StatEdge.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/StrongConnectivityHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorEngine.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorTreeExceptionFilter.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/decompose/FastExtendedPostdominanceHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/decompose/GenericDominatorEngine.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/decompose/IGraph.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/decompose/IGraphNode.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/ExceptionDeobfuscator.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/IrreducibleCFGDeobfuscator.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssertExprent.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/exps/IfExprent.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/exps/MonitorExprent.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectNode.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/stats/BasicBlockStatement.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchAllStatement.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/stats/GeneralStatement.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/stats/RootStatement.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/stats/SequenceStatement.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/stats/SynchronizedStatement.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/vars/CheckTypesResult.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionEdge.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionNode.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionPaar.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsGraph.java create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java create mode 100644 src/org/jetbrains/java/decompiler/modules/renamer/ClassWrapperNode.java create mode 100644 src/org/jetbrains/java/decompiler/modules/renamer/ConverterHelper.java create mode 100644 src/org/jetbrains/java/decompiler/modules/renamer/IdentifierConverter.java create mode 100644 src/org/jetbrains/java/decompiler/modules/renamer/PoolInterceptor.java create mode 100644 src/org/jetbrains/java/decompiler/struct/ContextUnit.java create mode 100644 src/org/jetbrains/java/decompiler/struct/IDecompiledData.java create mode 100644 src/org/jetbrains/java/decompiler/struct/ISaveClass.java create mode 100644 src/org/jetbrains/java/decompiler/struct/StructClass.java create mode 100644 src/org/jetbrains/java/decompiler/struct/StructContext.java create mode 100644 src/org/jetbrains/java/decompiler/struct/StructField.java create mode 100644 src/org/jetbrains/java/decompiler/struct/StructMethod.java create mode 100644 src/org/jetbrains/java/decompiler/struct/attr/StructAnnDefaultAttribute.java create mode 100644 src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java create mode 100644 src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java create mode 100644 src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationTypeAttribute.java create mode 100644 src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java create mode 100644 src/org/jetbrains/java/decompiler/struct/attr/StructConstantValueAttribute.java create mode 100644 src/org/jetbrains/java/decompiler/struct/attr/StructEnclosingMethodAttribute.java create mode 100644 src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java create mode 100644 src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java create mode 100644 src/org/jetbrains/java/decompiler/struct/attr/StructGenericSignatureAttribute.java create mode 100644 src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java create mode 100644 src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java create mode 100644 src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java create mode 100644 src/org/jetbrains/java/decompiler/struct/consts/LinkConstant.java create mode 100644 src/org/jetbrains/java/decompiler/struct/consts/PooledConstant.java create mode 100644 src/org/jetbrains/java/decompiler/struct/consts/PrimitiveConstant.java create mode 100644 src/org/jetbrains/java/decompiler/struct/consts/VariableTypeEnum.java create mode 100644 src/org/jetbrains/java/decompiler/struct/gen/DataPoint.java create mode 100644 src/org/jetbrains/java/decompiler/struct/gen/FieldDescriptor.java create mode 100644 src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java create mode 100644 src/org/jetbrains/java/decompiler/struct/gen/VarType.java create mode 100644 src/org/jetbrains/java/decompiler/struct/gen/generics/GenericClassDescriptor.java create mode 100644 src/org/jetbrains/java/decompiler/struct/gen/generics/GenericFieldDescriptor.java create mode 100644 src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java create mode 100644 src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMethodDescriptor.java create mode 100644 src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java create mode 100644 src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java create mode 100644 src/org/jetbrains/java/decompiler/util/DataInputFullStream.java create mode 100644 src/org/jetbrains/java/decompiler/util/FastFixedSetFactory.java create mode 100644 src/org/jetbrains/java/decompiler/util/FastSetFactory.java create mode 100644 src/org/jetbrains/java/decompiler/util/FastSparseSetFactory.java create mode 100644 src/org/jetbrains/java/decompiler/util/InterpreterUtil.java create mode 100644 src/org/jetbrains/java/decompiler/util/ListStack.java create mode 100644 src/org/jetbrains/java/decompiler/util/SFormsFastMap.java create mode 100644 src/org/jetbrains/java/decompiler/util/SFormsFastMapDirect.java create mode 100644 src/org/jetbrains/java/decompiler/util/SFormsFastMapOld.java create mode 100644 src/org/jetbrains/java/decompiler/util/VBStyleCollection.java (limited to 'src/org/jetbrains/java/decompiler') diff --git a/src/org/jetbrains/java/decompiler/code/CodeConstants.java b/src/org/jetbrains/java/decompiler/code/CodeConstants.java new file mode 100644 index 0000000..78cbcf0 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/CodeConstants.java @@ -0,0 +1,371 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code; + +public interface CodeConstants { + + // ---------------------------------------------------------------------- + // BYTECODE VERSIONS + // ---------------------------------------------------------------------- + + public final static int BYTECODE_JAVA_LE_4 = 1; + public final static int BYTECODE_JAVA_5 = 2; + public final static int BYTECODE_JAVA_6 = 3; + public final static int BYTECODE_JAVA_7 = 4; + public final static int BYTECODE_JAVA_8 = 5; + + // ---------------------------------------------------------------------- + // VARIABLE TYPES + // ---------------------------------------------------------------------- + + public final static int TYPE_BYTE = 0; + public final static int TYPE_CHAR = 1; + public final static int TYPE_DOUBLE = 2; + public final static int TYPE_FLOAT = 3; + public final static int TYPE_INT = 4; + public final static int TYPE_LONG = 5; + public final static int TYPE_SHORT = 6; + public final static int TYPE_BOOLEAN = 7; + public final static int TYPE_OBJECT = 8; + public final static int TYPE_ADDRESS = 9; + public final static int TYPE_VOID = 10; + public final static int TYPE_ANY = 11; + public final static int TYPE_GROUP2EMPTY = 12; + public final static int TYPE_NULL = 13; + public final static int TYPE_NOTINITIALIZED = 14; + public final static int TYPE_BYTECHAR = 15; + public final static int TYPE_SHORTCHAR = 16; + public final static int TYPE_UNKNOWN = 17; + public final static int TYPE_GENVAR = 18; + + // ---------------------------------------------------------------------- + // VARIABLE TYPE FAMILIES + // ---------------------------------------------------------------------- + + public final static int TYPE_FAMILY_UNKNOWN = 0; + public final static int TYPE_FAMILY_BOOLEAN = 1; + public final static int TYPE_FAMILY_INTEGER = 2; + public final static int TYPE_FAMILY_FLOAT = 3; + public final static int TYPE_FAMILY_LONG = 4; + public final static int TYPE_FAMILY_DOUBLE = 5; + public final static int TYPE_FAMILY_OBJECT = 6; + + // ---------------------------------------------------------------------- + // MODULE CONSTANTS + // ---------------------------------------------------------------------- + + public final static int STACKSIZE_SIMPLE = 1; + public final static int STACKSIZE_DOUBLE = 2; + + public final static int VAR_LOCAL = 0; + public final static int VAR_STACK = 1; + + public final static int VAR_WRITE = 0; + public final static int VAR_READ = 1; + + + // ---------------------------------------------------------------------- + // ACCESS FLAGS + // ---------------------------------------------------------------------- + + public final static int ACC_PUBLIC = 0x0001; + public final static int ACC_PRIVATE = 0x0002; + public final static int ACC_PROTECTED = 0x0004; + public final static int ACC_STATIC = 0x0008; + public final static int ACC_FINAL = 0x0010; + public final static int ACC_SYNCHRONIZED = 0x0020; + public final static int ACC_NATIVE = 0x0100; + public final static int ACC_ABSTRACT = 0x0400; + public final static int ACC_STRICT = 0x0800; + public final static int ACC_VOLATILE = 0x0040; + public final static int ACC_BRIDGE = 0x0040; + public final static int ACC_TRANSIENT = 0x0080; + public final static int ACC_VARARGS = 0x0080; + public final static int ACC_SYNTHETIC = 0x1000; + public final static int ACC_ANNOTATION = 0x2000; + public final static int ACC_ENUM = 0x4000; + + // ---------------------------------------------------------------------- + // CLASS FLAGS + // ---------------------------------------------------------------------- + + public final static int ACC_SUPER = 0x0020; + public final static int ACC_INTERFACE = 0x0200; + + + // ---------------------------------------------------------------------- + // DEPENDENCY CONSTANTS + // ---------------------------------------------------------------------- + + public final static int DEP_CONSTANT = 0; + public final static int DEP_UNKNOWN = 1; + public final static int DEP_GENERAL = 2; + public final static int DEP_PARAMS = 4; + public final static int DEP_STATIC = 8; + + // ---------------------------------------------------------------------- + // INSTRUCTION GROUPS + // ---------------------------------------------------------------------- + + public final static int GROUP_GENERAL = 1; + public final static int GROUP_JUMP = 2; + public final static int GROUP_SWITCH = 3; + public final static int GROUP_INVOCATION = 4; + public final static int GROUP_FIELDACCESS = 5; + public final static int GROUP_RETURN = 6; + + // ---------------------------------------------------------------------- + // POOL CONSTANTS + // ---------------------------------------------------------------------- + + public final static int CONSTANT_Utf8 = 1; + public final static int CONSTANT_Integer = 3; + public final static int CONSTANT_Float = 4; + public final static int CONSTANT_Long = 5; + public final static int CONSTANT_Double = 6; + public final static int CONSTANT_Class = 7; + public final static int CONSTANT_String = 8; + public final static int CONSTANT_Fieldref = 9; + public final static int CONSTANT_Methodref = 10; + public final static int CONSTANT_InterfaceMethodref = 11; + public final static int CONSTANT_NameAndType = 12; + public final static int CONSTANT_MethodHandle = 15; + public final static int CONSTANT_MethodType = 16; + public final static int CONSTANT_InvokeDynamic = 18; + + // ---------------------------------------------------------------------- + // MethodHandle reference_kind values + // ---------------------------------------------------------------------- + + public final static int CONSTANT_MethodHandle_REF_getField = 1; + public final static int CONSTANT_MethodHandle_REF_getStatic = 2; + public final static int CONSTANT_MethodHandle_REF_putField = 3; + public final static int CONSTANT_MethodHandle_REF_putStatic = 4; + public final static int CONSTANT_MethodHandle_REF_invokeVirtual = 5; + public final static int CONSTANT_MethodHandle_REF_invokeStatic = 6; + public final static int CONSTANT_MethodHandle_REF_invokeSpecial = 7; + public final static int CONSTANT_MethodHandle_REF_newInvokeSpecial = 8; + public final static int CONSTANT_MethodHandle_REF_invokeInterface = 9; + + // ---------------------------------------------------------------------- + // VM OPCODES + // ---------------------------------------------------------------------- + + public final static int opc_nop = 0; + public final static int opc_aconst_null = 1; + public final static int opc_iconst_m1 = 2; + public final static int opc_iconst_0 = 3; + public final static int opc_iconst_1 = 4; + public final static int opc_iconst_2 = 5; + public final static int opc_iconst_3 = 6; + public final static int opc_iconst_4 = 7; + public final static int opc_iconst_5 = 8; + public final static int opc_lconst_0 = 9; + public final static int opc_lconst_1 = 10; + public final static int opc_fconst_0 = 11; + public final static int opc_fconst_1 = 12; + public final static int opc_fconst_2 = 13; + public final static int opc_dconst_0 = 14; + public final static int opc_dconst_1 = 15; + public final static int opc_bipush = 16; + public final static int opc_sipush = 17; + public final static int opc_ldc = 18; + public final static int opc_ldc_w = 19; + public final static int opc_ldc2_w = 20; + public final static int opc_iload = 21; + public final static int opc_lload = 22; + public final static int opc_fload = 23; + public final static int opc_dload = 24; + public final static int opc_aload = 25; + public final static int opc_iload_0 = 26; + public final static int opc_iload_1 = 27; + public final static int opc_iload_2 = 28; + public final static int opc_iload_3 = 29; + public final static int opc_lload_0 = 30; + public final static int opc_lload_1 = 31; + public final static int opc_lload_2 = 32; + public final static int opc_lload_3 = 33; + public final static int opc_fload_0 = 34; + public final static int opc_fload_1 = 35; + public final static int opc_fload_2 = 36; + public final static int opc_fload_3 = 37; + public final static int opc_dload_0 = 38; + public final static int opc_dload_1 = 39; + public final static int opc_dload_2 = 40; + public final static int opc_dload_3 = 41; + public final static int opc_aload_0 = 42; + public final static int opc_aload_1 = 43; + public final static int opc_aload_2 = 44; + public final static int opc_aload_3 = 45; + public final static int opc_iaload = 46; + public final static int opc_laload = 47; + public final static int opc_faload = 48; + public final static int opc_daload = 49; + public final static int opc_aaload = 50; + public final static int opc_baload = 51; + public final static int opc_caload = 52; + public final static int opc_saload = 53; + public final static int opc_istore = 54; + public final static int opc_lstore = 55; + public final static int opc_fstore = 56; + public final static int opc_dstore = 57; + public final static int opc_astore = 58; + public final static int opc_istore_0 = 59; + public final static int opc_istore_1 = 60; + public final static int opc_istore_2 = 61; + public final static int opc_istore_3 = 62; + public final static int opc_lstore_0 = 63; + public final static int opc_lstore_1 = 64; + public final static int opc_lstore_2 = 65; + public final static int opc_lstore_3 = 66; + public final static int opc_fstore_0 = 67; + public final static int opc_fstore_1 = 68; + public final static int opc_fstore_2 = 69; + public final static int opc_fstore_3 = 70; + public final static int opc_dstore_0 = 71; + public final static int opc_dstore_1 = 72; + public final static int opc_dstore_2 = 73; + public final static int opc_dstore_3 = 74; + public final static int opc_astore_0 = 75; + public final static int opc_astore_1 = 76; + public final static int opc_astore_2 = 77; + public final static int opc_astore_3 = 78; + public final static int opc_iastore = 79; + public final static int opc_lastore = 80; + public final static int opc_fastore = 81; + public final static int opc_dastore = 82; + public final static int opc_aastore = 83; + public final static int opc_bastore = 84; + public final static int opc_castore = 85; + public final static int opc_sastore = 86; + public final static int opc_pop = 87; + public final static int opc_pop2 = 88; + public final static int opc_dup = 89; + public final static int opc_dup_x1 = 90; + public final static int opc_dup_x2 = 91; + public final static int opc_dup2 = 92; + public final static int opc_dup2_x1 = 93; + public final static int opc_dup2_x2 = 94; + public final static int opc_swap = 95; + public final static int opc_iadd = 96; + public final static int opc_ladd = 97; + public final static int opc_fadd = 98; + public final static int opc_dadd = 99; + public final static int opc_isub = 100; + public final static int opc_lsub = 101; + public final static int opc_fsub = 102; + public final static int opc_dsub = 103; + public final static int opc_imul = 104; + public final static int opc_lmul = 105; + public final static int opc_fmul = 106; + public final static int opc_dmul = 107; + public final static int opc_idiv = 108; + public final static int opc_ldiv = 109; + public final static int opc_fdiv = 110; + public final static int opc_ddiv = 111; + public final static int opc_irem = 112; + public final static int opc_lrem = 113; + public final static int opc_frem = 114; + public final static int opc_drem = 115; + public final static int opc_ineg = 116; + public final static int opc_lneg = 117; + public final static int opc_fneg = 118; + public final static int opc_dneg = 119; + public final static int opc_ishl = 120; + public final static int opc_lshl = 121; + public final static int opc_ishr = 122; + public final static int opc_lshr = 123; + public final static int opc_iushr = 124; + public final static int opc_lushr = 125; + public final static int opc_iand = 126; + public final static int opc_land = 127; + public final static int opc_ior = 128; + public final static int opc_lor = 129; + public final static int opc_ixor = 130; + public final static int opc_lxor = 131; + public final static int opc_iinc = 132; + public final static int opc_i2l = 133; + public final static int opc_i2f = 134; + public final static int opc_i2d = 135; + public final static int opc_l2i = 136; + public final static int opc_l2f = 137; + public final static int opc_l2d = 138; + public final static int opc_f2i = 139; + public final static int opc_f2l = 140; + public final static int opc_f2d = 141; + public final static int opc_d2i = 142; + public final static int opc_d2l = 143; + public final static int opc_d2f = 144; + public final static int opc_i2b = 145; + public final static int opc_i2c = 146; + public final static int opc_i2s = 147; + public final static int opc_lcmp = 148; + public final static int opc_fcmpl = 149; + public final static int opc_fcmpg = 150; + public final static int opc_dcmpl = 151; + public final static int opc_dcmpg = 152; + public final static int opc_ifeq = 153; + public final static int opc_ifne = 154; + public final static int opc_iflt = 155; + public final static int opc_ifge = 156; + public final static int opc_ifgt = 157; + public final static int opc_ifle = 158; + public final static int opc_if_icmpeq = 159; + public final static int opc_if_icmpne = 160; + public final static int opc_if_icmplt = 161; + public final static int opc_if_icmpge = 162; + public final static int opc_if_icmpgt = 163; + public final static int opc_if_icmple = 164; + public final static int opc_if_acmpeq = 165; + public final static int opc_if_acmpne = 166; + public final static int opc_goto = 167; + public final static int opc_jsr = 168; + public final static int opc_ret = 169; + public final static int opc_tableswitch = 170; + public final static int opc_lookupswitch = 171; + public final static int opc_ireturn = 172; + public final static int opc_lreturn = 173; + public final static int opc_freturn = 174; + public final static int opc_dreturn = 175; + public final static int opc_areturn = 176; + public final static int opc_return = 177; + public final static int opc_getstatic = 178; + public final static int opc_putstatic = 179; + public final static int opc_getfield = 180; + public final static int opc_putfield = 181; + public final static int opc_invokevirtual = 182; + public final static int opc_invokespecial = 183; + public final static int opc_invokestatic = 184; + public final static int opc_invokeinterface = 185; + public final static int opc_invokedynamic = 186; + public final static int opc_xxxunusedxxx = 186; + public final static int opc_new = 187; + public final static int opc_newarray = 188; + public final static int opc_anewarray = 189; + public final static int opc_arraylength = 190; + public final static int opc_athrow = 191; + public final static int opc_checkcast = 192; + public final static int opc_instanceof = 193; + public final static int opc_monitorenter = 194; + public final static int opc_monitorexit = 195; + public final static int opc_wide = 196; + public final static int opc_multianewarray = 197; + public final static int opc_ifnull = 198; + public final static int opc_ifnonnull = 199; + public final static int opc_goto_w = 200; + public final static int opc_jsr_w = 201; + + +} diff --git a/src/org/jetbrains/java/decompiler/code/ConstantsUtil.java b/src/org/jetbrains/java/decompiler/code/ConstantsUtil.java new file mode 100644 index 0000000..dcaea77 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/ConstantsUtil.java @@ -0,0 +1,519 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code; + +import org.jetbrains.java.decompiler.code.optinstructions.ALOAD; +import org.jetbrains.java.decompiler.code.optinstructions.ANEWARRAY; +import org.jetbrains.java.decompiler.code.optinstructions.ASTORE; +import org.jetbrains.java.decompiler.code.optinstructions.BIPUSH; +import org.jetbrains.java.decompiler.code.optinstructions.CHECKCAST; +import org.jetbrains.java.decompiler.code.optinstructions.DLOAD; +import org.jetbrains.java.decompiler.code.optinstructions.DSTORE; +import org.jetbrains.java.decompiler.code.optinstructions.FLOAD; +import org.jetbrains.java.decompiler.code.optinstructions.FSTORE; +import org.jetbrains.java.decompiler.code.optinstructions.GETFIELD; +import org.jetbrains.java.decompiler.code.optinstructions.GETSTATIC; +import org.jetbrains.java.decompiler.code.optinstructions.GOTO; +import org.jetbrains.java.decompiler.code.optinstructions.GOTO_W; +import org.jetbrains.java.decompiler.code.optinstructions.IINC; +import org.jetbrains.java.decompiler.code.optinstructions.ILOAD; +import org.jetbrains.java.decompiler.code.optinstructions.INSTANCEOF; +import org.jetbrains.java.decompiler.code.optinstructions.INVOKEDYNAMIC; +import org.jetbrains.java.decompiler.code.optinstructions.INVOKEINTERFACE; +import org.jetbrains.java.decompiler.code.optinstructions.INVOKESPECIAL; +import org.jetbrains.java.decompiler.code.optinstructions.INVOKESTATIC; +import org.jetbrains.java.decompiler.code.optinstructions.INVOKEVIRTUAL; +import org.jetbrains.java.decompiler.code.optinstructions.ISTORE; +import org.jetbrains.java.decompiler.code.optinstructions.JSR; +import org.jetbrains.java.decompiler.code.optinstructions.JSR_W; +import org.jetbrains.java.decompiler.code.optinstructions.LDC; +import org.jetbrains.java.decompiler.code.optinstructions.LDC2_W; +import org.jetbrains.java.decompiler.code.optinstructions.LDC_W; +import org.jetbrains.java.decompiler.code.optinstructions.LLOAD; +import org.jetbrains.java.decompiler.code.optinstructions.LOOKUPSWITCH; +import org.jetbrains.java.decompiler.code.optinstructions.LSTORE; +import org.jetbrains.java.decompiler.code.optinstructions.MULTIANEWARRAY; +import org.jetbrains.java.decompiler.code.optinstructions.NEW; +import org.jetbrains.java.decompiler.code.optinstructions.NEWARRAY; +import org.jetbrains.java.decompiler.code.optinstructions.PUTFIELD; +import org.jetbrains.java.decompiler.code.optinstructions.PUTSTATIC; +import org.jetbrains.java.decompiler.code.optinstructions.RET; +import org.jetbrains.java.decompiler.code.optinstructions.SIPUSH; +import org.jetbrains.java.decompiler.code.optinstructions.TABLESWITCH; + +public class ConstantsUtil { + + public static String getName(int opcode) { + return opcodeNames[opcode]; + } + + public static Instruction getInstructionInstance(int opcode, boolean wide, int group, int bytecode_version, int[] operands) { + + Instruction instr = getInstructionInstance(opcode, bytecode_version); + instr.wide = wide; + instr.group = group; + instr.bytecode_version = bytecode_version; + instr.setOperands(operands); + + return instr; + } + + private static Instruction getInstructionInstance(int opcode, int bytecode_version) { + try { + Instruction instr; + + if((opcode >= CodeConstants.opc_ifeq && + opcode <= CodeConstants.opc_if_acmpne) || + opcode == CodeConstants.opc_ifnull || + opcode == CodeConstants.opc_ifnonnull) { + instr = new IfInstruction(); + } else { + + Class cl = opcodeClasses[opcode]; + + if(opcode == CodeConstants.opc_invokedynamic && bytecode_version < CodeConstants.BYTECODE_JAVA_7) { + cl = null; // instruction unused in Java 6 and before + } + + if(cl == null) { + instr = new Instruction(); + } else { + instr = (Instruction)cl.newInstance(); + } + } + + instr.opcode = opcode; + return instr; + } catch (Exception ex) { + return null; + } + + } + + + private static String[] opcodeNames = { + "nop", // "nop", + "aconst_null", // "aconst_null", + "iconst_m1", // "iconst_m1", + "iconst_0", // "iconst_0", + "iconst_1", // "iconst_1", + "iconst_2", // "iconst_2", + "iconst_3", // "iconst_3", + "iconst_4", // "iconst_4", + "iconst_5", // "iconst_5", + "lconst_0", // "lconst_0", + "lconst_1", // "lconst_1", + "fconst_0", // "fconst_0", + "fconst_1", // "fconst_1", + "fconst_2", // "fconst_2", + "dconst_0", // "dconst_0", + "dconst_1", // "dconst_1", + "bipush", // "bipush", + "sipush", // "sipush", + "ldc", // "ldc", + "ldc_w", // "ldc_w", + "ldc2_w", // "ldc2_w", + "iload", // "iload", + "lload", // "lload", + "fload", // "fload", + "dload", // "dload", + "aload", // "aload", + "iload_0", // "iload_0", + "iload_1", // "iload_1", + "iload_2", // "iload_2", + "iload_3", // "iload_3", + "lload_0", // "lload_0", + "lload_1", // "lload_1", + "lload_2", // "lload_2", + "lload_3", // "lload_3", + "fload_0", // "fload_0", + "fload_1", // "fload_1", + "fload_2", // "fload_2", + "fload_3", // "fload_3", + "dload_0", // "dload_0", + "dload_1", // "dload_1", + "dload_2", // "dload_2", + "dload_3", // "dload_3", + "aload_0", // "aload_0", + "aload_1", // "aload_1", + "aload_2", // "aload_2", + "aload_3", // "aload_3", + "iaload", // "iaload", + "laload", // "laload", + "faload", // "faload", + "daload", // "daload", + "aaload", // "aaload", + "baload", // "baload", + "caload", // "caload", + "saload", // "saload", + "istore", // "istore", + "lstore", // "lstore", + "fstore", // "fstore", + "dstore", // "dstore", + "astore", // "astore", + "istore_0", // "istore_0", + "istore_1", // "istore_1", + "istore_2", // "istore_2", + "istore_3", // "istore_3", + "lstore_0", // "lstore_0", + "lstore_1", // "lstore_1", + "lstore_2", // "lstore_2", + "lstore_3", // "lstore_3", + "fstore_0", // "fstore_0", + "fstore_1", // "fstore_1", + "fstore_2", // "fstore_2", + "fstore_3", // "fstore_3", + "dstore_0", // "dstore_0", + "dstore_1", // "dstore_1", + "dstore_2", // "dstore_2", + "dstore_3", // "dstore_3", + "astore_0", // "astore_0", + "astore_1", // "astore_1", + "astore_2", // "astore_2", + "astore_3", // "astore_3", + "iastore", // "iastore", + "lastore", // "lastore", + "fastore", // "fastore", + "dastore", // "dastore", + "aastore", // "aastore", + "bastore", // "bastore", + "castore", // "castore", + "sastore", // "sastore", + "pop", // "pop", + "pop2", // "pop2", + "dup", // "dup", + "dup_x1", // "dup_x1", + "dup_x2", // "dup_x2", + "dup2", // "dup2", + "dup2_x1", // "dup2_x1", + "dup2_x2", // "dup2_x2", + "swap", // "swap", + "iadd", // "iadd", + "ladd", // "ladd", + "fadd", // "fadd", + "dadd", // "dadd", + "isub", // "isub", + "lsub", // "lsub", + "fsub", // "fsub", + "dsub", // "dsub", + "imul", // "imul", + "lmul", // "lmul", + "fmul", // "fmul", + "dmul", // "dmul", + "idiv", // "idiv", + "ldiv", // "ldiv", + "fdiv", // "fdiv", + "ddiv", // "ddiv", + "irem", // "irem", + "lrem", // "lrem", + "frem", // "frem", + "drem", // "drem", + "ineg", // "ineg", + "lneg", // "lneg", + "fneg", // "fneg", + "dneg", // "dneg", + "ishl", // "ishl", + "lshl", // "lshl", + "ishr", // "ishr", + "lshr", // "lshr", + "iushr", // "iushr", + "lushr", // "lushr", + "iand", // "iand", + "land", // "land", + "ior", // "ior", + "lor", // "lor", + "ixor", // "ixor", + "lxor", // "lxor", + "iinc", // "iinc", + "i2l", // "i2l", + "i2f", // "i2f", + "i2d", // "i2d", + "l2i", // "l2i", + "l2f", // "l2f", + "l2d", // "l2d", + "f2i", // "f2i", + "f2l", // "f2l", + "f2d", // "f2d", + "d2i", // "d2i", + "d2l", // "d2l", + "d2f", // "d2f", + "i2b", // "i2b", + "i2c", // "i2c", + "i2s", // "i2s", + "lcmp", // "lcmp", + "fcmpl", // "fcmpl", + "fcmpg", // "fcmpg", + "dcmpl", // "dcmpl", + "dcmpg", // "dcmpg", + "ifeq", // "ifeq", + "ifne", // "ifne", + "iflt", // "iflt", + "ifge", // "ifge", + "ifgt", // "ifgt", + "ifle", // "ifle", + "if_icmpeq", // "if_icmpeq", + "if_icmpne", // "if_icmpne", + "if_icmplt", // "if_icmplt", + "if_icmpge", // "if_icmpge", + "if_icmpgt", // "if_icmpgt", + "if_icmple", // "if_icmple", + "if_acmpeq", // "if_acmpeq", + "if_acmpne", // "if_acmpne", + "goto", // "goto", + "jsr", // "jsr", + "ret", // "ret", + "tableswitch", // "tableswitch", + "lookupswitch", // "lookupswitch", + "ireturn", // "ireturn", + "lreturn", // "lreturn", + "freturn", // "freturn", + "dreturn", // "dreturn", + "areturn", // "areturn", + "return", // "return", + "getstatic", // "getstatic", + "putstatic", // "putstatic", + "getfield", // "getfield", + "putfield", // "putfield", + "invokevirtual", // "invokevirtual", + "invokespecial", // "invokespecial", + "invokestatic", // "invokestatic", + "invokeinterface", // "invokeinterface", + //"xxxunusedxxx", // "xxxunusedxxx", Java 6 and before + "invokedynamic", // "invokedynamic", Java 7 and later + "new", // "new", + "newarray", // "newarray", + "anewarray", // "anewarray", + "arraylength", // "arraylength", + "athrow", // "athrow", + "checkcast", // "checkcast", + "instanceof", // "instanceof", + "monitorenter", // "monitorenter", + "monitorexit", // "monitorexit", + "wide", // "wide", + "multianewarray", // "multianewarray", + "ifnull", // "ifnull", + "ifnonnull", // "ifnonnull", + "goto_w", // "goto_w", + "jsr_w" // "jsr_w" + }; + + private static Class[] opcodeClasses = { + null, // "nop", + null, // "aconst_null", + null, // "iconst_m1", + null, // "iconst_0", + null, // "iconst_1", + null, // "iconst_2", + null, // "iconst_3", + null, // "iconst_4", + null, // "iconst_5", + null, // "lconst_0", + null, // "lconst_1", + null, // "fconst_0", + null, // "fconst_1", + null, // "fconst_2", + null, // "dconst_0", + null, // "dconst_1", + BIPUSH.class, // "bipush", + SIPUSH.class, // "sipush", + LDC.class, // "ldc", + LDC_W.class, // "ldc_w", + LDC2_W.class, // "ldc2_w", + ILOAD.class, // "iload", + LLOAD.class, // "lload", + FLOAD.class, // "fload", + DLOAD.class, // "dload", + ALOAD.class, // "aload", + null, // "iload_0", + null, // "iload_1", + null, // "iload_2", + null, // "iload_3", + null, // "lload_0", + null, // "lload_1", + null, // "lload_2", + null, // "lload_3", + null, // "fload_0", + null, // "fload_1", + null, // "fload_2", + null, // "fload_3", + null, // "dload_0", + null, // "dload_1", + null, // "dload_2", + null, // "dload_3", + null, // "aload_0", + null, // "aload_1", + null, // "aload_2", + null, // "aload_3", + null, // "iaload", + null, // "laload", + null, // "faload", + null, // "daload", + null, // "aaload", + null, // "baload", + null, // "caload", + null, // "saload", + ISTORE.class, // "istore", + LSTORE.class, // "lstore", + FSTORE.class, // "fstore", + DSTORE.class, // "dstore", + ASTORE.class, // "astore", + null, // "istore_0", + null, // "istore_1", + null, // "istore_2", + null, // "istore_3", + null, // "lstore_0", + null, // "lstore_1", + null, // "lstore_2", + null, // "lstore_3", + null, // "fstore_0", + null, // "fstore_1", + null, // "fstore_2", + null, // "fstore_3", + null, // "dstore_0", + null, // "dstore_1", + null, // "dstore_2", + null, // "dstore_3", + null, // "astore_0", + null, // "astore_1", + null, // "astore_2", + null, // "astore_3", + null, // "iastore", + null, // "lastore", + null, // "fastore", + null, // "dastore", + null, // "aastore", + null, // "bastore", + null, // "castore", + null, // "sastore", + null, // "pop", + null, // "pop2", + null, // "dup", + null, // "dup_x1", + null, // "dup_x2", + null, // "dup2", + null, // "dup2_x1", + null, // "dup2_x2", + null, // "swap", + null, // "iadd", + null, // "ladd", + null, // "fadd", + null, // "dadd", + null, // "isub", + null, // "lsub", + null, // "fsub", + null, // "dsub", + null, // "imul", + null, // "lmul", + null, // "fmul", + null, // "dmul", + null, // "idiv", + null, // "ldiv", + null, // "fdiv", + null, // "ddiv", + null, // "irem", + null, // "lrem", + null, // "frem", + null, // "drem", + null, // "ineg", + null, // "lneg", + null, // "fneg", + null, // "dneg", + null, // "ishl", + null, // "lshl", + null, // "ishr", + null, // "lshr", + null, // "iushr", + null, // "lushr", + null, // "iand", + null, // "land", + null, // "ior", + null, // "lor", + null, // "ixor", + null, // "lxor", + IINC.class, // "iinc", + null, // "i2l", + null, // "i2f", + null, // "i2d", + null, // "l2i", + null, // "l2f", + null, // "l2d", + null, // "f2i", + null, // "f2l", + null, // "f2d", + null, // "d2i", + null, // "d2l", + null, // "d2f", + null, // "i2b", + null, // "i2c", + null, // "i2s", + null, // "lcmp", + null, // "fcmpl", + null, // "fcmpg", + null, // "dcmpl", + null, // "dcmpg", + null, // "ifeq", + null, // "ifne", + null, // "iflt", + null, // "ifge", + null, // "ifgt", + null, // "ifle", + null, // "if_icmpeq", + null, // "if_icmpne", + null, // "if_icmplt", + null, // "if_icmpge", + null, // "if_icmpgt", + null, // "if_icmple", + null, // "if_acmpeq", + null, // "if_acmpne", + GOTO.class, // "goto", + JSR.class, // "jsr", + RET.class, // "ret", + TABLESWITCH.class, // "tableswitch", + LOOKUPSWITCH.class, // "lookupswitch", + null, // "ireturn", + null, // "lreturn", + null, // "freturn", + null, // "dreturn", + null, // "areturn", + null, // "return", + GETSTATIC.class, // "getstatic", + PUTSTATIC.class, // "putstatic", + GETFIELD.class, // "getfield", + PUTFIELD.class, // "putfield", + INVOKEVIRTUAL.class, // "invokevirtual", + INVOKESPECIAL.class, // "invokespecial", + INVOKESTATIC.class, // "invokestatic", + INVOKEINTERFACE.class, // "invokeinterface", + INVOKEDYNAMIC.class, // "xxxunusedxxx" Java 6 and before, "invokedynamic" Java 7 and later + NEW.class, // "new", + NEWARRAY.class, // "newarray", + ANEWARRAY.class, // "anewarray", + null, // "arraylength", + null, // "athrow", + CHECKCAST.class, // "checkcast", + INSTANCEOF.class, // "instanceof", + null, // "monitorenter", + null, // "monitorexit", + null, // "wide", + MULTIANEWARRAY.class, // "multianewarray", + null, // "ifnull", + null, // "ifnonnull", + GOTO_W.class, // "goto_w", + JSR_W.class // "jsr_w" + }; + + + +} diff --git a/src/org/jetbrains/java/decompiler/code/ExceptionHandler.java b/src/org/jetbrains/java/decompiler/code/ExceptionHandler.java new file mode 100644 index 0000000..87598ac --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/ExceptionHandler.java @@ -0,0 +1,62 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.main.DecompilerContext; + +public class ExceptionHandler { + + public int from = 0; + public int to = 0; + public int handler = 0; + + public int from_instr = 0; + public int to_instr = 0; + public int handler_instr = 0; + + public int class_index = 0; + public String exceptionClass = null; + + public ExceptionHandler(){} + + public ExceptionHandler(int from_raw, int to_raw, int handler_raw, String exceptionClass) { + this.from = from_raw; + this.to = to_raw; + this.handler = handler_raw; + this.exceptionClass = exceptionClass; + } + + public void writeToStream(DataOutputStream out) throws IOException { + out.writeShort(from); + out.writeShort(to); + out.writeShort(handler); + out.writeShort(class_index); + } + + public String toString() { + + String new_line_separator = DecompilerContext.getNewLineSeparator(); + + StringBuffer buf = new StringBuffer(); + buf.append("from: "+from+" to: "+to+" handler: "+handler+new_line_separator); + buf.append("from_instr: "+from_instr+" to_instr: "+to_instr+" handler_instr: "+handler_instr+new_line_separator); + buf.append("exceptionClass: "+exceptionClass+new_line_separator); + return buf.toString(); + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/ExceptionTable.java b/src/org/jetbrains/java/decompiler/code/ExceptionTable.java new file mode 100644 index 0000000..da8ec22 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/ExceptionTable.java @@ -0,0 +1,57 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code; + +import java.util.ArrayList; +import java.util.List; + +import org.jetbrains.java.decompiler.code.interpreter.Util; +import org.jetbrains.java.decompiler.struct.StructContext; + +public class ExceptionTable { + + private List handlers = new ArrayList(); + + public ExceptionTable() {} + + public ExceptionTable(List handlers) { + this.handlers = handlers; + } + + + public ExceptionHandler getHandlerByClass(StructContext context, int line, String valclass, boolean withany) { + + ExceptionHandler res = null; // no handler found + + for(ExceptionHandler handler : handlers) { + if(handler.from<=line && handler.to>line) { + String name = handler.exceptionClass; + + if((withany && name==null) || // any -> finally or synchronized handler + (name!=null && Util.instanceOf(context, valclass, name))) { + res = handler; + break; + } + } + } + + return res; + } + + public List getHandlers() { + return handlers; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/FullInstructionSequence.java b/src/org/jetbrains/java/decompiler/code/FullInstructionSequence.java new file mode 100644 index 0000000..f879fd0 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/FullInstructionSequence.java @@ -0,0 +1,38 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code; + +import org.jetbrains.java.decompiler.util.VBStyleCollection; + + +public class FullInstructionSequence extends InstructionSequence { + + // ***************************************************************************** + // constructors + // ***************************************************************************** + + public FullInstructionSequence(VBStyleCollection collinstr, ExceptionTable extable) { + this.collinstr = collinstr; + this.exceptionTable = extable; + + // translate raw exception handlers to instr + for(ExceptionHandler handler : extable.getHandlers()) { + handler.from_instr = this.getPointerByAbsOffset(handler.from); + handler.to_instr = this.getPointerByAbsOffset(handler.to); + handler.handler_instr = this.getPointerByAbsOffset(handler.handler); + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/IfInstruction.java b/src/org/jetbrains/java/decompiler/code/IfInstruction.java new file mode 100644 index 0000000..befae18 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/IfInstruction.java @@ -0,0 +1,36 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code; + +import java.io.DataOutputStream; +import java.io.IOException; + +/* + * opc_ifeq, opc_ifne, opc_iflt, opc_ifge, opc_ifgt, opc_ifle, opc_if_icmpeq, opc_if_icmpne, opc_if_icmplt, + * opc_if_icmpge, opc_if_icmpgt, opc_if_icmple, opc_if_acmpeq, opc_if_acmpne, opc_ifnull, opc_ifnonnull + */ + +public class IfInstruction extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opcode); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/Instruction.java b/src/org/jetbrains/java/decompiler/code/Instruction.java new file mode 100644 index 0000000..faa8926 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/Instruction.java @@ -0,0 +1,124 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code; + +import java.io.DataOutputStream; +import java.io.IOException; + +public class Instruction implements CodeConstants { + + // ***************************************************************************** + // public fields + // ***************************************************************************** + + public int opcode; + + public int group = CodeConstants.GROUP_GENERAL; + + public boolean wide = false; + + public int bytecode_version = BYTECODE_JAVA_LE_4; + + // ***************************************************************************** + // private fields + // ***************************************************************************** + + private int[] operands = null; + + // ***************************************************************************** + // public methods + // ***************************************************************************** + + public Instruction() {} + + public int length() { + return 1; + } + + public int operandsCount() { + return (operands==null)?0:operands.length; + } + + public int getOperand(int index) { + return operands[index]; + } + + public Instruction clone() { + return ConstantsUtil.getInstructionInstance(opcode, wide, group, bytecode_version, operands==null?null:(int[])operands.clone()); + } + + public String toString() { + + String res = wide?"@wide ":""; + res+="@"+ConstantsUtil.getName(opcode); + + int len = operandsCount(); + for(int i=0;i=opc_ireturn && opcode<=opc_return) && opcode!=opc_athrow + && opcode!=opc_jsr && opcode!=opc_tableswitch && opcode!=opc_lookupswitch; + } + + public boolean equalsInstruction(Instruction instr) { + if(opcode != instr.opcode || wide != instr.wide + || operandsCount() != instr.operandsCount()) { + return false; + } + + if(operands != null) { + for(int i=0;i collinstr = new VBStyleCollection(); + + protected int pointer = 0; + + protected ExceptionTable exceptionTable = new ExceptionTable(); + + // ***************************************************************************** + // public methods + // ***************************************************************************** + + // to nbe overwritten + public InstructionSequence clone() {return null;} + + public void clear() { + collinstr.clear(); + pointer = 0; + exceptionTable = new ExceptionTable(); + } + + public void addInstruction(Instruction inst, int offset){ + collinstr.addWithKey(inst, offset); + } + + public void addInstruction(int index, Instruction inst, int offset){ + collinstr.addWithKeyAndIndex(index, inst, offset); + } + + public void addSequence(InstructionSequence seq){ + for(int i=0;i handlers = exceptionTable.getHandlers(); + + out.writeShort(handlers.size()); + for(int i=0;i() { + + public int compare(ExceptionHandler handler0, ExceptionHandler handler1) { + + if(handler0.to == handler1.to) { + if(handler0.exceptionClass == null) { + return 1; + } else { + if(handler1.exceptionClass == null) { + return -1; + } else if(handler0.exceptionClass.equals(handler1.exceptionClass)){ + return (handler0.from > handler1.from)?-1:1; // invalid code + } else { + if(Util.instanceOf(context, handler0.exceptionClass, handler1.exceptionClass)) { + return -1; + } else { + return 1; + } + } + } + } else { + return (handler0.to > handler1.to)?1:-1; + } + } + }); + + } + + + // ***************************************************************************** + // getter and setter methods + // ***************************************************************************** + + public int getPointer() { + return pointer; + } + + public void setPointer(int pointer) { + this.pointer = pointer; + } + + public ExceptionTable getExceptionTable() { + return exceptionTable; + } + + public void setExceptionTable(ExceptionTable exceptionTable) { + this.exceptionTable = exceptionTable; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/JumpInstruction.java b/src/org/jetbrains/java/decompiler/code/JumpInstruction.java new file mode 100644 index 0000000..2daeeeb --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/JumpInstruction.java @@ -0,0 +1,41 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code; + +/* + * opc_ifeq, opc_ifne, opc_iflt, opc_ifge, opc_ifgt, opc_ifle, opc_if_icmpeq, opc_if_icmpne, opc_if_icmplt, + * opc_if_icmpge, opc_if_icmpgt, opc_if_icmple, opc_if_acmpeq, opc_if_acmpne, opc_ifnull, opc_ifnonnull + * opc_goto, opc_jsr, opc_goto_w, opc_jsr_w + */ + + +public class JumpInstruction extends Instruction { + + public int destination; + + public JumpInstruction() {} + + public void initInstruction(InstructionSequence seq) { + destination = seq.getPointerByRelOffset(this.getOperand(0)); + } + + public JumpInstruction clone() { + JumpInstruction newinstr = (JumpInstruction)super.clone(); + + newinstr.destination = destination; + return newinstr; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/SimpleInstructionSequence.java b/src/org/jetbrains/java/decompiler/code/SimpleInstructionSequence.java new file mode 100644 index 0000000..c082092 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/SimpleInstructionSequence.java @@ -0,0 +1,39 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code; + +import org.jetbrains.java.decompiler.util.VBStyleCollection; + +public class SimpleInstructionSequence extends InstructionSequence { + + public SimpleInstructionSequence() {} + + public SimpleInstructionSequence(VBStyleCollection collinstr) { + this.collinstr = collinstr; + } + + public SimpleInstructionSequence clone() { + SimpleInstructionSequence newseq = new SimpleInstructionSequence(collinstr.clone()); + newseq.setPointer(this.getPointer()); + + return newseq; + } + + public void removeInstruction(int index) { + collinstr.remove(index); + } + + +} diff --git a/src/org/jetbrains/java/decompiler/code/SwitchInstruction.java b/src/org/jetbrains/java/decompiler/code/SwitchInstruction.java new file mode 100644 index 0000000..63d0f4c --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/SwitchInstruction.java @@ -0,0 +1,93 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code; + +/* + * opc_tableswitch, lookupswitch + */ + +public class SwitchInstruction extends Instruction { + + private int[] destinations; + + private int[] values; + + private int defaultdest; + + public SwitchInstruction() {} + + + public void initInstruction(InstructionSequence seq) { + + int pref = (opcode==CodeConstants.opc_tableswitch?3:2); + int len = this.getOperands().length - pref; + defaultdest = seq.getPointerByRelOffset(this.getOperand(0)); + + int low = 0; + + if(opcode==CodeConstants.opc_lookupswitch) { + len/=2; + } else { + low = this.getOperand(1); + } + + destinations = new int[len]; + values = new int[len]; + + for(int i=0,k=0;i preds = new ArrayList(); + + private List succs = new ArrayList(); + + private List instrOldOffsets = new ArrayList(); + + private List predExceptions = new ArrayList(); + + private List succExceptions = new ArrayList(); + + + + public BasicBlock() {} + + public BasicBlock(int id) { + this.id = id; + } + + // ***************************************************************************** + // public methods + // ***************************************************************************** + + public Object clone() { + + BasicBlock block = new BasicBlock(); + block.id = id; + block.setSeq(seq.clone()); + block.setInstrOldOffsets(new ArrayList(instrOldOffsets)); + + return block; + } + + public void free() { + preds.clear(); + succs.clear(); + instrOldOffsets.clear(); + succExceptions.clear(); + seq = new SimpleInstructionSequence(); + } + + public Instruction getInstruction(int index) { + return seq.getInstr(index); + } + + public Instruction getLastInstruction() { + if(seq.isEmpty()) { + return null; + } else { + return seq.getLastInstr(); + } + } + + public int size() { + return seq.length(); + } + + public void addPredecessor(BasicBlock block) { + preds.add(block); + } + + public void removePredecessor(BasicBlock block) { + while(preds.remove(block)); + } + + public void addSuccessor(BasicBlock block) { + succs.add(block); + block.addPredecessor(this); + } + + public void removeSuccessor(BasicBlock block) { + while(succs.remove(block)); + block.removePredecessor(this); + } + + // FIXME: unify block comparisons: id or direkt equality + public void replaceSuccessor(BasicBlock oldBlock, BasicBlock newBlock) { + for(int i=0;i getInstrOldOffsets() { + return instrOldOffsets; + } + + public void setInstrOldOffsets(List instrInds) { + this.instrOldOffsets = instrInds; + } + + public List getPredecessors() { + List lst = new ArrayList(preds); + lst.addAll(predExceptions); + return lst; + } + + public List getPreds() { + return preds; + } + + public void setPreds(List preds) { + this.preds = preds; + } + + public InstructionSequence getSeq() { + return seq; + } + + public void setSeq(InstructionSequence seq) { + this.seq = seq; + } + + public List getSuccs() { + return succs; + } + + public void setSuccs(List succs) { + this.succs = succs; + } + + + public List getSuccExceptions() { + return succExceptions; + } + + + public void setSuccExceptions(List succExceptions) { + this.succExceptions = succExceptions; + } + + public List getPredExceptions() { + return predExceptions; + } + + public void setPredExceptions(List predExceptions) { + this.predExceptions = predExceptions; + } + + +} diff --git a/src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java b/src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java new file mode 100644 index 0000000..824e8af --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java @@ -0,0 +1,887 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.cfg; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.jetbrains.java.decompiler.code.CodeConstants; +import org.jetbrains.java.decompiler.code.ExceptionHandler; +import org.jetbrains.java.decompiler.code.Instruction; +import org.jetbrains.java.decompiler.code.InstructionSequence; +import org.jetbrains.java.decompiler.code.JumpInstruction; +import org.jetbrains.java.decompiler.code.SimpleInstructionSequence; +import org.jetbrains.java.decompiler.code.SwitchInstruction; +import org.jetbrains.java.decompiler.code.interpreter.InstructionImpact; +import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.modules.code.DeadCodeHelper; +import org.jetbrains.java.decompiler.struct.StructMethod; +import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import org.jetbrains.java.decompiler.struct.gen.DataPoint; +import org.jetbrains.java.decompiler.struct.gen.VarType; +import org.jetbrains.java.decompiler.util.ListStack; +import org.jetbrains.java.decompiler.util.VBStyleCollection; + +public class ControlFlowGraph implements CodeConstants { + + public int last_id = 0; + + // ***************************************************************************** + // private fields + // ***************************************************************************** + + private VBStyleCollection blocks; + + private BasicBlock first; + + private BasicBlock last; + + private List exceptions; + + private HashMap subroutines; + + private HashSet finallyExits = new HashSet(); + + // ***************************************************************************** + // constructors + // ***************************************************************************** + + public ControlFlowGraph(InstructionSequence seq) { + buildBlocks(seq); + } + + + // ***************************************************************************** + // public methods + // ***************************************************************************** + + public void free() { + + for(BasicBlock block: blocks) { + block.free(); + } + + blocks.clear(); + first = null; + last = null; + exceptions.clear(); + finallyExits.clear(); + } + + public void removeMarkers() { + for(BasicBlock block: blocks) { + block.mark = 0; + } + } + + public String toString() { + + String new_line_separator = DecompilerContext.getNewLineSeparator(); + + StringBuffer buf = new StringBuffer(); + + for(BasicBlock block: blocks) { + buf.append("----- Block "+block.id+" -----" + new_line_separator); + buf.append(block.toString()); + buf.append("----- Edges -----" + new_line_separator); + + List suc = block.getSuccs(); + for(int j=0;j>>>>>>>(regular) Block "+((BasicBlock)suc.get(j)).id+new_line_separator); + } + suc = block.getSuccExceptions(); + for(int j=0;j>>>>>>>(exception) Block "+handler.id+"\t"+"ERROR: range not found!"+new_line_separator); + } else { + List exceptionTypes = range.getExceptionTypes(); + if(exceptionTypes == null) { + buf.append(">>>>>>>>(exception) Block "+handler.id+"\t"+"NULL"+new_line_separator); + } else { + for(String exceptionType : exceptionTypes) { + buf.append(">>>>>>>>(exception) Block "+handler.id+"\t"+exceptionType+new_line_separator); + } + } + } + } + buf.append("----- ----- -----" + new_line_separator); + + } + + return buf.toString(); + + } + + public void inlineJsr(StructMethod mt) { + processJsr(); + removeJsr(mt); + + removeMarkers(); + + DeadCodeHelper.removeEmptyBlocks(this); + } + + public void removeBlock(BasicBlock block) { + + while(block.getSuccs().size()>0) { + block.removeSuccessor((BasicBlock)block.getSuccs().get(0)); + } + + while(block.getSuccExceptions().size()>0) { + block.removeSuccessorException((BasicBlock)block.getSuccExceptions().get(0)); + } + + while(block.getPreds().size()>0) { + ((BasicBlock)block.getPreds().get(0)).removeSuccessor(block); + } + + while(block.getPredExceptions().size()>0) { + ((BasicBlock)block.getPredExceptions().get(0)).removeSuccessorException(block); + } + + last.removePredecessor(block); + + blocks.removeWithKey(block.id); + + for(int i=exceptions.size()-1;i>=0;i--) { + ExceptionRangeCFG range = (ExceptionRangeCFG)exceptions.get(i); + if(range.getHandler() == block) { + exceptions.remove(i); + } else { + List lstRange = range.getProtectedRange(); + lstRange.remove(block); + + if(lstRange.isEmpty()) { + exceptions.remove(i); + } + } + } + + Iterator> it = subroutines.entrySet().iterator(); + while(it.hasNext()) { + Entry ent = it.next(); + if(ent.getKey() == block || ent.getValue() == block) { + it.remove(); + } + } + + } + + public ExceptionRangeCFG getExceptionRange(BasicBlock handler, BasicBlock block) { + + //List ranges = new ArrayList(); + + for(int i=exceptions.size()-1;i>=0;i--) { + ExceptionRangeCFG range = exceptions.get(i); + if(range.getHandler() == handler && range.getProtectedRange().contains(block)) { + return range; + //ranges.add(range); + } + } + + return null; + //return ranges.isEmpty() ? null : ranges; + } + +// public String getExceptionsUniqueString(BasicBlock handler, BasicBlock block) { +// +// List ranges = getExceptionRange(handler, block); +// +// if(ranges == null) { +// return null; +// } else { +// Set setExceptionStrings = new HashSet(); +// for(ExceptionRangeCFG range : ranges) { +// setExceptionStrings.add(range.getExceptionType()); +// } +// +// String ret = ""; +// for(String exception : setExceptionStrings) { +// ret += exception; +// } +// +// return ret; +// } +// } + + + // ***************************************************************************** + // private methods + // ***************************************************************************** + + private void buildBlocks(InstructionSequence instrseq) { + + short[] states = findStartInstructions(instrseq); + + HashMap mapInstrBlocks = new HashMap(); + VBStyleCollection colBlocks = createBasicBlocks(states, instrseq, mapInstrBlocks); + + blocks = colBlocks; + + connectBlocks(colBlocks, mapInstrBlocks); + + setExceptionEdges(instrseq, mapInstrBlocks); + + setSubroutineEdges(); + + setFirstAndLastBlocks(); + } + + private short[] findStartInstructions(InstructionSequence seq) { + + int len = seq.length(); + short[] inststates = new short[len]; + + HashSet excSet = new HashSet(); + + for(ExceptionHandler handler : seq.getExceptionTable().getHandlers()) { + excSet.add(handler.from_instr); + excSet.add(handler.to_instr); + excSet.add(handler.handler_instr); + } + + + for(int i=0;i=0;j--) { + inststates[dests[j]] = 1; + } + inststates[swinstr.getDefaultdest()] = 1; + if(i+1 < len) { + inststates[i+1] = 1; + } + } + } + + // first instruction + inststates[0] = 1; + + return inststates; + } + + + private VBStyleCollection createBasicBlocks(short[] startblock, InstructionSequence instrseq, + HashMap mapInstrBlocks) { + + VBStyleCollection col = new VBStyleCollection(); + + InstructionSequence currseq = null; + ArrayList lstOffs = null; + + int len = startblock.length; + short counter = 0; + int blockoffset = 0; + + BasicBlock currentBlock = null; + for(int i=0;i(); + + currentBlock.setSeq(currseq); + currentBlock.setInstrOldOffsets(lstOffs); + col.addWithKey(currentBlock, currentBlock.id); + + blockoffset = instrseq.getOffset(i); + } + + startblock[i] = counter; + mapInstrBlocks.put(i, currentBlock); + + currseq.addInstruction(instrseq.getInstr(i), instrseq.getOffset(i)-blockoffset); + lstOffs.add(instrseq.getOffset(i)); + } + + last_id = counter; + + return col; + } + + + private void connectBlocks(List lstbb, HashMap mapInstrBlocks) { + + for(int i=0;i instrBlocks) { + + exceptions = new ArrayList(); + + Map mapRanges = new HashMap(); + + for(ExceptionHandler handler : instrseq.getExceptionTable().getHandlers()) { + + BasicBlock from = instrBlocks.get(handler.from_instr); + BasicBlock to = instrBlocks.get(handler.to_instr); + BasicBlock handle = instrBlocks.get(handler.handler_instr); + + String key = from.id + ":" + to.id + ":" + handle.id; + + if(mapRanges.containsKey(key)) { + ExceptionRangeCFG range = mapRanges.get(key); + range.addExceptionType(handler.exceptionClass); + } else { + + List protectedRange = new ArrayList(); + for(int j=from.id;j subroutines = new HashMap(); + + for(BasicBlock block : blocks) { + + if(block.getSeq().getLastInstr().opcode == CodeConstants.opc_jsr) { + + LinkedList stack = new LinkedList(); + LinkedList> stackJsrStacks = new LinkedList>(); + + HashSet setVisited = new HashSet(); + + stack.add(block); + stackJsrStacks.add(new LinkedList()); + + while(!stack.isEmpty()) { + + BasicBlock node = stack.removeFirst(); + LinkedList jsrstack = stackJsrStacks.removeFirst(); + + setVisited.add(node); + + switch(node.getSeq().getLastInstr().opcode) { + case CodeConstants.opc_jsr: + jsrstack.add(node); + break; + case CodeConstants.opc_ret: + BasicBlock enter = jsrstack.getLast(); + BasicBlock exit = blocks.getWithKey(enter.id + 1); // FIXME: find successor in a better way + + if(exit!=null) { + if(!node.isSuccessor(exit)) { + node.addSuccessor(exit); + } + jsrstack.removeLast(); + subroutines.put(enter, exit); + } else { + throw new RuntimeException("ERROR: last instruction jsr"); + } + } + + if(!jsrstack.isEmpty()) { + for(BasicBlock succ : node.getSuccs()) { + if(!setVisited.contains(succ)) { + stack.add(succ); + stackJsrStacks.add(new LinkedList(jsrstack)); + } + } + } + } + } + } + + this.subroutines = subroutines; + } + + private void processJsr() { + + while(processJsrRanges()!=0); + } + + private int processJsrRanges() { + + List lstJsrAll = new ArrayList(); + + // get all jsr ranges + for(Entry ent : subroutines.entrySet()){ + BasicBlock jsr = ent.getKey(); + BasicBlock ret = ent.getValue(); + + lstJsrAll.add(new Object[]{jsr, getJsrRange(jsr, ret), ret}); + } + + // sort ranges + // FIXME: better sort order + List lstJsr = new ArrayList(); + for(Object[] arr : lstJsrAll) { + int i=0; + for(;i)arrJsr[1]).contains(arr[0])) { + break; + } + } + + lstJsr.add(i, arr); + } + + // find the first intersection + for(int i=0;i set = (HashSet)arr[1]; + + for(int j=i+1;j set1 = (HashSet)arr1[1]; + + if(!set.contains(arr1[0]) && !set1.contains(arr[0])) { // rang 0 doesn't contain entry 1 and vice versa + HashSet setc = new HashSet(set); + setc.retainAll(set1); + + if(!setc.isEmpty()) { + splitJsrRange((BasicBlock)arr[0], (BasicBlock)arr[2], setc); + return 1; + } + } + } + } + + return 0; + } + + private HashSet getJsrRange(BasicBlock jsr, BasicBlock ret) { + + HashSet blocks = new HashSet(); + + LinkedList lstNodes = new LinkedList(); + lstNodes.add(jsr); + + BasicBlock dom = jsr.getSuccs().get(0); + + while(!lstNodes.isEmpty()) { + + BasicBlock node = lstNodes.remove(0); + + for(int j=0;j<2;j++) { + List lst; + if(j==0) { + if(node.getLastInstruction().opcode == CodeConstants.opc_ret) { + if(node.getSuccs().contains(ret)) { + continue; + } + } + lst = node.getSuccs(); + } else { + if(node == jsr) { + continue; + } + lst = node.getSuccExceptions(); + } + + CHILD: + for(int i=lst.size()-1;i>=0;i--) { + + BasicBlock child = lst.get(i); + if(!blocks.contains(child)) { + + if(node != jsr) { + for(int k=0;k common_blocks) { + + LinkedList lstNodes = new LinkedList(); + HashMap mapNewNodes = new HashMap(); + + lstNodes.add(jsr); + mapNewNodes.put(jsr.id, jsr); + + while(!lstNodes.isEmpty()) { + + BasicBlock node = lstNodes.remove(0); + + for(int j=0;j<2;j++) { + List lst; + if(j==0) { + if(node.getLastInstruction().opcode == CodeConstants.opc_ret) { + if(node.getSuccs().contains(ret)) { + continue; + } + } + lst = node.getSuccs(); + } else { + if(node == jsr) { + continue; + } + lst = node.getSuccExceptions(); + } + + + for(int i=lst.size()-1;i>=0;i--) { + + BasicBlock child = (BasicBlock)lst.get(i); + Integer childid = child.id; + + if(mapNewNodes.containsKey(childid)) { + node.replaceSuccessor(child, (BasicBlock)mapNewNodes.get(childid)); + } else if(common_blocks.contains(child)) { + + // make a copy of the current block + BasicBlock copy = (BasicBlock)child.clone(); + copy.id = ++last_id; + // copy all successors + if(copy.getLastInstruction().opcode == CodeConstants.opc_ret && + child.getSuccs().contains(ret)) { + copy.addSuccessor(ret); + child.removeSuccessor(ret); + } else { + for(int k=0;k common_blocks, HashMap mapNewNodes) { + + for(int i=exceptions.size()-1;i>=0;i--) { + + ExceptionRangeCFG range = (ExceptionRangeCFG)exceptions.get(i); + List lstRange = range.getProtectedRange(); + + HashSet setBoth = new HashSet(common_blocks); + setBoth.retainAll(lstRange); + + if(setBoth.size()>0) { + List lstNewRange; + + if(setBoth.size()==lstRange.size()) { + lstNewRange = new ArrayList(); + ExceptionRangeCFG newRange = new ExceptionRangeCFG(lstNewRange, + (BasicBlock)mapNewNodes.get(range.getHandler().id),range.getExceptionTypes()); + exceptions.add(newRange); + } else { + lstNewRange = lstRange; + } + + for(BasicBlock block : setBoth) { + lstNewRange.add(mapNewNodes.get(block.id)); + } + } + } + + } + + private void removeJsr(StructMethod mt) { + removeJsrInstructions(mt.getClassStruct().getPool(), first, DataPoint.getInitialDataPoint(mt)); + } + + private void removeJsrInstructions(ConstantPool pool, BasicBlock block, DataPoint data) { + + ListStack stack = data.getStack(); + + InstructionSequence seq = block.getSeq(); + for(int i=0;i(data.getLocalVariables())); + point.getStack().push(new VarType(CodeConstants.TYPE_OBJECT, 0, null)); + + removeJsrInstructions(pool, suc, point); + } + } + + } + + private void setFirstAndLastBlocks() { + + first = blocks.get(0); + + last = new BasicBlock(); + last.id = ++last_id; + last.setSeq(new SimpleInstructionSequence()); + + for(BasicBlock block: blocks) { + if(block.getSuccs().isEmpty()) { + last.addPredecessor(block); + } + } + } + + public List getReversePostOrder() { + + LinkedList res = new LinkedList(); + addToReversePostOrderListIterative(first, res); + + return res; + } + + private void addToReversePostOrderListIterative(BasicBlock root, List lst) { + + LinkedList stackNode = new LinkedList(); + LinkedList stackIndex = new LinkedList(); + + HashSet setVisited = new HashSet(); + + stackNode.add(root); + stackIndex.add(0); + + while(!stackNode.isEmpty()) { + + BasicBlock node = stackNode.getLast(); + int index = stackIndex.removeLast(); + + setVisited.add(node); + + List lstSuccs = new ArrayList(node.getSuccs()); + lstSuccs.addAll(node.getSuccExceptions()); + + for(;index getBlocks() { + return blocks; + } + + public void setBlocks(VBStyleCollection blocks) { + this.blocks = blocks; + } + + public BasicBlock getFirst() { + return first; + } + + public void setFirst(BasicBlock first) { + this.first = first; + } + + public List getEndBlocks() { + return last.getPreds(); + } + + public List getExceptions() { + return exceptions; + } + + public void setExceptions(List exceptions) { + this.exceptions = exceptions; + } + + + public BasicBlock getLast() { + return last; + } + + + public void setLast(BasicBlock last) { + this.last = last; + } + + + public HashMap getSubroutines() { + return subroutines; + } + + + public void setSubroutines(HashMap subroutines) { + this.subroutines = subroutines; + } + + + public HashSet getFinallyExits() { + return finallyExits; + } + + + public void setFinallyExits(HashSet finallyExits) { + this.finallyExits = finallyExits; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/cfg/ExceptionRangeCFG.java b/src/org/jetbrains/java/decompiler/code/cfg/ExceptionRangeCFG.java new file mode 100644 index 0000000..53f4a77 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/cfg/ExceptionRangeCFG.java @@ -0,0 +1,128 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.cfg; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.jetbrains.java.decompiler.main.DecompilerContext; + +public class ExceptionRangeCFG { + + private List protectedRange = new ArrayList(); // FIXME: replace with set + + private BasicBlock handler; + + private List exceptionTypes; + + public ExceptionRangeCFG(List protectedRange, BasicBlock handler, List exceptionType) { + this.protectedRange = protectedRange; + this.handler = handler; + + if(exceptionType != null) { + this.exceptionTypes = new ArrayList(exceptionType); + } + } + + public boolean isCircular() { + return protectedRange.contains(handler); + } + + public String toString() { + + String new_line_separator = DecompilerContext.getNewLineSeparator(); + + StringBuffer buf = new StringBuffer(); + + buf.append("exceptionType:"); + for(String exception_type : exceptionTypes) { + buf.append(" "+exception_type); + } + buf.append(new_line_separator); + + buf.append("handler: "+handler.id+new_line_separator); + buf.append("range: "); + for(int i=0;i getProtectedRange() { + return protectedRange; + } + + public void setProtectedRange(List protectedRange) { + this.protectedRange = protectedRange; + } + + public List getExceptionTypes() { + return this.exceptionTypes; + } + + public void addExceptionType(String exceptionType) { + + if(this.exceptionTypes == null) { + return; + } + + if(exceptionType == null) { + this.exceptionTypes = null; + } else { + this.exceptionTypes.add(exceptionType); + } + } + + public String getUniqueExceptionsString() { + + if(exceptionTypes == null) { + return null; + } + + Set setExceptionStrings = new HashSet(); + + for(String exceptionType : exceptionTypes) { // normalize order + setExceptionStrings.add(exceptionType); + } + + String ret = ""; + for(String exception : setExceptionStrings) { + if(!ret.isEmpty()) { + ret += ":"; + } + ret += exception; + } + + return ret; + } + + +// public void setExceptionType(String exceptionType) { +// this.exceptionType = exceptionType; +// } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/AALOAD.java b/src/org/jetbrains/java/decompiler/code/instructions/AALOAD.java new file mode 100644 index 0000000..6e92fe6 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/AALOAD.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class AALOAD extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/AASTORE.java b/src/org/jetbrains/java/decompiler/code/instructions/AASTORE.java new file mode 100644 index 0000000..09f5c4b --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/AASTORE.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class AASTORE extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/ACONST_NULL.java b/src/org/jetbrains/java/decompiler/code/instructions/ACONST_NULL.java new file mode 100644 index 0000000..5733d40 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/ACONST_NULL.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class ACONST_NULL extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/ALOAD.java b/src/org/jetbrains/java/decompiler/code/instructions/ALOAD.java new file mode 100644 index 0000000..a9c9e05 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/ALOAD.java @@ -0,0 +1,43 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class ALOAD extends Instruction { + + private static int[] opcodes = new int[] {opc_aload_0,opc_aload_1,opc_aload_2,opc_aload_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_aload); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + if(wide) { + return 4; + } else { + return 2; + } + } else { + return 1; + } + } + + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/ANEWARRAY.java b/src/org/jetbrains/java/decompiler/code/instructions/ANEWARRAY.java new file mode 100644 index 0000000..aa9a6c9 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/ANEWARRAY.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class ANEWARRAY extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_anewarray); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/ARETURN.java b/src/org/jetbrains/java/decompiler/code/instructions/ARETURN.java new file mode 100644 index 0000000..915a50f --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/ARETURN.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class ARETURN extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/ARRAYLENGTH.java b/src/org/jetbrains/java/decompiler/code/instructions/ARRAYLENGTH.java new file mode 100644 index 0000000..a54aa41 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/ARRAYLENGTH.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class ARRAYLENGTH extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/ASTORE.java b/src/org/jetbrains/java/decompiler/code/instructions/ASTORE.java new file mode 100644 index 0000000..701f082 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/ASTORE.java @@ -0,0 +1,42 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class ASTORE extends Instruction { + + private static int[] opcodes = new int[] {opc_astore_0,opc_astore_1,opc_astore_2,opc_astore_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_astore); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + if(wide) { + return 4; + } else { + return 2; + } + } else { + return 1; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/ATHROW.java b/src/org/jetbrains/java/decompiler/code/instructions/ATHROW.java new file mode 100644 index 0000000..1ca07c5 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/ATHROW.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class ATHROW extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/BALOAD.java b/src/org/jetbrains/java/decompiler/code/instructions/BALOAD.java new file mode 100644 index 0000000..c9d9e79 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/BALOAD.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class BALOAD extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/BASTORE.java b/src/org/jetbrains/java/decompiler/code/instructions/BASTORE.java new file mode 100644 index 0000000..478a887 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/BASTORE.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class BASTORE extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/BIPUSH.java b/src/org/jetbrains/java/decompiler/code/instructions/BIPUSH.java new file mode 100644 index 0000000..90874c5 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/BIPUSH.java @@ -0,0 +1,30 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class BIPUSH extends Instruction { + + private static int[] opcodes = new int[] {opc_iconst_m1,opc_iconst_0,opc_iconst_1,opc_iconst_2,opc_iconst_3,opc_iconst_4,opc_iconst_5}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int value = getOperand(0); + if(value<-1 || value > 5) { + out.writeByte(opc_bipush); + out.writeByte(value); + } else { + out.writeByte(opcodes[value+1]); + } + } + + public int length() { + int value = getOperand(0); + if(value<-1 || value > 5) { + return 2; + } else { + return 1; + } + } +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/CALOAD.java b/src/org/jetbrains/java/decompiler/code/instructions/CALOAD.java new file mode 100644 index 0000000..cf3fb87 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/CALOAD.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class CALOAD extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/CASTORE.java b/src/org/jetbrains/java/decompiler/code/instructions/CASTORE.java new file mode 100644 index 0000000..2ed21e5 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/CASTORE.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class CASTORE extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/CHECKCAST.java b/src/org/jetbrains/java/decompiler/code/instructions/CHECKCAST.java new file mode 100644 index 0000000..a3bb57e --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/CHECKCAST.java @@ -0,0 +1,20 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class CHECKCAST extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_checkcast); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} + diff --git a/src/org/jetbrains/java/decompiler/code/instructions/D2F.java b/src/org/jetbrains/java/decompiler/code/instructions/D2F.java new file mode 100644 index 0000000..fd42a2e --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/D2F.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class D2F extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/D2I.java b/src/org/jetbrains/java/decompiler/code/instructions/D2I.java new file mode 100644 index 0000000..4fc7801 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/D2I.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class D2I extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/D2L.java b/src/org/jetbrains/java/decompiler/code/instructions/D2L.java new file mode 100644 index 0000000..cc90f1c --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/D2L.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class D2L extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DADD.java b/src/org/jetbrains/java/decompiler/code/instructions/DADD.java new file mode 100644 index 0000000..ac84423 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DADD.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DADD extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DALOAD.java b/src/org/jetbrains/java/decompiler/code/instructions/DALOAD.java new file mode 100644 index 0000000..00a0d17 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DALOAD.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DALOAD extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DASTORE.java b/src/org/jetbrains/java/decompiler/code/instructions/DASTORE.java new file mode 100644 index 0000000..e33959f --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DASTORE.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DASTORE extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DCMPG.java b/src/org/jetbrains/java/decompiler/code/instructions/DCMPG.java new file mode 100644 index 0000000..2b853ac --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DCMPG.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DCMPG extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DCMPL.java b/src/org/jetbrains/java/decompiler/code/instructions/DCMPL.java new file mode 100644 index 0000000..7fdba33 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DCMPL.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DCMPL extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DCONST_0.java b/src/org/jetbrains/java/decompiler/code/instructions/DCONST_0.java new file mode 100644 index 0000000..d0023f2 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DCONST_0.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DCONST_0 extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DCONST_1.java b/src/org/jetbrains/java/decompiler/code/instructions/DCONST_1.java new file mode 100644 index 0000000..bcd7c67 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DCONST_1.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DCONST_1 extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DDIV.java b/src/org/jetbrains/java/decompiler/code/instructions/DDIV.java new file mode 100644 index 0000000..40d86a8 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DDIV.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DDIV extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DLOAD.java b/src/org/jetbrains/java/decompiler/code/instructions/DLOAD.java new file mode 100644 index 0000000..ee098d6 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DLOAD.java @@ -0,0 +1,42 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DLOAD extends Instruction { + + private static int[] opcodes = new int[] {opc_dload_0,opc_dload_1,opc_dload_2,opc_dload_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_dload); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + if(wide) { + return 4; + } else { + return 2; + } + } else { + return 1; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DMUL.java b/src/org/jetbrains/java/decompiler/code/instructions/DMUL.java new file mode 100644 index 0000000..65bedca --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DMUL.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DMUL extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DNEG.java b/src/org/jetbrains/java/decompiler/code/instructions/DNEG.java new file mode 100644 index 0000000..15bd9f3 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DNEG.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DNEG extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DREM.java b/src/org/jetbrains/java/decompiler/code/instructions/DREM.java new file mode 100644 index 0000000..ab57911 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DREM.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DREM extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DRETURN.java b/src/org/jetbrains/java/decompiler/code/instructions/DRETURN.java new file mode 100644 index 0000000..0a6e376 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DRETURN.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DRETURN extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DSTORE.java b/src/org/jetbrains/java/decompiler/code/instructions/DSTORE.java new file mode 100644 index 0000000..fe1feb8 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DSTORE.java @@ -0,0 +1,41 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DSTORE extends Instruction { + + private static int[] opcodes = new int[] {opc_dstore_0,opc_dstore_1,opc_dstore_2,opc_dstore_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_dstore); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + if(wide) { + return 4; + } else { + return 2; + } + } else { + return 1; + } + } +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DSUB.java b/src/org/jetbrains/java/decompiler/code/instructions/DSUB.java new file mode 100644 index 0000000..d683a63 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DSUB.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DSUB extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DUP.java b/src/org/jetbrains/java/decompiler/code/instructions/DUP.java new file mode 100644 index 0000000..50119da --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DUP.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DUP extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DUP2.java b/src/org/jetbrains/java/decompiler/code/instructions/DUP2.java new file mode 100644 index 0000000..3929ee0 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DUP2.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DUP2 extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DUP2_X1.java b/src/org/jetbrains/java/decompiler/code/instructions/DUP2_X1.java new file mode 100644 index 0000000..ad59230 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DUP2_X1.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DUP2_X1 extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DUP2_X2.java b/src/org/jetbrains/java/decompiler/code/instructions/DUP2_X2.java new file mode 100644 index 0000000..d27ca93 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DUP2_X2.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DUP2_X2 extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DUP_X1.java b/src/org/jetbrains/java/decompiler/code/instructions/DUP_X1.java new file mode 100644 index 0000000..9b6b271 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DUP_X1.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DUP_X1 extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/DUP_X2.java b/src/org/jetbrains/java/decompiler/code/instructions/DUP_X2.java new file mode 100644 index 0000000..8c4b03e --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/DUP_X2.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DUP_X2 extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/F2D.java b/src/org/jetbrains/java/decompiler/code/instructions/F2D.java new file mode 100644 index 0000000..debb8de --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/F2D.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class F2D extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/F2I.java b/src/org/jetbrains/java/decompiler/code/instructions/F2I.java new file mode 100644 index 0000000..bbda5c8 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/F2I.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class F2I extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/F2L.java b/src/org/jetbrains/java/decompiler/code/instructions/F2L.java new file mode 100644 index 0000000..a58a398 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/F2L.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class F2L extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/FADD.java b/src/org/jetbrains/java/decompiler/code/instructions/FADD.java new file mode 100644 index 0000000..ab7a357 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/FADD.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FADD extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/FALOAD.java b/src/org/jetbrains/java/decompiler/code/instructions/FALOAD.java new file mode 100644 index 0000000..cc56e21 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/FALOAD.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FALOAD extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/FASTORE.java b/src/org/jetbrains/java/decompiler/code/instructions/FASTORE.java new file mode 100644 index 0000000..d18a2ef --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/FASTORE.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FASTORE extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/FCMPG.java b/src/org/jetbrains/java/decompiler/code/instructions/FCMPG.java new file mode 100644 index 0000000..a86b2a9 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/FCMPG.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FCMPG extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/FCMPL.java b/src/org/jetbrains/java/decompiler/code/instructions/FCMPL.java new file mode 100644 index 0000000..450546c --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/FCMPL.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FCMPL extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/FCONST_0.java b/src/org/jetbrains/java/decompiler/code/instructions/FCONST_0.java new file mode 100644 index 0000000..77f4e84 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/FCONST_0.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FCONST_0 extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/FCONST_1.java b/src/org/jetbrains/java/decompiler/code/instructions/FCONST_1.java new file mode 100644 index 0000000..e90fd44 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/FCONST_1.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FCONST_1 extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/FCONST_2.java b/src/org/jetbrains/java/decompiler/code/instructions/FCONST_2.java new file mode 100644 index 0000000..7736565 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/FCONST_2.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FCONST_2 extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/FDIV.java b/src/org/jetbrains/java/decompiler/code/instructions/FDIV.java new file mode 100644 index 0000000..0524b01 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/FDIV.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FDIV extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/FLOAD.java b/src/org/jetbrains/java/decompiler/code/instructions/FLOAD.java new file mode 100644 index 0000000..03ba1d2 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/FLOAD.java @@ -0,0 +1,42 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FLOAD extends Instruction { + + private static int[] opcodes = new int[] {opc_fload_0,opc_fload_1,opc_fload_2,opc_fload_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_fload); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + if(wide) { + return 4; + } else { + return 2; + } + } else { + return 1; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/FMUL.java b/src/org/jetbrains/java/decompiler/code/instructions/FMUL.java new file mode 100644 index 0000000..598145b --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/FMUL.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FMUL extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/FNEG.java b/src/org/jetbrains/java/decompiler/code/instructions/FNEG.java new file mode 100644 index 0000000..b1d96ea --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/FNEG.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FNEG extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/FREM.java b/src/org/jetbrains/java/decompiler/code/instructions/FREM.java new file mode 100644 index 0000000..b8dc0fe --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/FREM.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FREM extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/FRETURN.java b/src/org/jetbrains/java/decompiler/code/instructions/FRETURN.java new file mode 100644 index 0000000..3781401 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/FRETURN.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FRETURN extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/FSTORE.java b/src/org/jetbrains/java/decompiler/code/instructions/FSTORE.java new file mode 100644 index 0000000..203588b --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/FSTORE.java @@ -0,0 +1,41 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FSTORE extends Instruction { + + private static int[] opcodes = new int[] {opc_fstore_0,opc_fstore_1,opc_fstore_2,opc_fstore_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_fstore); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + if(wide) { + return 4; + } else { + return 2; + } + } else { + return 1; + } + } +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/FSUB.java b/src/org/jetbrains/java/decompiler/code/instructions/FSUB.java new file mode 100644 index 0000000..841ee0d --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/FSUB.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FSUB extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/GETFIELD.java b/src/org/jetbrains/java/decompiler/code/instructions/GETFIELD.java new file mode 100644 index 0000000..8500f46 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/GETFIELD.java @@ -0,0 +1,18 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class GETFIELD extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_getfield); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/GETSTATIC.java b/src/org/jetbrains/java/decompiler/code/instructions/GETSTATIC.java new file mode 100644 index 0000000..761624f --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/GETSTATIC.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class GETSTATIC extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_getstatic); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/GOTO.java b/src/org/jetbrains/java/decompiler/code/instructions/GOTO.java new file mode 100644 index 0000000..91f5081 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/GOTO.java @@ -0,0 +1,30 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class GOTO extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int operand = getOperand(0); + if(operand < -32768 || operand > 32767) { + out.writeByte(opc_goto_w); + out.writeInt(operand); + } else { + out.writeByte(opc_goto); + out.writeShort(operand); + } + } + + public int length() { + int operand = getOperand(0); + if(operand < -32768 || operand > 32767) { + return 5; + } else { + return 3; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/GOTO_W.java b/src/org/jetbrains/java/decompiler/code/instructions/GOTO_W.java new file mode 100644 index 0000000..830b766 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/GOTO_W.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class GOTO_W extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_goto_w); + out.writeInt(getOperand(0)); + } + + public int length() { + return 5; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/I2B.java b/src/org/jetbrains/java/decompiler/code/instructions/I2B.java new file mode 100644 index 0000000..f5a3fbd --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/I2B.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class I2B extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/I2C.java b/src/org/jetbrains/java/decompiler/code/instructions/I2C.java new file mode 100644 index 0000000..a180a64 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/I2C.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class I2C extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/I2D.java b/src/org/jetbrains/java/decompiler/code/instructions/I2D.java new file mode 100644 index 0000000..b0bad9a --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/I2D.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class I2D extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/I2F.java b/src/org/jetbrains/java/decompiler/code/instructions/I2F.java new file mode 100644 index 0000000..ca1a0fb --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/I2F.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class I2F extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/I2L.java b/src/org/jetbrains/java/decompiler/code/instructions/I2L.java new file mode 100644 index 0000000..24bca4e --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/I2L.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class I2L extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/I2S.java b/src/org/jetbrains/java/decompiler/code/instructions/I2S.java new file mode 100644 index 0000000..370ae2f --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/I2S.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class I2S extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IADD.java b/src/org/jetbrains/java/decompiler/code/instructions/IADD.java new file mode 100644 index 0000000..f427c40 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IADD.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class IADD extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IALOAD.java b/src/org/jetbrains/java/decompiler/code/instructions/IALOAD.java new file mode 100644 index 0000000..d70fae6 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IALOAD.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class IALOAD extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IAND.java b/src/org/jetbrains/java/decompiler/code/instructions/IAND.java new file mode 100644 index 0000000..00ae7a6 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IAND.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class IAND extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IASTORE.java b/src/org/jetbrains/java/decompiler/code/instructions/IASTORE.java new file mode 100644 index 0000000..78a1d28 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IASTORE.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class IASTORE extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IDIV.java b/src/org/jetbrains/java/decompiler/code/instructions/IDIV.java new file mode 100644 index 0000000..bec8cc9 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IDIV.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class IDIV extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IFEQ.java b/src/org/jetbrains/java/decompiler/code/instructions/IFEQ.java new file mode 100644 index 0000000..47711d8 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IFEQ.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class IFEQ extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_ifeq); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IFGE.java b/src/org/jetbrains/java/decompiler/code/instructions/IFGE.java new file mode 100644 index 0000000..9cfaba4 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IFGE.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class IFGE extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_ifge); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IFGT.java b/src/org/jetbrains/java/decompiler/code/instructions/IFGT.java new file mode 100644 index 0000000..99b171e --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IFGT.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class IFGT extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_ifgt); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IFLE.java b/src/org/jetbrains/java/decompiler/code/instructions/IFLE.java new file mode 100644 index 0000000..b21b2cf --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IFLE.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class IFLE extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_ifle); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IFLT.java b/src/org/jetbrains/java/decompiler/code/instructions/IFLT.java new file mode 100644 index 0000000..66ba02b --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IFLT.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class IFLT extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_iflt); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IFNE.java b/src/org/jetbrains/java/decompiler/code/instructions/IFNE.java new file mode 100644 index 0000000..983fea2 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IFNE.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class IFNE extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_ifne); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IFNONNULL.java b/src/org/jetbrains/java/decompiler/code/instructions/IFNONNULL.java new file mode 100644 index 0000000..2555a80 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IFNONNULL.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class IFNONNULL extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_ifnonnull); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IFNULL.java b/src/org/jetbrains/java/decompiler/code/instructions/IFNULL.java new file mode 100644 index 0000000..b695787 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IFNULL.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class IFNULL extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_ifnull); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IF_ACMPEQ.java b/src/org/jetbrains/java/decompiler/code/instructions/IF_ACMPEQ.java new file mode 100644 index 0000000..30e530b --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IF_ACMPEQ.java @@ -0,0 +1,20 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class IF_ACMPEQ extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_if_acmpeq); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} + diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IF_ACMPNE.java b/src/org/jetbrains/java/decompiler/code/instructions/IF_ACMPNE.java new file mode 100644 index 0000000..ccb513f --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IF_ACMPNE.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class IF_ACMPNE extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_if_acmpne); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPEQ.java b/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPEQ.java new file mode 100644 index 0000000..1343aca --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPEQ.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class IF_ICMPEQ extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_if_icmpeq); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPGE.java b/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPGE.java new file mode 100644 index 0000000..beeabec --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPGE.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class IF_ICMPGE extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_if_icmpge); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPGT.java b/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPGT.java new file mode 100644 index 0000000..e41d261 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPGT.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class IF_ICMPGT extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_if_icmpgt); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPLE.java b/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPLE.java new file mode 100644 index 0000000..c9288da --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPLE.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class IF_ICMPLE extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_if_icmple); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPLT.java b/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPLT.java new file mode 100644 index 0000000..107519e --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPLT.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class IF_ICMPLT extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_if_icmplt); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPNE.java b/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPNE.java new file mode 100644 index 0000000..703c10c --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IF_ICMPNE.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class IF_ICMPNE extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_if_icmpne); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IINC.java b/src/org/jetbrains/java/decompiler/code/instructions/IINC.java new file mode 100644 index 0000000..763a192 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IINC.java @@ -0,0 +1,28 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class IINC extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_iinc); + if(wide) { + out.writeShort(getOperand(0)); + out.writeShort(getOperand(1)); + } else { + out.writeByte(getOperand(0)); + out.writeByte(getOperand(1)); + } + } + + public int length() { + return wide?6:3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/ILOAD.java b/src/org/jetbrains/java/decompiler/code/instructions/ILOAD.java new file mode 100644 index 0000000..4b9bd59 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/ILOAD.java @@ -0,0 +1,38 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class ILOAD extends Instruction { + + private static int[] opcodes = new int[] {opc_iload_0,opc_iload_1,opc_iload_2,opc_iload_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_iload); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + return wide?4:2; + } else { + return 1; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IMUL.java b/src/org/jetbrains/java/decompiler/code/instructions/IMUL.java new file mode 100644 index 0000000..64dd4cc --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IMUL.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class IMUL extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/INEG.java b/src/org/jetbrains/java/decompiler/code/instructions/INEG.java new file mode 100644 index 0000000..cf341e7 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/INEG.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class INEG extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/INSTANCEOF.java b/src/org/jetbrains/java/decompiler/code/instructions/INSTANCEOF.java new file mode 100644 index 0000000..a4214ec --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/INSTANCEOF.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class INSTANCEOF extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_instanceof); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/INVOKEINTERFACE.java b/src/org/jetbrains/java/decompiler/code/instructions/INVOKEINTERFACE.java new file mode 100644 index 0000000..bd1ce37 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/INVOKEINTERFACE.java @@ -0,0 +1,21 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class INVOKEINTERFACE extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_invokeinterface); + out.writeShort(getOperand(0)); + out.writeByte(getOperand(1)); + out.writeByte(0); + } + + public int length() { + return 5; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/INVOKESPECIAL.java b/src/org/jetbrains/java/decompiler/code/instructions/INVOKESPECIAL.java new file mode 100644 index 0000000..d14a8ee --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/INVOKESPECIAL.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class INVOKESPECIAL extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_invokespecial); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/INVOKESTATIC.java b/src/org/jetbrains/java/decompiler/code/instructions/INVOKESTATIC.java new file mode 100644 index 0000000..8ef9f26 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/INVOKESTATIC.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class INVOKESTATIC extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_invokestatic); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/INVOKEVIRTUAL.java b/src/org/jetbrains/java/decompiler/code/instructions/INVOKEVIRTUAL.java new file mode 100644 index 0000000..687c6e4 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/INVOKEVIRTUAL.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class INVOKEVIRTUAL extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_invokevirtual); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IOR.java b/src/org/jetbrains/java/decompiler/code/instructions/IOR.java new file mode 100644 index 0000000..b3e6bae --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IOR.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class IOR extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IREM.java b/src/org/jetbrains/java/decompiler/code/instructions/IREM.java new file mode 100644 index 0000000..db1fbb8 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IREM.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class IREM extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IRETURN.java b/src/org/jetbrains/java/decompiler/code/instructions/IRETURN.java new file mode 100644 index 0000000..2a2e48c --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IRETURN.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class IRETURN extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/ISHL.java b/src/org/jetbrains/java/decompiler/code/instructions/ISHL.java new file mode 100644 index 0000000..5e0b1e0 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/ISHL.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class ISHL extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/ISHR.java b/src/org/jetbrains/java/decompiler/code/instructions/ISHR.java new file mode 100644 index 0000000..9a8c182 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/ISHR.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class ISHR extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/ISTORE.java b/src/org/jetbrains/java/decompiler/code/instructions/ISTORE.java new file mode 100644 index 0000000..7bc1647 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/ISTORE.java @@ -0,0 +1,38 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class ISTORE extends Instruction { + + private static int[] opcodes = new int[] {opc_istore_0,opc_istore_1,opc_istore_2,opc_istore_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_istore); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + return wide?4:2; + } else { + return 1; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/ISUB.java b/src/org/jetbrains/java/decompiler/code/instructions/ISUB.java new file mode 100644 index 0000000..3007c8a --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/ISUB.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class ISUB extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IUSHR.java b/src/org/jetbrains/java/decompiler/code/instructions/IUSHR.java new file mode 100644 index 0000000..3171c1a --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IUSHR.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class IUSHR extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/IXOR.java b/src/org/jetbrains/java/decompiler/code/instructions/IXOR.java new file mode 100644 index 0000000..f6568d2 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/IXOR.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class IXOR extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/JSR.java b/src/org/jetbrains/java/decompiler/code/instructions/JSR.java new file mode 100644 index 0000000..bb23f66 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/JSR.java @@ -0,0 +1,30 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class JSR extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int operand = getOperand(0); + if(operand < -32768 || operand > 32767) { + out.writeByte(opc_jsr_w); + out.writeInt(operand); + } else { + out.writeByte(opc_jsr); + out.writeShort(operand); + } + } + + public int length() { + int operand = getOperand(0); + if(operand < -32768 || operand > 32767) { + return 5; + } else { + return 3; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/JSR_W.java b/src/org/jetbrains/java/decompiler/code/instructions/JSR_W.java new file mode 100644 index 0000000..47af3e6 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/JSR_W.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class JSR_W extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_jsr_w); + out.writeInt(getOperand(0)); + } + + public int length() { + return 5; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/L2D.java b/src/org/jetbrains/java/decompiler/code/instructions/L2D.java new file mode 100644 index 0000000..59178d2 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/L2D.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class L2D extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/L2F.java b/src/org/jetbrains/java/decompiler/code/instructions/L2F.java new file mode 100644 index 0000000..37932b6 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/L2F.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class L2F extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/L2I.java b/src/org/jetbrains/java/decompiler/code/instructions/L2I.java new file mode 100644 index 0000000..c197282 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/L2I.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class L2I extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LADD.java b/src/org/jetbrains/java/decompiler/code/instructions/LADD.java new file mode 100644 index 0000000..8c5625c --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LADD.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LADD extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LALOAD.java b/src/org/jetbrains/java/decompiler/code/instructions/LALOAD.java new file mode 100644 index 0000000..3590f94 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LALOAD.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LALOAD extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LAND.java b/src/org/jetbrains/java/decompiler/code/instructions/LAND.java new file mode 100644 index 0000000..46a396c --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LAND.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LAND extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LASTORE.java b/src/org/jetbrains/java/decompiler/code/instructions/LASTORE.java new file mode 100644 index 0000000..107af51 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LASTORE.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LASTORE extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LCMP.java b/src/org/jetbrains/java/decompiler/code/instructions/LCMP.java new file mode 100644 index 0000000..8a9dac5 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LCMP.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LCMP extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LCONST_0.java b/src/org/jetbrains/java/decompiler/code/instructions/LCONST_0.java new file mode 100644 index 0000000..5617fbe --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LCONST_0.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LCONST_0 extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LCONST_1.java b/src/org/jetbrains/java/decompiler/code/instructions/LCONST_1.java new file mode 100644 index 0000000..8244407 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LCONST_1.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LCONST_1 extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LDC.java b/src/org/jetbrains/java/decompiler/code/instructions/LDC.java new file mode 100644 index 0000000..088e5a5 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LDC.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LDC extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_ldc); + out.writeByte(getOperand(0)); + } + + public int length() { + return 2; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LDC2_W.java b/src/org/jetbrains/java/decompiler/code/instructions/LDC2_W.java new file mode 100644 index 0000000..9b67a7e --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LDC2_W.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LDC2_W extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_ldc2_w); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LDC_W.java b/src/org/jetbrains/java/decompiler/code/instructions/LDC_W.java new file mode 100644 index 0000000..290462e --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LDC_W.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LDC_W extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_ldc_w); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LDIV.java b/src/org/jetbrains/java/decompiler/code/instructions/LDIV.java new file mode 100644 index 0000000..36b09ca --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LDIV.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LDIV extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LLOAD.java b/src/org/jetbrains/java/decompiler/code/instructions/LLOAD.java new file mode 100644 index 0000000..0cf9695 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LLOAD.java @@ -0,0 +1,38 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LLOAD extends Instruction { + + private static int[] opcodes = new int[] {opc_lload_0,opc_lload_1,opc_lload_2,opc_lload_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_lload); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + return wide?4:2; + } else { + return 1; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LMUL.java b/src/org/jetbrains/java/decompiler/code/instructions/LMUL.java new file mode 100644 index 0000000..075c50b --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LMUL.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LMUL extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LNEG.java b/src/org/jetbrains/java/decompiler/code/instructions/LNEG.java new file mode 100644 index 0000000..b2c9f10 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LNEG.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LNEG extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LOOKUPSWITCH.java b/src/org/jetbrains/java/decompiler/code/instructions/LOOKUPSWITCH.java new file mode 100644 index 0000000..dbe5f03 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LOOKUPSWITCH.java @@ -0,0 +1,28 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.SwitchInstruction; + +public class LOOKUPSWITCH extends SwitchInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + + out.writeByte(opc_lookupswitch); + + int padding = 3 - (offset%4); + for(int i=0;i3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_lstore); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + return wide?4:2; + } else { + return 1; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LSUB.java b/src/org/jetbrains/java/decompiler/code/instructions/LSUB.java new file mode 100644 index 0000000..14b019f --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LSUB.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LSUB extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LUSHR.java b/src/org/jetbrains/java/decompiler/code/instructions/LUSHR.java new file mode 100644 index 0000000..63d5ca4 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LUSHR.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LUSHR extends Instruction { + +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/code/instructions/LXOR.java b/src/org/jetbrains/java/decompiler/code/instructions/LXOR.java new file mode 100644 index 0000000..9812a1a --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/LXOR.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LXOR extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/MONITORENTER.java b/src/org/jetbrains/java/decompiler/code/instructions/MONITORENTER.java new file mode 100644 index 0000000..d2ed979 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/MONITORENTER.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class MONITORENTER extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/MONITOREXIT.java b/src/org/jetbrains/java/decompiler/code/instructions/MONITOREXIT.java new file mode 100644 index 0000000..f1324be --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/MONITOREXIT.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class MONITOREXIT extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/MULTIANEWARRAY.java b/src/org/jetbrains/java/decompiler/code/instructions/MULTIANEWARRAY.java new file mode 100644 index 0000000..313b708 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/MULTIANEWARRAY.java @@ -0,0 +1,20 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class MULTIANEWARRAY extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_multianewarray); + out.writeShort(getOperand(0)); + out.writeByte(getOperand(1)); + } + + public int length() { + return 4; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/NEW.java b/src/org/jetbrains/java/decompiler/code/instructions/NEW.java new file mode 100644 index 0000000..8c5ab34 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/NEW.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class NEW extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_new); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/NEWARRAY.java b/src/org/jetbrains/java/decompiler/code/instructions/NEWARRAY.java new file mode 100644 index 0000000..eb25456 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/NEWARRAY.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class NEWARRAY extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_newarray); + out.writeByte(getOperand(0)); + } + + public int length() { + return 2; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/NOP.java b/src/org/jetbrains/java/decompiler/code/instructions/NOP.java new file mode 100644 index 0000000..ef11da8 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/NOP.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class NOP extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/POP.java b/src/org/jetbrains/java/decompiler/code/instructions/POP.java new file mode 100644 index 0000000..8848163 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/POP.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class POP extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/POP2.java b/src/org/jetbrains/java/decompiler/code/instructions/POP2.java new file mode 100644 index 0000000..f07d5d5 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/POP2.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class POP2 extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/PUTFIELD.java b/src/org/jetbrains/java/decompiler/code/instructions/PUTFIELD.java new file mode 100644 index 0000000..b37efb0 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/PUTFIELD.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class PUTFIELD extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_putfield); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/PUTSTATIC.java b/src/org/jetbrains/java/decompiler/code/instructions/PUTSTATIC.java new file mode 100644 index 0000000..260e57c --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/PUTSTATIC.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class PUTSTATIC extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_putstatic); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/RET.java b/src/org/jetbrains/java/decompiler/code/instructions/RET.java new file mode 100644 index 0000000..490ad8c --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/RET.java @@ -0,0 +1,26 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class RET extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_ret); + if(wide) { + out.writeShort(getOperand(0)); + } else { + out.writeByte(getOperand(0)); + } + } + + public int length() { + return wide?4:2; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/RETURN.java b/src/org/jetbrains/java/decompiler/code/instructions/RETURN.java new file mode 100644 index 0000000..cbdcbfc --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/RETURN.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class RETURN extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/SALOAD.java b/src/org/jetbrains/java/decompiler/code/instructions/SALOAD.java new file mode 100644 index 0000000..c9da26e --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/SALOAD.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class SALOAD extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/SASTORE.java b/src/org/jetbrains/java/decompiler/code/instructions/SASTORE.java new file mode 100644 index 0000000..4a90aac --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/SASTORE.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class SASTORE extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/SIPUSH.java b/src/org/jetbrains/java/decompiler/code/instructions/SIPUSH.java new file mode 100644 index 0000000..a5f7025 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/SIPUSH.java @@ -0,0 +1,19 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class SIPUSH extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_sipush); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/SWAP.java b/src/org/jetbrains/java/decompiler/code/instructions/SWAP.java new file mode 100644 index 0000000..9fd99b3 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/SWAP.java @@ -0,0 +1,7 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class SWAP extends Instruction { + +} diff --git a/src/org/jetbrains/java/decompiler/code/instructions/TABLESWITCH.java b/src/org/jetbrains/java/decompiler/code/instructions/TABLESWITCH.java new file mode 100644 index 0000000..4a4be0a --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/instructions/TABLESWITCH.java @@ -0,0 +1,29 @@ +package org.jetbrains.java.decompiler.code.instructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.SwitchInstruction; + +public class TABLESWITCH extends SwitchInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + + out.writeByte(opc_tableswitch); + + int padding = 3 - (offset%4); + for(int i=0;i stack = data.getStack(); + int[][] arr = stack_impact[instr.opcode]; + + if(arr != null) { + // simple types only + + int[] read = arr[0]; + int[] write = arr[1]; + + if(read!=null) { + int depth = 0; + for(int i=0;i stack = data.getStack(); + + switch(instr.opcode) { + case CodeConstants.opc_aconst_null: + stack.push(new VarType(CodeConstants.TYPE_NULL,0,null)); + break; + case CodeConstants.opc_ldc: + case CodeConstants.opc_ldc_w: + case CodeConstants.opc_ldc2_w: + cn = pool.getPrimitiveConstant(instr.getOperand(0)); + switch(cn.type) { + case CodeConstants.CONSTANT_Integer: + stack.push(new VarType(CodeConstants.TYPE_INT)); + break; + case CodeConstants.CONSTANT_Float: + stack.push(new VarType(CodeConstants.TYPE_FLOAT)); + break; + case CodeConstants.CONSTANT_Long: + stack.push(new VarType(CodeConstants.TYPE_LONG)); + stack.push(new VarType(CodeConstants.TYPE_GROUP2EMPTY)); + break; + case CodeConstants.CONSTANT_Double: + stack.push(new VarType(CodeConstants.TYPE_DOUBLE)); + stack.push(new VarType(CodeConstants.TYPE_GROUP2EMPTY)); + break; + case CodeConstants.CONSTANT_String: + stack.push(new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/String")); + break; + case CodeConstants.CONSTANT_Class: + stack.push(new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/Class")); + break; + } + break; + case CodeConstants.opc_aload: + var1 = data.getVariable(instr.getOperand(0)); + if(var1!=null) { + stack.push(var1); + } else { + stack.push(new VarType(CodeConstants.TYPE_OBJECT,0,null)); + } + break; + case CodeConstants.opc_aaload: + var1 = stack.pop(2); + stack.push(new VarType(var1.type, var1.arraydim-1, var1.value)); + break; + case CodeConstants.opc_astore: + data.setVariable(instr.getOperand(0), (VarType)stack.pop()); + break; + case CodeConstants.opc_dup: + case CodeConstants.opc_dup_x1: + case CodeConstants.opc_dup_x2: + int depth1 = 88 - instr.opcode; + stack.insertByOffset(depth1, stack.getByOffset(-1).copy()); + break; + case CodeConstants.opc_dup2: + case CodeConstants.opc_dup2_x1: + case CodeConstants.opc_dup2_x2: + int depth2 = 90 - instr.opcode; + stack.insertByOffset(depth2, stack.getByOffset(-2).copy()); + stack.insertByOffset(depth2, stack.getByOffset(-1).copy()); + break; + case CodeConstants.opc_swap: + var1 = stack.pop(); + stack.insertByOffset(-1, var1); + break; + case CodeConstants.opc_getfield: + stack.pop(); + case CodeConstants.opc_getstatic: + ck = pool.getLinkConstant(instr.getOperand(0)); + var1 = new VarType(ck.descriptor); + stack.push(var1); + if(var1.stack_size==2) { + stack.push(new VarType(CodeConstants.TYPE_GROUP2EMPTY)); + } + break; + case CodeConstants.opc_putfield: + stack.pop(); + case CodeConstants.opc_putstatic: + ck = pool.getLinkConstant(instr.getOperand(0)); + var1 = new VarType(ck.descriptor); + stack.pop(var1.stack_size); + break; + case CodeConstants.opc_invokevirtual: + case CodeConstants.opc_invokespecial: + case CodeConstants.opc_invokeinterface: + stack.pop(); + case CodeConstants.opc_invokestatic: + case CodeConstants.opc_invokedynamic: + if(instr.opcode != CodeConstants.opc_invokedynamic || instr.bytecode_version >= CodeConstants.BYTECODE_JAVA_7) { + ck = pool.getLinkConstant(instr.getOperand(0)); + MethodDescriptor md = MethodDescriptor.parseDescriptor(ck.descriptor); + for(int i=0;i3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_aload); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + if(wide) { + return 4; + } else { + return 2; + } + } else { + return 1; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/ANEWARRAY.java b/src/org/jetbrains/java/decompiler/code/optinstructions/ANEWARRAY.java new file mode 100644 index 0000000..1e0d4ff --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/ANEWARRAY.java @@ -0,0 +1,33 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class ANEWARRAY extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_anewarray); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/ASTORE.java b/src/org/jetbrains/java/decompiler/code/optinstructions/ASTORE.java new file mode 100644 index 0000000..475df11 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/ASTORE.java @@ -0,0 +1,56 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class ASTORE extends Instruction { + + private static int[] opcodes = new int[] {opc_astore_0,opc_astore_1,opc_astore_2,opc_astore_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_astore); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + if(wide) { + return 4; + } else { + return 2; + } + } else { + return 1; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/BIPUSH.java b/src/org/jetbrains/java/decompiler/code/optinstructions/BIPUSH.java new file mode 100644 index 0000000..2fb2db5 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/BIPUSH.java @@ -0,0 +1,44 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class BIPUSH extends Instruction { + + private static int[] opcodes = new int[] {opc_iconst_m1,opc_iconst_0,opc_iconst_1,opc_iconst_2,opc_iconst_3,opc_iconst_4,opc_iconst_5}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int value = getOperand(0); + if(value<-1 || value > 5) { + out.writeByte(opc_bipush); + out.writeByte(value); + } else { + out.writeByte(opcodes[value+1]); + } + } + + public int length() { + int value = getOperand(0); + if(value<-1 || value > 5) { + return 2; + } else { + return 1; + } + } +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/CHECKCAST.java b/src/org/jetbrains/java/decompiler/code/optinstructions/CHECKCAST.java new file mode 100644 index 0000000..73417de --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/CHECKCAST.java @@ -0,0 +1,34 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class CHECKCAST extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_checkcast); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} + diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/DLOAD.java b/src/org/jetbrains/java/decompiler/code/optinstructions/DLOAD.java new file mode 100644 index 0000000..96d5449 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/DLOAD.java @@ -0,0 +1,56 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DLOAD extends Instruction { + + private static int[] opcodes = new int[] {opc_dload_0,opc_dload_1,opc_dload_2,opc_dload_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_dload); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + if(wide) { + return 4; + } else { + return 2; + } + } else { + return 1; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/DSTORE.java b/src/org/jetbrains/java/decompiler/code/optinstructions/DSTORE.java new file mode 100644 index 0000000..61a8776 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/DSTORE.java @@ -0,0 +1,55 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class DSTORE extends Instruction { + + private static int[] opcodes = new int[] {opc_dstore_0,opc_dstore_1,opc_dstore_2,opc_dstore_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_dstore); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + if(wide) { + return 4; + } else { + return 2; + } + } else { + return 1; + } + } +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/FLOAD.java b/src/org/jetbrains/java/decompiler/code/optinstructions/FLOAD.java new file mode 100644 index 0000000..5c8fe26 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/FLOAD.java @@ -0,0 +1,56 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FLOAD extends Instruction { + + private static int[] opcodes = new int[] {opc_fload_0,opc_fload_1,opc_fload_2,opc_fload_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_fload); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + if(wide) { + return 4; + } else { + return 2; + } + } else { + return 1; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/FSTORE.java b/src/org/jetbrains/java/decompiler/code/optinstructions/FSTORE.java new file mode 100644 index 0000000..3685254 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/FSTORE.java @@ -0,0 +1,55 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class FSTORE extends Instruction { + + private static int[] opcodes = new int[] {opc_fstore_0,opc_fstore_1,opc_fstore_2,opc_fstore_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_fstore); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + if(wide) { + return 4; + } else { + return 2; + } + } else { + return 1; + } + } +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/GETFIELD.java b/src/org/jetbrains/java/decompiler/code/optinstructions/GETFIELD.java new file mode 100644 index 0000000..b9a8ab5 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/GETFIELD.java @@ -0,0 +1,32 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class GETFIELD extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_getfield); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/GETSTATIC.java b/src/org/jetbrains/java/decompiler/code/optinstructions/GETSTATIC.java new file mode 100644 index 0000000..1890bc0 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/GETSTATIC.java @@ -0,0 +1,33 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class GETSTATIC extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_getstatic); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/GOTO.java b/src/org/jetbrains/java/decompiler/code/optinstructions/GOTO.java new file mode 100644 index 0000000..3a81194 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/GOTO.java @@ -0,0 +1,44 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class GOTO extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int operand = getOperand(0); + if(operand < -32768 || operand > 32767) { + out.writeByte(opc_goto_w); + out.writeInt(operand); + } else { + out.writeByte(opc_goto); + out.writeShort(operand); + } + } + + public int length() { + int operand = getOperand(0); + if(operand < -32768 || operand > 32767) { + return 5; + } else { + return 3; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/GOTO_W.java b/src/org/jetbrains/java/decompiler/code/optinstructions/GOTO_W.java new file mode 100644 index 0000000..6e1f6e7 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/GOTO_W.java @@ -0,0 +1,33 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class GOTO_W extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_goto_w); + out.writeInt(getOperand(0)); + } + + public int length() { + return 5; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/IINC.java b/src/org/jetbrains/java/decompiler/code/optinstructions/IINC.java new file mode 100644 index 0000000..e945969 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/IINC.java @@ -0,0 +1,42 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class IINC extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_iinc); + if(wide) { + out.writeShort(getOperand(0)); + out.writeShort(getOperand(1)); + } else { + out.writeByte(getOperand(0)); + out.writeByte(getOperand(1)); + } + } + + public int length() { + return wide?6:3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/ILOAD.java b/src/org/jetbrains/java/decompiler/code/optinstructions/ILOAD.java new file mode 100644 index 0000000..40bfa4d --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/ILOAD.java @@ -0,0 +1,52 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class ILOAD extends Instruction { + + private static int[] opcodes = new int[] {opc_iload_0,opc_iload_1,opc_iload_2,opc_iload_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_iload); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + return wide?4:2; + } else { + return 1; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/INSTANCEOF.java b/src/org/jetbrains/java/decompiler/code/optinstructions/INSTANCEOF.java new file mode 100644 index 0000000..f02dfc6 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/INSTANCEOF.java @@ -0,0 +1,33 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class INSTANCEOF extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_instanceof); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/INVOKEDYNAMIC.java b/src/org/jetbrains/java/decompiler/code/optinstructions/INVOKEDYNAMIC.java new file mode 100644 index 0000000..ee8c785 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/INVOKEDYNAMIC.java @@ -0,0 +1,20 @@ +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class INVOKEDYNAMIC extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_invokedynamic); + out.writeShort(getOperand(0)); + out.writeByte(0); + out.writeByte(0); + } + + public int length() { + return 5; + } +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/INVOKEINTERFACE.java b/src/org/jetbrains/java/decompiler/code/optinstructions/INVOKEINTERFACE.java new file mode 100644 index 0000000..e4f06f2 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/INVOKEINTERFACE.java @@ -0,0 +1,35 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class INVOKEINTERFACE extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_invokeinterface); + out.writeShort(getOperand(0)); + out.writeByte(getOperand(1)); + out.writeByte(0); + } + + public int length() { + return 5; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/INVOKESPECIAL.java b/src/org/jetbrains/java/decompiler/code/optinstructions/INVOKESPECIAL.java new file mode 100644 index 0000000..6b9b559 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/INVOKESPECIAL.java @@ -0,0 +1,33 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class INVOKESPECIAL extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_invokespecial); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/INVOKESTATIC.java b/src/org/jetbrains/java/decompiler/code/optinstructions/INVOKESTATIC.java new file mode 100644 index 0000000..0f1ad16 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/INVOKESTATIC.java @@ -0,0 +1,33 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class INVOKESTATIC extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_invokestatic); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/INVOKEVIRTUAL.java b/src/org/jetbrains/java/decompiler/code/optinstructions/INVOKEVIRTUAL.java new file mode 100644 index 0000000..f4537f3 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/INVOKEVIRTUAL.java @@ -0,0 +1,33 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class INVOKEVIRTUAL extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_invokevirtual); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/ISTORE.java b/src/org/jetbrains/java/decompiler/code/optinstructions/ISTORE.java new file mode 100644 index 0000000..0ced128 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/ISTORE.java @@ -0,0 +1,52 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class ISTORE extends Instruction { + + private static int[] opcodes = new int[] {opc_istore_0,opc_istore_1,opc_istore_2,opc_istore_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_istore); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + return wide?4:2; + } else { + return 1; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/JSR.java b/src/org/jetbrains/java/decompiler/code/optinstructions/JSR.java new file mode 100644 index 0000000..ef6c2ad --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/JSR.java @@ -0,0 +1,44 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class JSR extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int operand = getOperand(0); + if(operand < -32768 || operand > 32767) { + out.writeByte(opc_jsr_w); + out.writeInt(operand); + } else { + out.writeByte(opc_jsr); + out.writeShort(operand); + } + } + + public int length() { + int operand = getOperand(0); + if(operand < -32768 || operand > 32767) { + return 5; + } else { + return 3; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/JSR_W.java b/src/org/jetbrains/java/decompiler/code/optinstructions/JSR_W.java new file mode 100644 index 0000000..bc7ae59 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/JSR_W.java @@ -0,0 +1,33 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.JumpInstruction; + +public class JSR_W extends JumpInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_jsr_w); + out.writeInt(getOperand(0)); + } + + public int length() { + return 5; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/LDC.java b/src/org/jetbrains/java/decompiler/code/optinstructions/LDC.java new file mode 100644 index 0000000..4b1a715 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/LDC.java @@ -0,0 +1,33 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LDC extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_ldc); + out.writeByte(getOperand(0)); + } + + public int length() { + return 2; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/LDC2_W.java b/src/org/jetbrains/java/decompiler/code/optinstructions/LDC2_W.java new file mode 100644 index 0000000..4b7ea0b --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/LDC2_W.java @@ -0,0 +1,33 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LDC2_W extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_ldc2_w); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/LDC_W.java b/src/org/jetbrains/java/decompiler/code/optinstructions/LDC_W.java new file mode 100644 index 0000000..6a4e3a6 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/LDC_W.java @@ -0,0 +1,33 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LDC_W extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_ldc_w); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/LLOAD.java b/src/org/jetbrains/java/decompiler/code/optinstructions/LLOAD.java new file mode 100644 index 0000000..52f2b5c --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/LLOAD.java @@ -0,0 +1,52 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class LLOAD extends Instruction { + + private static int[] opcodes = new int[] {opc_lload_0,opc_lload_1,opc_lload_2,opc_lload_3}; + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + int index = getOperand(0); + if(index>3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_lload); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + return wide?4:2; + } else { + return 1; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/LOOKUPSWITCH.java b/src/org/jetbrains/java/decompiler/code/optinstructions/LOOKUPSWITCH.java new file mode 100644 index 0000000..1654622 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/LOOKUPSWITCH.java @@ -0,0 +1,42 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.SwitchInstruction; + +public class LOOKUPSWITCH extends SwitchInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + + out.writeByte(opc_lookupswitch); + + int padding = 3 - (offset%4); + for(int i=0;i3) { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_lstore); + if(wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } else { + out.writeByte(opcodes[index]); + } + } + + public int length() { + int index = getOperand(0); + if(index>3) { + return wide?4:2; + } else { + return 1; + } + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/MULTIANEWARRAY.java b/src/org/jetbrains/java/decompiler/code/optinstructions/MULTIANEWARRAY.java new file mode 100644 index 0000000..c7eb0b9 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/MULTIANEWARRAY.java @@ -0,0 +1,34 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class MULTIANEWARRAY extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_multianewarray); + out.writeShort(getOperand(0)); + out.writeByte(getOperand(1)); + } + + public int length() { + return 4; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/NEW.java b/src/org/jetbrains/java/decompiler/code/optinstructions/NEW.java new file mode 100644 index 0000000..eafe17c --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/NEW.java @@ -0,0 +1,33 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class NEW extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_new); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/NEWARRAY.java b/src/org/jetbrains/java/decompiler/code/optinstructions/NEWARRAY.java new file mode 100644 index 0000000..8764a6f --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/NEWARRAY.java @@ -0,0 +1,33 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class NEWARRAY extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_newarray); + out.writeByte(getOperand(0)); + } + + public int length() { + return 2; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/PUTFIELD.java b/src/org/jetbrains/java/decompiler/code/optinstructions/PUTFIELD.java new file mode 100644 index 0000000..096da07 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/PUTFIELD.java @@ -0,0 +1,33 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class PUTFIELD extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_putfield); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/PUTSTATIC.java b/src/org/jetbrains/java/decompiler/code/optinstructions/PUTSTATIC.java new file mode 100644 index 0000000..e543c88 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/PUTSTATIC.java @@ -0,0 +1,33 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class PUTSTATIC extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_putstatic); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/RET.java b/src/org/jetbrains/java/decompiler/code/optinstructions/RET.java new file mode 100644 index 0000000..d52d2a2 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/RET.java @@ -0,0 +1,40 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class RET extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + if(wide) { + out.writeByte(opc_wide); + } + out.writeByte(opc_ret); + if(wide) { + out.writeShort(getOperand(0)); + } else { + out.writeByte(getOperand(0)); + } + } + + public int length() { + return wide?4:2; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/SIPUSH.java b/src/org/jetbrains/java/decompiler/code/optinstructions/SIPUSH.java new file mode 100644 index 0000000..5bac32f --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/SIPUSH.java @@ -0,0 +1,33 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.Instruction; + +public class SIPUSH extends Instruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + out.writeByte(opc_sipush); + out.writeShort(getOperand(0)); + } + + public int length() { + return 3; + } + +} diff --git a/src/org/jetbrains/java/decompiler/code/optinstructions/TABLESWITCH.java b/src/org/jetbrains/java/decompiler/code/optinstructions/TABLESWITCH.java new file mode 100644 index 0000000..ca2eae5 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/code/optinstructions/TABLESWITCH.java @@ -0,0 +1,43 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.code.optinstructions; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.jetbrains.java.decompiler.code.SwitchInstruction; + +public class TABLESWITCH extends SwitchInstruction { + + public void writeToStream(DataOutputStream out, int offset) throws IOException { + + out.writeByte(opc_tableswitch); + + int padding = 3 - (offset%4); + for(int i=0;i lstParams = new ArrayList(); + + Exprent ascond = null, retcond = null; + if(exprres[0] != null) { + ascond = new FunctionExprent(FunctionExprent.FUNCTION_BOOLNOT, + Arrays.asList(new Exprent[]{(Exprent)exprres[0]})); + retcond = SecondaryFunctionsHelper.propagateBoolNot(ascond); + } + + lstParams.add(retcond==null?ascond:retcond); + if(!throwError.getLstParameters().isEmpty()) { + lstParams.add(throwError.getLstParameters().get(0)); + } + + AssertExprent asexpr = new AssertExprent(lstParams); + + Statement newstat = new BasicBlockStatement(new BasicBlock( + DecompilerContext.getCountercontainer().getCounterAndIncrement(CounterContainer.STATEMENT_COUNTER))); + newstat.setExprents(Arrays.asList(new Exprent[] {asexpr})); + + Statement first = stat.getFirst(); + + if(stat.iftype == IfStatement.IFTYPE_IFELSE || (first.getExprents() != null && + !first.getExprents().isEmpty())) { + + first.removeSuccessor(stat.getIfEdge()); + first.removeSuccessor(stat.getElseEdge()); + + List lstStatements = new ArrayList(); + if(first.getExprents() != null && !first.getExprents().isEmpty()) { + lstStatements.add(first); + } + lstStatements.add(newstat); + if(stat.iftype == IfStatement.IFTYPE_IFELSE) { + lstStatements.add(stat.getElsestat()); + } + + SequenceStatement sequence = new SequenceStatement(lstStatements); + sequence.setAllParent(); + + for(int i=0;i lstSuccs = ifelse.getAllSuccessorEdges(); + if(!lstSuccs.isEmpty()) { + StatEdge endedge = lstSuccs.get(0); + if(endedge.closure == stat) { + sequence.addLabeledEdge(endedge); + } + } + } + + newstat = sequence; + } + + newstat.getVarDefinitions().addAll(stat.getVarDefinitions()); + parent.replaceStatement(stat, newstat); + + return true; + } + + private static InvocationExprent isAssertionError(Statement stat) { + + if(stat == null || stat.getExprents() == null || stat.getExprents().size() !=1) { + return null; + } + + Exprent expr = stat.getExprents().get(0); + + if(expr.type == Exprent.EXPRENT_EXIT) { + ExitExprent exexpr = (ExitExprent)expr; + if(exexpr.getExittype() == ExitExprent.EXIT_THROW && exexpr.getValue().type == Exprent.EXPRENT_NEW) { + NewExprent nexpr = (NewExprent)exexpr.getValue(); + if(CLASS_ASSERTION_ERROR.equals(nexpr.getNewtype()) && nexpr.getConstructor() != null) { + return nexpr.getConstructor(); + } + } + } + + return null; + } + + private static Object[] getAssertionExprent(Exprent exprent, String classname, String key) { + + if(exprent.type == Exprent.EXPRENT_FUNCTION) { + FunctionExprent fexpr = (FunctionExprent)exprent; + if(fexpr.getFunctype() == FunctionExprent.FUNCTION_CADD) { + + for(int i=0;i<2;i++) { + Exprent param = fexpr.getLstOperands().get(i); + + if(isAssertionField(param, classname, key)) { + return new Object[] {fexpr.getLstOperands().get(1-i), true}; + } + } + + for(int i=0;i<2;i++) { + Exprent param = fexpr.getLstOperands().get(i); + + Object[] res = getAssertionExprent(param, classname, key); + if((Boolean)res[1]) { + if(param != res[0]) { + fexpr.getLstOperands().set(i, (Exprent)res[0]); + } + return new Object[] {fexpr, true}; + } + } + } else if(isAssertionField(fexpr, classname, key)) { + // assert false; + return new Object[] {null, true}; + } + } + + return new Object[] {exprent, false}; + } + + private static boolean isAssertionField(Exprent exprent, String classname, String key) { + + if(exprent.type == Exprent.EXPRENT_FUNCTION) { + FunctionExprent fparam = (FunctionExprent)exprent; + if(fparam.getFunctype() == FunctionExprent.FUNCTION_BOOLNOT && + fparam.getLstOperands().get(0).type == Exprent.EXPRENT_FIELD) { + FieldExprent fdparam = (FieldExprent)fparam.getLstOperands().get(0); + if(classname.equals(fdparam.getClassname()) + && key.equals(InterpreterUtil.makeUniqueKey(fdparam.getName(), fdparam.getDescriptor().descriptorString))) { + return true; + } + } + } + + return false; + } +} diff --git a/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java b/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java new file mode 100644 index 0000000..cdad6ca --- /dev/null +++ b/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java @@ -0,0 +1,309 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.main; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map.Entry; + +import org.jetbrains.java.decompiler.code.CodeConstants; +import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; +import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; +import org.jetbrains.java.decompiler.main.rels.ClassWrapper; +import org.jetbrains.java.decompiler.main.rels.MethodWrapper; +import org.jetbrains.java.decompiler.modules.decompiler.exps.AssignmentExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.ConstExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.ExitExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.FieldExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.FunctionExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.InvocationExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.NewExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; +import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectGraph; +import org.jetbrains.java.decompiler.modules.decompiler.stats.BasicBlockStatement; +import org.jetbrains.java.decompiler.modules.decompiler.stats.CatchStatement; +import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; +import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; +import org.jetbrains.java.decompiler.struct.StructField; +import org.jetbrains.java.decompiler.struct.StructMethod; +import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; +import org.jetbrains.java.decompiler.struct.gen.VarType; +import org.jetbrains.java.decompiler.util.InterpreterUtil; +import org.jetbrains.java.decompiler.util.VBStyleCollection; + +public class ClassReference14Processor { + + public ExitExprent bodyexprent; + + public ExitExprent handlerexprent; + + + public ClassReference14Processor() { + + InvocationExprent invfor = new InvocationExprent(); + invfor.setName("forName"); + invfor.setClassname("java/lang/Class"); + invfor.setStringDescriptor("(Ljava/lang/String;)Ljava/lang/Class;"); + invfor.setDescriptor(MethodDescriptor.parseDescriptor("(Ljava/lang/String;)Ljava/lang/Class;")); + invfor.setStatic(true); + invfor.setLstParameters(Arrays.asList(new Exprent[] {new VarExprent(0, VarType.VARTYPE_STRING, null)})); + + bodyexprent = new ExitExprent(ExitExprent.EXIT_RETURN, + invfor, + VarType.VARTYPE_CLASS); + + InvocationExprent constr = new InvocationExprent(); + constr.setName(""); + constr.setClassname("java/lang/NoClassDefFoundError"); + constr.setStringDescriptor("()V"); + constr.setFunctype(InvocationExprent.TYP_INIT); + constr.setDescriptor(MethodDescriptor.parseDescriptor("()V")); + + NewExprent newexpr = new NewExprent(new VarType(CodeConstants.TYPE_OBJECT,0,"java/lang/NoClassDefFoundError"), new ArrayList()); + newexpr.setConstructor(constr); + + InvocationExprent invcause = new InvocationExprent(); + invcause.setName("initCause"); + invcause.setClassname("java/lang/NoClassDefFoundError"); + invcause.setStringDescriptor("(Ljava/lang/Throwable;)Ljava/lang/Throwable;"); + invcause.setDescriptor(MethodDescriptor.parseDescriptor("(Ljava/lang/Throwable;)Ljava/lang/Throwable;")); + invcause.setInstance(newexpr); + invcause.setLstParameters(Arrays.asList(new Exprent[] {new VarExprent(2, new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/ClassNotFoundException"), null)})); + + handlerexprent = new ExitExprent(ExitExprent.EXIT_THROW, + invcause, + null); + } + + + public void processClassReferences(ClassNode node) { + + ClassWrapper wrapper = node.wrapper; + +// int major_version = wrapper.getClassStruct().major_version; +// int minor_version = wrapper.getClassStruct().minor_version; +// +// if(major_version > 48 || (major_version == 48 && minor_version > 0)) { +// // version 1.5 or above +// return; +// } + + if(wrapper.getClassStruct().isVersionGE_1_5()) { + // version 1.5 or above + return; + } + + // find the synthetic method Class class$(String) if present + HashMap mapClassMeths = new HashMap(); + findClassMethod(node, mapClassMeths); + + if(mapClassMeths.isEmpty()) { + return; + } + + HashSet setFound = new HashSet(); + processClassRec(node, mapClassMeths, setFound); + + if(!setFound.isEmpty()) { + for(ClassWrapper wrp : setFound) { + StructMethod mt = mapClassMeths.get(wrp).methodStruct; + wrp.getHideMembers().add(InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor())); + } + } + + } + + private void processClassRec(ClassNode node, final HashMap mapClassMeths, final HashSet setFound) { + + final ClassWrapper wrapper = node.wrapper; + + // search code + for(MethodWrapper meth : wrapper.getMethods()) { + + RootStatement root = meth.root; + if(root != null) { + + DirectGraph graph = meth.getOrBuildGraph(); + + graph.iterateExprents(new DirectGraph.ExprentIterator() { + public int processExprent(Exprent exprent) { + for(Entry ent : mapClassMeths.entrySet()) { + if(replaceInvocations(exprent, ent.getKey(), ent.getValue())) { + setFound.add(ent.getKey()); + } + } + return 0; + } + }); + + } + } + + // search initializers + for(int j=0;j<2;j++) { + VBStyleCollection initializers = j==0?wrapper.getStaticFieldInitializers():wrapper.getDynamicFieldInitializers(); + + for(int i=0; i ent : mapClassMeths.entrySet()) { + Exprent exprent = initializers.get(i); + if(replaceInvocations(exprent, ent.getKey(), ent.getValue())) { + setFound.add(ent.getKey()); + } + + String cl = isClass14Invocation(exprent, ent.getKey(), ent.getValue()); + if(cl != null) { + initializers.set(i, new ConstExprent(VarType.VARTYPE_CLASS, cl.replace('.', '/'))); + setFound.add(ent.getKey()); + } + } + } + } + + // iterate nested classes + for(ClassNode nd : node.nested) { + processClassRec(nd, mapClassMeths, setFound); + } + + } + + private void findClassMethod(ClassNode node, HashMap mapClassMeths) { + + boolean nosynthflag = DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET); + + ClassWrapper wrapper = node.wrapper; + + for(MethodWrapper meth : wrapper.getMethods()) { + StructMethod mt = meth.methodStruct; + + if(((mt.getAccessFlags() & CodeConstants.ACC_SYNTHETIC) != 0 || mt.getAttributes().containsKey("Synthetic") + || nosynthflag) && + mt.getDescriptor().equals("(Ljava/lang/String;)Ljava/lang/Class;") && + (mt.getAccessFlags() & CodeConstants.ACC_STATIC) != 0) { + + RootStatement root = meth.root; + if(root != null) { + if(root.getFirst().type == Statement.TYPE_TRYCATCH) { + CatchStatement cst = (CatchStatement)root.getFirst(); + if(cst.getStats().size() == 2 && cst.getFirst().type == Statement.TYPE_BASICBLOCK && + cst.getStats().get(1).type == Statement.TYPE_BASICBLOCK && + cst.getVars().get(0).getVartype().equals(new VarType(CodeConstants.TYPE_OBJECT,0,"java/lang/ClassNotFoundException"))) { + + BasicBlockStatement body = (BasicBlockStatement)cst.getFirst(); + BasicBlockStatement handler = (BasicBlockStatement)cst.getStats().get(1); + + if(body.getExprents().size() == 1 && handler.getExprents().size() == 1) { + if(bodyexprent.equals(body.getExprents().get(0)) && + handlerexprent.equals(handler.getExprents().get(0))) { + mapClassMeths.put(wrapper, meth); + break; + } + } + } + } + } + } + } + + // iterate nested classes + for(ClassNode nd : node.nested) { + findClassMethod(nd, mapClassMeths); + } + + } + + + private boolean replaceInvocations(Exprent exprent, ClassWrapper wrapper, MethodWrapper meth) { + + boolean res = false; + + for(;;) { + + boolean found = false; + + for(Exprent expr : exprent.getAllExprents()) { + String cl = isClass14Invocation(expr, wrapper, meth); + if(cl != null) { + exprent.replaceExprent(expr, new ConstExprent(VarType.VARTYPE_CLASS, cl.replace('.', '/'))); + found = true; + res = true; + break; + } + + res |= replaceInvocations(expr, wrapper, meth); + } + + if(!found) { + break; + } + } + + return res; + } + + + + private String isClass14Invocation(Exprent exprent, ClassWrapper wrapper, MethodWrapper meth) { + + if(exprent.type == Exprent.EXPRENT_FUNCTION) { + FunctionExprent fexpr = (FunctionExprent)exprent; + if(fexpr.getFunctype() == FunctionExprent.FUNCTION_IIF) { + if(fexpr.getLstOperands().get(0).type == Exprent.EXPRENT_FUNCTION) { + FunctionExprent headexpr = (FunctionExprent)fexpr.getLstOperands().get(0); + if(headexpr.getFunctype() == FunctionExprent.FUNCTION_EQ) { + if(headexpr.getLstOperands().get(0).type == Exprent.EXPRENT_FIELD && + headexpr.getLstOperands().get(1).type == Exprent.EXPRENT_CONST && + ((ConstExprent)headexpr.getLstOperands().get(1)).getConsttype().equals(VarType.VARTYPE_NULL)) { + + FieldExprent field = (FieldExprent)headexpr.getLstOperands().get(0); + ClassNode fieldnode = DecompilerContext.getClassprocessor().getMapRootClasses().get(field.getClassname()); + + if(fieldnode != null && fieldnode.classStruct.qualifiedName.equals(wrapper.getClassStruct().qualifiedName)) { // source class + StructField fd = wrapper.getClassStruct().getField(field.getName(), field.getDescriptor().descriptorString); // FIXME: can be null! why?? + + if(fd != null && (fd.access_flags & CodeConstants.ACC_STATIC) != 0 && + ((fd.access_flags & CodeConstants.ACC_SYNTHETIC) != 0 || fd.getAttributes().containsKey("Synthetic") + || DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET))) { + + if(fexpr.getLstOperands().get(1).type == Exprent.EXPRENT_ASSIGNMENT && fexpr.getLstOperands().get(2).equals(field)) { + AssignmentExprent asexpr = (AssignmentExprent)fexpr.getLstOperands().get(1); + + if(asexpr.getLeft().equals(field) && asexpr.getRight().type == Exprent.EXPRENT_INVOCATION) { + InvocationExprent invexpr = (InvocationExprent)asexpr.getRight(); + + if(invexpr.getClassname().equals(wrapper.getClassStruct().qualifiedName) && + invexpr.getName().equals(meth.methodStruct.getName()) && + invexpr.getStringDescriptor().equals(meth.methodStruct.getDescriptor())) { + + if(invexpr.getLstParameters().get(0).type == Exprent.EXPRENT_CONST) { + wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor())); // hide synthetic field + return ((ConstExprent)invexpr.getLstParameters().get(0)).getValue().toString(); + } + } + } + } + } + } + } + } + } + } + } + + return null; + } +} diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java new file mode 100644 index 0000000..c14fe79 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -0,0 +1,1107 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.main; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + +import org.jetbrains.java.decompiler.code.CodeConstants; +import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; +import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; +import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; +import org.jetbrains.java.decompiler.main.rels.ClassWrapper; +import org.jetbrains.java.decompiler.main.rels.MethodWrapper; +import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; +import org.jetbrains.java.decompiler.modules.decompiler.exps.AnnotationExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.ConstExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.NewExprent; +import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; +import org.jetbrains.java.decompiler.modules.decompiler.vars.VarTypeProcessor; +import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPaar; +import org.jetbrains.java.decompiler.modules.renamer.PoolInterceptor; +import org.jetbrains.java.decompiler.struct.StructClass; +import org.jetbrains.java.decompiler.struct.StructField; +import org.jetbrains.java.decompiler.struct.StructMethod; +import org.jetbrains.java.decompiler.struct.attr.StructAnnDefaultAttribute; +import org.jetbrains.java.decompiler.struct.attr.StructAnnotationAttribute; +import org.jetbrains.java.decompiler.struct.attr.StructAnnotationParameterAttribute; +import org.jetbrains.java.decompiler.struct.attr.StructConstantValueAttribute; +import org.jetbrains.java.decompiler.struct.attr.StructExceptionsAttribute; +import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; +import org.jetbrains.java.decompiler.struct.attr.StructGenericSignatureAttribute; +import org.jetbrains.java.decompiler.struct.consts.PrimitiveConstant; +import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor; +import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; +import org.jetbrains.java.decompiler.struct.gen.VarType; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericClassDescriptor; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericFieldDescriptor; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericMain; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericMethodDescriptor; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericType; +import org.jetbrains.java.decompiler.util.InterpreterUtil; +import org.jetbrains.java.decompiler.util.VBStyleCollection; + +public class ClassWriter { + + private static final int[] modval_class = new int[] {CodeConstants.ACC_PUBLIC, CodeConstants.ACC_PROTECTED, CodeConstants.ACC_PRIVATE, + CodeConstants.ACC_ABSTRACT, CodeConstants.ACC_STATIC, CodeConstants.ACC_FINAL, CodeConstants.ACC_STRICT}; + + private static final String[] modstr_class = new String[] {"public ", "protected ", "private ", "abstract ", "static ", "final ", "strictfp "}; + + private static final int[] modval_field = new int[] {CodeConstants.ACC_PUBLIC, CodeConstants.ACC_PROTECTED, CodeConstants.ACC_PRIVATE, + CodeConstants.ACC_STATIC, CodeConstants.ACC_FINAL, CodeConstants.ACC_TRANSIENT, CodeConstants.ACC_VOLATILE}; + + private static final String[] modstr_field = new String[] {"public ", "protected ", "private ", "static ", "final ", "transient ", "volatile "}; + + private static final int[] modval_meth = new int[] {CodeConstants.ACC_PUBLIC, CodeConstants.ACC_PROTECTED, CodeConstants.ACC_PRIVATE, + CodeConstants.ACC_ABSTRACT, CodeConstants.ACC_STATIC, CodeConstants.ACC_FINAL, CodeConstants.ACC_SYNCHRONIZED, + CodeConstants.ACC_NATIVE, CodeConstants.ACC_STRICT}; + + private static final String[] modstr_meth = new String[] {"public ", "protected ", "private ", "abstract ", "static ", "final ", "synchronized ", "native ", "strictfp "}; + + private static final HashSet mod_notinterface = new HashSet(Arrays.asList(new Integer[] {CodeConstants.ACC_ABSTRACT, CodeConstants.ACC_STATIC})); + private static final HashSet mod_notinterface_fields = new HashSet(Arrays.asList(new Integer[] {CodeConstants.ACC_PUBLIC, CodeConstants.ACC_STATIC, CodeConstants.ACC_FINAL})); + private static final HashSet mod_notinterface_meth = new HashSet(Arrays.asList(new Integer[] {CodeConstants.ACC_PUBLIC, CodeConstants.ACC_ABSTRACT})); + + private ClassReference14Processor ref14processor; + + private PoolInterceptor interceptor; + + public ClassWriter() { + ref14processor = new ClassReference14Processor(); + interceptor = DecompilerContext.getPoolInterceptor(); + } + + + private void invokeProcessors(ClassNode node) { + + ClassWrapper wrapper = node.wrapper; + StructClass cl = wrapper.getClassStruct(); + + InitializerProcessor.extractInitializers(wrapper); + + if(node.type == ClassNode.CLASS_ROOT && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_CLASS_1_4)) { + ref14processor.processClassReferences(node); + } + + if(DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM) && (cl.access_flags & CodeConstants.ACC_ENUM) != 0) { + EnumProcessor.clearEnum(wrapper); + } + + if(DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ASSERTIONS)) { + AssertProcessor.buildAssertions(node); + } + + } + + public void classLambdaToJava(ClassNode node, BufferedWriter writer, Exprent method_object, int indent) throws IOException { + + // get the class node with the content method + ClassNode node_content = node; + while(node_content != null && node_content.type == ClassNode.CLASS_LAMBDA) { + node_content = node_content.parent; + } + + if(node_content == null) { + return; + } + + boolean lambda_to_anonymous = DecompilerContext.getOption(IFernflowerPreferences.LAMBDA_TO_ANONYMOUS_CLASS); + + ClassNode nodeold = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASSNODE); + DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASSNODE, node); + + ClassWrapper wrapper = node_content.wrapper; + StructClass cl = wrapper.getClassStruct(); + + DecompilerContext.getLogger().startWriteClass(node.simpleName); + + if(node.lambda_information.is_method_reference) { + + if(!node.lambda_information.is_content_method_static && method_object != null) { // reference to a virtual method + writer.write(method_object.toJava(indent)); + } else { // reference to a static method + writer.write(ExprProcessor.getCastTypeName(new VarType(node.lambda_information.content_class_name, false))); + } + + writer.write("::"); + writer.write(node.lambda_information.content_method_name); + + writer.flush(); + + } else { + + // lambda method + StructMethod mt = cl.getMethod(node.lambda_information.content_method_key); + MethodWrapper meth = wrapper.getMethodWrapper(mt.getName(), mt.getDescriptor()); + + MethodDescriptor md_content = MethodDescriptor.parseDescriptor(node.lambda_information.content_method_descriptor); + MethodDescriptor md_lambda = MethodDescriptor.parseDescriptor(node.lambda_information.method_descriptor); + + if(!lambda_to_anonymous) { // lambda parameters '() ->' + + StringBuilder buff = new StringBuilder("("); + + boolean firstpar = true; + int index = node.lambda_information.is_content_method_static ? 0 : 1;; + + int start_index = md_content.params.length - md_lambda.params.length; + + for(int i=0;i= start_index) { + + if(!firstpar) { + buff.append(", "); + } + + String parname = meth.varproc.getVarName(new VarVersionPaar(index, 0)); + buff.append(parname==null ? "param"+index : parname); // null iff decompiled with errors + + firstpar = false; + } + + index+=md_content.params[i].stack_size; + } + buff.append(") ->"); + + writer.write(buff.toString()); + } + + StringWriter strwriter = new StringWriter(); + BufferedWriter bufstrwriter = new BufferedWriter(strwriter); + + if(lambda_to_anonymous) { + methodLambdaToJava(node, node_content, mt, bufstrwriter, indent+1, false); + } else { + methodLambdaToJava(node, node_content, mt, bufstrwriter, indent, true); + } + + bufstrwriter.flush(); + + // closing up class definition + writer.write(" {"); + writer.write(DecompilerContext.getNewLineSeparator()); + + writer.write(strwriter.toString()); + + writer.write(InterpreterUtil.getIndentString(indent)); + writer.write("}"); + writer.flush(); + } + + DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASSNODE, nodeold); + + DecompilerContext.getLogger().endWriteClass(); + } + + public void classToJava(ClassNode node, BufferedWriter writer, int indent) throws IOException { + + ClassWrapper wrapper = node.wrapper; + StructClass cl = wrapper.getClassStruct(); + + ClassNode nodeold = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASSNODE); + DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASSNODE, node); + + // last minute processing + invokeProcessors(node); + + DecompilerContext.getLogger().startWriteClass(cl.qualifiedName); + + writeClassDefinition(node, writer, indent); + + // methods + StringWriter strwriter = new StringWriter(); + BufferedWriter bufstrwriter = new BufferedWriter(strwriter); + + boolean firstmt = true; + boolean mthidden = false; + + for(StructMethod mt : cl.getMethods()) { + + int flags = mt.getAccessFlags(); + + boolean isSynthetic = (flags & CodeConstants.ACC_SYNTHETIC) != 0 || mt.getAttributes().containsKey("Synthetic"); + boolean isBridge = (flags & CodeConstants.ACC_BRIDGE) != 0; + + if((!isSynthetic || !DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC)) && + (!isBridge || !DecompilerContext.getOption(IFernflowerPreferences.REMOVE_BRIDGE)) && + !wrapper.getHideMembers().contains(InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()))) { + if(!mthidden && (!firstmt || node.type != ClassNode.CLASS_ANONYMOUS)) { + bufstrwriter.write(DecompilerContext.getNewLineSeparator()); + firstmt = false; + } + + mthidden = !methodToJava(node, mt, bufstrwriter, indent+1); + } + } + bufstrwriter.flush(); + + StringWriter strwriter1 = new StringWriter(); + BufferedWriter bufstrwriter1 = new BufferedWriter(strwriter1); + + int fields_count = 0; + + boolean enumfields = false; + + // fields + for(StructField fd: cl.getFields()) { + int flags = fd.access_flags; + boolean isSynthetic = (flags & CodeConstants.ACC_SYNTHETIC) != 0 || fd.getAttributes().containsKey("Synthetic"); + if((!isSynthetic || !DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC)) + && !wrapper.getHideMembers().contains(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()))) { + + boolean isEnum = DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM) && (flags & CodeConstants.ACC_ENUM) != 0; + if(isEnum) { + if(enumfields) { + bufstrwriter1.write(","); + bufstrwriter1.write(DecompilerContext.getNewLineSeparator()); + } else { + enumfields = true; + } + } else { + if(enumfields) { + bufstrwriter1.write(";"); + bufstrwriter1.write(DecompilerContext.getNewLineSeparator()); + enumfields = false; + } + } + + fieldToJava(wrapper, cl, fd, bufstrwriter1, indent+1); + fields_count++; + } + } + + if(enumfields) { + bufstrwriter1.write(";"); + bufstrwriter1.write(DecompilerContext.getNewLineSeparator()); + } + + bufstrwriter1.flush(); + + if(fields_count > 0) { + writer.write(DecompilerContext.getNewLineSeparator()); + writer.write(strwriter1.toString()); + writer.write(DecompilerContext.getNewLineSeparator()); + } + + + // methods + writer.write(strwriter.toString()); + + // member classes + for(ClassNode inner : node.nested) { + if(inner.type == ClassNode.CLASS_MEMBER) { + StructClass innercl = inner.classStruct; + + boolean isSynthetic = ((inner.access | innercl.access_flags) & CodeConstants.ACC_SYNTHETIC) != 0 || innercl.getAttributes().containsKey("Synthetic"); + if((!isSynthetic || !DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC)) + && !wrapper.getHideMembers().contains(innercl.qualifiedName)) { + writer.write(DecompilerContext.getNewLineSeparator()); + classToJava(inner, writer, indent+1); + } + } + } + + writer.write(InterpreterUtil.getIndentString(indent)); + writer.write("}"); + if(node.type != ClassNode.CLASS_ANONYMOUS) { + writer.write(DecompilerContext.getNewLineSeparator()); + } + writer.flush(); + + DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASSNODE, nodeold); + + DecompilerContext.getLogger().endWriteClass(); + } + + private void writeClassDefinition(ClassNode node, BufferedWriter writer, int indent) throws IOException { + + if(node.type == ClassNode.CLASS_ANONYMOUS) { + writer.write(" {"); + writer.write(DecompilerContext.getNewLineSeparator()); + } else { + + String indstr = InterpreterUtil.getIndentString(indent); + + ClassWrapper wrapper = node.wrapper; + StructClass cl = wrapper.getClassStruct(); + + int flags = node.type == ClassNode.CLASS_ROOT?cl.access_flags:node.access; + boolean isInterface = (flags & CodeConstants.ACC_INTERFACE) != 0; + boolean isAnnotation = (flags & CodeConstants.ACC_ANNOTATION) != 0; + boolean isEnum = DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM) && (flags & CodeConstants.ACC_ENUM) != 0; + + boolean isDeprecated = cl.getAttributes().containsKey("Deprecated"); + + if(interceptor != null) { + String oldname = interceptor.getOldName(cl.qualifiedName); + if(oldname != null) { + writer.write(indstr); + writer.write("// $FF: renamed from: "+getDescriptorPrintOut(oldname, 0)); + writer.write(DecompilerContext.getNewLineSeparator()); + } + } + + if (isDeprecated) { + writer.write(indstr); + writer.write("/** @deprecated */"); + writer.write(DecompilerContext.getNewLineSeparator()); + } + + // class annotations + List lstAnn = getAllAnnotations(cl.getAttributes()); + for(AnnotationExprent annexpr : lstAnn) { + writer.write(annexpr.toJava(indent)); + writer.write(DecompilerContext.getNewLineSeparator()); + } + + boolean isSynthetic = (flags & CodeConstants.ACC_SYNTHETIC) != 0 || cl.getAttributes().containsKey("Synthetic"); + + if(isSynthetic) { + writer.write(indstr); + writer.write("// $FF: synthetic class"); + writer.write(DecompilerContext.getNewLineSeparator()); + } + + writer.write(indstr); + + if(isEnum) { + // remove abstract and final flags (JLS 8.9 Enums) + flags &=~CodeConstants.ACC_ABSTRACT; + flags &=~CodeConstants.ACC_FINAL; + } + + for(int i=0;i0) { + writer.write(", "); + } + writer.write(descriptor.fparameters.get(i)); + + List lstBounds = descriptor.fbounds.get(i); + if (lstBounds.size() > 1 || !"java/lang/Object".equals(lstBounds.get(0).value)) { + writer.write(" extends "); + writer.write(GenericMain.getGenericCastTypeName(lstBounds.get(0))); + + for(int j=1;j"); + } + writer.write(" "); + + if(!isEnum && !isInterface && cl.superClass != null) { + VarType supertype = new VarType(cl.superClass.getString(), true); + if(!VarType.VARTYPE_OBJECT.equals(supertype)) { + writer.write("extends "); + if(descriptor != null) { + writer.write(GenericMain.getGenericCastTypeName(descriptor.superclass)); + } else { + writer.write(ExprProcessor.getCastTypeName(supertype)); + } + writer.write(" "); + } + } + + if(!isAnnotation) { + int[] interfaces = cl.getInterfaces(); + if(interfaces.length > 0) { + writer.write(isInterface?"extends ":"implements "); + for(int i=0;i0) { + writer.write(", "); + } + if(descriptor != null) { + writer.write(GenericMain.getGenericCastTypeName(descriptor.superinterfaces.get(i))); + } else { + writer.write(ExprProcessor.getCastTypeName(new VarType(cl.getInterface(i), true))); + } + } + writer.write(" "); + } + } + + writer.write("{"); + writer.write(DecompilerContext.getNewLineSeparator()); + } + + } + + private void fieldToJava(ClassWrapper wrapper, StructClass cl, StructField fd, BufferedWriter writer, int indent) throws IOException { + + String indstr = InterpreterUtil.getIndentString(indent); + + boolean isInterface = (cl.access_flags & CodeConstants.ACC_INTERFACE) != 0; + int flags = fd.access_flags; + + if(interceptor != null) { + String oldname = interceptor.getOldName(cl.qualifiedName+" "+fd.getName()+" "+fd.getDescriptor()); + if(oldname != null) { + String[] element = oldname.split(" "); + + writer.write(indstr); + writer.write("// $FF: renamed from: "+element[1]+" "+getDescriptorPrintOut(element[2], 1)); + writer.write(DecompilerContext.getNewLineSeparator()); + } + } + + boolean isDeprecated = fd.getAttributes().containsKey("Deprecated"); + + if (isDeprecated) { + writer.write(indstr); + writer.write("/** @deprecated */"); + writer.write(DecompilerContext.getNewLineSeparator()); + } + + // field annotations + List lstAnn = getAllAnnotations(fd.getAttributes()); + for(AnnotationExprent annexpr : lstAnn) { + writer.write(annexpr.toJava(indent)); + writer.write(DecompilerContext.getNewLineSeparator()); + } + + boolean isSynthetic = (flags & CodeConstants.ACC_SYNTHETIC) != 0 || fd.getAttributes().containsKey("Synthetic"); + boolean isEnum = DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM) && (flags & CodeConstants.ACC_ENUM) != 0; + + if(isSynthetic) { + writer.write(indstr); + writer.write("// $FF: synthetic field"); + writer.write(DecompilerContext.getNewLineSeparator()); + } + + writer.write(indstr); + + if(!isEnum) { + for(int i=0;i= start_index) { + + if(!firstpar) { + bufstrwriter.write(", "); + } + + VarType partype = md_content.params[i].copy(); + + String strpartype = ExprProcessor.getCastTypeName(partype); + if(ExprProcessor.UNDEFINED_TYPE_STRING.equals(strpartype) && DecompilerContext.getOption(IFernflowerPreferences.UNDEFINED_PARAM_TYPE_OBJECT)) { + strpartype = ExprProcessor.getCastTypeName(VarType.VARTYPE_OBJECT); + } + + bufstrwriter.write(strpartype); + bufstrwriter.write(" "); + + String parname = meth.varproc.getVarName(new VarVersionPaar(index, 0)); + bufstrwriter.write(parname==null?"param"+index:parname); // null iff decompiled with errors + + firstpar = false; + } + + index+=md_content.params[i].stack_size; + } + + bufstrwriter.write(")"); + bufstrwriter.write(" "); + bufstrwriter.write("{"); + bufstrwriter.write(DecompilerContext.getNewLineSeparator()); + } + + RootStatement root = wrapper.getMethodWrapper(mt.getName(), mt.getDescriptor()).root; + + if(root != null && !meth.decompiledWithErrors) { // check for existence + try { + String code = root.toJava(indent+1); + bufstrwriter.write(code); + } catch(Throwable ex) { + DecompilerContext.getLogger().writeMessage("Method "+mt.getName()+" "+mt.getDescriptor()+" couldn't be written.", ex); + meth.decompiledWithErrors = true; + } + } + + if(meth.decompiledWithErrors) { + bufstrwriter.write(InterpreterUtil.getIndentString(indent+1)); + bufstrwriter.write("// $FF: Couldn't be decompiled"); + bufstrwriter.write(DecompilerContext.getNewLineSeparator()); + } + + if(!code_only) { + bufstrwriter.write(indstr+"}"); + bufstrwriter.write(DecompilerContext.getNewLineSeparator()); + } + + bufstrwriter.flush(); + + writer.write(strwriter.toString()); + + DecompilerContext.setProperty(DecompilerContext.CURRENT_METHOD_WRAPPER, methold); + + return true; + } + + public boolean methodToJava(ClassNode node, StructMethod mt, BufferedWriter writer, int indent) throws IOException { + + ClassWrapper wrapper = node.wrapper; + StructClass cl = wrapper.getClassStruct(); + + MethodWrapper meth = wrapper.getMethodWrapper(mt.getName(), mt.getDescriptor()); + + MethodWrapper methold = (MethodWrapper)DecompilerContext.getProperty(DecompilerContext.CURRENT_METHOD_WRAPPER); + DecompilerContext.setProperty(DecompilerContext.CURRENT_METHOD_WRAPPER, meth); + + boolean isInterface = (cl.access_flags & CodeConstants.ACC_INTERFACE) != 0; + boolean isAnnotation = (cl.access_flags & CodeConstants.ACC_ANNOTATION) != 0; + boolean isEnum = (cl.access_flags & CodeConstants.ACC_ENUM) != 0 && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM); + boolean isDeprecated = mt.getAttributes().containsKey("Deprecated"); + + String indstr = InterpreterUtil.getIndentString(indent); + boolean clinit = false, init = false, dinit = false; + + MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); + + StringWriter strwriter = new StringWriter(); + BufferedWriter bufstrwriter = new BufferedWriter(strwriter); + + int flags = mt.getAccessFlags(); + if((flags & CodeConstants.ACC_NATIVE) != 0) { + flags &= ~CodeConstants.ACC_STRICT; // compiler bug: a strictfp class sets all methods to strictfp + } + + if("".equals(mt.getName())) { + flags &= CodeConstants.ACC_STATIC; // ingnore all modifiers except 'static' in a static initializer + } + + if(interceptor != null) { + String oldname = interceptor.getOldName(cl.qualifiedName+" "+mt.getName()+" "+mt.getDescriptor()); + if(oldname != null) { + String[] element = oldname.split(" "); + + bufstrwriter.write(indstr); + bufstrwriter.write("// $FF: renamed from: "+element[1]+" "+getDescriptorPrintOut(element[2], 2)); + bufstrwriter.write(DecompilerContext.getNewLineSeparator()); + } + } + + if (isDeprecated) { + writer.write(indstr); + writer.write("/** @deprecated */"); + writer.write(DecompilerContext.getNewLineSeparator()); + } + + // method annotations + List lstAnn = getAllAnnotations(mt.getAttributes()); + for(AnnotationExprent annexpr : lstAnn) { + bufstrwriter.write(annexpr.toJava(indent)); + bufstrwriter.write(DecompilerContext.getNewLineSeparator()); + } + + boolean isSynthetic = (flags & CodeConstants.ACC_SYNTHETIC) != 0 || mt.getAttributes().containsKey("Synthetic"); + boolean isBridge = (flags & CodeConstants.ACC_BRIDGE) != 0; + + if(isSynthetic) { + bufstrwriter.write(indstr); + bufstrwriter.write("// $FF: synthetic method"); + bufstrwriter.write(DecompilerContext.getNewLineSeparator()); + } + + if(isBridge) { + bufstrwriter.write(indstr); + bufstrwriter.write("// $FF: bridge method"); + bufstrwriter.write(DecompilerContext.getNewLineSeparator()); + } + + bufstrwriter.write(indstr); + for(int i=0;i".equals(name)) { + if (node.type == ClassNode.CLASS_ANONYMOUS) { + name = ""; + dinit = true; + } else { + name = node.simpleName; + init = true; + } + } else if ("".equals(name)) { + name = ""; + clinit = true; + } + + GenericMethodDescriptor descriptor = null; + if(DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES)) { + StructGenericSignatureAttribute attr = (StructGenericSignatureAttribute)mt.getAttributes().getWithKey("Signature"); + if(attr != null) { + descriptor = GenericMain.parseMethodSignature(attr.getSignature()); + int actualParams = md.params.length; + if(isEnum && init) actualParams -= 2; + if(actualParams != descriptor.params.size()) { + DecompilerContext.getLogger().writeMessage("Inconsistent generic signature in method "+mt.getName()+" "+mt.getDescriptor(), IFernflowerLogger.WARNING); + descriptor = null; + } + } + } + + boolean throwsExceptions = false; + + int param_count_explicit = 0; + + if(!clinit && !dinit) { + + boolean thisvar = (mt.getAccessFlags() & CodeConstants.ACC_STATIC) == 0; + + // formal type parameters + if(descriptor != null && !descriptor.fparameters.isEmpty()) { + bufstrwriter.write("<"); + for(int i=0;i0) { + bufstrwriter.write(", "); + } + bufstrwriter.write(descriptor.fparameters.get(i)); + + List lstBounds = descriptor.fbounds.get(i); + if (lstBounds.size() > 1 || !"java/lang/Object".equals(lstBounds.get(0).value)) { + bufstrwriter.write(" extends "); + bufstrwriter.write(GenericMain.getGenericCastTypeName(lstBounds.get(0))); + + for(int j = 1; j < lstBounds.size(); j++) { + bufstrwriter.write(" & " + GenericMain.getGenericCastTypeName(lstBounds.get(j))); + } + } + } + bufstrwriter.write("> "); + } + + if(!init) { + if(descriptor != null) { + bufstrwriter.write(GenericMain.getGenericCastTypeName(descriptor.ret)); + } else { + bufstrwriter.write(ExprProcessor.getCastTypeName(md.ret)); + } + bufstrwriter.write(" "); + } + + bufstrwriter.write(name); + bufstrwriter.write("("); + + // parameter annotations + List> lstParAnn = getAllParameterAnnotations(mt.getAttributes()); + + List signFields = meth.signatureFields; + + // compute last visible parameter + int lastparam_index = -1; + for(int i=0;i param_count_explicit) { + List annotations = lstParAnn.get(param_count_explicit); + for(int j=0;j 0); + + if(isVarArgs) { + partype.arraydim--; + } + + String strpartype = GenericMain.getGenericCastTypeName(partype); + if(ExprProcessor.UNDEFINED_TYPE_STRING.equals(strpartype) && + DecompilerContext.getOption(IFernflowerPreferences.UNDEFINED_PARAM_TYPE_OBJECT)) { + strpartype = ExprProcessor.getCastTypeName(VarType.VARTYPE_OBJECT); + } + + bufstrwriter.write(strpartype); + + if(isVarArgs) { + bufstrwriter.write(" ..."); + } + + } else { + VarType partype = md.params[i].copy(); + + boolean isVarArgs = (i == lastparam_index && (mt.getAccessFlags() & CodeConstants.ACC_VARARGS) != 0 + && partype.arraydim > 0); + + if(isVarArgs) { + partype.decArrayDim(); + } + + String strpartype = ExprProcessor.getCastTypeName(partype); + if(ExprProcessor.UNDEFINED_TYPE_STRING.equals(strpartype) && + DecompilerContext.getOption(IFernflowerPreferences.UNDEFINED_PARAM_TYPE_OBJECT)) { + strpartype = ExprProcessor.getCastTypeName(VarType.VARTYPE_OBJECT); + } + + bufstrwriter.write(strpartype); + + if(isVarArgs) { + bufstrwriter.write(" ..."); + } + } + + bufstrwriter.write(" "); + String parname = meth.varproc.getVarName(new VarVersionPaar(index, 0)); + bufstrwriter.write(parname==null?"param"+index:parname); // null iff decompiled with errors + firstpar = false; + param_count_explicit++; + } + + index+=md.params[i].stack_size; + } + + bufstrwriter.write(")"); + + StructExceptionsAttribute attr = (StructExceptionsAttribute)mt.getAttributes().getWithKey("Exceptions"); + if((descriptor!=null && !descriptor.exceptions.isEmpty()) || attr != null) { + throwsExceptions = true; + bufstrwriter.write(" throws "); + + for(int i=0;i0) { + bufstrwriter.write(", "); + } + if(descriptor!=null && !descriptor.exceptions.isEmpty()) { + bufstrwriter.write(GenericMain.getGenericCastTypeName(descriptor.exceptions.get(i))); + } else { + VarType exctype = new VarType(attr.getExcClassname(i, cl.getPool()), true); + bufstrwriter.write(ExprProcessor.getCastTypeName(exctype)); + } + } + } + } + + boolean hidemethod = false; + + if((flags & (CodeConstants.ACC_ABSTRACT | CodeConstants.ACC_NATIVE)) != 0) { // native or abstract method (explicit or interface) + if(isAnnotation) { + StructAnnDefaultAttribute attr = (StructAnnDefaultAttribute)mt.getAttributes().getWithKey("AnnotationDefault"); + if(attr != null) { + bufstrwriter.write(" default "); + bufstrwriter.write(attr.getDefaultValue().toJava(indent+1)); + } + } + + bufstrwriter.write(";"); + bufstrwriter.write(DecompilerContext.getNewLineSeparator()); + } else { + if(!clinit && !dinit) { + bufstrwriter.write(" "); + } + bufstrwriter.write("{"); + bufstrwriter.write(DecompilerContext.getNewLineSeparator()); + + RootStatement root = wrapper.getMethodWrapper(mt.getName(), mt.getDescriptor()).root; + + if(root != null && !meth.decompiledWithErrors) { // check for existence + try { + String code = root.toJava(indent+1); + + boolean singleinit = false; + if(init && param_count_explicit == 0 && !throwsExceptions && DecompilerContext.getOption(IFernflowerPreferences.HIDE_DEFAULT_CONSTRUCTOR)) { + int init_counter = 0; + for(MethodWrapper mth : wrapper.getMethods()) { + if("".equals(mth.methodStruct.getName())) { + init_counter++; + } + } + singleinit = (init_counter == 1); + } + + hidemethod = (clinit || dinit || singleinit) && code.length() == 0; + + bufstrwriter.write(code); + } catch(Throwable ex) { + DecompilerContext.getLogger().writeMessage("Method "+mt.getName()+" "+mt.getDescriptor()+" couldn't be written.", ex); + meth.decompiledWithErrors = true; + } + } + + if(meth.decompiledWithErrors) { + bufstrwriter.write(InterpreterUtil.getIndentString(indent+1)); + bufstrwriter.write("// $FF: Couldn't be decompiled"); + bufstrwriter.write(DecompilerContext.getNewLineSeparator()); + } + + bufstrwriter.write(indstr+"}"); + bufstrwriter.write(DecompilerContext.getNewLineSeparator()); + } + + bufstrwriter.flush(); + + if(!hidemethod) { + writer.write(strwriter.toString()); + } + + DecompilerContext.setProperty(DecompilerContext.CURRENT_METHOD_WRAPPER, methold); + + return !hidemethod; + } + + private List getAllAnnotations(VBStyleCollection attributes) { + + String[] annattrnames = new String[] {StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS, + StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS}; + + List lst = new ArrayList(); + + for(String attrname : annattrnames) { + StructAnnotationAttribute attr = (StructAnnotationAttribute)attributes.getWithKey(attrname); + if(attr != null) { + lst.addAll(attr.getAnnotations()); + } + } + + return lst; + } + + private List> getAllParameterAnnotations(VBStyleCollection attributes) { + + String[] annattrnames = new String[] {StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, + StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS}; + + List> ret = new ArrayList>(); + + for(String attrname : annattrnames) { + StructAnnotationParameterAttribute attr = (StructAnnotationParameterAttribute)attributes.getWithKey(attrname); + if(attr != null) { + for(int i=0;i lst = new ArrayList(); + boolean isnew = (ret.size()<=i); + + if(!isnew) { + lst = ret.get(i); + } + lst.addAll(attr.getParamAnnotations().get(i)); + + if(isnew) { + ret.add(lst); + } else { + ret.set(i, lst); + } + } + } + } + + return ret; + } + + private String getDescriptorPrintOut(String descriptor, int element) { + + switch(element) { + case 0: // class + return ExprProcessor.buildJavaClassName(descriptor); + case 1: // field + return getTypePrintOut(FieldDescriptor.parseDescriptor(descriptor).type); + case 2: // method + default: + MethodDescriptor md = MethodDescriptor.parseDescriptor(descriptor); + + StringBuilder buffer = new StringBuilder("("); + + boolean first = true; + for(VarType partype : md.params) { + if(first) { + first = false; + } else { + buffer.append(", "); + } + buffer.append(getTypePrintOut(partype)); + } + buffer.append(") "); + buffer.append(getTypePrintOut(md.ret)); + + return buffer.toString(); + } + } + + private String getTypePrintOut(VarType type) { + String strtype = ExprProcessor.getCastTypeName(type, false); + if(ExprProcessor.UNDEFINED_TYPE_STRING.equals(strtype) && + DecompilerContext.getOption(IFernflowerPreferences.UNDEFINED_PARAM_TYPE_OBJECT)) { + strtype = ExprProcessor.getCastTypeName(VarType.VARTYPE_OBJECT, false); + } + return strtype; + } +} diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java new file mode 100644 index 0000000..e0e144f --- /dev/null +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -0,0 +1,449 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.main; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.StringWriter; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; + +import org.jetbrains.java.decompiler.code.CodeConstants; +import org.jetbrains.java.decompiler.main.collectors.CounterContainer; +import org.jetbrains.java.decompiler.main.collectors.ImportCollector; +import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; +import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; +import org.jetbrains.java.decompiler.main.extern.IIdentifierRenamer; +import org.jetbrains.java.decompiler.main.rels.ClassWrapper; +import org.jetbrains.java.decompiler.main.rels.LambdaProcessor; +import org.jetbrains.java.decompiler.main.rels.NestedClassProcessor; +import org.jetbrains.java.decompiler.main.rels.NestedMemberAccess; +import org.jetbrains.java.decompiler.modules.decompiler.exps.InvocationExprent; +import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPaar; +import org.jetbrains.java.decompiler.struct.StructClass; +import org.jetbrains.java.decompiler.struct.StructContext; +import org.jetbrains.java.decompiler.struct.StructMethod; +import org.jetbrains.java.decompiler.struct.attr.StructInnerClassesAttribute; +import org.jetbrains.java.decompiler.struct.gen.VarType; +import org.jetbrains.java.decompiler.util.InterpreterUtil; + +public class ClassesProcessor { + + private HashMap mapRootClasses = new HashMap(); + + public ClassesProcessor(StructContext context) { + + HashMap mapInnerClasses = new HashMap(); + + HashMap> mapNestedClassReferences = new HashMap>(); + HashMap> mapEnclosingClassReferences = new HashMap>(); + + HashMap mapNewSimpleNames = new HashMap(); + + boolean bDecompileInner = DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_INNER); + + // create class nodes + for(StructClass cl: context.getClasses().values()) { + if(cl.isOwn() && !mapRootClasses.containsKey(cl.qualifiedName)) { + + if(bDecompileInner) { + StructInnerClassesAttribute inner = (StructInnerClassesAttribute)cl.getAttributes().getWithKey("InnerClasses"); + if(inner != null) { + + for(int i=0;i set = mapNestedClassReferences.get(enclClassName); + if(set == null) { + mapNestedClassReferences.put(enclClassName, set = new HashSet()); + } + set.add(innername); + + // reference to the enclosing class + set = mapEnclosingClassReferences.get(innername); + if(set == null) { + mapEnclosingClassReferences.put(innername, set = new HashSet()); + } + set.add(enclClassName); + } + } + } + } + } + + ClassNode node = new ClassNode(ClassNode.CLASS_ROOT, cl); + node.access = cl.access_flags; + mapRootClasses.put(cl.qualifiedName, node); + } + } + + if(bDecompileInner) { + + // connect nested classes + for(Entry ent: mapRootClasses.entrySet()) { + // root class? + if(!mapInnerClasses.containsKey(ent.getKey())) { + + HashSet setVisited = new HashSet(); + LinkedList stack = new LinkedList(); + + stack.add(ent.getKey()); + setVisited.add(ent.getKey()); + + while(!stack.isEmpty()) { + + String superClass = stack.removeFirst(); + ClassNode supernode = mapRootClasses.get(superClass); + + HashSet setNestedClasses = mapNestedClassReferences.get(superClass); + if(setNestedClasses != null) { + + StructClass scl = supernode.classStruct; + StructInnerClassesAttribute inner = (StructInnerClassesAttribute) scl.getAttributes().getWithKey("InnerClasses"); + for(int i = 0; i < inner.getStringentries().size(); i++) { + String nestedClass = inner.getStringentries().get(i)[0]; + if (!setNestedClasses.contains(nestedClass)) { + continue; + } + + if(setVisited.contains(nestedClass)) { + continue; + } + setVisited.add(nestedClass); + + ClassNode nestednode = mapRootClasses.get(nestedClass); + if(nestednode == null) { + DecompilerContext.getLogger().writeMessage("Nested class "+nestedClass+" missing!", IFernflowerLogger.WARNING); + continue; + } + + Object[] arr = mapInnerClasses.get(nestedClass); + + if((Integer)arr[2] == ClassNode.CLASS_MEMBER) { + // FIXME: check for consistent naming + } + + nestednode.type = (Integer)arr[2]; + nestednode.simpleName = (String)arr[1]; + nestednode.access = (Integer)arr[3]; + + if(nestednode.type == ClassNode.CLASS_ANONYMOUS) { + StructClass cl = nestednode.classStruct; + + // remove static if anonymous class + // a common compiler bug + nestednode.access &= ~CodeConstants.ACC_STATIC; + + int[] interfaces = cl.getInterfaces(); + + if(interfaces.length > 0) { + if(interfaces.length > 1) { + DecompilerContext.getLogger().writeMessage("Inconsistent anonymous class definition: "+cl.qualifiedName, IFernflowerLogger.WARNING); + } + nestednode.anonimousClassType = new VarType(cl.getInterface(0), true); + } else { + nestednode.anonimousClassType = new VarType(cl.superClass.getString(), true); + } + } else if(nestednode.type == ClassNode.CLASS_LOCAL) { + // only abstract and final are permitted + // a common compiler bug + nestednode.access &= (CodeConstants.ACC_ABSTRACT | CodeConstants.ACC_FINAL); + } + + supernode.nested.add(nestednode); + nestednode.parent = supernode; + + nestednode.enclosingClasses.addAll(mapEnclosingClassReferences.get(nestedClass)); + + stack.add(nestedClass); + } + } + } + } + } + + } + + } + + + public void writeClass(StructContext context, StructClass cl, BufferedWriter outwriter) throws IOException { + + ClassNode root = mapRootClasses.get(cl.qualifiedName); + if(root.type != ClassNode.CLASS_ROOT) { + return; + } + + try { + DecompilerContext.setImpcollector(new ImportCollector(root)); + DecompilerContext.setCountercontainer(new CounterContainer()); + + // lambda processing + LambdaProcessor lambda_proc = new LambdaProcessor(); + lambda_proc.processClass(root); + + // add simple class names to implicit import + addClassnameToImport(root, DecompilerContext.getImpcollector()); + // build wrappers for all nested classes + // that's where the actual processing takes place + initWrappers(root); + + NestedClassProcessor nestedproc = new NestedClassProcessor(); + nestedproc.processClass(root, root); + + NestedMemberAccess nstmember = new NestedMemberAccess(); + nstmember.propagateMemberAccess(root); + + ClassWriter clwriter = new ClassWriter(); + + StringWriter strwriter = new StringWriter(); + clwriter.classToJava(root, new BufferedWriter(strwriter), 0); + + if(DecompilerContext.getOption(IFernflowerPreferences.OUTPUT_COPYRIGHT_COMMENT)) { + outwriter.write("// Decompiled by: Fernflower "+Fernflower.version); + outwriter.write(DecompilerContext.getNewLineSeparator()); + outwriter.write("// Date: "+new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date())); + outwriter.write(DecompilerContext.getNewLineSeparator()); + outwriter.write("// Copyright: 2008-2010, Stiver"); + outwriter.write(DecompilerContext.getNewLineSeparator()); + outwriter.write("// Home page: http://www.reversed-java.com"); + outwriter.write(DecompilerContext.getNewLineSeparator()); + outwriter.write(DecompilerContext.getNewLineSeparator()); + } + + int index = cl.qualifiedName.lastIndexOf("/"); + if(index >= 0) { + String packageName = cl.qualifiedName.substring(0, index).replace('/', '.'); + outwriter.write("package "); + outwriter.write(packageName); + outwriter.write(";"); + outwriter.write(DecompilerContext.getNewLineSeparator()); + outwriter.write(DecompilerContext.getNewLineSeparator()); + } + + DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASSNODE, root); + + DecompilerContext.getImpcollector().writeImports(outwriter); + outwriter.write(DecompilerContext.getNewLineSeparator()); + + outwriter.write(strwriter.toString()); + outwriter.flush(); + + } finally { + destroyWrappers(root); + } + } + + private void initWrappers(ClassNode node) throws IOException { + + if(node.type == ClassNode.CLASS_LAMBDA) { + return; + } + + ClassWrapper wrapper = new ClassWrapper(node.classStruct); + wrapper.init(); + + node.wrapper = wrapper; + + for(ClassNode nd: node.nested) { + initWrappers(nd); + } + } + + private void addClassnameToImport(ClassNode node, ImportCollector imp) { + + if(node.simpleName != null && node.simpleName.length() > 0) { + imp.getShortName(node.type == ClassNode.CLASS_ROOT?node.classStruct.qualifiedName:node.simpleName, false); + } + + for(ClassNode nd: node.nested) { + addClassnameToImport(nd, imp); + } + } + + private void destroyWrappers(ClassNode node) { + + node.wrapper = null; + node.classStruct.releaseResources(); + + for(ClassNode nd: node.nested) { + destroyWrappers(nd); + } + } + + public HashMap getMapRootClasses() { + return mapRootClasses; + } + + + public class ClassNode { + + public static final int CLASS_ROOT = 0; + public static final int CLASS_MEMBER = 1; + public static final int CLASS_ANONYMOUS = 2; + public static final int CLASS_LOCAL = 4; + public static final int CLASS_LAMBDA = 8; + + public int type; + + public int access; + + public String simpleName; + + public StructClass classStruct; + + public ClassWrapper wrapper; + + public String enclosingMethod; + + public InvocationExprent superInvocation; + + public HashMap mapFieldsToVars = new HashMap(); + + public VarType anonimousClassType; + + public List nested = new ArrayList(); + + public Set enclosingClasses = new HashSet(); + + public ClassNode parent; + + public LambdaInformation lambda_information; + + public ClassNode(String content_class_name, String content_method_name, String content_method_descriptor, int content_method_invokation_type, + String lambda_class_name, String lambda_method_name, String lambda_method_descriptor, StructClass classStruct) { // lambda class constructor + this.type = CLASS_LAMBDA; + this.classStruct = classStruct; // 'parent' class containing the static function + + lambda_information = new LambdaInformation(); + + lambda_information.class_name = lambda_class_name; + lambda_information.method_name = lambda_method_name; + lambda_information.method_descriptor = lambda_method_descriptor; + + lambda_information.content_class_name = content_class_name; + lambda_information.content_method_name = content_method_name; + lambda_information.content_method_descriptor = content_method_descriptor; + lambda_information.content_method_invokation_type = content_method_invokation_type; + + lambda_information.content_method_key = InterpreterUtil.makeUniqueKey(lambda_information.content_method_name, lambda_information.content_method_descriptor); + + anonimousClassType = new VarType(lambda_class_name, true); + + boolean is_method_reference = (content_class_name != classStruct.qualifiedName); + StructMethod mt = null; + + if(!is_method_reference) { // content method in the same class, check synthetic flag + mt = classStruct.getMethod(content_method_name, content_method_descriptor); + is_method_reference = !((mt.getAccessFlags() & CodeConstants.ACC_SYNTHETIC) != 0 || mt.getAttributes().containsKey("Synthetic")); // if not synthetic -> method reference + } + + lambda_information.is_method_reference = is_method_reference; + lambda_information.is_content_method_static = (lambda_information.content_method_invokation_type == CodeConstants.CONSTANT_MethodHandle_REF_invokeStatic); // FIXME: redundant? + } + + public ClassNode(int type, StructClass classStruct) { + this.type = type; + this.classStruct = classStruct; + + simpleName = classStruct.qualifiedName.substring(classStruct.qualifiedName.lastIndexOf('/')+1); + } + + public ClassNode getClassNode(String qualifiedName) { + for(ClassNode node : nested) { + if(qualifiedName.equals(node.classStruct.qualifiedName)) { + return node; + } + } + return null; + } + + public class LambdaInformation { + + + + public String class_name; + public String method_name; + public String method_descriptor; + + public String content_class_name; + public String content_method_name; + public String content_method_descriptor; + public int content_method_invokation_type; // values from CONSTANT_MethodHandle_REF_* + + public String content_method_key; + + public boolean is_method_reference; + public boolean is_content_method_static; + } + } +} diff --git a/src/org/jetbrains/java/decompiler/main/DecompilerContext.java b/src/org/jetbrains/java/decompiler/main/DecompilerContext.java new file mode 100644 index 0000000..fc721b7 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/main/DecompilerContext.java @@ -0,0 +1,197 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.main; + +import java.util.HashMap; + +import org.jetbrains.java.decompiler.main.collectors.CounterContainer; +import org.jetbrains.java.decompiler.main.collectors.ImportCollector; +import org.jetbrains.java.decompiler.main.collectors.VarNamesCollector; +import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; +import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; +import org.jetbrains.java.decompiler.modules.renamer.PoolInterceptor; +import org.jetbrains.java.decompiler.struct.StructContext; + + +public class DecompilerContext { + + public static final String CURRENT_CLASS = "CURRENT_CLASS"; + public static final String CURRENT_METHOD = "CURRENT_METHOD"; + public static final String CURRENT_METHOD_DESCRIPTOR = "CURRENT_METHOD_DESCRIPTOR"; + public static final String CURRENT_VAR_PROCESSOR = "CURRENT_VAR_PROCESSOR"; + + public static final String CURRENT_CLASSNODE = "CURRENT_CLASSNODE"; + public static final String CURRENT_METHOD_WRAPPER = "CURRENT_METHOD_WRAPPER"; + + private static ThreadLocal currentContext = new ThreadLocal(); + + private HashMap properties = new HashMap(); + + private StructContext structcontext; + + private ImportCollector impcollector; + + private VarNamesCollector varncollector; + + private CounterContainer countercontainer; + + private ClassesProcessor classprocessor; + + private PoolInterceptor poolinterceptor; + + private IFernflowerLogger logger; + + + private DecompilerContext(HashMap properties) { + this.properties.putAll(properties); + } + + public static void initContext(HashMap propertiesCustom) { + + HashMap mapDefault = new HashMap(); + + // default settings + mapDefault.put(IFernflowerPreferences.DECOMPILE_INNER, "1"); + mapDefault.put(IFernflowerPreferences.DECOMPILE_CLASS_1_4, "1"); + mapDefault.put(IFernflowerPreferences.DECOMPILE_ASSERTIONS, "1"); + mapDefault.put(IFernflowerPreferences.REMOVE_BRIDGE, "1"); + mapDefault.put(IFernflowerPreferences.REMOVE_SYNTHETIC, "0"); + mapDefault.put(IFernflowerPreferences.HIDE_EMPTY_SUPER, "1"); + mapDefault.put(IFernflowerPreferences.HIDE_DEFAULT_CONSTRUCTOR, "1"); + mapDefault.put(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES, "0"); + mapDefault.put(IFernflowerPreferences.OUTPUT_COPYRIGHT_COMMENT, "0"); + mapDefault.put(IFernflowerPreferences.NO_EXCEPTIONS_RETURN, "1"); + mapDefault.put(IFernflowerPreferences.DECOMPILE_ENUM, "1"); + mapDefault.put(IFernflowerPreferences.FINALLY_DEINLINE, "1"); + mapDefault.put(IFernflowerPreferences.REMOVE_GETCLASS_NEW, "1"); + mapDefault.put(IFernflowerPreferences.LITERALS_AS_IS, "0"); + mapDefault.put(IFernflowerPreferences.ASCII_STRING_CHARACTERS, "0"); + mapDefault.put(IFernflowerPreferences.BOOLEAN_TRUE_ONE, "1"); + mapDefault.put(IFernflowerPreferences.SYNTHETIC_NOT_SET, "1"); + mapDefault.put(IFernflowerPreferences.UNDEFINED_PARAM_TYPE_OBJECT, "1"); + + mapDefault.put(IFernflowerPreferences.USE_DEBUG_VARNAMES, "1"); + mapDefault.put(IFernflowerPreferences.MAX_PROCESSING_METHOD, "0"); + + mapDefault.put(IFernflowerPreferences.REMOVE_EMPTY_RANGES, "1"); + + mapDefault.put(IFernflowerPreferences.NEW_LINE_SEPARATOR, "0"); + mapDefault.put(IFernflowerPreferences.INDENT_STRING, " "); + + mapDefault.put(IFernflowerPreferences.IDEA_NOT_NULL_ANNOTATION, "1"); + + if(propertiesCustom != null) { + mapDefault.putAll(propertiesCustom); + } + + currentContext.set(new DecompilerContext(mapDefault)); + } + + public static DecompilerContext getCurrentContext() { + return currentContext.get(); + } + + public static void setCurrentContext(DecompilerContext context) { + currentContext.set(context); + } + + public static Object getProperty(String key) { + return getCurrentContext().properties.get(key); + } + + public static void setProperty(String key, Object value) { + getCurrentContext().properties.put(key, value); + } + + public static boolean getOption(String key) { + return "1".equals(getCurrentContext().properties.get(key)); + } + + public static ImportCollector getImpcollector() { + return getCurrentContext().impcollector; + } + + public static void setImpcollector(ImportCollector impcollector) { + getCurrentContext().impcollector = impcollector; + } + + public static VarNamesCollector getVarncollector() { + return getCurrentContext().varncollector; + } + + public static void setVarncollector(VarNamesCollector varncollector) { + getCurrentContext().varncollector = varncollector; + } + + public static StructContext getStructcontext() { + return getCurrentContext().structcontext; + } + + public static void setStructcontext(StructContext structcontext) { + getCurrentContext().structcontext = structcontext; + } + + public static CounterContainer getCountercontainer() { + return getCurrentContext().countercontainer; + } + + public static void setCountercontainer(CounterContainer countercontainer) { + getCurrentContext().countercontainer = countercontainer; + } + + public static ClassesProcessor getClassprocessor() { + return getCurrentContext().classprocessor; + } + + public static void setClassprocessor(ClassesProcessor classprocessor) { + getCurrentContext().classprocessor = classprocessor; + } + + public static PoolInterceptor getPoolInterceptor() { + return getCurrentContext().poolinterceptor; + } + + public static void setPoolInterceptor(PoolInterceptor poolinterceptor) { + getCurrentContext().poolinterceptor = poolinterceptor; + } + + public static IFernflowerLogger getLogger() { + return getCurrentContext().logger; + } + + public static void setLogger(IFernflowerLogger logger) { + getCurrentContext().logger = logger; + setLogSeverity(); + } + + private static void setLogSeverity() { + IFernflowerLogger logger = getCurrentContext().logger; + + if(logger != null) { + String severity = (String)getProperty(IFernflowerPreferences.LOG_LEVEL); + if(severity != null) { + Integer iSeverity = IFernflowerLogger.mapLogLevel.get(severity.toUpperCase()); + if(iSeverity != null) { + logger.setSeverity(iSeverity); + } + } + } + } + + public static String getNewLineSeparator() { + return getOption(IFernflowerPreferences.NEW_LINE_SEPARATOR) ? + IFernflowerPreferences.LINE_SEPARATOR_LIN : IFernflowerPreferences.LINE_SEPARATOR_WIN ; + } +} diff --git a/src/org/jetbrains/java/decompiler/main/EnumProcessor.java b/src/org/jetbrains/java/decompiler/main/EnumProcessor.java new file mode 100644 index 0000000..7537596 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/main/EnumProcessor.java @@ -0,0 +1,159 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.main; + +import org.jetbrains.java.decompiler.code.CodeConstants; +import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; +import org.jetbrains.java.decompiler.main.rels.ClassWrapper; +import org.jetbrains.java.decompiler.main.rels.MethodWrapper; +import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.InvocationExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.NewExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; +import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; +import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPaar; +import org.jetbrains.java.decompiler.struct.StructClass; +import org.jetbrains.java.decompiler.struct.StructField; +import org.jetbrains.java.decompiler.struct.StructMethod; +import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor; +import org.jetbrains.java.decompiler.struct.gen.VarType; +import org.jetbrains.java.decompiler.util.InterpreterUtil; + +public class EnumProcessor { + + public static void clearEnum(ClassWrapper wrapper) { + + StructClass cl = wrapper.getClassStruct(); + + // hide values() and valueOf() + for(StructMethod meth : cl.getMethods()) { + + String name = meth.getName(); + int flag = 0; + + if("values".equals(name)) { + flag = 1; + } else if("valueOf".equals(name)) { + flag = 2; + } + + if(flag>0) { + String[] arr = meth.getDescriptor().split("[()]"); + String par = arr[1]; + + if((flag == 1 && par.length() == 0) || + flag == 2 && "Ljava/lang/String;".equals(par)) { + wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(name, meth.getDescriptor())); + } + } + } + + // hide all super invocations + for(MethodWrapper meth : wrapper.getMethods()) { + if("".equals(meth.methodStruct.getName())) { + Statement firstdata = findFirstData(meth.root); + if(firstdata == null || firstdata.getExprents().isEmpty()) { + return; + } + + Exprent exprent = firstdata.getExprents().get(0); + if(exprent.type == Exprent.EXPRENT_INVOCATION) { + InvocationExprent invexpr = (InvocationExprent)exprent; + if(isInvocationSuperConstructor(invexpr, meth, wrapper)) { + firstdata.getExprents().remove(0); + } + } + } + } + + // hide dummy synthetic fields of enum constants + for(StructField fd: cl.getFields()) { + if((fd.access_flags & CodeConstants.ACC_ENUM) != 0) { + Exprent initializer = wrapper.getStaticFieldInitializers().getWithKey(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor())); + if(initializer != null && initializer.type == Exprent.EXPRENT_NEW) { + NewExprent nexpr = (NewExprent)initializer; + if(nexpr.isAnonymous()) { + ClassNode child = DecompilerContext.getClassprocessor().getMapRootClasses().get(nexpr.getNewtype().value); + hideDummyFieldInConstant(child.wrapper); + } + } + } + } + + + + } + + private static void hideDummyFieldInConstant(ClassWrapper wrapper) { + + StructClass cl = wrapper.getClassStruct(); + for(StructField fd: cl.getFields()) { + if((fd.access_flags & CodeConstants.ACC_SYNTHETIC) != 0) { + FieldDescriptor descr = FieldDescriptor.parseDescriptor(fd.getDescriptor()); + VarType ret = descr.type; + + if(ret.type == CodeConstants.TYPE_OBJECT && ret.arraydim == 1 && cl.qualifiedName.equals(ret.value)) { + wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor())); + } + } + } + + } + + // FIXME: move to a util class (see also InitializerProcessor) + private static Statement findFirstData(Statement stat) { + + if(stat.getExprents() != null) { + return stat; + } else { + if(stat.isLabeled()) { + return null; + } + + switch(stat.type) { + case Statement.TYPE_SEQUENCE: + case Statement.TYPE_IF: + case Statement.TYPE_ROOT: + case Statement.TYPE_SWITCH: + case Statement.TYPE_SYNCRONIZED: + return findFirstData(stat.getFirst()); + default: + return null; + } + } + } + + // FIXME: move to util class (see also InitializerProcessor) + private static boolean isInvocationSuperConstructor(InvocationExprent inv, MethodWrapper meth, ClassWrapper wrapper) { + + if(inv.getFunctype() == InvocationExprent.TYP_INIT) { + if(inv.getInstance().type == Exprent.EXPRENT_VAR) { + VarExprent instvar = (VarExprent)inv.getInstance(); + VarVersionPaar varpaar = new VarVersionPaar(instvar); + + String classname = meth.varproc.getThisvars().get(varpaar); + + if(classname!=null) { // any this instance. TODO: Restrict to current class? + if(!wrapper.getClassStruct().qualifiedName.equals(inv.getClassname())) { + return true; + } + } + } + } + + return false; + } + +} diff --git a/src/org/jetbrains/java/decompiler/main/Fernflower.java b/src/org/jetbrains/java/decompiler/main/Fernflower.java new file mode 100644 index 0000000..021ab1a --- /dev/null +++ b/src/org/jetbrains/java/decompiler/main/Fernflower.java @@ -0,0 +1,110 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.main; + +import java.io.BufferedWriter; +import java.io.StringWriter; +import java.util.HashMap; + +import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; +import org.jetbrains.java.decompiler.main.collectors.CounterContainer; +import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider; +import org.jetbrains.java.decompiler.main.extern.IDecompilatSaver; +import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; +import org.jetbrains.java.decompiler.modules.renamer.IdentifierConverter; +import org.jetbrains.java.decompiler.struct.IDecompiledData; +import org.jetbrains.java.decompiler.struct.StructClass; +import org.jetbrains.java.decompiler.struct.StructContext; +import org.jetbrains.java.decompiler.struct.lazy.LazyLoader; + + +public class Fernflower implements IDecompiledData { + + public static final String version = "v0.8.4"; + + private StructContext structcontext; + + private ClassesProcessor clprocessor; + + public Fernflower(IBytecodeProvider provider, IDecompilatSaver saver, + HashMap propertiesCustom) { + + StructContext context = new StructContext(saver, this, new LazyLoader(provider)); + + structcontext = context; + + DecompilerContext.initContext(propertiesCustom); + DecompilerContext.setCountercontainer(new CounterContainer()); + + } + + public void decompileContext() { + + if(DecompilerContext.getOption(IFernflowerPreferences.RENAME_ENTITIES)) { + IdentifierConverter ren = new IdentifierConverter(); + ren.rename(structcontext); + ren = null; + } + + clprocessor = new ClassesProcessor(structcontext); + + DecompilerContext.setClassprocessor(clprocessor); + DecompilerContext.setStructcontext(structcontext); + + structcontext.saveContext(); + } + + public void clearContext() { + DecompilerContext.setCurrentContext(null); + } + + public String getClassEntryName(StructClass cl, String entryname) { + + ClassNode node = clprocessor.getMapRootClasses().get(cl.qualifiedName); + if(node.type != ClassNode.CLASS_ROOT) { + return null; + } else { + if(DecompilerContext.getOption(IFernflowerPreferences.RENAME_ENTITIES)) { + String simple_classname = cl.qualifiedName.substring(cl.qualifiedName.lastIndexOf('/')+1); + return entryname.substring(0, entryname.lastIndexOf('/')+1)+simple_classname+".java"; + } else { + return entryname.substring(0, entryname.lastIndexOf(".class"))+".java"; + } + } + } + + public StructContext getStructcontext() { + return structcontext; + } + + public String getClassContent(StructClass cl) { + + String res = null; + + try { + StringWriter strwriter = new StringWriter(); + clprocessor.writeClass(structcontext, cl, new BufferedWriter(strwriter)); + + res = strwriter.toString(); + } catch(ThreadDeath ex) { + throw ex; + } catch(Throwable ex) { + DecompilerContext.getLogger().writeMessage("Class "+cl.qualifiedName+" couldn't be fully decompiled.", ex); + } + + return res; + } + +} diff --git a/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java b/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java new file mode 100644 index 0000000..ff6233c --- /dev/null +++ b/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java @@ -0,0 +1,321 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.main; + +import java.util.ArrayList; +import java.util.List; + +import org.jetbrains.java.decompiler.code.CodeConstants; +import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; +import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; +import org.jetbrains.java.decompiler.main.rels.ClassWrapper; +import org.jetbrains.java.decompiler.main.rels.MethodWrapper; +import org.jetbrains.java.decompiler.modules.decompiler.exps.AssignmentExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.FieldExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.InvocationExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; +import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; +import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; +import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPaar; +import org.jetbrains.java.decompiler.struct.StructClass; +import org.jetbrains.java.decompiler.struct.StructField; +import org.jetbrains.java.decompiler.util.InterpreterUtil; + + +public class InitializerProcessor { + + public static void extractInitializers(ClassWrapper wrapper) { + + MethodWrapper meth = wrapper.getMethodWrapper("", "()V"); + if(meth != null && meth.root != null) { // successfully decompiled static constructor + extractStaticInitializers(wrapper, meth); + } + + extractDynamicInitializers(wrapper); + + // required e.g. if anonymous class is being decompiled as a standard one. + // This can happen if InnerClasses attributes are erased + liftConstructor(wrapper); + + if(DecompilerContext.getOption(IFernflowerPreferences.HIDE_EMPTY_SUPER)) { + hideEmptySuper(wrapper); + } + } + + + private static void liftConstructor(ClassWrapper wrapper) { + + for(MethodWrapper meth : wrapper.getMethods()) { + if("".equals(meth.methodStruct.getName()) && meth.root != null) { + Statement firstdata = findFirstData(meth.root); + if(firstdata == null) { + return; + } + + + int index = 0; + List lstExprents = firstdata.getExprents(); + + for(Exprent exprent : lstExprents) { + + int action = 0; + + if(exprent.type == Exprent.EXPRENT_ASSIGNMENT) { + AssignmentExprent asexpr = (AssignmentExprent)exprent; + if(asexpr.getLeft().type == Exprent.EXPRENT_FIELD && asexpr.getRight().type == Exprent.EXPRENT_VAR) { + FieldExprent fexpr = (FieldExprent)asexpr.getLeft(); + if(fexpr.getClassname().equals(wrapper.getClassStruct().qualifiedName)) { + StructField structField = wrapper.getClassStruct().getField(fexpr.getName(), fexpr.getDescriptor().descriptorString); + if(structField != null && (structField.access_flags & CodeConstants.ACC_FINAL) != 0) { + action = 1; + } + } + } + } else if(index > 0 && exprent.type == Exprent.EXPRENT_INVOCATION && + isInvocationInitConstructor((InvocationExprent)exprent, meth, wrapper, true)) { + // this() or super() + lstExprents.add(0, lstExprents.remove(index)); + action = 2; + } + + if(action != 1) { + break; + } + + index++; + } + } + } + } + + + private static void hideEmptySuper(ClassWrapper wrapper) { + + for(MethodWrapper meth : wrapper.getMethods()) { + if("".equals(meth.methodStruct.getName()) && meth.root != null) { + Statement firstdata = findFirstData(meth.root); + if(firstdata == null || firstdata.getExprents().isEmpty()) { + return; + } + + Exprent exprent = firstdata.getExprents().get(0); + if(exprent.type == Exprent.EXPRENT_INVOCATION) { + InvocationExprent invexpr = (InvocationExprent)exprent; + if(isInvocationInitConstructor(invexpr, meth, wrapper, false) && invexpr.getLstParameters().isEmpty()) { + firstdata.getExprents().remove(0); + } + } + } + } + } + + private static void extractStaticInitializers(ClassWrapper wrapper, MethodWrapper meth) { + + RootStatement root = meth.root; + StructClass cl = wrapper.getClassStruct(); + + Statement firstdata = findFirstData(root); + if(firstdata != null) { + while(!firstdata.getExprents().isEmpty()) { + Exprent exprent = firstdata.getExprents().get(0); + + boolean found = false; + + if(exprent.type == Exprent.EXPRENT_ASSIGNMENT) { + AssignmentExprent asexpr = (AssignmentExprent)exprent; + if(asexpr.getLeft().type == Exprent.EXPRENT_FIELD) { + FieldExprent fexpr = (FieldExprent)asexpr.getLeft(); + if(fexpr.isStatic() && fexpr.getClassname().equals(cl.qualifiedName) && + cl.hasField(fexpr.getName(), fexpr.getDescriptor().descriptorString)) { + + if(isExprentIndependent(asexpr.getRight(), meth)) { + + String keyField = InterpreterUtil.makeUniqueKey(fexpr.getName(), fexpr.getDescriptor().descriptorString); + if(!wrapper.getStaticFieldInitializers().containsKey(keyField)) { + wrapper.getStaticFieldInitializers().addWithKey(asexpr.getRight(), keyField); + firstdata.getExprents().remove(0); + found = true; + } + } + } + } + } + + if(!found) { + break; + } + } + } + } + + private static void extractDynamicInitializers(ClassWrapper wrapper) { + + StructClass cl = wrapper.getClassStruct(); + + boolean isAnonymous = DecompilerContext.getClassprocessor().getMapRootClasses().get(cl.qualifiedName).type == ClassNode.CLASS_ANONYMOUS; + + List> lstFirst = new ArrayList>(); + List lstMethWrappers = new ArrayList(); + + for(MethodWrapper meth : wrapper.getMethods()) { + if("".equals(meth.methodStruct.getName()) && meth.root != null) { // successfully decompiled constructor + Statement firstdata = findFirstData(meth.root); + if(firstdata == null || firstdata.getExprents().isEmpty()) { + return; + } + lstFirst.add(firstdata.getExprents()); + lstMethWrappers.add(meth); + + Exprent exprent = firstdata.getExprents().get(0); + if(!isAnonymous) { // FIXME: doesn't make sense + if(exprent.type != Exprent.EXPRENT_INVOCATION || !isInvocationInitConstructor((InvocationExprent)exprent, meth, wrapper, false)) { + return; + } + } + } + } + + if(lstFirst.isEmpty()) { + return; + } + + for(;;) { + + String fieldWithDescr = null; + Exprent value = null; + + for(int i=0; i lst = lstFirst.get(i); + + if(lst.size() < (isAnonymous?1:2)) { + return; + } + + Exprent exprent = lst.get(isAnonymous?0:1); + + boolean found = false; + + if(exprent.type == Exprent.EXPRENT_ASSIGNMENT) { + AssignmentExprent asexpr = (AssignmentExprent)exprent; + if(asexpr.getLeft().type == Exprent.EXPRENT_FIELD) { + FieldExprent fexpr = (FieldExprent)asexpr.getLeft(); + if(!fexpr.isStatic() && fexpr.getClassname().equals(cl.qualifiedName) && + cl.hasField(fexpr.getName(), fexpr.getDescriptor().descriptorString)) { // check for the physical existence of the field. Could be defined in a superclass. + + if(isExprentIndependent(asexpr.getRight(), lstMethWrappers.get(i))) { + String fieldKey = InterpreterUtil.makeUniqueKey(fexpr.getName(), fexpr.getDescriptor().descriptorString); + if(fieldWithDescr == null) { + fieldWithDescr = fieldKey; + value = asexpr.getRight(); + } else { + if(!fieldWithDescr.equals(fieldKey) || + !value.equals(asexpr.getRight())) { + return; + } + } + found = true; + } + } + } + } + + if(!found) { + return; + } + } + + if(!wrapper.getDynamicFieldInitializers().containsKey(fieldWithDescr)) { + wrapper.getDynamicFieldInitializers().addWithKey(value, fieldWithDescr); + + for(List lst : lstFirst) { + lst.remove(isAnonymous?0:1); + } + } else { + return; + } + } + + } + + private static boolean isExprentIndependent(Exprent exprent, MethodWrapper meth) { + + List lst = exprent.getAllExprents(true); + lst.add(exprent); + + for(Exprent expr : lst) { + switch(expr.type) { + case Exprent.EXPRENT_VAR: + VarVersionPaar varpaar = new VarVersionPaar((VarExprent)expr); + if(!meth.varproc.getExternvars().contains(varpaar)) { + String varname = meth.varproc.getVarName(varpaar); + + if(!varname.equals("this") && !varname.endsWith(".this")) { // FIXME: remove direct comparison with strings + return false; + } + } + break; + case Exprent.EXPRENT_FIELD: + return false; + } + } + + return true; + } + + + private static Statement findFirstData(Statement stat) { + + if(stat.getExprents() != null) { + return stat; + } else { + if(stat.isLabeled()) { // FIXME: Why?? + return null; + } + + switch(stat.type) { + case Statement.TYPE_SEQUENCE: + case Statement.TYPE_IF: + case Statement.TYPE_ROOT: + case Statement.TYPE_SWITCH: + case Statement.TYPE_SYNCRONIZED: + return findFirstData(stat.getFirst()); + default: + return null; + } + } + } + + private static boolean isInvocationInitConstructor(InvocationExprent inv, MethodWrapper meth, ClassWrapper wrapper, boolean withThis) { + + if(inv.getFunctype() == InvocationExprent.TYP_INIT) { + if(inv.getInstance().type == Exprent.EXPRENT_VAR) { + VarExprent instvar = (VarExprent)inv.getInstance(); + VarVersionPaar varpaar = new VarVersionPaar(instvar); + + String classname = meth.varproc.getThisvars().get(varpaar); + + if(classname!=null) { // any this instance. TODO: Restrict to current class? + if(withThis || !wrapper.getClassStruct().qualifiedName.equals(inv.getClassname())) { + return true; + } + } + } + } + + return false; + } +} diff --git a/src/org/jetbrains/java/decompiler/main/collectors/CounterContainer.java b/src/org/jetbrains/java/decompiler/main/collectors/CounterContainer.java new file mode 100644 index 0000000..dcc1968 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/main/collectors/CounterContainer.java @@ -0,0 +1,37 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.main.collectors; + +public class CounterContainer { + + public static final int STATEMENT_COUNTER = 0; + public static final int EXPRENT_COUNTER = 1; + public static final int VAR_COUNTER = 2; + + private int[] values = new int[]{1, 1, 1}; + + public void setCounter(int counter, int value) { + values[counter] = value; + } + + public int getCounter(int counter) { + return values[counter]; + } + + public int getCounterAndIncrement(int counter) { + return values[counter]++; + } + +} diff --git a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java new file mode 100644 index 0000000..cdc6529 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java @@ -0,0 +1,157 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.main.collectors; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map.Entry; + +import org.jetbrains.java.decompiler.main.ClassesProcessor; +import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; +import org.jetbrains.java.decompiler.struct.StructContext; + + +public class ImportCollector { + + private static final String JAVA_LANG_PACKAGE = "java.lang"; + + private HashMap mapSimpleNames = new HashMap(); + + private HashSet setNotImportedNames = new HashSet(); + + private String currentPackageSlash = ""; + + private String currentPackagePoint = ""; + + public ImportCollector(ClassNode root) { + + String clname = root.classStruct.qualifiedName; + int index = clname.lastIndexOf("/"); + if(index >= 0) { + currentPackageSlash = clname.substring(0, index); + currentPackagePoint = currentPackageSlash.replace('/', '.'); + currentPackageSlash += "/"; + } + } + + public String getShortName(String fullname) { + return getShortName(fullname, true); + } + + public String getShortName(String fullname, boolean imported) { + + ClassesProcessor clproc = DecompilerContext.getClassprocessor(); + ClassNode node = clproc.getMapRootClasses().get(fullname.replace('.', '/')); + + String retname = null; + + if(node != null && node.classStruct.isOwn()) { + + retname = node.simpleName; + + while(node.parent != null && node.type == ClassNode.CLASS_MEMBER) { + retname = node.parent.simpleName+"."+retname; + node = node.parent; + } + + if(node.type == ClassNode.CLASS_ROOT) { + fullname = node.classStruct.qualifiedName; + fullname = fullname.replace('/', '.'); + } else { + return retname; + } + + } else if(node == null || !node.classStruct.isOwn()) { + fullname = fullname.replace('$', '.'); + } + + String nshort = fullname; + String npackage = ""; + + int lastpoint = fullname.lastIndexOf("."); + + if(lastpoint >= 0) { + nshort = fullname.substring(lastpoint+1); + npackage = fullname.substring(0, lastpoint); + } + + StructContext context = DecompilerContext.getStructcontext(); + + boolean existsDefaultClass = (context.getClass(currentPackageSlash+nshort) != null + && !npackage.equals(currentPackagePoint)) // current package + || (context.getClass(nshort) != null); // default package + + if(existsDefaultClass || + (mapSimpleNames.containsKey(nshort) && !npackage.equals(mapSimpleNames.get(nshort)))) { + return fullname; + } else if(!mapSimpleNames.containsKey(nshort)) { + mapSimpleNames.put(nshort, npackage); + + if(!imported) { + setNotImportedNames.add(nshort); + } + } + + return retname==null?nshort:retname; + } + + public void writeImports(BufferedWriter writer) throws IOException { + + for(String s: packImports()) { + writer.write("import "); + writer.write(s); + writer.write(";"); + writer.write(DecompilerContext.getNewLineSeparator()); + } + + } + + private List packImports() { + + List> lst = new ArrayList>(mapSimpleNames.entrySet()); + + Collections.sort(lst, new Comparator>() { + public int compare(Entry par0, Entry par1) { + int res = par0.getValue().compareTo(par1.getValue()); + if(res == 0) { + res = par0.getKey().compareTo(par1.getKey()); + } + return res; + } + }); + + List res = new ArrayList(); + for(Entry ent: lst) { + if(!setNotImportedNames.contains(ent.getKey()) // not the current class or one of the nested ones. Also not the empty package. + && !JAVA_LANG_PACKAGE.equals(ent.getValue()) + && ent.getValue().length() > 0) { + + String imp = ent.getValue()+"."+ent.getKey(); + res.add(imp); + } + } + + return res; + } + + +} diff --git a/src/org/jetbrains/java/decompiler/main/collectors/VarNamesCollector.java b/src/org/jetbrains/java/decompiler/main/collectors/VarNamesCollector.java new file mode 100644 index 0000000..5fd33c0 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/main/collectors/VarNamesCollector.java @@ -0,0 +1,50 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.main.collectors; + +import java.util.HashSet; + +public class VarNamesCollector { + + private HashSet usedNames = new HashSet(); + + public VarNamesCollector() {} + + public VarNamesCollector(HashSet setNames) { + usedNames.addAll(setNames); + } + + public void addName(String value) { + usedNames.add(value); + } + + public String getFreeName(int index) { + return getFreeName("var"+index); + } + + public String getFreeName(String proposition) { + + while(usedNames.contains(proposition)) { + proposition+="x"; + } + usedNames.add(proposition); + return proposition; + } + + public HashSet getUsedNames() { + return usedNames; + } + +} diff --git a/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java b/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java new file mode 100644 index 0000000..408c430 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java @@ -0,0 +1,323 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.main.decompiler; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.main.Fernflower; +import org.jetbrains.java.decompiler.main.decompiler.helper.PrintStreamLogger; +import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider; +import org.jetbrains.java.decompiler.main.extern.IDecompilatSaver; +import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; +import org.jetbrains.java.decompiler.util.InterpreterUtil; + + +public class ConsoleDecompiler implements IBytecodeProvider, IDecompilatSaver { + + private File root; + + private Fernflower fernflower; + + private HashMap mapArchiveStreams = new HashMap(); + + private HashMap> mapArchiveEntries = new HashMap>(); + + public ConsoleDecompiler() { + this(null); + } + + public ConsoleDecompiler(HashMap propertiesCustom) { + this(new PrintStreamLogger(IFernflowerLogger.WARNING, System.out), propertiesCustom); + } + + protected ConsoleDecompiler(IFernflowerLogger logger, HashMap propertiesCustom) { + fernflower = new Fernflower(this, this, propertiesCustom); + DecompilerContext.setLogger(logger); + } + + public static void main(String[] args) { + + try { + + if(args != null && args.length > 1) { + + HashMap mapOptions = new HashMap(); + + List lstSources = new ArrayList(); + List lstLibraries = new ArrayList(); + + boolean isOption = true; + for(int i = 0; i < args.length - 1; ++i) { // last parameter - destination + String arg = args[i]; + + if(isOption && arg.startsWith("-") && + arg.length()>5 && arg.charAt(4) == '=') { + String value = arg.substring(5).toUpperCase(); + if("TRUE".equals(value)) { + value = "1"; + } else if("FALSE".equals(value)) { + value = "0"; + } + + mapOptions.put(arg.substring(1, 4), value); + } else { + isOption = false; + + if(arg.startsWith("-e=")) { + lstLibraries.add(arg.substring(3)); + } else { + lstSources.add(arg); + } + } + } + + if(lstSources.isEmpty()) { + printHelp(); + } else { + ConsoleDecompiler decompiler = new ConsoleDecompiler( + new PrintStreamLogger(IFernflowerLogger.INFO, System.out), + mapOptions); + + for(String source : lstSources) { + decompiler.addSpace(new File(source), true); + } + + for(String library : lstLibraries) { + decompiler.addSpace(new File(library), false); + } + + decompiler.decompileContext(new File(args[args.length-1])); + } + + } else { + printHelp(); + } + + } catch(Exception ex) { + ex.printStackTrace(); + } + + } + + private static void printHelp() { + System.out.println("Usage: java ConsoleDecompiler ( -