From 8928720baf2614366b0ba6704f6684bb06c2c905 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 28 Jul 2024 16:21:16 +0200 Subject: [PATCH 001/111] working module tactobc --- .../src/main/scala/org/opalj/tac/DUVar.scala | 4 +- OPAL/tactobc/build.sbt | 1 + .../scala/org/opalj/tactobc/ExprUtils.scala | 391 ++++++++++++++ .../org/opalj/tactobc/StmtProcessor.scala | 267 +++++++++ .../scala/org/opalj/tactobc/TACtoBC.scala | 509 ++++++++++++++++++ .../testingtactobc/HelloWorldToString.java | 28 + .../org/opalj/tactobc/HelloWorldToString.java | 28 + .../test/resources/HelloWorldToString.java | 27 + build.sbt | 37 ++ 9 files changed, 1290 insertions(+), 2 deletions(-) create mode 100644 OPAL/tactobc/build.sbt create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprUtils.scala create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorldToString.java create mode 100644 OPAL/tactobc/src/test/org/opalj/tactobc/HelloWorldToString.java create mode 100644 OPAL/tactobc/src/test/resources/HelloWorldToString.java diff --git a/OPAL/tac/src/main/scala/org/opalj/tac/DUVar.scala b/OPAL/tac/src/main/scala/org/opalj/tac/DUVar.scala index 81b2111708..8ef2f81955 100644 --- a/OPAL/tac/src/main/scala/org/opalj/tac/DUVar.scala +++ b/OPAL/tac/src/main/scala/org/opalj/tac/DUVar.scala @@ -110,7 +110,7 @@ object DefSites { * @param value The value information. */ class DVar[+Value <: ValueInformation /*org.opalj.ai.ValuesDomain#DomainValue*/ ] private ( - private[tac] var origin: ValueOrigin, + var origin: ValueOrigin, val value: Value, private[tac] var useSites: IntTrieSet ) extends DUVar[Value] { @@ -215,7 +215,7 @@ object DVar { class UVar[+Value <: ValueInformation /*org.opalj.ai.ValuesDomain#DomainValue*/ ] private ( val value: Value, - private[tac] var defSites: IntTrieSet + var defSites: IntTrieSet ) extends DUVar[Value] { def name: String = { diff --git a/OPAL/tactobc/build.sbt b/OPAL/tactobc/build.sbt new file mode 100644 index 0000000000..b511e98651 --- /dev/null +++ b/OPAL/tactobc/build.sbt @@ -0,0 +1 @@ +// build settings reside in the opal root build.sbt file diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprUtils.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprUtils.scala new file mode 100644 index 0000000000..fa2f99ea5d --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprUtils.scala @@ -0,0 +1,391 @@ +/* BSD 2-Clause License - see OPAL/LICENSE for details. */ +package org.opalj.tactobc + +import org.opalj.BinaryArithmeticOperators.{Add, And, Divide, Modulo, Multiply, Or, ShiftLeft, ShiftRight, Subtract, UnsignedShiftRight, XOr} +import org.opalj.br.{ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, ObjectType} +import org.opalj.br.instructions.{ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BIPUSH, DADD, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, FADD, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, IADD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, LADD, LAND, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, NEW, SIPUSH} +import org.opalj.bytecode.BytecodeProcessingFailedException +import org.opalj.collection.immutable.IntTrieSet +import org.opalj.tac.{BinaryExpr, ClassConst, Const, DUVar, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, LongConst, MethodHandleConst, MethodTypeConst, New, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} + +import scala.collection.mutable +import scala.collection.mutable.ArrayBuffer + +object ExprUtils { + + + def processExpression(expr: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + expr match { + case const: Const => loadConstant(const, instructionsWithPCs, currentPC) + case variable: Var[_] => loadVariable(variable, instructionsWithPCs, currentPC) + case fieldExpr: Expr[_] if fieldExpr.isInstanceOf[GetField[_]] || fieldExpr.isInstanceOf[GetStatic] => handleFieldAccess(fieldExpr, instructionsWithPCs, currentPC) + case binaryExpr: BinaryExpr[_] => handleBinaryExpr(binaryExpr, instructionsWithPCs, currentPC) + case virtualFunctionCallExpr: VirtualFunctionCall[_] => handleVirtualFunctionCall(virtualFunctionCallExpr, instructionsWithPCs, currentPC) + case staticFunctionCallExpr: StaticFunctionCall[_] => handleStaticFunctionCall(staticFunctionCallExpr, instructionsWithPCs, currentPC) + case newExpr: New => handleNewExpr(newExpr.tpe, instructionsWithPCs, currentPC) + case _ => + throw new UnsupportedOperationException("Unsupported expression type" + expr) + } + } + + def collectFromExpr(expr: Expr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + expr match { + case duVar: DUVar[_] => duVars += duVar + case binaryExpr: BinaryExpr[_] => collectFromBinaryExpr(binaryExpr, duVars) + case virtualFunctionCallExpr: VirtualFunctionCall[_] => collectFromVirtualMethodCall(virtualFunctionCallExpr, duVars) + case staticFunctionCallExpr: StaticFunctionCall[_] => collectFromStaticFunctionCall(staticFunctionCallExpr, duVars) + case _ => + } + } + + def collectFromStaticFunctionCall(staticFunctionCallExpr: StaticFunctionCall[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + // Process each parameter and collect from each + for (param <- staticFunctionCallExpr.params) { + collectFromExpr(param, duVars) + } + } + + def collectFromBinaryExpr(binaryExpr: BinaryExpr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectFromExpr(binaryExpr.left, duVars) + collectFromExpr(binaryExpr.right, duVars) + } + + def collectFromVirtualMethodCall(virtualFunctionCallExpr: VirtualFunctionCall[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectFromExpr(virtualFunctionCallExpr.receiver, duVars) + for (param <- virtualFunctionCallExpr.params) { + collectFromExpr(param, duVars) + } + } + + def handleNewExpr(tpe: ObjectType, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + val instruction = NEW(tpe) + instructionsWithPCs += ((currentPC, instruction)) + currentPC + instruction.length + } + + def handleStaticFunctionCall(expr: StaticFunctionCall[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // Initialize the PC after processing the receiver + var currentAfterParamsPC = currentPC + + // Process each parameter and update the PC accordingly + for (param <- expr.params) { + currentAfterParamsPC = ExprUtils.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + } + val instruction = if (expr.isInterface) { + INVOKEINTERFACE(expr.declaringClass, expr.name, expr.descriptor) + throw new UnsupportedOperationException("Unsupported expression type" + expr) + } else { + INVOKESTATIC(expr.declaringClass, expr.isInterface, expr.name, expr.descriptor) + } + + instructionsWithPCs += ((currentAfterParamsPC, instruction)) + currentAfterParamsPC + instruction.length + } + + def handleVirtualFunctionCall(expr: VirtualFunctionCall[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // Process the receiver object (e.g., aload_0 for `this`) + val afterReceiverPC = ExprUtils.processExpression(expr.receiver, instructionsWithPCs, currentPC) + + // Initialize the PC after processing the receiver + var currentAfterParamsPC = afterReceiverPC + + // Process each parameter and update the PC accordingly + for (param <- expr.params) { + currentAfterParamsPC = ExprUtils.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + } + val instruction = if (expr.isInterface) { + //INVOKEINTERFACE(expr.declaringClass, expr.name, expr.descriptor) + throw new UnsupportedOperationException("Unsupported expression type" + expr) + } else { + INVOKEVIRTUAL(expr.declaringClass, expr.name, expr.descriptor) + } + + instructionsWithPCs += ((currentAfterParamsPC, instruction)) + currentAfterParamsPC + instruction.length + } + + private def loadConstant(constExpr: Const, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + val instruction = constExpr match { + case IntConst(_, value) => value match { + case -1 => ICONST_M1 + case 0 => ICONST_0 + case 1 => ICONST_1 + case 2 => ICONST_2 + case 3 => ICONST_3 + case 4 => ICONST_4 + case 5 => ICONST_5 + case _ if value >= Byte.MinValue && value <= Byte.MaxValue => BIPUSH(value) + case _ if value >= Short.MinValue && value <= Short.MaxValue => SIPUSH(value) + case _ => LoadInt(value) + } + case FloatConst(_, value) => value match { + case 0 => FCONST_0 + case 1 => FCONST_1 + case 2 => FCONST_2 + case _ => LoadFloat(value) + } + case ClassConst(_, value) => LoadClass(value) + case StringConst(_, value) => LoadString(value) + case MethodHandleConst(_, value) => LoadMethodHandle(value) + case MethodTypeConst(_, value) => LoadMethodType(value) + case DoubleConst(_, value) => value match { + case 0 => DCONST_0 + case 1 => DCONST_1 + case _ => LoadDouble(value) + } + case LongConst(_, value) => value match { + case 0 => LCONST_0 + case 1 => LCONST_1 + case _ => LoadLong(value) + } + //todo: figure out how and what LoadDynamic is + //I think LDCDynamic is not an actual Instruction. + /*case Assignment(_, _, DynamicConst(_, bootstrapMethod, name, descriptor)) => + val instruction = LoadDynamic(-1, bootstrapMethod, name, descriptor) + instructionsWithPCs += ((currentPC, instruction)) + currentPC += instruction.length*/ + case _ => + //todo: check that this is the right exception to throw + throw BytecodeProcessingFailedException( + "unsupported constant value: " + constExpr + ) + } + instructionsWithPCs += ((currentPC, instruction)) + currentPC + instruction.length // Update and return the new program counter + } + + var uvarToLVIndex = mutable.Map[IntTrieSet, Int]() + var nextLVIndex = 1 + + def collectAllUVarsAndPopulate(duVars: mutable.ListBuffer[DUVar[_]]): mutable.Map[IntTrieSet, Int] = { + duVars.toArray.foreach { + case uVar : UVar[_] => populateUvarAndDvarToLVIndexMap(uVar) + case _ => + } + uvarToLVIndex + } + + def mapParametersAndPopulate(duVars: mutable.ListBuffer[DUVar[_]]): mutable.Map[IntTrieSet, Int] = { + duVars.foreach { + case uVar: UVar[_] if uVar.defSites.exists(origin => origin < 0) => + // Check if the defSites contain a parameter origin + uVar.defSites.foreach { origin => + if (origin == -1) { + // Assign LV index 0 for 'this' only for instance methods + uvarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) + } else if (origin < -1) { + if (origin == -2) { + // Assign LV index 0 for 'this' only for instance methods + uvarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) + } else { + // Assign LV indexes for parameters + uvarToLVIndex.getOrElseUpdate(IntTrieSet(origin), { + val lvIndex = nextLVIndex + nextLVIndex += 1 + lvIndex + }) + } + } + } + case _ => + } + uvarToLVIndex + } + + def populateUvarAndDvarToLVIndexMap(uVar: UVar[_]): Unit = { + // Check if any existing key contains any of the def-sites + val existingEntry = uvarToLVIndex.find { case (key, _) => key.intersect(uVar.defSites).nonEmpty } + existingEntry match { + case Some((existingDefSites, index)) => + // Merge the def-sites and update the map + val mergedDefSites = existingDefSites ++ uVar.defSites + uvarToLVIndex -= existingDefSites + uvarToLVIndex(mergedDefSites) = index + case None => + // No overlapping def-sites found, add a new entry + uvarToLVIndex.getOrElseUpdate(uVar.defSites, { + val lvIndex = nextLVIndex + nextLVIndex += 1 + lvIndex + }) + } + } + + // Method to get LVIndex for a variable + def getVariableLvlIndex(variable: Var[_]): Int = { + variable match { + case dVar: DVar[_] => + val uVarDefSites = uvarToLVIndex.find { case (defSites, _) => defSites.contains(dVar.origin) } + uVarDefSites match { + case Some((_, index)) => index + case None => throw new NoSuchElementException(s"No LVIndex found for DVar with origin ${dVar.origin}") + } + case uVar: UVar[_] => + val defSiteMatch = uvarToLVIndex.find { case (defSites, _) => defSites.exists(uVar.defSites.contains) } + defSiteMatch match { + case Some((_, index)) => index + case None => throw new NoSuchElementException(s"No LVIndex found for UVar with defSites ${uVar.defSites}") + } + case _ => throw new UnsupportedOperationException("Unsupported variable type") + } + } + + def loadVariable(variable: Var[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + val index = getVariableLvlIndex(variable) + val instruction = variable.cTpe match { + case ComputationalTypeInt => index match { + case 0 => ILOAD_0 + case 1 => ILOAD_1 + case 2 => ILOAD_2 + case 3 => ILOAD_3 + case _ => ILOAD(index) + } + case ComputationalTypeFloat => index match { + case 0 => FLOAD_0 + case 1 => FLOAD_1 + case 2 => FLOAD_2 + case 3 => FLOAD_3 + case _ => FLOAD(index) + } + case ComputationalTypeDouble => index match { + case 0 => DLOAD_0 + case 1 => DLOAD_1 + case 2 => DLOAD_2 + case 3 => DLOAD_3 + case _ => DLOAD(index) + } + case ComputationalTypeLong => index match { + case 0 => LLOAD_0 + case 1 => LLOAD_1 + case 2 => LLOAD_2 + case 3 => LLOAD_3 + case _ => LLOAD(index) + } + case ComputationalTypeReference => index match { + case 0 => ALOAD_0 + case 1 => ALOAD_1 + case 2 => ALOAD_2 + case 3 => ALOAD_3 + case _ => ALOAD(index) + } + case _ => throw new UnsupportedOperationException("Unsupported computational type for loading variable" + variable) + } + instructionsWithPCs += ((currentPC, instruction)) + currentPC + (if (index < 4) 1 else 2) + } + + def storeVariable(variable: Var[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + //val variableName = handleDVarName(variable) + val index = getVariableLvlIndex(variable) + val storeInstruction = variable.cTpe match { + case ComputationalTypeInt => index match { + //The must be an index into the local variable array of the current frame (ยง2.6). + // The value on the top of the operand stack must be of type int. It is popped from the operand stack, and the value of the local variable at is set to value. + case 0 => ISTORE_0 + case 1 => ISTORE_1 + case 2 => ISTORE_2 + case 3 => ISTORE_3 + case _ => ISTORE(index) + } + case ComputationalTypeFloat => index match { + case 0 => FSTORE_0 + case 1 => FSTORE_1 + case 2 => FSTORE_2 + case 3 => FSTORE_3 + case _ => FSTORE(index) + } + case ComputationalTypeDouble => index match { + case 0 => DSTORE_0 + case 1 => DSTORE_1 + case 2 => DSTORE_2 + case 3 => DSTORE_3 + case _ => DSTORE(index) + } + case ComputationalTypeLong => index match { + case 0 => LSTORE_0 + case 1 => LSTORE_1 + case 2 => LSTORE_2 + case 3 => LSTORE_3 + case _ => LSTORE(index) + } + case ComputationalTypeReference => index match { + case 0 => ASTORE_0 + case 1 => ASTORE_1 + case 2 => ASTORE_2 + case 3 => ASTORE_3 + case _ => ASTORE(index) + } + //todo: handle AASTORE + case _ => throw new UnsupportedOperationException("Unsupported computational type for storing variable" + variable) + } + instructionsWithPCs += ((currentPC, storeInstruction)) + currentPC + (if (index < 4) 1 else 2) + } + + def handleArrayStore(variable: Var[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + 1 + } + + private def handleFieldAccess(fieldExpr: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + val instruction = fieldExpr match { + case getFieldExpr: GetField[_] => + GETFIELD(getFieldExpr.declaringClass, getFieldExpr.name, getFieldExpr.declaredFieldType) + case getStaticExpr: GetStatic => + GETSTATIC(getStaticExpr.declaringClass, getStaticExpr.name, getStaticExpr.declaredFieldType) + case _ => throw new IllegalArgumentException("Expected a field access expression" + fieldExpr) + } + instructionsWithPCs += ((currentPC, instruction)) + currentPC + instruction.length // Update and return the new program counter + } + + def handleBinaryExpr(binaryExpr: BinaryExpr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // process the left expr and save the pc to give in the right expr processing + val leftPC = processExpression(binaryExpr.left, instructionsWithPCs, currentPC) + // process the right Expr + val rightPC = processExpression(binaryExpr.right, instructionsWithPCs, leftPC) + val (instruction, instructionLength) = (binaryExpr.cTpe, binaryExpr.op) match { + //Double + case (ComputationalTypeDouble, Add) => (DADD, DADD.length) + case (ComputationalTypeDouble, Subtract) => (DSUB, DSUB.length) + case (ComputationalTypeDouble, Multiply) => (DMUL, DMUL.length) + case (ComputationalTypeDouble, Divide) => (DDIV, DDIV.length) + case (ComputationalTypeDouble, Modulo) => (DREM, DREM.length) + //Todo figure out where and how to do with Negate + //Float + case (ComputationalTypeFloat, Add) => (FADD, FADD.length) + case (ComputationalTypeFloat, Subtract) => (FSUB, FSUB.length) + case (ComputationalTypeFloat, Multiply) => (FMUL, FMUL.length) + case (ComputationalTypeFloat, Divide) => (FDIV, FDIV.length) + case (ComputationalTypeFloat, Modulo) => (FREM, FREM.length) + //Int + case (ComputationalTypeInt, Add) => (IADD, IADD.length) + case (ComputationalTypeInt, Subtract) => (ISUB, ISUB.length) + case (ComputationalTypeInt, Multiply) => (IMUL, IMUL.length) + case (ComputationalTypeInt, Divide) => (IDIV, IDIV.length) + case (ComputationalTypeInt, Modulo) => (IREM, IREM.length) + case (ComputationalTypeInt, And) => (IAND, IAND.length) + case (ComputationalTypeInt, Or) => (IOR, IOR.length) + case (ComputationalTypeInt, ShiftLeft) => (ISHL, ISHL.length) + case (ComputationalTypeInt, ShiftRight) => (ISHR, ISHR.length) + case (ComputationalTypeInt, UnsignedShiftRight) => (IUSHR, IUSHR.length) + case (ComputationalTypeInt, XOr) => (IXOR, IXOR.length) + //Long + case (ComputationalTypeLong, Add) => (LADD, LADD.length) + case (ComputationalTypeLong, Subtract) => (LSUB, LSUB.length) + case (ComputationalTypeLong, Multiply) => (LMUL, LMUL.length) + case (ComputationalTypeLong, Divide) => (LDIV, LDIV.length) + case (ComputationalTypeLong, Modulo) => (LREM, LREM.length) + case (ComputationalTypeLong, And) => (LAND, LAND.length) + case (ComputationalTypeLong, Or) => (LOR, LOR.length) + case (ComputationalTypeLong, ShiftLeft) => (LSHL, LSHL.length) + case (ComputationalTypeLong, ShiftRight) => (LSHR, LSHR.length) + case (ComputationalTypeLong, UnsignedShiftRight) => (LUSHR, LUSHR.length) + case (ComputationalTypeLong, XOr) => (LXOR, LXOR.length) + //Unsupported + case _ => throw new UnsupportedOperationException("Unsupported operation or computational type in BinaryExpr" + binaryExpr) + } + val offsetPC = currentPC + (rightPC - currentPC) + instructionsWithPCs += ((offsetPC, instruction)) + offsetPC + instructionLength + } +} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala new file mode 100644 index 0000000000..eaf8adeb3d --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -0,0 +1,267 @@ +/* BSD 2-Clause License - see OPAL/LICENSE for details. */ +package org.opalj.tactobc + +import org.opalj.RelationalOperator +import org.opalj.RelationalOperators._ +import org.opalj.br.{BootstrapMethod, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, FieldType, MethodDescriptor, ObjectType, PCs, ReferenceType} +import org.opalj.br.instructions.{ARETURN, ATHROW, DRETURN, FRETURN, GOTO, IFNONNULL, IFNULL, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, PUTFIELD, PUTSTATIC, RET, RETURN, TABLESWITCH} +import org.opalj.collection.immutable.{IntIntPair, IntTrieSet} +import org.opalj.tac.{Expr, UVar, Var} + +import scala.collection.immutable.ArraySeq +import scala.collection.mutable.ArrayBuffer + +object StmtProcessor { + + //Assignment + def processAssignment(targetVar: Var[_], expr: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // Evaluate the RHS and update the PC accordingly + val afterExprPC = ExprUtils.processExpression(expr, instructionsWithPCs, currentPC) + // Store the result into the target variable and update the PC + val finalPC = ExprUtils.storeVariable(targetVar, instructionsWithPCs, afterExprPC) + // Return the updated PC + finalPC + } + + def processSwitch(defaultOffset: Int, index: Expr[_], npairs: ArraySeq[IntIntPair /*(Case Value, Jump Target)*/], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // Translate the index expression first + val afterExprPC = ExprUtils.processExpression(index, instructionsWithPCs, currentPC) + + // Prepare the bytecode pairs with placeholders for targets + val bCnpairs = prepareBCnpairs(npairs) + + if (isLookupSwitch(index)) { + // Add LOOKUPSWITCH instruction with placeholders for targets + val lookupswitchInstruction = LOOKUPSWITCH(defaultOffset, bCnpairs) + instructionsWithPCs += ((afterExprPC, lookupswitchInstruction)) + afterExprPC + lookupSwitchLength(bCnpairs.size, afterExprPC) + } else { + // Add TABLESWITCH instruction with placeholders for targets + val minValue = bCnpairs.minBy(_._1)._1 + val maxValue = bCnpairs.maxBy(_._1)._1 + val jumpTable = ArrayBuffer.fill(maxValue - minValue + 1)(-1) + + // Set the case values in the jump table + bCnpairs.foreach { case IntIntPair(caseValue, _) => + jumpTable(caseValue - minValue) = -1 + } + + val tableswitchInstruction = TABLESWITCH(defaultOffset, minValue, maxValue, jumpTable.to(ArraySeq)) + instructionsWithPCs += ((afterExprPC, tableswitchInstruction)) + afterExprPC + tableSwitchLength(minValue, maxValue, afterExprPC) + } + } + + def lookupSwitchLength(numPairs: Int, currentPC: Int): Int = { + // Opcode (1 byte) + padding (0-3 bytes) + default offset (4 bytes) + number of pairs (4 bytes) + pairs (8 bytes each) + val padding = (4 - (currentPC % 4)) % 4 + 1 + padding + 4 + 4 + (numPairs * 8) + } + + def tableSwitchLength(low: Int, high: Int, currentPC: Int): Int = { + // Opcode (1 byte) + padding (0-3 bytes) + default offset (4 bytes) + low value (4 bytes) + high value (4 bytes) + jump offsets (4 bytes each) + val padding = (4 - (currentPC % 4)) % 4 + val numOffsets = high - low + 1 + 1 + padding + 4 + 4 + 4 + (numOffsets * 4) + } + + def prepareBCnpairs(npairs: ArraySeq[IntIntPair]): ArraySeq[IntIntPair] = { + npairs.map { case IntIntPair(caseValue, _) => IntIntPair(caseValue, -1) } + } + + def isLookupSwitch(index: Expr[_]): Boolean = { + index match { + case variable: UVar[_] => variable.defSites.size == 1 + case _ => false + } + } + + def processReturn(instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + val instruction = RETURN + instructionsWithPCs += ((currentPC, instruction)) + currentPC + instruction.length + } + + def processReturnValue(expr: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + val afterExprPC = ExprUtils.processExpression(expr, instructionsWithPCs, currentPC) + val instruction = expr.cTpe match { + case ComputationalTypeInt => IRETURN + case ComputationalTypeLong => LRETURN + case ComputationalTypeFloat => FRETURN + case ComputationalTypeDouble => DRETURN + case ComputationalTypeReference => ARETURN + case _ => throw new UnsupportedOperationException("Unsupported computational type:" + expr.cTpe) + } + val offsetPC = currentPC + (afterExprPC - currentPC) + instructionsWithPCs += ((currentPC, instruction)) + currentPC + offsetPC + } + + def processVirtualMethodCall(declaringClass: ReferenceType, isInterface: Boolean, methodName: String, methodDescriptor: MethodDescriptor, receiver: Expr[_], params: Seq[Expr[_]], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // Process the receiver object (e.g., aload_0 for `this`) + val afterReceiverPC = ExprUtils.processExpression(receiver, instructionsWithPCs, currentPC) + + // Initialize the PC after processing the receiver + var currentAfterParamsPC = afterReceiverPC + + // Process each parameter and update the PC accordingly + for (param <- params) { + currentAfterParamsPC = ExprUtils.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + } + + val instruction = { /*if (isInterface) { + INVOKEINTERFACE + }else*/ + INVOKEVIRTUAL(declaringClass, methodName, methodDescriptor) + } + //val finalPC = currentPC + pcAfterLoadVariable + instructionsWithPCs += ((currentAfterParamsPC, instruction)) + currentAfterParamsPC + instruction.length + } + + def processArrayStore(arrayRef: Expr[_], index: Expr[_], value: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + //todo: handle this correctly + 1 + } + + def processInvokeDynamicMethodCall(bootstrapMethod: BootstrapMethod, name: String, descriptor: MethodDescriptor, params: Seq[Expr[_]]): Int = { + //todo: handle this correctly + 1 + } + + def processCheckCast(value: Expr[_], cmpTpe: ReferenceType, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + //todo: handle this correctly + 1 + } + + def processRet(returnAdresses: PCs, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + //todo: handle returnAdresses this correctly + val instruction = RET(returnAdresses.size) + instructionsWithPCs += ((currentPC, instruction)) + currentPC + instruction.length + } + + def processCaughtException(exceptionType: Option[ObjectType], throwingStmts: IntTrieSet, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + //todo: handle this correctly + 1 + } + + def processThrow(exception: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + //todo: handle this correctly + val instruction = ATHROW + instructionsWithPCs += ((currentPC, instruction)) + currentPC + 1 + } + + def processPutStatic(declaringClass: ObjectType, name: String, declaredFieldType: FieldType, value: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + //todo: look what to do with the value :) + val instruction = PUTSTATIC(declaringClass, name, declaredFieldType) + instructionsWithPCs += ((currentPC, instruction)) + currentPC + instruction.length + } + + def processPutField(declaringClass: ObjectType, name: String, declaredFieldType: FieldType, objRef: Expr[_], value: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + //todo: look what to do with the value AND the objRef :) + val instruction = PUTFIELD(declaringClass, name, declaredFieldType) + instructionsWithPCs += ((currentPC, instruction)) + currentPC + instruction.length + } + + def processMonitorEnter(objRef: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + //todo: look what to do with the objRef :) + val instruction = MONITORENTER + instructionsWithPCs += ((currentPC, instruction)) + currentPC + instruction.length + } + def processMonitorExit(objRef: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + //todo: look what to do with the objRef :) + val instruction = MONITOREXIT + instructionsWithPCs += ((currentPC, instruction)) + currentPC + instruction.length + } + + def processJSR(target: Int, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + //todo: look what to do with the target, how to get the length and if it is a jump instruction + //val instruction = JSR + //instructionsWithPCs += ((currentPC, instruction)) + currentPC + 1 + } + + def processNonVirtualMethodCall(declaringClass: ObjectType, isInterface: Boolean, methodName: String, methodDescriptor: MethodDescriptor, receiver: Expr[_], params: Seq[Expr[_]], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + val afterReceiverPC = ExprUtils.processExpression(receiver, instructionsWithPCs, currentPC) + + // Initialize the PC after processing the receiver + var currentAfterParamsPC = afterReceiverPC + + // Process each parameter and update the PC accordingly + for (param <- params) { + currentAfterParamsPC = ExprUtils.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + } + val instruction = INVOKESPECIAL(declaringClass, isInterface, methodName, methodDescriptor) + val finalPC = currentPC + currentAfterParamsPC + instructionsWithPCs += ((finalPC, instruction)) + finalPC + instruction.length + } + + def processStaticMethodCall(declaringClass: ObjectType, isInterface: Boolean, methodName: String, methodDescriptor: MethodDescriptor, params: Seq[Expr[_]], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // Initialize the PC after processing the receiver + var currentAfterParamsPC = currentPC + + // Process each parameter and update the PC accordingly + for (param <- params) { + currentAfterParamsPC = ExprUtils.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + } + val instruction = INVOKESTATIC(declaringClass, isInterface, methodName, methodDescriptor) + instructionsWithPCs += ((currentAfterParamsPC, instruction)) + currentAfterParamsPC + instruction.length + } + + def processGoto(instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + val instruction = GOTO(-1) + instructionsWithPCs += ((currentPC, instruction)) + val length = instruction.length + currentPC + length + } + + def processIf(left: Expr[_], condition: RelationalOperator, right: Expr[_], gotoLabel: Int, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // process the left expr and save the pc to give in the right expr processing + val leftPC = ExprUtils.processExpression(left, instructionsWithPCs, currentPC) + // process the right expr + val rightPC = ExprUtils.processExpression(right, instructionsWithPCs, leftPC) + generateIfInstruction(left, condition, right, instructionsWithPCs, currentPC, rightPC) + } + + def generateIfInstruction(left: Expr[_], condition: RelationalOperator, right: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int, rightPC: Int): Int = { + val instruction = (left, right) match { + case _ if right.isNullExpr || left.isNullExpr => + condition match { + case EQ => IFNULL(-1) + case NE => IFNONNULL(-1) + case _ => throw new UnsupportedOperationException(s"Unsupported condition: $condition") + } + case _ => + condition match { + case EQ => IF_ICMPEQ(-1) + case NE => IF_ICMPNE(-1) + case LT => IF_ICMPLT(-1) + case LE => IF_ICMPLE(-1) + case GT => IF_ICMPGT(-1) + case GE => IF_ICMPGE(-1) + case _ => throw new UnsupportedOperationException(s"Unsupported condition: $condition") + } + /*case EQ => IF_ACMPEQ(-1) + case NE => IF_ACMPNE(-1) + //Unsupported + case _ => IFNE(-1)//throw new UnsupportedOperationException(s"Unsupported condition: $condition")*/ + } + val offsetPC = { + if(rightPC > 0 && rightPC > currentPC){ + currentPC + (rightPC - currentPC) + } else { + currentPC + } + } + instructionsWithPCs += ((offsetPC, instruction)) + offsetPC + instruction.length + } +} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala new file mode 100644 index 0000000000..41627d4e8e --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala @@ -0,0 +1,509 @@ +/* BSD 2-Clause License - see OPAL/LICENSE for details. */ +package org.opalj.tac.tactobc + +import org.opalj.ba.CodeAttributeBuilder.computeStackMapTable +import org.opalj.ba.toDA +import org.opalj.bc.Assembler +import org.opalj.br.{ArrayType, Code, CompactLineNumberTable, LocalVariable, LocalVariableTable, Method, ObjectType, StackMapTable} +import org.opalj.br.analyses.Project +import org.opalj.br.instructions.{GOTO, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, Instruction, LOOKUPSWITCH, TABLESWITCH} +import org.opalj.br.reader.Java8Framework +import org.opalj.collection.immutable.{IntIntPair, IntTrieSet} +import org.opalj.da.ClassFileReader.ClassFile +import org.opalj.io.writeAndOpen +import org.opalj.util.InMemoryClassLoader + +import java.io.ByteArrayInputStream +import java.nio.file.{Files, Paths} +import org.opalj.tac._ +import org.opalj.tactobc.{ExprUtils, StmtProcessor} +import org.opalj.value.ValueInformation + +import java.io.File +import scala.Console.println +import scala.collection.immutable.ArraySeq +import scala.collection.mutable +import scala.collection.mutable.ArrayBuffer +import scala.jdk.CollectionConverters.EnumerationHasAsScala + +object TACtoBC { + + def main(args: Array[String]): Unit = { + if (args.length != 1) { + println("Usage: TACtoBC ") + return + } + + val file = new File(args(0)) + if (!file.exists()) { + println(s"File ${file.getPath} does not exist.") + return + } + //do this implicit val + val p = Project(file) + compileByteCode(file) + + val tacs = compileTAC(file) + + // Print out TAC + tacs.foreach { case (method, tac) => + tac.detach() + println(s"Method: ${method.toJava}") + println(tac.toString) + println("\n") + } + + // Print out the translation from TAC to Bytecode + val byteCodes = translateTACtoBC(tacs) + byteCodes.foreach { case (method, bytecode) => + println(s"Method: ${method.toJava}") + bytecode.foreach(instr => println(instr.toString)) + } + + val TheType = ObjectType("org/opalj/tactobc/testingtactobc/HelloWorldToString") + + // Debugging: Print the location of the class loader and resources + val loader = this.getClass.getClassLoader + val resources = loader.getResources("").asScala.toList + println(s"ClassLoader: $loader") + println(s"Resources: ${resources.mkString(", ")}") + + + val in = () => { + val stream = this.getClass.getResourceAsStream("/org/opalj/tactobc/testingtactobc/HelloWorldToString.class") + if (stream == null) throw new RuntimeException("Resource not found: /HelloWorldToString.class") + stream + } + val cf = Java8Framework.ClassFile(in).head + val newMethods = { + for (m <- cf.methods) yield { + m.body match { + case None => + m.copy() // methods which are native and abstract ... + case Some(originalBody) => + //Using find because of the extra methods that do contain the name of the method but are not part of the original file + byteCodes.find(bc => bc._1.name.contains(m.name)) match { + case Some((_, instructions)) => + // Prepare new instructions array with null values where necessary + val maxPc = instructions.map(_._1).max + val newInstructionsWithNulls = new Array[Instruction](maxPc + 1) + + // Initialize array with nulls + for (i <- newInstructionsWithNulls.indices) { + newInstructionsWithNulls(i) = null + } + + // Fill in actual instructions + for ((pc, instruction) <- instructions) { + newInstructionsWithNulls(pc) = instruction + } + + // Print each instruction with its PC - to see if the NULLS are placed correctly + println(s"Instructions for method ${m.name}:") + newInstructionsWithNulls.zipWithIndex.foreach { + case (instruction, pc) => + if (instruction == null) { + println(s"PC $pc: NULL") + } else { + println(s"PC $pc: ${instruction.toString}") + } + } + + // Print out the translation from TAC to Bytecode with nulls + //println("newInstrWithNulls" + newInstructionsWithNulls.foreach(instruction => println(instruction.toString))) + // Debugging: Print the instructions being passed to the new Code object + println(s"Original Instructions for ${m.name}: ${originalBody.instructions.mkString(", ")}") + println(s"New Instructions for ${m.name}: ${newInstructionsWithNulls.mkString(", ")}") + //ToDo: use CodeAttribute builder + val attributesOfOriginalBody = originalBody.attributes + //Todo: + val newLocalVariableTable = LocalVariableTable(ArraySeq( + LocalVariable(0, maxPc + 1, "args", ArrayType(ObjectType("java/lang/String")), 0) + )) + /*val newCompactLineNumber = CompactLineNumber( + Array(LineNumber(0, maxPc + 1)) + )*/ + //live variable + + // Remove CompactLineNumberTable attribute + val newAttributes = attributesOfOriginalBody.filterNot(_.isInstanceOf[CompactLineNumberTable]) + // Replace the LocalVariableTable attribute in the original attributes + val finalAttributes = newAttributes.map { + case _: LocalVariableTable => newLocalVariableTable + //case _: CompactLineNumberTable => + case other => other + } + + val newBody = Code( + //todo: use the size of the local variables map + 100, + 100, + newInstructionsWithNulls, + originalBody.exceptionHandlers, + finalAttributes) + + //todo: StackMapTable needs the localVariableTable to be able to be computed + println(s"New body for method ${m.name}: $newBody") + println(attributesOfOriginalBody) + val result = m.copy(body = Some(newBody)) + + result + case None => + println(s"Warning: No bytecode found for method ${m.name}. Keeping original method body.") + m.copy() + } + } + } + } + val cfWithNewInstructions = cf.copy(methods = newMethods) + val newMethodsForReal = { + for (m <- cfWithNewInstructions.methods) yield { + m.body match { + case None => + m.copy() // methods which are native and abstract ... + case Some(originalBody) => + //Using find because of the extra methods that do contain the name of the method but are not part of the original file + byteCodes.find(bc => bc._1.name.contains(m.name)) match { + case Some((_, instructions)) => + //ToDo: use CodeAttribute builder + val attributesOfOriginalBody = originalBody.attributes + + val newStackMapTable = computeStackMapTable(m)(p.classHierarchy) + //live variable + // Replace the LocalVariableTable attribute in the original attributes + val newAttributes1 = attributesOfOriginalBody.map { + case _: StackMapTable => newStackMapTable + case other => other + } + val newBody1 = Code( + //todo: use the size of the local variables map + 100, + 100, + originalBody.instructions, + originalBody.exceptionHandlers, + newAttributes1) + + //todo: StackMapTable needs the localVariableTable to be able to be computed + println(s"New body for method ${m.name}: $newBody1") + println(attributesOfOriginalBody) + val result = m.copy(body = Some(newBody1)) + + val it = result.body.get.iterator + val n = it.next() + val n1 = it.next() + print(n.toString + n1.toString) + + result + case None => + println(s"Warning: No bytecode found for method ${m.name}. Keeping original method body.") + m.copy() + } + } + } + } + val cfWithNewInstructionsForReal = cf.copy(methods = newMethodsForReal) + val newRawCF = Assembler(toDA(cfWithNewInstructionsForReal)) + val assembledMyIntfPath = Paths.get("tmp", "org", "opalj", "tactobc", "testingtactobc", "HelloWorldToString.class") + val newClassFile = Files.write(assembledMyIntfPath, newRawCF) + println("Created class file: " + newClassFile.toAbsolutePath) + + // Let's see the old class file... + val odlCFHTML = ClassFile(in).head.toXHTML(None) + val oldCFHTMLFile = writeAndOpen(odlCFHTML, "HelloWorldToString", ".html") + println("original: " + oldCFHTMLFile) + + // Let's see the new class file... + val newCF = ClassFile(() => new ByteArrayInputStream(newRawCF)).head.toXHTML(None) + println("genetated from TAC: " + writeAndOpen(newCF, "NewHelloWorldToString", ".html")) + + //println("Class file GeneratedHelloWorldToStringDALEQUEE.class has been generated." + newClass) + // Let's test that the new class does what it is expected to do... (we execute the + // instrumented method) + val cl = new InMemoryClassLoader(Map((TheType.toJava, newRawCF))) + val newClass = cl.findClass(TheType.toJava) + //val instance = newClass.getDeclaredConstructor().newInstance() + newClass.getMethod("main", (Array[String]()).getClass).invoke(null, null) + } + + /** + * Compiles the Three-Address Code (TAC) representation for all methods in the given .class file. + * + * @param file A File object representing the .class file to be analyzed and compiled into TAC. + * @return A Map associating each method in the class file with its corresponding TAC representation. + */ + def compileTAC(file: File): Map[Method, AITACode[TACMethodParameter, ValueInformation]] = { + val p = Project(file) + val tacProvider = p.get(LazyDetachedTACAIKey) + + // Store the TAC results in a map + val methodTACMap = scala.collection.mutable.Map.empty[Method, AITACode[TACMethodParameter, ValueInformation]] + + for { + cf <- p.allProjectClassFiles + m <- cf.methods + if m.body.isDefined + } { + val tac = tacProvider(m) + methodTACMap += (m -> tac) + } + + methodTACMap.toMap + } + + /** + * Compiles and prints the bytecode representation for all methods in the given .class file. + * + * @param file The .class file or JAR archive to be analyzed. + * @return A Map associating each method in the class file with its bytecode instructions. + */ + def compileByteCode(file: File): Map[Method, Array[String]] = { + val p = Project(file) + + // A map to store the bytecode representation of each method + val methodByteCodeMap = scala.collection.mutable.Map.empty[Method, Array[String]] + + for { + cf <- p.allProjectClassFiles + method <- cf.methods + if method.body.isDefined + } { + // Convert the body's instructions to a human-readable format + val instructions = method.body.get.instructions.zipWithIndex.map { case (instr, index) => + s"$index: ${instr}" + } + methodByteCodeMap += (method -> instructions.toArray) + + // Print the bytecode for each method + println(s"Method: ${method.toJava}") + instructions.foreach(println) + } + + methodByteCodeMap.toMap + } + + /** + * Translates the TAC representations of methods back to bytecode, encapsulated within OPAL's Code structure. + * + * This method iterates over each method's TAC representation and generates a corresponding sequence of + * bytecode instructions, effectively reversing the process of TAC generation. + * + * @param tacs A Map containing the TAC representations of methods to be translated back to bytecode. + * @return A Map associating each method with its newly generated bytecode, wrapped in OPAL's Code structure. + */ + def translateTACtoBC(tacs: Map[Method, AITACode[TACMethodParameter, ValueInformation]]): Map[Method, ArrayBuffer[(Int, Instruction)]] = { + tacs.map { case (method, tacCode) => + // Convert the TAC representation back to bytecode for each method + val bytecodeInstructions = translateSingleTACtoBC(tacCode) + method -> bytecodeInstructions + } + } + + /** + * Converts the TAC representation of a single method into bytecode instructions. + * + * This helper method processes one method's TAC representation at a time, converting it into a sequence + * of bytecode instructions. It handles various types of TAC statements and expressions, translating them + * into their equivalent bytecode form. + * + * @param tac The TAC representation of a method to be converted into bytecode. + * @return An array of bytecode instructions representing the method's functionality + */ + def translateSingleTACtoBC(tac: AITACode[TACMethodParameter, ValueInformation]): ArrayBuffer[(Int, Instruction)] = { + val generatedByteCodeWithPC = ArrayBuffer[(Int, Instruction)]() + var currentPC = 0 + val tacTargetToByteCodePcs = ArrayBuffer[(Int, Int)]() + val switchCases = ArrayBuffer[(Int, Int)]() // To store switch case targets + val duVars = mutable.ListBuffer[DUVar[_]]() + val tacStmts = tac.stmts.zipWithIndex + tacStmts.foreach { case (stmt, _) => + stmt match { + case Assignment(_, targetVar, expr) => + ExprUtils.collectFromExpr(targetVar, duVars) + ExprUtils.collectFromExpr(expr, duVars) + case If(_, left, _, right, _) => + ExprUtils.collectFromExpr(left, duVars) + ExprUtils.collectFromExpr(right, duVars) + case VirtualMethodCall(_, _, _, _, _, receiver, params) => + ExprUtils.collectFromExpr(receiver, duVars) + for (param <- params) { + ExprUtils.collectFromExpr(param, duVars) + } + case NonVirtualMethodCall(_, _, _, _, _, receiver, params) => + ExprUtils.collectFromExpr(receiver, duVars) + for (param <- params) { + ExprUtils.collectFromExpr(param, duVars) + } + case ReturnValue(_, expr) => + ExprUtils.collectFromExpr(expr, duVars) + case _ => + } + } + val resultDUVars = duVars + println(resultDUVars) + //ExprUtils.populateVariableLVIndexMap(duVars) + val parameters = ExprUtils.mapParametersAndPopulate(duVars) + println(parameters) + val resultingLVIndexMap = ExprUtils.collectAllUVarsAndPopulate(duVars) + println(resultingLVIndexMap) + //first pass + tacStmts.foreach { case (stmt, _) => + stmt match { + case Assignment(_, targetVar, expr) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processAssignment(targetVar, expr, generatedByteCodeWithPC, currentPC) + case ArrayStore(_, arrayRef, index, value) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processArrayStore(arrayRef, index, value, generatedByteCodeWithPC, currentPC) + case CaughtException(_, exceptionType, throwingStmts) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processCaughtException(exceptionType, throwingStmts, generatedByteCodeWithPC, currentPC) + case ExprStmt(_, expr) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = ExprUtils.processExpression(expr, generatedByteCodeWithPC, currentPC) + case If(_, left, condition, right, target) => + tacTargetToByteCodePcs += ((target, currentPC)) + currentPC = StmtProcessor.processIf(left, condition, right, target, generatedByteCodeWithPC, currentPC) + case Goto(_, target) => + tacTargetToByteCodePcs += ((target, currentPC)) + currentPC = StmtProcessor.processGoto(generatedByteCodeWithPC, currentPC) + case Switch(_, defaultTarget, index, npairs) => + npairs.foreach { pair => + switchCases += ((pair._1, pair._2)) //case values to jump target + } + tacTargetToByteCodePcs += ((defaultTarget, currentPC)) + currentPC = StmtProcessor.processSwitch(defaultTarget, index, npairs, generatedByteCodeWithPC, currentPC) + case JSR(_, target) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processJSR(target, generatedByteCodeWithPC, currentPC) + case VirtualMethodCall(_, declaringClass, isInterface, name, descriptor, receiver, params) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processVirtualMethodCall(declaringClass, isInterface, name, descriptor, receiver, params, generatedByteCodeWithPC, currentPC) + case NonVirtualMethodCall(_, declaringClass, isInterface, name, descriptor, receiver, params) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processNonVirtualMethodCall(declaringClass, isInterface, name, descriptor, receiver, params, generatedByteCodeWithPC, currentPC) + case StaticMethodCall(_, declaringClass, isInterface, name, descriptor, params) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processStaticMethodCall(declaringClass, isInterface, name, descriptor, params, generatedByteCodeWithPC, currentPC) + case InvokedynamicMethodCall(_, bootstrapMethod, name, descriptor, params) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processInvokeDynamicMethodCall(bootstrapMethod, name, descriptor, params) + case MonitorEnter(_, objRef) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processMonitorEnter(objRef, generatedByteCodeWithPC, currentPC) + case MonitorExit(_, objRef) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processMonitorExit(objRef, generatedByteCodeWithPC, currentPC) + case PutField(_, declaringClass, name, declaredFieldType, objRef, value) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processPutField(declaringClass, name, declaredFieldType, objRef, value, generatedByteCodeWithPC, currentPC) + case PutStatic(_, declaringClass, name, declaredFieldType, value) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processPutStatic(declaringClass, name, declaredFieldType, value, generatedByteCodeWithPC, currentPC) + case Checkcast(_, value, cmpTpe) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processCheckCast(value, cmpTpe, generatedByteCodeWithPC, currentPC) + case Ret(_, returnAddresses) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processRet(returnAddresses, generatedByteCodeWithPC, currentPC) + case ReturnValue(_, expr) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processReturnValue(expr, generatedByteCodeWithPC, currentPC) + case Return(_) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processReturn(generatedByteCodeWithPC, currentPC) + case Throw(_, exception) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processThrow(exception, generatedByteCodeWithPC, currentPC) + case _ => + } + } + //second pass -> this time through the translated bytecode to calculate the right branching targets + val result = ArrayBuffer[(Int, Instruction)]() + // Index for TAC statements + var tacTargetToByteCodePcsIndex = 0 + + generatedByteCodeWithPC.zipWithIndex.foreach { + case ((pc, instruction), _) => + // Match and update branch instructions + val updatedInstruction = instruction match { + case IF_ICMPEQ(-1) => + tacTargetToByteCodePcsIndex -= 1 + val instruction = IF_ICMPEQ(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + tacTargetToByteCodePcsIndex += 1 + instruction + case IF_ICMPNE(-1) => + tacTargetToByteCodePcsIndex -= 1 + val instruction = IF_ICMPNE(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + tacTargetToByteCodePcsIndex += 1 + instruction + case IF_ICMPLT(-1) => + tacTargetToByteCodePcsIndex -= 1 + val instruction = IF_ICMPLT(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + tacTargetToByteCodePcsIndex += 1 + instruction + case IF_ICMPLE(-1) => + tacTargetToByteCodePcsIndex -= 1 + val instruction = IF_ICMPLE(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + tacTargetToByteCodePcsIndex += 1 + instruction + case IF_ICMPGT(-1) => + tacTargetToByteCodePcsIndex -= 1 + val instruction = IF_ICMPGT(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + tacTargetToByteCodePcsIndex += 1 + instruction + case IF_ICMPGE(-1) => + tacTargetToByteCodePcsIndex -= 1 + val instruction = IF_ICMPGE(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + tacTargetToByteCodePcsIndex += 1 + instruction + case GOTO(-1) => + GOTO(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + case LOOKUPSWITCH(defaultOffset, matchOffsets) => + val updatedMatchOffsets = matchOffsets.map { case IntIntPair(caseValue, _) => + val tacTarget = findTacTarget(switchCases, caseValue) + IntIntPair(caseValue, updateSwitchTargets(tacTargetToByteCodePcs, tacTarget)) + } + val updatedDefaultOffset = updateSwitchTargets(tacTargetToByteCodePcs, defaultOffset) + LOOKUPSWITCH(updatedDefaultOffset, updatedMatchOffsets) + case TABLESWITCH(defaultOffset, low, high, jumpOffsets) => + val updatedJumpOffsets = jumpOffsets.zipWithIndex.map { case (_, index) => + val tacTarget = findTacTarget(switchCases, index) + updateSwitchTargets(tacTargetToByteCodePcs, tacTarget) + } + val updatedDefaultOffset = updateSwitchTargets(tacTargetToByteCodePcs, defaultOffset) + TABLESWITCH(updatedDefaultOffset, low, high, updatedJumpOffsets.to(ArraySeq)) + case _ => + instruction + } + result += ((pc, updatedInstruction)) + + // Only increment tacIndex when the current instruction corresponds to a TAC statement + if (tacTargetToByteCodePcsIndex < tacStmts.length && directAssociationExists(tacTargetToByteCodePcs, tacTargetToByteCodePcs(tacTargetToByteCodePcsIndex)._1, pc)) { + tacTargetToByteCodePcsIndex += 1 + } + } + ExprUtils.uvarToLVIndex = mutable.Map[IntTrieSet, Int]() + ExprUtils.nextLVIndex = 1 + result + } + + def findTacTarget(npairs: ArrayBuffer[(Int, Int)], caseValue: Int): Int = { + val tacTarget = npairs.find(_._1 == caseValue).map(_._2).get + tacTarget + } + + def updateBranchTargets(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTargetToByteCodePcsIndex: Int, currentPC: Int): Int = { + val tacTarget = tacTargetToByteCodePcs(tacTargetToByteCodePcsIndex)._1 + val byteCodeTarget = tacTargetToByteCodePcs(tacTarget)._2 - currentPC + byteCodeTarget + } + + def updateSwitchTargets(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTarget: Int): Int = { + val byteCodeTarget = tacTargetToByteCodePcs(tacTarget)._2 + byteCodeTarget + } + + def directAssociationExists(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTarget: Int, bytecodePC: Int): Boolean = { + tacTargetToByteCodePcs.exists { case (tacGoto, bcPC) => (tacGoto, bcPC) == (tacTarget, bytecodePC) } + } +} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorldToString.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorldToString.java new file mode 100644 index 0000000000..272eb60924 --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorldToString.java @@ -0,0 +1,28 @@ +package org.opalj.tactobc.testingtactobc; + +public class HelloWorldToString { + + public static void main(String[] args) { + System.out.println("Holi Fiooooo"); + int i = 0; + System.out.println(i); + int x = 1; + for(; i < 6; i++){ + dumbPrint(i,x); + x++; + } + dumbPrint(i,x); + } + + public static void dumbPrint(int i, int x){ + System.out.println("esto es de otro metodo".concat(String.valueOf(i))); + System.out.println(i); + System.out.println(x); + foo(); + } + + public static void foo(){ + System.out.println("y este tambien, osea mi StaticMethodCall funciona :D"); + } +} + diff --git a/OPAL/tactobc/src/test/org/opalj/tactobc/HelloWorldToString.java b/OPAL/tactobc/src/test/org/opalj/tactobc/HelloWorldToString.java new file mode 100644 index 0000000000..272eb60924 --- /dev/null +++ b/OPAL/tactobc/src/test/org/opalj/tactobc/HelloWorldToString.java @@ -0,0 +1,28 @@ +package org.opalj.tactobc.testingtactobc; + +public class HelloWorldToString { + + public static void main(String[] args) { + System.out.println("Holi Fiooooo"); + int i = 0; + System.out.println(i); + int x = 1; + for(; i < 6; i++){ + dumbPrint(i,x); + x++; + } + dumbPrint(i,x); + } + + public static void dumbPrint(int i, int x){ + System.out.println("esto es de otro metodo".concat(String.valueOf(i))); + System.out.println(i); + System.out.println(x); + foo(); + } + + public static void foo(){ + System.out.println("y este tambien, osea mi StaticMethodCall funciona :D"); + } +} + diff --git a/OPAL/tactobc/src/test/resources/HelloWorldToString.java b/OPAL/tactobc/src/test/resources/HelloWorldToString.java new file mode 100644 index 0000000000..ea00652a9b --- /dev/null +++ b/OPAL/tactobc/src/test/resources/HelloWorldToString.java @@ -0,0 +1,27 @@ + +public class HelloWorldToString { + + public static void main(String[] args) { + System.out.println("Holi Fiooooo"); + int i = 0; + System.out.println(i); + int x = 1; + for(; i < 6; i++){ + dumbPrint(i,x); + x++; + } + dumbPrint(i,x); + } + + public static void dumbPrint(int i, int x){ + System.out.println("esto es de otro metodo".concat(String.valueOf(i))); + System.out.println(i); + System.out.println(x); + foo(); + } + + public static void foo(){ + System.out.println("y este tambien, osea mi StaticMethodCall funciona :D"); + } +} + diff --git a/build.sbt b/build.sbt index 4e5e85a927..d76d9de574 100644 --- a/build.sbt +++ b/build.sbt @@ -177,6 +177,7 @@ lazy val `OPAL` = (project in file(".")) ai, ifds, tac, + tactobc, de, av, apk, @@ -325,6 +326,42 @@ lazy val `ThreeAddressCode` = (project in file("OPAL/tac")) .dependsOn(ifds % "it->it;it->test;test->test;compile->compile") .configs(IntegrationTest) +lazy val tactobc = `ThreeAddressCodeToBytecode` +lazy val `ThreeAddressCodeToBytecode` = (project in file("OPAL/tactobc")) + .settings(buildSettings: _*) + .settings( + name := "Three Address Code to Bytecode", + Compile / doc / scalacOptions := (Opts.doc + .title("OPAL - Three Address Code to Bytecode") ++ Seq("-groups", "-implicits")), + assembly / mainClass := Some("org.opalj.tactobc.TACtoBC"), + run / fork := true, + + // Ensure resources directory is included in the classpath + Compile / resourceDirectory := baseDirectory.value / "src" / "main" / "resources", + Test / resourceDirectory := baseDirectory.value / "src" / "test" / "resources", + + // Include resources in the classpath + Compile / resourceGenerators += Def.task { + val resources = (Compile / resourceDirectory).value + val targetDir = (Compile / classDirectory).value / "resources" + IO.copyDirectory(resources, targetDir) + Seq(targetDir) + }, + Test / resourceGenerators += Def.task { + val resources = (Test / resourceDirectory).value + val targetDir = (Test / classDirectory).value / "resources" + IO.copyDirectory(resources, targetDir) + Seq(targetDir) + } + ) + .dependsOn(br % "it->it;it->test;test->test;compile->compile") + .dependsOn(da % "it->it;it->test;test->test;compile->compile") + .dependsOn(ba % "it->it;it->test;test->test;compile->compile") + .dependsOn(tac % "it->it;it->test;test->test;compile->compile") + .dependsOn(ai % "it->it;it->test;test->test;compile->compile") + .dependsOn(ifds % "it->it;it->test;test->test;compile->compile") + .configs(IntegrationTest) + lazy val ba = `BytecodeAssembler` lazy val `BytecodeAssembler` = (project in file("OPAL/ba")) .settings(buildSettings: _*) From 68be1b4e8bec2a88746b340261153f2720cbc230 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 28 Jul 2024 20:34:02 +0200 Subject: [PATCH 002/111] preparing testing with more java programs --- .../tactobc/testingtactobc/CommandLine.java | 67 ++++++ .../org/opalj/tactobc/testingtactobc/FFT.java | 168 +++++++++++++ .../testingtactobc/HelloWorldToString.java | 8 +- .../opalj/tactobc/testingtactobc/Kernel.java | 223 ++++++++++++++++++ .../org/opalj/tactobc/testingtactobc/LU.java | 167 +++++++++++++ .../tactobc/testingtactobc/MonteCarlo.java | 29 +++ .../org/opalj/tactobc/testingtactobc/SOR.java | 32 +++ .../tactobc/testingtactobc/SparseCompRow.java | 30 +++ .../tactobc/testingtactobc/Stopwatch.java | 64 +++++ 9 files changed, 784 insertions(+), 4 deletions(-) create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/CommandLine.java create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/FFT.java create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/Kernel.java create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/LU.java create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/MonteCarlo.java create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/SOR.java create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/SparseCompRow.java create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/Stopwatch.java diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/CommandLine.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/CommandLine.java new file mode 100644 index 0000000000..24e29ffaca --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/CommandLine.java @@ -0,0 +1,67 @@ +package org.opalj.tactobc.testingtactobc; + +import java.util.Random; + +public class CommandLine { + private static final String[] DUMP_PROPERTIES = new String[]{"java.vendor", "java.version", "os.arch", "os.name", "os.version"}; + + public CommandLine() { + } + + public static void main(String[] args) { + System.out.println(); + System.out.println("SciMark " + CommandLine.class.getPackage().getImplementationVersion()); + System.out.println(); + double min_time = 2.0; + int FFT_size = 1024; + int SOR_size = 100; + int Sparse_size_M = 1000; + int Sparse_size_nz = 5000; + int LU_size = 100; + if (args.length > 0) { + if (args[0].equalsIgnoreCase("-h") || args[0].equalsIgnoreCase("-help")) { + System.out.println("Usage: [-large] [minimum_time]"); + return; + } + + int current_arg = 0; + if (args[current_arg].equalsIgnoreCase("-large")) { + FFT_size = 1048576; + SOR_size = 1000; + Sparse_size_M = 100000; + Sparse_size_nz = 1000000; + LU_size = 1000; + ++current_arg; + } + + if (args.length > current_arg) { + min_time = Double.parseDouble(args[current_arg]); + } + } + + double[] res = new double[6]; + Random R = new Random(101010); + res[1] = Kernel.measureFFT(FFT_size, min_time, R); + res[2] = Kernel.measureSOR(SOR_size, min_time, R); + res[3] = Kernel.measureMonteCarlo(min_time, R); + res[4] = Kernel.measureSparseMatmult(Sparse_size_M, Sparse_size_nz, min_time, R); + res[5] = Kernel.measureLU(LU_size, min_time, R); + res[0] = (res[1] + res[2] + res[3] + res[4] + res[5]) / 5.0; + System.out.format("Composite Score: %.2f%n", res[0]); + System.out.format("FFT (%s): %.2f%n", FFT_size, res[1]); + System.out.format("SOR (%s x %s): %.2f%n", Integer.valueOf(SOR_size), Integer.valueOf(SOR_size), res[2]); + System.out.format("Monte Carlo: %.2f%n", res[3]); + System.out.format("Sparse matmult (N=%s, nz=%s): %.2f%n", Sparse_size_M, Sparse_size_nz, res[4]); + System.out.format("LU (%s x %s ): %.2f%n", Integer.valueOf(LU_size), Integer.valueOf(LU_size), res[5]); + System.out.println(); + String[] var10 = DUMP_PROPERTIES; + int var11 = var10.length; + + for(int var12 = 0; var12 < var11; ++var12) { + String property = var10[var12]; + System.out.println(property + ": " + System.getProperty(property)); + } + + } +} + diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/FFT.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/FFT.java new file mode 100644 index 0000000000..37bc5663aa --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/FFT.java @@ -0,0 +1,168 @@ +package org.opalj.tactobc.testingtactobc; + +public class FFT { + public FFT() { + } + + public static double num_flops(int N) { + double logN = (double)log2(N); + return (5.0 * (double)N - 2.0) * logN + 2.0 * ((double)N + 1.0); + } + + public static void transform(double[] data) { + transform_internal(data, -1); + } + + public static void inverse(double[] data) { + transform_internal(data, 1); + int nd = data.length; + int n = nd / 2; + double norm = 1.0 / (double)n; + + for(int i = 0; i < nd; ++i) { + data[i] *= norm; + } + + } + + public static double test(double[] data) { + int nd = data.length; + double[] copy = new double[nd]; + System.arraycopy(data, 0, copy, 0, nd); + transform(data); + inverse(data); + double diff = 0.0; + + for(int i = 0; i < nd; ++i) { + double d = data[i] - copy[i]; + diff += d * d; + } + + return Math.sqrt(diff / (double)nd); + } + + public static double[] makeRandom(int n) { + int nd = 2 * n; + double[] data = new double[nd]; + + for(int i = 0; i < nd; ++i) { + data[i] = Math.random(); + } + + return data; + } + + public static void main(String[] args) { + int i; + if (args.length == 0) { + i = 1024; + System.out.println("n=" + i + " => RMS Error=" + test(makeRandom(i))); + } + + for(i = 0; i < args.length; ++i) { + int n = Integer.parseInt(args[i]); + System.out.println("n=" + n + " => RMS Error=" + test(makeRandom(n))); + } + + } + + protected static int log2(int n) { + int log = 0; + + for(int k = 1; k < n; ++log) { + k *= 2; + } + + if (n != 1 << log) { + throw new Error("FFT: Data length is not a power of 2!: " + n); + } else { + return log; + } + } + + protected static void transform_internal(double[] data, int direction) { + if (data.length != 0) { + int n = data.length / 2; + if (n != 1) { + int logn = log2(n); + bitreverse(data); + int bit = 0; + + for(int dual = 1; bit < logn; dual *= 2) { + double w_real = 1.0; + double w_imag = 0.0; + double theta = 2.0 * (double)direction * Math.PI / (2.0 * (double)dual); + double s = Math.sin(theta); + double t = Math.sin(theta / 2.0); + double s2 = 2.0 * t * t; + + int a; + int b; + int i; + double tmp_imag; + for(a = 0; a < n; a += 2 * dual) { + b = 2 * a; + i = 2 * (a + dual); + tmp_imag = data[i]; + double wd_imag = data[i + 1]; + data[i] = data[b] - tmp_imag; + data[i + 1] = data[b + 1] - wd_imag; + data[b] += tmp_imag; + data[b + 1] += wd_imag; + } + + for(a = 1; a < dual; ++a) { + double tmp_real = w_real - s * w_imag - s2 * w_real; + tmp_imag = w_imag + s * w_real - s2 * w_imag; + w_real = tmp_real; + w_imag = tmp_imag; + + for(b = 0; b < n; b += 2 * dual) { + i = 2 * (b + a); + int j = 2 * (b + a + dual); + double z1_real = data[j]; + double z1_imag = data[j + 1]; + double wd_real = w_real * z1_real - w_imag * z1_imag; + double wd_imag = w_real * z1_imag + w_imag * z1_real; + data[j] = data[i] - wd_real; + data[j + 1] = data[i + 1] - wd_imag; + data[i] += wd_real; + data[i + 1] += wd_imag; + } + } + + ++bit; + } + + } + } + } + + protected static void bitreverse(double[] data) { + int n = data.length / 2; + int nm1 = n - 1; + int i = 0; + + for(int j = 0; i < nm1; ++i) { + int ii = i << 1; + int jj = j << 1; + int k = n >> 1; + if (i < j) { + double tmp_real = data[ii]; + double tmp_imag = data[ii + 1]; + data[ii] = data[jj]; + data[ii + 1] = data[jj + 1]; + data[jj] = tmp_real; + data[jj + 1] = tmp_imag; + } + + while(k <= j) { + j -= k; + k >>= 1; + } + + j += k; + } + + } +} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorldToString.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorldToString.java index 272eb60924..6baa1ca332 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorldToString.java +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorldToString.java @@ -3,11 +3,11 @@ public class HelloWorldToString { public static void main(String[] args) { - System.out.println("Holi Fiooooo"); + System.out.println("HelloWorld!"); int i = 0; System.out.println(i); int x = 1; - for(; i < 6; i++){ + for(; i < 3; i++){ dumbPrint(i,x); x++; } @@ -15,14 +15,14 @@ public static void main(String[] args) { } public static void dumbPrint(int i, int x){ - System.out.println("esto es de otro metodo".concat(String.valueOf(i))); + System.out.println("this is a method ".concat(String.valueOf(i))); System.out.println(i); System.out.println(x); foo(); } public static void foo(){ - System.out.println("y este tambien, osea mi StaticMethodCall funciona :D"); + System.out.println("StaticMethod call works :)"); } } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/Kernel.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/Kernel.java new file mode 100644 index 0000000000..adde8ad1cb --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/Kernel.java @@ -0,0 +1,223 @@ +package org.opalj.tactobc.testingtactobc; + +import java.util.Random; + +public class Kernel { + public Kernel() { + } + + public static double measureFFT(int N, double mintime, Random R) { + double[] x = RandomVector(2 * N, R); + double[] oldx = NewVectorCopy(x); + long cycles = 1L; + Stopwatch Q = new Stopwatch(); + + while(true) { + Q.start(); + + for(int i = 0; (long)i < cycles; ++i) { + FFT.transform(x); + FFT.inverse(x); + } + + Q.stop(); + if (Q.read() >= mintime) { + double EPS = 1.0E-10; + if (FFT.test(x) / (double)N > 1.0E-10) { + return 0.0; + } + + return FFT.num_flops(N) * (double)cycles / Q.read() * 1.0E-6; + } + + cycles *= 2L; + } + } + + public static double measureSOR(int N, double min_time, Random R) { + double[][] G = RandomMatrix(N, N, R); + Stopwatch Q = new Stopwatch(); + long cycles = 1L; + + while(true) { + Q.start(); + SOR.execute(1.25, G, cycles); + Q.stop(); + if (Q.read() >= min_time) { + return SOR.num_flops(N, N, cycles) / Q.read() * 1.0E-6; + } + + cycles *= 2L; + } + } + + public static double measureMonteCarlo(double min_time, Random R) { + Stopwatch Q = new Stopwatch(); + long cycles = 1L; + + while(true) { + Q.start(); + MonteCarlo.integrate(cycles); + Q.stop(); + if (Q.read() >= min_time) { + return MonteCarlo.num_flops(cycles) / Q.read() * 1.0E-6; + } + + cycles *= 2L; + } + } + + public static double measureSparseMatmult(int N, int nz, double min_time, Random R) { + double[] x = RandomVector(N, R); + double[] y = new double[N]; + int nr = nz / N; + int anz = nr * N; + double[] val = RandomVector(anz, R); + int[] col = new int[anz]; + int[] row = new int[N + 1]; + row[0] = 0; + + for(int r = 0; r < N; ++r) { + int rowr = row[r]; + row[r + 1] = rowr + nr; + int step = r / nr; + if (step < 1) { + step = 1; + } + + for(int i = 0; i < nr; ++i) { + col[rowr + i] = i * step; + } + } + + Stopwatch Q = new Stopwatch(); + long cycles = 1L; + + while(true) { + Q.start(); + SparseCompRow.matmult(y, val, row, col, x, cycles); + Q.stop(); + if (Q.read() >= min_time) { + return SparseCompRow.num_flops(N, nz, cycles) / Q.read() * 1.0E-6; + } + + cycles *= 2L; + } + } + + public static double measureLU(int N, double min_time, Random R) { + double[][] A = RandomMatrix(N, N, R); + double[][] lu = new double[N][N]; + int[] pivot = new int[N]; + Stopwatch Q = new Stopwatch(); + long cycles = 1L; + + while(true) { + Q.start(); + + for(int i = 0; (long)i < cycles; ++i) { + CopyMatrix(lu, A); + LU.factor(lu, pivot); + } + + Q.stop(); + if (Q.read() >= min_time) { + double[] b = RandomVector(N, R); + double[] x = NewVectorCopy(b); + LU.solve(lu, pivot, x); + double EPS = 1.0E-12; + if (normabs(b, matvec(A, x)) / (double)N > 1.0E-12) { + return 0.0; + } + + return LU.num_flops(N) * (double)cycles / Q.read() * 1.0E-6; + } + + cycles *= 2L; + } + } + + private static double[] NewVectorCopy(double[] x) { + int N = x.length; + double[] y = new double[N]; + System.arraycopy(x, 0, y, 0, N); + return y; + } + + private static double normabs(double[] x, double[] y) { + int N = x.length; + double sum = 0.0; + + for(int i = 0; i < N; ++i) { + sum += Math.abs(x[i] - y[i]); + } + + return sum; + } + + private static void CopyMatrix(double[][] B, double[][] A) { + int M = A.length; + int N = A[0].length; + int remainder = N & 3; + + for(int i = 0; i < M; ++i) { + double[] Bi = B[i]; + double[] Ai = A[i]; + System.arraycopy(Ai, 0, Bi, 0, remainder); + + for(int j = remainder; j < N; j += 4) { + Bi[j] = Ai[j]; + Bi[j + 1] = Ai[j + 1]; + Bi[j + 2] = Ai[j + 2]; + Bi[j + 3] = Ai[j + 3]; + } + } + + } + + private static double[][] RandomMatrix(int M, int N, Random R) { + double[][] A = new double[M][N]; + + for(int i = 0; i < N; ++i) { + for(int j = 0; j < N; ++j) { + A[i][j] = R.nextDouble(); + } + } + + return A; + } + + private static double[] RandomVector(int N, Random R) { + double[] A = new double[N]; + + for(int i = 0; i < N; ++i) { + A[i] = R.nextDouble(); + } + + return A; + } + + private static double[] matvec(double[][] A, double[] x) { + int N = x.length; + double[] y = new double[N]; + matvec(A, x, y); + return y; + } + + private static void matvec(double[][] A, double[] x, double[] y) { + int M = A.length; + int N = A[0].length; + + for(int i = 0; i < M; ++i) { + double sum = 0.0; + double[] Ai = A[i]; + + for(int j = 0; j < N; ++j) { + sum += Ai[j] * x[j]; + } + + y[i] = sum; + } + + } +} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/LU.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/LU.java new file mode 100644 index 0000000000..e9c7820562 --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/LU.java @@ -0,0 +1,167 @@ +package org.opalj.tactobc.testingtactobc; + +public class LU { + private final double[][] LU_; + private final int[] pivot_; + + public LU(double[][] A) { + int M = A.length; + int N = A[0].length; + this.LU_ = new double[M][N]; + insert_copy(this.LU_, A); + this.pivot_ = new int[M]; + factor(this.LU_, this.pivot_); + } + + public static double num_flops(int N) { + return 2.0 * (double)N * (double)N * (double)N / 3.0; + } + + protected static double[] new_copy(double[] x) { + int N = x.length; + double[] T = new double[N]; + System.arraycopy(x, 0, T, 0, N); + return T; + } + + protected static double[][] new_copy(double[][] A) { + int M = A.length; + int N = A[0].length; + double[][] T = new double[M][N]; + + for(int i = 0; i < M; ++i) { + double[] Ti = T[i]; + double[] Ai = A[i]; + System.arraycopy(Ai, 0, Ti, 0, N); + } + + return T; + } + + public static int[] new_copy(int[] x) { + int N = x.length; + int[] T = new int[N]; + System.arraycopy(x, 0, T, 0, N); + return T; + } + + protected static void insert_copy(double[][] B, double[][] A) { + int M = A.length; + int N = A[0].length; + int remainder = N & 3; + + for(int i = 0; i < M; ++i) { + double[] Bi = B[i]; + double[] Ai = A[i]; + System.arraycopy(Ai, 0, Bi, 0, remainder); + + for(int j = remainder; j < N; j += 4) { + Bi[j] = Ai[j]; + Bi[j + 1] = Ai[j + 1]; + Bi[j + 2] = Ai[j + 2]; + Bi[j + 3] = Ai[j + 3]; + } + } + + } + + public static int factor(double[][] A, int[] pivot) { + int N = A.length; + int M = A[0].length; + int minMN = Math.min(M, N); + + for(int j = 0; j < minMN; ++j) { + int jp = j; + double t = Math.abs(A[j][j]); + + int ii; + for(ii = j + 1; ii < M; ++ii) { + double ab = Math.abs(A[ii][j]); + if (ab > t) { + jp = ii; + t = ab; + } + } + + pivot[j] = jp; + if (A[jp][j] == 0.0) { + return 1; + } + + if (jp != j) { + double[] tA = A[j]; + A[j] = A[jp]; + A[jp] = tA; + } + + if (j < M - 1) { + double recp = 1.0 / A[j][j]; + + for(int k = j + 1; k < M; ++k) { + A[k][j] *= recp; + } + } + + if (j < minMN - 1) { + for(ii = j + 1; ii < M; ++ii) { + double[] Aii = A[ii]; + double[] Aj = A[j]; + double AiiJ = Aii[j]; + + for(int jj = j + 1; jj < N; ++jj) { + Aii[jj] -= AiiJ * Aj[jj]; + } + } + } + } + + return 0; + } + + public static void solve(double[][] LU, int[] pvt, double[] b) { + int M = LU.length; + int N = LU[0].length; + int ii = 0; + + int i; + for(i = 0; i < M; ++i) { + int ip = pvt[i]; + double sum = b[ip]; + b[ip] = b[i]; + if (ii == 0) { + for(int j = ii; j < i; ++j) { + sum -= LU[i][j] * b[j]; + } + } else if (sum == 0.0) { + ii = i; + } + + b[i] = sum; + } + + for(i = N - 1; i >= 0; --i) { + double sum = b[i]; + + for(int j = i + 1; j < N; ++j) { + sum -= LU[i][j] * b[j]; + } + + b[i] = sum / LU[i][i]; + } + + } + + public double[][] getLU() { + return new_copy(this.LU_); + } + + public int[] getPivot() { + return new_copy(this.pivot_); + } + + public double[] solve(double[] b) { + double[] x = new_copy(b); + solve(this.LU_, this.pivot_, x); + return x; + } +} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/MonteCarlo.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/MonteCarlo.java new file mode 100644 index 0000000000..e92aef670e --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/MonteCarlo.java @@ -0,0 +1,29 @@ +package org.opalj.tactobc.testingtactobc; + +import java.util.Random; + +public class MonteCarlo { + static final int SEED = 113; + + public MonteCarlo() { + } + + public static double num_flops(long Num_samples) { + return (double)Num_samples * 4.0; + } + + public static double integrate(long Num_samples) { + Random R = new Random(113); + long under_curve = 0L; + + for(long count = 0L; count < Num_samples; ++count) { + double x = R.nextDouble(); + double y = R.nextDouble(); + if (x * x + y * y <= 1.0) { + ++under_curve; + } + } + + return (double)under_curve / (double)Num_samples * 4.0; + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/SOR.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/SOR.java new file mode 100644 index 0000000000..5f3e8468ac --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/SOR.java @@ -0,0 +1,32 @@ +package org.opalj.tactobc.testingtactobc; + +public class SOR { + public SOR() { + } + + public static double num_flops(int M, int N, long num_iterations) { + return ((double)M - 1.0) * ((double)N - 1.0) * (double)num_iterations * 6.0; + } + + public static void execute(double omega, double[][] G, long num_iterations) { + int M = G.length; + int N = G[0].length; + double omega_over_four = omega * 0.25; + double one_minus_omega = 1.0 - omega; + int Mm1 = M - 1; + int Nm1 = N - 1; + + for(long p = 0L; p < num_iterations; ++p) { + for(int i = 1; i < Mm1; ++i) { + double[] Gi = G[i]; + double[] Gim1 = G[i - 1]; + double[] Gip1 = G[i + 1]; + + for(int j = 1; j < Nm1; ++j) { + Gi[j] = omega_over_four * (Gim1[j] + Gip1[j] + Gi[j - 1] + Gi[j + 1]) + one_minus_omega * Gi[j]; + } + } + } + + } +} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/SparseCompRow.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/SparseCompRow.java new file mode 100644 index 0000000000..efbf082891 --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/SparseCompRow.java @@ -0,0 +1,30 @@ +package org.opalj.tactobc.testingtactobc; + +public class SparseCompRow { + public SparseCompRow() { + } + + public static double num_flops(int N, int nz, long num_iterations) { + int actual_nz = nz / N * N; + return (double)actual_nz * 2.0 * (double)num_iterations; + } + + public static void matmult(double[] y, double[] val, int[] row, int[] col, double[] x, long NUM_ITERATIONS) { + int M = row.length - 1; + + for(long reps = 0L; reps < NUM_ITERATIONS; ++reps) { + for(int r = 0; r < M; ++r) { + double sum = 0.0; + int rowR = row[r]; + int rowRp1 = row[r + 1]; + + for(int i = rowR; i < rowRp1; ++i) { + sum += x[col[i]] * val[i]; + } + + y[r] = sum; + } + } + + } +} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/Stopwatch.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/Stopwatch.java new file mode 100644 index 0000000000..4d4de1dcbb --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/Stopwatch.java @@ -0,0 +1,64 @@ +package org.opalj.tactobc.testingtactobc; + +public class Stopwatch { + + public static void main(String[] args){ + System.out.println("Timer started"); + Stopwatch stopwatch = new Stopwatch(); + stopwatch.start(); + System.out.println("seconds: ".concat(String.valueOf(seconds()))); + } + private boolean running; + private double last_time; + private double total; + + public Stopwatch() { + this.reset(); + } + + public static double seconds() { + return System.currentTimeMillis() * 0.001; + } + + public void reset() { + this.running = false; + this.last_time = 0.0; + this.total = 0.0; + } + + public void start() { + if (!this.running) { + this.running = true; + this.total = 0.0; + this.last_time = seconds(); + } + + } + + public void resume() { + if (!this.running) { + this.last_time = seconds(); + this.running = true; + } + + } + + public double stop() { + if (this.running) { + this.total += seconds() - this.last_time; + this.running = false; + } + + return this.total; + } + + public double read() { + if (this.running) { + this.total += seconds() - this.last_time; + this.last_time = seconds(); + } + + return this.total; + } +} + From e018d4966236d1d7981f9a491c502127a1c943c0 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 28 Jul 2024 20:34:54 +0200 Subject: [PATCH 003/111] handling more expr types (WIP) --- .../scala/org/opalj/tactobc/ExprUtils.scala | 46 +++++++++++++++++-- .../scala/org/opalj/tactobc/TACtoBC.scala | 15 +++--- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprUtils.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprUtils.scala index fa2f99ea5d..dafab03f96 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprUtils.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprUtils.scala @@ -2,11 +2,11 @@ package org.opalj.tactobc import org.opalj.BinaryArithmeticOperators.{Add, And, Divide, Modulo, Multiply, Or, ShiftLeft, ShiftRight, Subtract, UnsignedShiftRight, XOr} -import org.opalj.br.{ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, ObjectType} -import org.opalj.br.instructions.{ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BIPUSH, DADD, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, FADD, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, IADD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, LADD, LAND, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, NEW, SIPUSH} +import org.opalj.br.{ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FloatType, IntegerType, LongType, ObjectType, ShortType} +import org.opalj.br.instructions.{ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BIPUSH, D2F, D2I, D2L, DADD, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LAND, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, NEW, SIPUSH} import org.opalj.bytecode.BytecodeProcessingFailedException import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{BinaryExpr, ClassConst, Const, DUVar, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, LongConst, MethodHandleConst, MethodTypeConst, New, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} +import org.opalj.tac.{BinaryExpr, ClassConst, Const, DUVar, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, LongConst, MethodHandleConst, MethodTypeConst, New, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} import scala.collection.mutable import scala.collection.mutable.ArrayBuffer @@ -23,6 +23,7 @@ object ExprUtils { case virtualFunctionCallExpr: VirtualFunctionCall[_] => handleVirtualFunctionCall(virtualFunctionCallExpr, instructionsWithPCs, currentPC) case staticFunctionCallExpr: StaticFunctionCall[_] => handleStaticFunctionCall(staticFunctionCallExpr, instructionsWithPCs, currentPC) case newExpr: New => handleNewExpr(newExpr.tpe, instructionsWithPCs, currentPC) + case primitiveTypecaseExpr: PrimitiveTypecastExpr[_] => handlePrimitiveTypeCastExpr(primitiveTypecaseExpr, instructionsWithPCs, currentPC) case _ => throw new UnsupportedOperationException("Unsupported expression type" + expr) } @@ -34,10 +35,15 @@ object ExprUtils { case binaryExpr: BinaryExpr[_] => collectFromBinaryExpr(binaryExpr, duVars) case virtualFunctionCallExpr: VirtualFunctionCall[_] => collectFromVirtualMethodCall(virtualFunctionCallExpr, duVars) case staticFunctionCallExpr: StaticFunctionCall[_] => collectFromStaticFunctionCall(staticFunctionCallExpr, duVars) + case primitiveTypecaseExpr: PrimitiveTypecastExpr[_] => collectFromPrimitiveTypeCastExpr(primitiveTypecaseExpr, duVars) case _ => } } + def collectFromPrimitiveTypeCastExpr(primitiveTypecaseExpr: PrimitiveTypecastExpr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectFromExpr(primitiveTypecaseExpr.operand, duVars) + } + def collectFromStaticFunctionCall(staticFunctionCallExpr: StaticFunctionCall[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { // Process each parameter and collect from each for (param <- staticFunctionCallExpr.params) { @@ -388,4 +394,38 @@ object ExprUtils { instructionsWithPCs += ((offsetPC, instruction)) offsetPC + instructionLength } + def handlePrimitiveTypeCastExpr(primitiveTypecastExpr: PrimitiveTypecastExpr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + //todo: handle loading of operand Expr + val instruction = (primitiveTypecastExpr.operand.cTpe, primitiveTypecastExpr.targetTpe) match { + // -> to Float + case (ComputationalTypeDouble, FloatType) => D2F + case (ComputationalTypeInt, FloatType) => I2F + case (ComputationalTypeLong, FloatType) => L2F + // -> to Int + case (ComputationalTypeDouble, IntegerType) => D2I + case (ComputationalTypeFloat, IntegerType) => F2I + case (ComputationalTypeLong, IntegerType) => L2I + // -> to Long + case (ComputationalTypeDouble, LongType) => D2L + case (ComputationalTypeInt, LongType) => I2L + case (ComputationalTypeFloat, LongType) => F2L + // -> to Double + case (ComputationalTypeFloat, DoubleType) => F2D + case (ComputationalTypeInt, DoubleType) => I2D + case (ComputationalTypeLong, DoubleType) => L2D + // -> to Char + case (ComputationalTypeInt, CharType) => I2C + // -> to Byte + case (ComputationalTypeInt, ByteType) => I2B + // -> to Short + case (ComputationalTypeInt, ShortType) => I2S + // -> other cases are not supported + case _ => throw new UnsupportedOperationException("Unsupported operation or computational type in PrimitiveTypecastExpr" + primitiveTypecastExpr) + } + instructionsWithPCs += ((currentPC, instruction)) + currentPC + instruction.length + // process the left expr and save the pc to give in the right expr processing + val finalPC = processExpression(primitiveTypecastExpr.operand, instructionsWithPCs, currentPC) + finalPC + } } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala index 41627d4e8e..a5edd9381e 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala @@ -60,7 +60,7 @@ object TACtoBC { bytecode.foreach(instr => println(instr.toString)) } - val TheType = ObjectType("org/opalj/tactobc/testingtactobc/HelloWorldToString") + val TheType = ObjectType("org/opalj/tactobc/testingtactobc/Stopwatch") // Debugging: Print the location of the class loader and resources val loader = this.getClass.getClassLoader @@ -70,8 +70,8 @@ object TACtoBC { val in = () => { - val stream = this.getClass.getResourceAsStream("/org/opalj/tactobc/testingtactobc/HelloWorldToString.class") - if (stream == null) throw new RuntimeException("Resource not found: /HelloWorldToString.class") + val stream = this.getClass.getResourceAsStream("/org/opalj/tactobc/testingtactobc/Stopwatch.class") + if (stream == null) throw new RuntimeException("Resource not found: /Stopwatch.class") stream } val cf = Java8Framework.ClassFile(in).head @@ -203,18 +203,18 @@ object TACtoBC { } val cfWithNewInstructionsForReal = cf.copy(methods = newMethodsForReal) val newRawCF = Assembler(toDA(cfWithNewInstructionsForReal)) - val assembledMyIntfPath = Paths.get("tmp", "org", "opalj", "tactobc", "testingtactobc", "HelloWorldToString.class") + val assembledMyIntfPath = Paths.get("tmp", "org", "opalj", "tactobc", "testingtactobc", "Stopwatch.class") val newClassFile = Files.write(assembledMyIntfPath, newRawCF) println("Created class file: " + newClassFile.toAbsolutePath) // Let's see the old class file... val odlCFHTML = ClassFile(in).head.toXHTML(None) - val oldCFHTMLFile = writeAndOpen(odlCFHTML, "HelloWorldToString", ".html") + val oldCFHTMLFile = writeAndOpen(odlCFHTML, "Stopwatch", ".html") println("original: " + oldCFHTMLFile) // Let's see the new class file... val newCF = ClassFile(() => new ByteArrayInputStream(newRawCF)).head.toXHTML(None) - println("genetated from TAC: " + writeAndOpen(newCF, "NewHelloWorldToString", ".html")) + println("genetated from TAC: " + writeAndOpen(newCF, "Stopwatch", ".html")) //println("Class file GeneratedHelloWorldToStringDALEQUEE.class has been generated." + newClass) // Let's test that the new class does what it is expected to do... (we execute the @@ -328,6 +328,9 @@ object TACtoBC { for (param <- params) { ExprUtils.collectFromExpr(param, duVars) } + case PutField(_, _, _, _, objRef, value) => + ExprUtils.collectFromExpr(objRef, duVars) + ExprUtils.collectFromExpr(value, duVars) case NonVirtualMethodCall(_, _, _, _, _, receiver, params) => ExprUtils.collectFromExpr(receiver, duVars) for (param <- params) { From 332682874b29e9a1a81a013e4961a944a9c5eae5 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Tue, 30 Jul 2024 11:00:25 +0200 Subject: [PATCH 004/111] Separated the first pass in own class --- .../{ExprUtils.scala => ExprProcessor.scala} | 104 +------- .../scala/org/opalj/tactobc/FirstPass.scala | 181 ++++++++++++++ .../org/opalj/tactobc/StmtProcessor.scala | 22 +- .../scala/org/opalj/tactobc/TACtoBC.scala | 66 ++---- .../tactobc/testingtactobc/CommandLine.java | 67 ------ .../org/opalj/tactobc/testingtactobc/FFT.java | 168 ------------- ...elloWorldToString.java => HelloWorld.java} | 14 +- .../opalj/tactobc/testingtactobc/Kernel.java | 223 ------------------ .../org/opalj/tactobc/testingtactobc/LU.java | 167 ------------- .../tactobc/testingtactobc/MonteCarlo.java | 29 --- .../org/opalj/tactobc/testingtactobc/SOR.java | 32 --- .../tactobc/testingtactobc/SparseCompRow.java | 30 --- .../org/opalj/tactobc/HelloWorldToString.java | 28 --- .../test/org/opalj/tactobc/scimark-2.2.jar | Bin 0 -> 22619 bytes 14 files changed, 223 insertions(+), 908 deletions(-) rename OPAL/tactobc/src/main/scala/org/opalj/tactobc/{ExprUtils.scala => ExprProcessor.scala} (79%) create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala delete mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/CommandLine.java delete mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/FFT.java rename OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/{HelloWorldToString.java => HelloWorld.java} (70%) delete mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/Kernel.java delete mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/LU.java delete mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/MonteCarlo.java delete mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/SOR.java delete mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/SparseCompRow.java delete mode 100644 OPAL/tactobc/src/test/org/opalj/tactobc/HelloWorldToString.java create mode 100644 OPAL/tactobc/src/test/org/opalj/tactobc/scimark-2.2.jar diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprUtils.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala similarity index 79% rename from OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprUtils.scala rename to OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index dafab03f96..810e04342a 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprUtils.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -6,12 +6,12 @@ import org.opalj.br.{ByteType, CharType, ComputationalTypeDouble, ComputationalT import org.opalj.br.instructions.{ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BIPUSH, D2F, D2I, D2L, DADD, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LAND, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, NEW, SIPUSH} import org.opalj.bytecode.BytecodeProcessingFailedException import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{BinaryExpr, ClassConst, Const, DUVar, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, LongConst, MethodHandleConst, MethodTypeConst, New, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} +import org.opalj.tac.{BinaryExpr, ClassConst, Const, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, LongConst, MethodHandleConst, MethodTypeConst, New, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} import scala.collection.mutable import scala.collection.mutable.ArrayBuffer -object ExprUtils { +object ExprProcessor { def processExpression(expr: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { @@ -29,40 +29,6 @@ object ExprUtils { } } - def collectFromExpr(expr: Expr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - expr match { - case duVar: DUVar[_] => duVars += duVar - case binaryExpr: BinaryExpr[_] => collectFromBinaryExpr(binaryExpr, duVars) - case virtualFunctionCallExpr: VirtualFunctionCall[_] => collectFromVirtualMethodCall(virtualFunctionCallExpr, duVars) - case staticFunctionCallExpr: StaticFunctionCall[_] => collectFromStaticFunctionCall(staticFunctionCallExpr, duVars) - case primitiveTypecaseExpr: PrimitiveTypecastExpr[_] => collectFromPrimitiveTypeCastExpr(primitiveTypecaseExpr, duVars) - case _ => - } - } - - def collectFromPrimitiveTypeCastExpr(primitiveTypecaseExpr: PrimitiveTypecastExpr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - collectFromExpr(primitiveTypecaseExpr.operand, duVars) - } - - def collectFromStaticFunctionCall(staticFunctionCallExpr: StaticFunctionCall[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - // Process each parameter and collect from each - for (param <- staticFunctionCallExpr.params) { - collectFromExpr(param, duVars) - } - } - - def collectFromBinaryExpr(binaryExpr: BinaryExpr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - collectFromExpr(binaryExpr.left, duVars) - collectFromExpr(binaryExpr.right, duVars) - } - - def collectFromVirtualMethodCall(virtualFunctionCallExpr: VirtualFunctionCall[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - collectFromExpr(virtualFunctionCallExpr.receiver, duVars) - for (param <- virtualFunctionCallExpr.params) { - collectFromExpr(param, duVars) - } - } - def handleNewExpr(tpe: ObjectType, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { val instruction = NEW(tpe) instructionsWithPCs += ((currentPC, instruction)) @@ -75,7 +41,7 @@ object ExprUtils { // Process each parameter and update the PC accordingly for (param <- expr.params) { - currentAfterParamsPC = ExprUtils.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) } val instruction = if (expr.isInterface) { INVOKEINTERFACE(expr.declaringClass, expr.name, expr.descriptor) @@ -90,14 +56,14 @@ object ExprUtils { def handleVirtualFunctionCall(expr: VirtualFunctionCall[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // Process the receiver object (e.g., aload_0 for `this`) - val afterReceiverPC = ExprUtils.processExpression(expr.receiver, instructionsWithPCs, currentPC) + val afterReceiverPC = ExprProcessor.processExpression(expr.receiver, instructionsWithPCs, currentPC) // Initialize the PC after processing the receiver var currentAfterParamsPC = afterReceiverPC // Process each parameter and update the PC accordingly for (param <- expr.params) { - currentAfterParamsPC = ExprUtils.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) } val instruction = if (expr.isInterface) { //INVOKEINTERFACE(expr.declaringClass, expr.name, expr.descriptor) @@ -160,74 +126,20 @@ object ExprUtils { currentPC + instruction.length // Update and return the new program counter } - var uvarToLVIndex = mutable.Map[IntTrieSet, Int]() + var uVarToLVIndex = mutable.Map[IntTrieSet, Int]() var nextLVIndex = 1 - def collectAllUVarsAndPopulate(duVars: mutable.ListBuffer[DUVar[_]]): mutable.Map[IntTrieSet, Int] = { - duVars.toArray.foreach { - case uVar : UVar[_] => populateUvarAndDvarToLVIndexMap(uVar) - case _ => - } - uvarToLVIndex - } - - def mapParametersAndPopulate(duVars: mutable.ListBuffer[DUVar[_]]): mutable.Map[IntTrieSet, Int] = { - duVars.foreach { - case uVar: UVar[_] if uVar.defSites.exists(origin => origin < 0) => - // Check if the defSites contain a parameter origin - uVar.defSites.foreach { origin => - if (origin == -1) { - // Assign LV index 0 for 'this' only for instance methods - uvarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) - } else if (origin < -1) { - if (origin == -2) { - // Assign LV index 0 for 'this' only for instance methods - uvarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) - } else { - // Assign LV indexes for parameters - uvarToLVIndex.getOrElseUpdate(IntTrieSet(origin), { - val lvIndex = nextLVIndex - nextLVIndex += 1 - lvIndex - }) - } - } - } - case _ => - } - uvarToLVIndex - } - - def populateUvarAndDvarToLVIndexMap(uVar: UVar[_]): Unit = { - // Check if any existing key contains any of the def-sites - val existingEntry = uvarToLVIndex.find { case (key, _) => key.intersect(uVar.defSites).nonEmpty } - existingEntry match { - case Some((existingDefSites, index)) => - // Merge the def-sites and update the map - val mergedDefSites = existingDefSites ++ uVar.defSites - uvarToLVIndex -= existingDefSites - uvarToLVIndex(mergedDefSites) = index - case None => - // No overlapping def-sites found, add a new entry - uvarToLVIndex.getOrElseUpdate(uVar.defSites, { - val lvIndex = nextLVIndex - nextLVIndex += 1 - lvIndex - }) - } - } - // Method to get LVIndex for a variable def getVariableLvlIndex(variable: Var[_]): Int = { variable match { case dVar: DVar[_] => - val uVarDefSites = uvarToLVIndex.find { case (defSites, _) => defSites.contains(dVar.origin) } + val uVarDefSites = uVarToLVIndex.find { case (defSites, _) => defSites.contains(dVar.origin) } uVarDefSites match { case Some((_, index)) => index case None => throw new NoSuchElementException(s"No LVIndex found for DVar with origin ${dVar.origin}") } case uVar: UVar[_] => - val defSiteMatch = uvarToLVIndex.find { case (defSites, _) => defSites.exists(uVar.defSites.contains) } + val defSiteMatch = uVarToLVIndex.find { case (defSites, _) => defSites.exists(uVar.defSites.contains) } defSiteMatch match { case Some((_, index)) => index case None => throw new NoSuchElementException(s"No LVIndex found for UVar with defSites ${uVar.defSites}") diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala new file mode 100644 index 0000000000..7d5d6f4530 --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -0,0 +1,181 @@ +package org.opalj.tactobc + +import org.opalj.collection.immutable.IntTrieSet +import org.opalj.tac.{Assignment, BinaryExpr, DUVar, Expr, If, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, ReturnValue, StaticFunctionCall, Stmt, UVar, VirtualFunctionCall, VirtualMethodCall} +import org.opalj.tactobc.ExprProcessor.{nextLVIndex, uVarToLVIndex} +import org.opalj.value.ValueInformation + +import scala.collection.mutable + +object FirstPass { + + /** + * Collects all DUVars of the current method, adds parameters (if given) in the first available LVIndexes, + * populates then the uVarToLVIndex map so that each used (and unique) variable does have a unique LVIndex. + * @param stmt translateSingleTACtoBC iterates through all exisiting stmts for the method to be translated. + * The parameter "stmt" represents the current stmt to be inspected + * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method + */ + def prepareLVIndexes(tacStmts: Array[(Stmt[DUVar[ValueInformation]], Int)], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + tacStmts.foreach { case (stmt, _) => { + stmt match { + case Assignment(_, targetVar, expr) => + collectDUVarFromExpr(targetVar, duVars) + collectDUVarFromExpr(expr, duVars) + case If(_, left, _, right, _) => + collectDUVarFromExpr(left, duVars) + collectDUVarFromExpr(right, duVars) + case VirtualMethodCall(_, _, _, _, _, receiver, params) => + collectDUVarFromExpr(receiver, duVars) + for (param <- params) { + collectDUVarFromExpr(param, duVars) + } + case PutField(_, _, _, _, objRef, value) => + collectDUVarFromExpr(objRef, duVars) + collectDUVarFromExpr(value, duVars) + case NonVirtualMethodCall(_, _, _, _, _, receiver, params) => + collectDUVarFromExpr(receiver, duVars) + for (param <- params) { + collectDUVarFromExpr(param, duVars) + } + case ReturnValue(_, expr) => + collectDUVarFromExpr(expr, duVars) + case _ => + } + } + } + // give the first available indexes to parameters + val parameters = mapParametersAndPopulate(duVars) + println(parameters) + val lvIndexMap = collectAllUVarsAndPopulateUVarToLVIndexMap(duVars) + println(lvIndexMap) + } + + /** + * Filters all UVars of the duVars map in the parameter and populates the uVarToLVIndex map in order so that + * each unique uVar has a unique LVIndex + * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method + * @return a mutable.Map[IntTrieSet, Int]: the IntTrieSet corresponds a UVars defsites, the Int represents the LVIndex + */ + def collectAllUVarsAndPopulateUVarToLVIndexMap(duVars: mutable.ListBuffer[DUVar[_]]): mutable.Map[IntTrieSet, Int] = { + duVars.toArray.foreach { + case uVar : UVar[_] => populateUvarToLVIndexMap(uVar) + case _ => + } + uVarToLVIndex + } + + /** + * Gives the first available LVIndexes to the parameters of the method + * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method + * @return a mutable.Map[IntTrieSet, Int]: the IntTrieSet corresponds a UVars defsites, the Int represents the LVIndex + */ + def mapParametersAndPopulate(duVars: mutable.ListBuffer[DUVar[_]]): mutable.Map[IntTrieSet, Int] = { + duVars.foreach { + case uVar: UVar[_] if uVar.defSites.exists(origin => origin < 0) => + // Check if the defSites contain a parameter origin + uVar.defSites.foreach { origin => + if (origin == -1) { + // Assign LV index 0 for 'this' only for instance methods + uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) + } else if (origin < -1) { + if (origin == -2) { + // Assign LV index 0 for 'this' only for instance methods + uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) + } else { + // Assign LV indexes for parameters + uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), { + val lvIndex = nextLVIndex + nextLVIndex += 1 + lvIndex + }) + } + } + } + case _ => + } + uVarToLVIndex + } + + /** + * Populates the uVarToLVIndex map by givin each unique uVar a unique LVIndex + * @param uVar an used variable + */ + def populateUvarToLVIndexMap(uVar: UVar[_]): Unit = { + // Check if any existing key contains any of the def-sites + val existingEntry = uVarToLVIndex.find { case (key, _) => key.intersect(uVar.defSites).nonEmpty } + existingEntry match { + case Some((existingDefSites, index)) => + // Merge the def-sites and update the map + val mergedDefSites = existingDefSites ++ uVar.defSites + uVarToLVIndex -= existingDefSites + uVarToLVIndex(mergedDefSites) = index + case None => + // No overlapping def-sites found, add a new entry + uVarToLVIndex.getOrElseUpdate(uVar.defSites, { + val lvIndex = nextLVIndex + nextLVIndex += 1 + lvIndex + }) + } + } + + /** + * Helper method to traverse over expressions and collect the DUVars "embedded" in them + * @param expr the expression to be traversed + * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method + */ + def collectDUVarFromExpr(expr: Expr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + expr match { + case duVar: DUVar[_] => duVars += duVar + case binaryExpr: BinaryExpr[_] => collectDUVarFromBinaryExpr(binaryExpr, duVars) + case virtualFunctionCallExpr: VirtualFunctionCall[_] => collectDUVarFromVirtualMethodCall(virtualFunctionCallExpr, duVars) + case staticFunctionCallExpr: StaticFunctionCall[_] => collectDUVarFromStaticFunctionCall(staticFunctionCallExpr, duVars) + case primitiveTypecaseExpr: PrimitiveTypecastExpr[_] => collectDUVarFromPrimitiveTypeCastExpr(primitiveTypecaseExpr, duVars) + case _ => + } + } + + /** + * Helper method to traverse through a PrimitiveTypeCastExpr and collect the DUVars + * @param primitiveTypecaseExpr an Expr of type PrimitiveTypecastExpr + * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method + */ + def collectDUVarFromPrimitiveTypeCastExpr(primitiveTypecaseExpr: PrimitiveTypecastExpr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectDUVarFromExpr(primitiveTypecaseExpr.operand, duVars) + } + + /** + * Helper method to traverse through a StaticFunctionCall Expr and collect the DUVars + * @param staticFunctionCallExpr an Expr of type StaticFunctionCall + * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method + */ + def collectDUVarFromStaticFunctionCall(staticFunctionCallExpr: StaticFunctionCall[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + // Process each parameter and collect from each + for (param <- staticFunctionCallExpr.params) { + collectDUVarFromExpr(param, duVars) + } + } + + /** + * Helper method to traverse through a BinaryExpr Expr and collect the DUVars + * @param binaryExpr an Expr of type BinaryExpr + * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method + */ + def collectDUVarFromBinaryExpr(binaryExpr: BinaryExpr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectDUVarFromExpr(binaryExpr.left, duVars) + collectDUVarFromExpr(binaryExpr.right, duVars) + } + + /** + * Helper method to traverse through a VirtualFunctionCall Expr and collect the DUVars + * @param virtualFunctionCallExpr an Expr of type VirtualFunctionCall + * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method + */ + def collectDUVarFromVirtualMethodCall(virtualFunctionCallExpr: VirtualFunctionCall[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectDUVarFromExpr(virtualFunctionCallExpr.receiver, duVars) + for (param <- virtualFunctionCallExpr.params) { + collectDUVarFromExpr(param, duVars) + } + } +} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index eaf8adeb3d..da565ec06f 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -16,16 +16,16 @@ object StmtProcessor { //Assignment def processAssignment(targetVar: Var[_], expr: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // Evaluate the RHS and update the PC accordingly - val afterExprPC = ExprUtils.processExpression(expr, instructionsWithPCs, currentPC) + val afterExprPC = ExprProcessor.processExpression(expr, instructionsWithPCs, currentPC) // Store the result into the target variable and update the PC - val finalPC = ExprUtils.storeVariable(targetVar, instructionsWithPCs, afterExprPC) + val finalPC = ExprProcessor.storeVariable(targetVar, instructionsWithPCs, afterExprPC) // Return the updated PC finalPC } def processSwitch(defaultOffset: Int, index: Expr[_], npairs: ArraySeq[IntIntPair /*(Case Value, Jump Target)*/], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // Translate the index expression first - val afterExprPC = ExprUtils.processExpression(index, instructionsWithPCs, currentPC) + val afterExprPC = ExprProcessor.processExpression(index, instructionsWithPCs, currentPC) // Prepare the bytecode pairs with placeholders for targets val bCnpairs = prepareBCnpairs(npairs) @@ -83,7 +83,7 @@ object StmtProcessor { } def processReturnValue(expr: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val afterExprPC = ExprUtils.processExpression(expr, instructionsWithPCs, currentPC) + val afterExprPC = ExprProcessor.processExpression(expr, instructionsWithPCs, currentPC) val instruction = expr.cTpe match { case ComputationalTypeInt => IRETURN case ComputationalTypeLong => LRETURN @@ -99,14 +99,14 @@ object StmtProcessor { def processVirtualMethodCall(declaringClass: ReferenceType, isInterface: Boolean, methodName: String, methodDescriptor: MethodDescriptor, receiver: Expr[_], params: Seq[Expr[_]], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // Process the receiver object (e.g., aload_0 for `this`) - val afterReceiverPC = ExprUtils.processExpression(receiver, instructionsWithPCs, currentPC) + val afterReceiverPC = ExprProcessor.processExpression(receiver, instructionsWithPCs, currentPC) // Initialize the PC after processing the receiver var currentAfterParamsPC = afterReceiverPC // Process each parameter and update the PC accordingly for (param <- params) { - currentAfterParamsPC = ExprUtils.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) } val instruction = { /*if (isInterface) { @@ -188,14 +188,14 @@ object StmtProcessor { } def processNonVirtualMethodCall(declaringClass: ObjectType, isInterface: Boolean, methodName: String, methodDescriptor: MethodDescriptor, receiver: Expr[_], params: Seq[Expr[_]], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val afterReceiverPC = ExprUtils.processExpression(receiver, instructionsWithPCs, currentPC) + val afterReceiverPC = ExprProcessor.processExpression(receiver, instructionsWithPCs, currentPC) // Initialize the PC after processing the receiver var currentAfterParamsPC = afterReceiverPC // Process each parameter and update the PC accordingly for (param <- params) { - currentAfterParamsPC = ExprUtils.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) } val instruction = INVOKESPECIAL(declaringClass, isInterface, methodName, methodDescriptor) val finalPC = currentPC + currentAfterParamsPC @@ -209,7 +209,7 @@ object StmtProcessor { // Process each parameter and update the PC accordingly for (param <- params) { - currentAfterParamsPC = ExprUtils.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) } val instruction = INVOKESTATIC(declaringClass, isInterface, methodName, methodDescriptor) instructionsWithPCs += ((currentAfterParamsPC, instruction)) @@ -225,9 +225,9 @@ object StmtProcessor { def processIf(left: Expr[_], condition: RelationalOperator, right: Expr[_], gotoLabel: Int, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // process the left expr and save the pc to give in the right expr processing - val leftPC = ExprUtils.processExpression(left, instructionsWithPCs, currentPC) + val leftPC = ExprProcessor.processExpression(left, instructionsWithPCs, currentPC) // process the right expr - val rightPC = ExprUtils.processExpression(right, instructionsWithPCs, leftPC) + val rightPC = ExprProcessor.processExpression(right, instructionsWithPCs, leftPC) generateIfInstruction(left, condition, right, instructionsWithPCs, currentPC, rightPC) } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala index a5edd9381e..ed0b698ebe 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala @@ -1,5 +1,5 @@ /* BSD 2-Clause License - see OPAL/LICENSE for details. */ -package org.opalj.tac.tactobc +package org.opalj.tactobc import org.opalj.ba.CodeAttributeBuilder.computeStackMapTable import org.opalj.ba.toDA @@ -16,7 +16,7 @@ import org.opalj.util.InMemoryClassLoader import java.io.ByteArrayInputStream import java.nio.file.{Files, Paths} import org.opalj.tac._ -import org.opalj.tactobc.{ExprUtils, StmtProcessor} +import org.opalj.tactobc.{ExprProcessor, FirstPass, StmtProcessor} import org.opalj.value.ValueInformation import java.io.File @@ -60,7 +60,7 @@ object TACtoBC { bytecode.foreach(instr => println(instr.toString)) } - val TheType = ObjectType("org/opalj/tactobc/testingtactobc/Stopwatch") + val TheType = ObjectType("org/opalj/tactobc/testingtactobc/HelloWorld") // Debugging: Print the location of the class loader and resources val loader = this.getClass.getClassLoader @@ -68,10 +68,9 @@ object TACtoBC { println(s"ClassLoader: $loader") println(s"Resources: ${resources.mkString(", ")}") - val in = () => { - val stream = this.getClass.getResourceAsStream("/org/opalj/tactobc/testingtactobc/Stopwatch.class") - if (stream == null) throw new RuntimeException("Resource not found: /Stopwatch.class") + val stream = this.getClass.getResourceAsStream("/org/opalj/tactobc/testingtactobc/HelloWorld.class") + if (stream == null) throw new RuntimeException("Resource not found: /HelloWorld.class") stream } val cf = Java8Framework.ClassFile(in).head @@ -203,18 +202,18 @@ object TACtoBC { } val cfWithNewInstructionsForReal = cf.copy(methods = newMethodsForReal) val newRawCF = Assembler(toDA(cfWithNewInstructionsForReal)) - val assembledMyIntfPath = Paths.get("tmp", "org", "opalj", "tactobc", "testingtactobc", "Stopwatch.class") + val assembledMyIntfPath = Paths.get("tmp", "org", "opalj", "tactobc", "testingtactobc", "HelloWorld.class") val newClassFile = Files.write(assembledMyIntfPath, newRawCF) println("Created class file: " + newClassFile.toAbsolutePath) // Let's see the old class file... val odlCFHTML = ClassFile(in).head.toXHTML(None) - val oldCFHTMLFile = writeAndOpen(odlCFHTML, "Stopwatch", ".html") + val oldCFHTMLFile = writeAndOpen(odlCFHTML, "HelloWorld", ".html") println("original: " + oldCFHTMLFile) // Let's see the new class file... val newCF = ClassFile(() => new ByteArrayInputStream(newRawCF)).head.toXHTML(None) - println("genetated from TAC: " + writeAndOpen(newCF, "Stopwatch", ".html")) + println("genetated from TAC: " + writeAndOpen(newCF, "HelloWorld", ".html")) //println("Class file GeneratedHelloWorldToStringDALEQUEE.class has been generated." + newClass) // Let's test that the new class does what it is expected to do... (we execute the @@ -299,7 +298,7 @@ object TACtoBC { } /** - * Converts the TAC representation of a single method into bytecode instructions. + * Converts the TAC Stmts of a single method into bytecode instructions. * * This helper method processes one method's TAC representation at a time, converting it into a sequence * of bytecode instructions. It handles various types of TAC statements and expressions, translating them @@ -310,45 +309,14 @@ object TACtoBC { */ def translateSingleTACtoBC(tac: AITACode[TACMethodParameter, ValueInformation]): ArrayBuffer[(Int, Instruction)] = { val generatedByteCodeWithPC = ArrayBuffer[(Int, Instruction)]() + val tacStmts = tac.stmts.zipWithIndex + //first pass + val duVars = mutable.ListBuffer[DUVar[_]]() + FirstPass.prepareLVIndexes(tacStmts, duVars) + //second pass var currentPC = 0 val tacTargetToByteCodePcs = ArrayBuffer[(Int, Int)]() val switchCases = ArrayBuffer[(Int, Int)]() // To store switch case targets - val duVars = mutable.ListBuffer[DUVar[_]]() - val tacStmts = tac.stmts.zipWithIndex - tacStmts.foreach { case (stmt, _) => - stmt match { - case Assignment(_, targetVar, expr) => - ExprUtils.collectFromExpr(targetVar, duVars) - ExprUtils.collectFromExpr(expr, duVars) - case If(_, left, _, right, _) => - ExprUtils.collectFromExpr(left, duVars) - ExprUtils.collectFromExpr(right, duVars) - case VirtualMethodCall(_, _, _, _, _, receiver, params) => - ExprUtils.collectFromExpr(receiver, duVars) - for (param <- params) { - ExprUtils.collectFromExpr(param, duVars) - } - case PutField(_, _, _, _, objRef, value) => - ExprUtils.collectFromExpr(objRef, duVars) - ExprUtils.collectFromExpr(value, duVars) - case NonVirtualMethodCall(_, _, _, _, _, receiver, params) => - ExprUtils.collectFromExpr(receiver, duVars) - for (param <- params) { - ExprUtils.collectFromExpr(param, duVars) - } - case ReturnValue(_, expr) => - ExprUtils.collectFromExpr(expr, duVars) - case _ => - } - } - val resultDUVars = duVars - println(resultDUVars) - //ExprUtils.populateVariableLVIndexMap(duVars) - val parameters = ExprUtils.mapParametersAndPopulate(duVars) - println(parameters) - val resultingLVIndexMap = ExprUtils.collectAllUVarsAndPopulate(duVars) - println(resultingLVIndexMap) - //first pass tacStmts.foreach { case (stmt, _) => stmt match { case Assignment(_, targetVar, expr) => @@ -362,7 +330,7 @@ object TACtoBC { currentPC = StmtProcessor.processCaughtException(exceptionType, throwingStmts, generatedByteCodeWithPC, currentPC) case ExprStmt(_, expr) => tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = ExprUtils.processExpression(expr, generatedByteCodeWithPC, currentPC) + currentPC = ExprProcessor.processExpression(expr, generatedByteCodeWithPC, currentPC) case If(_, left, condition, right, target) => tacTargetToByteCodePcs += ((target, currentPC)) currentPC = StmtProcessor.processIf(left, condition, right, target, generatedByteCodeWithPC, currentPC) @@ -485,8 +453,8 @@ object TACtoBC { tacTargetToByteCodePcsIndex += 1 } } - ExprUtils.uvarToLVIndex = mutable.Map[IntTrieSet, Int]() - ExprUtils.nextLVIndex = 1 + ExprProcessor.uVarToLVIndex = mutable.Map[IntTrieSet, Int]() + ExprProcessor.nextLVIndex = 1 result } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/CommandLine.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/CommandLine.java deleted file mode 100644 index 24e29ffaca..0000000000 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/CommandLine.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.opalj.tactobc.testingtactobc; - -import java.util.Random; - -public class CommandLine { - private static final String[] DUMP_PROPERTIES = new String[]{"java.vendor", "java.version", "os.arch", "os.name", "os.version"}; - - public CommandLine() { - } - - public static void main(String[] args) { - System.out.println(); - System.out.println("SciMark " + CommandLine.class.getPackage().getImplementationVersion()); - System.out.println(); - double min_time = 2.0; - int FFT_size = 1024; - int SOR_size = 100; - int Sparse_size_M = 1000; - int Sparse_size_nz = 5000; - int LU_size = 100; - if (args.length > 0) { - if (args[0].equalsIgnoreCase("-h") || args[0].equalsIgnoreCase("-help")) { - System.out.println("Usage: [-large] [minimum_time]"); - return; - } - - int current_arg = 0; - if (args[current_arg].equalsIgnoreCase("-large")) { - FFT_size = 1048576; - SOR_size = 1000; - Sparse_size_M = 100000; - Sparse_size_nz = 1000000; - LU_size = 1000; - ++current_arg; - } - - if (args.length > current_arg) { - min_time = Double.parseDouble(args[current_arg]); - } - } - - double[] res = new double[6]; - Random R = new Random(101010); - res[1] = Kernel.measureFFT(FFT_size, min_time, R); - res[2] = Kernel.measureSOR(SOR_size, min_time, R); - res[3] = Kernel.measureMonteCarlo(min_time, R); - res[4] = Kernel.measureSparseMatmult(Sparse_size_M, Sparse_size_nz, min_time, R); - res[5] = Kernel.measureLU(LU_size, min_time, R); - res[0] = (res[1] + res[2] + res[3] + res[4] + res[5]) / 5.0; - System.out.format("Composite Score: %.2f%n", res[0]); - System.out.format("FFT (%s): %.2f%n", FFT_size, res[1]); - System.out.format("SOR (%s x %s): %.2f%n", Integer.valueOf(SOR_size), Integer.valueOf(SOR_size), res[2]); - System.out.format("Monte Carlo: %.2f%n", res[3]); - System.out.format("Sparse matmult (N=%s, nz=%s): %.2f%n", Sparse_size_M, Sparse_size_nz, res[4]); - System.out.format("LU (%s x %s ): %.2f%n", Integer.valueOf(LU_size), Integer.valueOf(LU_size), res[5]); - System.out.println(); - String[] var10 = DUMP_PROPERTIES; - int var11 = var10.length; - - for(int var12 = 0; var12 < var11; ++var12) { - String property = var10[var12]; - System.out.println(property + ": " + System.getProperty(property)); - } - - } -} - diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/FFT.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/FFT.java deleted file mode 100644 index 37bc5663aa..0000000000 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/FFT.java +++ /dev/null @@ -1,168 +0,0 @@ -package org.opalj.tactobc.testingtactobc; - -public class FFT { - public FFT() { - } - - public static double num_flops(int N) { - double logN = (double)log2(N); - return (5.0 * (double)N - 2.0) * logN + 2.0 * ((double)N + 1.0); - } - - public static void transform(double[] data) { - transform_internal(data, -1); - } - - public static void inverse(double[] data) { - transform_internal(data, 1); - int nd = data.length; - int n = nd / 2; - double norm = 1.0 / (double)n; - - for(int i = 0; i < nd; ++i) { - data[i] *= norm; - } - - } - - public static double test(double[] data) { - int nd = data.length; - double[] copy = new double[nd]; - System.arraycopy(data, 0, copy, 0, nd); - transform(data); - inverse(data); - double diff = 0.0; - - for(int i = 0; i < nd; ++i) { - double d = data[i] - copy[i]; - diff += d * d; - } - - return Math.sqrt(diff / (double)nd); - } - - public static double[] makeRandom(int n) { - int nd = 2 * n; - double[] data = new double[nd]; - - for(int i = 0; i < nd; ++i) { - data[i] = Math.random(); - } - - return data; - } - - public static void main(String[] args) { - int i; - if (args.length == 0) { - i = 1024; - System.out.println("n=" + i + " => RMS Error=" + test(makeRandom(i))); - } - - for(i = 0; i < args.length; ++i) { - int n = Integer.parseInt(args[i]); - System.out.println("n=" + n + " => RMS Error=" + test(makeRandom(n))); - } - - } - - protected static int log2(int n) { - int log = 0; - - for(int k = 1; k < n; ++log) { - k *= 2; - } - - if (n != 1 << log) { - throw new Error("FFT: Data length is not a power of 2!: " + n); - } else { - return log; - } - } - - protected static void transform_internal(double[] data, int direction) { - if (data.length != 0) { - int n = data.length / 2; - if (n != 1) { - int logn = log2(n); - bitreverse(data); - int bit = 0; - - for(int dual = 1; bit < logn; dual *= 2) { - double w_real = 1.0; - double w_imag = 0.0; - double theta = 2.0 * (double)direction * Math.PI / (2.0 * (double)dual); - double s = Math.sin(theta); - double t = Math.sin(theta / 2.0); - double s2 = 2.0 * t * t; - - int a; - int b; - int i; - double tmp_imag; - for(a = 0; a < n; a += 2 * dual) { - b = 2 * a; - i = 2 * (a + dual); - tmp_imag = data[i]; - double wd_imag = data[i + 1]; - data[i] = data[b] - tmp_imag; - data[i + 1] = data[b + 1] - wd_imag; - data[b] += tmp_imag; - data[b + 1] += wd_imag; - } - - for(a = 1; a < dual; ++a) { - double tmp_real = w_real - s * w_imag - s2 * w_real; - tmp_imag = w_imag + s * w_real - s2 * w_imag; - w_real = tmp_real; - w_imag = tmp_imag; - - for(b = 0; b < n; b += 2 * dual) { - i = 2 * (b + a); - int j = 2 * (b + a + dual); - double z1_real = data[j]; - double z1_imag = data[j + 1]; - double wd_real = w_real * z1_real - w_imag * z1_imag; - double wd_imag = w_real * z1_imag + w_imag * z1_real; - data[j] = data[i] - wd_real; - data[j + 1] = data[i + 1] - wd_imag; - data[i] += wd_real; - data[i + 1] += wd_imag; - } - } - - ++bit; - } - - } - } - } - - protected static void bitreverse(double[] data) { - int n = data.length / 2; - int nm1 = n - 1; - int i = 0; - - for(int j = 0; i < nm1; ++i) { - int ii = i << 1; - int jj = j << 1; - int k = n >> 1; - if (i < j) { - double tmp_real = data[ii]; - double tmp_imag = data[ii + 1]; - data[ii] = data[jj]; - data[ii + 1] = data[jj + 1]; - data[jj] = tmp_real; - data[jj + 1] = tmp_imag; - } - - while(k <= j) { - j -= k; - k >>= 1; - } - - j += k; - } - - } -} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorldToString.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorld.java similarity index 70% rename from OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorldToString.java rename to OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorld.java index 6baa1ca332..08109f9585 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorldToString.java +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorld.java @@ -1,28 +1,26 @@ package org.opalj.tactobc.testingtactobc; -public class HelloWorldToString { - +public class HelloWorld { public static void main(String[] args) { System.out.println("HelloWorld!"); int i = 0; System.out.println(i); int x = 1; - for(; i < 3; i++){ - dumbPrint(i,x); + for (; i < 3; i++) { + dumbPrint(i, x); x++; } - dumbPrint(i,x); + dumbPrint(i, x); } - public static void dumbPrint(int i, int x){ + public static void dumbPrint(int i, int x) { System.out.println("this is a method ".concat(String.valueOf(i))); System.out.println(i); System.out.println(x); foo(); } - public static void foo(){ + public static void foo() { System.out.println("StaticMethod call works :)"); } } - diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/Kernel.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/Kernel.java deleted file mode 100644 index adde8ad1cb..0000000000 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/Kernel.java +++ /dev/null @@ -1,223 +0,0 @@ -package org.opalj.tactobc.testingtactobc; - -import java.util.Random; - -public class Kernel { - public Kernel() { - } - - public static double measureFFT(int N, double mintime, Random R) { - double[] x = RandomVector(2 * N, R); - double[] oldx = NewVectorCopy(x); - long cycles = 1L; - Stopwatch Q = new Stopwatch(); - - while(true) { - Q.start(); - - for(int i = 0; (long)i < cycles; ++i) { - FFT.transform(x); - FFT.inverse(x); - } - - Q.stop(); - if (Q.read() >= mintime) { - double EPS = 1.0E-10; - if (FFT.test(x) / (double)N > 1.0E-10) { - return 0.0; - } - - return FFT.num_flops(N) * (double)cycles / Q.read() * 1.0E-6; - } - - cycles *= 2L; - } - } - - public static double measureSOR(int N, double min_time, Random R) { - double[][] G = RandomMatrix(N, N, R); - Stopwatch Q = new Stopwatch(); - long cycles = 1L; - - while(true) { - Q.start(); - SOR.execute(1.25, G, cycles); - Q.stop(); - if (Q.read() >= min_time) { - return SOR.num_flops(N, N, cycles) / Q.read() * 1.0E-6; - } - - cycles *= 2L; - } - } - - public static double measureMonteCarlo(double min_time, Random R) { - Stopwatch Q = new Stopwatch(); - long cycles = 1L; - - while(true) { - Q.start(); - MonteCarlo.integrate(cycles); - Q.stop(); - if (Q.read() >= min_time) { - return MonteCarlo.num_flops(cycles) / Q.read() * 1.0E-6; - } - - cycles *= 2L; - } - } - - public static double measureSparseMatmult(int N, int nz, double min_time, Random R) { - double[] x = RandomVector(N, R); - double[] y = new double[N]; - int nr = nz / N; - int anz = nr * N; - double[] val = RandomVector(anz, R); - int[] col = new int[anz]; - int[] row = new int[N + 1]; - row[0] = 0; - - for(int r = 0; r < N; ++r) { - int rowr = row[r]; - row[r + 1] = rowr + nr; - int step = r / nr; - if (step < 1) { - step = 1; - } - - for(int i = 0; i < nr; ++i) { - col[rowr + i] = i * step; - } - } - - Stopwatch Q = new Stopwatch(); - long cycles = 1L; - - while(true) { - Q.start(); - SparseCompRow.matmult(y, val, row, col, x, cycles); - Q.stop(); - if (Q.read() >= min_time) { - return SparseCompRow.num_flops(N, nz, cycles) / Q.read() * 1.0E-6; - } - - cycles *= 2L; - } - } - - public static double measureLU(int N, double min_time, Random R) { - double[][] A = RandomMatrix(N, N, R); - double[][] lu = new double[N][N]; - int[] pivot = new int[N]; - Stopwatch Q = new Stopwatch(); - long cycles = 1L; - - while(true) { - Q.start(); - - for(int i = 0; (long)i < cycles; ++i) { - CopyMatrix(lu, A); - LU.factor(lu, pivot); - } - - Q.stop(); - if (Q.read() >= min_time) { - double[] b = RandomVector(N, R); - double[] x = NewVectorCopy(b); - LU.solve(lu, pivot, x); - double EPS = 1.0E-12; - if (normabs(b, matvec(A, x)) / (double)N > 1.0E-12) { - return 0.0; - } - - return LU.num_flops(N) * (double)cycles / Q.read() * 1.0E-6; - } - - cycles *= 2L; - } - } - - private static double[] NewVectorCopy(double[] x) { - int N = x.length; - double[] y = new double[N]; - System.arraycopy(x, 0, y, 0, N); - return y; - } - - private static double normabs(double[] x, double[] y) { - int N = x.length; - double sum = 0.0; - - for(int i = 0; i < N; ++i) { - sum += Math.abs(x[i] - y[i]); - } - - return sum; - } - - private static void CopyMatrix(double[][] B, double[][] A) { - int M = A.length; - int N = A[0].length; - int remainder = N & 3; - - for(int i = 0; i < M; ++i) { - double[] Bi = B[i]; - double[] Ai = A[i]; - System.arraycopy(Ai, 0, Bi, 0, remainder); - - for(int j = remainder; j < N; j += 4) { - Bi[j] = Ai[j]; - Bi[j + 1] = Ai[j + 1]; - Bi[j + 2] = Ai[j + 2]; - Bi[j + 3] = Ai[j + 3]; - } - } - - } - - private static double[][] RandomMatrix(int M, int N, Random R) { - double[][] A = new double[M][N]; - - for(int i = 0; i < N; ++i) { - for(int j = 0; j < N; ++j) { - A[i][j] = R.nextDouble(); - } - } - - return A; - } - - private static double[] RandomVector(int N, Random R) { - double[] A = new double[N]; - - for(int i = 0; i < N; ++i) { - A[i] = R.nextDouble(); - } - - return A; - } - - private static double[] matvec(double[][] A, double[] x) { - int N = x.length; - double[] y = new double[N]; - matvec(A, x, y); - return y; - } - - private static void matvec(double[][] A, double[] x, double[] y) { - int M = A.length; - int N = A[0].length; - - for(int i = 0; i < M; ++i) { - double sum = 0.0; - double[] Ai = A[i]; - - for(int j = 0; j < N; ++j) { - sum += Ai[j] * x[j]; - } - - y[i] = sum; - } - - } -} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/LU.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/LU.java deleted file mode 100644 index e9c7820562..0000000000 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/LU.java +++ /dev/null @@ -1,167 +0,0 @@ -package org.opalj.tactobc.testingtactobc; - -public class LU { - private final double[][] LU_; - private final int[] pivot_; - - public LU(double[][] A) { - int M = A.length; - int N = A[0].length; - this.LU_ = new double[M][N]; - insert_copy(this.LU_, A); - this.pivot_ = new int[M]; - factor(this.LU_, this.pivot_); - } - - public static double num_flops(int N) { - return 2.0 * (double)N * (double)N * (double)N / 3.0; - } - - protected static double[] new_copy(double[] x) { - int N = x.length; - double[] T = new double[N]; - System.arraycopy(x, 0, T, 0, N); - return T; - } - - protected static double[][] new_copy(double[][] A) { - int M = A.length; - int N = A[0].length; - double[][] T = new double[M][N]; - - for(int i = 0; i < M; ++i) { - double[] Ti = T[i]; - double[] Ai = A[i]; - System.arraycopy(Ai, 0, Ti, 0, N); - } - - return T; - } - - public static int[] new_copy(int[] x) { - int N = x.length; - int[] T = new int[N]; - System.arraycopy(x, 0, T, 0, N); - return T; - } - - protected static void insert_copy(double[][] B, double[][] A) { - int M = A.length; - int N = A[0].length; - int remainder = N & 3; - - for(int i = 0; i < M; ++i) { - double[] Bi = B[i]; - double[] Ai = A[i]; - System.arraycopy(Ai, 0, Bi, 0, remainder); - - for(int j = remainder; j < N; j += 4) { - Bi[j] = Ai[j]; - Bi[j + 1] = Ai[j + 1]; - Bi[j + 2] = Ai[j + 2]; - Bi[j + 3] = Ai[j + 3]; - } - } - - } - - public static int factor(double[][] A, int[] pivot) { - int N = A.length; - int M = A[0].length; - int minMN = Math.min(M, N); - - for(int j = 0; j < minMN; ++j) { - int jp = j; - double t = Math.abs(A[j][j]); - - int ii; - for(ii = j + 1; ii < M; ++ii) { - double ab = Math.abs(A[ii][j]); - if (ab > t) { - jp = ii; - t = ab; - } - } - - pivot[j] = jp; - if (A[jp][j] == 0.0) { - return 1; - } - - if (jp != j) { - double[] tA = A[j]; - A[j] = A[jp]; - A[jp] = tA; - } - - if (j < M - 1) { - double recp = 1.0 / A[j][j]; - - for(int k = j + 1; k < M; ++k) { - A[k][j] *= recp; - } - } - - if (j < minMN - 1) { - for(ii = j + 1; ii < M; ++ii) { - double[] Aii = A[ii]; - double[] Aj = A[j]; - double AiiJ = Aii[j]; - - for(int jj = j + 1; jj < N; ++jj) { - Aii[jj] -= AiiJ * Aj[jj]; - } - } - } - } - - return 0; - } - - public static void solve(double[][] LU, int[] pvt, double[] b) { - int M = LU.length; - int N = LU[0].length; - int ii = 0; - - int i; - for(i = 0; i < M; ++i) { - int ip = pvt[i]; - double sum = b[ip]; - b[ip] = b[i]; - if (ii == 0) { - for(int j = ii; j < i; ++j) { - sum -= LU[i][j] * b[j]; - } - } else if (sum == 0.0) { - ii = i; - } - - b[i] = sum; - } - - for(i = N - 1; i >= 0; --i) { - double sum = b[i]; - - for(int j = i + 1; j < N; ++j) { - sum -= LU[i][j] * b[j]; - } - - b[i] = sum / LU[i][i]; - } - - } - - public double[][] getLU() { - return new_copy(this.LU_); - } - - public int[] getPivot() { - return new_copy(this.pivot_); - } - - public double[] solve(double[] b) { - double[] x = new_copy(b); - solve(this.LU_, this.pivot_, x); - return x; - } -} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/MonteCarlo.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/MonteCarlo.java deleted file mode 100644 index e92aef670e..0000000000 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/MonteCarlo.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.opalj.tactobc.testingtactobc; - -import java.util.Random; - -public class MonteCarlo { - static final int SEED = 113; - - public MonteCarlo() { - } - - public static double num_flops(long Num_samples) { - return (double)Num_samples * 4.0; - } - - public static double integrate(long Num_samples) { - Random R = new Random(113); - long under_curve = 0L; - - for(long count = 0L; count < Num_samples; ++count) { - double x = R.nextDouble(); - double y = R.nextDouble(); - if (x * x + y * y <= 1.0) { - ++under_curve; - } - } - - return (double)under_curve / (double)Num_samples * 4.0; - } -} \ No newline at end of file diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/SOR.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/SOR.java deleted file mode 100644 index 5f3e8468ac..0000000000 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/SOR.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.opalj.tactobc.testingtactobc; - -public class SOR { - public SOR() { - } - - public static double num_flops(int M, int N, long num_iterations) { - return ((double)M - 1.0) * ((double)N - 1.0) * (double)num_iterations * 6.0; - } - - public static void execute(double omega, double[][] G, long num_iterations) { - int M = G.length; - int N = G[0].length; - double omega_over_four = omega * 0.25; - double one_minus_omega = 1.0 - omega; - int Mm1 = M - 1; - int Nm1 = N - 1; - - for(long p = 0L; p < num_iterations; ++p) { - for(int i = 1; i < Mm1; ++i) { - double[] Gi = G[i]; - double[] Gim1 = G[i - 1]; - double[] Gip1 = G[i + 1]; - - for(int j = 1; j < Nm1; ++j) { - Gi[j] = omega_over_four * (Gim1[j] + Gip1[j] + Gi[j - 1] + Gi[j + 1]) + one_minus_omega * Gi[j]; - } - } - } - - } -} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/SparseCompRow.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/SparseCompRow.java deleted file mode 100644 index efbf082891..0000000000 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/SparseCompRow.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.opalj.tactobc.testingtactobc; - -public class SparseCompRow { - public SparseCompRow() { - } - - public static double num_flops(int N, int nz, long num_iterations) { - int actual_nz = nz / N * N; - return (double)actual_nz * 2.0 * (double)num_iterations; - } - - public static void matmult(double[] y, double[] val, int[] row, int[] col, double[] x, long NUM_ITERATIONS) { - int M = row.length - 1; - - for(long reps = 0L; reps < NUM_ITERATIONS; ++reps) { - for(int r = 0; r < M; ++r) { - double sum = 0.0; - int rowR = row[r]; - int rowRp1 = row[r + 1]; - - for(int i = rowR; i < rowRp1; ++i) { - sum += x[col[i]] * val[i]; - } - - y[r] = sum; - } - } - - } -} diff --git a/OPAL/tactobc/src/test/org/opalj/tactobc/HelloWorldToString.java b/OPAL/tactobc/src/test/org/opalj/tactobc/HelloWorldToString.java deleted file mode 100644 index 272eb60924..0000000000 --- a/OPAL/tactobc/src/test/org/opalj/tactobc/HelloWorldToString.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.opalj.tactobc.testingtactobc; - -public class HelloWorldToString { - - public static void main(String[] args) { - System.out.println("Holi Fiooooo"); - int i = 0; - System.out.println(i); - int x = 1; - for(; i < 6; i++){ - dumbPrint(i,x); - x++; - } - dumbPrint(i,x); - } - - public static void dumbPrint(int i, int x){ - System.out.println("esto es de otro metodo".concat(String.valueOf(i))); - System.out.println(i); - System.out.println(x); - foo(); - } - - public static void foo(){ - System.out.println("y este tambien, osea mi StaticMethodCall funciona :D"); - } -} - diff --git a/OPAL/tactobc/src/test/org/opalj/tactobc/scimark-2.2.jar b/OPAL/tactobc/src/test/org/opalj/tactobc/scimark-2.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..56f3dddaff29433fbeab3afaae21b7d7eed4f863 GIT binary patch literal 22619 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

-b|O^PpumqzP|zWC3uIMP<|VV(VwPzpDM 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 literal 0 HcmV?d00001 From 59695c99139a302b35b37a5c70ed6986d97302ea Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Tue, 30 Jul 2024 11:13:51 +0200 Subject: [PATCH 005/111] Separated the second pass in own class --- .../scala/org/opalj/tactobc/SecondPass.scala | 86 +++++++++++++++++++ .../scala/org/opalj/tactobc/TACtoBC.scala | 83 ++---------------- 2 files changed, 92 insertions(+), 77 deletions(-) create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala new file mode 100644 index 0000000000..211ab5db3a --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala @@ -0,0 +1,86 @@ +package org.opalj.tactobc + +import org.opalj.br.instructions.Instruction +import org.opalj.tac.{ArrayStore, Assignment, CaughtException, Checkcast, DUVar, ExprStmt, Goto, If, InvokedynamicMethodCall, JSR, MonitorEnter, MonitorExit, NonVirtualMethodCall, PutField, PutStatic, Ret, Return, ReturnValue, StaticMethodCall, Stmt, Switch, Throw, VirtualMethodCall} +import org.opalj.value.ValueInformation + +import scala.collection.mutable.ArrayBuffer + +object SecondPass { + + def translateStmtsToInstructions(tacStmts: Array[(Stmt[DUVar[ValueInformation]], Int)], generatedByteCodeWithPC: ArrayBuffer[(Int, Instruction)], tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], switchCases: ArrayBuffer[(Int, Int)]): Unit = { + var currentPC = 0 + tacStmts.foreach { case (stmt, _) => + stmt match { + case Assignment(_, targetVar, expr) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processAssignment(targetVar, expr, generatedByteCodeWithPC, currentPC) + case ArrayStore(_, arrayRef, index, value) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processArrayStore(arrayRef, index, value, generatedByteCodeWithPC, currentPC) + case CaughtException(_, exceptionType, throwingStmts) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processCaughtException(exceptionType, throwingStmts, generatedByteCodeWithPC, currentPC) + case ExprStmt(_, expr) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = ExprProcessor.processExpression(expr, generatedByteCodeWithPC, currentPC) + case If(_, left, condition, right, target) => + tacTargetToByteCodePcs += ((target, currentPC)) + currentPC = StmtProcessor.processIf(left, condition, right, target, generatedByteCodeWithPC, currentPC) + case Goto(_, target) => + tacTargetToByteCodePcs += ((target, currentPC)) + currentPC = StmtProcessor.processGoto(generatedByteCodeWithPC, currentPC) + case Switch(_, defaultTarget, index, npairs) => + npairs.foreach { pair => + switchCases += ((pair._1, pair._2)) //case values to jump target + } + tacTargetToByteCodePcs += ((defaultTarget, currentPC)) + currentPC = StmtProcessor.processSwitch(defaultTarget, index, npairs, generatedByteCodeWithPC, currentPC) + case JSR(_, target) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processJSR(target, generatedByteCodeWithPC, currentPC) + case VirtualMethodCall(_, declaringClass, isInterface, name, descriptor, receiver, params) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processVirtualMethodCall(declaringClass, isInterface, name, descriptor, receiver, params, generatedByteCodeWithPC, currentPC) + case NonVirtualMethodCall(_, declaringClass, isInterface, name, descriptor, receiver, params) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processNonVirtualMethodCall(declaringClass, isInterface, name, descriptor, receiver, params, generatedByteCodeWithPC, currentPC) + case StaticMethodCall(_, declaringClass, isInterface, name, descriptor, params) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processStaticMethodCall(declaringClass, isInterface, name, descriptor, params, generatedByteCodeWithPC, currentPC) + case InvokedynamicMethodCall(_, bootstrapMethod, name, descriptor, params) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processInvokeDynamicMethodCall(bootstrapMethod, name, descriptor, params) + case MonitorEnter(_, objRef) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processMonitorEnter(objRef, generatedByteCodeWithPC, currentPC) + case MonitorExit(_, objRef) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processMonitorExit(objRef, generatedByteCodeWithPC, currentPC) + case PutField(_, declaringClass, name, declaredFieldType, objRef, value) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processPutField(declaringClass, name, declaredFieldType, objRef, value, generatedByteCodeWithPC, currentPC) + case PutStatic(_, declaringClass, name, declaredFieldType, value) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processPutStatic(declaringClass, name, declaredFieldType, value, generatedByteCodeWithPC, currentPC) + case Checkcast(_, value, cmpTpe) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processCheckCast(value, cmpTpe, generatedByteCodeWithPC, currentPC) + case Ret(_, returnAddresses) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processRet(returnAddresses, generatedByteCodeWithPC, currentPC) + case ReturnValue(_, expr) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processReturnValue(expr, generatedByteCodeWithPC, currentPC) + case Return(_) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processReturn(generatedByteCodeWithPC, currentPC) + case Throw(_, exception) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processThrow(exception, generatedByteCodeWithPC, currentPC) + case _ => + } + } + } + +} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala index ed0b698ebe..49aa67f296 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala @@ -16,7 +16,7 @@ import org.opalj.util.InMemoryClassLoader import java.io.ByteArrayInputStream import java.nio.file.{Files, Paths} import org.opalj.tac._ -import org.opalj.tactobc.{ExprProcessor, FirstPass, StmtProcessor} +import org.opalj.tactobc.{ExprProcessor, FirstPass} import org.opalj.value.ValueInformation import java.io.File @@ -308,87 +308,16 @@ object TACtoBC { * @return An array of bytecode instructions representing the method's functionality */ def translateSingleTACtoBC(tac: AITACode[TACMethodParameter, ValueInformation]): ArrayBuffer[(Int, Instruction)] = { - val generatedByteCodeWithPC = ArrayBuffer[(Int, Instruction)]() val tacStmts = tac.stmts.zipWithIndex - //first pass + //first pass -> prepare the LVIndexes to map the Variable to Indexes val duVars = mutable.ListBuffer[DUVar[_]]() FirstPass.prepareLVIndexes(tacStmts, duVars) - //second pass - var currentPC = 0 + //second pass -> generate Bytecode Instructions from TAC Stmts + val generatedByteCodeWithPC = ArrayBuffer[(Int, Instruction)]() val tacTargetToByteCodePcs = ArrayBuffer[(Int, Int)]() val switchCases = ArrayBuffer[(Int, Int)]() // To store switch case targets - tacStmts.foreach { case (stmt, _) => - stmt match { - case Assignment(_, targetVar, expr) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processAssignment(targetVar, expr, generatedByteCodeWithPC, currentPC) - case ArrayStore(_, arrayRef, index, value) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processArrayStore(arrayRef, index, value, generatedByteCodeWithPC, currentPC) - case CaughtException(_, exceptionType, throwingStmts) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processCaughtException(exceptionType, throwingStmts, generatedByteCodeWithPC, currentPC) - case ExprStmt(_, expr) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = ExprProcessor.processExpression(expr, generatedByteCodeWithPC, currentPC) - case If(_, left, condition, right, target) => - tacTargetToByteCodePcs += ((target, currentPC)) - currentPC = StmtProcessor.processIf(left, condition, right, target, generatedByteCodeWithPC, currentPC) - case Goto(_, target) => - tacTargetToByteCodePcs += ((target, currentPC)) - currentPC = StmtProcessor.processGoto(generatedByteCodeWithPC, currentPC) - case Switch(_, defaultTarget, index, npairs) => - npairs.foreach { pair => - switchCases += ((pair._1, pair._2)) //case values to jump target - } - tacTargetToByteCodePcs += ((defaultTarget, currentPC)) - currentPC = StmtProcessor.processSwitch(defaultTarget, index, npairs, generatedByteCodeWithPC, currentPC) - case JSR(_, target) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processJSR(target, generatedByteCodeWithPC, currentPC) - case VirtualMethodCall(_, declaringClass, isInterface, name, descriptor, receiver, params) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processVirtualMethodCall(declaringClass, isInterface, name, descriptor, receiver, params, generatedByteCodeWithPC, currentPC) - case NonVirtualMethodCall(_, declaringClass, isInterface, name, descriptor, receiver, params) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processNonVirtualMethodCall(declaringClass, isInterface, name, descriptor, receiver, params, generatedByteCodeWithPC, currentPC) - case StaticMethodCall(_, declaringClass, isInterface, name, descriptor, params) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processStaticMethodCall(declaringClass, isInterface, name, descriptor, params, generatedByteCodeWithPC, currentPC) - case InvokedynamicMethodCall(_, bootstrapMethod, name, descriptor, params) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processInvokeDynamicMethodCall(bootstrapMethod, name, descriptor, params) - case MonitorEnter(_, objRef) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processMonitorEnter(objRef, generatedByteCodeWithPC, currentPC) - case MonitorExit(_, objRef) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processMonitorExit(objRef, generatedByteCodeWithPC, currentPC) - case PutField(_, declaringClass, name, declaredFieldType, objRef, value) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processPutField(declaringClass, name, declaredFieldType, objRef, value, generatedByteCodeWithPC, currentPC) - case PutStatic(_, declaringClass, name, declaredFieldType, value) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processPutStatic(declaringClass, name, declaredFieldType, value, generatedByteCodeWithPC, currentPC) - case Checkcast(_, value, cmpTpe) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processCheckCast(value, cmpTpe, generatedByteCodeWithPC, currentPC) - case Ret(_, returnAddresses) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processRet(returnAddresses, generatedByteCodeWithPC, currentPC) - case ReturnValue(_, expr) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processReturnValue(expr, generatedByteCodeWithPC, currentPC) - case Return(_) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processReturn(generatedByteCodeWithPC, currentPC) - case Throw(_, exception) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processThrow(exception, generatedByteCodeWithPC, currentPC) - case _ => - } - } - //second pass -> this time through the translated bytecode to calculate the right branching targets + SecondPass.translateStmtsToInstructions(tacStmts, generatedByteCodeWithPC, tacTargetToByteCodePcs, switchCases) + //third pass -> this time through the translated bytecode to calculate the right branching targets val result = ArrayBuffer[(Int, Instruction)]() // Index for TAC statements var tacTargetToByteCodePcsIndex = 0 From 91a75f28a650a76d699ab8346f5a47180855def9 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Tue, 30 Jul 2024 11:33:50 +0200 Subject: [PATCH 006/111] Separated the third pass in own class --- .../scala/org/opalj/tactobc/FirstPass.scala | 3 +- .../scala/org/opalj/tactobc/TACtoBC.scala | 96 +--------------- .../scala/org/opalj/tactobc/ThirdPass.scala | 104 ++++++++++++++++++ 3 files changed, 109 insertions(+), 94 deletions(-) create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index 7d5d6f4530..ade7d3d282 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -16,7 +16,8 @@ object FirstPass { * The parameter "stmt" represents the current stmt to be inspected * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method */ - def prepareLVIndexes(tacStmts: Array[(Stmt[DUVar[ValueInformation]], Int)], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + def prepareLVIndexes(tacStmts: Array[(Stmt[DUVar[ValueInformation]], Int)]): Unit = { + val duVars = mutable.ListBuffer[DUVar[_]]() tacStmts.foreach { case (stmt, _) => { stmt match { case Assignment(_, targetVar, expr) => diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala index 49aa67f296..0fc2ca48e1 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala @@ -6,9 +6,8 @@ import org.opalj.ba.toDA import org.opalj.bc.Assembler import org.opalj.br.{ArrayType, Code, CompactLineNumberTable, LocalVariable, LocalVariableTable, Method, ObjectType, StackMapTable} import org.opalj.br.analyses.Project -import org.opalj.br.instructions.{GOTO, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, Instruction, LOOKUPSWITCH, TABLESWITCH} +import org.opalj.br.instructions.Instruction import org.opalj.br.reader.Java8Framework -import org.opalj.collection.immutable.{IntIntPair, IntTrieSet} import org.opalj.da.ClassFileReader.ClassFile import org.opalj.io.writeAndOpen import org.opalj.util.InMemoryClassLoader @@ -16,13 +15,11 @@ import org.opalj.util.InMemoryClassLoader import java.io.ByteArrayInputStream import java.nio.file.{Files, Paths} import org.opalj.tac._ -import org.opalj.tactobc.{ExprProcessor, FirstPass} import org.opalj.value.ValueInformation import java.io.File import scala.Console.println import scala.collection.immutable.ArraySeq -import scala.collection.mutable import scala.collection.mutable.ArrayBuffer import scala.jdk.CollectionConverters.EnumerationHasAsScala @@ -310,100 +307,13 @@ object TACtoBC { def translateSingleTACtoBC(tac: AITACode[TACMethodParameter, ValueInformation]): ArrayBuffer[(Int, Instruction)] = { val tacStmts = tac.stmts.zipWithIndex //first pass -> prepare the LVIndexes to map the Variable to Indexes - val duVars = mutable.ListBuffer[DUVar[_]]() - FirstPass.prepareLVIndexes(tacStmts, duVars) + FirstPass.prepareLVIndexes(tacStmts) //second pass -> generate Bytecode Instructions from TAC Stmts val generatedByteCodeWithPC = ArrayBuffer[(Int, Instruction)]() val tacTargetToByteCodePcs = ArrayBuffer[(Int, Int)]() val switchCases = ArrayBuffer[(Int, Int)]() // To store switch case targets SecondPass.translateStmtsToInstructions(tacStmts, generatedByteCodeWithPC, tacTargetToByteCodePcs, switchCases) //third pass -> this time through the translated bytecode to calculate the right branching targets - val result = ArrayBuffer[(Int, Instruction)]() - // Index for TAC statements - var tacTargetToByteCodePcsIndex = 0 - - generatedByteCodeWithPC.zipWithIndex.foreach { - case ((pc, instruction), _) => - // Match and update branch instructions - val updatedInstruction = instruction match { - case IF_ICMPEQ(-1) => - tacTargetToByteCodePcsIndex -= 1 - val instruction = IF_ICMPEQ(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - tacTargetToByteCodePcsIndex += 1 - instruction - case IF_ICMPNE(-1) => - tacTargetToByteCodePcsIndex -= 1 - val instruction = IF_ICMPNE(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - tacTargetToByteCodePcsIndex += 1 - instruction - case IF_ICMPLT(-1) => - tacTargetToByteCodePcsIndex -= 1 - val instruction = IF_ICMPLT(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - tacTargetToByteCodePcsIndex += 1 - instruction - case IF_ICMPLE(-1) => - tacTargetToByteCodePcsIndex -= 1 - val instruction = IF_ICMPLE(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - tacTargetToByteCodePcsIndex += 1 - instruction - case IF_ICMPGT(-1) => - tacTargetToByteCodePcsIndex -= 1 - val instruction = IF_ICMPGT(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - tacTargetToByteCodePcsIndex += 1 - instruction - case IF_ICMPGE(-1) => - tacTargetToByteCodePcsIndex -= 1 - val instruction = IF_ICMPGE(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - tacTargetToByteCodePcsIndex += 1 - instruction - case GOTO(-1) => - GOTO(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - case LOOKUPSWITCH(defaultOffset, matchOffsets) => - val updatedMatchOffsets = matchOffsets.map { case IntIntPair(caseValue, _) => - val tacTarget = findTacTarget(switchCases, caseValue) - IntIntPair(caseValue, updateSwitchTargets(tacTargetToByteCodePcs, tacTarget)) - } - val updatedDefaultOffset = updateSwitchTargets(tacTargetToByteCodePcs, defaultOffset) - LOOKUPSWITCH(updatedDefaultOffset, updatedMatchOffsets) - case TABLESWITCH(defaultOffset, low, high, jumpOffsets) => - val updatedJumpOffsets = jumpOffsets.zipWithIndex.map { case (_, index) => - val tacTarget = findTacTarget(switchCases, index) - updateSwitchTargets(tacTargetToByteCodePcs, tacTarget) - } - val updatedDefaultOffset = updateSwitchTargets(tacTargetToByteCodePcs, defaultOffset) - TABLESWITCH(updatedDefaultOffset, low, high, updatedJumpOffsets.to(ArraySeq)) - case _ => - instruction - } - result += ((pc, updatedInstruction)) - - // Only increment tacIndex when the current instruction corresponds to a TAC statement - if (tacTargetToByteCodePcsIndex < tacStmts.length && directAssociationExists(tacTargetToByteCodePcs, tacTargetToByteCodePcs(tacTargetToByteCodePcsIndex)._1, pc)) { - tacTargetToByteCodePcsIndex += 1 - } - } - ExprProcessor.uVarToLVIndex = mutable.Map[IntTrieSet, Int]() - ExprProcessor.nextLVIndex = 1 - result - } - - def findTacTarget(npairs: ArrayBuffer[(Int, Int)], caseValue: Int): Int = { - val tacTarget = npairs.find(_._1 == caseValue).map(_._2).get - tacTarget - } - - def updateBranchTargets(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTargetToByteCodePcsIndex: Int, currentPC: Int): Int = { - val tacTarget = tacTargetToByteCodePcs(tacTargetToByteCodePcsIndex)._1 - val byteCodeTarget = tacTargetToByteCodePcs(tacTarget)._2 - currentPC - byteCodeTarget - } - - def updateSwitchTargets(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTarget: Int): Int = { - val byteCodeTarget = tacTargetToByteCodePcs(tacTarget)._2 - byteCodeTarget - } - - def directAssociationExists(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTarget: Int, bytecodePC: Int): Boolean = { - tacTargetToByteCodePcs.exists { case (tacGoto, bcPC) => (tacGoto, bcPC) == (tacTarget, bytecodePC) } + ThirdPass.updateTargetsOfJumpInstructions(tacStmts, generatedByteCodeWithPC, tacTargetToByteCodePcs, switchCases) } } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala new file mode 100644 index 0000000000..dd1af17804 --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala @@ -0,0 +1,104 @@ +package org.opalj.tactobc + +import org.opalj.br.instructions.{GOTO, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, Instruction, LOOKUPSWITCH, TABLESWITCH} +import org.opalj.collection.immutable.{IntIntPair, IntTrieSet} +import org.opalj.tac.{DUVar, Stmt} +import org.opalj.value.ValueInformation + +import scala.collection.immutable.ArraySeq +import scala.collection.mutable +import scala.collection.mutable.ArrayBuffer + +object ThirdPass { + + def updateTargetsOfJumpInstructions(tacStmts: Array[(Stmt[DUVar[ValueInformation]], Int)], generatedByteCodeWithPC: ArrayBuffer[(Int, Instruction)], tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], switchCases: ArrayBuffer[(Int, Int)]): ArrayBuffer[(Int, Instruction)] = { + val result = ArrayBuffer[(Int, Instruction)]() + // Index for TAC statements + var tacTargetToByteCodePcsIndex = 0 + + generatedByteCodeWithPC.zipWithIndex.foreach { + case ((pc, instruction), _) => + // Match and update branch instructions + val updatedInstruction = instruction match { + case IF_ICMPEQ(-1) => + tacTargetToByteCodePcsIndex -= 1 + val instruction = IF_ICMPEQ(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + tacTargetToByteCodePcsIndex += 1 + instruction + case IF_ICMPNE(-1) => + tacTargetToByteCodePcsIndex -= 1 + val instruction = IF_ICMPNE(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + tacTargetToByteCodePcsIndex += 1 + instruction + case IF_ICMPLT(-1) => + tacTargetToByteCodePcsIndex -= 1 + val instruction = IF_ICMPLT(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + tacTargetToByteCodePcsIndex += 1 + instruction + case IF_ICMPLE(-1) => + tacTargetToByteCodePcsIndex -= 1 + val instruction = IF_ICMPLE(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + tacTargetToByteCodePcsIndex += 1 + instruction + case IF_ICMPGT(-1) => + tacTargetToByteCodePcsIndex -= 1 + val instruction = IF_ICMPGT(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + tacTargetToByteCodePcsIndex += 1 + instruction + case IF_ICMPGE(-1) => + tacTargetToByteCodePcsIndex -= 1 + val instruction = IF_ICMPGE(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + tacTargetToByteCodePcsIndex += 1 + instruction + case GOTO(-1) => + GOTO(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + case LOOKUPSWITCH(defaultOffset, matchOffsets) => + val updatedMatchOffsets = matchOffsets.map { case IntIntPair(caseValue, _) => + val tacTarget = findTacTarget(switchCases, caseValue) + IntIntPair(caseValue, updateSwitchTargets(tacTargetToByteCodePcs, tacTarget)) + } + val updatedDefaultOffset = updateSwitchTargets(tacTargetToByteCodePcs, defaultOffset) + LOOKUPSWITCH(updatedDefaultOffset, updatedMatchOffsets) + case TABLESWITCH(defaultOffset, low, high, jumpOffsets) => + val updatedJumpOffsets = jumpOffsets.zipWithIndex.map { case (_, index) => + val tacTarget = findTacTarget(switchCases, index) + updateSwitchTargets(tacTargetToByteCodePcs, tacTarget) + } + val updatedDefaultOffset = updateSwitchTargets(tacTargetToByteCodePcs, defaultOffset) + TABLESWITCH(updatedDefaultOffset, low, high, updatedJumpOffsets.to(ArraySeq)) + case _ => + instruction + } + result += ((pc, updatedInstruction)) + + // Only increment tacIndex when the current instruction corresponds to a TAC statement + if (tacTargetToByteCodePcsIndex < tacStmts.length && directAssociationExists(tacTargetToByteCodePcs, tacTargetToByteCodePcs(tacTargetToByteCodePcsIndex)._1, pc)) { + tacTargetToByteCodePcsIndex += 1 + } + } + ExprProcessor.uVarToLVIndex = mutable.Map[IntTrieSet, Int]() + ExprProcessor.nextLVIndex = 1 + result + } + + def findTacTarget(npairs: ArrayBuffer[(Int, Int)], caseValue: Int): Int = { + val tacTarget = npairs.find(_._1 == caseValue).map(_._2).get + tacTarget + } + + def updateBranchTargets(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTargetToByteCodePcsIndex: Int, currentPC: Int): Int = { + val tacTarget = tacTargetToByteCodePcs(tacTargetToByteCodePcsIndex)._1 + val byteCodeTarget = tacTargetToByteCodePcs(tacTarget)._2 - currentPC + byteCodeTarget + } + + def updateSwitchTargets(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTarget: Int): Int = { + val byteCodeTarget = tacTargetToByteCodePcs(tacTarget)._2 + byteCodeTarget + } + + def directAssociationExists(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTarget: Int, bytecodePC: Int): Boolean = { + tacTargetToByteCodePcs.exists { case (tacGoto, bcPC) => (tacGoto, bcPC) == (tacTarget, bytecodePC) } + } + +} From daebb60db0742889a105868a2c8712d3bd080db5 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Tue, 30 Jul 2024 11:56:15 +0200 Subject: [PATCH 007/111] refactored documentation --- .../scala/org/opalj/tactobc/FirstPass.scala | 78 ++++++++++++------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index ade7d3d282..da57ebf0e7 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -7,16 +7,29 @@ import org.opalj.value.ValueInformation import scala.collection.mutable +/** + * Handles the initial preparation of local variable (LV) indexes + * for translating three-address code (TAC) to bytecode. This involves collecting all + * defined-use variables (DUVars) in the method, assigning LV indexes to parameters, + * and populating a map that assigns unique LV indexes to each unique variable. + * + * Key responsibilities: + * - Collect all DUVars from the method's statements. + * - Assign LV indexes to method parameters. + * - Populate a map (`uVarToLVIndex`) with unique LV indexes for each variable used in the method. + */ object FirstPass { /** - * Collects all DUVars of the current method, adds parameters (if given) in the first available LVIndexes, - * populates then the uVarToLVIndex map so that each used (and unique) variable does have a unique LVIndex. - * @param stmt translateSingleTACtoBC iterates through all exisiting stmts for the method to be translated. - * The parameter "stmt" represents the current stmt to be inspected - * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method + * Prepares local variable (LV) indexes for the given method by: + * 1. Collecting all defined-use variables (DUVars) from the method's statements. + * 2. Assigning LV indexes to method parameters. + * 3. Populating the `uVarToLVIndex` map with unique LV indexes for each unique variable. + * + * @param tacStmts Array of tuples where each tuple contains a TAC statement and its index. */ def prepareLVIndexes(tacStmts: Array[(Stmt[DUVar[ValueInformation]], Int)]): Unit = { + // container for all DUVars in the method val duVars = mutable.ListBuffer[DUVar[_]]() tacStmts.foreach { case (stmt, _) => { stmt match { @@ -53,10 +66,10 @@ object FirstPass { } /** - * Filters all UVars of the duVars map in the parameter and populates the uVarToLVIndex map in order so that - * each unique uVar has a unique LVIndex - * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method - * @return a mutable.Map[IntTrieSet, Int]: the IntTrieSet corresponds a UVars defsites, the Int represents the LVIndex + * Populates the `uVarToLVIndex` map with unique LV indexes for each variable in the given DUVars list. + * + * @param duVars ListBuffer containing all DUVars of the method. + * @return A map where keys are def-sites of UVars and values are their corresponding LV indexes. */ def collectAllUVarsAndPopulateUVarToLVIndexMap(duVars: mutable.ListBuffer[DUVar[_]]): mutable.Map[IntTrieSet, Int] = { duVars.toArray.foreach { @@ -67,9 +80,10 @@ object FirstPass { } /** - * Gives the first available LVIndexes to the parameters of the method - * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method - * @return a mutable.Map[IntTrieSet, Int]: the IntTrieSet corresponds a UVars defsites, the Int represents the LVIndex + * Assigns the first available LV indexes to method parameters. + * + * @param duVars ListBuffer containing all DUVars of the method. + * @return A map where keys are def-sites of UVars and values are their corresponding LV indexes. */ def mapParametersAndPopulate(duVars: mutable.ListBuffer[DUVar[_]]): mutable.Map[IntTrieSet, Int] = { duVars.foreach { @@ -99,8 +113,9 @@ object FirstPass { } /** - * Populates the uVarToLVIndex map by givin each unique uVar a unique LVIndex - * @param uVar an used variable + * Populates the `uVarToLVIndex` map with unique LV indexes for each unique UVar. + * + * @param uVar A variable used in the method. */ def populateUvarToLVIndexMap(uVar: UVar[_]): Unit = { // Check if any existing key contains any of the def-sites @@ -122,9 +137,10 @@ object FirstPass { } /** - * Helper method to traverse over expressions and collect the DUVars "embedded" in them - * @param expr the expression to be traversed - * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method + * Traverses an expression to collect all DUVars embedded within it. + * + * @param expr The expression to be traversed + * @param duVars ListBuffer to be extended with all DUVars found in the expression. */ def collectDUVarFromExpr(expr: Expr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { expr match { @@ -138,18 +154,20 @@ object FirstPass { } /** - * Helper method to traverse through a PrimitiveTypeCastExpr and collect the DUVars - * @param primitiveTypecaseExpr an Expr of type PrimitiveTypecastExpr - * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method + * Traverses a `PrimitiveTypeCastExpr` to collect all DUVars embedded within it. + * + * @param primitiveTypecaseExpr The `PrimitiveTypecastExpr` to be traversed. + * @param duVars ListBuffer to be extended with all DUVars found in the expression. */ def collectDUVarFromPrimitiveTypeCastExpr(primitiveTypecaseExpr: PrimitiveTypecastExpr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { collectDUVarFromExpr(primitiveTypecaseExpr.operand, duVars) } /** - * Helper method to traverse through a StaticFunctionCall Expr and collect the DUVars - * @param staticFunctionCallExpr an Expr of type StaticFunctionCall - * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method + * Traverses a `StaticFunctionCall` expression to collect all DUVars embedded within it. + * + * @param staticFunctionCallExpr The `StaticFunctionCall` expression to be traversed. + * @param duVars ListBuffer to be extended with all DUVars found in the expression. */ def collectDUVarFromStaticFunctionCall(staticFunctionCallExpr: StaticFunctionCall[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { // Process each parameter and collect from each @@ -159,9 +177,10 @@ object FirstPass { } /** - * Helper method to traverse through a BinaryExpr Expr and collect the DUVars - * @param binaryExpr an Expr of type BinaryExpr - * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method + * Traverses a `BinaryExpr` to collect all DUVars embedded within it. + * + * @param binaryExpr The `BinaryExpr` to be traversed. + * @param duVars ListBuffer to be extended with all DUVars found in the expression. */ def collectDUVarFromBinaryExpr(binaryExpr: BinaryExpr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { collectDUVarFromExpr(binaryExpr.left, duVars) @@ -169,9 +188,10 @@ object FirstPass { } /** - * Helper method to traverse through a VirtualFunctionCall Expr and collect the DUVars - * @param virtualFunctionCallExpr an Expr of type VirtualFunctionCall - * @param duVars a ListBuffer[DUVar[_]] that is extended with all DUVars of the given method + * Traverses a `VirtualFunctionCall` expression to collect all DUVars embedded within it. + * + * @param virtualFunctionCallExpr The `VirtualFunctionCall` expression to be traversed. + * @param duVars ListBuffer to be extended with all DUVars found in the expression. */ def collectDUVarFromVirtualMethodCall(virtualFunctionCallExpr: VirtualFunctionCall[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { collectDUVarFromExpr(virtualFunctionCallExpr.receiver, duVars) From b1e2f97e412289a78421a6aa0b1d5e39dcd52a78 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Tue, 30 Jul 2024 12:07:19 +0200 Subject: [PATCH 008/111] refactored documentation --- .../scala/org/opalj/tactobc/SecondPass.scala | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala index 211ab5db3a..4eaeef6262 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala @@ -6,8 +6,32 @@ import org.opalj.value.ValueInformation import scala.collection.mutable.ArrayBuffer +/** + * Handles the translation of three-address code (TAC) statements + * into Java bytecode instructions. + * + * This object processes each TAC statement and generates corresponding bytecode instructions, + * updating the program counter (PC) as it proceeds. + * + * Key responsibilities: + * - Translate TAC statements to bytecode instructions. + * - Maintain mappings from TAC targets to bytecode program counters (PCs). + */ object SecondPass { + /** + * Translates TAC statements to bytecode instructions. + * + * This method iterates over the given TAC statements, processes each statement according to its type, + * generates the corresponding bytecode instructions, and updates the program counter (PC) according to the instruction length. + * + * The `-1` value is used as a placeholder for statements that do not require a target. + * + * @param tacStmts Array of tuples where each tuple contains a TAC statement and its index. + * @param generatedByteCodeWithPC ArrayBuffer to store the generated bytecode instructions along with their PCs. + * @param tacTargetToByteCodePcs ArrayBuffer to map TAC targets to bytecode PCs. + * @param switchCases ArrayBuffer to store switch case mappings. + */ def translateStmtsToInstructions(tacStmts: Array[(Stmt[DUVar[ValueInformation]], Int)], generatedByteCodeWithPC: ArrayBuffer[(Int, Instruction)], tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], switchCases: ArrayBuffer[(Int, Int)]): Unit = { var currentPC = 0 tacStmts.foreach { case (stmt, _) => @@ -82,5 +106,4 @@ object SecondPass { } } } - } From b462576bffa496b10f157f3a5dc64d4c8577842d Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Thu, 1 Aug 2024 16:44:36 +0200 Subject: [PATCH 009/111] Loading more example programs --- .../org/opalj/tactobc/ExprProcessor.scala | 56 ++++++++++++++- .../scala/org/opalj/tactobc/FirstPass.scala | 39 +++++++++- .../scala/org/opalj/tactobc/TACtoBC.scala | 67 +++++++++++------- .../src/test/resources/scimark-2.2.jar | Bin 0 -> 22619 bytes 4 files changed, 132 insertions(+), 30 deletions(-) create mode 100644 OPAL/tactobc/src/test/resources/scimark-2.2.jar diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index 810e04342a..a3c37d1239 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -3,10 +3,10 @@ package org.opalj.tactobc import org.opalj.BinaryArithmeticOperators.{Add, And, Divide, Modulo, Multiply, Or, ShiftLeft, ShiftRight, Subtract, UnsignedShiftRight, XOr} import org.opalj.br.{ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FloatType, IntegerType, LongType, ObjectType, ShortType} -import org.opalj.br.instructions.{ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BIPUSH, D2F, D2I, D2L, DADD, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LAND, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, NEW, SIPUSH} +import org.opalj.br.instructions.{AALOAD, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BIPUSH, D2F, D2I, D2L, DADD, DALOAD, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, NEW, NEWARRAY, SIPUSH} import org.opalj.bytecode.BytecodeProcessingFailedException import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{BinaryExpr, ClassConst, Const, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, LongConst, MethodHandleConst, MethodTypeConst, New, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} +import org.opalj.tac.{ArrayLength, ArrayLoad, BinaryExpr, ClassConst, Const, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, LongConst, MethodHandleConst, MethodTypeConst, New, NewArray, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} import scala.collection.mutable import scala.collection.mutable.ArrayBuffer @@ -24,11 +24,62 @@ object ExprProcessor { case staticFunctionCallExpr: StaticFunctionCall[_] => handleStaticFunctionCall(staticFunctionCallExpr, instructionsWithPCs, currentPC) case newExpr: New => handleNewExpr(newExpr.tpe, instructionsWithPCs, currentPC) case primitiveTypecaseExpr: PrimitiveTypecastExpr[_] => handlePrimitiveTypeCastExpr(primitiveTypecaseExpr, instructionsWithPCs, currentPC) + case arrayLength: ArrayLength[_] => handleArrayLength(arrayLength, instructionsWithPCs, currentPC) + case arrayLoadExpr: ArrayLoad[_] => handleArrayLoad(arrayLoadExpr, instructionsWithPCs, currentPC) + case newArrayExpr: NewArray[_] => handleNewArray(newArrayExpr, instructionsWithPCs, currentPC) case _ => throw new UnsupportedOperationException("Unsupported expression type" + expr) } } + def handleNewArray(newArrayExpr: NewArray[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // Initialize the PC after processing the counts + var currentAfterCountsPC = currentPC + + // Process each parameter and update the PC accordingly + for (count <- newArrayExpr.counts) { + currentAfterCountsPC = ExprProcessor.processExpression(count, instructionsWithPCs, currentAfterCountsPC) + } + //todo: handle the differenciation between: + //NEWARRAY, ANEWARRAY and MULTIANEWARRAY + //val instruction = NEWARRAY(newArrayExpr.tpe.id) + val instruction = newArrayExpr.tpe.elementType.computationalType match { + case ComputationalTypeReference => ANEWARRAY(newArrayExpr.tpe) + case _ => NEWARRAY + } + instructionsWithPCs += ((currentAfterCountsPC, instruction)) + currentAfterCountsPC + instruction.length + } + + def handleArrayLoad(arrayLoadExpr: ArrayLoad[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // Load the array reference onto the stack + val pcAfterArrayRefLoad = processExpression(arrayLoadExpr.arrayRef, instructionsWithPCs, currentPC) + // Load the index onto the stack + val pcAfterIndexLoad = processExpression(arrayLoadExpr.index, instructionsWithPCs, pcAfterArrayRefLoad) + val instruction = arrayLoadExpr.arrayRef.cTpe match { + case ComputationalTypeInt => IALOAD + case ComputationalTypeLong => LALOAD + case ComputationalTypeFloat => FALOAD + case ComputationalTypeDouble => DALOAD + //Todo: look how to compare with primitives (?) + //case ComputationalType => BALOAD + //case Compu => CALOAD + //case C => SALOAD + case ComputationalTypeReference => AALOAD + case _ => throw new IllegalArgumentException("Unsupported array load type") + } + instructionsWithPCs += ((pcAfterIndexLoad, instruction)) + pcAfterIndexLoad + instruction.length + } + + def handleArrayLength(arrayLength: ArrayLength[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // Process the receiver object (e.g., aload_0 for `this`) + val afterReceiverPC = ExprProcessor.processExpression(arrayLength.arrayRef, instructionsWithPCs, currentPC) + val instruction = ARRAYLENGTH + instructionsWithPCs += ((afterReceiverPC, instruction)) + afterReceiverPC + instruction.length + } + def handleNewExpr(tpe: ObjectType, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { val instruction = NEW(tpe) instructionsWithPCs += ((currentPC, instruction)) @@ -240,6 +291,7 @@ object ExprProcessor { currentPC + (if (index < 4) 1 else 2) } + //todo: probably get rid of this :) def handleArrayStore(variable: Var[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { 1 } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index da57ebf0e7..422474bda6 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -1,7 +1,7 @@ package org.opalj.tactobc import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{Assignment, BinaryExpr, DUVar, Expr, If, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, ReturnValue, StaticFunctionCall, Stmt, UVar, VirtualFunctionCall, VirtualMethodCall} +import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, DUVar, Expr, ExprStmt, If, NewArray, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, ReturnValue, StaticFunctionCall, Stmt, UVar, VirtualFunctionCall, VirtualMethodCall} import org.opalj.tactobc.ExprProcessor.{nextLVIndex, uVarToLVIndex} import org.opalj.value.ValueInformation @@ -54,6 +54,12 @@ object FirstPass { } case ReturnValue(_, expr) => collectDUVarFromExpr(expr, duVars) + case ArrayStore(_, arrayRef, index, value) => + collectDUVarFromExpr(arrayRef, duVars) + collectDUVarFromExpr(index, duVars) + collectDUVarFromExpr(value, duVars) + case ExprStmt(_, expr) => + collectDUVarFromExpr(expr, duVars) case _ => } } @@ -149,10 +155,41 @@ object FirstPass { case virtualFunctionCallExpr: VirtualFunctionCall[_] => collectDUVarFromVirtualMethodCall(virtualFunctionCallExpr, duVars) case staticFunctionCallExpr: StaticFunctionCall[_] => collectDUVarFromStaticFunctionCall(staticFunctionCallExpr, duVars) case primitiveTypecaseExpr: PrimitiveTypecastExpr[_] => collectDUVarFromPrimitiveTypeCastExpr(primitiveTypecaseExpr, duVars) + case arrayLengthExpr: ArrayLength[_] => collectDUVarFromArrayLengthExpr(arrayLengthExpr, duVars) + case arrayLoadExpr: ArrayLoad[_] => collectDUVarFromArrayLoadExpr(arrayLoadExpr, duVars) + case newArrayExpr: NewArray[_] => collectDUVarFromNewArrayExpr(newArrayExpr, duVars) case _ => } } + def collectDUVarFromNewArrayExpr(newArrayExpr: NewArray[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + for (count <- newArrayExpr.counts) { + collectDUVarFromExpr(count, duVars) + } + // tpe does not contain any expr + } + + /** + * Traverses a `ArrayLoad` expr to collect all DUVars embedded within it. + * + * @param arrayLoadExpr The `ArrayLength` expr to be traversed. + * @param duVars ListBuffer to be extended with all DUVars found in the expression. + */ + def collectDUVarFromArrayLoadExpr(arrayLoadExpr: ArrayLoad[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectDUVarFromExpr(arrayLoadExpr.index, duVars) + collectDUVarFromExpr(arrayLoadExpr.arrayRef, duVars) + } + + /** + * Traverses a `ArrayLength` expr to collect all DUVars embedded within it. + * + * @param arrayLength The `ArrayLength` expr to be traversed. + * @param duVars ListBuffer to be extended with all DUVars found in the expression. + */ + def collectDUVarFromArrayLengthExpr(arrayLength: ArrayLength[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectDUVarFromExpr(arrayLength.arrayRef, duVars) + } + /** * Traverses a `PrimitiveTypeCastExpr` to collect all DUVars embedded within it. * diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala index 0fc2ca48e1..8cc1fcb709 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala @@ -5,6 +5,8 @@ import org.opalj.ba.CodeAttributeBuilder.computeStackMapTable import org.opalj.ba.toDA import org.opalj.bc.Assembler import org.opalj.br.{ArrayType, Code, CompactLineNumberTable, LocalVariable, LocalVariableTable, Method, ObjectType, StackMapTable} + +import scala.Console.println import org.opalj.br.analyses.Project import org.opalj.br.instructions.Instruction import org.opalj.br.reader.Java8Framework @@ -18,7 +20,6 @@ import org.opalj.tac._ import org.opalj.value.ValueInformation import java.io.File -import scala.Console.println import scala.collection.immutable.ArraySeq import scala.collection.mutable.ArrayBuffer import scala.jdk.CollectionConverters.EnumerationHasAsScala @@ -27,36 +28,51 @@ object TACtoBC { def main(args: Array[String]): Unit = { if (args.length != 1) { - println("Usage: TACtoBC ") + println("Usage: ListClassFiles ") return } - val file = new File(args(0)) - if (!file.exists()) { - println(s"File ${file.getPath} does not exist.") + val inputDirPath = args(0) + val inputDir = new File(inputDirPath) + if (!inputDir.exists() || !inputDir.isDirectory) { + println(s"Directory ${inputDir.getPath} does not exist or is not a directory.") return } - //do this implicit val - val p = Project(file) - compileByteCode(file) - val tacs = compileTAC(file) - - // Print out TAC - tacs.foreach { case (method, tac) => - tac.detach() - println(s"Method: ${method.toJava}") - println(tac.toString) - println("\n") + val classFiles = listClassFiles(inputDir) + classFiles.foreach{ + classfile => + //todo: figure out how to get the input stream of the file + //(1) compile bytecode + compileByteCode(classfile) + //(2) compile tac + val tacs = compileTAC(classfile) + // Print out TAC + tacs.foreach { case (method, tac) => + tac.detach() + println(s"Method: ${method.toJava}") + println(tac.toString) + println("\n") + } + //(3) generate bc from compiled tac + // > Print out the translation from TAC to Bytecode + val byteCodes = translateTACtoBC(tacs) + byteCodes.foreach { case (method, bytecode) => + println(s"Method: ${method.toJava}") + bytecode.foreach(instr => println(instr.toString)) + } + //(4) generate .class files from translation + val p = Project(classfile) + generateClassFiles(byteCodes, p) + // println(classfile.getAbsolutePath))) } + } - // Print out the translation from TAC to Bytecode - val byteCodes = translateTACtoBC(tacs) - byteCodes.foreach { case (method, bytecode) => - println(s"Method: ${method.toJava}") - bytecode.foreach(instr => println(instr.toString)) - } + def listClassFiles(directory: File): List[File] = { + directory.listFiles().toList.filter(_.getName.endsWith(".class")) + } + def generateClassFiles(byteCodes: Map[Method, ArrayBuffer[(Int, Instruction)]], p: Project[_]) : Unit = { val TheType = ObjectType("org/opalj/tactobc/testingtactobc/HelloWorld") // Debugging: Print the location of the class loader and resources @@ -66,6 +82,7 @@ object TACtoBC { println(s"Resources: ${resources.mkString(", ")}") val in = () => { + //todo: change this to be the input stream of the class file and give the classfile as parameter val stream = this.getClass.getResourceAsStream("/org/opalj/tactobc/testingtactobc/HelloWorld.class") if (stream == null) throw new RuntimeException("Resource not found: /HelloWorld.class") stream @@ -116,17 +133,12 @@ object TACtoBC { val newLocalVariableTable = LocalVariableTable(ArraySeq( LocalVariable(0, maxPc + 1, "args", ArrayType(ObjectType("java/lang/String")), 0) )) - /*val newCompactLineNumber = CompactLineNumber( - Array(LineNumber(0, maxPc + 1)) - )*/ - //live variable // Remove CompactLineNumberTable attribute val newAttributes = attributesOfOriginalBody.filterNot(_.isInstanceOf[CompactLineNumberTable]) // Replace the LocalVariableTable attribute in the original attributes val finalAttributes = newAttributes.map { case _: LocalVariableTable => newLocalVariableTable - //case _: CompactLineNumberTable => case other => other } @@ -215,6 +227,7 @@ object TACtoBC { //println("Class file GeneratedHelloWorldToStringDALEQUEE.class has been generated." + newClass) // Let's test that the new class does what it is expected to do... (we execute the // instrumented method) + //todo: the map should have all class files val cl = new InMemoryClassLoader(Map((TheType.toJava, newRawCF))) val newClass = cl.findClass(TheType.toJava) //val instance = newClass.getDeclaredConstructor().newInstance() diff --git a/OPAL/tactobc/src/test/resources/scimark-2.2.jar b/OPAL/tactobc/src/test/resources/scimark-2.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..56f3dddaff29433fbeab3afaae21b7d7eed4f863 GIT binary patch literal 22619 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

-b|O^PpumqzP|zWC3uIMP<|VV(VwPzpDM zeo;Dtp*UPsF3j=+H9?)PsS&NsZ zHK#wUWLNvz7~KWychT7f;E!?HpJK@pgm=AV!!NZXUW-(`hD%~D^~NEMuL*VxUh|RJ zNU7S1ZR=T~IP<(X>45UUvy?9AJg*__k!|0(zj*Ho_`YYe`S{R1{RH;xX-IU`z`iPR z(gp6BI-R05e>^!1U{~jjs94?^CGLu#m6m^=mqK&cs#Pd!M>d%zRnsiDMH9G2wW$W2 zoTI2l+ShWQC8QXLkZ*_`w=8c<=$R5$8kt?rNJG%BGk#sg2xmsu*BX5)!xZd}F|^^x z%z!f)*P zxfa*(&3oC)?wXk}%)R#V@k+1WAg0=jpTAXeyl;+BrQ7^<(|9FedPS&!H#m=rBd zp*?&YV^ZWTxn1TwTCIG%I1mH9R7ZsR4Mtl(5TD5ysgMv+T7Ej%(VxNCV--0Ok|?%4 zoS0laR|A6i?gQP~(7mUm`Q@mi1iIvnD+!`>VJx5}^h`UBNjiVBnO(yf-f^0h69BjM zi%0vG5baKJ2Zr4JpeorjeM?-z2RH6ektb&Cma1a4-d{QS4L5ff{1xtdI`#)ae*Y%< z6=H4=nTHxA7uo8rJN(u+?htfgjQb8u&(+vnb1Oi7nActP=q|ect~gy>m?tuC5((vE z?OBygP%!0$Crlwqg`KfDV$rCGe|CXgzA|jYiyu**SO$d5L7V4}Q2Q=DnK%%$q$G<2 zj)E3!VJqTrD+X!F*3)2sq!CxjDf(4s2GTpaj&cUEJFd-Kd*c+{3lskDS(r%b2O4e6 z-86A=;3s2mjAG*&Jf{O|uV5we3v`lV6GxDzXh1`jnG-ZV12eu}0zdrh6u^(t z(qZibdZoD|x5!A`I2ms2MF^rza?kn{RqfOHm`T+AS=0sj;92SjdzF$)F}Vw4DpRtdk6@`0uu0m)`-RcuOkZEjELYEN8ca7M zw|bsjl{3wuK*yURxecp|<0Kyp{$*)v#GG5qqW^Xxlw|w-I4%8 z=x)sw2DcpUdqSxK5F`r;DN!>}ArwWqMS>D30V@SknfYP*!El4}SnZ_#cm^;yhm(j- zIS3NJKQ;L`RM_BJ@I7JuQO5SVhg)vOm-FX0u|Jd)RVl$Z0;@zgBZ=3if11tpWeUEl zXX!rku&s9Nu^j_Mh!M3beZ*-}0n_v|P9G0bHQ>v;)v@li^L7ACjNyJw1`7T-u+H(87br#%=sI(_bEWO zATbY|9lVCYg*S@{HVa6iP`vP7&g5Jr{K8+O1(~+`3nChHL*L%{&4fV@0+v{NS`ppB zi{)5+Y#*_`IS5s(A#&Sw0&nw(UK_i&Y+@a?JoIJwx zusDXev`KE1U_%3)JA~1^`U}5}BDw>e#$|@95Q>N#&3M2&e*VzE-P<{4&~+h9G?Cxa zC!>?=e*hdiIQ~FHgf>>F6elNpd?S@Ca+9nck5gH2(!MN7X`NxeN2$j*QSHh|Qq@V+ z_4&-kG8?~;`y&7zRUjw?O2JyTi_O#_ePKDa%RPhHDqYh3ChmtF)F@PiLx*G*KkO8t z2IV@YL2gDNlDkz^I(Ep|ShfcTjfA97^2QoubjFON_|tcQ!rG1mdpPO#uSPc#q$jZZ z*XZc}c3S;Mqmh)Mv7M2{KMc-BSy~=h5#`(V*L(gAAehIyfQa7Wd@xm9IV6Y@C4%6( zvtp=Wzu{?evXD*&hNOgyjLh&bE2D#jMn?M{c>O*7D|<9zpVwvxR+-b>--5H7Y_D0j zQuMywT;TSo1qz_~!TCc7B9i!>2DqB(+GD$4sqC&eU1SKEu0Cz9`U2P(I?%k^!sT($ybvFlKd3tY_8Ov!y#dh9^M8t0UO3sPPC9Dr2Ms=D%ECcUPUab zrl^4u0@jTj*!bJUmSY7Bazj8PqgPJ0@6(mMR03@q$PucOb8Mnor}^ecL?dJ=?J68k zRiw33f+`=+(}@Gc~%ggWEtgJL}_(C&4TUWGxNGaw21Y1o=hO*)78TvrQpXKq1?@*bTsjE zf>m-Bd5dyNGf)TX)byf{z%pw)ytIkj!F28Dhs$dmOIse}@e-cqex&f_Q=l^h${EIv zrpS--NQ}-REzBx|P9Ig(vWPAWwi+h2hvv&*^fg&z_J zE&J9uZME&Yo^XFU%wYbVga9^<7F(`KKHlNoi_?&ZPHITZRxG;8wkK(xww4CUeBSTh z-hf_g5MOU*E-Q6?_Udh?k~6<~+^p7Xz#aYem$B)Ca4|pdPYe7}*{Y78YBt!AqX*8; zG71X)(+@NMWTKzOLkbSnb;abPF-cEDq<>TITCs(1^J&neL^2Cc!B|5z%Yvei8l5T& zx~NpxPzkoJp@lD3euqkH=Q547N;9ph?Ks-3)}^gl&2&Bn`*vUj&*a>ThOm+EH+xVb zOT(^KO?PZo3L<}z)k2A+X`H{!0j)c6Z(=8SAA%X-1bMSSa6(LixN%wv;$nV7IS3WO z;wE|>FB>S2&LPi7khFxLETWGI#LTqIu4H!O{8Jua2xaJU1guSiUUFRVf_j^#&d8%JCZ z#}vUsJOy5@$z2jlX^zdxJ1d=Ay+sr+Q@=$d>q&51kbfh-cyZ-8k6uc0oh{^|gplLD zZ-nS!K2c#xXBMH_Iq=i+waq@;Ov-OZlyj%PZh5*DLL~C?DG!TCibgXH=z?=g??Xj& zPT)0OHVVvj2nT^mW)+W9a?OHV_KFS<$ z)u8-RCo6-aepfsRX11gl<9SFuc)@7Hv`|hxQa^-^L-|15c~EGuL%0I~u4d@i9m3T@ zoAZtl6f+*)7(uAv2#t8a5sQjf{LZ;K7c$R8$o`?%C>-Hl_v;FYxO^J}Y`X<$@GI<> z7x6938R{+br6KnFuRh-YE>tJ#JU^lTTd02d_h$HaprZVbK3qWsNfIGbTVwP8)s!ph zZft7rY++~n&-9kUf)tP-3U5(sRhDT@#=Q2ta7OdIG<>Ln5(y0wW^dePzVU_ibnJro zim<#OypI4r>b52@Fl1&xh8O%vu2XxS{tZ5WoWe`I@Q!FfG%5!SH}dy*P-IJ`Iu+LD zpEQGlq%Fu$DT@x_gF2Pty@d=35kOsL=&9+0Ne0(An7hpD{aeK@M3FA@oOBT6$^`tz4tnpMZ)+ z0(sdz0I(=n#CoMTd>}o2$rKoRlXjhVhVD4 z*X;Dq%=9|GU#}0iJ$wm^CxSGQZ9Y0=z*es}wRG*HtMr`ZM{5ZP(hKgKA~jIMdPfb* zd%P5pO}>6v+@)6~iiVu-JGgX7r6o>p(&Ps6>C;uengt9&lE`lXxFFqwm6w3V3!osi zr577{8!nfwgZ5hF;Ov;;^9QZtle)P+We`0khQKKx$-Xm>*fwecy|dTy0BQ_mi4G3)aouWY)BV z0>`1m>(ocwEAfH$jU`;PN%XlM8KeB-xf)oNlx8@pdxlCGdqUZ510Dmm7`rLl0Oyv4 zM_RA#16*_hm- zJJZ>P`EduFz7#0g#&u+i>EdY6xU@%wXdq^rnRUc7iVq-f@+vXni=q!ONhCO7Q40se z$)Kt2(VHmUL4sSN0lUwf1}s3+A*_Y{`Rin=#7e!QlVb0Lw>XQL1|jjPbPs@`clE&W zH()T#9J@QEFnJNuOa5`$<{u!ULZ@i1w7iP#Y+!NU1H5L(V81*99aOmNm$us-z|c21 zs0U}7?Tvp93jyf?dJV470_YhduHg1$*zFSswD%9`zCr&rkjhnAOM`*}06_iy3&4MH zn*ZJ^{$Z{)YP#yk;uyZ6-qwvY!5~E>;e{=U1VCCbP`>^mmX?8N2%wvbq?m?`>+{ zmaH--17`^xXzAUmNDSGsAC=8jR#HR^$=Z`?yM^ADAv@L1>=!%jP>U5rBp`Bsq`c~v z<5AXrBA->3TzQwCw-AQm`9;a+J%vt{f?luF5RlZ#RmP*CGEg~ks8OZQ*QK|DfVS(* z=Q3Su*5?;cCmUW^HP5d5Y!)6La1k8yN zP#&TT2zaU19TVp$+OG}(n(dJrggskplskd7=*)`E&do(1Pu#u7ZpWHKPicY%8%-`d zVRK^tmGW8`AiYN?19l*_^n8?jwwwi&vDJkmhmk(48sIaBYnvWRO>E ziPc_u9|8X7c#}))uEFx$1(5p0E=6g<&-G>hC$YSUJyITKOJR)VdA?ekbt&optK__+ zn%b5)jDkoJK|}-tQWLr$2#Qqc3B83NL8{b%2?P)X6+`bJRS=XeQlu!MOYdEpG^K-B zXiDdW=hbMg_mz{Cm6Jc_%g#P)&Fnoh`!}Yq+j%ZaVWeob!^%SO>e?LSag<(}q38$7 zOp9kOtS9c+$Ewy%yee)!rZF>dZ}K^&%HN`HGe27NNG(9lq!1dMXRT5h&r{Y@^j;TyE68kGG~WdsIzgmj^}`t%R9F-n+4#}-_&a=QnTT=tv0STj*+PZ zi1ObVDL&_84rSeIniIJ;;B)LCf>+G#CFhl9$~^h{;G#v1Rhuo-CcTMi^>4FA&GWLR zg6Ku(PW3F_EP)u;sf?u;6dju)eH*+wqT>UvSuqET+ix%Hm%ZO&WCV`JcIl0yja#K6 zZwpA;PdNB;RC15*0xnTJt!89uhle8RlQ=M%tamwV9PU-ZDz4tn^cWQjSCrt}kuI919>%1{u829;; z&Qzs^H1S;5=cZD(x3!^T{+}qXf9`I{?2C(fS|gbC^=#cUVqY>8+cuv^lo@;}#~9j< zEZW(TOMeaxu)0%%@mfS)jS6#2n=kAR4l(MsR;6}T5`!;{(pTDXhV)qBc3{aZ!fES4oUHwFydX~hSV zxY{w%Nw2|9Lf#_Su5#<)XBE5F+qCoVdzS1&cBD3YOD8>Q7wBVKgTC}Krzrb=+Lq)k zSy;>N(dh{lNYUPhnqel?UHQo=`Ld&m&v%KkKNcUyaN1d0tzk7Sg=#3Efmh?TPuQ0% zSysB#ygHt}BT+#`bv_Y<3c4Nb0azb>w|i#lfS^-e_*E}C13+mUa~#FPLXSJArnY1CDKBvfj)XD82YbZzVd`msMLG}ky4;XZ z*(`}-jn!rKTRZ5&w?{=vA<6|Xjl3>F)!3R*Rza!cMFh4p=ca>A4`eyZMA`2#TE>$h zckAmNdcNc66BHSrJtCc8%CRwC`(cY)u{{N%Bf>cxLsqEa)ub>C0xasvAv1k7xtVgN z(pJLWd%VPk&lzzgefot^N4KDXeLfeIWdNnd{XAGT(n+V8j!)#w5P7a)zdbgxvj_FS z0i$1-5X5+i=UdBeYM3rUBgTMzT=nXWCR<+WA+Lc{TK5J)nGbTJUl7*LkA|vKr}+y$ zI^=D5j-E+K9zuC|CH#ITqJ*=sPk4)*pqn=Rzu~XF!t-ew!IcMa)V;Ugb8{ z>LZE5a#NC@chp)7Vi<5*uZTQSliEtC+ZnAc@0ug!UuSn2a>@Ko!zv^=t2UW8a58E0 zrO1Jxx|zPb`QZ4Ih=ih#Fv^Nfmv$quAppI>cwR!Net+?nG4JVX<6lMT+73`XSw_?R zYg25oLjAitm0FTD4v>Zt$eRk=V|V(wyC&eOrI$ly?oaTd3JhJs&@8SwAm~weP8j^j5xwTTzKM>^zoR57E}vhr^)MfPR|4{)n2dg#k@;p z=`cEuYJc}vq6K`xURK*s?P*zRT90~_1)V5IhT(O<; zm!k{aMFxl{Ndu;mB3Z~$y)EH>*mYdDplm`iB}3{wKW)7HIfLGC_ddA%`5~SZ+M9PU z!j)jdn8jfITKk6hMs`ET-Ze4k3!gjLbq&H|i+OSrcQg5U&R#F$&c~K#mw{*us^nSo z?_|lsw|r#bI~TmM+hA|(K99HKDF`JxQL8{!)n}U|hqjHZM9oH)^;2Vn>{zIoH(2*sa3N8A3;c|2-y}ahsXPmzm}QQ%;>);@km+|hW`+Z`>IK{ii}IAz zxch{2Qa_3kwdxnO8yn>*tdY;x`i*^6)Q)YmsmwIVE%aM=_)!^+LBEx9fZN;Qd9w`d6uW$>rqhr~d4b+9xImkczDg}YTAwYmc-dd3;v(2D!^0pcXB zaW|E7D0+`2xO7P#=uRBV?zH01u*Ct~dK%>k(%6TAC-kDa8(UMjTU~%#=1IE=Q3$@) zxTzVz=otaCo2#!Rg&umEZp-X3dDWQDeR{X73*UQ8-61mI0$qt2=NStR;9FHKr>IG7 z|7aib9>COGx>Kj#h8$hjd}3h}5l>ZE1!7_|uB6;&aOv^y^;NF6QrT8H_+?Sbj+4|n zO)m{L!8uhLTxv%c=Tv{{P<_{g`jgDl50xe)?vUro zSF0Z&=gL85X#h{HRBZaVcoF+C_M;!$K{QLthkaO^tI0emg60T$;02bU4J;hwby*Nt zKHEf*_qEh*rAuroXc3-mes5=WN`BRK$M{tYRLR77j^;_s_++xU!N*fNeMb30dEAMp zT=i?xUXsAc_sj)A)^BrA^g>02gy%QVJCKA##Y}krL+4>wp91%XY;z`8!$ND!7X^`} z2fEbftzY@az_xEGGHHWLMMj6fUCC=Cs0C!>PxojZlxpk#1{ zs{=f?XE~zJab-q})4)IwJ4YSi2t}=jONa+tJhn1Zw3}Y?lq#OC>gtf~ZmW@nAk0cQ3F{%E+ zBb1hNTUOr4YaQwN&iv@-sq&3Qk!ItmD!ozG^J+~ldbPKU!$2x9h2D#A z&KTGBCT(f;>H$d1oR6*3p3sir(2pAvk}x+ zhhLEGADvcvz6&@(&ZxvVeSWTl#t~}be!bTH(&a!>(-A!%bj-=E(8LT=_(<g>O0f$E^*vne14-?EF5t*6E*2>FqvH zA<;vo96^9_t$PrE5Zrwo^DdT(3=V^u0m+pRCo1lmgZfFPvO{7F^nM>6Kfwaby8^Mfz?xi$eWLBl*OOz6{Q=jb1i zL<)UY>5C^ludg%N%;#D}w_wiyx7I_CA>;MZ<`*d%7k<%?}syNl885r0{9&!}PM%wC;VTpla zL4(JoVDR)Kw(dgo_hL8~SksShnOz#{sAC}owjRi(HTe&9rip1&3oY`zxvd_3I{|W5 zf2D-?^VDaP)Fvn$uPw7jc0-}WeO+^pgOIAaoiC3V-X}I3D?Q0A|_ly3mS^riDxwPy#WZ2<7F2N?Rg{JD|*ygn7OT|>4VTWox;|3 z@nEIY&I-fe9m`F<4iTRGcNwMJ+nuZxdWT7ovU;%MaVveRjT!`+1*rEJli zulbanYsqj&o_>;VK84cjK0rJCCF%xh?qIs8w*k`QH(grhm~3Is%aUC3A)ucnM={XB zgsKxexd*r~x_$Qd96}}+MZ5&gO&`9+|9^Llbh?GS>4dhu>8#4n+p4Cjc40-WP(Y)r zL!G~E4kFklC_uET8@vGtE{fXFQ4JCi+2{+V?O!cx(+Lg|SzAMdu7_Z83D6@)>4@(Fc!cmG`~@o=br z{-Hy$#P8Rk1syJbduZ`ja66Pv{Abfc@kG3-49@iDzx*Mk_|L|NVv2ZU#NUno6m$R6 zXb!~{@xZ+Q4frF7e+T0qCZX8k4|KZsSHc-%k*f0iK$8HD8-JmaAxA>+RnYY6Ft^#?qiMw*cRdo_ZPM3@`Kld5G2Nk7N= zJ+ncGB21IuQTvMjh{D&WeodPEivH7P0gu*I{hJT`lNYoC c|C^7Gby}*&a9Tq|L}ziYLfl<64n{=uFEvdAO8@`> literal 0 HcmV?d00001 From 42455732379526f187d774f8c913683add8c2493 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Thu, 1 Aug 2024 18:23:15 +0200 Subject: [PATCH 010/111] translation process work, generation of class files not yet (WIP) --- .../org/opalj/tactobc/ExprProcessor.scala | 26 ++++++++++---- .../scala/org/opalj/tactobc/FirstPass.scala | 4 ++- .../scala/org/opalj/tactobc/SecondPass.scala | 5 ++- .../org/opalj/tactobc/StmtProcessor.scala | 34 +++++++++++++++++-- 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index a3c37d1239..a05d8f5323 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -2,8 +2,8 @@ package org.opalj.tactobc import org.opalj.BinaryArithmeticOperators.{Add, And, Divide, Modulo, Multiply, Or, ShiftLeft, ShiftRight, Subtract, UnsignedShiftRight, XOr} -import org.opalj.br.{ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FloatType, IntegerType, LongType, ObjectType, ShortType} -import org.opalj.br.instructions.{AALOAD, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BIPUSH, D2F, D2I, D2L, DADD, DALOAD, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, NEW, NEWARRAY, SIPUSH} +import org.opalj.br.{BooleanType, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FloatType, IntegerType, LongType, ObjectType, ReferenceType, ShortType} +import org.opalj.br.instructions.{AALOAD, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BIPUSH, D2F, D2I, D2L, DADD, DALOAD, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, MULTIANEWARRAY, NEW, NEWARRAY, SIPUSH} import org.opalj.bytecode.BytecodeProcessingFailedException import org.opalj.collection.immutable.IntTrieSet import org.opalj.tac.{ArrayLength, ArrayLoad, BinaryExpr, ClassConst, Const, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, LongConst, MethodHandleConst, MethodTypeConst, New, NewArray, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} @@ -35,17 +35,29 @@ object ExprProcessor { def handleNewArray(newArrayExpr: NewArray[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // Initialize the PC after processing the counts var currentAfterCountsPC = currentPC - // Process each parameter and update the PC accordingly for (count <- newArrayExpr.counts) { currentAfterCountsPC = ExprProcessor.processExpression(count, instructionsWithPCs, currentAfterCountsPC) } + if(newArrayExpr.counts.size > 1) { + val instruction = MULTIANEWARRAY(newArrayExpr.tpe.toString, newArrayExpr.counts.size) + instructionsWithPCs += ((currentAfterCountsPC, instruction)) + return currentAfterCountsPC + instruction.length + } //todo: handle the differenciation between: - //NEWARRAY, ANEWARRAY and MULTIANEWARRAY + //NEWARRAY, ANEWARRAY and MULTIANEWARRAY (done) //val instruction = NEWARRAY(newArrayExpr.tpe.id) - val instruction = newArrayExpr.tpe.elementType.computationalType match { - case ComputationalTypeReference => ANEWARRAY(newArrayExpr.tpe) - case _ => NEWARRAY + val instruction = newArrayExpr.tpe.componentType match { + case _: ReferenceType => ANEWARRAY(newArrayExpr.tpe) + case _: BooleanType => NEWARRAY(BooleanType.atype) + case _: CharType => NEWARRAY(CharType.atype) + case _: FloatType => NEWARRAY(FloatType.atype) + case _: DoubleType => NEWARRAY(DoubleType.atype) + case _: ByteType => NEWARRAY(ShortType.atype) + case _: ShortType => NEWARRAY(ShortType.atype) + case _: IntegerType => NEWARRAY(IntegerType.atype) + case _: LongType => NEWARRAY(LongType.atype) + case _ => throw new IllegalArgumentException("Unsupported array load type") } instructionsWithPCs += ((currentAfterCountsPC, instruction)) currentAfterCountsPC + instruction.length diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index 422474bda6..8b9df8abc0 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -1,7 +1,7 @@ package org.opalj.tactobc import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, DUVar, Expr, ExprStmt, If, NewArray, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, ReturnValue, StaticFunctionCall, Stmt, UVar, VirtualFunctionCall, VirtualMethodCall} +import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, DUVar, Expr, ExprStmt, If, NewArray, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, Stmt, UVar, VirtualFunctionCall, VirtualMethodCall} import org.opalj.tactobc.ExprProcessor.{nextLVIndex, uVarToLVIndex} import org.opalj.value.ValueInformation @@ -47,6 +47,8 @@ object FirstPass { case PutField(_, _, _, _, objRef, value) => collectDUVarFromExpr(objRef, duVars) collectDUVarFromExpr(value, duVars) + case PutStatic(_, _, _, _, value) => + collectDUVarFromExpr(value, duVars) case NonVirtualMethodCall(_, _, _, _, _, receiver, params) => collectDUVarFromExpr(receiver, duVars) for (param <- params) { diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala index 4eaeef6262..96e7a943e6 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala @@ -1,7 +1,7 @@ package org.opalj.tactobc import org.opalj.br.instructions.Instruction -import org.opalj.tac.{ArrayStore, Assignment, CaughtException, Checkcast, DUVar, ExprStmt, Goto, If, InvokedynamicMethodCall, JSR, MonitorEnter, MonitorExit, NonVirtualMethodCall, PutField, PutStatic, Ret, Return, ReturnValue, StaticMethodCall, Stmt, Switch, Throw, VirtualMethodCall} +import org.opalj.tac.{ArrayStore, Assignment, CaughtException, Checkcast, DUVar, ExprStmt, Goto, If, InvokedynamicMethodCall, JSR, MonitorEnter, MonitorExit, NonVirtualMethodCall, Nop, PutField, PutStatic, Ret, Return, ReturnValue, StaticMethodCall, Stmt, Switch, Throw, VirtualMethodCall} import org.opalj.value.ValueInformation import scala.collection.mutable.ArrayBuffer @@ -102,6 +102,9 @@ object SecondPass { case Throw(_, exception) => tacTargetToByteCodePcs += ((-1, currentPC)) currentPC = StmtProcessor.processThrow(exception, generatedByteCodeWithPC, currentPC) + case Nop(_) => + tacTargetToByteCodePcs += ((-1, currentPC)) + currentPC = StmtProcessor.processNop(generatedByteCodeWithPC, currentPC) case _ => } } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index da565ec06f..f91e1a9454 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -4,7 +4,7 @@ package org.opalj.tactobc import org.opalj.RelationalOperator import org.opalj.RelationalOperators._ import org.opalj.br.{BootstrapMethod, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, FieldType, MethodDescriptor, ObjectType, PCs, ReferenceType} -import org.opalj.br.instructions.{ARETURN, ATHROW, DRETURN, FRETURN, GOTO, IFNONNULL, IFNULL, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, PUTFIELD, PUTSTATIC, RET, RETURN, TABLESWITCH} +import org.opalj.br.instructions.{AASTORE, ARETURN, ATHROW, DASTORE, DRETURN, FASTORE, FRETURN, GOTO, IASTORE, IFNONNULL, IFNULL, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, LASTORE, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, NOP, PUTFIELD, PUTSTATIC, RET, RETURN, TABLESWITCH} import org.opalj.collection.immutable.{IntIntPair, IntTrieSet} import org.opalj.tac.{Expr, UVar, Var} @@ -121,7 +121,37 @@ object StmtProcessor { def processArrayStore(arrayRef: Expr[_], index: Expr[_], value: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { //todo: handle this correctly - 1 + // Load the array reference onto the stack + val pcAfterArrayRefLoad = ExprProcessor.processExpression(arrayRef, instructionsWithPCs, currentPC) + + // Load the index onto the stack + val pcAfterIndexLoad = ExprProcessor.processExpression(index, instructionsWithPCs, pcAfterArrayRefLoad) + + // Load the value to be stored onto the stack + val pcAfterValueLoad = ExprProcessor.processExpression(value, instructionsWithPCs, pcAfterIndexLoad) + + // Determine the type of the value to be stored and select the appropriate store instruction + val instruction = value.cTpe match { + case ComputationalTypeInt => IASTORE + case ComputationalTypeLong => LASTORE + case ComputationalTypeFloat => FASTORE + case ComputationalTypeDouble => DASTORE + //case UVar(_, _: Byte) => BASTORE + //case UVar(_, _: Char) => CASTORE + //case UVar(_, _: Short) => SASTORE + case ComputationalTypeReference => AASTORE + case _ => throw new IllegalArgumentException("Unsupported array store type") + } + + // Add the store instruction + instructionsWithPCs += ((pcAfterValueLoad, instruction)) + pcAfterValueLoad + instruction.length + } + + def processNop(instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + val instruction = NOP + instructionsWithPCs += ((currentPC, instruction)) + currentPC + instruction.length } def processInvokeDynamicMethodCall(bootstrapMethod: BootstrapMethod, name: String, descriptor: MethodDescriptor, params: Seq[Expr[_]]): Int = { From b5d42993ea7f0ad5a8dbf441937b513ac41168ee Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Thu, 1 Aug 2024 19:19:21 +0200 Subject: [PATCH 011/111] generation of class files (WIP) added parameters for: path to dir where the .class files are and for the path to dir where the new .class files are going to be located --- .../scala/org/opalj/tactobc/TACtoBC.scala | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala index 8cc1fcb709..94ece88c11 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala @@ -27,18 +27,24 @@ import scala.jdk.CollectionConverters.EnumerationHasAsScala object TACtoBC { def main(args: Array[String]): Unit = { - if (args.length != 1) { - println("Usage: ListClassFiles ") + if (args.length != 2) { + println("Usage: ListClassFiles ") return } val inputDirPath = args(0) + val outputDirPath = args(1) val inputDir = new File(inputDirPath) if (!inputDir.exists() || !inputDir.isDirectory) { println(s"Directory ${inputDir.getPath} does not exist or is not a directory.") return } + val outputDir = new File(outputDirPath) + if (!outputDir.exists()) { + outputDir.mkdirs() + } + val classFiles = listClassFiles(inputDir) classFiles.foreach{ classfile => @@ -63,7 +69,7 @@ object TACtoBC { } //(4) generate .class files from translation val p = Project(classfile) - generateClassFiles(byteCodes, p) + generateClassFiles(byteCodes, p, inputDirPath, outputDirPath, classfile.getName) // println(classfile.getAbsolutePath))) } } @@ -72,7 +78,7 @@ object TACtoBC { directory.listFiles().toList.filter(_.getName.endsWith(".class")) } - def generateClassFiles(byteCodes: Map[Method, ArrayBuffer[(Int, Instruction)]], p: Project[_]) : Unit = { + def generateClassFiles(byteCodes: Map[Method, ArrayBuffer[(Int, Instruction)]], p: Project[_], inputDirPath: String, outputDirPath: String, classFileName: String): Unit = { val TheType = ObjectType("org/opalj/tactobc/testingtactobc/HelloWorld") // Debugging: Print the location of the class loader and resources @@ -81,10 +87,13 @@ object TACtoBC { println(s"ClassLoader: $loader") println(s"Resources: ${resources.mkString(", ")}") + // Dynamically determine the type and resource stream + val inputFilePath = Paths.get(inputDirPath, classFileName).toString + val outputFilePath = Paths.get(outputDirPath, classFileName).toString + val in = () => { - //todo: change this to be the input stream of the class file and give the classfile as parameter - val stream = this.getClass.getResourceAsStream("/org/opalj/tactobc/testingtactobc/HelloWorld.class") - if (stream == null) throw new RuntimeException("Resource not found: /HelloWorld.class") + val stream = Files.newInputStream(Paths.get(inputFilePath)) + if (stream == null) throw new RuntimeException(s"Resource not found: $inputFilePath") stream } val cf = Java8Framework.ClassFile(in).head @@ -211,18 +220,19 @@ object TACtoBC { } val cfWithNewInstructionsForReal = cf.copy(methods = newMethodsForReal) val newRawCF = Assembler(toDA(cfWithNewInstructionsForReal)) - val assembledMyIntfPath = Paths.get("tmp", "org", "opalj", "tactobc", "testingtactobc", "HelloWorld.class") - val newClassFile = Files.write(assembledMyIntfPath, newRawCF) + val outputClassFilePath = Paths.get(outputFilePath + classFileName) + Files.createDirectories(outputClassFilePath.getParent) + val newClassFile = Files.write(outputClassFilePath, newRawCF) println("Created class file: " + newClassFile.toAbsolutePath) // Let's see the old class file... val odlCFHTML = ClassFile(in).head.toXHTML(None) - val oldCFHTMLFile = writeAndOpen(odlCFHTML, "HelloWorld", ".html") + val oldCFHTMLFile = writeAndOpen(odlCFHTML, "original", ".html") println("original: " + oldCFHTMLFile) // Let's see the new class file... val newCF = ClassFile(() => new ByteArrayInputStream(newRawCF)).head.toXHTML(None) - println("genetated from TAC: " + writeAndOpen(newCF, "HelloWorld", ".html")) + println("genetated from TAC: " + writeAndOpen(newCF, "translated", ".html")) //println("Class file GeneratedHelloWorldToStringDALEQUEE.class has been generated." + newClass) // Let's test that the new class does what it is expected to do... (we execute the From 48e27cc97271e45cddf7b359dc7ce498040c9da4 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Thu, 1 Aug 2024 19:23:54 +0200 Subject: [PATCH 012/111] probably fixed PutStatic --- .../src/main/scala/org/opalj/tactobc/StmtProcessor.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index f91e1a9454..f8626e497b 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -184,10 +184,10 @@ object StmtProcessor { } def processPutStatic(declaringClass: ObjectType, name: String, declaredFieldType: FieldType, value: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - //todo: look what to do with the value :) + val pcAfterValueExpr = ExprProcessor.processExpression(value, instructionsWithPCs, currentPC) val instruction = PUTSTATIC(declaringClass, name, declaredFieldType) - instructionsWithPCs += ((currentPC, instruction)) - currentPC + instruction.length + instructionsWithPCs += ((pcAfterValueExpr, instruction)) + pcAfterValueExpr + instruction.length } def processPutField(declaringClass: ObjectType, name: String, declaredFieldType: FieldType, objRef: Expr[_], value: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { From 803eeb83664b1bb1ce38566de48534c5ad8c9baa Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Thu, 1 Aug 2024 19:29:35 +0200 Subject: [PATCH 013/111] probably fixed PutField --- .../src/main/scala/org/opalj/tactobc/StmtProcessor.scala | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index f8626e497b..59b215ee63 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -191,10 +191,13 @@ object StmtProcessor { } def processPutField(declaringClass: ObjectType, name: String, declaredFieldType: FieldType, objRef: Expr[_], value: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - //todo: look what to do with the value AND the objRef :) + // Load the object reference onto the stack + val pcAfterObjRefLoad = ExprProcessor.processExpression(objRef, instructionsWithPCs, currentPC) + // Load the value to be stored onto the stack + val pcAfterValueLoad = ExprProcessor.processExpression(value, instructionsWithPCs, pcAfterObjRefLoad) val instruction = PUTFIELD(declaringClass, name, declaredFieldType) - instructionsWithPCs += ((currentPC, instruction)) - currentPC + instruction.length + instructionsWithPCs += ((pcAfterValueLoad, instruction)) + pcAfterValueLoad + instruction.length } def processMonitorEnter(objRef: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { From b682731397fccbae9f9fd12d05cb15dc948abf37 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Thu, 1 Aug 2024 19:45:09 +0200 Subject: [PATCH 014/111] probably fixed Monitor Enter and MonitorExit --- .../scala/org/opalj/tactobc/ExprProcessor.scala | 9 --------- .../scala/org/opalj/tactobc/StmtProcessor.scala | 15 ++++++++------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index a05d8f5323..b9a4e74882 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -44,9 +44,6 @@ object ExprProcessor { instructionsWithPCs += ((currentAfterCountsPC, instruction)) return currentAfterCountsPC + instruction.length } - //todo: handle the differenciation between: - //NEWARRAY, ANEWARRAY and MULTIANEWARRAY (done) - //val instruction = NEWARRAY(newArrayExpr.tpe.id) val instruction = newArrayExpr.tpe.componentType match { case _: ReferenceType => ANEWARRAY(newArrayExpr.tpe) case _: BooleanType => NEWARRAY(BooleanType.atype) @@ -296,18 +293,12 @@ object ExprProcessor { case 3 => ASTORE_3 case _ => ASTORE(index) } - //todo: handle AASTORE case _ => throw new UnsupportedOperationException("Unsupported computational type for storing variable" + variable) } instructionsWithPCs += ((currentPC, storeInstruction)) currentPC + (if (index < 4) 1 else 2) } - //todo: probably get rid of this :) - def handleArrayStore(variable: Var[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - 1 - } - private def handleFieldAccess(fieldExpr: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { val instruction = fieldExpr match { case getFieldExpr: GetField[_] => diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index 59b215ee63..21d7b44ccb 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -121,7 +121,6 @@ object StmtProcessor { def processArrayStore(arrayRef: Expr[_], index: Expr[_], value: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { //todo: handle this correctly - // Load the array reference onto the stack val pcAfterArrayRefLoad = ExprProcessor.processExpression(arrayRef, instructionsWithPCs, currentPC) // Load the index onto the stack @@ -201,16 +200,18 @@ object StmtProcessor { } def processMonitorEnter(objRef: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - //todo: look what to do with the objRef :) + // Load the object reference onto the stack + val pcAfterObjRefLoad = ExprProcessor.processExpression(objRef, instructionsWithPCs, currentPC) val instruction = MONITORENTER - instructionsWithPCs += ((currentPC, instruction)) - currentPC + instruction.length + instructionsWithPCs += ((pcAfterObjRefLoad, instruction)) + pcAfterObjRefLoad + instruction.length } def processMonitorExit(objRef: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - //todo: look what to do with the objRef :) + // Load the object reference onto the stack + val pcAfterObjRefLoad = ExprProcessor.processExpression(objRef, instructionsWithPCs, currentPC) val instruction = MONITOREXIT - instructionsWithPCs += ((currentPC, instruction)) - currentPC + instruction.length + instructionsWithPCs += ((pcAfterObjRefLoad, instruction)) + pcAfterObjRefLoad + instruction.length } def processJSR(target: Int, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { From 44a2d79496fd4be06dc84d8b494b179e139380ed Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Thu, 1 Aug 2024 20:19:28 +0200 Subject: [PATCH 015/111] probably fixed NonVirtualMethodCall --- .../src/main/scala/org/opalj/tactobc/StmtProcessor.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index 21d7b44ccb..902db9a3fd 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -232,9 +232,8 @@ object StmtProcessor { currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) } val instruction = INVOKESPECIAL(declaringClass, isInterface, methodName, methodDescriptor) - val finalPC = currentPC + currentAfterParamsPC - instructionsWithPCs += ((finalPC, instruction)) - finalPC + instruction.length + instructionsWithPCs += ((currentAfterParamsPC, instruction)) + currentAfterParamsPC + instruction.length } def processStaticMethodCall(declaringClass: ObjectType, isInterface: Boolean, methodName: String, methodDescriptor: MethodDescriptor, params: Seq[Expr[_]], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { From ac2c4bcca28f6d00e5dd9064c1c7965ed214979e Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Fri, 2 Aug 2024 18:27:37 +0200 Subject: [PATCH 016/111] probably fixed ReturnValue --- .../src/main/scala/org/opalj/tactobc/StmtProcessor.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index 902db9a3fd..4feb6414f3 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -92,9 +92,8 @@ object StmtProcessor { case ComputationalTypeReference => ARETURN case _ => throw new UnsupportedOperationException("Unsupported computational type:" + expr.cTpe) } - val offsetPC = currentPC + (afterExprPC - currentPC) - instructionsWithPCs += ((currentPC, instruction)) - currentPC + offsetPC + instructionsWithPCs += ((afterExprPC, instruction)) + afterExprPC + instruction.length } def processVirtualMethodCall(declaringClass: ReferenceType, isInterface: Boolean, methodName: String, methodDescriptor: MethodDescriptor, receiver: Expr[_], params: Seq[Expr[_]], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { From 7e93e15c5e26c5fed56183d5c535643078163b1d Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Fri, 2 Aug 2024 19:51:10 +0200 Subject: [PATCH 017/111] generating .class files again works! :) --- OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala index 94ece88c11..605d8abc11 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala @@ -79,7 +79,7 @@ object TACtoBC { } def generateClassFiles(byteCodes: Map[Method, ArrayBuffer[(Int, Instruction)]], p: Project[_], inputDirPath: String, outputDirPath: String, classFileName: String): Unit = { - val TheType = ObjectType("org/opalj/tactobc/testingtactobc/HelloWorld") + val TheType = ObjectType("jnt/scimark2/".concat(classFileName.replace(".class", ""))) // Debugging: Print the location of the class loader and resources val loader = this.getClass.getClassLoader @@ -220,7 +220,7 @@ object TACtoBC { } val cfWithNewInstructionsForReal = cf.copy(methods = newMethodsForReal) val newRawCF = Assembler(toDA(cfWithNewInstructionsForReal)) - val outputClassFilePath = Paths.get(outputFilePath + classFileName) + val outputClassFilePath = Paths.get(outputFilePath) Files.createDirectories(outputClassFilePath.getParent) val newClassFile = Files.write(outputClassFilePath, newRawCF) println("Created class file: " + newClassFile.toAbsolutePath) From cc16c440c36ba870be8c1beb43dbebdfe8f4fd8c Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 4 Aug 2024 09:55:05 +0200 Subject: [PATCH 018/111] added StaticMethodCall for collecting DUVars --- .../src/main/scala/org/opalj/tactobc/FirstPass.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index 8b9df8abc0..c7e1fbc074 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -1,7 +1,7 @@ package org.opalj.tactobc import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, DUVar, Expr, ExprStmt, If, NewArray, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, Stmt, UVar, VirtualFunctionCall, VirtualMethodCall} +import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, DUVar, Expr, ExprStmt, If, NewArray, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, StaticMethodCall, Stmt, UVar, VirtualFunctionCall, VirtualMethodCall} import org.opalj.tactobc.ExprProcessor.{nextLVIndex, uVarToLVIndex} import org.opalj.value.ValueInformation @@ -49,6 +49,10 @@ object FirstPass { collectDUVarFromExpr(value, duVars) case PutStatic(_, _, _, _, value) => collectDUVarFromExpr(value, duVars) + case StaticMethodCall(_,_,_,_,_,params) => + for (param <- params) { + collectDUVarFromExpr(param, duVars) + } case NonVirtualMethodCall(_, _, _, _, _, receiver, params) => collectDUVarFromExpr(receiver, duVars) for (param <- params) { From 7e2ee643d0c6974aad4d0313d6fb194043cdb35e Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 4 Aug 2024 10:34:44 +0200 Subject: [PATCH 019/111] idea for matching between ArrayTypes that works for primitive types --- .../org/opalj/tactobc/ExprProcessor.scala | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index b9a4e74882..36d830b8fa 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -2,11 +2,12 @@ package org.opalj.tactobc import org.opalj.BinaryArithmeticOperators.{Add, And, Divide, Modulo, Multiply, Or, ShiftLeft, ShiftRight, Subtract, UnsignedShiftRight, XOr} -import org.opalj.br.{BooleanType, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FloatType, IntegerType, LongType, ObjectType, ReferenceType, ShortType} -import org.opalj.br.instructions.{AALOAD, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BIPUSH, D2F, D2I, D2L, DADD, DALOAD, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, MULTIANEWARRAY, NEW, NEWARRAY, SIPUSH} +import org.opalj.br.{ArrayType, BooleanType, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FloatType, IntegerType, LongType, ObjectType, ReferenceType, ShortType, Type} +import org.opalj.br.instructions.{ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BIPUSH, D2F, D2I, D2L, DADD, DALOAD, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, MULTIANEWARRAY, NEW, NEWARRAY, SIPUSH} import org.opalj.bytecode.BytecodeProcessingFailedException import org.opalj.collection.immutable.IntTrieSet import org.opalj.tac.{ArrayLength, ArrayLoad, BinaryExpr, ClassConst, Const, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, LongConst, MethodHandleConst, MethodTypeConst, New, NewArray, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} +import org.opalj.value.IsSReferenceValue import scala.collection.mutable import scala.collection.mutable.ArrayBuffer @@ -65,22 +66,35 @@ object ExprProcessor { val pcAfterArrayRefLoad = processExpression(arrayLoadExpr.arrayRef, instructionsWithPCs, currentPC) // Load the index onto the stack val pcAfterIndexLoad = processExpression(arrayLoadExpr.index, instructionsWithPCs, pcAfterArrayRefLoad) - val instruction = arrayLoadExpr.arrayRef.cTpe match { - case ComputationalTypeInt => IALOAD - case ComputationalTypeLong => LALOAD - case ComputationalTypeFloat => FALOAD - case ComputationalTypeDouble => DALOAD + + // Infer the element type from the array reference expression + val elementType = inferElementType(arrayLoadExpr.arrayRef) + + val instruction = elementType match { + case IntegerType => IALOAD + case LongType => LALOAD + case FloatType => FALOAD + case DoubleType => DALOAD //Todo: look how to compare with primitives (?) //case ComputationalType => BALOAD //case Compu => CALOAD //case C => SALOAD - case ComputationalTypeReference => AALOAD - case _ => throw new IllegalArgumentException("Unsupported array load type") + //case ReferenceType => AALOAD + case _ => throw new IllegalArgumentException("Unsupported array load type" + arrayLoadExpr.arrayRef.asVar) } instructionsWithPCs += ((pcAfterIndexLoad, instruction)) pcAfterIndexLoad + instruction.length } + + + // Helper function to infer the element type from the array reference expression + def inferElementType(expr: Expr[_]): Type = { + expr.asInstanceOf[UVar[_]].value.asInstanceOf[IsSReferenceValue[_]].theUpperTypeBound.asInstanceOf[ArrayType] match { + case ArrayType(componentType) => componentType + case _ => throw new IllegalArgumentException(s"Expected an array type but found: ${expr.cTpe}") + } + } def handleArrayLength(arrayLength: ArrayLength[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // Process the receiver object (e.g., aload_0 for `this`) val afterReceiverPC = ExprProcessor.processExpression(arrayLength.arrayRef, instructionsWithPCs, currentPC) From b1f03c937e24d127de3b38e7c19cee0c587efc13 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 4 Aug 2024 10:41:07 +0200 Subject: [PATCH 020/111] probably handling ArrayLoad correctly for all types --- .../org/opalj/tactobc/ExprProcessor.scala | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index 36d830b8fa..6c031a8c4d 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -3,7 +3,7 @@ package org.opalj.tactobc import org.opalj.BinaryArithmeticOperators.{Add, And, Divide, Modulo, Multiply, Or, ShiftLeft, ShiftRight, Subtract, UnsignedShiftRight, XOr} import org.opalj.br.{ArrayType, BooleanType, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FloatType, IntegerType, LongType, ObjectType, ReferenceType, ShortType, Type} -import org.opalj.br.instructions.{ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BIPUSH, D2F, D2I, D2L, DADD, DALOAD, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, MULTIANEWARRAY, NEW, NEWARRAY, SIPUSH} +import org.opalj.br.instructions.{AALOAD, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BALOAD, BIPUSH, CALOAD, D2F, D2I, D2L, DADD, DALOAD, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, MULTIANEWARRAY, NEW, NEWARRAY, SALOAD, SIPUSH} import org.opalj.bytecode.BytecodeProcessingFailedException import org.opalj.collection.immutable.IntTrieSet import org.opalj.tac.{ArrayLength, ArrayLoad, BinaryExpr, ClassConst, Const, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, LongConst, MethodHandleConst, MethodTypeConst, New, NewArray, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} @@ -75,19 +75,21 @@ object ExprProcessor { case LongType => LALOAD case FloatType => FALOAD case DoubleType => DALOAD - //Todo: look how to compare with primitives (?) - //case ComputationalType => BALOAD - //case Compu => CALOAD - //case C => SALOAD - //case ReferenceType => AALOAD - case _ => throw new IllegalArgumentException("Unsupported array load type" + arrayLoadExpr.arrayRef.asVar) + case ByteType => BALOAD + case CharType => CALOAD + case ShortType => SALOAD + case _ => + if(elementType.isReferenceType){ + AALOAD + }else{ + throw new IllegalArgumentException("Unsupported array load type" + arrayLoadExpr.arrayRef.asVar) + } } instructionsWithPCs += ((pcAfterIndexLoad, instruction)) pcAfterIndexLoad + instruction.length } - // Helper function to infer the element type from the array reference expression def inferElementType(expr: Expr[_]): Type = { expr.asInstanceOf[UVar[_]].value.asInstanceOf[IsSReferenceValue[_]].theUpperTypeBound.asInstanceOf[ArrayType] match { From c7807cce7f018afd69cf90e15523629528246883 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 4 Aug 2024 11:29:07 +0200 Subject: [PATCH 021/111] probably handling ArrayLoad correctly when it is in a UVar --- .../org/opalj/tactobc/ExprProcessor.scala | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index 6c031a8c4d..7059a94ff1 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -224,7 +224,42 @@ object ExprProcessor { } } + def isArrayType(variable: Var[_]): Boolean = { + try{ + variable.asInstanceOf[UVar[_]].value.asInstanceOf[IsSReferenceValue[_]].theUpperTypeBound.asInstanceOf[ArrayType] + true + }catch { + case _: Exception => false + } + } + + def loadArray(variable: Var[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // Infer the element type from the array reference expression + val elementType = inferElementType(variable) + + val instruction = elementType match { + case IntegerType => IALOAD + case LongType => LALOAD + case FloatType => FALOAD + case DoubleType => DALOAD + case ByteType => BALOAD + case CharType => CALOAD + case ShortType => SALOAD + case _ => + if(elementType.isReferenceType){ + AALOAD + }else{ + throw new IllegalArgumentException("Unsupported array load type" + variable) + } + } + instructionsWithPCs += ((currentPC, instruction)) + currentPC + instruction.length + } + def loadVariable(variable: Var[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + if(isArrayType(variable)){ + return loadArray(variable, instructionsWithPCs, currentPC) + } val index = getVariableLvlIndex(variable) val instruction = variable.cTpe match { case ComputationalTypeInt => index match { From 0dfdc4b1cd676f9ae973a447685f863359a6855d Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 4 Aug 2024 15:28:32 +0200 Subject: [PATCH 022/111] rollback of handling UVars that are arrays They just have to be treated as reference types --- .../org/opalj/tactobc/ExprProcessor.scala | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index 7059a94ff1..6c031a8c4d 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -224,42 +224,7 @@ object ExprProcessor { } } - def isArrayType(variable: Var[_]): Boolean = { - try{ - variable.asInstanceOf[UVar[_]].value.asInstanceOf[IsSReferenceValue[_]].theUpperTypeBound.asInstanceOf[ArrayType] - true - }catch { - case _: Exception => false - } - } - - def loadArray(variable: Var[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Infer the element type from the array reference expression - val elementType = inferElementType(variable) - - val instruction = elementType match { - case IntegerType => IALOAD - case LongType => LALOAD - case FloatType => FALOAD - case DoubleType => DALOAD - case ByteType => BALOAD - case CharType => CALOAD - case ShortType => SALOAD - case _ => - if(elementType.isReferenceType){ - AALOAD - }else{ - throw new IllegalArgumentException("Unsupported array load type" + variable) - } - } - instructionsWithPCs += ((currentPC, instruction)) - currentPC + instruction.length - } - def loadVariable(variable: Var[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - if(isArrayType(variable)){ - return loadArray(variable, instructionsWithPCs, currentPC) - } val index = getVariableLvlIndex(variable) val instruction = variable.cTpe match { case ComputationalTypeInt => index match { From 86d3c2fd08b280e5fd9c6b30ed526b0c7103d2ef Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 4 Aug 2024 16:04:41 +0200 Subject: [PATCH 023/111] =?UTF-8?q?handled=20cases=20when=20there=20is=20s?= =?UTF-8?q?ome=20read=20to=20=C2=B4this=C2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/scala/org/opalj/tactobc/FirstPass.scala | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index c7e1fbc074..35ac823798 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -107,8 +107,15 @@ object FirstPass { uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) } else if (origin < -1) { if (origin == -2) { - // Assign LV index 0 for 'this' only for instance methods - uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) + if(uVarToLVIndex.contains(IntTrieSet(-1,-1))){ + uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), { + val lvIndex = nextLVIndex + nextLVIndex += 1 + lvIndex + }) + }else{ + uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) + } } else { // Assign LV indexes for parameters uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), { From 192086dc022d4495d7355ad41140e5f4519474c8 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 4 Aug 2024 16:05:13 +0200 Subject: [PATCH 024/111] separated handling methods for field exprs --- .../org/opalj/tactobc/ExprProcessor.scala | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index 6c031a8c4d..826c5f7dbc 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -19,7 +19,8 @@ object ExprProcessor { expr match { case const: Const => loadConstant(const, instructionsWithPCs, currentPC) case variable: Var[_] => loadVariable(variable, instructionsWithPCs, currentPC) - case fieldExpr: Expr[_] if fieldExpr.isInstanceOf[GetField[_]] || fieldExpr.isInstanceOf[GetStatic] => handleFieldAccess(fieldExpr, instructionsWithPCs, currentPC) + case getField: GetField[_] => handleGetField(getField, instructionsWithPCs, currentPC) + case getStatic: GetStatic => handleGetStatic(getStatic, instructionsWithPCs, currentPC) case binaryExpr: BinaryExpr[_] => handleBinaryExpr(binaryExpr, instructionsWithPCs, currentPC) case virtualFunctionCallExpr: VirtualFunctionCall[_] => handleVirtualFunctionCall(virtualFunctionCallExpr, instructionsWithPCs, currentPC) case staticFunctionCallExpr: StaticFunctionCall[_] => handleStaticFunctionCall(staticFunctionCallExpr, instructionsWithPCs, currentPC) @@ -315,14 +316,17 @@ object ExprProcessor { currentPC + (if (index < 4) 1 else 2) } - private def handleFieldAccess(fieldExpr: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val instruction = fieldExpr match { - case getFieldExpr: GetField[_] => - GETFIELD(getFieldExpr.declaringClass, getFieldExpr.name, getFieldExpr.declaredFieldType) - case getStaticExpr: GetStatic => - GETSTATIC(getStaticExpr.declaringClass, getStaticExpr.name, getStaticExpr.declaredFieldType) - case _ => throw new IllegalArgumentException("Expected a field access expression" + fieldExpr) - } + def handleGetField(getField: GetField[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // Load the object reference onto the stack + val pcAfterObjectRefLoad = processExpression(getField.objRef, instructionsWithPCs, currentPC) + // Generate the GETFIELD instruction + val instruction = GETFIELD(getField.declaringClass, getField.name, getField.declaredFieldType) + instructionsWithPCs += ((pcAfterObjectRefLoad, instruction)) + pcAfterObjectRefLoad + instruction.length // Update and return the new program counter + } + + def handleGetStatic(getStatic: GetStatic, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + val instruction = GETSTATIC(getStatic.declaringClass, getStatic.name, getStatic.declaredFieldType) instructionsWithPCs += ((currentPC, instruction)) currentPC + instruction.length // Update and return the new program counter } From fee0fccc7632517cdc8986c57a5d2bfdd896e4ca Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Mon, 5 Aug 2024 15:23:30 +0200 Subject: [PATCH 025/111] refactored mapping parameters to handle instance and static methods correctly --- .../scala/org/opalj/tactobc/FirstPass.scala | 38 +++++++------------ .../scala/org/opalj/tactobc/TACtoBC.scala | 17 +++++---- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index 35ac823798..e31dc17360 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -1,5 +1,6 @@ package org.opalj.tactobc +import org.opalj.br.Method import org.opalj.collection.immutable.IntTrieSet import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, DUVar, Expr, ExprStmt, If, NewArray, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, StaticMethodCall, Stmt, UVar, VirtualFunctionCall, VirtualMethodCall} import org.opalj.tactobc.ExprProcessor.{nextLVIndex, uVarToLVIndex} @@ -28,8 +29,9 @@ object FirstPass { * * @param tacStmts Array of tuples where each tuple contains a TAC statement and its index. */ - def prepareLVIndexes(tacStmts: Array[(Stmt[DUVar[ValueInformation]], Int)]): Unit = { + def prepareLVIndexes(method: Method, tacStmts: Array[(Stmt[DUVar[ValueInformation]], Int)]): Unit = { // container for all DUVars in the method + val isStaticMethod = method.isStatic val duVars = mutable.ListBuffer[DUVar[_]]() tacStmts.foreach { case (stmt, _) => { stmt match { @@ -71,7 +73,7 @@ object FirstPass { } } // give the first available indexes to parameters - val parameters = mapParametersAndPopulate(duVars) + val parameters = mapParametersAndPopulate(duVars, isStaticMethod) println(parameters) val lvIndexMap = collectAllUVarsAndPopulateUVarToLVIndexMap(duVars) println(lvIndexMap) @@ -97,33 +99,21 @@ object FirstPass { * @param duVars ListBuffer containing all DUVars of the method. * @return A map where keys are def-sites of UVars and values are their corresponding LV indexes. */ - def mapParametersAndPopulate(duVars: mutable.ListBuffer[DUVar[_]]): mutable.Map[IntTrieSet, Int] = { + def mapParametersAndPopulate(duVars: mutable.ListBuffer[DUVar[_]], isStaticMethod: Boolean): mutable.Map[IntTrieSet, Int] = { + nextLVIndex = if (isStaticMethod) 0 else 1 // Start at 1 for instance methods to reserve 0 for 'this' duVars.foreach { case uVar: UVar[_] if uVar.defSites.exists(origin => origin < 0) => // Check if the defSites contain a parameter origin uVar.defSites.foreach { origin => - if (origin == -1) { - // Assign LV index 0 for 'this' only for instance methods + if (origin == -1 && !isStaticMethod) { + // Assign LV index 0 for 'this' for instance methods uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) - } else if (origin < -1) { - if (origin == -2) { - if(uVarToLVIndex.contains(IntTrieSet(-1,-1))){ - uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), { - val lvIndex = nextLVIndex - nextLVIndex += 1 - lvIndex - }) - }else{ - uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) - } - } else { - // Assign LV indexes for parameters - uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), { - val lvIndex = nextLVIndex - nextLVIndex += 1 - lvIndex - }) - } + } else if (origin == -2) { + uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), nextLVIndex) + nextLVIndex += 1 + } else if (origin < -2) { + uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), nextLVIndex) + nextLVIndex += 1 } } case _ => diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala index 605d8abc11..5e1ecaa8ff 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala @@ -12,7 +12,6 @@ import org.opalj.br.instructions.Instruction import org.opalj.br.reader.Java8Framework import org.opalj.da.ClassFileReader.ClassFile import org.opalj.io.writeAndOpen -import org.opalj.util.InMemoryClassLoader import java.io.ByteArrayInputStream import java.nio.file.{Files, Paths} @@ -79,7 +78,9 @@ object TACtoBC { } def generateClassFiles(byteCodes: Map[Method, ArrayBuffer[(Int, Instruction)]], p: Project[_], inputDirPath: String, outputDirPath: String, classFileName: String): Unit = { - val TheType = ObjectType("jnt/scimark2/".concat(classFileName.replace(".class", ""))) + //val helloWorldPath = "org/opalj/tactobc/testingtactobc/" + //val benchmarkPath = "jnt/scimark2/" + //val TheType = ObjectType(benchmarkPath.concat(classFileName.replace(".class", ""))) // Debugging: Print the location of the class loader and resources val loader = this.getClass.getClassLoader @@ -238,10 +239,10 @@ object TACtoBC { // Let's test that the new class does what it is expected to do... (we execute the // instrumented method) //todo: the map should have all class files - val cl = new InMemoryClassLoader(Map((TheType.toJava, newRawCF))) - val newClass = cl.findClass(TheType.toJava) + //val cl = new InMemoryClassLoader(Map((TheType.toJava, newRawCF))) + //val newClass = cl.findClass(TheType.toJava) //val instance = newClass.getDeclaredConstructor().newInstance() - newClass.getMethod("main", (Array[String]()).getClass).invoke(null, null) + //newClass.getMethod("main", (Array[String]()).getClass).invoke(null, null) } /** @@ -312,7 +313,7 @@ object TACtoBC { def translateTACtoBC(tacs: Map[Method, AITACode[TACMethodParameter, ValueInformation]]): Map[Method, ArrayBuffer[(Int, Instruction)]] = { tacs.map { case (method, tacCode) => // Convert the TAC representation back to bytecode for each method - val bytecodeInstructions = translateSingleTACtoBC(tacCode) + val bytecodeInstructions = translateSingleTACtoBC(method, tacCode) method -> bytecodeInstructions } } @@ -327,10 +328,10 @@ object TACtoBC { * @param tac The TAC representation of a method to be converted into bytecode. * @return An array of bytecode instructions representing the method's functionality */ - def translateSingleTACtoBC(tac: AITACode[TACMethodParameter, ValueInformation]): ArrayBuffer[(Int, Instruction)] = { + def translateSingleTACtoBC(method: Method, tac: AITACode[TACMethodParameter, ValueInformation]): ArrayBuffer[(Int, Instruction)] = { val tacStmts = tac.stmts.zipWithIndex //first pass -> prepare the LVIndexes to map the Variable to Indexes - FirstPass.prepareLVIndexes(tacStmts) + FirstPass.prepareLVIndexes(method, tacStmts) //second pass -> generate Bytecode Instructions from TAC Stmts val generatedByteCodeWithPC = ArrayBuffer[(Int, Instruction)]() val tacTargetToByteCodePcs = ArrayBuffer[(Int, Int)]() From fac1bd9344e17684047a7f9a33bc24f11a9f0e7c Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Mon, 5 Aug 2024 16:50:04 +0200 Subject: [PATCH 026/111] extended to hanlde InvokedynamicFunctionCall --- .../org/opalj/tactobc/ExprProcessor.scala | 18 ++++++++++++++++-- .../scala/org/opalj/tactobc/FirstPass.scala | 10 +++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index 826c5f7dbc..0268d81286 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -3,10 +3,10 @@ package org.opalj.tactobc import org.opalj.BinaryArithmeticOperators.{Add, And, Divide, Modulo, Multiply, Or, ShiftLeft, ShiftRight, Subtract, UnsignedShiftRight, XOr} import org.opalj.br.{ArrayType, BooleanType, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FloatType, IntegerType, LongType, ObjectType, ReferenceType, ShortType, Type} -import org.opalj.br.instructions.{AALOAD, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BALOAD, BIPUSH, CALOAD, D2F, D2I, D2L, DADD, DALOAD, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, MULTIANEWARRAY, NEW, NEWARRAY, SALOAD, SIPUSH} +import org.opalj.br.instructions.{AALOAD, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BALOAD, BIPUSH, CALOAD, D2F, D2I, D2L, DADD, DALOAD, DCONST_0, DCONST_1, DDIV, DEFAULT_INVOKEDYNAMIC, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, MULTIANEWARRAY, NEW, NEWARRAY, SALOAD, SIPUSH} import org.opalj.bytecode.BytecodeProcessingFailedException import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{ArrayLength, ArrayLoad, BinaryExpr, ClassConst, Const, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, LongConst, MethodHandleConst, MethodTypeConst, New, NewArray, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} +import org.opalj.tac.{ArrayLength, ArrayLoad, BinaryExpr, ClassConst, Const, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, InvokedynamicFunctionCall, LongConst, MethodHandleConst, MethodTypeConst, New, NewArray, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} import org.opalj.value.IsSReferenceValue import scala.collection.mutable @@ -29,11 +29,25 @@ object ExprProcessor { case arrayLength: ArrayLength[_] => handleArrayLength(arrayLength, instructionsWithPCs, currentPC) case arrayLoadExpr: ArrayLoad[_] => handleArrayLoad(arrayLoadExpr, instructionsWithPCs, currentPC) case newArrayExpr: NewArray[_] => handleNewArray(newArrayExpr, instructionsWithPCs, currentPC) + case invokedynamicFunctionCall: InvokedynamicFunctionCall[_] => handleInvokedynamicFunctionCall(invokedynamicFunctionCall, instructionsWithPCs, currentPC) case _ => throw new UnsupportedOperationException("Unsupported expression type" + expr) } } + def handleInvokedynamicFunctionCall(invokedynamicFunctionCall: InvokedynamicFunctionCall[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // Initialize the PC after processing the receiver + var currentAfterParamsPC = currentPC + + // Process each parameter and update the PC accordingly + for (param <- invokedynamicFunctionCall.params) { + currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + } + val instruction = DEFAULT_INVOKEDYNAMIC(invokedynamicFunctionCall.bootstrapMethod, invokedynamicFunctionCall.name, invokedynamicFunctionCall.descriptor) + instructionsWithPCs += ((currentAfterParamsPC, instruction)) + currentAfterParamsPC + instruction.length + } + def handleNewArray(newArrayExpr: NewArray[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // Initialize the PC after processing the counts var currentAfterCountsPC = currentPC diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index e31dc17360..9a4947923a 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -2,7 +2,7 @@ package org.opalj.tactobc import org.opalj.br.Method import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, DUVar, Expr, ExprStmt, If, NewArray, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, StaticMethodCall, Stmt, UVar, VirtualFunctionCall, VirtualMethodCall} +import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, DUVar, Expr, ExprStmt, If, InvokedynamicFunctionCall, NewArray, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, StaticMethodCall, Stmt, UVar, VirtualFunctionCall, VirtualMethodCall} import org.opalj.tactobc.ExprProcessor.{nextLVIndex, uVarToLVIndex} import org.opalj.value.ValueInformation @@ -161,10 +161,18 @@ object FirstPass { case arrayLengthExpr: ArrayLength[_] => collectDUVarFromArrayLengthExpr(arrayLengthExpr, duVars) case arrayLoadExpr: ArrayLoad[_] => collectDUVarFromArrayLoadExpr(arrayLoadExpr, duVars) case newArrayExpr: NewArray[_] => collectDUVarFromNewArrayExpr(newArrayExpr, duVars) + case invokedynamicFunctionCall: InvokedynamicFunctionCall[_] => collectDUVarFromInvokedynamicFunctionCall(invokedynamicFunctionCall, duVars) case _ => } } + def collectDUVarFromInvokedynamicFunctionCall(invokedynamicFunctionCall: InvokedynamicFunctionCall[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + // Process each parameter and collect from each + for (param <- invokedynamicFunctionCall.params) { + collectDUVarFromExpr(param, duVars) + } + } + def collectDUVarFromNewArrayExpr(newArrayExpr: NewArray[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { for (count <- newArrayExpr.counts) { collectDUVarFromExpr(count, duVars) From ea4ab956b3bb5953253be4db35ddce47e24294b7 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Mon, 5 Aug 2024 16:50:34 +0200 Subject: [PATCH 027/111] getting rid of helper methods to concat strings --- OPAL/tactobc/src/main/resources/reference.conf | 1 + 1 file changed, 1 insertion(+) create mode 100644 OPAL/tactobc/src/main/resources/reference.conf diff --git a/OPAL/tactobc/src/main/resources/reference.conf b/OPAL/tactobc/src/main/resources/reference.conf new file mode 100644 index 0000000000..7483891cc6 --- /dev/null +++ b/OPAL/tactobc/src/main/resources/reference.conf @@ -0,0 +1 @@ +org.opalj.br.reader.ClassFileReader.Invokedynamic.rewrite = false \ No newline at end of file From eb66912fe47a090666e26d99c8de47a32126b011 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Mon, 5 Aug 2024 17:21:26 +0200 Subject: [PATCH 028/111] refactored ArrayStore --- .../org/opalj/tactobc/StmtProcessor.scala | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index 4feb6414f3..7b79e45c53 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -3,10 +3,11 @@ package org.opalj.tactobc import org.opalj.RelationalOperator import org.opalj.RelationalOperators._ -import org.opalj.br.{BootstrapMethod, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, FieldType, MethodDescriptor, ObjectType, PCs, ReferenceType} -import org.opalj.br.instructions.{AASTORE, ARETURN, ATHROW, DASTORE, DRETURN, FASTORE, FRETURN, GOTO, IASTORE, IFNONNULL, IFNULL, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, LASTORE, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, NOP, PUTFIELD, PUTSTATIC, RET, RETURN, TABLESWITCH} +import org.opalj.br.{BootstrapMethod, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FieldType, FloatType, IntegerType, LongType, MethodDescriptor, ObjectType, PCs, ReferenceType, ShortType} +import org.opalj.br.instructions.{AASTORE, ARETURN, ATHROW, BASTORE, CASTORE, DASTORE, DRETURN, FASTORE, FRETURN, GOTO, IASTORE, IFNONNULL, IFNULL, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, LASTORE, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, NOP, PUTFIELD, PUTSTATIC, RET, RETURN, SASTORE, TABLESWITCH} import org.opalj.collection.immutable.{IntIntPair, IntTrieSet} import org.opalj.tac.{Expr, UVar, Var} +import org.opalj.tactobc.ExprProcessor.inferElementType import scala.collection.immutable.ArraySeq import scala.collection.mutable.ArrayBuffer @@ -119,7 +120,7 @@ object StmtProcessor { } def processArrayStore(arrayRef: Expr[_], index: Expr[_], value: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - //todo: handle this correctly + // Load the arrayRef onto the stack val pcAfterArrayRefLoad = ExprProcessor.processExpression(arrayRef, instructionsWithPCs, currentPC) // Load the index onto the stack @@ -128,19 +129,19 @@ object StmtProcessor { // Load the value to be stored onto the stack val pcAfterValueLoad = ExprProcessor.processExpression(value, instructionsWithPCs, pcAfterIndexLoad) - // Determine the type of the value to be stored and select the appropriate store instruction - val instruction = value.cTpe match { - case ComputationalTypeInt => IASTORE - case ComputationalTypeLong => LASTORE - case ComputationalTypeFloat => FASTORE - case ComputationalTypeDouble => DASTORE - //case UVar(_, _: Byte) => BASTORE - //case UVar(_, _: Char) => CASTORE - //case UVar(_, _: Short) => SASTORE - case ComputationalTypeReference => AASTORE + // Infer the element type from the array reference expression + val elementType = inferElementType(arrayRef) + val instruction = elementType match { + case IntegerType => IASTORE + case LongType => LASTORE + case FloatType => FASTORE + case DoubleType => DASTORE + case ByteType => BASTORE + case CharType => CASTORE + case ShortType => SASTORE + case _: ObjectType => AASTORE case _ => throw new IllegalArgumentException("Unsupported array store type") } - // Add the store instruction instructionsWithPCs += ((pcAfterValueLoad, instruction)) pcAfterValueLoad + instruction.length From e88985d8b3acc9b3f40d9aa6dacf3114d28d7959 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Mon, 5 Aug 2024 17:57:50 +0200 Subject: [PATCH 029/111] refactored NewArray for MULTIANEWARRAY --- .../org/opalj/tactobc/ExprProcessor.scala | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index 0268d81286..d106315f20 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -56,7 +56,12 @@ object ExprProcessor { currentAfterCountsPC = ExprProcessor.processExpression(count, instructionsWithPCs, currentAfterCountsPC) } if(newArrayExpr.counts.size > 1) { - val instruction = MULTIANEWARRAY(newArrayExpr.tpe.toString, newArrayExpr.counts.size) + // Construct the array type string for the multi-dimensional array + val arrayTypeString = newArrayExpr.tpe match { + case arrayType: ArrayType => constructArrayTypeString(arrayType) + case _ => throw new IllegalArgumentException("Expected an array type for MULTIANEWARRAY") + } + val instruction = MULTIANEWARRAY(arrayTypeString, newArrayExpr.counts.size) instructionsWithPCs += ((currentAfterCountsPC, instruction)) return currentAfterCountsPC + instruction.length } @@ -76,6 +81,18 @@ object ExprProcessor { currentAfterCountsPC + instruction.length } + def constructArrayTypeString(arrayType: ArrayType): String = { + def loop(tpe: Type, depth: Int): (String, Int) = tpe match { + case ArrayType(componentType) => + loop(componentType, depth + 1) + case baseType => + (baseType.toString, depth) + } + + val (baseTypeString, depth) = loop(arrayType, 0) + "[" * depth + baseTypeString + } + def handleArrayLoad(arrayLoadExpr: ArrayLoad[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // Load the array reference onto the stack val pcAfterArrayRefLoad = processExpression(arrayLoadExpr.arrayRef, instructionsWithPCs, currentPC) From c01e762e08adcd6b531a6c014ad3c7fdfd3db68d Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Mon, 5 Aug 2024 20:28:48 +0200 Subject: [PATCH 030/111] refactored ArrayLoad --- .../src/main/scala/org/opalj/tactobc/ExprProcessor.scala | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index d106315f20..4abc25599f 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -110,12 +110,8 @@ object ExprProcessor { case ByteType => BALOAD case CharType => CALOAD case ShortType => SALOAD - case _ => - if(elementType.isReferenceType){ - AALOAD - }else{ - throw new IllegalArgumentException("Unsupported array load type" + arrayLoadExpr.arrayRef.asVar) - } + case _: ReferenceType => AALOAD + case _ => throw new IllegalArgumentException("Unsupported array load type" + elementType) } instructionsWithPCs += ((pcAfterIndexLoad, instruction)) pcAfterIndexLoad + instruction.length From 822f3eed18edd8cb194344424e5d1b4ef1448b77 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Mon, 5 Aug 2024 20:29:18 +0200 Subject: [PATCH 031/111] refactoring --- OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index 9a4947923a..7d8902e595 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -100,7 +100,6 @@ object FirstPass { * @return A map where keys are def-sites of UVars and values are their corresponding LV indexes. */ def mapParametersAndPopulate(duVars: mutable.ListBuffer[DUVar[_]], isStaticMethod: Boolean): mutable.Map[IntTrieSet, Int] = { - nextLVIndex = if (isStaticMethod) 0 else 1 // Start at 1 for instance methods to reserve 0 for 'this' duVars.foreach { case uVar: UVar[_] if uVar.defSites.exists(origin => origin < 0) => // Check if the defSites contain a parameter origin @@ -109,6 +108,7 @@ object FirstPass { // Assign LV index 0 for 'this' for instance methods uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) } else if (origin == -2) { + nextLVIndex = if (isStaticMethod) 0 else 1 // Start at 1 for instance methods to reserve 0 for 'this' uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), nextLVIndex) nextLVIndex += 1 } else if (origin < -2) { From 2ec9321aae0b909924ffbdb56d9a8cfa69d66c72 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Tue, 6 Aug 2024 20:42:45 +0200 Subject: [PATCH 032/111] fixed NewArray for reference types --- .../src/main/scala/org/opalj/tactobc/ExprProcessor.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index 4abc25599f..a7b67c96ce 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -66,7 +66,7 @@ object ExprProcessor { return currentAfterCountsPC + instruction.length } val instruction = newArrayExpr.tpe.componentType match { - case _: ReferenceType => ANEWARRAY(newArrayExpr.tpe) + case _: ReferenceType => ANEWARRAY(newArrayExpr.tpe.componentType.toJava.replace(".", "/")) case _: BooleanType => NEWARRAY(BooleanType.atype) case _: CharType => NEWARRAY(CharType.atype) case _: FloatType => NEWARRAY(FloatType.atype) From 3dedf8129326cd4da4528e2ed0363dc723744729 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 7 Aug 2024 23:02:40 +0200 Subject: [PATCH 033/111] fixed handling doubles and longs they require 2 slots in the LVIndex map --- .../scala/org/opalj/tactobc/FirstPass.scala | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index 7d8902e595..07fd2cf39a 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -110,10 +110,10 @@ object FirstPass { } else if (origin == -2) { nextLVIndex = if (isStaticMethod) 0 else 1 // Start at 1 for instance methods to reserve 0 for 'this' uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), nextLVIndex) - nextLVIndex += 1 + incrementLVIndex(uVar) } else if (origin < -2) { uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), nextLVIndex) - nextLVIndex += 1 + incrementLVIndex(uVar) } } case _ => @@ -139,12 +139,23 @@ object FirstPass { // No overlapping def-sites found, add a new entry uVarToLVIndex.getOrElseUpdate(uVar.defSites, { val lvIndex = nextLVIndex - nextLVIndex += 1 + incrementLVIndex(uVar) lvIndex }) } } + /** + * Increments the LV index appropriately based on the type of the UVar. + * + * @param uVar The UVar for which the LV index is to be incremented. + */ + def incrementLVIndex(uVar: UVar[_]): Unit = { + // Temporary type checking using toString method + val isDoubleOrLongType = uVar.value.toString.contains("long") || uVar.value.toString.contains("Double") + nextLVIndex += (if (isDoubleOrLongType) 2 else 1) + } + /** * Traverses an expression to collect all DUVars embedded within it. * From 4bc194f2b824bf2efff42e8902783a7711f40eb0 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 7 Aug 2024 23:59:44 +0200 Subject: [PATCH 034/111] handling more stmts --- .../org/opalj/tactobc/ExprProcessor.scala | 39 ++++++++++++++++++- .../scala/org/opalj/tactobc/FirstPass.scala | 15 ++++++- .../org/opalj/tactobc/StmtProcessor.scala | 15 +++++-- 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index a7b67c96ce..c8ab742c17 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -2,11 +2,12 @@ package org.opalj.tactobc import org.opalj.BinaryArithmeticOperators.{Add, And, Divide, Modulo, Multiply, Or, ShiftLeft, ShiftRight, Subtract, UnsignedShiftRight, XOr} +import org.opalj.RelationalOperators.{CMPG, CMPL} import org.opalj.br.{ArrayType, BooleanType, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FloatType, IntegerType, LongType, ObjectType, ReferenceType, ShortType, Type} -import org.opalj.br.instructions.{AALOAD, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BALOAD, BIPUSH, CALOAD, D2F, D2I, D2L, DADD, DALOAD, DCONST_0, DCONST_1, DDIV, DEFAULT_INVOKEDYNAMIC, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, MULTIANEWARRAY, NEW, NEWARRAY, SALOAD, SIPUSH} +import org.opalj.br.instructions.{AALOAD, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BALOAD, BIPUSH, CALOAD, D2F, D2I, D2L, DADD, DALOAD, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DEFAULT_INVOKEDYNAMIC, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCMP, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, MULTIANEWARRAY, NEW, NEWARRAY, SALOAD, SIPUSH} import org.opalj.bytecode.BytecodeProcessingFailedException import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{ArrayLength, ArrayLoad, BinaryExpr, ClassConst, Const, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, InvokedynamicFunctionCall, LongConst, MethodHandleConst, MethodTypeConst, New, NewArray, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} +import org.opalj.tac.{ArrayLength, ArrayLoad, BinaryExpr, ClassConst, Compare, Const, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, InvokedynamicFunctionCall, LongConst, MethodHandleConst, MethodTypeConst, New, NewArray, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} import org.opalj.value.IsSReferenceValue import scala.collection.mutable @@ -30,11 +31,45 @@ object ExprProcessor { case arrayLoadExpr: ArrayLoad[_] => handleArrayLoad(arrayLoadExpr, instructionsWithPCs, currentPC) case newArrayExpr: NewArray[_] => handleNewArray(newArrayExpr, instructionsWithPCs, currentPC) case invokedynamicFunctionCall: InvokedynamicFunctionCall[_] => handleInvokedynamicFunctionCall(invokedynamicFunctionCall, instructionsWithPCs, currentPC) + case compare: Compare[_] => handleCompare(compare, instructionsWithPCs, currentPC) case _ => throw new UnsupportedOperationException("Unsupported expression type" + expr) } } + def handleCompare(compare: Compare[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // Process the left expression and update the PC + val pcAfterLeft = processExpression(compare.left, instructionsWithPCs, currentPC) + + // Process the right expression and update the PC + val pcAfterRight = processExpression(compare.right, instructionsWithPCs, pcAfterLeft) + + // Determine the appropriate comparison instruction + val instruction = compare.left.cTpe match { + case ComputationalTypeFloat => + compare.condition match { + case CMPG => FCMPG + case CMPL => FCMPL + case _ => throw new IllegalArgumentException("Unsupported comparison operator for float type") + } + case ComputationalTypeDouble => + compare.condition match { + case CMPG => DCMPG + case CMPL => DCMPL + case _ => throw new IllegalArgumentException("Unsupported comparison operator for double type") + } + case ComputationalTypeLong => + LCMP + case _ => throw new IllegalArgumentException("Unsupported comparison type") + } + + // Add the comparison instruction to the list + instructionsWithPCs += ((pcAfterRight, instruction)) + + // Update the PC and return it + pcAfterRight + instruction.length + } + def handleInvokedynamicFunctionCall(invokedynamicFunctionCall: InvokedynamicFunctionCall[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // Initialize the PC after processing the receiver var currentAfterParamsPC = currentPC diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index 07fd2cf39a..f4171b8519 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -2,7 +2,7 @@ package org.opalj.tactobc import org.opalj.br.Method import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, DUVar, Expr, ExprStmt, If, InvokedynamicFunctionCall, NewArray, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, StaticMethodCall, Stmt, UVar, VirtualFunctionCall, VirtualMethodCall} +import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, Compare, DUVar, Expr, ExprStmt, GetField, If, InvokedynamicFunctionCall, NewArray, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, StaticMethodCall, Stmt, Throw, UVar, VirtualFunctionCall, VirtualMethodCall} import org.opalj.tactobc.ExprProcessor.{nextLVIndex, uVarToLVIndex} import org.opalj.value.ValueInformation @@ -68,6 +68,8 @@ object FirstPass { collectDUVarFromExpr(value, duVars) case ExprStmt(_, expr) => collectDUVarFromExpr(expr, duVars) + case Throw(_, exception) => + collectDUVarFromExpr(exception, duVars) case _ => } } @@ -173,10 +175,21 @@ object FirstPass { case arrayLoadExpr: ArrayLoad[_] => collectDUVarFromArrayLoadExpr(arrayLoadExpr, duVars) case newArrayExpr: NewArray[_] => collectDUVarFromNewArrayExpr(newArrayExpr, duVars) case invokedynamicFunctionCall: InvokedynamicFunctionCall[_] => collectDUVarFromInvokedynamicFunctionCall(invokedynamicFunctionCall, duVars) + case getField: GetField[_] => collectDUVarFromGetField(getField, duVars) + case compare: Compare[_] => collectDUVarFromCompare(compare, duVars) case _ => } } + def collectDUVarFromCompare(compare: Compare[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectDUVarFromExpr(compare.left, duVars) + collectDUVarFromExpr(compare.right, duVars) + } + + def collectDUVarFromGetField(getField: GetField[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectDUVarFromExpr(getField.objRef, duVars) + } + def collectDUVarFromInvokedynamicFunctionCall(invokedynamicFunctionCall: InvokedynamicFunctionCall[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { // Process each parameter and collect from each for (param <- invokedynamicFunctionCall.params) { diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index 7b79e45c53..d577382865 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -100,6 +100,7 @@ object StmtProcessor { def processVirtualMethodCall(declaringClass: ReferenceType, isInterface: Boolean, methodName: String, methodDescriptor: MethodDescriptor, receiver: Expr[_], params: Seq[Expr[_]], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // Process the receiver object (e.g., aload_0 for `this`) val afterReceiverPC = ExprProcessor.processExpression(receiver, instructionsWithPCs, currentPC) + println(s"Receiver loaded at PC: $afterReceiverPC, Receiver: $receiver") // Initialize the PC after processing the receiver var currentAfterParamsPC = afterReceiverPC @@ -107,6 +108,7 @@ object StmtProcessor { // Process each parameter and update the PC accordingly for (param <- params) { currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + println(s"Parameter loaded at PC: $currentAfterParamsPC, Parameter: $param") } val instruction = { /*if (isInterface) { @@ -114,6 +116,7 @@ object StmtProcessor { }else*/ INVOKEVIRTUAL(declaringClass, methodName, methodDescriptor) } + println(s"Generated method call instruction: $instruction at PC: $currentAfterParamsPC") //val finalPC = currentPC + pcAfterLoadVariable instructionsWithPCs += ((currentAfterParamsPC, instruction)) currentAfterParamsPC + instruction.length @@ -122,15 +125,20 @@ object StmtProcessor { def processArrayStore(arrayRef: Expr[_], index: Expr[_], value: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // Load the arrayRef onto the stack val pcAfterArrayRefLoad = ExprProcessor.processExpression(arrayRef, instructionsWithPCs, currentPC) + println(s"ArrayRef: $arrayRef, Type: ${arrayRef.cTpe}, PC after load: $pcAfterArrayRefLoad") // Load the index onto the stack val pcAfterIndexLoad = ExprProcessor.processExpression(index, instructionsWithPCs, pcAfterArrayRefLoad) + println(s"Index: $index, Type: ${index.cTpe}, PC after load: $pcAfterIndexLoad") // Load the value to be stored onto the stack val pcAfterValueLoad = ExprProcessor.processExpression(value, instructionsWithPCs, pcAfterIndexLoad) + println(s"Value: $value, Type: ${value.cTpe}, PC after load: $pcAfterValueLoad") // Infer the element type from the array reference expression val elementType = inferElementType(arrayRef) + println(s"Inferred Element Type: $elementType") + val instruction = elementType match { case IntegerType => IASTORE case LongType => LASTORE @@ -142,6 +150,7 @@ object StmtProcessor { case _: ObjectType => AASTORE case _ => throw new IllegalArgumentException("Unsupported array store type") } + println(s"Generated Instruction: $instruction at PC $pcAfterValueLoad") // Add the store instruction instructionsWithPCs += ((pcAfterValueLoad, instruction)) pcAfterValueLoad + instruction.length @@ -176,10 +185,10 @@ object StmtProcessor { } def processThrow(exception: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - //todo: handle this correctly + val pcAfterException = ExprProcessor.processExpression(exception, instructionsWithPCs, currentPC) val instruction = ATHROW - instructionsWithPCs += ((currentPC, instruction)) - currentPC + 1 + instructionsWithPCs += ((pcAfterException, instruction)) + pcAfterException + 1 } def processPutStatic(declaringClass: ObjectType, name: String, declaredFieldType: FieldType, value: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { From 136bd3a9d60c2825a646ed7c291309ba8a93fad8 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Thu, 8 Aug 2024 19:03:11 +0200 Subject: [PATCH 035/111] refactored mapping parameters first to process parameters only one time --- .../scala/org/opalj/tactobc/FirstPass.scala | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index f4171b8519..169c4df0ff 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -105,18 +105,23 @@ object FirstPass { duVars.foreach { case uVar: UVar[_] if uVar.defSites.exists(origin => origin < 0) => // Check if the defSites contain a parameter origin - uVar.defSites.foreach { origin => - if (origin == -1 && !isStaticMethod) { - // Assign LV index 0 for 'this' for instance methods - uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) - } else if (origin == -2) { - nextLVIndex = if (isStaticMethod) 0 else 1 // Start at 1 for instance methods to reserve 0 for 'this' - uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), nextLVIndex) - incrementLVIndex(uVar) - } else if (origin < -2) { - uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), nextLVIndex) - incrementLVIndex(uVar) - } + val existingEntry = uVarToLVIndex.find { case (key, _) => key.intersect(uVar.defSites).nonEmpty } + existingEntry match { + case Some((existingDefSites, _)) => // Do nothing if already processed + case None => + uVar.defSites.foreach { origin => + if (origin == -1 && !isStaticMethod) { + // Assign LV index 0 for 'this' for instance methods + uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) + } else if (origin == -2) { + nextLVIndex = if (isStaticMethod) 0 else 1 // Start at 1 for instance methods to reserve 0 for 'this' + uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), nextLVIndex) + incrementLVIndex(uVar) + } else if (origin < -2) { + uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), nextLVIndex) + incrementLVIndex(uVar) + } + } } case _ => } From 0b82515730101e1c7f95921acfc39092ea91689d Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Fri, 9 Aug 2024 11:52:47 +0200 Subject: [PATCH 036/111] refactored handling parameters first analyzing them and ordering them by origin values to give the proper LVIndex --- .../scala/org/opalj/tactobc/FirstPass.scala | 63 ++++++++++++------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index 169c4df0ff..e0636dcf87 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -102,28 +102,49 @@ object FirstPass { * @return A map where keys are def-sites of UVars and values are their corresponding LV indexes. */ def mapParametersAndPopulate(duVars: mutable.ListBuffer[DUVar[_]], isStaticMethod: Boolean): mutable.Map[IntTrieSet, Int] = { - duVars.foreach { - case uVar: UVar[_] if uVar.defSites.exists(origin => origin < 0) => - // Check if the defSites contain a parameter origin - val existingEntry = uVarToLVIndex.find { case (key, _) => key.intersect(uVar.defSites).nonEmpty } - existingEntry match { - case Some((existingDefSites, _)) => // Do nothing if already processed - case None => - uVar.defSites.foreach { origin => - if (origin == -1 && !isStaticMethod) { - // Assign LV index 0 for 'this' for instance methods - uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) - } else if (origin == -2) { - nextLVIndex = if (isStaticMethod) 0 else 1 // Start at 1 for instance methods to reserve 0 for 'this' - uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), nextLVIndex) - incrementLVIndex(uVar) - } else if (origin < -2) { - uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), nextLVIndex) - incrementLVIndex(uVar) - } + // Step 2: Filter and Sort DUVar instances with negative origins + val parameterVars = duVars.collect { + case uVar: UVar[_] if uVar.defSites.exists(_ < 0) => uVar + } + val seenDefSites = mutable.Set[Int]() + val uniqueParameterVars = parameterVars.filter { uVar => + // Extract the minimum defSite from the IntTrieSet + val minDefSite = uVar.defSites.head + + // Check if we've already seen this defSite + if (seenDefSites.contains(minDefSite)) { + false // Skip this UVar, as it's already been added + } else { + seenDefSites += minDefSite // Mark this defSite as seen + true // Keep this UVar + } + } + val sortedParameterVars = uniqueParameterVars.sortBy { uVar => + // Sort by the minimum value in defSites, since we want the most negative number first + uVar.defSites.head + }(Ordering[Int].reverse) + println(sortedParameterVars) + // Iterate over the sorted list of unique parameters + sortedParameterVars.foreach { uVar => + // Check if the defSites contain a parameter origin + val existingEntry = uVarToLVIndex.find { case (key, _) => key.intersect(uVar.defSites).nonEmpty } + existingEntry match { + case Some((existingDefSites, _)) => // Do nothing if already processed + case None => + uVar.defSites.foreach { origin => + if (origin == -1 && !isStaticMethod) { + // Assign LV index 0 for 'this' for instance methods + uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) + } else if (origin == -2) { + nextLVIndex = if (isStaticMethod) 0 else 1 // Start at 1 for instance methods to reserve 0 for 'this' + uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), nextLVIndex) + incrementLVIndex(uVar) + } else if (origin < -2) { + uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), nextLVIndex) + incrementLVIndex(uVar) } - } - case _ => + } + } } uVarToLVIndex } From 1ebca1c4f25c6eda6382cda12097a430818dc0b6 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Fri, 9 Aug 2024 13:51:53 +0200 Subject: [PATCH 037/111] refactored .class file generation process to find the correct method and handle situations such as method overloading --- .../scala/org/opalj/tactobc/TACtoBC.scala | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala index 5e1ecaa8ff..b8c1a64d1d 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala @@ -16,6 +16,7 @@ import org.opalj.io.writeAndOpen import java.io.ByteArrayInputStream import java.nio.file.{Files, Paths} import org.opalj.tac._ +import org.opalj.util.InMemoryClassLoader import org.opalj.value.ValueInformation import java.io.File @@ -79,8 +80,8 @@ object TACtoBC { def generateClassFiles(byteCodes: Map[Method, ArrayBuffer[(Int, Instruction)]], p: Project[_], inputDirPath: String, outputDirPath: String, classFileName: String): Unit = { //val helloWorldPath = "org/opalj/tactobc/testingtactobc/" - //val benchmarkPath = "jnt/scimark2/" - //val TheType = ObjectType(benchmarkPath.concat(classFileName.replace(".class", ""))) + val benchmarkPath = "jnt/scimark2/" + val TheType = ObjectType(benchmarkPath.concat(classFileName.replace(".class", ""))) // Debugging: Print the location of the class loader and resources val loader = this.getClass.getClassLoader @@ -104,8 +105,12 @@ object TACtoBC { case None => m.copy() // methods which are native and abstract ... case Some(originalBody) => - //Using find because of the extra methods that do contain the name of the method but are not part of the original file - byteCodes.find(bc => bc._1.name.contains(m.name)) match { + val methodSignature = m.descriptor.toJava(m.name) + byteCodes.find { + case (method, _) => + method.name == m.name && + method.descriptor.toJava(method.name) == methodSignature + } match { case Some((_, instructions)) => // Prepare new instructions array with null values where necessary val maxPc = instructions.map(_._1).max @@ -154,8 +159,8 @@ object TACtoBC { val newBody = Code( //todo: use the size of the local variables map - 100, - 100, + 10000, + 10000, newInstructionsWithNulls, originalBody.exceptionHandlers, finalAttributes) @@ -195,8 +200,8 @@ object TACtoBC { } val newBody1 = Code( //todo: use the size of the local variables map - 100, - 100, + 10000, + 10000, originalBody.instructions, originalBody.exceptionHandlers, newAttributes1) @@ -239,10 +244,10 @@ object TACtoBC { // Let's test that the new class does what it is expected to do... (we execute the // instrumented method) //todo: the map should have all class files - //val cl = new InMemoryClassLoader(Map((TheType.toJava, newRawCF))) - //val newClass = cl.findClass(TheType.toJava) + val cl = new InMemoryClassLoader(Map((TheType.toJava, newRawCF))) + val newClass = cl.findClass(TheType.toJava) //val instance = newClass.getDeclaredConstructor().newInstance() - //newClass.getMethod("main", (Array[String]()).getClass).invoke(null, null) + newClass.getMethod("main", (Array[String]()).getClass).invoke(null, Array[String]()) } /** From da967a5cf1ee798558a0056bf1b774330c840851 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Fri, 9 Aug 2024 18:49:01 +0200 Subject: [PATCH 038/111] Added testcases with parameterized tests --- .../opalj/tactobc/ClassFileGenerator.scala | 179 +++++++++++++++++ .../org/opalj/tactobc/StmtProcessor.scala | 16 +- .../scala/org/opalj/tactobc/TACtoBC.scala | 190 +----------------- .../tactobc/testingtactobc/HelloWorld.java | 77 +++++-- .../tactobc/testingtactobc/Stopwatch.java | 64 ------ OPAL/tactobc/src/test/java/HelloSofi.java | 8 + .../test/resources/HelloWorldToString.java | 27 --- .../scala/org/opalj/tactobc/TACtoBCTest.scala | 77 +++++++ .../org/opalj/tactobc/TestCaseEnum.scala | 20 ++ 9 files changed, 360 insertions(+), 298 deletions(-) create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/ClassFileGenerator.scala delete mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/Stopwatch.java create mode 100644 OPAL/tactobc/src/test/java/HelloSofi.java delete mode 100644 OPAL/tactobc/src/test/resources/HelloWorldToString.java create mode 100644 OPAL/tactobc/src/test/scala/org/opalj/tactobc/TACtoBCTest.scala create mode 100644 OPAL/tactobc/src/test/scala/org/opalj/tactobc/TestCaseEnum.scala diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ClassFileGenerator.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ClassFileGenerator.scala new file mode 100644 index 0000000000..3a9746622c --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ClassFileGenerator.scala @@ -0,0 +1,179 @@ +/* BSD 2-Clause License - see OPAL/LICENSE for details. */ +package org.opalj.tactobc + +import org.opalj.ba.CodeAttributeBuilder.computeStackMapTable +import org.opalj.ba.toDA +import org.opalj.bc.Assembler +import org.opalj.br.{ArrayType, Code, CompactLineNumberTable, LocalVariable, LocalVariableTable, Method, ObjectType, StackMapTable} +import org.opalj.br.analyses.Project +import org.opalj.br.instructions.Instruction +import org.opalj.br.reader.Java8Framework + +import java.nio.file.{Files, Paths} +import scala.Console.println +import scala.collection.immutable.ArraySeq +import scala.collection.mutable.ArrayBuffer + +object ClassFileGenerator { + + def generateClassFiles(byteCodes: Map[Method, ArrayBuffer[(Int, Instruction)]], p: Project[_], inputDirPath: String, outputDirPath: String, classFileName: String): Unit = { + //val helloWorldPath = "org/opalj/tactobc/testingtactobc/" +// val benchmarkPath = "jnt/scimark2/" +// val TheType = ObjectType(benchmarkPath.concat(classFileName.replace(".class", ""))) + + // Debugging: Print the location of the class loader and resources +// val loader = this.getClass.getClassLoader +// val resources = loader.getResources("").asScala.toList +// println(s"ClassLoader: $loader") +// println(s"Resources: ${resources.mkString(", ")}") + // Dynamically determine the type and resource stream + val inputFilePath = Paths.get(inputDirPath, classFileName).toString + val outputFilePath = Paths.get(outputDirPath, classFileName).toString + + val in = () => { + val stream = Files.newInputStream(Paths.get(inputFilePath)) + if (stream == null) throw new RuntimeException(s"Resource not found: $inputFilePath") + stream + } + val cf = Java8Framework.ClassFile(in).head + val newMethods = { + for (m <- cf.methods) yield { + m.body match { + case None => + m.copy() // methods which are native and abstract ... + case Some(originalBody) => + val methodSignature = m.descriptor.toJava(m.name) + byteCodes.find { + case (method, _) => + method.name == m.name && + method.descriptor.toJava(method.name) == methodSignature + } match { + case Some((_, instructions)) => + // Prepare new instructions array with null values where necessary + val maxPc = instructions.map(_._1).max + val newInstructionsWithNulls = new Array[Instruction](maxPc + 1) + + // Initialize array with nulls + for (i <- newInstructionsWithNulls.indices) { + newInstructionsWithNulls(i) = null + } + + // Fill in actual instructions + for ((pc, instruction) <- instructions) { + newInstructionsWithNulls(pc) = instruction + } + + // Print each instruction with its PC - to see if the NULLS are placed correctly + println(s"Instructions for method ${m.name}:") + newInstructionsWithNulls.zipWithIndex.foreach { + case (instruction, pc) => + if (instruction == null) { + println(s"PC $pc: NULL") + } else { + println(s"PC $pc: ${instruction.toString}") + } + } + + // Print out the translation from TAC to Bytecode with nulls + //println("newInstrWithNulls" + newInstructionsWithNulls.foreach(instruction => println(instruction.toString))) + // Debugging: Print the instructions being passed to the new Code object + println(s"Original Instructions for ${m.name}: ${originalBody.instructions.mkString(", ")}") + println(s"New Instructions for ${m.name}: ${newInstructionsWithNulls.mkString(", ")}") + //ToDo: use CodeAttribute builder + val attributesOfOriginalBody = originalBody.attributes + //Todo: + val newLocalVariableTable = LocalVariableTable(ArraySeq( + LocalVariable(0, maxPc + 1, "args", ArrayType(ObjectType("java/lang/String")), 0) + )) + + // Remove CompactLineNumberTable attribute + val newAttributes = attributesOfOriginalBody.filterNot(_.isInstanceOf[CompactLineNumberTable]) + // Replace the LocalVariableTable attribute in the original attributes + val finalAttributes = newAttributes.map { + case _: LocalVariableTable => newLocalVariableTable + case other => other + } + + val newBody = Code( + //todo: use the size of the local variables map + 10000, + 10000, + newInstructionsWithNulls, + originalBody.exceptionHandlers, + finalAttributes) + + //todo: StackMapTable needs the localVariableTable to be able to be computed + println(s"New body for method ${m.name}: $newBody") + println(attributesOfOriginalBody) + val result = m.copy(body = Some(newBody)) + + result + case None => + println(s"Warning: No bytecode found for method ${m.name}. Keeping original method body.") + m.copy() + } + } + } + } + val cfWithNewInstructions = cf.copy(methods = newMethods) + val newMethodsForReal = { + for (m <- cfWithNewInstructions.methods) yield { + m.body match { + case None => + m.copy() // methods which are native and abstract ... + case Some(originalBody) => + //Using find because of the extra methods that do contain the name of the method but are not part of the original file + byteCodes.find(bc => bc._1.name.contains(m.name)) match { + case Some((_, instructions)) => + //ToDo: use CodeAttribute builder + val attributesOfOriginalBody = originalBody.attributes + + val newStackMapTable = computeStackMapTable(m)(p.classHierarchy) + //live variable + // Replace the LocalVariableTable attribute in the original attributes + val newAttributes1 = attributesOfOriginalBody.map { + case _: StackMapTable => newStackMapTable + case other => other + } + val newBody1 = Code( + //todo: use the size of the local variables map + 10000, + 10000, + originalBody.instructions, + originalBody.exceptionHandlers, + newAttributes1) + + //todo: StackMapTable needs the localVariableTable to be able to be computed + println(s"New body for method ${m.name}: $newBody1") + println(attributesOfOriginalBody) + val result = m.copy(body = Some(newBody1)) + + val it = result.body.get.iterator + val n = it.next() + val n1 = it.next() + print(n.toString + n1.toString) + + result + case None => + println(s"Warning: No bytecode found for method ${m.name}. Keeping original method body.") + m.copy() + } + } + } + } + val cfWithNewInstructionsForReal = cf.copy(methods = newMethodsForReal) + val newRawCF = Assembler(toDA(cfWithNewInstructionsForReal)) + val outputClassFilePath = Paths.get(outputFilePath) + Files.createDirectories(outputClassFilePath.getParent) + val newClassFile = Files.write(outputClassFilePath, newRawCF) + println("Created class file: " + newClassFile.toAbsolutePath) + //println("Class file GeneratedHelloWorldToStringDALEQUEE.class has been generated." + newClass) + // Let's test that the new class does what it is expected to do... (we execute the + // instrumented method) + //todo: the map should have all class files +// val cl = new InMemoryClassLoader(Map((TheType.toJava, newRawCF))) +// val newClass = cl.findClass(TheType.toJava) +// //val instance = newClass.getDeclaredConstructor().newInstance() +// newClass.getMethod("main", (Array[String]()).getClass).invoke(null, Array[String]()) + } +} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index d577382865..7404b3b579 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -3,7 +3,7 @@ package org.opalj.tactobc import org.opalj.RelationalOperator import org.opalj.RelationalOperators._ -import org.opalj.br.{BootstrapMethod, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FieldType, FloatType, IntegerType, LongType, MethodDescriptor, ObjectType, PCs, ReferenceType, ShortType} +import org.opalj.br.{ArrayType, BootstrapMethod, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FieldType, FloatType, IntegerType, LongType, MethodDescriptor, ObjectType, PCs, ReferenceType, ShortType} import org.opalj.br.instructions.{AASTORE, ARETURN, ATHROW, BASTORE, CASTORE, DASTORE, DRETURN, FASTORE, FRETURN, GOTO, IASTORE, IFNONNULL, IFNULL, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, LASTORE, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, NOP, PUTFIELD, PUTSTATIC, RET, RETURN, SASTORE, TABLESWITCH} import org.opalj.collection.immutable.{IntIntPair, IntTrieSet} import org.opalj.tac.{Expr, UVar, Var} @@ -139,6 +139,7 @@ object StmtProcessor { val elementType = inferElementType(arrayRef) println(s"Inferred Element Type: $elementType") + val instruction = elementType match { case IntegerType => IASTORE case LongType => LASTORE @@ -148,7 +149,18 @@ object StmtProcessor { case CharType => CASTORE case ShortType => SASTORE case _: ObjectType => AASTORE - case _ => throw new IllegalArgumentException("Unsupported array store type") + case ArrayType(componentType) => componentType match { + case _: ReferenceType => AASTORE + case _: CharType => CASTORE + case _: FloatType => FASTORE + case _: DoubleType => DASTORE + case _: ByteType => BASTORE + case _: ShortType => SASTORE + case _: IntegerType => IASTORE + case _: LongType => LASTORE + case _ => throw new IllegalArgumentException(s"Unsupported array store type $componentType") + } + case _ => throw new IllegalArgumentException(s"Unsupported array store type $elementType") } println(s"Generated Instruction: $instruction at PC $pcAfterValueLoad") // Add the store instruction diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala index b8c1a64d1d..c6f17a42fa 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala @@ -1,28 +1,18 @@ /* BSD 2-Clause License - see OPAL/LICENSE for details. */ package org.opalj.tactobc -import org.opalj.ba.CodeAttributeBuilder.computeStackMapTable -import org.opalj.ba.toDA -import org.opalj.bc.Assembler -import org.opalj.br.{ArrayType, Code, CompactLineNumberTable, LocalVariable, LocalVariableTable, Method, ObjectType, StackMapTable} + +import org.opalj.br.Method import scala.Console.println import org.opalj.br.analyses.Project import org.opalj.br.instructions.Instruction -import org.opalj.br.reader.Java8Framework -import org.opalj.da.ClassFileReader.ClassFile -import org.opalj.io.writeAndOpen -import java.io.ByteArrayInputStream -import java.nio.file.{Files, Paths} import org.opalj.tac._ -import org.opalj.util.InMemoryClassLoader import org.opalj.value.ValueInformation import java.io.File -import scala.collection.immutable.ArraySeq import scala.collection.mutable.ArrayBuffer -import scala.jdk.CollectionConverters.EnumerationHasAsScala object TACtoBC { @@ -46,7 +36,7 @@ object TACtoBC { } val classFiles = listClassFiles(inputDir) - classFiles.foreach{ + classFiles.foreach { classfile => //todo: figure out how to get the input stream of the file //(1) compile bytecode @@ -69,7 +59,7 @@ object TACtoBC { } //(4) generate .class files from translation val p = Project(classfile) - generateClassFiles(byteCodes, p, inputDirPath, outputDirPath, classfile.getName) + ClassFileGenerator.generateClassFiles(byteCodes, p, inputDirPath, outputDirPath, classfile.getName) // println(classfile.getAbsolutePath))) } } @@ -78,178 +68,6 @@ object TACtoBC { directory.listFiles().toList.filter(_.getName.endsWith(".class")) } - def generateClassFiles(byteCodes: Map[Method, ArrayBuffer[(Int, Instruction)]], p: Project[_], inputDirPath: String, outputDirPath: String, classFileName: String): Unit = { - //val helloWorldPath = "org/opalj/tactobc/testingtactobc/" - val benchmarkPath = "jnt/scimark2/" - val TheType = ObjectType(benchmarkPath.concat(classFileName.replace(".class", ""))) - - // Debugging: Print the location of the class loader and resources - val loader = this.getClass.getClassLoader - val resources = loader.getResources("").asScala.toList - println(s"ClassLoader: $loader") - println(s"Resources: ${resources.mkString(", ")}") - - // Dynamically determine the type and resource stream - val inputFilePath = Paths.get(inputDirPath, classFileName).toString - val outputFilePath = Paths.get(outputDirPath, classFileName).toString - - val in = () => { - val stream = Files.newInputStream(Paths.get(inputFilePath)) - if (stream == null) throw new RuntimeException(s"Resource not found: $inputFilePath") - stream - } - val cf = Java8Framework.ClassFile(in).head - val newMethods = { - for (m <- cf.methods) yield { - m.body match { - case None => - m.copy() // methods which are native and abstract ... - case Some(originalBody) => - val methodSignature = m.descriptor.toJava(m.name) - byteCodes.find { - case (method, _) => - method.name == m.name && - method.descriptor.toJava(method.name) == methodSignature - } match { - case Some((_, instructions)) => - // Prepare new instructions array with null values where necessary - val maxPc = instructions.map(_._1).max - val newInstructionsWithNulls = new Array[Instruction](maxPc + 1) - - // Initialize array with nulls - for (i <- newInstructionsWithNulls.indices) { - newInstructionsWithNulls(i) = null - } - - // Fill in actual instructions - for ((pc, instruction) <- instructions) { - newInstructionsWithNulls(pc) = instruction - } - - // Print each instruction with its PC - to see if the NULLS are placed correctly - println(s"Instructions for method ${m.name}:") - newInstructionsWithNulls.zipWithIndex.foreach { - case (instruction, pc) => - if (instruction == null) { - println(s"PC $pc: NULL") - } else { - println(s"PC $pc: ${instruction.toString}") - } - } - - // Print out the translation from TAC to Bytecode with nulls - //println("newInstrWithNulls" + newInstructionsWithNulls.foreach(instruction => println(instruction.toString))) - // Debugging: Print the instructions being passed to the new Code object - println(s"Original Instructions for ${m.name}: ${originalBody.instructions.mkString(", ")}") - println(s"New Instructions for ${m.name}: ${newInstructionsWithNulls.mkString(", ")}") - //ToDo: use CodeAttribute builder - val attributesOfOriginalBody = originalBody.attributes - //Todo: - val newLocalVariableTable = LocalVariableTable(ArraySeq( - LocalVariable(0, maxPc + 1, "args", ArrayType(ObjectType("java/lang/String")), 0) - )) - - // Remove CompactLineNumberTable attribute - val newAttributes = attributesOfOriginalBody.filterNot(_.isInstanceOf[CompactLineNumberTable]) - // Replace the LocalVariableTable attribute in the original attributes - val finalAttributes = newAttributes.map { - case _: LocalVariableTable => newLocalVariableTable - case other => other - } - - val newBody = Code( - //todo: use the size of the local variables map - 10000, - 10000, - newInstructionsWithNulls, - originalBody.exceptionHandlers, - finalAttributes) - - //todo: StackMapTable needs the localVariableTable to be able to be computed - println(s"New body for method ${m.name}: $newBody") - println(attributesOfOriginalBody) - val result = m.copy(body = Some(newBody)) - - result - case None => - println(s"Warning: No bytecode found for method ${m.name}. Keeping original method body.") - m.copy() - } - } - } - } - val cfWithNewInstructions = cf.copy(methods = newMethods) - val newMethodsForReal = { - for (m <- cfWithNewInstructions.methods) yield { - m.body match { - case None => - m.copy() // methods which are native and abstract ... - case Some(originalBody) => - //Using find because of the extra methods that do contain the name of the method but are not part of the original file - byteCodes.find(bc => bc._1.name.contains(m.name)) match { - case Some((_, instructions)) => - //ToDo: use CodeAttribute builder - val attributesOfOriginalBody = originalBody.attributes - - val newStackMapTable = computeStackMapTable(m)(p.classHierarchy) - //live variable - // Replace the LocalVariableTable attribute in the original attributes - val newAttributes1 = attributesOfOriginalBody.map { - case _: StackMapTable => newStackMapTable - case other => other - } - val newBody1 = Code( - //todo: use the size of the local variables map - 10000, - 10000, - originalBody.instructions, - originalBody.exceptionHandlers, - newAttributes1) - - //todo: StackMapTable needs the localVariableTable to be able to be computed - println(s"New body for method ${m.name}: $newBody1") - println(attributesOfOriginalBody) - val result = m.copy(body = Some(newBody1)) - - val it = result.body.get.iterator - val n = it.next() - val n1 = it.next() - print(n.toString + n1.toString) - - result - case None => - println(s"Warning: No bytecode found for method ${m.name}. Keeping original method body.") - m.copy() - } - } - } - } - val cfWithNewInstructionsForReal = cf.copy(methods = newMethodsForReal) - val newRawCF = Assembler(toDA(cfWithNewInstructionsForReal)) - val outputClassFilePath = Paths.get(outputFilePath) - Files.createDirectories(outputClassFilePath.getParent) - val newClassFile = Files.write(outputClassFilePath, newRawCF) - println("Created class file: " + newClassFile.toAbsolutePath) - - // Let's see the old class file... - val odlCFHTML = ClassFile(in).head.toXHTML(None) - val oldCFHTMLFile = writeAndOpen(odlCFHTML, "original", ".html") - println("original: " + oldCFHTMLFile) - - // Let's see the new class file... - val newCF = ClassFile(() => new ByteArrayInputStream(newRawCF)).head.toXHTML(None) - println("genetated from TAC: " + writeAndOpen(newCF, "translated", ".html")) - - //println("Class file GeneratedHelloWorldToStringDALEQUEE.class has been generated." + newClass) - // Let's test that the new class does what it is expected to do... (we execute the - // instrumented method) - //todo: the map should have all class files - val cl = new InMemoryClassLoader(Map((TheType.toJava, newRawCF))) - val newClass = cl.findClass(TheType.toJava) - //val instance = newClass.getDeclaredConstructor().newInstance() - newClass.getMethod("main", (Array[String]()).getClass).invoke(null, Array[String]()) - } - /** * Compiles the Three-Address Code (TAC) representation for all methods in the given .class file. * diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorld.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorld.java index 08109f9585..8bed309fae 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorld.java +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorld.java @@ -2,25 +2,64 @@ public class HelloWorld { public static void main(String[] args) { - System.out.println("HelloWorld!"); - int i = 0; - System.out.println(i); - int x = 1; - for (; i < 3; i++) { - dumbPrint(i, x); - x++; - } - dumbPrint(i, x); + //todo: separate cases in methods to have testscenarios +// double[][] test1 = new double[1][3]; +// test1[0][0] = 1.1d; +// System.out.println(test1[0][0] * 2); +// String[] strArray = new String[3]; + double d = 1.1d; + System.out.println(d); +// String[] str = new String[2]; +// str[0] = "Hallo"; +// System.out.println(str[0]); +// double[] yay = new double[1]; +// yay[0] = 1.1d; +// HelloWorld hello = new HelloWorld(); +// hello.instanceMethod(yay); +// System.out.println("Successfully succeed: " + yay[0]); +// double d2 = 2 * d; +// System.out.println(d2); +// long l = 1L; +// long l2 = 2 * l; +// System.out.println(l2); +// Object[] objArr = new Object[1]; +// objArr[0] = 1.1d; +// System.out.println("Successfully succeed: " + objArr[0]); +// String[] test = new String[1]; +// test[0] = "Yay!"; +// System.out.println("Successfully succeed: " + test[0]); +// + Object string = new Object(); + System.out.println(string.toString()); + string = String.valueOf(1.1d); + System.out.println("Successfully succeedded, amazing piece of code: " + string); +// strArray[0] = "Hello"; +// System.out.println(strArray[0]); // Should print "Hello" +// System.out.println("HelloWorld!"); +// int i = 0; +// System.out.println(i); +// int x = 1; +// int[] ar = new int[3]; +// for (; i < 3; i++) { +// dumbPrint(i, x); +// x++; +// ar[i] = x; +// System.out.println(ar.length); +// } +// dumbPrint(i, ar[0]); } - public static void dumbPrint(int i, int x) { - System.out.println("this is a method ".concat(String.valueOf(i))); - System.out.println(i); - System.out.println(x); - foo(); - } - - public static void foo() { - System.out.println("StaticMethod call works :)"); - } +// public void instanceMethod(double[] d){ +// System.out.println(d[0]); +// } +// public static void dumbPrint(int i, int x) { +// System.out.println("this is a method "); +// System.out.println(i); +// System.out.println(x); +// foo(); +// } +// +// public static void foo() { +// System.out.println("StaticMethod call works :)"); +// } } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/Stopwatch.java b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/Stopwatch.java deleted file mode 100644 index 4d4de1dcbb..0000000000 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/Stopwatch.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.opalj.tactobc.testingtactobc; - -public class Stopwatch { - - public static void main(String[] args){ - System.out.println("Timer started"); - Stopwatch stopwatch = new Stopwatch(); - stopwatch.start(); - System.out.println("seconds: ".concat(String.valueOf(seconds()))); - } - private boolean running; - private double last_time; - private double total; - - public Stopwatch() { - this.reset(); - } - - public static double seconds() { - return System.currentTimeMillis() * 0.001; - } - - public void reset() { - this.running = false; - this.last_time = 0.0; - this.total = 0.0; - } - - public void start() { - if (!this.running) { - this.running = true; - this.total = 0.0; - this.last_time = seconds(); - } - - } - - public void resume() { - if (!this.running) { - this.last_time = seconds(); - this.running = true; - } - - } - - public double stop() { - if (this.running) { - this.total += seconds() - this.last_time; - this.running = false; - } - - return this.total; - } - - public double read() { - if (this.running) { - this.total += seconds() - this.last_time; - this.last_time = seconds(); - } - - return this.total; - } -} - diff --git a/OPAL/tactobc/src/test/java/HelloSofi.java b/OPAL/tactobc/src/test/java/HelloSofi.java new file mode 100644 index 0000000000..428606bd00 --- /dev/null +++ b/OPAL/tactobc/src/test/java/HelloSofi.java @@ -0,0 +1,8 @@ +public class HelloSofi { + public static void main(String[] args) { + Object string = new Object(); + System.out.println(string.toString()); + string = String.valueOf(1.1d); + System.out.println("Successfully succeedded, amazing piece of code: " + string); + } +} diff --git a/OPAL/tactobc/src/test/resources/HelloWorldToString.java b/OPAL/tactobc/src/test/resources/HelloWorldToString.java deleted file mode 100644 index ea00652a9b..0000000000 --- a/OPAL/tactobc/src/test/resources/HelloWorldToString.java +++ /dev/null @@ -1,27 +0,0 @@ - -public class HelloWorldToString { - - public static void main(String[] args) { - System.out.println("Holi Fiooooo"); - int i = 0; - System.out.println(i); - int x = 1; - for(; i < 6; i++){ - dumbPrint(i,x); - x++; - } - dumbPrint(i,x); - } - - public static void dumbPrint(int i, int x){ - System.out.println("esto es de otro metodo".concat(String.valueOf(i))); - System.out.println(i); - System.out.println(x); - foo(); - } - - public static void foo(){ - System.out.println("y este tambien, osea mi StaticMethodCall funciona :D"); - } -} - diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/TACtoBCTest.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/TACtoBCTest.scala new file mode 100644 index 0000000000..69972fe2b2 --- /dev/null +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/TACtoBCTest.scala @@ -0,0 +1,77 @@ +package org.opalj.tactobc + +import org.opalj.br.analyses.Project +import org.opalj.util.InMemoryClassLoader +import org.scalatest.funspec.AnyFunSpec +import org.scalatest.matchers.should.Matchers + +import java.io.{ByteArrayOutputStream, File, PrintStream} +import java.nio.file.{Files, Paths} + +class TACtoBCTest extends AnyFunSpec with Matchers { + + describe("TACtoBC Class File Generation") { + + TestCaseEnum.values.foreach { testCase => + it(s"should generate a class file for ${testCase.asInstanceOf[TestCaseEnum.TestCase].classFileName} that produces the expected output") { + runTestForCase(testCase.asInstanceOf[TestCaseEnum.TestCase]) + } + } + } + + private def runTestForCase(testCase: TestCaseEnum.TestCase): Unit = { + // Load the original class file + val originalClassFile = new File(Paths.get(testCase.inputDirPath, testCase.classFileName).toString) + + // Create the OPAL project from the original class file + val project = Project(originalClassFile) + + // Compile the TAC from the original class file + val tacs = TACtoBC.compileTAC(originalClassFile) + + val byteCodes = TACtoBC.translateTACtoBC(tacs) + + // Generate the new class file using ClassFileGenerator + ClassFileGenerator.generateClassFiles(byteCodes, project, testCase.inputDirPath, testCase.outputDirPath, testCase.classFileName) + + // Load the original class and the generated class + val originalClass = loadClassFromFile(testCase) + val generatedClass = loadClassFromFile(testCase) + + // Compare the output of the main method or another method in the original and generated classes + val originalOutput = invokeMainMethod(originalClass) + val generatedOutput = invokeMainMethod(generatedClass) + + // Assert that the outputs are the same + originalOutput shouldEqual generatedOutput + } + + private def loadClassFromFile(testCase: TestCaseEnum.TestCase): Class[_] = { + val classFileName = testCase.classFileName.replace(".class", "") + + // If the package name is empty, use just the class file name + val className = if (testCase.packageName.isEmpty) { + classFileName + } else { + s"${testCase.packageName}.$classFileName" + } + + // Read the .class file as a byte array + val classFile = new File(Paths.get(testCase.outputDirPath, testCase.classFileName).toString) + val classLoader = new InMemoryClassLoader(Map(className -> Files.readAllBytes(classFile.toPath))) + + classLoader.findClass(className) + } + + + private def invokeMainMethod(clazz: Class[_]): String = { + // Capture the output of the main method + val outputStream = new ByteArrayOutputStream() + val printStream = new PrintStream(outputStream) + Console.withOut(printStream) { + // Invoke the main method + clazz.getMethod("main", classOf[Array[String]]).invoke(null, Array[String]()) + } + outputStream.toString.trim + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/TestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/TestCaseEnum.scala new file mode 100644 index 0000000000..c12d953934 --- /dev/null +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/TestCaseEnum.scala @@ -0,0 +1,20 @@ +package org.opalj.tactobc + +object TestCaseEnum extends Enumeration { + type TestCaseEnum = TestCase + + val HelloWorld = TestCase( + inputDirPath = "/home/sofia/Thesis/opal/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc", + outputDirPath = "/home/sofia/Thesis/opal/OPAL/tactobc/src/test/org/opalj/tactobc/testingtactobc", + classFileName = "HelloWorld.class", + packageName = "org.opalj.tactobc.testingtactobc" + ) + val HelloSofi = TestCase( + inputDirPath = "/home/sofia/Thesis/opal/OPAL/tactobc/src/test/testingtactobc/original", + outputDirPath = "/home/sofia/Thesis/opal/OPAL/tactobc/src/test/testingtactobc/generated", + classFileName = "HelloSofi.class", + packageName = "" + ) + + case class TestCase(inputDirPath: String, outputDirPath: String, classFileName: String, packageName: String) extends super.Val +} From a9603a65698e4fa83b7aaf294034b4e0daf99892 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Fri, 9 Aug 2024 18:54:24 +0200 Subject: [PATCH 039/111] cleanup --- .../java}/HelloWorld.java | 2 -- .../src/test/org/opalj/tactobc/scimark-2.2.jar | Bin 22619 -> 0 bytes .../scala/org/opalj/tactobc/TestCaseEnum.scala | 6 +++--- 3 files changed, 3 insertions(+), 5 deletions(-) rename OPAL/tactobc/src/{main/scala/org/opalj/tactobc/testingtactobc => test/java}/HelloWorld.java (98%) delete mode 100644 OPAL/tactobc/src/test/org/opalj/tactobc/scimark-2.2.jar diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorld.java b/OPAL/tactobc/src/test/java/HelloWorld.java similarity index 98% rename from OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorld.java rename to OPAL/tactobc/src/test/java/HelloWorld.java index 8bed309fae..a8aad1340a 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc/HelloWorld.java +++ b/OPAL/tactobc/src/test/java/HelloWorld.java @@ -1,5 +1,3 @@ -package org.opalj.tactobc.testingtactobc; - public class HelloWorld { public static void main(String[] args) { //todo: separate cases in methods to have testscenarios diff --git a/OPAL/tactobc/src/test/org/opalj/tactobc/scimark-2.2.jar b/OPAL/tactobc/src/test/org/opalj/tactobc/scimark-2.2.jar deleted file mode 100644 index 56f3dddaff29433fbeab3afaae21b7d7eed4f863..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22619 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

-b|O^PpumqzP|zWC3uIMP<|VV(VwPzpDM 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 diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/TestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/TestCaseEnum.scala index c12d953934..5210415be6 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/TestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/TestCaseEnum.scala @@ -4,10 +4,10 @@ object TestCaseEnum extends Enumeration { type TestCaseEnum = TestCase val HelloWorld = TestCase( - inputDirPath = "/home/sofia/Thesis/opal/OPAL/tactobc/src/main/scala/org/opalj/tactobc/testingtactobc", - outputDirPath = "/home/sofia/Thesis/opal/OPAL/tactobc/src/test/org/opalj/tactobc/testingtactobc", + inputDirPath = "/home/sofia/Thesis/opal/OPAL/tactobc/src/test/testingtactobc/original", + outputDirPath = "/home/sofia/Thesis/opal/OPAL/tactobc/src/test/testingtactobc/generated", classFileName = "HelloWorld.class", - packageName = "org.opalj.tactobc.testingtactobc" + packageName = "" ) val HelloSofi = TestCase( inputDirPath = "/home/sofia/Thesis/opal/OPAL/tactobc/src/test/testingtactobc/original", From e87ed62dcc7b6a8d668ed0f21758742844bb34e3 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 13:51:27 +0200 Subject: [PATCH 040/111] Testing working - plug and play --- .../test/resources/javaFiles/Assignment.java | 80 +++++++++++++++++ .../javaFiles}/HelloSofi.java | 0 .../javaFiles}/HelloWorld.java | 0 .../tactobc/SingleClassFileTACtoBCTest.scala | 88 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 18 ++++ .../scala/org/opalj/tactobc/TACtoBCTest.scala | 77 ---------------- .../org/opalj/tactobc/TestCaseEnum.scala | 20 ----- 7 files changed, 186 insertions(+), 97 deletions(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/Assignment.java rename OPAL/tactobc/src/test/{java => resources/javaFiles}/HelloSofi.java (100%) rename OPAL/tactobc/src/test/{java => resources/javaFiles}/HelloWorld.java (100%) create mode 100644 OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTACtoBCTest.scala create mode 100644 OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala delete mode 100644 OPAL/tactobc/src/test/scala/org/opalj/tactobc/TACtoBCTest.scala delete mode 100644 OPAL/tactobc/src/test/scala/org/opalj/tactobc/TestCaseEnum.scala diff --git a/OPAL/tactobc/src/test/resources/javaFiles/Assignment.java b/OPAL/tactobc/src/test/resources/javaFiles/Assignment.java new file mode 100644 index 0000000000..036e8c853c --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/Assignment.java @@ -0,0 +1,80 @@ +public class Assignment { + + public static void main(String[] args) { + // Test integer assignment + int a = 10; + int b = 20; + int sum = a + b; + + // Test double assignment + double x = 3.14; + double y = 2.71; + double product = x * y; + + // Test string assignment + String firstName = "John"; + String lastName = "Doe"; + String fullName = firstName + " " + lastName; + + // Test boolean assignment + boolean isTrue = true; + boolean isFalse = false; + boolean andResult = isTrue && isFalse; + + // Test char assignment + char letter = 'A'; + char nextLetter = (char) (letter + 1); + + // Test long assignment + long largeNumber = 123456789L; + long result = largeNumber * 2; + + // Test float assignment + float pi = 3.14f; + float halfPi = pi / 2; + + // Test short assignment + short smallNumber = 100; + short smallerNumber = (short) (smallNumber - 10); + + // Test byte assignment + byte byteValue = 10; + byte incrementedByte = (byte) (byteValue + 1); + + // Test array assignment + int[] numbers = {1, 2, 3, 4, 5}; + int firstNumber = numbers[0]; + numbers[0] = firstNumber + 10; + + // Test object assignment + Person person = new Person("Jane", "Doe"); + String personFullName = person.getFullName(); + + // Print the results + System.out.println("Sum of integers: " + sum); // 30 + System.out.println("Product of doubles: " + product); // 8.5094 + System.out.println("Full name: " + fullName); // John Doe + System.out.println("Boolean AND result: " + andResult); // false + System.out.println("Next letter after 'A': " + nextLetter); // B + System.out.println("Result of long operation: " + result); // 246913578 + System.out.println("Half of pi (float): " + halfPi); // 1.57 + System.out.println("Smaller short number: " + smallerNumber); // 90 + System.out.println("Incremented byte value: " + incrementedByte); // 11 + System.out.println("First number in array after update: " + numbers[0]); // 11 + System.out.println("Person's full name: " + personFullName); // Jane Doe + } + + static class Person { + String firstName; + String lastName; + + Person(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + String getFullName() { + return this.firstName + " " + this.lastName; + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/java/HelloSofi.java b/OPAL/tactobc/src/test/resources/javaFiles/HelloSofi.java similarity index 100% rename from OPAL/tactobc/src/test/java/HelloSofi.java rename to OPAL/tactobc/src/test/resources/javaFiles/HelloSofi.java diff --git a/OPAL/tactobc/src/test/java/HelloWorld.java b/OPAL/tactobc/src/test/resources/javaFiles/HelloWorld.java similarity index 100% rename from OPAL/tactobc/src/test/java/HelloWorld.java rename to OPAL/tactobc/src/test/resources/javaFiles/HelloWorld.java diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTACtoBCTest.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTACtoBCTest.scala new file mode 100644 index 0000000000..c69971ee72 --- /dev/null +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTACtoBCTest.scala @@ -0,0 +1,88 @@ +package org.opalj.tactobc + +import org.opalj.br.analyses.Project +import org.opalj.util.InMemoryClassLoader +import org.scalatest.funspec.AnyFunSpec +import org.scalatest.matchers.should.Matchers +import org.scalatest.prop.TableDrivenPropertyChecks._ + +import java.io.{ByteArrayOutputStream, File, PrintStream} +import java.nio.file.{Files, Paths} +import scala.Console.println +import scala.sys.process._ + +class SingleClassFileTACtoBCTest extends AnyFunSpec with Matchers { + + describe("TACtoBC Single Class File Generation") { + + val testCases = Table( + ("Java File Name", "Class File Name"), + SingleClassFileTestCaseEnum.testCases.map(tc => (tc.javaFileName, tc.classFileName)): _* + ) + + forAll(testCases) { (javaFileName, classFileName) => + it(s"should compile and generate class file for $javaFileName, create the TAC representation of it, convert it back to bytecode, generate a new .class file and compare the output of both original and generated .class files") { + + // Compile the Java file + compileJavaFile(javaFileName) + + // Load the original class file + val originalClassFile = new File(Paths.get(SingleClassFileTestCaseEnum.inputDirPath, classFileName).toString) + + // Create the OPAL project from the original class file + val project = Project(originalClassFile) + + // Compile the TAC from the original class file + val tacs = TACtoBC.compileTAC(originalClassFile) + // Print out TAC + tacs.foreach { case (method, tac) => + tac.detach() + println(s"Method: ${method.toJava}") + println(tac.toString) + println("\n") + } + val byteCodes = TACtoBC.translateTACtoBC(tacs) + + // Generate the new class file using ClassFileGenerator + ClassFileGenerator.generateClassFiles(byteCodes, project, SingleClassFileTestCaseEnum.inputDirPath, SingleClassFileTestCaseEnum.outputDirPath, classFileName) + + // Load the original class and the generated class + val originalClass = loadClassFromFile(SingleClassFileTestCaseEnum.inputDirPath, classFileName) + val generatedClass = loadClassFromFile(SingleClassFileTestCaseEnum.outputDirPath, classFileName) + + // Compare the output of the main method in the original and generated classes + val originalOutput = invokeMainMethod(originalClass) + val generatedOutput = invokeMainMethod(generatedClass) + + // Assert that the outputs are the same + originalOutput shouldEqual generatedOutput + } + } + } + + private def compileJavaFile(javaFileName: String): Unit = { + val javaFilePath = Paths.get(SingleClassFileTestCaseEnum.javaFileDirPath, javaFileName).toString + val command = s"javac -d ${SingleClassFileTestCaseEnum.inputDirPath} $javaFilePath" + val result = command.! + + if (result != 0) { + throw new RuntimeException(s"Compilation of $javaFileName failed.") + } + } + + private def loadClassFromFile(dirPath: String, classFileName: String): Class[_] = { + val className = classFileName.replace(".class", "") + val classFile = new File(Paths.get(dirPath, classFileName).toString) + val classLoader = new InMemoryClassLoader(Map(className -> Files.readAllBytes(classFile.toPath))) + classLoader.findClass(className) + } + + private def invokeMainMethod(clazz: Class[_]): String = { + val outputStream = new ByteArrayOutputStream() + val printStream = new PrintStream(outputStream) + Console.withOut(printStream) { + clazz.getMethod("main", classOf[Array[String]]).invoke(null, Array[String]()) + } + outputStream.toString.trim + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala new file mode 100644 index 0000000000..9c2e9cb0a3 --- /dev/null +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -0,0 +1,18 @@ +package org.opalj.tactobc + +object SingleClassFileTestCaseEnum extends Enumeration { + // Fixed directories for input and output + val projectRoot: String = System.getProperty("user.dir") + val javaFileDirPath: String = s"$projectRoot/OPAL/tactobc/src/test/resources/javaFiles" + val inputDirPath: String = s"$projectRoot/OPAL/tactobc/src/test/classfilestocompare/original" + val outputDirPath: String = s"$projectRoot/OPAL/tactobc/src/test/classfilestocompare/generated" + + // Test cases with Java and Class file names + val testCases: Seq[TestCase] = Seq( + TestCase("HelloWorld.java", "HelloWorld.class"), + TestCase("HelloSofi.java", "HelloSofi.class"), + ) + + // Case class to represent each test case + case class TestCase(javaFileName: String, classFileName: String) +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/TACtoBCTest.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/TACtoBCTest.scala deleted file mode 100644 index 69972fe2b2..0000000000 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/TACtoBCTest.scala +++ /dev/null @@ -1,77 +0,0 @@ -package org.opalj.tactobc - -import org.opalj.br.analyses.Project -import org.opalj.util.InMemoryClassLoader -import org.scalatest.funspec.AnyFunSpec -import org.scalatest.matchers.should.Matchers - -import java.io.{ByteArrayOutputStream, File, PrintStream} -import java.nio.file.{Files, Paths} - -class TACtoBCTest extends AnyFunSpec with Matchers { - - describe("TACtoBC Class File Generation") { - - TestCaseEnum.values.foreach { testCase => - it(s"should generate a class file for ${testCase.asInstanceOf[TestCaseEnum.TestCase].classFileName} that produces the expected output") { - runTestForCase(testCase.asInstanceOf[TestCaseEnum.TestCase]) - } - } - } - - private def runTestForCase(testCase: TestCaseEnum.TestCase): Unit = { - // Load the original class file - val originalClassFile = new File(Paths.get(testCase.inputDirPath, testCase.classFileName).toString) - - // Create the OPAL project from the original class file - val project = Project(originalClassFile) - - // Compile the TAC from the original class file - val tacs = TACtoBC.compileTAC(originalClassFile) - - val byteCodes = TACtoBC.translateTACtoBC(tacs) - - // Generate the new class file using ClassFileGenerator - ClassFileGenerator.generateClassFiles(byteCodes, project, testCase.inputDirPath, testCase.outputDirPath, testCase.classFileName) - - // Load the original class and the generated class - val originalClass = loadClassFromFile(testCase) - val generatedClass = loadClassFromFile(testCase) - - // Compare the output of the main method or another method in the original and generated classes - val originalOutput = invokeMainMethod(originalClass) - val generatedOutput = invokeMainMethod(generatedClass) - - // Assert that the outputs are the same - originalOutput shouldEqual generatedOutput - } - - private def loadClassFromFile(testCase: TestCaseEnum.TestCase): Class[_] = { - val classFileName = testCase.classFileName.replace(".class", "") - - // If the package name is empty, use just the class file name - val className = if (testCase.packageName.isEmpty) { - classFileName - } else { - s"${testCase.packageName}.$classFileName" - } - - // Read the .class file as a byte array - val classFile = new File(Paths.get(testCase.outputDirPath, testCase.classFileName).toString) - val classLoader = new InMemoryClassLoader(Map(className -> Files.readAllBytes(classFile.toPath))) - - classLoader.findClass(className) - } - - - private def invokeMainMethod(clazz: Class[_]): String = { - // Capture the output of the main method - val outputStream = new ByteArrayOutputStream() - val printStream = new PrintStream(outputStream) - Console.withOut(printStream) { - // Invoke the main method - clazz.getMethod("main", classOf[Array[String]]).invoke(null, Array[String]()) - } - outputStream.toString.trim - } -} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/TestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/TestCaseEnum.scala deleted file mode 100644 index 5210415be6..0000000000 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/TestCaseEnum.scala +++ /dev/null @@ -1,20 +0,0 @@ -package org.opalj.tactobc - -object TestCaseEnum extends Enumeration { - type TestCaseEnum = TestCase - - val HelloWorld = TestCase( - inputDirPath = "/home/sofia/Thesis/opal/OPAL/tactobc/src/test/testingtactobc/original", - outputDirPath = "/home/sofia/Thesis/opal/OPAL/tactobc/src/test/testingtactobc/generated", - classFileName = "HelloWorld.class", - packageName = "" - ) - val HelloSofi = TestCase( - inputDirPath = "/home/sofia/Thesis/opal/OPAL/tactobc/src/test/testingtactobc/original", - outputDirPath = "/home/sofia/Thesis/opal/OPAL/tactobc/src/test/testingtactobc/generated", - classFileName = "HelloSofi.class", - packageName = "" - ) - - case class TestCase(inputDirPath: String, outputDirPath: String, classFileName: String, packageName: String) extends super.Val -} From c6c5bf01de089120caccdd6e9b0559646f5ed039 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 14:00:33 +0200 Subject: [PATCH 041/111] Added assignment tests --- .../test/resources/javaFiles/Assignment.java | 18 ------------------ .../tactobc/SingleClassFileTestCaseEnum.scala | 1 + 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/OPAL/tactobc/src/test/resources/javaFiles/Assignment.java b/OPAL/tactobc/src/test/resources/javaFiles/Assignment.java index 036e8c853c..2e90311ed6 100644 --- a/OPAL/tactobc/src/test/resources/javaFiles/Assignment.java +++ b/OPAL/tactobc/src/test/resources/javaFiles/Assignment.java @@ -46,9 +46,6 @@ public static void main(String[] args) { int firstNumber = numbers[0]; numbers[0] = firstNumber + 10; - // Test object assignment - Person person = new Person("Jane", "Doe"); - String personFullName = person.getFullName(); // Print the results System.out.println("Sum of integers: " + sum); // 30 @@ -61,20 +58,5 @@ public static void main(String[] args) { System.out.println("Smaller short number: " + smallerNumber); // 90 System.out.println("Incremented byte value: " + incrementedByte); // 11 System.out.println("First number in array after update: " + numbers[0]); // 11 - System.out.println("Person's full name: " + personFullName); // Jane Doe - } - - static class Person { - String firstName; - String lastName; - - Person(String firstName, String lastName) { - this.firstName = firstName; - this.lastName = lastName; - } - - String getFullName() { - return this.firstName + " " + this.lastName; - } } } \ No newline at end of file diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 9c2e9cb0a3..539f0988d3 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -11,6 +11,7 @@ object SingleClassFileTestCaseEnum extends Enumeration { val testCases: Seq[TestCase] = Seq( TestCase("HelloWorld.java", "HelloWorld.class"), TestCase("HelloSofi.java", "HelloSofi.class"), + TestCase("Assignment.java", "Assignment.class") ) // Case class to represent each test case From e2f6c41f8fd4bbce426cdabad3e22f284629fcd1 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 14:24:50 +0200 Subject: [PATCH 042/111] Fixed handlePrimitiveTypeCastExpr --- .../main/scala/org/opalj/tactobc/ExprProcessor.scala | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index c8ab742c17..afc687e01f 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -444,7 +444,9 @@ object ExprProcessor { offsetPC + instructionLength } def handlePrimitiveTypeCastExpr(primitiveTypecastExpr: PrimitiveTypecastExpr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - //todo: handle loading of operand Expr + // First, process the operand expression and add its instructions to the buffer + val operandPC = processExpression(primitiveTypecastExpr.operand, instructionsWithPCs, currentPC) + val instruction = (primitiveTypecastExpr.operand.cTpe, primitiveTypecastExpr.targetTpe) match { // -> to Float case (ComputationalTypeDouble, FloatType) => D2F @@ -471,10 +473,7 @@ object ExprProcessor { // -> other cases are not supported case _ => throw new UnsupportedOperationException("Unsupported operation or computational type in PrimitiveTypecastExpr" + primitiveTypecastExpr) } - instructionsWithPCs += ((currentPC, instruction)) - currentPC + instruction.length - // process the left expr and save the pc to give in the right expr processing - val finalPC = processExpression(primitiveTypecastExpr.operand, instructionsWithPCs, currentPC) - finalPC + instructionsWithPCs += ((operandPC, instruction)) + operandPC + instruction.length } } From 06434c6b47ea14869c3d4244b72de1b1aa53e7d1 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 14:25:56 +0200 Subject: [PATCH 043/111] added testcase for ArithmeticOperations --- .../javaFiles/ArithmeticOperations.java | 64 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 +- 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/ArithmeticOperations.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/ArithmeticOperations.java b/OPAL/tactobc/src/test/resources/javaFiles/ArithmeticOperations.java new file mode 100644 index 0000000000..af197fe25f --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/ArithmeticOperations.java @@ -0,0 +1,64 @@ +public class ArithmeticOperations { + + public static void main(String[] args) { +// // Integer Arithmetic Operations + int a = 10; + int b = 5; +// int additionResult = a + b; +// int subtractionResult = a - b; +// int multiplicationResult = a * b; +// int divisionResult = a / b; +// int modulusResult = a % b; +// +// System.out.println("Integer Addition: " + additionResult); +// System.out.println("Integer Subtraction: " + subtractionResult); +// System.out.println("Integer Multiplication: " + multiplicationResult); +// System.out.println("Integer Division: " + divisionResult); +// System.out.println("Integer Modulus: " + modulusResult); + +// // Floating-Point Arithmetic Operations + double x = 5.5; + double y = 2.5; +// double additionDoubleResult = x + y; +// double subtractionDoubleResult = x - y; +// double multiplicationDoubleResult = x * y; +// double divisionDoubleResult = x / y; +// +// System.out.println("Double Addition: " + additionDoubleResult); +// System.out.println("Double Subtraction: " + subtractionDoubleResult); +// System.out.println("Double Multiplication: " + multiplicationDoubleResult); +// System.out.println("Double Division: " + divisionDoubleResult); + + // Mixed Operations (int and double) + double mixedAdditionResult = a + x; + double mixedMultiplicationResult = b * y; + + System.out.println("Mixed Addition (int + double): " + mixedAdditionResult); + System.out.println("Mixed Multiplication (int * double): " + mixedMultiplicationResult); +// +// // Long Arithmetic Operations +// long p = 100000L; +// long q = 50000L; +// long longAdditionResult = p + q; +// long longSubtractionResult = p - q; +// long longMultiplicationResult = p * q; +// long longDivisionResult = p / q; +// +// System.out.println("Long Addition: " + longAdditionResult); +// System.out.println("Long Subtraction: " + longSubtractionResult); +// System.out.println("Long Multiplication: " + longMultiplicationResult); +// System.out.println("Long Division: " + longDivisionResult); +// +// // Short and Byte Operations +// short s1 = 10; +// short s2 = 20; +// byte b1 = 2; +// byte b2 = 3; +// +// int shortAdditionResult = s1 + s2; +// int byteAdditionResult = b1 + b2; +// +// System.out.println("Short Addition: " + shortAdditionResult); +// System.out.println("Byte Addition: " + byteAdditionResult); + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 539f0988d3..9b71edf765 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -11,7 +11,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { val testCases: Seq[TestCase] = Seq( TestCase("HelloWorld.java", "HelloWorld.class"), TestCase("HelloSofi.java", "HelloSofi.class"), - TestCase("Assignment.java", "Assignment.class") + TestCase("Assignment.java", "Assignment.class"), + TestCase("ArithmeticOperations.java", "ArithmeticOperations.class") ) // Case class to represent each test case From 464dba911f3dc10c62a4e10e3af1187d8d95b4ad Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 14:25:56 +0200 Subject: [PATCH 044/111] added testcase for ArithmeticOperations --- .../javaFiles/ArithmeticOperations.java | 64 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 +- 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/ArithmeticOperations.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/ArithmeticOperations.java b/OPAL/tactobc/src/test/resources/javaFiles/ArithmeticOperations.java new file mode 100644 index 0000000000..10fb0d12fd --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/ArithmeticOperations.java @@ -0,0 +1,64 @@ +public class ArithmeticOperations { + + public static void main(String[] args) { + // Integer Arithmetic Operations + int a = 10; + int b = 5; + int additionResult = a + b; + int subtractionResult = a - b; + int multiplicationResult = a * b; + int divisionResult = a / b; + int modulusResult = a % b; + + System.out.println("Integer Addition: " + additionResult); + System.out.println("Integer Subtraction: " + subtractionResult); + System.out.println("Integer Multiplication: " + multiplicationResult); + System.out.println("Integer Division: " + divisionResult); + System.out.println("Integer Modulus: " + modulusResult); + + // Floating-Point Arithmetic Operations + double x = 5.5; + double y = 2.5; + double additionDoubleResult = x + y; + double subtractionDoubleResult = x - y; + double multiplicationDoubleResult = x * y; + double divisionDoubleResult = x / y; + + System.out.println("Double Addition: " + additionDoubleResult); + System.out.println("Double Subtraction: " + subtractionDoubleResult); + System.out.println("Double Multiplication: " + multiplicationDoubleResult); + System.out.println("Double Division: " + divisionDoubleResult); + + // Mixed Operations (int and double) + double mixedAdditionResult = a + x; + double mixedMultiplicationResult = b * y; + + System.out.println("Mixed Addition (int + double): " + mixedAdditionResult); + System.out.println("Mixed Multiplication (int * double): " + mixedMultiplicationResult); + + // Long Arithmetic Operations + long p = 100000L; + long q = 50000L; + long longAdditionResult = p + q; + long longSubtractionResult = p - q; + long longMultiplicationResult = p * q; + long longDivisionResult = p / q; + + System.out.println("Long Addition: " + longAdditionResult); + System.out.println("Long Subtraction: " + longSubtractionResult); + System.out.println("Long Multiplication: " + longMultiplicationResult); + System.out.println("Long Division: " + longDivisionResult); + + // Short and Byte Operations + short s1 = 10; + short s2 = 20; + byte b1 = 2; + byte b2 = 3; + + int shortAdditionResult = s1 + s2; + int byteAdditionResult = b1 + b2; + + System.out.println("Short Addition: " + shortAdditionResult); + System.out.println("Byte Addition: " + byteAdditionResult); + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 539f0988d3..9b71edf765 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -11,7 +11,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { val testCases: Seq[TestCase] = Seq( TestCase("HelloWorld.java", "HelloWorld.class"), TestCase("HelloSofi.java", "HelloSofi.class"), - TestCase("Assignment.java", "Assignment.class") + TestCase("Assignment.java", "Assignment.class"), + TestCase("ArithmeticOperations.java", "ArithmeticOperations.class") ) // Case class to represent each test case From 87b9622d81f3cdb2130b71e2c480be54b2cf99e6 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 15:00:49 +0200 Subject: [PATCH 045/111] added testcase for PrimitiveTypeCast --- .../javaFiles/PrimitiveTypeCast.java | 46 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 +- 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/PrimitiveTypeCast.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/PrimitiveTypeCast.java b/OPAL/tactobc/src/test/resources/javaFiles/PrimitiveTypeCast.java new file mode 100644 index 0000000000..4fc6b6cd2e --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/PrimitiveTypeCast.java @@ -0,0 +1,46 @@ +public class PrimitiveTypeCast { + + public static void main(String[] args) { + // Initial values + int intValue = 100; + double doubleValue = 123.456; + long longValue = 9876543210L; + float floatValue = 3.14f; + + //Cast to different types + + // int to byte, short, char + byte byteValue = (byte) intValue; + short shortValue = (short) intValue; + char charValue = (char) intValue; + + // long to int, float, double + int intFromLong = (int) longValue; + float floatFromLong = (float) longValue; + double doubleFromLong = (double) longValue; + + // double to int, long, float + int intFromDouble = (int) doubleValue; +// long longFromDouble = (long) doubleValue; + float floatFromDouble = (float) doubleValue; + + // float to int, long, double + int intFromFloat = (int) floatValue; +// long longFromFloat = (long) floatValue; + double doubleFromFloat = (double) floatValue; + + // Output the results + System.out.println("int to byte: " + byteValue); + System.out.println("int to short: " + shortValue); + System.out.println("int to char: " + (int) charValue); // Print char as int to show ASCII value + System.out.println("long to int: " + intFromLong); + System.out.println("long to float: " + floatFromLong); + System.out.println("long to double: " + doubleFromLong); + System.out.println("double to int: " + intFromDouble); +// System.out.println("double to long: " + longFromDouble); + System.out.println("double to float: " + floatFromDouble); + System.out.println("float to int: " + intFromFloat); +// System.out.println("float to long: " + longFromFloat); + System.out.println("float to double: " + doubleFromFloat); + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 9b71edf765..1b222690e7 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -12,7 +12,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("HelloWorld.java", "HelloWorld.class"), TestCase("HelloSofi.java", "HelloSofi.class"), TestCase("Assignment.java", "Assignment.class"), - TestCase("ArithmeticOperations.java", "ArithmeticOperations.class") + TestCase("ArithmeticOperations.java", "ArithmeticOperations.class"), + TestCase("PrimitiveTypeCast.java", "PrimitiveTypeCast.class") ) // Case class to represent each test case From 5dd0d4cf47c02abdb818d532c07472addaaa3a07 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 15:07:21 +0200 Subject: [PATCH 046/111] added "Long" as condition for checking how much slots the variable needs --- OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index e0636dcf87..c16b624e61 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -180,7 +180,7 @@ object FirstPass { */ def incrementLVIndex(uVar: UVar[_]): Unit = { // Temporary type checking using toString method - val isDoubleOrLongType = uVar.value.toString.contains("long") || uVar.value.toString.contains("Double") + val isDoubleOrLongType = uVar.value.toString.contains("long") || uVar.value.toString.contains("Long")|| uVar.value.toString.contains("Double") nextLVIndex += (if (isDoubleOrLongType) 2 else 1) } From 0afd80bccc35e0d81a6be8236d4a472e102bca26 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 15:07:45 +0200 Subject: [PATCH 047/111] completed testsuite for PrimitiveTypeCast --- .../src/test/resources/javaFiles/PrimitiveTypeCast.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OPAL/tactobc/src/test/resources/javaFiles/PrimitiveTypeCast.java b/OPAL/tactobc/src/test/resources/javaFiles/PrimitiveTypeCast.java index 4fc6b6cd2e..4df4a750c6 100644 --- a/OPAL/tactobc/src/test/resources/javaFiles/PrimitiveTypeCast.java +++ b/OPAL/tactobc/src/test/resources/javaFiles/PrimitiveTypeCast.java @@ -21,12 +21,12 @@ public static void main(String[] args) { // double to int, long, float int intFromDouble = (int) doubleValue; -// long longFromDouble = (long) doubleValue; + long longFromDouble = (long) doubleValue; float floatFromDouble = (float) doubleValue; // float to int, long, double int intFromFloat = (int) floatValue; -// long longFromFloat = (long) floatValue; + long longFromFloat = (long) floatValue; double doubleFromFloat = (double) floatValue; // Output the results @@ -37,10 +37,10 @@ public static void main(String[] args) { System.out.println("long to float: " + floatFromLong); System.out.println("long to double: " + doubleFromLong); System.out.println("double to int: " + intFromDouble); -// System.out.println("double to long: " + longFromDouble); + System.out.println("double to long: " + longFromDouble); System.out.println("double to float: " + floatFromDouble); System.out.println("float to int: " + intFromFloat); -// System.out.println("float to long: " + longFromFloat); + System.out.println("float to long: " + longFromFloat); System.out.println("float to double: " + doubleFromFloat); } } From 5ba359f5e3f59b0152e65eea34b21e820c6a8561 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 15:17:06 +0200 Subject: [PATCH 048/111] added testcase for ForLoop --- .../src/test/resources/javaFiles/ForLoop.java | 35 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 +- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/ForLoop.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/ForLoop.java b/OPAL/tactobc/src/test/resources/javaFiles/ForLoop.java new file mode 100644 index 0000000000..39534631a8 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/ForLoop.java @@ -0,0 +1,35 @@ +public class ForLoop { + + public static void main(String[] args) { + // Simple for loop with int + int sum = 0; + for (int i = 0; i < 10; i++) { + sum += i; + } + System.out.println("Sum of first 10 numbers: " + sum); + + // For loop with an array of integers + int[] numbers = {1, 2, 3, 4, 5}; + int arraySum = 0; + for (int i = 0; i < numbers.length; i++) { + arraySum += numbers[i]; + } + System.out.println("Sum of array elements: " + arraySum); + + // For loop with a double type + double product = 1.0; + for (int i = 1; i <= 5; i++) { + product *= i * 1.5; + } + System.out.println("Product of first 5 numbers multiplied by 1.5: " + product); + + // Nested for loops + int multiplicationTableSum = 0; + for (int i = 1; i <= 3; i++) { + for (int j = 1; j <= 3; j++) { + multiplicationTableSum += i * j; + } + } + System.out.println("Sum of 3x3 multiplication table: " + multiplicationTableSum); + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 1b222690e7..8467ee1b78 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -13,7 +13,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("HelloSofi.java", "HelloSofi.class"), TestCase("Assignment.java", "Assignment.class"), TestCase("ArithmeticOperations.java", "ArithmeticOperations.class"), - TestCase("PrimitiveTypeCast.java", "PrimitiveTypeCast.class") + TestCase("PrimitiveTypeCast.java", "PrimitiveTypeCast.class"), + TestCase("ForLoop.java", "ForLoop.class") ) // Case class to represent each test case From 18a799816dec57f0945c4e6a067744b7308e3675 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 15:45:37 +0200 Subject: [PATCH 049/111] added logic to collect DUVars from Switch Stmt --- OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index c16b624e61..4d44a79505 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -2,7 +2,7 @@ package org.opalj.tactobc import org.opalj.br.Method import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, Compare, DUVar, Expr, ExprStmt, GetField, If, InvokedynamicFunctionCall, NewArray, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, StaticMethodCall, Stmt, Throw, UVar, VirtualFunctionCall, VirtualMethodCall} +import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, Compare, DUVar, Expr, ExprStmt, GetField, If, InvokedynamicFunctionCall, NewArray, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, StaticMethodCall, Stmt, Switch, Throw, UVar, VirtualFunctionCall, VirtualMethodCall} import org.opalj.tactobc.ExprProcessor.{nextLVIndex, uVarToLVIndex} import org.opalj.value.ValueInformation @@ -70,6 +70,8 @@ object FirstPass { collectDUVarFromExpr(expr, duVars) case Throw(_, exception) => collectDUVarFromExpr(exception, duVars) + case Switch(_, _, index, _) => + collectDUVarFromExpr(index, duVars) case _ => } } From 06b0d7cd4a2d63ebaf1bc4291a1151b661a513cc Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 16:13:35 +0200 Subject: [PATCH 050/111] added testcase for MethodCalls --- .../test/resources/javaFiles/MethodCall.java | 62 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 +- 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/MethodCall.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/MethodCall.java b/OPAL/tactobc/src/test/resources/javaFiles/MethodCall.java new file mode 100644 index 0000000000..0f040d0301 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/MethodCall.java @@ -0,0 +1,62 @@ +public class MethodCall { + + public static void main(String[] args) { + // Instance method call + MethodCall instance = new MethodCall(); + int instanceResult = instance.instanceMethod(5, 3); + System.out.println("Instance method result: " + instanceResult); + + // Static method call + int staticResult = staticMethod(10, 2); + System.out.println("Static method result: " + staticResult); + + // Overloaded method call + String overloadedResult1 = instance.overloadedMethod(5); + String overloadedResult2 = instance.overloadedMethod(5, 3); + System.out.println("Overloaded method result (1 parameter): " + overloadedResult1); + System.out.println("Overloaded method result (2 parameters): " + overloadedResult2); + + // Calling a method that calls another method + int nestedCallResult = instance.nestedMethodCall(7, 3); + System.out.println("Nested method call result: " + nestedCallResult); + + // Method with multiple return statements + int multipleReturnResult = instance.multipleReturnMethod(15); + System.out.println("Multiple return method result: " + multipleReturnResult); + } + + // Instance method + public int instanceMethod(int a, int b) { + return a + b; + } + + // Static method + public static int staticMethod(int x, int y) { + return x * y; + } + + // Overloaded methods + public String overloadedMethod(int a) { + return "Overloaded with one parameter: " + a; + } + + public String overloadedMethod(int a, int b) { + return "Overloaded with two parameters: " + (a + b); + } + + // Method that calls another method + public int nestedMethodCall(int a, int b) { + return instanceMethod(a, b) * staticMethod(a, b); + } + + // Method with multiple return statements + public int multipleReturnMethod(int value) { + if (value > 10) { + return value * 2; + } else if (value == 10) { + return value * 3; + } else { + return value * 4; + } + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 8467ee1b78..4bd1cb540c 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -14,7 +14,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("Assignment.java", "Assignment.class"), TestCase("ArithmeticOperations.java", "ArithmeticOperations.class"), TestCase("PrimitiveTypeCast.java", "PrimitiveTypeCast.class"), - TestCase("ForLoop.java", "ForLoop.class") + TestCase("ForLoop.java", "ForLoop.class"), + TestCase("MethodCall.java", "MethodCall.class") ) // Case class to represent each test case From 882fb5094d1f77b9024f478340ab296990474f73 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 16:22:39 +0200 Subject: [PATCH 051/111] fixed handleNewArray for Multidimensional Arrays --- .../src/main/scala/org/opalj/tactobc/ExprProcessor.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index afc687e01f..f363e681d6 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -87,7 +87,7 @@ object ExprProcessor { // Initialize the PC after processing the counts var currentAfterCountsPC = currentPC // Process each parameter and update the PC accordingly - for (count <- newArrayExpr.counts) { + for (count <- newArrayExpr.counts.reverse) { currentAfterCountsPC = ExprProcessor.processExpression(count, instructionsWithPCs, currentAfterCountsPC) } if(newArrayExpr.counts.size > 1) { From e8d33d7b4e91ddb17c0b83e49dd63308744b5519 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 16:23:36 +0200 Subject: [PATCH 052/111] added testcase for Arrays --- .../src/test/resources/javaFiles/Array.java | 61 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 +- 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/Array.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/Array.java b/OPAL/tactobc/src/test/resources/javaFiles/Array.java new file mode 100644 index 0000000000..ac3beaf214 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/Array.java @@ -0,0 +1,61 @@ +public class Array { + + public static void main(String[] args) { + // Single-Dimensional Array + int[] singleArray = new int[5]; + + // Assign values to the single-dimensional array + singleArray[0] = 10; + singleArray[1] = 20; + singleArray[2] = 30; + singleArray[3] = 40; + singleArray[4] = 50; + + // Access and print the values in the single-dimensional array + System.out.println("Single Array Elements:"); + for (int i = 0; i < singleArray.length; i++) { + System.out.println("Element at index " + i + ": " + singleArray[i]); + } + + // Multi-Dimensional Array + int[][] multiArray = new int[2][3]; + + // Assign values to the multi-dimensional array + multiArray[0][0] = 1; + multiArray[0][1] = 2; + multiArray[0][2] = 3; + multiArray[1][0] = 4; + multiArray[1][1] = 5; + multiArray[1][2] = 6; + + // Access and print the values in the multi-dimensional array + System.out.println("\nMulti-Dimensional Array Elements:"); + for (int i = 0; i < multiArray.length; i++) { + for (int j = 0; j < multiArray[i].length; j++) { + System.out.println("Element at index [" + i + "][" + j + "]: " + multiArray[i][j]); + } + } + + // Array of Strings + String[] stringArray = {"Apple", "Banana", "Cherry"}; + + // Access and print the values in the string array + System.out.println("\nString Array Elements:"); + for (int i = 0; i < stringArray.length; i++) { + System.out.println("Element at index " + i + ": " + stringArray[i]); + } + + // Array Length Test + System.out.println("\nArray Lengths:"); + System.out.println("Length of singleArray: " + singleArray.length); + System.out.println("Length of multiArray: " + multiArray.length); + System.out.println("Length of stringArray: " + stringArray.length); + + // Modify and reprint the single-dimensional array + singleArray[2] = 100; + System.out.println("\nModified Single Array Elements:"); + for (int i = 0; i < singleArray.length; i++) { + System.out.println("Element at index " + i + ": " + singleArray[i]); + } + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 4bd1cb540c..6ef07388dd 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -15,7 +15,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("ArithmeticOperations.java", "ArithmeticOperations.class"), TestCase("PrimitiveTypeCast.java", "PrimitiveTypeCast.class"), TestCase("ForLoop.java", "ForLoop.class"), - TestCase("MethodCall.java", "MethodCall.class") + TestCase("MethodCall.java", "MethodCall.class"), + TestCase("Array.java", "Array.class") ) // Case class to represent each test case From 2369d2401e6a476f8a0614bb45282f494205277e Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 16:40:00 +0200 Subject: [PATCH 053/111] added testcase for Parameters --- .../test/resources/javaFiles/Parameters.java | 55 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 +- 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/Parameters.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/Parameters.java b/OPAL/tactobc/src/test/resources/javaFiles/Parameters.java new file mode 100644 index 0000000000..183d63eb2a --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/Parameters.java @@ -0,0 +1,55 @@ +public class Parameters { + + public static void main(String[] args) { + // Test with primitive types + int a = 10; + double b = 20.5; + char c = 'A'; + + System.out.println("Sum of int and double: " + sum(a, b)); + System.out.println("Character to int: " + charToInt(c)); + + // Test with array parameters + int[] numbers = {1, 2, 3, 4, 5}; + System.out.println("Sum of array elements: " + sumArray(numbers)); + + // Test with varargs + System.out.println("Sum with varargs: " + sumVarArgs(1, 2, 3, 4, 5)); + + // Test with multiple primitive parameters + System.out.println("Average of three numbers: " + average(5, 10, 15)); + } + + // Method with primitive parameters + public static double sum(int x, double y) { + return x + y; + } + + // Method with a char parameter + public static int charToInt(char ch) { + return ch; + } + + // Method with an array parameter + public static int sumArray(int[] array) { + int sum = 0; + for (int num : array) { + sum += num; + } + return sum; + } + + // Method with varargs parameter + public static int sumVarArgs(int... numbers) { + int sum = 0; + for (int num : numbers) { + sum += num; + } + return sum; + } + + // Method with multiple primitive parameters + public static double average(int x, int y, int z) { + return (x + y + z) / 3.0; + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 6ef07388dd..bc101e1053 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -16,7 +16,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("PrimitiveTypeCast.java", "PrimitiveTypeCast.class"), TestCase("ForLoop.java", "ForLoop.class"), TestCase("MethodCall.java", "MethodCall.class"), - TestCase("Array.java", "Array.class") + TestCase("Array.java", "Array.class"), + TestCase("Parameters.java", "Parameters.class") ) // Case class to represent each test case From 4e02d175b32bb522ed29a65db591af8ae61abaf5 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 16:53:20 +0200 Subject: [PATCH 054/111] added testcase for StaticField --- .../test/resources/javaFiles/StaticField.java | 23 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 ++- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/StaticField.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/StaticField.java b/OPAL/tactobc/src/test/resources/javaFiles/StaticField.java new file mode 100644 index 0000000000..0181fd35f0 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/StaticField.java @@ -0,0 +1,23 @@ +public class StaticField { + + // A static field + private static int staticValue; + + public static void main(String[] args) { + // Set the static field + setStaticValue(42); + + // Get the static field value and print it + System.out.println("Static field value: " + getStaticValue()); + } + + // Method to set the static field + public static void setStaticValue(int value) { + staticValue = value; + } + + // Method to get the static field value + public static int getStaticValue() { + return staticValue; + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index bc101e1053..410a4c8688 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -17,7 +17,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("ForLoop.java", "ForLoop.class"), TestCase("MethodCall.java", "MethodCall.class"), TestCase("Array.java", "Array.class"), - TestCase("Parameters.java", "Parameters.class") + TestCase("Parameters.java", "Parameters.class"), + TestCase("StaticField.java", "StaticField.class") ) // Case class to represent each test case From e8249974b32f78011b7ca2c873b0560db050f9fb Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 17:09:54 +0200 Subject: [PATCH 055/111] added testcase for InstanceField --- .../resources/javaFiles/InstanceField.java | 26 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 ++- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/InstanceField.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/InstanceField.java b/OPAL/tactobc/src/test/resources/javaFiles/InstanceField.java new file mode 100644 index 0000000000..e171005df1 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/InstanceField.java @@ -0,0 +1,26 @@ +public class InstanceField { + + // An instance field + private int instanceValue; + + public static void main(String[] args) { + // Create an instance of the class + InstanceField testInstance = new InstanceField(); + + // Set the instance field + testInstance.setInstanceValue(42); + + // Get the instance field value and print it + System.out.println("Instance field value: " + testInstance.getInstanceValue()); + } + + // Method to set the instance field + public void setInstanceValue(int value) { + this.instanceValue = value; + } + + // Method to get the instance field value + public int getInstanceValue() { + return this.instanceValue; + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 410a4c8688..a672071e02 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -18,7 +18,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("MethodCall.java", "MethodCall.class"), TestCase("Array.java", "Array.class"), TestCase("Parameters.java", "Parameters.class"), - TestCase("StaticField.java", "StaticField.class") + TestCase("StaticField.java", "StaticField.class"), + TestCase("InstanceField.java", "InstanceField.class") ) // Case class to represent each test case From 0ecdb82156e10d34c9723bd7eb712e938ec724b9 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 17:35:02 +0200 Subject: [PATCH 056/111] added testcase for If --- .../src/test/resources/javaFiles/If.java | 66 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 +- 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/If.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/If.java b/OPAL/tactobc/src/test/resources/javaFiles/If.java new file mode 100644 index 0000000000..48f44d3669 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/If.java @@ -0,0 +1,66 @@ +public class If { + + public static void main(String[] args) { + // Test simple if statement with a loop + int a = 10; + int b = 20; + for (int i = 0; i < 5; i++) { + if (a + i < b) { + System.out.println("Iteration " + i + ": a + i is less than b"); + } + } + + // Test if-else statement with a loop + for (int i = 5; i > 0; i--) { + if (a * i > b) { + System.out.println("Iteration " + i + ": a * i is greater than b"); + } else { + System.out.println("Iteration " + i + ": a * i is not greater than b"); + } + } + + // Test if-else if-else statement with a loop + int c = 15; + for (int i = 0; i < 5; i++) { + if (a + i > c) { + System.out.println("Iteration " + i + ": a + i is greater than c"); + } else if (b - i > c) { + System.out.println("Iteration " + i + ": b - i is greater than c"); + } else { + System.out.println("Iteration " + i + ": c is greater than or equal to both a + i and b - i"); + } + } + + // Test nested if statement with a loop + for (int i = 0; i < 5; i++) { + if (a < b) { + if (c + i < b) { + System.out.println("Iteration " + i + ": c + i is less than b"); + } else { + System.out.println("Iteration " + i + ": c + i is greater than or equal to b"); + } + } + } + + // Test if with multiple conditions inside a loop + boolean x = true; + boolean y = false; + for (int i = 0; i < 5; i++) { + if (x && !y && i % 2 == 0) { + System.out.println("Iteration " + i + ": x is true, y is false, and i is even"); + } + } + + // Test if with variables being reassigned inside a loop + int d = 5; + for (int i = 0; i < 3; i++) { + if (d == 5 + i) { + d = 10 + i; + System.out.println("Iteration " + i + ": d was " + (5 + i) + ", now it's " + d); + } + } + if (d == 12) { + System.out.println("After the loop, d is now 12"); + } + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index a672071e02..0787bcb7a9 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -19,7 +19,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("Array.java", "Array.class"), TestCase("Parameters.java", "Parameters.class"), TestCase("StaticField.java", "StaticField.class"), - TestCase("InstanceField.java", "InstanceField.class") + TestCase("InstanceField.java", "InstanceField.class"), + TestCase("If.java", "If.class") ) // Case class to represent each test case From f1171511d86e086cfbbc3351b985b8023491f5f2 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 17:39:12 +0200 Subject: [PATCH 057/111] added testcase for WhileLoop --- .../test/resources/javaFiles/WhileLoop.java | 64 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 5 +- 2 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/WhileLoop.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/WhileLoop.java b/OPAL/tactobc/src/test/resources/javaFiles/WhileLoop.java new file mode 100644 index 0000000000..761fea6ed9 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/WhileLoop.java @@ -0,0 +1,64 @@ +public class WhileLoop { + + public static void main(String[] args) { + // Simple while loop + int counter = 0; + while (counter < 5) { + System.out.println("Simple while loop: counter = " + counter); + counter++; + } + + // While loop with multiple conditions + int a = 10; + int b = 20; + while (a < b && a % 2 == 0) { + System.out.println("While loop with multiple conditions: a = " + a); + a += 2; + } + + // Nested while loop + int outer = 1; + while (outer <= 3) { + int inner = 1; + while (inner <= 2) { + System.out.println("Nested while loop: outer = " + outer + ", inner = " + inner); + inner++; + } + outer++; + } + + // While loop with break + int x = 0; + while (true) { + System.out.println("While loop with break: x = " + x); + if (x >= 3) { + break; + } + x++; + } + + // While loop with continue + int y = 0; + while (y < 5) { + y++; + if (y % 2 == 0) { + continue; + } + System.out.println("While loop with continue: y = " + y); + } + + // Do-while loop + int z = 0; + do { + System.out.println("Do-while loop: z = " + z); + z++; + } while (z < 3); + + // Do-while loop with complex condition + int m = 10; + do { + System.out.println("Do-while loop with complex condition: m = " + m); + m--; + } while (m > 0 && m % 3 != 0); + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 0787bcb7a9..4b6cbf5b41 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -9,8 +9,6 @@ object SingleClassFileTestCaseEnum extends Enumeration { // Test cases with Java and Class file names val testCases: Seq[TestCase] = Seq( - TestCase("HelloWorld.java", "HelloWorld.class"), - TestCase("HelloSofi.java", "HelloSofi.class"), TestCase("Assignment.java", "Assignment.class"), TestCase("ArithmeticOperations.java", "ArithmeticOperations.class"), TestCase("PrimitiveTypeCast.java", "PrimitiveTypeCast.class"), @@ -20,7 +18,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("Parameters.java", "Parameters.class"), TestCase("StaticField.java", "StaticField.class"), TestCase("InstanceField.java", "InstanceField.class"), - TestCase("If.java", "If.class") + TestCase("If.java", "If.class"), + TestCase("WhileLoop.java", "WhileLoop.class") ) // Case class to represent each test case From e7ae24eba2f616fdb85da1eb417d228652459b4b Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 17:39:57 +0200 Subject: [PATCH 058/111] deleted Hello programs --- .../test/resources/javaFiles/HelloSofi.java | 8 --- .../test/resources/javaFiles/HelloWorld.java | 63 ------------------- 2 files changed, 71 deletions(-) delete mode 100644 OPAL/tactobc/src/test/resources/javaFiles/HelloSofi.java delete mode 100644 OPAL/tactobc/src/test/resources/javaFiles/HelloWorld.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/HelloSofi.java b/OPAL/tactobc/src/test/resources/javaFiles/HelloSofi.java deleted file mode 100644 index 428606bd00..0000000000 --- a/OPAL/tactobc/src/test/resources/javaFiles/HelloSofi.java +++ /dev/null @@ -1,8 +0,0 @@ -public class HelloSofi { - public static void main(String[] args) { - Object string = new Object(); - System.out.println(string.toString()); - string = String.valueOf(1.1d); - System.out.println("Successfully succeedded, amazing piece of code: " + string); - } -} diff --git a/OPAL/tactobc/src/test/resources/javaFiles/HelloWorld.java b/OPAL/tactobc/src/test/resources/javaFiles/HelloWorld.java deleted file mode 100644 index a8aad1340a..0000000000 --- a/OPAL/tactobc/src/test/resources/javaFiles/HelloWorld.java +++ /dev/null @@ -1,63 +0,0 @@ -public class HelloWorld { - public static void main(String[] args) { - //todo: separate cases in methods to have testscenarios -// double[][] test1 = new double[1][3]; -// test1[0][0] = 1.1d; -// System.out.println(test1[0][0] * 2); -// String[] strArray = new String[3]; - double d = 1.1d; - System.out.println(d); -// String[] str = new String[2]; -// str[0] = "Hallo"; -// System.out.println(str[0]); -// double[] yay = new double[1]; -// yay[0] = 1.1d; -// HelloWorld hello = new HelloWorld(); -// hello.instanceMethod(yay); -// System.out.println("Successfully succeed: " + yay[0]); -// double d2 = 2 * d; -// System.out.println(d2); -// long l = 1L; -// long l2 = 2 * l; -// System.out.println(l2); -// Object[] objArr = new Object[1]; -// objArr[0] = 1.1d; -// System.out.println("Successfully succeed: " + objArr[0]); -// String[] test = new String[1]; -// test[0] = "Yay!"; -// System.out.println("Successfully succeed: " + test[0]); -// - Object string = new Object(); - System.out.println(string.toString()); - string = String.valueOf(1.1d); - System.out.println("Successfully succeedded, amazing piece of code: " + string); -// strArray[0] = "Hello"; -// System.out.println(strArray[0]); // Should print "Hello" -// System.out.println("HelloWorld!"); -// int i = 0; -// System.out.println(i); -// int x = 1; -// int[] ar = new int[3]; -// for (; i < 3; i++) { -// dumbPrint(i, x); -// x++; -// ar[i] = x; -// System.out.println(ar.length); -// } -// dumbPrint(i, ar[0]); - } - -// public void instanceMethod(double[] d){ -// System.out.println(d[0]); -// } -// public static void dumbPrint(int i, int x) { -// System.out.println("this is a method "); -// System.out.println(i); -// System.out.println(x); -// foo(); -// } -// -// public static void foo() { -// System.out.println("StaticMethod call works :)"); -// } -} From 20a2b6bac9095d04c6600dec6a9ea715b629ef6a Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 18:25:32 +0200 Subject: [PATCH 059/111] added processinng checkcast with tests --- .../org/opalj/tactobc/ExprProcessor.scala | 9 +++++++-- .../scala/org/opalj/tactobc/FirstPass.scala | 4 +++- .../org/opalj/tactobc/StmtProcessor.scala | 8 +++++--- .../test/resources/javaFiles/CheckCast.java | 20 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 ++- 5 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/CheckCast.java diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index f363e681d6..7df3b79ecb 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -4,7 +4,7 @@ package org.opalj.tactobc import org.opalj.BinaryArithmeticOperators.{Add, And, Divide, Modulo, Multiply, Or, ShiftLeft, ShiftRight, Subtract, UnsignedShiftRight, XOr} import org.opalj.RelationalOperators.{CMPG, CMPL} import org.opalj.br.{ArrayType, BooleanType, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FloatType, IntegerType, LongType, ObjectType, ReferenceType, ShortType, Type} -import org.opalj.br.instructions.{AALOAD, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BALOAD, BIPUSH, CALOAD, D2F, D2I, D2L, DADD, DALOAD, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DEFAULT_INVOKEDYNAMIC, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCMP, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, MULTIANEWARRAY, NEW, NEWARRAY, SALOAD, SIPUSH} +import org.opalj.br.instructions.{AALOAD, ACONST_NULL, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BALOAD, BIPUSH, CALOAD, D2F, D2I, D2L, DADD, DALOAD, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DEFAULT_INVOKEDYNAMIC, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCMP, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, MULTIANEWARRAY, NEW, NEWARRAY, SALOAD, SIPUSH} import org.opalj.bytecode.BytecodeProcessingFailedException import org.opalj.collection.immutable.IntTrieSet import org.opalj.tac.{ArrayLength, ArrayLoad, BinaryExpr, ClassConst, Compare, Const, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, InvokedynamicFunctionCall, LongConst, MethodHandleConst, MethodTypeConst, New, NewArray, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} @@ -216,7 +216,11 @@ object ExprProcessor { } private def loadConstant(constExpr: Const, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val instruction = constExpr match { + val instruction = { + if(constExpr.isNullExpr){ + ACONST_NULL + }else + constExpr match { case IntConst(_, value) => value match { case -1 => ICONST_M1 case 0 => ICONST_0 @@ -261,6 +265,7 @@ object ExprProcessor { "unsupported constant value: " + constExpr ) } + } instructionsWithPCs += ((currentPC, instruction)) currentPC + instruction.length // Update and return the new program counter } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index 4d44a79505..4104145c69 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -2,7 +2,7 @@ package org.opalj.tactobc import org.opalj.br.Method import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, Compare, DUVar, Expr, ExprStmt, GetField, If, InvokedynamicFunctionCall, NewArray, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, StaticMethodCall, Stmt, Switch, Throw, UVar, VirtualFunctionCall, VirtualMethodCall} +import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, Checkcast, Compare, DUVar, Expr, ExprStmt, GetField, If, InvokedynamicFunctionCall, NewArray, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, StaticMethodCall, Stmt, Switch, Throw, UVar, VirtualFunctionCall, VirtualMethodCall} import org.opalj.tactobc.ExprProcessor.{nextLVIndex, uVarToLVIndex} import org.opalj.value.ValueInformation @@ -72,6 +72,8 @@ object FirstPass { collectDUVarFromExpr(exception, duVars) case Switch(_, _, index, _) => collectDUVarFromExpr(index, duVars) + case Checkcast(_, value, _) => + collectDUVarFromExpr(value, duVars) case _ => } } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index 7404b3b579..4365e31c5c 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -4,7 +4,7 @@ package org.opalj.tactobc import org.opalj.RelationalOperator import org.opalj.RelationalOperators._ import org.opalj.br.{ArrayType, BootstrapMethod, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FieldType, FloatType, IntegerType, LongType, MethodDescriptor, ObjectType, PCs, ReferenceType, ShortType} -import org.opalj.br.instructions.{AASTORE, ARETURN, ATHROW, BASTORE, CASTORE, DASTORE, DRETURN, FASTORE, FRETURN, GOTO, IASTORE, IFNONNULL, IFNULL, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, LASTORE, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, NOP, PUTFIELD, PUTSTATIC, RET, RETURN, SASTORE, TABLESWITCH} +import org.opalj.br.instructions.{AASTORE, ARETURN, ATHROW, BASTORE, CASTORE, DASTORE, DRETURN, FASTORE, FRETURN, GOTO, IASTORE, IFNONNULL, IFNULL, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, LASTORE, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, NOP, PUTFIELD, PUTSTATIC, RET, RETURN, SASTORE, TABLESWITCH, CHECKCAST} import org.opalj.collection.immutable.{IntIntPair, IntTrieSet} import org.opalj.tac.{Expr, UVar, Var} import org.opalj.tactobc.ExprProcessor.inferElementType @@ -180,8 +180,10 @@ object StmtProcessor { } def processCheckCast(value: Expr[_], cmpTpe: ReferenceType, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - //todo: handle this correctly - 1 + val nextPC = ExprProcessor.processExpression(value, instructionsWithPCs, currentPC) + val instruction = CHECKCAST(cmpTpe) + instructionsWithPCs += ((nextPC, instruction)) + nextPC + instruction.length } def processRet(returnAdresses: PCs, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { diff --git a/OPAL/tactobc/src/test/resources/javaFiles/CheckCast.java b/OPAL/tactobc/src/test/resources/javaFiles/CheckCast.java new file mode 100644 index 0000000000..28dcb33c2d --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/CheckCast.java @@ -0,0 +1,20 @@ +public class CheckCast { + + public static void main(String[] args) { + // Test case 1: Valid cast + Object obj = "This is a string"; + String str = (String) obj; // Valid CHECKCAST + System.out.println("Successfully casted to String: " + str); + + + // Test case 2: Null reference casting + Object nullObj = null; + String nullCast = (String) nullObj; // Valid CHECKCAST, null can be cast to any reference type + System.out.println("Successfully casted null reference to String"); + + // Test case 3: Casting within the same type + Object anotherString = "Another string"; + String sameTypeCast = (String) anotherString; // Valid CHECKCAST + System.out.println("Successfully casted to String: " + sameTypeCast); + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 4b6cbf5b41..3da8a27e9a 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -19,7 +19,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("StaticField.java", "StaticField.class"), TestCase("InstanceField.java", "InstanceField.class"), TestCase("If.java", "If.class"), - TestCase("WhileLoop.java", "WhileLoop.class") + TestCase("WhileLoop.java", "WhileLoop.class"), + TestCase("CheckCast.java", "CheckCast.class") ) // Case class to represent each test case From ae130635b66eb6804eeb18df34da96ece7c543b2 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 18:28:26 +0200 Subject: [PATCH 060/111] cleanup --- .../src/main/scala/org/opalj/tactobc/StmtProcessor.scala | 8 -------- 1 file changed, 8 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index 4365e31c5c..b41852be4f 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -100,7 +100,6 @@ object StmtProcessor { def processVirtualMethodCall(declaringClass: ReferenceType, isInterface: Boolean, methodName: String, methodDescriptor: MethodDescriptor, receiver: Expr[_], params: Seq[Expr[_]], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // Process the receiver object (e.g., aload_0 for `this`) val afterReceiverPC = ExprProcessor.processExpression(receiver, instructionsWithPCs, currentPC) - println(s"Receiver loaded at PC: $afterReceiverPC, Receiver: $receiver") // Initialize the PC after processing the receiver var currentAfterParamsPC = afterReceiverPC @@ -108,7 +107,6 @@ object StmtProcessor { // Process each parameter and update the PC accordingly for (param <- params) { currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) - println(s"Parameter loaded at PC: $currentAfterParamsPC, Parameter: $param") } val instruction = { /*if (isInterface) { @@ -116,7 +114,6 @@ object StmtProcessor { }else*/ INVOKEVIRTUAL(declaringClass, methodName, methodDescriptor) } - println(s"Generated method call instruction: $instruction at PC: $currentAfterParamsPC") //val finalPC = currentPC + pcAfterLoadVariable instructionsWithPCs += ((currentAfterParamsPC, instruction)) currentAfterParamsPC + instruction.length @@ -125,19 +122,15 @@ object StmtProcessor { def processArrayStore(arrayRef: Expr[_], index: Expr[_], value: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // Load the arrayRef onto the stack val pcAfterArrayRefLoad = ExprProcessor.processExpression(arrayRef, instructionsWithPCs, currentPC) - println(s"ArrayRef: $arrayRef, Type: ${arrayRef.cTpe}, PC after load: $pcAfterArrayRefLoad") // Load the index onto the stack val pcAfterIndexLoad = ExprProcessor.processExpression(index, instructionsWithPCs, pcAfterArrayRefLoad) - println(s"Index: $index, Type: ${index.cTpe}, PC after load: $pcAfterIndexLoad") // Load the value to be stored onto the stack val pcAfterValueLoad = ExprProcessor.processExpression(value, instructionsWithPCs, pcAfterIndexLoad) - println(s"Value: $value, Type: ${value.cTpe}, PC after load: $pcAfterValueLoad") // Infer the element type from the array reference expression val elementType = inferElementType(arrayRef) - println(s"Inferred Element Type: $elementType") val instruction = elementType match { @@ -162,7 +155,6 @@ object StmtProcessor { } case _ => throw new IllegalArgumentException(s"Unsupported array store type $elementType") } - println(s"Generated Instruction: $instruction at PC $pcAfterValueLoad") // Add the store instruction instructionsWithPCs += ((pcAfterValueLoad, instruction)) pcAfterValueLoad + instruction.length From 80028fd5dca4cfddea50482861f9b32cdf84edfb Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 18:36:19 +0200 Subject: [PATCH 061/111] cleanup --- .../src/main/scala/org/opalj/tactobc/ExprProcessor.scala | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index 7df3b79ecb..bdfefcd46d 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -259,11 +259,7 @@ object ExprProcessor { val instruction = LoadDynamic(-1, bootstrapMethod, name, descriptor) instructionsWithPCs += ((currentPC, instruction)) currentPC += instruction.length*/ - case _ => - //todo: check that this is the right exception to throw - throw BytecodeProcessingFailedException( - "unsupported constant value: " + constExpr - ) + case _ => throw BytecodeProcessingFailedException("unsupported constant value: " + constExpr) } } instructionsWithPCs += ((currentPC, instruction)) From c55bf2a77c77851eb9a82c86f663d1a87cfa0906 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 18:36:37 +0200 Subject: [PATCH 062/111] added testcase for Compare --- .../src/test/resources/javaFiles/Compare.java | 54 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 +- 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/Compare.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/Compare.java b/OPAL/tactobc/src/test/resources/javaFiles/Compare.java new file mode 100644 index 0000000000..67a6a332c6 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/Compare.java @@ -0,0 +1,54 @@ +public class Compare { + + public static void main(String[] args) { + // Test case 1: Float comparison + float f1 = 10.5f; + float f2 = 20.5f; + + int floatComparisonResult; + if (f1 > f2) { + floatComparisonResult = 1; + } else if (f1 < f2) { + floatComparisonResult = -1; + } else { + floatComparisonResult = 0; + } + System.out.println("Float comparison result: " + floatComparisonResult); + + // Test case 2: Double comparison + double d1 = 100.123; + double d2 = 100.456; + + int doubleComparisonResult; + if (d1 > d2) { + doubleComparisonResult = 1; + } else if (d1 < d2) { + doubleComparisonResult = -1; + } else { + doubleComparisonResult = 0; + } + System.out.println("Double comparison result: " + doubleComparisonResult); + + // Test case 3: Long comparison + long l1 = 123456789L; + long l2 = 987654321L; + + int longComparisonResult = (l1 < l2) ? -1 : ((l1 > l2) ? 1 : 0); + System.out.println("Long comparison result: " + longComparisonResult); + + // Combining results to ensure they are used in further logic + int combinedResult = floatComparisonResult + doubleComparisonResult + longComparisonResult; + if (combinedResult > 0) { + System.out.println("Overall: positive result"); + } else if (combinedResult < 0) { + System.out.println("Overall: negative result"); + } else { + System.out.println("Overall: zero result"); + } + + // Complex usage: Looping based on comparisons + for (int i = 0; i < combinedResult; i++) { + System.out.println("Loop iteration: " + i); + } + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 3da8a27e9a..f0b1dc79f5 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -20,7 +20,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("InstanceField.java", "InstanceField.class"), TestCase("If.java", "If.class"), TestCase("WhileLoop.java", "WhileLoop.class"), - TestCase("CheckCast.java", "CheckCast.class") + TestCase("CheckCast.java", "CheckCast.class"), + TestCase("Compare.java", "Compare.class") ) // Case class to represent each test case From 449b9f57caade121bf34096158d0d6d868583128 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 18:41:43 +0200 Subject: [PATCH 063/111] added for more coverage of instructions --- .../javaFiles/ArithmeticOperations.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/OPAL/tactobc/src/test/resources/javaFiles/ArithmeticOperations.java b/OPAL/tactobc/src/test/resources/javaFiles/ArithmeticOperations.java index 10fb0d12fd..35d07fd5de 100644 --- a/OPAL/tactobc/src/test/resources/javaFiles/ArithmeticOperations.java +++ b/OPAL/tactobc/src/test/resources/javaFiles/ArithmeticOperations.java @@ -43,11 +43,31 @@ public static void main(String[] args) { long longSubtractionResult = p - q; long longMultiplicationResult = p * q; long longDivisionResult = p / q; + long longModulusResult = p % q; System.out.println("Long Addition: " + longAdditionResult); System.out.println("Long Subtraction: " + longSubtractionResult); System.out.println("Long Multiplication: " + longMultiplicationResult); System.out.println("Long Division: " + longDivisionResult); + System.out.println("Long Modulus: " + longModulusResult); + + // Bitwise Operations with Longs + long longAndResult = p & q; + long longOrResult = p | q; + long longXorResult = p ^ q; + + System.out.println("Long AND: " + longAndResult); + System.out.println("Long OR: " + longOrResult); + System.out.println("Long XOR: " + longXorResult); + + // Shift Operations with Longs + long longShiftLeftResult = p << 2; + long longShiftRightResult = p >> 2; + long longUnsignedShiftRightResult = p >>> 2; + + System.out.println("Long Shift Left: " + longShiftLeftResult); + System.out.println("Long Shift Right: " + longShiftRightResult); + System.out.println("Long Unsigned Shift Right: " + longUnsignedShiftRightResult); // Short and Byte Operations short s1 = 10; From 12c90159375db16f778f9f3d76953f656b721c60 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 18:56:36 +0200 Subject: [PATCH 064/111] added processing of JSR --- .../scala/org/opalj/tactobc/SecondPass.scala | 4 +-- .../org/opalj/tactobc/StmtProcessor.scala | 25 +++++++++++++------ .../scala/org/opalj/tactobc/ThirdPass.scala | 4 ++- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala index 96e7a943e6..6de20771d1 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala @@ -61,8 +61,8 @@ object SecondPass { tacTargetToByteCodePcs += ((defaultTarget, currentPC)) currentPC = StmtProcessor.processSwitch(defaultTarget, index, npairs, generatedByteCodeWithPC, currentPC) case JSR(_, target) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processJSR(target, generatedByteCodeWithPC, currentPC) + tacTargetToByteCodePcs += ((target, currentPC)) + currentPC = StmtProcessor.processJSR(generatedByteCodeWithPC, currentPC) case VirtualMethodCall(_, declaringClass, isInterface, name, descriptor, receiver, params) => tacTargetToByteCodePcs += ((-1, currentPC)) currentPC = StmtProcessor.processVirtualMethodCall(declaringClass, isInterface, name, descriptor, receiver, params, generatedByteCodeWithPC, currentPC) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index b41852be4f..aa90769886 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -4,7 +4,7 @@ package org.opalj.tactobc import org.opalj.RelationalOperator import org.opalj.RelationalOperators._ import org.opalj.br.{ArrayType, BootstrapMethod, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FieldType, FloatType, IntegerType, LongType, MethodDescriptor, ObjectType, PCs, ReferenceType, ShortType} -import org.opalj.br.instructions.{AASTORE, ARETURN, ATHROW, BASTORE, CASTORE, DASTORE, DRETURN, FASTORE, FRETURN, GOTO, IASTORE, IFNONNULL, IFNULL, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, LASTORE, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, NOP, PUTFIELD, PUTSTATIC, RET, RETURN, SASTORE, TABLESWITCH, CHECKCAST} +import org.opalj.br.instructions.{AASTORE, ARETURN, ATHROW, BASTORE, CASTORE, DASTORE, DRETURN, FASTORE, FRETURN, GOTO, IASTORE, IFNONNULL, IFNULL, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, LASTORE, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, NOP, PUTFIELD, PUTSTATIC, RET, RETURN, SASTORE, TABLESWITCH, CHECKCAST, JSR} import org.opalj.collection.immutable.{IntIntPair, IntTrieSet} import org.opalj.tac.{Expr, UVar, Var} import org.opalj.tactobc.ExprProcessor.inferElementType @@ -178,10 +178,20 @@ object StmtProcessor { nextPC + instruction.length } - def processRet(returnAdresses: PCs, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - //todo: handle returnAdresses this correctly - val instruction = RET(returnAdresses.size) + def processRet(returnAddresses: PCs, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // Ensure there is only one return address, as RET can only work with one local variable index + if (returnAddresses.size != 1) { + throw new IllegalArgumentException(s"RET instruction expects exactly one return address, but got: ${returnAddresses.size}") + } + + // The RET instruction requires the index of the local variable that holds the return address + val localVarIndex = returnAddresses.head + + // Create the RET instruction with the correct local variable index + val instruction = RET(localVarIndex) instructionsWithPCs += ((currentPC, instruction)) + + // Return the next program counter currentPC + instruction.length } @@ -229,10 +239,9 @@ object StmtProcessor { pcAfterObjRefLoad + instruction.length } - def processJSR(target: Int, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - //todo: look what to do with the target, how to get the length and if it is a jump instruction - //val instruction = JSR - //instructionsWithPCs += ((currentPC, instruction)) + def processJSR(instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + val instruction = JSR(-1) + instructionsWithPCs += ((currentPC, instruction)) currentPC + 1 } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala index dd1af17804..1628b4b54e 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala @@ -1,6 +1,6 @@ package org.opalj.tactobc -import org.opalj.br.instructions.{GOTO, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, Instruction, LOOKUPSWITCH, TABLESWITCH} +import org.opalj.br.instructions.{GOTO, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, Instruction, LOOKUPSWITCH, TABLESWITCH, JSR} import org.opalj.collection.immutable.{IntIntPair, IntTrieSet} import org.opalj.tac.{DUVar, Stmt} import org.opalj.value.ValueInformation @@ -52,6 +52,8 @@ object ThirdPass { instruction case GOTO(-1) => GOTO(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + case JSR(-1) => + JSR(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) case LOOKUPSWITCH(defaultOffset, matchOffsets) => val updatedMatchOffsets = matchOffsets.map { case IntIntPair(caseValue, _) => val tacTarget = findTacTarget(switchCases, caseValue) From 305907e4934d819182db6cc172d7e509a424eb28 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sun, 11 Aug 2024 18:56:52 +0200 Subject: [PATCH 065/111] added testcase for JSR --- .../src/test/resources/javaFiles/Jsr.java | 18 ++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 ++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/Jsr.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/Jsr.java b/OPAL/tactobc/src/test/resources/javaFiles/Jsr.java new file mode 100644 index 0000000000..a003d1e607 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/Jsr.java @@ -0,0 +1,18 @@ +public class Jsr { + + public static void main(String[] args) { + System.out.println("Before subroutine"); + executeSubroutine(); + System.out.println("After subroutine"); + } + + private static void executeSubroutine() { + System.out.println("In subroutine"); + // Simulating a subroutine with a loop or some operations + for (int i = 0; i < 3; i++) { + System.out.println("Subroutine iteration: " + i); + } + // Return from the subroutine (RET equivalent) + return; // RET is simulated by this return statement in Java + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index f0b1dc79f5..dba9ba921b 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -21,7 +21,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("If.java", "If.class"), TestCase("WhileLoop.java", "WhileLoop.class"), TestCase("CheckCast.java", "CheckCast.class"), - TestCase("Compare.java", "Compare.class") + TestCase("Compare.java", "Compare.class"), + TestCase("Jsr.java", "Jsr.class") ) // Case class to represent each test case From 4731076611a1f81700dba551dff95f47b8138096 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Mon, 12 Aug 2024 16:37:00 +0200 Subject: [PATCH 066/111] cleanup --- OPAL/tactobc/src/test/resources/scimark-2.2.jar | Bin 22619 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 OPAL/tactobc/src/test/resources/scimark-2.2.jar diff --git a/OPAL/tactobc/src/test/resources/scimark-2.2.jar b/OPAL/tactobc/src/test/resources/scimark-2.2.jar deleted file mode 100644 index 56f3dddaff29433fbeab3afaae21b7d7eed4f863..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22619 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

-b|O^PpumqzP|zWC3uIMP<|VV(VwPzpDM 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 From a8ab4b055dab40d90a9a05ead0853c035374d2ec Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 14 Aug 2024 14:37:54 +0200 Subject: [PATCH 067/111] fix processing if for reference types --- .../org/opalj/tactobc/StmtProcessor.scala | 38 ++++++++++--------- .../scala/org/opalj/tactobc/ThirdPass.scala | 12 +++++- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index aa90769886..d4cfa63b17 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -4,7 +4,7 @@ package org.opalj.tactobc import org.opalj.RelationalOperator import org.opalj.RelationalOperators._ import org.opalj.br.{ArrayType, BootstrapMethod, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FieldType, FloatType, IntegerType, LongType, MethodDescriptor, ObjectType, PCs, ReferenceType, ShortType} -import org.opalj.br.instructions.{AASTORE, ARETURN, ATHROW, BASTORE, CASTORE, DASTORE, DRETURN, FASTORE, FRETURN, GOTO, IASTORE, IFNONNULL, IFNULL, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, LASTORE, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, NOP, PUTFIELD, PUTSTATIC, RET, RETURN, SASTORE, TABLESWITCH, CHECKCAST, JSR} +import org.opalj.br.instructions.{AASTORE, ARETURN, ATHROW, BASTORE, CASTORE, CHECKCAST, DASTORE, DRETURN, FASTORE, FRETURN, GOTO, IASTORE, IFNONNULL, IFNULL, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, JSR, LASTORE, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, NOP, PUTFIELD, PUTSTATIC, RET, RETURN, SASTORE, TABLESWITCH} import org.opalj.collection.immutable.{IntIntPair, IntTrieSet} import org.opalj.tac.{Expr, UVar, Var} import org.opalj.tactobc.ExprProcessor.inferElementType @@ -289,14 +289,25 @@ object StmtProcessor { } def generateIfInstruction(left: Expr[_], condition: RelationalOperator, right: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int, rightPC: Int): Int = { - val instruction = (left, right) match { - case _ if right.isNullExpr || left.isNullExpr => + val instruction = (left.cTpe, right.cTpe) match { + // Handle null comparisons + case (_, _) if right.isNullExpr || left.isNullExpr => condition match { case EQ => IFNULL(-1) case NE => IFNONNULL(-1) case _ => throw new UnsupportedOperationException(s"Unsupported condition: $condition") } - case _ => + + // Handle reference comparisons (object references) + case (ComputationalTypeReference, ComputationalTypeReference) => + condition match { + case EQ => IF_ACMPEQ(-1) + case NE => IF_ACMPNE(-1) + case _ => throw new UnsupportedOperationException(s"Unsupported condition: $condition") + } + + // Handle integer comparisons + case (ComputationalTypeInt, ComputationalTypeInt) => condition match { case EQ => IF_ICMPEQ(-1) case NE => IF_ICMPNE(-1) @@ -306,19 +317,12 @@ object StmtProcessor { case GE => IF_ICMPGE(-1) case _ => throw new UnsupportedOperationException(s"Unsupported condition: $condition") } - /*case EQ => IF_ACMPEQ(-1) - case NE => IF_ACMPNE(-1) - //Unsupported - case _ => IFNE(-1)//throw new UnsupportedOperationException(s"Unsupported condition: $condition")*/ - } - val offsetPC = { - if(rightPC > 0 && rightPC > currentPC){ - currentPC + (rightPC - currentPC) - } else { - currentPC - } + + // Handle unsupported types + case _ => throw new UnsupportedOperationException(s"Unsupported types: left = ${left.cTpe}, right = ${right.cTpe}") } - instructionsWithPCs += ((offsetPC, instruction)) - offsetPC + instruction.length + + instructionsWithPCs += ((rightPC, instruction)) + rightPC + instruction.length } } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala index 1628b4b54e..ac1b536d85 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala @@ -1,6 +1,6 @@ package org.opalj.tactobc -import org.opalj.br.instructions.{GOTO, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, Instruction, LOOKUPSWITCH, TABLESWITCH, JSR} +import org.opalj.br.instructions.{GOTO, IF_ACMPEQ, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, IF_ACMPNE, Instruction, JSR, LOOKUPSWITCH, TABLESWITCH} import org.opalj.collection.immutable.{IntIntPair, IntTrieSet} import org.opalj.tac.{DUVar, Stmt} import org.opalj.value.ValueInformation @@ -50,6 +50,16 @@ object ThirdPass { val instruction = IF_ICMPGE(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) tacTargetToByteCodePcsIndex += 1 instruction + case IF_ACMPEQ(-1) => + tacTargetToByteCodePcsIndex -= 1 + val instruction = IF_ACMPEQ(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + tacTargetToByteCodePcsIndex += 1 + instruction + case IF_ACMPNE(-1) => + tacTargetToByteCodePcsIndex -= 1 + val instruction = IF_ACMPNE(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) + tacTargetToByteCodePcsIndex += 1 + instruction case GOTO(-1) => GOTO(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) case JSR(-1) => From 3f7002c35e92c6991ea4445b283820d07e6c8b3b Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 14 Aug 2024 14:38:22 +0200 Subject: [PATCH 068/111] added testcase for reference types --- OPAL/tactobc/src/test/resources/javaFiles/If.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/OPAL/tactobc/src/test/resources/javaFiles/If.java b/OPAL/tactobc/src/test/resources/javaFiles/If.java index 48f44d3669..d8c761cf99 100644 --- a/OPAL/tactobc/src/test/resources/javaFiles/If.java +++ b/OPAL/tactobc/src/test/resources/javaFiles/If.java @@ -62,5 +62,13 @@ public static void main(String[] args) { if (d == 12) { System.out.println("After the loop, d is now 12"); } + + // Object comparison using == (reference comparison) + String str1 = "Hello"; + String str2 = "Hello"; + + if (str1 == str2) { + System.out.println("str1 == str2: Both references are the same"); + } } } From 74b9573b5c73290033e04c3c2fdf618eeefd6732 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 14 Aug 2024 14:38:22 +0200 Subject: [PATCH 069/111] added testcase for reference types --- .../src/test/resources/javaFiles/If.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/OPAL/tactobc/src/test/resources/javaFiles/If.java b/OPAL/tactobc/src/test/resources/javaFiles/If.java index 48f44d3669..39308d0f03 100644 --- a/OPAL/tactobc/src/test/resources/javaFiles/If.java +++ b/OPAL/tactobc/src/test/resources/javaFiles/If.java @@ -62,5 +62,22 @@ public static void main(String[] args) { if (d == 12) { System.out.println("After the loop, d is now 12"); } + + // Object comparison using == (reference comparison) + String str1 = "Hello"; + String str2 = "Hello"; + + if (str1 == str2) { + System.out.println("str1 == str2: Both references are the same"); + } + + String s1 = new String("test"); + String s2 = new String("test"); + + if (s1.equals(s2)) { + System.out.println("Equal strings"); + } else { + System.out.println("Not equal strings"); + } } } From 414eae94b51aa2d74a859f58f28dcfb1446dd2a4 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 14 Aug 2024 17:48:47 +0200 Subject: [PATCH 070/111] added testcase checking constants loading --- .../test/resources/javaFiles/Constants.java | 55 +++++++++++++++++++ .../tactobc/SingleClassFileTACtoBCTest.scala | 4 ++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 +- 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/Constants.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/Constants.java b/OPAL/tactobc/src/test/resources/javaFiles/Constants.java new file mode 100644 index 0000000000..f865c8a2e5 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/Constants.java @@ -0,0 +1,55 @@ +public class Constants { + + public static void main(String[] args) { + // Integer constants + int intMin1 = -1; + int int0 = 0; + int int1 = 1; + int int2 = 2; + int int3 = 3; + int int4 = 4; + int int5 = 5; + int int127 = 127; // Should use BIPUSH + int int128 = 128; // Should use SIPUSH + int int32767 = 32767; // Maximum short value + int intBig = 100000; // Should use LDC + + System.out.println("Integer Constants:"); + System.out.println(intMin1 + ", " + int0 + ", " + int1 + ", " + int2 + ", " + int3 + ", " + int4 + ", " + int5); + System.out.println(int127 + ", " + int128 + ", " + int32767 + ", " + intBig); + + // Float constants + float float0 = 0.0f; + float float1 = 1.0f; + float float2 = 2.0f; + float float3Point5 = 3.5f; // Should use LDC + + System.out.println("Float Constants:"); + System.out.println(float0 + ", " + float1 + ", " + float2 + ", " + float3Point5); + + // Double constants + double double0 = 0.0; + double double1 = 1.0; + double double1Point5 = 1.5; // Should use LDC + + System.out.println("Double Constants:"); + System.out.println(double0 + ", " + double1 + ", " + double1Point5); + + // Long constants + long long0 = 0L; + long long1 = 1L; + long longBig = 100000L; // Should use LDC2_W + + System.out.println("Long Constants:"); + System.out.println(long0 + ", " + long1 + ", " + longBig); + + // String constants + String stringConst = "Hello, World!"; + String stringEmpty = ""; + String stringNull = null; // Should use ACONST_NULL + + System.out.println("String Constants:"); + System.out.println(stringConst + ", " + stringEmpty); + System.out.println(stringNull); // This will print "null" + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTACtoBCTest.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTACtoBCTest.scala index c69971ee72..bd578eef0a 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTACtoBCTest.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTACtoBCTest.scala @@ -1,6 +1,7 @@ package org.opalj.tactobc import org.opalj.br.analyses.Project +import org.opalj.tactobc.TACtoBC.compileByteCode import org.opalj.util.InMemoryClassLoader import org.scalatest.funspec.AnyFunSpec import org.scalatest.matchers.should.Matchers @@ -32,6 +33,9 @@ class SingleClassFileTACtoBCTest extends AnyFunSpec with Matchers { // Create the OPAL project from the original class file val project = Project(originalClassFile) + //(1) compile bytecode + compileByteCode(originalClassFile) + // Compile the TAC from the original class file val tacs = TACtoBC.compileTAC(originalClassFile) // Print out TAC diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index dba9ba921b..1c8dda60cb 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -22,7 +22,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("WhileLoop.java", "WhileLoop.class"), TestCase("CheckCast.java", "CheckCast.class"), TestCase("Compare.java", "Compare.class"), - TestCase("Jsr.java", "Jsr.class") + TestCase("Jsr.java", "Jsr.class"), + TestCase("Constants.java", "Constants.class") ) // Case class to represent each test case From f20cafe46874a120d6d8dec96d626f3dfd2c4153 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 14 Aug 2024 18:12:34 +0200 Subject: [PATCH 071/111] added processing of Negation --- .../org/opalj/tactobc/ExprProcessor.scala | 23 +++++++++++++++++-- .../scala/org/opalj/tactobc/FirstPass.scala | 7 +++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index bdfefcd46d..a1759b3e43 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -4,10 +4,10 @@ package org.opalj.tactobc import org.opalj.BinaryArithmeticOperators.{Add, And, Divide, Modulo, Multiply, Or, ShiftLeft, ShiftRight, Subtract, UnsignedShiftRight, XOr} import org.opalj.RelationalOperators.{CMPG, CMPL} import org.opalj.br.{ArrayType, BooleanType, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FloatType, IntegerType, LongType, ObjectType, ReferenceType, ShortType, Type} -import org.opalj.br.instructions.{AALOAD, ACONST_NULL, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BALOAD, BIPUSH, CALOAD, D2F, D2I, D2L, DADD, DALOAD, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DEFAULT_INVOKEDYNAMIC, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCMP, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, MULTIANEWARRAY, NEW, NEWARRAY, SALOAD, SIPUSH} +import org.opalj.br.instructions.{AALOAD, ACONST_NULL, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BALOAD, BIPUSH, CALOAD, D2F, D2I, D2L, DADD, DALOAD, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DEFAULT_INVOKEDYNAMIC, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DNEG, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FNEG, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INEG, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCMP, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LNEG, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, MULTIANEWARRAY, NEW, NEWARRAY, SALOAD, SIPUSH} import org.opalj.bytecode.BytecodeProcessingFailedException import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{ArrayLength, ArrayLoad, BinaryExpr, ClassConst, Compare, Const, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, InvokedynamicFunctionCall, LongConst, MethodHandleConst, MethodTypeConst, New, NewArray, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} +import org.opalj.tac.{ArrayLength, ArrayLoad, BinaryExpr, ClassConst, Compare, Const, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, InvokedynamicFunctionCall, LongConst, MethodHandleConst, MethodTypeConst, New, NewArray, PrefixExpr, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} import org.opalj.value.IsSReferenceValue import scala.collection.mutable @@ -32,11 +32,30 @@ object ExprProcessor { case newArrayExpr: NewArray[_] => handleNewArray(newArrayExpr, instructionsWithPCs, currentPC) case invokedynamicFunctionCall: InvokedynamicFunctionCall[_] => handleInvokedynamicFunctionCall(invokedynamicFunctionCall, instructionsWithPCs, currentPC) case compare: Compare[_] => handleCompare(compare, instructionsWithPCs, currentPC) + case prefixExpr: PrefixExpr[_] => handlePrefixExpr(prefixExpr, instructionsWithPCs, currentPC) case _ => throw new UnsupportedOperationException("Unsupported expression type" + expr) } } + def handlePrefixExpr(prefixExpr: PrefixExpr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + // Process the operand (the expression being negated) + val operandPC = ExprProcessor.processExpression(prefixExpr.operand, instructionsWithPCs, currentPC) + + // Determine the appropriate negation instruction based on the operand type + val instruction = prefixExpr.operand.cTpe match { + case ComputationalTypeInt => INEG + case ComputationalTypeLong => LNEG + case ComputationalTypeFloat => FNEG + case ComputationalTypeDouble => DNEG + case _ => throw new UnsupportedOperationException(s"Unsupported type for negation: ${prefixExpr.operand.cTpe}") + } + + // Add the instruction to the list + instructionsWithPCs += ((operandPC, instruction)) + operandPC + instruction.length // Update and return the new program counter + } + def handleCompare(compare: Compare[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // Process the left expression and update the PC val pcAfterLeft = processExpression(compare.left, instructionsWithPCs, currentPC) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index 4104145c69..92c8c0e2d9 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -2,7 +2,7 @@ package org.opalj.tactobc import org.opalj.br.Method import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, Checkcast, Compare, DUVar, Expr, ExprStmt, GetField, If, InvokedynamicFunctionCall, NewArray, NonVirtualMethodCall, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, StaticMethodCall, Stmt, Switch, Throw, UVar, VirtualFunctionCall, VirtualMethodCall} +import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, Checkcast, Compare, DUVar, Expr, ExprStmt, GetField, If, InvokedynamicFunctionCall, NewArray, NonVirtualMethodCall, PrefixExpr, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, StaticMethodCall, Stmt, Switch, Throw, UVar, VirtualFunctionCall, VirtualMethodCall} import org.opalj.tactobc.ExprProcessor.{nextLVIndex, uVarToLVIndex} import org.opalj.value.ValueInformation @@ -207,10 +207,15 @@ object FirstPass { case invokedynamicFunctionCall: InvokedynamicFunctionCall[_] => collectDUVarFromInvokedynamicFunctionCall(invokedynamicFunctionCall, duVars) case getField: GetField[_] => collectDUVarFromGetField(getField, duVars) case compare: Compare[_] => collectDUVarFromCompare(compare, duVars) + case prefixExpr: PrefixExpr[_] => collectDUVarFromPrefixExpr(prefixExpr, duVars) case _ => } } + def collectDUVarFromPrefixExpr(prefixExpr: PrefixExpr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectDUVarFromExpr(prefixExpr.operand, duVars) + } + def collectDUVarFromCompare(compare: Compare[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { collectDUVarFromExpr(compare.left, duVars) collectDUVarFromExpr(compare.right, duVars) From 1ba7f1c8bed632a1b22c663877d86d2d2adbd14c Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 14 Aug 2024 18:12:50 +0200 Subject: [PATCH 072/111] added testcase for Negation --- .../test/resources/javaFiles/Negation.java | 35 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 +- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/Negation.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/Negation.java b/OPAL/tactobc/src/test/resources/javaFiles/Negation.java new file mode 100644 index 0000000000..51998462dd --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/Negation.java @@ -0,0 +1,35 @@ +public class Negation { + + public static void main(String[] args) { + // Integer negation + int intValue = 42; + int negatedInt = -intValue; + System.out.println("Negated int: " + negatedInt); + + // Long negation + long longValue = 123456789L; + long negatedLong = -longValue; + System.out.println("Negated long: " + negatedLong); + + // Float negation + float floatValue = 3.14f; + float negatedFloat = -floatValue; + System.out.println("Negated float: " + negatedFloat); + + // Double negation + double doubleValue = 2.71828; + double negatedDouble = -doubleValue; + System.out.println("Negated double: " + negatedDouble); + + // Test negation in expressions + int exprInt = -(intValue + 10); + long exprLong = -(longValue * 2); + float exprFloat = -(floatValue / 2.0f); + double exprDouble = -(doubleValue - 1.0); + + System.out.println("Negated int in expression: " + exprInt); + System.out.println("Negated long in expression: " + exprLong); + System.out.println("Negated float in expression: " + exprFloat); + System.out.println("Negated double in expression: " + exprDouble); + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 1c8dda60cb..00e70ff038 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -23,7 +23,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("CheckCast.java", "CheckCast.class"), TestCase("Compare.java", "Compare.class"), TestCase("Jsr.java", "Jsr.class"), - TestCase("Constants.java", "Constants.class") + TestCase("Constants.java", "Constants.class"), + TestCase("Negation.java", "Negation.class") ) // Case class to represent each test case From 474069f5fc41baef5a6f5fb0d4d30f43574b176a Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 14 Aug 2024 18:40:08 +0200 Subject: [PATCH 073/111] added handling for InstanceOf --- .../main/scala/org/opalj/tactobc/ExprProcessor.scala | 12 ++++++++++-- .../src/main/scala/org/opalj/tactobc/FirstPass.scala | 7 ++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index a1759b3e43..3dcabdce0a 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -4,10 +4,10 @@ package org.opalj.tactobc import org.opalj.BinaryArithmeticOperators.{Add, And, Divide, Modulo, Multiply, Or, ShiftLeft, ShiftRight, Subtract, UnsignedShiftRight, XOr} import org.opalj.RelationalOperators.{CMPG, CMPL} import org.opalj.br.{ArrayType, BooleanType, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FloatType, IntegerType, LongType, ObjectType, ReferenceType, ShortType, Type} -import org.opalj.br.instructions.{AALOAD, ACONST_NULL, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BALOAD, BIPUSH, CALOAD, D2F, D2I, D2L, DADD, DALOAD, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DEFAULT_INVOKEDYNAMIC, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DNEG, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FNEG, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INEG, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCMP, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LNEG, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, MULTIANEWARRAY, NEW, NEWARRAY, SALOAD, SIPUSH} +import org.opalj.br.instructions.{AALOAD, ACONST_NULL, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BALOAD, BIPUSH, CALOAD, D2F, D2I, D2L, DADD, DALOAD, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DEFAULT_INVOKEDYNAMIC, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DNEG, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FNEG, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INEG, INSTANCEOF, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCMP, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LNEG, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, MULTIANEWARRAY, NEW, NEWARRAY, SALOAD, SIPUSH} import org.opalj.bytecode.BytecodeProcessingFailedException import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{ArrayLength, ArrayLoad, BinaryExpr, ClassConst, Compare, Const, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, IntConst, InvokedynamicFunctionCall, LongConst, MethodHandleConst, MethodTypeConst, New, NewArray, PrefixExpr, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} +import org.opalj.tac.{ArrayLength, ArrayLoad, BinaryExpr, ClassConst, Compare, Const, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, InstanceOf, IntConst, InvokedynamicFunctionCall, LongConst, MethodHandleConst, MethodTypeConst, New, NewArray, PrefixExpr, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} import org.opalj.value.IsSReferenceValue import scala.collection.mutable @@ -33,11 +33,19 @@ object ExprProcessor { case invokedynamicFunctionCall: InvokedynamicFunctionCall[_] => handleInvokedynamicFunctionCall(invokedynamicFunctionCall, instructionsWithPCs, currentPC) case compare: Compare[_] => handleCompare(compare, instructionsWithPCs, currentPC) case prefixExpr: PrefixExpr[_] => handlePrefixExpr(prefixExpr, instructionsWithPCs, currentPC) + case instanceOf: InstanceOf[_] => handleInstanceOf(instanceOf, instructionsWithPCs, currentPC) case _ => throw new UnsupportedOperationException("Unsupported expression type" + expr) } } + def handleInstanceOf(instanceOf: InstanceOf[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + val afterExprPC = ExprProcessor.processExpression(instanceOf.value, instructionsWithPCs, currentPC) + val instruction = INSTANCEOF(instanceOf.cmpTpe) + instructionsWithPCs += ((afterExprPC, instruction)) + afterExprPC + instruction.length + } + def handlePrefixExpr(prefixExpr: PrefixExpr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // Process the operand (the expression being negated) val operandPC = ExprProcessor.processExpression(prefixExpr.operand, instructionsWithPCs, currentPC) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala index 92c8c0e2d9..0dd26d3704 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala @@ -2,7 +2,7 @@ package org.opalj.tactobc import org.opalj.br.Method import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, Checkcast, Compare, DUVar, Expr, ExprStmt, GetField, If, InvokedynamicFunctionCall, NewArray, NonVirtualMethodCall, PrefixExpr, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, StaticMethodCall, Stmt, Switch, Throw, UVar, VirtualFunctionCall, VirtualMethodCall} +import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, Checkcast, Compare, DUVar, Expr, ExprStmt, GetField, If, InstanceOf, InvokedynamicFunctionCall, NewArray, NonVirtualMethodCall, PrefixExpr, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, StaticMethodCall, Stmt, Switch, Throw, UVar, VirtualFunctionCall, VirtualMethodCall} import org.opalj.tactobc.ExprProcessor.{nextLVIndex, uVarToLVIndex} import org.opalj.value.ValueInformation @@ -208,10 +208,15 @@ object FirstPass { case getField: GetField[_] => collectDUVarFromGetField(getField, duVars) case compare: Compare[_] => collectDUVarFromCompare(compare, duVars) case prefixExpr: PrefixExpr[_] => collectDUVarFromPrefixExpr(prefixExpr, duVars) + case instanceOf: InstanceOf[_] => collectDUVarFromInstanceOf(instanceOf, duVars) case _ => } } + def collectDUVarFromInstanceOf(instanceOf: InstanceOf[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectDUVarFromExpr(instanceOf.value, duVars) + } + def collectDUVarFromPrefixExpr(prefixExpr: PrefixExpr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { collectDUVarFromExpr(prefixExpr.operand, duVars) } From 8064da90b7b8879a53d7e610a78a165e752eb560 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 14 Aug 2024 18:40:23 +0200 Subject: [PATCH 074/111] added testcases for InstanceOf --- .../test/resources/javaFiles/InstanceOf.java | 25 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 ++- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/InstanceOf.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/InstanceOf.java b/OPAL/tactobc/src/test/resources/javaFiles/InstanceOf.java new file mode 100644 index 0000000000..f028c8af46 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/InstanceOf.java @@ -0,0 +1,25 @@ +public class InstanceOf { + + public static void main(String[] args) { + // Test with String + Object obj = "Hello, World!"; + System.out.println("obj is an instance of String: " + (obj instanceof String)); // true + System.out.println("obj is an instance of CharSequence: " + (obj instanceof CharSequence)); // true + System.out.println("obj is an instance of Object: " + (obj instanceof Object)); // true + System.out.println("obj is an instance of Integer: " + (obj instanceof Integer)); // false + + // Test with Integer + obj = 42; + System.out.println("obj is an instance of Integer: " + (obj instanceof Integer)); // true + System.out.println("obj is an instance of Number: " + (obj instanceof Number)); // true + System.out.println("obj is an instance of Object: " + (obj instanceof Object)); // true + System.out.println("obj is an instance of String: " + (obj instanceof String)); // false + + // Test with Array + obj = new int[]{1, 2, 3}; + System.out.println("obj is an instance of int[]: " + (obj instanceof int[])); // true + System.out.println("obj is an instance of Object: " + (obj instanceof Object)); // true + System.out.println("obj is an instance of String[]: " + (obj instanceof String[])); // false + System.out.println("obj is an instance of Integer[]: " + (obj instanceof Integer[])); // false + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 00e70ff038..ebfda1ddaf 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -24,7 +24,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("Compare.java", "Compare.class"), TestCase("Jsr.java", "Jsr.class"), TestCase("Constants.java", "Constants.class"), - TestCase("Negation.java", "Negation.class") + TestCase("Negation.java", "Negation.class"), + TestCase("InstanceOf.java", "InstanceOf.class") ) // Case class to represent each test case From 7bf3b5d935283f7cd37765514f7a0d6f5021eac1 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 14 Aug 2024 19:12:08 +0200 Subject: [PATCH 075/111] fixed handling of InvokeInterface --- .../src/main/scala/org/opalj/tactobc/ExprProcessor.scala | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index 3dcabdce0a..efd60d3803 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -211,7 +211,6 @@ object ExprProcessor { } val instruction = if (expr.isInterface) { INVOKEINTERFACE(expr.declaringClass, expr.name, expr.descriptor) - throw new UnsupportedOperationException("Unsupported expression type" + expr) } else { INVOKESTATIC(expr.declaringClass, expr.isInterface, expr.name, expr.descriptor) } @@ -232,8 +231,7 @@ object ExprProcessor { currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) } val instruction = if (expr.isInterface) { - //INVOKEINTERFACE(expr.declaringClass, expr.name, expr.descriptor) - throw new UnsupportedOperationException("Unsupported expression type" + expr) + INVOKEINTERFACE(expr.declaringClass.asObjectType, expr.name, expr.descriptor) } else { INVOKEVIRTUAL(expr.declaringClass, expr.name, expr.descriptor) } From 5a7a12cfe7c01b21273b5ea732e015eaa7610c72 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 14 Aug 2024 19:12:25 +0200 Subject: [PATCH 076/111] added testcase for InvokeInterface --- .../resources/javaFiles/InvokeInterface.java | 17 +++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/InvokeInterface.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/InvokeInterface.java b/OPAL/tactobc/src/test/resources/javaFiles/InvokeInterface.java new file mode 100644 index 0000000000..1545abb479 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/InvokeInterface.java @@ -0,0 +1,17 @@ +import java.util.List; +import java.util.ArrayList; +public class InvokeInterface { + + public static void main(String[] args) { + // Create an instance of ArrayList, which implements the List interface + List myList = new ArrayList<>(); + + // Add elements to the list (invokeinterface) + myList.add("Hello"); + myList.add("World"); + + // Get the size of the list (invokeinterface) + int size = myList.size(); + System.out.println("Size of the list: " + size); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index ebfda1ddaf..01953ff521 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -25,7 +25,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("Jsr.java", "Jsr.class"), TestCase("Constants.java", "Constants.class"), TestCase("Negation.java", "Negation.class"), - TestCase("InstanceOf.java", "InstanceOf.class") + TestCase("InstanceOf.java", "InstanceOf.class"), + TestCase("InvokeInterface.java", "InvokeInterface.class") ) // Case class to represent each test case From 7cd26aea20fd7d40d1b0a61969a7680addd8bc33 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 14 Aug 2024 19:21:21 +0200 Subject: [PATCH 077/111] cleanup --- .../main/scala/org/opalj/tactobc/StmtProcessor.scala | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index d4cfa63b17..3bd515962c 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -4,7 +4,7 @@ package org.opalj.tactobc import org.opalj.RelationalOperator import org.opalj.RelationalOperators._ import org.opalj.br.{ArrayType, BootstrapMethod, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FieldType, FloatType, IntegerType, LongType, MethodDescriptor, ObjectType, PCs, ReferenceType, ShortType} -import org.opalj.br.instructions.{AASTORE, ARETURN, ATHROW, BASTORE, CASTORE, CHECKCAST, DASTORE, DRETURN, FASTORE, FRETURN, GOTO, IASTORE, IFNONNULL, IFNULL, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, JSR, LASTORE, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, NOP, PUTFIELD, PUTSTATIC, RET, RETURN, SASTORE, TABLESWITCH} +import org.opalj.br.instructions.{AASTORE, ARETURN, ATHROW, BASTORE, CASTORE, CHECKCAST, DASTORE, DRETURN, FASTORE, FRETURN, GOTO, IASTORE, IFNONNULL, IFNULL, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, JSR, LASTORE, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, NOP, PUTFIELD, PUTSTATIC, RET, RETURN, SASTORE, TABLESWITCH} import org.opalj.collection.immutable.{IntIntPair, IntTrieSet} import org.opalj.tac.{Expr, UVar, Var} import org.opalj.tactobc.ExprProcessor.inferElementType @@ -109,12 +109,11 @@ object StmtProcessor { currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) } - val instruction = { /*if (isInterface) { - INVOKEINTERFACE - }else*/ - INVOKEVIRTUAL(declaringClass, methodName, methodDescriptor) + val instruction = { if (isInterface) { + INVOKEINTERFACE(declaringClass.asObjectType, methodName, methodDescriptor) + }else + INVOKEVIRTUAL(declaringClass, methodName, methodDescriptor) } - //val finalPC = currentPC + pcAfterLoadVariable instructionsWithPCs += ((currentAfterParamsPC, instruction)) currentAfterParamsPC + instruction.length } From 09a8551fdefd4d2497367230ef795a7d174b0f24 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 14 Aug 2024 19:39:44 +0200 Subject: [PATCH 078/111] fixed InvokeDynamic handling --- .../main/scala/org/opalj/tactobc/SecondPass.scala | 2 +- .../scala/org/opalj/tactobc/StmtProcessor.scala | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala index 6de20771d1..93675b7fbe 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala @@ -74,7 +74,7 @@ object SecondPass { currentPC = StmtProcessor.processStaticMethodCall(declaringClass, isInterface, name, descriptor, params, generatedByteCodeWithPC, currentPC) case InvokedynamicMethodCall(_, bootstrapMethod, name, descriptor, params) => tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processInvokeDynamicMethodCall(bootstrapMethod, name, descriptor, params) + currentPC = StmtProcessor.processInvokeDynamicMethodCall(bootstrapMethod, name, descriptor, params, generatedByteCodeWithPC, currentPC) case MonitorEnter(_, objRef) => tacTargetToByteCodePcs += ((-1, currentPC)) currentPC = StmtProcessor.processMonitorEnter(objRef, generatedByteCodeWithPC, currentPC) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index 3bd515962c..2015bce9a9 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -4,7 +4,7 @@ package org.opalj.tactobc import org.opalj.RelationalOperator import org.opalj.RelationalOperators._ import org.opalj.br.{ArrayType, BootstrapMethod, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FieldType, FloatType, IntegerType, LongType, MethodDescriptor, ObjectType, PCs, ReferenceType, ShortType} -import org.opalj.br.instructions.{AASTORE, ARETURN, ATHROW, BASTORE, CASTORE, CHECKCAST, DASTORE, DRETURN, FASTORE, FRETURN, GOTO, IASTORE, IFNONNULL, IFNULL, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, JSR, LASTORE, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, NOP, PUTFIELD, PUTSTATIC, RET, RETURN, SASTORE, TABLESWITCH} +import org.opalj.br.instructions.{AASTORE, ARETURN, ATHROW, BASTORE, CASTORE, CHECKCAST, DASTORE, DEFAULT_INVOKEDYNAMIC, DRETURN, FASTORE, FRETURN, GOTO, IASTORE, IFNONNULL, IFNULL, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, JSR, LASTORE, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, NOP, PUTFIELD, PUTSTATIC, RET, RETURN, SASTORE, TABLESWITCH} import org.opalj.collection.immutable.{IntIntPair, IntTrieSet} import org.opalj.tac.{Expr, UVar, Var} import org.opalj.tactobc.ExprProcessor.inferElementType @@ -165,9 +165,14 @@ object StmtProcessor { currentPC + instruction.length } - def processInvokeDynamicMethodCall(bootstrapMethod: BootstrapMethod, name: String, descriptor: MethodDescriptor, params: Seq[Expr[_]]): Int = { - //todo: handle this correctly - 1 + def processInvokeDynamicMethodCall(bootstrapMethod: BootstrapMethod, name: String, descriptor: MethodDescriptor, params: Seq[Expr[_]], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { + var currentAfterParamsPC = currentPC + for (param <- params) { + currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + } + val invokeDynamicInstruction = DEFAULT_INVOKEDYNAMIC(bootstrapMethod, name, descriptor) + instructionsWithPCs += ((currentAfterParamsPC, invokeDynamicInstruction)) + currentAfterParamsPC + invokeDynamicInstruction.length } def processCheckCast(value: Expr[_], cmpTpe: ReferenceType, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { @@ -230,6 +235,7 @@ object StmtProcessor { instructionsWithPCs += ((pcAfterObjRefLoad, instruction)) pcAfterObjRefLoad + instruction.length } + def processMonitorExit(objRef: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { // Load the object reference onto the stack val pcAfterObjRefLoad = ExprProcessor.processExpression(objRef, instructionsWithPCs, currentPC) From 94c329bf25363173bd4921403d424bc0334445a5 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 14 Aug 2024 19:40:07 +0200 Subject: [PATCH 079/111] added testcase for InvokeDynamic --- .../resources/javaFiles/InvokeDynamic.java | 23 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 ++- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/InvokeDynamic.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/InvokeDynamic.java b/OPAL/tactobc/src/test/resources/javaFiles/InvokeDynamic.java new file mode 100644 index 0000000000..bc90eab0f4 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/InvokeDynamic.java @@ -0,0 +1,23 @@ +public class InvokeDynamic { + + public static void main(String[] args) { + // Test 1: Lambda Expression + Runnable r = () -> System.out.println("Running in a lambda!"); + r.run(); + + // Test 2: String Concatenation with invokedynamic + String str1 = "Hello"; + String str2 = "World"; + String result = str1 + ", " + str2 + "!"; + System.out.println(result); + + // Test 3: Method Reference + InvokeDynamic test = new InvokeDynamic(); + Runnable r2 = test::methodReferenceExample; + r2.run(); + } + + public void methodReferenceExample() { + System.out.println("Method Reference Example"); + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 01953ff521..f37dafb6c0 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -26,7 +26,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("Constants.java", "Constants.class"), TestCase("Negation.java", "Negation.class"), TestCase("InstanceOf.java", "InstanceOf.class"), - TestCase("InvokeInterface.java", "InvokeInterface.class") + TestCase("InvokeInterface.java", "InvokeInterface.class"), + TestCase("InvokeDynamic.java", "InvokeDynamic.class") ) // Case class to represent each test case From 95b20234c7dd1959accf24dc8f1acef8ae2757b7 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 14 Aug 2024 19:56:41 +0200 Subject: [PATCH 080/111] cleanup negate was fixed allready --- .../tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index efd60d3803..5acfa7c6fc 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -431,7 +431,6 @@ object ExprProcessor { case (ComputationalTypeDouble, Multiply) => (DMUL, DMUL.length) case (ComputationalTypeDouble, Divide) => (DDIV, DDIV.length) case (ComputationalTypeDouble, Modulo) => (DREM, DREM.length) - //Todo figure out where and how to do with Negate //Float case (ComputationalTypeFloat, Add) => (FADD, FADD.length) case (ComputationalTypeFloat, Subtract) => (FSUB, FSUB.length) From 9b2b9923160ce17af191cddf254d182d9d679910 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Thu, 15 Aug 2024 12:40:20 +0200 Subject: [PATCH 081/111] fixed Switch targets To be relative to the current pc --- .../main/scala/org/opalj/tactobc/StmtProcessor.scala | 4 ++-- .../src/main/scala/org/opalj/tactobc/ThirdPass.scala | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index 2015bce9a9..11a7437698 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -35,7 +35,7 @@ object StmtProcessor { // Add LOOKUPSWITCH instruction with placeholders for targets val lookupswitchInstruction = LOOKUPSWITCH(defaultOffset, bCnpairs) instructionsWithPCs += ((afterExprPC, lookupswitchInstruction)) - afterExprPC + lookupSwitchLength(bCnpairs.size, afterExprPC) + afterExprPC + lookupSwitchLength(bCnpairs.size, afterExprPC) - 1 } else { // Add TABLESWITCH instruction with placeholders for targets val minValue = bCnpairs.minBy(_._1)._1 @@ -49,7 +49,7 @@ object StmtProcessor { val tableswitchInstruction = TABLESWITCH(defaultOffset, minValue, maxValue, jumpTable.to(ArraySeq)) instructionsWithPCs += ((afterExprPC, tableswitchInstruction)) - afterExprPC + tableSwitchLength(minValue, maxValue, afterExprPC) + afterExprPC + tableSwitchLength(minValue, maxValue, afterExprPC) - 1 } } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala index ac1b536d85..55b080278d 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala @@ -67,16 +67,16 @@ object ThirdPass { case LOOKUPSWITCH(defaultOffset, matchOffsets) => val updatedMatchOffsets = matchOffsets.map { case IntIntPair(caseValue, _) => val tacTarget = findTacTarget(switchCases, caseValue) - IntIntPair(caseValue, updateSwitchTargets(tacTargetToByteCodePcs, tacTarget)) + IntIntPair(caseValue, updateSwitchTargets(tacTargetToByteCodePcs, tacTarget, pc)) } - val updatedDefaultOffset = updateSwitchTargets(tacTargetToByteCodePcs, defaultOffset) + val updatedDefaultOffset = updateSwitchTargets(tacTargetToByteCodePcs, defaultOffset, pc) LOOKUPSWITCH(updatedDefaultOffset, updatedMatchOffsets) case TABLESWITCH(defaultOffset, low, high, jumpOffsets) => val updatedJumpOffsets = jumpOffsets.zipWithIndex.map { case (_, index) => val tacTarget = findTacTarget(switchCases, index) - updateSwitchTargets(tacTargetToByteCodePcs, tacTarget) + updateSwitchTargets(tacTargetToByteCodePcs, tacTarget, pc) } - val updatedDefaultOffset = updateSwitchTargets(tacTargetToByteCodePcs, defaultOffset) + val updatedDefaultOffset = updateSwitchTargets(tacTargetToByteCodePcs, defaultOffset, pc) TABLESWITCH(updatedDefaultOffset, low, high, updatedJumpOffsets.to(ArraySeq)) case _ => instruction @@ -104,8 +104,8 @@ object ThirdPass { byteCodeTarget } - def updateSwitchTargets(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTarget: Int): Int = { - val byteCodeTarget = tacTargetToByteCodePcs(tacTarget)._2 + def updateSwitchTargets(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTarget: Int, currentPC: Int): Int = { + val byteCodeTarget = tacTargetToByteCodePcs(tacTarget)._2 - currentPC byteCodeTarget } From e2ac1dda8f3b0bb2462d215c6ca50d3b687b50d9 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Thu, 15 Aug 2024 12:40:47 +0200 Subject: [PATCH 082/111] added Switch testcase --- .../src/test/resources/javaFiles/Switch.java | 26 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 ++- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/Switch.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/Switch.java b/OPAL/tactobc/src/test/resources/javaFiles/Switch.java new file mode 100644 index 0000000000..c60b8bc4a7 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/Switch.java @@ -0,0 +1,26 @@ +public class Switch { + + public static void main(String[] args) { + // Array of days to ensure all cases are covered + String[] fruits = {"Banana", "Brocoli", "Wednesday"}; + + // Loop through all possible days + for (String fruit : fruits) { + printFruit(fruit); + } + } + + public static void printFruit(String fruit) { + switch (fruit) { + case "Banana": + System.out.println(fruit + " is a fruit"); + break; + case "Brocoli": + System.out.println(fruit + " is a vegetable."); + break; + default: + System.out.println(fruit + " is not valid."); + break; + } + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index f37dafb6c0..1c5abb15e0 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -27,7 +27,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("Negation.java", "Negation.class"), TestCase("InstanceOf.java", "InstanceOf.class"), TestCase("InvokeInterface.java", "InvokeInterface.class"), - TestCase("InvokeDynamic.java", "InvokeDynamic.class") + TestCase("InvokeDynamic.java", "InvokeDynamic.class"), + TestCase("Switch.java", "Switch.class") ) // Case class to represent each test case From 7c22bd1199ae15534c74d8ed1d745122fd32a919 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Thu, 15 Aug 2024 12:40:47 +0200 Subject: [PATCH 083/111] added Switch testcase --- .../src/test/resources/javaFiles/Switch.java | 26 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 ++- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/Switch.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/Switch.java b/OPAL/tactobc/src/test/resources/javaFiles/Switch.java new file mode 100644 index 0000000000..5cd5f450a2 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/Switch.java @@ -0,0 +1,26 @@ +public class Switch { + + public static void main(String[] args) { + // Array of fruits to ensure all cases are covered + String[] fruits = {"Banana", "Brocoli", "Wednesday"}; + + // Loop through all possible fruits + for (String fruit : fruits) { + printFruit(fruit); + } + } + + public static void printFruit(String fruit) { + switch (fruit) { + case "Banana": + System.out.println(fruit + " is a fruit"); + break; + case "Brocoli": + System.out.println(fruit + " is a vegetable."); + break; + default: + System.out.println(fruit + " is not valid."); + break; + } + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index f37dafb6c0..1c5abb15e0 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -27,7 +27,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("Negation.java", "Negation.class"), TestCase("InstanceOf.java", "InstanceOf.class"), TestCase("InvokeInterface.java", "InvokeInterface.class"), - TestCase("InvokeDynamic.java", "InvokeDynamic.class") + TestCase("InvokeDynamic.java", "InvokeDynamic.class"), + TestCase("Switch.java", "Switch.class") ) // Case class to represent each test case From 111138904814505fcdca0b0b7f8e8c184b210525 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sat, 17 Aug 2024 15:15:53 +0200 Subject: [PATCH 084/111] added Reassignment testcases --- .../resources/javaFiles/Reassignment.java | 40 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 +- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/Reassignment.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/Reassignment.java b/OPAL/tactobc/src/test/resources/javaFiles/Reassignment.java new file mode 100644 index 0000000000..0c83f520a3 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/Reassignment.java @@ -0,0 +1,40 @@ +public class Reassignment { + + public static void main(String[] args) { + int x = 10; + int y = 5; + int z = 0; + + System.out.println("Initial values - x: " + x + ", y: " + y + ", z: " + z); + + // Conditional reassignment + if (x > y) { + x = x + y; + System.out.println("After conditional reassignment, x: " + x); + } + + // Loop with reassignment + for (int i = 0; i < 3; i++) { + z = z + (x * i) - y; + System.out.println("After loop iteration " + i + ", z: " + z); + } + + // Nested reassignments + if (z > 10) { + x = x * 2; + y = y + z; + z = x - y; + System.out.println("After nested reassignment, x: " + x + ", y: " + y + ", z: " + z); + } + + // Reassign using previous values + z = (x * y) + z; + System.out.println("Final value of z after using previous values: " + z); + + // Complex reassignments with multiple operations + x = x + (y - z) * 2; + y = y * 3 + z - x; + z = x - y + z; + System.out.println("Complex final values - x: " + x + ", y: " + y + ", z: " + z); + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 1c5abb15e0..78bf17528d 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -28,7 +28,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("InstanceOf.java", "InstanceOf.class"), TestCase("InvokeInterface.java", "InvokeInterface.class"), TestCase("InvokeDynamic.java", "InvokeDynamic.class"), - TestCase("Switch.java", "Switch.class") + TestCase("Switch.java", "Switch.class"), + TestCase("Reassignment.java", "Reassignment.class") ) // Case class to represent each test case From facf3955a24309ee8dbdb1d3d21c0df2032626c6 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sat, 17 Aug 2024 17:53:15 +0200 Subject: [PATCH 085/111] added IfZero testcases --- .../src/test/resources/javaFiles/IfZero.java | 59 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 +- 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/IfZero.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/IfZero.java b/OPAL/tactobc/src/test/resources/javaFiles/IfZero.java new file mode 100644 index 0000000000..324bc7c0e9 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/IfZero.java @@ -0,0 +1,59 @@ +public class IfZero { + + public static void main(String[] args) { + IfZero test = new IfZero(); + + // Test with a positive number, zero, and a negative number + int[] testValues = {10, 0, -5}; + + for (int value : testValues) { + System.out.println("Testing with k = " + value); + test.compareWithZero(value); + System.out.println(); + } + } + + public void compareWithZero(int k) { + // Equal to zero + if (k == 0) { + System.out.println("k is equal to zero."); + } else { + System.out.println("k is not equal to zero."); + } + + // Not equal to zero + if (k != 0) { + System.out.println("k is not equal to zero."); + } else { + System.out.println("k is equal to zero."); + } + + // Less than zero + if (k < 0) { + System.out.println("k is less than zero."); + } else { + System.out.println("k is not less than zero."); + } + + // Greater than zero + if (k > 0) { + System.out.println("k is greater than zero."); + } else { + System.out.println("k is not greater than zero."); + } + + // Less than or equal to zero + if (k <= 0) { + System.out.println("k is less than or equal to zero."); + } else { + System.out.println("k is greater than zero."); + } + + // Greater than or equal to zero + if (k >= 0) { + System.out.println("k is greater than or equal to zero."); + } else { + System.out.println("k is less than zero."); + } + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 78bf17528d..10b3bd0e94 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -29,7 +29,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("InvokeInterface.java", "InvokeInterface.class"), TestCase("InvokeDynamic.java", "InvokeDynamic.class"), TestCase("Switch.java", "Switch.class"), - TestCase("Reassignment.java", "Reassignment.class") + TestCase("Reassignment.java", "Reassignment.class"), + TestCase("IfZero.java", "IfZero.class") ) // Case class to represent each test case From 81bc5582a2a329618568e0777c207c99b7382065 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sat, 17 Aug 2024 19:10:18 +0200 Subject: [PATCH 086/111] added BigNumbers testcases --- .../test/resources/javaFiles/BigNumbers.java | 48 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 +- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/BigNumbers.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/BigNumbers.java b/OPAL/tactobc/src/test/resources/javaFiles/BigNumbers.java new file mode 100644 index 0000000000..58cea3e3ad --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/BigNumbers.java @@ -0,0 +1,48 @@ +public class BigNumbers { + + public static void main(String[] args) { + // Testing with Integer.MAX_VALUE and Integer.MIN_VALUE + int maxValue = Integer.MAX_VALUE; + int minValue = Integer.MIN_VALUE; + int largeValue = 1_000_000_000; + int largeNegativeValue = -1_000_000_000; + + // Arithmetic operations + int sum = maxValue + largeValue; // May cause overflow + int diff = minValue - largeValue; // May cause underflow + int product = maxValue * 2; // Likely overflow + int quotient = maxValue / 2; // Safe operation + int remainder = maxValue % largeValue; // Safe operation + + // Comparisons + boolean isMaxGreaterThanMin = maxValue > minValue; + boolean isLargeValueGreaterThanMax = largeValue > maxValue; + boolean isMinLessThanLargeNegativeValue = minValue < largeNegativeValue; + boolean isEqual = maxValue == Integer.MAX_VALUE; + + // Print results + System.out.println("Sum (maxValue + largeValue): " + sum); + System.out.println("Difference (minValue - largeValue): " + diff); + System.out.println("Product (maxValue * 2): " + product); + System.out.println("Quotient (maxValue / 2): " + quotient); + System.out.println("Remainder (maxValue % largeValue): " + remainder); + + System.out.println("Is maxValue > minValue? " + isMaxGreaterThanMin); + System.out.println("Is largeValue > maxValue? " + isLargeValueGreaterThanMax); + System.out.println("Is minValue < largeNegativeValue? " + isMinLessThanLargeNegativeValue); + System.out.println("Is maxValue equal to Integer.MAX_VALUE? " + isEqual); + + // Assignment to test how big numbers are stored and retrieved + int assignTest = Integer.MAX_VALUE; + System.out.println("Assigned maxValue: " + assignTest); + + assignTest = Integer.MIN_VALUE; + System.out.println("Assigned minValue: " + assignTest); + + assignTest = largeValue; + System.out.println("Assigned largeValue: " + assignTest); + + assignTest = largeNegativeValue; + System.out.println("Assigned largeNegativeValue: " + assignTest); + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 10b3bd0e94..9167688b23 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -30,7 +30,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("InvokeDynamic.java", "InvokeDynamic.class"), TestCase("Switch.java", "Switch.class"), TestCase("Reassignment.java", "Reassignment.class"), - TestCase("IfZero.java", "IfZero.class") + TestCase("IfZero.java", "IfZero.class"), + TestCase("BigNumbers.java", "BigNumbers.class") ) // Case class to represent each test case From 6dbba64560acc6e58702beeedb799992eb320665 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sat, 17 Aug 2024 19:13:04 +0200 Subject: [PATCH 087/111] added more BigNumbers testcases --- .../test/resources/javaFiles/BigNumbers.java | 168 +++++++++++++----- 1 file changed, 126 insertions(+), 42 deletions(-) diff --git a/OPAL/tactobc/src/test/resources/javaFiles/BigNumbers.java b/OPAL/tactobc/src/test/resources/javaFiles/BigNumbers.java index 58cea3e3ad..138244897c 100644 --- a/OPAL/tactobc/src/test/resources/javaFiles/BigNumbers.java +++ b/OPAL/tactobc/src/test/resources/javaFiles/BigNumbers.java @@ -2,47 +2,131 @@ public class BigNumbers { public static void main(String[] args) { // Testing with Integer.MAX_VALUE and Integer.MIN_VALUE - int maxValue = Integer.MAX_VALUE; - int minValue = Integer.MIN_VALUE; - int largeValue = 1_000_000_000; - int largeNegativeValue = -1_000_000_000; - - // Arithmetic operations - int sum = maxValue + largeValue; // May cause overflow - int diff = minValue - largeValue; // May cause underflow - int product = maxValue * 2; // Likely overflow - int quotient = maxValue / 2; // Safe operation - int remainder = maxValue % largeValue; // Safe operation - - // Comparisons - boolean isMaxGreaterThanMin = maxValue > minValue; - boolean isLargeValueGreaterThanMax = largeValue > maxValue; - boolean isMinLessThanLargeNegativeValue = minValue < largeNegativeValue; - boolean isEqual = maxValue == Integer.MAX_VALUE; - - // Print results - System.out.println("Sum (maxValue + largeValue): " + sum); - System.out.println("Difference (minValue - largeValue): " + diff); - System.out.println("Product (maxValue * 2): " + product); - System.out.println("Quotient (maxValue / 2): " + quotient); - System.out.println("Remainder (maxValue % largeValue): " + remainder); - - System.out.println("Is maxValue > minValue? " + isMaxGreaterThanMin); - System.out.println("Is largeValue > maxValue? " + isLargeValueGreaterThanMax); - System.out.println("Is minValue < largeNegativeValue? " + isMinLessThanLargeNegativeValue); - System.out.println("Is maxValue equal to Integer.MAX_VALUE? " + isEqual); - - // Assignment to test how big numbers are stored and retrieved - int assignTest = Integer.MAX_VALUE; - System.out.println("Assigned maxValue: " + assignTest); - - assignTest = Integer.MIN_VALUE; - System.out.println("Assigned minValue: " + assignTest); - - assignTest = largeValue; - System.out.println("Assigned largeValue: " + assignTest); - - assignTest = largeNegativeValue; - System.out.println("Assigned largeNegativeValue: " + assignTest); + int maxValueInt = Integer.MAX_VALUE; + int minValueInt = Integer.MIN_VALUE; + int largeValueInt = 1_000_000_000; + int largeNegativeValueInt = -1_000_000_000; + + // Testing with Long.MAX_VALUE and Long.MIN_VALUE + long maxValueLong = Long.MAX_VALUE; + long minValueLong = Long.MIN_VALUE; + long largeValueLong = 1_000_000_000_000L; + long largeNegativeValueLong = -1_000_000_000_000L; + + // Testing with Double.MAX_VALUE and Double.MIN_VALUE + double maxValueDouble = Double.MAX_VALUE; + double minValueDouble = Double.MIN_VALUE; + double largeValueDouble = 1e100; + double largeNegativeValueDouble = -1e100; + + // Testing with Float.MAX_VALUE and Float.MIN_VALUE + float maxValueFloat = Float.MAX_VALUE; + float minValueFloat = Float.MIN_VALUE; + float largeValueFloat = 1e30f; + float largeNegativeValueFloat = -1e30f; + + // Arithmetic operations for int + int sumInt = maxValueInt + largeValueInt; // May cause overflow + int diffInt = minValueInt - largeValueInt; // May cause underflow + int productInt = maxValueInt * 2; // Likely overflow + int quotientInt = maxValueInt / 2; // Safe operation + int remainderInt = maxValueInt % largeValueInt; // Safe operation + + // Arithmetic operations for long + long sumLong = maxValueLong + largeValueLong; // May cause overflow + long diffLong = minValueLong - largeValueLong; // May cause underflow + long productLong = maxValueLong * 2; // Likely overflow + long quotientLong = maxValueLong / 2; // Safe operation + long remainderLong = maxValueLong % largeValueLong; // Safe operation + + // Arithmetic operations for double + double sumDouble = maxValueDouble + largeValueDouble; // Large sum + double diffDouble = minValueDouble - largeValueDouble; // Small difference + double productDouble = maxValueDouble * 2; // Large product + double quotientDouble = maxValueDouble / 2; // Safe operation + double remainderDouble = maxValueDouble % largeValueDouble; // Remainder + + // Arithmetic operations for float + float sumFloat = maxValueFloat + largeValueFloat; // Large sum + float diffFloat = minValueFloat - largeValueFloat; // Small difference + float productFloat = maxValueFloat * 2; // Large product + float quotientFloat = maxValueFloat / 2; // Safe operation + float remainderFloat = maxValueFloat % largeValueFloat; // Remainder + + // Print results for int + System.out.println("Int Sum (maxValue + largeValue): " + sumInt); + System.out.println("Int Difference (minValue - largeValue): " + diffInt); + System.out.println("Int Product (maxValue * 2): " + productInt); + System.out.println("Int Quotient (maxValue / 2): " + quotientInt); + System.out.println("Int Remainder (maxValue % largeValue): " + remainderInt); + + // Print results for long + System.out.println("Long Sum (maxValue + largeValue): " + sumLong); + System.out.println("Long Difference (minValue - largeValue): " + diffLong); + System.out.println("Long Product (maxValue * 2): " + productLong); + System.out.println("Long Quotient (maxValue / 2): " + quotientLong); + System.out.println("Long Remainder (maxValue % largeValue): " + remainderLong); + + // Print results for double + System.out.println("Double Sum (maxValue + largeValue): " + sumDouble); + System.out.println("Double Difference (minValue - largeValue): " + diffDouble); + System.out.println("Double Product (maxValue * 2): " + productDouble); + System.out.println("Double Quotient (maxValue / 2): " + quotientDouble); + System.out.println("Double Remainder (maxValue % largeValue): " + remainderDouble); + + // Print results for float + System.out.println("Float Sum (maxValue + largeValue): " + sumFloat); + System.out.println("Float Difference (minValue - largeValue): " + diffFloat); + System.out.println("Float Product (maxValue * 2): " + productFloat); + System.out.println("Float Quotient (maxValue / 2): " + quotientFloat); + System.out.println("Float Remainder (maxValue % largeValue): " + remainderFloat); + + // Comparisons for int + boolean isMaxGreaterThanMinInt = maxValueInt > minValueInt; + boolean isLargeValueGreaterThanMaxInt = largeValueInt > maxValueInt; + boolean isMinLessThanLargeNegativeValueInt = minValueInt < largeNegativeValueInt; + boolean isEqualInt = maxValueInt == Integer.MAX_VALUE; + + // Print comparison results for int + System.out.println("Is maxValue > minValue? (int) " + isMaxGreaterThanMinInt); + System.out.println("Is largeValue > maxValue? (int) " + isLargeValueGreaterThanMaxInt); + System.out.println("Is minValue < largeNegativeValue? (int) " + isMinLessThanLargeNegativeValueInt); + System.out.println("Is maxValue equal to Integer.MAX_VALUE? (int) " + isEqualInt); + + // Comparisons for long + boolean isMaxGreaterThanMinLong = maxValueLong > minValueLong; + boolean isLargeValueGreaterThanMaxLong = largeValueLong > maxValueLong; + boolean isMinLessThanLargeNegativeValueLong = minValueLong < largeNegativeValueLong; + boolean isEqualLong = maxValueLong == Long.MAX_VALUE; + + // Print comparison results for long + System.out.println("Is maxValue > minValue? (long) " + isMaxGreaterThanMinLong); + System.out.println("Is largeValue > maxValue? (long) " + isLargeValueGreaterThanMaxLong); + System.out.println("Is minValue < largeNegativeValue? (long) " + isMinLessThanLargeNegativeValueLong); + System.out.println("Is maxValue equal to Long.MAX_VALUE? (long) " + isEqualLong); + + // Comparisons for double + boolean isMaxGreaterThanMinDouble = maxValueDouble > minValueDouble; + boolean isLargeValueGreaterThanMaxDouble = largeValueDouble > maxValueDouble; + boolean isMinLessThanLargeNegativeValueDouble = minValueDouble < largeNegativeValueDouble; + boolean isEqualDouble = maxValueDouble == Double.MAX_VALUE; + + // Print comparison results for double + System.out.println("Is maxValue > minValue? (double) " + isMaxGreaterThanMinDouble); + System.out.println("Is largeValue > maxValue? (double) " + isLargeValueGreaterThanMaxDouble); + System.out.println("Is minValue < largeNegativeValue? (double) " + isMinLessThanLargeNegativeValueDouble); + System.out.println("Is maxValue equal to Double.MAX_VALUE? (double) " + isEqualDouble); + + // Comparisons for float + boolean isMaxGreaterThanMinFloat = maxValueFloat > minValueFloat; + boolean isLargeValueGreaterThanMaxFloat = largeValueFloat > maxValueFloat; + boolean isMinLessThanLargeNegativeValueFloat = minValueFloat < largeNegativeValueFloat; + boolean isEqualFloat = maxValueFloat == Float.MAX_VALUE; + + // Print comparison results for float + System.out.println("Is maxValue > minValue? (float) " + isMaxGreaterThanMinFloat); + System.out.println("Is largeValue > maxValue? (float) " + isLargeValueGreaterThanMaxFloat); + System.out.println("Is minValue < largeNegativeValue? (float) " + isMinLessThanLargeNegativeValueFloat); + System.out.println("Is maxValue equal to Float.MAX_VALUE? (float) " + isEqualFloat); } } From 5a97d29b127c5190eab013be92afdabcaef3ee60 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sat, 17 Aug 2024 19:50:55 +0200 Subject: [PATCH 088/111] added ObjectPropertyAccess testcases --- .../javaFiles/ObjectPropertyAccess.java | 53 +++++++++++++++++++ .../tactobc/SingleClassFileTestCaseEnum.scala | 3 +- 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/ObjectPropertyAccess.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/ObjectPropertyAccess.java b/OPAL/tactobc/src/test/resources/javaFiles/ObjectPropertyAccess.java new file mode 100644 index 0000000000..8e46818e0d --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/ObjectPropertyAccess.java @@ -0,0 +1,53 @@ +public class ObjectPropertyAccess { + + // Object attributes + private int[] m = {10, 20, 30, 40, 50}; // Example array + private int i; // Index i + private int j; // Index j + private int k; // Result of subtraction + + public static void main(String[] args) { + ObjectPropertyAccess test = new ObjectPropertyAccess(); + test.runTests(); + } + + public void runTests() { + // Test case 1: Normal subtraction + this.i = 4; // Refers to m[4] = 50 + this.j = 3; // Refers to m[3] = 40 + this.k = this.m[this.i] - this.m[this.j]; + System.out.println("Test 1 (m[4] - m[3]): k = " + this.k); // Expected: 10 + + // Test case 2: Subtraction leading to zero + this.i = 2; // Refers to m[2] = 30 + this.j = 2; // Refers to m[2] = 30 + this.k = this.m[this.i] - this.m[this.j]; + System.out.println("Test 2 (m[2] - m[2]): k = " + this.k); // Expected: 0 + + // Test case 3: Subtraction leading to a negative result + this.i = 1; // Refers to m[1] = 20 + this.j = 4; // Refers to m[4] = 50 + this.k = this.m[this.i] - this.m[this.j]; + System.out.println("Test 3 (m[1] - m[4]): k = " + this.k); // Expected: -30 + + // Test case 4: Subtraction at boundary values (first element) + this.i = 0; // Refers to m[0] = 10 + this.j = 4; // Refers to m[4] = 50 + this.k = this.m[this.i] - this.m[this.j]; + System.out.println("Test 4 (m[0] - m[4]): k = " + this.k); // Expected: -40 + + // Test case 5: Subtraction at boundary values (last element) + this.i = 4; // Refers to m[4] = 50 + this.j = 0; // Refers to m[0] = 10 + this.k = this.m[this.i] - this.m[this.j]; + System.out.println("Test 5 (m[4] - m[0]): k = " + this.k); // Expected: 40 + + // Test case 6: Subtraction leading to potential overflow/underflow + this.m = new int[]{Integer.MAX_VALUE, Integer.MIN_VALUE}; + this.i = 0; // Refers to Integer.MAX_VALUE + this.j = 1; // Refers to Integer.MIN_VALUE + this.k = this.m[this.i] - this.m[this.j]; + System.out.println("Test 6 (Integer.MAX_VALUE - Integer.MIN_VALUE): k = " + this.k); + // Expected: Large positive value, may demonstrate overflow behavior + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala index 9167688b23..077551cd5c 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/SingleClassFileTestCaseEnum.scala @@ -31,7 +31,8 @@ object SingleClassFileTestCaseEnum extends Enumeration { TestCase("Switch.java", "Switch.class"), TestCase("Reassignment.java", "Reassignment.class"), TestCase("IfZero.java", "IfZero.class"), - TestCase("BigNumbers.java", "BigNumbers.class") + TestCase("BigNumbers.java", "BigNumbers.class"), + TestCase("ObjectPropertyAccess.java", "ObjectPropertyAccess.class") ) // Case class to represent each test case From bf1fcd82c7fc8edcc3af926c093403638a374a9e Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Fri, 23 Aug 2024 02:13:33 +0200 Subject: [PATCH 089/111] added mutable java files testcases (WIP) --- .../ArithmeticOperations.java | 15 +++ .../ArithmeticOperations_mutation_1.java | 17 +++ .../ArithmeticOperations_mutation_2.java | 17 +++ .../ArithmeticOperations_mutation_3.java | 19 +++ .../ArithmeticOperations_mutation_4.java | 15 +++ .../ArithmeticOperations_mutation_5.java | 15 +++ .../javaFilesMutation/array/Array.java | 16 +++ .../array/Array_mutation_1.java | 19 +++ .../array/Array_mutation_2.java | 19 +++ .../array/Array_mutation_3.java | 18 +++ .../array/Array_mutation_4.java | 17 +++ .../array/Array_mutation_5.java | 17 +++ .../assignment/Assignment.java | 28 +++++ .../assignment/Assignment_mutation_1.java | 29 +++++ .../assignment/Assignment_mutation_2.java | 29 +++++ .../assignment/Assignment_mutation_3.java | 28 +++++ .../assignment/Assignment_mutation_4.java | 28 +++++ .../assignment/Assignment_mutation_5.java | 30 +++++ .../bigNumbers/BigNumbers.java | 44 +++++++ .../bigNumbers/BigNumbers_mutation_1.java | 46 ++++++++ .../bigNumbers/BigNumbers_mutation_2.java | 46 ++++++++ .../bigNumbers/BigNumbers_mutation_3.java | 45 +++++++ .../bigNumbers/BigNumbers_mutation_4.java | 45 +++++++ .../bigNumbers/BigNumbers_mutation_5.java | 43 +++++++ .../checkCast/CheckCast.java | 20 ++++ .../checkCast/CheckCast_mutation_1.java | 21 ++++ .../checkCast/CheckCast_mutation_2.java | 18 +++ .../checkCast/CheckCast_mutation_3.java | 23 ++++ .../checkCast/CheckCast_mutation_4.java | 21 ++++ .../checkCast/CheckCast_mutation_5.java | 18 +++ .../javaFilesMutation/compare/Compare.java | 26 ++++ .../compare/Compare_mutation_1.java | 29 +++++ .../compare/Compare_mutation_2.java | 28 +++++ .../compare/Compare_mutation_3.java | 29 +++++ .../compare/Compare_mutation_4.java | 28 +++++ .../compare/Compare_mutation_5.java | 27 +++++ .../constants/Constants.java | 42 +++++++ .../constants/Constants_mutation_1.java | 44 +++++++ .../constants/Constants_mutation_2.java | 46 ++++++++ .../constants/Constants_mutation_3.java | 47 ++++++++ .../constants/Constants_mutation_4.java | 44 +++++++ .../constants/Constants_mutation_5.java | 48 ++++++++ .../javaFilesMutation/forLoop/ForLoop.java | 26 ++++ .../forLoop/ForLoop_mutation_1.java | 28 +++++ .../forLoop/ForLoop_mutation_2.java | 28 +++++ .../forLoop/ForLoop_mutation_3.java | 28 +++++ .../forLoop/ForLoop_mutation_4.java | 28 +++++ .../forLoop/ForLoop_mutation_5.java | 28 +++++ .../resources/javaFilesMutation/if/If.java | 61 ++++++++++ .../javaFilesMutation/if/If_mutation_1.java | 62 ++++++++++ .../javaFilesMutation/if/If_mutation_2.java | 63 ++++++++++ .../javaFilesMutation/if/If_mutation_3.java | 63 ++++++++++ .../javaFilesMutation/if/If_mutation_4.java | 61 ++++++++++ .../javaFilesMutation/if/If_mutation_5.java | 61 ++++++++++ .../javaFilesMutation/ifZero/IfZero.java | 21 ++++ .../ifZero/IfZero_mutation_1.java | 25 ++++ .../ifZero/IfZero_mutation_2.java | 23 ++++ .../ifZero/IfZero_mutation_3.java | 21 ++++ .../ifZero/IfZero_mutation_4.java | 21 ++++ .../ifZero/IfZero_mutation_5.java | 23 ++++ .../instanceField/InstanceField.java | 10 ++ .../InstanceField_mutation_1.java | 11 ++ .../InstanceField_mutation_2.java | 13 ++ .../InstanceField_mutation_3.java | 14 +++ .../InstanceField_mutation_4.java | 14 +++ .../InstanceField_mutation_5.java | 10 ++ .../instanceOf/InstanceOf.java | 11 ++ .../instanceOf/InstanceOf_mutation_1.java | 12 ++ .../instanceOf/InstanceOf_mutation_2.java | 16 +++ .../instanceOf/InstanceOf_mutation_3.java | 13 ++ .../instanceOf/InstanceOf_mutation_4.java | 13 ++ .../instanceOf/InstanceOf_mutation_5.java | 12 ++ .../invokeDynamic/InvokeDynamic.java | 18 +++ .../InvokeDynamic_mutation_1.java | 21 ++++ .../InvokeDynamic_mutation_2.java | 27 +++++ .../InvokeDynamic_mutation_3.java | 27 +++++ .../invokeInterface/InvokeInterface.java | 17 +++ .../resources/javaFilesMutation/jsr/Jsr.java | 18 +++ .../methodCall/MethodCall.java | 62 ++++++++++ .../javaFilesMutation/negation/Negation.java | 35 ++++++ .../ObjectPropertyAccess.java | 53 +++++++++ .../parameters/Parameters.java | 55 +++++++++ .../primitiveTypeCast/PrimitiveTypeCast.java | 46 ++++++++ .../reassignment/Reassignment.java | 41 +++++++ .../staticField/StaticField.java | 23 ++++ .../javaFilesMutation/switch/Switch.java | 26 ++++ .../whileLoop/WhileLoop.java | 64 ++++++++++ .../tactobc/MutatedClassFileTACtoBCTest.scala | 111 ++++++++++++++++++ .../MutatedClassFileTestCaseEnum.scala | 78 ++++++++++++ 89 files changed, 2746 insertions(+) create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/if/If.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop.java create mode 100644 OPAL/tactobc/src/test/scala/org/opalj/tactobc/MutatedClassFileTACtoBCTest.scala create mode 100644 OPAL/tactobc/src/test/scala/org/opalj/tactobc/MutatedClassFileTestCaseEnum.scala diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations.java new file mode 100644 index 0000000000..7860610e68 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations.java @@ -0,0 +1,15 @@ +public class ArithmeticOperations { + public static void main(String[] args) { + int a = 10; + int b = 5; + int sum = a + b; + int difference = a - b; + int product = a * b; + int quotient = a / b; + + System.out.println("Sum: " + sum); + System.out.println("Difference: " + difference); + System.out.println("Product: " + product); + System.out.println("Quotient: " + quotient); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_1.java new file mode 100644 index 0000000000..63d09ed11b --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_1.java @@ -0,0 +1,17 @@ +public class ArithmeticOperations_mutation_1 { + public static void main(String[] args) { + int[] arrA = {10}; + int[] arrB = {5}; + int a = arrA[0]; + int b = arrB[0]; + int sum = a + b; + int difference = a - b; + int product = a * b; + int quotient = a / b; + + System.out.println("Sum: " + sum); + System.out.println("Difference: " + difference); + System.out.println("Product: " + product); + System.out.println("Quotient: " + quotient); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_2.java new file mode 100644 index 0000000000..0f73124d25 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_2.java @@ -0,0 +1,17 @@ +public class ArithmeticOperations_mutation_2 { + public static void main(String[] args) { + int[] aArr = {10}; + int[] bArr = {5}; + int a = aArr[0]; + int b = bArr[0]; + int sum = a + b; + int difference = a - b; + int product = a * b; + int quotient = a / b; + + System.out.println("Sum: " + sum); + System.out.println("Difference: " + difference); + System.out.println("Product: " + product); + System.out.println("Quotient: " + quotient); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_3.java new file mode 100644 index 0000000000..f09cda479e --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_3.java @@ -0,0 +1,19 @@ +public class ArithmeticOperations_mutation_3 { + public static void main(String[] args) { + int a = 10; + int b = 5; + int sum = a + b; + int difference = a - b; + int product = a * b; + int quotient = calculateQuotient(a, b); + + System.out.println("Sum: " + sum); + System.out.println("Difference: " + difference); + System.out.println("Product: " + product); + System.out.println("Quotient: " + quotient); + } + + private static int calculateQuotient(int a, int b) { + return a / b; + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_4.java new file mode 100644 index 0000000000..9cb7e5bd3f --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_4.java @@ -0,0 +1,15 @@ +public class ArithmeticOperations_mutation_4 { + public static void main(String[] args) { + int a = 10; + int b = 5; + int product = a * b; + int sum = a + b; + int difference = a - b; + int quotient = a / b; + + System.out.println("Sum: " + sum); + System.out.println("Difference: " + difference); + System.out.println("Product: " + product); + System.out.println("Quotient: " + quotient); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_5.java new file mode 100644 index 0000000000..9c2bfaea53 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/arithmeticOperations/ArithmeticOperations_mutation_5.java @@ -0,0 +1,15 @@ +public class ArithmeticOperations_mutation_5 { + public static void main(String[] args) { + int[] a = {10}; + int[] b = {5}; + int sum = a[0] + b[0]; + int difference = a[0] - b[0]; + int product = a[0] * b[0]; + int quotient = a[0] / b[0]; + + System.out.println("Sum: " + sum); + System.out.println("Difference: " + difference); + System.out.println("Product: " + product); + System.out.println("Quotient: " + quotient); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array.java new file mode 100644 index 0000000000..42f929aed8 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array.java @@ -0,0 +1,16 @@ +public class Array { + + public static void main(String[] args) { + // Single-Dimensional Array + int[] array = {10, 20, 30}; + + // Print original values + System.out.println(array[0]); + System.out.println(array[1]); + System.out.println(array[2]); + + // Modify and print the second element + array[1] = 100; + System.out.println(array[1]); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_1.java new file mode 100644 index 0000000000..47bfbd7cde --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_1.java @@ -0,0 +1,19 @@ +public class Array_mutation_1 { + + // Declare a static field + private static final int INITIAL_VALUE = 20; + + public static void main(String[] args) { + // Single-Dimensional Array + int[] array = {10, INITIAL_VALUE, 30}; + + // Print original values + System.out.println(array[0]); + System.out.println(array[1]); + System.out.println(array[2]); + + // Modify and print the second element + array[1] = 100; + System.out.println(array[1]); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_2.java new file mode 100644 index 0000000000..18e466f932 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_2.java @@ -0,0 +1,19 @@ +public class Array_mutation_2 { + + public static void main(String[] args) { + // Single-Dimensional Array + int[] array = {10, 20, 30}; + + // Print original values + System.out.println(array[0]); + System.out.println(array[1]); + System.out.println(array[2]); + + // Store the result of a calculation in a temporary variable + int modifiedValue = array[1]; + + // Modify and print the second element + modifiedValue = 100; + System.out.println(modifiedValue); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_3.java new file mode 100644 index 0000000000..ebb6313d16 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_3.java @@ -0,0 +1,18 @@ +public class Array_mutation_3 { + + public static int myStaticField = 0; + + public static void main(String[] args) { + // Single-Dimensional Array + int[] array = {10, 20, 30}; + + // Print original values + System.out.println(array[0]); + System.out.println(array[1]); + System.out.println(array[2]); + + // Modify and print the second element + array[1] = myStaticField + 100; + System.out.println(array[1]); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_4.java new file mode 100644 index 0000000000..b8b6a8c8aa --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_4.java @@ -0,0 +1,17 @@ +public class Array_mutation_4 { + + public static void main(String[] args) { + // Single-Dimensional Array + int[] array = {10, 20, 30}; + + // Print original values + System.out.println(array[0]); + System.out.println(array[1]); + System.out.println(array[2]); + + // Modify and print the second element + int[] temp = {100}; + array[1] = temp[0]; + System.out.println(array[1]); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_5.java new file mode 100644 index 0000000000..08437eea46 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/array/Array_mutation_5.java @@ -0,0 +1,17 @@ +public class Array_mutation_5 { + + public static void main(String[] args) { + // Single-Dimensional Array + int[] array = {10, 20, 30}; + + // Print original values + System.out.println(array[0]); + System.out.println(array[1]); + System.out.println(array[2]); + + if (true) { + array[1] = 100; + } + System.out.println(array[1]); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment.java new file mode 100644 index 0000000000..46d023dc67 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment.java @@ -0,0 +1,28 @@ +public class Assignment { + + public static void main(String[] args) { + // Test integer assignment + int a = 10; + int b = 20; + int sum = a + b; + System.out.println("Sum of integers: " + sum); + + // Test string assignment + String firstName = "John"; + String lastName = "Doe"; + String fullName = firstName + " " + lastName; + System.out.println("Full name: " + fullName); + + // Test boolean assignment + boolean isTrue = true; + boolean isFalse = false; + boolean andResult = isTrue && isFalse; + System.out.println("Boolean AND result: " + andResult); + + // Test array assignment + int[] numbers = {1, 2, 3}; + int firstNumber = numbers[0]; + numbers[0] = firstNumber + 10; + System.out.println("First number in array after update: " + numbers[0]); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_1.java new file mode 100644 index 0000000000..1d85f3af08 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_1.java @@ -0,0 +1,29 @@ +public class Assignment_mutation_1 { + + public static void main(String[] args) { + // Test integer assignment + int a = 10; + int b = 20; + int sum = a + b; + int sumTemp = sum; // Store the result in a temporary variable + System.out.println("Sum of integers: " + sumTemp); + + // Test string assignment + String firstName = "John"; + String lastName = "Doe"; + String fullName = firstName + " " + lastName; + System.out.println("Full name: " + fullName); + + // Test boolean assignment + boolean isTrue = true; + boolean isFalse = false; + boolean andResult = isTrue && isFalse; + System.out.println("Boolean AND result: " + andResult); + + // Test array assignment + int[] numbers = {1, 2, 3}; + int firstNumber = numbers[0]; + numbers[0] = firstNumber + 10; + System.out.println("First number in array after update: " + numbers[0]); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_2.java new file mode 100644 index 0000000000..29265a843d --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_2.java @@ -0,0 +1,29 @@ +public class Assignment_mutation_2 { + + public static void main(String[] args) { + // Test integer assignment + int[] aArray = {10}; + int a = aArray[0]; + int b = 20; + int sum = a + b; + System.out.println("Sum of integers: " + sum); + + // Test string assignment + String firstName = "John"; + String lastName = "Doe"; + String fullName = firstName + " " + lastName; + System.out.println("Full name: " + fullName); + + // Test boolean assignment + boolean isTrue = true; + boolean isFalse = false; + boolean andResult = isTrue && isFalse; + System.out.println("Boolean AND result: " + andResult); + + // Test array assignment + int[] numbers = {1, 2, 3}; + int firstNumber = numbers[0]; + numbers[0] = firstNumber + 10; + System.out.println("First number in array after update: " + numbers[0]); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_3.java new file mode 100644 index 0000000000..6ce0e67834 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_3.java @@ -0,0 +1,28 @@ +public class Assignment_mutation_3 { + + public static void main(String[] args) { + // Test integer assignment + int[] a = {10}; + int b = 20; + int sum = a[0] + b; + System.out.println("Sum of integers: " + sum); + + // Test string assignment + String firstName = "John"; + String lastName = "Doe"; + String fullName = firstName + " " + lastName; + System.out.println("Full name: " + fullName); + + // Test boolean assignment + boolean isTrue = true; + boolean isFalse = false; + boolean andResult = isTrue && isFalse; + System.out.println("Boolean AND result: " + andResult); + + // Test array assignment + int[] numbers = {1, 2, 3}; + int firstNumber = numbers[0]; + numbers[0] = firstNumber + 10; + System.out.println("First number in array after update: " + numbers[0]); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_4.java new file mode 100644 index 0000000000..e34d87f8fe --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_4.java @@ -0,0 +1,28 @@ +public class Assignment_mutation_4 { + + public static void main(String[] args) { + // Test integer assignment + int[] a = {10}; + int b = 20; + int sum = a[0] + b; + System.out.println("Sum of integers: " + sum); + + // Test string assignment + String firstName = "John"; + String lastName = "Doe"; + String fullName = firstName + " " + lastName; + System.out.println("Full name: " + fullName); + + // Test boolean assignment + boolean isTrue = true; + boolean isFalse = false; + boolean andResult = isTrue && isFalse; + System.out.println("Boolean AND result: " + andResult); + + // Test array assignment + int[] numbers = {1, 2, 3}; + int firstNumber = numbers[0]; + numbers[0] = firstNumber + 10; + System.out.println("First number in array after update: " + numbers[0]); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_5.java new file mode 100644 index 0000000000..0eb1d710c7 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/assignment/Assignment_mutation_5.java @@ -0,0 +1,30 @@ +public class Assignment_mutation_5 { + + public static void main(String[] args) { + // Test integer assignment + int a = 10; + int b = 20; + int sum = a + b; + int result = sum; // Temp variable to store the result + System.out.println("Sum of integers: " + result); + + // Test string assignment + String firstName = "John"; + String lastName = "Doe"; + String fullName = firstName + " " + lastName; + System.out.println("Full name: " + fullName); + + // Test boolean assignment + boolean isTrue = true; + boolean isFalse = false; + boolean andResult = isTrue && isFalse; + System.out.println("Boolean AND result: " + andResult); + + // Test array assignment + int[] numbers = {1, 2, 3}; + int firstNumber = numbers[0]; + int updatedNumber = firstNumber + 10; + numbers[0] = updatedNumber; + System.out.println("First number in array after update: " + numbers[0]); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers.java new file mode 100644 index 0000000000..37a2430b81 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers.java @@ -0,0 +1,44 @@ +public class BigNumbers { + + public static void main(String[] args) { + // Test with int + int maxValueInt = Integer.MAX_VALUE; + int largeValueInt = 1_000_000_000; + + int sumInt = maxValueInt + largeValueInt; // Overflow possible + System.out.println("Int Sum (maxValue + largeValue): " + sumInt); + + boolean isMaxGreaterThanMinInt = maxValueInt > largeValueInt; + System.out.println("Is maxValue > largeValue? (int) " + isMaxGreaterThanMinInt); + + // Test with long + long maxValueLong = Long.MAX_VALUE; + long largeValueLong = 1_000_000_000_000L; + + long sumLong = maxValueLong + largeValueLong; // Overflow possible + System.out.println("Long Sum (maxValue + largeValue): " + sumLong); + + boolean isMaxGreaterThanLargeValueLong = maxValueLong > largeValueLong; + System.out.println("Is maxValue > largeValue? (long) " + isMaxGreaterThanLargeValueLong); + + // Test with double + double maxValueDouble = Double.MAX_VALUE; + double largeValueDouble = 1e100; + + double sumDouble = maxValueDouble + largeValueDouble; + System.out.println("Double Sum (maxValue + largeValue): " + sumDouble); + + boolean isMaxGreaterThanLargeValueDouble = maxValueDouble > largeValueDouble; + System.out.println("Is maxValue > largeValue? (double) " + isMaxGreaterThanLargeValueDouble); + + // Test with float + float maxValueFloat = Float.MAX_VALUE; + float largeValueFloat = 1e30f; + + float sumFloat = maxValueFloat + largeValueFloat; + System.out.println("Float Sum (maxValue + largeValue): " + sumFloat); + + boolean isMaxGreaterThanLargeValueFloat = maxValueFloat > largeValueFloat; + System.out.println("Is maxValue > largeValue? (float) " + isMaxGreaterThanLargeValueFloat); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_1.java new file mode 100644 index 0000000000..9066226bb0 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_1.java @@ -0,0 +1,46 @@ +public class BigNumbers_mutation_1 { + + public static void main(String[] args) { + // Test with int + int maxValueInt = Integer.MAX_VALUE; + int largeValueInt = 1_000_000_000; + + int sumInt = maxValueInt + largeValueInt; // Overflow possible + System.out.println("Int Sum (maxValue + largeValue): " + sumInt); + + if (true) { + boolean isMaxGreaterThanMinInt = maxValueInt > largeValueInt; + System.out.println("Is maxValue > largeValue? (int) " + isMaxGreaterThanMinInt); + } + + // Test with long + long maxValueLong = Long.MAX_VALUE; + long largeValueLong = 1_000_000_000_000L; + + long sumLong = maxValueLong + largeValueLong; // Overflow possible + System.out.println("Long Sum (maxValue + largeValue): " + sumLong); + + boolean isMaxGreaterThanLargeValueLong = maxValueLong > largeValueLong; + System.out.println("Is maxValue > largeValue? (long) " + isMaxGreaterThanLargeValueLong); + + // Test with double + double maxValueDouble = Double.MAX_VALUE; + double largeValueDouble = 1e100; + + double sumDouble = maxValueDouble + largeValueDouble; + System.out.println("Double Sum (maxValue + largeValue): " + sumDouble); + + boolean isMaxGreaterThanLargeValueDouble = maxValueDouble > largeValueDouble; + System.out.println("Is maxValue > largeValue? (double) " + isMaxGreaterThanLargeValueDouble); + + // Test with float + float maxValueFloat = Float.MAX_VALUE; + float largeValueFloat = 1e30f; + + float sumFloat = maxValueFloat + largeValueFloat; + System.out.println("Float Sum (maxValue + largeValue): " + sumFloat); + + boolean isMaxGreaterThanLargeValueFloat = maxValueFloat > largeValueFloat; + System.out.println("Is maxValue > largeValue? (float) " + isMaxGreaterThanLargeValueFloat); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_2.java new file mode 100644 index 0000000000..45c24e7266 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_2.java @@ -0,0 +1,46 @@ +public class BigNumbers_mutation_2 { + + public static void main(String[] args) { + // Test with int + int maxValueInt = Integer.MAX_VALUE; + int largeValueInt = 1_000_000_000; + + int sumInt = maxValueInt + largeValueInt; // Overflow possible + System.out.println("Int Sum (maxValue + largeValue): " + sumInt); + + boolean isMaxGreaterThanMinInt = maxValueInt > largeValueInt; + System.out.println("Is maxValue > largeValue? (int) " + isMaxGreaterThanMinInt); + + // Test with long + long maxValueLong = Long.MAX_VALUE; + long largeValueLong = 1_000_000_000_000L; + + long sumLong = maxValueLong + largeValueLong; // Overflow possible + System.out.println("Long Sum (maxValue + largeValue): " + sumLong); + + boolean isMaxGreaterThanLargeValueLong = maxValueLong > largeValueLong; + System.out.println("Is maxValue > largeValue? (long) " + isMaxGreaterThanLargeValueLong); + + // Test with double + double maxValueDouble = Double.MAX_VALUE; + double largeValueDouble = 1e100; + + double sumDouble = maxValueDouble + largeValueDouble; + System.out.println("Double Sum (maxValue + largeValue): " + sumDouble); + + boolean isMaxGreaterThanLargeValueDouble = maxValueDouble > largeValueDouble; + System.out.println("Is maxValue > largeValue? (double) " + isMaxGreaterThanLargeValueDouble); + + // Test with float + float maxValueFloat = Float.MAX_VALUE; + float largeValueFloat = 1e30f; + + if (true) { + float sumFloat = maxValueFloat + largeValueFloat; + System.out.println("Float Sum (maxValue + largeValue): " + sumFloat); + } + + boolean isMaxGreaterThanLargeValueFloat = maxValueFloat > largeValueFloat; + System.out.println("Is maxValue > largeValue? (float) " + isMaxGreaterThanLargeValueFloat); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_3.java new file mode 100644 index 0000000000..a6633b219c --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_3.java @@ -0,0 +1,45 @@ +public class BigNumbers_mutation_3 { + + public static void main(String[] args) { + // Test with int + int maxValueInt = Integer.MAX_VALUE; + int largeValueInt = 1_000_000_000; + + int sumIntTemp = maxValueInt + largeValueInt; // Overflow possible + int sumInt = sumIntTemp; // Store the result in a temporary variable + System.out.println("Int Sum (maxValue + largeValue): " + sumInt); + + boolean isMaxGreaterThanMinInt = maxValueInt > largeValueInt; + System.out.println("Is maxValue > largeValue? (int) " + isMaxGreaterThanMinInt); + + // Test with long + long maxValueLong = Long.MAX_VALUE; + long largeValueLong = 1_000_000_000_000L; + + long sumLong = maxValueLong + largeValueLong; // Overflow possible + System.out.println("Long Sum (maxValue + largeValue): " + sumLong); + + boolean isMaxGreaterThanLargeValueLong = maxValueLong > largeValueLong; + System.out.println("Is maxValue > largeValue? (long) " + isMaxGreaterThanLargeValueLong); + + // Test with double + double maxValueDouble = Double.MAX_VALUE; + double largeValueDouble = 1e100; + + double sumDouble = maxValueDouble + largeValueDouble; + System.out.println("Double Sum (maxValue + largeValue): " + sumDouble); + + boolean isMaxGreaterThanLargeValueDouble = maxValueDouble > largeValueDouble; + System.out.println("Is maxValue > largeValue? (double) " + isMaxGreaterThanLargeValueDouble); + + // Test with float + float maxValueFloat = Float.MAX_VALUE; + float largeValueFloat = 1e30f; + + float sumFloat = maxValueFloat + largeValueFloat; + System.out.println("Float Sum (maxValue + largeValue): " + sumFloat); + + boolean isMaxGreaterThanLargeValueFloat = maxValueFloat > largeValueFloat; + System.out.println("Is maxValue > largeValue? (float) " + isMaxGreaterThanLargeValueFloat); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_4.java new file mode 100644 index 0000000000..ed1edf8dd2 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_4.java @@ -0,0 +1,45 @@ +public class BigNumbers_mutation_4 { + + public static void main(String[] args) { + // Test with int + int maxValueInt = Integer.MAX_VALUE; + int largeValueInt = 1_000_000_000; + + int sumIntTemp = maxValueInt + largeValueInt; // Store the result in a temp variable + int sumInt = sumIntTemp; // Use the temp variable + System.out.println("Int Sum (maxValue + largeValue): " + sumInt); + + boolean isMaxGreaterThanMinInt = maxValueInt > largeValueInt; + System.out.println("Is maxValue > largeValue? (int) " + isMaxGreaterThanMinInt); + + // Test with long + long maxValueLong = Long.MAX_VALUE; + long largeValueLong = 1_000_000_000_000L; + + long sumLong = maxValueLong + largeValueLong; // Overflow possible + System.out.println("Long Sum (maxValue + largeValue): " + sumLong); + + boolean isMaxGreaterThanLargeValueLong = maxValueLong > largeValueLong; + System.out.println("Is maxValue > largeValue? (long) " + isMaxGreaterThanLargeValueLong); + + // Test with double + double maxValueDouble = Double.MAX_VALUE; + double largeValueDouble = 1e100; + + double sumDouble = maxValueDouble + largeValueDouble; + System.out.println("Double Sum (maxValue + largeValue): " + sumDouble); + + boolean isMaxGreaterThanLargeValueDouble = maxValueDouble > largeValueDouble; + System.out.println("Is maxValue > largeValue? (double) " + isMaxGreaterThanLargeValueDouble); + + // Test with float + float maxValueFloat = Float.MAX_VALUE; + float largeValueFloat = 1e30f; + + float sumFloat = maxValueFloat + largeValueFloat; + System.out.println("Float Sum (maxValue + largeValue): " + sumFloat); + + boolean isMaxGreaterThanLargeValueFloat = maxValueFloat > largeValueFloat; + System.out.println("Is maxValue > largeValue? (float) " + isMaxGreaterThanLargeValueFloat); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_5.java new file mode 100644 index 0000000000..a6909eabbd --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/bigNumbers/BigNumbers_mutation_5.java @@ -0,0 +1,43 @@ +public class BigNumbers_mutation_5 { + + public static class MyNumbers { + public static int maxValueInt = Integer.MAX_VALUE; + public static long maxValueLong = Long.MAX_VALUE; + public static double maxValueDouble = Double.MAX_VALUE; + public static float maxValueFloat = Float.MAX_VALUE; + } + + public static void main(String[] args) { + // Test with int + int largeValueInt = 1_000_000_000; + int sumInt = MyNumbers.maxValueInt + largeValueInt; // Overflow possible + System.out.println("Int Sum (maxValue + largeValue): " + sumInt); + + boolean isMaxGreaterThanMinInt = MyNumbers.maxValueInt > largeValueInt; + System.out.println("Is maxValue > largeValue? (int) " + isMaxGreaterThanMinInt); + + // Test with long + long largeValueLong = 1_000_000_000_000L; + long sumLong = MyNumbers.maxValueLong + largeValueLong; // Overflow possible + System.out.println("Long Sum (maxValue + largeValue): " + sumLong); + + boolean isMaxGreaterThanLargeValueLong = MyNumbers.maxValueLong > largeValueLong; + System.out.println("Is maxValue > largeValue? (long) " + isMaxGreaterThanLargeValueLong); + + // Test with double + double largeValueDouble = 1e100; + double sumDouble = MyNumbers.maxValueDouble + largeValueDouble; + System.out.println("Double Sum (maxValue + largeValue): " + sumDouble); + + boolean isMaxGreaterThanLargeValueDouble = MyNumbers.maxValueDouble > largeValueDouble; + System.out.println("Is maxValue > largeValue? (double) " + isMaxGreaterThanLargeValueDouble); + + // Test with float + float largeValueFloat = 1e30f; + float sumFloat = MyNumbers.maxValueFloat + largeValueFloat; + System.out.println("Float Sum (maxValue + largeValue): " + sumFloat); + + boolean isMaxGreaterThanLargeValueFloat = MyNumbers.maxValueFloat > largeValueFloat; + System.out.println("Is maxValue > largeValue? (float) " + isMaxGreaterThanLargeValueFloat); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast.java new file mode 100644 index 0000000000..28dcb33c2d --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast.java @@ -0,0 +1,20 @@ +public class CheckCast { + + public static void main(String[] args) { + // Test case 1: Valid cast + Object obj = "This is a string"; + String str = (String) obj; // Valid CHECKCAST + System.out.println("Successfully casted to String: " + str); + + + // Test case 2: Null reference casting + Object nullObj = null; + String nullCast = (String) nullObj; // Valid CHECKCAST, null can be cast to any reference type + System.out.println("Successfully casted null reference to String"); + + // Test case 3: Casting within the same type + Object anotherString = "Another string"; + String sameTypeCast = (String) anotherString; // Valid CHECKCAST + System.out.println("Successfully casted to String: " + sameTypeCast); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_1.java new file mode 100644 index 0000000000..9d4767a4c0 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_1.java @@ -0,0 +1,21 @@ +public class CheckCast_mutation_1 { + + public static void main(String[] args) { + // Test case 1: Valid cast + Object obj = "This is a string"; + if (true) { + String str = (String) obj; // Valid CHECKCAST + } + System.out.println("Successfully casted to String: " + obj); + + // Test case 2: Null reference casting + Object nullObj = null; + String nullCast = (String) nullObj; // Valid CHECKCAST, null can be cast to any reference type + System.out.println("Successfully casted null reference to String"); + + // Test case 3: Casting within the same type + Object anotherString = "Another string"; + String sameTypeCast = (String) anotherString; // Valid CHECKCAST + System.out.println("Successfully casted to String: " + sameTypeCast); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_2.java new file mode 100644 index 0000000000..99eff35e2b --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_2.java @@ -0,0 +1,18 @@ +public class CheckCast_mutation_2 { + + public static void main(String[] args) { + // Test case 1: Valid cast + Object obj = "This is a string"; + System.out.println("Successfully casted to String: " + (String) obj); + + // Test case 2: Null reference casting + Object nullObj = null; + String nullCast = (String) nullObj; // Valid CHECKCAST, null can be cast to any reference type + System.out.println("Successfully casted null reference to String"); + + // Test case 3: Casting within the same type + Object anotherString = "Another string"; + String sameTypeCast = (String) anotherString; // Valid CHECKCAST + System.out.println("Successfully casted to String: " + sameTypeCast); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_3.java new file mode 100644 index 0000000000..1da57ada68 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_3.java @@ -0,0 +1,23 @@ +public class CheckCast_mutation_3 { + + public static void main(String[] args) { + // Test case 1: Valid cast + Object obj = "This is a string"; + String str = castToType(obj, String.class); // Valid CHECKCAST + System.out.println("Successfully casted to String: " + str); + + // Test case 2: Null reference casting + Object nullObj = null; + String nullCast = (String) nullObj; // Valid CHECKCAST, null can be cast to any reference type + System.out.println("Successfully casted null reference to String"); + + // Test case 3: Casting within the same type + Object anotherString = "Another string"; + String sameTypeCast = (String) anotherString; // Valid CHECKCAST + System.out.println("Successfully casted to String: " + sameTypeCast); + } + + public static T castToType(Object obj, Class clazz) { + return clazz.cast(obj); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_4.java new file mode 100644 index 0000000000..8e0e4f4f3d --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_4.java @@ -0,0 +1,21 @@ +public class CheckCast_mutation_4 { + + public static void main(String[] args) { + // Test case 1: Valid cast + Object obj = "This is a string"; + if (true) { + String str = (String) obj; // Valid CHECKCAST + } + System.out.println("Successfully casted to String: " + obj); + + // Test case 2: Null reference casting + Object nullObj = null; + String nullCast = (String) nullObj; // Valid CHECKCAST, null can be cast to any reference type + System.out.println("Successfully casted null reference to String"); + + // Test case 3: Casting within the same type + Object anotherString = "Another string"; + String sameTypeCast = (String) anotherString; // Valid CHECKCAST + System.out.println("Successfully casted to String: " + sameTypeCast); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_5.java new file mode 100644 index 0000000000..57dd89aab0 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/checkCast/CheckCast_mutation_5.java @@ -0,0 +1,18 @@ +public class CheckCast_mutation_5 { + + public static void main(String[] args) { + // Test case 1: Valid cast + Object obj = "This is a string"; + System.out.println("Successfully casted to String: " + (String) obj); + + // Test case 2: Null reference casting + Object nullObj = null; + String nullCast = (String) nullObj; // Valid CHECKCAST, null can be cast to any reference type + System.out.println("Successfully casted null reference to String"); + + // Test case 3: Casting within the same type + Object anotherString = "Another string"; + String sameTypeCast = (String) anotherString; // Valid CHECKCAST + System.out.println("Successfully casted to String: " + sameTypeCast); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare.java new file mode 100644 index 0000000000..07833ed45a --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare.java @@ -0,0 +1,26 @@ +public class Compare { + + public static void main(String[] args) { + // Float comparison + float f1 = 10.5f; + float f2 = 20.5f; + int floatComparisonResult = Float.compare(f1, f2); + System.out.println("Float comparison result: " + floatComparisonResult); + + // Double comparison + double d1 = 100.123; + double d2 = 100.456; + int doubleComparisonResult = Double.compare(d1, d2); + System.out.println("Double comparison result: " + doubleComparisonResult); + + // Long comparison + long l1 = 123456789L; + long l2 = 987654321L; + int longComparisonResult = Long.compare(l1, l2); + System.out.println("Long comparison result: " + longComparisonResult); + + // Combining results + int combinedResult = floatComparisonResult + doubleComparisonResult + longComparisonResult; + System.out.println("Combined result: " + combinedResult); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_1.java new file mode 100644 index 0000000000..c3782f2a39 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_1.java @@ -0,0 +1,29 @@ +public class Compare_mutation_1 { + + public static void main(String[] args) { + // Float comparison + float f1 = 10.5f; + float f2 = 20.5f; + int floatComparisonResult = Float.compare(f1, f2); + int floatComparisonResultTemp = floatComparisonResult; // Temporary variable + System.out.println("Float comparison result: " + floatComparisonResult); + + // Double comparison + double d1 = 100.123; + double d2 = 100.456; + int doubleComparisonResult = Double.compare(d1, d2); + int doubleComparisonResultTemp = doubleComparisonResult; // Temporary variable + System.out.println("Double comparison result: " + doubleComparisonResult); + + // Long comparison + long l1 = 123456789L; + long l2 = 987654321L; + int longComparisonResult = Long.compare(l1, l2); + int longComparisonResultTemp = longComparisonResult; // Temporary variable + System.out.println("Long comparison result: " + longComparisonResult); + + // Combining results + int combinedResult = floatComparisonResultTemp + doubleComparisonResultTemp + longComparisonResultTemp; + System.out.println("Combined result: " + combinedResult); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_2.java new file mode 100644 index 0000000000..59b6e1cbaf --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_2.java @@ -0,0 +1,28 @@ +public class Compare_mutation_2 { + + public static void main(String[] args) { + // Float comparison + float f1 = 10.5f; + float f2 = 20.5f; + int floatComparisonResult = Float.compare(f1, f2); + System.out.println("Float comparison result: " + floatComparisonResult); + + // Double comparison + double d1 = 100.123; + double d2 = 100.456; + int doubleComparisonResult = Double.compare(d1, d2); + System.out.println("Double comparison result: " + doubleComparisonResult); + + // Long comparison + long l1 = 123456789L; + long l2 = 987654321L; + int longComparisonResult = Long.compare(l1, l2); + System.out.println("Long comparison result: " + longComparisonResult); + + // Combining results + if (true) { + int combinedResult = floatComparisonResult + doubleComparisonResult + longComparisonResult; + System.out.println("Combined result: " + combinedResult); + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_3.java new file mode 100644 index 0000000000..28896b2337 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_3.java @@ -0,0 +1,29 @@ +public class Compare_mutation_3 { + + public static void main(String[] args) { + // Float comparison + float f1 = 10.5f; + float f2 = 20.5f; + int floatComparisonResult = Float.compare(f1, f2); + int floatResult = floatComparisonResult; // Store the result in a temporary variable + System.out.println("Float comparison result: " + floatResult); + + // Double comparison + double d1 = 100.123; + double d2 = 100.456; + int doubleComparisonResult = Double.compare(d1, d2); + int doubleResult = doubleComparisonResult; // Store the result in a temporary variable + System.out.println("Double comparison result: " + doubleResult); + + // Long comparison + long l1 = 123456789L; + long l2 = 987654321L; + int longComparisonResult = Long.compare(l1, l2); + int longResult = longComparisonResult; // Store the result in a temporary variable + System.out.println("Long comparison result: " + longResult); + + // Combining results + int combinedResult = floatResult + doubleResult + longResult; + System.out.println("Combined result: " + combinedResult); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_4.java new file mode 100644 index 0000000000..dbd9f37135 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_4.java @@ -0,0 +1,28 @@ +public class Compare_mutation_4 { + + public static void main(String[] args) { + // Float comparison + float f1 = 10.5f; + float f2 = 20.5f; + int floatComparisonResult = Float.compare(f1, f2); + System.out.println("Float comparison result: " + floatComparisonResult); + + // Double comparison + double d1 = 100.123; + double d2 = 100.456; + int doubleComparisonResult = Double.compare(d1, d2); + System.out.println("Double comparison result: " + doubleComparisonResult); + + // Long comparison + long l1 = 123456789L; + long l2 = 987654321L; + int longComparisonResult = Long.compare(l1, l2); + System.out.println("Long comparison result: " + longComparisonResult); + + // Combining results + if (true) { + int combinedResult = floatComparisonResult + doubleComparisonResult + longComparisonResult; + System.out.println("Combined result: " + combinedResult); + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_5.java new file mode 100644 index 0000000000..ab4decae70 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/compare/Compare_mutation_5.java @@ -0,0 +1,27 @@ +public class Compare_mutation_5 { + + public static void main(String[] args) { + // Float comparison + float[] fArray = {10.5f}; + float f1 = fArray[0]; + float f2 = 20.5f; + int floatComparisonResult = Float.compare(f1, f2); + System.out.println("Float comparison result: " + floatComparisonResult); + + // Double comparison + double d1 = 100.123; + double d2 = 100.456; + int doubleComparisonResult = Double.compare(d1, d2); + System.out.println("Double comparison result: " + doubleComparisonResult); + + // Long comparison + long l1 = 123456789L; + long l2 = 987654321L; + int longComparisonResult = Long.compare(l1, l2); + System.out.println("Long comparison result: " + longComparisonResult); + + // Combining results + int combinedResult = floatComparisonResult + doubleComparisonResult + longComparisonResult; + System.out.println("Combined result: " + combinedResult); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants.java new file mode 100644 index 0000000000..35723ec0ad --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants.java @@ -0,0 +1,42 @@ +public class Constants { + + public static void main(String[] args) { + // Integer constants + int intMin1 = -1; + int int0 = 0; + int int1 = 1; + int int127 = 127; // BIPUSH + int intBig = 100000; // LDC + + System.out.println("Integer Constants:"); + System.out.println(intMin1 + ", " + int0 + ", " + int1 + ", " + int127 + ", " + intBig); + + // Float constants + float float0 = 0.0f; + float float1 = 1.0f; + + System.out.println("Float Constants:"); + System.out.println(float0 + ", " + float1); + + // Double constants + double double0 = 0.0; + double double1 = 1.0; + + System.out.println("Double Constants:"); + System.out.println(double0 + ", " + double1); + + // Long constants + long long0 = 0L; + long long1 = 1L; + + System.out.println("Long Constants:"); + System.out.println(long0 + ", " + long1); + + // String constants + String stringConst = "Hello!"; + String stringEmpty = ""; + + System.out.println("String Constants:"); + System.out.println(stringConst + ", " + stringEmpty); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_1.java new file mode 100644 index 0000000000..24058e521b --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_1.java @@ -0,0 +1,44 @@ +public class Constants_mutation_1 { + + public static void main(String[] args) { + // Integer constants + int intMin1 = -1; + int int0 = 0; + int int1 = 1; + int int127 = 127; // BIPUSH + int intBig = 100000; // LDC + + System.out.println("Integer Constants:"); + System.out.println(intMin1 + ", " + int0 + ", " + int1 + ", " + int127 + ", " + intBig); + + // Float constants + float float0 = 0.0f; + float float1 = 1.0f; + + System.out.println("Float Constants:"); + System.out.println(float0 + ", " + float1); + + // Double constants + double double0 = 0.0; + double double1 = 1.0; + + System.out.println("Double Constants:"); + System.out.println(double0 + ", " + double1); + + // Long constants + long long0 = 0L; + long long1 = 1L; + + System.out.println("Long Constants:"); + if (true) { + System.out.println(long0 + ", " + long1); + } + + // String constants + String stringConst = "Hello!"; + String stringEmpty = ""; + + System.out.println("String Constants:"); + System.out.println(stringConst + ", " + stringEmpty); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_2.java new file mode 100644 index 0000000000..87e521f38c --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_2.java @@ -0,0 +1,46 @@ +public class Constants_mutation_2 { + + public static void main(String[] args) { + // Integer constants + int intMin1 = -1; + int int0 = 0; + int int1 = 1; + int int127 = 127; // BIPUSH + int intBig = 100000; // LDC + + System.out.println("Integer Constants:"); + printIntConstants(intMin1, int0, int1, int127, intBig); + + // Float constants + float float0 = 0.0f; + float float1 = 1.0f; + + System.out.println("Float Constants:"); + System.out.println(float0 + ", " + float1); + + // Double constants + double double0 = 0.0; + double double1 = 1.0; + + System.out.println("Double Constants:"); + System.out.println(double0 + ", " + double1); + + // Long constants + long long0 = 0L; + long long1 = 1L; + + System.out.println("Long Constants:"); + System.out.println(long0 + ", " + long1); + + // String constants + String stringConst = "Hello!"; + String stringEmpty = ""; + + System.out.println("String Constants:"); + System.out.println(stringConst + ", " + stringEmpty); + } + + public static void printIntConstants(int intMin1, int int0, int int1, int int127, int intBig) { + System.out.println(intMin1 + ", " + int0 + ", " + int1 + ", " + int127 + ", " + intBig); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_3.java new file mode 100644 index 0000000000..ccc76371e5 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_3.java @@ -0,0 +1,47 @@ +public class Constants_mutation_3 { + + public static void main(String[] args) { + // Integer constants + int[] intArray = new int[]{-1, 0, 1, 127, 100000}; + int intMin1 = intArray[0]; + int int0 = intArray[1]; + int int1 = intArray[2]; + int int127 = intArray[3]; // BIPUSH + int intBig = intArray[4]; // LDC + + System.out.println("Integer Constants:"); + System.out.println(intMin1 + ", " + int0 + ", " + int1 + ", " + int127 + ", " + intBig); + + // Float constants + float[] floatArray = new float[]{0.0f, 1.0f}; + float float0 = floatArray[0]; + float float1 = floatArray[1]; + + System.out.println("Float Constants:"); + System.out.println(float0 + ", " + float1); + + // Double constants + double[] doubleArray = new double[]{0.0, 1.0}; + double double0 = doubleArray[0]; + double double1 = doubleArray[1]; + + System.out.println("Double Constants:"); + System.out.println(double0 + ", " + double1); + + // Long constants + long[] longArray = new long[]{0L, 1L}; + long long0 = longArray[0]; + long long1 = longArray[1]; + + System.out.println("Long Constants:"); + System.out.println(long0 + ", " + long1); + + // String constants + String[] stringArray = new String[]{"Hello!", ""}; + String stringConst = stringArray[0]; + String stringEmpty = stringArray[1]; + + System.out.println("String Constants:"); + System.out.println(stringConst + ", " + stringEmpty); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_4.java new file mode 100644 index 0000000000..18f78df83f --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_4.java @@ -0,0 +1,44 @@ +public class Constants_mutation_4 { + + public static void main(String[] args) { + // Integer constants + int intMin1 = -1; + int int0 = 0; + int int1 = 1; + int int127 = 127; // BIPUSH + int intBig = 100000; // LDC + + System.out.println("Integer Constants:"); + if (true) { + System.out.println(intMin1 + ", " + int0 + ", " + int1 + ", " + int127 + ", " + intBig); + } + + // Float constants + float float0 = 0.0f; + float float1 = 1.0f; + + System.out.println("Float Constants:"); + System.out.println(float0 + ", " + float1); + + // Double constants + double double0 = 0.0; + double double1 = 1.0; + + System.out.println("Double Constants:"); + System.out.println(double0 + ", " + double1); + + // Long constants + long long0 = 0L; + long long1 = 1L; + + System.out.println("Long Constants:"); + System.out.println(long0 + ", " + long1); + + // String constants + String stringConst = "Hello!"; + String stringEmpty = ""; + + System.out.println("String Constants:"); + System.out.println(stringConst + ", " + stringEmpty); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_5.java new file mode 100644 index 0000000000..69a8b9a68e --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/constants/Constants_mutation_5.java @@ -0,0 +1,48 @@ +public class Constants_mutation_5 { + + public static void main(String[] args) { + // Integer constants + int intMin1 = -1; + int int0 = 0; + int int1 = 1; + int int127 = 127; // BIPUSH + myclass obj = new myclass(); + obj.intBig = 100000; + int intBig = obj.intBig; // LDC + + System.out.println("Integer Constants:"); + System.out.println(intMin1 + ", " + int0 + ", " + int1 + ", " + int127 + ", " + intBig); + + // Float constants + float float0 = 0.0f; + float float1 = 1.0f; + + System.out.println("Float Constants:"); + System.out.println(float0 + ", " + float1); + + // Double constants + double double0 = 0.0; + double double1 = 1.0; + + System.out.println("Double Constants:"); + System.out.println(double0 + ", " + double1); + + // Long constants + long long0 = 0L; + long long1 = 1L; + + System.out.println("Long Constants:"); + System.out.println(long0 + ", " + long1); + + // String constants + String stringConst = "Hello!"; + String stringEmpty = ""; + + System.out.println("String Constants:"); + System.out.println(stringConst + ", " + stringEmpty); + } +} + +class myclass { + public int intBig = 0; +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop.java new file mode 100644 index 0000000000..565c5e6b8b --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop.java @@ -0,0 +1,26 @@ +public class ForLoop { + + public static void main(String[] args) { + // Simple for loop with int + int sum = 0; + for (int i = 0; i < 5; i++) { + sum += i; + } + System.out.println("Sum of first 5 numbers: " + sum); + + // For loop with an array of integers + int[] numbers = {1, 2, 3}; + int arraySum = 0; + for (int i = 0; i < numbers.length; i++) { + arraySum += numbers[i]; + } + System.out.println("Sum of array elements: " + arraySum); + + // For loop with a double type + double product = 1.0; + for (int i = 1; i <= 3; i++) { + product *= i * 1.5; + } + System.out.println("Product of first 3 numbers multiplied by 1.5: " + product); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_1.java new file mode 100644 index 0000000000..2e0edf69ce --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_1.java @@ -0,0 +1,28 @@ +public class ForLoop_mutation_1 { + + public static void main(String[] args) { + // Simple for loop with int + int sum = 0; + int temp = 0; + for (int i = 0; i < 5; i++) { + temp = i; + sum += temp; + } + System.out.println("Sum of first 5 numbers: " + sum); + + // For loop with an array of integers + int[] numbers = {1, 2, 3}; + int arraySum = 0; + for (int i = 0; i < numbers.length; i++) { + arraySum += numbers[i]; + } + System.out.println("Sum of array elements: " + arraySum); + + // For loop with a double type + double product = 1.0; + for (int i = 1; i <= 3; i++) { + product *= i * 1.5; + } + System.out.println("Product of first 3 numbers multiplied by 1.5: " + product); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_2.java new file mode 100644 index 0000000000..8dedb98592 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_2.java @@ -0,0 +1,28 @@ +public class ForLoop_mutation_2 { + + public static void main(String[] args) { + // Simple for loop with int + int sum = 0; + for (int i = 0; i < 5; i++) { + if (true) { + sum += i; + } + } + System.out.println("Sum of first 5 numbers: " + sum); + + // For loop with an array of integers + int[] numbers = {1, 2, 3}; + int arraySum = 0; + for (int i = 0; i < numbers.length; i++) { + arraySum += numbers[i]; + } + System.out.println("Sum of array elements: " + arraySum); + + // For loop with a double type + double product = 1.0; + for (int i = 1; i <= 3; i++) { + product *= i * 1.5; + } + System.out.println("Product of first 3 numbers multiplied by 1.5: " + product); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_3.java new file mode 100644 index 0000000000..66a8f99b57 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_3.java @@ -0,0 +1,28 @@ +public class ForLoop_mutation_3 { + + public static void main(String[] args) { + // Simple for loop with int + int sum = 0; + for (int i = 0; i < 5; i++) { + if (true) { + sum += i; + } + } + System.out.println("Sum of first 5 numbers: " + sum); + + // For loop with an array of integers + int[] numbers = {1, 2, 3}; + int arraySum = 0; + for (int i = 0; i < numbers.length; i++) { + arraySum += numbers[i]; + } + System.out.println("Sum of array elements: " + arraySum); + + // For loop with a double type + double product = 1.0; + for (int i = 1; i <= 3; i++) { + product *= i * 1.5; + } + System.out.println("Product of first 3 numbers multiplied by 1.5: " + product); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_4.java new file mode 100644 index 0000000000..099ecba666 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_4.java @@ -0,0 +1,28 @@ +public class ForLoop_mutation_4 { + + public static void main(String[] args) { + // Simple for loop with int + int[] sumArray = {0}; + int sum = sumArray[0]; + for (int i = 0; i < 5; i++) { + sum += i; + } + System.out.println("Sum of first 5 numbers: " + sum); + + // For loop with an array of integers + int[] numbers = {1, 2, 3}; + int arraySum = 0; + for (int i = 0; i < numbers.length; i++) { + arraySum += numbers[i]; + } + System.out.println("Sum of array elements: " + arraySum); + + // For loop with a double type + double[] productArray = {1.0}; + double product = productArray[0]; + for (int i = 1; i <= 3; i++) { + product *= i * 1.5; + } + System.out.println("Product of first 3 numbers multiplied by 1.5: " + product); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_5.java new file mode 100644 index 0000000000..51c693a2c9 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/forLoop/ForLoop_mutation_5.java @@ -0,0 +1,28 @@ +public class ForLoop_mutation_5 { + + public static void main(String[] args) { + // Simple for loop with int + int sum = 0; + for (int i = 0; i < 5; i++) { + if (true) { + sum += i; + } + } + System.out.println("Sum of first 5 numbers: " + sum); + + // For loop with an array of integers + int[] numbers = {1, 2, 3}; + int arraySum = 0; + for (int i = 0; i < numbers.length; i++) { + arraySum += numbers[i]; + } + System.out.println("Sum of array elements: " + arraySum); + + // For loop with a double type + double product = 1.0; + for (int i = 1; i <= 3; i++) { + product *= i * 1.5; + } + System.out.println("Product of first 3 numbers multiplied by 1.5: " + product); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If.java new file mode 100644 index 0000000000..bff2a9a807 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If.java @@ -0,0 +1,61 @@ +public class If { + public static void main(String[] args) { + // Simple if statement + int a = 10; + int b = 20; + if (a < b) { + System.out.println("a is less than b"); + } + + // If-else statement + int c = 15; + if (a > c) { + System.out.println("a is greater than c"); + } else { + System.out.println("a is not greater than c"); + } + + // If-else if-else statement + if (a < c) { + System.out.println("a is less than c"); + } else if (b > c) { + System.out.println("b is greater than c"); + } else { + System.out.println("Neither condition is true"); + } + + // Nested if statement + if (a < b) { + if (c < b) { + System.out.println("c is less than b"); + } else { + System.out.println("c is not less than b"); + } + } + + // Multiple conditions in if statement + boolean x = true; + boolean y = false; + if (x && !y) { + System.out.println("x is true and y is false"); + } + + // Object comparison using == + String str1 = "Hello"; + String str2 = "Hello"; + + if (str1 == str2) { + System.out.println("str1 == str2: Both references are the same"); + } + + // Object comparison using equals() + String s1 = new String("test"); + String s2 = new String("test"); + + if (s1.equals(s2)) { + System.out.println("s1 equals s2: Both strings have the same value"); + } else { + System.out.println("s1 does not equal s2"); + } + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_1.java new file mode 100644 index 0000000000..fc0576bf95 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_1.java @@ -0,0 +1,62 @@ +public class If_mutation_1 { + public static void main(String[] args) { + // Simple if statement + int[] arr = {10}; + int a = arr[0]; + int b = 20; + if (a < b) { + System.out.println("a is less than b"); + } + + // If-else statement + int c = 15; + if (a > c) { + System.out.println("a is greater than c"); + } else { + System.out.println("a is not greater than c"); + } + + // If-else if-else statement + if (a < c) { + System.out.println("a is less than c"); + } else if (b > c) { + System.out.println("b is greater than c"); + } else { + System.out.println("Neither condition is true"); + } + + // Nested if statement + if (a < b) { + if (c < b) { + System.out.println("c is less than b"); + } else { + System.out.println("c is not less than b"); + } + } + + // Multiple conditions in if statement + boolean x = true; + boolean y = false; + if (x && !y) { + System.out.println("x is true and y is false"); + } + + // Object comparison using == + String str1 = "Hello"; + String str2 = "Hello"; + + if (str1 == str2) { + System.out.println("str1 == str2: Both references are the same"); + } + + // Object comparison using equals() + String s1 = new String("test"); + String s2 = new String("test"); + + if (s1.equals(s2)) { + System.out.println("s1 equals s2: Both strings have the same value"); + } else { + System.out.println("s1 does not equal s2"); + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_2.java new file mode 100644 index 0000000000..1166a8368a --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_2.java @@ -0,0 +1,63 @@ +public class If_mutation_2 { + public static void main(String[] args) { + // Simple if statement + int a = 10; + int b = 20; + if (a < b) { + if (true) { + System.out.println("a is less than b"); + } + } + + // If-else statement + int c = 15; + if (a > c) { + System.out.println("a is greater than c"); + } else { + System.out.println("a is not greater than c"); + } + + // If-else if-else statement + if (a < c) { + System.out.println("a is less than c"); + } else if (b > c) { + System.out.println("b is greater than c"); + } else { + System.out.println("Neither condition is true"); + } + + // Nested if statement + if (a < b) { + if (c < b) { + System.out.println("c is less than b"); + } else { + System.out.println("c is not less than b"); + } + } + + // Multiple conditions in if statement + boolean x = true; + boolean y = false; + if (x && !y) { + System.out.println("x is true and y is false"); + } + + // Object comparison using == + String str1 = "Hello"; + String str2 = "Hello"; + + if (str1 == str2) { + System.out.println("str1 == str2: Both references are the same"); + } + + // Object comparison using equals() + String s1 = new String("test"); + String s2 = new String("test"); + + if (s1.equals(s2)) { + System.out.println("s1 equals s2: Both strings have the same value"); + } else { + System.out.println("s1 does not equal s2"); + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_3.java new file mode 100644 index 0000000000..a0e1860931 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_3.java @@ -0,0 +1,63 @@ +public class If_mutation_3 { + public static void main(String[] args) { + // Simple if statement + int[] aArr = {10}; + int a = aArr[0]; + int b = 20; + if (a < b) { + System.out.println("a is less than b"); + } + + // If-else statement + int[] cArr = {15}; + int c = cArr[0]; + if (a > c) { + System.out.println("a is greater than c"); + } else { + System.out.println("a is not greater than c"); + } + + // If-else if-else statement + if (a < c) { + System.out.println("a is less than c"); + } else if (b > c) { + System.out.println("b is greater than c"); + } else { + System.out.println("Neither condition is true"); + } + + // Nested if statement + if (a < b) { + if (c < b) { + System.out.println("c is less than b"); + } else { + System.out.println("c is not less than b"); + } + } + + // Multiple conditions in if statement + boolean x = true; + boolean y = false; + if (x && !y) { + System.out.println("x is true and y is false"); + } + + // Object comparison using == + String str1 = "Hello"; + String str2 = "Hello"; + + if (str1 == str2) { + System.out.println("str1 == str2: Both references are the same"); + } + + // Object comparison using equals() + String s1 = new String("test"); + String s2 = new String("test"); + + if (s1.equals(s2)) { + System.out.println("s1 equals s2: Both strings have the same value"); + } else { + System.out.println("s1 does not equal s2"); + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_4.java new file mode 100644 index 0000000000..cbe3dba9e6 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_4.java @@ -0,0 +1,61 @@ +public class If_mutation_4 { + public static void main(String[] args) { + // Simple if statement + int a = 10; + int b = 20; + if (a < b) { + System.out.println("a is less than b"); + } + + // If-else statement + int c = 15; + if (a > c) { + System.out.println("a is greater than c"); + } else { + System.out.println("a is not greater than c"); + } + + // If-else if-else statement + if (a < c) { + System.out.println("a is less than c"); + } else if (b > c) { + System.out.println("b is greater than c"); + } else { + System.out.println("Neither condition is true"); + } + + // Nested if statement + if (a < b) { + if (c < b) { + System.out.println("c is less than b"); + } else { + System.out.println("c is not less than b"); + } + } + + // Multiple conditions in if statement + boolean x = true; + boolean y = false; + if (x && !y) { + System.out.println("x is true and y is false"); + } + + // Object comparison using == + String str1 = "Hello"; + String str2 = "Hello"; + if (true) { + if (str1 == str2) { + System.out.println("str1 == str2: Both references are the same"); + } + } + + // Object comparison using equals() + String s1 = new String("test"); + String s2 = new String("test"); + if (s1.equals(s2)) { + System.out.println("s1 equals s2: Both strings have the same value"); + } else { + System.out.println("s1 does not equal s2"); + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_5.java new file mode 100644 index 0000000000..414aedab50 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/if/If_mutation_5.java @@ -0,0 +1,61 @@ +public class If_mutation_5 { + public static void main(String[] args) { + // Simple if statement + int[] a = {10}; + int b = 20; + if (a[0] < b) { + System.out.println("a is less than b"); + } + + // If-else statement + int[] c = {15}; + if (a[0] > c[0]) { + System.out.println("a is greater than c"); + } else { + System.out.println("a is not greater than c"); + } + + // If-else if-else statement + if (a[0] < c[0]) { + System.out.println("a is less than c"); + } else if (b > c[0]) { + System.out.println("b is greater than c"); + } else { + System.out.println("Neither condition is true"); + } + + // Nested if statement + if (a[0] < b) { + if (c[0] < b) { + System.out.println("c is less than b"); + } else { + System.out.println("c is not less than b"); + } + } + + // Multiple conditions in if statement + boolean x = true; + boolean y = false; + if (x && !y) { + System.out.println("x is true and y is false"); + } + + // Object comparison using == + String str1 = "Hello"; + String str2 = "Hello"; + + if (str1 == str2) { + System.out.println("str1 == str2: Both references are the same"); + } + + // Object comparison using equals() + String s1 = new String("test"); + String s2 = new String("test"); + + if (s1.equals(s2)) { + System.out.println("s1 equals s2: Both strings have the same value"); + } else { + System.out.println("s1 does not equal s2"); + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero.java new file mode 100644 index 0000000000..94fea88350 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero.java @@ -0,0 +1,21 @@ +public class IfZero { + + public static void main(String[] args) { + // Test with a positive number, zero, and a negative number + int[] testValues = {10, 0, -5}; + + for (int value : testValues) { + compareWithZero(value); + } + } + + public static void compareWithZero(int k) { + if (k == 0) { + System.out.println("k is equal to zero."); + } else if (k > 0) { + System.out.println("k is greater than zero."); + } else { + System.out.println("k is less than zero."); + } + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_1.java new file mode 100644 index 0000000000..4ec8baf83d --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_1.java @@ -0,0 +1,25 @@ +public class IfZero_mutation_1 { + + public static void main(String[] args) { + // Test with a positive number, zero, and a negative number + int[] testValues = {10, 0, -5}; + + for (int value : testValues) { + compareWithZero(value); + } + } + + public static void compareWithZero(int k) { + if (isZero(k)) { + System.out.println("k is equal to zero."); + } else if (k > 0) { + System.out.println("k is greater than zero."); + } else { + System.out.println("k is less than zero."); + } + } + + public static boolean isZero(int k) { + return k == 0; + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_2.java new file mode 100644 index 0000000000..9f80ed6f03 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_2.java @@ -0,0 +1,23 @@ +public class IfZero_mutation_2 { + + public static void main(String[] args) { + // Test with a positive number, zero, and a negative number + int[] testValues = {10, 0, -5}; + + for (int value : testValues) { + compareWithZero(value); + } + } + + public static void compareWithZero(int k) { + if (k == 0) { + if (true) { + System.out.println("k is equal to zero."); + } + } else if (k > 0) { + System.out.println("k is greater than zero."); + } else { + System.out.println("k is less than zero."); + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_3.java new file mode 100644 index 0000000000..9d48496820 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_3.java @@ -0,0 +1,21 @@ +public class IfZero_mutation_3 { + + public static void main(String[] args) { + // Test with a positive number, zero, and a negative number + int[] testValues = {10, 0, -5}; + + for (int value : testValues) { + compareWithZero(value); + } + } + + public static void compareWithZero(int k) { + if (k == 0) { + System.out.println("k is equal to zero."); + } else if (true) { // redundant if statement + System.out.println("k is greater than zero."); + } else { + System.out.println("k is less than zero."); + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_4.java new file mode 100644 index 0000000000..0ceda51efb --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_4.java @@ -0,0 +1,21 @@ +public class IfZero_mutation_4 { + + public static void main(String[] args) { + // Test with a positive number, zero, and a negative number + int[][] testValues = {{10}, {0}, {-5}}; + + for (int i = 0; i < testValues.length; i++) { + compareWithZero(testValues[i][0]); + } + } + + public static void compareWithZero(int k) { + if (k == 0) { + System.out.println("k is equal to zero."); + } else if (k > 0) { + System.out.println("k is greater than zero."); + } else { + System.out.println("k is less than zero."); + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_5.java new file mode 100644 index 0000000000..67c469b321 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/ifZero/IfZero_mutation_5.java @@ -0,0 +1,23 @@ +public class IfZero_mutation_5 { + + public static void main(String[] args) { + // Test with a positive number, zero, and a negative number + int[] testValues = {10, 0, -5}; + + for (int value : testValues) { + compareWithZero(value); + } + } + + public static void compareWithZero(int k) { + if (k == 0) { + if (true) { + System.out.println("k is equal to zero."); + } + } else if (k > 0) { + System.out.println("k is greater than zero."); + } else { + System.out.println("k is less than zero."); + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField.java new file mode 100644 index 0000000000..8481baa939 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField.java @@ -0,0 +1,10 @@ +public class InstanceField { + + private int instanceValue; + + public static void main(String[] args) { + InstanceField testInstance = new InstanceField(); + testInstance.instanceValue = 42; + System.out.println("Instance field value: " + testInstance.instanceValue); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_1.java new file mode 100644 index 0000000000..bb17c6f009 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_1.java @@ -0,0 +1,11 @@ +public class InstanceField_mutation_1 { + + private int instanceValue; + + public static void main(String[] args) { + InstanceField testInstance = new InstanceField(); + int value = 42; + testInstance.instanceValue = value; + System.out.println("Instance field value: " + testInstance.instanceValue); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_2.java new file mode 100644 index 0000000000..9ef037f205 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_2.java @@ -0,0 +1,13 @@ +public class InstanceField_mutation_2 { + + private int instanceValue; + + public InstanceField(int value) { + this.instanceValue = value; + } + + public static void main(String[] args) { + InstanceField testInstance = new InstanceField(42); + System.out.println("Instance field value: " + testInstance.instanceValue); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_3.java new file mode 100644 index 0000000000..3cc8d5a8f1 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_3.java @@ -0,0 +1,14 @@ +public class InstanceField_mutation_3 { + + private int instanceValue; + + public static void main(String[] args) { + InstanceField testInstance = new InstanceField(); + testInstance.assignValue(42); + System.out.println("Instance field value: " + testInstance.instanceValue); + } + + public void assignValue(int value) { + this.instanceValue = value; + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_4.java new file mode 100644 index 0000000000..9a56c94aa0 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_4.java @@ -0,0 +1,14 @@ +public class InstanceField_mutation_4 { + + private int instanceValue; + + public static void main(String[] args) { + InstanceField testInstance = new InstanceField(); + initializeField(testInstance, 42); + System.out.println("Instance field value: " + testInstance.instanceValue); + } + + private static void initializeField(InstanceField instance, int value) { + instance.instanceValue = value; + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_5.java new file mode 100644 index 0000000000..12ac0746ea --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_5.java @@ -0,0 +1,10 @@ +public class InstanceField_mutation_5 { + + private Integer instanceValue; + + public static void main(String[] args) { + InstanceField testInstance = new InstanceField(); + testInstance.instanceValue = Integer.valueOf(42); + System.out.println("Instance field value: " + testInstance.instanceValue); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf.java new file mode 100644 index 0000000000..6ab3f079e0 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf.java @@ -0,0 +1,11 @@ +public class InstanceOf { + + public static void main(String[] args) { + // Test with String + Object obj = "Hello, World!"; + System.out.println("obj is an instance of String: " + (obj instanceof String)); // true + System.out.println("obj is an instance of CharSequence: " + (obj instanceof CharSequence)); // true + System.out.println("obj is an instance of Object: " + (obj instanceof Object)); // true + System.out.println("obj is an instance of Integer: " + (obj instanceof Integer)); // false + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_1.java new file mode 100644 index 0000000000..49544af590 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_1.java @@ -0,0 +1,12 @@ +public class InstanceOf_mutation_1 { + + public static void main(String[] args) { + // Test with String + Object obj = "Hello, World!"; + boolean isString = obj instanceof String; + System.out.println("obj is an instance of String: " + isString); + System.out.println("obj is an instance of CharSequence: " + (obj instanceof CharSequence)); // true + System.out.println("obj is an instance of Object: " + (obj instanceof Object)); // true + System.out.println("obj is an instance of Integer: " + (obj instanceof Integer)); // false + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_2.java new file mode 100644 index 0000000000..b84d5f2f0a --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_2.java @@ -0,0 +1,16 @@ +public class InstanceOf_mutation_2 { + + public static void main(String[] args) { + // Create a class with static fields + class MyClass { + static Object obj = "Hello, World!"; + static String str = "Hello, World!"; + static Integer integer = new Integer(5); + } + // Test with String + System.out.println("obj is an instance of String: " + (MyClass.obj instanceof String)); // true + System.out.println("obj is an instance of CharSequence: " + (MyClass.obj instanceof CharSequence)); // true + System.out.println("obj is an instance of Object: " + (MyClass.obj instanceof Object)); // true + System.out.println("obj is an instance of Integer: " + (MyClass.obj instanceof Integer)); // false + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_3.java new file mode 100644 index 0000000000..fea4a9f8c4 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_3.java @@ -0,0 +1,13 @@ +public class InstanceOf_mutation_3 { + + public static final Object INSTANCE = new Object(); + + public static void main(String[] args) { + // Test with String + Object obj = INSTANCE; + System.out.println("obj is an instance of String: " + (obj instanceof String)); // true + System.out.println("obj is an instance of CharSequence: " + (obj instanceof CharSequence)); // true + System.out.println("obj is an instance of Object: " + (obj instanceof Object)); // true + System.out.println("obj is an instance of Integer: " + (obj instanceof Integer)); // false + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_4.java new file mode 100644 index 0000000000..7f20ed728b --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_4.java @@ -0,0 +1,13 @@ +public class InstanceOf_mutation_4 { + + public static String mystaticstring = "Hello, World!"; + + public static void main(String[] args) { + // Test with String + Object obj = mystaticstring; + System.out.println("obj is an instance of String: " + (obj instanceof String)); // true + System.out.println("obj is an instance of CharSequence: " + (obj instanceof CharSequence)); // true + System.out.println("obj is an instance of Object: " + (obj instanceof Object)); // true + System.out.println("obj is an instance of Integer: " + (obj instanceof Integer)); // false + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_5.java new file mode 100644 index 0000000000..ebfa166893 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceOf/InstanceOf_mutation_5.java @@ -0,0 +1,12 @@ +public class InstanceOf_mutation_5 { + + public static void main(String[] args) { + // Test with String + Object[] objArray = {"Hello, World!"}; + Object obj = objArray[0]; + System.out.println("obj is an instance of String: " + (obj instanceof String)); // true + System.out.println("obj is an instance of CharSequence: " + (obj instanceof CharSequence)); // true + System.out.println("obj is an instance of Object: " + (obj instanceof Object)); // true + System.out.println("obj is an instance of Integer: " + (obj instanceof Integer)); // false + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic.java new file mode 100644 index 0000000000..faa06d67c2 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic.java @@ -0,0 +1,18 @@ +public class InvokeDynamic { + + public static void main(String[] args) { + // Lambda Expression + Runnable r = () -> System.out.println("Running in a lambda!"); + r.run(); + + // String Concatenation + System.out.println("Hello, World!"); + + // Method Reference + new InvokeDynamic().methodReferenceExample(); + } + + public void methodReferenceExample() { + System.out.println("Method Reference Example"); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_1.java new file mode 100644 index 0000000000..201b8d3d82 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_1.java @@ -0,0 +1,21 @@ +public class InvokeDynamic_mutation_1 { + + public static void main(String[] args) { + // Lambda Expression + Runnable r = () -> System.out.println("Running in a lambda expression!"); + r.run(); + + // String Concatenation + String greeting = "Hello"; + String punctuation = "!"; + System.out.println(greeting + ", World" + punctuation); + + // Method Reference + InvokeDynamic instance = new InvokeDynamic(); + instance.runMethodReference(); + } + + public void runMethodReference() { + System.out.println("Method Reference Example"); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_2.java new file mode 100644 index 0000000000..dcdf715d55 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_2.java @@ -0,0 +1,27 @@ +public class InvokeDynamic_mutation_2 { + + public static void main(String[] args) { + // Lambda Expression + Runnable r = () -> printLambdaMessage(); + r.run(); + + // String Concatenation + String message = buildMessage("Hello", "World"); + System.out.println(message); + + // Method Reference + new InvokeDynamic().methodReference(); + } + + private static void printLambdaMessage() { + System.out.println("Running in a lambda!"); + } + + private static String buildMessage(String part1, String part2) { + return part1 + ", " + part2 + "!"; + } + + public void methodReference() { + System.out.println("Method Reference Example"); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_3.java new file mode 100644 index 0000000000..1025a1b310 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_3.java @@ -0,0 +1,27 @@ +public class InvokeDynamic_mutation_3 { + + public static void main(String[] args) { + // Lambda Expression + Runnable r = () -> printLambdaMessage(); + r.run(); + + // String Concatenation + String message = buildMessage("Hello", "World"); + System.out.println(message); + + // Method Reference + new InvokeDynamic().methodReference(); + } + + private static void printLambdaMessage() { + System.out.println("Running in a lambda!"); + } + + private static String buildMessage(String part1, String part2) { + return part1 + ", " + part2 + "!"; + } + + public void methodReference() { + System.out.println("Method Reference Example"); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface.java new file mode 100644 index 0000000000..1545abb479 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface.java @@ -0,0 +1,17 @@ +import java.util.List; +import java.util.ArrayList; +public class InvokeInterface { + + public static void main(String[] args) { + // Create an instance of ArrayList, which implements the List interface + List myList = new ArrayList<>(); + + // Add elements to the list (invokeinterface) + myList.add("Hello"); + myList.add("World"); + + // Get the size of the list (invokeinterface) + int size = myList.size(); + System.out.println("Size of the list: " + size); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr.java new file mode 100644 index 0000000000..a003d1e607 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr.java @@ -0,0 +1,18 @@ +public class Jsr { + + public static void main(String[] args) { + System.out.println("Before subroutine"); + executeSubroutine(); + System.out.println("After subroutine"); + } + + private static void executeSubroutine() { + System.out.println("In subroutine"); + // Simulating a subroutine with a loop or some operations + for (int i = 0; i < 3; i++) { + System.out.println("Subroutine iteration: " + i); + } + // Return from the subroutine (RET equivalent) + return; // RET is simulated by this return statement in Java + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall.java new file mode 100644 index 0000000000..0f040d0301 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall.java @@ -0,0 +1,62 @@ +public class MethodCall { + + public static void main(String[] args) { + // Instance method call + MethodCall instance = new MethodCall(); + int instanceResult = instance.instanceMethod(5, 3); + System.out.println("Instance method result: " + instanceResult); + + // Static method call + int staticResult = staticMethod(10, 2); + System.out.println("Static method result: " + staticResult); + + // Overloaded method call + String overloadedResult1 = instance.overloadedMethod(5); + String overloadedResult2 = instance.overloadedMethod(5, 3); + System.out.println("Overloaded method result (1 parameter): " + overloadedResult1); + System.out.println("Overloaded method result (2 parameters): " + overloadedResult2); + + // Calling a method that calls another method + int nestedCallResult = instance.nestedMethodCall(7, 3); + System.out.println("Nested method call result: " + nestedCallResult); + + // Method with multiple return statements + int multipleReturnResult = instance.multipleReturnMethod(15); + System.out.println("Multiple return method result: " + multipleReturnResult); + } + + // Instance method + public int instanceMethod(int a, int b) { + return a + b; + } + + // Static method + public static int staticMethod(int x, int y) { + return x * y; + } + + // Overloaded methods + public String overloadedMethod(int a) { + return "Overloaded with one parameter: " + a; + } + + public String overloadedMethod(int a, int b) { + return "Overloaded with two parameters: " + (a + b); + } + + // Method that calls another method + public int nestedMethodCall(int a, int b) { + return instanceMethod(a, b) * staticMethod(a, b); + } + + // Method with multiple return statements + public int multipleReturnMethod(int value) { + if (value > 10) { + return value * 2; + } else if (value == 10) { + return value * 3; + } else { + return value * 4; + } + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation.java new file mode 100644 index 0000000000..51998462dd --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation.java @@ -0,0 +1,35 @@ +public class Negation { + + public static void main(String[] args) { + // Integer negation + int intValue = 42; + int negatedInt = -intValue; + System.out.println("Negated int: " + negatedInt); + + // Long negation + long longValue = 123456789L; + long negatedLong = -longValue; + System.out.println("Negated long: " + negatedLong); + + // Float negation + float floatValue = 3.14f; + float negatedFloat = -floatValue; + System.out.println("Negated float: " + negatedFloat); + + // Double negation + double doubleValue = 2.71828; + double negatedDouble = -doubleValue; + System.out.println("Negated double: " + negatedDouble); + + // Test negation in expressions + int exprInt = -(intValue + 10); + long exprLong = -(longValue * 2); + float exprFloat = -(floatValue / 2.0f); + double exprDouble = -(doubleValue - 1.0); + + System.out.println("Negated int in expression: " + exprInt); + System.out.println("Negated long in expression: " + exprLong); + System.out.println("Negated float in expression: " + exprFloat); + System.out.println("Negated double in expression: " + exprDouble); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess.java new file mode 100644 index 0000000000..8e46818e0d --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess.java @@ -0,0 +1,53 @@ +public class ObjectPropertyAccess { + + // Object attributes + private int[] m = {10, 20, 30, 40, 50}; // Example array + private int i; // Index i + private int j; // Index j + private int k; // Result of subtraction + + public static void main(String[] args) { + ObjectPropertyAccess test = new ObjectPropertyAccess(); + test.runTests(); + } + + public void runTests() { + // Test case 1: Normal subtraction + this.i = 4; // Refers to m[4] = 50 + this.j = 3; // Refers to m[3] = 40 + this.k = this.m[this.i] - this.m[this.j]; + System.out.println("Test 1 (m[4] - m[3]): k = " + this.k); // Expected: 10 + + // Test case 2: Subtraction leading to zero + this.i = 2; // Refers to m[2] = 30 + this.j = 2; // Refers to m[2] = 30 + this.k = this.m[this.i] - this.m[this.j]; + System.out.println("Test 2 (m[2] - m[2]): k = " + this.k); // Expected: 0 + + // Test case 3: Subtraction leading to a negative result + this.i = 1; // Refers to m[1] = 20 + this.j = 4; // Refers to m[4] = 50 + this.k = this.m[this.i] - this.m[this.j]; + System.out.println("Test 3 (m[1] - m[4]): k = " + this.k); // Expected: -30 + + // Test case 4: Subtraction at boundary values (first element) + this.i = 0; // Refers to m[0] = 10 + this.j = 4; // Refers to m[4] = 50 + this.k = this.m[this.i] - this.m[this.j]; + System.out.println("Test 4 (m[0] - m[4]): k = " + this.k); // Expected: -40 + + // Test case 5: Subtraction at boundary values (last element) + this.i = 4; // Refers to m[4] = 50 + this.j = 0; // Refers to m[0] = 10 + this.k = this.m[this.i] - this.m[this.j]; + System.out.println("Test 5 (m[4] - m[0]): k = " + this.k); // Expected: 40 + + // Test case 6: Subtraction leading to potential overflow/underflow + this.m = new int[]{Integer.MAX_VALUE, Integer.MIN_VALUE}; + this.i = 0; // Refers to Integer.MAX_VALUE + this.j = 1; // Refers to Integer.MIN_VALUE + this.k = this.m[this.i] - this.m[this.j]; + System.out.println("Test 6 (Integer.MAX_VALUE - Integer.MIN_VALUE): k = " + this.k); + // Expected: Large positive value, may demonstrate overflow behavior + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters.java new file mode 100644 index 0000000000..183d63eb2a --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters.java @@ -0,0 +1,55 @@ +public class Parameters { + + public static void main(String[] args) { + // Test with primitive types + int a = 10; + double b = 20.5; + char c = 'A'; + + System.out.println("Sum of int and double: " + sum(a, b)); + System.out.println("Character to int: " + charToInt(c)); + + // Test with array parameters + int[] numbers = {1, 2, 3, 4, 5}; + System.out.println("Sum of array elements: " + sumArray(numbers)); + + // Test with varargs + System.out.println("Sum with varargs: " + sumVarArgs(1, 2, 3, 4, 5)); + + // Test with multiple primitive parameters + System.out.println("Average of three numbers: " + average(5, 10, 15)); + } + + // Method with primitive parameters + public static double sum(int x, double y) { + return x + y; + } + + // Method with a char parameter + public static int charToInt(char ch) { + return ch; + } + + // Method with an array parameter + public static int sumArray(int[] array) { + int sum = 0; + for (int num : array) { + sum += num; + } + return sum; + } + + // Method with varargs parameter + public static int sumVarArgs(int... numbers) { + int sum = 0; + for (int num : numbers) { + sum += num; + } + return sum; + } + + // Method with multiple primitive parameters + public static double average(int x, int y, int z) { + return (x + y + z) / 3.0; + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast.java new file mode 100644 index 0000000000..4df4a750c6 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast.java @@ -0,0 +1,46 @@ +public class PrimitiveTypeCast { + + public static void main(String[] args) { + // Initial values + int intValue = 100; + double doubleValue = 123.456; + long longValue = 9876543210L; + float floatValue = 3.14f; + + //Cast to different types + + // int to byte, short, char + byte byteValue = (byte) intValue; + short shortValue = (short) intValue; + char charValue = (char) intValue; + + // long to int, float, double + int intFromLong = (int) longValue; + float floatFromLong = (float) longValue; + double doubleFromLong = (double) longValue; + + // double to int, long, float + int intFromDouble = (int) doubleValue; + long longFromDouble = (long) doubleValue; + float floatFromDouble = (float) doubleValue; + + // float to int, long, double + int intFromFloat = (int) floatValue; + long longFromFloat = (long) floatValue; + double doubleFromFloat = (double) floatValue; + + // Output the results + System.out.println("int to byte: " + byteValue); + System.out.println("int to short: " + shortValue); + System.out.println("int to char: " + (int) charValue); // Print char as int to show ASCII value + System.out.println("long to int: " + intFromLong); + System.out.println("long to float: " + floatFromLong); + System.out.println("long to double: " + doubleFromLong); + System.out.println("double to int: " + intFromDouble); + System.out.println("double to long: " + longFromDouble); + System.out.println("double to float: " + floatFromDouble); + System.out.println("float to int: " + intFromFloat); + System.out.println("float to long: " + longFromFloat); + System.out.println("float to double: " + doubleFromFloat); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment.java new file mode 100644 index 0000000000..82d6d228b7 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment.java @@ -0,0 +1,41 @@ +public class Reassignment { + + public static void main(String[] args) { + int x = 10; + int y = 5; + int z = Integer.MAX_VALUE; + double test = 2.3d; + + System.out.println("Initial values - x: " + x + ", y: " + y + ", z: " + z); + + // Conditional reassignment + if (-3< 0) { + x = Integer.MAX_VALUE+5; + System.out.println("After conditional reassignment, x: " + x); + } + + // Loop with reassignment + for (int i = 0; i < 3; i++) { + z = z + (x * i) - y; + System.out.println("After loop iteration " + i + ", z: " + z); + } + + // Nested reassignments + if (z > 10) { + x = x * 2; + y = y + z; + z = x - y; + System.out.println("After nested reassignment, x: " + x + ", y: " + y + ", z: " + z); + } + + // Reassign using previous values + z = (x * y) + z; + System.out.println("Final value of z after using previous values: " + z); + + // Complex reassignments with multiple operations + x = x + (y - z) * 2; + y = y * 3 + z - x; + z = x - y + z; + System.out.println("Complex final values - x: " + x + ", y: " + y + ", z: " + z); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField.java new file mode 100644 index 0000000000..0181fd35f0 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField.java @@ -0,0 +1,23 @@ +public class StaticField { + + // A static field + private static int staticValue; + + public static void main(String[] args) { + // Set the static field + setStaticValue(42); + + // Get the static field value and print it + System.out.println("Static field value: " + getStaticValue()); + } + + // Method to set the static field + public static void setStaticValue(int value) { + staticValue = value; + } + + // Method to get the static field value + public static int getStaticValue() { + return staticValue; + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch.java new file mode 100644 index 0000000000..5cd5f450a2 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch.java @@ -0,0 +1,26 @@ +public class Switch { + + public static void main(String[] args) { + // Array of fruits to ensure all cases are covered + String[] fruits = {"Banana", "Brocoli", "Wednesday"}; + + // Loop through all possible fruits + for (String fruit : fruits) { + printFruit(fruit); + } + } + + public static void printFruit(String fruit) { + switch (fruit) { + case "Banana": + System.out.println(fruit + " is a fruit"); + break; + case "Brocoli": + System.out.println(fruit + " is a vegetable."); + break; + default: + System.out.println(fruit + " is not valid."); + break; + } + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop.java new file mode 100644 index 0000000000..761fea6ed9 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop.java @@ -0,0 +1,64 @@ +public class WhileLoop { + + public static void main(String[] args) { + // Simple while loop + int counter = 0; + while (counter < 5) { + System.out.println("Simple while loop: counter = " + counter); + counter++; + } + + // While loop with multiple conditions + int a = 10; + int b = 20; + while (a < b && a % 2 == 0) { + System.out.println("While loop with multiple conditions: a = " + a); + a += 2; + } + + // Nested while loop + int outer = 1; + while (outer <= 3) { + int inner = 1; + while (inner <= 2) { + System.out.println("Nested while loop: outer = " + outer + ", inner = " + inner); + inner++; + } + outer++; + } + + // While loop with break + int x = 0; + while (true) { + System.out.println("While loop with break: x = " + x); + if (x >= 3) { + break; + } + x++; + } + + // While loop with continue + int y = 0; + while (y < 5) { + y++; + if (y % 2 == 0) { + continue; + } + System.out.println("While loop with continue: y = " + y); + } + + // Do-while loop + int z = 0; + do { + System.out.println("Do-while loop: z = " + z); + z++; + } while (z < 3); + + // Do-while loop with complex condition + int m = 10; + do { + System.out.println("Do-while loop with complex condition: m = " + m); + m--; + } while (m > 0 && m % 3 != 0); + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/MutatedClassFileTACtoBCTest.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/MutatedClassFileTACtoBCTest.scala new file mode 100644 index 0000000000..79dc8c24fb --- /dev/null +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/MutatedClassFileTACtoBCTest.scala @@ -0,0 +1,111 @@ +package org.opalj.tactobc + +import org.opalj.br.analyses.Project +import org.opalj.util.InMemoryClassLoader +import org.scalatest.funspec.AnyFunSpec +import org.scalatest.matchers.should.Matchers +import org.scalatest.prop.TableDrivenPropertyChecks._ + +import java.io.{ByteArrayOutputStream, File, PrintStream} +import java.nio.file.{Files, Paths} +import scala.sys.process._ + +class MutatedClassFileTACtoBCTest extends AnyFunSpec with Matchers { + + describe("TACtoBC Mutation Testing") { + + val testCases = Table( + ("original Java File Name", "source Folder", "Class File Name of Original", "mutated Java File Name", "Class File Name"), + MutatedClassFileTestCaseEnum.testCases.map(tc => (tc.originalJavaFileName, tc.sourceFolder, tc.classFileOfOriginalName, tc.mutatedJavaFileName, tc.generatedClassFileOfMutationName)): _* + ) + + forAll(testCases) { (originalJavaFileName, sourceFolder, classFileOfOriginalName, mutatedJavaFileName, classFileName) => + it(s"should compile $originalJavaFileName, generate TAC, convert back to bytecode, and compare with the mutated class file $mutatedJavaFileName") { + runTestCase(originalJavaFileName, sourceFolder, classFileOfOriginalName, mutatedJavaFileName, classFileName) + } + } + } + + private def runTestCase(originalJavaFileName: String, sourceFolder: String, classFileOfOriginalName: String, mutatedJavaFileName: String, classFileName: String): Unit = { + try { + // (1) Compile the original Java file to generate its .class file + compileOriginalJavaFile(sourceFolder, originalJavaFileName) + + // (2) Compile the mutated Java file to generate its .class file + compileMutatedJavaFile(sourceFolder, mutatedJavaFileName) + + // Load the mutated class file + val mutatedClassFile = new File(Paths.get(MutatedClassFileTestCaseEnum.inputDirMutatedJavaPath, classFileName).toString) + + // Create the OPAL project from the original class file + val project = Project(mutatedClassFile) + + // (3) Compile TAC from the original class file + val tacs = TACtoBC.compileTAC(mutatedClassFile) + + // Convert TAC back to bytecode + val byteCodes = TACtoBC.translateTACtoBC(tacs) + + // Generate the new class file using ClassFileGenerator + ClassFileGenerator.generateClassFiles(byteCodes, project, MutatedClassFileTestCaseEnum.inputDirMutatedJavaPath, MutatedClassFileTestCaseEnum.outputDirPath, classFileName) + + // (4) Load the original class and the mutated/generated class + val originalClass = loadClassFromFile(MutatedClassFileTestCaseEnum.inputDirOriginalJavaPath, classFileOfOriginalName) + val generatedClass = loadClassFromFile(MutatedClassFileTestCaseEnum.outputDirPath, classFileName) + + // (5) Compare the output of the main method in the original and mutated/generated classes + val originalOutput = invokeMainMethod(originalClass) + val generatedOutput = invokeMainMethod(generatedClass) + + // Assert that the outputs are the same + originalOutput shouldEqual generatedOutput + + } catch { + case ex: VerifyError => + println(s"Test Failure - Verification failed for test case: ${ex.getMessage}") + // Continue testing other cases + case ex: RuntimeException => + println(s"Test Failure - Runtime exception in test case: ${ex.getMessage}") + // Handle exceptions specific to runtime issues + case ex: Exception => + println(s"Test Failure - General exception: ${ex.getMessage}") + ex.printStackTrace() // Log stack trace for more info + } + } + + private def compileOriginalJavaFile(sourceFolder: String, javaFileName: String): Unit = { + val javaFilePath = Paths.get(MutatedClassFileTestCaseEnum.javaFileDirPath, sourceFolder, javaFileName).toString + val command = s"javac -d ${MutatedClassFileTestCaseEnum.inputDirOriginalJavaPath} $javaFilePath" + val result = command.! + + if (result != 0) { + throw new RuntimeException(s"Compilation of $javaFileName failed.") + } + } + + private def compileMutatedJavaFile(sourceFolder: String, javaFileName: String): Unit = { + val javaFilePath = Paths.get(MutatedClassFileTestCaseEnum.javaFileDirPath, sourceFolder, javaFileName).toString + val command = s"javac -d ${MutatedClassFileTestCaseEnum.inputDirMutatedJavaPath} $javaFilePath" + val result = command.! + + if (result != 0) { + throw new RuntimeException(s"Compilation of $javaFileName failed.") + } + } + + private def loadClassFromFile(dirPath: String, classFileName: String): Class[_] = { + val className = classFileName.replace(".class", "") + val classFile = new File(Paths.get(dirPath, classFileName).toString) + val classLoader = new InMemoryClassLoader(Map(className -> Files.readAllBytes(classFile.toPath))) + classLoader.findClass(className) + } + + private def invokeMainMethod(clazz: Class[_]): String = { + val outputStream = new ByteArrayOutputStream() + val printStream = new PrintStream(outputStream) + Console.withOut(printStream) { + clazz.getMethod("main", classOf[Array[String]]).invoke(null, Array[String]()) + } + outputStream.toString.trim + } +} diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/MutatedClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/MutatedClassFileTestCaseEnum.scala new file mode 100644 index 0000000000..dc9725444c --- /dev/null +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/MutatedClassFileTestCaseEnum.scala @@ -0,0 +1,78 @@ +package org.opalj.tactobc + +object MutatedClassFileTestCaseEnum extends Enumeration { + + // Fixed directories for input and output + val projectRoot: String = System.getProperty("user.dir") + val javaFileDirPath: String = s"$projectRoot/OPAL/tactobc/src/test/resources/javaFilesMutation" + val inputDirOriginalJavaPath: String = s"$projectRoot/OPAL/tactobc/src/test/classfilestocompare/mutation/original" + val inputDirMutatedJavaPath: String = s"$projectRoot/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated" + val outputDirPath: String = s"$projectRoot/OPAL/tactobc/src/test/classfilestocompare/mutation/generated" + + // Test cases with Java and Class file names + val testCases: Seq[TestCase] = Seq( + TestCase("ArithmeticOperations.java", "/arithmeticOperations", "ArithmeticOperations.class", "ArithmeticOperations_mutation_1.java", "ArithmeticOperations_mutation_1.class"), + TestCase("ArithmeticOperations.java", "/arithmeticOperations", "ArithmeticOperations.class", "ArithmeticOperations_mutation_2.java", "ArithmeticOperations_mutation_2.class"), + TestCase("ArithmeticOperations.java", "/arithmeticOperations", "ArithmeticOperations.class", "ArithmeticOperations_mutation_3.java", "ArithmeticOperations_mutation_3.class"), + TestCase("ArithmeticOperations.java", "/arithmeticOperations", "ArithmeticOperations.class", "ArithmeticOperations_mutation_4.java", "ArithmeticOperations_mutation_4.class"), + TestCase("ArithmeticOperations.java", "/arithmeticOperations", "ArithmeticOperations.class", "ArithmeticOperations_mutation_5.java", "ArithmeticOperations_mutation_5.class"), + TestCase("Array.java", "/array", "Array.class", "Array_mutation_1.java", "Array_mutation_1.class"), + TestCase("Array.java", "/array", "Array.class", "Array_mutation_2.java", "Array_mutation_2.class"), + TestCase("Array.java", "/array", "Array.class", "Array_mutation_3.java", "Array_mutation_3.class"), + TestCase("Array.java", "/array", "Array.class", "Array_mutation_4.java", "Array_mutation_4.class"), + TestCase("Array.java", "/array", "Array.class", "Array_mutation_5.java", "Array_mutation_5.class"), + TestCase("Assignment.java", "/assignment", "Assignment.class", "Assignment_mutation_1.java", "Assignment_mutation_1.class"), + TestCase("Assignment.java", "/assignment", "Assignment.class", "Assignment_mutation_2.java", "Assignment_mutation_2.class"), + TestCase("Assignment.java", "/assignment", "Assignment.class", "Assignment_mutation_3.java", "Assignment_mutation_3.class"), + TestCase("Assignment.java", "/assignment", "Assignment.class", "Assignment_mutation_4.java", "Assignment_mutation_4.class"), + TestCase("Assignment.java", "/assignment", "Assignment.class", "Assignment_mutation_5.java", "Assignment_mutation_5.class"), + TestCase("BigNumbers.java", "/bigNumbers", "BigNumbers.class", "BigNumbers_mutation_1.java", "BigNumbers_mutation_1.class"), + TestCase("BigNumbers.java", "/bigNumbers", "BigNumbers.class", "BigNumbers_mutation_2.java", "BigNumbers_mutation_2.class"), + TestCase("BigNumbers.java", "/bigNumbers", "BigNumbers.class", "BigNumbers_mutation_3.java", "BigNumbers_mutation_3.class"), + TestCase("BigNumbers.java", "/bigNumbers", "BigNumbers.class", "BigNumbers_mutation_4.java", "BigNumbers_mutation_4.class"), + TestCase("BigNumbers.java", "/bigNumbers", "BigNumbers.class", "BigNumbers_mutation_5.java", "BigNumbers_mutation_5.class"), + TestCase("CheckCast.java", "/checkCast", "CheckCast.class", "CheckCast_mutation_1.java", "CheckCast_mutation_1.class"), + TestCase("CheckCast.java", "/checkCast", "CheckCast.class", "CheckCast_mutation_2.java", "CheckCast_mutation_2.class"), + TestCase("CheckCast.java", "/checkCast", "CheckCast.class", "CheckCast_mutation_3.java", "CheckCast_mutation_3.class"), + TestCase("CheckCast.java", "/checkCast", "CheckCast.class", "CheckCast_mutation_4.java", "CheckCast_mutation_4.class"), + TestCase("CheckCast.java", "/checkCast", "CheckCast.class", "CheckCast_mutation_5.java", "CheckCast_mutation_5.class"), + TestCase("Compare.java", "/compare", "Compare.class", "Compare_mutation_1.java", "Compare_mutation_1.class"), + TestCase("Compare.java", "/compare", "Compare.class", "Compare_mutation_2.java", "Compare_mutation_2.class"), + TestCase("Compare.java", "/compare", "Compare.class", "Compare_mutation_3.java", "Compare_mutation_3.class"), + TestCase("Compare.java", "/compare", "Compare.class", "Compare_mutation_4.java", "Compare_mutation_4.class"), + TestCase("Compare.java", "/compare", "Compare.class", "Compare_mutation_5.java", "Compare_mutation_5.class"), + TestCase("Constants.java", "/constants", "Constants.class", "Constants_mutation_1.java", "Constants_mutation_1.class"), + TestCase("Constants.java", "/constants", "Constants.class", "Constants_mutation_2.java", "Constants_mutation_2.class"), + TestCase("Constants.java", "/constants", "Constants.class", "Constants_mutation_3.java", "Constants_mutation_3.class"), + TestCase("Constants.java", "/constants", "Constants.class", "Constants_mutation_4.java", "Constants_mutation_4.class"), + TestCase("Constants.java", "/constants", "Constants.class", "Constants_mutation_5.java", "Constants_mutation_5.class"), + TestCase("ForLoop.java", "/forLoop", "ForLoop.class", "ForLoop_mutation_1.java", "ForLoop_mutation_1.class"), + TestCase("ForLoop.java", "/forLoop", "ForLoop.class", "ForLoop_mutation_2.java", "ForLoop_mutation_2.class"), + TestCase("ForLoop.java", "/forLoop", "ForLoop.class", "ForLoop_mutation_3.java", "ForLoop_mutation_3.class"), + TestCase("ForLoop.java", "/forLoop", "ForLoop.class", "ForLoop_mutation_4.java", "ForLoop_mutation_4.class"), + TestCase("ForLoop.java", "/forLoop", "ForLoop.class", "ForLoop_mutation_5.java", "ForLoop_mutation_5.class"), + TestCase("If.java", "/if", "If.class", "If_mutation_1.java", "If_mutation_1.class"), + TestCase("If.java", "/if", "If.class", "If_mutation_2.java", "If_mutation_2.class"), + TestCase("If.java", "/if", "If.class", "If_mutation_3.java", "If_mutation_3.class"), + TestCase("If.java", "/if", "If.class", "If_mutation_4.java", "If_mutation_4.class"), + TestCase("If.java", "/if", "If.class", "If_mutation_5.java", "If_mutation_5.class"), + TestCase("If.java", "/ifZero", "If.class", "If_mutation_1.java", "If_mutation_1.class"), + TestCase("If.java", "/ifZero", "If.class", "If_mutation_2.java", "If_mutation_2.class"), + TestCase("If.java", "/ifZero", "If.class", "If_mutation_3.java", "If_mutation_3.class"), + TestCase("If.java", "/ifZero", "If.class", "If_mutation_4.java", "If_mutation_4.class"), + TestCase("If.java", "/ifZero", "If.class", "If_mutation_5.java", "If_mutation_5.class"), + TestCase("InstanceField.java", "/instanceField", "InstanceField.class", "InstanceField_mutation_1.java", "InstanceField_mutation_1.class"), + TestCase("InstanceField.java", "/instanceField", "InstanceField.class", "InstanceField_mutation_2.java", "InstanceField_mutation_2.class"), + TestCase("InstanceField.java", "/instanceField", "InstanceField.class", "InstanceField_mutation_3.java", "InstanceField_mutation_3.class"), + TestCase("InstanceField.java", "/instanceField", "InstanceField.class", "InstanceField_mutation_4.java", "InstanceField_mutation_4.class"), + TestCase("InstanceField.java", "/instanceField", "InstanceField.class", "InstanceField_mutation_5.java", "InstanceField_mutation_5.class"), + TestCase("InstanceOf.java", "/instanceOf", "InstanceOf.class", "InstanceOf_mutation_1.java", "InstanceOf_mutation_1.class"), + TestCase("InstanceOf.java", "/instanceOf", "InstanceOf.class", "InstanceOf_mutation_2.java", "InstanceOf_mutation_2.class"), + TestCase("InstanceOf.java", "/instanceOf", "InstanceOf.class", "InstanceOf_mutation_3.java", "InstanceOf_mutation_3.class"), + TestCase("InstanceOf.java", "/instanceOf", "InstanceOf.class", "InstanceOf_mutation_4.java", "InstanceOf_mutation_4.class"), + TestCase("InstanceOf.java", "/instanceOf", "InstanceOf.class", "InstanceOf_mutation_5.java", "InstanceOf_mutation_5.class") + ) + + // Case class to represent each test case + case class TestCase(originalJavaFileName: String, sourceFolder: String, classFileOfOriginalName: String, mutatedJavaFileName: String, generatedClassFileOfMutationName: String) +} From 673b3290eed5bdedbda295817b9f74714572f7e3 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Sat, 24 Aug 2024 11:46:44 +0200 Subject: [PATCH 090/111] added mutable java files testcases and fixed some input java files --- .../resources/javaFiles/Reassignment.java | 7 +- .../src/test/resources/javaFiles/Test.java | 10 +++ .../resources/javaFiles/TestingArrays.java | 21 ++++++ .../InstanceField_mutation_1.java | 2 +- .../InstanceField_mutation_2.java | 4 +- .../InstanceField_mutation_3.java | 2 +- .../InstanceField_mutation_4.java | 4 +- .../InstanceField_mutation_5.java | 2 +- .../InvokeDynamic_mutation_1.java | 2 +- .../InvokeDynamic_mutation_2.java | 2 +- .../InvokeDynamic_mutation_3.java | 2 +- .../InvokeDynamic_mutation_4.java | 26 +++++++ .../InvokeDynamic_mutation_5.java | 15 +++++ .../InvokeInterface_mutation_1.java | 22 ++++++ .../InvokeInterface_mutation_2.java | 21 ++++++ .../InvokeInterface_mutation_3.java | 23 +++++++ .../InvokeInterface_mutation_4.java | 21 ++++++ .../InvokeInterface_mutation_5.java | 23 +++++++ .../javaFilesMutation/jsr/Jsr_mutation_1.java | 19 ++++++ .../javaFilesMutation/jsr/Jsr_mutation_2.java | 19 ++++++ .../javaFilesMutation/jsr/Jsr_mutation_3.java | 22 ++++++ .../javaFilesMutation/jsr/Jsr_mutation_4.java | 18 +++++ .../javaFilesMutation/jsr/Jsr_mutation_5.java | 21 ++++++ .../methodCall/MethodCall.java | 48 ------------- .../methodCall/MethodCall_mutation_1.java | 15 +++++ .../methodCall/MethodCall_mutation_2.java | 16 +++++ .../methodCall/MethodCall_mutation_3.java | 13 ++++ .../methodCall/MethodCall_mutation_4.java | 14 ++++ .../methodCall/MethodCall_mutation_5.java | 19 ++++++ .../javaFilesMutation/negation/Negation.java | 11 --- .../negation/Negation_mutation_1.java | 24 +++++++ .../negation/Negation_mutation_2.java | 28 ++++++++ .../negation/Negation_mutation_3.java | 27 ++++++++ .../negation/Negation_mutation_4.java | 29 ++++++++ .../negation/Negation_mutation_5.java | 26 +++++++ .../ObjectPropertyAccess.java | 32 --------- .../ObjectPropertyAccess_mutation_1.java | 22 ++++++ .../ObjectPropertyAccess_mutation_2.java | 23 +++++++ .../ObjectPropertyAccess_mutation_3.java | 21 ++++++ .../ObjectPropertyAccess_mutation_4.java | 21 ++++++ .../ObjectPropertyAccess_mutation_5.java | 26 +++++++ .../parameters/Parameters.java | 38 ----------- .../parameters/Parameters_mutation_1.java | 18 +++++ .../parameters/Parameters_mutation_2.java | 16 +++++ .../parameters/Parameters_mutation_3.java | 24 +++++++ .../parameters/Parameters_mutation_4.java | 22 ++++++ .../parameters/Parameters_mutation_5.java | 26 +++++++ .../primitiveTypeCast/PrimitiveTypeCast.java | 31 --------- .../PrimitiveTypeCast_mutation_1.java | 18 +++++ .../PrimitiveTypeCast_mutation_2.java | 17 +++++ .../PrimitiveTypeCast_mutation_3.java | 15 +++++ .../PrimitiveTypeCast_mutation_4.java | 18 +++++ .../PrimitiveTypeCast_mutation_5.java | 13 ++++ .../reassignment/Reassignment.java | 24 ------- .../reassignment/Reassignment_mutation_1.java | 18 +++++ .../reassignment/Reassignment_mutation_2.java | 21 ++++++ .../reassignment/Reassignment_mutation_3.java | 22 ++++++ .../reassignment/Reassignment_mutation_4.java | 19 ++++++ .../reassignment/Reassignment_mutation_5.java | 18 +++++ .../staticField/StaticField_mutation_1.java | 26 +++++++ .../staticField/StaticField_mutation_2.java | 23 +++++++ .../staticField/StaticField_mutation_3.java | 23 +++++++ .../staticField/StaticField_mutation_4.java | 28 ++++++++ .../staticField/StaticField_mutation_5.java | 29 ++++++++ .../switch/Switch_mutation_1.java | 28 ++++++++ .../switch/Switch_mutation_2.java | 32 +++++++++ .../switch/Switch_mutation_3.java | 27 ++++++++ .../switch/Switch_mutation_4.java | 27 ++++++++ .../switch/Switch_mutation_5.java | 40 +++++++++++ .../whileLoop/WhileLoop.java | 45 ------------- .../whileLoop/WhileLoop_mutation_1.java | 22 ++++++ .../whileLoop/WhileLoop_mutation_2.java | 20 ++++++ .../whileLoop/WhileLoop_mutation_3.java | 19 ++++++ .../whileLoop/WhileLoop_mutation_4.java | 21 ++++++ .../whileLoop/WhileLoop_mutation_5.java | 20 ++++++ .../MutatedClassFileTestCaseEnum.scala | 67 +++++++++++++++++-- 76 files changed, 1350 insertions(+), 248 deletions(-) create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/Test.java create mode 100644 OPAL/tactobc/src/test/resources/javaFiles/TestingArrays.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_5.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_1.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_2.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_3.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_4.java create mode 100644 OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_5.java diff --git a/OPAL/tactobc/src/test/resources/javaFiles/Reassignment.java b/OPAL/tactobc/src/test/resources/javaFiles/Reassignment.java index 0c83f520a3..82d6d228b7 100644 --- a/OPAL/tactobc/src/test/resources/javaFiles/Reassignment.java +++ b/OPAL/tactobc/src/test/resources/javaFiles/Reassignment.java @@ -3,13 +3,14 @@ public class Reassignment { public static void main(String[] args) { int x = 10; int y = 5; - int z = 0; + int z = Integer.MAX_VALUE; + double test = 2.3d; System.out.println("Initial values - x: " + x + ", y: " + y + ", z: " + z); // Conditional reassignment - if (x > y) { - x = x + y; + if (-3< 0) { + x = Integer.MAX_VALUE+5; System.out.println("After conditional reassignment, x: " + x); } diff --git a/OPAL/tactobc/src/test/resources/javaFiles/Test.java b/OPAL/tactobc/src/test/resources/javaFiles/Test.java new file mode 100644 index 0000000000..91833263cd --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/Test.java @@ -0,0 +1,10 @@ +public class Test { + + public static void main(String[] args){ + int x = 0; + for (int i = 0; i < 3; i++){ + x += Integer.MAX_VALUE; + } + System.out.println(x); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFiles/TestingArrays.java b/OPAL/tactobc/src/test/resources/javaFiles/TestingArrays.java new file mode 100644 index 0000000000..b57aa4dbdc --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFiles/TestingArrays.java @@ -0,0 +1,21 @@ +public class TestingArrays { + + private int[] m = {1, 2, 3, 4, 5}; + private int i = 4; + private int j = 3; + public static void main(String[] args) { + // Isolate the operation that seems to cause issues + TestingArrays test = new TestingArrays(); + test.doSomething(); + } + + public int doSomething(){ + int k = this.m[this.i] - this.m[this.j]; + System.out.println("k = " + k); // Print the value of k for debugging + if (k < 0) { + k += Integer.MAX_VALUE; + System.out.println("k = " + k); // Print the value of k for debugging + } + return k; + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_1.java index bb17c6f009..c722dce7a8 100644 --- a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_1.java +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_1.java @@ -3,7 +3,7 @@ public class InstanceField_mutation_1 { private int instanceValue; public static void main(String[] args) { - InstanceField testInstance = new InstanceField(); + InstanceField_mutation_1 testInstance = new InstanceField_mutation_1(); int value = 42; testInstance.instanceValue = value; System.out.println("Instance field value: " + testInstance.instanceValue); diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_2.java index 9ef037f205..27f9cf3237 100644 --- a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_2.java +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_2.java @@ -2,12 +2,12 @@ public class InstanceField_mutation_2 { private int instanceValue; - public InstanceField(int value) { + public InstanceField_mutation_2(int value) { this.instanceValue = value; } public static void main(String[] args) { - InstanceField testInstance = new InstanceField(42); + InstanceField_mutation_2 testInstance = new InstanceField_mutation_2(42); System.out.println("Instance field value: " + testInstance.instanceValue); } } diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_3.java index 3cc8d5a8f1..e8ed201be1 100644 --- a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_3.java +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_3.java @@ -3,7 +3,7 @@ public class InstanceField_mutation_3 { private int instanceValue; public static void main(String[] args) { - InstanceField testInstance = new InstanceField(); + InstanceField_mutation_3 testInstance = new InstanceField_mutation_3(); testInstance.assignValue(42); System.out.println("Instance field value: " + testInstance.instanceValue); } diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_4.java index 9a56c94aa0..f62ed48749 100644 --- a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_4.java +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_4.java @@ -3,12 +3,12 @@ public class InstanceField_mutation_4 { private int instanceValue; public static void main(String[] args) { - InstanceField testInstance = new InstanceField(); + InstanceField_mutation_4 testInstance = new InstanceField_mutation_4(); initializeField(testInstance, 42); System.out.println("Instance field value: " + testInstance.instanceValue); } - private static void initializeField(InstanceField instance, int value) { + private static void initializeField(InstanceField_mutation_4 instance, int value) { instance.instanceValue = value; } } diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_5.java index 12ac0746ea..fb5dc0af9d 100644 --- a/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_5.java +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/instanceField/InstanceField_mutation_5.java @@ -3,7 +3,7 @@ public class InstanceField_mutation_5 { private Integer instanceValue; public static void main(String[] args) { - InstanceField testInstance = new InstanceField(); + InstanceField_mutation_5 testInstance = new InstanceField_mutation_5(); testInstance.instanceValue = Integer.valueOf(42); System.out.println("Instance field value: " + testInstance.instanceValue); } diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_1.java index 201b8d3d82..28887d1c60 100644 --- a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_1.java +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_1.java @@ -11,7 +11,7 @@ public static void main(String[] args) { System.out.println(greeting + ", World" + punctuation); // Method Reference - InvokeDynamic instance = new InvokeDynamic(); + InvokeDynamic_mutation_1 instance = new InvokeDynamic_mutation_1(); instance.runMethodReference(); } diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_2.java index dcdf715d55..e64eeac867 100644 --- a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_2.java +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_2.java @@ -10,7 +10,7 @@ public static void main(String[] args) { System.out.println(message); // Method Reference - new InvokeDynamic().methodReference(); + new InvokeDynamic_mutation_2().methodReference(); } private static void printLambdaMessage() { diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_3.java index 1025a1b310..bc3277d0c7 100644 --- a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_3.java +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_3.java @@ -10,7 +10,7 @@ public static void main(String[] args) { System.out.println(message); // Method Reference - new InvokeDynamic().methodReference(); + new InvokeDynamic_mutation_3().methodReference(); } private static void printLambdaMessage() { diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_4.java new file mode 100644 index 0000000000..5809a373eb --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_4.java @@ -0,0 +1,26 @@ +public class InvokeDynamic_mutation_4 { + + public static void main(String[] args) { + // Lambda Expression replaced with Method Reference + Runnable r = InvokeDynamic_mutation_4::printLambdaMessage; + r.run(); + + // String Concatenation using a method + printGreeting("Hello", "World"); + + // Method Reference + new InvokeDynamic_mutation_4().methodReferenceExample(); + } + + private static void printLambdaMessage() { + System.out.println("Running in a lambda!"); + } + + private static void printGreeting(String greeting, String target) { + System.out.println(greeting + ", " + target + "!"); + } + + public void methodReferenceExample() { + System.out.println("Method Reference Example"); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_5.java new file mode 100644 index 0000000000..aaa66b66a1 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeDynamic/InvokeDynamic_mutation_5.java @@ -0,0 +1,15 @@ +public class InvokeDynamic_mutation_5 { + + public static void main(String[] args) { + // Lambda Expression remains the same + Runnable r = () -> System.out.println("Running in a lambda!"); + r.run(); + + // Simplified String Concatenation + String message = "Hello, World!"; + System.out.println(message); + + // Inlined Method Reference Example + System.out.println("Method Reference Example"); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_1.java new file mode 100644 index 0000000000..7219e00989 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_1.java @@ -0,0 +1,22 @@ +import java.util.List; +import java.util.ArrayList; + +public class InvokeInterface_mutation_1 { + + public static void main(String[] args) { + // Create an instance of ArrayList, which implements the List interface + List myList = new ArrayList<>(); + + // Add elements to the list (invokeinterface) + myList.add("Hello"); + myList.add("World"); + + // Get the size of the list (invokeinterface) + int size = getSize(myList); + System.out.println("Size of the list: " + size); + } + + public static int getSize(List myList) { + return myList.size(); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_2.java new file mode 100644 index 0000000000..cf77b36f8c --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_2.java @@ -0,0 +1,21 @@ +import java.util.List; +import java.util.ArrayList; +public class InvokeInterface_mutation_2 { + + public static void main(String[] args) { + // Create an instance of ArrayList, which implements the List interface + List myList = new ArrayList<>(); + + // Add elements to the list + String[] arr = {"Hello"}; + myList.add(arr[0]); + + // Add elements to the list + String[] arr2 = {"World"}; + myList.add(arr2[0]); + + // Get the size of the list + int[] sizeArr = {myList.size()}; + System.out.println("Size of the list: " + sizeArr[0]); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_3.java new file mode 100644 index 0000000000..e7e0b7ad05 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_3.java @@ -0,0 +1,23 @@ +import java.util.List; +import java.util.ArrayList; +public class InvokeInterface_mutation_3 { + + public static void main(String[] args) { + // Create an instance of ArrayList, which implements the List interface + List myList = new ArrayList<>(); + + // Add elements to the list (invokeinterface) + myList.add("Hello"); + myList.add("World"); + + // Calculate the size of the list + int size = myList.size(); + int calculatedSize = size; // Store the result in a temporary variable + + // Get the size of the list (invokeinterface) + System.out.println("Size of the list: " + calculatedSize); + + // Print the list + System.out.println("Elements of the list: " + myList); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_4.java new file mode 100644 index 0000000000..809fcdae9e --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_4.java @@ -0,0 +1,21 @@ +import java.util.List; +import java.util.ArrayList; +public class InvokeInterface_mutation_4 { + + public static void main(String[] args) { + // Create an instance of ArrayList, which implements the List interface + List myList = new ArrayList<>(); + + // Create an array of elements to be added to the list + String[] elements = {"Hello", "World"}; + + // Add elements to the list (invokeinterface) + for (String element : elements) { + myList.add(element); + } + + // Get the size of the list (invokeinterface) + int[] sizeArray = {myList.size()}; + System.out.println("Size of the list: " + sizeArray[0]); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_5.java new file mode 100644 index 0000000000..1d1abfed2a --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/invokeInterface/InvokeInterface_mutation_5.java @@ -0,0 +1,23 @@ +import java.util.List; +import java.util.ArrayList; +public class InvokeInterface_mutation_5 { + + public static void main(String[] args) { + // Create an instance of ArrayList, which implements the List interface + List myList = new ArrayList<>(); + + // Create a class to hold the list size + class SizeHolder { + static int listSize = 0; + } + + // Add elements to the list + myList.add("Hello"); + myList.add("World"); + SizeHolder.listSize = myList.size(); + + // Get the size of the list from the SizeHolder class + int size = SizeHolder.listSize; + System.out.println("Size of the list: " + size); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_1.java new file mode 100644 index 0000000000..35accd0b58 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_1.java @@ -0,0 +1,19 @@ +public class Jsr_mutation_1 { + + public static void main(String[] args) { + System.out.println("Before subroutine"); + int[] arr = {3}; + executeSubroutine(arr); + System.out.println("After subroutine"); + } + + private static void executeSubroutine(int[] arr) { + System.out.println("In subroutine"); + // Simulating a subroutine with a loop or some operations + for (int i = arr[0]; i < arr[1]; i++) { + System.out.println("Subroutine iteration: " + i); + } + // Return from the subroutine (RET equivalent) + return; // RET is simulated by this return statement in Java + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_2.java new file mode 100644 index 0000000000..f0033ee404 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_2.java @@ -0,0 +1,19 @@ +public class Jsr_mutation_2 { + + public static void main(String[] args) { + System.out.println("Before subroutine"); + executeSubroutine(); + System.out.println("After subroutine"); + } + + private static void executeSubroutine() { + System.out.println("In subroutine"); + // Simulating a subroutine with a loop or some operations + for (int i = 0; i < 3; i++) { + System.out.println("Subroutine iteration: " + i); + } + if (true) { + return; // RET is simulated by this return statement in Java + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_3.java new file mode 100644 index 0000000000..6ccc5046b4 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_3.java @@ -0,0 +1,22 @@ +public class Jsr_mutation_3 { + + public static void main(String[] args) { + System.out.println("Before subroutine"); + executeSubroutine(); + System.out.println("After subroutine"); + } + + private static void executeSubroutine() { + System.out.println("In subroutine"); + for (int i = 0; i < 3; i++) { + printIteration(i); + System.out.println("Subroutine iteration: " + i); + } + // Return from the subroutine (RET equivalent) + return; // RET is simulated by this return statement in Java + } + + private static void printIteration(int i) { + System.out.println("Subroutine iteration: " + i); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_4.java new file mode 100644 index 0000000000..7a57b7fe5b --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_4.java @@ -0,0 +1,18 @@ +public class Jsr_mutation_4 { + + public static void main(String[] args) { + System.out.println("Before subroutine"); + System.out.println("After subroutine"); + executeSubroutine(); + } + + private static void executeSubroutine() { + System.out.println("In subroutine"); + // Simulating a subroutine with a loop or some operations + for (int i = 0; i < 3; i++) { + System.out.println("Subroutine iteration: " + i); + } + // Return from the subroutine (RET equivalent) + return; // RET is simulated by this return statement in Java + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_5.java new file mode 100644 index 0000000000..331170caf0 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/jsr/Jsr_mutation_5.java @@ -0,0 +1,21 @@ +public class Jsr_mutation_5 { + + public static void main(String[] args) { + System.out.println("Before subroutine"); + executeSubroutine(); + System.out.println("After subroutine"); + } + + private static void executeSubroutine() { + System.out.println("In subroutine"); + for (int i = 0; i < 3; i++) { + printIteration(i); + } + // Return from the subroutine (RET equivalent) + return; // RET is simulated by this return statement in Java + } + + private static void printIteration(int i) { + System.out.println("Subroutine iteration: " + i); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall.java index 0f040d0301..a6fbd6ede8 100644 --- a/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall.java +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall.java @@ -5,58 +5,10 @@ public static void main(String[] args) { MethodCall instance = new MethodCall(); int instanceResult = instance.instanceMethod(5, 3); System.out.println("Instance method result: " + instanceResult); - - // Static method call - int staticResult = staticMethod(10, 2); - System.out.println("Static method result: " + staticResult); - - // Overloaded method call - String overloadedResult1 = instance.overloadedMethod(5); - String overloadedResult2 = instance.overloadedMethod(5, 3); - System.out.println("Overloaded method result (1 parameter): " + overloadedResult1); - System.out.println("Overloaded method result (2 parameters): " + overloadedResult2); - - // Calling a method that calls another method - int nestedCallResult = instance.nestedMethodCall(7, 3); - System.out.println("Nested method call result: " + nestedCallResult); - - // Method with multiple return statements - int multipleReturnResult = instance.multipleReturnMethod(15); - System.out.println("Multiple return method result: " + multipleReturnResult); } // Instance method public int instanceMethod(int a, int b) { return a + b; } - - // Static method - public static int staticMethod(int x, int y) { - return x * y; - } - - // Overloaded methods - public String overloadedMethod(int a) { - return "Overloaded with one parameter: " + a; - } - - public String overloadedMethod(int a, int b) { - return "Overloaded with two parameters: " + (a + b); - } - - // Method that calls another method - public int nestedMethodCall(int a, int b) { - return instanceMethod(a, b) * staticMethod(a, b); - } - - // Method with multiple return statements - public int multipleReturnMethod(int value) { - if (value > 10) { - return value * 2; - } else if (value == 10) { - return value * 3; - } else { - return value * 4; - } - } } diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_1.java new file mode 100644 index 0000000000..18eeb07aff --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_1.java @@ -0,0 +1,15 @@ +public class MethodCall_mutation_1 { + + public static void main(String[] args) { + // Instance method call + MethodCall_mutation_1 instance = new MethodCall_mutation_1(); + int instanceResult = instance.instanceMethod(5, 3); + int tempResult = instanceResult; // Temporary variable + System.out.println("Instance method result: " + tempResult); + } + + // Instance method + public int instanceMethod(int a, int b) { + return a + b; + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_2.java new file mode 100644 index 0000000000..682b69f25b --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_2.java @@ -0,0 +1,16 @@ +public class MethodCall_mutation_2 { + + public static void main(String[] args) { + // Instance method call + MethodCall_mutation_2 instance = new MethodCall_mutation_2(); + int instanceResult = instance.instanceMethod(5, 3); + if (true) { // Redundant if statement + System.out.println("Instance method result: " + instanceResult); + } + } + + // Instance method + public int instanceMethod(int a, int b) { + return a + b; + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_3.java new file mode 100644 index 0000000000..875423c6e2 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_3.java @@ -0,0 +1,13 @@ +public class MethodCall_mutation_3 { + + public static void main(String[] args) { + // Instance method call inlined + MethodCall_mutation_3 instance = new MethodCall_mutation_3(); + System.out.println("Instance method result: " + instance.instanceMethod(5, 3)); + } + + // Instance method + public int instanceMethod(int a, int b) { + return a + b; + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_4.java new file mode 100644 index 0000000000..08635dcc49 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_4.java @@ -0,0 +1,14 @@ +public class MethodCall_mutation_4 { + + public static void main(String[] args) { + // Instance method call with parameters swapped + MethodCall_mutation_4 instance = new MethodCall_mutation_4(); + int instanceResult = instance.instanceMethod(3, 5); // Parameters swapped + System.out.println("Instance method result: " + instanceResult); + } + + // Instance method + public int instanceMethod(int a, int b) { + return a + b; + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_5.java new file mode 100644 index 0000000000..ffd396c66a --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/methodCall/MethodCall_mutation_5.java @@ -0,0 +1,19 @@ +public class MethodCall_mutation_5 { + + public static void main(String[] args) { + // Instance method call + MethodCall_mutation_5 instance = new MethodCall_mutation_5(); + int instanceResult = instance.instanceMethod(5, 3); + instance.printResult(instanceResult); + } + + // Instance method + public int instanceMethod(int a, int b) { + return a + b; + } + + // New method to print the result + public void printResult(int result) { + System.out.println("Instance method result: " + result); + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation.java index 51998462dd..f003a6e062 100644 --- a/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation.java +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation.java @@ -20,16 +20,5 @@ public static void main(String[] args) { double doubleValue = 2.71828; double negatedDouble = -doubleValue; System.out.println("Negated double: " + negatedDouble); - - // Test negation in expressions - int exprInt = -(intValue + 10); - long exprLong = -(longValue * 2); - float exprFloat = -(floatValue / 2.0f); - double exprDouble = -(doubleValue - 1.0); - - System.out.println("Negated int in expression: " + exprInt); - System.out.println("Negated long in expression: " + exprLong); - System.out.println("Negated float in expression: " + exprFloat); - System.out.println("Negated double in expression: " + exprDouble); } } diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_1.java new file mode 100644 index 0000000000..69297369f3 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_1.java @@ -0,0 +1,24 @@ +public class Negation_mutation_1 { + + public static void main(String[] args) { + // Integer negation + int[] intValueArr = {42}; + int negatedInt = -intValueArr[0]; + System.out.println("Negated int: " + negatedInt); + + // Long negation + long longValue = 123456789L; + long negatedLong = -longValue; + System.out.println("Negated long: " + negatedLong); + + // Float negation + float[] floatValueArr = {(float) 3.14}; + float negatedFloat = -floatValueArr[0]; + System.out.println("Negated float: " + negatedFloat); + + // Double negation + double doubleValue = 2.71828; + double negatedDouble = -doubleValue; + System.out.println("Negated double: " + negatedDouble); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_2.java new file mode 100644 index 0000000000..9caa0313d2 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_2.java @@ -0,0 +1,28 @@ +public class Negation_mutation_2 { + + public static void main(String[] args) { + // Integer negation + int intValue = 42; + int negatedInt = negate(intValue); + System.out.println("Negated int: " + negatedInt); + + // Long negation + long longValue = 123456789L; + long negatedLong = -longValue; + System.out.println("Negated long: " + negatedLong); + + // Float negation + float floatValue = 3.14f; + float negatedFloat = -floatValue; + System.out.println("Negated float: " + negatedFloat); + + // Double negation + double doubleValue = 2.71828; + double negatedDouble = -doubleValue; + System.out.println("Negated double: " + negatedDouble); + } + + public static int negate(int value) { + return -value; + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_3.java new file mode 100644 index 0000000000..28aee7839f --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_3.java @@ -0,0 +1,27 @@ +public class Negation_mutation_3 { + + public static void main(String[] args) { + // Integer negation + int[] intArr = {42}; + int intValue = intArr[0]; + int negatedInt = -intValue; + System.out.println("Negated int: " + negatedInt); + + // Long negation + long longValue = 123456789L; + long negatedLong = -longValue; + System.out.println("Negated long: " + negatedLong); + + // Float negation + float[] floatArr = {(float) 3.14}; + float floatValue = floatArr[0]; + float negatedFloat = -floatValue; + System.out.println("Negated float: " + negatedFloat); + + // Double negation + double[] doubleArr = {2.71828}; + double doubleValue = doubleArr[0]; + double negatedDouble = -doubleValue; + System.out.println("Negated double: " + negatedDouble); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_4.java new file mode 100644 index 0000000000..7a8c8e7b0f --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_4.java @@ -0,0 +1,29 @@ +public class Negation_mutation_4 { + + private static int INT_FIELD = 42; + private static long LONG_FIELD = 123456789L; + private static float FLOAT_FIELD = 3.14f; + private static double DOUBLE_FIELD = 2.71828; + + public static void main(String[] args) { + // Integer negation + int intValue = INT_FIELD; + int negatedInt = -intValue; + System.out.println("Negated int: " + negatedInt); + + // Long negation + long longValue = LONG_FIELD; + long negatedLong = -longValue; + System.out.println("Negated long: " + negatedLong); + + // Float negation + float floatValue = FLOAT_FIELD; + float negatedFloat = -floatValue; + System.out.println("Negated float: " + negatedFloat); + + // Double negation + double doubleValue = DOUBLE_FIELD; + double negatedDouble = -doubleValue; + System.out.println("Negated double: " + negatedDouble); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_5.java new file mode 100644 index 0000000000..b3ab1f0c11 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/negation/Negation_mutation_5.java @@ -0,0 +1,26 @@ +public class Negation_mutation_5 { + + public static void main(String[] args) { + // Integer negation + int intValue = 42; + if (true) { + int negatedInt = -intValue; + } + System.out.println("Negated int: " + intValue); + + // Long negation + long longValue = 123456789L; + long negatedLong = -longValue; + System.out.println("Negated long: " + negatedLong); + + // Float negation + float floatValue = 3.14f; + float negatedFloat = -floatValue; + System.out.println("Negated float: " + negatedFloat); + + // Double negation + double doubleValue = 2.71828; + double negatedDouble = -doubleValue; + System.out.println("Negated double: " + negatedDouble); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess.java index 8e46818e0d..61bfe555df 100644 --- a/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess.java +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess.java @@ -17,37 +17,5 @@ public void runTests() { this.j = 3; // Refers to m[3] = 40 this.k = this.m[this.i] - this.m[this.j]; System.out.println("Test 1 (m[4] - m[3]): k = " + this.k); // Expected: 10 - - // Test case 2: Subtraction leading to zero - this.i = 2; // Refers to m[2] = 30 - this.j = 2; // Refers to m[2] = 30 - this.k = this.m[this.i] - this.m[this.j]; - System.out.println("Test 2 (m[2] - m[2]): k = " + this.k); // Expected: 0 - - // Test case 3: Subtraction leading to a negative result - this.i = 1; // Refers to m[1] = 20 - this.j = 4; // Refers to m[4] = 50 - this.k = this.m[this.i] - this.m[this.j]; - System.out.println("Test 3 (m[1] - m[4]): k = " + this.k); // Expected: -30 - - // Test case 4: Subtraction at boundary values (first element) - this.i = 0; // Refers to m[0] = 10 - this.j = 4; // Refers to m[4] = 50 - this.k = this.m[this.i] - this.m[this.j]; - System.out.println("Test 4 (m[0] - m[4]): k = " + this.k); // Expected: -40 - - // Test case 5: Subtraction at boundary values (last element) - this.i = 4; // Refers to m[4] = 50 - this.j = 0; // Refers to m[0] = 10 - this.k = this.m[this.i] - this.m[this.j]; - System.out.println("Test 5 (m[4] - m[0]): k = " + this.k); // Expected: 40 - - // Test case 6: Subtraction leading to potential overflow/underflow - this.m = new int[]{Integer.MAX_VALUE, Integer.MIN_VALUE}; - this.i = 0; // Refers to Integer.MAX_VALUE - this.j = 1; // Refers to Integer.MIN_VALUE - this.k = this.m[this.i] - this.m[this.j]; - System.out.println("Test 6 (Integer.MAX_VALUE - Integer.MIN_VALUE): k = " + this.k); - // Expected: Large positive value, may demonstrate overflow behavior } } diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_1.java new file mode 100644 index 0000000000..58d1779b12 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_1.java @@ -0,0 +1,22 @@ +public class ObjectPropertyAccess_mutation_1 { + + // Object attributes + private int[] m = {10, 20, 30, 40, 50}; // Example array + private int i; // Index i + private int j; // Index j + private int k; // Result of subtraction + + public static void main(String[] args) { + ObjectPropertyAccess_mutation_1 test = new ObjectPropertyAccess_mutation_1(); + test.runTests(); + } + + public void runTests() { + // Test case 1: Normal subtraction + this.i = 4; // Refers to m[4] = 50 + this.j = 3; // Refers to m[3] = 40 + int tempResult = this.m[this.i] - this.m[this.j]; // Temporary variable + this.k = tempResult; + System.out.println("Test 1 (m[4] - m[3]): k = " + this.k); // Expected: 10 + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_2.java new file mode 100644 index 0000000000..966c019025 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_2.java @@ -0,0 +1,23 @@ +public class ObjectPropertyAccess_mutation_2 { + + // Object attributes + private int[] m = {10, 20, 30, 40, 50}; // Example array + private int i; // Index i + private int j; // Index j + private int k; // Result of subtraction + + public static void main(String[] args) { + ObjectPropertyAccess_mutation_2 test = new ObjectPropertyAccess_mutation_2(); + test.runTests(); + } + + public void runTests() { + // Test case 1: Normal subtraction + this.i = 4; // Refers to m[4] = 50 + this.j = 3; // Refers to m[3] = 40 + if (true) { // Redundant if statement + this.k = this.m[this.i] - this.m[this.j]; + } + System.out.println("Test 1 (m[4] - m[3]): k = " + this.k); // Expected: 10 + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_3.java new file mode 100644 index 0000000000..0f6d23e9d0 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_3.java @@ -0,0 +1,21 @@ +public class ObjectPropertyAccess_mutation_3 { + + // Object attributes + private int[] m = {10, 20, 30, 40, 50}; // Example array + private int i; // Index i + private int j; // Index j + private int k; // Result of subtraction + + public static void main(String[] args) { + ObjectPropertyAccess_mutation_3 test = new ObjectPropertyAccess_mutation_3(); + test.runTests(); + } + + public void runTests() { + // Test case 1: Normal subtraction + this.i = 4; // Refers to m[4] = 50 + this.j = 3; // Refers to m[3] = 40 + this.k = this.m[this.i] - this.m[this.j]; + System.out.println("Test 1 (m[4] - m[3]): k = " + (this.m[this.i] - this.m[this.j])); // Inlined subtraction + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_4.java new file mode 100644 index 0000000000..909c4083d3 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_4.java @@ -0,0 +1,21 @@ +public class ObjectPropertyAccess_mutation_4 { + + // Object attributes + private int[] m = {10, 20, 30, 40, 50}; // Example array + private int i; // Index i + private int j; // Index j + private int k; // Result of subtraction + + public static void main(String[] args) { + ObjectPropertyAccess_mutation_4 test = new ObjectPropertyAccess_mutation_4(); + test.runTests(); + } + + public void runTests() { + // Test case 1: Normal subtraction + this.j = 3; // Refers to m[3] = 40 + this.i = 4; // Refers to m[4] = 50 + this.k = this.m[this.i] - this.m[this.j]; + System.out.println("Test 1 (m[4] - m[3]): k = " + this.k); // Expected: 10 + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_5.java new file mode 100644 index 0000000000..bdcf33bf9f --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/objectPropertyAccess/ObjectPropertyAccess_mutation_5.java @@ -0,0 +1,26 @@ +public class ObjectPropertyAccess_mutation_5 { + + // Object attributes + private int[] m = {10, 20, 30, 40, 50}; // Example array + private int i; // Index i + private int j; // Index j + private int k; // Result of subtraction + + public static void main(String[] args) { + ObjectPropertyAccess_mutation_5 test = new ObjectPropertyAccess_mutation_5(); + test.runTests(); + } + + public void runTests() { + // Test case 1: Normal subtraction + this.i = 4; // Refers to m[4] = 50 + this.j = 3; // Refers to m[3] = 40 + this.k = calculateDifference(this.i, this.j); + System.out.println("Test 1 (m[4] - m[3]): k = " + this.k); // Expected: 10 + } + + // New method to calculate the difference + private int calculateDifference(int i, int j) { + return this.m[i] - this.m[j]; + } +} diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters.java index 183d63eb2a..c0c38fc3b7 100644 --- a/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters.java +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters.java @@ -7,17 +7,6 @@ public static void main(String[] args) { char c = 'A'; System.out.println("Sum of int and double: " + sum(a, b)); - System.out.println("Character to int: " + charToInt(c)); - - // Test with array parameters - int[] numbers = {1, 2, 3, 4, 5}; - System.out.println("Sum of array elements: " + sumArray(numbers)); - - // Test with varargs - System.out.println("Sum with varargs: " + sumVarArgs(1, 2, 3, 4, 5)); - - // Test with multiple primitive parameters - System.out.println("Average of three numbers: " + average(5, 10, 15)); } // Method with primitive parameters @@ -25,31 +14,4 @@ public static double sum(int x, double y) { return x + y; } - // Method with a char parameter - public static int charToInt(char ch) { - return ch; - } - - // Method with an array parameter - public static int sumArray(int[] array) { - int sum = 0; - for (int num : array) { - sum += num; - } - return sum; - } - - // Method with varargs parameter - public static int sumVarArgs(int... numbers) { - int sum = 0; - for (int num : numbers) { - sum += num; - } - return sum; - } - - // Method with multiple primitive parameters - public static double average(int x, int y, int z) { - return (x + y + z) / 3.0; - } } diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_1.java new file mode 100644 index 0000000000..e6271c4748 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_1.java @@ -0,0 +1,18 @@ +public class Parameters_mutation_1 { + + public static void main(String[] args) { + // Test with primitive types + int a = 10; + double b = 20.5; + char c = 'A'; + + double sumResult = sum(a, b); + System.out.println("Sum of int and double: " + sumResult); + } + + // Method with primitive parameters + public static double sum(int x, double y) { + return x + y; + } + +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_2.java new file mode 100644 index 0000000000..a85c33a7a7 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_2.java @@ -0,0 +1,16 @@ +public class Parameters_mutation_2 { + + public static void main(String[] args) { + // Test with primitive types + int[] aArray = {10}; + double b = 20.5; + char c = 'A'; + + System.out.println("Sum of int and double: " + sum(aArray[0], b)); + } + + // Method with primitive parameters + public static double sum(int x, double y) { + return x + y; + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_3.java new file mode 100644 index 0000000000..4bb79ab688 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_3.java @@ -0,0 +1,24 @@ +public class Parameters_mutation_3 { + + public static void main(String[] args) { + // Create a class with static fields + Parameters_mutation_3 myclass = new Parameters_mutation_3(); + + // Test with primitive types + int a = myclass.x; // replaced direct value assignment with an assignment through a new instance + double b = myclass.y; + char c = myclass.charValue; + + System.out.println("Sum of int and double: " + sum(a, b)); + } + + // Method with primitive parameters + public static double sum(int x, double y) { + return x + y; + } + + // Static fields + public static int x = 10; + public static double y = 20.5; + public static char charValue = 'A'; +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_4.java new file mode 100644 index 0000000000..7960af5f8d --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_4.java @@ -0,0 +1,22 @@ +public class Parameters_mutation_4 { + + public static void main(String[] args) { + // Test with primitive types + int a = 10; + double b = 20.5; + char c = 'A'; + + // Create a new instance of Parameters + Parameters_mutation_4 myclass = new Parameters_mutation_4(); + + System.out.println("Sum of int and double: " + sum(a, myclass.myDouble)); + } + + // Method with primitive parameters + public double myDouble = 0.0; + + public static double sum(int x, double y) { + return x + y; + } + +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_5.java new file mode 100644 index 0000000000..53b88c2278 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/parameters/Parameters_mutation_5.java @@ -0,0 +1,26 @@ +public class Parameters_mutation_5{ + + public static void main(String[] args) { + // Test with primitive types + int a = Parameters_mutation_5.fieldInt; + double b = Parameters_mutation_5.fieldDouble; + char c = Parameters_mutation_5.fieldChar; + + System.out.println("Sum of int and double: " + sum(a, b)); + } + + // Method with primitive parameters + public static double sum(int x, double y) { + return x + y; + } + + static { + fieldInt = 10; + fieldDouble = 20.5; + fieldChar = 'A'; + } + + static int fieldInt; + static double fieldDouble; + static char fieldChar; +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast.java index 4df4a750c6..2ab109a9de 100644 --- a/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast.java +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast.java @@ -3,44 +3,13 @@ public class PrimitiveTypeCast { public static void main(String[] args) { // Initial values int intValue = 100; - double doubleValue = 123.456; - long longValue = 9876543210L; - float floatValue = 3.14f; //Cast to different types // int to byte, short, char byte byteValue = (byte) intValue; - short shortValue = (short) intValue; - char charValue = (char) intValue; - - // long to int, float, double - int intFromLong = (int) longValue; - float floatFromLong = (float) longValue; - double doubleFromLong = (double) longValue; - - // double to int, long, float - int intFromDouble = (int) doubleValue; - long longFromDouble = (long) doubleValue; - float floatFromDouble = (float) doubleValue; - - // float to int, long, double - int intFromFloat = (int) floatValue; - long longFromFloat = (long) floatValue; - double doubleFromFloat = (double) floatValue; // Output the results System.out.println("int to byte: " + byteValue); - System.out.println("int to short: " + shortValue); - System.out.println("int to char: " + (int) charValue); // Print char as int to show ASCII value - System.out.println("long to int: " + intFromLong); - System.out.println("long to float: " + floatFromLong); - System.out.println("long to double: " + doubleFromLong); - System.out.println("double to int: " + intFromDouble); - System.out.println("double to long: " + longFromDouble); - System.out.println("double to float: " + floatFromDouble); - System.out.println("float to int: " + intFromFloat); - System.out.println("float to long: " + longFromFloat); - System.out.println("float to double: " + doubleFromFloat); } } diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_1.java new file mode 100644 index 0000000000..30fc47d0df --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_1.java @@ -0,0 +1,18 @@ +public class PrimitiveTypeCast_mutation_1 { + + public static void main(String[] args) { + // Initial values + int intValue = 100; + + // Calculate the result + int intermediateValue = intValue - 50; + + //Cast to different types + + // int to byte, short, char + byte byteValue = (byte) intermediateValue; + + // Output the results + System.out.println("int to byte: " + byteValue); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_2.java new file mode 100644 index 0000000000..eafbc9c90d --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_2.java @@ -0,0 +1,17 @@ +public class PrimitiveTypeCast_mutation_2 { + + public static void main(String[] args) { + // Initial values + int intValue = 100; + + //Cast to different types + + // int to byte, short, char + if (true) { + byte byteValue = (byte) intValue; + } + + // Output the results + System.out.println("int to byte: " + (byte) intValue); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_3.java new file mode 100644 index 0000000000..e552784bb8 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_3.java @@ -0,0 +1,15 @@ +public class PrimitiveTypeCast_mutation_3 { + + public static void main(String[] args) { + // Initial values + int[] intValueArr = {100}; + + //Cast to different types + + // int to byte, short, char + byte byteValue = (byte) intValueArr[0]; + + // Output the results + System.out.println("int to byte: " + byteValue); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_4.java new file mode 100644 index 0000000000..a5f4a281b7 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_4.java @@ -0,0 +1,18 @@ +public class PrimitiveTypeCast_mutation_4 { + + public static void main(String[] args) { + // Initial values + int intValue = 100; + + // Perform a calculation + int calculationResult = intValue * 2; + + //Cast to different types + + // Store the result in a temporary variable + byte byteValue = (byte) calculationResult; + + // Output the results + System.out.println("int to byte: " + byteValue); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_5.java new file mode 100644 index 0000000000..1d11660010 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/primitiveTypeCast/PrimitiveTypeCast_mutation_5.java @@ -0,0 +1,13 @@ +public class PrimitiveTypeCast_mutation_5 { + + public static void main(String[] args) { + // Initial values + int intValue = 100; + + // Output the results + System.out.println("int to byte: " + (byte) intValue); + + // int to byte, short, char + byte byteValue = (byte) intValue; + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment.java index 82d6d228b7..1cd1db1e26 100644 --- a/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment.java +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment.java @@ -13,29 +13,5 @@ public static void main(String[] args) { x = Integer.MAX_VALUE+5; System.out.println("After conditional reassignment, x: " + x); } - - // Loop with reassignment - for (int i = 0; i < 3; i++) { - z = z + (x * i) - y; - System.out.println("After loop iteration " + i + ", z: " + z); - } - - // Nested reassignments - if (z > 10) { - x = x * 2; - y = y + z; - z = x - y; - System.out.println("After nested reassignment, x: " + x + ", y: " + y + ", z: " + z); - } - - // Reassign using previous values - z = (x * y) + z; - System.out.println("Final value of z after using previous values: " + z); - - // Complex reassignments with multiple operations - x = x + (y - z) * 2; - y = y * 3 + z - x; - z = x - y + z; - System.out.println("Complex final values - x: " + x + ", y: " + y + ", z: " + z); } } diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_1.java new file mode 100644 index 0000000000..0175c20c6c --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_1.java @@ -0,0 +1,18 @@ +public class Reassignment_mutation_1 { + + public static void main(String[] args) { + int x = 10; + int y = 5; + int z = Integer.MAX_VALUE; + double test = 2.3d; + + System.out.println("Initial values - x: " + x + ", y: " + y + ", z: " + z); + + // Conditional reassignment + int[] arr = {Integer.MAX_VALUE+5}; + if (-3< 0) { + x = arr[0]; + System.out.println("After conditional reassignment, x: " + x); + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_2.java new file mode 100644 index 0000000000..d8687c033b --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_2.java @@ -0,0 +1,21 @@ +public class Reassignment_mutation_2 { + + public static class Myclass { + public static int field = Integer.MAX_VALUE; + } + + public static void main(String[] args) { + int x = 10; + int y = 5; + int z = Myclass.field; + double test = 2.3d; + + System.out.println("Initial values - x: " + x + ", y: " + y + ", z: " + z); + + // Conditional reassignment + if (-3< 0) { + x = Myclass.field + 5; + System.out.println("After conditional reassignment, x: " + x); + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_3.java new file mode 100644 index 0000000000..cbdce5a3f7 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_3.java @@ -0,0 +1,22 @@ +public class Reassignment_mutation_3 { + + public static void main(String[] args) { + int x = 10; + int y = 5; + int z = Integer.MAX_VALUE; + double test = 2.3d; + + System.out.println("Initial values - x: " + x + ", y: " + y + ", z: " + z); + + // Conditional reassignment + x = performCalculation(x); + System.out.println("After conditional reassignment, x: " + x); + } + + public static int performCalculation(int x) { + if (-3 < 0) { + return Integer.MAX_VALUE + 5; + } + return x; + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_4.java new file mode 100644 index 0000000000..1666ac1e95 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_4.java @@ -0,0 +1,19 @@ +public class Reassignment_mutation_4 { + + public static void main(String[] args) { + int x = 10; + int y = 5; + int z = Integer.MAX_VALUE; + double test = 2.3d; + + System.out.println("Initial values - x: " + x + ", y: " + y + ", z: " + z); + + System.out.println("After conditional reassignment, x: " + x); + + // Conditional reassignment + if (-3< 0) { + x = Integer.MAX_VALUE+5; + } + System.out.println("Initial values - x: " + x + ", y: " + y + ", z: " + z); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_5.java new file mode 100644 index 0000000000..ae5970a0f2 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/reassignment/Reassignment_mutation_5.java @@ -0,0 +1,18 @@ +public class Reassignment_mutation_5 { + + public static void main(String[] args) { + int x = 10; + int y = 5; + int z = Integer.MAX_VALUE; + double test = 2.3d; + + System.out.println("Initial values - x: " + x + ", y: " + y + ", z: " + z); + + // Conditional reassignment + if (-3< 0) { + int temp = Integer.MAX_VALUE+5; + x = temp; + System.out.println("After conditional reassignment, x: " + x); + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_1.java new file mode 100644 index 0000000000..be281b1934 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_1.java @@ -0,0 +1,26 @@ +public class StaticField_mutation_1 { + + // A static field + private static int staticValue; + + public static void main(String[] args) { + // Perform a calculation and store the result in a temporary variable + int temp = 42; + + // Set the static field + setStaticValue(temp); + + // Get the static field value and print it + System.out.println("Static field value: " + getStaticValue()); + } + + // Method to set the static field + public static void setStaticValue(int value) { + staticValue = value; + } + + // Method to get the static field value + public static int getStaticValue() { + return staticValue; + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_2.java new file mode 100644 index 0000000000..1bc460d1cd --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_2.java @@ -0,0 +1,23 @@ +public class StaticField_mutation_2 { + + // A static field + private static int staticValue; + + public static void main(String[] args) { + // Set the static field + StaticField_mutation_2.staticValue = 42; // replaced direct assignment with assignment through a static field + + // Get the static field value and print it + System.out.println("Static field value: " + getStaticValue()); + } + + // Method to set the static field + public static void setStaticValue(int value) { + staticValue = value; + } + + // Method to get the static field value + public static int getStaticValue() { + return staticValue; + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_3.java new file mode 100644 index 0000000000..d43ae2edf0 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_3.java @@ -0,0 +1,23 @@ +public class StaticField_mutation_3 { + + // A static field + private static int staticValue; + + public static void main(String[] args) { + // Set the static field + staticValue = 42; // replaced setStaticValue(42) with staticValue = 42 + + // Get the static field value and print it + System.out.println("Static field value: " + staticValue); + } + + // Method to set the static field + public static void setStaticValue(int value) { + staticValue = value; + } + + // Method to get the static field value + public static int getStaticValue() { + return staticValue; + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_4.java new file mode 100644 index 0000000000..1b10089225 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_4.java @@ -0,0 +1,28 @@ +public class StaticField_mutation_4 { + + // A static field + private static int staticValue; + + public static void main(String[] args) { + // Set the static field + setStaticValue(42); + + // Print the static field value + printStaticFieldValue(); + } + + // Method to set the static field + public static void setStaticValue(int value) { + staticValue = value; + } + + // Method to get the static field value + public static int getStaticValue() { + return staticValue; + } + + // Method to print the static field value + public static void printStaticFieldValue() { + System.out.println("Static field value: " + getStaticValue()); + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_5.java new file mode 100644 index 0000000000..cd1352e72d --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/staticField/StaticField_mutation_5.java @@ -0,0 +1,29 @@ +public class StaticField_mutation_5 { + + // A static field + private static int staticValue; + + public static void main(String[] args) { + // Set the static field + setStaticValue(42); + + // Get the static field value and print it + System.out.println("Static field value: " + getStaticValue()); + } + + // Method to set the static field + public static void setStaticValue(int value) { + calculateStaticValue(value); + staticValue = value; + } + + // Method to calculate and set the static field value + public static void calculateStaticValue(int value) { + value = value * 2; + } + + // Method to get the static field value + public static int getStaticValue() { + return staticValue; + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_1.java new file mode 100644 index 0000000000..4e4b0b23f9 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_1.java @@ -0,0 +1,28 @@ +public class Switch_mutation_1 { + + public static void main(String[] args) { + // Array of fruits to ensure all cases are covered + String[] fruits = {"Banana", "Brocoli", "Wednesday"}; + + // Loop through all possible fruits + for (String fruit : fruits) { + printFruit(fruit); + } + } + + public static void printFruit(String fruit) { + switch (fruit) { + case "Banana": + if (true) { + System.out.println(fruit + " is a fruit"); + } + break; + case "Brocoli": + System.out.println(fruit + " is a vegetable."); + break; + default: + System.out.println(fruit + " is not valid."); + break; + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_2.java new file mode 100644 index 0000000000..045907f9fd --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_2.java @@ -0,0 +1,32 @@ +public class Switch_mutation_2 { + + public static void main(String[] args) { + // Array of fruits to ensure all cases are covered + String[] fruits = {"Banana", "Brocoli", "Wednesday"}; + Myclass myclass = new Myclass(); + + // Loop through all possible fruits + for (String fruit : fruits) { + int x = myclass.field; + printFruit(fruit); + } + } + + public static void printFruit(String fruit) { + switch (fruit) { + case "Banana": + System.out.println(fruit + " is a fruit"); + break; + case "Brocoli": + System.out.println(fruit + " is a vegetable."); + break; + default: + System.out.println(fruit + " is not valid."); + break; + } + } +} + +class Myclass { + static int field = 5; +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_3.java new file mode 100644 index 0000000000..2f9b844cb7 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_3.java @@ -0,0 +1,27 @@ +public class Switch_mutation_3 { + + public static void main(String[] args) { + // Array of fruits to ensure all cases are covered + String[] fruits = {"Banana", "Brocoli", "Wednesday"}; + + // Loop through all possible fruits + for (String fruit : fruits) { + System.out.println(fruit); + printFruit(fruit); + } + } + + public static void printFruit(String fruit) { + switch (fruit) { + case "Banana": + System.out.println(fruit + " is a fruit"); + break; + case "Brocoli": + System.out.println(fruit + " is a vegetable."); + break; + default: + System.out.println(fruit + " is not valid."); + break; + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_4.java new file mode 100644 index 0000000000..bfe6f9eec2 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_4.java @@ -0,0 +1,27 @@ +public class Switch_mutation_4 { + + public static void main(String[] args) { + // Array of fruits to ensure all cases are covered + String[] fruits = {"Banana", "Brocoli", "Wednesday"}; + + // Loop through all possible fruits + for (String fruit : fruits) { + printFruit(fruit); + } + } + + public static void printFruit(String fruit) { + switch (fruit) { + case "Banana": + System.out.println(fruit + " is a fruit"); + break; + case "Brocoli": + System.out.println("is not valid."); + System.out.println(fruit + " is a vegetable."); + break; + default: + System.out.println(fruit + " is not valid."); + break; + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_5.java new file mode 100644 index 0000000000..7bac25e9c6 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/switch/Switch_mutation_5.java @@ -0,0 +1,40 @@ +public class Switch_mutation_5 { + + public static void main(String[] args) { + // Array of fruits to ensure all cases are covered + String[] fruits = {"Banana", "Brocoli", "Wednesday"}; + + // Loop through all possible fruits + for (String fruit : fruits) { + printFruit(fruit); + } + } + + public static void printFruit(String fruit) { + if(isValidFruit(fruit)) { + switch (fruit) { + case "Banana": + System.out.println(fruit + " is a fruit"); + break; + case "Brocoli": + System.out.println(fruit + " is a vegetable."); + break; + default: + System.out.println(fruit + " is not valid."); + break; + } + } else { + System.out.println(fruit + " is not valid."); + } + } + + public static boolean isValidFruit(String fruit) { + switch (fruit) { + case "Banana": + case "Brocoli": + return true; + default: + return false; + } + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop.java index 761fea6ed9..31753cfeeb 100644 --- a/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop.java +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop.java @@ -8,45 +8,6 @@ public static void main(String[] args) { counter++; } - // While loop with multiple conditions - int a = 10; - int b = 20; - while (a < b && a % 2 == 0) { - System.out.println("While loop with multiple conditions: a = " + a); - a += 2; - } - - // Nested while loop - int outer = 1; - while (outer <= 3) { - int inner = 1; - while (inner <= 2) { - System.out.println("Nested while loop: outer = " + outer + ", inner = " + inner); - inner++; - } - outer++; - } - - // While loop with break - int x = 0; - while (true) { - System.out.println("While loop with break: x = " + x); - if (x >= 3) { - break; - } - x++; - } - - // While loop with continue - int y = 0; - while (y < 5) { - y++; - if (y % 2 == 0) { - continue; - } - System.out.println("While loop with continue: y = " + y); - } - // Do-while loop int z = 0; do { @@ -54,11 +15,5 @@ public static void main(String[] args) { z++; } while (z < 3); - // Do-while loop with complex condition - int m = 10; - do { - System.out.println("Do-while loop with complex condition: m = " + m); - m--; - } while (m > 0 && m % 3 != 0); } } diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_1.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_1.java new file mode 100644 index 0000000000..5c95aa7abb --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_1.java @@ -0,0 +1,22 @@ +public class WhileLoop_mutation_1 { + + public static void main(String[] args) { + // Simple while loop + int counter = 0; + WhileLoop_mutation_1 myclass = new WhileLoop_mutation_1(); + while (counter < myclass.staticValue) { + System.out.println("Simple while loop: counter = " + counter); + counter++; + } + + // Do-while loop + int z = 0; + do { + System.out.println("Do-while loop: z = " + z); + z++; + } while (z < 3); + + } + + public static int staticValue = 5; +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_2.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_2.java new file mode 100644 index 0000000000..71de569978 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_2.java @@ -0,0 +1,20 @@ +public class WhileLoop_mutation_2 { + + public static void main(String[] args) { + // Simple while loop + int counter = 0; + counter++; + while (counter < 5) { + System.out.println("Simple while loop: counter = " + counter); + counter++; + } + + // Do-while loop + int z = 0; + do { + System.out.println("Do-while loop: z = " + z); + z++; + } while (z < 3); + + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_3.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_3.java new file mode 100644 index 0000000000..16ef45b7b2 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_3.java @@ -0,0 +1,19 @@ +public class WhileLoop_mutation_3 { + + public static void main(String[] args) { + // Simple while loop + int[] counterArr = {0}; + while (counterArr[0] < 5) { + System.out.println("Simple while loop: counter = " + counterArr[0]); + counterArr[0]++; + } + + // Do-while loop + int z = 0; + do { + System.out.println("Do-while loop: z = " + z); + z++; + } while (z < 3); + + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_4.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_4.java new file mode 100644 index 0000000000..c5fed6eb73 --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_4.java @@ -0,0 +1,21 @@ +public class WhileLoop_mutation_4 { + + public static void main(String[] args) { + // Simple while loop + int counter = 0; + System.out.println("Simple while loop: counter = " + counter); + while (counter < 5) { + System.out.println("Simple while loop: counter = " + counter); + counter++; + } + + // Do-while loop + int z = 0; + z++; + do { + System.out.println("Do-while loop: z = " + z); + z++; + } while (z < 3); + + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_5.java b/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_5.java new file mode 100644 index 0000000000..511f42b06a --- /dev/null +++ b/OPAL/tactobc/src/test/resources/javaFilesMutation/whileLoop/WhileLoop_mutation_5.java @@ -0,0 +1,20 @@ +public class WhileLoop_mutation_5 { + + public static void main(String[] args) { + // Simple while loop + int[] counterArray = {0}; + while (counterArray[0] < 5) { + System.out.println("Simple while loop: counter = " + counterArray[0]); + counterArray[0]++; + } + + // Do-while loop + int z = 0; + int[] zArray = {z}; + do { + System.out.println("Do-while loop: z = " + zArray[0]); + zArray[0]++; + } while (zArray[0] < 3); + + } +} \ No newline at end of file diff --git a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/MutatedClassFileTestCaseEnum.scala b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/MutatedClassFileTestCaseEnum.scala index dc9725444c..ced429946f 100644 --- a/OPAL/tactobc/src/test/scala/org/opalj/tactobc/MutatedClassFileTestCaseEnum.scala +++ b/OPAL/tactobc/src/test/scala/org/opalj/tactobc/MutatedClassFileTestCaseEnum.scala @@ -56,11 +56,11 @@ object MutatedClassFileTestCaseEnum extends Enumeration { TestCase("If.java", "/if", "If.class", "If_mutation_3.java", "If_mutation_3.class"), TestCase("If.java", "/if", "If.class", "If_mutation_4.java", "If_mutation_4.class"), TestCase("If.java", "/if", "If.class", "If_mutation_5.java", "If_mutation_5.class"), - TestCase("If.java", "/ifZero", "If.class", "If_mutation_1.java", "If_mutation_1.class"), - TestCase("If.java", "/ifZero", "If.class", "If_mutation_2.java", "If_mutation_2.class"), - TestCase("If.java", "/ifZero", "If.class", "If_mutation_3.java", "If_mutation_3.class"), - TestCase("If.java", "/ifZero", "If.class", "If_mutation_4.java", "If_mutation_4.class"), - TestCase("If.java", "/ifZero", "If.class", "If_mutation_5.java", "If_mutation_5.class"), + TestCase("IfZero.java", "/ifZero", "IfZero.class", "IfZero_mutation_1.java", "IfZero_mutation_1.class"), + TestCase("IfZero.java", "/ifZero", "IfZero.class", "IfZero_mutation_2.java", "IfZero_mutation_2.class"), + TestCase("IfZero.java", "/ifZero", "IfZero.class", "IfZero_mutation_3.java", "IfZero_mutation_3.class"), + TestCase("IfZero.java", "/ifZero", "IfZero.class", "IfZero_mutation_4.java", "IfZero_mutation_4.class"), + TestCase("IfZero.java", "/ifZero", "IfZero.class", "IfZero_mutation_5.java", "IfZero_mutation_5.class"), TestCase("InstanceField.java", "/instanceField", "InstanceField.class", "InstanceField_mutation_1.java", "InstanceField_mutation_1.class"), TestCase("InstanceField.java", "/instanceField", "InstanceField.class", "InstanceField_mutation_2.java", "InstanceField_mutation_2.class"), TestCase("InstanceField.java", "/instanceField", "InstanceField.class", "InstanceField_mutation_3.java", "InstanceField_mutation_3.class"), @@ -70,7 +70,62 @@ object MutatedClassFileTestCaseEnum extends Enumeration { TestCase("InstanceOf.java", "/instanceOf", "InstanceOf.class", "InstanceOf_mutation_2.java", "InstanceOf_mutation_2.class"), TestCase("InstanceOf.java", "/instanceOf", "InstanceOf.class", "InstanceOf_mutation_3.java", "InstanceOf_mutation_3.class"), TestCase("InstanceOf.java", "/instanceOf", "InstanceOf.class", "InstanceOf_mutation_4.java", "InstanceOf_mutation_4.class"), - TestCase("InstanceOf.java", "/instanceOf", "InstanceOf.class", "InstanceOf_mutation_5.java", "InstanceOf_mutation_5.class") + TestCase("InstanceOf.java", "/instanceOf", "InstanceOf.class", "InstanceOf_mutation_5.java", "InstanceOf_mutation_5.class"), + TestCase("InvokeDynamic.java", "/invokeDynamic", "InvokeDynamic.class", "InvokeDynamic_mutation_1.java", "InvokeDynamic_mutation_1.class"), + TestCase("InvokeDynamic.java", "/invokeDynamic", "InvokeDynamic.class", "InvokeDynamic_mutation_2.java", "InvokeDynamic_mutation_2.class"), + TestCase("InvokeDynamic.java", "/invokeDynamic", "InvokeDynamic.class", "InvokeDynamic_mutation_3.java", "InvokeDynamic_mutation_3.class"), + TestCase("InvokeDynamic.java", "/invokeDynamic", "InvokeDynamic.class", "InvokeDynamic_mutation_4.java", "InvokeDynamic_mutation_4.class"), + TestCase("InvokeDynamic.java", "/invokeDynamic", "InvokeDynamic.class", "InvokeDynamic_mutation_5.java", "InvokeDynamic_mutation_5.class"), + TestCase("InvokeInterface.java", "/invokeInterface", "InvokeInterface.class", "InvokeInterface_mutation_1.java", "InvokeInterface_mutation_1.class"), + TestCase("InvokeInterface.java", "/invokeInterface", "InvokeInterface.class", "InvokeInterface_mutation_2.java", "InvokeInterface_mutation_2.class"), + TestCase("InvokeInterface.java", "/invokeInterface", "InvokeInterface.class", "InvokeInterface_mutation_3.java", "InvokeInterface_mutation_3.class"), + TestCase("InvokeInterface.java", "/invokeInterface", "InvokeInterface.class", "InvokeInterface_mutation_4.java", "InvokeInterface_mutation_4.class"), + TestCase("InvokeInterface.java", "/invokeInterface", "InvokeInterface.class", "InvokeInterface_mutation_5.java", "InvokeInterface_mutation_5.class"), + TestCase("Jsr.java", "/jsr", "Jsr.class", "Jsr_mutation_1.java", "Jsr_mutation_1.class"), + TestCase("Jsr.java", "/jsr", "Jsr.class", "Jsr_mutation_2.java", "Jsr_mutation_2.class"), + TestCase("Jsr.java", "/jsr", "Jsr.class", "Jsr_mutation_3.java", "Jsr_mutation_3.class"), + TestCase("Jsr.java", "/jsr", "Jsr.class", "Jsr_mutation_4.java", "Jsr_mutation_4.class"), + TestCase("Jsr.java", "/jsr", "Jsr.class", "Jsr_mutation_5.java", "Jsr_mutation_5.class"), + TestCase("MethodCall.java", "/methodCall", "MethodCall.class", "MethodCall_mutation_1.java", "MethodCall_mutation_1.class"), + TestCase("MethodCall.java", "/methodCall", "MethodCall.class", "MethodCall_mutation_2.java", "MethodCall_mutation_2.class"), + TestCase("MethodCall.java", "/methodCall", "MethodCall.class", "MethodCall_mutation_3.java", "MethodCall_mutation_3.class"), + TestCase("MethodCall.java", "/methodCall", "MethodCall.class", "MethodCall_mutation_4.java", "MethodCall_mutation_4.class"), + TestCase("MethodCall.java", "/methodCall", "MethodCall.class", "MethodCall_mutation_5.java", "MethodCall_mutation_5.class"), + TestCase("Negation.java", "/negation", "Negation.class", "Negation_mutation_1.java", "Negation_mutation_1.class"), + TestCase("Negation.java", "/negation", "Negation.class", "Negation_mutation_2.java", "Negation_mutation_2.class"), + TestCase("Negation.java", "/negation", "Negation.class", "Negation_mutation_3.java", "Negation_mutation_3.class"), + TestCase("Negation.java", "/negation", "Negation.class", "Negation_mutation_4.java", "Negation_mutation_4.class"), + TestCase("Negation.java", "/negation", "Negation.class", "Negation_mutation_5.java", "Negation_mutation_5.class"), + TestCase("ObjectPropertyAccess.java", "/objectPropertyAccess", "ObjectPropertyAccess.class", "ObjectPropertyAccess_mutation_1.java", "ObjectPropertyAccess_mutation_1.class"), + TestCase("ObjectPropertyAccess.java", "/objectPropertyAccess", "ObjectPropertyAccess.class", "ObjectPropertyAccess_mutation_2.java", "ObjectPropertyAccess_mutation_2.class"), + TestCase("ObjectPropertyAccess.java", "/objectPropertyAccess", "ObjectPropertyAccess.class", "ObjectPropertyAccess_mutation_3.java", "ObjectPropertyAccess_mutation_3.class"), + TestCase("ObjectPropertyAccess.java", "/objectPropertyAccess", "ObjectPropertyAccess.class", "ObjectPropertyAccess_mutation_4.java", "ObjectPropertyAccess_mutation_4.class"), + TestCase("ObjectPropertyAccess.java", "/objectPropertyAccess", "ObjectPropertyAccess.class", "ObjectPropertyAccess_mutation_5.java", "ObjectPropertyAccess_mutation_5.class"), + TestCase("Parameters.java", "/parameters", "Parameters.class", "Parameters_mutation_1.java", "Parameters_mutation_1.class"), + TestCase("Parameters.java", "/parameters", "Parameters.class", "Parameters_mutation_2.java", "Parameters_mutation_2.class"), + TestCase("Parameters.java", "/parameters", "Parameters.class", "Parameters_mutation_3.java", "Parameters_mutation_3.class"), + TestCase("Parameters.java", "/parameters", "Parameters.class", "Parameters_mutation_4.java", "Parameters_mutation_4.class"), + TestCase("Parameters.java", "/parameters", "Parameters.class", "Parameters_mutation_5.java", "Parameters_mutation_5.class"), + TestCase("PrimitiveTypeCast.java", "/primitiveTypeCast", "PrimitiveTypeCast.class", "PrimitiveTypeCast_mutation_1.java", "PrimitiveTypeCast_mutation_1.class"), + TestCase("PrimitiveTypeCast.java", "/primitiveTypeCast", "PrimitiveTypeCast.class", "PrimitiveTypeCast_mutation_2.java", "PrimitiveTypeCast_mutation_2.class"), + TestCase("PrimitiveTypeCast.java", "/primitiveTypeCast", "PrimitiveTypeCast.class", "PrimitiveTypeCast_mutation_3.java", "PrimitiveTypeCast_mutation_3.class"), + TestCase("PrimitiveTypeCast.java", "/primitiveTypeCast", "PrimitiveTypeCast.class", "PrimitiveTypeCast_mutation_4.java", "PrimitiveTypeCast_mutation_4.class"), + TestCase("PrimitiveTypeCast.java", "/primitiveTypeCast", "PrimitiveTypeCast.class", "PrimitiveTypeCast_mutation_5.java", "PrimitiveTypeCast_mutation_5.class"), + TestCase("Reassignment.java", "/reassignment", "Reassignment.class", "Reassignment_mutation_1.java", "Reassignment_mutation_1.class"), + TestCase("Reassignment.java", "/reassignment", "Reassignment.class", "Reassignment_mutation_2.java", "Reassignment_mutation_2.class"), + TestCase("Reassignment.java", "/reassignment", "Reassignment.class", "Reassignment_mutation_3.java", "Reassignment_mutation_3.class"), + TestCase("Reassignment.java", "/reassignment", "Reassignment.class", "Reassignment_mutation_4.java", "Reassignment_mutation_4.class"), + TestCase("Reassignment.java", "/reassignment", "Reassignment.class", "Reassignment_mutation_5.java", "Reassignment_mutation_5.class"), + TestCase("StaticField.java", "/staticField", "StaticField.class", "StaticField_mutation_1.java", "StaticField_mutation_1.class"), + TestCase("StaticField.java", "/staticField", "StaticField.class", "StaticField_mutation_2.java", "StaticField_mutation_2.class"), + TestCase("StaticField.java", "/staticField", "StaticField.class", "StaticField_mutation_3.java", "StaticField_mutation_3.class"), + TestCase("StaticField.java", "/staticField", "StaticField.class", "StaticField_mutation_4.java", "StaticField_mutation_4.class"), + TestCase("StaticField.java", "/staticField", "StaticField.class", "StaticField_mutation_5.java", "StaticField_mutation_5.class"), + TestCase("WhileLoop.java", "/whileLoop", "WhileLoop.class", "WhileLoop_mutation_1.java", "WhileLoop_mutation_1.class"), + TestCase("WhileLoop.java", "/whileLoop", "WhileLoop.class", "WhileLoop_mutation_2.java", "WhileLoop_mutation_2.class"), + TestCase("WhileLoop.java", "/whileLoop", "WhileLoop.class", "WhileLoop_mutation_3.java", "WhileLoop_mutation_3.class"), + TestCase("WhileLoop.java", "/whileLoop", "WhileLoop.class", "WhileLoop_mutation_4.java", "WhileLoop_mutation_4.class"), + TestCase("WhileLoop.java", "/whileLoop", "WhileLoop.class", "WhileLoop_mutation_5.java", "WhileLoop_mutation_5.class") ) // Case class to represent each test case From a5a81629e2a1d4b78b9704f246e8a80a11e4b5e6 Mon Sep 17 00:00:00 2001 From: "S. Aranda-Simbron" Date: Wed, 4 Sep 2024 21:00:15 +0200 Subject: [PATCH 091/111] added documentation --- .../scala/org/opalj/tactobc/ThirdPass.scala | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala index 55b080278d..fc69ab6613 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala @@ -9,8 +9,26 @@ import scala.collection.immutable.ArraySeq import scala.collection.mutable import scala.collection.mutable.ArrayBuffer +/** + * Handles the post-processing of the translation of three-address code (TAC) statements + * into Java bytecode instructions. + * + * Key responsibilities: + * - Update the target of jump instructions + */ object ThirdPass { + /** + * Updates the targets of all jump instructions in the generated bytecode. + * For each conditional and unconditional jump instruction (such as IF_ICMPEQ, GOTO, etc.), + * this method adjusts the branch offset to point to the correct bytecode location. + * + * @param tacStmts TAC statements and their respective indexes. + * @param generatedByteCodeWithPC generated bytecode instructions with their respective program counter (PC) + * @param tacTargetToByteCodePcs mapping of TAC targets to their respective generated bytecode program counters (PCs). + * @param switchCases switch case mappings for lookup and table switch instructions. + * @return the final, updated bytecode instructions, with adjusted branch targets. + */ def updateTargetsOfJumpInstructions(tacStmts: Array[(Stmt[DUVar[ValueInformation]], Int)], generatedByteCodeWithPC: ArrayBuffer[(Int, Instruction)], tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], switchCases: ArrayBuffer[(Int, Int)]): ArrayBuffer[(Int, Instruction)] = { val result = ArrayBuffer[(Int, Instruction)]() // Index for TAC statements @@ -93,22 +111,54 @@ object ThirdPass { result } + /** + * Finds the corresponding TAC target for a given switch case value. + * + * @param npairs A list of pairs where each pair contains a switch case value and the corresponding TAC target. + * @param caseValue The value of the switch case being processed. + * @return The TAC target associated with the given switch case value. + */ def findTacTarget(npairs: ArrayBuffer[(Int, Int)], caseValue: Int): Int = { val tacTarget = npairs.find(_._1 == caseValue).map(_._2).get tacTarget } + /** + * Updates the branch target for jump instructions such as IF_ICMPEQ, GOTO, JSR, etc. + * + * @param tacTargetToByteCodePcs A list mapping TAC targets to bytecode program counters. + * @param tacTargetToByteCodePcsIndex The index of the current TAC target. + * @param currentPC The current bytecode program counter (PC). + * @return The updated branch target offset. + */ def updateBranchTargets(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTargetToByteCodePcsIndex: Int, currentPC: Int): Int = { val tacTarget = tacTargetToByteCodePcs(tacTargetToByteCodePcsIndex)._1 val byteCodeTarget = tacTargetToByteCodePcs(tacTarget)._2 - currentPC byteCodeTarget } + /** + * Updates the switch case target offsets for LOOKUPSWITCH and TABLESWITCH instructions. + * + * @param tacTargetToByteCodePcs A list mapping TAC targets to generated bytecode program counters. + * @param tacTarget The TAC target that corresponds to a switch case. + * @param currentPC The current bytecode program counter (PC). + * @return The updated switch case target PC. + */ def updateSwitchTargets(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTarget: Int, currentPC: Int): Int = { val byteCodeTarget = tacTargetToByteCodePcs(tacTarget)._2 - currentPC byteCodeTarget } + /** + * Checks if a direct association exists between a given TAC target and a bytecode program counter. + * This is used to verify if a bytecode instruction corresponds to a specific TAC statement. + * + * @param tacTargetToByteCodePcs A list mapping TAC targets to bytecode program counters. + * @param tacTarget The TAC target to check. + * @param bytecodePC The bytecode program counter (PC) to check. + * @return true if the association exists, false otherwise. + */ def directAssociationExists(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTarget: Int, bytecodePC: Int): Boolean = { tacTargetToByteCodePcs.exists { case (tacGoto, bcPC) => (tacGoto, bcPC) == (tacTarget, bytecodePC) } } From 65cb10afef61fc7d45d2af7b95fb9de5160e8ebd Mon Sep 17 00:00:00 2001 From: lucahuen Date: Wed, 22 Jan 2025 15:31:09 +0100 Subject: [PATCH 092/111] changed the implementation of translating Stmts to Instructions -> now using Labels instead of Program Counter --- .../opalj/tactobc/ClassFileGenerator.scala | 224 ++-- .../org/opalj/tactobc/ExprProcessor.scala | 1086 ++++++++++------- .../scala/org/opalj/tactobc/FirstPass.scala | 314 ----- .../opalj/tactobc/LvIndicesPreparator.scala | 331 +++++ .../scala/org/opalj/tactobc/SecondPass.scala | 112 -- .../org/opalj/tactobc/StmtProcessor.scala | 706 ++++++----- .../tactobc/StmtToInstructionTranslator.scala | 166 +++ .../scala/org/opalj/tactobc/TACtoBC.scala | 281 +++-- .../scala/org/opalj/tactobc/ThirdPass.scala | 166 --- .../generated/ArithmeticOperations.class | Bin 0 -> 2492 bytes .../classfilestocompare/generated/Array.class | Bin 0 -> 3029 bytes .../generated/Assignment.class | Bin 0 -> 2028 bytes .../generated/BigNumbers.class | Bin 0 -> 9115 bytes .../generated/CheckCast.class | Bin 0 -> 1028 bytes .../generated/Compare.class | Bin 0 -> 1648 bytes .../generated/Constants.class | Bin 0 -> 1581 bytes .../generated/ForLoop.class | Bin 0 -> 1961 bytes .../classfilestocompare/generated/If.class | Bin 0 -> 2849 bytes .../generated/IfZero.class | Bin 0 -> 1779 bytes .../generated/InstanceField.class | Bin 0 -> 1042 bytes .../generated/InstanceOf.class | Bin 0 -> 1778 bytes .../generated/InvokeDynamic.class | Bin 0 -> 1657 bytes .../generated/InvokeInterface.class | Bin 0 -> 1013 bytes .../classfilestocompare/generated/Jsr.class | Bin 0 -> 1105 bytes .../generated/MethodCall.class | Bin 0 -> 1932 bytes .../generated/Negation.class | Bin 0 -> 1466 bytes .../generated/ObjectPropertyAccess.class | Bin 0 -> 1955 bytes .../generated/Parameters.class | Bin 0 -> 1771 bytes .../generated/PrimitiveTypeCast.class | Bin 0 -> 1672 bytes .../generated/Reassignment.class | Bin 0 -> 1687 bytes .../generated/StaticField.class | Bin 0 -> 1009 bytes .../generated/Switch.class | Bin 0 -> 1447 bytes .../generated/WhileLoop.class | Bin 0 -> 2014 bytes .../ArithmeticOperations_mutation_1.class | Bin 0 -> 1086 bytes .../ArithmeticOperations_mutation_2.class | Bin 0 -> 1086 bytes .../ArithmeticOperations_mutation_3.class | Bin 0 -> 1095 bytes .../ArithmeticOperations_mutation_4.class | Bin 0 -> 1023 bytes .../ArithmeticOperations_mutation_5.class | Bin 0 -> 1143 bytes .../mutation/generated/Array_mutation_1.class | Bin 0 -> 546 bytes .../mutation/generated/Array_mutation_2.class | Bin 0 -> 478 bytes .../mutation/generated/Array_mutation_3.class | Bin 0 -> 583 bytes .../mutation/generated/Array_mutation_4.class | Bin 0 -> 518 bytes .../mutation/generated/Array_mutation_5.class | Bin 0 -> 489 bytes .../generated/Assignment_mutation_1.class | Bin 0 -> 1328 bytes .../generated/Assignment_mutation_2.class | Bin 0 -> 1356 bytes .../generated/Assignment_mutation_3.class | Bin 0 -> 1356 bytes .../generated/Assignment_mutation_4.class | Bin 0 -> 1356 bytes .../generated/Assignment_mutation_5.class | Bin 0 -> 1328 bytes .../generated/BigNumbers_mutation_1.class | Bin 0 -> 1915 bytes .../generated/BigNumbers_mutation_2.class | Bin 0 -> 1915 bytes .../generated/BigNumbers_mutation_3.class | Bin 0 -> 1915 bytes .../generated/BigNumbers_mutation_4.class | Bin 0 -> 1915 bytes .../generated/BigNumbers_mutation_5.class | Bin 0 -> 2127 bytes .../generated/CheckCast_mutation_1.class | Bin 0 -> 1111 bytes .../generated/CheckCast_mutation_2.class | Bin 0 -> 1043 bytes .../generated/CheckCast_mutation_3.class | Bin 0 -> 1340 bytes .../generated/CheckCast_mutation_4.class | Bin 0 -> 1111 bytes .../generated/CheckCast_mutation_5.class | Bin 0 -> 1043 bytes .../generated/Compare_mutation_1.class | Bin 0 -> 1265 bytes .../generated/Compare_mutation_2.class | Bin 0 -> 1265 bytes .../generated/Compare_mutation_3.class | Bin 0 -> 1265 bytes .../generated/Compare_mutation_4.class | Bin 0 -> 1265 bytes .../generated/Compare_mutation_5.class | Bin 0 -> 1294 bytes .../generated/Constants_mutation_1.class | Bin 0 -> 1384 bytes .../generated/Constants_mutation_2.class | Bin 0 -> 1461 bytes .../generated/Constants_mutation_3.class | Bin 0 -> 1703 bytes .../generated/Constants_mutation_4.class | Bin 0 -> 1384 bytes .../generated/Constants_mutation_5.class | Bin 0 -> 1447 bytes .../generated/ForLoop_mutation_1.class | Bin 0 -> 1445 bytes .../generated/ForLoop_mutation_2.class | Bin 0 -> 1445 bytes .../generated/ForLoop_mutation_3.class | Bin 0 -> 1445 bytes .../generated/ForLoop_mutation_4.class | Bin 0 -> 1578 bytes .../generated/ForLoop_mutation_5.class | Bin 0 -> 1445 bytes .../generated/IfZero_mutation_1.class | Bin 0 -> 841 bytes .../generated/IfZero_mutation_2.class | Bin 0 -> 751 bytes .../generated/IfZero_mutation_3.class | Bin 0 -> 698 bytes .../generated/IfZero_mutation_4.class | Bin 0 -> 882 bytes .../generated/IfZero_mutation_5.class | Bin 0 -> 751 bytes .../mutation/generated/If_mutation_1.class | Bin 0 -> 1366 bytes .../mutation/generated/If_mutation_2.class | Bin 0 -> 1165 bytes .../mutation/generated/If_mutation_3.class | Bin 0 -> 1616 bytes .../mutation/generated/If_mutation_4.class | Bin 0 -> 1165 bytes .../mutation/generated/If_mutation_5.class | Bin 0 -> 1863 bytes .../generated/InstanceField_mutation_1.class | Bin 0 -> 918 bytes .../generated/InstanceField_mutation_2.class | Bin 0 -> 931 bytes .../generated/InstanceField_mutation_3.class | Bin 0 -> 981 bytes .../generated/InstanceField_mutation_4.class | Bin 0 -> 1011 bytes .../generated/InstanceField_mutation_5.class | Bin 0 -> 1029 bytes .../generated/InstanceOf_mutation_1.class | Bin 0 -> 1186 bytes .../generated/InstanceOf_mutation_2.class | Bin 0 -> 1277 bytes .../generated/InstanceOf_mutation_3.class | Bin 0 -> 1268 bytes .../generated/InstanceOf_mutation_4.class | Bin 0 -> 1288 bytes .../generated/InstanceOf_mutation_5.class | Bin 0 -> 1218 bytes .../generated/InvokeDynamic_mutation_1.class | Bin 0 -> 1501 bytes .../generated/InvokeDynamic_mutation_2.class | Bin 0 -> 1607 bytes .../generated/InvokeDynamic_mutation_3.class | Bin 0 -> 1607 bytes .../generated/InvokeDynamic_mutation_4.class | Bin 0 -> 1595 bytes .../generated/InvokeDynamic_mutation_5.class | Bin 0 -> 1075 bytes .../InvokeInterface_mutation_1.class | Bin 0 -> 1163 bytes .../InvokeInterface_mutation_2.class | Bin 0 -> 1136 bytes .../InvokeInterface_mutation_3.class | Bin 0 -> 1222 bytes .../InvokeInterface_mutation_4.class | Bin 0 -> 1207 bytes .../InvokeInterface_mutation_5.class | Bin 0 -> 1126 bytes .../mutation/generated/Jsr_mutation_1.class | Bin 0 -> 1158 bytes .../mutation/generated/Jsr_mutation_2.class | Bin 0 -> 1090 bytes .../mutation/generated/Jsr_mutation_3.class | Bin 0 -> 1171 bytes .../mutation/generated/Jsr_mutation_4.class | Bin 0 -> 1090 bytes .../mutation/generated/Jsr_mutation_5.class | Bin 0 -> 1149 bytes .../generated/MethodCall_mutation_1.class | Bin 0 -> 943 bytes .../generated/MethodCall_mutation_2.class | Bin 0 -> 943 bytes .../generated/MethodCall_mutation_3.class | Bin 0 -> 943 bytes .../generated/MethodCall_mutation_4.class | Bin 0 -> 943 bytes .../generated/MethodCall_mutation_5.class | Bin 0 -> 1002 bytes .../generated/Negation_mutation_1.class | Bin 0 -> 1197 bytes .../generated/Negation_mutation_2.class | Bin 0 -> 1199 bytes .../generated/Negation_mutation_3.class | Bin 0 -> 1226 bytes .../generated/Negation_mutation_4.class | Bin 0 -> 1354 bytes .../generated/Negation_mutation_5.class | Bin 0 -> 1135 bytes .../ObjectPropertyAccess_mutation_1.class | Bin 0 -> 1178 bytes .../ObjectPropertyAccess_mutation_2.class | Bin 0 -> 1178 bytes .../ObjectPropertyAccess_mutation_3.class | Bin 0 -> 1217 bytes .../ObjectPropertyAccess_mutation_4.class | Bin 0 -> 1178 bytes .../ObjectPropertyAccess_mutation_5.class | Bin 0 -> 1253 bytes .../generated/Parameters_mutation_1.class | Bin 0 -> 934 bytes .../generated/Parameters_mutation_2.class | Bin 0 -> 960 bytes .../generated/Parameters_mutation_3.class | Bin 0 -> 1094 bytes .../generated/Parameters_mutation_4.class | Bin 0 -> 979 bytes .../generated/Parameters_mutation_5.class | Bin 0 -> 1098 bytes .../PrimitiveTypeCast_mutation_1.class | Bin 0 -> 868 bytes .../PrimitiveTypeCast_mutation_2.class | Bin 0 -> 857 bytes .../PrimitiveTypeCast_mutation_3.class | Bin 0 -> 885 bytes .../PrimitiveTypeCast_mutation_4.class | Bin 0 -> 867 bytes .../PrimitiveTypeCast_mutation_5.class | Bin 0 -> 857 bytes .../generated/Reassignment_mutation_1.class | Bin 0 -> 1020 bytes .../generated/Reassignment_mutation_2.class | Bin 0 -> 1070 bytes .../generated/Reassignment_mutation_3.class | Bin 0 -> 1062 bytes .../generated/Reassignment_mutation_4.class | Bin 0 -> 1013 bytes .../generated/Reassignment_mutation_5.class | Bin 0 -> 991 bytes .../generated/StaticField_mutation_1.class | Bin 0 -> 1023 bytes .../generated/StaticField_mutation_2.class | Bin 0 -> 1013 bytes .../generated/StaticField_mutation_3.class | Bin 0 -> 1003 bytes .../generated/StaticField_mutation_4.class | Bin 0 -> 1085 bytes .../generated/StaticField_mutation_5.class | Bin 0 -> 1088 bytes .../generated/WhileLoop_mutation_1.class | Bin 0 -> 1144 bytes .../generated/WhileLoop_mutation_2.class | Bin 0 -> 1046 bytes .../generated/WhileLoop_mutation_3.class | Bin 0 -> 1137 bytes .../generated/WhileLoop_mutation_4.class | Bin 0 -> 1104 bytes .../generated/WhileLoop_mutation_5.class | Bin 0 -> 1210 bytes .../ArithmeticOperations_mutation_1.class | Bin 0 -> 1108 bytes .../ArithmeticOperations_mutation_2.class | Bin 0 -> 1108 bytes .../ArithmeticOperations_mutation_3.class | Bin 0 -> 1155 bytes .../ArithmeticOperations_mutation_4.class | Bin 0 -> 1073 bytes .../ArithmeticOperations_mutation_5.class | Bin 0 -> 1101 bytes .../mutation/mutated/Array_mutation_1.class | Bin 0 -> 532 bytes .../mutation/mutated/Array_mutation_2.class | Bin 0 -> 479 bytes .../mutation/mutated/Array_mutation_3.class | Bin 0 -> 571 bytes .../mutation/mutated/Array_mutation_4.class | Bin 0 -> 489 bytes .../mutation/mutated/Array_mutation_5.class | Bin 0 -> 475 bytes .../mutated/Assignment_mutation_1.class | Bin 0 -> 1471 bytes .../mutated/Assignment_mutation_2.class | Bin 0 -> 1489 bytes .../mutated/Assignment_mutation_3.class | Bin 0 -> 1480 bytes .../mutated/Assignment_mutation_4.class | Bin 0 -> 1480 bytes .../mutated/Assignment_mutation_5.class | Bin 0 -> 1479 bytes .../mutated/BigNumbers_mutation_1.class | Bin 0 -> 1932 bytes .../mutated/BigNumbers_mutation_2.class | Bin 0 -> 1926 bytes .../mutated/BigNumbers_mutation_3.class | Bin 0 -> 1964 bytes .../mutated/BigNumbers_mutation_4.class | Bin 0 -> 1964 bytes .../BigNumbers_mutation_5$MyNumbers.class | Bin 0 -> 663 bytes .../mutated/BigNumbers_mutation_5.class | Bin 0 -> 1934 bytes .../mutated/CheckCast_mutation_1.class | Bin 0 -> 1167 bytes .../mutated/CheckCast_mutation_2.class | Bin 0 -> 1097 bytes .../mutated/CheckCast_mutation_3.class | Bin 0 -> 1403 bytes .../mutated/CheckCast_mutation_4.class | Bin 0 -> 1167 bytes .../mutated/CheckCast_mutation_5.class | Bin 0 -> 1097 bytes .../mutation/mutated/Compare_mutation_1.class | Bin 0 -> 1351 bytes .../mutation/mutated/Compare_mutation_2.class | Bin 0 -> 1327 bytes .../mutation/mutated/Compare_mutation_3.class | Bin 0 -> 1352 bytes .../mutation/mutated/Compare_mutation_4.class | Bin 0 -> 1327 bytes .../mutation/mutated/Compare_mutation_5.class | Bin 0 -> 1344 bytes .../mutated/Constants_mutation_1.class | Bin 0 -> 1438 bytes .../mutated/Constants_mutation_2.class | Bin 0 -> 1531 bytes .../mutated/Constants_mutation_3.class | Bin 0 -> 1593 bytes .../mutated/Constants_mutation_4.class | Bin 0 -> 1438 bytes .../mutated/Constants_mutation_5.class | Bin 0 -> 1506 bytes .../mutation/mutated/ForLoop_mutation_1.class | Bin 0 -> 1276 bytes .../mutation/mutated/ForLoop_mutation_2.class | Bin 0 -> 1259 bytes .../mutation/mutated/ForLoop_mutation_3.class | Bin 0 -> 1259 bytes .../mutation/mutated/ForLoop_mutation_4.class | Bin 0 -> 1307 bytes .../mutation/mutated/ForLoop_mutation_5.class | Bin 0 -> 1259 bytes .../mutation/mutated/IfZero_mutation_1.class | Bin 0 -> 864 bytes .../mutation/mutated/IfZero_mutation_2.class | Bin 0 -> 776 bytes .../mutation/mutated/IfZero_mutation_3.class | Bin 0 -> 726 bytes .../mutation/mutated/IfZero_mutation_4.class | Bin 0 -> 759 bytes .../mutation/mutated/IfZero_mutation_5.class | Bin 0 -> 776 bytes .../mutation/mutated/If_mutation_1.class | Bin 0 -> 1282 bytes .../mutation/mutated/If_mutation_2.class | Bin 0 -> 1252 bytes .../mutation/mutated/If_mutation_3.class | Bin 0 -> 1301 bytes .../mutation/mutated/If_mutation_4.class | Bin 0 -> 1252 bytes .../mutation/mutated/If_mutation_5.class | Bin 0 -> 1292 bytes .../mutated/InstanceField_mutation_1.class | Bin 0 -> 966 bytes .../mutated/InstanceField_mutation_2.class | Bin 0 -> 977 bytes .../mutated/InstanceField_mutation_3.class | Bin 0 -> 1039 bytes .../mutated/InstanceField_mutation_4.class | Bin 0 -> 1069 bytes .../mutated/InstanceField_mutation_5.class | Bin 0 -> 1067 bytes .../mutated/InstanceOf_mutation_1.class | Bin 0 -> 1210 bytes .../InstanceOf_mutation_2$1MyClass.class | Bin 0 -> 655 bytes .../mutated/InstanceOf_mutation_2.class | Bin 0 -> 1301 bytes .../mutated/InstanceOf_mutation_3.class | Bin 0 -> 1296 bytes .../mutated/InstanceOf_mutation_4.class | Bin 0 -> 1316 bytes .../mutated/InstanceOf_mutation_5.class | Bin 0 -> 1219 bytes .../mutated/InvokeDynamic_mutation_1.class | Bin 0 -> 1582 bytes .../mutated/InvokeDynamic_mutation_2.class | Bin 0 -> 1700 bytes .../mutated/InvokeDynamic_mutation_3.class | Bin 0 -> 1700 bytes .../mutated/InvokeDynamic_mutation_4.class | Bin 0 -> 1680 bytes .../mutated/InvokeDynamic_mutation_5.class | Bin 0 -> 1135 bytes .../mutated/InvokeInterface_mutation_1.class | Bin 0 -> 1223 bytes .../mutated/InvokeInterface_mutation_2.class | Bin 0 -> 1138 bytes .../mutated/InvokeInterface_mutation_3.class | Bin 0 -> 1270 bytes .../mutated/InvokeInterface_mutation_4.class | Bin 0 -> 1221 bytes ...vokeInterface_mutation_5$1SizeHolder.class | Bin 0 -> 485 bytes .../mutated/InvokeInterface_mutation_5.class | Bin 0 -> 1200 bytes .../mutation/mutated/Jsr_mutation_1.class | Bin 0 -> 1125 bytes .../mutation/mutated/Jsr_mutation_2.class | Bin 0 -> 1100 bytes .../mutation/mutated/Jsr_mutation_3.class | Bin 0 -> 1197 bytes .../mutation/mutated/Jsr_mutation_4.class | Bin 0 -> 1100 bytes .../mutation/mutated/Jsr_mutation_5.class | Bin 0 -> 1181 bytes .../mutated/MethodCall_mutation_1.class | Bin 0 -> 999 bytes .../mutated/MethodCall_mutation_2.class | Bin 0 -> 993 bytes .../mutated/MethodCall_mutation_3.class | Bin 0 -> 987 bytes .../mutated/MethodCall_mutation_4.class | Bin 0 -> 993 bytes .../mutated/MethodCall_mutation_5.class | Bin 0 -> 1072 bytes .../mutated/Negation_mutation_1.class | Bin 0 -> 1214 bytes .../mutated/Negation_mutation_2.class | Bin 0 -> 1267 bytes .../mutated/Negation_mutation_3.class | Bin 0 -> 1246 bytes .../mutated/Negation_mutation_4.class | Bin 0 -> 1426 bytes .../mutated/Negation_mutation_5.class | Bin 0 -> 1198 bytes .../ObjectPropertyAccess_mutation_1.class | Bin 0 -> 1182 bytes .../ObjectPropertyAccess_mutation_2.class | Bin 0 -> 1176 bytes .../ObjectPropertyAccess_mutation_3.class | Bin 0 -> 1191 bytes .../ObjectPropertyAccess_mutation_4.class | Bin 0 -> 1176 bytes .../ObjectPropertyAccess_mutation_5.class | Bin 0 -> 1261 bytes .../mutated/Parameters_mutation_1.class | Bin 0 -> 998 bytes .../mutated/Parameters_mutation_2.class | Bin 0 -> 998 bytes .../mutated/Parameters_mutation_3.class | Bin 0 -> 1175 bytes .../mutated/Parameters_mutation_4.class | Bin 0 -> 1054 bytes .../mutated/Parameters_mutation_5.class | Bin 0 -> 1173 bytes .../PrimitiveTypeCast_mutation_1.class | Bin 0 -> 914 bytes .../PrimitiveTypeCast_mutation_2.class | Bin 0 -> 906 bytes .../PrimitiveTypeCast_mutation_3.class | Bin 0 -> 913 bytes .../PrimitiveTypeCast_mutation_4.class | Bin 0 -> 913 bytes .../PrimitiveTypeCast_mutation_5.class | Bin 0 -> 906 bytes .../mutated/Reassignment_mutation_1.class | Bin 0 -> 1096 bytes .../Reassignment_mutation_2$Myclass.class | Bin 0 -> 430 bytes .../mutated/Reassignment_mutation_2.class | Bin 0 -> 1152 bytes .../mutated/Reassignment_mutation_3.class | Bin 0 -> 1161 bytes .../mutated/Reassignment_mutation_4.class | Bin 0 -> 1098 bytes .../mutated/Reassignment_mutation_5.class | Bin 0 -> 1088 bytes .../mutated/StaticField_mutation_1.class | Bin 0 -> 1095 bytes .../mutated/StaticField_mutation_2.class | Bin 0 -> 1079 bytes .../mutated/StaticField_mutation_3.class | Bin 0 -> 1069 bytes .../mutated/StaticField_mutation_4.class | Bin 0 -> 1169 bytes .../mutated/StaticField_mutation_5.class | Bin 0 -> 1177 bytes .../mutated/WhileLoop_mutation_1.class | Bin 0 -> 1138 bytes .../mutated/WhileLoop_mutation_2.class | Bin 0 -> 1031 bytes .../mutated/WhileLoop_mutation_3.class | Bin 0 -> 1048 bytes .../mutated/WhileLoop_mutation_4.class | Bin 0 -> 1047 bytes .../mutated/WhileLoop_mutation_5.class | Bin 0 -> 1071 bytes .../mutation/mutated/myclass.class | Bin 0 -> 241 bytes .../original/ArithmeticOperations.class | Bin 0 -> 1051 bytes .../mutation/original/Array.class | Bin 0 -> 453 bytes .../mutation/original/Assignment.class | Bin 0 -> 1440 bytes .../mutation/original/BigNumbers.class | Bin 0 -> 1923 bytes .../mutation/original/CheckCast.class | Bin 0 -> 1082 bytes .../mutation/original/Compare.class | Bin 0 -> 1305 bytes .../mutation/original/Constants.class | Bin 0 -> 1416 bytes .../mutation/original/ForLoop.class | Bin 0 -> 1237 bytes .../mutation/original/If.class | Bin 0 -> 1230 bytes .../mutation/original/IfZero.class | Bin 0 -> 754 bytes .../mutation/original/InstanceField.class | Bin 0 -> 938 bytes .../mutation/original/InstanceOf.class | Bin 0 -> 1182 bytes .../mutation/original/InvokeDynamic.class | Bin 0 -> 1200 bytes .../mutation/original/InvokeInterface.class | Bin 0 -> 1054 bytes .../mutation/original/Jsr.class | Bin 0 -> 1078 bytes .../mutation/original/MethodCall.class | Bin 0 -> 971 bytes .../mutation/original/Negation.class | Bin 0 -> 1176 bytes .../original/ObjectPropertyAccess.class | Bin 0 -> 1154 bytes .../mutation/original/Parameters.class | Bin 0 -> 968 bytes .../mutation/original/PrimitiveTypeCast.class | Bin 0 -> 883 bytes .../mutation/original/Reassignment.class | Bin 0 -> 1058 bytes .../mutation/original/StaticField.class | Bin 0 -> 1067 bytes .../mutation/original/WhileLoop.class | Bin 0 -> 1002 bytes .../original/ArithmeticOperations.class | Bin 0 -> 2538 bytes .../classfilestocompare/original/Array.class | Bin 0 -> 1909 bytes .../original/Assignment.class | Bin 0 -> 2137 bytes .../original/BigNumbers.class | Bin 0 -> 4544 bytes .../original/CheckCast.class | Bin 0 -> 1082 bytes .../original/Compare.class | Bin 0 -> 1503 bytes .../original/Constants.class | Bin 0 -> 1669 bytes .../original/ForLoop.class | Bin 0 -> 1397 bytes .../classfilestocompare/original/If.class | Bin 0 -> 2325 bytes .../classfilestocompare/original/IfZero.class | Bin 0 -> 1593 bytes .../original/InstanceField.class | Bin 0 -> 1100 bytes .../original/InstanceOf.class | Bin 0 -> 1686 bytes .../original/InvokeDynamic.class | Bin 0 -> 1736 bytes .../original/InvokeInterface.class | Bin 0 -> 1054 bytes .../classfilestocompare/original/Jsr.class | Bin 0 -> 1078 bytes .../original/MethodCall.class | Bin 0 -> 1957 bytes .../original/Negation.class | Bin 0 -> 1484 bytes .../original/ObjectPropertyAccess.class | Bin 0 -> 1774 bytes .../original/Parameters.class | Bin 0 -> 1751 bytes .../original/PrimitiveTypeCast.class | Bin 0 -> 1722 bytes .../original/Reassignment.class | Bin 0 -> 1565 bytes .../original/StaticField.class | Bin 0 -> 1067 bytes .../classfilestocompare/original/Switch.class | Bin 0 -> 1420 bytes .../original/WhileLoop.class | Bin 0 -> 1631 bytes .../tactobc/MutatedClassFileTACtoBCTest.scala | 253 ++-- .../MutatedClassFileTestCaseEnum.scala | 6 +- .../tactobc/SingleClassFileTACtoBCTest.scala | 2 +- 318 files changed, 1904 insertions(+), 1743 deletions(-) delete mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/LvIndicesPreparator.scala delete mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala create mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtToInstructionTranslator.scala delete mode 100644 OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/ArithmeticOperations.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/Array.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/Assignment.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/BigNumbers.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/CheckCast.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/Compare.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/Constants.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/ForLoop.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/If.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/IfZero.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/InstanceField.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/InstanceOf.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/InvokeDynamic.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/InvokeInterface.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/Jsr.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/MethodCall.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/Negation.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/ObjectPropertyAccess.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/Parameters.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/PrimitiveTypeCast.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/Reassignment.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/StaticField.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/Switch.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/generated/WhileLoop.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ArithmeticOperations_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ArithmeticOperations_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ArithmeticOperations_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ArithmeticOperations_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ArithmeticOperations_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Array_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Array_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Array_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Array_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Array_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Assignment_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Assignment_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Assignment_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Assignment_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Assignment_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/BigNumbers_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/BigNumbers_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/BigNumbers_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/BigNumbers_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/BigNumbers_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/CheckCast_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/CheckCast_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/CheckCast_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/CheckCast_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/CheckCast_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Compare_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Compare_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Compare_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Compare_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Compare_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Constants_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Constants_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Constants_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Constants_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Constants_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ForLoop_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ForLoop_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ForLoop_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ForLoop_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ForLoop_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/IfZero_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/IfZero_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/IfZero_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/IfZero_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/IfZero_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/If_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/If_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/If_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/If_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/If_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceField_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceField_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceField_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceField_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceField_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceOf_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceOf_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceOf_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceOf_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceOf_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeDynamic_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeDynamic_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeDynamic_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeDynamic_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeDynamic_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeInterface_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeInterface_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeInterface_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeInterface_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeInterface_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Jsr_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Jsr_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Jsr_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Jsr_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Jsr_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/MethodCall_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/MethodCall_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/MethodCall_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/MethodCall_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/MethodCall_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Negation_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Negation_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Negation_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Negation_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Negation_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ObjectPropertyAccess_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ObjectPropertyAccess_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ObjectPropertyAccess_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ObjectPropertyAccess_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ObjectPropertyAccess_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Parameters_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Parameters_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Parameters_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Parameters_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Parameters_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/PrimitiveTypeCast_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/PrimitiveTypeCast_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/PrimitiveTypeCast_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/PrimitiveTypeCast_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/PrimitiveTypeCast_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Reassignment_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Reassignment_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Reassignment_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Reassignment_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Reassignment_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/StaticField_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/StaticField_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/StaticField_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/StaticField_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/StaticField_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/WhileLoop_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/WhileLoop_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/WhileLoop_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/WhileLoop_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/generated/WhileLoop_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ArithmeticOperations_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ArithmeticOperations_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ArithmeticOperations_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ArithmeticOperations_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ArithmeticOperations_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Array_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Array_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Array_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Array_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Array_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Assignment_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Assignment_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Assignment_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Assignment_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Assignment_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/BigNumbers_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/BigNumbers_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/BigNumbers_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/BigNumbers_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/BigNumbers_mutation_5$MyNumbers.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/BigNumbers_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/CheckCast_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/CheckCast_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/CheckCast_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/CheckCast_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/CheckCast_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Compare_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Compare_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Compare_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Compare_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Compare_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Constants_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Constants_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Constants_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Constants_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Constants_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ForLoop_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ForLoop_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ForLoop_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ForLoop_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ForLoop_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/IfZero_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/IfZero_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/IfZero_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/IfZero_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/IfZero_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/If_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/If_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/If_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/If_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/If_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceField_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceField_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceField_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceField_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceField_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceOf_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceOf_mutation_2$1MyClass.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceOf_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceOf_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceOf_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceOf_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InvokeDynamic_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InvokeDynamic_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InvokeDynamic_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InvokeDynamic_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InvokeDynamic_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InvokeInterface_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InvokeInterface_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InvokeInterface_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InvokeInterface_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InvokeInterface_mutation_5$1SizeHolder.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InvokeInterface_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Jsr_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Jsr_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Jsr_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Jsr_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Jsr_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/MethodCall_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/MethodCall_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/MethodCall_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/MethodCall_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/MethodCall_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Negation_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Negation_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Negation_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Negation_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Negation_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ObjectPropertyAccess_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ObjectPropertyAccess_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ObjectPropertyAccess_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ObjectPropertyAccess_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ObjectPropertyAccess_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Parameters_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Parameters_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Parameters_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Parameters_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Parameters_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/PrimitiveTypeCast_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/PrimitiveTypeCast_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/PrimitiveTypeCast_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/PrimitiveTypeCast_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/PrimitiveTypeCast_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Reassignment_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Reassignment_mutation_2$Myclass.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Reassignment_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Reassignment_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Reassignment_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Reassignment_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/StaticField_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/StaticField_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/StaticField_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/StaticField_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/StaticField_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/WhileLoop_mutation_1.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/WhileLoop_mutation_2.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/WhileLoop_mutation_3.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/WhileLoop_mutation_4.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/WhileLoop_mutation_5.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/myclass.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/ArithmeticOperations.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/Array.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/Assignment.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/BigNumbers.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/CheckCast.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/Compare.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/Constants.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/ForLoop.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/If.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/IfZero.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/InstanceField.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/InstanceOf.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/InvokeDynamic.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/InvokeInterface.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/Jsr.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/MethodCall.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/Negation.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/ObjectPropertyAccess.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/Parameters.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/PrimitiveTypeCast.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/Reassignment.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/StaticField.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/mutation/original/WhileLoop.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/ArithmeticOperations.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/Array.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/Assignment.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/BigNumbers.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/CheckCast.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/Compare.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/Constants.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/ForLoop.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/If.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/IfZero.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/InstanceField.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/InstanceOf.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/InvokeDynamic.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/InvokeInterface.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/Jsr.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/MethodCall.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/Negation.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/ObjectPropertyAccess.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/Parameters.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/PrimitiveTypeCast.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/Reassignment.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/StaticField.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/Switch.class create mode 100644 OPAL/tactobc/src/test/classfilestocompare/original/WhileLoop.class diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ClassFileGenerator.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ClassFileGenerator.scala index 3a9746622c..b5ca3fc802 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ClassFileGenerator.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ClassFileGenerator.scala @@ -1,179 +1,91 @@ /* BSD 2-Clause License - see OPAL/LICENSE for details. */ package org.opalj.tactobc -import org.opalj.ba.CodeAttributeBuilder.computeStackMapTable +import java.nio.file.Files +import java.nio.file.Paths +import scala.Console.println + +import org.opalj.ba.CODE +import org.opalj.ba.CodeElement import org.opalj.ba.toDA import org.opalj.bc.Assembler -import org.opalj.br.{ArrayType, Code, CompactLineNumberTable, LocalVariable, LocalVariableTable, Method, ObjectType, StackMapTable} +import org.opalj.br.Method import org.opalj.br.analyses.Project -import org.opalj.br.instructions.Instruction import org.opalj.br.reader.Java8Framework -import java.nio.file.{Files, Paths} -import scala.Console.println -import scala.collection.immutable.ArraySeq -import scala.collection.mutable.ArrayBuffer - object ClassFileGenerator { - def generateClassFiles(byteCodes: Map[Method, ArrayBuffer[(Int, Instruction)]], p: Project[_], inputDirPath: String, outputDirPath: String, classFileName: String): Unit = { - //val helloWorldPath = "org/opalj/tactobc/testingtactobc/" -// val benchmarkPath = "jnt/scimark2/" -// val TheType = ObjectType(benchmarkPath.concat(classFileName.replace(".class", ""))) - - // Debugging: Print the location of the class loader and resources -// val loader = this.getClass.getClassLoader -// val resources = loader.getResources("").asScala.toList -// println(s"ClassLoader: $loader") -// println(s"Resources: ${resources.mkString(", ")}") - // Dynamically determine the type and resource stream - val inputFilePath = Paths.get(inputDirPath, classFileName).toString - val outputFilePath = Paths.get(outputDirPath, classFileName).toString - - val in = () => { - val stream = Files.newInputStream(Paths.get(inputFilePath)) - if (stream == null) throw new RuntimeException(s"Resource not found: $inputFilePath") - stream - } - val cf = Java8Framework.ClassFile(in).head - val newMethods = { - for (m <- cf.methods) yield { - m.body match { - case None => - m.copy() // methods which are native and abstract ... - case Some(originalBody) => - val methodSignature = m.descriptor.toJava(m.name) - byteCodes.find { - case (method, _) => - method.name == m.name && - method.descriptor.toJava(method.name) == methodSignature - } match { - case Some((_, instructions)) => - // Prepare new instructions array with null values where necessary - val maxPc = instructions.map(_._1).max - val newInstructionsWithNulls = new Array[Instruction](maxPc + 1) - - // Initialize array with nulls - for (i <- newInstructionsWithNulls.indices) { - newInstructionsWithNulls(i) = null - } - - // Fill in actual instructions - for ((pc, instruction) <- instructions) { - newInstructionsWithNulls(pc) = instruction - } - - // Print each instruction with its PC - to see if the NULLS are placed correctly - println(s"Instructions for method ${m.name}:") - newInstructionsWithNulls.zipWithIndex.foreach { - case (instruction, pc) => - if (instruction == null) { - println(s"PC $pc: NULL") - } else { - println(s"PC $pc: ${instruction.toString}") - } - } - - // Print out the translation from TAC to Bytecode with nulls - //println("newInstrWithNulls" + newInstructionsWithNulls.foreach(instruction => println(instruction.toString))) - // Debugging: Print the instructions being passed to the new Code object - println(s"Original Instructions for ${m.name}: ${originalBody.instructions.mkString(", ")}") - println(s"New Instructions for ${m.name}: ${newInstructionsWithNulls.mkString(", ")}") - //ToDo: use CodeAttribute builder - val attributesOfOriginalBody = originalBody.attributes - //Todo: - val newLocalVariableTable = LocalVariableTable(ArraySeq( - LocalVariable(0, maxPc + 1, "args", ArrayType(ObjectType("java/lang/String")), 0) - )) + def generateClassFiles( + byteCodes: Map[Method, Seq[CodeElement[Nothing]]], + p: Project[_], + inputDirPath: String, + outputDirPath: String, + classFileName: String + ): Unit = { + + // Define Paths for input and output + val inputFilePath = Paths.get(inputDirPath, classFileName).toString + val outputFilePath = Paths.get(outputDirPath, classFileName).toString + + val in = () => { + val stream = Files.newInputStream(Paths.get(inputFilePath)) + if (stream == null) throw new RuntimeException(s"Resource not found: $inputFilePath") + stream + } - // Remove CompactLineNumberTable attribute - val newAttributes = attributesOfOriginalBody.filterNot(_.isInstanceOf[CompactLineNumberTable]) - // Replace the LocalVariableTable attribute in the original attributes - val finalAttributes = newAttributes.map { - case _: LocalVariableTable => newLocalVariableTable - case other => other + val cf = Java8Framework.ClassFile(in).head + val newMethods = { + for (m <- cf.methods) yield { + m.body match { + case None => + m.copy() // methods which are native and abstract ... + case Some(originalBody) => + val methodDescriptor = m.descriptor + byteCodes.find { + case (method, _) => + method.name == m.name && + method.descriptor == methodDescriptor + } match { + case Some((_, instructions)) => + // Print out the translation from TAC to Bytecode + println(s"Original Instructions for method $m: \n${originalBody.instructions.mkString("\n ")}") + println(s"New Instructions for method $m: \n${instructions.mkString("\n ")}") + + val attributesOfOriginalBody = originalBody.attributes + + val codeAttrBuilder = CODE(instructions.toIndexedSeq) + val newBody = codeAttrBuilder(cf.version, m) + + // todo: StackMapTable needs the localVariableTable to be able to be computed + println(s"New body for method ${m.name}: $newBody") + println(attributesOfOriginalBody) + val result = m.copy(body = Some(newBody._1)) + + result + case None => + println(s"Warning: No bytecode found for method ${m.name}. Keeping original method body.") + m.copy() + } } - - val newBody = Code( - //todo: use the size of the local variables map - 10000, - 10000, - newInstructionsWithNulls, - originalBody.exceptionHandlers, - finalAttributes) - - //todo: StackMapTable needs the localVariableTable to be able to be computed - println(s"New body for method ${m.name}: $newBody") - println(attributesOfOriginalBody) - val result = m.copy(body = Some(newBody)) - - result - case None => - println(s"Warning: No bytecode found for method ${m.name}. Keeping original method body.") - m.copy() } } - } - } - val cfWithNewInstructions = cf.copy(methods = newMethods) - val newMethodsForReal = { - for (m <- cfWithNewInstructions.methods) yield { - m.body match { - case None => - m.copy() // methods which are native and abstract ... - case Some(originalBody) => - //Using find because of the extra methods that do contain the name of the method but are not part of the original file - byteCodes.find(bc => bc._1.name.contains(m.name)) match { - case Some((_, instructions)) => - //ToDo: use CodeAttribute builder - val attributesOfOriginalBody = originalBody.attributes + val cfWithNewInstructions = cf.copy(methods = newMethods) - val newStackMapTable = computeStackMapTable(m)(p.classHierarchy) - //live variable - // Replace the LocalVariableTable attribute in the original attributes - val newAttributes1 = attributesOfOriginalBody.map { - case _: StackMapTable => newStackMapTable - case other => other - } - val newBody1 = Code( - //todo: use the size of the local variables map - 10000, - 10000, - originalBody.instructions, - originalBody.exceptionHandlers, - newAttributes1) + val newRawCF = Assembler(toDA(cfWithNewInstructions)) - //todo: StackMapTable needs the localVariableTable to be able to be computed - println(s"New body for method ${m.name}: $newBody1") - println(attributesOfOriginalBody) - val result = m.copy(body = Some(newBody1)) + val outputClassFilePath = Paths.get(outputFilePath) - val it = result.body.get.iterator - val n = it.next() - val n1 = it.next() - print(n.toString + n1.toString) + Files.createDirectories(outputClassFilePath.getParent) - result - case None => - println(s"Warning: No bytecode found for method ${m.name}. Keeping original method body.") - m.copy() - } - } - } - } - val cfWithNewInstructionsForReal = cf.copy(methods = newMethodsForReal) - val newRawCF = Assembler(toDA(cfWithNewInstructionsForReal)) - val outputClassFilePath = Paths.get(outputFilePath) - Files.createDirectories(outputClassFilePath.getParent) - val newClassFile = Files.write(outputClassFilePath, newRawCF) - println("Created class file: " + newClassFile.toAbsolutePath) - //println("Class file GeneratedHelloWorldToStringDALEQUEE.class has been generated." + newClass) - // Let's test that the new class does what it is expected to do... (we execute the - // instrumented method) - //todo: the map should have all class files + val newClassFile = Files.write(outputClassFilePath, newRawCF) + println("Created class file: " + newClassFile.toAbsolutePath) + // println("Class file GeneratedHelloWorldToStringDALEQUEE.class has been generated." + newClass) + // Let's test that the new class does what it is expected to do... (we execute the + // instrumented method) + // todo: the map should have all class files // val cl = new InMemoryClassLoader(Map((TheType.toJava, newRawCF))) // val newClass = cl.findClass(TheType.toJava) // //val instance = newClass.getDeclaredConstructor().newInstance() // newClass.getMethod("main", (Array[String]()).getClass).invoke(null, Array[String]()) - } + } } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala index 5acfa7c6fc..9e3bd06467 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ExprProcessor.scala @@ -1,504 +1,666 @@ /* BSD 2-Clause License - see OPAL/LICENSE for details. */ package org.opalj.tactobc -import org.opalj.BinaryArithmeticOperators.{Add, And, Divide, Modulo, Multiply, Or, ShiftLeft, ShiftRight, Subtract, UnsignedShiftRight, XOr} -import org.opalj.RelationalOperators.{CMPG, CMPL} -import org.opalj.br.{ArrayType, BooleanType, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FloatType, IntegerType, LongType, ObjectType, ReferenceType, ShortType, Type} -import org.opalj.br.instructions.{AALOAD, ACONST_NULL, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, BALOAD, BIPUSH, CALOAD, D2F, D2I, D2L, DADD, DALOAD, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DEFAULT_INVOKEDYNAMIC, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DNEG, DREM, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, F2D, F2I, F2L, FADD, FALOAD, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FNEG, FREM, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INEG, INSTANCEOF, INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, Instruction, L2D, L2F, L2I, LADD, LALOAD, LAND, LCMP, LCONST_0, LCONST_1, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LNEG, LOR, LREM, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, LoadClass, LoadDouble, LoadFloat, LoadInt, LoadLong, LoadMethodHandle, LoadMethodType, LoadString, MULTIANEWARRAY, NEW, NEWARRAY, SALOAD, SIPUSH} +import scala.language.existentials + +import scala.collection.mutable + +import org.opalj.BinaryArithmeticOperators.Add +import org.opalj.BinaryArithmeticOperators.And +import org.opalj.BinaryArithmeticOperators.Divide +import org.opalj.BinaryArithmeticOperators.Modulo +import org.opalj.BinaryArithmeticOperators.Multiply +import org.opalj.BinaryArithmeticOperators.Or +import org.opalj.BinaryArithmeticOperators.ShiftLeft +import org.opalj.BinaryArithmeticOperators.ShiftRight +import org.opalj.BinaryArithmeticOperators.Subtract +import org.opalj.BinaryArithmeticOperators.UnsignedShiftRight +import org.opalj.BinaryArithmeticOperators.XOr +import org.opalj.RelationalOperators.CMPG +import org.opalj.RelationalOperators.CMPL +import org.opalj.ba.InstructionElement +import org.opalj.br.ArrayType +import org.opalj.br.ByteType +import org.opalj.br.CharType +import org.opalj.br.ComputationalTypeDouble +import org.opalj.br.ComputationalTypeFloat +import org.opalj.br.ComputationalTypeInt +import org.opalj.br.ComputationalTypeLong +import org.opalj.br.ComputationalTypeReference +import org.opalj.br.DoubleType +import org.opalj.br.FloatType +import org.opalj.br.IntegerType +import org.opalj.br.LongType +import org.opalj.br.ObjectType +import org.opalj.br.ReferenceType +import org.opalj.br.ShortType +import org.opalj.br.Type +import org.opalj.br.instructions.AALOAD +import org.opalj.br.instructions.ACONST_NULL +import org.opalj.br.instructions.ALOAD +import org.opalj.br.instructions.ALOAD_0 +import org.opalj.br.instructions.ALOAD_1 +import org.opalj.br.instructions.ALOAD_2 +import org.opalj.br.instructions.ALOAD_3 +import org.opalj.br.instructions.ANEWARRAY +import org.opalj.br.instructions.ARRAYLENGTH +import org.opalj.br.instructions.ASTORE +import org.opalj.br.instructions.BALOAD +import org.opalj.br.instructions.CALOAD +import org.opalj.br.instructions.D2F +import org.opalj.br.instructions.D2I +import org.opalj.br.instructions.D2L +import org.opalj.br.instructions.DADD +import org.opalj.br.instructions.DALOAD +import org.opalj.br.instructions.DCMPG +import org.opalj.br.instructions.DCMPL +import org.opalj.br.instructions.DCONST_0 +import org.opalj.br.instructions.DCONST_1 +import org.opalj.br.instructions.DDIV +import org.opalj.br.instructions.DEFAULT_INVOKEDYNAMIC +import org.opalj.br.instructions.DLOAD +import org.opalj.br.instructions.DLOAD_0 +import org.opalj.br.instructions.DLOAD_1 +import org.opalj.br.instructions.DLOAD_2 +import org.opalj.br.instructions.DLOAD_3 +import org.opalj.br.instructions.DMUL +import org.opalj.br.instructions.DNEG +import org.opalj.br.instructions.DREM +import org.opalj.br.instructions.DSTORE +import org.opalj.br.instructions.DSUB +import org.opalj.br.instructions.F2D +import org.opalj.br.instructions.F2I +import org.opalj.br.instructions.F2L +import org.opalj.br.instructions.FADD +import org.opalj.br.instructions.FALOAD +import org.opalj.br.instructions.FCMPG +import org.opalj.br.instructions.FCMPL +import org.opalj.br.instructions.FCONST_0 +import org.opalj.br.instructions.FCONST_1 +import org.opalj.br.instructions.FCONST_2 +import org.opalj.br.instructions.FDIV +import org.opalj.br.instructions.FLOAD +import org.opalj.br.instructions.FLOAD_0 +import org.opalj.br.instructions.FLOAD_1 +import org.opalj.br.instructions.FLOAD_2 +import org.opalj.br.instructions.FLOAD_3 +import org.opalj.br.instructions.FMUL +import org.opalj.br.instructions.FNEG +import org.opalj.br.instructions.FREM +import org.opalj.br.instructions.FSTORE +import org.opalj.br.instructions.FSUB +import org.opalj.br.instructions.GETFIELD +import org.opalj.br.instructions.GETSTATIC +import org.opalj.br.instructions.I2B +import org.opalj.br.instructions.I2C +import org.opalj.br.instructions.I2D +import org.opalj.br.instructions.I2F +import org.opalj.br.instructions.I2L +import org.opalj.br.instructions.I2S +import org.opalj.br.instructions.IADD +import org.opalj.br.instructions.IALOAD +import org.opalj.br.instructions.IAND +import org.opalj.br.instructions.IDIV +import org.opalj.br.instructions.ILOAD +import org.opalj.br.instructions.IMUL +import org.opalj.br.instructions.INEG +import org.opalj.br.instructions.INSTANCEOF +import org.opalj.br.instructions.INVOKEINTERFACE +import org.opalj.br.instructions.INVOKESTATIC +import org.opalj.br.instructions.INVOKEVIRTUAL +import org.opalj.br.instructions.IOR +import org.opalj.br.instructions.IREM +import org.opalj.br.instructions.ISHL +import org.opalj.br.instructions.ISHR +import org.opalj.br.instructions.ISTORE +import org.opalj.br.instructions.ISUB +import org.opalj.br.instructions.IUSHR +import org.opalj.br.instructions.IXOR +import org.opalj.br.instructions.L2D +import org.opalj.br.instructions.L2F +import org.opalj.br.instructions.L2I +import org.opalj.br.instructions.LADD +import org.opalj.br.instructions.LALOAD +import org.opalj.br.instructions.LAND +import org.opalj.br.instructions.LCMP +import org.opalj.br.instructions.LCONST_0 +import org.opalj.br.instructions.LCONST_1 +import org.opalj.br.instructions.LDIV +import org.opalj.br.instructions.LLOAD +import org.opalj.br.instructions.LLOAD_0 +import org.opalj.br.instructions.LLOAD_1 +import org.opalj.br.instructions.LLOAD_2 +import org.opalj.br.instructions.LLOAD_3 +import org.opalj.br.instructions.LMUL +import org.opalj.br.instructions.LNEG +import org.opalj.br.instructions.LoadClass +import org.opalj.br.instructions.LoadConstantInstruction +import org.opalj.br.instructions.LoadDouble +import org.opalj.br.instructions.LoadDynamic +import org.opalj.br.instructions.LoadFloat +import org.opalj.br.instructions.LoadLong +import org.opalj.br.instructions.LoadMethodHandle +import org.opalj.br.instructions.LoadMethodType +import org.opalj.br.instructions.LoadString +import org.opalj.br.instructions.LOR +import org.opalj.br.instructions.LREM +import org.opalj.br.instructions.LSHL +import org.opalj.br.instructions.LSHR +import org.opalj.br.instructions.LSTORE +import org.opalj.br.instructions.LSUB +import org.opalj.br.instructions.LUSHR +import org.opalj.br.instructions.LXOR +import org.opalj.br.instructions.MULTIANEWARRAY +import org.opalj.br.instructions.NEW +import org.opalj.br.instructions.NEWARRAY +import org.opalj.br.instructions.SALOAD import org.opalj.bytecode.BytecodeProcessingFailedException import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{ArrayLength, ArrayLoad, BinaryExpr, ClassConst, Compare, Const, DVar, DoubleConst, Expr, FloatConst, GetField, GetStatic, InstanceOf, IntConst, InvokedynamicFunctionCall, LongConst, MethodHandleConst, MethodTypeConst, New, NewArray, PrefixExpr, PrimitiveTypecastExpr, StaticFunctionCall, StringConst, UVar, Var, VirtualFunctionCall} +import org.opalj.tac.ArrayLength +import org.opalj.tac.ArrayLoad +import org.opalj.tac.BinaryExpr +import org.opalj.tac.ClassConst +import org.opalj.tac.Compare +import org.opalj.tac.Const +import org.opalj.tac.DoubleConst +import org.opalj.tac.DVar +import org.opalj.tac.DynamicConst +import org.opalj.tac.Expr +import org.opalj.tac.FloatConst +import org.opalj.tac.GetField +import org.opalj.tac.GetStatic +import org.opalj.tac.InstanceOf +import org.opalj.tac.IntConst +import org.opalj.tac.InvokedynamicFunctionCall +import org.opalj.tac.LongConst +import org.opalj.tac.MethodHandleConst +import org.opalj.tac.MethodTypeConst +import org.opalj.tac.New +import org.opalj.tac.NewArray +import org.opalj.tac.PrefixExpr +import org.opalj.tac.PrimitiveTypecastExpr +import org.opalj.tac.StaticFunctionCall +import org.opalj.tac.StringConst +import org.opalj.tac.UVar +import org.opalj.tac.Var +import org.opalj.tac.VirtualFunctionCall import org.opalj.value.IsSReferenceValue -import scala.collection.mutable -import scala.collection.mutable.ArrayBuffer - object ExprProcessor { - - def processExpression(expr: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - expr match { - case const: Const => loadConstant(const, instructionsWithPCs, currentPC) - case variable: Var[_] => loadVariable(variable, instructionsWithPCs, currentPC) - case getField: GetField[_] => handleGetField(getField, instructionsWithPCs, currentPC) - case getStatic: GetStatic => handleGetStatic(getStatic, instructionsWithPCs, currentPC) - case binaryExpr: BinaryExpr[_] => handleBinaryExpr(binaryExpr, instructionsWithPCs, currentPC) - case virtualFunctionCallExpr: VirtualFunctionCall[_] => handleVirtualFunctionCall(virtualFunctionCallExpr, instructionsWithPCs, currentPC) - case staticFunctionCallExpr: StaticFunctionCall[_] => handleStaticFunctionCall(staticFunctionCallExpr, instructionsWithPCs, currentPC) - case newExpr: New => handleNewExpr(newExpr.tpe, instructionsWithPCs, currentPC) - case primitiveTypecaseExpr: PrimitiveTypecastExpr[_] => handlePrimitiveTypeCastExpr(primitiveTypecaseExpr, instructionsWithPCs, currentPC) - case arrayLength: ArrayLength[_] => handleArrayLength(arrayLength, instructionsWithPCs, currentPC) - case arrayLoadExpr: ArrayLoad[_] => handleArrayLoad(arrayLoadExpr, instructionsWithPCs, currentPC) - case newArrayExpr: NewArray[_] => handleNewArray(newArrayExpr, instructionsWithPCs, currentPC) - case invokedynamicFunctionCall: InvokedynamicFunctionCall[_] => handleInvokedynamicFunctionCall(invokedynamicFunctionCall, instructionsWithPCs, currentPC) - case compare: Compare[_] => handleCompare(compare, instructionsWithPCs, currentPC) - case prefixExpr: PrefixExpr[_] => handlePrefixExpr(prefixExpr, instructionsWithPCs, currentPC) - case instanceOf: InstanceOf[_] => handleInstanceOf(instanceOf, instructionsWithPCs, currentPC) - case _ => - throw new UnsupportedOperationException("Unsupported expression type" + expr) + def processExpression(expr: Expr[_], uVarToLVIndex: mutable.Map[IntTrieSet, Int]): List[InstructionElement] = { + expr match { + case const: Const => loadConstant(const) + case variable: Var[_] => loadVariable(variable, uVarToLVIndex) + case getField: GetField[_] => handleGetField(getField, uVarToLVIndex) + case getStatic: GetStatic => handleGetStatic(getStatic) + case binaryExpr: BinaryExpr[_] => handleBinaryExpr(binaryExpr, uVarToLVIndex) + case virtualFunctionCallExpr: VirtualFunctionCall[_] => + handleVirtualFunctionCall(virtualFunctionCallExpr, uVarToLVIndex) + case staticFunctionCallExpr: StaticFunctionCall[_] => + handleStaticFunctionCall(staticFunctionCallExpr, uVarToLVIndex) + case newExpr: New => handleNewExpr(newExpr.tpe) + case primitiveTypecaseExpr: PrimitiveTypecastExpr[_] => + handlePrimitiveTypeCastExpr(primitiveTypecaseExpr, uVarToLVIndex) + case arrayLength: ArrayLength[_] => handleArrayLength(arrayLength, uVarToLVIndex) + case arrayLoadExpr: ArrayLoad[_] => handleArrayLoad(arrayLoadExpr, uVarToLVIndex) + case newArrayExpr: NewArray[_] => handleNewArray(newArrayExpr, uVarToLVIndex) + case invokedynamicFunctionCall: InvokedynamicFunctionCall[_] => + handleInvokedynamicFunctionCall(invokedynamicFunctionCall, uVarToLVIndex) + case compare: Compare[_] => handleCompare(compare, uVarToLVIndex) + case prefixExpr: PrefixExpr[_] => handlePrefixExpr(prefixExpr, uVarToLVIndex) + case instanceOf: InstanceOf[_] => handleInstanceOf(instanceOf, uVarToLVIndex) + case _ => + throw new UnsupportedOperationException("Unsupported expression type" + expr) + } } - } - - def handleInstanceOf(instanceOf: InstanceOf[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val afterExprPC = ExprProcessor.processExpression(instanceOf.value, instructionsWithPCs, currentPC) - val instruction = INSTANCEOF(instanceOf.cmpTpe) - instructionsWithPCs += ((afterExprPC, instruction)) - afterExprPC + instruction.length - } - - def handlePrefixExpr(prefixExpr: PrefixExpr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Process the operand (the expression being negated) - val operandPC = ExprProcessor.processExpression(prefixExpr.operand, instructionsWithPCs, currentPC) - - // Determine the appropriate negation instruction based on the operand type - val instruction = prefixExpr.operand.cTpe match { - case ComputationalTypeInt => INEG - case ComputationalTypeLong => LNEG - case ComputationalTypeFloat => FNEG - case ComputationalTypeDouble => DNEG - case _ => throw new UnsupportedOperationException(s"Unsupported type for negation: ${prefixExpr.operand.cTpe}") + + def handleInstanceOf( + instanceOf: InstanceOf[_], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + instructions ++= ExprProcessor.processExpression(instanceOf.value, uVarToLVIndex) + instructions += INSTANCEOF(instanceOf.cmpTpe) + instructions.toList } - // Add the instruction to the list - instructionsWithPCs += ((operandPC, instruction)) - operandPC + instruction.length // Update and return the new program counter - } - - def handleCompare(compare: Compare[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Process the left expression and update the PC - val pcAfterLeft = processExpression(compare.left, instructionsWithPCs, currentPC) - - // Process the right expression and update the PC - val pcAfterRight = processExpression(compare.right, instructionsWithPCs, pcAfterLeft) - - // Determine the appropriate comparison instruction - val instruction = compare.left.cTpe match { - case ComputationalTypeFloat => - compare.condition match { - case CMPG => FCMPG - case CMPL => FCMPL - case _ => throw new IllegalArgumentException("Unsupported comparison operator for float type") - } - case ComputationalTypeDouble => - compare.condition match { - case CMPG => DCMPG - case CMPL => DCMPL - case _ => throw new IllegalArgumentException("Unsupported comparison operator for double type") + def handlePrefixExpr( + prefixExpr: PrefixExpr[_], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + + // Process the operand (the expression being negated) + instructions ++= ExprProcessor.processExpression(prefixExpr.operand, uVarToLVIndex) + + // Determine the appropriate negation instruction based on the operand type + val instruction = prefixExpr.operand.cTpe match { + case ComputationalTypeInt => INEG + case ComputationalTypeLong => LNEG + case ComputationalTypeFloat => FNEG + case ComputationalTypeDouble => DNEG + case _ => + throw new UnsupportedOperationException(s"Unsupported type for negation: ${prefixExpr.operand.cTpe}") } - case ComputationalTypeLong => - LCMP - case _ => throw new IllegalArgumentException("Unsupported comparison type") + instructions += instruction + instructions.toList } - // Add the comparison instruction to the list - instructionsWithPCs += ((pcAfterRight, instruction)) - - // Update the PC and return it - pcAfterRight + instruction.length - } + def handleCompare(compare: Compare[_], uVarToLVIndex: mutable.Map[IntTrieSet, Int]): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + // Process the left expression and update the PC + instructions ++= processExpression(compare.left, uVarToLVIndex) + + // Process the right expression and update the PC + instructions ++= processExpression(compare.right, uVarToLVIndex) + + // Determine the appropriate comparison instruction + val instruction = compare.left.cTpe match { + case ComputationalTypeFloat => + compare.condition match { + case CMPG => FCMPG + case CMPL => FCMPL + case _ => throw new IllegalArgumentException("Unsupported comparison operator for float type") + } + case ComputationalTypeDouble => + compare.condition match { + case CMPG => DCMPG + case CMPL => DCMPL + case _ => throw new IllegalArgumentException("Unsupported comparison operator for double type") + } + case ComputationalTypeLong => + LCMP + case _ => throw new IllegalArgumentException("Unsupported comparison type") + } + instructions += instruction + instructions.toList + } - def handleInvokedynamicFunctionCall(invokedynamicFunctionCall: InvokedynamicFunctionCall[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Initialize the PC after processing the receiver - var currentAfterParamsPC = currentPC + def handleInvokedynamicFunctionCall( + invokedynamicFunctionCall: InvokedynamicFunctionCall[_], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() - // Process each parameter and update the PC accordingly - for (param <- invokedynamicFunctionCall.params) { - currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) - } - val instruction = DEFAULT_INVOKEDYNAMIC(invokedynamicFunctionCall.bootstrapMethod, invokedynamicFunctionCall.name, invokedynamicFunctionCall.descriptor) - instructionsWithPCs += ((currentAfterParamsPC, instruction)) - currentAfterParamsPC + instruction.length - } - - def handleNewArray(newArrayExpr: NewArray[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Initialize the PC after processing the counts - var currentAfterCountsPC = currentPC - // Process each parameter and update the PC accordingly - for (count <- newArrayExpr.counts.reverse) { - currentAfterCountsPC = ExprProcessor.processExpression(count, instructionsWithPCs, currentAfterCountsPC) - } - if(newArrayExpr.counts.size > 1) { - // Construct the array type string for the multi-dimensional array - val arrayTypeString = newArrayExpr.tpe match { - case arrayType: ArrayType => constructArrayTypeString(arrayType) - case _ => throw new IllegalArgumentException("Expected an array type for MULTIANEWARRAY") - } - val instruction = MULTIANEWARRAY(arrayTypeString, newArrayExpr.counts.size) - instructionsWithPCs += ((currentAfterCountsPC, instruction)) - return currentAfterCountsPC + instruction.length - } - val instruction = newArrayExpr.tpe.componentType match { - case _: ReferenceType => ANEWARRAY(newArrayExpr.tpe.componentType.toJava.replace(".", "/")) - case _: BooleanType => NEWARRAY(BooleanType.atype) - case _: CharType => NEWARRAY(CharType.atype) - case _: FloatType => NEWARRAY(FloatType.atype) - case _: DoubleType => NEWARRAY(DoubleType.atype) - case _: ByteType => NEWARRAY(ShortType.atype) - case _: ShortType => NEWARRAY(ShortType.atype) - case _: IntegerType => NEWARRAY(IntegerType.atype) - case _: LongType => NEWARRAY(LongType.atype) - case _ => throw new IllegalArgumentException("Unsupported array load type") - } - instructionsWithPCs += ((currentAfterCountsPC, instruction)) - currentAfterCountsPC + instruction.length - } - - def constructArrayTypeString(arrayType: ArrayType): String = { - def loop(tpe: Type, depth: Int): (String, Int) = tpe match { - case ArrayType(componentType) => - loop(componentType, depth + 1) - case baseType => - (baseType.toString, depth) + // Process each parameter and update the PC accordingly + for (param <- invokedynamicFunctionCall.params) { + instructions ++= ExprProcessor.processExpression(param, uVarToLVIndex) + } + val instruction = DEFAULT_INVOKEDYNAMIC( + invokedynamicFunctionCall.bootstrapMethod, + invokedynamicFunctionCall.name, + invokedynamicFunctionCall.descriptor + ) + instructions += instruction + instructions.toList } - val (baseTypeString, depth) = loop(arrayType, 0) - "[" * depth + baseTypeString - } - - def handleArrayLoad(arrayLoadExpr: ArrayLoad[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Load the array reference onto the stack - val pcAfterArrayRefLoad = processExpression(arrayLoadExpr.arrayRef, instructionsWithPCs, currentPC) - // Load the index onto the stack - val pcAfterIndexLoad = processExpression(arrayLoadExpr.index, instructionsWithPCs, pcAfterArrayRefLoad) - - // Infer the element type from the array reference expression - val elementType = inferElementType(arrayLoadExpr.arrayRef) - - val instruction = elementType match { - case IntegerType => IALOAD - case LongType => LALOAD - case FloatType => FALOAD - case DoubleType => DALOAD - case ByteType => BALOAD - case CharType => CALOAD - case ShortType => SALOAD - case _: ReferenceType => AALOAD - case _ => throw new IllegalArgumentException("Unsupported array load type" + elementType) + def handleNewArray(newArrayExpr: NewArray[_], uVarToLVIndex: mutable.Map[IntTrieSet, Int]): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + // Process each parameter and update the PC accordingly + for (count <- newArrayExpr.counts.reverse) { + instructions ++= ExprProcessor.processExpression(count, uVarToLVIndex) + } + if (newArrayExpr.counts.size > 1) { + // Construct the array type string for the multi-dimensional array + val arrayTypeString = newArrayExpr.tpe match { + case arrayType: ArrayType => + constructArrayTypeString(arrayType) + case _ => throw new IllegalArgumentException("Expected an array type for MULTIANEWARRAY") + } + instructions += MULTIANEWARRAY(arrayTypeString, newArrayExpr.counts.size) + } else { + val instruction = + if (newArrayExpr.tpe.componentType.isReferenceType) { + ANEWARRAY(newArrayExpr.tpe.componentType.asReferenceType) + } else { + NEWARRAY(newArrayExpr.tpe.componentType.asBaseType.atype) + } + instructions += instruction + } + instructions.toList } - instructionsWithPCs += ((pcAfterIndexLoad, instruction)) - pcAfterIndexLoad + instruction.length - } + def constructArrayTypeString(arrayType: ArrayType): String = { + def loop(tpe: Type, depth: Int): (String, Int) = tpe match { + case ArrayType(componentType) => + loop(componentType, depth + 1) + case baseType => + (baseType.toString, depth) + } - // Helper function to infer the element type from the array reference expression - def inferElementType(expr: Expr[_]): Type = { - expr.asInstanceOf[UVar[_]].value.asInstanceOf[IsSReferenceValue[_]].theUpperTypeBound.asInstanceOf[ArrayType] match { - case ArrayType(componentType) => componentType - case _ => throw new IllegalArgumentException(s"Expected an array type but found: ${expr.cTpe}") - } - } - def handleArrayLength(arrayLength: ArrayLength[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Process the receiver object (e.g., aload_0 for `this`) - val afterReceiverPC = ExprProcessor.processExpression(arrayLength.arrayRef, instructionsWithPCs, currentPC) - val instruction = ARRAYLENGTH - instructionsWithPCs += ((afterReceiverPC, instruction)) - afterReceiverPC + instruction.length - } - - def handleNewExpr(tpe: ObjectType, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val instruction = NEW(tpe) - instructionsWithPCs += ((currentPC, instruction)) - currentPC + instruction.length - } - - def handleStaticFunctionCall(expr: StaticFunctionCall[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Initialize the PC after processing the receiver - var currentAfterParamsPC = currentPC - - // Process each parameter and update the PC accordingly - for (param <- expr.params) { - currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) - } - val instruction = if (expr.isInterface) { - INVOKEINTERFACE(expr.declaringClass, expr.name, expr.descriptor) - } else { - INVOKESTATIC(expr.declaringClass, expr.isInterface, expr.name, expr.descriptor) + val (baseTypeString, depth) = loop(arrayType, 0) + "[" * depth + baseTypeString } - instructionsWithPCs += ((currentAfterParamsPC, instruction)) - currentAfterParamsPC + instruction.length - } - - def handleVirtualFunctionCall(expr: VirtualFunctionCall[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Process the receiver object (e.g., aload_0 for `this`) - val afterReceiverPC = ExprProcessor.processExpression(expr.receiver, instructionsWithPCs, currentPC) - - // Initialize the PC after processing the receiver - var currentAfterParamsPC = afterReceiverPC + def handleArrayLoad( + arrayLoadExpr: ArrayLoad[_], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + // Load the array reference onto the stack + instructions ++= processExpression(arrayLoadExpr.arrayRef, uVarToLVIndex) + // Load the index onto the stack + instructions ++= processExpression(arrayLoadExpr.index, uVarToLVIndex) + + // Infer the element type from the array reference expression + val elementType = inferElementType(arrayLoadExpr.arrayRef) + + val instruction = elementType match { + case IntegerType => IALOAD + case LongType => LALOAD + case FloatType => FALOAD + case DoubleType => DALOAD + case ByteType => BALOAD + case CharType => CALOAD + case ShortType => SALOAD + case _: ReferenceType => AALOAD + case _ => throw new IllegalArgumentException("Unsupported array load type" + elementType) + } + instructions += instruction + instructions.toList + } - // Process each parameter and update the PC accordingly - for (param <- expr.params) { - currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + // Helper function to infer the element type from the array reference expression + def inferElementType(expr: Expr[_]): Type = { + expr.asInstanceOf[UVar[_]].value.asInstanceOf[IsSReferenceValue[_]].theUpperTypeBound.asInstanceOf[ArrayType] match { + case ArrayType(componentType) => + println(s"ArrayType($componentType)") + componentType + case _ => throw new IllegalArgumentException(s"Expected an array type but found: ${expr.cTpe}") + } } - val instruction = if (expr.isInterface) { - INVOKEINTERFACE(expr.declaringClass.asObjectType, expr.name, expr.descriptor) - } else { - INVOKEVIRTUAL(expr.declaringClass, expr.name, expr.descriptor) + def handleArrayLength( + arrayLength: ArrayLength[_], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + // Process the receiver object (e.g., aload_0 for `this`) + instructions ++= ExprProcessor.processExpression(arrayLength.arrayRef, uVarToLVIndex) + instructions += ARRAYLENGTH + instructions.toList } - instructionsWithPCs += ((currentAfterParamsPC, instruction)) - currentAfterParamsPC + instruction.length - } - - private def loadConstant(constExpr: Const, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val instruction = { - if(constExpr.isNullExpr){ - ACONST_NULL - }else - constExpr match { - case IntConst(_, value) => value match { - case -1 => ICONST_M1 - case 0 => ICONST_0 - case 1 => ICONST_1 - case 2 => ICONST_2 - case 3 => ICONST_3 - case 4 => ICONST_4 - case 5 => ICONST_5 - case _ if value >= Byte.MinValue && value <= Byte.MaxValue => BIPUSH(value) - case _ if value >= Short.MinValue && value <= Short.MaxValue => SIPUSH(value) - case _ => LoadInt(value) - } - case FloatConst(_, value) => value match { - case 0 => FCONST_0 - case 1 => FCONST_1 - case 2 => FCONST_2 - case _ => LoadFloat(value) - } - case ClassConst(_, value) => LoadClass(value) - case StringConst(_, value) => LoadString(value) - case MethodHandleConst(_, value) => LoadMethodHandle(value) - case MethodTypeConst(_, value) => LoadMethodType(value) - case DoubleConst(_, value) => value match { - case 0 => DCONST_0 - case 1 => DCONST_1 - case _ => LoadDouble(value) - } - case LongConst(_, value) => value match { - case 0 => LCONST_0 - case 1 => LCONST_1 - case _ => LoadLong(value) - } - //todo: figure out how and what LoadDynamic is - //I think LDCDynamic is not an actual Instruction. - /*case Assignment(_, _, DynamicConst(_, bootstrapMethod, name, descriptor)) => - val instruction = LoadDynamic(-1, bootstrapMethod, name, descriptor) - instructionsWithPCs += ((currentPC, instruction)) - currentPC += instruction.length*/ - case _ => throw BytecodeProcessingFailedException("unsupported constant value: " + constExpr) + def handleNewExpr(tpe: ObjectType): List[InstructionElement] = { + List( + NEW(tpe) + ) } - } - instructionsWithPCs += ((currentPC, instruction)) - currentPC + instruction.length // Update and return the new program counter - } - - var uVarToLVIndex = mutable.Map[IntTrieSet, Int]() - var nextLVIndex = 1 - - // Method to get LVIndex for a variable - def getVariableLvlIndex(variable: Var[_]): Int = { - variable match { - case dVar: DVar[_] => - val uVarDefSites = uVarToLVIndex.find { case (defSites, _) => defSites.contains(dVar.origin) } - uVarDefSites match { - case Some((_, index)) => index - case None => throw new NoSuchElementException(s"No LVIndex found for DVar with origin ${dVar.origin}") + + def handleStaticFunctionCall( + expr: StaticFunctionCall[_], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + // Process each parameter and update the PC accordingly + for (param <- expr.params) { + instructions ++= ExprProcessor.processExpression(param, uVarToLVIndex) } - case uVar: UVar[_] => - val defSiteMatch = uVarToLVIndex.find { case (defSites, _) => defSites.exists(uVar.defSites.contains) } - defSiteMatch match { - case Some((_, index)) => index - case None => throw new NoSuchElementException(s"No LVIndex found for UVar with defSites ${uVar.defSites}") + val instruction = if (expr.isInterface) { + INVOKEINTERFACE(expr.declaringClass, expr.name, expr.descriptor) + } else { + INVOKESTATIC(expr.declaringClass, expr.isInterface, expr.name, expr.descriptor) } - case _ => throw new UnsupportedOperationException("Unsupported variable type") + instructions += instruction + instructions.toList } - } - - def loadVariable(variable: Var[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val index = getVariableLvlIndex(variable) - val instruction = variable.cTpe match { - case ComputationalTypeInt => index match { - case 0 => ILOAD_0 - case 1 => ILOAD_1 - case 2 => ILOAD_2 - case 3 => ILOAD_3 - case _ => ILOAD(index) - } - case ComputationalTypeFloat => index match { - case 0 => FLOAD_0 - case 1 => FLOAD_1 - case 2 => FLOAD_2 - case 3 => FLOAD_3 - case _ => FLOAD(index) - } - case ComputationalTypeDouble => index match { - case 0 => DLOAD_0 - case 1 => DLOAD_1 - case 2 => DLOAD_2 - case 3 => DLOAD_3 - case _ => DLOAD(index) - } - case ComputationalTypeLong => index match { - case 0 => LLOAD_0 - case 1 => LLOAD_1 - case 2 => LLOAD_2 - case 3 => LLOAD_3 - case _ => LLOAD(index) + + def handleVirtualFunctionCall( + expr: VirtualFunctionCall[_], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + + // Process the receiver object (e.g., aload_0 for `this`) + instructions ++= ExprProcessor.processExpression(expr.receiver, uVarToLVIndex) + + // Process each parameter and update the PC accordingly + for (param <- expr.params) { + instructions ++= ExprProcessor.processExpression(param, uVarToLVIndex) } - case ComputationalTypeReference => index match { - case 0 => ALOAD_0 - case 1 => ALOAD_1 - case 2 => ALOAD_2 - case 3 => ALOAD_3 - case _ => ALOAD(index) + val instruction = if (expr.isInterface) { + INVOKEINTERFACE(expr.declaringClass.asObjectType, expr.name, expr.descriptor) + } else { + INVOKEVIRTUAL(expr.declaringClass, expr.name, expr.descriptor) } - case _ => throw new UnsupportedOperationException("Unsupported computational type for loading variable" + variable) - } - instructionsWithPCs += ((currentPC, instruction)) - currentPC + (if (index < 4) 1 else 2) - } - - def storeVariable(variable: Var[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - //val variableName = handleDVarName(variable) - val index = getVariableLvlIndex(variable) - val storeInstruction = variable.cTpe match { - case ComputationalTypeInt => index match { - //The must be an index into the local variable array of the current frame (ยง2.6). - // The value on the top of the operand stack must be of type int. It is popped from the operand stack, and the value of the local variable at is set to value. - case 0 => ISTORE_0 - case 1 => ISTORE_1 - case 2 => ISTORE_2 - case 3 => ISTORE_3 - case _ => ISTORE(index) + instructions += instruction + instructions.toList + } + + private def loadConstant(constExpr: Const): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + val instruction = { + if (constExpr.isNullExpr) { + ACONST_NULL + } else + constExpr match { + case IntConst(_, value) => LoadConstantInstruction(value) + case FloatConst(_, value) => value match { + case 0 => FCONST_0 + case 1 => FCONST_1 + case 2 => FCONST_2 + case _ => LoadFloat(value) + } + case ClassConst(_, value) => LoadClass(value) + case StringConst(_, value) => LoadString(value) + case MethodHandleConst(_, value) => LoadMethodHandle(value) + case MethodTypeConst(_, value) => LoadMethodType(value) + case DoubleConst(_, value) => value match { + case 0 => DCONST_0 + case 1 => DCONST_1 + case _ => LoadDouble(value) + } + case LongConst(_, value) => value match { + case 0 => LCONST_0 + case 1 => LCONST_1 + case _ => LoadLong(value) + } + case DynamicConst(_, bootstrapMethod, name, descriptor) => + LoadDynamic(bootstrapMethod, name, descriptor) + + case _ => throw BytecodeProcessingFailedException("unsupported constant value: " + constExpr) + } } - case ComputationalTypeFloat => index match { - case 0 => FSTORE_0 - case 1 => FSTORE_1 - case 2 => FSTORE_2 - case 3 => FSTORE_3 - case _ => FSTORE(index) + instructions += instruction + instructions.toList + } + + // Method to get LVIndex for a variable + def getVariableLvIndex(variable: Var[_], uVarToLVIndex: mutable.Map[IntTrieSet, Int]): Int = { + variable match { + case dVar: DVar[_] => + val uVarDefSites = uVarToLVIndex.find { case (defSites, _) => + defSites.contains(dVar.origin) + } + uVarDefSites match { + case Some((_, index)) => index + case None => + throw new NoSuchElementException(s"No LVIndex found for DVar with origin ${dVar.origin}") + } + case uVar: UVar[_] => + val defSiteMatch = uVarToLVIndex.find { case (defSites, index) => + defSites.exists(uVar.defSites.contains) + } + defSiteMatch match { + case Some((_, index)) => index + case None => + throw new NoSuchElementException(s"No LVIndex found for UVar with defSites ${uVar.defSites}") + } + case _ => throw new UnsupportedOperationException("Unsupported variable type") } - case ComputationalTypeDouble => index match { - case 0 => DSTORE_0 - case 1 => DSTORE_1 - case 2 => DSTORE_2 - case 3 => DSTORE_3 - case _ => DSTORE(index) + } + + def loadVariable(variable: Var[_], uVarToLVIndex: mutable.Map[IntTrieSet, Int]): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + + val index = getVariableLvIndex(variable, uVarToLVIndex) + val instruction = variable.cTpe match { + case ComputationalTypeInt => ILOAD.canonicalRepresentation(index) + case ComputationalTypeFloat => index match { + case 0 => FLOAD_0 + case 1 => FLOAD_1 + case 2 => FLOAD_2 + case 3 => FLOAD_3 + case _ => FLOAD(index) + } + case ComputationalTypeDouble => index match { + case 0 => DLOAD_0 + case 1 => DLOAD_1 + case 2 => DLOAD_2 + case 3 => DLOAD_3 + case _ => DLOAD(index) + } + case ComputationalTypeLong => index match { + case 0 => LLOAD_0 + case 1 => LLOAD_1 + case 2 => LLOAD_2 + case 3 => LLOAD_3 + case _ => LLOAD(index) + } + case ComputationalTypeReference => index match { + case 0 => ALOAD_0 + case 1 => ALOAD_1 + case 2 => ALOAD_2 + case 3 => ALOAD_3 + case _ => ALOAD(index) + } + case _ => + throw new UnsupportedOperationException("Unsupported computational type for loading variable" + variable) } - case ComputationalTypeLong => index match { - case 0 => LSTORE_0 - case 1 => LSTORE_1 - case 2 => LSTORE_2 - case 3 => LSTORE_3 - case _ => LSTORE(index) + instructions += instruction + instructions.toList + } + + def storeVariable( + variable: Var[_], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): InstructionElement = { +// val variableName = handleDVarName(variable) + val index = getVariableLvIndex(variable, uVarToLVIndex) + variable.cTpe match { + // The must be an index into the local variable array of the current frame (ยง2.6). + // The value on the top of the operand stack must be of type int. It is popped from the operand stack, + // and the value of the local variable at is set to value. + case ComputationalTypeInt => ISTORE.canonicalRepresentation(index) + case ComputationalTypeFloat => FSTORE.canonicalRepresentation(index) + case ComputationalTypeDouble => DSTORE.canonicalRepresentation(index) + case ComputationalTypeLong => LSTORE.canonicalRepresentation(index) + case ComputationalTypeReference => ASTORE.canonicalRepresentation(index) + case _ => + throw new UnsupportedOperationException("Unsupported computational type for storing variable" + variable) } - case ComputationalTypeReference => index match { - case 0 => ASTORE_0 - case 1 => ASTORE_1 - case 2 => ASTORE_2 - case 3 => ASTORE_3 - case _ => ASTORE(index) + } + + def handleGetField(getField: GetField[_], uVarToLVIndex: mutable.Map[IntTrieSet, Int]): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + // Load the object reference onto the stack + instructions ++= processExpression(getField.objRef, uVarToLVIndex) + // Generate the GETFIELD instruction + instructions += GETFIELD(getField.declaringClass, getField.name, getField.declaredFieldType) + instructions.toList + } + + def handleGetStatic(getStatic: GetStatic): List[InstructionElement] = { + List( + GETSTATIC(getStatic.declaringClass, getStatic.name, getStatic.declaredFieldType) + ) + } + + def handleBinaryExpr( + binaryExpr: BinaryExpr[_], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + + val instructions = mutable.ListBuffer[InstructionElement]() + + // process the left expr and save the pc to give in the right expr processing + instructions ++= processExpression(binaryExpr.left, uVarToLVIndex) + // process the right Expr + instructions ++= processExpression(binaryExpr.right, uVarToLVIndex) + + val instruction = (binaryExpr.cTpe, binaryExpr.op) match { + // Double + case (ComputationalTypeDouble, Add) => DADD + case (ComputationalTypeDouble, Subtract) => DSUB + case (ComputationalTypeDouble, Multiply) => DMUL + case (ComputationalTypeDouble, Divide) => DDIV + case (ComputationalTypeDouble, Modulo) => DREM + // Float + case (ComputationalTypeFloat, Add) => FADD + case (ComputationalTypeFloat, Subtract) => FSUB + case (ComputationalTypeFloat, Multiply) => FMUL + case (ComputationalTypeFloat, Divide) => FDIV + case (ComputationalTypeFloat, Modulo) => FREM + // Int + case (ComputationalTypeInt, Add) => IADD + case (ComputationalTypeInt, Subtract) => ISUB + case (ComputationalTypeInt, Multiply) => IMUL + case (ComputationalTypeInt, Divide) => IDIV + case (ComputationalTypeInt, Modulo) => IREM + case (ComputationalTypeInt, And) => IAND + case (ComputationalTypeInt, Or) => IOR + case (ComputationalTypeInt, ShiftLeft) => ISHL + case (ComputationalTypeInt, ShiftRight) => ISHR + case (ComputationalTypeInt, UnsignedShiftRight) => IUSHR + case (ComputationalTypeInt, XOr) => IXOR + // Long + case (ComputationalTypeLong, Add) => LADD + case (ComputationalTypeLong, Subtract) => LSUB + case (ComputationalTypeLong, Multiply) => LMUL + case (ComputationalTypeLong, Divide) => LDIV + case (ComputationalTypeLong, Modulo) => LREM + case (ComputationalTypeLong, And) => LAND + case (ComputationalTypeLong, Or) => LOR + case (ComputationalTypeLong, ShiftLeft) => LSHL + case (ComputationalTypeLong, ShiftRight) => LSHR + case (ComputationalTypeLong, UnsignedShiftRight) => LUSHR + case (ComputationalTypeLong, XOr) => LXOR + // Unsupported + case _ => throw new UnsupportedOperationException( + "Unsupported operation or computational type in BinaryExpr" + binaryExpr + ) } - case _ => throw new UnsupportedOperationException("Unsupported computational type for storing variable" + variable) - } - instructionsWithPCs += ((currentPC, storeInstruction)) - currentPC + (if (index < 4) 1 else 2) - } - - def handleGetField(getField: GetField[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Load the object reference onto the stack - val pcAfterObjectRefLoad = processExpression(getField.objRef, instructionsWithPCs, currentPC) - // Generate the GETFIELD instruction - val instruction = GETFIELD(getField.declaringClass, getField.name, getField.declaredFieldType) - instructionsWithPCs += ((pcAfterObjectRefLoad, instruction)) - pcAfterObjectRefLoad + instruction.length // Update and return the new program counter - } - - def handleGetStatic(getStatic: GetStatic, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val instruction = GETSTATIC(getStatic.declaringClass, getStatic.name, getStatic.declaredFieldType) - instructionsWithPCs += ((currentPC, instruction)) - currentPC + instruction.length // Update and return the new program counter - } - - def handleBinaryExpr(binaryExpr: BinaryExpr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // process the left expr and save the pc to give in the right expr processing - val leftPC = processExpression(binaryExpr.left, instructionsWithPCs, currentPC) - // process the right Expr - val rightPC = processExpression(binaryExpr.right, instructionsWithPCs, leftPC) - val (instruction, instructionLength) = (binaryExpr.cTpe, binaryExpr.op) match { - //Double - case (ComputationalTypeDouble, Add) => (DADD, DADD.length) - case (ComputationalTypeDouble, Subtract) => (DSUB, DSUB.length) - case (ComputationalTypeDouble, Multiply) => (DMUL, DMUL.length) - case (ComputationalTypeDouble, Divide) => (DDIV, DDIV.length) - case (ComputationalTypeDouble, Modulo) => (DREM, DREM.length) - //Float - case (ComputationalTypeFloat, Add) => (FADD, FADD.length) - case (ComputationalTypeFloat, Subtract) => (FSUB, FSUB.length) - case (ComputationalTypeFloat, Multiply) => (FMUL, FMUL.length) - case (ComputationalTypeFloat, Divide) => (FDIV, FDIV.length) - case (ComputationalTypeFloat, Modulo) => (FREM, FREM.length) - //Int - case (ComputationalTypeInt, Add) => (IADD, IADD.length) - case (ComputationalTypeInt, Subtract) => (ISUB, ISUB.length) - case (ComputationalTypeInt, Multiply) => (IMUL, IMUL.length) - case (ComputationalTypeInt, Divide) => (IDIV, IDIV.length) - case (ComputationalTypeInt, Modulo) => (IREM, IREM.length) - case (ComputationalTypeInt, And) => (IAND, IAND.length) - case (ComputationalTypeInt, Or) => (IOR, IOR.length) - case (ComputationalTypeInt, ShiftLeft) => (ISHL, ISHL.length) - case (ComputationalTypeInt, ShiftRight) => (ISHR, ISHR.length) - case (ComputationalTypeInt, UnsignedShiftRight) => (IUSHR, IUSHR.length) - case (ComputationalTypeInt, XOr) => (IXOR, IXOR.length) - //Long - case (ComputationalTypeLong, Add) => (LADD, LADD.length) - case (ComputationalTypeLong, Subtract) => (LSUB, LSUB.length) - case (ComputationalTypeLong, Multiply) => (LMUL, LMUL.length) - case (ComputationalTypeLong, Divide) => (LDIV, LDIV.length) - case (ComputationalTypeLong, Modulo) => (LREM, LREM.length) - case (ComputationalTypeLong, And) => (LAND, LAND.length) - case (ComputationalTypeLong, Or) => (LOR, LOR.length) - case (ComputationalTypeLong, ShiftLeft) => (LSHL, LSHL.length) - case (ComputationalTypeLong, ShiftRight) => (LSHR, LSHR.length) - case (ComputationalTypeLong, UnsignedShiftRight) => (LUSHR, LUSHR.length) - case (ComputationalTypeLong, XOr) => (LXOR, LXOR.length) - //Unsupported - case _ => throw new UnsupportedOperationException("Unsupported operation or computational type in BinaryExpr" + binaryExpr) + instructions += instruction + instructions.toList } - val offsetPC = currentPC + (rightPC - currentPC) - instructionsWithPCs += ((offsetPC, instruction)) - offsetPC + instructionLength - } - def handlePrimitiveTypeCastExpr(primitiveTypecastExpr: PrimitiveTypecastExpr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // First, process the operand expression and add its instructions to the buffer - val operandPC = processExpression(primitiveTypecastExpr.operand, instructionsWithPCs, currentPC) - - val instruction = (primitiveTypecastExpr.operand.cTpe, primitiveTypecastExpr.targetTpe) match { - // -> to Float - case (ComputationalTypeDouble, FloatType) => D2F - case (ComputationalTypeInt, FloatType) => I2F - case (ComputationalTypeLong, FloatType) => L2F - // -> to Int - case (ComputationalTypeDouble, IntegerType) => D2I - case (ComputationalTypeFloat, IntegerType) => F2I - case (ComputationalTypeLong, IntegerType) => L2I - // -> to Long - case (ComputationalTypeDouble, LongType) => D2L - case (ComputationalTypeInt, LongType) => I2L - case (ComputationalTypeFloat, LongType) => F2L - // -> to Double - case (ComputationalTypeFloat, DoubleType) => F2D - case (ComputationalTypeInt, DoubleType) => I2D - case (ComputationalTypeLong, DoubleType) => L2D - // -> to Char - case (ComputationalTypeInt, CharType) => I2C - // -> to Byte - case (ComputationalTypeInt, ByteType) => I2B - // -> to Short - case (ComputationalTypeInt, ShortType) => I2S - // -> other cases are not supported - case _ => throw new UnsupportedOperationException("Unsupported operation or computational type in PrimitiveTypecastExpr" + primitiveTypecastExpr) + def handlePrimitiveTypeCastExpr( + primitiveTypecastExpr: PrimitiveTypecastExpr[_], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + // First, process the operand expression and add its instructions to the buffer + instructions ++= processExpression(primitiveTypecastExpr.operand, uVarToLVIndex) + + val instruction = (primitiveTypecastExpr.operand.cTpe, primitiveTypecastExpr.targetTpe) match { + // -> to Float + case (ComputationalTypeDouble, FloatType) => D2F + case (ComputationalTypeInt, FloatType) => I2F + case (ComputationalTypeLong, FloatType) => L2F + // -> to Int + case (ComputationalTypeDouble, IntegerType) => D2I + case (ComputationalTypeFloat, IntegerType) => F2I + case (ComputationalTypeLong, IntegerType) => L2I + // -> to Long + case (ComputationalTypeDouble, LongType) => D2L + case (ComputationalTypeInt, LongType) => I2L + case (ComputationalTypeFloat, LongType) => F2L + // -> to Double + case (ComputationalTypeFloat, DoubleType) => F2D + case (ComputationalTypeInt, DoubleType) => I2D + case (ComputationalTypeLong, DoubleType) => L2D + // -> to Char + case (ComputationalTypeInt, CharType) => I2C + // -> to Byte + case (ComputationalTypeInt, ByteType) => I2B + // -> to Short + case (ComputationalTypeInt, ShortType) => I2S + // -> other cases are not supported + case _ => throw new UnsupportedOperationException( + "Unsupported operation or computational type in PrimitiveTypecastExpr" + primitiveTypecastExpr + ) + } + instructions += instruction + instructions.toList } - instructionsWithPCs += ((operandPC, instruction)) - operandPC + instruction.length - } } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala deleted file mode 100644 index 0dd26d3704..0000000000 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/FirstPass.scala +++ /dev/null @@ -1,314 +0,0 @@ -package org.opalj.tactobc - -import org.opalj.br.Method -import org.opalj.collection.immutable.IntTrieSet -import org.opalj.tac.{ArrayLength, ArrayLoad, ArrayStore, Assignment, BinaryExpr, Checkcast, Compare, DUVar, Expr, ExprStmt, GetField, If, InstanceOf, InvokedynamicFunctionCall, NewArray, NonVirtualMethodCall, PrefixExpr, PrimitiveTypecastExpr, PutField, PutStatic, ReturnValue, StaticFunctionCall, StaticMethodCall, Stmt, Switch, Throw, UVar, VirtualFunctionCall, VirtualMethodCall} -import org.opalj.tactobc.ExprProcessor.{nextLVIndex, uVarToLVIndex} -import org.opalj.value.ValueInformation - -import scala.collection.mutable - -/** - * Handles the initial preparation of local variable (LV) indexes - * for translating three-address code (TAC) to bytecode. This involves collecting all - * defined-use variables (DUVars) in the method, assigning LV indexes to parameters, - * and populating a map that assigns unique LV indexes to each unique variable. - * - * Key responsibilities: - * - Collect all DUVars from the method's statements. - * - Assign LV indexes to method parameters. - * - Populate a map (`uVarToLVIndex`) with unique LV indexes for each variable used in the method. - */ -object FirstPass { - - /** - * Prepares local variable (LV) indexes for the given method by: - * 1. Collecting all defined-use variables (DUVars) from the method's statements. - * 2. Assigning LV indexes to method parameters. - * 3. Populating the `uVarToLVIndex` map with unique LV indexes for each unique variable. - * - * @param tacStmts Array of tuples where each tuple contains a TAC statement and its index. - */ - def prepareLVIndexes(method: Method, tacStmts: Array[(Stmt[DUVar[ValueInformation]], Int)]): Unit = { - // container for all DUVars in the method - val isStaticMethod = method.isStatic - val duVars = mutable.ListBuffer[DUVar[_]]() - tacStmts.foreach { case (stmt, _) => { - stmt match { - case Assignment(_, targetVar, expr) => - collectDUVarFromExpr(targetVar, duVars) - collectDUVarFromExpr(expr, duVars) - case If(_, left, _, right, _) => - collectDUVarFromExpr(left, duVars) - collectDUVarFromExpr(right, duVars) - case VirtualMethodCall(_, _, _, _, _, receiver, params) => - collectDUVarFromExpr(receiver, duVars) - for (param <- params) { - collectDUVarFromExpr(param, duVars) - } - case PutField(_, _, _, _, objRef, value) => - collectDUVarFromExpr(objRef, duVars) - collectDUVarFromExpr(value, duVars) - case PutStatic(_, _, _, _, value) => - collectDUVarFromExpr(value, duVars) - case StaticMethodCall(_,_,_,_,_,params) => - for (param <- params) { - collectDUVarFromExpr(param, duVars) - } - case NonVirtualMethodCall(_, _, _, _, _, receiver, params) => - collectDUVarFromExpr(receiver, duVars) - for (param <- params) { - collectDUVarFromExpr(param, duVars) - } - case ReturnValue(_, expr) => - collectDUVarFromExpr(expr, duVars) - case ArrayStore(_, arrayRef, index, value) => - collectDUVarFromExpr(arrayRef, duVars) - collectDUVarFromExpr(index, duVars) - collectDUVarFromExpr(value, duVars) - case ExprStmt(_, expr) => - collectDUVarFromExpr(expr, duVars) - case Throw(_, exception) => - collectDUVarFromExpr(exception, duVars) - case Switch(_, _, index, _) => - collectDUVarFromExpr(index, duVars) - case Checkcast(_, value, _) => - collectDUVarFromExpr(value, duVars) - case _ => - } - } - } - // give the first available indexes to parameters - val parameters = mapParametersAndPopulate(duVars, isStaticMethod) - println(parameters) - val lvIndexMap = collectAllUVarsAndPopulateUVarToLVIndexMap(duVars) - println(lvIndexMap) - } - - /** - * Populates the `uVarToLVIndex` map with unique LV indexes for each variable in the given DUVars list. - * - * @param duVars ListBuffer containing all DUVars of the method. - * @return A map where keys are def-sites of UVars and values are their corresponding LV indexes. - */ - def collectAllUVarsAndPopulateUVarToLVIndexMap(duVars: mutable.ListBuffer[DUVar[_]]): mutable.Map[IntTrieSet, Int] = { - duVars.toArray.foreach { - case uVar : UVar[_] => populateUvarToLVIndexMap(uVar) - case _ => - } - uVarToLVIndex - } - - /** - * Assigns the first available LV indexes to method parameters. - * - * @param duVars ListBuffer containing all DUVars of the method. - * @return A map where keys are def-sites of UVars and values are their corresponding LV indexes. - */ - def mapParametersAndPopulate(duVars: mutable.ListBuffer[DUVar[_]], isStaticMethod: Boolean): mutable.Map[IntTrieSet, Int] = { - // Step 2: Filter and Sort DUVar instances with negative origins - val parameterVars = duVars.collect { - case uVar: UVar[_] if uVar.defSites.exists(_ < 0) => uVar - } - val seenDefSites = mutable.Set[Int]() - val uniqueParameterVars = parameterVars.filter { uVar => - // Extract the minimum defSite from the IntTrieSet - val minDefSite = uVar.defSites.head - - // Check if we've already seen this defSite - if (seenDefSites.contains(minDefSite)) { - false // Skip this UVar, as it's already been added - } else { - seenDefSites += minDefSite // Mark this defSite as seen - true // Keep this UVar - } - } - val sortedParameterVars = uniqueParameterVars.sortBy { uVar => - // Sort by the minimum value in defSites, since we want the most negative number first - uVar.defSites.head - }(Ordering[Int].reverse) - println(sortedParameterVars) - // Iterate over the sorted list of unique parameters - sortedParameterVars.foreach { uVar => - // Check if the defSites contain a parameter origin - val existingEntry = uVarToLVIndex.find { case (key, _) => key.intersect(uVar.defSites).nonEmpty } - existingEntry match { - case Some((existingDefSites, _)) => // Do nothing if already processed - case None => - uVar.defSites.foreach { origin => - if (origin == -1 && !isStaticMethod) { - // Assign LV index 0 for 'this' for instance methods - uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), 0) - } else if (origin == -2) { - nextLVIndex = if (isStaticMethod) 0 else 1 // Start at 1 for instance methods to reserve 0 for 'this' - uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), nextLVIndex) - incrementLVIndex(uVar) - } else if (origin < -2) { - uVarToLVIndex.getOrElseUpdate(IntTrieSet(origin), nextLVIndex) - incrementLVIndex(uVar) - } - } - } - } - uVarToLVIndex - } - - /** - * Populates the `uVarToLVIndex` map with unique LV indexes for each unique UVar. - * - * @param uVar A variable used in the method. - */ - def populateUvarToLVIndexMap(uVar: UVar[_]): Unit = { - // Check if any existing key contains any of the def-sites - val existingEntry = uVarToLVIndex.find { case (key, _) => key.intersect(uVar.defSites).nonEmpty } - existingEntry match { - case Some((existingDefSites, index)) => - // Merge the def-sites and update the map - val mergedDefSites = existingDefSites ++ uVar.defSites - uVarToLVIndex -= existingDefSites - uVarToLVIndex(mergedDefSites) = index - case None => - // No overlapping def-sites found, add a new entry - uVarToLVIndex.getOrElseUpdate(uVar.defSites, { - val lvIndex = nextLVIndex - incrementLVIndex(uVar) - lvIndex - }) - } - } - - /** - * Increments the LV index appropriately based on the type of the UVar. - * - * @param uVar The UVar for which the LV index is to be incremented. - */ - def incrementLVIndex(uVar: UVar[_]): Unit = { - // Temporary type checking using toString method - val isDoubleOrLongType = uVar.value.toString.contains("long") || uVar.value.toString.contains("Long")|| uVar.value.toString.contains("Double") - nextLVIndex += (if (isDoubleOrLongType) 2 else 1) - } - - /** - * Traverses an expression to collect all DUVars embedded within it. - * - * @param expr The expression to be traversed - * @param duVars ListBuffer to be extended with all DUVars found in the expression. - */ - def collectDUVarFromExpr(expr: Expr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - expr match { - case duVar: DUVar[_] => duVars += duVar - case binaryExpr: BinaryExpr[_] => collectDUVarFromBinaryExpr(binaryExpr, duVars) - case virtualFunctionCallExpr: VirtualFunctionCall[_] => collectDUVarFromVirtualMethodCall(virtualFunctionCallExpr, duVars) - case staticFunctionCallExpr: StaticFunctionCall[_] => collectDUVarFromStaticFunctionCall(staticFunctionCallExpr, duVars) - case primitiveTypecaseExpr: PrimitiveTypecastExpr[_] => collectDUVarFromPrimitiveTypeCastExpr(primitiveTypecaseExpr, duVars) - case arrayLengthExpr: ArrayLength[_] => collectDUVarFromArrayLengthExpr(arrayLengthExpr, duVars) - case arrayLoadExpr: ArrayLoad[_] => collectDUVarFromArrayLoadExpr(arrayLoadExpr, duVars) - case newArrayExpr: NewArray[_] => collectDUVarFromNewArrayExpr(newArrayExpr, duVars) - case invokedynamicFunctionCall: InvokedynamicFunctionCall[_] => collectDUVarFromInvokedynamicFunctionCall(invokedynamicFunctionCall, duVars) - case getField: GetField[_] => collectDUVarFromGetField(getField, duVars) - case compare: Compare[_] => collectDUVarFromCompare(compare, duVars) - case prefixExpr: PrefixExpr[_] => collectDUVarFromPrefixExpr(prefixExpr, duVars) - case instanceOf: InstanceOf[_] => collectDUVarFromInstanceOf(instanceOf, duVars) - case _ => - } - } - - def collectDUVarFromInstanceOf(instanceOf: InstanceOf[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - collectDUVarFromExpr(instanceOf.value, duVars) - } - - def collectDUVarFromPrefixExpr(prefixExpr: PrefixExpr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - collectDUVarFromExpr(prefixExpr.operand, duVars) - } - - def collectDUVarFromCompare(compare: Compare[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - collectDUVarFromExpr(compare.left, duVars) - collectDUVarFromExpr(compare.right, duVars) - } - - def collectDUVarFromGetField(getField: GetField[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - collectDUVarFromExpr(getField.objRef, duVars) - } - - def collectDUVarFromInvokedynamicFunctionCall(invokedynamicFunctionCall: InvokedynamicFunctionCall[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - // Process each parameter and collect from each - for (param <- invokedynamicFunctionCall.params) { - collectDUVarFromExpr(param, duVars) - } - } - - def collectDUVarFromNewArrayExpr(newArrayExpr: NewArray[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - for (count <- newArrayExpr.counts) { - collectDUVarFromExpr(count, duVars) - } - // tpe does not contain any expr - } - - /** - * Traverses a `ArrayLoad` expr to collect all DUVars embedded within it. - * - * @param arrayLoadExpr The `ArrayLength` expr to be traversed. - * @param duVars ListBuffer to be extended with all DUVars found in the expression. - */ - def collectDUVarFromArrayLoadExpr(arrayLoadExpr: ArrayLoad[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - collectDUVarFromExpr(arrayLoadExpr.index, duVars) - collectDUVarFromExpr(arrayLoadExpr.arrayRef, duVars) - } - - /** - * Traverses a `ArrayLength` expr to collect all DUVars embedded within it. - * - * @param arrayLength The `ArrayLength` expr to be traversed. - * @param duVars ListBuffer to be extended with all DUVars found in the expression. - */ - def collectDUVarFromArrayLengthExpr(arrayLength: ArrayLength[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - collectDUVarFromExpr(arrayLength.arrayRef, duVars) - } - - /** - * Traverses a `PrimitiveTypeCastExpr` to collect all DUVars embedded within it. - * - * @param primitiveTypecaseExpr The `PrimitiveTypecastExpr` to be traversed. - * @param duVars ListBuffer to be extended with all DUVars found in the expression. - */ - def collectDUVarFromPrimitiveTypeCastExpr(primitiveTypecaseExpr: PrimitiveTypecastExpr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - collectDUVarFromExpr(primitiveTypecaseExpr.operand, duVars) - } - - /** - * Traverses a `StaticFunctionCall` expression to collect all DUVars embedded within it. - * - * @param staticFunctionCallExpr The `StaticFunctionCall` expression to be traversed. - * @param duVars ListBuffer to be extended with all DUVars found in the expression. - */ - def collectDUVarFromStaticFunctionCall(staticFunctionCallExpr: StaticFunctionCall[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - // Process each parameter and collect from each - for (param <- staticFunctionCallExpr.params) { - collectDUVarFromExpr(param, duVars) - } - } - - /** - * Traverses a `BinaryExpr` to collect all DUVars embedded within it. - * - * @param binaryExpr The `BinaryExpr` to be traversed. - * @param duVars ListBuffer to be extended with all DUVars found in the expression. - */ - def collectDUVarFromBinaryExpr(binaryExpr: BinaryExpr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - collectDUVarFromExpr(binaryExpr.left, duVars) - collectDUVarFromExpr(binaryExpr.right, duVars) - } - - /** - * Traverses a `VirtualFunctionCall` expression to collect all DUVars embedded within it. - * - * @param virtualFunctionCallExpr The `VirtualFunctionCall` expression to be traversed. - * @param duVars ListBuffer to be extended with all DUVars found in the expression. - */ - def collectDUVarFromVirtualMethodCall(virtualFunctionCallExpr: VirtualFunctionCall[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { - collectDUVarFromExpr(virtualFunctionCallExpr.receiver, duVars) - for (param <- virtualFunctionCallExpr.params) { - collectDUVarFromExpr(param, duVars) - } - } -} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/LvIndicesPreparator.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/LvIndicesPreparator.scala new file mode 100644 index 0000000000..18a406faaf --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/LvIndicesPreparator.scala @@ -0,0 +1,331 @@ +package org.opalj.tactobc + +import scala.collection.mutable + +import org.opalj.br.Method +import org.opalj.collection.immutable.IntTrieSet +import org.opalj.tac.ArrayLength +import org.opalj.tac.ArrayLoad +import org.opalj.tac.ArrayStore +import org.opalj.tac.Assignment +import org.opalj.tac.BinaryExpr +import org.opalj.tac.Checkcast +import org.opalj.tac.Compare +import org.opalj.tac.DUVar +import org.opalj.tac.Expr +import org.opalj.tac.ExprStmt +import org.opalj.tac.GetField +import org.opalj.tac.If +import org.opalj.tac.InstanceOf +import org.opalj.tac.InvokedynamicFunctionCall +import org.opalj.tac.NewArray +import org.opalj.tac.NonVirtualMethodCall +import org.opalj.tac.PrefixExpr +import org.opalj.tac.PrimitiveTypecastExpr +import org.opalj.tac.PutField +import org.opalj.tac.PutStatic +import org.opalj.tac.ReturnValue +import org.opalj.tac.StaticFunctionCall +import org.opalj.tac.StaticMethodCall +import org.opalj.tac.Stmt +import org.opalj.tac.Switch +import org.opalj.tac.Throw +import org.opalj.tac.UVar +import org.opalj.tac.VirtualFunctionCall +import org.opalj.tac.VirtualMethodCall +import org.opalj.value.ValueInformation + +/** + * Handles the initial preparation of local variable (LV) indices + * for translating three-address code (TAC) to bytecode. This involves collecting all + * defined-use variables (DUVars) in the method, assigning LV indices to parameters, + * and populating a map that assigns unique LV indices to each unique variable. + * + * Key responsibilities: + * - Collect all DUVars from the method's statements. + * - Assign LV indices to method parameters. + * - Populate a map (`uVarToLVIndex`) with unique LV indices for each variable used in the method. + */ +object LvIndicesPreparator { + + /** + * Prepares local variable (LV) indices for the given method by: + * 1. Collecting all defined-use variables (DUVars) from the method's statements. + * 2. Assigning LV indices to method parameters. + * 3. Populating the `uVarToLVIndex` map with unique LV indices for each unique variable. + * + * @param tacStmts Array of tuples where each tuple contains a TAC statement and its index. + */ + def prepareLvIndices( + method: Method, + tacStmts: Array[(Stmt[DUVar[ValueInformation]], Int)] + ): mutable.Map[IntTrieSet, Int] = { + + // container for all DUVars in the method + val duVars = mutable.ListBuffer[DUVar[_]]() + tacStmts.foreach { + case (stmt, _) => + stmt match { + case Assignment(_, targetVar, expr) => + collectDUVarFromExpr(targetVar, duVars) + collectDUVarFromExpr(expr, duVars) + case If(_, left, _, right, _) => + collectDUVarFromExpr(left, duVars) + collectDUVarFromExpr(right, duVars) + case VirtualMethodCall(_, _, _, _, _, receiver, params) => + collectDUVarFromExpr(receiver, duVars) + for (param <- params) { + collectDUVarFromExpr(param, duVars) + } + case PutField(_, _, _, _, objRef, value) => + collectDUVarFromExpr(objRef, duVars) + collectDUVarFromExpr(value, duVars) + case PutStatic(_, _, _, _, value) => + collectDUVarFromExpr(value, duVars) + case StaticMethodCall(_, _, _, _, _, params) => + for (param <- params) { + collectDUVarFromExpr(param, duVars) + } + case NonVirtualMethodCall(_, _, _, _, _, receiver, params) => + collectDUVarFromExpr(receiver, duVars) + for (param <- params) { + collectDUVarFromExpr(param, duVars) + } + case ReturnValue(_, expr) => + collectDUVarFromExpr(expr, duVars) + case ArrayStore(_, arrayRef, index, value) => + collectDUVarFromExpr(arrayRef, duVars) + collectDUVarFromExpr(index, duVars) + collectDUVarFromExpr(value, duVars) + case ExprStmt(_, expr) => + collectDUVarFromExpr(expr, duVars) + case Throw(_, exception) => + collectDUVarFromExpr(exception, duVars) + case Switch(_, _, index, _) => + collectDUVarFromExpr(index, duVars) + case Checkcast(_, value, _) => + collectDUVarFromExpr(value, duVars) + case _ => + } + } + + val uVarToLVIndex = mutable.Map[IntTrieSet, Int]() + val nextLVIndexAfterParameters = + mapParametersAndPopulate(method, uVarToLVIndex) + collectAllUVarsAndPopulateUVarToLVIndexMap(duVars, uVarToLVIndex, nextLVIndexAfterParameters) + println(s"--------------------------------lvIndexMap for method $method: \n" + uVarToLVIndex) + uVarToLVIndex + } + + /** + * Populates the `uVarToLVIndex` map with unique LV indices for each variable in the given DUVars list. + * + * @param duVars ListBuffer containing all DUVars of the method. + * @return A map where keys are def-sites of UVars and values are their corresponding LV indices. + */ + def collectAllUVarsAndPopulateUVarToLVIndexMap( + duVars: mutable.ListBuffer[DUVar[_]], + uVarToLVIndex: mutable.Map[IntTrieSet, Int], + initialLVIndex: Int + ): Unit = { + var nextLVIndex = initialLVIndex + duVars.toArray.foreach { + case uVar: UVar[_] => nextLVIndex = populateUvarToLVIndexMap(uVar, uVarToLVIndex, nextLVIndex) + case _ => + } + + } + + /** + * Iterates over the parameterTypes of the method and assigns defSites -2, -3, -4, ... to LVIndices starting at 0 or 1 (for static/non-static methods respectively) + */ + def mapParametersAndPopulate( + method: Method, + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): Int = { + var nextLVIndex = if (method.isStatic) 0 else 1 + + method.descriptor.parameterTypes.zipWithIndex.foreach { case (tpe, index) => + println(s"Mapping defSite ${-(index + 2)} to LVIndex $nextLVIndex (type: $tpe)") + // for some reason defSite -1 is *always* reserved for 'this' so we always start at -2 and then go further down per parameter (-3, -4, etc.) + uVarToLVIndex.getOrElseUpdate(IntTrieSet(-(index + 2)), nextLVIndex) + nextLVIndex += (if (tpe.isDoubleType || tpe.isLongType) 2 else 1) + } + if (!method.isStatic) { + uVarToLVIndex.getOrElseUpdate(IntTrieSet(-1), 0) + } + println(s"--------------------------------parameters for method $method: \n" + uVarToLVIndex) + nextLVIndex + } + + /** + * Populates the `uVarToLVIndex` map with unique LV indices for each unique UVar. + * + * @param uVar A variable used in the method. + */ + def populateUvarToLVIndexMap(uVar: UVar[_], uVarToLVIndex: mutable.Map[IntTrieSet, Int], initialLVIndex: Int): Int = { + var nextLVIndex = initialLVIndex + val existingEntry = uVarToLVIndex.find { case (key, _) => key.intersect(uVar.defSites).nonEmpty } + existingEntry match { + case Some((existingDefSites, index)) => + val mergedDefSites = existingDefSites ++ uVar.defSites + uVarToLVIndex -= existingDefSites + uVarToLVIndex(mergedDefSites) = index + + case None => + uVarToLVIndex.getOrElseUpdate(uVar.defSites, nextLVIndex) + nextLVIndex = incrementLVIndex(uVar, nextLVIndex) + } + nextLVIndex + } + + /** + * Increments the LV index appropriately based on the type of the UVar. + * + * @param uVar The UVar for which the LV index is to be incremented. + */ + def incrementLVIndex(uVar: UVar[_], initialLVIndex: Int): Int = { + initialLVIndex + uVar.cTpe.operandSize + } + + /** + * Traverses an expression to collect all DUVars embedded within it. + * + * @param expr The expression to be traversed + * @param duVars ListBuffer to be extended with all DUVars found in the expression. + */ + def collectDUVarFromExpr(expr: Expr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + expr match { + case duVar: DUVar[_] => duVars += duVar + case binaryExpr: BinaryExpr[_] => collectDUVarFromBinaryExpr(binaryExpr, duVars) + case virtualFunctionCallExpr: VirtualFunctionCall[_] => + collectDUVarFromVirtualMethodCall(virtualFunctionCallExpr, duVars) + case staticFunctionCallExpr: StaticFunctionCall[_] => + collectDUVarFromStaticFunctionCall(staticFunctionCallExpr, duVars) + case primitiveTypecaseExpr: PrimitiveTypecastExpr[_] => + collectDUVarFromPrimitiveTypeCastExpr(primitiveTypecaseExpr, duVars) + case arrayLengthExpr: ArrayLength[_] => collectDUVarFromArrayLengthExpr(arrayLengthExpr, duVars) + case arrayLoadExpr: ArrayLoad[_] => collectDUVarFromArrayLoadExpr(arrayLoadExpr, duVars) + case newArrayExpr: NewArray[_] => collectDUVarFromNewArrayExpr(newArrayExpr, duVars) + case invokedynamicFunctionCall: InvokedynamicFunctionCall[_] => + collectDUVarFromInvokedynamicFunctionCall(invokedynamicFunctionCall, duVars) + case getField: GetField[_] => collectDUVarFromGetField(getField, duVars) + case compare: Compare[_] => collectDUVarFromCompare(compare, duVars) + case prefixExpr: PrefixExpr[_] => collectDUVarFromPrefixExpr(prefixExpr, duVars) + case instanceOf: InstanceOf[_] => collectDUVarFromInstanceOf(instanceOf, duVars) + case _ => + } + } + + def collectDUVarFromInstanceOf(instanceOf: InstanceOf[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectDUVarFromExpr(instanceOf.value, duVars) + } + + def collectDUVarFromPrefixExpr(prefixExpr: PrefixExpr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectDUVarFromExpr(prefixExpr.operand, duVars) + } + + def collectDUVarFromCompare(compare: Compare[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectDUVarFromExpr(compare.left, duVars) + collectDUVarFromExpr(compare.right, duVars) + } + + def collectDUVarFromGetField(getField: GetField[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectDUVarFromExpr(getField.objRef, duVars) + } + + def collectDUVarFromInvokedynamicFunctionCall( + invokedynamicFunctionCall: InvokedynamicFunctionCall[_], + duVars: mutable.ListBuffer[DUVar[_]] + ): Unit = { + // Process each parameter and collect from each + for (param <- invokedynamicFunctionCall.params) { + collectDUVarFromExpr(param, duVars) + } + } + + def collectDUVarFromNewArrayExpr(newArrayExpr: NewArray[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + for (count <- newArrayExpr.counts) { + collectDUVarFromExpr(count, duVars) + } + // tpe does not contain any expr + } + + /** + * Traverses a `ArrayLoad` expr to collect all DUVars embedded within it. + * + * @param arrayLoadExpr The `ArrayLength` expr to be traversed. + * @param duVars ListBuffer to be extended with all DUVars found in the expression. + */ + def collectDUVarFromArrayLoadExpr(arrayLoadExpr: ArrayLoad[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + println(arrayLoadExpr) + collectDUVarFromExpr(arrayLoadExpr.index, duVars) + collectDUVarFromExpr(arrayLoadExpr.arrayRef, duVars) + } + + /** + * Traverses a `ArrayLength` expr to collect all DUVars embedded within it. + * + * @param arrayLength The `ArrayLength` expr to be traversed. + * @param duVars ListBuffer to be extended with all DUVars found in the expression. + */ + def collectDUVarFromArrayLengthExpr(arrayLength: ArrayLength[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectDUVarFromExpr(arrayLength.arrayRef, duVars) + } + + /** + * Traverses a `PrimitiveTypeCastExpr` to collect all DUVars embedded within it. + * + * @param primitiveTypecaseExpr The `PrimitiveTypecastExpr` to be traversed. + * @param duVars ListBuffer to be extended with all DUVars found in the expression. + */ + def collectDUVarFromPrimitiveTypeCastExpr( + primitiveTypecaseExpr: PrimitiveTypecastExpr[_], + duVars: mutable.ListBuffer[DUVar[_]] + ): Unit = { + collectDUVarFromExpr(primitiveTypecaseExpr.operand, duVars) + } + + /** + * Traverses a `StaticFunctionCall` expression to collect all DUVars embedded within it. + * + * @param staticFunctionCallExpr The `StaticFunctionCall` expression to be traversed. + * @param duVars ListBuffer to be extended with all DUVars found in the expression. + */ + def collectDUVarFromStaticFunctionCall( + staticFunctionCallExpr: StaticFunctionCall[_], + duVars: mutable.ListBuffer[DUVar[_]] + ): Unit = { + // Process each parameter and collect from each + for (param <- staticFunctionCallExpr.params) { + collectDUVarFromExpr(param, duVars) + } + } + + /** + * Traverses a `BinaryExpr` to collect all DUVars embedded within it. + * + * @param binaryExpr The `BinaryExpr` to be traversed. + * @param duVars ListBuffer to be extended with all DUVars found in the expression. + */ + def collectDUVarFromBinaryExpr(binaryExpr: BinaryExpr[_], duVars: mutable.ListBuffer[DUVar[_]]): Unit = { + collectDUVarFromExpr(binaryExpr.left, duVars) + collectDUVarFromExpr(binaryExpr.right, duVars) + } + + /** + * Traverses a `VirtualFunctionCall` expression to collect all DUVars embedded within it. + * + * @param virtualFunctionCallExpr The `VirtualFunctionCall` expression to be traversed. + * @param duVars ListBuffer to be extended with all DUVars found in the expression. + */ + def collectDUVarFromVirtualMethodCall( + virtualFunctionCallExpr: VirtualFunctionCall[_], + duVars: mutable.ListBuffer[DUVar[_]] + ): Unit = { + collectDUVarFromExpr(virtualFunctionCallExpr.receiver, duVars) + for (param <- virtualFunctionCallExpr.params) { + collectDUVarFromExpr(param, duVars) + } + } +} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala deleted file mode 100644 index 93675b7fbe..0000000000 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/SecondPass.scala +++ /dev/null @@ -1,112 +0,0 @@ -package org.opalj.tactobc - -import org.opalj.br.instructions.Instruction -import org.opalj.tac.{ArrayStore, Assignment, CaughtException, Checkcast, DUVar, ExprStmt, Goto, If, InvokedynamicMethodCall, JSR, MonitorEnter, MonitorExit, NonVirtualMethodCall, Nop, PutField, PutStatic, Ret, Return, ReturnValue, StaticMethodCall, Stmt, Switch, Throw, VirtualMethodCall} -import org.opalj.value.ValueInformation - -import scala.collection.mutable.ArrayBuffer - -/** - * Handles the translation of three-address code (TAC) statements - * into Java bytecode instructions. - * - * This object processes each TAC statement and generates corresponding bytecode instructions, - * updating the program counter (PC) as it proceeds. - * - * Key responsibilities: - * - Translate TAC statements to bytecode instructions. - * - Maintain mappings from TAC targets to bytecode program counters (PCs). - */ -object SecondPass { - - /** - * Translates TAC statements to bytecode instructions. - * - * This method iterates over the given TAC statements, processes each statement according to its type, - * generates the corresponding bytecode instructions, and updates the program counter (PC) according to the instruction length. - * - * The `-1` value is used as a placeholder for statements that do not require a target. - * - * @param tacStmts Array of tuples where each tuple contains a TAC statement and its index. - * @param generatedByteCodeWithPC ArrayBuffer to store the generated bytecode instructions along with their PCs. - * @param tacTargetToByteCodePcs ArrayBuffer to map TAC targets to bytecode PCs. - * @param switchCases ArrayBuffer to store switch case mappings. - */ - def translateStmtsToInstructions(tacStmts: Array[(Stmt[DUVar[ValueInformation]], Int)], generatedByteCodeWithPC: ArrayBuffer[(Int, Instruction)], tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], switchCases: ArrayBuffer[(Int, Int)]): Unit = { - var currentPC = 0 - tacStmts.foreach { case (stmt, _) => - stmt match { - case Assignment(_, targetVar, expr) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processAssignment(targetVar, expr, generatedByteCodeWithPC, currentPC) - case ArrayStore(_, arrayRef, index, value) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processArrayStore(arrayRef, index, value, generatedByteCodeWithPC, currentPC) - case CaughtException(_, exceptionType, throwingStmts) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processCaughtException(exceptionType, throwingStmts, generatedByteCodeWithPC, currentPC) - case ExprStmt(_, expr) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = ExprProcessor.processExpression(expr, generatedByteCodeWithPC, currentPC) - case If(_, left, condition, right, target) => - tacTargetToByteCodePcs += ((target, currentPC)) - currentPC = StmtProcessor.processIf(left, condition, right, target, generatedByteCodeWithPC, currentPC) - case Goto(_, target) => - tacTargetToByteCodePcs += ((target, currentPC)) - currentPC = StmtProcessor.processGoto(generatedByteCodeWithPC, currentPC) - case Switch(_, defaultTarget, index, npairs) => - npairs.foreach { pair => - switchCases += ((pair._1, pair._2)) //case values to jump target - } - tacTargetToByteCodePcs += ((defaultTarget, currentPC)) - currentPC = StmtProcessor.processSwitch(defaultTarget, index, npairs, generatedByteCodeWithPC, currentPC) - case JSR(_, target) => - tacTargetToByteCodePcs += ((target, currentPC)) - currentPC = StmtProcessor.processJSR(generatedByteCodeWithPC, currentPC) - case VirtualMethodCall(_, declaringClass, isInterface, name, descriptor, receiver, params) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processVirtualMethodCall(declaringClass, isInterface, name, descriptor, receiver, params, generatedByteCodeWithPC, currentPC) - case NonVirtualMethodCall(_, declaringClass, isInterface, name, descriptor, receiver, params) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processNonVirtualMethodCall(declaringClass, isInterface, name, descriptor, receiver, params, generatedByteCodeWithPC, currentPC) - case StaticMethodCall(_, declaringClass, isInterface, name, descriptor, params) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processStaticMethodCall(declaringClass, isInterface, name, descriptor, params, generatedByteCodeWithPC, currentPC) - case InvokedynamicMethodCall(_, bootstrapMethod, name, descriptor, params) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processInvokeDynamicMethodCall(bootstrapMethod, name, descriptor, params, generatedByteCodeWithPC, currentPC) - case MonitorEnter(_, objRef) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processMonitorEnter(objRef, generatedByteCodeWithPC, currentPC) - case MonitorExit(_, objRef) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processMonitorExit(objRef, generatedByteCodeWithPC, currentPC) - case PutField(_, declaringClass, name, declaredFieldType, objRef, value) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processPutField(declaringClass, name, declaredFieldType, objRef, value, generatedByteCodeWithPC, currentPC) - case PutStatic(_, declaringClass, name, declaredFieldType, value) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processPutStatic(declaringClass, name, declaredFieldType, value, generatedByteCodeWithPC, currentPC) - case Checkcast(_, value, cmpTpe) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processCheckCast(value, cmpTpe, generatedByteCodeWithPC, currentPC) - case Ret(_, returnAddresses) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processRet(returnAddresses, generatedByteCodeWithPC, currentPC) - case ReturnValue(_, expr) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processReturnValue(expr, generatedByteCodeWithPC, currentPC) - case Return(_) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processReturn(generatedByteCodeWithPC, currentPC) - case Throw(_, exception) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processThrow(exception, generatedByteCodeWithPC, currentPC) - case Nop(_) => - tacTargetToByteCodePcs += ((-1, currentPC)) - currentPC = StmtProcessor.processNop(generatedByteCodeWithPC, currentPC) - case _ => - } - } - } -} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala index 11a7437698..43f7ffb8ea 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtProcessor.scala @@ -1,333 +1,437 @@ /* BSD 2-Clause License - see OPAL/LICENSE for details. */ package org.opalj.tactobc +import scala.collection.immutable.ArraySeq +import scala.collection.mutable +import scala.collection.mutable.ArrayBuffer + import org.opalj.RelationalOperator import org.opalj.RelationalOperators._ -import org.opalj.br.{ArrayType, BootstrapMethod, ByteType, CharType, ComputationalTypeDouble, ComputationalTypeFloat, ComputationalTypeInt, ComputationalTypeLong, ComputationalTypeReference, DoubleType, FieldType, FloatType, IntegerType, LongType, MethodDescriptor, ObjectType, PCs, ReferenceType, ShortType} -import org.opalj.br.instructions.{AASTORE, ARETURN, ATHROW, BASTORE, CASTORE, CHECKCAST, DASTORE, DEFAULT_INVOKEDYNAMIC, DRETURN, FASTORE, FRETURN, GOTO, IASTORE, IFNONNULL, IFNULL, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IRETURN, Instruction, JSR, LASTORE, LOOKUPSWITCH, LRETURN, MONITORENTER, MONITOREXIT, NOP, PUTFIELD, PUTSTATIC, RET, RETURN, SASTORE, TABLESWITCH} -import org.opalj.collection.immutable.{IntIntPair, IntTrieSet} -import org.opalj.tac.{Expr, UVar, Var} +import org.opalj.ba.InstructionElement +import org.opalj.br.ArrayType +import org.opalj.br.BootstrapMethod +import org.opalj.br.ByteType +import org.opalj.br.CharType +import org.opalj.br.ComputationalTypeDouble +import org.opalj.br.ComputationalTypeFloat +import org.opalj.br.ComputationalTypeInt +import org.opalj.br.ComputationalTypeLong +import org.opalj.br.ComputationalTypeReference +import org.opalj.br.DoubleType +import org.opalj.br.FieldType +import org.opalj.br.FloatType +import org.opalj.br.IntegerType +import org.opalj.br.LongType +import org.opalj.br.MethodDescriptor +import org.opalj.br.ObjectType +import org.opalj.br.PCs +import org.opalj.br.ReferenceType +import org.opalj.br.ShortType +import org.opalj.br.instructions.AASTORE +import org.opalj.br.instructions.ARETURN +import org.opalj.br.instructions.ATHROW +import org.opalj.br.instructions.BASTORE +import org.opalj.br.instructions.CASTORE +import org.opalj.br.instructions.CHECKCAST +import org.opalj.br.instructions.DASTORE +import org.opalj.br.instructions.DEFAULT_INVOKEDYNAMIC +import org.opalj.br.instructions.DRETURN +import org.opalj.br.instructions.FASTORE +import org.opalj.br.instructions.FRETURN +import org.opalj.br.instructions.IASTORE +import org.opalj.br.instructions.INVOKEINTERFACE +import org.opalj.br.instructions.INVOKESPECIAL +import org.opalj.br.instructions.INVOKESTATIC +import org.opalj.br.instructions.INVOKEVIRTUAL +import org.opalj.br.instructions.IRETURN +import org.opalj.br.instructions.LabeledGOTO +import org.opalj.br.instructions.LabeledIF_ACMPEQ +import org.opalj.br.instructions.LabeledIF_ACMPNE +import org.opalj.br.instructions.LabeledIF_ICMPEQ +import org.opalj.br.instructions.LabeledIF_ICMPGE +import org.opalj.br.instructions.LabeledIF_ICMPGT +import org.opalj.br.instructions.LabeledIF_ICMPLE +import org.opalj.br.instructions.LabeledIF_ICMPLT +import org.opalj.br.instructions.LabeledIF_ICMPNE +import org.opalj.br.instructions.LabeledIFNONNULL +import org.opalj.br.instructions.LabeledIFNULL +import org.opalj.br.instructions.LabeledJSR +import org.opalj.br.instructions.LabeledLOOKUPSWITCH +import org.opalj.br.instructions.LabeledTABLESWITCH +//import org.opalj.br.instructions.LabeledGOTO +import org.opalj.br.instructions.LASTORE +import org.opalj.br.instructions.LRETURN +import org.opalj.br.instructions.MONITORENTER +import org.opalj.br.instructions.MONITOREXIT +import org.opalj.br.instructions.NOP +//import org.opalj.br.instructions.PCLabel +import org.opalj.br.instructions.PUTFIELD +import org.opalj.br.instructions.PUTSTATIC +import org.opalj.br.instructions.RET +import org.opalj.br.instructions.RETURN +import org.opalj.br.instructions.RewriteLabel +import org.opalj.br.instructions.SASTORE +import org.opalj.collection.immutable.IntTrieSet +import org.opalj.tac.Expr +import org.opalj.tac.UVar +import org.opalj.tac.Var import org.opalj.tactobc.ExprProcessor.inferElementType -import scala.collection.immutable.ArraySeq -import scala.collection.mutable.ArrayBuffer - object StmtProcessor { - //Assignment - def processAssignment(targetVar: Var[_], expr: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Evaluate the RHS and update the PC accordingly - val afterExprPC = ExprProcessor.processExpression(expr, instructionsWithPCs, currentPC) - // Store the result into the target variable and update the PC - val finalPC = ExprProcessor.storeVariable(targetVar, instructionsWithPCs, afterExprPC) - // Return the updated PC - finalPC - } - - def processSwitch(defaultOffset: Int, index: Expr[_], npairs: ArraySeq[IntIntPair /*(Case Value, Jump Target)*/], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Translate the index expression first - val afterExprPC = ExprProcessor.processExpression(index, instructionsWithPCs, currentPC) - - // Prepare the bytecode pairs with placeholders for targets - val bCnpairs = prepareBCnpairs(npairs) - - if (isLookupSwitch(index)) { - // Add LOOKUPSWITCH instruction with placeholders for targets - val lookupswitchInstruction = LOOKUPSWITCH(defaultOffset, bCnpairs) - instructionsWithPCs += ((afterExprPC, lookupswitchInstruction)) - afterExprPC + lookupSwitchLength(bCnpairs.size, afterExprPC) - 1 - } else { - // Add TABLESWITCH instruction with placeholders for targets - val minValue = bCnpairs.minBy(_._1)._1 - val maxValue = bCnpairs.maxBy(_._1)._1 - val jumpTable = ArrayBuffer.fill(maxValue - minValue + 1)(-1) - - // Set the case values in the jump table - bCnpairs.foreach { case IntIntPair(caseValue, _) => - jumpTable(caseValue - minValue) = -1 - } - - val tableswitchInstruction = TABLESWITCH(defaultOffset, minValue, maxValue, jumpTable.to(ArraySeq)) - instructionsWithPCs += ((afterExprPC, tableswitchInstruction)) - afterExprPC + tableSwitchLength(minValue, maxValue, afterExprPC) - 1 + // Assignment + def processAssignment( + targetVar: Var[_], + expr: Expr[_], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + instructions ++= ExprProcessor.processExpression(expr, uVarToLVIndex) + instructions += ExprProcessor.storeVariable(targetVar, uVarToLVIndex) + instructions.toList + } + + def processSwitch( + defaultTarget: RewriteLabel, + index: Expr[_], + npairs: ArraySeq[(Int, RewriteLabel) /*(Case Value, Jump Target)*/ ], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + // Translate the index expression first + instructions ++= ExprProcessor.processExpression(index, uVarToLVIndex) + + if (isLookupSwitch(index)) { + // Add LOOKUPSWITCH instruction with placeholders for targets + val lookupswitchInstruction = LabeledLOOKUPSWITCH(defaultTarget, npairs) + instructions += lookupswitchInstruction + } else { + // Add TABLESWITCH instruction with placeholders for targets + val minValue = npairs.minBy(_._1)._1 + val maxValue = npairs.maxBy(_._1)._1 + val jumpTable = ArrayBuffer.fill(maxValue - minValue + 1)(defaultTarget) + + // Set the case values in the jump table + npairs.foreach { case (caseValue, target) => + jumpTable(caseValue - minValue) = target + } + instructions += LabeledTABLESWITCH(defaultTarget, minValue, maxValue, jumpTable.to(ArraySeq)) + } + instructions.toList + } + + def isLookupSwitch(index: Expr[_]): Boolean = { + // todo: decision of when to use lookupswtich/tableswitch + index match { + case variable: UVar[_] => variable.defSites.size == 1 + case _ => false + } + } + + def processReturn(): List[InstructionElement] = { + List(RETURN) + } + + def processReturnValue(expr: Expr[_], uVarToLVIndex: mutable.Map[IntTrieSet, Int]): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + instructions ++= ExprProcessor.processExpression(expr, uVarToLVIndex) + val instruction = expr.cTpe match { + case ComputationalTypeInt => IRETURN + case ComputationalTypeLong => LRETURN + case ComputationalTypeFloat => FRETURN + case ComputationalTypeDouble => DRETURN + case ComputationalTypeReference => ARETURN + case _ => throw new UnsupportedOperationException("Unsupported computational type:" + expr.cTpe) + } + instructions += instruction + instructions.toList + } + + def processVirtualMethodCall( + declaringClass: ReferenceType, + isInterface: Boolean, + methodName: String, + methodDescriptor: MethodDescriptor, + receiver: Expr[_], + params: Seq[Expr[_]], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + + // Process the receiver object (e.g., aload_0 for `this`) + instructions ++= ExprProcessor.processExpression(receiver, uVarToLVIndex) + + // Process each parameter and update the PC accordingly + for (param <- params) { + instructions ++= ExprProcessor.processExpression(param, uVarToLVIndex) + } + + val instruction = { + if (isInterface) { + INVOKEINTERFACE(declaringClass.asObjectType, methodName, methodDescriptor) + } else { + INVOKEVIRTUAL(declaringClass, methodName, methodDescriptor) + } + } + instructions += instruction + instructions.toList + } + + def processArrayStore( + arrayRef: Expr[_], + index: Expr[_], + value: Expr[_], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + + // Load the arrayRef onto the stack + instructions ++= ExprProcessor.processExpression(arrayRef, uVarToLVIndex) + + // Load the index onto the stack + instructions ++= ExprProcessor.processExpression(index, uVarToLVIndex) + + // Load the value to be stored onto the stack + instructions ++= ExprProcessor.processExpression(value, uVarToLVIndex) + + // Infer the element type from the array reference expression + val elementType = inferElementType(arrayRef) + + val instruction = elementType match { + case IntegerType => IASTORE + case LongType => LASTORE + case FloatType => FASTORE + case DoubleType => DASTORE + case ByteType => BASTORE + case CharType => CASTORE + case ShortType => SASTORE + case _: ObjectType => AASTORE + case ArrayType(componentType) => componentType match { + case _: ReferenceType => AASTORE + case _: CharType => CASTORE + case _: FloatType => FASTORE + case _: DoubleType => DASTORE + case _: ByteType => BASTORE + case _: ShortType => SASTORE + case _: IntegerType => IASTORE + case _: LongType => LASTORE + case _ => throw new IllegalArgumentException(s"Unsupported array store type $componentType") + } + case _ => throw new IllegalArgumentException(s"Unsupported array store type $elementType") + } + // Add the store instruction + instructions += instruction + instructions.toList } - } - - def lookupSwitchLength(numPairs: Int, currentPC: Int): Int = { - // Opcode (1 byte) + padding (0-3 bytes) + default offset (4 bytes) + number of pairs (4 bytes) + pairs (8 bytes each) - val padding = (4 - (currentPC % 4)) % 4 - 1 + padding + 4 + 4 + (numPairs * 8) - } - - def tableSwitchLength(low: Int, high: Int, currentPC: Int): Int = { - // Opcode (1 byte) + padding (0-3 bytes) + default offset (4 bytes) + low value (4 bytes) + high value (4 bytes) + jump offsets (4 bytes each) - val padding = (4 - (currentPC % 4)) % 4 - val numOffsets = high - low + 1 - 1 + padding + 4 + 4 + 4 + (numOffsets * 4) - } - - def prepareBCnpairs(npairs: ArraySeq[IntIntPair]): ArraySeq[IntIntPair] = { - npairs.map { case IntIntPair(caseValue, _) => IntIntPair(caseValue, -1) } - } - - def isLookupSwitch(index: Expr[_]): Boolean = { - index match { - case variable: UVar[_] => variable.defSites.size == 1 - case _ => false + + def processNop(): List[InstructionElement] = { + List(NOP) } - } - - def processReturn(instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val instruction = RETURN - instructionsWithPCs += ((currentPC, instruction)) - currentPC + instruction.length - } - - def processReturnValue(expr: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val afterExprPC = ExprProcessor.processExpression(expr, instructionsWithPCs, currentPC) - val instruction = expr.cTpe match { - case ComputationalTypeInt => IRETURN - case ComputationalTypeLong => LRETURN - case ComputationalTypeFloat => FRETURN - case ComputationalTypeDouble => DRETURN - case ComputationalTypeReference => ARETURN - case _ => throw new UnsupportedOperationException("Unsupported computational type:" + expr.cTpe) + + def processInvokeDynamicMethodCall( + bootstrapMethod: BootstrapMethod, + name: String, + descriptor: MethodDescriptor, + params: Seq[Expr[_]], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + for (param <- params) { + instructions ++= ExprProcessor.processExpression(param, uVarToLVIndex) + } + instructions += DEFAULT_INVOKEDYNAMIC(bootstrapMethod, name, descriptor) + instructions.toList } - instructionsWithPCs += ((afterExprPC, instruction)) - afterExprPC + instruction.length - } - def processVirtualMethodCall(declaringClass: ReferenceType, isInterface: Boolean, methodName: String, methodDescriptor: MethodDescriptor, receiver: Expr[_], params: Seq[Expr[_]], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Process the receiver object (e.g., aload_0 for `this`) - val afterReceiverPC = ExprProcessor.processExpression(receiver, instructionsWithPCs, currentPC) + def processCheckCast( + value: Expr[_], + cmpTpe: ReferenceType, + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + instructions ++= ExprProcessor.processExpression(value, uVarToLVIndex) + instructions += CHECKCAST(cmpTpe) + instructions.toList + } + + def processRet(returnAddresses: PCs): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + + // Ensure there is only one return address, as RET can only work with one local variable index + if (returnAddresses.size != 1) { + throw new IllegalArgumentException( + s"RET instruction expects exactly one return address, but got: ${returnAddresses.size}" + ) + } + + // The RET instruction requires the index of the local variable that holds the return address + val localVarIndex = returnAddresses.head - // Initialize the PC after processing the receiver - var currentAfterParamsPC = afterReceiverPC + // Create the RET instruction with the correct local variable index + instructions += RET(localVarIndex) + instructions.toList - // Process each parameter and update the PC accordingly - for (param <- params) { - currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) } - val instruction = { if (isInterface) { - INVOKEINTERFACE(declaringClass.asObjectType, methodName, methodDescriptor) - }else - INVOKEVIRTUAL(declaringClass, methodName, methodDescriptor) + def processCaughtException( + exceptionType: Option[ObjectType], + throwingStmts: IntTrieSet + ): List[InstructionElement] = { + // todo: handle this correctly + List[InstructionElement]() } - instructionsWithPCs += ((currentAfterParamsPC, instruction)) - currentAfterParamsPC + instruction.length - } - - def processArrayStore(arrayRef: Expr[_], index: Expr[_], value: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Load the arrayRef onto the stack - val pcAfterArrayRefLoad = ExprProcessor.processExpression(arrayRef, instructionsWithPCs, currentPC) - - // Load the index onto the stack - val pcAfterIndexLoad = ExprProcessor.processExpression(index, instructionsWithPCs, pcAfterArrayRefLoad) - - // Load the value to be stored onto the stack - val pcAfterValueLoad = ExprProcessor.processExpression(value, instructionsWithPCs, pcAfterIndexLoad) - - // Infer the element type from the array reference expression - val elementType = inferElementType(arrayRef) - - - val instruction = elementType match { - case IntegerType => IASTORE - case LongType => LASTORE - case FloatType => FASTORE - case DoubleType => DASTORE - case ByteType => BASTORE - case CharType => CASTORE - case ShortType => SASTORE - case _: ObjectType => AASTORE - case ArrayType(componentType) => componentType match { - case _: ReferenceType => AASTORE - case _: CharType => CASTORE - case _: FloatType => FASTORE - case _: DoubleType => DASTORE - case _: ByteType => BASTORE - case _: ShortType => SASTORE - case _: IntegerType => IASTORE - case _: LongType => LASTORE - case _ => throw new IllegalArgumentException(s"Unsupported array store type $componentType") - } - case _ => throw new IllegalArgumentException(s"Unsupported array store type $elementType") + + def processThrow(exception: Expr[_], uVarToLVIndex: mutable.Map[IntTrieSet, Int]): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + instructions ++= ExprProcessor.processExpression(exception, uVarToLVIndex) + instructions += ATHROW + instructions.toList } - // Add the store instruction - instructionsWithPCs += ((pcAfterValueLoad, instruction)) - pcAfterValueLoad + instruction.length - } - - def processNop(instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val instruction = NOP - instructionsWithPCs += ((currentPC, instruction)) - currentPC + instruction.length - } - - def processInvokeDynamicMethodCall(bootstrapMethod: BootstrapMethod, name: String, descriptor: MethodDescriptor, params: Seq[Expr[_]], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - var currentAfterParamsPC = currentPC - for (param <- params) { - currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + + def processPutStatic( + declaringClass: ObjectType, + name: String, + declaredFieldType: FieldType, + value: Expr[_], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + instructions ++= ExprProcessor.processExpression(value, uVarToLVIndex) + instructions += PUTSTATIC(declaringClass, name, declaredFieldType) + instructions.toList } - val invokeDynamicInstruction = DEFAULT_INVOKEDYNAMIC(bootstrapMethod, name, descriptor) - instructionsWithPCs += ((currentAfterParamsPC, invokeDynamicInstruction)) - currentAfterParamsPC + invokeDynamicInstruction.length - } - - def processCheckCast(value: Expr[_], cmpTpe: ReferenceType, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val nextPC = ExprProcessor.processExpression(value, instructionsWithPCs, currentPC) - val instruction = CHECKCAST(cmpTpe) - instructionsWithPCs += ((nextPC, instruction)) - nextPC + instruction.length - } - - def processRet(returnAddresses: PCs, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Ensure there is only one return address, as RET can only work with one local variable index - if (returnAddresses.size != 1) { - throw new IllegalArgumentException(s"RET instruction expects exactly one return address, but got: ${returnAddresses.size}") + + def processPutField( + declaringClass: ObjectType, + name: String, + declaredFieldType: FieldType, + objRef: Expr[_], + value: Expr[_], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + // Load the object reference onto the stack + instructions ++= ExprProcessor.processExpression(objRef, uVarToLVIndex) + // Load the value to be stored onto the stack + instructions ++= ExprProcessor.processExpression(value, uVarToLVIndex) + instructions += PUTFIELD(declaringClass, name, declaredFieldType) + instructions.toList } - // The RET instruction requires the index of the local variable that holds the return address - val localVarIndex = returnAddresses.head - - // Create the RET instruction with the correct local variable index - val instruction = RET(localVarIndex) - instructionsWithPCs += ((currentPC, instruction)) - - // Return the next program counter - currentPC + instruction.length - } - - def processCaughtException(exceptionType: Option[ObjectType], throwingStmts: IntTrieSet, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - //todo: handle this correctly - 1 - } - - def processThrow(exception: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val pcAfterException = ExprProcessor.processExpression(exception, instructionsWithPCs, currentPC) - val instruction = ATHROW - instructionsWithPCs += ((pcAfterException, instruction)) - pcAfterException + 1 - } - - def processPutStatic(declaringClass: ObjectType, name: String, declaredFieldType: FieldType, value: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val pcAfterValueExpr = ExprProcessor.processExpression(value, instructionsWithPCs, currentPC) - val instruction = PUTSTATIC(declaringClass, name, declaredFieldType) - instructionsWithPCs += ((pcAfterValueExpr, instruction)) - pcAfterValueExpr + instruction.length - } - - def processPutField(declaringClass: ObjectType, name: String, declaredFieldType: FieldType, objRef: Expr[_], value: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Load the object reference onto the stack - val pcAfterObjRefLoad = ExprProcessor.processExpression(objRef, instructionsWithPCs, currentPC) - // Load the value to be stored onto the stack - val pcAfterValueLoad = ExprProcessor.processExpression(value, instructionsWithPCs, pcAfterObjRefLoad) - val instruction = PUTFIELD(declaringClass, name, declaredFieldType) - instructionsWithPCs += ((pcAfterValueLoad, instruction)) - pcAfterValueLoad + instruction.length - } - - def processMonitorEnter(objRef: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Load the object reference onto the stack - val pcAfterObjRefLoad = ExprProcessor.processExpression(objRef, instructionsWithPCs, currentPC) - val instruction = MONITORENTER - instructionsWithPCs += ((pcAfterObjRefLoad, instruction)) - pcAfterObjRefLoad + instruction.length - } - - def processMonitorExit(objRef: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Load the object reference onto the stack - val pcAfterObjRefLoad = ExprProcessor.processExpression(objRef, instructionsWithPCs, currentPC) - val instruction = MONITOREXIT - instructionsWithPCs += ((pcAfterObjRefLoad, instruction)) - pcAfterObjRefLoad + instruction.length - } - - def processJSR(instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val instruction = JSR(-1) - instructionsWithPCs += ((currentPC, instruction)) - currentPC + 1 - } - - def processNonVirtualMethodCall(declaringClass: ObjectType, isInterface: Boolean, methodName: String, methodDescriptor: MethodDescriptor, receiver: Expr[_], params: Seq[Expr[_]], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val afterReceiverPC = ExprProcessor.processExpression(receiver, instructionsWithPCs, currentPC) - - // Initialize the PC after processing the receiver - var currentAfterParamsPC = afterReceiverPC - - // Process each parameter and update the PC accordingly - for (param <- params) { - currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + def processMonitorEnter( + objRef: Expr[_], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + // Load the object reference onto the stack + instructions ++= ExprProcessor.processExpression(objRef, uVarToLVIndex) + instructions += MONITORENTER + instructions.toList } - val instruction = INVOKESPECIAL(declaringClass, isInterface, methodName, methodDescriptor) - instructionsWithPCs += ((currentAfterParamsPC, instruction)) - currentAfterParamsPC + instruction.length - } - - def processStaticMethodCall(declaringClass: ObjectType, isInterface: Boolean, methodName: String, methodDescriptor: MethodDescriptor, params: Seq[Expr[_]], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // Initialize the PC after processing the receiver - var currentAfterParamsPC = currentPC - - // Process each parameter and update the PC accordingly - for (param <- params) { - currentAfterParamsPC = ExprProcessor.processExpression(param, instructionsWithPCs, currentAfterParamsPC) + + def processMonitorExit(objRef: Expr[_], uVarToLVIndex: mutable.Map[IntTrieSet, Int]): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + // Load the object reference onto the stack + instructions ++= ExprProcessor.processExpression(objRef, uVarToLVIndex) + instructions += MONITOREXIT + instructions.toList } - val instruction = INVOKESTATIC(declaringClass, isInterface, methodName, methodDescriptor) - instructionsWithPCs += ((currentAfterParamsPC, instruction)) - currentAfterParamsPC + instruction.length - } - - def processGoto(instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - val instruction = GOTO(-1) - instructionsWithPCs += ((currentPC, instruction)) - val length = instruction.length - currentPC + length - } - - def processIf(left: Expr[_], condition: RelationalOperator, right: Expr[_], gotoLabel: Int, instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int): Int = { - // process the left expr and save the pc to give in the right expr processing - val leftPC = ExprProcessor.processExpression(left, instructionsWithPCs, currentPC) - // process the right expr - val rightPC = ExprProcessor.processExpression(right, instructionsWithPCs, leftPC) - generateIfInstruction(left, condition, right, instructionsWithPCs, currentPC, rightPC) - } - - def generateIfInstruction(left: Expr[_], condition: RelationalOperator, right: Expr[_], instructionsWithPCs: ArrayBuffer[(Int, Instruction)], currentPC: Int, rightPC: Int): Int = { - val instruction = (left.cTpe, right.cTpe) match { - // Handle null comparisons - case (_, _) if right.isNullExpr || left.isNullExpr => - condition match { - case EQ => IFNULL(-1) - case NE => IFNONNULL(-1) - case _ => throw new UnsupportedOperationException(s"Unsupported condition: $condition") - } - // Handle reference comparisons (object references) - case (ComputationalTypeReference, ComputationalTypeReference) => - condition match { - case EQ => IF_ACMPEQ(-1) - case NE => IF_ACMPNE(-1) - case _ => throw new UnsupportedOperationException(s"Unsupported condition: $condition") + def processJSR(target: RewriteLabel): List[InstructionElement] = { + List(LabeledJSR(target)) + } + + def processNonVirtualMethodCall( + declaringClass: ObjectType, + isInterface: Boolean, + methodName: String, + methodDescriptor: MethodDescriptor, + receiver: Expr[_], + params: Seq[Expr[_]], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + + instructions ++= ExprProcessor.processExpression(receiver, uVarToLVIndex) + + // Process each parameter and update the PC accordingly + for (param <- params) { + instructions ++= ExprProcessor.processExpression(param, uVarToLVIndex) } + instructions += INVOKESPECIAL(declaringClass, isInterface, methodName, methodDescriptor) + instructions.toList + } - // Handle integer comparisons - case (ComputationalTypeInt, ComputationalTypeInt) => - condition match { - case EQ => IF_ICMPEQ(-1) - case NE => IF_ICMPNE(-1) - case LT => IF_ICMPLT(-1) - case LE => IF_ICMPLE(-1) - case GT => IF_ICMPGT(-1) - case GE => IF_ICMPGE(-1) - case _ => throw new UnsupportedOperationException(s"Unsupported condition: $condition") + def processStaticMethodCall( + declaringClass: ObjectType, + isInterface: Boolean, + methodName: String, + methodDescriptor: MethodDescriptor, + params: Seq[Expr[_]], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + val instructions = mutable.ListBuffer[InstructionElement]() + + // Process each parameter and update the PC accordingly + for (param <- params) { + instructions ++= ExprProcessor.processExpression(param, uVarToLVIndex) } + instructions += INVOKESTATIC(declaringClass, isInterface, methodName, methodDescriptor) + instructions.toList + } - // Handle unsupported types - case _ => throw new UnsupportedOperationException(s"Unsupported types: left = ${left.cTpe}, right = ${right.cTpe}") + def processGoto(target: RewriteLabel): List[InstructionElement] = { + List(LabeledGOTO(target)) } - instructionsWithPCs += ((rightPC, instruction)) - rightPC + instruction.length - } + def processIf( + left: Expr[_], + condition: RelationalOperator, + right: Expr[_], + target: RewriteLabel, + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): List[InstructionElement] = { + + val instructions = mutable.ListBuffer[InstructionElement]() + + // process the left expr and save the pc to give in the right expr processing + instructions ++= ExprProcessor.processExpression(left, uVarToLVIndex) + // process the right expr + instructions ++= ExprProcessor.processExpression(right, uVarToLVIndex) + + val instruction = (left.cTpe, right.cTpe) match { + // Handle null comparisons + case (_, _) if right.isNullExpr || left.isNullExpr => + condition match { + case EQ => LabeledIFNULL(target) + case NE => LabeledIFNONNULL(target) + case _ => throw new UnsupportedOperationException(s"Unsupported condition: $condition") + } + + // Handle reference comparisons (object references) + case (ComputationalTypeReference, ComputationalTypeReference) => + condition match { + case EQ => LabeledIF_ACMPEQ(target) + case NE => LabeledIF_ACMPNE(target) + case _ => throw new UnsupportedOperationException(s"Unsupported condition: $condition") + } + + // Handle integer comparisons + case (ComputationalTypeInt, ComputationalTypeInt) => + condition match { + case EQ => LabeledIF_ICMPEQ(target) + case NE => LabeledIF_ICMPNE(target) + case LT => LabeledIF_ICMPLT(target) + case LE => LabeledIF_ICMPLE(target) + case GT => LabeledIF_ICMPGT(target) + case GE => LabeledIF_ICMPGE(target) + case _ => throw new UnsupportedOperationException(s"Unsupported condition: $condition") + } + // Handle unsupported types + case _ => + throw new UnsupportedOperationException(s"Unsupported types: left = ${left.cTpe}, right = ${right.cTpe}") + } + instructions += instruction + instructions.toList + } } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtToInstructionTranslator.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtToInstructionTranslator.scala new file mode 100644 index 0000000000..063aec3ebc --- /dev/null +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/StmtToInstructionTranslator.scala @@ -0,0 +1,166 @@ +package org.opalj.tactobc + +import scala.collection.immutable.ArraySeq +import scala.collection.mutable + +import org.opalj.ba.CodeElement +import org.opalj.ba.LabelElement +import org.opalj.br.instructions.RewriteLabel +import org.opalj.collection.immutable.IntIntPair +import org.opalj.collection.immutable.IntTrieSet +import org.opalj.tac._ +import org.opalj.value.ValueInformation + +/** + * Handles the translation of three-address code (TAC) statements + * into Java bytecode instructions. + * + * This object processes each TAC statement and generates corresponding bytecode instructions, + * updating the program counter (PC) as it proceeds. + * + * Key responsibilities: + * - Translate TAC statements to bytecode instructions. + * - Maintain mappings from TAC targets to bytecode program counters (PCs). + */ +object StmtToInstructionTranslator { + + /** + * Translates TAC statements to bytecode instructions. + * + * This method iterates over the given TAC statements, processes each statement according to its type, + * generates the corresponding bytecode instructions, and updates the program counter (PC) according to the instruction length. + * + * The `-1` value is used as a placeholder for statements that do not require a target. + * + * @param tacStmts Array of tuples where each tuple contains a TAC statement and its index. + * @param generatedByteCodeWithPC ArrayBuffer to store the generated bytecode instructions along with their PCs. + * @param tacTargetToByteCodePcs ArrayBuffer to map TAC targets to bytecode PCs. + * @param switchCases ArrayBuffer to store switch case mappings. + */ + def translateStmtsToInstructions( + tacStmts: Array[(Stmt[DUVar[ValueInformation]], Int)], + uVarToLVIndex: mutable.Map[IntTrieSet, Int] + ): Seq[CodeElement[Nothing]] = { + + // Indexes with their mapped labels + val indexMap = tacStmts.map(_ => RewriteLabel()) + + // Result which will be returned at the end of the function + val listedCodeElements = mutable.ListBuffer[CodeElement[Nothing]]() + + // zipWithIndex -> every Tac-Stmt gets its own index -> allows finding the right Label in the indexMap + tacStmts.zipWithIndex.foreach { case ((stmt, _), tacIndex) => + // Add the corresponding label, which will be followed by its instructions + listedCodeElements += LabelElement(indexMap(tacIndex)) + stmt match { + case Assignment(_, targetVar, expr) => + // Add the InstructionElements to the List + listedCodeElements ++= StmtProcessor.processAssignment(targetVar, expr, uVarToLVIndex) + case ArrayStore(_, arrayRef, index, value) => + listedCodeElements ++= StmtProcessor.processArrayStore(arrayRef, index, value, uVarToLVIndex) + case CaughtException(_, exceptionType, throwingStmts) => + // todo + listedCodeElements ++= StmtProcessor.processCaughtException(exceptionType, throwingStmts) + case ExprStmt(_, expr) => + listedCodeElements ++= ExprProcessor.processExpression(expr, uVarToLVIndex) + case If(_, left, condition, right, target) => + listedCodeElements ++= StmtProcessor.processIf( + left, + condition, + right, + indexMap(target), + uVarToLVIndex + ) + case Goto(_, target) => + listedCodeElements ++= StmtProcessor.processGoto(indexMap(target)) + case Switch(_, defaultTarget, index, npairs) => + val labeledNpairs: ArraySeq[(Int, RewriteLabel)] = npairs.map({ case IntIntPair(key, value) => + val label = indexMap(value) + (key, label) + }) + listedCodeElements ++= StmtProcessor.processSwitch( + indexMap(defaultTarget), + index, + labeledNpairs, + uVarToLVIndex + ) + case JSR(_, target) => + listedCodeElements ++= StmtProcessor.processJSR(indexMap(target)) + case VirtualMethodCall(_, declaringClass, isInterface, name, descriptor, receiver, params) => + listedCodeElements ++= StmtProcessor.processVirtualMethodCall( + declaringClass, + isInterface, + name, + descriptor, + receiver, + params, + uVarToLVIndex + ) + case NonVirtualMethodCall(_, declaringClass, isInterface, name, descriptor, receiver, params) => + listedCodeElements ++= StmtProcessor.processNonVirtualMethodCall( + declaringClass, + isInterface, + name, + descriptor, + receiver, + params, + uVarToLVIndex + ) + case StaticMethodCall(_, declaringClass, isInterface, name, descriptor, params) => + listedCodeElements ++= StmtProcessor.processStaticMethodCall( + declaringClass, + isInterface, + name, + descriptor, + params, + uVarToLVIndex + ) + case InvokedynamicMethodCall(_, bootstrapMethod, name, descriptor, params) => + listedCodeElements ++= StmtProcessor.processInvokeDynamicMethodCall( + bootstrapMethod, + name, + descriptor, + params, + uVarToLVIndex + ) + case MonitorEnter(_, objRef) => + listedCodeElements ++= StmtProcessor.processMonitorEnter(objRef, uVarToLVIndex) + case MonitorExit(_, objRef) => + listedCodeElements ++= StmtProcessor.processMonitorExit(objRef, uVarToLVIndex) + case PutField(_, declaringClass, name, declaredFieldType, objRef, value) => + listedCodeElements ++= StmtProcessor.processPutField( + declaringClass, + name, + declaredFieldType, + objRef, + value, + uVarToLVIndex + ) + case PutStatic(_, declaringClass, name, declaredFieldType, value) => + listedCodeElements ++= StmtProcessor.processPutStatic( + declaringClass, + name, + declaredFieldType, + value, + uVarToLVIndex + ) + case Checkcast(_, value, cmpTpe) => + listedCodeElements ++= StmtProcessor.processCheckCast(value, cmpTpe, uVarToLVIndex) + case Ret(_, returnAddresses) => + listedCodeElements ++= StmtProcessor.processRet(returnAddresses) + case ReturnValue(_, expr) => + listedCodeElements ++= StmtProcessor.processReturnValue(expr, uVarToLVIndex) + case Return(_) => + listedCodeElements ++= StmtProcessor.processReturn() + case Throw(_, exception) => + listedCodeElements ++= StmtProcessor.processThrow(exception, uVarToLVIndex) + case Nop(_) => + listedCodeElements ++= StmtProcessor.processNop() + case _ => + } + } + + listedCodeElements.toSeq + } + +} diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala index c6f17a42fa..ae2106c824 100644 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala +++ b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/TACtoBC.scala @@ -1,166 +1,165 @@ /* BSD 2-Clause License - see OPAL/LICENSE for details. */ package org.opalj.tactobc - +import org.opalj.ba.CodeElement import org.opalj.br.Method - -import scala.Console.println import org.opalj.br.analyses.Project -import org.opalj.br.instructions.Instruction - import org.opalj.tac._ import org.opalj.value.ValueInformation import java.io.File -import scala.collection.mutable.ArrayBuffer +import scala.Console.println object TACtoBC { - def main(args: Array[String]): Unit = { - if (args.length != 2) { - println("Usage: ListClassFiles ") - return - } + def main(args: Array[String]): Unit = { + if (args.length != 2) { + println("Usage: ListClassFiles ") + return + } - val inputDirPath = args(0) - val outputDirPath = args(1) - val inputDir = new File(inputDirPath) - if (!inputDir.exists() || !inputDir.isDirectory) { - println(s"Directory ${inputDir.getPath} does not exist or is not a directory.") - return + val inputDirPath = args(0) + val outputDirPath = args(1) + val inputDir = new File(inputDirPath) + if (!inputDir.exists() || !inputDir.isDirectory) { + println(s"Directory ${inputDir.getPath} does not exist or is not a directory.") + return + } + + val outputDir = new File(outputDirPath) + if (!outputDir.exists()) { + outputDir.mkdirs() + } + + val classFiles = listClassFiles(inputDir) + classFiles.foreach { + classfile => + // todo: figure out how to get the input stream of the file + // (1) compile bytecode + compileByteCode(classfile) + // (2) compile tac + val tacs = compileTAC(classfile) + // Print out TAC + tacs.foreach { case (method, tac) => + tac.detach() + println(s"Method: ${method.toJava}") + println(tac.toString) + println("\n") + } + // (3) generate bc from compiled tac + // > Print out the translation from TAC to Bytecode + val byteCodes = translateTACStoBC(tacs) + byteCodes.foreach { case (method, bytecode) => + println(s"Method: ${method.toJava}") + bytecode.foreach(instr => println(instr.toString)) + } + // (4) generate .class files from translation + val p = Project(classfile) + ClassFileGenerator.generateClassFiles(byteCodes, p, inputDirPath, outputDirPath, classfile.getName) + // println(classfile.getAbsolutePath))) + } } - val outputDir = new File(outputDirPath) - if (!outputDir.exists()) { - outputDir.mkdirs() + def listClassFiles(directory: File): List[File] = { + directory.listFiles().toList.filter(_.getName.endsWith(".class")) } - val classFiles = listClassFiles(inputDir) - classFiles.foreach { - classfile => - //todo: figure out how to get the input stream of the file - //(1) compile bytecode - compileByteCode(classfile) - //(2) compile tac - val tacs = compileTAC(classfile) - // Print out TAC - tacs.foreach { case (method, tac) => - tac.detach() - println(s"Method: ${method.toJava}") - println(tac.toString) - println("\n") - } - //(3) generate bc from compiled tac - // > Print out the translation from TAC to Bytecode - val byteCodes = translateTACtoBC(tacs) - byteCodes.foreach { case (method, bytecode) => - println(s"Method: ${method.toJava}") - bytecode.foreach(instr => println(instr.toString)) + /** + * Compiles the Three-Address Code (TAC) representation for all methods in the given .class file. + * + * @param file A File object representing the .class file to be analyzed and compiled into TAC. + * @return A Map associating each method in the class file with its corresponding TAC representation. + */ + def compileTAC(file: File): Map[Method, AITACode[TACMethodParameter, ValueInformation]] = { + val p = Project(file) + val tacProvider = p.get(LazyDetachedTACAIKey) + + // Store the TAC results in a map + val methodTACMap = scala.collection.mutable.Map.empty[Method, AITACode[TACMethodParameter, ValueInformation]] + + for { + cf <- p.allProjectClassFiles + m <- cf.methods + if m.body.isDefined + } { + val tac = tacProvider(m) + methodTACMap += (m -> tac) } - //(4) generate .class files from translation - val p = Project(classfile) - ClassFileGenerator.generateClassFiles(byteCodes, p, inputDirPath, outputDirPath, classfile.getName) - // println(classfile.getAbsolutePath))) + + methodTACMap.toMap } - } - - def listClassFiles(directory: File): List[File] = { - directory.listFiles().toList.filter(_.getName.endsWith(".class")) - } - - /** - * Compiles the Three-Address Code (TAC) representation for all methods in the given .class file. - * - * @param file A File object representing the .class file to be analyzed and compiled into TAC. - * @return A Map associating each method in the class file with its corresponding TAC representation. - */ - def compileTAC(file: File): Map[Method, AITACode[TACMethodParameter, ValueInformation]] = { - val p = Project(file) - val tacProvider = p.get(LazyDetachedTACAIKey) - - // Store the TAC results in a map - val methodTACMap = scala.collection.mutable.Map.empty[Method, AITACode[TACMethodParameter, ValueInformation]] - - for { - cf <- p.allProjectClassFiles - m <- cf.methods - if m.body.isDefined - } { - val tac = tacProvider(m) - methodTACMap += (m -> tac) + + /** + * Compiles and prints the bytecode representation for all methods in the given .class file. + * + * @param file The .class file or JAR archive to be analyzed. + * @return A Map associating each method in the class file with its bytecode instructions. + */ + def compileByteCode(file: File): Map[Method, Array[String]] = { + val p = Project(file) + + // A map to store the bytecode representation of each method + val methodByteCodeMap = scala.collection.mutable.Map.empty[Method, Array[String]] + + for { + cf <- p.allProjectClassFiles + method <- cf.methods + if method.body.isDefined + } { + // Convert the body's instructions to a human-readable format + val instructions = method.body.get.instructions.zipWithIndex.map { case (instr, index) => + s"$index: ${instr}" + } + methodByteCodeMap += (method -> instructions.toArray) + + // Print the bytecode for each method + println(s"Method: ${method.toJava}") + instructions.foreach(println) + } + + methodByteCodeMap.toMap } - methodTACMap.toMap - } - - /** - * Compiles and prints the bytecode representation for all methods in the given .class file. - * - * @param file The .class file or JAR archive to be analyzed. - * @return A Map associating each method in the class file with its bytecode instructions. - */ - def compileByteCode(file: File): Map[Method, Array[String]] = { - val p = Project(file) - - // A map to store the bytecode representation of each method - val methodByteCodeMap = scala.collection.mutable.Map.empty[Method, Array[String]] - - for { - cf <- p.allProjectClassFiles - method <- cf.methods - if method.body.isDefined - } { - // Convert the body's instructions to a human-readable format - val instructions = method.body.get.instructions.zipWithIndex.map { case (instr, index) => - s"$index: ${instr}" - } - methodByteCodeMap += (method -> instructions.toArray) - - // Print the bytecode for each method - println(s"Method: ${method.toJava}") - instructions.foreach(println) + /** + * Translates the TAC representations of methods back to bytecode, encapsulated within OPAL's Code structure. + * + * This method iterates over each method's TAC representation and generates a corresponding sequence of + * bytecode instructions, effectively reversing the process of TAC generation. + * + * @param tacs A Map containing the TAC representations of methods to be translated back to bytecode. + * @return A Map associating each method with its newly generated bytecode, wrapped in OPAL's Code structure. + */ + def translateTACStoBC(tacs: Map[Method, AITACode[TACMethodParameter, ValueInformation]]): Map[ + Method, + Seq[CodeElement[Nothing]] + ] = { + + tacs.map { case (method, tacCode) => + // Convert the TAC representation back to bytecode for each method + val bytecodeInstructions = translateSingleTACtoBC(method, tacCode) + method -> bytecodeInstructions + } } - methodByteCodeMap.toMap - } - - /** - * Translates the TAC representations of methods back to bytecode, encapsulated within OPAL's Code structure. - * - * This method iterates over each method's TAC representation and generates a corresponding sequence of - * bytecode instructions, effectively reversing the process of TAC generation. - * - * @param tacs A Map containing the TAC representations of methods to be translated back to bytecode. - * @return A Map associating each method with its newly generated bytecode, wrapped in OPAL's Code structure. - */ - def translateTACtoBC(tacs: Map[Method, AITACode[TACMethodParameter, ValueInformation]]): Map[Method, ArrayBuffer[(Int, Instruction)]] = { - tacs.map { case (method, tacCode) => - // Convert the TAC representation back to bytecode for each method - val bytecodeInstructions = translateSingleTACtoBC(method, tacCode) - method -> bytecodeInstructions + /** + * Converts the TAC Stmts of a single method into bytecode instructions. + * + * This helper method processes one method's TAC representation at a time, converting it into a sequence + * of bytecode instructions. It handles various types of TAC statements and expressions, translating them + * into their equivalent bytecode form. + * + * @param tac The TAC representation of a method to be converted into bytecode. + * @return An array of bytecode instructions representing the method's functionality + */ + def translateSingleTACtoBC( + method: Method, + tac: AITACode[TACMethodParameter, ValueInformation] + ): Seq[CodeElement[Nothing]] = { + val tacStmts = tac.stmts.zipWithIndex + + // fill uVarToLVIndexMap + val uVarToLVIndex = LvIndicesPreparator.prepareLvIndices(method, tacStmts) + StmtToInstructionTranslator.translateStmtsToInstructions(tacStmts, uVarToLVIndex) + } - } - - /** - * Converts the TAC Stmts of a single method into bytecode instructions. - * - * This helper method processes one method's TAC representation at a time, converting it into a sequence - * of bytecode instructions. It handles various types of TAC statements and expressions, translating them - * into their equivalent bytecode form. - * - * @param tac The TAC representation of a method to be converted into bytecode. - * @return An array of bytecode instructions representing the method's functionality - */ - def translateSingleTACtoBC(method: Method, tac: AITACode[TACMethodParameter, ValueInformation]): ArrayBuffer[(Int, Instruction)] = { - val tacStmts = tac.stmts.zipWithIndex - //first pass -> prepare the LVIndexes to map the Variable to Indexes - FirstPass.prepareLVIndexes(method, tacStmts) - //second pass -> generate Bytecode Instructions from TAC Stmts - val generatedByteCodeWithPC = ArrayBuffer[(Int, Instruction)]() - val tacTargetToByteCodePcs = ArrayBuffer[(Int, Int)]() - val switchCases = ArrayBuffer[(Int, Int)]() // To store switch case targets - SecondPass.translateStmtsToInstructions(tacStmts, generatedByteCodeWithPC, tacTargetToByteCodePcs, switchCases) - //third pass -> this time through the translated bytecode to calculate the right branching targets - ThirdPass.updateTargetsOfJumpInstructions(tacStmts, generatedByteCodeWithPC, tacTargetToByteCodePcs, switchCases) - } } diff --git a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala b/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala deleted file mode 100644 index fc69ab6613..0000000000 --- a/OPAL/tactobc/src/main/scala/org/opalj/tactobc/ThirdPass.scala +++ /dev/null @@ -1,166 +0,0 @@ -package org.opalj.tactobc - -import org.opalj.br.instructions.{GOTO, IF_ACMPEQ, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, IF_ACMPNE, Instruction, JSR, LOOKUPSWITCH, TABLESWITCH} -import org.opalj.collection.immutable.{IntIntPair, IntTrieSet} -import org.opalj.tac.{DUVar, Stmt} -import org.opalj.value.ValueInformation - -import scala.collection.immutable.ArraySeq -import scala.collection.mutable -import scala.collection.mutable.ArrayBuffer - -/** - * Handles the post-processing of the translation of three-address code (TAC) statements - * into Java bytecode instructions. - * - * Key responsibilities: - * - Update the target of jump instructions - */ -object ThirdPass { - - /** - * Updates the targets of all jump instructions in the generated bytecode. - * For each conditional and unconditional jump instruction (such as IF_ICMPEQ, GOTO, etc.), - * this method adjusts the branch offset to point to the correct bytecode location. - * - * @param tacStmts TAC statements and their respective indexes. - * @param generatedByteCodeWithPC generated bytecode instructions with their respective program counter (PC) - * @param tacTargetToByteCodePcs mapping of TAC targets to their respective generated bytecode program counters (PCs). - * @param switchCases switch case mappings for lookup and table switch instructions. - * @return the final, updated bytecode instructions, with adjusted branch targets. - */ - def updateTargetsOfJumpInstructions(tacStmts: Array[(Stmt[DUVar[ValueInformation]], Int)], generatedByteCodeWithPC: ArrayBuffer[(Int, Instruction)], tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], switchCases: ArrayBuffer[(Int, Int)]): ArrayBuffer[(Int, Instruction)] = { - val result = ArrayBuffer[(Int, Instruction)]() - // Index for TAC statements - var tacTargetToByteCodePcsIndex = 0 - - generatedByteCodeWithPC.zipWithIndex.foreach { - case ((pc, instruction), _) => - // Match and update branch instructions - val updatedInstruction = instruction match { - case IF_ICMPEQ(-1) => - tacTargetToByteCodePcsIndex -= 1 - val instruction = IF_ICMPEQ(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - tacTargetToByteCodePcsIndex += 1 - instruction - case IF_ICMPNE(-1) => - tacTargetToByteCodePcsIndex -= 1 - val instruction = IF_ICMPNE(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - tacTargetToByteCodePcsIndex += 1 - instruction - case IF_ICMPLT(-1) => - tacTargetToByteCodePcsIndex -= 1 - val instruction = IF_ICMPLT(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - tacTargetToByteCodePcsIndex += 1 - instruction - case IF_ICMPLE(-1) => - tacTargetToByteCodePcsIndex -= 1 - val instruction = IF_ICMPLE(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - tacTargetToByteCodePcsIndex += 1 - instruction - case IF_ICMPGT(-1) => - tacTargetToByteCodePcsIndex -= 1 - val instruction = IF_ICMPGT(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - tacTargetToByteCodePcsIndex += 1 - instruction - case IF_ICMPGE(-1) => - tacTargetToByteCodePcsIndex -= 1 - val instruction = IF_ICMPGE(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - tacTargetToByteCodePcsIndex += 1 - instruction - case IF_ACMPEQ(-1) => - tacTargetToByteCodePcsIndex -= 1 - val instruction = IF_ACMPEQ(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - tacTargetToByteCodePcsIndex += 1 - instruction - case IF_ACMPNE(-1) => - tacTargetToByteCodePcsIndex -= 1 - val instruction = IF_ACMPNE(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - tacTargetToByteCodePcsIndex += 1 - instruction - case GOTO(-1) => - GOTO(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - case JSR(-1) => - JSR(updateBranchTargets(tacTargetToByteCodePcs, tacTargetToByteCodePcsIndex, pc)) - case LOOKUPSWITCH(defaultOffset, matchOffsets) => - val updatedMatchOffsets = matchOffsets.map { case IntIntPair(caseValue, _) => - val tacTarget = findTacTarget(switchCases, caseValue) - IntIntPair(caseValue, updateSwitchTargets(tacTargetToByteCodePcs, tacTarget, pc)) - } - val updatedDefaultOffset = updateSwitchTargets(tacTargetToByteCodePcs, defaultOffset, pc) - LOOKUPSWITCH(updatedDefaultOffset, updatedMatchOffsets) - case TABLESWITCH(defaultOffset, low, high, jumpOffsets) => - val updatedJumpOffsets = jumpOffsets.zipWithIndex.map { case (_, index) => - val tacTarget = findTacTarget(switchCases, index) - updateSwitchTargets(tacTargetToByteCodePcs, tacTarget, pc) - } - val updatedDefaultOffset = updateSwitchTargets(tacTargetToByteCodePcs, defaultOffset, pc) - TABLESWITCH(updatedDefaultOffset, low, high, updatedJumpOffsets.to(ArraySeq)) - case _ => - instruction - } - result += ((pc, updatedInstruction)) - - // Only increment tacIndex when the current instruction corresponds to a TAC statement - if (tacTargetToByteCodePcsIndex < tacStmts.length && directAssociationExists(tacTargetToByteCodePcs, tacTargetToByteCodePcs(tacTargetToByteCodePcsIndex)._1, pc)) { - tacTargetToByteCodePcsIndex += 1 - } - } - ExprProcessor.uVarToLVIndex = mutable.Map[IntTrieSet, Int]() - ExprProcessor.nextLVIndex = 1 - result - } - - /** - * Finds the corresponding TAC target for a given switch case value. - * - * @param npairs A list of pairs where each pair contains a switch case value and the corresponding TAC target. - * @param caseValue The value of the switch case being processed. - * @return The TAC target associated with the given switch case value. - */ - def findTacTarget(npairs: ArrayBuffer[(Int, Int)], caseValue: Int): Int = { - val tacTarget = npairs.find(_._1 == caseValue).map(_._2).get - tacTarget - } - - /** - * Updates the branch target for jump instructions such as IF_ICMPEQ, GOTO, JSR, etc. - * - * @param tacTargetToByteCodePcs A list mapping TAC targets to bytecode program counters. - * @param tacTargetToByteCodePcsIndex The index of the current TAC target. - * @param currentPC The current bytecode program counter (PC). - * @return The updated branch target offset. - */ - def updateBranchTargets(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTargetToByteCodePcsIndex: Int, currentPC: Int): Int = { - val tacTarget = tacTargetToByteCodePcs(tacTargetToByteCodePcsIndex)._1 - val byteCodeTarget = tacTargetToByteCodePcs(tacTarget)._2 - currentPC - byteCodeTarget - } - - /** - * Updates the switch case target offsets for LOOKUPSWITCH and TABLESWITCH instructions. - * - * @param tacTargetToByteCodePcs A list mapping TAC targets to generated bytecode program counters. - * @param tacTarget The TAC target that corresponds to a switch case. - * @param currentPC The current bytecode program counter (PC). - * @return The updated switch case target PC. - */ - def updateSwitchTargets(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTarget: Int, currentPC: Int): Int = { - val byteCodeTarget = tacTargetToByteCodePcs(tacTarget)._2 - currentPC - byteCodeTarget - } - - /** - * Checks if a direct association exists between a given TAC target and a bytecode program counter. - * This is used to verify if a bytecode instruction corresponds to a specific TAC statement. - * - * @param tacTargetToByteCodePcs A list mapping TAC targets to bytecode program counters. - * @param tacTarget The TAC target to check. - * @param bytecodePC The bytecode program counter (PC) to check. - * @return true if the association exists, false otherwise. - */ - def directAssociationExists(tacTargetToByteCodePcs: ArrayBuffer[(Int, Int)], tacTarget: Int, bytecodePC: Int): Boolean = { - tacTargetToByteCodePcs.exists { case (tacGoto, bcPC) => (tacGoto, bcPC) == (tacTarget, bytecodePC) } - } - -} diff --git a/OPAL/tactobc/src/test/classfilestocompare/generated/ArithmeticOperations.class b/OPAL/tactobc/src/test/classfilestocompare/generated/ArithmeticOperations.class new file mode 100644 index 0000000000000000000000000000000000000000..af6344a825fc88b200d1f8e96ab806bbfc889348 GIT binary patch literal 2492 zcmaJ>TT|Oc6h7i&gE7G@me7V=OcDr}22Uo9RO8&hgp>qBf&(O>Nf5TM1+rwUH3?1A zPNy@?d!PE)ztBFkGkWMt-})c=1NtXAJ-d>Los#O|JDTs@_MAOu|NO`Q9RTLwYYCEb zb&FN1CbNpGHM4Fo%XPdcND?IWj6)-B8%{aBy0d2%Srj@Yh}^Ioi`|l-b7FEM4&4xm zK^H_N=*qbz6KS`>B#@Vdv*o5A)-8t>Slu+L**L_YuPt!l$YW+T3jMus3gW1mcU|VO zx>3uUtm2kD2`;@qhUFZ(`(_%WSx!0UIz@vm8b#*TkD@Rr!En{sHv@VTYr;Q|84kl3 zKTZVa5yga2f&`x%PRTaCOUtgi->79<%z`YfOq=85qng>O49&M%A_QH_PPR~Ch@4^D z1&f*3ks(ONfPg#@0Y!qLC5M@1v!0qOl`MW0vni@%RWA2}nE(Z5reoHnVEBg?G?A z<~V^4agwIZf^}$lP3Q{Dj~TjYRG!SPOoUJ6*vKnlHGG9ouYg z$TeQe!bci%o#0ezXc2mTSjuMvB3!SA`V%V25{Pn>X7aW|ZV~9=%2eKZZI+G?mYT2} zmYPnL#Ca!0S#tz>x#@Ud+MX$Jm}+xaAh;r0wK zSrDPVAdui}Ot7nKf_zC}@V)7ikli7;3TR4%X`y26vedG<%Y=(baN1EBRwR^bR=E;r zD+H2Udq%jfJDyc`@OFY2@6Gmc)wtPUq2ktAdp{il3ZKx#{1N+L;0_23b5&Q>upDgL zMC+a(ZxYs6a2xfaxoFw=6w;HP))~I062zAr$E@dU!}CmhpvM05$er{&Md3(-bN_D| zg*W&}2hSOd;z9Ta&q{Y3eU9FxxN3eK-R!dy4kcQ@_FmPA235AI6XzqzO70 zl0!1_VFJk{9iqvQRAkwQX(WfKLWe_=%Bl}DNS>yYo<=eW>C8wHu4c}vBkI{=<~$eW z%tbEtGnct=Gt)ftsCwQ99bGTbQFO_nVHU}8I!4Dsa#FqQ!%ZZo=p>yA$t&u# z4|kB9p;zb(l5*@_CatE`kz(eW-1jbXRlUkn>O9wV^_mYkG}h>Ks)Z3Us_w%glCv~J zXOT?8Jw2O*CH9*%MH3tH$wNP%BBwnlF#T<`Ya@$D_cI4kbFU((-%l~YcG|o{PIZO z>DIRKZ~KkD+pQV+XS~(-c<_?4<3kx;Oj@F57^kA_`ml$jMJv<_Nn6?Tp^9Xc+O&!! zPNkDbYHqhyi)aV3BfHyLU9QOo+ggK%_T;(`HFRLqqb!VaC^vlYkbFfC=_@3IvG0UK z9RCh@#RneWUJ1U0ui!0Ee6s+402TKhH(B5%ftLkN3A`fkQ-K+QHw4}mI4|(7z-57t c1U?qHDe#%V=K{9{76tAKv;^7$U4iv~0a`yop8x;= literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/generated/Array.class b/OPAL/tactobc/src/test/classfilestocompare/generated/Array.class new file mode 100644 index 0000000000000000000000000000000000000000..7c1f31f5f9975c96ac79115c2fd203a02c63a515 GIT binary patch literal 3029 zcmd5-%~umw6u*y2GI96{0}t|0a6piN0vhnC6F!6h5+Mc&f{I^5GRR1n$w>xJ+4S$| z+Ai#-3%h8~;k2A?+C{tRpVL+8eKWBHLEDYT4&+VV{ruf~e;0oHYySWMrr=>1&V)e; zLv0x9!cZTEhA=dSAwob?(oWvmw9LGgwd@xKQ=2N4j6H3(VD6ZY^7aMCC=ZP@rjAe7uPOQk&mtslzRsQ4fjP5Xtr)%eLGJ0#dAhwGJq>D$oLL1OiDXkKiR|*Cjv~ zJ!i`qUcyRTtj9EV5_QlHXO9KW?v-70M~03w&=E-26iJs5x5aon<7GKy)_-E#6}0zF5ySoSMt+Z^^ila8G;+&LrXIwh>S51YSZ zY@5D#&2qQ!TiG>mJ_Nq1PF#uNCzv70rJOlu31fd5 zhXhp#)TM0OEF}v@xojf&dQTAeH0sH)LZI{GrZQmOkWW?I7ZtZxJT*8lTxL8O-kR`D z@EsiZ0ith(9?n1pmV9;SYwXx2`urZ|3RQko^jeA6MHF7oYH1y<&jffwq=h%)t${XX zf;s(56g?tC1LQ#+yo;Gcs?9#5u)V3#FOw;Jn_d%6c1XWo_R>uf(IQ_JA`Q zrR+5f2=!SsjSlg46t(X|96&$E&a!i8OrwG4Jo@JFk09?1@ebNaJAQ%D8eNn4d8X0x zalK38-2r}qb!)%Za(P0!{LGhKiel@`3VLrmH(l{MK@hFN%38s!Vt2A4*@7zRi)?`{dI-~O=78U&X?nLZf+aLf$Mp^@tqXdZ|jtkJc7m_yA&_JBRC zXx2sUNA%G?q)_vit+U6d3GyeAJb#KzctW3gJ$_QuM|^P*8PepRM}{sL5@J8_IYbh+ z|Enz;AHugV`CkkH6Ui{@r~K&o9*_n|evp16g|7VzDHzl}-XALYv7T*eP_kCD{ b2l)T(BHlF!!XV0qy_0+AE$^K5&iTIqq%kal literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/generated/Assignment.class b/OPAL/tactobc/src/test/classfilestocompare/generated/Assignment.class new file mode 100644 index 0000000000000000000000000000000000000000..eae975ca785a9f44b544f05008ba5f1cfc2b6d92 GIT binary patch literal 2028 zcma)6OH&(15bi-w1h&PZL5#6s!8`;u$j?Ctj1dU&Mt~eUF?p~^1FTu?s&+@Nkb8bW zl1qMttDHlUQl)aqEmb+^oXRohTvO>?t;=%RO6Afs^Ud_v-%R)Pum3cD27nwqk3ujC zq2SW`-@gzDZdzw1fk5681Y$YI(NE2)Fl7Y71me%N7h2lT%+qx7__-(}8YK{3&`n(~ zqEl+}NjJoxD+Zm=ja(~MMTD0+2Y=lE>&v0=Qs`yki$B(0BG0mANk`gRZAZv6tKtwC zeM7CAFRXKsE=gNAPgg9ntjU5_mX>`HfdqkMRXZ0=_^B?>aOOzOl*sXIYWp3QW`K3g ztQf)>-L|ardTqYtSTjm1;)icKKE9}l)=mHTVGBd^CFUnvAfIAIGmMfh#e6sPK{5su z`mcn6;X@IXL}7qHrd9E~QhcP9+J{`m>k8&?FoXsohrdy8g7XgKx9XArZ7R~O^d7#X zL{FhrQOhWdy_L$+g(F2Z0u!B(f^h;$sa{pB6BT{Lsj!`_D|QO`QX6fQ+){wRG=X04 z`QHv0fi!_g%~fDvVbS;8*sYp7a5o0G;U1pYv#myLwiVkN6?mqkH0u%TUf)6izz zTE&9dFil~v7@Fej>Q*b!*WZSp6UR0)9m9*^-@Ji)tYjCLLIy9u~5*PVc#xy$|C{g=<@9w;Om zS30siEY5lwFa(gD0|@Yic#bPU-b)qQd&Cno@il*x0CkooU}QGgNBffc?6MNbuuGY% zNtV27W(x5NAHZnW=m5P|;n(T)Z}j{Jbi5ei6Jegh#RN?i!+bKrr*JVzr-~7NGsfiuv7K`*ZJSSwc%yXM)Op5>mM_w15qS3SGw*`jA3d-fyGe)=yv CVCW+N literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/generated/BigNumbers.class b/OPAL/tactobc/src/test/classfilestocompare/generated/BigNumbers.class new file mode 100644 index 0000000000000000000000000000000000000000..2f1312513eaddb6164bc9864bf9f11bba2c3575f GIT binary patch literal 9115 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 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/generated/Constants.class b/OPAL/tactobc/src/test/classfilestocompare/generated/Constants.class new file mode 100644 index 0000000000000000000000000000000000000000..c394333999152026bbf0127cdadbc648302e7157 GIT binary patch literal 1581 zcmaJ>-BQ~|7(HtnOBVhWmhI)&fI|&6xRfH>GJg%O1B5hboRW*qbgF=cI0%WcMP|54 zuksAN%qz4P?Tjz_0DYofwfSVJ#7=N`JiFfS`_9?jvuE|!KfONze2o(kl8A8;Q4ui_ z@gUgSccHzX01*ihNruF+ZJp=$ZL90(mebW396&&saxme$1h$Pr;dOLhVWL~YCAg& z!Q%2s6bdpD(#SG|_U$u+!uGYppd9zXZM*!0cH_{V4E?em#U!SNh+8*Z$G8+Q6TvK| z87A(43CJ@DS1ylf5p~hy?r+RHY~9_-0v09Aqd@%kZQJQO9sTN&;k>lZx(tO6XK7on z?F*yqA?d`Yy3^E89lLWQ;4_BorG8;};pc7V<*g(PzYH$yvv>;}=+>EObPLC}eQ|wN z|8#!?ks;u-n=9jv@*f83J?ZPq10kPcUpLKG+c8MiWvoaj;`2lpB@&U9@*n?1tT9X# z54|?X=1b_3d?AxP*BPV_Xb~F>xjt?LXj3NZsBTe{+K8g6TT~10{!I%|qx)p*nbJ{!s^{^dlqa4rK&!M0A&W zo1B*^4qnWE&=bl}`2)FM-8>>V#v?DyeuO|DB(SFeH5yc7 zAvHdxCcoVts& zXJ@jr*|}`K2aRwGe4Z~*DqdSk)QV};Yb!2lQ5LlVU*rWJRmv^pin*1ZdoFF2m-s3r zB9(QivXRF9%BG81lbKfLYrO1ZDw*}nMrN~zCSj_)!mE^!$F#Z}(YBbj=VEGdNYi+Y zYd&V1*ZEct4+*iuxA~4A-sQV|kN$gF2k|W_9>8Nfp;02$pW+$5r>j|_`6NPErC7P& Lf7S1I`u)Lsk|T9N literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/generated/ForLoop.class b/OPAL/tactobc/src/test/classfilestocompare/generated/ForLoop.class new file mode 100644 index 0000000000000000000000000000000000000000..882b4270bcbb293a4010406df119bce9e0326d5c GIT binary patch literal 1961 zcmbtU&2A$_5dJ#jc$|q7J9awp*oiaF53%!O$N6b+val>c5s`LfB(HW4d&$I}-OSpa zvBu*Sc>*M!fb-^%GaNvQ&^`d-0XQN~JOU?%nz11cWDyV_s;8=}zW(~FYJdOR)f)g0 z@PI)+vYm&v-I2i<;xF}Ada0#bFG|(Zmqy){Au)vSnU?8(z#!!dPofw_SV0IfL+H?M z7!wV4EM}# zbQzYfX_(e4yJ?gN&9q(|+E!h6kMz20JLfW{7-rjg)98nvn(i5WbzR+Z3FFIrpHFa^ z0ZRXXPjsu%GP=uj>t?TWFqGCmWjJ!9@bP)a7~UMDKN~{mt9DQr3Jo9*^;WB9x&|qd z#I%A0cr1(=hIFmh*6ionbJOX%T6s&edhJug>F#SRf)weRKOTk~9O|Q_6V${EL-H2k zWz17=JANlxmJc$-XaM2&asirxEOHE~0S(=8^mEN<8Eu1f3`i^`z>o>w|CNrT9|LvR zZuIKzHSN7WSZnQG%QZVK(`aa?=UTbA7eM5F3Ln4a9%~7VV4Y!cKw;;zoj+ly-==M8 zu727w0;J6Zq~OxSvJY+~W9#Oq1ydtqn_=YHv5Z}YiJGg|n~(I)V;_-5xUHL{&rJRn zxWW?#rDpe>x^ZOs$HKC!jF*j^!Uh*kv~N%qjhxcTSUGJ62|Z@-s^8mUr^B=HS4J)qLNVJiWuh#AAgM` zk8>MkMrf-?wUBnQQ#rcB5v z2Tkxz&>0WuzeMRD79JW{xRJ}4jI4|uTK3rWFKDiZMSpJy`7POf=rjudGI?-hz*r*d zVGa5JR_hNRy+tZbqx}C$uUQ1jM6rD*91_7Ni$xqWuou!x>*yX?$0$cnYo%3&i literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/generated/If.class b/OPAL/tactobc/src/test/classfilestocompare/generated/If.class new file mode 100644 index 0000000000000000000000000000000000000000..cff1baf98fe8f2742b0b5ee8a57316d252a0f22d GIT binary patch literal 2849 zcmb_dOHxmdEn;Rk|v#Y6JbPfFp_JFr2L7l zyK9DK>UFY6rgWx1pxw7K{U_bjJy&vDJ8=^F(2VcvobNm5p2zi%zaRbpU!PD7hP{#uh?65#dZpIRktd(?rqz8)!MZsbgtQ@k}F|k zWy`ZGzM$l~<&3_m7puDCKGt({5_&FwzGsyLVbOU|mC)hYRZl|yP1n=yR#7OwrJzSb z-$Uz>l`UD$gY2!1hjzhJ&?}*9spu5F3liki)ZGaBp@q?h0b*QrH_08@-6LLh-3J%l z>}@jWt$P*Q+FgtwhM^YX_5G@6?<(NO5XUfyF1oHqPFm#~wzutWlBdbP-6%Sb+#Neh zY;=iL*C|-u6|3O6m3;*#Bn<6ZJ9cn!o2mBd4wcxekU0$@0co|cq0h9j zP*5?iK^E$*;VHBY&p8bpLO0jq%@-n!US-eD==);1WtFP5rtAk6?MJqwVo^h!)+(q2hEn3(#GPRT6d{m+>+4!?^ zK8@fi)`V)FQrcWwjeIG%M!mi6S%sY&R{4&#QKA;?*tLq3-&m>*VCt@f@VdKKDcDzv zLRrag&5Bx)5Xn1^U0E$z)v8Snjlb4+?K(!mx`f2rRTX?p7Y#ZLqlnUbA-)h*4Lu(; zGTQaiEYaMVeu=?nLXKm&iCclV^BXFF3xtvT!bWf3pwTZIVb$nnVb*ES)nx$eAFEhVC2DTKzl7Mocw^Sd0xFU;@7BVHP{Y0%>zT%(>4Zvlv;A)#^XX zMqD*USe%UM@C)JpgjbxWG&XR2W0M}Gwf=#gGeIvytS?URL6uv1o zB~B*AH8ZM_W@)jVCd4$GJj6xfo#7ciBY2a6&+xM({vMaid9Bkl_&hgW;)>WW(Ec1>;OA&h#|tm;fpMOl zm%m0#u$x+kxyVhvNbp*~xTJNN%Y2D1(~&3+2{$NCUm{jVH#7y;{elsLs396?s#7tv ziiE5o3L(~lB9RmnAnDZU4SWqL(I-TM?T|twzB<%)$iN*L@i*BF;B}mOi;AQmt>B%| zC_M5jc;Qx%`V0@PR8Svz;79Zy^cNrz=6HiIiRnt-x3+=D{ezeR`8oK;1_r0zyqyNzADB!rK zJoKDMvoH$S>HD7a`%{<1>1KJ(4&$agQQtm(seSCy8I*MMi_fSd4Mm2+9q+EU()Gff zm5tkX{I=9kVn|;O!a!bSNYB+co}b5QJV!dt2-9FQXg!su8&c|eoO@UpB@V)!RaME0IBVbx78$ZF z>9srSUT@R8-KCQ9?P#y(_5Du+xvRRPTI(e{90aol+j z-iDxehp`;w&PL_F;CBEQ>7jDz!7jH&U zXTP_4vYQEHDsc0l=g*+un&8KST3woej#4zdZnqUkpN4P|%LXoBC7;Ht41CicND|Th ziW;C5xneUNuPdFKlWC5WR?%;A`lY;O;$_s8hHoqFX$#Ka5)E*&nxhyEs|<--O$}E_ z`aLh8DOTz;h)Y`xMl0IyxBaz1O)e9!d5oIC#zwO^H=Op+jWv+t0g?FODMB!2||4KJ+o z#K#vdKES#AD3R%=c+#B{DKSUTLh=Vx6qqJZ6KSE1c{)$H^FkN%L*BiZXYiDp5r)W& zc_wFWR+u6?4RxIlg9AG4zFf0=F9p$Tu+5@;& zDfPKix_|iRSig^uIK*`b4VQ=Ys+Vd>!&P?l#P}f*tY@>5^fv}t$7^WNX;9Z6;6vP? Op3jr5ll>Zf-uM^q%Y**_ literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/generated/InstanceField.class b/OPAL/tactobc/src/test/classfilestocompare/generated/InstanceField.class new file mode 100644 index 0000000000000000000000000000000000000000..35c9a3c4d906b5acb512b2042cf0e6f681f55afe GIT binary patch literal 1042 zcmaJ=U2hUW6g@*JTZZMMR9dlGsZs^hqE%7BG*Oa9k{V4g^}(kR#&+9fm#_l~|HL2R zi$-Zu6Muj|%6Nxe;x;rs?B1Ds&zw8=-ZQ`doc#ju0(FLD%kh+OI&#mFcGm!7$Q+B2 zsM^9gtiJhpEIZ1;0s*Z6cp&VdWMD0Z*mKLV)Got9seE9~$)17BapbXPB89Z(Strm-*HxYxi2iG-j@+)tQ2bZ0<&4}DStVY}Ic&O4N2oo~ zQSM-DV1r?;Cr+gAes8HGTIuE~;`m(hZ#HdPz~U!(C7iA;z2d&>o(%hq5X{dK_MAKT zZrqpQU;zIRV({nFD2H4DMN`;z+ftHxQ@|$2b=*kDaFa@yjiK;KPrNYF(6hXYdmMMLP4egoi-4=8a4kWy@&N;H zyTgH&q)kH0&MrJv=(f(!V744b4w|;`JW1W(nw#K7y*KcfVdMW$15ZfT{;aS`l8I8? zj4WxHR#94$%;}$?-7;B5cCm5_{*@LQN>U5LxxmIN-;u2G9RD(f#Bm=Fg3vB8r^&nX z6OlU4^HXFpm0BXtbBPHqeZ!S{GS4TtS~GLz8OlICl~3kV6I5sE=!FDaS>lQiSFE!B g14%!=fF1Hg@DPv4azfVd6wl~UT%*0Nqe$PaznlR3c>n+a literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/generated/InstanceOf.class b/OPAL/tactobc/src/test/classfilestocompare/generated/InstanceOf.class new file mode 100644 index 0000000000000000000000000000000000000000..f436ea1adf7ad07a9a1f8d6c759bb96eb3944e77 GIT binary patch literal 1778 zcmaJ?TT|Oc6#f>21;${ISzx&eFkr6cx)775ZJbctk~po?WTs3X1SlX7618P!_!oWb zL;pnk&~`kX&g8W}D$}!)TI3n0FGt?}zWvVGb6NlWq4^hp&+(=k9SnU(mg9J<##^uE zoX;?%%5L2^-7~B5PD6rW;L5x+3y$et6e_1z)|s!Niy`^gc5VL&Ln6QQCJhbUDJ0Ru z&{^`%E!y@PJ_A1v4%=SgRn2z&s$a9rn}amc=xY(K-q(HWMnk3t1L$vsd^&ldL8slP zp6A#7ntA)e@-MyfIz#RuINQDRuB`(3Ab!bn&rJW&JoCNUy#~%Oa${aw;r3hGzocL4 zmOg3xln`w4_?czZ(Ue54Fv|Hy~BtSC~WFTC@Ue>B{X5jZRA=v2-+PRbfSVVG(kA0_+b`{2N*I=a+>Y`jCF zylZ&MFwA{OUh|J z9lD+ohM0-4IfZ5AET0XplM{0yM_5wM^Z7qh#f5}i?38)2z!!PG(kYj^eVGLVhQ*1@pj>1ZEn{PL9 zNauFNj@XT`J%t@f$z>B?5wn$qsIPFaa Vb~&(Xf!zx1L0~@%?DN2W`42y;w8#Je literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/generated/InvokeDynamic.class b/OPAL/tactobc/src/test/classfilestocompare/generated/InvokeDynamic.class new file mode 100644 index 0000000000000000000000000000000000000000..d6540588f83ad69643e5221f7fff54778f6edb4e GIT binary patch literal 1657 zcmcIk>r&G|6#kY1DQRd+87TsBX8ns=nqkx z@c|s4$?r(4vSk^sh9fwB(z#CDS}@ z^V)iqk1%x23)^<+TytEz%5Z#9cpFYNy&_%F35MzmUyr&dCjV5 z=wV21@^?IEbNME>yuK+ao`x7h_bp3W-W`TWc4E~)FXB23Bp5o2PL+TnPSax;D7Bm| zC->B~q*wM_!D|HrDID7eT;6VYqNZV>2ZQKmIChAehT{xcUE$c0ptC-9D=-44vZMH(6K*Sz96?zV^ITSK(a4k>XRBE+9E>m|+2{CtyDq}!|E~0}Jlc2S;I&0=+hxlWRE$xa z)iHuhq8npL#0{KQ#nh1{!30&(Z4%vs*)WLeGrn#s@AH^SQ7>L#NVUn_(`(2ni+Bt( zxX6%cTLcOEg)2I;!o9gY!Y?xn)%ce1#cP(gL2nI@OOHzS;s28#bknO4Ykub!!W;w{ zgowO~YdWsrI`MXcrj1Rd*+>+5h8y9S1N0DhAPIv9A_G@(D+PwzsvtC7eJuu?o@EEa z*wAo~A?}K|P0JNaj$CTmHp6)M#zTS+L#V9sxcM~N=X zGmK?R3*jBHkCVN+xBB973LSVt8$k`A>Yy;8dpWN%=w+wrR>Yj87Eo#*__Ruw!B~(| zxJ8>c8iHD2>_8hGHhmga7)~E;s^K}UGJjfW1k?&szfNMDHX8l+(N`axjLxpf9V9<0 zeNtC55~xp6mddT~6Nd77isfUbZpJ?2RLc}SSj19b`jSi);^Ho*fxK?&UvY_Y?#Rbd zk-TBXOk)>!NE26By=Jc&C!BB4^9eJtgS%$p3m%$@U6jZsX(n6V{xwXM>F|g;|B5Jr nWs0E#Pw|XSot(;efmK?XXXtwv5scGw4wLlUByA!1UckBEEeWt0|vwRn)IYzXBaD$-&vS|X(EjbL$apYf?@hJ ztFNV7+3aXb?X-9 zaVa$0q^rKB^e9`Z${SyLx~YA^yHyKUaCKyo<{;3bYhYml*Kv(puawe(_IdBM(EF+# zFf5++Ay3y*AvEdj)s)xbdXu-b@&^WPGR${*M?~fwsrTtG(A?96@i{)t5G5+G#l5yG zg2jeXoqn$x8#<~Iw~Qpd9rQ%pISl_0Lx^aqmSd(NM2)*{Q))pQS;UfwTezJY#~q@p zNlPuN-J;$XMVGj8iY$$C$VWYnGprV--!0HF-TTAz=*A7KFc`g%0@pi7>JTElng@7j zqJl?6YL`n2oGZoW_#4S!HdWtmiB0Je^)vO+GhGRpVzBC-C;XbrgFw*km;T}Jf15Y( zf??s}PyyQl9YX;UN_$<*=@tS_OToKNs{=-x&Wd9u~MBj=d5 zd4zm{IT_ouGsl=qppbAZQmj+OHjiC5luxOEjO7W{|OH7~%5d+brL?3){C<83r&NjPKBJchP zpMCLJAJp*R5AZMeU&K4z2HHT}Was1FJLjHz@A>`r_!oc`JhL!lVc0^FA+;{^QD-|0 zI?9uRVSH8W2B8?Rjjik|5e}G)mr-cKWEeZ(hrHx-xmS9%eIOdj#0W!j*^{1n&R`Vh z-#8eBW5Y&@VW<}DP!@yIG2}M7kG-JuI`pKft5EP()xj9X2Y~BGkrFKv6C=2UEW^YF z&rD1*m~D;YOM))O*j-`-?8&{VW^x&>jVW9q{M8^(kqUWxQ>gu5Ct@g^)#Ay+peai6 z%UU2CT&?kj3c@23*BPc-yeVSyTTkuNDNUn;B zmVt*`M{RLI_`AONxb@ZfK2r~(#(lr;DM4+$fxL}r%w&?dNhQ=zr=BN&$dwn!N}gFL z==QDmWAz%SA#P_$LUV)T>9*IzJgKR!c%!+=+gp6w*J=_UM5Cj`SuO{6wHPeiBQdnN zN3)tN_Lp)xEC#zCbi#&M^E8x2id)nJVsO@_6k*NhQ6#A4v**TkQNv9T*c0^%BX9*qu+7W zC_Bk=D(B=6~+nB2dY=X*WX=IcMm7+4*wvN24;_p|y;}2`0LLbkm=SDH98t z0C0jiq`Rl?(sOCw2ufJ$Fh($ literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/generated/MethodCall.class b/OPAL/tactobc/src/test/classfilestocompare/generated/MethodCall.class new file mode 100644 index 0000000000000000000000000000000000000000..96a29daf8ca5f2ba48e4f3b8f859469230a0783b GIT binary patch literal 1932 zcmaJ?%~IP|6#g#Qk}U)_f(r=QV18rM6dIbUtqHUVEsa|UDW*w(HdTx!RKT5B!KeY&>)l}9SlkQAgKGo-e?Bb#Bwal3)# zHtfh7L%Lk6RcZ2q5^sUih!|2)j+$E`hU=l?n&jTnz(oAK zcWV1B&pNV?F3eXkD`sPjVM2_|o55AA;+BA{GgS6p+h2`RD&Hz~EZ-ttY`+o`a+_iK zx>~M_Fa=Yi2=6nj{C9-)%Lv^l#D^LNg;CzMX;9;mME6wOiCEcWC_D(27x^|wo$T93 z8Z8o0Gv207I-Qn%U@?86}=8)7~4U%v@_it$M+`EK!L+ri= zSzwjAcj7nf9Y@5-MTH5HR>d&VIMrO&_P1MBw`P4WJf?>$ zT3yT$dnsB1AOm`xs0xNG-A3ul=$l@7fy^&LPgi=cVzrnGVI~=c@3)HQp+1WmK9BW( z(*WEc>0iHNpsMJ~3#b`$NHSGj;X_>QVZ!jOQN+! literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/generated/Negation.class b/OPAL/tactobc/src/test/classfilestocompare/generated/Negation.class new file mode 100644 index 0000000000000000000000000000000000000000..3d53975a81478cedf88de0c3debf97b460f36f5d GIT binary patch literal 1466 zcmaJ>%Wm6N5Ixr~+O#Aqv`Ff@ekiW&$nryu?dat+b)&?!Qzt3lpj~7W#=21$)1)9? zIrU$3Q=s3_UAt%jF4{$R1^PKfcR`1w)GDZ)&0ONl%(*jX=JJns!LI;5!_%>YqrZM< zn0z8ymb5)r!3ab8jdf|29LsH$p1yn|&ZL4dhKakjYs-5KqlLAv5}1IZVjPnUV-2q< z2==;?K|hI-ZLjoY$9CnZ>^1s_-k9frY~Pwt|X4{3voSBGd-60 zf+NdqI>OJNc;0!py+05Z-!h22m-y_eEe4&v@aF>zv1@mvhEy~G(ae!(^&Fc7CoK!dgA~1s!px5}8s9v_>=3aPEHWtVP<_V@Nd~IuQH1l$ z;iifuERPctl;?ly3^V;29M5eh7oK{ z9E|@q_1zDDf6H*APtf$bFC7uxyc04!xQ1a*!zk`Vl~eJwvGaWfYMK@Cw@_j)|z4E_@F>Iw3JfcoM9ID`i z9(Mc$aFaxhH65YB()%W>lD;?SWOR-ff5Fs`^Z`uaAr50Vnj`~2zyeTD@&r%*jE^(OS5ii*TS2e3S~i<~Tbm2r^VzuoWpXd@dA>mIv|3)&RekYAc}ZWAxGIEf1EU=mrv X<|2D5vKx`zjch%#pG5W`vW8AR-Jl!V6q@G6@hPf(!;W#OB%I!3kgz2xQ7+Ix1EZgKaUk$dp&@ z$LQB+r%7hqOg}(BRO#wu7iY-y#qHgm_I~%jy}i-j|J42hfOR+s{CsnB6ZnN41){kh z&h0bzpyFKG7594m?98rKRR|~$Ik!GoiK110m+)g$XjMQdaLaN#=XSxZq(I9lPqZx+ z$^~~tfk1rnI0T*0r9m5nL(l=Cdk}tW49s-%#V@PYUjP9#vhd>@wrmc+*kp6n}#qtDG;|)v;a2xwyJaH-*(t+%)sm z!lUa;`y1iSIrA?pJ$VNiz1t1OP z;YmYB($kUjbtIc~Jk_~oc`IM-oEJ6gN6j}yE$Ps58#V7m&D@Pz)gf>jwa|3(nI_hT z&K1WyF39{)ES@d9_B*>`?ybN1{&;=&^(H6lzq#zbKX;qCO&waj_1d9xRXMY_3PoE1 z@vT>9dg)Ujlr5L-N~UO4t2P(V_?;sBR{5y#LV@A`4^?50pQ&GNFv_QD<7*3YrubR$ zsKt9!vgaoydw#jx2RP&Wn%VZS_apng+<#|$hDbYUsD05=9RUhOH0l%`7{bn6kh&sK z3bWUR;an?4BE!_pUIe>yZKOxy)We>RJvo)4kt88|QN)}fIzEE_8`FWc^n2s1 z`x<;9`Tas*ze$6VKOp({#Q@$nX$S{#C{M!%4%hiH$sfUy8l;&&Dq>=k`9XSM-~;BX z^w7YE4gR>~kBM;{Gbt|lk0gIWJi-Z+CNYkac`^(%>iox&KZR2@SYiIOcr2!wA0X2} zQ}PoACK~)%$)6FkIAhYh zif3X|=6?&fxbn6Gw4*DO72CLjS+2b2dJDZ^?>WBUdfMiC3ec{ByDTM0dj{?`q~sVp zK>H$x`zF1TQeH|a2jV3jm~@D*@GwtD1|HR=97`#$@pTQhS;~nx7AGvlufhQAaD}!& l7M^pjamDV!KIFKDC)l6hw>Hgl329T(E=#*6ZARLye*pxIs5<}v literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/generated/Parameters.class b/OPAL/tactobc/src/test/classfilestocompare/generated/Parameters.class new file mode 100644 index 0000000000000000000000000000000000000000..e248d69659d0ca4889d3f6ea7f5fe0d99edf7924 GIT binary patch literal 1771 zcmb_d%~B#)6h2oP8d@9>xJrX)`w#eozc+(Ajts<1&uB2gOcrju;*Bywx79SJ++{bF zH^@4hY*Lj<7Kufr<^l39d4Vi4IonG5OTd@Sy$FLJ0t!eV6OhX0xd`k9 z5f1+d$oxiF{6b(#R@e1hg+Qo&$*p5kH*5^gmUDVwZ{sU3+-G+1mL9l88)o6iY8ZCS zwghi&ham>>cN(hQwr$apfrelN64*?;(<0!{>Xlq23`tNG7=RR}JTXnXZCm{MP}rB| zd7Hq@{cAOh8}mvOuu8+YD4Rx|+xxt3o7Sxi83Lm%ekFR>pEvAF{I6|u!$yp6vb{cC zay*n?fv4O!Z;JNJfoWcKuDAQbdR6*w-bp;Zy%zmWFZ`qrp{K%juJ6i&DD!5s*02RK zH36Ce<1iTsz!ZUGt<%!XFEr#*!_KsGvvbxITN(+%46>cA^n-aN9gMjc$}&$N{vJ7G z$f3H|jy_Gp0qN_sN>T`k12}*j&x*Saq@AaE!?P9xgld6A0^uA*^zf zx7z}zZ}uM({JzVp&z_790f1!frmPf`rh+B1-<7Z z&yoEt{DwS^Doja0v^W?ovEiR!bSpxYnK ztP7jyOQ>-*fxaN4l>Vx0jriE8#FFX=9i_>t#8f{^p`p@L)z8uaHikx;j#UFJBeQWd zGIYEuvxy+n(3qfF)u}S2j@&_!P14CO>|m8?bxNJ~I#>;|89IZdW_@fqoww^w_tM$fuW?l%dk;Zdy9s`R>i{8Amn(2YAL|;0?n1 zWq3~TcLU%LpzyV`WdAFo4-OG~06vB)J{83N1Zr@MFE@s^hCNT?-K=}Ax#zZfmfUmy EFXl>iDgXcg literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/generated/PrimitiveTypeCast.class b/OPAL/tactobc/src/test/classfilestocompare/generated/PrimitiveTypeCast.class new file mode 100644 index 0000000000000000000000000000000000000000..c9d739b5650d653dd810bb57970550a6d0eb2ff2 GIT binary patch literal 1672 zcmaKsOH(6N6vzJ;0)Y-ONt5p6@_qzNcm)AFA&euE5rJWx(TsySYE_f8&_k!2N*XM_ zf$!(WonJv+XjLy}k*AE}pW(NN8k;@#s%TAgTwq5p<%>h?{B-hAP~5c&}n z(1!trNY!d+{o5b?RUG;0@h5$hq37^t`EQzNUDyoLp(m$XMapK{HM^y$&8;CMkbEjt z?W%2S%_zh{3?oIZ9m}%Yc1u0KquHlcqs@@(6sDV()|pl$HQhX^T4r6fch$OWwXUL& z88S`vO!M)PZlBUu+g44RG=9wc^?1t*RQv>cs@X8KcJ9!!&MwZkLeu;#Ve(X<+q|$d znEo)N;P-K>5JG`ORW*#7Zfn$$EVzISMiTuPWq5&_HDy~<$5*yinPLMNr(WiF!V*Cu zH*!*>zE3d>Kd0GI%rHdH-R>KvD-xvb;BFVel86Y( zbgG}kHLQzc!|z?i4ZPJQ@PRRiuMXwWK;OSKX^~$JIROqIpY16t6Rg zoxsjA-Vib1R+{ioINyPYL2vEXp6hgXL`)5+Y4ir!AKA;lp>m#|%Qv zx@gt4UER=V)-%_C#XUU?L;I$wwW@~NZfkU9=AOBB&$}>Dyvs20|5KxQpB@tbf?=Ar z*?leOy`b|$?+ICf{!%nD8v7Q0$KWrnpL$Zmec#QFXnGl7x04M;NF%lxPa|H6iL9KE zgzuE3B>bQZOTzbxEXO`oxE%YeJSN9J-<-_GzgA|m@o!4=+4#5Rg-qfLWjT}hvb35> ze6_jpE7Fyelys;pR79TQ;%|7-g=uNn!4g4(Jwj${f$}xd7(nc?Y`$3p~#Y0bI;1 zIM^q+#25Ke09T}C2ZscUe1#VSxF)YUxJz)IukrN&D%lMOZxbwWg_j8WP42}z)ao8Q yz!8lCwfj9h#0TJz=>Gsi7$Y{}*@9OLN;)6#j1fP-2|eR&t#P=b$Mjz*)% zcR-XO`IRO6ef!+)Sgx-j!jOI;FJ;-0?s@r(=P#@#X=4oWd$w!)_ZcFE;sNi>>S##KA&mtxJ@7og@AqW) ziRHJwR-Yk%ordjRdKXri&}{d->bXtnpUS51^{zB5GAwuGg%zs5w*59e^?m93gz-Zm z%qJ*jj1qp}k#t**)z3fnyo*7%GT|0}Wm0n^@aa|8nlz5xznMS?S*sK$RAY#$bey{F zTf_)QHi0E9r{Y*)*sKw`wsg!(=?tvCd1$^oHd)EM3gj!2vv`{-E!1kYN!;<*72K*$ z&0S+yoYDae8w^@kwZw6$OOv#WAyiX0v6X;{Z6g2V%(r@G({o#tm*-Mu)XD$mq!gq# ziyejariAu%FccV8LoCPhx+c}$lL}B37nZfpkfpNTP*q9C3=SC%LJ-%YxoJ(w1>b(j7E zB;TU94Bd?G*#7TG{G#lb!^gNEn%Upfk21hSIw2CXBBwKv{1utwd7j`oo*ZHwI9@R3 zjfLNk*JngZ8Phy9M3D>`BW+~J5D|J@EOMPM{)oFg#r3vW;z_>L5S&h~6=G(|fe?=< zaM{Qj%M{4`=^3Llom;mrT2DvB&qg*$@R@ z;Ki2M=S9BX5(oT1DN73SP^oxnhz|+&$T&2P2v+gQaF68oh>Y+lRyBO2C=L!0uffz% zd3{|QFrp6J?yQ=o4&5VEuyHGL;7np16u~DHIYSAZ(48Q46`$i22GqZ3mj=ZkT`rKj OfjkK0JAr&Zkm6s9eSh8n literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/generated/StaticField.class b/OPAL/tactobc/src/test/classfilestocompare/generated/StaticField.class new file mode 100644 index 0000000000000000000000000000000000000000..3f04ad1c54e7c1ba61b594f1f5a856df412af363 GIT binary patch literal 1009 zcmaJ=U2hUm5Iwh07M6w54_c{OsZs^hQom5am?#O6q(&1AKKOKnE8Vi}CG3TSf8vku z#hPf-2Y-M+$~c!@b!!_RcJJ)WnKN@|&i?p$@*Ti4JZ4C?6<2n*X$z-kfH7na`IJ{2 z?)EFM-XDstG7uq{H-~k&GZ74|#SnX9yS94D5Gj^A77WBqM3G>KHe^p&SVSy=1y~H} zzEFOZAe}OZAnpC*juu;*DT8H`5?6>>P836Sf8LQTE3e14OH5VPa7g{z3;W6|$yKC6JmFYto9Jx6$jeJKZ%Q9T6ntAstL65q^5A{-3h z??MdzQtG9UE1+m_$7$P2&}^11>+mcPOLOa_q9G7G|M!5Ke7s%mDR+HJ}35q~1m9uiGuh{*~PrpNu{ipoq7o_}f1b2vT0e5kaPLqHS@DPuX!zKFG JeP5$z=NFa$^TYrE literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/generated/Switch.class b/OPAL/tactobc/src/test/classfilestocompare/generated/Switch.class new file mode 100644 index 0000000000000000000000000000000000000000..0d6610fd6c6423414ca698c3230a200885550c90 GIT binary patch literal 1447 zcmaJ>-EJF26#m9PyY_k=$7`>XB{aB@wuzhCP+$Q&q!5?TNR6oEs#VJkQ+tTF+3Xtc z*eDOcDCtzp;=eUBmgQ1k*3_4px~J70RT+t;Bp%s=I0-tc*_*ZAbgQ_+<= zvgEPh1)khwNUp9uFp-04z(AfM)ed{&%&v|cdcmHKc?M%Zf93XY3py!KdX`dpk1U%O63Sw9!qKoRwmsEY zx%eW~Ra&C369i(|_IVTulK#rMZ^Vj5V6ZS}R4cqt)#bz$)nigy3ot$kt`A*86vl7h$t>&CU zC+*H#$!3vO^G>nj-ei$w2E<eQvafhmQ@#eTH_xiah~v_gsat#vAnVL<7D@38WVo~+dj>Wajo?g z%}W;Bt*sy9)y+%E@35S7wIeJNfmF>&5$dMxG~rsx)okqt@^90t9+g+=u>Lbvn|kdT z-UgZ(M|U#EXda=i;4H!K6KptH$C$ti3eFMy0l}t|b4-Fy8Q*|@f)(hBAjMWmO65wW sazfPdGoZ53lcdirF~ZiQDudiV!pFEnr?p0Sne49AjPgUiv?(?vvDsO@YZ}CGCFu?Y{l?>9>D+KLfaj9fpyo zhqhxq^t_e|#*lq(zA!f((|xx2`TldO;j2&>Qnzi__U|$%mFkl;l1OPtKxIg5dj}S| zy{^x|ABM@cxA{fecKy2Fw#?>M8X86ii0j84-)gED8$kwX3f=cSzvH*f)+5V5^bR@< z<+p9v?hEh8+9WpHeYWkn4b$H-8@|^*Rx!aa)ijT+$omZ{1`;11x2*nP4F9r^A)4A&wa*n(Y@3c#w|$EyGKsu~ z9Qb$&1%^`HZnhlDcqx@I9Fn4DG`z0sTW#Zx!GNyWXLkSBEYvDG8Js2-(oJO*%%DRz5N@h*= zs~!(i#m&J@50_TOErzkWZ#Iq|nXSj>zC%|g(KKz6q)<7Bruu|It9#vc!`h*hV910= zm6!CYRGA^YD~G!6n4OMAtG@id>vGriW!pp44;tq)g5v_eAD2_#+|m zDZzQ3^VhhQ5QU_e;srkS8cVY1GzAJhtWl<}PwTqOEKu3PY49h{(@Xv|_*D@_iJjra zp6tCgtIz1OgiMJ!UgUEpNb@2=i`1$jO2cBFm-sw2%1h)eC51uXMoTR41?8LIZ%MVt zOFg_tR7?7zzC=`~!S9MF%g{0}_wYW2R`g|kMfOuBmU2q0@-kojF8GV4QIWtZuk;`Y zxTaV2H3_T??TPi2*x>7Yqa{brutnw7gx$b~Uscq1_Da I_0WFsFC;dXRsaA1 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ArithmeticOperations_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ArithmeticOperations_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..111d500624e11b65160996460d76dbd0e63a259b GIT binary patch literal 1086 zcmaiyT~8B16o%hnx7~Kz(l54ULB6zTL2Sj3y(okPF+>tbF*SPO1+MJ?3)|ghcS^!P z@jrN_7m_r@AK;HNp51M9i9~Pa%seymo_WuiA3sOm0c^uySlIR~aoXp?>b3{mGlk_k z{!xD@!r9Tf0>)4{GcU}hZ8|5-_Qx~c6$&JVXT;@UrDL4?W8f9pQ1azmbKC%njkrr7w72K`xC+WNGV#>k40Z=HP&fQ@7_c)c!of zaxUC+-Xt~4IoWZYt|@lSu5i6e1x1Ex-#q6Len<9b<_psir17a9y(cs?R*4e4GM%2y z{o20ko(~5bv13t|IJt50&Eb4Vz#Ilbig1#+aQN=u#7;-PI z<74h|r_004_ex-axO(WhyT0M}q3aTNm&1rI5HWFImT5TmI zLrEDaJ*g>Lsx2AmH7(sRGLoSZQX58A%V^mTMlJ|FqY#8sqZ|a=sC-4fHL2xBxC6BE z`lO!!hPweQYK0M&36}JtUK+zGtvo`Vpr%jh+89=~$_Nh$PU}^DnqXu?LW7)uKvF564a7D_rkVL4l#tH_v&9-;q6<`NDJrX?&`M?-`qkRKf(WOs8ja zzq;?b=flBf>{ys3PHtR$b2;Gg&FJ|1m_k^!&D9u+BwD6zcPzoFA|*_#C_>96QKss4 zhW+LeOJRm;Slf$VjS>VmW{cFwIfl|LMOHA+pbUbl+fE=7%N|JteOttmiUlk)Oun>^ zkGaR4E+1#UR|E^h)kDwi4ZC6t?-wxt^=Z!D87nTiRD zEcnbcrfF56$S5Y(u8{f?>=RzcqiFkzeCxzM%Ug5T>VdSKR}Fc6UX$Chkk@VQ`+PRcYtP2 zpVD*Ra5sPjEkD8v!J=N!ixHgGN+Z+=YWlRUMX;ikM|enZMz82I1Va-N>h$ahH1L?B cN_IBz4A03-p4PKeiwZG)JXXi!gYmfb3(NipXaE2J literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ArithmeticOperations_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ArithmeticOperations_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..6349de193f64de2c5bc058eff44bd3be2b8cf448 GIT binary patch literal 1095 zcmaiy+iuf95QhJ44o)1Whm^FqNl%bMQlJ3}0n&q1f+`{vwI~QKxG0OWZQVL{WUnig zC*dKufeS#n-~o6j#Mm+5iVALa?QeGH-}z_0{}_A&u!SbW{FZCVqn?navD+6em!@NT z`#oQVU;C>H7{mB6Kjn3c+lTetx5vVe3K9(Ib<;NGCPSiHd#NFXw2CAYhGfg>3Wf=T zTZV6ODW3a|G=(i0Qq^|5*4CgRr(y&eU3Prp#hp;Xbn1JqY0Hju1@EnC7{%B*`OcXq zMNh#*76pt`=&|ESPrAJSOvodr>oHXRJl3>NofA=~Y^HtKa%_XkZEi@%JyTF*nC|ft zF~qOP1p4wMwZJ~xMg)rDaes&Tvjm!eJqU`>OsfvH5XV0W%97vj$e%gf*W%MYWFK6}BNlJiK{ckZ!)p2~+5Zk6jV^sOigsucdF=%bu7H-Spo+qe-OMgwl zMg3E7pJDFbM-@CEpNIX%B9)aSGeL#WG$T!Gmi{JaXSAo5zaaB5h|`GEkVoObjRdju zOv&0Pe+c7Q+{T?K{*K~fMD1~PJ+o0Nzu7F6yNz_IeALL6%3qOhXrD0IOwJCl05ns2 zQcr!xwSXzb^Z+%28C}sc5mbxW0d5k^>8hTKV7{mgP$xL5=k-y7!*?cdmy}1aihH!H c^r8kH;t_OQqW>8xw?u3G z*U$$|`rrrfLmAIrqDv(DGMC?(^FMPgKYk9s1K37~VSd}Q)v3#sZ5<4_XDV9?|Hutg zbUIqoz!=8Q%nP&anBt^;@ZpSGN<)SrziA6wZ82n8%WulaA+I9~jUn5WeNI>gilMe2 zIoq;*=-EQ`l*dhXqYNFTE5f}?UvXDMrHE0K$@E-GJjQP+Jv#Zy6pA!Hwc`Io$s{UqfET9dJKS&XOL-m) zHd4>xC~0!V@%80^r;W+;cPWLqY8%Tblt^?<$LZOMQ$;3mLq`?0u{@@zy1l?%Utk5? zq#CyN(ymE>&|{`bjjS_FUQ=WZvkclGthysYkyP|VBJA5d7Ie&Ek)g6(U2urU5scbG{x?Dvjq*>RrDb`dgo&E1%B-N9FXYpOzp#f?B zXZBXZq!`M3LU6C^n7+@cgG+x+!FB!9@Q7jV-%m9>p*qL?#v-MarDB4177jD5MY>JU z&S=lAd_&=LXeWFh4-)f7dOk+X8P_)p&+3iSPO;v2zg2JaJNbIU>6E`Q1xBE{>lor}#Dy{Fjk%)> z!?xVx(M0&G<4qX|f%Lh4skcqtI&JsfpYwr`K_U>@HY`Kz5RjVduM-f4hyo#y352@# zkR!Gyf&e}6FB^9I$T2L@7Y^4)TM1AgenYr_OTmNKuM4vKm{YIl6epsuH6uN;OuHSRNyJjV;jvT{79qCrEXQRGq>yK&PY@ z)zWA1VVN#Zy%%>XYFVuWutuv>Xd%9YQc!;xt bK0Jn}un8)pabH9e3&>P|Z203nf86*5RZ{FmOJw#iukWpeIvq9n^ z`T%{5_5e~<@c=wj)p6ib#9?=Ke=|GZH~aYa_XB_tb_D!UQK;Mba;23{^KAakfna*6 zZq#t0vWwy5+hua59T)04W!@ireG*-d#)@fnaj-WNaHsjII7?2`1>2*S ze-f37*hPh>00cH+!RF}jt%52qQ4Yy_gGrmC;ArjN!~4kxaB>q{&*>j9u)*xReYo|< z{a_sVt~A4KGAE|A{GPN!vdErT((!j>H6(|slV9k*cMVw!sTRq4;8Oh#K?xhC^g{9? z*$f)ge1^UyTOqX~*$#YaGc;w#KbPH*I@DeFB2)H4>P5025cRp@$)>i5QWce{@OHc)1RqEQE*o!q~PK%Y$+5$5R?jqZd{buh7xHLiK*b$2k>2V zp&;S|_)y}+cB6O~cbIROIp=(Sy?p@aV@ts9Cy9SQUMy2T4dZBhXh1N%_V4`m+>d7M z!PRvzNew6hdN+*1v?rjn_D2>p=q6Mc0_t%*4H(DERDjNYmczJxk%Un?Oq0N0bS#)C z{yIFozfFUMfl>iwSOWEb)(qGJ#!Yr-9K96>?E2k@c9olLz@yxZs7>+HSO{`u?M4*=(QDBzu!Wwg7_wpCOmMSlH6LNL9J z-bb@E%5P@NH@ES+lF$U&*=|+K))z^fZUn@o3j?N&14se=S+R))ti?J_@}xQw(59zX z0_LK5x^U5Qprg%=Vp|E&^JYs@%wCpBUahJ!j9 z5|D4}Icd&brkAHzF2bxu z{_??G9DR3QXlI_I^x&BErLGKbsLX&2GM9#u-ifjTl4LFKFnsE0$_~g5Rm*p%^#zAD zZ0pJm$PHD;Z&POvJwtT^>V~T4d(>m7tKl6i)%P}PKz$m#Rus^XsF^#~)hM7*s3!iH OCanIG=$K6&;N&-a(rfSl literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Array_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Array_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..0690512aef838d529bc1874922475f7d8588ca82 GIT binary patch literal 518 zcmZvX&1&0F5QWdR{_JbnmVd^!?6#1d6NJ18vq(Z91PX-~7Yx~S5!6Hk1zQS=9Plf3 z*DM?ep%2i9Djhl5B;+pcFyAn9&iVWA@ehC#j1;_+Jdf7r%T*B-NtT}PJ5WNeqq}Ij zh|;U+?B{iSQ8+LZ?4u-2iem+1vU}#jf~{e~Q7})l%UE!>DirAJb~(wW-}59b=0zSy z%R?6$^;d`I>)Rq;I%w3;gsaefXU&19;M|mV7OCh=zLdfpbT!)O30Ovn@c!h-v*^~b zC?@IE;qIA&o@cB4BL18##2&qk8kUOKK}AxOuL4zulD{ThTdI<3?LDCSyPON|WAHNG zz`zG#zwD#&lm2ELdz#JQBbhUkEw9IRKo;3EiyiM1R|9gWI=e^fKpR{Os1|bF*Hqtt zO4u;j4ag0-={KnP0zHdc0kuMI`yRCgn%tqzlRoGg-19D({4Vu~L~melUz&c%!+-`f a+zO3M_5<=m9{VF2%ldN$g`v2v!2b_QYhsN6 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Array_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Array_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..fe920adb8573ecb8f7672ed769e777da148beec5 GIT binary patch literal 489 zcmZvX%SyvQ6o&t4Zf%;j>E%SDD7b4Sq$_7(iy(p^C>08BTu9VVQkq0!D)b?I03Sma z3L-v$4<(*dH;S{EGxMFx|DTV~*LMK>SQD`Kvn*I##PdAJqcpkLF(8;ugS((V3zA8H zbU6*Las!HhK8%tm-xE-}y)z3MbQ3BJ0reog4jHHOT!4<3%~9Gv&7ve9=UEuU0}Cdq zzXp#Nw|N*Fs8vvhCD8t-&44Xn+!S+W3F~x^3gH&oCYtClh=Yi^(>?zdT{>pPD47g; zX9DIpoo83!VKifV^mkRiP{bBWyhU+J5XDk_SNPZDC^%}{FDO42dBzS_e$o$6_zm3a z!}T}wMA@@Vsd^ivj#R1H9jSYykv`I-VQ^l zN0u+^ZjI_c(AH$bqlPb=u1!sbs%+WUvh7ie+RIr?Iv#a=>9|A=SA5$PSY=}+xL+N( BUS0qI literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Assignment_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Assignment_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..580f65566fbccde3129bc187b0b0ff686b4049e4 GIT binary patch literal 1328 zcmaJ>+iuf95ItKbaq6aR>eg-DtAQ5M0u5IKX}Of33J?&aAduhzw(YicYp)}FjnqHk zH{b!J2=M{D@B#b_Vw?nFL?92lp4*w7Gc)=6qx}WIChA3KMdTQA55oh=pxp}vgS8pQ z-o6ZkRIh_Xapi^b^+g?dhVmhQ%d0+@`_;zwq1aJ6bcVu)Cp~qG;wvl9OBjSysv5I)>u}}x$ zZp^Us`x%~m8y<-&p?Pw@9?BiAw)l<;qhlQw!&JbJL|6U7QwQ`FD=rmbysLEI(;~ImDUR7g1buSP^r?XXQZ_rk5;@UNEVh)I65vJHv3jk87rkU%`K?(kHE$U|3}+Z6&_%NFInz8Rr;I_ksOK zU27%=P^CxHMEHVBXYiTL`15?qlh0n zd{2>>w061bKFu|eOG(TH+#{kUE7>;wD)u>p(F~JlM{IdMP5MmV)mcmXK(#-RQbcv1 z$FZORT>fi_`;DIt+N*{CyXv?@OV}M(oIrt=FZ~S=<+O`*4wE!SH={eh`U$1?shx~B zQ0tk$6FZBf`&KqK$`dzd=ic1Q+lD;O_+$qhq%Z58`OS(-|sGLOpxp#k6F^qcg{-ZJl{Dlb+iu%N5It*BqD;%SOnYt9SNfL9i6gaXyG>;`t)sw5ilhplAO+foWMgk^#=HpR zGJyZ2ztKLlfDrTp`YZi_z7-ux3d$f#^svjhotZf^tH1v3{|Vq2?Fx(vOa}A&_#$F3 z?!}6MAE&8*9)&8>&%#Vg?Z?rxTNX+TwO8`BYz8tqZ+2e1Qm5L2#ZW%-BVXU4`1=0S zDkfpus9=g<+wmCz8gZrx_TeDdkDHGZKhj;DC>b7BF@xE6fV)?zR-uKtNjRvH>24hB zR420cNa>6CEM?gJzYITm9bc*@q508yJC07JK9Q$7POdC)hNVzms-gNvUtiEys%4}J zdfZ;kr^&|@dFOs1e zv~j?2Z4B%O`f50sK$D85jR=&CyyGA4d5KE1Ko8J9%lrB11Hqp=Fz^M#-ie>2+KaOA zg-VE2PbP`H^5jcRV%9s8dRUrpVCE#6q4bHU#d>j!Z<~F}V0YszIaMcqK%2fY_USb8 zIZ*EpqDUp}K&Gjp1>AdYiN~#<1$tK-A9uCz9X-O~x?&4udVKkBf+(lANar+3b96Jh zOV|HE_1D}^#;?&Dng1bnc1icQd9?b*eq`LK*}^Lj5|wyfFWwRWscYS z_>wG+JLfuNDT{eN|Hf`D7=oK((Oux2FLq3^R1(W1Eb-+|Nw{UPLW0XzsI*o3T5X6m zLu^pN>wJx`KNp*%+~Av?Jjb>nJQBTz*y3A#+@@?h?zX!_*@h$-IHa~GaD;E@&e{5w c{u%GW#RAD5N?0Y``rxb&&YOet*5Lf=KOI_0NB{r; literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Assignment_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Assignment_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..d5cc70c5cd2463103686ec09f481a17232cd366a GIT binary patch literal 1356 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 P-m}*{yYAU{J$vgPJ+RLq literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/BigNumbers_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/BigNumbers_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..32516afa9cc4c19158b11f2729372d557fa10c5f GIT binary patch literal 1915 zcmb7FOLN;)6#lLyTd|XnMDa^`Dv6!gDbqjz=h>9TA=D*l3l1r?i*n-#SB)$gTkenr zlRp6i!y2Y57IXnKW~Q6&vgSv?iW$}n=3L2B>>-cAizD50zWbd|=bm$Y`gij=fE#!q zowQmlY3dwU$D4cUbu7c z*eJOQ6o$~cX`Ai_gOthc_aTf(1U=|wkn_%=L2jqv677z+*>o1})=b+ix;2AW*81=Y z2D*rg$931JC>RPu#UOVvW0$zQ%}cIR zJ5~^5NL2Wd;k)md?jw4uyWDn(Z}K2RNqXYleV2)uuZ6R+>;E$XB>cnDF&q~PQz2RlzVH6s;$ILDKfyuip=nb7se}%a?xYYl8gN zIpm8f0(e6d?R=FMW$|Rbr9#4d=;RMyNoem`;fM5>FTP+%Z#j(v%eYj_y3n$9j+PA- zGOkm%UZCaB%j2oJp(2QRf^S<6zx>3vMC$ExQg5pW;a#fe1*tz3X}rt@6^h6_+}Ww^ z!&k7=J)Pd5DY(thUvzotXqQ*_IMs@#y~0gup?KyDn(RJ9r06tiC1cwZ;E^*gnX95h z8TtygZPfA>uh$J4)%1VH{j5P%KshEZhAQ}ot}B1AF-0}%q3#2<3=_8&*?w9L(UZ|L zIR7*HeiU&EzK;+5F#DZOH4CsYm949RYolYIY&^s8syyC=4y*<>SquJzSvePa3Q0ti zSg46B6zb6wt%pKUyt)*Q;_6awJRI-kOZ@^h5btl|O+pQ71KJ>=Am@hK3~Fqsi6x2+ zYpOQvF)Xh{qgY*uC!@)DX(cHbMv}=U-X_$jHlmFZO2od-jm5^K?+})A<4+Nia^nIz z5hJyEf=+4^+9W|$X<1k0<*9_8m^xUV7MPjDbQ3oTlhS6i6k$Z{t6Vyk_UUFlx>*68 zi_JFi9ziqOoR%S|s2amvvcDkILJEq4UB;M#X$5zvxGnno8R+u)Az79?FuO=xi1DG4 zB)#187XqwBQuP0|udOQ(2y_wA?NFpo2w)E%(o^)uJ$#J&&=95dB6ZIw`Nln)@$BoK Q&3X2kXE#0jj%RQE14q}-BLDyZ literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/BigNumbers_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/BigNumbers_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..e4c8c7766cfd23213dc63cdb6df1d36454ff9e48 GIT binary patch literal 1915 zcmb7FOLN;)6#lLyTX_;kekxDJu@gIG8fd|JHl;~0bxGQSLkjJp+&CgtBTL4XJ7mG+ zPr$&ihUuycx_}uo!=}5e`y*h*3~L5+uH-59kjLP~k?uL){m!Rz&$&MNyZI}C8+afc zw^}V}<+~He$Mhxkl zp)TUmQQb8v3Wj^3B21xm$8qa!jaRn~_mQ(-XGs4m!?d3`hsHdynfAekW0$#G;APjT z9Vv)0Br5#S@ZI-J_Yu9-U2eO?@om=E<9$q<#ZPdP+xwPLPj5NSVWYaz0rRtTdb&35 z9950ZU>p9RgTb%bO0L7zrr6+?RWeNiA&fAjingnl8WlZT;a}`>t6}Ju zbc@#x3~!NJ)>#k6sJ_`^Cv7{qV4G0sxF;DRryPKSDF&q~PQkx8X&k{*asF@W+_s>w1Q^7D76s;$ILDKfy%OAqzoZfQmg9|_P4MBeE z4Du@~0=O!QcD723vUoDzRv}?7bo_^}B((Fq_$>3)i!T{6n@(fTGA`7zDzt2#p=C{l zjO)~`=V;mY@_1@)s0dk1N&T5f<7Frt4ZC>5sR4bbH3OA{R;@MMZa=Q$DC8tp<8wFE8H`X8tqorwytC$}w?1RKdq|UHOBJDXLKqbswl@n7Fmb4$^9vo{XNs zxt}rcqli=R1AOR*+3$3!Ie?9+Y*h_h8y)*}?KvXL@^}+EupHE6E%*~=1I5-83CP* z%{1{oL9^PdmL;gD8pB<(zaZ2?8j6B##+ZVXf;&{)7XAGUb@}{|EXy63Z6wac_)tlb zUhVk{0oEcZ`v2P3))fc@x`^m@DA6Ybu!E22Df;6cKEZuxh|>BBb* literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/BigNumbers_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/BigNumbers_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..2211fb895b73cfeba604b17b232b9adcb9f6d76a GIT binary patch literal 1915 zcmb7FOLN;)6#lLyTX_;k@k@!5$c~-ZDbqkH&a){^f~iZ=793J&7v;tgt{Pbiw%j2L zCVv73hBZuAUC;&0m>D+RW!)bED`r?Tm~$mhafUnwFOGE2`R;c8RaqOUvIKLq4Kc`Sa4B#|+UmvwFK(+coNqhqb25UDL52UR4le2tVde_?*S<>fD{( z$413fpfH41Oxtu<8Khi(X8^tE>q8Iv8RT_m&mgzcbcuG;+iW^>ck8C@mfgC+Ys&+8 z4MQi0%ZClus3{okg^DnR)*Q!exOIN8Ww?)=y#_<(Um2$T#Mw9Ih|RRC>yBOFZjo19 zr+%m)$`G&deZzO(Gu=n@)^NG)634eWUyt`O9Tq>qO>Xa5MkBN7IQz|mVYO=W6_m9d0!Z z{gQ6+de!h2`6Zq8AW8MjmAYv=$pzblO2<9PFmlQPC`d6V2jWC5Taa`q>rjX@okFG$ zX=E8vrH1}W$ZD66>w1nz@q~klk>ayOwdGmKC98;|wjU zDr8)zZaqiKo|nf{b3;WCvji_%4!`)sH$>{<8L5jZLU@lVdQR%kL>e!1NrfUZk92ox z=kOJ5o}5l^&=lNe7%aQIvcJU-wmH>`roF~ZYN1%}6q@`FLtoix)+wU?W8}>Y?rfwG0!t7TG~s4bzj+ zGdTM*27VNA3VwhO{V@BTPBjm(q{>#*z_qdDr>oB~vLuhUpaV-mP1b@xVOlPPo(fnpbkhPl z6P<41eS+q+87)UpQ8k9UWPd@ZjSLh8TZ}OUX$5zvxNZ9T89L$fL$WM)VYU!I7vn=E zNqV*CF9cYdr0D-^Uq@FU5I8|Zw?mmeA%JasL{HHl_wWhsLqmktSEzf&$T#lUoM+$k QY{9eFJiF%EcRhRSA6zBRCjbBd literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/BigNumbers_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/BigNumbers_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..bf7cdd2426783ef7418ceda6445a958462232ddf GIT binary patch literal 2127 zcmb7FO;;OL7=CWPCP`Bo1}0&ELVyGkK9Zg);j?H7#s;CZ4N`4YI)rJMlFVQ->5+y1 zq8>f2?Q!M8EcBc#+_>w)l|RC@YmfE4cR~$EK8{(ulid5<=Y8gVpZn(3->qK&+{S@> z>DyQEd|vqT6@#*BlGhC@^U+id=hF&mj2380mgsTk0XXc4-9=DTAxE4Sd zUBqiO=%BJ8vKvQV?YdQK@T9@lNXDnSV#f?nEMwJf`C*R-Qe-9E7P z>kRRK-@`DUTZejv*bK9rv&@oa=e3e;)s7{o4AH7~s5{FK4f}w;)osnRiQ}83qeoPu z&Eh1uqnY~^y&m7Nti#69QU}b*(z$Z#;P&y6-nrR^Kki^~%D$B9SZY(`v`VFD*g92Y z0E0pF2!SCL=rwaeapp#mGFpOqiAcT!%gjITN4HLR5gRF7)hQ%liFbj7Oh6Dq~{IZ zjs7#IP?|fPoK-MQy_TzJ^}0@1KJaEXQQ!VELe9GU5=sn17eghG44*SBFhY&=k+ngV zqk9EE#Vhoyo1ToG-pQX4{E_b?fKTz6v+bIsV>dw7m)Wf*x|atApR6Ltu&ylhH<4TDqfdWn zVUVMS`UYFLL#SbONF5fexrJC?tgrv;?5Hy8u#O4VF^-QbV=a6@_=Fl)6NHyt^Ak;M z&5uXNqZ51cNe)UylPzo$Xi`n7lY(?>ekwW@o%kv{txP+lGlF!6SC(!80XIq%uvqyf~$5WJ{qL0>ZlJ$nE0wW?$ Ti#R9ZvWV}AxGv&-5qJIpxsdd8 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/CheckCast_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/CheckCast_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..9f47a9d7088ecbcce7b9457ea7c98704dce0236d GIT binary patch literal 1111 zcmaJ<*>2N76g|@{c1-A!ZkVNYp)EuJdAw5>$p7BqTxuoIDt46fsn3nv~ucw_~^D&x+#LQ_^E1BxUDM19ke6OwWs94 zrU8SB9rF`j_PIPN?|nEHt~QWk$UgO?r=KyTilw)CTteQ0h06@-s%nUVsJNzqaRRGI zGfdb1r1VtzH8rovFL-+^j{+tK1G_Xu+rV@VGnis9PPiY5y+elOVw@t;)mABCic3<; zE3hq0;40;Pu9OaSz&pD_H&r8KSo}AcCr?yMl;gOnk}lUf+|?@R8o0qQ+vY71o8Ni5 zNnfGnQd5qP$xixN;sP(YZ1^HvtSQxsI$P(vOIQX1_q!c21pYpOkBJxTrihBeOf3Gl*!~uWE_NQv1=8hhhRGph8YmH6ogTZsB*K$R z`kR$hvx+qfD_AGhw7EyXnPPIvGbDpmS5e@K9nU9i*~7HD(QAVt|58d3RDB+Xg6LT~ zNAWOn4BTg!yBKQVA*ntl6ALg&?Y-X!SWo=)9;4d?os7=R%2$kj>iLmF8F%__jtqf; zHw9K({eg+kn0>YS4cB(pPEiCZ>2*8(1sklAu`{u|k}Zr>3_EKZWG|#Drfv2eIophb lEIVgg2N76g|@{wU%_-HOf2f^o%f` zR;RlhoX9T3r6~JCotNKyypXQp$T4JJc*-*`8B(S7lLBs_kVhUj8PYY~lmzRZVVJKE zlRaI2OKlorm!eZGU>Y+cg&Te9x5F`;!yJmEu3^U<3xvMX+R(tFdnipyH$#S%zs-5- zQnzI}ny{voE6l!djSl)8Hp5~^v}FXp^Gu7rLL-!+8lOs0m%|a`DiOhJp_;x7SL#}~ zd);axEMiF_BZD;~OSF5B$hs6I-$SJu<_zqav$+!TjOo4=iq8VFfta z+Wv|SR!Q4w!pK+26elWKJ7Z@FFQzKo=CQ-F`7ouDvn@ME-iRlKZDO0i4$5@qiSY@Z Q;u&n*BHJSSK0V970b}hMTL1t6 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/CheckCast_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/CheckCast_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..f5ab15bd84443a14918e9ae5f5f03ed9db63c7cb GIT binary patch literal 1340 zcmaJ=T~E_c7=8}>Xji7d__BUrQNRrbQ&G_kQCvba0X5m87hI5Ici76hc3ICz_D}p7 z>IE7ujMx4sQMkuar#QHJEEJFFP4*i!mtHs@mF8U~?t?Xr6#8S4o=WSN2rL9tqz6@g*2!T(*6jk#(Wmp=5 zm5YFdCDWL}tcGb^W6=D}s$1=~>4Y0Y@+0X%z0y#?>$sso!%ZT>?b1o6`)QV2cu!hM z;#=@mDUCVY9-y+)BZXQD=2N%>gIup%SCW{#y(eVDt$7R!7Y$p^vD*}({$Id+ zoniQX1R~U{=C)n2q##D_A**2txv?ac8H{1`dp@v5gQ>{>qjOj|S|v33;A$~oXJMJJddPds<_>bDRwNI zhDjfGmDc=YFr?o&j_3sQBuJjcOA-$gN5Lk;-2X!r&|OUS#l$>KWSZIsVqpH=r0)dn zCTL}}CYHZr{HyOr3N*nO3EWe(#>l3wET2H%%YO+Xd>%(INs$|P8Uodk2ny_HMs_o7 zZzcZ&x8AP)0{e!$#rWze?gPby9@i5mc*2TFJsJ9xOsuHtimsA96ECLpROrz3R6lD} i*Yr{H_Kz3Cv!HwtC0aEq{~Ryy5;_)WuhM>n-qpVje`q@Z literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/CheckCast_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/CheckCast_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..3b4bdec54bd6d7c2b9818fbd9a4769ed24f06486 GIT binary patch literal 1111 zcmaJ<*>2N76g|@{c1-A!ZkVNYAuZ_|ma-)XsYI$kYAI3*Jn&Er&a`pk%tZFMQvQVB zfCoT*Ks@tNh#MS=L!(BH$8+zw>p4Gvoqh+fg(oJ`CNd_n4CDJvFLdbPPN)M<9x<%d zBi9vSco_M9*Kv8MMZ=MFaRPBD0wG=DXyw%V@X;-)bW;Rp@l&;?a9cHsJ7`CmYfs68 zO#=oMJLV_6>~nck-urMYTx}r7kbUY&Pd{Twm6qS;aS3?~7A`ZSYpNjzqT-qc#tEz< z%`m<5C#9##uc>)We!<(-JPMc`4D8YrZ3ELe%wUSaIN^RI_6`}AN^y!rSJmZ&DK1GV zufVo2fvc4Fxl%gR0q^Vz-BgW`q4;kyPoAijD93R%C0(w!xvN#sHE@Grw#{22Hox<9 zlfFXDrKTJolb!Ul#06e(+3-bJ+)=6(b*ksPOIQX1_q!c21pYpOkBJxTrihBeOceiHY=4VG7dwxo0_pNL!{iV$4J;E~ogTZsB*K$R z`kR$hvx+qfD_AGhw7EyXnNo7fGbDpmS5e@KZOg6LU1 zNAWOn3~VyYT?{qwkW?R&i3OOX_TFyDYS4cB(pPEi6X>2*8(1sklAu`{u|k}Zr>3_EKZWG|#Drfv2eIophb lEIVggia-EYx<@i&0JEDZnv literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/CheckCast_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/CheckCast_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..10149308edcc114c9b265cd806febe21e98e7e60 GIT binary patch literal 1043 zcmaJ<*>2N76g|@{bO=dY{p0QRtJA#EXJAU5Wb6WN8h6lGti^YWXI7t%ExIfm>DPkH7gL#niXQos!q^2p;RL%OD$l3?944D$sZB%dQgo^XOk-xGaHCKCb~t8pm_u>YHSCyUfzVf48yZ-252b18X2`Jew>eK; z>b5LL6V|kHh1nOb(LtZXW?1Zqwv6C+o@vonXoNCU<5MZ>ayVjKB_en&RMVH?N?q%A zuUk!oMJ!2VB=NZ4l}TqD{vlBz`j^%91QeI33EyvcM$&(}gS&a$#=WU5mKdCI8efZA zahL^%VJ$gMOq^tip+WHnMOv+g46|cY;#g(i-GOYrA|=OFCE*{Tl*by@N%)TNC~%>a zobnI<2}8c2dx0zWJ)hRY9=C2ggEkln2TIAH=8G_tB+u$U5|0yy<1xe1|3f*R(&9#9 zVi^`K?BJRJ8|*K=r^uS2lhK*k_=d^P13z-u#8&KnkIXRbsL1MHFn_rD1B;tiSOJc< zw!dP7Rnm5vF!EJ0#feJR&e&PPi>V5?dF-%kK1`|PY|GA(H{wZQo7g6>gEF0YVtj&U Pcn%x4$hOG7PtWpiaw-{N literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Compare_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Compare_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..d636a959a07d2faf12ff86b12d88042c50345b83 GIT binary patch literal 1265 zcmaJ=T~pIQ6g>-V1EE+OnwFqN6wrdB^|K5VQEaV(Ak5(Cs1Fj_9SEe^PP5hFclhEP zFa801P^J(30B8IQ`cE8hl8&UK*oWQiz2}}iIrr|jU+rT6i&&2==77lJCxAgKiF(6q z^0)PtG^Hh+w>K5^GMwEt-1Pg8nN4g51?>Bfj z*@3?aF$6Xjr$V6)Mai`74NG!z!zjauZ}M2+ujLA7tjXP$E$7BqAI8Yn z+)|jXbE(I2NuyC1XBhg2@d_rXX$`Lvw&Rh66m=-P=3hZh#br#z9=uY17HhAwbjapM z4vyb<^{gyfTQ*ma_u5}B2kpP9;s$OpoC~t2e8C-!26Q}1N};^@uKS0%A3KK(XHL4j zBAjgnMUQ=XIbgr1VjeW4hL<~q`+$@``2C>}URdN!LA@4Dlt$;mwk5x-O^jnmiHTH6z`_rQj*U=>MS#R_RR!!-$KB z&|CC=J!Bg_O-V1EE+NnwFqd5YVEdRn#(2{D9U92{0J~;B~fpf zO}IlZxUDN;SBGA)2dHrdQ%PgM^Af3=xlLNd|q*ud_t{S<`alhHP@PUW`M- zaF>#eLs#;;0=*w;q$sr{gmh)oY^-y+D{3yomh)q*4`bwO zZY50DxzuC1sL?1)Fbx00cm-3`w1(FS+wn+3iaHct^DiT(;u5A~4_+xhi?!ETI%M;s zACBL4^{gyf+csB__u5}B2kpP9;s$0I&IZ|2zTmb-13D2UrBF7%>;7T>$L=SFGbdeM z6V8r;qQ}0v8nEA0u>cxU!^@q*{Xj#HXMi{V+m^#?Ve3j7dc9<%Zd&9(Iv4KK9}5`N z4bf^=dBw76_A`IKr0bqchWLu(@Mg(2U6<2%O`VAEnvw3|Qt+7J{Qsc}*6B?K!-#Q2 z=q-A`9{ixtkC;frSMkw}9V`Z)9;l$(-lJ`C%Gat#e zF$v5^jffHbf-5Opor|S#ZLV)5Hqv*5TLsmF4d`kc1;WLR0VD3?W@iUen43+c2h)io z+%F_OoTew+SR&l8p&7%3%j)WzLP}5R$u|YvL!@=RjfaHD7-=Izh(K&FmPuX@Rm7ex^w;ul25dM- literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Compare_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Compare_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..35ca348cd27dca7b97b062d3ea26d0294dd3ae6e GIT binary patch literal 1265 zcmaJ=T~pIQ6g>-V1EE+NnwFqd5YVEdRnam~{D9U92{0J~;B~fpf zO}IlZxUDN;SBGA)2dHrdQ%PgM^Af3=xlLNd|q*ud_t{S<`alhHP@PUW`M- zaF>#eLs#;;0=*w;q$sr{gmh)oY^-y+D{3yomh)q*4`bwO zZY50DxzuC1sL?1)Fbx00cm-3`w1(FS+wn+3iaHct^DiT(;u5A~4_+xhi?!ETI%M;s zACBL4^{gyf+csB__u5}B2kpP9;s$OpoDH(4e8Fvv26Q4yN}+6i*Zsr%kKIoUXHL4j zCY&7wMUQ=THDJH1VgWRyhL<~q`+$@``2C>}URdN!LA@4Dl7m;mwk5x-O^jnmQ5RH6z`_rQk8c`Ts)|tkateh7se4 z&|CC=J!Bg_O!gH!->fwB=3DjWRy4d`kc1;WLR0VD3?W@iUen43+c2h)io z+%F_OoTew+SR&l8p&7%3%j)WzLP}5R$u|YvL!@=RjfaHD7-=Izh(K&FmPuX@Rm7ex^w;ul474~& literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Compare_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Compare_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..5bc203cdda167d76ad41f8a55200fae61d24da08 GIT binary patch literal 1265 zcmaJ=T~pIQ6g>-V1EE+OnwFqd5YU37^#jX5@dH|`AgD7qI_iUjb_W7!w$p5J_#M9Z z#*2RdAC&0>KfoFPg8mc7o1`P@DE47@d+)htPtLvj?N|F4z#^VU7IQ#k@e{zHl|;Q^ zHu<}HOPbOW&bt`}y$ok}%sn%2o6c7L+2#(fN(E7d*n;I)@*YEPZt7(m3i?#U(9aMl zi5h1}oK#h8VNy|?L8%5;Fhp~e%G7ckXOK`ah_l2aT9QFu_3JE=f8Mklxh|XBtQX_Z zFw~`FeczS5u0Zcc8YxOG2_aqCG#hJNZi|}BFma;5a`wb7&l8*FY?XvlHD$%DO3~a` zU@&Cr<}MGyuPnJuCs&$|B#w`{K#%|R9hTsN$EH)WxjV5c#BQrm48ek1!jZ1R7yAt! zPIlmLLkxk<#i>xJLs2qqd)<DA*SXYVxunr3j57@V!*~Ug)U<}z3ES~VLW(*RUh}UYr{XfEVh>&`KZ~_DSvq9% zBL~OtyLwg@txcON$b0QCmxK1-RB;2h7|sRRQ@&tEqX8X{l2Rydzw7>C{>Szq!5l~r z>bht(tGr^_H2ayqU($6?CPRGLad@+2o36`gye3b?cg;xma4C4gaN++@1#9#sgJHxN zBJ>u$Uk}+vPm|UG`j@1g(H@=t3iZ&-qaPJK>ZA{-Y?xvnG*;Gn9*$2OA$jjJGV_sa z8xz2M)QA|-FPKi@>Rc>^Yjb_WvEjZW+%BjdY(Q7rC=f1g3>a}AH#<9+!rW{kJ(x}$ z;eH|M;WRzj#uDL%49yrKTvk^%3MoCMCpQYZhe+#s8xIMQG15kc5P{fUJSKTPSjGzN cD#>2OQ#^y=%N`;57b!O8uXp@)(O=8I0TTQ;O8@`> literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Compare_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Compare_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..c242ca2fc6daa6c5564a637ea6e180767e33c6e0 GIT binary patch literal 1294 zcmaJ=+iuf95Ix&moVY1zO`OC@0|i=0xrJ+bNx77i(3X~qia@{vxXG$Db-Yo$0rgLK zjq*$v>uOx5)Nfjd)B_7d{4EkCx&Jv}2ZOf4xvdztAB>@cw z2Qt~%btP{q(BnuWMXnn{NLRMa);gElqTw=3?q^^*FU1Zo5u4>~RfSVGWzDQh(cV>H zFl3tM4)@KEEV)f5SDKC_j@Ly$pI-HS7XN}}(`ne;om>-Qr_-tgVE!#Z%Ru0R-4+iz z`|zg$24CjNbimZ7sG7FDVM$JkQ4mMffzHg`L=oS$GZOpva{ zl^|XJQjg`RMx$_y;ox6{S1?6QYk8fp9gifCQJ=zV{s|OS9LIF@`eWrsrSYUdhe9d$ z=F6*ro-K*arp*c@7wPg4(xY% zO*mT$Djxgls?UB!#R6zZ4bS%v?&}(cJORA<-?SXw2ufGg5b~VirfHD^>0+=?za?N$ zH$lFoW*G9*?UhqtS?>AIZ8Yid9Fff*SbE(Nz44*eghV4dEiKa4nn zFug_Z8zR~0Y0^4Oe`B;W+9M}FL4EJ}5l0QT`tHvZRv_EE@IwA`bUk!cW3%DYg-rN< zs2n-1N6yVgwV_!h6U``l7%Rsos!l}986wb_zWQVgOd$?Fm zdbm+N*+rRfW5%d4*2B%rXerFiq|#bCwTElvw1>;+=`L;%E^B0rEaCK+o_t<5bVE-+ zFXuc+Ue9%LlOW?p-WVr{Ur7kdl=~1?uu8j1HLc+e?!rKp{&Q5@VX__Rt(SZ2VsBmg E1?5gWZU6uP literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Constants_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Constants_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..85548263c330e32ca61cdc991f87af8af1f39b80 GIT binary patch literal 1384 zcmaKs-BQ~|6vzLIKO_s|4+VcLC1AiLhLAXM+O7s25R6i*t>xeC!#+l7P`K4)tFQ~P<`*C*z}I@ zeYwC;+?K;bUyKESVft#Jx4ofql_!I@>jnx8h4=2c+w|Swr1|pjy*N?^Y=-n>FYwe8 zhD2lKRTk4IS-6EVL$V`}1<7)#7)tw>!Jce>M-?fmOSrvu792BUi4QIYO7slOW^fyy zG2FT)%)mT@ai;V50i|w)xi1R~H{8~hEMU<>4NH{&nUrdv`tI2aq29^k0Ym-6UcBI3 zo{DA|Nt-`%Ro6XIvVURV4nw8qo{CU@?WuQH-C_7CzHpQ!Twuoyj(stx?@M_)JZpbi zUrZSb{QlxhT!X)f@nP%RD={fb(Q$qMz*Bc*yMuus z*DQbHn(NNnz_$!@|Bo7YPOnbr4{~aeUKxE&Q2q1<(Y;DfMH(56sny?6`9;qogKy|_ z5l;V&6z-7r*Tj=VE17Ji3O}^ccB*Ckin)Dz;>EqS-%zLjj(NM3ETu~6k}<+M;AFVT zGc-53nayraX~MD-&Lp?^WE7FBWGho6vCNw(g$Uko^v#_M%shR`{(}xBHLE0 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Constants_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Constants_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..6765c583dbd9d794bed205ac75ac85a8bb4759f2 GIT binary patch literal 1461 zcmaJ>*>V#{6g_P%GaAcU25V{KMP48>I4B{BY)ix}GQu`8NtILZzymedU1soT+9kE9 z@>AaO4SCEjz(Ydmfe*+}X64S_8xPm-Gv>}fK!Lp|qa;<@}D=R-!MvC$hPP?82$IO`HgR`y@Z3D9j%;74- zl?%)aEHD_S+K=ax>+;a|AhDs~y3S+~OBPC4CZz)|-PuSQgIV6yk0xHjbqiU1MTtC+ zQgv0wIo%iPl|1S)tb7vf`fucks0>4pt3yXMokJx%X9jLC6xz;-7{bq7^(qwW_i%=R zmtlY%$3OB!ccmreN$<3NUPuTTGyLW3R9rxR9^wycR9_82fs2OYc?Yf%bpLDk+QLoT zO2<*5lCiZCGx04$zT9kvErWa22H)A#vfpdU_Vy)|s-~=K%HG~3lub>cR^ABTO%NrN zae!Rnza$|ZD5yS{>xMYk7>q+{Xs3ArPz*p0tXc&pEmz+K!6j{ijrD}?`4qva%}jdJ)`uzE zsHJ&|rvvhIF;ler*dTI_PxBnXiS?qjKBLKbo7D=Y!Q8#FY#r9KMJRL4uoGP;RXpG1dPpGoh6ZdJS3Yq lkMa1(CW0ohCh!P5v|41nhZgqf@3cz$6rFrS*zLjh!T*p0V|xGq literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Constants_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Constants_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..ac8f8b8013e4d81c959fa5080e3003146709fe5f GIT binary patch literal 1703 zcmaJ?TT|j#5bk3F35WvG103%cRMZT3JxEYj2SiaER2-el!&F974kIQO#HsRW-u5@_ zgcDcx3R(&@F>c0P^F{ zGW5vMD}$eazhIeHV;Re=*}7@hGy+QAw2dpH+7S%oDwb|{gn}izTK*5#y=PP^);NJ+ z*1G#xF**Q1p#QPZhnqWFx679KVOfFzfxu_|i=L?H=2fEj@w0JZOP~;Nub0iTy-7fb z&7S$7AE+1lAVfgSSeFKdtvj0lEi}MoD{+J!+1Qt%-=uxOV4#DzbYHWL8wrLyFbsnP z`ksJEFiJqWb$BW!QpcLyjmDZAPCK29!-N;cU=sOXT9#e2tNQJsVSlnNYXqX-_EI*# zSl33PiNwuc=yp!Ou&wI71k(hB z>F@h%i*x`_?{AGK(%-k`H%FhIZ40$1GJ2&_D%%E*H3qX@n1MOJ8|Df05OwU^Plgu+ zSS;^c?JTX)IpBnXs$9TV=%8d+A`pt@a?d2MD5#oMCncMGCMD^ltT`$B`_H6kPD;8{ z3k~r~uz}e2QMVdx8$c`a4D}BV^%m~tMlYjYLb3L7{tG=L;4N8q)e9q6uApq$@jx|IgZd5PL2|Ax>>tk+-XrJ* z@k#LMn)@BXzc}mQftQeJE_X%21@93Pk=F+wyobVO7Z=rGDi%fV61ZEXF6u72xFm8} zr4p5kZte+u-^eeoASGhH0b@ivZdHV{8ByU3`!ZKDf0Zfe&}D zjj$m)93D9q`KWJg44u*N*s;LJ(HdV^n-cj1S`!Ov(+=mPB4|-I$)c?qGvTT5bR9Ud z$Jh*uHP~nA?1QAu34FdcrLs9XA5l+49`~mb=)@z56M-+HwYZpC75NfcON*(b!@jIY z+6r4{D=qd^WHpkkLkih7mSS3iJx$XO-P*dqH$2HrwoW%fn@1ww@+P;@*$QnR2|R;V zCXw6~c^0i~BAIvCcNC)K*bd9J*bhRxp?n?Ik-fkUSfRmwNDu#jP3@Jyi;7!2Vy|eC z9hF3WtjO94ddKXfB=8bir6uiLhUV%l`oI2$B~7 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Constants_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Constants_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..c5b19997a3c9000a57c32f6402f0667ca3823e4c GIT binary patch literal 1384 zcmaKs-BQ~|6vzLIKO_s|4+VcLC1AiLCLwXsrUvAEn>xUdNoVLJ7rDqNutOANEn}}U z!&UG44880tv={A+FY*9+nLa>gIz5XNA_u6(qqY9~J7>?H{Y#(z9eo7w1Un`&CM*+^ zCb9{zUw$(&Wg=%H&ye4h!C|c(|3cz=8L!Q#lA9NGogRA(4 z;mQSJ2Id)zW1YtjD0L&ueOg$!;kK@10gD!DSfcz-rBnmecaNV7^-dlP80ug4;sqb% zk!XgIwE2Bkb=`d>`zHpjF;sf)kqG5io_crI9fn`y3rAVP1-9Jaz!!u1u9Qc^ z2Ei3x<`t4NYctl`tcI&Lb2zVZ9>H_vneyxi_X(cob9|m;JMApmrn98+nw@kOc#SVa yc%3iur4b$xzRc@M7+5E1gQ40+5~NYyryBjp3+LsdP)ZpqR>N2?vpe}3mOXU=^3d-M^&J^Z92rNhuMt|J`- zd;M0&gpQ1kEJL;<{KIln_ycMCa$qr-ZC^TvPXC;kYk9(!=cN3;?7RQ5P3}6LCl(m; zJ7W0UbIuunVd^Z1zN4&d0mMjB;M%8?BAPX^NIX;@03f<=bO3(PdEQ2b-%$MeZ`HSm3Uf}k=Dm2wqp z23B#6{BH{(2eNM;KXl{^aWG)0d_J`6zY<4IEwH32b#2+QyHfN|G~8gA?%799AphdZ z7iVQ;coPjAdIQs|;-d)~e) z9V%-LUm3WGud_*f!!W_Fmp^|xzGL9kwi;0{Vd<1{-K6&2pu1L9I<^>!)mG~gxM5Oz z-B!rX&LzlQg?z7&y}e72dkWcR*o+o6Oeu2IP`Sj(j&kxN<=wMg>WpGFTDX5rpE4Nx zV%YCGE!U$?=4V$Lc^NlVe=wxmzVGy#s?iW=3=3+IvjDQ~OBaK6Zm`mPdk`94s+bPsHlUcwNi=R@XmZrnCMY zvu5JX`rMzmy8Z{Q)>FS@`H?wh#c%NVUs$J=WfT&HWI-$Fh13X}fHlqyK2DqCo0;@x zRv~FKW=-%kp9oEI)0ye)2zLn1^Bm8UoY|VnZWR@5nwmAqO+FdIrP5TXIKmGEb6(<{ zcOj+*;y`d@00Nc!e*I r&?0=5ukclpgYv}CrXr1D4-aTIs8A2_7*D`)oz@xJ`IfX>r+@1oM8;xB literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ForLoop_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ForLoop_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..d9867f2e095e357e026c9d7cadc3926cbf541614 GIT binary patch literal 1445 zcmah}-EJF26#gb&@7RvxzjzX_?Ks<#A}2shC|R(R29=-Da+ z9#`@c@CsZPq+A0MND=A-@C4k!D{#kE&Dph49W{ZKc4p7deCM3+oY~)AU%Ucv7Y7W5 zBR{z3`-8{*k&?>sy~jHoj3M`2zK{)9dQTfCXV2}9;)pTm`;O-*Iu@&MK1?GHJp~P% zK|A!jHmUuQVi5PD!;athDsVj2R)H=1dugPwcnP>Y9xA)fv6MsxX)=B8`)a5HIk<1D zXMT6cu<<4h$9v)T>;|DZ-qSqvDZJIW8n9C?P-zUxF)Z~9NnCr&U_=C0|D`e$}9Y?&;9646>eo=2O-3_;2TYG;LE`3l}S z))@F8Y=rBDAae=LAi`Fz!%U%u8w{mc7BUFr*tA`{ZxfAC67LkiP|-j8o5In^DtuGxad8K{@+~z}uRNEf~9s9@$ombz!2-_i@4C!Of zvx7rd4u>|4)2+8g@~UCtXfo9P+m&OFuGDn+aDz(MB3c)SSh`uXCP~iI&S;Ns{er{~ zkwX$6V|Qw1-_s$Jw1317V*80ZmFi1m)+(n5743BYeDc?i$hNe#3siwt+|Z2p&$y{u zy3l`3wRp@*XjanTA|a9|nw5%MizKAP;z`^}>(&wpX|Z$?vvM&jWAIm2R%Ar>CCX&T zY+HGe6ZumsCov#eP~-4dcG#CO;b#c!G`MZDWA zl~zinUb9*%m#V#HSriGScs}_(M5&d^7kHmg){UC6PAFmF47X|h3Hobj#L0xH(Kxml z{jD&;F$zQN7+i1Eu&tjNS>hQ2Af?uy2uj3>JMY e;1hgGdx|n@VIOy3AV+eMd{#+kMC(ShZvF%1>qkET literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ForLoop_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ForLoop_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..1da3c50e6b73641feefafb5e0c75fa4e363607df GIT binary patch literal 1445 zcmah}-EJF26#gb&@7RvxzjzX_?Ks;uMNWX2wq(Ih8U#TRky-`GRk`RzGqJbr*6Uqs zJ+9;@;1#$oNVx_ikRsFv;0d^cSKyATnzL)8I%+~!+L=8+^PO|Pb7p^kef|o-=h$Z` z9QwgM-yb~gkCar7?>)ZF!5DJS$CKaJ(0O&u$Q!<2^m_y^d6evZMT9%#mkU?aQ7$Re$5CXY@5x(o=--U45EQ zRLl%z8sIDGbzOV7K?L+hgWWl|X_R@*g@X^q1AE>$bAL34FlB9bb51pbIFPQ}c9czw zETfo00V1nog~4c#`lkQHeBuN{W$u{XsDEk)!-SC2^wwhKl~#KNOB025PY1 z9d*>3tnd7nwb>uJ${Dzh-8E0g=B@3W2%;XQ@Z}YCY!$G8_o*-aW9&@L><2nzlJ?Koerzvsw^DtH%v$ASzoMP&olXA!3E7smc8)60iW`~{{{`1| zOBecYsTPk}3C&6xTqH#DShG@bYmtPMSUiqfY28{PAuX1UV^%I^Weonx%8HE0zC@V} znQbdCaw30XyDqWEodrHJ>M zrP4~N)N58t05-Da+ z9#`@c@CsZPq+A0MND=A-@C4k!D{#kE&Dph49W{ZKc4p7deCM3+oY~)AU%Ucv7Y7W5 zBR{z3`-8{*k&?>sy~jHoj3M`2zK{)9dQTfCXV2}9;)pTm`;O-*Iu@&MK1?GHJp~P% zK|A!jHmUuQVi5PD!;athDsVj2R)H=1dugPwcnP>Y9xA)fv6MsxX)=B8`)a5HIk<1D zXMT6cu<<4h$9v)T>;|DZ-qSqvDZJIW8n9C?P-zUxF)Z~9NnCr&U_=C0|D`e$}9Y?&;9646>eo=2O-3_;2TYG;LE`3l}S z))@F8Y=rBDAae=LAi`Fz!%U%u8w{mc7BUFr*tA`{ZxfAC67LkiP|-j8o5Ing-rnAgAnIWXUtCkiRsjomkLs8wa+V~=2bYH@ngfmo z!@{Fuj@t}NZ6!Os`*QF=p1CxQT3ySf*&%W?8d}x+O$Wi0`l=ir+L>ig>qK zDy@`Cy=JvkE>(NYvM3Tt@qF@oh*B$+FYrF0tQ$3BolwHU8Fpy>3Hobj#L0xH(Kxml z{jD&;F$zQN7+i1Eu&tjNS>hQ2Af?uy2uj3>JMY e;1hgGdx|n@VIOy3AV+eMd{#+kMC(ShZvF%H^+!Vh literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ForLoop_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ForLoop_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..645ef2e61414ed40881246e37eed036ac60b9cd1 GIT binary patch literal 1578 zcmb7DL2nvI6#j-?b^&8!g9lh+ndGGt)`{vEBf1kew@C80+ zNFI3p1JCO`Y4@Zh9nXDoTL)v9ePO+{Hd~haZ1ec^g@3^uiecNj9#1X^PCE!}WEA6(9=_qCpr=u@DPj;nm zb&hQL+-r0hR^O)KxG%k?y-8?}`)uEH>y|vQ>eBQ3I_4NMZL4XI%-=flIsJ8|}(^Iy)0?BbG_arND>%jy-uec7Hs9Fj8%&G+`P;>|3o? z&5<@KlEQopN$`Y*G=ov=wN3A-`PA{d(%d%PUi;McyH%4#kR@5y4kyvZoB_x}lCCqy zkh(&59ZL*)C%A}~8-PqCG=>PSG7mF`WfT~)<18%SxB8~tvfDPvI80(C35J|@_b;NO z!9W-6HF|aVHtSn&vNqejmUKET$8MOXeRFGLdkC=>q;T&)>L@1>!cD4UQpj9s3hOOF_0HLvH_?E@!p z&b<2|HUe20;)kwl`}-}c+qJ2!itn`MRZXR1hhh2st~x%Wr!{Iq6i5PfC~t@arWZzY zl=gG9GFrpsUl93m=n#d#ozZcqKtVU@N|w~!+(qn2*;9nNzQomIMTFORctb=Kp+$tw zHLkxxibuG1B4|=igmyOg<0mAlQ64$RB2bMPQ6u&85!@YI|DfBy6t|fYMA1;_8=#Eh o{|p{R2f+$Hr8$HOs`*}Lgkj)s*tHZhU58<#<-2eap literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ForLoop_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ForLoop_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..05322a2ddb68d78c719d7569cb07a68c8a64436c GIT binary patch literal 1445 zcmah}-EJF26#gb&@7RvxzjzX_?Ks<#A}2shDOs?S29=6pFX!ciX+CL?>U~M=vb`2`7n(*^b|C3 z2JOJ_+NAbJib33q4m*D1>%j3;TLrf4@1~K$;sxOLc&O|?$5Ij*q{;N9@2jB-?l7NbL1IT`?6VbhnYeR*BDB(EMySKv1z+@-zFNPB;G54p`w5B4~3(Lfg0?0 zM;-Mh>s$Y2ZT3g5at5wrcg@qWd2@Rwf~bcne04<~TLmoO1FB=5$XSvcA6*=tXbw0U z3=5BrIBqg5wUzAj?#sagdFs+MYJKTY$t(3s;5HvJq}u){=-7u&=)C&&Mc5AMWJn)* zo*f*xayYbUoNl}|l9vq=N0XuU|E?Unbfu=lhig>27SXyu#L~^8HA!-wc1C-A>sKUx zj2x2q6gyKh`+*Lbr2R9tAKOdZu2f$lvsO9TuV^QGXOq8wLbj!?oudl0;)Z6#f5CO# z(uMw8s>NegLbH+v7YUI()~rXr~iA->0kD1O^qDdPQR zskBlm^_taExm4{n%c4jq#k0vDAxf=OKF5cIvToFjbwUXXXShY{&(L2(BTgnnjmELf z=x>Dyj!>8i95s%Q8OJAN37?3*39ci5g~Jq}jOx|)87RdEV)Rb1g~~hK!@foCFwOF5v?21y7?~#4o61- literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/IfZero_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/IfZero_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..f8a58128708895c9a3f7b0d6ab9f0a2b6ff3c43f GIT binary patch literal 841 zcmZuu-A)rh6#i!aW_Kyj7Phr5X#J&y1;Wiqq}P)5A_X==aaTsp^YOqHcEv!WUs2ZLe@}hUA|A z%3p5#QER!rvllc4hs9u2!YCB$3~H&ok-!)dHf)SDX!qmi0rkVa6r*#gTHZ_`iIfc! zX(Ge}!Qea`%7*ds<6anvhM=6CwFIW&oU?4a?u($qk+pCI8JhJH8b_Xicco4{BI(kp z_AoLDhf!-yW}LySjRLMRj5mbe+^_lFC;m>G!cI2hPS@`RPeZYLmYOKnaYLrQNxoYb zMLBLWC|gyIIhwQMhh&~9U2?I!!C*JyL9ZD+2&G}>!c#BFxya9?SCplJ$w#Gil1?ew z8SVP~H%xq%eONNwsJ#b;h`_!4A*Lz?^&Qe*kgKKHBX{vDt{q?@uYN>^uvIOstm-)} zrw{Qd2^nd1mFJ8cCrD~D6lu*sJw}dYPbh%Nr1@!C@>h<0=g3zfcp|U9hpAN#psSU_ zCqhm&I28LBM7B`I{D|}xD$NDdj7s5$T~pVSwx_wXj#k$^UG)st(H*0%dp!BaGhK%} zX5BsVY}KpIqwH|C5T;+A7+&phkkPLTDZ&DM HDRBP*Yhk7y literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/IfZero_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/IfZero_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..268718f33e69c860b7b223fd5f0d8839dc78d324 GIT binary patch literal 751 zcmZuu-EI;=7(K)O%1g z#>fkYjqc8#KM))`gSruff!Jh_sD}-Jy;Y6QR7h@grX-X z&A6387P%9`z1LIWk2&%>3NWdoGs-xM41AL4j6#yG{?lFrBjF$%wvr_0Q8rLQg<+{D zyup6Qn>_Y*Migmz5RE5Z>^}*_Zqg`at+tbrHC!;D;Uf8NpBCjTe8$QFY8B}N3WPm0Q%(6+Sze%d0-A~`HPy0GRtZW(8CGdG zAr-7S+0qLiFCABL?a1scWy=uJQ8!k;8y#sgYq+wrX31UIRU}t+EX7j0ip#UVUCpt$ zrFES{*N|M@(k_Xiwu9ELJ_Xh HR|?g?eczi# literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/IfZero_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/IfZero_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..33fef9f524144674cb4d13b4db6250156bb6e503 GIT binary patch literal 698 zcmZuu+iDX*82)AtncYol4(%lNq+44x)iptcy|ASqiV$dw5UF4<+G$+VZIj)&oe1j7 zh&R2~3l)(*fKTExC>Z}uBO>iw%;Ee0?=Umpe}6pza1Yll=oSoy=|eX>a)Xyc*>hFw zz6p}J#!wlf-6W7INL;lqqra76vrcTz{N|k!mZl?XTr<0r~%g+pmvQ z(B~-HD4{^n&!KV5Fz`XD(~C&Dda6ARM#5p#T}zXcQE?z}kzuN>WaqFc2T$Z)k0Rwe zaep9_;AyD#(~DBpY9po0W5GcNi{!g~R+Qs1gSOq^SRzJWhGbr@p3}Ix#o)B#VbTd6 zhN)rs%!Ag_dtr&pEcz=z2TPxh<|#TAX=SvUH$EfxA+1x9!cEE#pur?;c}{AqGfsalA literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/IfZero_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/IfZero_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..ac78b0684e799311da399d0b84972402bb4c2758 GIT binary patch literal 882 zcmaJ;+fEZv6kVrt>kPe4=d=!>4tQ%pATj1V6f`j=CL}^hYA~@6IMfja+8J!8Ci)$I zfH5XK>w_ADe1KozkN9L_-KT(tK%9qt&aAcf+H3Fg{rA^H0QWGPhMIN92PLo7<=Q$!s=jDKyqHY#FC!m1I9a7BGUy)8m zr#AB$xet zN?ms~S0_k{GE7pmp*VaC`#PsrFWPn)V@{cif~-coq18_1g z#>fkYjqc8#KM))`gSruff!Jh_sD}-Jy;Y6QR7h@grX-X z&A6387P%9`z1LIWk2&%>3NWdoGs-xM41AL4j6#yG{?lFrBjF$%wvr_0Q8rLQg<+{D zyup6Qn>_Y*Migmz5RE5Z>^}*_Zqg`at+tbrHC!;D;Uf8NpBCjTe8$QFY8B}N3WPm0Q%(6+Sze%d0-A~`HPy0GRtZW(8CGdG zAr-7S+0qLiFCABL?a1scWy=uJQ8!k;8y#sgYq+wrX31UIRU}t+EX7j0ip#UVUCpt$ zrFES{*N|M@(k_Xiwu9ELJ_Xh HR|?g?i1?dK literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/If_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/If_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..f87eff59ce5fdeb6c42a27b66d204b60094ab1ec GIT binary patch literal 1366 zcmbVMU2hvj6g}gQ?0RFz&e-c@;y9Un0C5O*6IvHG9|({tDp3U~C=c|ZnmCihWxZRx z>!|%Tl`2%8=|d~Eh#$ajqJ%rURgps~Rb6>!_TF>uz2}|>|MkzyKLLD=uWXcTOxY;g zsMwgc!EID+)NHsm>NaL<%rdM;@o-b_?n=71Jo!x+pUI&<(L){dbR^YK%lJ&oNDVYY z^+@(3c{h!0|NauXmOwhkGbgK#wL>05n6 z=3}O}&F)yj9QkRU44AQ(&LxVb>1K52*Iz*XZg3Q^jhz(E>>`U*fVFcwjX#__*}aO> z&22Q@+ryN z8d}wm3}p~fraM?nnMyFr*F2JSy^zb7ec|w6PQx^XBNPz)<$>(j?nb~j#m*lGd`CEa z@-g~KNr!%4a^bG=U4_<#6HqGkKst`6p&nUPeKve4Lh1i@oPW5!((8vJv^{raPDhoj zZiyYyc7(gpe!RLRyP=M{hV)I_wZq#Q5{>3^4h$!<7{y5%@Se9utrA|J#;h(zWZP>$ zA;)1Sq;|c99M0hEfN*Cw2xU*lSO(|7HI$E`>A0Xl-&Q(~OVW*4J2FPXw2%em&2+d^;*^bxuyYjxRip_y#Ppg?Rh8pcrJwwpcTIoDZs6@9$cWPoEr{1eP zGPsKQIIX>-az*m}}EX%Mg1jtH=thxQ{7?ON32U zVkTh+lJDhZzS{QQ_F4!-R<6B3T^J|6lp%`j{7=^c4U12`=0=A;f{`ij-rk+9j1yJD?+E^ zGVpI)kD{(<1^$s2d4VsyP(Ow{gA|zuJ5TRUy*BQr_KSv{Zp>Ke2Pr$#urf`1xLCF|YuM6Wp!6Ho zq;6(pmg_wG5}Rq;u#DG+97)-^V!_Vy5i4iqsdbcgqfNU&eTAP;QGG=-C&ze^k5S(* z36*J%$`UtuiBbyrB0-kTw6u7cTQPFo(%x}Y%# zp_8UAr}!kF>NiZA!*YgC^BGD3O4+PABIo!lpQDVKmx8|YT=4my6O{`llZ$+TFH-pr zY|AB6lgoUGFTcWd6|Ydd%2)U*#gtxoi7)M{RZabvNT`{Htn(VL_a&^ES=r!gyg@1T zNEr6%7GmTA*I{VbVH)I-uRA#HZ&8Zlz87CQ-31rn9FPM_$w?ih|xcYdS!0^4P(wR A;s5{u literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/If_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/If_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..77dc68cf0b3f85ffcb80ba07ba07db1a6c366dbd GIT binary patch literal 1165 zcmbVLO;6NN6g_1=+8Jh;na&r_&xeW*3^0I*TEs+6j3%HaV_4{dJcb7pJ1w>yBEQC+ z?o4z6i6(AM-1~DB?`w@R!ot|3@8#Tk&$;K`reA-2{0!g@ZW|XEZU%fy?EZ1UcZJg< zAH%Pdbm;da7w$UWQ)ojt0i{w8q~mxR>XB8|XVaG=l>TqW`G*^;-Cig{+jCdvbX3Xe zw%8RdN4T4<$7|cN6Y8jINZ+zuJG`wS(HL9Ff#FmZ!#GU?-t*R}Rl@7hnAN3-Y0LGhVltC9hWrdJ4(lKNxBhhN5)8)7P6q6T*j3w zM$zckkMcUkl~c+$F+n55YyC?qo^fI9Sq@WZsnTik^Za--9rShb?ND@HEQ_6|V$Gqk zlU-qxxmx1{!q|$2Y}@Pk9eLkY#b)2Kr_{_CL5=pPo&jiTt#qCxRH9p>J2ifQGw)R% z8C=7BoYvk^xuSgmKH%b#nOJU4>|;!UM`qSaPO>CHLRQKgu+l8W(uCh4p+dTuvJ9p( zBMwCpR>m}}EX%Mg1+^Kl?g%u1y=l+O?BrC2`I<&w0-CoU1s0{PpYa0Pf&GM@mOp$FL4l zM@Gkp4yGfkV^qhO4z6Qd$Apea1%)7Nm94!!i|!T2y4wuTt(JG{wLHJ(1(w_Ltnl2k z0{6mGz`ykB6t%2c(?6+)^`>vt11oH`sg^mG-_Kf}8xkNqcYUj-AnnR*!wU%Zfz+{r zk(xyL&F}`2(uvRuLgI+39S+$Ll&zB{>61O)cWt*}1r-H0rK2dI@Y)Rds{3bwb?#nv ztXP+BLy8{z{;dJa^-rwlGCFk|f%Fq8zwM{@zSn3p6^uqzIsG*2lvHJ5*s#4P3vSePf<2h9@_pf=lNo_!HD z*PErU$VYe-(ttOMrZw$I zB{oV1R_Z$NwCr!BNoj_<@F91%pSS zTl@B*`|NA?xIy+47jB(IW^?ap%s*0K95vgmns=`*!DiReZRwq4PSZZ+)dNMYmp&IM z8m7BK_uj&5Ec_zt=*MUHJT9w$Ld76cm>vhO2|msz zqUKFiOcG|&7E?@PQ`ZBgP1Tv<(|o2gz%qNBS#I&!Xuw>N&Dmm}%}Z0nu|OOPwpe6~ zG7*VfGIeK}FY)CLN6zeX@;t}$lmeuaf;r%<@B&|AlK}eD$Z;m2E0ciQBwH z<=?RGteKiq=4-tC8dVurC|>6kzD_ZvE3dFEHrR&xLoA_c8jj#qE;36z!j=6H0&rE_7r)^bH2g>%+YyFtXPVtU$z6b+jIgN6i>4%o4x35cqmJ67k0f{x-%C4z^i|T}2cv?s;8l1WjZO z1sAKhHlM+DYT;b8;(M!Fabk676xj?mXsG3OoGZ#`DQ+y1>P3d7OQ!DN7K1agGI+|8 z#L9^%tga<&xwwrxr0bAN0T1D~_IvMBk`{G9$*IrEYsO0U#D;L7k9AlSpWb4 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceField_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceField_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..235c28f9582018f3ef410b58bb8ccfbcf6e3afea GIT binary patch literal 931 zcmaJkA3oC80wY1nTsn7 zh~Wl<(NY6K8>M!Dn77EkKoM%98J0WexolN?p7n0bZFI)&%_~!YAW?Q!WCxpDYh4B0`4#@UDI_F zMFw;1%iu_#yMa2`fpqm{O`o=`K2&q z+ENO)<#5jvB*e}YF|U)sM2%td|4-1$d1uz zRZeNGeM9CmSwI>UR6|Ui5PszD55zjz%CqYFDY9RXYZ%q9$n0;N;V#ff`hvQKd*Q2=Kufz literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceField_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceField_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..a12468fe720c996c34f27fb0996a93b380f16e8b GIT binary patch literal 981 zcmaJ0NUioZ zY%qqYLw?L_E?4`tHy;m0*VsrhOvtFG!`-1^U@eC9bE%}+Vn~+Coh)pOIk1pnu$sCj zvPdDFK>}HZaqjzaUq!uEsa5Vcl*wdq1CxO_O(1$`7-n}z^`tUw;|bnxWHE!A zmsV?^_(t??%w;f-SxUXq+W5xfgV(|w=$_9|{QD58j`fkK5t>x{O|81zZ1b+s-ieJ{ z4D)?{B*O4}X%5H>?qdk!b1B?sbdCrm9I(Sx&lP@gSL>tUpb;wzr^F+d8sD7^L_8Ul ze~2N3cW;zqp$MYMUAHZbpo=Uc?_dcllWE+hCtPq^_!N*@I1Xs47uXn9>8Nz@7*;ef zfVi6@Q4|?wuDQC6dkppdmQuoNx}+RIM66vQ^Ew)AJZ4z=f2oZPl5R*FR!Msnoq&-gxssP8 zpOj4hQ?m|CbshDSOe;*MQbs2ifV|F#5#2)P{Sj#4xv54Q#`{W{V-atK(RZ2 E0DNxuzyJUM literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceField_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceField_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..e8d2c8e8a63444eca0d0ebed87ac1f934288b09b GIT binary patch literal 1011 zcmaJNt zL!)9a@dx;$jCZ<=E{di}=kDBl&pmU``TpbN8-PbxXP9d$-*D9tTT*!4o!-!JBemLD zbHEsK`}~mCJg#0^aGgB0&n0!wE7wBt(PDW?4at!x91%PWk8>T0zEk<{#%KRsc2l+H^;#Qbnr>q67 zd_}BPJw`59d01Weg2@k<+elPDVtli3f)!vRnNQ@CpHU4k;#j4w7;3mZn#gb$Yq*a* M{V*a|qzPAl0<&8KkpKVy literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceField_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceField_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..8a467845b664aa37d79654b248b215e9b9c90362 GIT binary patch literal 1029 zcmaJ=?M@Rx6g^YgE?tX!e^ddBg7ibEsHkbhM4AwrR57W+AO0X?JCvc@nPzuN!khRS z8Wn?y58y)?@3M<5Lj18icW2H$bMHN8fBioB3E%~uGR)MJXSiyLEh(JVZntl^ky`Dp zTVM<$2mFwi9Io1>?GFc{X)Fvd49PHOhdX`2FkU~0)szu!;Z_)u&!m#(Im19MzmtZA zK^t+T7~)mk5;kIfJbEe9!VrUX=reEcF-+xZ`77wt7{-W=>ljTVfnj zUh2{tS1QvmuHfBD8k3m1&{5;aGoou@CWQ>9>1b1H;~AItUJ0|WTOPyWd3jPD>W(N8 zn^f(pR!wfUc++V2$ighcbeDHTu>DS&eTw|C8shkvi_{;o1Q)#Is^ti8v95Ke->XDm z!7b693yE)!dLnul!rw<20=X*D*@YBU?l=u;1WjZfw`|NIJDkJX*Wht|=wls>3}`kTgq|cwNE zM+zIW-!b;OxbhVfpK+s{D1O02Ii881U>PVUGl@*{8&(3U0o7MVK?|kRXnP0zqKLEVIP8u?o*KRH_6!x8t z;!Z;xo*uWliYrSx$D11B4C5F4ikEEeoRtnwE<{6VNHV0hEXPti4DsUfyDT)Mb)=AC zNYrFg44kSf*K*D@WQi=hijp1pl9nvJAw&@_c&nPlD8>d4UU!seX_&|$k8y%tN~t=^ zYW|L==KvR+l58P@=|dyKX5#9ht^W z9aAvIQkY?wmnRpd)iJqaTH$q>^3)8(D<(^0mYQ39AJq&qds1_G8i09*$syg>KtrIl zz3Z?YPb6Y1l<=LE0&Xm zWDl!^XhzD=LMTH}s+=yQd)OdIH!_AELRo?ylt&69Jv<^PXJm~WL4k`n%9J;Tr+7xY cPJSxb!Zr-tpzj$f=N83o`|FCouKVl5KeBW*l>h($ literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceOf_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceOf_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..14932e7e13804c476974f47cf2d63a9334aa6585 GIT binary patch literal 1277 zcmaJ>TTc@~6#j-@rY(hDpx`1x(V_)}3To9BZ!{s2fSA;1q7P&!11z+=b$3eACx3u{ zz`r36n)Jb>ul^|G*-K=bR3CO`_ndFO^PS7=uiw3&0A8ZTklQhAC5(pLKR#%6lu){9 z9BgnfhV+@Z5T&LtPD=ZSXR@Iko8UnLetSSG7NJ=UO@Zd{n>vP5DDUo(w{P}`!ROsmVG zF-*6_x%ABMb#+Q_PURGFd@Tk9`z&67SHd`IO1rRYn&+K%H30LX1T6yx-*($F==9+q z0}NhMs!IWrPf-)iW?fg3s&*Z-3C!R|DvCLVc`9#SxAVft>we$!=5gL5ujE+_dFoy9 zLy*&t>`>jz(%9T$m>AMrjztFEcDmg(9Fl-6pTe1!J18b_8%qpRSB0;g3ac(ZbtKIp z#|p#ZaGgP%t9CUD<_P*nUS5S<W-o0iL^NGGvtQ{^dT<8!z@A$L%1b$ zN^q(e?8V;<84`7~V>RTq-lW?wGjv|p91#r39m9~8JGhdji2FlK>0gN)7>dDZ;-FhN z_kSqI3%au2^kIQY5T*`-cIMn%TI2MUp`FnlS^k08H^)!r$9UqqzYsh_w$GPHy}qQY zz0$|@)7c&hKqb7Yg}-B&Toq2fN<@qFakm`JMSCcbKc;al<^x6@KwOLW5iTcki5@lx zkkm%Cqz_0rfH7^Xj|b)P+;|U<2$0rNTABc!un;OFWdv1h((W{MlJ=+cJf|Pp7BpO= T_ZiA_p5!mM>zcc+yKDImk%LRA literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceOf_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceOf_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..2edb43edd04c753dd5002601ce0c7bba621eaba5 GIT binary patch literal 1268 zcmaJ=Z%@-e9Da^<>sB^_;lLt7QP2UxRCMYFDlQTi5lluj(HG+gB)`Te~gKRe$5tYe)aSG7IK?Yh`L*ln~Vm!@OyuBc!P z!^ixT7c6cc7Pj|}MO~_hF(j*7wVm~?$}@)S=HHAmLt@pmP5Fo+mY;u}hKi&H1*tUR zNTe`;K?bGb>eWC&}q_RLo(FBZN)Tlj?ZM>6#Bc5s^@O;71s2&D;HDGufaJ17#A(bIZ{pdgGG9+Kk$lu)K!qkz`%7*8m%ar&R2 RYflqF6g@*9+b%7SLct=!qM$9W`oO9!_@D`ah+bLPywclzsh_XmJiD913wklYoPC0C6j*|cg44Cy_) zrMO)c2dBsNw&Kc^_VI>>5X0C7zv6j|+h_TMlM7K*8X^oM^$u-NX0@f7rhUec+VAly zZmg7mhFBb7#2Lb6SrZJg&8lVErh3j0%H|FkqMPn#0wYN3h+>og*;eGp(=%oM9UY)Z zQt&!Sjw99QsX{(PUBhG?X-xD(t_=;-6y26mkyYM!BhCgw(?m}i)mCl`jbS!9@SbJkxI4R;x|hEpWVc0>ZUe2Ls)0$JpA+`}@%R4?)6 zbKb0oPi;Y+r(u<0X|T^A&vm<=0#)#z_wq92G9RQcESM(5|qp&GD(6w8zGeF;2~^c fi)Nh+y`cZLZDi;N%+SpZirsd{ygNR0$0vUPJ>*FJ literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceOf_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InstanceOf_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..64111a13c405270df37ac065b9ba11eb57e1df3d GIT binary patch literal 1218 zcmaJ=T~8B16g|_gZA(kr#exeWi-H!cR8gw7NTN*$BoIt$B+&=5v;!<`cj|UZ!hi4w z@Hg~9lO~$@>W?zs{fONr)qR-Rx#!Ng=YGtu--90jUSTVV2t#&Rkk~YBQ*JRtODpd(P>@U` zffPfmA=;eGqA!Vd&%11j${WYDWm7ub=+raFAUi_byy{8bQIJa^kI7L;(#=x^Dp_9( zA$!s>y8B$7iFS`+X(-OLFU19~Pz>^K2)kv-ZKEZHbETljFw-$ExNkl*Zmi3j8DWGT=men*R zr#j8xW*XDbatX{bEQsTC-R$Xxt(!r+baA5l+BSC@meK2Rnxf^Qw2@I5ogoD;7;gXHRY9HJmp^k@M2y~*`$ec& z^vr0Tpi_Z%Mtgkq8`7U$94S1-MgU(^wo_#L6x*Epj>LX+OJ%iKd0vY(qt$r17+Cl0*=8O3Oo)D&L1x+Q)R~bc>bVcwC&uLGCp@vPogoYb*o~3l>$Tsh-tKRz1 HTi5>pG@Cd^ literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeDynamic_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeDynamic_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..78954e60f31a6b6647675f91656b535b7253ac27 GIT binary patch literal 1501 zcmcIkTT|0O6#kZ8QbM@}5$lbBMY&qMAV|GI1*x>^h@%faI7_=~B-wP5Ed&3=zo8E> z;*3AQ@i#f1Gy%eZj4!s+ZgMW)+5NtA_UG@t9{?6m%^;OQIs+|(48!2drj(ZaU|Q1T zrp=x8Iyc2u!xO%5xpIghwIXcWWnlDtt}4_=w{E@^?}aC1O_)nt+-cZ?TxGfGZivU* zk~>!IozqlY5x~0}8rm6pKJiUnu(|wDc)tEg)Rcw}hV(s4TIvBqVsz|v7M2#aceo|<(^PNKb(OC?-UzAi8HNwfX0~tL=t}hyS}XEO~nF z*zvL@Zrf{?5+uejuILy-zB`SP9&}}KIS^CFC>h2`Nv}zCpB;^Z1f9p%?I3#slLmF? z6oYX{=DuG;A&BVez%*_!je8Wv5v8`$( zo>Ag_a&l@94}kepE}2Ua!guKN>0Ejj4|C}qEQWwAU^rGc5!J02$?C-9LEQwF$kB#n eJfT&mgfdo9p$ln{-VO3xMFQ6_PQSb4E&c)EypzxX literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeDynamic_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeDynamic_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..6e74f14e3d7d15b0494480f486d05ba5276a8810 GIT binary patch literal 1607 zcmb_c*-{fh6g>?|CJY0FC}EtfwF6Z9+s!vc}a4uPLv&W8e_O5tna^K>W;BujrSrxKxDk zZn}H`B?z#}W!({euIzc+t;RycEQk`7gy93nCp!%hRfguzBM3p=3o{W>2vOpWQ?->? zurPvA6NhnRD1oEI1}kLQL=wjs=At!9$V897_}DCm5{FmhIFl!uRb7sRhoLq?&}p18F@C3nwwAiMU3fUQ02I1cPIH#YdVpqE~R2Ft202Yrm>H zz7np1#Xj7?0>hzpq;59@w-}5z{SM_j66L5fO0) zzegLZr$kpC9r-;d2D9q5nl-Uv>l1Qf?Ju|DoX(ZzbWKXpEIHiw1?}t9ey_Ud>K-5i z4;aS(ZED~VU7cXNF+o*Xv=~5wIHBW1-^288m|jM2eD*U^AGDqfiH%S_iXQZ8*=&9n z<3OeGUYn#$Jqn>sN=xVy`+~^;p$}`gA8MBf!65CGU0ejp`LDQ21Hmfko(F}qUobZx z|A?FOu}mxz|Aaf=V9qBpiO;y3NqoX;0LOIeL%2+s&;WUr)4i2^fxJ3-(>h1YdMK(k rTTjQzv-v%~HOb*29%BO;=);jFO@?I0F-wK#aSr+47Ac{c literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeDynamic_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeDynamic_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..85ab770b441ceb0966f911f10862c4abff4a5a45 GIT binary patch literal 1607 zcmb_c*-{fh6g>?|CJY0FC}EtfwF6Z9+s!vc}a4uPLv&W8e_O5tna^K>W;BujrSrxKxDk zZn}H`B?z#}W!({euIzc+t;RycEQk`7gy93nCp!%hRfguzBM3p=3o{W>2vOpWQ?->? zurPvA6NhnRD1oEI1}kLQL=wjs=At!9$V897_}DCm5{FmhIFl!uRb7sRhoLq?&}p18F@C3nwwAiMU3fUQ02I1cPIH#YdVpqE~R2Ft202Yrm>H zz7np1#Xj7?0>hzpq;59@w-}5z{SM_j66L5fO0) zzegLZr$kpC9r-;d2D9q5nl-Uv>l1Qf?Ju|DoX(ZzbWKXpEIHiw1?}t9ey_Ud>K-5i z4;aS(ZED~VU7cXNF+o*Xv=~5wIHBW1-^288m|jM2eD*U^AGDqfiH%S_iXQZ8*=&9n z<3OeGUYn#$Jqn>sN=xVy`+~^;p$}`gA8MBf!65CGU0ejp`LDQ21Hmfko(F}qUobZx z|A?FOu}mxz|Aaf=V9qBpiO;y3NqoX;0LOIeL%2+s&;WUr)4i2^fxJ3-(>h1YdMK(k rTTjQzv-v%~HOb*29%BO;=);jFO@?I0F-wK#aSr+49jBq3 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeDynamic_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeDynamic_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..6bd5f6e7213054b48afa633bc875ab748eedd2fd GIT binary patch literal 1595 zcmb_c+fvg|6kP`jDWTlLwJKN;2AzVEfy-amhz{{S$Hw^39@Q5}U6MU*?`_*L@(dkW zArI_)VpHr1M_4(LSop}zf*}}MHj9>}Tl)#!O7Mii&D}ijCXW^C*gg{TCl)vL+>Tk4 zTkX}ld%9JV~1HQ*|(soW1G&9tiR|1A#1DP^EKjbpE@`iAGGq!zH zEKG&WwxmN{h9yBl-|^i^LHwK2PkFoVV5pEFZJHa#mM+Cq46SHW(Sr7dYIHQBo6 zt?~j1*X8>nhPxh|D(;b0Cqe8KErzy%aAa?ieAnPb#Ij401sscE*e`vAm|$|fRQHDv zB9{@VExRZgT79K%r#3twNH4faT|LH=Yuwv9aiuU7jMv~P#u%DQyfa z8$kom!Z`Y?I2EQuIoW3LTE#2O5{>5QK(OHi>yBccVIo{}5dDTBm5XAS!J-C+B?fiN zE;>1}sC%cSbLB5LWYmM0A+};!!buz4bp?UeR|fn|JFOtY&~>}1f;GBE{tZAkkuyfS z08~+pbd>1XME{!T%{=MQ85%!(dek6=M}c|_732W)pQ8uJB){PyEfdRX6>GyIUorF@ z>SQDyIYTlYImM_SfO%980>mjmB?YMaf@c}6GMgMe#k6mxdYcoNb&*+w%rr8~4kgdA z3{ZxUEiHa1WJM5iRf}YXl9y(cSRq9P-e8s9Dmi4ajt#`&-2sg>ajNDHy6BfC?ZO{= C{HsR* literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeDynamic_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeDynamic_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..3a158a0b68ea4089ab45be7dce41fa8f99106102 GIT binary patch literal 1075 zcma)4YflqF6g@*9+b)Zg@{p?F7F%t3)fYafF%i^2ENZCH4}Ks+JK)0ZOtYO5`?K_e zMn3ohjK9fvr$yQZC1#VI$35rVJLldXzmC5Hc!F{Q(F9@%#2F^GTT*&*-}R)+U7rWL zb)IDy*$}?37TtF$^y_q<-V*wQs=M1_PlQ6&g!}9x4;sFp(55_6hvI2l^1!R@1TD?A zr{vCx1&bkdz>j#z=W@UFYWG0Yw1p%?{E;U;{g@$AD86+t49A9z5r*ixs*`3!wKT(I zr9<{q>2>HyUDcuBLD@kHV*|p~c2kSM!gvxBNHdK8g=S%j!D<*CUy^j8tKBJ#gvo)j zsbm@%8y9hj9O!zH3%Dn9H!0tmQo5-_-soD*^t-`j2S%%@D zcfs(pKlKT(E4jgC-51SVMXAG9qkOi)zMBE!n|4F=!~Z|nO?f`IcsA`i_x-A;1vSG( z*2Y!LjmB{;1;@b^)64{})5Q(yWY{9RrwaWdX5{#;Z`ei5r)ee^7}7m6|HLgU8H6*8 zWt3<(Oe>7m`@Vusd&gi`RV%EC=bo9$nazJp<+91c;A~1M!gZfFn}S-I?`0n_Z?Gj6 z?lH`s54G@s=DXWMWXTAd-UmcLa{!0_qjVahmC+iT|B4HrOgv>9<4(dE4ABRSe8%L9 zG^@-ne8J@o3`yL=?GxAvf#L)!9%B)xEPMmaX?o}-v9=bMh(epyXgabQ%S1D=Q;7)f d5NQZ^u|lg&V)yY7tH@x6&ZdSOm77Na`QK%#7uf&+ literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeInterface_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeInterface_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..9e488bd094b2e85ae223419250dffe9621c3d2a7 GIT binary patch literal 1163 zcmaJ=>rN9v6#k~SEv0g4Em%;f3er-b;svp-D3lPI6g8=lM1PR69m>LXr`es7)F<&F z{G&faF!2F=DC61PMp{5O*}0s{cg~#eoL|4segas>W*Gi30t~@zVHlG3U1=G0hKaIy zERRIlRKnWlHL=%hE3R~D?k#HwGK?JZW1cg(*~q>6a42d@gT@dl>ZY#N82stX+b9MQ zi6D$YhCoTy1;ap9Z zKN1MVDMt}Qd=R6!&Y(4fs=Au^MR*q~eh#&6S-j)K)o>$%q?4te*Xikru4m8V3Ym9N zOyZ^!^)?Y4VV5MIK(}y3D<%v=t>Uc(V}2ZQSXrRJCI((bOAcKYB z5EdEY4pk|+pHc@RWe^ql6bmEgP*Cp0>2`zTz8s^zeL${mo%$=T;SqH}%b~z9FYwrf zaJq5@Pa=4XRcfLp*U4}!-TRKemJE@qY+E(4r5n_0)8&6o#FCQ?L$qv~!YUcuwgu5J zdx^@cNYL<{Ve0>;8rEsHJkqGCLNrs(=Lby`BD7wk+bHdf_Tc;pqF)?6DXCN8bJYn_ z`W)H(DH06D$F486f&`7@e1IbGE1QRi~lU+E)ln*iA%j}|i%6>;` xCGZvZ^1(#l3=e^PC>czKzTv4C+>fG*{S0fgJ6XQK21+z(b94{WeTn}2e*g>tDE9yW literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeInterface_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeInterface_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..4fcf68b33320393579e5d00f63e276cebbf04bdc GIT binary patch literal 1136 zcmaJ=ZBNrs6n-vy=_rG}K*1uyR8Yo*DQeXYP$VHNnPM^{iGCp0?E;0aCG8!_{26}o zlm9_KNWhmL;Eyt%(kTUBnzX0qoaekg_kRCz{0+b|9;FaVABRG=^<7c9q;OAN8;;)^tT zp{husk0HL|HU-1rNmN@}c6r(Jc&BFh6gZ$F6M!N)>(aBFZ3Q`ofzy}}K1k_#lX}#q zYv;SD6kn#HVYm-N7@@Mh^@hq)H`O$Bj0Wb5q`PfN;bFApmY-2ENhJkuRnoYG@w2^j zd?{KA3ca|D335GlUFl1Y?>`Z8$8Guylc#-HCwnW01FX1CgUeOkkgnHJFv&2|;(H=A zZ&-4N{(Q+DNjcs{r|D)13#@UcX$ya{=DK_B{Yqr$uu9Z&Ch&P@Uqqc<_^U{Uki1GU zV(O+?;kI43q@ayl!*vx?n9d|oBogbi)PlQJkUOGa6N6@frBDj^s7CX2s|De+c{*)# zzxY49aRoOSl>LAL+c`&SH$`xk=5braE!-heTihbx@N{&J-$(|v?zX*#ShZ}Texmx% zb37N2#*nT$j__7&?)!phnEHdtzmcGz!Z7}SsDeeh5g}=Ga*}itf~N;8xES>9CoM;k zkxa}SBK;xolheSxuKPU_7$)1>&&bqDhseek$G#%}G-kx}%uLK`aXnFw8Od2KId3W@ zT{*&q9>k55mLizh8#B~=kJ+d9YO3Bxz%>1(=gt0--rq$IXaiqVGZQnir6Y_n7&$$o zWwqS;M_e(7Vn&|S{G2hU4IZNmn3_JMYoBm8>@|k_)LjoAz$6(AwSXl&q`P*N^c3kc H^xpUhUG5wO literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeInterface_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeInterface_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..fca184e835b052d11a371a390bf272d7f99fa870 GIT binary patch literal 1222 zcmaJ>?NZY~6g>-V(}v1N5wNIGwO~tuswirUC{&Qn6mg~sGx~#B+XVt?wv%j`sZZi- z=noN`@d11&$D5{L3TS?0H}~v4_v75nuiqy>0W6^yMt2wihTxhoO-bvPw9P8RXwf>9 z2cl>xVejyY*se7cSBA8<=QIQv`uF)E&zjuY&2D_$7Zs&JV+bu6mZ26Ix>M=RC?e2x zgwewgD9EZ{7;JeplwoF;7$72ErEG>$rStLf>Gx3#;%X0K z7@`1<@reRZ++q|XxaOMU^er2T+&ynYX5ZL`rOL_{yq1sRI&O4SQf@j*)HIAmFpir9 zEla5!W%K&FPvZ5A)U8n>#ZaFQh{4;uBnuV^od-_qguwpkZ`uzmc4kHM2EpZ1yB6a{XYWkU(- zND>n|?qISngu5hHnVOoAI|;QX5+-StORzA~t{z1{Pdl3Ho{7<1O`j^=*>MfC3|ifl zz_iYZ+NN-)<{s|r$l^h#G_5Xcct{L~+-!)A9fnDNBQL4%EU$Sy*6|2WNR<^+)C9?J zp{(3FzSE3+{W{}IVj%{GXEb*;Zcr`5DSxX^T{ju@vTWEDv1*t!o#VxSUaDDlt{9?4 z%My0McF!*V28us0zBJ^u9u01GF+)gHuO{ zesOUEpW{Uv<_OSH;N1`Ol`==@kFoX4^f89J5bJuKnQ84Z#~5Xp4}3);7aR(lU-A)rx5dKd8cDpUK6c;Qi6a}T$Qbb*~^}h+BNfDD0P4of}?Gcu4cbnZ)6MO^T zz-w>3)(Z*v^8mhwFX4qcOKV&d-Q?`-oSFG%=6q-N%lG}y0PdoyBCI095M36Q<&b>j zxK@i{qGmsL+M;Gl;XdO{vEJ!PE=|W?zpNn2klyCcdCB7TW@&X}TQsEtg&}ssv`u-7 zAv~9Vm_!_!1{Dd0NY!ZxhS7tlo;0n}UDxG1bbpJV42%3OL#MN$7%Pvl|a+|EWw>afonTm5i}0m zp9B#47ypHm~{1IV{(%#DtNYx9w zNJnp;{DjQ?uo20yav8)xc+8&OF zpsSImhWh5m*NBnO6Cbs5GHeVL_HdHH7|tg3A$@rD9Zr`=!bXbJ)Vz__)B7j^6L;(ZGdKp|22b;3i4G<=gagxhIEzm I^RzDf1n4L&uK)l5 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeInterface_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/InvokeInterface_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..a6b60dcae53d6f7dd70740a93c83cd22aee5b133 GIT binary patch literal 1126 zcmaJ=e@_!Z5Pe(PUMZCy#e&5jR4v$2prV4>A__%9lcFRwlIR~~Z5LR$-ZpnzlKM&f z8e$>=6F-0-$~f1na-ew0-OTOGytg}V_Q%iD?*NwZGJ>86f()T`VVa8Uma@${!&uom zR0pDLX<_g1n%Hi%G}lsD+w%rO41@dpkmpTq?dD&9*cUZzz+eb3N=xb`hMr9JZ4AAL zMiD_DL$IXkf?>E*)zZ?;FWWY6SENIQ{ZS0KN&RP0FEB(vyiU7GWGWZ=irIHD4C87a z;z$sIBR>)W@s?v4#Wi<1$q+G#q1p*C3S7qxhRMs1mY#ES*Ogfpwt-u{7{^TlRV__> z@U|dTe$$qgu4-HGMlpulxO1)@)wZKW!$7(h6SzyE6{WPJZQk4vdQa6IhVwdXGFub4wG(Cx1)2C?3H&x9X;F(iNo+TFs)b za~_L-ZJGo-oO(v;ds={=Eh z}Ork7-D715_ZYtjw48h=-I$9O#G$mzZ5a>g5lQx zQw^-pZSoYP2@BILa-RU0d#UJqh5m-fGP0qmW5hnYaS9et?1ncH?3As3!$2i>jKMhD z$W5PMB!GC}Rc@x^Tk&JnmXJUbVhse75`EwShcdv@cDLD`5_$Ar z`0R_%`k;mwe}M1)9r13rfi@5yc4z0#opaB<=j`vlr@sKKV99`HKsOL$7^pZIzrE|Z zZDl)>VPsYAyPoWe4X^Ag>Gg#MU-{lnv#o@(U1w*JgEI^tiDOY{2(qo=6E)>}Cma(D<4sYQVfd}B4(ZER!cm0rvA1v+B`ok#IC~B0 z&#b#{z1=EZ=GPPHySR1Il2@c}_vDA8FU|FYx)5d2XjE+_X{=Mon3%-$Pz-mdh3dHh zGIZ{BL@j2Rftg@@m0qmw00W47NpjPDhRAk>W3FGO&X_so$zW9_YV{4#+7i2sz+m#d zthJTAsL7ybw=01pc@#_-cu3}G3Y)YW%l5W*E*^tfb=zJ|uGs|EF@iAX|spVVd}wGzTCG7Py<r_zGLu9a87B| zU-$R}B8XG0{FSVqWE=Af-*79soSVp7Iy6hmrL?>iOX;cDCrndLk*D-iWPzfQ=4peH zQ@Zxf(m$X53BVa1(0c)qGx{y!96640j)jl{a7M@cBFb36ERIKb+@-Th>;pPhhfXA< zqb*PTG>cl)(qmREtp#K@)7lR#cK9Tt=TyS>qIg0G5j=%Ot4YYuQA7!8+@`%j`@8ha F{sRer9a8`R literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Jsr_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Jsr_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..2beefac57633e7d2545e8e639cc2fb4b397dd961 GIT binary patch literal 1090 zcmaJ<%Tg0T6g{0xGGPp_AYe2=K+q5#5qu{?6{Lz14Qf>=UAVv|G%zITPR(>E`4iV} zT)Fuk-uw=`R3lcp8HhLnMYML+_?c`^{ZXHMJ`R z!{EBuSDxs?2G;hq@VcPB7rwVsZ)&bxC3lu>*bD?iQ6neg6CZB)r3D?QmWc) z6fW1-fpi6KpESf3?(aMNgV7geJD@g2k=JTvR|^{J1kw)1G1(u*6tz%37eJccz1C9m zX%@q@8Q*3nS9^el;!c9pbhmpwt?}BJC1I5{uT-~qW1H{RjIhKdQBZe3j zNDOuE(ym4_ovoZNi@_n$$r_}a(H+VDK;KvMPHxm+`&l4_C}B(AF#IyXO4+&Z zxD{TBuBOI5W1PUel{!TR$VZY^GD43j>%+>IvpF`gia M6xlJdZ__vP58$5_;{X5v literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Jsr_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Jsr_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..3d630941fcd422d9927c9858f076e444d3833edb GIT binary patch literal 1171 zcmaJ=%~I1)7(KU5n-EK(MZjXgf}o}RR7L!0!5QcbW3{L=Wpv>JFXaNEZPH0@8F>@e zZd~g^85TZ(@8GM5-)$na1LGpOx##=N`F`{3&*@J9Ygjd)8HgB&GW3`2jMv_Aowl@W z!H`%NdyXr5u)(!GDcl|?{=##&n{COZ<=ERxI&_A?Lw>~b4Q}t}U+)}>n$*$95M8ls zOFm-=XJ_BWa1AjNCi)q)lCw(z!xWiexY8k8PX3K+*|I8K!JEYx29f9yt{!_*G<6L1 z;X0BGLs!srj4PWy{JVjd2qO zCMbh-$B~|Nd23V1183J`n7*jivX7j)$otwQ$F6a?!E4fSk9ABkj5c{)`0zVR9?+L3 zxh+ZKQ+H~CiXY%Pw|5)Do31!cz1=EauAmF)A#NSF#1-!EyZrs(6lc4jK%&GOjjAOD zHU2iHO-x~CAc{LwLiKz_GGzDrRLC#`S=Hcjw^q<%C6Pv+O2@qbqx1zL1}R+yxGO{yEvz|_9edw^~UIvJgj+z-UR zDm%GReSz6R2vNe8zhU@gl2vkZ-*Gd%8hw@?|BR{h32u?0prubS4-_IPEfpb$wDw{3 z%h_)w$B?J@6hdc+BdTLm$D)b{oM8r904SsnOL!QB%~9A0VH2cYNrpD(=1KJg59sCzt&@WzQ3CSF4E#yUy)T;DZ}Wip2F2#@JBiS!gjtRRI9-3_|mrDygp Dzf>cA literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Jsr_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Jsr_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..586b4a07a8be55ebd71753c47aae467bd57de6b2 GIT binary patch literal 1090 zcmaJ<%Tg0T6g{0xGGPp_AYe2=K+q5#5ye*`R6(jJ(V$j^(uE6bLIXpR?$k_&l0R|n z#pj^y!-_!S=`#Qh>p8f)`hNm%DF+^gBGW2fBwBOwIR8zZB zFbuAXedUQRY+!9)3$F|6d*ORK^`_?9RdQ$9hRrZ=#E*Hd#^pio_3n|VXd68Y(Pyr7 z^(sR+Gy67qsyRT@hwugu!kYo|+`;Ou*eLjEG%%P%xF;K+?e|ZW8~xQrg!ZZ)^#DsP=q@>5E=m zd911;7ep47tZ==-D_VIcHpUo6>%1xg_?@c{>E>%LHF13EOx$J(5-Ngrl^JTxd77i?zNVh zPqP@N&G1^eESqx5DHNA@1a1GT^xA+##t{CE*QVOqFZ)XA|Maso=&%J%mx#vE9|2_Q$U=1qbVhnvHHxo2=e6JyG zS1=^k#h&Mj4&T7qo)mtEEAcY$w`&c_rR}-fi#l|MfkS@8^A30S^KW(zMMdi9Wr!`? zt}Ry?qS={uaa=>(go!=|t?2Di!YE~C7%DfxwwHhF+pe^vFLTJl}6h_3hyI)XBZeY~J2*wx^&Davv*er*nWlJg|jd2qO zCOQ=~8FXZ*cb4Rp>L#ym@f}C?PJ9xTh7{ICKjXNg>NPM$q&04noZ;+;Zh9!ky64G2 z`np}>i=JEIa)Vc-=O62sVHm0LstDchZFxX{f#j|vj?eAo zw^+giFSxtwh+wMhdDTX}a8*^CrvtckTo+x!+v^G!pfGclqR1V`vZbKm&SK6)4)gsn zEKmuTZOhPmIE$qWGjLxGvDD7h8l$3kn4+D2#9&%p!>@=9TTNoHb3GSS9~t5$*A;%z z;Xxp%Gt*bP+pRA;o-s`PKUBvOEqd5TOwzbb(gbK=YTxPXCo4%eqq`^f6Nzu?ox*56 zTF(|D1OO(#W9U_im2GV#rn_(P!c6+B*AEc(FY&u2$OcpGDCKUCj1kB zgfIHgCN=Q~_@j(>*^O?s@nLu7ew}mYp8MnH#diSD@R*_SQs`qf>T=gToXj-Wj*^Fa zCK$uY2|wjcm&>E(tB)sQs7)jpj3540!vq@BYuRxUL#nEP5xOysjz!zzWI zE2Vwy@o7loGgSYy>&R0z7EMBP z(ZU8cmkn$&6noK>E0cwO6;JpxSGOuGgEEcP?#0m}&H&_Ao|LaJtX(m86L%QQX&{6v z1CUrl5kw$)6+0I0;vPvp;SMFP+ws@@&SbC#YUT~af#cF*Y=(pUYtwdvJ{WR6DTUW{ zx$g_oVdoz$uTsIpLx%1Dr@hoiAqWC_+ndGg1L!#d}M=tZ!=rl^@Gc4_=zT!qJT}WLJIa)?B jT{O;cKjcWFPE`ps@PJN>(01_%dnlqnc82T{ecQhPw{-9^ literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/MethodCall_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/MethodCall_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..6583447cf15a9a22e32397d39f4749f7d9a555c3 GIT binary patch literal 943 zcmaJGVMf=bPP!c6+B*AEc(FY&u2$OcpGDCKUCj1kB zgfIHgCN=Q~_@j(>*^O?s@nLu7ew}mYp8MnH#diSDu*Xn%DfF=#b-C*vPG*{GN6EuI z6O3WygrD-J%jHq?)yESt)FzS)#uG<6y2FsPYj1N%!?2Ko$&l)*kziPIq_4RgiV&C~ zZTEV$o`nR=94uT5Zr7yiUizcBt@~Erikn00J)XJNiSZCOn@UaNp?;L$hx1eK97@zF0 zpT(mil#t*Bmm^pB)xJ{W*|Z%?3t8fxONDRdQxOkF>F;9*;dI-zm@9$^WEnVG&_r&c zXki1J%LcX>ioIycmB~WCiYNS;t6LS8L7B#C_u^;~X8>|5Ps&#q)~=Yli8~DDG!Vj- z0Z6Q&2qKWYiX97gagQXQaEB7t?f7ecXEIm=HS>nzz;S6YHp4;wwQ0LS9}Kykl)~$} z-1i0Pu=9_WSE*p)A;b3nQ%y8!XG7I+n^rGH?+22g#e_lsELp2`GCI@sb7Z~*aWZLD zqi{YdGqy?}I_1xccosHlQGB1^O!C&hA<=J~BbRwX=RctEE`XuEiX$0(vec82T{ecQhPye9B7 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/MethodCall_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/MethodCall_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..00b822e862928e15cb8212f7212d6dde29a4c0e2 GIT binary patch literal 943 zcmaJ%$QoqO(&pXc8JJi{Y~!b_o#)TqZ@_h2&9Tsul0 zJT}1?R*v}zZ@F9^wqAWa7DH_!$zVKjq@%kG$y)tw4rv$`QZN}(Jv9;xOOEt4mqQT} zGo)*_UAHYH0#H)TG>P^X)Q)Ps_8h4P+7o=z$>A!NF31k%z7`V`D_N{!IR^_@0-iMj zJy%Nm+T+tu#%HMhY1fe_YAjmB>&U~Nl0&Zd`A{owZepEbW5UNGOuuvV5q$+6YvTA+ z3p-mpI${Y0UT`^bge zT<-gVeAxNN%gbCaai3xP|4(~MpDi-$4eVudXp8MnH`F8-%@Q9)CQs^T!>T%aSn9MZSj*6&fVZ3_vQIas(7+^$l&nrWi%FGw8KdhIz<540!vq?5xkRxUI!nEP5xOysjz!zzWI zE2Vwy@o7loGgSYy>&O!|7A-<^3*PenW!rN56MgwyTRW3C7ykY(U#K@+)- zqJ<4?E*sclDB97KE0cwO6;JpxSGOxHgEEb^X2;PY&H&^_o|LaJtX(p96So-5X&{6v z1CUrl5kw$)6+0Gg;|@ta;SMFP*W$1FoylMg)XW=-eaEH6*bE2x*QV_TeK6!~DTUW_ zx$g_oVdoz$FH^z9eTMD-r*%`7+^lkqF#fI=V literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/MethodCall_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/MethodCall_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..836da61c78e9f5b5e3d604a50c508de4e35d6442 GIT binary patch literal 1002 zcmaJ<+fEZv6kVscX@?55SPJ1*OHqj=8N$Mrm;DZl%Y)@e5bWSsKO42{^ zBYe>ZNHFmO{3zp|&KRabe3&_xz4zMtthIjqzW52?1$G&7uY@|5y%x8u!@)>#WlH;S zM+0M+KjEjmZgKml{^s+E=qe3ShQu?|HdT`$TB#nS5l2Et3>rhMC3}Kl*0f#4?XK{F z8R8Ygs2VyV(9+N`x0bZKT~p(k3AfyqvOgL& zLTSO9LN`-|@5e)NO?sFWUz|quDukzM$5etCS-~A0MU>_eSY=o?0+C9CiTovJqQlb? zOX42UN@|4Af)PECwJaIuKEuL;Lspt`&V29kD Mr*o3dcj+tt0sCe6`Tzg` literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Negation_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Negation_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..3844283644f4e4c488946c761c99b038e1887cd4 GIT binary patch literal 1197 zcmaJ=O-~b16g`iAOgq+oPurokfT9*eieE!%QNbDl21HY%3l?T*$1*UTY1&r||H6%l zzrlrxE;MO~F5H>;bBsIVotdH~f}8gy_q=oNz31Nf_N)IHz%rJ-ORGP=G9(^qO_l4G z`MlNR?#DF&BMi}9bzdzSs@W`VZtrS!F2Kv+U(`*V-(m0+rk;l2hakd-0E4$`H8cua zJ$MNVn8I%?&@(`3`+`xoUFKcvEoeahe&ZxCvHO zvtel6$#u)x>$NLG&)h7-kz>Rs2W@Q_96a9|QgB_XObvww5>?eOYC6}*kt8G$38W%^ zq#44_Fto-vnN}WW0m$TKVQpAqkjQ3c<21>0G{O_i7LaEU+P3?KX^RY1F_5t5H;xGr zV>s_4B?w#JC5FgR4TfblogyyT{0FBLQHX84e?_%~)-0<9qPAlG-oaEi~D83oVH>>z1KUahg zh?WDA&_@m^2jzeq{D=!lOwNlbu{R&G;czO{$27qaIV?vA_9{^+dgw35JW4#yN(nh8 z#nXw$9wkX%$+?o0mi9|2o0?9i`X~}LBd6tzqdd1DXXKX)SsTt}vVAB7=jEK7C)n-7 lg9WO51Z7m{7OA7#xQivo)HE;(FESJxbpMeqn^$yc z2zvp6ng)l2qVj=*=6JA(t3>Qt6!ldZDQBp^w2^5M@rd zWz*5Yo7zlo2GEayiXIG5f@n&Hp)H5j5SgcS!;(c==Xy04KnR1UN)}HVl2;W({D>k< z(5eu!A?teWF_-(I++djaC(y8t#39cRn_*Q7!Yb)O8wCp(R!zJ>PEbgLc7qT-iN2tf+)ZBB-R&bR; zsoCzEmQ8Y&!tU$@CRJR+bssT7+5I`h5b9_!g;jAxOxgL5E)a1m0)}a7T_^3ODRftS z#?D*6An#5D9?bSG`@Z?#y!-u{A>1J-i{_rmoyzxZhP4YA<|8z63p9gO-JmDNQ{Cpb zZA$Mjs72ANm-xD2(!eI2DyKifjO`yoVAHaAyT8v{Muctty!xrk&C5oB9m@2fH2cBZqt&enoB#QS5kdDnIfC!Nre=ZI8By z4q5NC=KX{lF{I{vabI&zAuQ{UD=o|rs%m~sB{;(7`xE^~^8p(jNCaBAOK4CV(1K3# zy@gORbi5F@;b=14LYCl|7S&<|cLdQ#@6zibLB3&`A9-)fr3Wq2>cJ8o(5}+O6%?=r V%~3uKFGeXg=BziJ^|rIl{RM+mC6@pI literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Negation_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Negation_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..de653c2bd4fa977538bca06b2b0a995c1003511c GIT binary patch literal 1226 zcmaJ=K~ED=5dI$9cH6bmQo3!og#uEvAW{@v+JXw!5HKJrMh_g!LRVPW?l$c!hJWG3 z#NXge51KSY58gDM{Uyemadx+8iQr}4%gp<}nfYekmtXCV02Z<6TUh?_nW6u_zN2x& zww~2m+`G((=wXQNX$M-t)U2Jt`qrMl%|-Ya0`rDt@LLQ*e*8%o0f-X(2r~F8c2y_0 z-Qo=LstY#k!h?ok@eSV4wc1=5=MX+Yym8p%dQC)c2oap8&>h?6P2SMzYdYVxt4)U7 z-!csAz~0vj#AaAK72Dd@_>#8G?Z%;q7(=qA?dzWVslj*Y*5sPSiQ{$NtH*7o!{Q}a z)~u?jH*>4Dz2Bl@ATu$VM^fzr%+y@_qHqXO5&b;Z}4)^-T`SzI8$MPs;u&H6RDL zD!xOs9F)a227z)&2`ZuY7>y%0D7tyJ4~hu~noK6zC=fKIB$bp4Rb=HzET;uE6UTIEKuOD))W9P_ z&C)Ge7Si(!jK0QXIy<|5?nyHE zQkjc$ia|R=FhMU8BMk;Afo|3dl&M~c)t1GfBgMUh8Lpk ziZBQXE3Yv$OyvyS)cI3}`sm;WgLld~%D90p2_AG4V3j#TIPJVcw_>YB-Q;V$sHugx zj9&CzdgI!0iE9NBw|wZwO@ihuiM+aDdKQ^q{tAE!F2QBH6E5INw`;#9djXCpRSG*c#FCe6U&~Ou z;}rf7T4s7q5e%^8z$wBZv`q*R;S|azx&#WM39N>;l4a!c41Gb53;VEyR26>lhW+K%7j1SKbmN@;b5e-f<=NuN>B+A>^4-7Won@g&ygl8QEM5j;sq4k UrgI0;HB7#kvraneGiROu3&8Y0TmS$7 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Negation_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Negation_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..776524a469488f68653165bbada8ce88620d217d GIT binary patch literal 1135 zcmaJ=!A=uV6g>~xPCJxRrqFgk5frr`P@^KyqJlL944_GkE?AgH`z!;~c}@F@A@L*J znD`CubfHNXx^QRW=NNa!J2ORx2yWh+-1F|a=bn4#+po@N0IOIHt*rm}%8=R?HLfh_ zJg>Kv|1qzjhatJo4|(3^PA&gvcVASLh7dz!*>Ws(m!UT|^)!wMG#z0?8A2sl6%>|j z#W1|-C0jE8xM?}6teS$?i*fWJeuB7s)Ka3ZArZp>`U$!(rD~}rZ)^#*C#x-n$-goz z=TIJqJh53$tt6caS8KeYWb;Ua!H}u*1L23CS!$2IT8cZ0INs)bJzg_i7QetccdE8% zO>Rng&~6k1&-^OE$ce-!M-34KyU%w548Ci{sX(YpQR22;wv-@8hA^xnh4erK8HR*6 z3{f2?(+cA(3X{CdZ3HR0h1|?hgC=>7MtF+Z8pas3hU>oVxFi7;T?%)8 z1a0U0FvGyH23tBcPs9~B|KS-Tat0WtXmrPEFKo$u@z>nEwKMW&4fJ3xvJ(Chd-Lw+ zYlgvNf~suq+QO@R!)17I2E#1_y_l!Xt8i4aX79lFeH!K}&P_pT#?EWi%`^jQ#(q2Krwj{)%COM0;*i`xJ#nr%vV%(#_}& zPk%z}y*m!XuzukGM31$%Rll)Lw`XQi!G_9ZUm- zm>D%=1RHEo&*+DXeJ&c$^mULYwBL-I{a*6*r9?LIaw+M;MmE{OZGuy#VWtT7mGokX iYWJXkBHcP^x`TUIfl0D~5rmMX*ob#t_0AdZy!jjVKppo0 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ObjectPropertyAccess_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ObjectPropertyAccess_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..2ef9303ac055b4c2c6407cd3905cb38dad341389 GIT binary patch literal 1178 zcmah||4te~5dId9J2;L?)zeZ$vDFq3rT*x(1+}pxrY0IpH0>Y6m@91b1nvm8nD{1r zjW$IS+w=kYP)+AJQZbtLkJ*`>o&9EZzS&>DuYUsA!dr%!%BM446Z;*f%{$^^t5)N# zd)(>@Q&^6DysUsR#Lvugv(Pl{lY$?vAjrThk{yyWk_JhOAy6fUyl&Z+*klN1vL7@= zp{bA%(-46gK>#BRQrW3O-Jt> zN4TP6w)eO=b?Pp|+)WXdeeN`P!LOz4*fmpZn>FEdE)>i&Ot#Dh_uU^YaY~jeOj{7f z=giPk1}J`l_oiKMa(8amaT?urX((*);vvtii-#9&eoy#t&wRp4*}D*Bv)Meb1gDNX zM@GdnWJhG=7?K_v>E(2$Rb4wuFQ!}7)uU`N-AHewSr~b0Y-VQ|Z&0KMvouPBRbUwF z_v?1&6)ZC-ZI6m3QL7KPV*ueXyNWdxD|pGE9yr}jjc;2`P7M5KP?x-n4BC!u^G>;G zx-O@l&)?zgzK$y>GEDzFRKYq;w$Bh|Y4jv|sYIG4k*t6>hkZ>`*w-}dq=R7I2cY#K z?W(kok*?&f@F2XN{GsjzH{+@yrBnNS7-iLy1ot;k>Ts;ficT;u%BD z>k(b8C`L5CVrY3is%w>8zK8f1f&~4p2}}+WB}fOz7yFLD?!pyD7cQauVMNZ~dQK?F ztEZ~0=aM}no&9EZzS&>DuYUsA##@Hj@~1Oi69*lq%{!vEU8`}| zJ#KY{DJ;i6UQ@srVrS;LnQNN%NzM;f5M*E$$u7wmNrR-t5U7$vE?TxFwitrx#Sa>y z&{Rkm(GY(u+Qpu@vmFy9QaHne@a#y$-#=X!0CMcj~S~kOEy1I9hydpZ5eNym1 zLy$eFM;a90daNPrTho--=?VtjziK(T1G*>ZHaA-Z4KtX%^`=VC6}+WjE`ldW(a}4{ z5w7T%?R_pzow~~~e^Z2IpF0hn^J^(NcFhz!W=%Mqo`MC2sg~K`zWbvkPRVkGX$!*m zoF0100L4%6-n8pY?#}NyPNUl{422C|Jmk4`@vztC_k<7k%qOg{co(8%Hk%boaO%i& zq*Xk_;;4)aL&9StwVFz|svAeCezcfRHBy@?7DkpDo8BG98x-lmtc=lMWY_n9)FA)1ekf7f+iK#)NIOzcSM!qAkw{(TErAz337?Jb0o)Zf4 z>ZvNlOyUA@c{4M8fkfsTVtI+y_*Ps>t{6(+A=8>LLUCCStr%giuDTJ)=#dK~zv5{= vO2^=9bTkX33>uL-)kYr#U(KgW@QHQ9em7xkP%tg=yP7$EzdOpMHVsqzr@?ACX{MYp; zXbO51>Z}DLmd;s7$I^L991Il$k6pc>`h@%xc}urfx3GW)UAvWD^ch^&r zCUOl$6IZb`t)s+{kG4^`St$0Jt1k-I3%%ybi=|qjQ&=ysG|DvC;`U^`agkA&$}AmL zm0@l)ualEEaFfC4N2}=4YWd_i#v!83u3*)~E!<`>cZ1=eCAYk;qz(M%P%BYJ25Z~* zqzvXPfCoh&yiVrpc{jr=Sp$E}K(=2LvSEo^Qd;|5Thb!ME|Lx{MxB<@f(3Eag! V;wCjw$2vCPV3G7R>B~gde**ao6ixsD literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ObjectPropertyAccess_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/ObjectPropertyAccess_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..a9d10a0864f791b04c8bc57b4bffa76343e7d1b4 GIT binary patch literal 1178 zcmah||4te~5dId9J2=it)zeZ$vDFq4rT*x(1+}pxrY0IpFzp}2m@91b1nvm8nD8cj zjW$IS+w=kYP)+AJQZbtLkJ*`>o&9EZzS&>DuYUsA!CQve(x-D?6^Cu7#oMC0Q>}8> zJ!y7?DJ;i6*-*e3V&~?CnQNH#Y0eK<5M*E$$sWl$Nu8w05U7wt-n48>Y%>JYiyt&Z zp{bBCq9Fn`f&fMtq@q*fD%m3p;daM9;;wKtjC-L0Oi)16v}}gSbY=f0d0DhA`?TPJ zDv&*>M;b!D^;kpLx27qv(-921f7NnwhjdTSZEiLT8fGwi>rLgZD|l1ETm(;$qN8_? zBV5roTL)a6IW?DI{-y}azHsV1=hsqn?5Zht&8l$PT?GpaQ%$qZefLL8oRQ@U(-wsB zIX(200g9jCy=m7P+@0TdoO-8K7z!J_c*t|>;!(H7?+G97nNL_@@h(KsY&6Q2;M9@l zNUL~;#ZegIdT zAHfTV76}j^z(*m*aRjMA@GzO(@yt1M+kF4=`5S<{Xfn*TU+fB3Zbe~VL~`%0>xwvj z-Wy0qdSUSVItODY>^g6pn(qX!YNII%$XULYyPYg`J z(4k<`KpuJ?860I$n&FOMIN>_JJMbMT?t3p^ibw=5S#zaUtK8DbbCN-e2Ek(y%h-UK z0A+BB!h4PvFq|rNHh!nJEh8^@)kr9FP!poF26%d!HgFs#lIU3jT57W>!EhiM%oM~6 zYg>dM2}d}+hJkZ9f2j8Dy;zDK$6_8Aut1;gg`tdP!t@3=6;0@q#yDSJcw1 znqlBN@`2;ZFxulNGo0=@U6Gofdh#`$V(A2uFy5BNiW;G$1P`5H#~1O!Mi_Pn{l=Kv zsP-|-p}@y`eeoCf@$RLAZIu6nXga>X?MXo$SwdAu17 zI#-{S>sHrVvzUfU)YwvM9B-6l0(0d!E#OsJfMLH5cb?-q1MerJ@M*~AcsoWA$&7E{ zrVbmo81(IM5V_)k=hN~m{AZz85=I826$Bz``c51R>iOaybNgGzIcTY8|Lw|ghh9KB zAc53cN$p$ literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Parameters_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Parameters_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..3d1da6a60ca4411afa4cd6003759b2b11d79800e GIT binary patch literal 934 zcmaJ=%Wl(95IwhfI5B~y&pZmng_Jr4nikkJsSuE;BB+Q;L9k#^-6ogTjqMxR*Ojtk z$1m^~2o`|4-~;$5#5gwKii(9jzB6ae%$+m-@$>9EfXBGcu&~cP?g%A3|G)_pSC(`S zwlpw?;t4*Y>0w2BTI27F9`l&LzGak3=#U!`~zrqOrE>30F+f=C<9l zl%R=JP}Nb!(sUMA8OpuDG2~l=W@b=l#y|##wrCnGhh>_o*-4VcB|{ElmPA=$n7d%? z8g4RZqfiIi4M`IH#1x^_tGK13hBcDf;T8cG&E#eNAQ|+Y47|SBwQRvqy>P=e!af)Z zUDp*}+vdJ6NQTvaq`XK34I2#0|A%VWq+N|f!wPL)da{-&T1;A5dgtjpLza=vtbaxB z(*%%59qVy;6Dj1#TPx~2^U%9X<~K}lr$1w%nJuT!a06&+m25@(0`qq^?RlJC3V#dA rzEpkxtiIOY&XhABCnZw2O?C=*aF?u3@CLSUk3?FebB@l}=(+w2KhW!C literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Parameters_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Parameters_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..331f4eb976e8fa073d633013ad5776a4744651e3 GIT binary patch literal 960 zcmaJ=T~8B16g|UsyX|(7&q51=MT@jpsiGk%B}6SDLLiXT=z|YrXh&GOyVLB>lJMr6 zf5CrY^g#_V{s4cJ@wQ!ciNuH9yL0Evxp(e4`{U>3cK}cEh#`B(eeMb+{NTt96<4+q2asgH|fPw4fttA_0RT(U5JCeDe4$Q3JFu zLq+_1eHL3*4}IHHP2~&j)-6~VzEYui5h&pr7)fIkH|TT_x(s@0XREwrVH^`ChA>G- zo=K?!<@4^oP^YpTFckmxX?y3gBdS!z_D&koYjL&BTT1#D2BsONUEUFc^ebDP(pR9k zr--lEh7hTr+eF@=bweS)k4eZ5bXrV!gmpn5Su%w&G+_$sR{xoJ3h* zn7Bp`19upVZciV_>ygCzi70wfFXFC=B9=&Mm)iuKD#b7J2gzVIW$3rWw(SUpnQI-k z((8l4+VMQ$Hyj=Wf@E0yN6PC&FtEZf|9_}~2jta(XjmZcB>J}0$e3hVdZ%eUMv+m} zm%kwOu@6Y2jOA#17aE2syP4RS{bufKo1^AhqB56F98AKj8J{q=p3&CyN>*Q4OJ6F zU+`ZTArXU#KfoVloNZTKBJpAN-kE#m%RKfK{wA^zU$&+d>J~+p~Sel_{OQ zISq^PpI>E-^Bs4ESf45|7dcXzqv3kFstdq=iO)+Adqpdpz;2f7j~^Y5t$ zU?2rO2z48XBN5zs7-Ch~Aco{(-7+0hEi-f$in|Pn#g=Pe0R1{*$moR6(5v(nb-Uf_ z$&{rX*K|}(xq{mj13BEf(r>NlDPe0EPGJN?lO z@P$Hzju z&(`chmUe*+?ldgnjc-eN?4ML3uy&Pb9dYu2IR z0fTlD?8kBfl1M)xMRC`_9OiXA#3Pb|%}oLh6rw-#2g#t?nx@nPMa@Xp0Ht2)F z*mNA>RxR#%g4Qtc&nmB5f`&zgk^e(AkU$gdrD2q`6Qlp{Bw>@F>6Qvq-#SU^bjHZ* zLqBLh+Oj@tx&SCW7#>V71(&^RZ;dAtUCI|>hf)5jV=wuX&PhDWJ{hY!RJPn^0 zT9tvBZ|K;bzCiX2#?l$mTW7dk)`p5-F}4sNj9=nDP)=sGZ1M{p|E3}Bhcp>#Q==+f nxer^#$$F6TDd>dQ7wFr8GAeZH1Yg24tRRbV@{{CGlg<1BeDVNq literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Parameters_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Parameters_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..164dadd2d91631c325f6ed23b8d0c15b0f4d05c1 GIT binary patch literal 979 zcmaJA!mn+0K&L=)PZ7ua(xA`&2x68&flcmp91$!ur929|wFGQXB^f!B__Eg($)7R& zO@d)C>zb7a#T0e!I4xTVn$#?=>9~ryu?(&=Dj*I+jo-nO$xZaJrOy%wHsf-jbo; z78`bCo#KVITaEf)Ft$8T_;rT|fgl+c&q;Za2paA(%>5s#;XXNbAR6Y$JHzyT@^NHV zI;H4D2B!5A-STu#(QcGappR~rm%hOGNOvHI+gOQF>x9WsY-L=3{2fEhjXcibbHBEog=8S1kXbAqU4aGt`PkG$X}#+tyM$O8F3#BKB2Uhfu*C U+I528!x|o-Kp*+6ye~?rnB&NqFJ~+qJujD^ohV zOBxtM`iP(Kvc;W)^6R}L(NY@v7*hMDu-dgl?lQ0%Lx14cWp~dK6sa>LgGj?s#R{fV{3_f!=ypdsmp1`NcJ@K1vbv6^fXL2{*KnU1Me8TyK)9frh8;2Ib~Mn?=; zx{zJs&TIw!nXWqVzlAzp0MOLYUcP|&G? zNlJMkrSg=^JFkQ~lx>e;`tJlx=R_WhGF361gPL?&Ty5}{lJ2R7X@;!Lk3}#1)>Mad z@)UOzaeOTH`V8h6vh)gUa;I$xZ+c70<8G%Kf%U3HBbO52oOVR?GK9a2F!UByEk!~h zMU7il(^P^cbqBLLW>6eRpu~`CcI|@PFVHLt)LEe&th7>KN!+Dr7wb{7u%yp%e~5NE z&v4_4b!d3NpmqHHSdLE;=_jNp?HG87M>-a;NGh3?ykTTO10ruK#AnlbHGd9c7}qyv&yh~Aua2K%=rch;P||vsFi4hBEI#)Yx!!dO zkMShDUI;1!GiNYX&X8`LVWN^4D}KZ6fgc5PjQxI5nY7ThbDmmIP8r%13|$hon@Zkt&diKnj8bhiaRw+HLIJ$eu*X z&)~-2fCET9@B{c!h;eO!E2>(u$2;@p&FsAS_5186fR}hAP<Z8Yr)WSXrHMdXlok%c3W?b)GXx1Eqc z`QSWR+cuXm)Tcm6zgvWhYZr+7vyhbU;QBlkP~^~_wG>hy$8Qv!*kLHp_}7LuQ#(>^ zX4B@lXU#y;z8sJZW)7AF)_gfqvHPQ@6aEWH8e)zw&A6ZQ%OosufmhNDJry<%tQ}3p z-4raYlJ;CkjHZ?jCh$)whIne-R?3x7^rYwYH7TCR3U0VqMtL!hRe=Q_R*h`!Xhy12 z69wGlSvL356iJ~d^VTw}xh}AB$*>)42sq*q_&z}05@ z3V)FTZr@IVf!fy|t6aZodmcya2ozr%qk^6%!%(pXTmR{JnF0=)0-IMu9c=R+#)_ei zIo`kMnS+Sdk-zhNT4F2M=C*&J@HL9F`z{(u_zA-u_BBewozk-x>($}z#^>kRZ&>W) r%Goniflj`XtK`4qPMn>=7USn|5BJ%+%+taHJVXU0J{S1B#&6{hX8h*! literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/PrimitiveTypeCast_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/PrimitiveTypeCast_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..d3f8e8e0bc9297b0d2e791ae47f7ac379518cdde GIT binary patch literal 857 zcmaJwel9PQu*3ykNi+0R*f_LyG#PhO zu((Rvb0smFS~{4(KcyJrsdd{aS3=Q~p4Zo;cp}TV<6;Rb3k9qS%=55nWNRlgQoA)# z#9f|cYd=kq6pAwMEwP&G0?XG7+rfPSXBo;xB)2JPR(raT>(DP&%D%PO+pN`il;GiY2aWmAxHt%7q80yII z{zXp)B3eiO&hcrHtzetq{(<7xD9-LJG?H+W;d%B|%EP^HSa`es`FZsMRbV%_Q^|eD fW}K2mlR+6g#3QyYC%5q!Pf$Ub&qY43@mu)=W?ki@ literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/PrimitiveTypeCast_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/PrimitiveTypeCast_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..614f5e05a77a2a9f34a89892deb6d4ea9c1df5af GIT binary patch literal 885 zcmaJ-W`90DE}Juy*3hku-8D-p$6M%L8*d zniy`RR;RCQFoxnKpYo>1)p_&y>{9fN4T~YWBb79}3|6iFzJLs}4$`n0(p^0ejFP4@KnuAk78+1%@j_7@up=JlB_rQKANKxEgpOs2*xP zoQyk(w5UtcbE7b1Eg6i{KPC_&);jfsD~9ND&+ADeh>;~caIgq>K8t0BIU=iUbop#% zM7zv#ct~8<_LC5CqpLXgB1F+`}}W0W0iphEhMxTM78 zTJj2iGZ~zop7?!nAU#sKa@Y23hvP65-YO;huE&EwkOrIo>3Ew0HfjtTcc8!Mau}hPVcP#aE`3q;-Hmoth?!B ztCeZEneA5A&3#L3{2@E literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/PrimitiveTypeCast_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/PrimitiveTypeCast_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..c3e0135b5c83d4519a460396780908a158734cfa GIT binary patch literal 867 zcmaJfgc5Ph4(acV-FwxlIAEeTD*DIdNd4oRs*BUK<36)6Y~9I9=yYPPX=BYP7m zKZ6^80}dedzz^U@A;z@@uBd9s9`DSXH?#BR*YAs;0AArKL;YPS18L+;yq`}*k4NSt zm>O=RRwvJGFow!GpK;IU>dZSnJr@IGBhOIWlS-O>hP>PUP=q)OIvB{7~_HkiUcWf+pFb=w(NO3~xK-%!DG}!r1$LkcZ;WBL947IUKdzdJO zCUUfY@sk6K*O9&pbXq3M$XdHUQ2H9j$-RwM8ukcolW)5++_PS8)JOZ9pI;QdVX0$P q3m2#ZonpYU{PSrmm?LsKWaMTzmTLM=J?Wz`?z^LfP_&`82fhUeK=DG&F)Vd3ri=jYW6RDs>xP9^sp fn{i4OO$KG~5RcfpoZQA^JV6CzJ{S4C#&6{ha>?bX literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Reassignment_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Reassignment_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..cb3d815f53e382da3e16e3ae5bbaaae557d425d2 GIT binary patch literal 1020 zcmaJq*kRTd`F7E;JCB&w<@ z$gR4XA-~s8c2((_?@C?QzToYREV3B609@|{TC`1!WiXCW3O!Lu2ioVIr$Qg8X27uc zw+&aGsFo-Znkx^hN;bIO;SH_)o{34Crp;R-a=&)<5#0jKr6!Eeg{YtYFawmRz%G|f zPXvp5O0~M3jo7oOO5AfH@kOsA;=#f5H!*~0Ya7LwYXDK@o>zCZppE1)W#Jm8$5Ob? zuu!Ary4-V4xYredv+BIBIBdn~_3a0;Y22Vm3$xRR*iBx_(3KxE{%9_6lXLg;OzPYf=io>QO6#_+9!(BbTvjqQo%&|EDI_ zN#l_kXb%a}cK8j^2qbl~!}K>nC!;gD{2kVpFpdnCac>ajFfdBKm*duE`f-kJeZ@p2 zF*7@Nig}=tv=esn8x|AgR6g~?s+dMOof|4=Y%`zEXZDSmTq3y1-kH7k?m2hvJ@f1L*-rqQc*ZdCMsVME4rE(Mz1Qw)t{o-! zRtzwPkt2S>D=wD@mDit+L{l3`Fr?QV>F5oHM0x&Q7Ad4HBw;WlYpNv}Qu~f@TMVq8 zg@r+e*(*3oJH4h$>;|r7FoY~2s;*|pZ})i}RoV3%sTbg%a*k^Edak@a(3NEvidNs*EOi zuC~Q~c_!uqtg8yTmjlBhX{*g0A{{TsdvwmqU^P_NYlR1Dd=l)|e8 z(i1daBa$J*+&^l$Y|aKAG0glw)j*XlN~jAIF+dk2cn0V&bYIA3=xdZ#Mr&%}2h49l zoZQQ(MB!Z|Fi5_aBi6e4{1n3*r^v4+C#R;*a0^&X6_SP2ca$koO`BCCpUxW}t7edt y$(v_bq8zJ`DOi*fq9<^l@CNVzE41clH$?A4VttG!cuMmhCx76ZrW$7ZcHs}!sTJ1% literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Reassignment_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Reassignment_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..4f55caa27754fca092f66cb5a8eb840a5f430c50 GIT binary patch literal 1062 zcmaJ=T~8B16g@*fwp}Y9MZj9XML}Bxs-kEBNuUXF6O6_heei*d?EnM2GtKUlSYPyK z_#=GL2Q@tS1N>3q-L~Qq!F{;1d+*(IKhBw-zm9$YSjWS}`{U!|#0MbBF!o&VFqFH> z7s_n=EyIn}YJ1T_f?;r3 z%rNEBawYeiL+-Ui=*&BBmmN0ev^(}4*$l4Gq$SsN!^d6F1cklhZ)?kk;F}+Xnn_sz^QB1 zpzgJz{)z7sVa;`h$etBB*-QiXaut{G+6^G+<$oVe4i5bJxjjjL3=gxD9_fuU}!m69G^JCBzaSXWFhqx)5Y&7Ev2KFHIhEU zJcTj^tB|44A50=5R-)GuXtSTSDwB-6b)k`&5+rYN}4T(WO?yr9u~4TGRQHcs=6r% z)*Zu8+8z8Xb>*2am8lzF@YY5id0ae2T<--&v@DF~P{0U<9%^j@qXWq{;vCQ(Iy(|_&uJanYSp-9w4ASC~ zicXZ{J36V#VAplWZ-^b~k&UL$apr0`6+^zJl<=z_wIWF0g?~J9mbw-y472}FwQz?# z9=U<`kRoq~Pl84utJ8UbzQ*Wgbf=fT!~PP+k;4*h4a2XI9Hc!d*qhl0MYi=7W9zA@ z>6t!ef%UYLa?;;0AEKG5J{AeHoQz`;R!rQ_hIp=&{gZAxImf0@R40jLs+PbCR_V5> V;%(f;JvazuAEAgt*wo;>@f!>+2oL}O literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Reassignment_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/Reassignment_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..99dcb4087a6aa1f9ba44a54ddf9f6bc0be75b06c GIT binary patch literal 991 zcmaJ<-A)rh7(K(b-FB@|iUlh_E?Tr8Q2%29Nw9|41f#J=FT5aQJHpWIOtU*B)*F2c zUqdf6;lc;-p{(C_8(bo=7c)EGnK|FjIluoL{Q|Is`_|`vzi)j35)4zX1P=nar`kf9 z-FDY-BemLnV8dd_9q>b5@wnQnym)^g8pcMFA+;fuG@A@odGSpaHqs7K$S@?Tx+y5E zyN02#Gk7d@<)tr`sT*JL_IegsTs%Qs?*&G*ZH#4*!ze*dv^Ih9dFQz>`??u0l>U_= z)uC>Q3b9GGSJkS)%{Ffs?e}afcAH2d@y7_JO)d@V=y44N6TL*_j1n!Faam{7RZf~%DqBV^x)M>d^tHpVT*+aUSJn1~kFmZ|kHm)+*olp`_ zkxKEg3@JiU=W)$}i|aJ}tq(@{ZbPdk)uk0xMoJ!AW_eIv8Ve!USq0t9gP}|YX>&bmPU#J2RvMl)wPb2aRWAzM>Q_*IWe5v1?Je;zqaT^kjKx%02uxI-R~ z+(2_kkhjBcgjyi0(|UnU7A@LVq2gVNCfKC030{&KeDHxB+anB2=QJ~?B>agV z;ft6k;lU5^qm27>MjbBkVdm_!FKh4FYt7GJCqDpe;0Z&vt+;YJO-H!h?cP9Nq_@3l zf-z+F_yMoE+}o+W{;(%H%ETzccrdKk;_g5&uogpd-SHgtjA67~*|K3`%z}XwgVB&( zVIzTL3L~%?(mO(h4Wn|ZAb@mm#%+{a8YzP*iwdU+Sq>D#?B;MHN7ml>jz>to;Jvzy zOPD=1ZTm1#qGw_*h0Dm=NMlmtVSFlwlMQzjp@a=yaIfo%ptLFF{-9rvrG;JM zo>PTy5Bnk>jMCr75JFPwm6$7nXmHnUJ4(=QuA*q6fW^rquF(d=?H504zKaK%!?hwC zLy1DP^B7XpPXpYTCbisTn7Ls4CMpbOU(?}w8st2LX7UzpTc~20G|}S@C1%UKF zlw;5WXf&;4vJA3Gh}HaC literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/StaticField_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/StaticField_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..a937656e58cc3afdd035ea8c5a8ad8c3784d6107 GIT binary patch literal 1013 zcmaJ{_?A@nLuF%)R&Ak8^(hI{5+MDIPIoT8b;H)3AiyJs6Dqi*ycl zbTEe05g+ra&7EHL)%zpSQ95D_bKW$g&Fzt3U`>X^p5<8T2}7(@Zky0CYd}MiL95HI zFcC*0i5Zv-3q7HNf?+yk5I{_h6vN8?w4NoauU*TbI9KpN%|r@IXL@N(JS7G?mXo-I zw21{Q8U&xApl4DlPq}>fLa0O8^%#nOXRw^H?29VlT28MnoeozG-ciz>=*Tjx4tQS# z&u=YtNEQw1D8l$y3Obu^B18!aJm*f=7G7~*%Km6ri-ZMLqAzC>-%N%g>I}o*MG%6O z*UFKn5Ted)yJaasyUAnCKn_eM@YyVkeTH@mY!(G_m6}ncu$~WaElpau z&aiyJ_H}GB=tG|l+wnmn&4ds><2O+0m5 z*DqNb*(7cH&(Up(PDW?E@(spkGJvG7#L%4%-HBt&*K(gi|1I1O{S|_b)9ZSwvX}pY z`D3iS{EpSfYbPiIyV_P(`-;jR+%0T}d8cJ_loYsQs1nc&?%*z+1_j>313W|)m+9{J IdzHS8-z1Xzw*UYD literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/StaticField_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/StaticField_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..b4de8a47e31275e49fd540d94b6e773e8523e4d9 GIT binary patch literal 1003 zcmaJ;7=AL`*$GJa$o&5mt98VasEzPyv*|&w$JsOPsi;_n> zCKyBdgpYa6;j&kI{ozD(w22tQoHvbVb7v$NSd$^KXG>c@V~CY2?G#MRS}>4gFdC{W zQivmw#0*jl3q7HOgkd;E5J60hG{ef_G@q?%Z(Lgv&J}!6Pa%z^3$?T+o)!ZW%Sl{A zhFmX{(w=tt@TJhls_QY7{#I_wvFeK&vDvcMP_o1IKJRGdPE4#atPXfz1kdkmeM}a$ zCpB?=DhKsU`wv-y1P5Gp9pRM@mFka%^$0A;5`DQ4_;xZBQD+E$A7KavU9Uu*LW%}= zoR+NxO=Jx@3)hifOkkbn7EHAG(bupz_I24UvRM?!Rc=O^!hAkKF+&@$!LWSA%uU>8 zFo(Vfj`T?)#e@{T&YQSnp@h4n^MKm~%$B2_oFhqg?~?2W)zxOOT59BW#J=s&Cgp=R zE^p$tUm!!ODWz~54);7k;%xpS@Kw^7c)(EjKh(q{+TcJ+Y|xq-G#Dz)-&(Q^vT32| zKS#GEIvJhu>UUUQ$N-X9z+&jmgzm&C=Igo7p}&G^=&ureoL&p*>R$dU=1;Nmil9%| z&u|OaHMZ7_Zz%uay@&f@+9y A8~^|S literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/StaticField_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/StaticField_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..805cdf619bf334b1684ea11ab8d6a9415e23af75 GIT binary patch literal 1085 zcmaJ=T~8B16g|_HF5NB#iUn;Ii-NWVsUP^oHYU=fkp!YiO?~izjO|z!wmVICO2R+! zNBANp+VJ2H@JAW%bQfuX_^>-O_v73<=brif=kynV*QhYe*A-Vzv*rl5wb$wEgY@<` z3^0b71AfHIF8A8yx1SC~QyGXdB>iDVgS&mfz_uCU6~}YbD~4#H*sx$=(nJgihFDd$ zgoO#j6NtcKNVSCu3Wn*FK>#WLf;m>$)<`p$H7PO8km>duFH9ZwI?T6lP1lMbL$x~G z@#sE%} zW*I9c?&98b9QTRAV1D_}S~2+}t%A)wn?#XZG_?_=ussd1nkK!iG0Y8_8fV|YI)gEs zuS)~Wj1mz-Xe~U%BNJsjW-#lr-)oARO0N7n!`++BC p;q;!u@P933zhf$JN3lWq5j@2+T1^Ukflb)-G?wVB>lElK{RQJL2b2H+ literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/StaticField_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/StaticField_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..79035764ee72a94fbe79f69e6683304d6a7e34d5 GIT binary patch literal 1088 zcmaJ=TW=CU6#j++Teb)-E!09qs;yGA#aq1;G*J>_lX^)o^}&Z`T*h|GvP0OR3ID_& z;fpm<(g%NlKgxK9-NwZ>KJ3n!bH4MP>-_qC`V+u&)EROu#g%O}ZQ-={y90fZ?*5hm z#xQ%tk9pPM?m_j<$0K1W15*q$-q>T0I|ISMb{OJy+qKm*hN<%UUJ?eTO+=Akh&E)K zFbfuUtbxOo@Ph@e(ejRl#}H2-f)qpQK&S}>@ezH>n@}f_!6lPC<|&{YD2D9rI8j?x z-}Y^nDEfkTYe{60n<%0+^pxltxSYTe7L%C8oaQMI=!KNZQ+?ihCDfs8dkm|8i?`il z*%4LZwcUe;bS}NJ^VZh=Cc*)(iBfQmJ zDLaE+Ed=wUgf$b6?}j}QHU{tyAqIa|we^rHplEQ%Y1v9pZ%SA(aTV9naa^Yk`fV?L z(rZvU)}!4nv1zQ4iKY}{3gT&kn;BZ7GQ<1@-8WESFnW3%j;l$|Q|Q^>#)gSo*rZkI za+`p;a=4Npm_{c3ncrhDTXN91MALR?wF-XX|E}+*PKhD8>k*cpE}vo@*p6;2MZcqZ u#!K%e@XH3giTnun^WTv6AyarjWD#uPA)O|H9%CCddM#JzuIpK)@5UblnFl}s literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/WhileLoop_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/WhileLoop_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..9904df72ac43db60d926e4bebfd522b5a72c04f5 GIT binary patch literal 1144 zcmaJ=+fEZv6kVsC&P<1Lr(m&Q5zrQdikGS_kZ28&1fod^nD_vP;RJ?GXPWjDgJ0q+ zzW6LAl3?No_!0Ui);*m`7-Hkgx$M2p+P8In{<-`C;5nW#jO-j)w%Bmp`fjZyxwKqo zcS!?d7&zu9Ja2R7F#mf0SeQ~nl%c2Tfy`}gw*&)QPap<0jtDdcrR*M%QC~J~%dzAt zLo}P)W>A+q*8~#iF`%H=Abc-*-IioXZgc`!ZvIWfa%4p|1h1767{K7QBr2y(DQX&q z;~2pZxn8)gY{~|&Zwh(j9yA$du2Qy~6Spez#AZ2%W!EveT;ry68>bq^7{+S6Dtz;f zC6DMtbvcqaK4$%VI)w);et=ipIj}`@hMHAv)k`6mA0=$L_HgU8F2c?L{w~Deces=b znF5M3x9y501$88aaRWDSvtLD;VX|V?>bA(d_Xe1;X@bR!>9!mx8kv<0(=kcC&8~+j zgTNkBW{4Cp#W38Z`5LAfw7NG9+wn+3Sp^ii?F43V$G{Bkl89cq3*j_A_zC2Oz&bI) zl?DVF?lJUMBsZ&@yuQWvZBmX>;}!)R&31X<3CXCqt%fPqs9=UvH{~vRA^QoY1Hx%HHm(#f4vmA!(h7UD@Y89!_P@**-U()t9^ zHf5!1SkMshat7L%h7uUa()N3yvfWf27iYO zx4Lny3r$$~1N;#t{t@e)&KQT-IE(js@44^XuhZ|pF24bIj7JO;hfUiNyHa{b?T+Hg zmhRDt0md+L#?N`h;qGbW`N^56D+4J8eZzKbwZ)Jsl@D@ALpPzpV9=_vA;>K|iXp$- zdu+?f3*UBCP5FYi*K;s&?Fw=2B2c1jU@(gzJP~26-@vaor(`zPXi4r{HZo?75JPn}L z@zxVzQI@3V%ESE&Pb9%O{8fS>n%a6f;fg7$+;M8Q5;T!Qy6m`0_{Gg4%iucAwzQL^j1z}UH^ykI(+uN%hHqeo!SKRuIBrOis4Aui z_jwaV6SJ5jVLX*f$uizV1>7D3>*Yvx8WR|}!!TG=yx!X5-abEZNDx|^+mvv!)aOC@ zfWfTEj$aqs)G&k9PmRlAI}EuU*A;%%;Xxp1rwjk+qTfahEYno~A8OzM={iyX<}g5d z4!;3vl;llkmaI{_8Qtl{ugH7~adMZj7{hNV+$7)2)W)=SyqVc5%zVJ?XAG}tg-aBG zwX~&K=`XldAoyeVXKGasQ6sNkVu9d{Wmp-4^SXAts_U!Syq?d#@BRo=F_h?hh*X!# z(GA?Ce`ol0samaPlHCm}_+vykQn*K91GtYRx=kXg5X}lKjF3G<$Q1dk-Z}ppoI(gQ literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/WhileLoop_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/WhileLoop_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..3bdf88c556f5aa5e856ae29db19199a7d20b618d GIT binary patch literal 1137 zcmaJ=%}x_h7(KVscG{t()1Lt=f<-}FEUk*pg1$YRxxZEj6CpE`zaAdYuMFP~vCK8qLNCAW_) zqc=wlX!ScQfooorpye8H=b~c-o&NRx0E5@Hl~TauQ`ER+HB4bpN3zH%$UsX)F~Km? zFxwr=D7kJ8%^;;8*k!tzp{Y(WWJfe##x#T6ai?L~ zE=eFOpTeEzZ4?yDV3vgO!dVQa@y1KwZU$@^BUq_VAmbiGXn#{iks;X-yxH33ogIE; zkubt-Zc^Zh;s{`AmqBSb{ch9Ppu!pQqf}XO%VJ1u+P2ZHS-jUXXtwkJ=wsAmWjv(r z{{O0s$E0sh37AEQbnSj2Dwt$WYn)DL+8OPUg)fMGa{Xj}fU@uY2?;r}y$!EUeO0!l zbx9AGr?qfh(j#RpQqiL^UDl$S`~hp9ky=(HJyzCY6+N!SuW$=k9?L8Fu}j>M^h8-p zRPxF_@SPnvzDrV99&Ae>VngndWCtyWb)~JhA^5MKGfByp4C(>`+o4l&5vP$ z);gpCRH!oUGZ`g%-obBxEyVt~nCl%--MQ-~58)#vEYdlI3aYd#6y_0@@C12^0(#6L LOp+}>T<3lRqfQX; literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/WhileLoop_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/generated/WhileLoop_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..5b8b1f48cb7ba4e30affa00285a7cbcddcee55f7 GIT binary patch literal 1104 zcmaJ=T~8B16g@*fX1kPc7Od4;1hhqeypgxN5_8&sAL( zh|P9S%F3+?y(MZ|wJta&7-k!yE(3Vq)~EF5Y2j+(c%KXU>0YMC5)^nL++#<23p9Xw zySW}p3#x>XzJt3LO&JdM(%*y_f~l?NLr{;REF7n5Ye^HC!nBD=SYvU_Fl4HBqv^=( zTVIr{L#mXrHPv>tY-OKhnSpCG+uU}TvRBw=x;{y&rWvLN44>mB18@3jIId3;>Z(WK z>v;=V6B*2rF`lcHa2xM}2IeQhx;4T#?GbR?=~uTa6i1F>q^d=&UJ=b*apaIqq77kF z8#B29H2FOSv#Q#yn%tr>Fr)@~bk)BkLvq`7WvlE6&y%F|;y-Q~q%+5Tn)UxvIUbVR z17BbcL*#P*8KUcx>1j>S*97g1_Sn)l7@z$(!S}G-3xB8dBw;eL@daa*^d)WpFPB%o z;^K3?%yy`tQ3>1S_-;VHE}1 XO(K4PM_5A&TTc@~7(LTnx@9R)3Ii>?{+djf8Bfs@EnT_1N&!=Yj62}<*-~=QaQeN zxM+Yeq|W7~EV$A;E$keh+a+Z{V~DRfo}<(}&|xs>>;8#NuwPdUe5>i~ z_=VS1$5TaBwPkrZ2@_p+h>KS>WtR8u6T;weZhXY*7xXTfnn>h$A}>05=MBbyr7p{~x~_3g6UiJ;=0&$I zdU!YQITF2e=DjKpH@KH)`jQ+;*VmvM;_&A^V(D)kE#xO_g8)yxrkTUR)8JMM~ zA^J72g~T5d3#<)rOx}e;k2dbquX!@YkVk=blVU!`Q#^x3AwjP~3`2xj&2{=Wjx*IsTh(kr6biEL#$BTO(TW02Hn6QjBDYIb6*LYqTGN$`C61ny5((8I;x>O!R<

(MVsruJV<~+gm~%yDdM3 zIeLUfV857UDJ(Dyy^)89!V^wYM6LoA+VE~&TNX<5RbtGVuJ(5~FPJ<>GluDZhtjmWec>J^ zX;;E;fEI^-5R!Mvnxd1@nOOV*_LUSyE=1R%p2jq0=nO-@AWk-L6#uF3#j<+67AdLv z)>5prwj3*&@u__LlbImdGLs~aO^u{wroKVTCps7czGEabk{yg+8d?XpFO5_O6OnO6 z#teb9LfrF2ZxR}2=?`8Y?=p0(!oVwvt099uT8%?w2{B8!0qXreos)!KqE;S6 Vaz2s|BU!`>-RpF>il;C!@fRqo3Wopy literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ArithmeticOperations_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ArithmeticOperations_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..f5519ba4e0818a43f6badf557dc315e0eb86457a GIT binary patch literal 1108 zcmah|ZBG+H5Pp`vTzed)6bpj#q5`&nt)iZZH5jZRk`#+6!4N;-(k`%YFU{Q^3ID`@ zVf2G0jqwNgql|M`0wpwZA7*D}=b3qCcJ9yL&Tjx~c%fqeF%5A82_zY^$NZF+E$$qa z>-)!|sTh*4q$AZTL#$BTNh5`{2Hn6Qj4R=dGhYdtqTGN$`C61ny5%iTI;x>O!R<

XgEcXrymkSNY20?M+W5pcLmNPh%Q0bcUf{5hoisjQ`SiV_Cgkif@d%>@eeMQ3W)#! literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ArithmeticOperations_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ArithmeticOperations_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..80da677c216abd51ade2a1e23f8ca365b1ffac16 GIT binary patch literal 1155 zcmah|%Tg0T6g^EQnJ^3j;Uy$IRL}&KsAyDzlo*RLRlKZFxNw2Zq=A8%p43baRs4i& zKf;YJ)XKsS@S`m6Oh7`B(#?JMx#!;Q{`I^06Tk|}2D*^Yp_xb`#n6AmPk7Pc@}Ri6 zcO)#ukXo{(t(F-Q`NEEYG`e*dCVF5pOs)8~I&_7yt<8q;xw1VO?7E?ft=$EN0gF3U z=x`<8hMuy8B*bLCS}jz&aSeSs`b`WVbE$LfG*H5&hF(b3!)q}o+beGQwp2Cc3+|RP zM1RP{Fh&?gU4ASop0v1nM|8*v6qhQXv-xVFbvz!4&f4;TX1`cFlt`t zTVmCYif8__(fNohZR?fisX+O>u`bl1R}a$2(^b_%cX67fF~`vR+TPz6zL1uPL-(lB zmhaU=OU3>?L(ln@P@pe`2L>MEk&cCEt&fSy#apoDiFYiDt^Kt&y~-`+`KJt@+ShYd z*dq0Y%eo_inKjQl4jbjG)3-$~9o#-`hz{lL`)j?#Eev$-G8OR2BuooHeZ_=ZukhqWd( zICqjwO#XFJO-#kkMbCNqt`WTiG$NR!-YNQhI>Dte4goS|43W(fm?rJ+a_cVbzH<=t4`#}mpMlq=yG7BTh*LbnjT literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ArithmeticOperations_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ArithmeticOperations_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..73a575fc8b01fff04cf3eeddf7643876c70fd1c2 GIT binary patch literal 1073 zcmah|-A)rx5dIGR*|IDJi{-CHP(fQ%s)#kQNP;y)ViimYUU-3r?Ewz#?rC<jIx)<|5^Uci8`TeK!3&1*_n;1aCK+-}AX@=2be#$Ej_YNyt z`^Uo84Cz(rNxjC9D3x~yk-?w=)4~v}E8)$vKns_mR7gqrMqEg$%C;{(-PFF|ZY@Wc zSqmc=WtedJiKr{j=K7=5MG3!Wu7q>IcSPHdW}`Vnas3^Z&tFiYB6!zEVmD+UM=dsukKg))yIuK7>k3;YEg#G#;9Gge3!&X!nn) zmCL^@y;F4}D%~Y_f5!&5wersxzV`0$Jh0o;8}79n5zIG~Itkmg>(lpGt|ac9wMC!s z-u-p&uGV`3=Oyagahg(#8iTdzdBU$dJP1T!;3>nxwVC?0YTy~et$&Bow!3rTHm2!T zqHll>haL#gB55>hjW{A`OcX$zyEZ90a(XV0|Q9t&`czeVi-B%C%j~F=de`Y zKN3yFka{j1sn!@0`ND1nX=HR5CI(?%a&MgaO4#J(1{5@2ixNqbKXV5!g zHOmQ;Tuo8f&4D4Cqn3#zkkxU6VQ$@{`nFKAS?>ssD@joH>_A1*-V+9`>b3;Ka7{Ym zOvc;*;`dd;1dCH%#j>mCQ4%GK_BESCazPCKHH zd++?>y{q)Dz*&kax2%R#qQYQqI*#zF7WaMO>v+Vlbfu?$P<7CI&i>n#rXBZ%TbQO@ z3C{p64t)@!H%Xfz&WIri#g(<>lbLyiMO?%#{0yGQLjZpy1uoN zD6S@opVngDDr>ROE+=EbDyP0dpXp)<_>NJM$F(jd&y{2s*Uyzy7gLdPfu=}b6tv|T zLNH3;rwHEyVOgOs{1^sa(ES!ne4qk{$dczg`43Rj3&f`>YK3~Z9nqzT-i>Gh59r>Y KyN8sgjH$nUvg9q^@ifZ?##~RoSCz)Z%;1(TG%j=f@VOskVb~VzUH^QIpXrF>GiMufnvz)3n|ng zgI29|3}mUO6-9i~3u48U2xV_42NN>}EDN)k`vuaTjFlfyZx|C)*`30Ruz3~rGIJ|jGLrmBpLLoQ|mCyI;YOL({g*AmV0r`z#NJlg>tO8R2@Ew zeT_CGJpCvf`V4tjNdGhr`hIlI`y-0z0T+a~P`&&ZYq~YfB;?gz!eF+;I2!mTA}KEa z-MNvBiA@+JAi%JKG8V`#(kq1}IxLZt?q!OslVxPn+mB#(pADF%lja;&vG!RSK%YV$ zWS-5gW}9ADx97cX+OBx+J#uxe@qm2d=wD7caq7A~^uEJC6cw5f$da}*L}6iz{-{BU Q@1lTx6p3`5@+nl_0k1u0$N&HU literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Array_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Array_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..306cc2b3e98cd638b8d11b553f86b9c98821dcd5 GIT binary patch literal 479 zcmZutT}uK%6g}hay1K2o`O&8Z27wkR2tBER1VJEeUZYW#nlu>LkF_X6Pp-i4sLW i7W=e#@};>_D3Q?tEYy%e0}hU9oh{_Zc#AX%Y<~jhR$a~j literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Array_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Array_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..f31f4f59c4585a70ef0ef5c3d874e522d657fdf9 GIT binary patch literal 571 zcmZuuT}uK%6g}hay1K5pW!ksZLtq8^&_fSOB!M7E8yJH0Q0uzL$bQte2L7xH3L^Re z{ix`UT2}Njb7t;2_nbTP{_*k#poT3CF-R(89SY(M#=yF>%C6=2%Vu}r*bzg#%6%Rk zF-XPTb`l9BRcJa=(0|cequa>wh!qS;lxvO~@t}MbazAQCp<{U!4Rgq-Fm%jgfg$@3 zhe5p-3fE_liw)tph@6VNjwLLUV=WA=(WN(xtcVBxhF5SqU#i@0^cri&h9+l#8zhBvHGbF0EJDpc+1;fyG>Rjk@e|<|L zJhmxaj9!u z^rNCXMn%y)+k%u6si@eTHj+X0B9wmAib7X-H50SQ8L%>#!#qR& z9}a_Ytt!So123JH+Xf1xQx8Ki>3VS_A{qGIJ-R#&1};OcDSh`m_Ihr3DSBf%;hvCG zyimIO^e}x48Ib<4R&FzxtsoBjZbK?^@o!^WdBP_0G#9lJU}`cHi?my(%qZ(SPhj^1 zNQa`jRyd7CEKyd}J8)=}Pm(WYN3%?)!>xkT(X9=q`2eG$*^kI7z`ua50H3l4&RK=; nYPR!D_z~NpFCYixFoiXe+=dAoS?tqr50OIy7Fk#(P68_*1WjN5 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Array_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Array_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..170e7048c248ff83ae2c526ed6e420a9b51ba774 GIT binary patch literal 475 zcmZutT}uK%6g}hax;m}7rS_fBL!b%z5It#u1VJEeU;Loauf{1=V zKPtLoR20p_y=U${_ntHJ_Wt||pp9*g6bu`t0}E*ecPj2gV}Lo zgHfsWvdAE7gF9G)^NZe{-^PAGtT3UWQfIM9hKMlr{UOV$akdjFOp#BM^|Dvqly^_NyBTE z>rW4h$B+T3Ce3P(fp^0s8u@2ZlS_XW*R?0?p+NtlPYO)`48;=Nb}2K;*1;3lJpt08 zsM{K6v5pPOni{}dtT;};@V?=4uW!0VuWz|!uk!%AX4D^%)4==!mIgJ`9edy9ABi$- cT56H640cFp9~^b$aELrwa7lEN`YCLE0BmkuY5)KL literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Assignment_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Assignment_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..7a332d138ce04f144a33e17960e1fe0aad7e56a2 GIT binary patch literal 1471 zcmaJ>-EI>{6#gb&d+p6Sah(`&Na&UZ8dHe*X&o!^O1bae={j5FE)o<|x+9K$O8SuVY$ZxSL{>LNk6;rYe4_ zNgRf&DI_WRl##(@ZSuJe_UBZDfhiMLNxu1|hv zo!H+O;Um89(TU-6mx^$1>6h_XYr71^p5p!EhkTIWP28Y@ra(>9&-OTJ1%uTK;;=6| zuJ$#T8r-t(4;kMJ0u`x{4;~726dXi(e8o`i#l90fbEsG1P=ry_VR2k*Jzf0wVGRm(Iq{rW1-N_Ee%;VYt$9!$>(YDFAUgJPi4X!=EV;I`QCuE6p;U z!L$``@0sE=lCG?g9RS3!8f@cZe8eguxPxzFW+C!)peAUKW( zt?^o)Iyqzb=wu*L;HO(Kx_+(GbMcX)%{{N@D$$}kZAmG@w#TDLL?*tcVvOaK7OIIK z7%u%kly3egFMNh8G~fC&L6?Qz36fvXzXe(ut=Vhuz~0h^VTq(x>wN(=T%(nstOx@| zI(=2LR!Xz07w4a@Ei{ZjU{;KwR{V)i%IBNeaozB=lbPj)O|oK_tfyT~NGC%q zCU70|L=y7@dR-_Hx|2Ej(gR2DT#+)EgH7&>xQr>>ps8sRZWS|F$1HxLm*`hqK!7S@ zLjFcUzr;MgB&G#Se83JY6W1AiOe~Lnj7qakgN~bt>sz=@t3!@gsZe(k`E??{N#wVQ QY@tmkix8XW;6AGV0y76+M*si- literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Assignment_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Assignment_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..e634074a3d8ee899d01b5db08a4c9fd234a327e0 GIT binary patch literal 1489 zcmaJ>U2hvj6g^|FJ@#gs7$gbD{(MQNNXflL7@-r#F-@9?9N)d z6z{sgdrFKuLy<**#& zkY^~p6t6_x7wWj)J$NbmnjwGJQ=Y!hkX^0q6;VKu!*(zQ=K{QU7Hb(0DjbqiWj7)6 z!unT{r*uz8QUt9s#hi99gA&7hAWmgFRDGep_VfwOVl9-8$#-?THg->RkgunXTQf$%5^msg)nYOU=tTQ#6u>*JmqcV|cRbr_v7{B*vsZ-C>|JQC{A zm+|s$7@iIXt;w99Te;x)^lTtg;O9#*{ta8_`{NBoTljv@)3QZ*+Ez+NZC}K(j5)rb zWK5hXO)AGW!`1(X(hV>^7v8}Q>T~mC=%=Ckg6wx0i(DZGYLDZU1`eukB8*oMO%kygWzH&LwazLo3l=knd=RCOx5 z-f+lPoRa;bYY1s&gyjTov}Y3SJ9OL7fk=Cvx?mu563T~Bt4{-$E_sz$M}Rs emqI_Fl-*A3r-}V6v8}}3qo9CIhz^C`LG@p(!eavf literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Assignment_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Assignment_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..475851d80bbfb2bab7e05ba4ca720437442caa06 GIT binary patch literal 1480 zcmaJ>(Q?~F6g_LpUR!Y!*NK}tG(nU!#4W^>f+=>JHg#~DlGY3^VL~6;jk8VENGp%D z>Wp9c19+lez%x9+jECU^_$c76+!>OwrXJ7T)!uW@J$vt!{{CnD7l18%Wg~+uhgCuj zd4}>!@k%s2p^h58gO_rk8S=MWnc-$iPzufTQH84b zt|4(4)>24P?o&Y)mrcm~M(p>g2n(|uYvkXGBKJu7Qt4-Ytc7+1_3Q@Sq!S!UhPho= z$;YvOAj2o(z@rn(7cLdy!ur!`t@S;IbA2raCy&H1!E<~>1xlXEFmXw-9qCXEA4z>297Y8+87lqQcY+rV^-LbgFlsrhfSc48 zW;QK`QaAQIM+sjhu3JBL3zd8O-yk#bc2UT7IQ z@$gV+!!no0U7IHV9!JNNf16?T|Dku)tKdX7CNnpg&aN2fARICLe7do3fRo!i5bDsA z(dupxoW#TSbj?qloC$m~8p;&-=~hf$!}jUVgUHt>>SK2VFlQnL$FQSgC zv=Wrf!a|8of3p6x_p@cYw_9GgeJ#6j>G|ew;LBs21AfQ(%3{l^)LOZkRm+X>4$#Vz zyOtkgCGlHLo^2MY{549|!fSBr7g*V5kucTbm~@S~-1p3Y2yRm+5JZ1YXB1HVLyuo^8zITP)xJ zi->R$Bh>H%mhdBqzD6u7$oz|M%qR0hjt#~*KA!v;)#ffuIzCDA-oU4{I+XPeRqC_E YexBGb65CGfZG1^6n-E<*z(dsj13H9aC;$Ke literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Assignment_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Assignment_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..2f9de3229a635fc2d379552286c66885443755e5 GIT binary patch literal 1480 zcmaJ>(Q?~F6g_LpUR!Y!*NK}tG(nU!#4W@WiYa!RHg#~DlGY3^VL~6;jk8VENGp%D z>Wp9c19+lez%x9+jECU^_$c76+!>OwrXJ7T)!uW@J$vt!{{CnD7l18%Wg~+uhgCuj zd4}>!@k%s2p^h58gO_rk8S=MWnc-$iPzufTQH84b zt|4(4)>24P?o&Y)mrcm~M(p>g2n(|uYvkXGBKJu7Qt4-Ytc7+1_3Q@Sq!S!UhPho= z$;YvOAj2o(z@rn(7cLdy!ur!`t@S;IbA2raCy&H1!E<~>1xlXEFmXw-9qCXEA4z>297Y8+87lqQcY+rV^-LbgFlsrhfSc48 zW;QK`QaAQIM+sjhu3JBL3zd8O-yk#bc2UT7IQ z@$gV+!!no0U7IHV9!JNNf16?T|Dku)tKdX7CNnpg&aN2fARICLe7do3fRo!i5bDsA z(dupxoW#TSbj?qloC$m~8p;&-=~hf$!}jUVgUHt>>SK2VFlQnL$FQSgC zv=Wrf!a|8of3p6x_p@cYw_9GgeJ#6j>G|ew;LBs21AfQ(%3{l^)LOZkRm+X>4$#Vz zyOtkgCGlHLo^2MY{549|!fSBr7g*V5kucTbm~@S~-1p3Y2yRm+5JZ1YXB1HVLyuo^8zITP)xJ zi->R$Bh>H%mhdBqzD6u7$oz|M%qR0hjt#~*KA!v;)#ffuIzCDAeu^8kI+XPeRqC_E YexBGb65CGfZG1^6n-E<*z(dsj13~9vDgXcg literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Assignment_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Assignment_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..9e42e42efa1c98c7cca110df58433f18e18fe049 GIT binary patch literal 1479 zcmaJ>Z*S8^82?@4#EI+BENy_47CcsW@NKs-6l3_giJ!^Nfutlo-zW{7AF|+2`tss}5-vDK1q+wu_s!k$K_=*}C$eWuc5| z6Eij{ILk1d!p~q1^lqNiB;ypdojlGn7~cnnGLKpEbt4dEFwAM6<{9p$7^TpRFO?~a zmo$mPa5aS_C7v=exU5Y+)6PCkMHo0^;wtIaqsTpwzL4sLA1kihK)$#`k+g$-!7#Pu zO0gaLdm?b&MrP1_qDdeQ0yt*KYGXq3Esp_N@xnyME!J)lTt8Py&w+z zqT}klW>cM8()A(ZdqJQg74pGDp$>!nD399=)^*zNF)aMw?5=zh9Etj<*G660;e8c^#|*!oEa(T|D4GXc?t3Cy*b0K9 zc+eWp^@){JhL4X2A_ac31f%2EI@uQ=DB9ffdae>J%G0KlB5Zp+ibQ1MJ|$x;rZiVg ze8+I{<4`*Jqqy)Xu26sLXMzq3-4i6Q(ce6cjK=KszrcQ{3Bw{ut=97bYPe1#L0JXV z%e4AS$yzSWtX!CTxjNr4{(xCAhA0Am;*;{ZX0}{y=Bn9hZiov&(9O7c4HyZg& zqfp7egA!A+fes#^`W}^SU}pdT literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/BigNumbers_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/BigNumbers_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..9dd2252923ef1046669d4679742fc0c9604cb8bb GIT binary patch literal 1932 zcmah~T~ixX7=8{}vLPf5Ecu`X+7zKCZEdVp2o0r_U~DS1)gaYYr6*yVZrSX{?4~2m zI9&P%YIPjP8+Cf&cp(=$lMB7@jtj56(;wiSGyVYLdrlC-5Mg)bJ!jvK=e%F%-L37$ z&j7BW=tmbkDwF`a;brK1#2@pN$*pqgR`HQuav8kShGn=j44y=CS%r_Ge@`iIxq4Zz zc{ZBOrYG~o7J3jsP{pwTLg?FvS6Fvky+SZ{olqkS62!1mw`+#w7TlW7D;bTP(gGMj zm?2i-YkJnUO5D9;xDRRPxZH9bvQ6ZZEpzE8*&0?k<3|)R6@vjB#|egk4)_deRh(v8 z0^}e>a#;hzuy9~RXx!~^jEYkX$M!O?U|Z#G5x#i3$^XB8|F#brrFC53oDn!TI^byV zU|2YtBlg?sC_#t(A)mO4eT0>5v7((p&N+ zPA-$6!VOAmG;yy}UKxS~mzUNSc~$DGn4=PPP-XBJ?0T)F=L~^*qN5uZM2M8QIooy} zx5lfBy8F;xb$ob@VU&6@UZ_{%i3w@NZ$+c_i44=2(svX5vajtV~ z)zqD_1>0V$S2G8jq>Z!BaB01&cTjKdoz|$zv^Vq)M3$Ro!Eklz=s@1G^jg;Bj-xv& z-ls|&h^dpSD(*9!JY1EgWGgP5#$~$t;_0GMLNk@9R+O`={13t@*DE4d0*HMDIug{lJfi3=Mw+Re1)*GocVaqBJlh1!2S| zl`uvpy-_9V<&!>=Mtu#8NvYsH`RYGQzp(T-@cfSD*{R+z&QApgdk2H1sSrsALk(Pz zQo;Ld*Ro$&_BU`*%Ct*qO?xFh5Yu7<#dMftv2X(uQYLtx?%G9!U8I32DH9p!k{NhF zNTRV8^jtbN)p4)+^QRvTXO3CWgQhfFAARP9e6Z& zF{mQFuSRorqipK_^}pM6{)LUg_oI)0{Y-;`jG%i((9LzE^9j1w78 zt@G7+-F;v$I|01OFibOYK$jyeHJexFmy{gNX^ra*Vpuljd;3Rh}ruSG} zNv3E<(!%U5hSQ?KNAk^!egB`&Bo0Y!R}NU)+2jG&$N$S`+(+o#kK2e3}5X%RojN`=3L{} zvZ*^GMcZC!tY!}m$sWx<$Az_3y@UDQ*=b)@*}Vh3O_AfKSu$LmCOTZOEWMsHx#Q@L zijSxh2Xg8Zs)~CIFC1=4w`4mnoWdnK`r_xItAy@Ul2i0HL@T4!cjhOsALxPMGD!i8 z=OCtWg;p|UPw246N&BZ3oYF#<2L|s=Z=h?aiQ~YJhz$&W2UU3n#XF{uKBhD=Ab}{7 zvBOkzU!#g3oAVuVdfOjN)lD{!B# zYbp!fhJN}75TaVd(S>39kYwm1auE^o(J(`EIFA@UAk-iq3;l2~h)=1spW`H+Ac=2r z8qX--=akn5QuqaD@f*(J54=qNpy~#;==x@ChP5z(fQqa1!W2aT+N$ubig~?Wq29t6 y^LS?H!-brTdJb>UdVykHq>kmKye8#!DT`9xkn)z4??|~ov4iqs_z+9rIPou9d*k~6 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/BigNumbers_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/BigNumbers_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..beb99542f80a9b8a5560e56caf9f1acaf32ab790 GIT binary patch literal 1964 zcmah~+fy4=82_DQlMOK`WC;o7QqvY{LOVsRa%q54g4op1i$SVXg+o}=h0Si<-Bfu{ z{s3R=)aipyI(={)$3E1VjN?n+cyxT%N8gf&hXH9qar)A2zvF9=^G{u9rN9;Dlir-V}pBomo^7VuyCe` z(P;RykG9c<2%;)ZM9_|o19-(v*V8KmW7i0^s~|xPd-#@PSYFX{bY9776qFW0C*lmr z3g6IkwpHTZ9mBgvJJ;iu=aOwYpJ|%QK*`py%GodyNUG?L;3Rq&I$Pi~s8!+3v;@du zh|Hn}hCUHMztC7};YP)a3@7#~P_V6XK%_680LB03Z{K!6qp}VPoO1%_dJ7y4e)Orx z9H`N(U0XHv;MQMFxZuK*{P%+oo_(f4!LWdPS-{PU_%NPFa^9nae2_LZ0Dt-c9XlOzqRSl1kHz zWQ5vV3};1ykHwo8e*YiOBn%07lVPygH65hnvT)c|hlQ$+MkJhOhRYsvX5ekr zD5qATs#sw-b+jtolFhtu8kgzli^oS-3EingC+Mr6Rz_=J=qIorX~Qr{REWjC4O6&6 zE2*-d>9BVb_YbXYLJLp!_N`3yk0?*@LYGoU40wvJ-o9_3DvzP~M*>0+sH0a3;z*4K z<2W-KN(2)jJ{l%zB3#FSlnUO1ub*2+gk_|Tmv$_N#-nju7;o>6cDI+tV+_g&zyJQ{XQYNb4lT}zp z5A6eVBL?XWAx!m%678X%$vN6xLI=hu^+}q=S;TRhuKE=uQ6UY7GXI3i`#DbG3#9Of zTJV_i{SJfpfpU9_G@fAyzv4W8#|2E2rzM0MIE#RatBf9Cnl;El+s-#r6y-UO{$)}} z@R;B4Z}LYF`wyS_eAM=7`n@41^P0sQw7yE&EK*>8m)auUR_Q@5*z<>uY0&dX_yg3^NMMVKL0 z=9~JwZ56qD*KqIC&T+ZrI%J#3CY$CmP_i|wQaXSrVk-KAIEj9S-ZuCQYDIW6Edg>E zBDt)AVNe7xBs5mqxKZ&U!-@S08bgIIn=a#L>TgJ4xt88yK8p=o6 zzjrkFFfLFg1WKkYiYidjB%d=%H*4jBUUgQ>HJ7`FZLMBrQ0DD*ot)$hOK-}TIE74t zGB>EK(Zs!Wb!F(vyS%u$$SYD`#T>P$jVePRZ`Z0tJ!1&e{h67e-SOiMhBGvi@qDcuPn7v5%iOH#@$+$$S4+D5NM4CEKe7y`vrc?ZW2QypYCJ(R zk`!uhGMp6+J{E6L`2Bx8lQ1OUEryY1laGbG!!UdVD76YJC5$C_<%Zb zD5rLzs#s$HIG61r1~PSMv8t&CRh=ucoj(uQH0s1S>NCuVS! zR#Ig@(_!x;?jKs`lopsC7+jkf8dIL&g@{r|2zZLfz~DDfmB&y#V_qTf)-fOjVZ_IM zVVoKFM}1L09}kc;8mMDfN(JxX*Uv43!ZKLLOS_h%lU-q4nC$NB>gz5}hDh2Ms^g-R z3f`A{mc7EVw~kk&OuIZ0)?S;4#KN&iVIoShShS8YDHFUe_UvN9E>_2+l!+>I$SQ20 zpY~q55q5$&g+$vN6xLJuY=^=X>L1%z>juKG2^P$rEkW&Sah_cNTr=ZNDG zwcs)3`yEE`1LgJ<2|U9ne#LqGjtiJ2Pb=^@a28$_*BCv(ENhU1&fRaOD9Upl{mZ0| z;4zQK)8vmK^dCO!=%BXG((euPGOq=^PV1|b%`){hBk6TXZ%CSx^rob@C4EcMCA>#= M0kU}?tKc~KFWi9U2><{9 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/BigNumbers_mutation_5$MyNumbers.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/BigNumbers_mutation_5$MyNumbers.class new file mode 100644 index 0000000000000000000000000000000000000000..5d304809e990529f48c29db474abd1066fdcd51b GIT binary patch literal 663 zcmZuu%TB^T6g`($DHIff8jX+O`vvI2mBz$Jh#16$#;qA}LTXBz(AMaRZ!#=QT=)V0 zjDH~BDPm(nCz&&yx#yhw`22qV0C0l+6e5Ufh#80@L703LPoiQ8yIr|%KFXFyNF15A z=^YcIn_G7pl7w6sRI@$VmfdJ?Fc|1a!_bg1ki`UH>C|jD{7zGL-TRL33D0!w`-9c1 zm)}c5x+9+NgylyF)yD`oX5^(h0>m?0P=qKaVVrH0vmxt}|J(~^na zSIAv3u!tqrA905<%s$spBus?9Rm%}xtk)Zwt{PawIw3P62G7i^5@Ki0gJf>qwB@j@ zTfxSJF~+ywK(BltZ1S$2fhdyL`U^b_ z41k%u-bbo{d>@4Z=K7e=FZZz$lJlH}$|TM!&GZ~JmfGgK2zIa=UUw$`WOg`LhJLw}8bRN`hs&shY>ash-9QE^N|6vtnUQ0*+@f38c`Y5K$OknHVVGgK#<%p0ZB@8?$8aCf&T+ZrI^>(k zCEM;Y8}c=*jdTzvaZ1H$4QDXQaJ&aTgSstlGc5sf5F%NMf|3>i#DvAY9@q3yh=2Y0 zG$KnC*D!$#4BB25^0u`>Wmt()?GpkgDR5SL;6&lYm~X9_`+nlduOExLPijcv6^76r z*pl5Sn>xWQMWNubfV(2#mU_bVVNCfj_xG-Vn$|FbS%!f~8VLi6D^i=!3 zwO?kIS6sWk!|+A-bLtqjo3qTVs;N8iylrnaw$leEqwC}a$F-epy@z@CY_*9j-95z} zhzvK)qT%XkdYn1S((4(MJC0855!h!h6=mwmf&6-ft)j|s_Ha|;({_#+$2`4%@$(R$ z5c`r`ps!I{8LfR6e+K)3HjH>0QZ4oYEFwee0)3R}#UCTxA5nF#3IFK_H<}2YY2gI$ z6Gp_zw@{U5P`vY`7;WLKRGh&0w9>@+A%#!-NHOGV;iZlX9X|QG<8;kW%0Yh%7dvj3 zW&=&UJQAqP_LF9$zlB#jZglwhzT1Fs8))IGR7R&}LQPy74wYxZq!w A%K!iX literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/CheckCast_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/CheckCast_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..0e0dbd3cac9fc1aa4507e70f169df4f487e52c08 GIT binary patch literal 1167 zcmaJ=TTc@~6#fREU*ueODeDFne5Ur)UNih71f_7{O@o_fDWi ziz2F!5=>T4le((-o`Pv|7Q9t9kwMnNI3^g3WA24w`+(tIJ|=f5EEl?(u$-PyEL`BsF!${SYVk>Oz3x9|2dxRuf+$CL8`Hxo{RoG=PYbx{|vEfGK zT)*HeQOR_IZ;YfJGBZ?*-b; zkY!|(i{HV%(1I>Ay`#_3I)nSjlZ~jK$Tdawb=IgZ{X%B*E3Pg5z}N{Ufp5sM&1FKj z2+iK6ZFa7d$R!9VB?-zU&uN!Q7GYAjBnDw1O{u17%ySsREQU$M7#5MmD$VU0CWuoY a?f_v+WYZ*Rh5pNULOYXIPw^Ztk^2it?lI8- literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/CheckCast_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/CheckCast_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..5974d9b4bdf666ee322a011b9ecb5af8c202e14a GIT binary patch literal 1097 zcmaJ=U2hUW6g^Wu7ATfVX)9{$Rw+V@#qUHgCY7YA39TkH^}&Z`Sf*vmGDCJ}oA6Kk z8~UJ0AB@lbDC1qWS_s4qyZ3{8&zy5-=GX7b9{_goGKD!r3`En2A%rMtqtnw0^QA=l^%tJk3JlfJLHwv{}2$`Ea+j$p_%Z7B}@ zep|RlyzNjX+UGX$S}A>+)>b}dNVSyjT4K)*iu1F;cLK>Y=C?{|+B7~m5W1^6UIJwX zbC#%oDrzRn#Ic=11&<8u1bb3tC|sWuTVAN1sD_%uZQA3OR_>7D^Y|#Q3d5!Mx$HQ? zD>Rkr`Gfkju(8ZUWhs zqH5qd!}|YA>Dq+4uz`DY#e!!JEVyL!-JocVEF&A+`VRJm9ESV!4gL=NBp#qZHYjze zHBPpcHJV?M-2REoC2j)Wu*?oB6dh7Fdxyg8S}mH7Ql=K8R6h2%>>9sF$h0UTgqS5i sM^`tGd0J-yo5;`}FX9z}M<@y?7x9p6f|zX4Tf$?CQsh0sGrU0l4@X-b!vFvP literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/CheckCast_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/CheckCast_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..fc52796a7b7c974b47d7d83cce6b109267faaa26 GIT binary patch literal 1403 zcmaJ>T~8B16g>lNw_OT_@?}MEQNXr*R0Ty_M4<`Mq@YO~eDHw`+kr0K?l!x#Bz^IB z_%qZ8G&~re{ZYodZILZDChgpryLawA=ggh?_51P%fF10r7{H){P#j@I7)H7d ztO>ndoLi*=pFicZ6FKPQe?6BuQ~AjudV)OgDI46m3iA^1UHzG;<}lq|2}r z#MWWh1EuRyaR;*s=Hj>ujbXgar?()3()7!l79r}Fm1Mrhuu}GPUAXRvXPPa|mq}DL zix!$APJ|;YU1-wQI(4I1U>Mo4Y*`ad_gGXc;emp592sO864%nUg=7f%NpCRgD%wY6 ziZ9w#I;BL(u*8AaI2KNYADiR}HMl`!rqUk*XLF^|Aw#TeoLXFZ4#gI?D)~TEx88P8 zhpsOW)dsv(sT8&g85*f=%C_g|V$bl)r~0+lnopN{Vb`{$D;?h47qVto-6)lqBS;b!QGTE!?fFh-AJlCaQ|MHqZ6b7Xxwk>%_K7C+N0hrvSNFv2Bdc==;(c|*4 zxV?WQ9LVi?R9cGE}`X{X@^Ha*-9wC~D817?qF?G(+x!jOSs3nLiq{oV<* zXi-EJQi93qX;N1e-%~J6&VskfCNjuc7{>&Iam>9?Y#%V(%g5v{h2=sQ6lX4HskkW% z)40ws-QrDAQPSc1gR2{~3N)8G_$SzzXP;muZs4YYTNY+8%P`(YElF%g+C53-bW1#s zN{zD_mTRHoh#)u!J+EUsoVrlAC2ee990*@XN7!1~u~Qm%7>3uS(hcEXGK>oQf!5-ec|u$eUFeti@T(2D*y3nqYAqWW=(~@BR1TK zoa+~SB`TRt@QqSB&^~W(3f)lkAdLqMcE6%7swmlPB!!}hhgdc6C_0nJ4D*-Q%$3Kg zDT;B;@iA?1M=QU>@VUE{XT&)5TQ2LK2&lzU_Po%tuF(tJk00kCL7>AgU^ z8M2IQa`8LZ7h2F|rg!u?T4!({d9o4p6S=0yzRnuerC-Qwe#Nz=9~e8qB=8M6wz*8` z7NObOw9U?y61fB+r6fVQp!$s$Y&m&70pq$$-jjd>13n8h%O7{em6Sf#mrg$d#m bh&w>o64^9KTA}|k)@Wza>It6V1#*7@SxYh3 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/CheckCast_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/CheckCast_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..a2ebf2cc1a2df66bd7dc9933d88f58e7812ac079 GIT binary patch literal 1097 zcmaJ=TTc@~6#fpqY$=suxmgul6tD%P-Y~H>CfI~%QqZIXAABIgcA!hQGtKTSN&ks| zLmxEZ!T9WtGM;5oXxg~hopaf9zWKhn{Q7g=7vXqzO}};!IRLp-w9A zk4~jy2L9P{eJ*^avURs~3^-6!RQ~%G&P|HkzU1$RIclJ+E&&g5|Yr#ewb1 zW9dufNZV*Trjo%TVRBn()0Y0_T3N6OGxfG~I(6O74Z- zBkAvpBabu5u5g*xTb*4MA5^IjPX-7Cl`+dUa>q~iA7*G9HsFo*# z<%ZUsuvZ%vb}ci|xZm%|5#`sHCO*3ZC*cyJEx!KGu0HQimAV4SNN-p%#$L)hz0g% s`05rh!ShUF1$o}%DZFIx1V<6&RXk*yVJ2(*mGGFOEPGGz3|lDv0ak(@$p8QV literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Compare_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Compare_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..00011e974f6d293f8504cf5f368767de612ba33c GIT binary patch literal 1351 zcmaJ>TTc@~6#fRbF25F8%mIQCf}2TT6k`md zExu)yh1=lru`M@A^CfqsPrkWYK6DQ#kgx4-lyppBQp4c{vN*zU=z#bHx2>`{t_re0 zM1C!He7MSb4tNG@&RJ}1{mSu`n| zQMX;|Zl|?wd5?IIKhokh5z6GA9mI%1Ulkp%VO4Dfc65K}GYS(iyD5b9rN`SVmfRFg ze*n}D6Tv-Cg|}?`!kzLgzvIY-DK>x`43l9M{$X&FVO;V2$8ja3x=xImy|_jURUNl* zTSHCt!ZO25uWYvaN^Dt$@Y2KfsPcvs-ZsO#-FN!eFeG!EyG_UPXX-+1b=sxD(!B`zah%paaL_MFa#kd(S>SSWZyP&rtu*uI2rg3U+ zC^MKD+QI3fVH(AxvN5_iAJ~`?Q-5J5Uld2w_DB~Og6$r_>8y^sxR3EaInhCB literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Compare_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Compare_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..b0183ab222e301b52d794eab7f43cb52fc5f688c GIT binary patch literal 1327 zcmaJ>%~BIV5dH>|Y!X6(Aqjs5K|vEOiK2oKKp-(1jDQ8@??HxS3l=szsojYdZ{p31 zFQ5mda=^P)zJk7qWzVivfdb4{^>n8D>+Y|oXMX%?9RXOvvoJc)slgY49|4A*J^qg8 zOm6Mu*0%Tbs$>Yv8I~az7&STY4CoK_X}2Dfzv zf2LH*mP6>l1r6~CdXYGhY2(0=dYux8CgGA5H$YLZ4QcDVo{v+xsR;Ve&(K%r z`+7lGRW4r`a+fqma!Wdd&6Kkq+@(NR!`jJ*F^C}z7b8exn4$NK_*8B~Wiu@m)X1$$=&?EIyZ<=D)Z(nMhxK%(X^|2$xy}ioen*rY9eOKLP$s2yzx|*yQ1a< zLE|v!p7V%z%7!DX5nFefrkovNK`b&1d0jZiVVPk-@jS;|^r&tVqgp#|EPzrNkMLMS zSpAbxz40jVsucDC!-wN%`p?lL^O##TQ+LKHLhLsi`O}R$wsQiw zdC<_$a6jH^?+WFQkL14)1#X%fhSc*6k+Nm!cERM1qdOX&GK`<%bXKVv))m;Y>Uz%1%tN;2pu+OA0Op{b*rH61IGqft#@9-f;tB7mGc<|ws zu|tFwz95!vAqjlNKmwO$d3J9duuAHcB3uaad+EAEx76ZbQuEl(c6O{`q4!kBDhSq=mw%x?gh*v zj%9jfo*;pj-EI>{6#gbzd*h80JC4`+!;mOH*hOI4fYZd3CfG697!qUzDqO(CUL{M`JJ#-) zDuM^;U2k{+xPZtPJV2%1_o}=})ib+DPLzOGnmL|1Ki_xeob%Uz{m%fl@W{XrhIMFh zL=a_2zT&TW!Qt+HVQ24^)shU+TefS<+YH0G{1a^}2WVUG0E50!9q~BEFwT$|7*-v@ z$xd&HPM3QYLnK$N=4&w|F`*+B$0X9HA~lbEX>}-o=#ib-2wd5suxQ#YrFd;1GAXZaUqT@E;3A>KZ$Psrhh55pJhqN7H0qa{JViAEbCZN8Mu6kP(}3ioPcUCv2giH#<$mqDqkSd2sebMPjE^Xny zSY^=4qD|2f4coOI_Bwl(_m~IqwGOw5P$u{MJVp#gQ}n!+Rkan^sk5%HDNMxdju6t9 z9`8P|V^d}Z4g?!0IDJx6ZLvk`1E%!OI_hQb|&8O8G(*Oid!9x-YU z{3fEP8n}ylI%=vG>I_SRwAt=!acC97M-R)R%3D%+M+|?QeABOrA(?yJZ9A5~)DYsZ z*Dak*)QOW*hL4ZB);a1YQysQY>10WMby4Py)3l{kVu;sV*Ye5^_kGLP@ql6Z45#y; z>eykp_j-wKVzMCrTPyv zs5X3?(krQv?Zu^I#BOJc+6N>|tq&9Uh?z7ltw+*WSl6c`)A}(Mi!n1+G?b3f2Mv!v zC%-nD#+9|P%xGrp7*~r4Gf_+`on#+B1v;i?8ZXV{%i@GOp6FvWI36IZ2UsH18BzLZ z5Mcxf!h3(?J8c>YF6QutEQYZ`yoON1E!t;^ b=QeTvC0KtA)~#SI<38ORbl1Q`>|*ABaqU5R literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Compare_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Compare_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..882e571daa24dc031c29ed5aab4acaf4c4d84087 GIT binary patch literal 1327 zcmaJ>+foxj5IqA)HVGlYkc68-P|!q6;uVAl0*TRJ1S}|TJiw4_!OCVQwL8J$Pki&m zAHWBt@}Tcl`3w3dmOZ;x1qv`*)zg{o)7_`1XMX%?eFLz77h!auQ-d!8KLQLr@Ay8? zncUjRt!%&3tCAt`(69_S$IzL{zVt0*0N=tVAWUDEhDZe6h%&_5z>+CA;k2r#H@K}c z_%o$awj4qaE@+5H(2K;0Olt>@)a#T$GzpiixS> zdl<$9avE+a_-%%0yMYy9?WnFTEh%sZQgL)5rQtq9yx=u;v)+_k8p7JV$KWf78fA-B z3`<{b*0*(goxAycb#4%$RA%EWMhxLK(X^|2$xy}ioen*rY9eNfLP$s2yzyL@yQ1a< zLE|v!p7V%z%7!DX5nFefrkojJLCiA@d0jZiVUb}#@jS;|^r&tVqgp#|EPzrNPw-Sj zSI;&I-D-6T`cct6w z@xmzX(Ilx~2aO}$b&`|xFHI|>)qnjf*dZwlQzVsH=^;G8G_A_@JA8=ID&kr(9(;Ud z>+inv{5Ir4_-SIHkU~K0CfglpFiHKnr91^oEiH*U*+!RC<@&Fxslnfb9TQhA? z1RuiNzU&Xc0~=Y04_FC_FJS*s4CN0DMk4;<^R6y(QS zveOm5%@8lt>%~SA$8ek@W8nm{`!cQU1j_DE0@)+KTr&*i$kHR<@zjd)ZPBS@sNB4T z5sWg7bi}q@m0nAzRYz?R7bxMWfP4#$V&on|AYaGZte6flpsvms) zOD<#5P@VTc&a71{G!cHPm%jvNdmDJiO=0=$4&8dXv5#^jx(t$%b)@;bhc>pBOALjA@)dQP(1<8-%Dmh?`EJ zZsHE^ay0ZTEHg|E+U9t#j!$;F_95nbTOF-XW$#G-2vHTTyW%Lj!eBK#&-SaX2m(9cxX& z{cBU&-Ut`Y;wnv&{teMM(ykLN)7J!@jL!JQf56@o!!Sowt2Lj*buuKGnx>p+0Bik}q7(mzAG R7}6^4k=`U-lj1zW*mqbNLFWJf literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Constants_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Constants_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..3ab5833134b2df9b2c3f806d5d30b78c4f0b9f1f GIT binary patch literal 1438 zcmaJ>%Wl&^6g|_VvE!N~O-RxJEddH7ZE1M+mGVppZ7B~as4Q3@Cmp439ZwWbDs{yI z36^YG0lxqXkh0(d_$b7k7`36bu&fz-&YW}axpVDbzk5Fc+{a@BLkMXIn;1rfA+cla zStZAEo26&<9o~=(k!9PphjsjGNgLC0w_RCR$BZin+29$h^o9-w!tgHaRRPJ>r%wK*3gKC8NbPUL|Q(vuyl{e;VHvE}JlX4HE# z`NLZW^=MeV$0N9BP;)=fP*J{D7$y(<+IIKEE-(3I^4p_oHKge5GkhE@&)cIgTIF_0&j5{?@`1DOyLu;Ls*~~Ls-NT%`tkqOXVu}$J?X`ipWqU-F4*t E002H%j{pDw literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Constants_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Constants_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..18aa62e10c2a5ec98916de40889502106bef66e4 GIT binary patch literal 1531 zcmaJ>TTc@~6#fR3OGhG6OHa5-7?3{DH`ObG{&Y!=P-vAzB%|H{HHH1ur5n)KYvESNR z*YxaJNMRFBoitJdaqB$b_ zwB&elU6#0A%;|_TSc{(IyS&t&7oIO|Px{jaT48BuGtrI?hPDQ=4BCN0ayX+Hn(MLHITw%)^ zb{5HX$wWT}7&?pgKBv%aTRwB-UJXbxT_|MgdFdFWL+3?#%jM@VhZW`(hGcqvzF}mV zA-*EK-E(nQRopcdx3ttS?mAU&fxE64(2-?;j+?|G5b7M(ZH0A*VX}dw^~p3i%>u)? z0-0b)9qU*h$Pmhl9j@|mJpQCy+~TDTnq2##6GHm3WFM?@xhHmf9S;bejrKDgbBwMltxo>&2<8nuLP5i0MSp=|==1?N z-dnNHvw>tmxeNBT6s1FkFSSw~I|e5%*xruI{h<{h_R9yk`h043&IE289`FY4wTc8! zGFMxHV~D)%y6cYQIRCy$OI? zg6bVKPSRH&&2-xkzWNjF8!Z^7XjEpkj$#@)n#q;5P?&mFpPOcy?}cU)N8=$&8xMbn zZpD5e(bL=45$Xv4Lb7EtVoqvmznAuD?u>M56sxdlY z8WS;P90`m`Ga0KOQ#D$n(+O*Ax>cEP1m;vC)mp)=s`-@s7P^RLnDUJv1dT==2Bi{1 z3zF0W`w_<=61YO?jG+zpX!il>lSc~6)QFywDldudYx3M9<=zpy_ZY?zM(`17d?G?o z)vy9#2qQwL0TwaquF6os-E*8&-v&mhXI`fY%+R`t&Yh(>Myos_-LH-hu}FIceJ^1J HPmuZt)}Cf4 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Constants_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Constants_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..83c3effefa1d259441c38fcf404b008fd8001868 GIT binary patch literal 1593 zcmaJ>O>Y}j6g@99_Ke4N>`wiWDNRUALhU%UlK}a!+d`XQlHlUBu7XA^qDk_UPBWf~ z>~W+>NbHbUu|nzwi66iQ79gwwt8Oas5BLeJSg}If=ZP9888I5o`Ao+Y;E9-^CDvrXZd` z0?Bin)=AgrZGw6|VrClyHQTFfb!^vf`5kVxYbsI<`iATC1Kycj_1vy+xqi2*;R%b*+yCC4T4LZCiaD@oh#L9Mv0Q&#x|#$Yhy+twi`{XNV7)b^jgj>KRT zHpElBtf1lzN~rF5mOr#K9Sq|_b%G&RsMkY@lMGkZyxy+EFEDQk=39cfwie2qW=J(W z_uvBWmf#fxZ*wz*r(ov1_X7`9%+i*vbI0*+s30HaOgsW1rgyLhUE}1FMAWZ zhW8jUubtg#_k7E@J$HvhHYoWAp67S{j&<~q`%k_7t_mvCB%7T)dsTcu5ydza#RCniSX1z!$h*!k zbyn@Rd+Z(ZN?=n^G<9pw_c|vG&xh?f1qKn9rliDm-88#IY)eQa>PU6 z!;S>!uQu%Zsl=+~I4#@fHHO57>+;U3V|BZ{t6+m+`ch6|OI7eO!^HnXsg8oYa0Bns zH6fl6Itg@9(07qWH#B*E zB`NT42Kce~Sh7zU2l{bSifx&)wpC3TDXFrQHd1nBNf-F30G~_e^giAW@V}yHN_wef z%KGhAHDhF?g=*Hw$P3k+pi}~iku`FC%nvAMt{sz|WF@YVQxi~dlTPj}@^BU!VH4zJ z5)Gtb(mlBY9h~mTHnRAfYWXV|_?npCP@>qXZnG51kWi(#BdFmHwWHL#PkVNE@O>X2(VRx(b!<{}<3FvHdE)>8 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Constants_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Constants_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..9b0fcab37d17088f7aba8ce6d2bfb504b906ed73 GIT binary patch literal 1438 zcmaJ>TTc@~7(LV5F3Z}MVha_43Mefg^~$A1yc8=SUXl`g@WE_h0xR2{raLv^$p;gC z^wlTzFX)3NeeehPqm18lja1mU+04w&`Of(+^X>fn)%gM7E*=^PA*>-{B8nJ8@}>34 zDms?CUwl%3$#*3~Y{hnMxylgE7k0v6Z$I~;4~B+*6DH35!>Jv4k~hdyw27JC>Z;kI z__SravL;*HYLs;(7*ZRqXR?sm*2~{0o$)3H@Z zV+@&mwHipwF$}DUcHQA8m=lUQshDePfy|2xi7nyopWsa^US9DwHv@SybU5qWal{23 za}3ZiPcitlIH7e#XqHy{PO@GI}Aomv|GEpYAfSxkodgn0y>da#MJdb-C z9xz-yl~Yit8a5cl{%=Zs0gSOOPa#Z z`S?(5NbBHy7mP3KiDg59<32d74;vkdQ!)D%O=B^xz$qWhn3;G7m%3o8P)ep|O9KkN z?8Dh)cA$e|7d}p+PAx*2QN}SupwXzqpp@e1rwGp=PZ!fHr8G|$(*n}CPxkA`;vq&* zqcH0j2S*MEm_QSgcufJk!8G2XfcKceM`DMuL_R`TMv3M)t!`7f%H8o6DS|vQR7rOe F+20$XSgim6 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Constants_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/Constants_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..6c3b6389b8b1a7ea4cfa922cea414f653bd9b702 GIT binary patch literal 1506 zcmaJ>TW=dh7(L_LuGe-PZ(=8#OG!d6c3R>>+g$84&^VYlq!&mPT2-RjI8%3%^-km+ zSB-e!0f`^L1429@{y{4sk}L58_)&;&yj9~SD^{zyojK>5^UdX-e|vuexPz|^L=e>w zOCyd1!|;Lq!Y;eE*DBxNJK#;pkXUs*N3JnMi=|x+I)m0eZo0Pb8_*Dqg8legl3M9B zG8m%yjwjch76WS}F^rrBGmR09z9+tO>`UGzP0^(g`R#sKN0c9Qh`l2_+-_HO6d25g zCwYr^W@^IorR_<-VqhGWhKV#LF~u+v!lgAHDJ9n<@nWFfH$~Ep*Q%CwO|pL>jSn!x zFxIvYIq5fT`Hdr=zl+3R6&va+ombE?M~3RIu;swgOfXzjs+SlF#dbAQxw}mXy{q z!*WR0&SxPcnuZF)=(`*~ZFi+D9pOEtkg=NB=gNcQ@q69&9`8J~DGda)ZHKn1P<#>+ zW0%3$5#3Ic*Bv$43KL&Yr+{{3T?pyRj(v2O%jaU>*HL50uxm4?zmCr-qUvW8_`<*@ z8XC5g?=NZhPA`Dty%2}I9Hc2Y9(B7ZMdz5|m%;SBoft&iw7q?o`xm!`IP4x(&-)n| zd5`$;_=ty0AIwN_C98v3e=AY5U3bTkyvmSncpmT6)CJ|fhI-e1MTq%l9jj>H;q4$vf_UrwU~H~teO7{V^mL0P3L3zM2`Z2MpDaKdRbTa zY=DnxV|ouC_Q9c*WOgN`z{>$Ro*Ym0Q0#-rrHrwZRp8YCEMyAV9zN=W=JiU>{G?(k z_+|iGIm_%}u@9g6I=}=uh*J_0h|wdMpu1&|%MmIkkfJnYP{I)T&5>`DUffYMkjEo> z!=AvxxAcZR!xXx7`d(rN-(e0v(DHx6W&DgQ_?6hdV;-+?6;XUju_E}4R6v>$)G3qe S{c;1_G-go$F7D$iSpNY}ZD%V0 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ForLoop_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ForLoop_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..7287f1c36a224fa2e0250f984a51111a11b1029a GIT binary patch literal 1276 zcmaJ>TTc@~6#j<2m0BqlmR1p56%|mZh*YuQ4MQYBYEq*in!wPGvUD%a?v$iHlju+I zSs#4X2Th3K2l!WvFFqL)(X(5O7#jCs&Y3gccW!fLKkshu0Jw!>5*<(ss3~aB8M-(4 zCeJ(EdzLS)ZHS6w&}VGVme(1S;gN@(NTAa|GKE7({R1yILn&NB`3)kOi?Jiy&)*Mh zPnKmMxLeFn%&rvD=w`^eye8&+ufpXcTdtE9O76*!xWfx0Eqa^>ac%DzC7MBxf!-8M z^fC0b@y}q?qiBv7IXUQJ-U6Q_p4z7qYOvO4cGFYT2JjDl-88x#TkXy zESA6phTPsU4+7q_gdqkUeyud5cRp%s22~m zZlC2J;)7;gw1Mw$eru46`>%J;#T<8>vMoiCA+_LnBA9b{7>dxq6^1hhYHF9NfoX=p z|3m2wwd%r24A9I)Uk6Phy*OG=&~AVvBdLvk1bascgGFm}9O<1zJVlbAEJfA?SzjtM z%B*sIAn_XMf!Y4!t20{)d;9C#dl>!OI1GHi5&ctgSy4;Ns#aRo^wN@2P?dsaYGXUE zkulXVQyX6`s9PHGz7o$=w~>vB>1jXU@ z+m1NfCG?Q4(N2d7gZ>Z+%A*rUNYB#lG`cWJ^HM-JZjyC@WQjOW(1#U5tRn|W@;P~a zfqudRgV1;Bzr@%NbnoJ%fuTq>eO-~a+7=EU^-7U2gC={wtSrru&TM+9d+$~G`mxhp7cQC zU+}C4&w9{=7=D0%#e)|QMuYn97GnvGdzkl~ndg1p&)Ltv_VxkXK_QL^6dh^;QD_X^ z&-f0{Tikh)Un@NmWyzq;nT{#v8I;knhaHHaLq|M;6G$9^7aP75Hlf@)8KqZ3BGb)3 z@JvS*r6;&uNRiKE0$u247_fO&EVxdY%SWbsN}4aZBYmg;}l~LQ(#DHx4%;y^ra~G!62NW0DrHIQyr%nQj4y);<~jh zyDqsjU1#eWgSy~W1Vh(~>4^JvyCl4IUb5&!wYf?D`$sq11;Ef*l)PMB<+Tv6<2*xT zbD1Gtbn9MOESdqyz;TzkAYrQbUDuVq^muJm$fs__kKq!-$zt6$+{eaa)AOYXi8CFNGv;!@D?oY`@+|8gW>$KoZ5w|V}{}M z|Dp7Tnt9<2vNUtS7oka{7f0(b?Xn~p$>^nzVDCs_FlY^~1HFR`&yozFKj~B_`9hgf zZVkm=qjPX*du}(v-v0jf9{S)OI)M-9(LTjD6m@MwjjnA(wY61cUYSiGU^bZ5uY zYHoXeS0$sbWR%^*Kxou8qpH(dTGQSjol(=;%RXeP)fshHBjguCX4E~L3ZX%ikub_d z^pGB<5y+VCWbL)ZPR1C?p4<;6mv3B1TE}(LPUQ84K6T;d%vAbQ7o3Y23stPW}O54K_sp literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ForLoop_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ForLoop_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..80cc8e5f924902445285d410a998058e2b9306aa GIT binary patch literal 1259 zcmaJ>O-~a+7=EU^-7U3z6$(YDtcnVVR76lHVgy4Z0Wm3&5DqZ311#N-W_L=`lO9O? z3!d@dSr3{J;}7t!c<|!EXh7fHV!+V2hk4(bdEV#!oc(fq_!+<>~g~rgb z%lCNJ;?8z(T;B!f0(I;NavQ2Ga+Hz0-v9q|M%An^}8U-hN13FTJED76q0nQr!( zXF4)3J;CiDF&V=!O)~V{6TThm!#aggK&BR{Np-KbzEXd&bi)#>z3E; zisaICo%K-$b=EBkhUNv+5l<`jrtp^erbQ>J%}w&((Z5zN0EWiAP6`3dsQai%xZtFO@0f zK~L-ejom#PQ~MG2_V@Sq(7O-O2z)@R_9?!qs7tGAbZIrJEiEe3%D9?Rhdv*mB{P&# zhc~A8RWkZUMwvr&hDOa3syeQvH0=#iX*H$2YDc_+NG%S)HF}^@It`bWI+7VR7 xexm6ZhK{~KZ977%Lb4MIu7_@Kpr2$r?Xy&tfpEPUuD38oH*q>0$9+tq>knu0Hb(#e literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ForLoop_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/ForLoop_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..b3e4cc74601e1189d626d7f311872b0e6aad2b91 GIT binary patch literal 1307 zcmaJ>&rcgi6#j<&iDL{kESLt!(m;zzu}c!1fCE(vLPa9Ds?$`61B~qnY`j0*-Ek!M zjFLmlla_U)P~L|EO!yqP!e`{sM^&Ft@IC#L|uz-kJ8 zPz=yLzCSgAc0b;+RLb9_gxF(`BShy5_oZy=S%6{Oz_uXZ9SJc

``m&V!)mY9%9KX@yPyvbckqmk3zK};jBQo(R!+5pr z*})_GkrPJJUb6i}S+rs^69tCc`8E$j-m!%%JV6ytc0XgFRt1fAUA`l@^&f%lwO#47 zTt_tQTE|{2ED>l>$ITRO;kJRLxQZo)nRnO6@t*`uQS5fF+viPQmqFNJcyX~g=Yicc zzT$qv710dUyV-7)FPHFw=RM$qPD}I%zu1KCg)U!g^Et&jcipNZMVTSJ<@+LBcX$|P!o(oG>x z>XwngJ-R`g7(#{YxAZh?^v;_Y#rG8X19Esu_Bk>Ch^x3xY?S{QG6rTC`x}`vOrKA! qGfWxySRwBi6wDO-~a+7=EU^-7U4yQYciRvMOppq@sdi5u+Fa35ZDvgm{pl9boN#G`mxip7cQC zU+}C4&w9{=7=M6&#e)|QM&rl3TMUpk?qS|{W}f$XKW9Jx-v0#PE{btPpy*H&h(cpX zJ>gGz!Q#$NVP)%yC`$%y#&k?M%b?^();bVFhmLpxCy+P>FExBAY(lwpGRiE4M5bGK z=$VczNl$RQm?ocH2_%tX=(l-Q%(+gP%XL%klIBb9NS|!;iz7|*Fb=XcogE4^jUFAn z31ra6(9?#WL9YegEGHmor5IUDgP}{i^PS?LFHN}*1mO$@`1@^~>Nw4io_D<^*R4Ia z>yk^;bskSLsB>;bFeH~uM?9$8Tf$rATNa(DHaE$CU;a_M02n$;l9#K?ycXhhoM(tU zT4acq+`3m5^JYNO-|BKaNSG>q&vm6QJziTDa@Vc+F^n>tEY)qp-8QyO&zHue;e-+S zw+t4;7(@2pntL8^7{U^^ph}0g;|$ayw^A?5LxOAn2n@S!Nwa2|qGD_{jEV6{GD>Q= z62}Ct>bMqE?>fWq;nk2d81*i2)AI~7a#!&K*Ly;f{3 z-I0@HhO3R5Xahf5{N^ARkGA)KVvbu@$&{kVkXUpa;mujx_l2+H2E+N5oZ5w|W18Xg z|Dp7Tnt9<2ax``_@u(zZz7_a@D25%LQmv+6!hh0q|%NEqcj zx=D}HPNPU;-dZ*2&=}vam>c#P|#YI7ciwXuqH` y_5)qNVdxkR)Sh4HR!H_k!G+N6MdV5L(!M}t841@*;d&X9bQ7o3Dcr;@ocs%Qyf#Y! literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/IfZero_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/IfZero_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..d338e8f4720b665ed9686196ddd83afbe4a11c6d GIT binary patch literal 864 zcmZuv%Wl&^6g?B$8OP15X&zt*q&)L#qO$0wr~)A&MM?=$P*K`NH3=qlo7ll|K(OW~ zV8Mb-Hf&%46+-<0zJ(7!LZaMpA{9iW(cHOn?>*<-x%2(^*AoDDQ8N&N!l6c?AnFrrvOlwrB?bl39S{o%wHzU?~u>kNsW zI~)nmdTjd#GRUA78?(xI6bU2=(jK2hb|Xk(g(DqB2HAfkv|o;WYe>xQgoI?8fjHZ( zKlE(JZ~LAlhMPLhF{~UF>~X<*HW7n@?-pJWEp=w%0>{ND^0-7P3yK-|NJ0%9LNCtX zgWd_-cKVy89UTRRT!7vuI^XgN{(*323_7kbq=VqV8jt^qP|x?=Cl)t*&vxp`?w LzavwtL3r&C*q^2V literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/IfZero_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/IfZero_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..fcbd6d8c59d049ad801ebb312c20f3d4a77998d4 GIT binary patch literal 776 zcmZuvU2D@&7=BKZG;P-JPmOlQ&$ZiVaTmLp3`7tLofSGNb>KLy$1Yow)bv!*Yk!3o zUU;)>y-*R^5Ae760|deOo>WkAB%Js2JkRsy&DWowPXOG;s)ZOd6M6~;;taV%{*1RK z+#k2P!$UEW4Dnm8@5*fkt={NcNFZs#N?{2phJ5?ULlFl1-du9&2LApALv|E+Qyz*3 zt~^jh2EE>H^pnUSYa*9I9)*91dM{>Dc!VF!iLTscmYzI{q+uB)Qc;Q6 O4QSbnN!ayBY~vSsvz=}L literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/IfZero_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/IfZero_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..0b7edce434e2911c36f0ba7ff9f0c9808799d00f GIT binary patch literal 726 zcmZvaU279T6o%i~k4~~p+BD5ajYik+#FhjVdQ&NgPza<(NQuN=lt~=ZX|ua=J5lu7 zU*V-Uz19mAk^TUGi$6dRtY@}@h=FC!*_pG?`_7*8?bnwR0QXVzV8P~aGH@}+kUJ1B zL~|^{QL{5RkVDNdcTa^%Z!*}mde1`&X$~)gd1M%tTF;)yINA%QT4)u8dv_TYhfy#Q zv3#ubzBy!YYOQ)NjRh=njOI>KRrN z$0kqX5`2oL^d%hH2ky*$_4;+~JF(|2<}JMGo&wUbSI-6=ZNcPOkCoyNLbbU%Z? zaoF+ccf++3Zi%Ex40&+eAWN$hZ^I*dKpEC4DsVZja9pE@k%u4Ds~?pq~|I9E0rg^K$cdTA>;^ONMsyXG*XP@jj5Zz0pU-Q4*&oF literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/IfZero_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/IfZero_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..1a1a4e8cb2d6240b9e83aaf05a4a0d23cce419d0 GIT binary patch literal 759 zcmZuvO>fgc5PfSqapJnoXHy7iae+2TD-sF8DFq23Aw>!VDOFI2M70S^>Nd86v#A7U zegy{(TzZBBAO!sZ{2A^bK4u*xKvb4?W_D)Yo9EfjKR%oQxQQ(b8gvtejTqt#=>vYm z>tpVZ>g~aS7)pltj_bSf27_Lyc1_|R5yu&9^y@@i(@AsPwRwtN+LvhSZKwjckL4+@M<<+IN&qY_hMk`lNa| zzh`(z-DpYhg& z`{P!3cpyfSA%4sCUAe`e)f;^a2_#KeDJ&tykZ(VED8gXRn@cX;z~8&ckR1iyl!xMh zEB95AL9e$P{UkETn#iS)N8ul$-iw(O9^nUbqAPbI32xB3AG*Hm$xv`_Gl3FA@z8N+ zj(9rf6GsNlO9F3NsGw@%ObTaVQ_Crr8O*7In)rlXU%*Eb61MA)Hyix~&NEaa^fA#% z5jt|8`wNBymKjP>aUy23zbZ7@o#3&ckvpz0?#;cS2zU5!LK)rTF40x$yQlFnqNjzfq@U7iVuc~L+h(wO!8{y^yRJg7{P)?LYHnPl?ZjxWfCi=(O6LWNYGfH% zWA!80J8~EtI#pTuNxFE6tZID@o$|nq_!n!S<*e>N*SZ5E_oLfc+g?B3(l+$6UVDqu zdRcF77-i!V%vU-)I{Bt>V-aqJsEG^(n7Brg*2rFmh0Bz!B6b2BhKVawq?eI~@3h3E z`lEh}ctk)-+KT-enfFK+iXTuuf^EN9gy*7gNmXj({$aKw?P;1JOHUp}(y)vYsi;Kk O2DEI(B(0PqCvdb6_^Cp>zTLjeeat$-<#dH?_azIa2jVE zq>$#Y^2i{|;NFxga({l{zYVB$cHgX(J9-EL~2Vb}wY1JcC z(5Ix*d`#p8lb1u!*9$sSvNvO6m~y1>BGFY*B=oZMMazMU%^Zb1wxGzc?<3B*xDPmXJZ#bG4`4QKHIpBJq%m#d`uV8?})qRX;F3~ zV%x`%Ij6eaz($o}BGTcMn4J|gPdCMxKrf3>EviuYZ50U_D%!CUk?bjsiS@mSRkCrA z!O|+y4r-{Iju(w}IFBhzQ=`@GJ}taK;p7<1)PAyYl%XC?i3BF1k3~>D)PqPY%auV1 zVnue1A`RL*<#Yln(QH3Xrd*EW3`6G^Z}j?F8WC?yQE}e~9mOy*@A>Ltzt>XXkFwPz zkJXbNwSKgE{cF7^q6ID6zg&>FVm!x5hSc@*49-H(58LXjXGjX`R;!z1hMoA9UI25Y zKx!jP<9GB_p_$Q~nRpKNgbaozjV5gD9Al${@vs+>}_)T+htz1|4iKb$^8Paj2Oam`*uYcAjDK zVY0%J!3xL7G*YBuDegg#ZIKii43RJ{I7;+&s31?O4q-orF-_hkia14)A25n57{kvf zqeCbU+Yw*~ekJrh?8AM^_zhJ&pcDBBhwwYe+Yge6 zEqigSIBTMdpg#2?`BKsi*sCUb7`pun+fjV?<^KNzB1kWBRdkrU%?~hSr=_Kqh`;LC z^Omw4TN^63Ax&^%tL{qA#36>Xuhjwklemc^3_TCG;au4Bd|jUwM9m|%eunT>S*tlF z3JfJrxkG$ng3~@c$}c-=iMw(^y3(#nj|*2)#*%xYE)A4+_QtQ0iQ^0*B|Q~G5rewp zX)T?MV+h04X!)Q)j(1f!7=y9mT@$An2E8F3m~n4A2#SY#;PEA~)(nBKiJGp+2<1+g zd51#O>HA>98aT($c5UHay`h9I;ysEWH08`ohQxKtmeY-TMY^{|rAC@iU0BrmuEN}2 zy(gj>C8{eo#Oh!B*o@O~tMZDa!Kocy2K9L1AkNa@>!$@&WkhH_Pp3TXjP`Kp1K3*< z7)EK;*IJHZ4CAzuDSM7q#7O%y85>WgCvv@;*!K=bs_i`z$;4zX{}S!`oT2mU;HsO% zTz)gqXMKIHciS%4w99Kd;>+b}@k#ocmj_7LsWnT@_j`9U{prTTtYV1tnE%t8M zT}M>hdqhIwQVtv{R3r{aAkj*t?YZL0nL9`L15)wLu8K)o%bt1r-uJ$F?|ZZU{po|p z0M6mOgE6Emr1QuiD^R$hc2%>lyzS&V3C8?pAUKP0fm!muw47Z#+w3-a6u+889pn5^>7BE z?5W*R336BUjUp}f&YVr3C7Sl*Wae6UM_}UO*7dwkp1|0(ivrGuKMcD1f@?^M`%Y_^Ylh=^ zn=gR*jDcz+%k^D8Rk#c8nfiT*pJ@oRxtg%Cb6Cb1?u3fRNFz`0Kk0|g)l|V*Uptj* ztQ4kK=PP$G{tK+)#63(U!Kw9jx|~imTABG$=6g(e~OBQRU!5u&2AM6R>|7KtntiPsPVgpdSY0d;@P;7 GbN>QH#3GIW literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/If_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/If_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..bfe021075f3ae0ca6e2ebdaa018e7702024d4a21 GIT binary patch literal 1252 zcmZuw%}*0S6#osh-EAqhmKLa`GN@pSO8F2(zWg9Dnjo5BNYsN)%K$6wF78f=T)cSn z;K6vnBQbjNpa(UYc<^ZAQU4k-zS)&j(9Q15oA-Y2_r7Mo{`&YCzy+L-p$W|fLUDu< zVMyK+8=_Pd_Dbnm`JSvOhRBp|a_Z!ine&M( zr*z%5Y_*_VDQc4@4v>%FmdC5o^SD|SHZRAJ#6bh8INFeAX#0;RgR!o8sy0y<0&YJ^ zBDU<6$>O4kc5?NpS16W}ZopnK(aF%^8*E4M{l-K8CPXe>#8uX5?uQ>{$j(bktrCC5 zv6n1mIkpBWw=PX^Vyo;c&%_aiw6E0({8hM#V+@@ScHOzKm-wbWEsLs0Y<&#j%d%Q^ zOcWUUJ>?GZ>1j^;@C3i;s8#ODW$8-0B0Vl#Nfk@(iJCOfzjro%mrR^w2r22Q7>XFs z6HjYtFpeP%)1c-3ItAX>;ourf7H^q2%`o5%@c_oX-6SXN46Rp|@6_r_=qBDF_Ry@eBpDKOmM!P&wX$??h;o%Qp_;I0^zDV) z|C>D#Ehtf0yDHZI;A0C;-L1$=mUd3RC?+vQJ3-kqG$TgZAIaEMGCiH^+D6M;7^&8GNF)<8x%>+p(B}-DUj?QP z5_9?OK%e#XxvpJYu7S&I9P#DywD=_54Py_9p|Mc&SU3~fLNXJ69*`d;eX4gNLZ6Y1 zWQ~`B`Z%dSp?EWO;yq4Hm<=(SHM7xoC~XB1Mj8=DNz}DB`L#bpH_0KYR<|iaKfXaf zY75#CM-Hv%LjnV&89^E|$Y7Q%^XSAPx^SBsdKZVW1`ZFs*dX*Kj^hyuc#M;Hf>U^k z5}soa+Ze@bjNt=~<_pI0jiP_2ZckJ6BH}w}W9%nV%t$1Rw6TK@#&*zdph)iy`UAnB K;mr7{pZg6mFBu~M literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/If_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/If_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..3afa298c099fcac82c1dad6682bb464f394f2947 GIT binary patch literal 1292 zcmZuxO-vg{6#fRUJ!{7VV{E|1gdqiDlVFE5&=f)%h!h2hLM5U|ltVN&11z<7>FyX6 zDay6SN|ky@FO{OIIrLDqQi+sQ+}m@{z4zFhLzFkWLJkCLz3AWc90`WZj@*;ghIF^8E43X}*9?i9j_c@K46#!AK@v8S9H}(UA$5$~+Cf zz))CLj@~Bzy60{<+VNZi)P76Z5X4qL)t-%u47t#13V5e+8zT(;Umu4H>28R9bJ~=R zfY`G;OTAQt4-xAx2^&qeMKEB5y+Hy<`zTACp~oTB3HcpHkLYsqoda;sTW{(V_% zki}|BhgRQPT0d*|M6{}9{makfZiwgjl%ZpNks-C}wfwre>ll*kiEI_~m|++n(+gmJ z9iV9=LHAGSG)R(>jE_GD`;8Qa8M+&{(UX|PO_Bs7y(F1MtV1%X&gXAX> z(hao%!=zf%R%|++x1J!AkN*&*`H<|{(U}DOc_C5YKS$WG6XP6?@%%vlo%VP|YZqZ!gNYj*hz%f9dh!HwXpc6OHh1+CZL=N|n$2xkk ziGH{!qD8}ggbVlv0^ed3-(d{j;}U*E3D0l^zYxQ(sNw)uafs{q3sd-q*7h&4{zuvW tr%lXJ_6ekqFu-w(y+)A)@9F0K{0M!F9if+_OxF>{BZbrQZinU1zXh&GBEJ9t literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceField_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceField_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..f8457d3b80f11b35e8a8fd9c142815ce6032a7a5 GIT binary patch literal 966 zcmaJ=?M@Rx6g^Wuwp|xnK?*1zRYBXLRP>)!6Kz6hQa_RsjPVB<+7X8C&NRETP5LIj zhDIg9#0T)9jCZ;_F_7lJhJa&=7go8;BQR{W2gNY28D;_+|FwDqd z(d+m1&w#@Sr+NMbCT4V}W5I z;2lxZs>RJaX^zRWMVW}O#d;}$4;mq?R7X`8OSs|SriW#$FwBkNXK=bUo3AX%Ws1^1 z!(>gjsgrC&D)BlF4n?@f4}ChB47em*zW8B0&~55Cw3^xAm48XNWy>O6UTSS36Y}mW zVUBe>O5-lI{1;XDXq7MYtg256EIW;&ixSEXHmy4M8P?A)QmUTrh)NRg%%Fj$YD`qQ-r{DUGNycy*;j zSo3)liO4~PVdGLy<4Sd~&9M6aP@3wbFWjPOP0>^_vNW>frO2nZKz5aOE3`6Nr^=^b zp9g_!WbJPY%Ai0LN$9S9N_1NI0q6ZGGL2mM+2-;$xLp+PUOy;UOMj=?_Da^=$wE literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceField_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceField_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..0ba73368902af390eff5c699c8e5efe21d22c543 GIT binary patch literal 977 zcmaJy8jSHrv%uPJx$KgA7ZTpY z*Up7-IRVO?Dac4i-FI!Q#2v^q_dH?O5RCd;;ELc&s^5&Vo4VWm1MyI8|j2kRa-u*tA6B|n4Hv(Lba|?^ z2~EIz&xJYG?J$8nQT~m}zO&kA2Uh02EK9{vbg_-w4(?cWb{KMhK2@rL?ugPzhLK?V zyk&GSWOzTxavV6S_>8NzFTz|+>rTH{zQ}3f<{a=~*b`I2Csi4ZS$Xo4#wjY?_v_M# zGJ{uDN(2?3hoJ}^++*0fz-d~m4(>B-{6CZ?e8daaXh0)0Rg88TZ?Ym})4bB2C9g=n zeRqpr!HR32;d~&E5e}F`l=d0K5JwUYt?Rfk#_iFY#jSor;!T>sv$c;%Z-0VwiY4F+ mR{zf9!le!})I$_GLPoHKn{*~9V}aH!l*n_*x{F;rK;{>O81|t6 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceField_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceField_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..80afb4f80f50b3eaf453e9bd8781baa8cdd19955 GIT binary patch literal 1039 zcmaJ=ZEq4m5Pr6_99*w2(syf-)>eUPQR_=0#>A2|lHf~1gE4++7FgSDk6m)Nknm6Z z8yansn)n0!QN~%olm_&}&CK1+Jo7xWv%h{{`~>h4PhE^5;$Ymv1fmSHC%nybK37M% zx78C-GYrw^Qc3fIA(GBi9K;xwiz+l+)x^FOe*Lh~GTcb54tHHRh*&e}!NU~8Bo9M* zq$=ER35M}>F;j_S2D1*Xc}QUHO2cv|G@?O$bc@<9l)6-;&bqCC8@-lR--C{177v5_y(6$x0wDoy3j4_R$xbJ zlh^(=;T=nhrnaZG2~EJ8uZ20*^)QAkN&Z`v`eY9#)wW}QmSQte+;wpeI}UPoI`^az%ZsIMn_O~sHV-s8CZR#FDSg7O=I3LatFKy3e&)|N= z^!7K*Utk$H!;MRf1jf5aF`_Vy7`2KM5?!l4-bNoUnqB>l`O7+cqd|ESlo`QoipOvV XY4S0u+@>dk2lVDr^bn8m1S@|45n289 literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceField_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceField_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..a608d0040d4709cd2ff2672827dc27f3fe540f8b GIT binary patch literal 1069 zcmaJ=>rN9v7(GKT+pY^m?ucMP(6%V`f|^)kB29=*>Ln?uG5#P!JHo(rrrDj6;FI_o z8Wn?y58y)?zv%~`A+iPri#%@Lq}DNYPv|YF45CG?Tq$B;TY^o7kHCa`?n>fv5XbkEp&q0&M|+BxtMtp`K0UcqJ-|91WA+~&3<<^n literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceField_mutation_5.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceField_mutation_5.class new file mode 100644 index 0000000000000000000000000000000000000000..8d68baaef304ac50448dc40600b4bed28391191d GIT binary patch literal 1067 zcmaJ=>rN9v6#k|yY*`m6AU72(3et;GZ+NRQkw#*ZDkdcu;}0@zhcd98X?CY1yos-& zQ8AeK06vuQOk2Yesy}w-%cZPVDpNIq;H}~WmEwwrtC(k)Y4HP5(yGqQJ8AaFvQkaRu#y>& zI7*(-q-qvjTtnKyqKE6aL3F$7&SsA0oTWkSOT}sU53GCEj#eH4$v_ znol>07MBz^o%s;q6A5&yx)a#mSm*hFwQAMUqDrl6Z9)_9_G@AGbR$gS78T)dRC?ET zINfd6(=;0!#;S_~?l`z>>vfM|>9l!L9qI#7=uzpFaD&&44vrW;MpgD5dl_GG)$m2Q zRMGmN(=MLZ6uCJQxOLPP1Kguk>5XtP+N3^2iTi$48c}5M%1Vi#dU%2`&TQuy6`9fkYQ9Y2Ou+NE2Wj8M=!h YiyZAq0>4dP9{1_wlJx)&@fdS|08mjC)Bpeg literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceOf_mutation_1.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceOf_mutation_1.class new file mode 100644 index 0000000000000000000000000000000000000000..adbd7d887fb33e1d397c96aaeac2abfcd980a4d4 GIT binary patch literal 1210 zcmaJ>TTc@~6#k}^Zdr=JauY;Y1hfUDf_DlSX+j{WVp0N$K9FfUz`}N>?oLVgC;kn6 z(4-G0zWSq#XLp;lgw=gGbLL#W^Uawv`}j})#XeS^Tbnar-pDI!&yi<+$Y8+0oeTysbkl$B zYf&dS)g<(>QdrSZ`45z)DOvD(!6I^21|t|{n5gqhQB<GbpQoL{0E5bYE6_+f@ zI(LZFc=l5qD+aTynqF1xIzjMMEc$A|hdREal=ij98}EcZS2aJ46^2<=xv(AI=F)cB z)NFNXN3GkiSsJShi}69-JqSae{1Y#loiJ#f!H&mkcZ;G1Q+Q_LIbIle8Ql6ShJ{X7 z9eJfLMLyyf4Z<$3YUN!seCfWuc3^bgJuYjm@E1x-T{atq+wJVK+(I zSLhzTHbjxTZrRbIz>wLOQg}s|`@ZlEkY(}Knc}D#*kYLZe<;1m=vp%fPE!}%99M-f!>FQctmRu>IJ_5T6Zj?wEPQwTi?(>-NG>N9b=@E z?OuxjJKIDHGhN%+7SRa2ojNlx2(g!NQ%I9ON^+j6uEV6iPCwbRj-Qrr3mwNlX!};EhBmeCpa))>yEuT7r<<52QHkb(`g!H5APhSUgV42 zz~m>topHsu;xaqZ4^_-&4}`u_Eenf;v2PVFe&Y}K?|OkG6f5VS?DglZHrU3Yi1nU| z`510pN)aWS6ue8Tzg5ihxGBD98n!tDN48mHg1iGp^U5a%VVa{EMlzYDd(bTh#3>}t zhGt{-ow~tA%~#A@cNjFk+#?ES_C3b#@asc6oba-&w%Ck~4CYvsVrvVG8I(}Q-y~B) Mh0)=j4r3K~1t>0sy#N3J literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceOf_mutation_2.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceOf_mutation_2.class new file mode 100644 index 0000000000000000000000000000000000000000..3e5a04bc8f0281bd789deeae9ed72b7b8e0f1281 GIT binary patch literal 1301 zcmaJ>TTc@~6#k|ZmX?J=ks>ItYS9*z3V5XmLWM}e#iRrieIU~^z(RMn?oLViPy8G5 zph+K0eDy~e&+gWA8&;e2%-J*FeCIOf%&*_A9{|>|nM4dd8sa*7(Z?`+&M$eP#^q^Y zzj7|BilJ}Cl%`r`=*i^|6X-`mLsG{8^e%Y0=_+9n%5Ko1u^petvwCZ1hhQmP+Xa|JX*{y>^4g^?z$dV<(wfMaD{>@YPiwuT#=X4 zG^Lc$F^-!I;}*XVC0kax`e3Rv(mYp+NXK#?^C3nGjgA(Rn8Ym&w{=Wmnqf2|dB;iS>y?L8p!$ht7Z zOZKr~NbQ(X>@}>4a1MB-MwYn6O$sWL`xF%wL$Yi)oT}I|J@8~C`@9zq!@!P{SO)dRiq`|L8M2)koAT1W5QQMdpe?p|RoPCH;Y;`~+rS{- zcU&IVgqz*5?Tbdec)hqGOV`1JW?e+U!`Bm}R}8meo1(;PwX&&1kwM>QL_&qjseifn<)prf6lf_Rf6=`$`H!o}{hI=i{`i73H3`GNabVi^P zco0kUl)Oa>aXcb>439BSYn*}@LV>hN(qGco6JIX+@~JPMW0m&3NgSeejs9=2L0l7m E06XYV;Q#;t literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceOf_mutation_3.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceOf_mutation_3.class new file mode 100644 index 0000000000000000000000000000000000000000..15a68c711cfd3eaf720e710ffa710f79048a796f GIT binary patch literal 1296 zcmaJ>ZBG+H5Pr4=u05(iks?*(GY(PjgunTl>4UhUVH@RVN9$N>Zg$24)#X+FnJe#er~>h$6+%S5SL`VW?zF zvDv6qguBfv4t?pXahsS^nfJY@sopD9r`091tQu}rY}kHWx@UhDeSWIpx>DNHF0a25 z`cUn8G2|GgROQIBJ&Q}rZZ+3Z`&L-0WsAkI#4y*}sWa!mm7c;s@WR&>I6YvndgHaK zLtaAzcx2)+o)}p6yPRj3ZCBBjC+b+_LXBbLH+WSm_mtsdXSZ68VZJZ9+;fCCTT<${ zQO}>RY{!?b!0pqz=;7Ykn=rk6=VNO@6u9G*Z7nE+L{UoN798$*!ZSc4Hg_(kUQ!LL zGFPk26A%M~-w=6ALO;W3gM?b6l-L4+MQ{tZX-^aALsGsNtapO-Zm{0R3f-G@ L_Y}|RFF5fVWk*CI literal 0 HcmV?d00001 diff --git a/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceOf_mutation_4.class b/OPAL/tactobc/src/test/classfilestocompare/mutation/mutated/InstanceOf_mutation_4.class new file mode 100644 index 0000000000000000000000000000000000000000..cff338ce95a0e4c95940512d1210b461d721466e GIT binary patch literal 1316 zcmaJ>T~8B16g|@d+t%f)NRcYAAZQCnMe&QG0yPAZDkde6=mVLy11#+B)ZHlw|HQu` zCYtoY#8-cm@$PP8+qC*JGk50PbI-kZW`6x{`~a|pHwi=#)zGJ-9|H^{=lqiAEbg4< z_RHs@q8J7?OvhBO7^0c%VH`2UH6(Q0fX*4XC+E-@9 zQ?BWpG9-&F;!?1ek7EeK8b)-CBH0nSM9#vdfU-{U$3s_B=H3&RB5%R%yoQ^dJ^^Wx zl1k~Az%7Oen_q~6bShjOnd*#IzEtHAW9CD)TTcRM+}3bM#}uX+#sa~eQ5m$FufcMB zl5UFZp$3B?)ylPS#@&+mR2NjEBv-@FIbA(1qCW8~>7FzExP$xs(?o7itXe!Va$}>0U8>Zf{@{ z80NdnovJ0g`J$8;^;*8WvTZvZjt5sY(F5Mzn=rk6`~7QD6u4!TOeOLR`kvzmw_tJ4 z6P|`ms%uwHy`*Z`W|;mzlpb`L7iQ@#N9e&Y#QoPyt0=AM8=x^m))dW*=KjU+U|#}Y zmPY?LbXvqx6KWHYPqlRot$2;WrJopUU>x{{$