/* * TryCatchOperation.java * @Author Oleg Gorobets * Created: 14.08.2007 * CVS-ID: $Id: *************************************************************************/ package org.swfparser.operation; import java.util.List; import java.util.Stack; import org.apache.log4j.Logger; import org.swfparser.CodeUtil; import org.swfparser.ExecutionContext; import org.swfparser.Operation; import org.swfparser.annotations.NewAnalyzer; import org.swfparser.exception.StatementBlockException; import org.swfparser.util.PrintfFormat; import com.jswiff.swfrecords.actions.Action; import com.jswiff.swfrecords.actions.ActionBlock; import com.jswiff.swfrecords.actions.ActionConstants; import com.jswiff.swfrecords.actions.Branch; import com.jswiff.swfrecords.actions.Try; @NewAnalyzer public class TryCatchOperation extends AbstractCompoundOperation { private static Logger logger = Logger.getLogger(TryCatchOperation.class); private List<Operation> tryOperations; private List<Operation> catchOperations; private List<Operation> finallyOperations; protected Try action; private static PrintfFormat actionFormat = new PrintfFormat("@@@@@@A %08X: [%s] 0x%02X (%s) %s"); private static PrintfFormat offsetFormat = new PrintfFormat("0x%08X"); public TryCatchOperation(Stack<Operation> stack, ExecutionContext context, Try action) throws StatementBlockException { super(context); this.action = action; logger.debug("Starting try-catch block..."); logger.debug("@try actions"); printActions(action.getTryBlock().getActions()); logger.debug("@catch actions"); printActions(action.getCatchBlock().getActions()); List<Action> tryActions = prepareTryActions(action.getTryBlock().getActions()); tryOperations = executeWithCopiedStack(context, tryActions, this).getOperations(); if (action.hasCatchBlock()) { catchOperations = executeWithCopiedStack(context, action.getCatchBlock().getActions(), this).getOperations(); } if (action.hasFinallyBlock()) { finallyOperations = executeWithCopiedStack(context, action.getFinallyBlock().getActions(), this).getOperations(); } } public String getStringValue(int level) { logger.debug("Writing try with "); StringBuffer buf = new StringBuffer() .append(CodeUtil.getIndent(level)) .append("try {\n"); for (Operation operation : tryOperations) { buf .append(operation.getStringValue(level+1)) .append(CodeUtil.endOfStatement(operation)) .append("\n"); } buf .append(CodeUtil.getIndent(level)) .append("}"); if (action.hasCatchBlock()) { String catchName; if (action.catchInRegister()) { short registerNum = action.getCatchRegister(); catchName = new StoreRegisterOperation.RegisterHandle(registerNum).getStringValue(0); } else { catchName = action.getCatchVariable(); } buf.append(" catch (").append(catchName).append(") {\n"); for (Operation operation : catchOperations) { buf .append(operation.getStringValue(level+1)) .append(CodeUtil.endOfStatement(operation)) .append("\n"); } buf .append(CodeUtil.getIndent(level)) .append("}"); } if (action.hasFinallyBlock()) { buf.append(" finally {\n"); for (Operation operation : finallyOperations) { buf .append(operation.getStringValue(level+1)) .append(CodeUtil.endOfStatement(operation)) .append("\n"); } buf .append(CodeUtil.getIndent(level)) .append("}"); } return buf.toString(); } private void printActions(List<Action> actions) { for (Action action : actions) { String actionInfo=""; if (action instanceof Branch) { Branch brnch = (Branch) action; // Action jumpDestination = labels.get(brnch.getBranchLabel()); actionInfo += " branch label = "+brnch.getBranchLabel() +", branch offset = "+ brnch.getBranchOffset()/*+"("+ ( jumpDestination!=null ? offsetFormat.sprintf( jumpDestination.getOffset() ) : "[null]")+")"*/; } logger.debug(actionFormat.sprintf(new Object[]{action.getOffset(),(action.getLabel()==null)?"":action.getLabel(),action.getCode(),ActionConstants.getActionName(action.getCode()),actionInfo})); } } protected List<Action> prepareTryActions(List<Action> actions) { logger.debug("Preparing try-actions"); for (Action action : actions) { if (action instanceof Branch) { Branch branch = (Branch) action; if (ActionBlock.LABEL_OUT.equals(branch.getBranchLabel())) { logger.debug("Action "+action+" is pointing out of the try block. Setting to "+ActionBlock.LABEL_END); branch.setBranchLabel(ActionBlock.LABEL_END); } } } return actions; } }