From 2e8da872c053650a8a1d2aef52bce22eddb5bc86 Mon Sep 17 00:00:00 2001 From: dolby-oss Date: Fri, 15 May 2009 16:06:09 +0000 Subject: [PATCH] support for replication-based translation of Do loops in Java, so that the standard LOOP node type can be used. git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@3596 f5eafffb-2e1d-0410-98e4-8ec43c5233c4 --- .../jdt/JDTJava2CAstTranslator.java | 4 ++ .../polyglot/PolyglotJava2CAstTranslator.java | 51 +++++++++++++++---- .../ibm/wala/cast/tree/CAstNodeTypeMap.java | 5 ++ .../tree/impl/CAstControlFlowRecorder.java | 8 +++ .../tree/impl/CAstNodeTypeMapRecorder.java | 10 ++++ 5 files changed, 68 insertions(+), 10 deletions(-) diff --git a/com.ibm.wala.cast.java.jdt/source/com/ibm/wala/cast/java/translator/jdt/JDTJava2CAstTranslator.java b/com.ibm.wala.cast.java.jdt/source/com/ibm/wala/cast/java/translator/jdt/JDTJava2CAstTranslator.java index 1e2d1bff8..71ba3d238 100644 --- a/com.ibm.wala.cast.java.jdt/source/com/ibm/wala/cast/java/translator/jdt/JDTJava2CAstTranslator.java +++ b/com.ibm.wala.cast.java.jdt/source/com/ibm/wala/cast/java/translator/jdt/JDTJava2CAstTranslator.java @@ -328,6 +328,10 @@ public class JDTJava2CAstTranslator implements TranslatorToCAst { public CAstType getNodeType(CAstNode node) { throw new UnsupportedOperationException(); } + + public Collection getMappedNodes() { + throw new UnsupportedOperationException(); + } }; } diff --git a/com.ibm.wala.cast.java.polyglot/source/com/ibm/wala/cast/java/translator/polyglot/PolyglotJava2CAstTranslator.java b/com.ibm.wala.cast.java.polyglot/source/com/ibm/wala/cast/java/translator/polyglot/PolyglotJava2CAstTranslator.java index bb77000ad..94bb33ebe 100644 --- a/com.ibm.wala.cast.java.polyglot/source/com/ibm/wala/cast/java/translator/polyglot/PolyglotJava2CAstTranslator.java +++ b/com.ibm.wala.cast.java.polyglot/source/com/ibm/wala/cast/java/translator/polyglot/PolyglotJava2CAstTranslator.java @@ -129,10 +129,12 @@ import com.ibm.wala.cast.tree.CAstSymbol; import com.ibm.wala.cast.tree.CAstType; import com.ibm.wala.cast.tree.CAstTypeDictionary; import com.ibm.wala.cast.tree.impl.AbstractSourcePosition; +import com.ibm.wala.cast.tree.impl.CAstCloner; import com.ibm.wala.cast.tree.impl.CAstControlFlowRecorder; import com.ibm.wala.cast.tree.impl.CAstImpl; import com.ibm.wala.cast.tree.impl.CAstNodeTypeMapRecorder; import com.ibm.wala.cast.tree.impl.CAstOperator; +import com.ibm.wala.cast.tree.impl.CAstRewriter; import com.ibm.wala.cast.tree.impl.CAstSourcePositionRecorder; import com.ibm.wala.cast.tree.impl.CAstSymbolImpl; import com.ibm.wala.classLoader.CallSiteReference; @@ -174,6 +176,8 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst { protected PolyglotIdentityMapper fIdentityMapper; + protected boolean replicateForDoLoop = false; + protected final boolean DEBUG = true; final protected TranslatingVisitor getTranslator() { @@ -1086,23 +1090,46 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst { } public CAstNode visit(Do d, WalkContext wc) { - Node header = fNodeFactory.Empty(Position.COMPILER_GENERATED); Node breakTarget = makeBreakTarget(d); Node continueTarget = makeContinueTarget(d); - CAstNode loopGoto = makeNode(wc, fFactory, d, CAstNode.IFGOTO, walkNodes(d.cond(), wc)); - - wc.cfg().map(loopGoto, loopGoto); - wc.cfg().add(loopGoto, header, Boolean.TRUE); - String loopLabel = (String) wc.getLabelMap().get(d); - WalkContext lc = new LoopContext(wc, loopLabel, breakTarget, continueTarget); - CAstNode continueNode = walkNodes(continueTarget, wc); + CAstNode breakBody = walkNodes(breakTarget, wc); - return makeNode(wc, fFactory, d, CAstNode.BLOCK_STMT, walkNodes(header, wc), makeNode(wc, fFactory, d, CAstNode.BLOCK_STMT, - walkNodes(d.body(), lc), continueNode), loopGoto, walkNodes(breakTarget, wc)); + WalkContext lc = new LoopContext(wc, loopLabel, breakTarget, continueTarget); + CAstNode loopBody = walkNodes(d.body(), lc); + + if (replicateForDoLoop) { + CAstRewriter.Rewrite x = (new CAstCloner(fFactory, false)).copy(loopBody, wc.cfg(), wc.pos(), wc.getNodeTypeMap(), null); + CAstNode otherBody = x.newRoot(); + + wc.cfg().addAll(x.newCfg()); + wc.pos().addAll(x.newPos()); + wc.getNodeTypeMap().addAll(x.newTypes()); + + return makeNode(wc, fFactory, d, CAstNode.BLOCK_STMT, + loopBody, + makeNode(wc, fFactory, d, CAstNode.LOOP, + walkNodes(d.cond(), wc), + makeNode(wc, fFactory, d, CAstNode.BLOCK_STMT, otherBody, continueNode)), + breakBody); + + } else { + Node header = fNodeFactory.Empty(Position.COMPILER_GENERATED); + + CAstNode loopGoto = makeNode(wc, fFactory, d, CAstNode.IFGOTO, walkNodes(d.cond(), wc)); + + wc.cfg().map(loopGoto, loopGoto); + wc.cfg().add(loopGoto, header, Boolean.TRUE); + + return makeNode(wc, fFactory, d, CAstNode.BLOCK_STMT, + walkNodes(header, wc), + makeNode(wc, fFactory, d, CAstNode.BLOCK_STMT, loopBody, continueNode), + loopGoto, + breakBody); + } } public CAstNode visit(For f, WalkContext wc) { @@ -1562,6 +1589,10 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst { public CAstType getNodeType(CAstNode node) { throw new UnsupportedOperationException(); } + + public Collection getMappedNodes() { + throw new UnsupportedOperationException(); + } }; } diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstNodeTypeMap.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstNodeTypeMap.java index 45845e9d8..7ae74d023 100644 --- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstNodeTypeMap.java +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstNodeTypeMap.java @@ -13,6 +13,11 @@ */ package com.ibm.wala.cast.tree; +import java.util.Collection; + public interface CAstNodeTypeMap { + + Collection getMappedNodes(); + CAstType getNodeType(CAstNode node); } diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/impl/CAstControlFlowRecorder.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/impl/CAstControlFlowRecorder.java index 922c3e2ab..980f1c91a 100644 --- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/impl/CAstControlFlowRecorder.java +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/impl/CAstControlFlowRecorder.java @@ -146,6 +146,14 @@ public class CAstControlFlowRecorder implements CAstControlFlowMap { CAstToNode.put(ast, node); } + public void addAll(CAstControlFlowMap other) { + for(CAstNode n : other.getMappedNodes()) { + for(Object l : other.getTargetLabels(n)) { + add(n, l, other.getTarget(n, l)); + } + } + } + public boolean isMapped(Object node) { return nodeToCAst.containsKey(node); } diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/impl/CAstNodeTypeMapRecorder.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/impl/CAstNodeTypeMapRecorder.java index 8a8a5b153..8bbc2ffb6 100644 --- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/impl/CAstNodeTypeMapRecorder.java +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/impl/CAstNodeTypeMapRecorder.java @@ -13,6 +13,7 @@ */ package com.ibm.wala.cast.tree.impl; +import java.util.Collection; import java.util.HashMap; import com.ibm.wala.cast.tree.CAstNode; @@ -33,4 +34,13 @@ public class CAstNodeTypeMapRecorder put(node, type); } + public Collection getMappedNodes() { + return keySet(); + } + + public void addAll(CAstNodeTypeMap other) { + for(CAstNode o : other.getMappedNodes()) { + put(o, other.getNodeType(o)); + } + } }