Search in sources :

Example 6 with BytecodeTypeRef

use of de.mirkosertic.bytecoder.core.BytecodeTypeRef in project Bytecoder by mirkosertic.

the class OpenCLCompileBackend method generateCodeFor.

@Override
public OpenCLCompileResult generateCodeFor(CompileOptions aOptions, BytecodeLinkerContext aLinkerContext, Class aEntryPointClass, String aEntryPointMethodName, BytecodeMethodSignature aEntryPointSignatue) {
    BytecodeLinkerContext theLinkerContext = new BytecodeLinkerContext(loader, aOptions.getLogger());
    BytecodeLinkedClass theKernelClass = theLinkerContext.resolveClass(BytecodeObjectTypeRef.fromRuntimeClass(aEntryPointClass));
    theKernelClass.resolveVirtualMethod(aEntryPointMethodName, aEntryPointSignatue);
    BytecodeResolvedMethods theMethodMap = theKernelClass.resolvedMethods();
    StringWriter theStrWriter = new StringWriter();
    OpenCLInputOutputs theInputOutputs;
    // First of all, we link the kernel method
    BytecodeMethod theKernelMethod = theKernelClass.getBytecodeClass().methodByNameAndSignatureOrNull("processWorkItem", new BytecodeMethodSignature(BytecodePrimitiveTypeRef.VOID, new BytecodeTypeRef[0]));
    ProgramGenerator theGenerator = programGeneratorFactory.createFor(aLinkerContext);
    Program theSSAProgram = theGenerator.generateFrom(theKernelClass.getBytecodeClass(), theKernelMethod);
    // Run optimizer
    aOptions.getOptimizer().optimize(theSSAProgram.getControlFlowGraph(), aLinkerContext);
    // Every member of the kernel class becomes a kernel function argument
    try {
        theInputOutputs = inputOutputsFor(theLinkerContext, theKernelClass, theSSAProgram);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    // And then we ca pass it to the code generator to generate the kernel code
    OpenCLWriter theSSAWriter = new OpenCLWriter(theKernelClass, aOptions, theSSAProgram, "", new PrintWriter(theStrWriter), aLinkerContext, theInputOutputs);
    // We use the relooper here
    Relooper theRelooper = new Relooper();
    theMethodMap.stream().forEach(aMethodMapEntry -> {
        BytecodeMethod theMethod = aMethodMapEntry.getValue();
        if (theMethod.isConstructor()) {
            return;
        }
        if (theMethod != theKernelMethod) {
            Program theSSAProgram1 = theGenerator.generateFrom(aMethodMapEntry.getProvidingClass().getBytecodeClass(), theMethod);
            // Run optimizer
            aOptions.getOptimizer().optimize(theSSAProgram1.getControlFlowGraph(), aLinkerContext);
            // Try to reloop it!
            try {
                Relooper.Block theReloopedBlock = theRelooper.reloop(theSSAProgram1.getControlFlowGraph());
                theSSAWriter.printReloopedInline(theMethod, theSSAProgram1, theReloopedBlock);
            } catch (Exception e) {
                throw new IllegalStateException("Error relooping cfg", e);
            }
        }
    });
    // Finally, we write the kernel method
    try {
        Relooper.Block theReloopedBlock = theRelooper.reloop(theSSAProgram.getControlFlowGraph());
        theSSAWriter.printReloopedKernel(theSSAProgram, theReloopedBlock);
    } catch (Exception e) {
        throw new IllegalStateException("Error relooping cfg", e);
    }
    return new OpenCLCompileResult(theInputOutputs, theStrWriter.toString());
}
Also used : Program(de.mirkosertic.bytecoder.ssa.Program) BytecodeMethodSignature(de.mirkosertic.bytecoder.core.BytecodeMethodSignature) BytecodeMethod(de.mirkosertic.bytecoder.core.BytecodeMethod) NaiveProgramGenerator(de.mirkosertic.bytecoder.ssa.NaiveProgramGenerator) ProgramGenerator(de.mirkosertic.bytecoder.ssa.ProgramGenerator) BytecodeTypeRef(de.mirkosertic.bytecoder.core.BytecodeTypeRef) BytecodeResolvedMethods(de.mirkosertic.bytecoder.core.BytecodeResolvedMethods) StringWriter(java.io.StringWriter) Relooper(de.mirkosertic.bytecoder.relooper.Relooper) BytecodeLinkerContext(de.mirkosertic.bytecoder.core.BytecodeLinkerContext) BytecodeLinkedClass(de.mirkosertic.bytecoder.core.BytecodeLinkedClass) PrintWriter(java.io.PrintWriter)

Example 7 with BytecodeTypeRef

use of de.mirkosertic.bytecoder.core.BytecodeTypeRef in project Bytecoder by mirkosertic.

the class WASMSSAWriter method writeNewMultiArrayValue.

private void writeNewMultiArrayValue(NewMultiArrayExpression aValue) {
    List<Value> theDimensions = aValue.incomingDataFlows();
    BytecodeTypeRef theType = aValue.getType();
    String theMethodName;
    switch(theDimensions.size()) {
        case 1:
            theMethodName = WASMWriterUtils.toMethodName(BytecodeObjectTypeRef.fromRuntimeClass(MemoryManager.class), "newArray", new BytecodeMethodSignature(BytecodeObjectTypeRef.fromRuntimeClass(Address.class), new BytecodeTypeRef[] { BytecodePrimitiveTypeRef.INT, BytecodePrimitiveTypeRef.INT, BytecodePrimitiveTypeRef.INT }));
            break;
        case 2:
            theMethodName = WASMWriterUtils.toMethodName(BytecodeObjectTypeRef.fromRuntimeClass(MemoryManager.class), "newArray", new BytecodeMethodSignature(BytecodeObjectTypeRef.fromRuntimeClass(Address.class), new BytecodeTypeRef[] { BytecodePrimitiveTypeRef.INT, BytecodePrimitiveTypeRef.INT, BytecodePrimitiveTypeRef.INT, BytecodePrimitiveTypeRef.INT }));
            break;
        default:
            throw new IllegalStateException("Unsupported number of dimensions : " + theDimensions.size());
    }
    print("(call $");
    print(theMethodName);
    // UNUSED argument
    print(" (i32.const 0) ");
    for (Value theDimension : theDimensions) {
        print(" ");
        writeValue(theDimension);
    }
    // We also need the runtime class
    print(" (get_global $jlrArray__runtimeClass)");
    // Plus the vtable index
    print(" (i32.const ");
    print(idResolver.resolveVTableMethodByType(BytecodeObjectTypeRef.fromRuntimeClass(Array.class)));
    print(")");
    println(") ;; new array of type " + theType);
}
Also used : BytecodeTypeRef(de.mirkosertic.bytecoder.core.BytecodeTypeRef) BytecodeMethodSignature(de.mirkosertic.bytecoder.core.BytecodeMethodSignature) Address(de.mirkosertic.bytecoder.classlib.Address) StringValue(de.mirkosertic.bytecoder.ssa.StringValue) ByteValue(de.mirkosertic.bytecoder.ssa.ByteValue) Value(de.mirkosertic.bytecoder.ssa.Value) ClassReferenceValue(de.mirkosertic.bytecoder.ssa.ClassReferenceValue) FloatValue(de.mirkosertic.bytecoder.ssa.FloatValue) NullValue(de.mirkosertic.bytecoder.ssa.NullValue) DoubleValue(de.mirkosertic.bytecoder.ssa.DoubleValue) IntegerValue(de.mirkosertic.bytecoder.ssa.IntegerValue) LongValue(de.mirkosertic.bytecoder.ssa.LongValue) ShortValue(de.mirkosertic.bytecoder.ssa.ShortValue)

Example 8 with BytecodeTypeRef

use of de.mirkosertic.bytecoder.core.BytecodeTypeRef in project Bytecoder by mirkosertic.

the class WASMWriterUtils method toMethodName.

public static String toMethodName(String aMethodName, BytecodeMethodSignature aSignature) {
    String theName = typeRefToString(aSignature.getReturnType());
    theName += aMethodName.replace("<", "").replace(">", "");
    for (BytecodeTypeRef theTypeRef : aSignature.getArguments()) {
        theName += typeRefToString(theTypeRef);
    }
    return theName;
}
Also used : BytecodeTypeRef(de.mirkosertic.bytecoder.core.BytecodeTypeRef)

Example 9 with BytecodeTypeRef

use of de.mirkosertic.bytecoder.core.BytecodeTypeRef in project Bytecoder by mirkosertic.

the class WASMWriterUtils method toWASMMethodSignature.

public static String toWASMMethodSignature(BytecodeMethodSignature aSignatutre) {
    String theTypeDefinition = "(func";
    theTypeDefinition += " (param ";
    theTypeDefinition += WASMWriterUtils.toType(TypeRef.Native.REFERENCE);
    theTypeDefinition += ")";
    for (int i = 0; i < aSignatutre.getArguments().length; i++) {
        BytecodeTypeRef theParamType = aSignatutre.getArguments()[i];
        theTypeDefinition += " (param ";
        theTypeDefinition += WASMWriterUtils.toType(TypeRef.toType(theParamType));
        theTypeDefinition += ")";
    }
    if (!aSignatutre.getReturnType().isVoid()) {
        // result
        theTypeDefinition += " (result ";
        theTypeDefinition += WASMWriterUtils.toType(TypeRef.toType(aSignatutre.getReturnType()));
        theTypeDefinition += ")";
    }
    theTypeDefinition += ")";
    return theTypeDefinition;
}
Also used : BytecodeTypeRef(de.mirkosertic.bytecoder.core.BytecodeTypeRef)

Example 10 with BytecodeTypeRef

use of de.mirkosertic.bytecoder.core.BytecodeTypeRef in project Bytecoder by mirkosertic.

the class NaiveProgramGenerator method generateFrom.

@Override
public Program generateFrom(BytecodeClass aOwningClass, BytecodeMethod aMethod) {
    BytecodeCodeAttributeInfo theCode = aMethod.getCode(aOwningClass);
    Program theProgram = new Program();
    // Initialize programm arguments
    BytecodeLocalVariableTableAttributeInfo theDebugInfos = null;
    if (theCode != null) {
        theDebugInfos = theCode.attributeByType(BytecodeLocalVariableTableAttributeInfo.class);
    }
    int theCurrentIndex = 0;
    if (!aMethod.getAccessFlags().isStatic()) {
        theProgram.addArgument(new LocalVariableDescription(theCurrentIndex), Variable.createThisRef());
        theCurrentIndex++;
    }
    BytecodeTypeRef[] theTypes = aMethod.getSignature().getArguments();
    for (int i = 0; i < theTypes.length; i++) {
        BytecodeTypeRef theRef = theTypes[i];
        if (theDebugInfos != null) {
            BytecodeLocalVariableTableEntry theEntry = theDebugInfos.matchingEntryFor(BytecodeOpcodeAddress.START_AT_ZERO, theCurrentIndex);
            if (theEntry != null) {
                String theVariableName = theDebugInfos.resolveVariableName(theEntry);
                theProgram.addArgument(new LocalVariableDescription(theCurrentIndex), Variable.createMethodParameter(i + 1, theVariableName, TypeRef.toType(theTypes[i])));
            } else {
                theProgram.addArgument(new LocalVariableDescription(theCurrentIndex), Variable.createMethodParameter(i + 1, TypeRef.toType(theTypes[i])));
            }
        } else {
            theProgram.addArgument(new LocalVariableDescription(theCurrentIndex), Variable.createMethodParameter(i + 1, TypeRef.toType(theTypes[i])));
        }
        theCurrentIndex++;
        if (theRef == BytecodePrimitiveTypeRef.LONG || theRef == BytecodePrimitiveTypeRef.DOUBLE) {
            theCurrentIndex++;
        }
    }
    List<BytecodeBasicBlock> theBlocks = new ArrayList<>();
    Function<BytecodeOpcodeAddress, BytecodeBasicBlock> theBasicBlockByAddress = aValue -> {
        for (BytecodeBasicBlock theBlock : theBlocks) {
            if (Objects.equals(aValue, theBlock.getStartAddress())) {
                return theBlock;
            }
        }
        throw new IllegalStateException("No Block for " + aValue.getAddress());
    };
    if (aMethod.getAccessFlags().isAbstract() || aMethod.getAccessFlags().isNative()) {
        return theProgram;
    }
    BytecodeProgram theBytecode = theCode.getProgramm();
    Set<BytecodeOpcodeAddress> theJumpTarget = theBytecode.getJumpTargets();
    BytecodeBasicBlock currentBlock = null;
    for (BytecodeInstruction theInstruction : theBytecode.getInstructions()) {
        if (theJumpTarget.contains(theInstruction.getOpcodeAddress())) {
            // Jump target, start a new basic block
            currentBlock = null;
        }
        if (theBytecode.isStartOfTryBlock(theInstruction.getOpcodeAddress())) {
            // start of try block, hence new basic block
            currentBlock = null;
        }
        if (currentBlock == null) {
            BytecodeBasicBlock.Type theType = BytecodeBasicBlock.Type.NORMAL;
            for (BytecodeExceptionTableEntry theHandler : theBytecode.getExceptionHandlers()) {
                if (Objects.equals(theHandler.getHandlerPc(), theInstruction.getOpcodeAddress())) {
                    if (theHandler.isFinally()) {
                        theType = BytecodeBasicBlock.Type.FINALLY;
                    } else {
                        theType = BytecodeBasicBlock.Type.EXCEPTION_HANDLER;
                    }
                }
            }
            BytecodeBasicBlock theCurrentTemp = currentBlock;
            currentBlock = new BytecodeBasicBlock(theType);
            if (theCurrentTemp != null && !theCurrentTemp.endsWithReturn() && !theCurrentTemp.endsWithThrow() && theCurrentTemp.endsWithGoto() && !theCurrentTemp.endsWithConditionalJump()) {
                theCurrentTemp.addSuccessor(currentBlock);
            }
            theBlocks.add(currentBlock);
        }
        currentBlock.addInstruction(theInstruction);
        if (theInstruction.isJumpSource()) {
            // conditional or unconditional jump, start new basic block
            currentBlock = null;
        } else if (theInstruction instanceof BytecodeInstructionRET) {
            // returning, start new basic block
            currentBlock = null;
        } else if (theInstruction instanceof BytecodeInstructionRETURN) {
            // returning, start new basic block
            currentBlock = null;
        } else if (theInstruction instanceof BytecodeInstructionObjectRETURN) {
            // returning, start new basic block
            currentBlock = null;
        } else if (theInstruction instanceof BytecodeInstructionGenericRETURN) {
            // returning, start new basic block
            currentBlock = null;
        } else if (theInstruction instanceof BytecodeInstructionATHROW) {
            // thowing an exception, start new basic block
            currentBlock = null;
        } else if (theInstruction instanceof BytecodeInstructionInvoke) {
        // invocation, start new basic block
        // currentBlock = null;
        }
    }
    // Now, we have to build the successors of each block
    for (int i = 0; i < theBlocks.size(); i++) {
        BytecodeBasicBlock theBlock = theBlocks.get(i);
        if (!theBlock.endsWithReturn() && !theBlock.endsWithThrow()) {
            if (theBlock.endsWithJump()) {
                for (BytecodeInstruction theInstruction : theBlock.getInstructions()) {
                    if (theInstruction.isJumpSource()) {
                        for (BytecodeOpcodeAddress theBlockJumpTarget : theInstruction.getPotentialJumpTargets()) {
                            theBlock.addSuccessor(theBasicBlockByAddress.apply(theBlockJumpTarget));
                        }
                    }
                }
                if (theBlock.endsWithConditionalJump()) {
                    if (i < theBlocks.size() - 1) {
                        theBlock.addSuccessor(theBlocks.get(i + 1));
                    } else {
                        throw new IllegalStateException("Block at end with no jump target!");
                    }
                }
            } else {
                if (i < theBlocks.size() - 1) {
                    theBlock.addSuccessor(theBlocks.get(i + 1));
                } else {
                    throw new IllegalStateException("Block at end with no jump target!");
                }
            }
        }
    }
    // Ok, now we transform it to GraphNodes with yet empty content
    Map<BytecodeBasicBlock, RegionNode> theCreatedBlocks = new HashMap<>();
    ControlFlowGraph theGraph = theProgram.getControlFlowGraph();
    for (BytecodeBasicBlock theBlock : theBlocks) {
        RegionNode theSingleAssignmentBlock;
        switch(theBlock.getType()) {
            case NORMAL:
                theSingleAssignmentBlock = theGraph.createAt(theBlock.getStartAddress(), RegionNode.BlockType.NORMAL);
                break;
            case EXCEPTION_HANDLER:
                theSingleAssignmentBlock = theGraph.createAt(theBlock.getStartAddress(), RegionNode.BlockType.EXCEPTION_HANDLER);
                break;
            case FINALLY:
                theSingleAssignmentBlock = theGraph.createAt(theBlock.getStartAddress(), RegionNode.BlockType.FINALLY);
                break;
            default:
                throw new IllegalStateException("Unsupported block type : " + theBlock.getType());
        }
        theCreatedBlocks.put(theBlock, theSingleAssignmentBlock);
    }
    // Initialize Block dependency graph
    for (Map.Entry<BytecodeBasicBlock, RegionNode> theEntry : theCreatedBlocks.entrySet()) {
        for (BytecodeBasicBlock theSuccessor : theEntry.getKey().getSuccessors()) {
            RegionNode theSuccessorBlock = theCreatedBlocks.get(theSuccessor);
            if (theSuccessorBlock == null) {
                throw new IllegalStateException("Cannot find successor block");
            }
            theEntry.getValue().addSuccessor(theSuccessorBlock);
        }
    }
    // And add dependencies for exception handlers and finally blocks
    for (BytecodeExceptionTableEntry theHandler : theBytecode.getExceptionHandlers()) {
        RegionNode theStart = theProgram.getControlFlowGraph().nodeStartingAt(theHandler.getStartPC());
        RegionNode theHandlerNode = theProgram.getControlFlowGraph().nodeStartingAt(theHandler.getHandlerPc());
        theStart.addSuccessor(theHandlerNode);
    }
    // Now we can add the SSA instructions to the graph nodes
    Set<RegionNode> theVisited = new HashSet<>();
    RegionNode theStart = theProgram.getControlFlowGraph().startNode();
    // First of all, we need to mark the back-edges of the graph
    theProgram.getControlFlowGraph().calculateReachabilityAndMarkBackEdges();
    try {
        // Now we can continue to create the program flow
        ParsingHelperCache theParsingHelperCache = new ParsingHelperCache(theProgram, aMethod, theStart, theDebugInfos);
        // This will traverse the CFG from bottom to top
        for (RegionNode theNode : theProgram.getControlFlowGraph().finalNodes()) {
            initializeBlock(theProgram, aOwningClass, aMethod, theNode, theVisited, theParsingHelperCache, theBasicBlockByAddress);
        }
        // finally blocks
        for (Map.Entry<BytecodeBasicBlock, RegionNode> theEntry : theCreatedBlocks.entrySet()) {
            RegionNode theBlock = theEntry.getValue();
            if (theBlock.getType() != RegionNode.BlockType.NORMAL) {
                initializeBlock(theProgram, aOwningClass, aMethod, theBlock, theVisited, theParsingHelperCache, theBasicBlockByAddress);
            }
        }
        // Additionally, we have to add gotos
        for (RegionNode theNode : theProgram.getControlFlowGraph().getKnownNodes()) {
            ExpressionList theCurrentList = theNode.getExpressions();
            Expression theLast = theCurrentList.lastExpression();
            if (theLast instanceof GotoExpression) {
                GotoExpression theGoto = (GotoExpression) theLast;
                if (Objects.equals(theGoto.getJumpTarget(), theNode.getStartAddress())) {
                    theCurrentList.remove(theGoto);
                }
            }
            if (!theNode.getExpressions().endWithNeverReturningExpression()) {
                Map<RegionNode.Edge, RegionNode> theSuccessors = theNode.getSuccessors();
                for (Expression theExpression : theCurrentList.toList()) {
                    if (theExpression instanceof IFExpression) {
                        IFExpression theIF = (IFExpression) theExpression;
                        BytecodeOpcodeAddress theGoto = theIF.getGotoAddress();
                        theSuccessors = theSuccessors.entrySet().stream().filter(t -> !Objects.equals(t.getValue().getStartAddress(), theGoto)).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                    }
                }
                List<RegionNode> theSuccessorRegions = theSuccessors.values().stream().filter(t -> t.getType() == RegionNode.BlockType.NORMAL).collect(Collectors.toList());
                if (theSuccessorRegions.size() == 1) {
                    theNode.getExpressions().add(new GotoExpression(theSuccessorRegions.get(0).getStartAddress()).withComment("Resolving pass thru direct"));
                } else {
                    // Special case, the node includes gotos and a fall thru to the same node
                    theSuccessors = theNode.getSuccessors();
                    theSuccessorRegions = theSuccessors.values().stream().filter(t -> t.getType() == RegionNode.BlockType.NORMAL).collect(Collectors.toList());
                    if (theSuccessorRegions.size() == 1) {
                        theNode.getExpressions().add(new GotoExpression(theSuccessorRegions.get(0).getStartAddress()).withComment("Resolving pass thru direct"));
                    } else {
                        throw new IllegalStateException("Invalid number of successors : " + theSuccessors.size() + " for " + theNode.getStartAddress().getAddress());
                    }
                }
            }
        }
        // Check that all PHI-propagations for back-edges are set
        for (RegionNode theNode : theProgram.getControlFlowGraph().getKnownNodes()) {
            ParsingHelper theHelper = theParsingHelperCache.resolveFinalStateForNode(theNode);
            for (Map.Entry<RegionNode.Edge, RegionNode> theEdge : theNode.getSuccessors().entrySet()) {
                if (theEdge.getKey().getType() == RegionNode.EdgeType.BACK) {
                    RegionNode theReceiving = theEdge.getValue();
                    BlockState theReceivingState = theReceiving.toStartState();
                    for (Map.Entry<VariableDescription, Value> theEntry : theReceivingState.getPorts().entrySet()) {
                        Value theExportingValue = theHelper.requestValue(theEntry.getKey());
                        if (theExportingValue == null) {
                            throw new IllegalStateException("No value for " + theEntry.getKey() + " to jump from " + theNode.getStartAddress().getAddress() + " to " + theReceiving.getStartAddress().getAddress());
                        }
                        Variable theReceivingTarget = (Variable) theEntry.getValue();
                        theReceivingTarget.initializeWith(theExportingValue);
                    }
                }
            }
        }
        // Make sure that all jump conditions are met
        for (RegionNode theNode : theProgram.getControlFlowGraph().getKnownNodes()) {
            forEachExpressionOf(theNode, aPoint -> {
                if (aPoint.expression instanceof GotoExpression) {
                    GotoExpression theGoto = (GotoExpression) aPoint.expression;
                    RegionNode theGotoNode = theProgram.getControlFlowGraph().nodeStartingAt(theGoto.getJumpTarget());
                    BlockState theImportingState = theGotoNode.toStartState();
                    for (Map.Entry<VariableDescription, Value> theImporting : theImportingState.getPorts().entrySet()) {
                        ParsingHelper theHelper = theParsingHelperCache.resolveFinalStateForNode(theNode);
                        Value theExportingValue = theHelper.requestValue(theImporting.getKey());
                        if (theExportingValue == null) {
                            throw new IllegalStateException("No value for " + theImporting.getKey() + " to jump from " + theNode.getStartAddress().getAddress() + " to " + theGotoNode.getStartAddress().getAddress());
                        }
                    }
                }
            });
        }
        // Insert PHI value resolving at required places
        for (RegionNode theNode : theProgram.getControlFlowGraph().getKnownNodes()) {
            forEachExpressionOf(theNode, aPoint -> {
                if (aPoint.expression instanceof GotoExpression) {
                    GotoExpression theGoto = (GotoExpression) aPoint.expression;
                    RegionNode theGotoNode = theProgram.getControlFlowGraph().nodeStartingAt(theGoto.getJumpTarget());
                    BlockState theImportingState = theGotoNode.toStartState();
                    String theComments = "";
                    for (Map.Entry<VariableDescription, Value> theImporting : theImportingState.getPorts().entrySet()) {
                        theComments = theComments + theImporting.getKey() + " is of type " + theImporting.getValue().resolveType().resolve() + " with values " + theImporting.getValue().incomingDataFlows();
                        Value theReceivingValue = theImporting.getValue();
                        ParsingHelper theHelper = theParsingHelperCache.resolveFinalStateForNode(theNode);
                        Value theExportingValue = theHelper.requestValue(theImporting.getKey());
                        if (theExportingValue == null) {
                            throw new IllegalStateException("No value for " + theImporting.getKey() + " to jump from " + theNode.getStartAddress().getAddress() + " to " + theGotoNode.getStartAddress().getAddress());
                        }
                        if (theReceivingValue != theExportingValue) {
                            VariableAssignmentExpression theInit = new VariableAssignmentExpression((Variable) theReceivingValue, theExportingValue);
                            aPoint.expressionList.addBefore(theInit, theGoto);
                        }
                    }
                    theGoto.withComment(theComments);
                }
            });
        }
    } catch (Exception e) {
        throw new ControlFlowProcessingException("Error processing CFG for " + aOwningClass.getThisInfo().getConstant().stringValue() + "." + aMethod.getName().stringValue(), e, theProgram.getControlFlowGraph());
    }
    return theProgram;
}
Also used : BytecodeInstructionGenericADD(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericADD) BytecodeInstructionINVOKEINTERFACE(de.mirkosertic.bytecoder.core.BytecodeInstructionINVOKEINTERFACE) BytecodeLocalVariableTableAttributeInfo(de.mirkosertic.bytecoder.core.BytecodeLocalVariableTableAttributeInfo) BytecodeInstructionL2Generic(de.mirkosertic.bytecoder.core.BytecodeInstructionL2Generic) BytecodeInstructionARRAYLENGTH(de.mirkosertic.bytecoder.core.BytecodeInstructionARRAYLENGTH) BytecodeInstructionGenericREM(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericREM) BytecodeLocalVariableTableEntry(de.mirkosertic.bytecoder.core.BytecodeLocalVariableTableEntry) BytecodeInstructionGenericDIV(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericDIV) BytecodeExceptionTableEntry(de.mirkosertic.bytecoder.core.BytecodeExceptionTableEntry) Map(java.util.Map) BytecodeInstructionGETFIELD(de.mirkosertic.bytecoder.core.BytecodeInstructionGETFIELD) BytecodeInstructionD2Generic(de.mirkosertic.bytecoder.core.BytecodeInstructionD2Generic) BytecodeInstructionMONITORENTER(de.mirkosertic.bytecoder.core.BytecodeInstructionMONITORENTER) BytecodeInstructionGenericNEG(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericNEG) BytecodeInstructionGOTO(de.mirkosertic.bytecoder.core.BytecodeInstructionGOTO) BytecodeInstructionGenericMUL(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericMUL) BytecodeInstructionGenericLOAD(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericLOAD) Set(java.util.Set) BytecodeLongConstant(de.mirkosertic.bytecoder.core.BytecodeLongConstant) BytecodeInstructionInvoke(de.mirkosertic.bytecoder.core.BytecodeInstructionInvoke) BytecodeArrayTypeRef(de.mirkosertic.bytecoder.core.BytecodeArrayTypeRef) BytecodeBasicBlock(de.mirkosertic.bytecoder.core.BytecodeBasicBlock) BytecodeInstructionGenericSHR(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericSHR) BytecodeInstructionANEWARRAY(de.mirkosertic.bytecoder.core.BytecodeInstructionANEWARRAY) BytecodeInstructionGenericSTORE(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericSTORE) BytecodeInstructionObjectRETURN(de.mirkosertic.bytecoder.core.BytecodeInstructionObjectRETURN) BytecodeMethodRefConstant(de.mirkosertic.bytecoder.core.BytecodeMethodRefConstant) BytecodeInstructionGenericSHL(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericSHL) BytecodeInstructionLCMP(de.mirkosertic.bytecoder.core.BytecodeInstructionLCMP) BytecodeInstructionPOP(de.mirkosertic.bytecoder.core.BytecodeInstructionPOP) BytecodeInstructionObjectArrayLOAD(de.mirkosertic.bytecoder.core.BytecodeInstructionObjectArrayLOAD) BytecodeInstructionLCONST(de.mirkosertic.bytecoder.core.BytecodeInstructionLCONST) BytecodeInstructionALOAD(de.mirkosertic.bytecoder.core.BytecodeInstructionALOAD) MethodHandle(java.lang.invoke.MethodHandle) BytecodeReferenceIndex(de.mirkosertic.bytecoder.core.BytecodeReferenceIndex) BytecodeBootstrapMethod(de.mirkosertic.bytecoder.core.BytecodeBootstrapMethod) BytecodeBootstrapMethodsAttributeInfo(de.mirkosertic.bytecoder.core.BytecodeBootstrapMethodsAttributeInfo) BytecodeInstructionGenericRETURN(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericRETURN) BytecodeInstructionGenericXOR(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericXOR) BytecodeInstructionDUP2(de.mirkosertic.bytecoder.core.BytecodeInstructionDUP2) ArrayList(java.util.ArrayList) BytecodeInstructionINVOKESTATIC(de.mirkosertic.bytecoder.core.BytecodeInstructionINVOKESTATIC) BytecodeInstructionPUTSTATIC(de.mirkosertic.bytecoder.core.BytecodeInstructionPUTSTATIC) BytecodeInstructionLOOKUPSWITCH(de.mirkosertic.bytecoder.core.BytecodeInstructionLOOKUPSWITCH) BytecodeInstructionINVOKEVIRTUAL(de.mirkosertic.bytecoder.core.BytecodeInstructionINVOKEVIRTUAL) BytecodeClass(de.mirkosertic.bytecoder.core.BytecodeClass) BytecodeInstructionObjectArraySTORE(de.mirkosertic.bytecoder.core.BytecodeInstructionObjectArraySTORE) BytecodeStringConstant(de.mirkosertic.bytecoder.core.BytecodeStringConstant) BytecodeDoubleConstant(de.mirkosertic.bytecoder.core.BytecodeDoubleConstant) BytecodeInstructionINVOKESPECIAL(de.mirkosertic.bytecoder.core.BytecodeInstructionINVOKESPECIAL) BytecodeInstructionGenericArraySTORE(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericArraySTORE) BytecodeObjectTypeRef(de.mirkosertic.bytecoder.core.BytecodeObjectTypeRef) BytecodeInstructionACONSTNULL(de.mirkosertic.bytecoder.core.BytecodeInstructionACONSTNULL) BytecodeInstructionRET(de.mirkosertic.bytecoder.core.BytecodeInstructionRET) Address(de.mirkosertic.bytecoder.classlib.Address) BytecodeInstructionNEW(de.mirkosertic.bytecoder.core.BytecodeInstructionNEW) BytecodeInstructionBIPUSH(de.mirkosertic.bytecoder.core.BytecodeInstructionBIPUSH) BytecodeInstructionCHECKCAST(de.mirkosertic.bytecoder.core.BytecodeInstructionCHECKCAST) BytecodeUtf8Constant(de.mirkosertic.bytecoder.core.BytecodeUtf8Constant) BytecodeOpcodeAddress(de.mirkosertic.bytecoder.core.BytecodeOpcodeAddress) BytecodeInstructionASTORE(de.mirkosertic.bytecoder.core.BytecodeInstructionASTORE) BytecodeInstructionIFNULL(de.mirkosertic.bytecoder.core.BytecodeInstructionIFNULL) BytecodeInstructionMONITOREXIT(de.mirkosertic.bytecoder.core.BytecodeInstructionMONITOREXIT) BytecodeIntegerConstant(de.mirkosertic.bytecoder.core.BytecodeIntegerConstant) BytecodeMethodTypeConstant(de.mirkosertic.bytecoder.core.BytecodeMethodTypeConstant) BytecodeInstructionPOP2(de.mirkosertic.bytecoder.core.BytecodeInstructionPOP2) Array(java.lang.reflect.Array) BytecodeInstructionDUP(de.mirkosertic.bytecoder.core.BytecodeInstructionDUP) BytecodeInstructionDUP2X1(de.mirkosertic.bytecoder.core.BytecodeInstructionDUP2X1) BytecodeInstructionINSTANCEOF(de.mirkosertic.bytecoder.core.BytecodeInstructionINSTANCEOF) BytecodeInstructionATHROW(de.mirkosertic.bytecoder.core.BytecodeInstructionATHROW) BytecodeInstructionTABLESWITCH(de.mirkosertic.bytecoder.core.BytecodeInstructionTABLESWITCH) BytecodeInstructionGenericOR(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericOR) BytecodeInstructionF2Generic(de.mirkosertic.bytecoder.core.BytecodeInstructionF2Generic) BytecodeInstructionINVOKEDYNAMIC(de.mirkosertic.bytecoder.core.BytecodeInstructionINVOKEDYNAMIC) BytecodePrimitiveTypeRef(de.mirkosertic.bytecoder.core.BytecodePrimitiveTypeRef) BytecodeLinkerContext(de.mirkosertic.bytecoder.core.BytecodeLinkerContext) BytecodeInstructionGenericCMP(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericCMP) Collection(java.util.Collection) BytecodeInstructionRETURN(de.mirkosertic.bytecoder.core.BytecodeInstructionRETURN) MemoryManager(de.mirkosertic.bytecoder.classlib.MemoryManager) BytecodeInstructionIFICMP(de.mirkosertic.bytecoder.core.BytecodeInstructionIFICMP) BytecodeMethodSignature(de.mirkosertic.bytecoder.core.BytecodeMethodSignature) Collectors(java.util.stream.Collectors) BytecodeInstructionPUTFIELD(de.mirkosertic.bytecoder.core.BytecodeInstructionPUTFIELD) BytecodeInstructionGenericSUB(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericSUB) BytecodeProgram(de.mirkosertic.bytecoder.core.BytecodeProgram) Objects(java.util.Objects) BytecodeInstructionIFACMP(de.mirkosertic.bytecoder.core.BytecodeInstructionIFACMP) BytecodeMethodHandleConstant(de.mirkosertic.bytecoder.core.BytecodeMethodHandleConstant) List(java.util.List) BytecodeConstant(de.mirkosertic.bytecoder.core.BytecodeConstant) BytecodeInstructionIINC(de.mirkosertic.bytecoder.core.BytecodeInstructionIINC) BytecodeInstructionFCONST(de.mirkosertic.bytecoder.core.BytecodeInstructionFCONST) BytecodeInstructionICONST(de.mirkosertic.bytecoder.core.BytecodeInstructionICONST) BytecodeInstruction(de.mirkosertic.bytecoder.core.BytecodeInstruction) BytecodeInstructionGETSTATIC(de.mirkosertic.bytecoder.core.BytecodeInstructionGETSTATIC) BytecodeCodeAttributeInfo(de.mirkosertic.bytecoder.core.BytecodeCodeAttributeInfo) BytecodeInstructionNOP(de.mirkosertic.bytecoder.core.BytecodeInstructionNOP) BytecodeTypeRef(de.mirkosertic.bytecoder.core.BytecodeTypeRef) BytecodeClassinfoConstant(de.mirkosertic.bytecoder.core.BytecodeClassinfoConstant) BytecodeInstructionDUPX2(de.mirkosertic.bytecoder.core.BytecodeInstructionDUPX2) BytecodeInstructionDUPX1(de.mirkosertic.bytecoder.core.BytecodeInstructionDUPX1) BytecodeInstructionGenericArrayLOAD(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericArrayLOAD) HashMap(java.util.HashMap) BytecodeFloatConstant(de.mirkosertic.bytecoder.core.BytecodeFloatConstant) Function(java.util.function.Function) Stack(java.util.Stack) BytecodeInstructionIFCOND(de.mirkosertic.bytecoder.core.BytecodeInstructionIFCOND) HashSet(java.util.HashSet) BytecodeInstructionGenericAND(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericAND) BytecodeInstructionDCONST(de.mirkosertic.bytecoder.core.BytecodeInstructionDCONST) BytecodeInvokeDynamicConstant(de.mirkosertic.bytecoder.core.BytecodeInvokeDynamicConstant) BytecodeInstructionNEWMULTIARRAY(de.mirkosertic.bytecoder.core.BytecodeInstructionNEWMULTIARRAY) BytecodeMethod(de.mirkosertic.bytecoder.core.BytecodeMethod) VM(de.mirkosertic.bytecoder.classlib.VM) BytecodeLinkedClass(de.mirkosertic.bytecoder.core.BytecodeLinkedClass) BytecodeInstructionIFNONNULL(de.mirkosertic.bytecoder.core.BytecodeInstructionIFNONNULL) BytecodeInstructionNEWARRAY(de.mirkosertic.bytecoder.core.BytecodeInstructionNEWARRAY) Consumer(java.util.function.Consumer) BytecodeInstructionI2Generic(de.mirkosertic.bytecoder.core.BytecodeInstructionI2Generic) BytecodeInstructionGenericLDC(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericLDC) Collections(java.util.Collections) BytecodeInstructionSIPUSH(de.mirkosertic.bytecoder.core.BytecodeInstructionSIPUSH) BytecodeInstructionGenericUSHR(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericUSHR) HashMap(java.util.HashMap) BytecodeLocalVariableTableEntry(de.mirkosertic.bytecoder.core.BytecodeLocalVariableTableEntry) BytecodeInstructionATHROW(de.mirkosertic.bytecoder.core.BytecodeInstructionATHROW) ArrayList(java.util.ArrayList) BytecodeBasicBlock(de.mirkosertic.bytecoder.core.BytecodeBasicBlock) BytecodeOpcodeAddress(de.mirkosertic.bytecoder.core.BytecodeOpcodeAddress) HashSet(java.util.HashSet) BytecodeProgram(de.mirkosertic.bytecoder.core.BytecodeProgram) BytecodeLocalVariableTableAttributeInfo(de.mirkosertic.bytecoder.core.BytecodeLocalVariableTableAttributeInfo) BytecodeInstruction(de.mirkosertic.bytecoder.core.BytecodeInstruction) BytecodeTypeRef(de.mirkosertic.bytecoder.core.BytecodeTypeRef) BytecodeExceptionTableEntry(de.mirkosertic.bytecoder.core.BytecodeExceptionTableEntry) Map(java.util.Map) HashMap(java.util.HashMap) BytecodeInstructionGenericRETURN(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericRETURN) BytecodeProgram(de.mirkosertic.bytecoder.core.BytecodeProgram) BytecodeInstructionInvoke(de.mirkosertic.bytecoder.core.BytecodeInstructionInvoke) BytecodeLocalVariableTableEntry(de.mirkosertic.bytecoder.core.BytecodeLocalVariableTableEntry) BytecodeExceptionTableEntry(de.mirkosertic.bytecoder.core.BytecodeExceptionTableEntry) BytecodeInstructionObjectRETURN(de.mirkosertic.bytecoder.core.BytecodeInstructionObjectRETURN) BytecodeInstructionRET(de.mirkosertic.bytecoder.core.BytecodeInstructionRET) BytecodeInstructionRETURN(de.mirkosertic.bytecoder.core.BytecodeInstructionRETURN) BytecodeCodeAttributeInfo(de.mirkosertic.bytecoder.core.BytecodeCodeAttributeInfo)

Aggregations

BytecodeTypeRef (de.mirkosertic.bytecoder.core.BytecodeTypeRef)17 BytecodeMethodSignature (de.mirkosertic.bytecoder.core.BytecodeMethodSignature)11 BytecodeObjectTypeRef (de.mirkosertic.bytecoder.core.BytecodeObjectTypeRef)7 BytecodeLinkedClass (de.mirkosertic.bytecoder.core.BytecodeLinkedClass)6 BytecodeArrayTypeRef (de.mirkosertic.bytecoder.core.BytecodeArrayTypeRef)5 BytecodeMethod (de.mirkosertic.bytecoder.core.BytecodeMethod)5 StringValue (de.mirkosertic.bytecoder.ssa.StringValue)5 Address (de.mirkosertic.bytecoder.classlib.Address)4 MemoryManager (de.mirkosertic.bytecoder.classlib.MemoryManager)4 BytecodeProgram (de.mirkosertic.bytecoder.core.BytecodeProgram)4 ArrayList (java.util.ArrayList)4 BytecodeInstructionACONSTNULL (de.mirkosertic.bytecoder.core.BytecodeInstructionACONSTNULL)3 HashSet (java.util.HashSet)3 ConstantPool (de.mirkosertic.bytecoder.backend.ConstantPool)2 VM (de.mirkosertic.bytecoder.classlib.VM)2 BytecodeClass (de.mirkosertic.bytecoder.core.BytecodeClass)2 BytecodeInstructionGOTO (de.mirkosertic.bytecoder.core.BytecodeInstructionGOTO)2 BytecodeInstructionGenericADD (de.mirkosertic.bytecoder.core.BytecodeInstructionGenericADD)2 BytecodeInstructionGenericLOAD (de.mirkosertic.bytecoder.core.BytecodeInstructionGenericLOAD)2 BytecodeInstructionGenericRETURN (de.mirkosertic.bytecoder.core.BytecodeInstructionGenericRETURN)2