From c25af548273472dbee4ed4c914b70081fd508cde Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 28 Oct 1998 18:25:20 +0000 Subject: [PATCH] string += implemented git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@92 379699f6-c40d-0410-875b-85095c16579e --- jode/jode/flow/CreateAssignExpression.java | 195 ++++++++++++--------- 1 file changed, 117 insertions(+), 78 deletions(-) diff --git a/jode/jode/flow/CreateAssignExpression.java b/jode/jode/flow/CreateAssignExpression.java index 8bc8339..1978bad 100644 --- a/jode/jode/flow/CreateAssignExpression.java +++ b/jode/jode/flow/CreateAssignExpression.java @@ -23,108 +23,147 @@ import jode.*; public class CreateAssignExpression implements Transformation{ public boolean transform(FlowBlock flow) { + if (!(flow.lastModified instanceof InstructionContainer) + || !(flow.lastModified.outer instanceof SequentialBlock) + || !(((InstructionContainer)flow.lastModified).getInstruction() + instanceof StoreInstruction) + || !(((InstructionContainer)flow.lastModified).getInstruction() + .isVoid())) + return false; + return (createAssignOp(flow) || createAssignExpression(flow)); } public boolean createAssignOp(FlowBlock flow) { - Expression rightHandSide; - StoreInstruction store; - BinaryOperator binop; - InstructionContainer lastBlock; - SequentialBlock opBlock; - SequentialBlock sequBlock; - boolean isExpression = false; - try { - InstructionBlock ib; - lastBlock = (InstructionContainer) flow.lastModified; - store = (StoreInstruction) lastBlock.getInstruction(); - - opBlock = (SequentialBlock) lastBlock.outer; - if (opBlock.subBlocks[1] != lastBlock) + + /* Situation: + * + * (push loadstoreOps) <- not checked + * sequBlock: + * dup + * opBlock: + * load(stack) * rightHandSide + * (optional dup_x) + * store(stack) + * + * We transform it to: + * (push loadstoreOps) + * rightHandSide + * store(stack) *= (stack) + * + * If the optional dup is present the store*= becomes non void. + */ + InstructionContainer lastBlock + = (InstructionContainer) flow.lastModified; + SequentialBlock opBlock = (SequentialBlock) lastBlock.outer; + StoreInstruction store + = (StoreInstruction) lastBlock.getInstruction(); + + boolean isAssignOp = false; + if (opBlock.subBlocks[0] instanceof SpecialBlock) { + SpecialBlock dup = (SpecialBlock) opBlock.subBlocks[0]; + if (dup.type != SpecialBlock.DUP + || dup.depth != store.getLValueOperandCount() + || dup.count != store.getLValueType().stackSize() + || !(opBlock.outer instanceof SequentialBlock)) return false; + opBlock = (SequentialBlock) opBlock.outer; + isAssignOp = true; + } - if (opBlock.subBlocks[0] instanceof SpecialBlock) { - SpecialBlock dup = (SpecialBlock) opBlock.subBlocks[0]; - if (dup.type != SpecialBlock.DUP - || dup.depth != store.getLValueOperandCount() - || dup.count != store.getLValueType().stackSize()) - return false; - opBlock = (SequentialBlock) lastBlock.outer; - isExpression = true; - } + if (!(opBlock.subBlocks[0] instanceof InstructionBlock)) + return false; - ib = (InstructionBlock) opBlock.subBlocks[0]; - ComplexExpression binopExpr = - (ComplexExpression) ib.getInstruction(); - binop = (BinaryOperator) binopExpr.getOperator(); - if (binop.getOperatorIndex() < binop.ADD_OP || - binop.getOperatorIndex() >= binop.ASSIGN_OP) - return false; + InstructionBlock ib = (InstructionBlock) opBlock.subBlocks[0]; + + if (!(opBlock.outer instanceof SequentialBlock) + || !(opBlock.outer.getSubBlocks()[0] instanceof SpecialBlock)) + return false; - rightHandSide = binopExpr.getSubExpressions()[1]; - if (rightHandSide.isVoid()) - return false; /* XXX */ + SequentialBlock sequBlock = (SequentialBlock) opBlock.outer; + SpecialBlock dup = (SpecialBlock) sequBlock.subBlocks[0]; + if (dup.type != SpecialBlock.DUP + || dup.depth != 0 + || dup.count != store.getLValueOperandCount()) + return false; - Operator load = (Operator) binopExpr.getSubExpressions()[0]; - if (!store.matches(load)) - return false; + if (!(ib.getInstruction() instanceof ComplexExpression)) + return false; + ComplexExpression expr = (ComplexExpression) ib.getInstruction(); - sequBlock = (SequentialBlock) opBlock.outer; + int opIndex; + Expression rightHandSide; - SpecialBlock dup = (SpecialBlock) sequBlock.subBlocks[0]; - if (dup.type != SpecialBlock.DUP - || dup.depth != 0 - || dup.count != store.getLValueOperandCount()) + if (expr.getOperator() instanceof BinaryOperator) { + BinaryOperator binop = (BinaryOperator) expr.getOperator(); + + opIndex = binop.getOperatorIndex(); + + if (opIndex < binop.ADD_OP || opIndex >= binop.ASSIGN_OP + || !(expr.getSubExpressions()[0] instanceof Operator) + || !store.matches((Operator) expr.getSubExpressions()[0])) return false; - } catch (ClassCastException ex) { - return false; - } catch (NullPointerException ex) { - return false; + + rightHandSide = expr.getSubExpressions()[1]; + } else { + Expression simple = expr.simplifyString(); + rightHandSide = simple; + /* Now search for the leftmost operand ... */ + ComplexExpression last = null; + while (simple instanceof ComplexExpression + && simple.getOperator() instanceof StringAddOperator) { + last = (ComplexExpression) simple; + simple = last.getSubExpressions()[0]; + } + + /* ... check it ... */ + if (last == null || !(simple instanceof Operator) + || !store.matches((Operator) simple)) + return false; + + /* ... and remove it. */ + if (last.getParent() != null) { + ((ComplexExpression)last.getParent()).getSubExpressions()[0] + = last.getSubExpressions()[1]; + } else + rightHandSide = last.getSubExpressions()[1]; + + opIndex = Operator.ADD_OP; } - ((InstructionBlock)opBlock.subBlocks[0]) - .setInstruction(rightHandSide); - opBlock.moveDefinitions(sequBlock, opBlock); - opBlock.replace(sequBlock); - - store.setOperatorIndex(store.OPASSIGN_OP+binop.getOperatorIndex()); - store.setLValueType(binop.getType() - .intersection(store.getLValueType())); - - if (isExpression) - lastBlock.setInstruction - (new AssignOperator(store.getOperatorIndex(), store)); - else - lastBlock.setInstruction(store); - lastBlock.moveDefinitions(opBlock.subBlocks[1], lastBlock); + dup.removeBlock(); + ib.setInstruction(rightHandSide); + + store.setOperatorIndex(store.OPASSIGN_OP+opIndex); + + if (isAssignOp) + store.makeNonVoid(); lastBlock.replace(opBlock.subBlocks[1]); return true; } public boolean createAssignExpression(FlowBlock flow) { - StoreInstruction store; - InstructionContainer lastBlock; - SequentialBlock sequBlock; - try { - lastBlock = (InstructionContainer) flow.lastModified; - store = (StoreInstruction) lastBlock.getInstruction(); - - sequBlock = (SequentialBlock) lastBlock.outer; + /* Situation: + * sequBlock: + * dup_X(lvalue_count) + * store instruction + */ + InstructionContainer lastBlock + = (InstructionContainer) flow.lastModified; + SequentialBlock sequBlock = (SequentialBlock) lastBlock.outer; + StoreInstruction store = (StoreInstruction) lastBlock.getInstruction(); + + if (sequBlock.subBlocks[0] instanceof SpecialBlock) { SpecialBlock dup = (SpecialBlock) sequBlock.subBlocks[0]; if (dup.type != SpecialBlock.DUP || dup.depth != store.getLValueOperandCount() || dup.count != store.getLValueType().stackSize()) return false; - } catch (NullPointerException ex) { - return false; - } catch (ClassCastException ex) { - return false; + + dup.removeBlock(); + store.makeNonVoid(); + return true; } - lastBlock.setInstruction - (new AssignOperator(store.getOperatorIndex(), store)); - lastBlock.moveDefinitions(sequBlock, lastBlock); - lastBlock.replace(sequBlock); - return true; - + return false; } }