SFormsFastMapDirect (String nodeid, String predid, DirectGraph dgraph, String destid) { SFormsFastMapDirect mapNew = new SFormsFastMapDirect(); boolean isFinallyExit = dgraph.mapShortRangeFinallyPaths.containsKey(predid); if (nodeid.equals(dgraph.mapNegIfBranch.get(predid))) { if (outNegVarVersions.containsKey(predid)) { mapNew = outNegVarVersions.get(predid).getCopy(); } } else if (outVarVersions.containsKey(predid)) { mapNew = outVarVersions.get(predid).getCopy(); } if (isFinallyExit) { SFormsFastMapDirect mapNewTemp = mapNew.getCopy(); SFormsFastMapDirect mapTrueSource = new SFormsFastMapDirect(); String exceptionDest = dgraph.mapFinallyMonitorExceptionPathExits.get(predid); boolean isExceptionMonitorExit = (exceptionDest != null && !nodeid.equals(exceptionDest)); HashSet<String> setLongPathWrapper = new HashSet<>(); for (List<FinallyPathWrapper> lstwrapper : dgraph.mapLongRangeFinallyPaths.values()) { for (FinallyPathWrapper finwraplong : lstwrapper) { setLongPathWrapper.add(finwraplong.destination + "##" + finwraplong.source); } } for (FinallyPathWrapper finwrap : dgraph.mapShortRangeFinallyPaths.get(predid)) { SFormsFastMapDirect map; boolean recFinally = dgraph.mapShortRangeFinallyPaths.containsKey(finwrap.source); if (recFinally) { // recursion map = getFilteredOutMap(finwrap.entry, finwrap.source, dgraph, destid); } else { if (finwrap.entry.equals(dgraph.mapNegIfBranch.get(finwrap.source))) { map = outNegVarVersions.get(finwrap.source); } else { map = outVarVersions.get(finwrap.source); } } // false path? boolean isFalsePath; if (recFinally) { isFalsePath = !finwrap.destination.equals(nodeid); } else { isFalsePath = !setLongPathWrapper.contains(destid + "##" + finwrap.source); } if (isFalsePath) { mapNewTemp.complement(map); } else { if (mapTrueSource.isEmpty()) { if (map != null) { mapTrueSource = map.getCopy(); } } else { mergeMaps(mapTrueSource, map); } } } if (isExceptionMonitorExit) { mapNew = mapTrueSource; } else { mapNewTemp.union(mapTrueSource); mapNew.intersection(mapNewTemp); if (!mapTrueSource.isEmpty() && !mapNew.isEmpty()) { // FIXME: what for?? // replace phi versions with corresponding phantom ones HashMap<VarVersionPair, VarVersionPair> mapPhantom = phantomexitnodes.get(predid); if (mapPhantom == null) { mapPhantom = new HashMap<>(); } SFormsFastMapDirect mapExitVar = mapNew.getCopy(); mapExitVar.complement(mapTrueSource); for (Entry<Integer, FastSparseSet<Integer>> ent : mapExitVar.entryList()) { for (Integer version : ent.getValue()) { Integer varindex = ent.getKey(); VarVersionPair exitvar = new VarVersionPair(varindex, version); FastSparseSet<Integer> newSet = mapNew.get(varindex); // remove the actual exit version newSet.remove(version); // get or create phantom version VarVersionPair phantomvar = mapPhantom.get(exitvar); if (phantomvar == null) { Integer newversion = getNextFreeVersion(exitvar.var, null); phantomvar = new VarVersionPair(exitvar.var, newversion.intValue()); VarVersionNode exitnode = ssuversions.nodes.getWithKey(exitvar); VarVersionNode phantomnode = ssuversions.createNode(phantomvar); phantomnode.flags |= VarVersionNode.FLAG_PHANTOM_FIN_EXIT; VarVersionEdge edge = new VarVersionEdge(VarVersionEdge.EDGE_PHANTOM, exitnode, phantomnode); exitnode.addSuccessor(edge); phantomnode.addPredecessor(edge); mapPhantom.put(exitvar, phantomvar); } // add phantom version newSet.add(phantomvar.version); } } if (!mapPhantom.isEmpty()) { phantomexitnodes.put(predid, mapPhantom); } } } } return mapNew; }