git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1416 379699f6-c40d-0410-875b-85095c16579emaster
parent
0277d99ebb
commit
7a96e31c81
@ -0,0 +1,161 @@ |
|||||||
|
/* LoopBlock Copyright (C) 1998-2002 Jochen Hoenicke. |
||||||
|
* |
||||||
|
* This program is free software; you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Lesser General Public License as published by |
||||||
|
* the Free Software Foundation; either version 2, or (at your option) |
||||||
|
* any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with this program; see the file COPYING.LESSER. If not, write to |
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
||||||
|
* |
||||||
|
* $Id: LoopBlock.java 1411 2012-03-01 22:39:08Z hoenicke $ |
||||||
|
*/ |
||||||
|
|
||||||
|
package net.sf.jode.flow; |
||||||
|
import net.sf.jode.decompiler.TabbedPrintWriter; |
||||||
|
|
||||||
|
/** |
||||||
|
* This is the structured block for an Loop block. |
||||||
|
*/ |
||||||
|
public class LabelledBlock extends StructuredBlock implements BreakableBlock { |
||||||
|
|
||||||
|
/** |
||||||
|
* The body of this labelled block. This is always a valid block and not null. |
||||||
|
*/ |
||||||
|
StructuredBlock bodyBlock; |
||||||
|
|
||||||
|
/** |
||||||
|
* The stack after the break. |
||||||
|
*/ |
||||||
|
VariableStack breakedStack; |
||||||
|
|
||||||
|
/** |
||||||
|
* The serial number for labels. |
||||||
|
*/ |
||||||
|
static int serialno = 0; |
||||||
|
|
||||||
|
/** |
||||||
|
* The label of this instruction, or null if it needs no label. |
||||||
|
*/ |
||||||
|
String label = null; |
||||||
|
|
||||||
|
public LabelledBlock() { |
||||||
|
} |
||||||
|
|
||||||
|
public void setBody(StructuredBlock body) { |
||||||
|
bodyBlock = body; |
||||||
|
bodyBlock.outer = this; |
||||||
|
body.setFlowBlock(flowBlock); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Replaces the given sub block with a new block. |
||||||
|
* @param oldBlock the old sub block. |
||||||
|
* @param newBlock the new sub block. |
||||||
|
* @return false, if oldBlock wasn't a direct sub block. |
||||||
|
*/ |
||||||
|
public boolean replaceSubBlock(StructuredBlock oldBlock, |
||||||
|
StructuredBlock newBlock) { |
||||||
|
if (bodyBlock != oldBlock) |
||||||
|
return false; |
||||||
|
|
||||||
|
bodyBlock = newBlock; |
||||||
|
newBlock.outer = this; |
||||||
|
oldBlock.outer = null; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns all sub block of this structured block. |
||||||
|
*/ |
||||||
|
public StructuredBlock[] getSubBlocks() { |
||||||
|
return new StructuredBlock[] { bodyBlock }; |
||||||
|
} |
||||||
|
|
||||||
|
public void dumpSource(TabbedPrintWriter writer) |
||||||
|
throws java.io.IOException |
||||||
|
{ |
||||||
|
super.dumpSource(writer); |
||||||
|
} |
||||||
|
|
||||||
|
public void dumpInstruction(TabbedPrintWriter writer) |
||||||
|
throws java.io.IOException |
||||||
|
{ |
||||||
|
if (label != null) { |
||||||
|
writer.untab(); |
||||||
|
writer.println(label+":"); |
||||||
|
writer.tab(); |
||||||
|
} |
||||||
|
boolean needBrace = bodyBlock.needsBraces(); |
||||||
|
if (needBrace) |
||||||
|
writer.openBrace(); |
||||||
|
else |
||||||
|
writer.println(); |
||||||
|
writer.tab(); |
||||||
|
bodyBlock.dumpSource(writer); |
||||||
|
writer.untab(); |
||||||
|
writer.closeBrace(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the label of this block and creates a new label, if |
||||||
|
* there wasn't a label previously. |
||||||
|
*/ |
||||||
|
public String getLabel() { |
||||||
|
if (label == null) |
||||||
|
label = "label_"+(serialno++); |
||||||
|
return label; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Is called by BreakBlock, to tell us that this block is breaked. |
||||||
|
*/ |
||||||
|
public void setBreaked() { |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* This is called after the analysis is completely done. It |
||||||
|
* will remove all PUSH/stack_i expressions, (if the bytecode |
||||||
|
* is correct). |
||||||
|
* @param stack the stack at begin of the block |
||||||
|
* @return null if there is no way to the end of this block, |
||||||
|
* otherwise the stack after the block has executed. |
||||||
|
*/ |
||||||
|
public VariableStack mapStackToLocal(VariableStack stack) { |
||||||
|
VariableStack afterBody = bodyBlock.mapStackToLocal(stack); |
||||||
|
mergeBreakedStack(afterBody); |
||||||
|
return breakedStack; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Is called by BreakBlock, to tell us what the stack can be after a |
||||||
|
* break. |
||||||
|
* @return false if the stack is inconsistent. |
||||||
|
*/ |
||||||
|
public void mergeBreakedStack(VariableStack stack) { |
||||||
|
if (breakedStack != null) |
||||||
|
breakedStack.merge(stack); |
||||||
|
else |
||||||
|
breakedStack = stack; |
||||||
|
} |
||||||
|
|
||||||
|
public void removePush() { |
||||||
|
bodyBlock.removePush(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Determines if there is a sub block, that flows through to the end |
||||||
|
* of this block. If this returns true, you know that jump is null. |
||||||
|
* @return true, if the jump may be safely changed. |
||||||
|
*/ |
||||||
|
public boolean jumpMayBeChanged() { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
Loading…
Reference in new issue