Exemple #1
0
        private void VarMapToGraph(VarVersionPair varpaar, SFormsFastMapDirect varmap)
        {
            VBStyleCollection <VarVersionNode, VarVersionPair> nodes = ssuversions.nodes;
            VarVersionNode node = nodes.GetWithKey(varpaar);

            node.live = new SFormsFastMapDirect(varmap);
        }
Exemple #2
0
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            TextBuffer buffer = new TextBuffer();

            tracer.AddMapping(bytecode);
            if (classDef)
            {
                ClassesProcessor.ClassNode child = DecompilerContext.GetClassProcessor().GetMapRootClasses
                                                       ().GetOrNull(varType.value);
                new ClassWriter().ClassToJava(child, buffer, indent, tracer);
                tracer.IncrementCurrentSourceLine(buffer.CountLines());
            }
            else
            {
                VarVersionPair varVersion = GetVarVersionPair();
                string         name       = null;
                if (processor != null)
                {
                    name = processor.GetVarName(varVersion);
                }
                if (definition)
                {
                    if (processor != null && processor.GetVarFinal(varVersion) == VarTypeProcessor.Var_Explicit_Final)
                    {
                        buffer.Append("final ");
                    }
                    AppendDefinitionType(buffer);
                    buffer.Append(" ");
                }
                buffer.Append(name == null ? ("var" + index + (this.version == 0 ? string.Empty :
                                                               "_" + this.version)) : name);
            }
            return(buffer);
        }
Exemple #3
0
        private static bool IsExprentIndependent(Exprent exprent, MethodWrapper method)
        {
            List <Exprent> lst = exprent.GetAllExprents(true);

            lst.Add(exprent);
            foreach (Exprent expr in lst)
            {
                switch (expr.type)
                {
                case Exprent.Exprent_Var:
                {
                    VarVersionPair varPair = new VarVersionPair((VarExprent)expr);
                    if (!method.varproc.GetExternalVars().Contains(varPair))
                    {
                        string varName = method.varproc.GetVarName(varPair);
                        if (!varName.Equals("this") && !varName.EndsWith(".this"))
                        {
                            // FIXME: remove direct comparison with strings
                            return(false);
                        }
                    }
                    break;
                }

                case Exprent.Exprent_Field:
                {
                    return(false);
                }
                }
            }
            return(true);
        }
Exemple #4
0
        public static List <VarVersionPair> GetSyntheticParametersMask(ClassesProcessor.ClassNode
                                                                       node, string descriptor, int parameters)
        {
            List <VarVersionPair> mask    = null;
            ClassWrapper          wrapper = node.GetWrapper();

            if (wrapper != null)
            {
                // own class
                MethodWrapper methodWrapper = wrapper.GetMethodWrapper(ICodeConstants.Init_Name,
                                                                       descriptor);
                if (methodWrapper == null)
                {
                    if (DecompilerContext.GetOption(IFernflowerPreferences.Ignore_Invalid_Bytecode))
                    {
                        return(null);
                    }
                    throw new Exception("Constructor " + node.classStruct.qualifiedName + "." + ICodeConstants
                                        .Init_Name + descriptor + " not found");
                }
                mask = methodWrapper.synthParameters;
            }
            else if (parameters > 0 && node.type == ClassesProcessor.ClassNode.Class_Member &&
                     (node.access & ICodeConstants.Acc_Static) == 0)
            {
                // non-static member class
                mask    = new List <VarVersionPair>(Enumerable.Repeat <VarVersionPair>(null, parameters));
                mask[0] = new VarVersionPair(-1, 0);
            }
            return(mask);
        }
Exemple #5
0
        // vers.size() == 0 means uninitialized variable, which is impossible
        private void CreateOrUpdatePhiNode(VarVersionPair phivar, FastSparseSetFactory <int> .FastSparseSet <int> vers, Statement stat)
        {
            FastSparseSetFactory <int> .FastSparseSet <int> versCopy = vers.GetCopy();
            HashSet <int> phiVers = new HashSet <int>();
            // take into account the corresponding mm/pp node if existing
            int ppvers = phantomppnodes.ContainsKey(phivar) ? phantomppnodes.GetOrNull(phivar
                                                                                       ).version : -1;
            // ssu graph
            VarVersionNode        phinode  = ssuversions.nodes.GetWithKey(phivar);
            List <VarVersionEdge> lstPreds = new List <VarVersionEdge>(phinode.preds);

            if (lstPreds.Count == 1)
            {
                // not yet a phi node
                VarVersionEdge edge = lstPreds[0];
                edge.source.RemoveSuccessor(edge);
                phinode.RemovePredecessor(edge);
            }
            else
            {
                foreach (VarVersionEdge edge in lstPreds)
                {
                    int verssrc = new Sharpen.EnumeratorAdapter <VarVersionEdge>(edge.source.preds.GetEnumerator()).Next().source.version;
                    if (!vers.Contains(verssrc) && verssrc != ppvers)
                    {
                        edge.source.RemoveSuccessor(edge);
                        phinode.RemovePredecessor(edge);
                    }
                    else
                    {
                        versCopy.Remove(verssrc);
                        phiVers.Add(verssrc);
                    }
                }
            }
            List <VarVersionNode> colnodes = new List <VarVersionNode>();
            List <VarVersionPair> colpaars = new List <VarVersionPair>();

            foreach (int ver in versCopy)
            {
                VarVersionNode prenode = ssuversions.nodes.GetWithKey(new VarVersionPair(phivar.var
                                                                                         , ver));
                int            tempver  = GetNextFreeVersion(phivar.var, stat);
                VarVersionNode tempnode = new VarVersionNode(phivar.var, tempver);
                colnodes.Add(tempnode);
                colpaars.Add(new VarVersionPair(phivar.var, tempver));
                VarVersionEdge edge = new VarVersionEdge(VarVersionEdge.Edge_General, prenode, tempnode
                                                         );
                prenode.AddSuccessor(edge);
                tempnode.AddPredecessor(edge);
                edge = new VarVersionEdge(VarVersionEdge.Edge_General, tempnode, phinode);
                tempnode.AddSuccessor(edge);
                phinode.AddPredecessor(edge);
                phiVers.Add(tempver);
            }
            ssuversions.AddNodes(colnodes, colpaars);
        }
Exemple #6
0
        public virtual SFormsFastMapDirect GetLiveVarVersionsMap(VarVersionPair varpaar)
        {
            VarVersionNode node = ssuversions.nodes.GetWithKey(varpaar);

            if (node != null)
            {
                return(node.live);
            }
            return(null);
        }
Exemple #7
0
        private static Dictionary <int, HashSet <VarVersionPair> > GetAllVarVersions(VarVersionPair
                                                                                     leftvar, Exprent exprent, SSAUConstructorSparseEx ssau)
        {
            Dictionary <int, HashSet <VarVersionPair> > map = new Dictionary <int, HashSet <VarVersionPair
                                                                                            > >();
            SFormsFastMapDirect mapLiveVars = ssau.GetLiveVarVersionsMap(leftvar);
            List <Exprent>      lst         = exprent.GetAllExprents(true);

            lst.Add(exprent);
            foreach (Exprent expr in lst)
            {
                if (expr.type == Exprent.Exprent_Var)
                {
                    int varindex = ((VarExprent)expr).GetIndex();
                    if (leftvar.var != varindex)
                    {
                        if (mapLiveVars.ContainsKey(varindex))
                        {
                            HashSet <VarVersionPair> verset = new HashSet <VarVersionPair>();
                            foreach (int vers in mapLiveVars.Get(varindex))
                            {
                                verset.Add(new VarVersionPair(varindex, vers));
                            }
                            Sharpen.Collections.Put(map, varindex, verset);
                        }
                        else
                        {
                            throw new Exception("inkonsistent live map!");
                        }
                    }
                    else
                    {
                        Sharpen.Collections.Put(map, varindex, null);
                    }
                }
                else if (expr.type == Exprent.Exprent_Field)
                {
                    if (ssau.GetMapFieldVars().ContainsKey(expr.id))
                    {
                        int?varindex = ssau.GetMapFieldVars().GetOrNullable(expr.id);
                        if (mapLiveVars.ContainsKey(varindex.Value))
                        {
                            HashSet <VarVersionPair> verset = new HashSet <VarVersionPair>();
                            foreach (int vers in mapLiveVars.Get(varindex.Value))
                            {
                                verset.Add(new VarVersionPair(varindex.Value, vers));
                            }
                            Sharpen.Collections.Put(map, varindex.Value, verset);
                        }
                    }
                }
            }
            return(map);
        }
Exemple #8
0
        private static bool IsVersionToBeReplaced(VarVersionPair usedvar, Dictionary <int
                                                                                      , HashSet <VarVersionPair> > mapVars, SSAUConstructorSparseEx ssau, VarVersionPair
                                                  leftpaar)
        {
            VarVersionsGraph    ssuversions = ssau.GetSsuversions();
            SFormsFastMapDirect mapLiveVars = ssau.GetLiveVarVersionsMap(usedvar);

            if (mapLiveVars == null)
            {
                // dummy version, predecessor of a phi node
                return(false);
            }
            // compare protected ranges
            if (!InterpreterUtil.EqualObjects(ssau.GetMapVersionFirstRange().GetOrNullable(leftpaar
                                                                                           ), ssau.GetMapVersionFirstRange().GetOrNullable(usedvar)))
            {
                return(false);
            }
            foreach (KeyValuePair <int, HashSet <VarVersionPair> > ent in mapVars)
            {
                FastSparseSetFactory <int> .FastSparseSet <int> liveverset = mapLiveVars.Get(ent.Key);
                if (liveverset == null)
                {
                    return(false);
                }
                HashSet <VarVersionNode> domset = new HashSet <VarVersionNode>();
                foreach (VarVersionPair verpaar in ent.Value)
                {
                    domset.Add(ssuversions.nodes.GetWithKey(verpaar));
                }
                bool isdom = false;
                foreach (int livever in liveverset)
                {
                    VarVersionNode node = ssuversions.nodes.GetWithKey(new VarVersionPair(ent.Key, livever
                                                                                          ));
                    if (ssuversions.IsDominatorSet(node, domset))
                    {
                        isdom = true;
                        break;
                    }
                }
                if (!isdom)
                {
                    return(false);
                }
            }
            return(true);
        }
Exemple #9
0
        private static bool GetUsedVersions(SSAUConstructorSparseEx ssa, VarVersionPair
                                            var, List <VarVersionNode> res)
        {
            VarVersionsGraph            ssuversions = ssa.GetSsuversions();
            VarVersionNode              varnode     = ssuversions.nodes.GetWithKey(var);
            HashSet <VarVersionNode>    setVisited  = new HashSet <VarVersionNode>();
            HashSet <VarVersionNode>    setNotDoms  = new HashSet <VarVersionNode>();
            LinkedList <VarVersionNode> stack       = new LinkedList <VarVersionNode>();

            stack.AddLast(varnode);
            while (!(stack.Count == 0))
            {
                VarVersionNode nd = stack.RemoveAtReturningValue(0);
                setVisited.Add(nd);
                if (nd != varnode && (nd.flags & VarVersionNode.Flag_Phantom_Finexit) == 0)
                {
                    res.Add(nd);
                }
                foreach (VarVersionEdge edge in nd.succs)
                {
                    VarVersionNode succ = edge.dest;
                    if (!setVisited.Contains(edge.dest))
                    {
                        bool isDominated = true;
                        foreach (VarVersionEdge prededge in succ.preds)
                        {
                            if (!setVisited.Contains(prededge.source))
                            {
                                isDominated = false;
                                break;
                            }
                        }
                        if (isDominated)
                        {
                            stack.AddLast(succ);
                        }
                        else
                        {
                            setNotDoms.Add(succ);
                        }
                    }
                }
            }
            setNotDoms.RemoveAll(setVisited);
            return(!(setNotDoms.Count == 0));
        }
Exemple #10
0
 public static bool IsInvocationInitConstructor(InvocationExprent inv, MethodWrapper
                                                method, ClassWrapper wrapper, bool withThis)
 {
     if (inv.GetFunctype() == InvocationExprent.Typ_Init && inv.GetInstance().type ==
         Exprent.Exprent_Var)
     {
         VarExprent     instVar   = (VarExprent)inv.GetInstance();
         VarVersionPair varPair   = new VarVersionPair(instVar);
         string         className = method.varproc.GetThisVars().GetOrNull(varPair);
         if (className != null)
         {
             // any this instance. TODO: Restrict to current class?
             return(withThis || !wrapper.GetClassStruct().qualifiedName.Equals(inv.GetClassname
                                                                                   ()));
         }
     }
     return(false);
 }
Exemple #11
0
        // propagate (var = new X) forward to the <init> invocation
        private static bool IsConstructorInvocationRemote(List <Exprent> list, int index)
        {
            Exprent current = list[index];

            if (current.type == Exprent.Exprent_Assignment)
            {
                AssignmentExprent @as = (AssignmentExprent)current;
                if (@as.GetLeft().type == Exprent.Exprent_Var && @as.GetRight().type == Exprent.Exprent_New)
                {
                    NewExprent     newExpr  = (NewExprent)@as.GetRight();
                    VarType        newType  = newExpr.GetNewType();
                    VarVersionPair leftPair = new VarVersionPair((VarExprent)@as.GetLeft());
                    if (newType.type == ICodeConstants.Type_Object && newType.arrayDim == 0 && newExpr
                        .GetConstructor() == null)
                    {
                        for (int i = index + 1; i < list.Count; i++)
                        {
                            Exprent remote = list[i];
                            // <init> invocation
                            if (remote.type == Exprent.Exprent_Invocation)
                            {
                                InvocationExprent @in = (InvocationExprent)remote;
                                if (@in.GetFunctype() == InvocationExprent.Typ_Init && @in.GetInstance().type ==
                                    Exprent.Exprent_Var && @as.GetLeft().Equals(@in.GetInstance()))
                                {
                                    newExpr.SetConstructor(@in);
                                    @in.SetInstance(null);
                                    list[i] = @as.Copy();
                                    return(true);
                                }
                            }
                            // check for variable in use
                            HashSet <VarVersionPair> setVars = remote.GetAllVariables();
                            if (setVars.Contains(leftPair))
                            {
                                // variable used somewhere in between -> exit, need a better reduced code
                                return(false);
                            }
                        }
                    }
                }
            }
            return(false);
        }
Exemple #12
0
        private int[] IterateExprent(List <Exprent> lstExprents, int index, Exprent next,
                                     Dictionary <VarVersionPair, Exprent> mapVarValues, SSAUConstructorSparseEx ssau)
        {
            Exprent exprent = lstExprents[index];
            int     changed = 0;

            foreach (Exprent expr in exprent.GetAllExprents())
            {
                var oldExpr = expr;
                while (true)
                {
                    object[] arr     = IterateChildExprent(oldExpr, exprent, next, mapVarValues, ssau);
                    Exprent  retexpr = (Exprent)arr[0];
                    changed |= (bool)arr[1] ? 1 : 0;
                    bool isReplaceable = (bool)arr[2];
                    if (retexpr != null)
                    {
                        if (isReplaceable)
                        {
                            ReplaceSingleVar(exprent, (VarExprent)oldExpr, retexpr, ssau);
                            oldExpr = retexpr;
                        }
                        else
                        {
                            exprent.ReplaceExprent(oldExpr, retexpr);
                        }
                        changed = 1;
                    }
                    if (!isReplaceable)
                    {
                        break;
                    }
                }
            }
            // no var on the highest level, so no replacing
            VarExprent left  = null;
            Exprent    right = null;

            if (exprent.type == Exprent.Exprent_Assignment)
            {
                AssignmentExprent @as = (AssignmentExprent)exprent;
                if (@as.GetLeft().type == Exprent.Exprent_Var)
                {
                    left  = (VarExprent)@as.GetLeft();
                    right = @as.GetRight();
                }
            }
            if (left == null)
            {
                return(new int[] { -1, changed });
            }
            VarVersionPair        leftpaar = new VarVersionPair(left);
            List <VarVersionNode> usedVers = new List <VarVersionNode>();
            bool notdom = GetUsedVersions(ssau, leftpaar, usedVers);

            if (!notdom && (usedVers.Count == 0))
            {
                if (left.IsStack() && (right.type == Exprent.Exprent_Invocation || right.type ==
                                       Exprent.Exprent_Assignment || right.type == Exprent.Exprent_New))
                {
                    if (right.type == Exprent.Exprent_New)
                    {
                        // new Object(); permitted
                        NewExprent nexpr = (NewExprent)right;
                        if (nexpr.IsAnonymous() || nexpr.GetNewType().arrayDim > 0 || nexpr.GetNewType().
                            type != ICodeConstants.Type_Object)
                        {
                            return(new int[] { -1, changed });
                        }
                    }
                    lstExprents[index] = right;
                    return(new int[] { index + 1, 1 });
                }
                else if (right.type == Exprent.Exprent_Var)
                {
                    lstExprents.RemoveAtReturningValue(index);
                    return(new int[] { index, 1 });
                }
                else
                {
                    return(new int[] { -1, changed });
                }
            }
            int useflags = right.GetExprentUse();

            // stack variables only
            if (!left.IsStack() && (right.type != Exprent.Exprent_Var || ((VarExprent)right).
                                    IsStack()))
            {
                // special case catch(... ex)
                return(new int[] { -1, changed });
            }
            if ((useflags & Exprent.Multiple_Uses) == 0 && (notdom || usedVers.Count > 1))
            {
                return(new int[] { -1, changed });
            }
            Dictionary <int, HashSet <VarVersionPair> > mapVars = GetAllVarVersions(leftpaar, right
                                                                                    , ssau);
            bool isSelfReference = mapVars.ContainsKey(leftpaar.var);

            if (isSelfReference && notdom)
            {
                return(new int[] { -1, changed });
            }
            HashSet <VarVersionPair> setNextVars = next == null ? null : GetAllVersions(next);

            // FIXME: fix the entire method!
            if (right.type != Exprent.Exprent_Const && right.type != Exprent.Exprent_Var && setNextVars
                != null && mapVars.ContainsKey(leftpaar.var))
            {
                foreach (VarVersionNode usedvar in usedVers)
                {
                    if (!setNextVars.Contains(new VarVersionPair(usedvar.var, usedvar.version)))
                    {
                        return(new int[] { -1, changed });
                    }
                }
            }
            Sharpen.Collections.Remove(mapVars, leftpaar.var);
            bool vernotreplaced = false;
            bool verreplaced    = false;
            HashSet <VarVersionPair> setTempUsedVers = new HashSet <VarVersionPair>();

            foreach (VarVersionNode usedvar in usedVers)
            {
                VarVersionPair usedver = new VarVersionPair(usedvar.var, usedvar.version);
                if (IsVersionToBeReplaced(usedver, mapVars, ssau, leftpaar) && (right.type == Exprent
                                                                                .Exprent_Const || right.type == Exprent.Exprent_Var || right.type == Exprent.Exprent_Field ||
                                                                                setNextVars == null || setNextVars.Contains(usedver)))
                {
                    setTempUsedVers.Add(usedver);
                    verreplaced = true;
                }
                else
                {
                    vernotreplaced = true;
                }
            }
            if (isSelfReference && vernotreplaced)
            {
                return(new int[] { -1, changed });
            }
            else
            {
                foreach (VarVersionPair usedver in setTempUsedVers)
                {
                    Exprent copy = right.Copy();
                    if (right.type == Exprent.Exprent_Field && ssau.GetMapFieldVars().ContainsKey(right
                                                                                                  .id))
                    {
                        Sharpen.Collections.Put(ssau.GetMapFieldVars(), copy.id, ssau.GetMapFieldVars().GetOrNullable
                                                    (right.id));
                    }
                    Sharpen.Collections.Put(mapVarValues, usedver, copy);
                }
            }
            if (!notdom && !vernotreplaced)
            {
                // remove assignment
                lstExprents.RemoveAtReturningValue(index);
                return(new int[] { index, 1 });
            }
            else if (verreplaced)
            {
                return(new int[] { index + 1, changed });
            }
            else
            {
                return(new int[] { -1, changed });
            }
        }
Exemple #13
0
        private SFormsFastMapDirect GetFilteredOutMap(string nodeid, string predid, DirectGraph
                                                      dgraph, string destid)
        {
            SFormsFastMapDirect mapNew = new SFormsFastMapDirect();
            bool isFinallyExit         = dgraph.mapShortRangeFinallyPaths.ContainsKey(predid);

            if (nodeid.Equals(dgraph.mapNegIfBranch.GetOrNull(predid)))
            {
                if (outNegVarVersions.ContainsKey(predid))
                {
                    mapNew = outNegVarVersions.GetOrNull(predid).GetCopy();
                }
            }
            else if (outVarVersions.ContainsKey(predid))
            {
                mapNew = outVarVersions.GetOrNull(predid).GetCopy();
            }
            if (isFinallyExit)
            {
                SFormsFastMapDirect mapNewTemp    = mapNew.GetCopy();
                SFormsFastMapDirect mapTrueSource = new SFormsFastMapDirect();
                string exceptionDest = dgraph.mapFinallyMonitorExceptionPathExits.GetOrNull(predid
                                                                                            );
                bool isExceptionMonitorExit = (exceptionDest != null && !nodeid.Equals(exceptionDest
                                                                                       ));
                HashSet <string> setLongPathWrapper = new HashSet <string>();
                foreach (List <FlattenStatementsHelper.FinallyPathWrapper> lstwrapper in dgraph.mapLongRangeFinallyPaths
                         .Values)
                {
                    foreach (FlattenStatementsHelper.FinallyPathWrapper finwraplong in lstwrapper)
                    {
                        setLongPathWrapper.Add(finwraplong.destination + "##" + finwraplong.source);
                    }
                }
                foreach (FlattenStatementsHelper.FinallyPathWrapper finwrap in dgraph.mapShortRangeFinallyPaths
                         .GetOrNull(predid))
                {
                    SFormsFastMapDirect map;
                    bool recFinally = dgraph.mapShortRangeFinallyPaths.ContainsKey(finwrap.source);
                    if (recFinally)
                    {
                        // recursion
                        map = GetFilteredOutMap(finwrap.entry, finwrap.source, dgraph, destid);
                    }
                    else if (finwrap.entry.Equals(dgraph.mapNegIfBranch.GetOrNull(finwrap.source)))
                    {
                        map = outNegVarVersions.GetOrNull(finwrap.source);
                    }
                    else
                    {
                        map = outVarVersions.GetOrNull(finwrap.source);
                    }
                    // false path?
                    bool 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
                        Dictionary <VarVersionPair, VarVersionPair> mapPhantom = phantomexitnodes.GetOrNull
                                                                                     (predid);
                        if (mapPhantom == null)
                        {
                            mapPhantom = new Dictionary <VarVersionPair, VarVersionPair>();
                        }
                        SFormsFastMapDirect mapExitVar = mapNew.GetCopy();
                        mapExitVar.Complement(mapTrueSource);
                        foreach (KeyValuePair <int, FastSparseSetFactory <int> .FastSparseSet <int> > ent in mapExitVar
                                 .EntryList())
                        {
                            foreach (int version in ent.Value)
                            {
                                int            varindex = ent.Key;
                                VarVersionPair exitvar  = new VarVersionPair(varindex, version);
                                FastSparseSetFactory <int> .FastSparseSet <int> newSet = mapNew.Get(varindex);
                                // remove the actual exit version
                                newSet.Remove(version);
                                // get or create phantom version
                                VarVersionPair phantomvar = mapPhantom.GetOrNull(exitvar);
                                if (phantomvar == null)
                                {
                                    int newversion = GetNextFreeVersion(exitvar.var, null);
                                    phantomvar = new VarVersionPair(exitvar.var, newversion);
                                    VarVersionNode exitnode    = ssuversions.nodes.GetWithKey(exitvar);
                                    VarVersionNode phantomnode = ssuversions.CreateNode(phantomvar);
                                    phantomnode.flags |= VarVersionNode.Flag_Phantom_Finexit;
                                    VarVersionEdge edge = new VarVersionEdge(VarVersionEdge.Edge_Phantom, exitnode, phantomnode
                                                                             );
                                    exitnode.AddSuccessor(edge);
                                    phantomnode.AddPredecessor(edge);
                                    Sharpen.Collections.Put(mapPhantom, exitvar, phantomvar);
                                }
                                // add phantom version
                                newSet.Add(phantomvar.version);
                            }
                        }
                        if (!(mapPhantom.Count == 0))
                        {
                            Sharpen.Collections.Put(phantomexitnodes, predid, mapPhantom);
                        }
                    }
                }
            }
            return(mapNew);
        }
        private FinallyProcessor.Record GetFinallyInformation(StructMethod mt, RootStatement
                                                              root, CatchAllStatement fstat)
        {
            Dictionary <BasicBlock, bool> mapLast             = new Dictionary <BasicBlock, bool>();
            BasicBlockStatement           firstBlockStatement = fstat.GetHandler().GetBasichead();
            BasicBlock  firstBasicBlock = firstBlockStatement.GetBlock();
            Instruction instrFirst      = firstBasicBlock.GetInstruction(0);
            int         firstcode       = 0;

            switch (instrFirst.opcode)
            {
            case ICodeConstants.opc_pop:
            {
                firstcode = 1;
                break;
            }

            case ICodeConstants.opc_astore:
            {
                firstcode = 2;
                break;
            }
            }
            ExprProcessor proc = new ExprProcessor(methodDescriptor, varProcessor);

            proc.ProcessStatement(root, mt.GetClassStruct());
            SSAConstructorSparseEx ssa = new SSAConstructorSparseEx();

            ssa.SplitVariables(root, mt);
            List <Exprent> lstExprents = firstBlockStatement.GetExprents();
            VarVersionPair varpaar     = new VarVersionPair((VarExprent)((AssignmentExprent)lstExprents
                                                                         [firstcode == 2 ? 1 : 0]).GetLeft());
            FlattenStatementsHelper flatthelper = new FlattenStatementsHelper();
            DirectGraph             dgraph      = flatthelper.BuildDirectGraph(root);
            LinkedList <DirectNode> stack       = new LinkedList <DirectNode>();

            stack.AddLast(dgraph.first);
            HashSet <DirectNode> setVisited = new HashSet <DirectNode>();

            while (!(stack.Count == 0))
            {
                DirectNode node = Sharpen.Collections.RemoveFirst(stack);
                if (setVisited.Contains(node))
                {
                    continue;
                }
                setVisited.Add(node);
                BasicBlockStatement blockStatement = null;
                if (node.block != null)
                {
                    blockStatement = node.block;
                }
                else if (node.preds.Count == 1)
                {
                    blockStatement = node.preds[0].block;
                }
                bool isTrueExit = true;
                if (firstcode != 1)
                {
                    isTrueExit = false;
                    for (int i = 0; i < node.exprents.Count; i++)
                    {
                        Exprent exprent = node.exprents[i];
                        if (firstcode == 0)
                        {
                            List <Exprent> lst = exprent.GetAllExprents();
                            lst.Add(exprent);
                            bool found = false;
                            foreach (Exprent expr in lst)
                            {
                                if (expr.type == Exprent.Exprent_Var && new VarVersionPair((VarExprent)expr).Equals
                                        (varpaar))
                                {
                                    found = true;
                                    break;
                                }
                            }
                            if (found)
                            {
                                found = false;
                                if (exprent.type == Exprent.Exprent_Exit)
                                {
                                    ExitExprent exexpr = (ExitExprent)exprent;
                                    if (exexpr.GetExitType() == ExitExprent.Exit_Throw && exexpr.GetValue().type == Exprent
                                        .Exprent_Var)
                                    {
                                        found = true;
                                    }
                                }
                                if (!found)
                                {
                                    return(null);
                                }
                                else
                                {
                                    isTrueExit = true;
                                }
                            }
                        }
                        else if (firstcode == 2)
                        {
                            // search for a load instruction
                            if (exprent.type == Exprent.Exprent_Assignment)
                            {
                                AssignmentExprent assexpr = (AssignmentExprent)exprent;
                                if (assexpr.GetRight().type == Exprent.Exprent_Var && new VarVersionPair((VarExprent
                                                                                                          )assexpr.GetRight()).Equals(varpaar))
                                {
                                    Exprent next = null;
                                    if (i == node.exprents.Count - 1)
                                    {
                                        if (node.succs.Count == 1)
                                        {
                                            DirectNode nd = node.succs[0];
                                            if (!(nd.exprents.Count == 0))
                                            {
                                                next = nd.exprents[0];
                                            }
                                        }
                                    }
                                    else
                                    {
                                        next = node.exprents[i + 1];
                                    }
                                    bool found = false;
                                    if (next != null && next.type == Exprent.Exprent_Exit)
                                    {
                                        ExitExprent exexpr = (ExitExprent)next;
                                        if (exexpr.GetExitType() == ExitExprent.Exit_Throw && exexpr.GetValue().type == Exprent
                                            .Exprent_Var && assexpr.GetLeft().Equals(exexpr.GetValue()))
                                        {
                                            found = true;
                                        }
                                    }
                                    if (!found)
                                    {
                                        return(null);
                                    }
                                    else
                                    {
                                        isTrueExit = true;
                                    }
                                }
                            }
                        }
                    }
                }
                // find finally exits
                if (blockStatement != null && blockStatement.GetBlock() != null)
                {
                    Statement handler = fstat.GetHandler();
                    foreach (StatEdge edge in blockStatement.GetSuccessorEdges(Statement.Statedge_Direct_All
                                                                               ))
                    {
                        if (edge.GetType() != StatEdge.Type_Regular && handler.ContainsStatement(blockStatement
                                                                                                 ) && !handler.ContainsStatement(edge.GetDestination()))
                        {
                            bool?existingFlag = mapLast.GetOrNullable(blockStatement.GetBlock());
                            // note: the dummy node is also processed!
                            if (existingFlag == null || !existingFlag.Value)
                            {
                                Sharpen.Collections.Put(mapLast, blockStatement.GetBlock(), isTrueExit);
                                break;
                            }
                        }
                    }
                }
                Sharpen.Collections.AddAll(stack, node.succs);
            }
            // empty finally block?
            if (fstat.GetHandler().type == Statement.Type_Basicblock)
            {
                bool isEmpty            = false;
                bool isFirstLast        = mapLast.ContainsKey(firstBasicBlock);
                InstructionSequence seq = firstBasicBlock.GetSeq();
                switch (firstcode)
                {
                case 0:
                {
                    isEmpty = isFirstLast && seq.Length() == 1;
                    break;
                }

                case 1:
                {
                    isEmpty = seq.Length() == 1;
                    break;
                }

                case 2:
                {
                    isEmpty = isFirstLast ? seq.Length() == 3 : seq.Length() == 1;
                    break;
                }
                }
                if (isEmpty)
                {
                    firstcode = 3;
                }
            }
            return(new FinallyProcessor.Record(firstcode, mapLast));
        }
Exemple #15
0
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            TextBuffer buf = new TextBuffer();

            if (isStatic__)
            {
                ClassesProcessor.ClassNode node = (ClassesProcessor.ClassNode)DecompilerContext.GetProperty
                                                      (DecompilerContext.Current_Class_Node);
                if (node == null || !classname.Equals(node.classStruct.qualifiedName) || IsAmbiguous
                        ())
                {
                    buf.Append(DecompilerContext.GetImportCollector().GetShortNameInClassContext(ExprProcessor
                                                                                                 .BuildJavaClassName(classname)));
                    buf.Append(".");
                }
            }
            else
            {
                string super_qualifier = null;
                if (instance != null && instance.type == Exprent.Exprent_Var)
                {
                    VarExprent     instVar       = (VarExprent)instance;
                    VarVersionPair pair          = new VarVersionPair(instVar);
                    MethodWrapper  currentMethod = (MethodWrapper)DecompilerContext.GetProperty(DecompilerContext
                                                                                                .Current_Method_Wrapper);
                    if (currentMethod != null)
                    {
                        // FIXME: remove
                        string this_classname = currentMethod.varproc.GetThisVars().GetOrNull(pair);
                        if (this_classname != null)
                        {
                            if (!classname.Equals(this_classname))
                            {
                                // TODO: direct comparison to the super class?
                                super_qualifier = this_classname;
                            }
                        }
                    }
                }
                if (super_qualifier != null)
                {
                    TextUtil.WriteQualifiedSuper(buf, super_qualifier);
                }
                else
                {
                    TextBuffer buff   = new TextBuffer();
                    bool       casted = ExprProcessor.GetCastedExprent(instance, new VarType(ICodeConstants
                                                                                             .Type_Object, 0, classname), buff, indent, true, tracer);
                    string res = buff.ToString();
                    if (casted || instance.GetPrecedence() > GetPrecedence())
                    {
                        res = "(" + res + ")";
                    }
                    buf.Append(res);
                }
                if (buf.ToString().Equals(VarExprent.Var_Nameless_Enclosure))
                {
                    // FIXME: workaround for field access of an anonymous enclosing class. Find a better way.
                    buf.SetLength(0);
                }
                else
                {
                    buf.Append(".");
                }
            }
            buf.Append(name);
            tracer.AddMapping(bytecode);
            return(buf);
        }
Exemple #16
0
        private void ProcessExprent(Exprent expr, SFormsFastMapDirect[] varmaparr, Statement
                                    stat, bool calcLiveVars)
        {
            if (expr == null)
            {
                return;
            }
            VarExprent varassign = null;
            bool       finished  = false;

            switch (expr.type)
            {
            case Exprent.Exprent_Assignment:
            {
                AssignmentExprent assexpr = (AssignmentExprent)expr;
                if (assexpr.GetCondType() == AssignmentExprent.Condition_None)
                {
                    Exprent dest = assexpr.GetLeft();
                    if (dest.type == Exprent.Exprent_Var)
                    {
                        varassign = (VarExprent)dest;
                    }
                }
                break;
            }

            case Exprent.Exprent_Function:
            {
                FunctionExprent func = (FunctionExprent)expr;
                switch (func.GetFuncType())
                {
                case FunctionExprent.Function_Iif:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars);
                    SFormsFastMapDirect varmapFalse;
                    if (varmaparr[1] == null)
                    {
                        varmapFalse = new SFormsFastMapDirect(varmaparr[0]);
                    }
                    else
                    {
                        varmapFalse  = varmaparr[1];
                        varmaparr[1] = null;
                    }
                    ProcessExprent(func.GetLstOperands()[1], varmaparr, stat, calcLiveVars);
                    SFormsFastMapDirect[] varmaparrNeg = new SFormsFastMapDirect[] { varmapFalse, null };
                    ProcessExprent(func.GetLstOperands()[2], varmaparrNeg, stat, calcLiveVars);
                    MergeMaps(varmaparr[0], varmaparrNeg[0]);
                    varmaparr[1] = null;
                    finished     = true;
                    break;
                }

                case FunctionExprent.Function_Cadd:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars);
                    SFormsFastMapDirect[] varmaparrAnd = new SFormsFastMapDirect[] { new SFormsFastMapDirect
                                                                                         (varmaparr[0]), null };
                    ProcessExprent(func.GetLstOperands()[1], varmaparrAnd, stat, calcLiveVars);
                    // false map
                    varmaparr[1] = MergeMaps(varmaparr[varmaparr[1] == null ? 0 : 1], varmaparrAnd[varmaparrAnd
                                                                                                   [1] == null ? 0 : 1]);
                    // true map
                    varmaparr[0] = varmaparrAnd[0];
                    finished     = true;
                    break;
                }

                case FunctionExprent.Function_Cor:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars);
                    SFormsFastMapDirect[] varmaparrOr = new SFormsFastMapDirect[] { new SFormsFastMapDirect
                                                                                        (varmaparr[varmaparr[1] == null ? 0 : 1]), null };
                    ProcessExprent(func.GetLstOperands()[1], varmaparrOr, stat, calcLiveVars);
                    // false map
                    varmaparr[1] = varmaparrOr[varmaparrOr[1] == null ? 0 : 1];
                    // true map
                    varmaparr[0] = MergeMaps(varmaparr[0], varmaparrOr[0]);
                    finished     = true;
                    break;
                }
                }
                break;
            }
            }
            if (!finished)
            {
                List <Exprent> lst = expr.GetAllExprents();
                lst.Remove(varassign);
                foreach (Exprent ex in lst)
                {
                    ProcessExprent(ex, varmaparr, stat, calcLiveVars);
                }
            }
            SFormsFastMapDirect varmap = varmaparr[0];

            // field access
            if (expr.type == Exprent.Exprent_Field)
            {
                int?index;
                if (mapFieldVars.ContainsKey(expr.id))
                {
                    index = mapFieldVars.GetOrNullable(expr.id);
                }
                else
                {
                    index = fieldvarcounter--;
                    Sharpen.Collections.Put(mapFieldVars, expr.id, index);
                    // ssu graph
                    ssuversions.CreateNode(new VarVersionPair(index, 1));
                }
                SetCurrentVar(varmap, index, 1);
            }
            else if (expr.type == Exprent.Exprent_Invocation || (expr.type == Exprent.Exprent_Assignment &&
                                                                 ((AssignmentExprent)expr).GetLeft().type == Exprent.Exprent_Field) || (expr.
                                                                                                                                        type == Exprent.Exprent_New && ((NewExprent)expr).GetNewType().type == ICodeConstants
                                                                                                                                        .Type_Object) || expr.type == Exprent.Exprent_Function)
            {
                bool ismmpp = true;
                if (expr.type == Exprent.Exprent_Function)
                {
                    ismmpp = false;
                    FunctionExprent fexpr = (FunctionExprent)expr;
                    if (fexpr.GetFuncType() >= FunctionExprent.Function_Imm && fexpr.GetFuncType() <=
                        FunctionExprent.Function_Ppi)
                    {
                        if (fexpr.GetLstOperands()[0].type == Exprent.Exprent_Field)
                        {
                            ismmpp = true;
                        }
                    }
                }
                if (ismmpp)
                {
                    varmap.RemoveAllFields();
                }
            }
            if (varassign != null)
            {
                int varindex = varassign.GetIndex();
                if (varassign.GetVersion() == 0)
                {
                    // get next version
                    int nextver = GetNextFreeVersion(varindex, stat);
                    // set version
                    varassign.SetVersion(nextver);
                    // ssu graph
                    ssuversions.CreateNode(new VarVersionPair(varindex, nextver));
                    SetCurrentVar(varmap, varindex, nextver);
                }
                else
                {
                    if (calcLiveVars)
                    {
                        VarMapToGraph(new VarVersionPair(varindex, varassign.GetVersion()), varmap);
                    }
                    SetCurrentVar(varmap, varindex, varassign.GetVersion());
                }
            }
            else if (expr.type == Exprent.Exprent_Function)
            {
                // MM or PP function
                FunctionExprent func_1 = (FunctionExprent)expr;
                switch (func_1.GetFuncType())
                {
                case FunctionExprent.Function_Imm:
                case FunctionExprent.Function_Mmi:
                case FunctionExprent.Function_Ipp:
                case FunctionExprent.Function_Ppi:
                {
                    if (func_1.GetLstOperands()[0].type == Exprent.Exprent_Var)
                    {
                        VarExprent     var      = (VarExprent)func_1.GetLstOperands()[0];
                        int            varindex = var.GetIndex();
                        VarVersionPair varpaar  = new VarVersionPair(varindex, var.GetVersion());
                        // ssu graph
                        VarVersionPair phantomver = phantomppnodes.GetOrNull(varpaar);
                        if (phantomver == null)
                        {
                            // get next version
                            int nextver = GetNextFreeVersion(varindex, null);
                            phantomver = new VarVersionPair(varindex, nextver);
                            //ssuversions.createOrGetNode(phantomver);
                            ssuversions.CreateNode(phantomver);
                            VarVersionNode vernode = ssuversions.nodes.GetWithKey(varpaar);
                            FastSparseSetFactory <int> .FastSparseSet <int> vers = factory.SpawnEmptySet();
                            if (vernode.preds.Count == 1)
                            {
                                vers.Add(new Sharpen.EnumeratorAdapter <VarVersionEdge>(vernode.preds.GetEnumerator()).Next().source.version);
                            }
                            else
                            {
                                foreach (VarVersionEdge edge in vernode.preds)
                                {
                                    vers.Add(new Sharpen.EnumeratorAdapter <VarVersionEdge>(edge.source.preds.GetEnumerator()).Next().source.version);
                                }
                            }
                            vers.Add(nextver);
                            CreateOrUpdatePhiNode(varpaar, vers, stat);
                            Sharpen.Collections.Put(phantomppnodes, varpaar, phantomver);
                        }
                        if (calcLiveVars)
                        {
                            VarMapToGraph(varpaar, varmap);
                        }
                        SetCurrentVar(varmap, varindex, var.GetVersion());
                    }
                    break;
                }
                }
            }
            else if (expr.type == Exprent.Exprent_Var)
            {
                VarExprent vardest      = (VarExprent)expr;
                int        varindex     = vardest.GetIndex();
                int        current_vers = vardest.GetVersion();
                FastSparseSetFactory <int> .FastSparseSet <int> vers = varmap.Get(varindex);
                int cardinality = vers.GetCardinality();
                if (cardinality == 1)
                {
                    // size == 1
                    if (current_vers != 0)
                    {
                        if (calcLiveVars)
                        {
                            VarMapToGraph(new VarVersionPair(varindex, current_vers), varmap);
                        }
                        SetCurrentVar(varmap, varindex, current_vers);
                    }
                    else
                    {
                        // split last version
                        int usever = GetNextFreeVersion(varindex, stat);
                        // set version
                        vardest.SetVersion(usever);
                        SetCurrentVar(varmap, varindex, usever);
                        // ssu graph
                        int            lastver = new Sharpen.EnumeratorAdapter <int>(vers.GetEnumerator()).Next();
                        VarVersionNode prenode = ssuversions.nodes.GetWithKey(new VarVersionPair(varindex
                                                                                                 , lastver));
                        VarVersionNode usenode = ssuversions.CreateNode(new VarVersionPair(varindex, usever
                                                                                           ));
                        VarVersionEdge edge = new VarVersionEdge(VarVersionEdge.Edge_General, prenode, usenode
                                                                 );
                        prenode.AddSuccessor(edge);
                        usenode.AddPredecessor(edge);
                    }
                }
                else if (cardinality == 2)
                {
                    // size > 1
                    if (current_vers != 0)
                    {
                        if (calcLiveVars)
                        {
                            VarMapToGraph(new VarVersionPair(varindex, current_vers), varmap);
                        }
                        SetCurrentVar(varmap, varindex, current_vers);
                    }
                    else
                    {
                        // split version
                        int usever = GetNextFreeVersion(varindex, stat);
                        // set version
                        vardest.SetVersion(usever);
                        // ssu node
                        ssuversions.CreateNode(new VarVersionPair(varindex, usever));
                        SetCurrentVar(varmap, varindex, usever);
                        current_vers = usever;
                    }
                    CreateOrUpdatePhiNode(new VarVersionPair(varindex, current_vers), vers, stat);
                }
            }
        }
        private void ProcessExprent(Exprent expr, SFormsFastMapDirect[] varmaparr)
        {
            if (expr == null)
            {
                return;
            }
            VarExprent varassign = null;
            bool       finished  = false;

            switch (expr.type)
            {
            case Exprent.Exprent_Assignment:
            {
                AssignmentExprent assexpr = (AssignmentExprent)expr;
                if (assexpr.GetCondType() == AssignmentExprent.Condition_None)
                {
                    Exprent dest = assexpr.GetLeft();
                    if (dest.type == Exprent.Exprent_Var)
                    {
                        varassign = (VarExprent)dest;
                    }
                }
                break;
            }

            case Exprent.Exprent_Function:
            {
                FunctionExprent func = (FunctionExprent)expr;
                switch (func.GetFuncType())
                {
                case FunctionExprent.Function_Iif:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr);
                    SFormsFastMapDirect varmapFalse;
                    if (varmaparr[1] == null)
                    {
                        varmapFalse = new SFormsFastMapDirect(varmaparr[0]);
                    }
                    else
                    {
                        varmapFalse  = varmaparr[1];
                        varmaparr[1] = null;
                    }
                    ProcessExprent(func.GetLstOperands()[1], varmaparr);
                    SFormsFastMapDirect[] varmaparrNeg = new SFormsFastMapDirect[] { varmapFalse, null };
                    ProcessExprent(func.GetLstOperands()[2], varmaparrNeg);
                    MergeMaps(varmaparr[0], varmaparrNeg[0]);
                    varmaparr[1] = null;
                    finished     = true;
                    break;
                }

                case FunctionExprent.Function_Cadd:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr);
                    SFormsFastMapDirect[] varmaparrAnd = new SFormsFastMapDirect[] { new SFormsFastMapDirect
                                                                                         (varmaparr[0]), null };
                    ProcessExprent(func.GetLstOperands()[1], varmaparrAnd);
                    // false map
                    varmaparr[1] = MergeMaps(varmaparr[varmaparr[1] == null ? 0 : 1], varmaparrAnd[varmaparrAnd
                                                                                                   [1] == null ? 0 : 1]);
                    // true map
                    varmaparr[0] = varmaparrAnd[0];
                    finished     = true;
                    break;
                }

                case FunctionExprent.Function_Cor:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr);
                    SFormsFastMapDirect[] varmaparrOr = new SFormsFastMapDirect[] { new SFormsFastMapDirect
                                                                                        (varmaparr[varmaparr[1] == null ? 0 : 1]), null };
                    ProcessExprent(func.GetLstOperands()[1], varmaparrOr);
                    // false map
                    varmaparr[1] = varmaparrOr[varmaparrOr[1] == null ? 0 : 1];
                    // true map
                    varmaparr[0] = MergeMaps(varmaparr[0], varmaparrOr[0]);
                    finished     = true;
                    break;
                }
                }
                break;
            }
            }
            if (finished)
            {
                return;
            }
            List <Exprent> lst = expr.GetAllExprents();

            lst.Remove(varassign);
            foreach (Exprent ex in lst)
            {
                ProcessExprent(ex, varmaparr);
            }
            SFormsFastMapDirect varmap = varmaparr[0];

            if (varassign != null)
            {
                int varindex = varassign.GetIndex();
                if (varassign.GetVersion() == 0)
                {
                    // get next version
                    int nextver = GetNextFreeVersion(varindex);
                    // set version
                    varassign.SetVersion(nextver);
                    SetCurrentVar(varmap, varindex, nextver);
                }
                else
                {
                    SetCurrentVar(varmap, varindex, varassign.GetVersion());
                }
            }
            else if (expr.type == Exprent.Exprent_Var)
            {
                VarExprent vardest  = (VarExprent)expr;
                int        varindex = vardest.GetIndex();
                FastSparseSetFactory <int> .FastSparseSet <int> vers = varmap.Get(varindex);
                int cardinality = vers.GetCardinality();
                if (cardinality == 1)
                {
                    // == 1
                    // set version
                    int it = new Sharpen.EnumeratorAdapter <int>(vers.GetEnumerator()).Next();
                    vardest.SetVersion(it);
                }
                else if (cardinality == 2)
                {
                    // size > 1
                    int            current_vers = vardest.GetVersion();
                    VarVersionPair currpaar     = new VarVersionPair(varindex, current_vers);
                    if (current_vers != 0 && phi.ContainsKey(currpaar))
                    {
                        SetCurrentVar(varmap, varindex, current_vers);
                        // update phi node
                        phi.GetOrNull(currpaar).Union(vers);
                    }
                    else
                    {
                        // increase version
                        int nextver = GetNextFreeVersion(varindex);
                        // set version
                        vardest.SetVersion(nextver);
                        SetCurrentVar(varmap, varindex, nextver);
                        // create new phi node
                        Sharpen.Collections.Put(phi, new VarVersionPair(varindex, nextver), vers);
                    }
                }
            }
        }
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            TextBuffer buf             = new TextBuffer();
            string     super_qualifier = null;
            bool       isInstanceThis  = false;

            tracer.AddMapping(bytecode);
            if (instance is InvocationExprent)
            {
                ((InvocationExprent)instance).MarkUsingBoxingResult();
            }
            if (isStatic__)
            {
                if (IsBoxingCall() && canIgnoreBoxing)
                {
                    // process general "boxing" calls, e.g. 'Object[] data = { true }' or 'Byte b = 123'
                    // here 'byte' and 'short' values do not need an explicit narrowing type cast
                    ExprProcessor.GetCastedExprent(lstParameters[0], descriptor.@params[0], buf, indent
                                                   , false, false, false, false, tracer);
                    return(buf);
                }
                ClassesProcessor.ClassNode node = (ClassesProcessor.ClassNode)DecompilerContext.GetProperty
                                                      (DecompilerContext.Current_Class_Node);
                if (node == null || !classname.Equals(node.classStruct.qualifiedName))
                {
                    buf.Append(DecompilerContext.GetImportCollector().GetShortNameInClassContext(ExprProcessor
                                                                                                 .BuildJavaClassName(classname)));
                }
            }
            else
            {
                if (instance != null && instance.type == Exprent.Exprent_Var)
                {
                    VarExprent     instVar = (VarExprent)instance;
                    VarVersionPair varPair = new VarVersionPair(instVar);
                    VarProcessor   varProc = instVar.GetProcessor();
                    if (varProc == null)
                    {
                        MethodWrapper currentMethod = (MethodWrapper)DecompilerContext.GetProperty(DecompilerContext
                                                                                                   .Current_Method_Wrapper);
                        if (currentMethod != null)
                        {
                            varProc = currentMethod.varproc;
                        }
                    }
                    string this_classname = null;
                    if (varProc != null)
                    {
                        this_classname = varProc.GetThisVars().GetOrNull(varPair);
                    }
                    if (this_classname != null)
                    {
                        isInstanceThis = true;
                        if (invocationTyp == Invoke_Special)
                        {
                            if (!classname.Equals(this_classname))
                            {
                                // TODO: direct comparison to the super class?
                                StructClass cl          = DecompilerContext.GetStructContext().GetClass(classname);
                                bool        isInterface = cl != null && cl.HasModifier(ICodeConstants.Acc_Interface);
                                super_qualifier = !isInterface ? this_classname : classname;
                            }
                        }
                    }
                }
                if (functype == Typ_General)
                {
                    if (super_qualifier != null)
                    {
                        TextUtil.WriteQualifiedSuper(buf, super_qualifier);
                    }
                    else if (instance != null)
                    {
                        TextBuffer res = instance.ToJava(indent, tracer);
                        if (IsUnboxingCall())
                        {
                            // we don't print the unboxing call - no need to bother with the instance wrapping / casting
                            buf.Append(res);
                            return(buf);
                        }
                        VarType rightType = instance.GetExprType();
                        VarType leftType  = new VarType(ICodeConstants.Type_Object, 0, classname);
                        if (rightType.Equals(VarType.Vartype_Object) && !leftType.Equals(rightType))
                        {
                            buf.Append("((").Append(ExprProcessor.GetCastTypeName(leftType)).Append(")");
                            if (instance.GetPrecedence() >= FunctionExprent.GetPrecedence(FunctionExprent.Function_Cast
                                                                                          ))
                            {
                                res.Enclose("(", ")");
                            }
                            buf.Append(res).Append(")");
                        }
                        else if (instance.GetPrecedence() > GetPrecedence())
                        {
                            buf.Append("(").Append(res).Append(")");
                        }
                        else
                        {
                            buf.Append(res);
                        }
                    }
                }
            }
            switch (functype)
            {
            case Typ_General:
            {
                if (VarExprent.Var_Nameless_Enclosure.Equals(buf.ToString()))
                {
                    buf = new TextBuffer();
                }
                if (buf.Length() > 0)
                {
                    buf.Append(".");
                }
                buf.Append(name);
                if (invocationTyp == Invoke_Dynamic)
                {
                    buf.Append("<invokedynamic>");
                }
                buf.Append("(");
                break;
            }

            case Typ_Clinit:
            {
                throw new Exception("Explicit invocation of " + ICodeConstants.Clinit_Name);
            }

            case Typ_Init:
            {
                if (super_qualifier != null)
                {
                    buf.Append("super(");
                }
                else if (isInstanceThis)
                {
                    buf.Append("this(");
                }
                else if (instance != null)
                {
                    buf.Append(instance.ToJava(indent, tracer)).Append(".<init>(");
                }
                else
                {
                    throw new Exception("Unrecognized invocation of " + ICodeConstants.Init_Name);
                }
                break;
            }
            }
            List <VarVersionPair> mask = null;
            bool isEnum = false;

            if (functype == Typ_Init)
            {
                ClassesProcessor.ClassNode newNode = DecompilerContext.GetClassProcessor().GetMapRootClasses
                                                         ().GetOrNull(classname);
                if (newNode != null)
                {
                    mask = ExprUtil.GetSyntheticParametersMask(newNode, stringDescriptor, lstParameters
                                                               .Count);
                    isEnum = newNode.classStruct.HasModifier(ICodeConstants.Acc_Enum) && DecompilerContext
                             .GetOption(IFernflowerPreferences.Decompile_Enum);
                }
            }
            BitSet setAmbiguousParameters = GetAmbiguousParameters();

            // omit 'new Type[] {}' for the last parameter of a vararg method call
            if (lstParameters.Count == [email protected] && IsVarArgCall())
            {
                Exprent lastParam = lstParameters[lstParameters.Count - 1];
                if (lastParam.type == Exprent_New && lastParam.GetExprType().arrayDim >= 1)
                {
                    ((NewExprent)lastParam).SetVarArgParam(true);
                }
            }
            bool firstParameter = true;
            int  start          = isEnum ? 2 : 0;

            for (int i = start; i < lstParameters.Count; i++)
            {
                if (mask == null || mask[i] == null)
                {
                    TextBuffer buff      = new TextBuffer();
                    bool       ambiguous = setAmbiguousParameters.Get(i);
                    // 'byte' and 'short' literals need an explicit narrowing type cast when used as a parameter
                    ExprProcessor.GetCastedExprent(lstParameters[i], descriptor.@params[i], buff, indent
                                                   , true, ambiguous, true, true, tracer);
                    // the last "new Object[0]" in the vararg call is not printed
                    if (buff.Length() > 0)
                    {
                        if (!firstParameter)
                        {
                            buf.Append(", ");
                        }
                        buf.Append(buff);
                    }
                    firstParameter = false;
                }
            }
            buf.Append(')');
            return(buf);
        }
Exemple #19
0
        private static object[] IterateChildExprent(Exprent exprent, Exprent parent, Exprent
                                                    next, Dictionary <VarVersionPair, Exprent> mapVarValues, SSAUConstructorSparseEx
                                                    ssau)
        {
            bool changed = false;

            foreach (Exprent expr in exprent.GetAllExprents())
            {
                var oldExpr = expr;
                while (true)
                {
                    object[] arr     = IterateChildExprent(oldExpr, parent, next, mapVarValues, ssau);
                    Exprent  retexpr = (Exprent)arr[0];
                    changed |= (bool)arr[1];
                    bool isReplaceable = (bool)arr[2];
                    if (retexpr != null)
                    {
                        if (isReplaceable)
                        {
                            ReplaceSingleVar(exprent, (VarExprent)oldExpr, retexpr, ssau);
                            oldExpr = retexpr;
                        }
                        else
                        {
                            exprent.ReplaceExprent(oldExpr, retexpr);
                        }
                        changed = true;
                    }
                    if (!isReplaceable)
                    {
                        break;
                    }
                }
            }
            Exprent dest = IsReplaceableVar(exprent, mapVarValues);

            if (dest != null)
            {
                return(new object[] { dest, true, true });
            }
            VarExprent left  = null;
            Exprent    right = null;

            if (exprent.type == Exprent.Exprent_Assignment)
            {
                AssignmentExprent @as = (AssignmentExprent)exprent;
                if (@as.GetLeft().type == Exprent.Exprent_Var)
                {
                    left  = (VarExprent)@as.GetLeft();
                    right = @as.GetRight();
                }
            }
            if (left == null)
            {
                return(new object[] { null, changed, false });
            }
            bool isHeadSynchronized = false;

            if (next == null && parent.type == Exprent.Exprent_Monitor)
            {
                MonitorExprent monexpr = (MonitorExprent)parent;
                if (monexpr.GetMonType() == MonitorExprent.Monitor_Enter && exprent.Equals(monexpr
                                                                                           .GetValue()))
                {
                    isHeadSynchronized = true;
                }
            }
            // stack variable or synchronized head exprent
            if (!left.IsStack() && !isHeadSynchronized)
            {
                return(new object[] { null, changed, false });
            }
            VarVersionPair        leftpaar = new VarVersionPair(left);
            List <VarVersionNode> usedVers = new List <VarVersionNode>();
            bool notdom = GetUsedVersions(ssau, leftpaar, usedVers);

            if (!notdom && (usedVers.Count == 0))
            {
                return(new object[] { right, changed, false });
            }
            // stack variables only
            if (!left.IsStack())
            {
                return(new object[] { null, changed, false });
            }
            int useflags = right.GetExprentUse();

            if ((useflags & Exprent.Both_Flags) != Exprent.Both_Flags)
            {
                return(new object[] { null, changed, false });
            }
            Dictionary <int, HashSet <VarVersionPair> > mapVars = GetAllVarVersions(leftpaar, right
                                                                                    , ssau);

            if (mapVars.ContainsKey(leftpaar.var) && notdom)
            {
                return(new object[] { null, changed, false });
            }
            Sharpen.Collections.Remove(mapVars, leftpaar.var);
            HashSet <VarVersionPair> setAllowedVars = GetAllVersions(parent);

            if (next != null)
            {
                Sharpen.Collections.AddAll(setAllowedVars, GetAllVersions(next));
            }
            bool vernotreplaced = false;
            HashSet <VarVersionPair> setTempUsedVers = new HashSet <VarVersionPair>();

            foreach (VarVersionNode usedvar in usedVers)
            {
                VarVersionPair usedver = new VarVersionPair(usedvar.var, usedvar.version);
                if (IsVersionToBeReplaced(usedver, mapVars, ssau, leftpaar) && (right.type == Exprent
                                                                                .Exprent_Var || setAllowedVars.Contains(usedver)))
                {
                    setTempUsedVers.Add(usedver);
                }
                else
                {
                    vernotreplaced = true;
                }
            }
            if (!notdom && !vernotreplaced)
            {
                foreach (VarVersionPair usedver in setTempUsedVers)
                {
                    Exprent copy = right.Copy();
                    if (right.type == Exprent.Exprent_Field && ssau.GetMapFieldVars().ContainsKey(right
                                                                                                  .id))
                    {
                        Sharpen.Collections.Put(ssau.GetMapFieldVars(), copy.id, ssau.GetMapFieldVars().GetOrNullable
                                                    (right.id));
                    }
                    Sharpen.Collections.Put(mapVarValues, usedver, copy);
                }
                // remove assignment
                return(new object[] { right, changed, false });
            }
            return(new object[] { null, changed, false });
        }