Search in sources :

Example 1 with BreakExpression

use of de.mirkosertic.bytecoder.ssa.BreakExpression in project Bytecoder by mirkosertic.

the class Relooper method debugPrint.

private void debugPrint(PrintStream aStream, int aInset, ExpressionList aExpressionList) {
    for (Expression theExpression : aExpressionList.toList()) {
        if (theExpression instanceof BreakExpression) {
            BreakExpression theBreak = (BreakExpression) theExpression;
            printInset(aStream, aInset);
            aStream.println("Break " + theBreak.blockToBreak().name() + " and jump to " + theBreak.jumpTarget().getAddress());
        } else if (theExpression instanceof ContinueExpression) {
            ContinueExpression theContinue = (ContinueExpression) theExpression;
            printInset(aStream, aInset);
            aStream.println("Continue at " + theContinue.labelToReturnTo().name());
        } else if (theExpression instanceof ReturnExpression) {
            printInset(aStream, aInset);
            aStream.println("Return");
        } else if (theExpression instanceof GotoExpression) {
            throw new IllegalStateException("Goto should have been removed!");
        }
    }
}
Also used : ReturnExpression(de.mirkosertic.bytecoder.ssa.ReturnExpression) GotoExpression(de.mirkosertic.bytecoder.ssa.GotoExpression) ContinueExpression(de.mirkosertic.bytecoder.ssa.ContinueExpression) Expression(de.mirkosertic.bytecoder.ssa.Expression) GotoExpression(de.mirkosertic.bytecoder.ssa.GotoExpression) ReturnExpression(de.mirkosertic.bytecoder.ssa.ReturnExpression) BreakExpression(de.mirkosertic.bytecoder.ssa.BreakExpression) ContinueExpression(de.mirkosertic.bytecoder.ssa.ContinueExpression) BreakExpression(de.mirkosertic.bytecoder.ssa.BreakExpression)

Example 2 with BreakExpression

use of de.mirkosertic.bytecoder.ssa.BreakExpression in project Bytecoder by mirkosertic.

the class Relooper method replaceGotosIn.

private void replaceGotosIn(Stack<Block> aTraversalStack, Block aBlock) {
    if (aBlock == null) {
        return;
    }
    if (aBlock instanceof SimpleBlock) {
        SimpleBlock theSimple = (SimpleBlock) aBlock;
        aTraversalStack.push(theSimple);
        RegionNode theInternalLabel = theSimple.internalLabel();
        replaceGotosIn(aTraversalStack, theSimple, theInternalLabel, theInternalLabel.getExpressions());
        replaceGotosIn(aTraversalStack, theSimple.next());
        aTraversalStack.pop();
        RegionNode theNode = theSimple.internalLabel;
        Expression theLastExpression = theNode.getExpressions().lastExpression();
        // can be silent, they only need to set the __label__ variable
        if (theLastExpression instanceof BreakExpression) {
            BreakExpression theBreak = (BreakExpression) theLastExpression;
            if (Objects.equals(theBreak.blockToBreak().name(), theSimple.label().name())) {
                theBreak.silent();
            }
        }
        return;
    }
    if (aBlock instanceof LoopBlock) {
        LoopBlock theLoop = (LoopBlock) aBlock;
        aTraversalStack.push(theLoop);
        replaceGotosIn(aTraversalStack, theLoop.inner());
        replaceGotosIn(aTraversalStack, theLoop.next());
        aTraversalStack.pop();
        return;
    }
    if (aBlock instanceof MultipleBlock) {
        MultipleBlock theMultiple = (MultipleBlock) aBlock;
        aTraversalStack.push(theMultiple);
        for (Block theHandler : theMultiple.handlers()) {
            replaceGotosIn(aTraversalStack, theHandler);
        }
        replaceGotosIn(aTraversalStack, theMultiple.next());
        aTraversalStack.pop();
        return;
    }
    throw new IllegalStateException("Don't know how to handle " + aBlock);
}
Also used : Expression(de.mirkosertic.bytecoder.ssa.Expression) GotoExpression(de.mirkosertic.bytecoder.ssa.GotoExpression) ReturnExpression(de.mirkosertic.bytecoder.ssa.ReturnExpression) BreakExpression(de.mirkosertic.bytecoder.ssa.BreakExpression) ContinueExpression(de.mirkosertic.bytecoder.ssa.ContinueExpression) RegionNode(de.mirkosertic.bytecoder.ssa.RegionNode) BreakExpression(de.mirkosertic.bytecoder.ssa.BreakExpression)

Example 3 with BreakExpression

use of de.mirkosertic.bytecoder.ssa.BreakExpression in project Bytecoder by mirkosertic.

the class Relooper method replaceGotosIn.

private void replaceGotosIn(Stack<Block> aTraversalStack, SimpleBlock aCurrent, RegionNode aLabel, ExpressionList aList) {
    for (Expression theExpression : aList.toList()) {
        if (theExpression instanceof ExpressionListContainer) {
            ExpressionListContainer theContainer = (ExpressionListContainer) theExpression;
            for (ExpressionList theList : theContainer.getExpressionLists()) {
                replaceGotosIn(aTraversalStack, aCurrent, aLabel, theList);
            }
        }
        if (theExpression instanceof GotoExpression) {
            GotoExpression theGoto = (GotoExpression) theExpression;
            boolean theGotoFound = false;
            // We search the successor edge
            for (Map.Entry<RegionNode.Edge, RegionNode> theSuc : aLabel.getSuccessors().entrySet()) {
                if (Objects.equals(theSuc.getValue().getStartAddress(), theGoto.getJumpTarget())) {
                    theGotoFound = true;
                    RegionNode theTarget = theSuc.getValue();
                    // We found the matching edge
                    if (theSuc.getKey().getType() == RegionNode.EdgeType.NORMAL) {
                        // We can only branch to the next block
                        // We search the whole hiararchy to find the right block to break out
                        boolean theSomethingFound = false;
                        for (int i = aTraversalStack.size() - 1; i >= 0; i--) {
                            Block theNestingBlock = aTraversalStack.get(i);
                            if (theNestingBlock.next() != null && theNestingBlock.next().entries().contains(theTarget)) {
                                theNestingBlock.requireLabel();
                                BreakExpression theBreak = new BreakExpression(theNestingBlock.label(), theTarget.getStartAddress());
                                aList.replace(theGoto, theBreak);
                                if (theNestingBlock.next() instanceof SimpleBlock && theNestingBlock.next().entries().size() == 1) {
                                    theBreak.noSetRequired();
                                }
                                theSomethingFound = true;
                                break;
                            } else if (theNestingBlock.entries().contains(theTarget)) {
                                theNestingBlock.requireLabel();
                                ContinueExpression theContinue = new ContinueExpression(theNestingBlock.label(), theTarget.getStartAddress());
                                aList.replace(theGoto, theContinue);
                                theSomethingFound = true;
                                break;
                            }
                        }
                        if (!theSomethingFound) {
                            throw new IllegalStateException("Failed to jump to " + theTarget.getStartAddress().getAddress() + " from " + aCurrent.label().name() + " : no matching entry found!");
                        }
                    } else {
                        // We can only branch back into the known stack of nested blocks
                        boolean theSomethingFound = false;
                        for (Block theNestingBlock : aTraversalStack) {
                            if (theNestingBlock.entries().contains(theTarget)) {
                                theSomethingFound = true;
                                // We can return to the target in the hierarchy
                                theNestingBlock.requireLabel();
                                ContinueExpression theContinue = new ContinueExpression(theNestingBlock.label(), theTarget.getStartAddress());
                                aList.replace(theGoto, theContinue);
                                break;
                            }
                        }
                        if (!theSomethingFound) {
                            throw new IllegalStateException("No back edge target found for " + theTarget.getStartAddress().getAddress());
                        }
                    }
                }
            }
            if (!theGotoFound) {
                throw new IllegalStateException("No GOTO possible for " + theGoto.getJumpTarget().getAddress() + " in label " + aCurrent.label().name());
            }
        }
    }
}
Also used : BreakExpression(de.mirkosertic.bytecoder.ssa.BreakExpression) GotoExpression(de.mirkosertic.bytecoder.ssa.GotoExpression) ContinueExpression(de.mirkosertic.bytecoder.ssa.ContinueExpression) Expression(de.mirkosertic.bytecoder.ssa.Expression) GotoExpression(de.mirkosertic.bytecoder.ssa.GotoExpression) ReturnExpression(de.mirkosertic.bytecoder.ssa.ReturnExpression) BreakExpression(de.mirkosertic.bytecoder.ssa.BreakExpression) ContinueExpression(de.mirkosertic.bytecoder.ssa.ContinueExpression) ExpressionListContainer(de.mirkosertic.bytecoder.ssa.ExpressionListContainer) RegionNode(de.mirkosertic.bytecoder.ssa.RegionNode) ExpressionList(de.mirkosertic.bytecoder.ssa.ExpressionList) HashMap(java.util.HashMap) Map(java.util.Map)

Example 4 with BreakExpression

use of de.mirkosertic.bytecoder.ssa.BreakExpression in project Bytecoder by mirkosertic.

the class OpenCLWriter method writeExpressions.

private void writeExpressions(ExpressionList aList) {
    for (Expression theExpression : aList.toList()) {
        if (options.isDebugOutput()) {
            String theComment = theExpression.getComment();
            if (theComment != null && !theComment.isEmpty()) {
                print("// ");
                println(theComment);
            }
        }
        if (theExpression instanceof VariableAssignmentExpression) {
            VariableAssignmentExpression theInit = (VariableAssignmentExpression) theExpression;
            Variable theVariable = theInit.getVariable();
            Value theValue = theInit.getValue();
            if (theVariable.resolveType().isObject() && theValue instanceof InvocationExpression) {
                print(toType(theVariable.resolveType(), false));
                print(" ");
                print(theVariable.getName());
                print("_temp = ");
                printValue(theValue);
                println(";");
                print(theVariable.getName());
                print(" = &");
                print(theVariable.getName());
                println("_temp;");
            } else {
                print(theVariable.getName());
                print(" = ");
                printValue(theValue);
                println(";");
            }
        } else if (theExpression instanceof ArrayStoreExpression) {
            ArrayStoreExpression theStore = (ArrayStoreExpression) theExpression;
            List<Value> theIncomingData = theStore.incomingDataFlows();
            Value theArray = theIncomingData.get(0);
            Value theIndex = theIncomingData.get(1);
            Value theValue = theIncomingData.get(2);
            printValue(theArray);
            print("[");
            printValue(theIndex);
            print("] = ");
            printValue(theValue);
            println(";");
        } else if (theExpression instanceof IFExpression) {
            IFExpression theE = (IFExpression) theExpression;
            print("if ");
            printValue(theE.incomingDataFlows().get(0));
            println(" {");
            withDeeperIndent().writeExpressions(theE.getExpressions());
            println("}");
        } else if (theExpression instanceof BreakExpression) {
            BreakExpression theBreak = (BreakExpression) theExpression;
            if (theBreak.isSetLabelRequired()) {
                print("$__label__ = ");
                print(theBreak.jumpTarget().getAddress());
                println(";");
            }
            if (!theBreak.isSilent()) {
                print("goto $");
                print(theBreak.blockToBreak().name());
                println("_next;");
            }
        } else if (theExpression instanceof ContinueExpression) {
            ContinueExpression theContinue = (ContinueExpression) theExpression;
            print("$__label__ = ");
            print(theContinue.jumpTarget().getAddress());
            println(";");
            print("goto $");
            print(theContinue.labelToReturnTo().name());
            println(";");
        } else if (theExpression instanceof ReturnExpression) {
            println("return;");
        } else if (theExpression instanceof PutFieldExpression) {
            PutFieldExpression thePutField = (PutFieldExpression) theExpression;
            List<Value> theIncomingData = thePutField.incomingDataFlows();
            Value theTarget = theIncomingData.get(0);
            BytecodeFieldRefConstant theField = thePutField.getField();
            Value thevalue = theIncomingData.get(1);
            printValue(theTarget);
            printInstanceFieldReference(theField);
            print(" = ");
            printValue(thevalue);
            println(";");
        } else if (theExpression instanceof ReturnValueExpression) {
            ReturnValueExpression theReturn = (ReturnValueExpression) theExpression;
            List<Value> theIncomingData = theReturn.incomingDataFlows();
            print("return ");
            printValue(theIncomingData.get(0));
            println(";");
        } else {
            throw new IllegalArgumentException("Not supported. " + theExpression);
        }
    }
}
Also used : Variable(de.mirkosertic.bytecoder.ssa.Variable) InvocationExpression(de.mirkosertic.bytecoder.ssa.InvocationExpression) IFExpression(de.mirkosertic.bytecoder.ssa.IFExpression) PutFieldExpression(de.mirkosertic.bytecoder.ssa.PutFieldExpression) BreakExpression(de.mirkosertic.bytecoder.ssa.BreakExpression) VariableAssignmentExpression(de.mirkosertic.bytecoder.ssa.VariableAssignmentExpression) ReturnValueExpression(de.mirkosertic.bytecoder.ssa.ReturnValueExpression) ReturnExpression(de.mirkosertic.bytecoder.ssa.ReturnExpression) ArrayStoreExpression(de.mirkosertic.bytecoder.ssa.ArrayStoreExpression) ContinueExpression(de.mirkosertic.bytecoder.ssa.ContinueExpression) InvokeVirtualMethodExpression(de.mirkosertic.bytecoder.ssa.InvokeVirtualMethodExpression) TypeConversionExpression(de.mirkosertic.bytecoder.ssa.TypeConversionExpression) CompareExpression(de.mirkosertic.bytecoder.ssa.CompareExpression) DirectInvokeMethodExpression(de.mirkosertic.bytecoder.ssa.DirectInvokeMethodExpression) InvocationExpression(de.mirkosertic.bytecoder.ssa.InvocationExpression) VariableAssignmentExpression(de.mirkosertic.bytecoder.ssa.VariableAssignmentExpression) InvokeStaticMethodExpression(de.mirkosertic.bytecoder.ssa.InvokeStaticMethodExpression) ReturnExpression(de.mirkosertic.bytecoder.ssa.ReturnExpression) ReturnValueExpression(de.mirkosertic.bytecoder.ssa.ReturnValueExpression) ArrayStoreExpression(de.mirkosertic.bytecoder.ssa.ArrayStoreExpression) BinaryExpression(de.mirkosertic.bytecoder.ssa.BinaryExpression) GetFieldExpression(de.mirkosertic.bytecoder.ssa.GetFieldExpression) ContinueExpression(de.mirkosertic.bytecoder.ssa.ContinueExpression) IFExpression(de.mirkosertic.bytecoder.ssa.IFExpression) ArrayEntryExpression(de.mirkosertic.bytecoder.ssa.ArrayEntryExpression) Expression(de.mirkosertic.bytecoder.ssa.Expression) PutFieldExpression(de.mirkosertic.bytecoder.ssa.PutFieldExpression) BreakExpression(de.mirkosertic.bytecoder.ssa.BreakExpression) DoubleValue(de.mirkosertic.bytecoder.ssa.DoubleValue) Value(de.mirkosertic.bytecoder.ssa.Value) IntegerValue(de.mirkosertic.bytecoder.ssa.IntegerValue) LongValue(de.mirkosertic.bytecoder.ssa.LongValue) FloatValue(de.mirkosertic.bytecoder.ssa.FloatValue) ExpressionList(de.mirkosertic.bytecoder.ssa.ExpressionList) List(java.util.List) BytecodeFieldRefConstant(de.mirkosertic.bytecoder.core.BytecodeFieldRefConstant)

Example 5 with BreakExpression

use of de.mirkosertic.bytecoder.ssa.BreakExpression in project Bytecoder by mirkosertic.

the class WASMSSAWriter method writeExpression.

private void writeExpression(Expression aExpression) {
    if (options.isDebugOutput()) {
        String theComment = aExpression.getComment();
        if (theComment != null && !theComment.isEmpty()) {
            print(";; ");
            println(theComment);
        }
    }
    if (aExpression instanceof CheckCastExpression) {
        return;
    }
    if (aExpression instanceof ReturnExpression) {
        writeReturnExpression((ReturnExpression) aExpression);
        return;
    }
    if (aExpression instanceof VariableAssignmentExpression) {
        writeInitVariableExpression((VariableAssignmentExpression) aExpression);
        return;
    }
    if (aExpression instanceof DirectInvokeMethodExpression) {
        writeDirectMethodInvokeExpression((DirectInvokeMethodExpression) aExpression);
        return;
    }
    if (aExpression instanceof IFExpression) {
        writeIFExpression((IFExpression) aExpression);
        return;
    }
    if (aExpression instanceof GotoExpression) {
        writeGotoExpression((GotoExpression) aExpression);
        return;
    }
    if (aExpression instanceof ReturnValueExpression) {
        writeReturnExpression((ReturnValueExpression) aExpression);
        return;
    }
    if (aExpression instanceof PutFieldExpression) {
        writePutFieldExpression((PutFieldExpression) aExpression);
        return;
    }
    if (aExpression instanceof SetMemoryLocationExpression) {
        writeSetMemoryLocationExpression((SetMemoryLocationExpression) aExpression);
        return;
    }
    if (aExpression instanceof PutStaticExpression) {
        writePutStaticExpression((PutStaticExpression) aExpression);
        return;
    }
    if (aExpression instanceof InvokeStaticMethodExpression) {
        writeInvokeStaticExpression((InvokeStaticMethodExpression) aExpression);
        return;
    }
    if (aExpression instanceof ThrowExpression) {
        writeThrowExpression((ThrowExpression) aExpression);
        return;
    }
    if (aExpression instanceof ArrayStoreExpression) {
        writeArrayStoreExpression((ArrayStoreExpression) aExpression);
        return;
    }
    if (aExpression instanceof InvokeVirtualMethodExpression) {
        writeInvokeVirtualExpression((InvokeVirtualMethodExpression) aExpression);
        return;
    }
    if (aExpression instanceof TableSwitchExpression) {
        writeTableSwitchExpression((TableSwitchExpression) aExpression);
        return;
    }
    if (aExpression instanceof LookupSwitchExpression) {
        writeLookupSwitchExpression((LookupSwitchExpression) aExpression);
        return;
    }
    if (aExpression instanceof UnreachableExpression) {
        writeUnreachable((UnreachableExpression) aExpression);
        return;
    }
    if (aExpression instanceof BreakExpression) {
        BreakExpression theBreak = (BreakExpression) aExpression;
        if (theBreak.isSetLabelRequired()) {
            print("(set_local $__label__ (i32.const ");
            print(theBreak.jumpTarget().getAddress());
            println("))");
        }
        if (!theBreak.isSilent()) {
            print("(br $");
            print(theBreak.blockToBreak().name());
            println(")");
        }
        return;
    }
    if (aExpression instanceof ContinueExpression) {
        ContinueExpression theContinue = (ContinueExpression) aExpression;
        print("(set_local $__label__ (i32.const ");
        print(theContinue.jumpTarget().getAddress());
        println("))");
        print("(br $");
        print(theContinue.labelToReturnTo().name());
        println("_inner)");
        return;
    }
    throw new IllegalStateException("Not supported : " + aExpression);
}
Also used : LookupSwitchExpression(de.mirkosertic.bytecoder.ssa.LookupSwitchExpression) ThrowExpression(de.mirkosertic.bytecoder.ssa.ThrowExpression) IFExpression(de.mirkosertic.bytecoder.ssa.IFExpression) PutStaticExpression(de.mirkosertic.bytecoder.ssa.PutStaticExpression) DirectInvokeMethodExpression(de.mirkosertic.bytecoder.ssa.DirectInvokeMethodExpression) PutFieldExpression(de.mirkosertic.bytecoder.ssa.PutFieldExpression) InvokeStaticMethodExpression(de.mirkosertic.bytecoder.ssa.InvokeStaticMethodExpression) BreakExpression(de.mirkosertic.bytecoder.ssa.BreakExpression) VariableAssignmentExpression(de.mirkosertic.bytecoder.ssa.VariableAssignmentExpression) TableSwitchExpression(de.mirkosertic.bytecoder.ssa.TableSwitchExpression) ReturnValueExpression(de.mirkosertic.bytecoder.ssa.ReturnValueExpression) ReturnExpression(de.mirkosertic.bytecoder.ssa.ReturnExpression) ArrayStoreExpression(de.mirkosertic.bytecoder.ssa.ArrayStoreExpression) GotoExpression(de.mirkosertic.bytecoder.ssa.GotoExpression) CheckCastExpression(de.mirkosertic.bytecoder.ssa.CheckCastExpression) InvokeVirtualMethodExpression(de.mirkosertic.bytecoder.ssa.InvokeVirtualMethodExpression) ContinueExpression(de.mirkosertic.bytecoder.ssa.ContinueExpression) SetMemoryLocationExpression(de.mirkosertic.bytecoder.ssa.SetMemoryLocationExpression) UnreachableExpression(de.mirkosertic.bytecoder.ssa.UnreachableExpression)

Aggregations

BreakExpression (de.mirkosertic.bytecoder.ssa.BreakExpression)6 ContinueExpression (de.mirkosertic.bytecoder.ssa.ContinueExpression)6 Expression (de.mirkosertic.bytecoder.ssa.Expression)5 GotoExpression (de.mirkosertic.bytecoder.ssa.GotoExpression)5 ReturnExpression (de.mirkosertic.bytecoder.ssa.ReturnExpression)5 ArrayStoreExpression (de.mirkosertic.bytecoder.ssa.ArrayStoreExpression)3 DirectInvokeMethodExpression (de.mirkosertic.bytecoder.ssa.DirectInvokeMethodExpression)3 ExpressionList (de.mirkosertic.bytecoder.ssa.ExpressionList)3 IFExpression (de.mirkosertic.bytecoder.ssa.IFExpression)3 InvokeStaticMethodExpression (de.mirkosertic.bytecoder.ssa.InvokeStaticMethodExpression)3 InvokeVirtualMethodExpression (de.mirkosertic.bytecoder.ssa.InvokeVirtualMethodExpression)3 BytecodeFieldRefConstant (de.mirkosertic.bytecoder.core.BytecodeFieldRefConstant)2 ArrayEntryExpression (de.mirkosertic.bytecoder.ssa.ArrayEntryExpression)2 BinaryExpression (de.mirkosertic.bytecoder.ssa.BinaryExpression)2 CheckCastExpression (de.mirkosertic.bytecoder.ssa.CheckCastExpression)2 CompareExpression (de.mirkosertic.bytecoder.ssa.CompareExpression)2 DoubleValue (de.mirkosertic.bytecoder.ssa.DoubleValue)2 FloatValue (de.mirkosertic.bytecoder.ssa.FloatValue)2 GetFieldExpression (de.mirkosertic.bytecoder.ssa.GetFieldExpression)2 IntegerValue (de.mirkosertic.bytecoder.ssa.IntegerValue)2