示例#1
0
 private static bool AddArrayInitializer(Exprent first, Exprent second)
 {
     if (first.type == Exprent.Exprent_Assignment)
     {
         AssignmentExprent @as = (AssignmentExprent)first;
         if (@as.GetRight().type == Exprent.Exprent_New && @as.GetLeft().type == Exprent.Exprent_Var)
         {
             NewExprent newExpr = (NewExprent)@as.GetRight();
             if (!(newExpr.GetLstArrayElements().Count == 0))
             {
                 VarExprent arrVar = (VarExprent)@as.GetLeft();
                 if (second.type == Exprent.Exprent_Assignment)
                 {
                     AssignmentExprent aas = (AssignmentExprent)second;
                     if (aas.GetLeft().type == Exprent.Exprent_Array)
                     {
                         ArrayExprent arrExpr = (ArrayExprent)aas.GetLeft();
                         if (arrExpr.GetArray().type == Exprent.Exprent_Var && arrVar.Equals(arrExpr.GetArray
                                                                                                 ()) && arrExpr.GetIndex().type == Exprent.Exprent_Const)
                         {
                             int constValue = ((ConstExprent)arrExpr.GetIndex()).GetIntValue();
                             if (constValue < newExpr.GetLstArrayElements().Count)
                             {
                                 Exprent init = newExpr.GetLstArrayElements()[constValue];
                                 if (init.type == Exprent.Exprent_Const)
                                 {
                                     ConstExprent cinit      = (ConstExprent)init;
                                     VarType      arrType    = newExpr.GetNewType().DecreaseArrayDim();
                                     ConstExprent defaultVal = ExprProcessor.GetDefaultArrayValue(arrType);
                                     if (cinit.Equals(defaultVal))
                                     {
                                         Exprent tempExpr = aas.GetRight();
                                         if (!tempExpr.ContainsExprent(arrVar))
                                         {
                                             newExpr.GetLstArrayElements()[constValue] = tempExpr;
                                             if (tempExpr.type == Exprent.Exprent_New)
                                             {
                                                 NewExprent tempNewExpr = (NewExprent)tempExpr;
                                                 int        dims        = newExpr.GetNewType().arrayDim;
                                                 if (dims > 1 && !(tempNewExpr.GetLstArrayElements().Count == 0))
                                                 {
                                                     tempNewExpr.SetDirectArrayInit(true);
                                                 }
                                             }
                                             return(true);
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     return(false);
 }
示例#2
0
        private static Exprent IsReplaceableVar(Exprent exprent, Dictionary <VarVersionPair
                                                                             , Exprent> mapVarValues)
        {
            Exprent dest = null;

            if (exprent.type == Exprent.Exprent_Var)
            {
                VarExprent var = (VarExprent)exprent;
                dest = mapVarValues.GetOrNull(new VarVersionPair(var));
            }
            return(dest);
        }
示例#3
0
 private static bool IsTrivialStackAssignment(Exprent first)
 {
     if (first.type == Exprent.Exprent_Assignment)
     {
         AssignmentExprent asf = (AssignmentExprent)first;
         if (asf.GetLeft().type == Exprent.Exprent_Var && asf.GetRight().type == Exprent.Exprent_Var)
         {
             VarExprent left  = (VarExprent)asf.GetLeft();
             VarExprent right = (VarExprent)asf.GetRight();
             return(left.GetIndex() == right.GetIndex() && left.IsStack() && right.IsStack());
         }
     }
     return(false);
 }
示例#4
0
        private static HashSet <VarVersionPair> GetAllVersions(Exprent exprent)
        {
            HashSet <VarVersionPair> res      = new HashSet <VarVersionPair>();
            List <Exprent>           listTemp = new List <Exprent>(exprent.GetAllExprents(true));

            listTemp.Add(exprent);
            foreach (Exprent expr in listTemp)
            {
                if (expr.type == Exprent.Exprent_Var)
                {
                    VarExprent var = (VarExprent)expr;
                    res.Add(new VarVersionPair(var));
                }
            }
            return(res);
        }
示例#5
0
        private static void ReplaceSingleVar(Exprent parent, VarExprent var, Exprent dest
                                             , SSAUConstructorSparseEx ssau)
        {
            parent.ReplaceExprent(var, dest);
            // live sets
            SFormsFastMapDirect      livemap = ssau.GetLiveVarVersionsMap(new VarVersionPair(var));
            HashSet <VarVersionPair> setVars = GetAllVersions(dest);

            foreach (VarVersionPair varpaar in setVars)
            {
                VarVersionNode node      = ssau.GetSsuversions().nodes.GetWithKey(varpaar);
                var            toRemove  = new List <KeyValuePair <int, FastSparseSetFactory <int> .FastSparseSet <int> > >();
                var            entryList = node.live.EntryList();
                for (var index = 0; index < entryList.Count; index++)
                {
                    var itent = entryList[index];
                    KeyValuePair <int, FastSparseSetFactory <int> .FastSparseSet <int> > ent =
                        entryList.ElementAtOrDefault(index + 1);
                    if (ent.Value == null)
                    {
                        break;
                    }

                    int key = ent.Key;
                    if (!livemap.ContainsKey(key))
                    {
                        toRemove.Add(itent);
                    }
                    else
                    {
                        FastSparseSetFactory <int> .FastSparseSet <int> set = ent.Value;
                        set.Complement(livemap.Get(key));
                        if (set.IsEmpty())
                        {
                            toRemove.Add(itent);
                        }
                    }
                }

                foreach (var keyValuePair in toRemove)
                {
                    node.live.PutInternal(keyValuePair.Key, keyValuePair.Value, true);
                    // entryList.RemoveAll(c => c.Key == keyValuePair.Key);
                }
            }
        }
 private static bool SetDefinition(Exprent expr, int index)
 {
     if (expr.type == Exprent.Exprent_Assignment)
     {
         Exprent left = ((AssignmentExprent)expr).GetLeft();
         if (left.type == Exprent.Exprent_Var)
         {
             VarExprent var = (VarExprent)left;
             if (var.GetIndex() == index)
             {
                 var.SetDefinition(true);
                 return(true);
             }
         }
     }
     return(false);
 }
示例#7
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);
 }
示例#8
0
 private static void UpdateVersions(DirectGraph graph, Dictionary <VarVersionPair,
                                                                   int> versions)
 {
     graph.IterateExprents((Exprent exprent) => {
         List <Exprent> lst = exprent.GetAllExprents(true);
         lst.Add(exprent);
         foreach (Exprent expr in lst)
         {
             if (expr.type == Exprent.Exprent_Var)
             {
                 VarExprent var = (VarExprent)expr;
                 int?version    = versions.GetOrNullable(new VarVersionPair(var));
                 if (version != null)
                 {
                     var.SetVersion(version.Value);
                 }
             }
         }
         return(0);
     }
                           );
 }
示例#9
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 });
        }
示例#10
0
        private static bool FindAndRemoveParameterCheck(Statement stat, StructMethod mt)
        {
            Statement st = stat.GetFirst();

            while (st.type == Statement.Type_Sequence)
            {
                st = st.GetFirst();
            }
            if (st.type == Statement.Type_If)
            {
                IfStatement ifstat           = (IfStatement)st;
                Statement   ifbranch         = ifstat.GetIfstat();
                Exprent     if_condition     = ifstat.GetHeadexprent().GetCondition();
                bool        is_notnull_check = false;
                // TODO: FUNCTION_NE also possible if reversed order (in theory)
                if (ifbranch != null && if_condition.type == Exprent.Exprent_Function && ((FunctionExprent
                                                                                           )if_condition).GetFuncType() == FunctionExprent.Function_Eq && ifbranch.type ==
                    Statement.Type_Basicblock && ifbranch.GetExprents().Count == 1 && ifbranch.GetExprents
                        ()[0].type == Exprent.Exprent_Exit)
                {
                    FunctionExprent func         = (FunctionExprent)if_condition;
                    Exprent         first_param  = func.GetLstOperands()[0];
                    Exprent         second_param = func.GetLstOperands()[1];
                    if (second_param.type == Exprent.Exprent_Const && second_param.GetExprType().type
                        == ICodeConstants.Type_Null)
                    {
                        // TODO: reversed parameter order
                        if (first_param.type == Exprent.Exprent_Var)
                        {
                            VarExprent       var     = (VarExprent)first_param;
                            bool             thisvar = !mt.HasModifier(ICodeConstants.Acc_Static);
                            MethodDescriptor md      = MethodDescriptor.ParseDescriptor(mt.GetDescriptor());
                            // parameter annotations
                            StructAnnotationParameterAttribute param_annotations = mt.GetAttribute(StructGeneralAttribute
                                                                                                   .Attribute_Runtime_Invisible_Parameter_Annotations);
                            if (param_annotations != null)
                            {
                                List <List <AnnotationExprent> > param_annotations_lists = param_annotations.GetParamAnnotations
                                                                                               ();
                                int method_param_number = [email protected];
                                int index = thisvar ? 1 : 0;
                                for (int i = 0; i < method_param_number; i++)
                                {
                                    if (index == var.GetIndex())
                                    {
                                        if (param_annotations_lists.Count >= method_param_number - i)
                                        {
                                            int shift = method_param_number - param_annotations_lists.Count;
                                            // NOTE: workaround for compiler bug, count annotations starting with the last parameter
                                            List <AnnotationExprent> annotations = param_annotations_lists[i - shift];
                                            foreach (AnnotationExprent ann in annotations)
                                            {
                                                if (ann.GetClassName().Equals("org/jetbrains/annotations/NotNull"))
                                                {
                                                    is_notnull_check = true;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    index += md.@params[i].stackSize;
                                }
                            }
                        }
                    }
                }
                if (!is_notnull_check)
                {
                    return(false);
                }
                RemoveParameterCheck(stat);
                return(true);
            }
            return(false);
        }
示例#11
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 });
            }
        }
示例#12
0
        private Exprent ReplaceAccessExprent(ClassesProcessor.ClassNode caller, MethodWrapper
                                             methdest, InvocationExprent invexpr)
        {
            ClassesProcessor.ClassNode node = DecompilerContext.GetClassProcessor().GetMapRootClasses
                                                  ().GetOrNull(invexpr.GetClassname());
            MethodWrapper methsource = null;

            if (node != null && node.GetWrapper() != null)
            {
                methsource = node.GetWrapper().GetMethodWrapper(invexpr.GetName(), invexpr.GetStringDescriptor
                                                                    ());
            }
            if (methsource == null || !mapMethodType.ContainsKey(methsource))
            {
                return(null);
            }
            // if same method, return
            if (node.classStruct.qualifiedName.Equals(caller.classStruct.qualifiedName) && methsource
                .methodStruct.GetName().Equals(methdest.methodStruct.GetName()) && methsource.methodStruct
                .GetDescriptor().Equals(methdest.methodStruct.GetDescriptor()))
            {
                // no recursive invocations permitted!
                return(null);
            }
            NestedMemberAccess.MethodAccess type = mapMethodType.GetOrNull(methsource);
            //		// FIXME: impossible case. MethodAccess.NORMAL is not saved in the map
            //		if(type == MethodAccess.NORMAL) {
            //			return null;
            //		}
            if (!SameTree(caller, node))
            {
                return(null);
            }
            DirectGraph graph      = methsource.GetOrBuildGraph();
            Exprent     source     = graph.first.exprents[0];
            Exprent     retexprent = null;

            switch (type.ordinal())
            {
            case 1:
            {
                ExitExprent exsource = (ExitExprent)source;
                if (exsource.GetValue().type == Exprent.Exprent_Var)
                {
                    // qualified this
                    VarExprent var     = (VarExprent)exsource.GetValue();
                    string     varname = methsource.varproc.GetVarName(new VarVersionPair(var));
                    if (!methdest.setOuterVarNames.Contains(varname))
                    {
                        VarNamesCollector vnc = new VarNamesCollector();
                        vnc.AddName(varname);
                        methdest.varproc.RefreshVarNames(vnc);
                        methdest.setOuterVarNames.Add(varname);
                    }
                    int        index = methdest.counter.GetCounterAndIncrement(CounterContainer.Var_Counter);
                    VarExprent ret   = new VarExprent(index, var.GetVarType(), methdest.varproc);
                    methdest.varproc.SetVarName(new VarVersionPair(index, 0), varname);
                    retexprent = ret;
                }
                else
                {
                    // field
                    FieldExprent ret = (FieldExprent)exsource.GetValue().Copy();
                    if (!ret.IsStatic())
                    {
                        ret.ReplaceExprent(ret.GetInstance(), invexpr.GetLstParameters()[0]);
                    }
                    retexprent = ret;
                }
                break;
            }

            case 2:
            {
                AssignmentExprent ret_1;
                if (source.type == Exprent.Exprent_Exit)
                {
                    ExitExprent extex = (ExitExprent)source;
                    ret_1 = (AssignmentExprent)extex.GetValue().Copy();
                }
                else
                {
                    ret_1 = (AssignmentExprent)source.Copy();
                }
                FieldExprent fexpr = (FieldExprent)ret_1.GetLeft();
                if (fexpr.IsStatic())
                {
                    ret_1.ReplaceExprent(ret_1.GetRight(), invexpr.GetLstParameters()[0]);
                }
                else
                {
                    ret_1.ReplaceExprent(ret_1.GetRight(), invexpr.GetLstParameters()[1]);
                    fexpr.ReplaceExprent(fexpr.GetInstance(), invexpr.GetLstParameters()[0]);
                }
                // do not use copied bytecodes
                ret_1.GetLeft().bytecode  = null;
                ret_1.GetRight().bytecode = null;
                retexprent = ret_1;
                break;
            }

            case 4:
            {
                retexprent = ReplaceFunction(invexpr, source);
                break;
            }

            case 3:
            {
                if (source.type == Exprent.Exprent_Exit)
                {
                    source = ((ExitExprent)source).GetValue();
                }
                InvocationExprent invret = (InvocationExprent)source.Copy();
                int index_1 = 0;
                if (!invret.IsStatic())
                {
                    invret.ReplaceExprent(invret.GetInstance(), invexpr.GetLstParameters()[0]);
                    index_1 = 1;
                }
                for (int i = 0; i < invret.GetLstParameters().Count; i++)
                {
                    invret.ReplaceExprent(invret.GetLstParameters()[i], invexpr.GetLstParameters()[i
                                                                                                   + index_1]);
                }
                retexprent = invret;
                break;
            }
            }
            if (retexprent != null)
            {
                // preserve original bytecodes
                retexprent.bytecode = null;
                retexprent.AddBytecodeOffsets(invexpr.bytecode);
                // hide synthetic access method
                bool hide = true;
                if (node.type == ClassesProcessor.ClassNode.Class_Root || (node.access & ICodeConstants
                                                                           .Acc_Static) != 0)
                {
                    StructMethod mt = methsource.methodStruct;
                    if (!mt.IsSynthetic())
                    {
                        hide = false;
                    }
                }
                if (hide)
                {
                    node.GetWrapper().GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(invexpr.GetName
                                                                                               (), invexpr.GetStringDescriptor()));
                }
            }
            return(retexprent);
        }
示例#13
0
        private void SetNewVarIndices(VarTypeProcessor typeProcessor, DirectGraph graph,
                                      VarVersionsProcessor previousVersionsProcessor)
        {
            Dictionary <VarVersionPair, VarType> mapExprentMaxTypes = typeProcessor.GetMapExprentMaxTypes
                                                                          ();
            Dictionary <VarVersionPair, VarType> mapExprentMinTypes = typeProcessor.GetMapExprentMinTypes
                                                                          ();
            Dictionary <VarVersionPair, int> mapFinalVars = typeProcessor.GetMapFinalVars();
            CounterContainer counters = DecompilerContext.GetCounterContainer();
            Dictionary <VarVersionPair, int> mapVarPaar = new Dictionary <VarVersionPair, int>
                                                              ();
            Dictionary <int, int> mapOriginalVarIndices = new Dictionary <int, int>();

            // map var-version pairs on new var indexes
            foreach (VarVersionPair pair in new List <VarVersionPair>(mapExprentMinTypes.Keys))
            {
                if (pair.version >= 0)
                {
                    int newIndex = pair.version == 1 ? pair.var : counters.GetCounterAndIncrement(CounterContainer
                                                                                                  .Var_Counter);
                    VarVersionPair newVar = new VarVersionPair(newIndex, 0);
                    Sharpen.Collections.Put(mapExprentMinTypes, newVar, mapExprentMinTypes.GetOrNull(
                                                pair));
                    Sharpen.Collections.Put(mapExprentMaxTypes, newVar, mapExprentMaxTypes.GetOrNull(
                                                pair));
                    if (mapFinalVars.ContainsKey(pair))
                    {
                        Sharpen.Collections.Put(mapFinalVars, newVar, Sharpen.Collections.Remove(mapFinalVars
                                                                                                 , pair));
                    }
                    Sharpen.Collections.Put(mapVarPaar, pair, newIndex);
                    Sharpen.Collections.Put(mapOriginalVarIndices, newIndex, pair.var);
                }
            }
            // set new vars
            graph.IterateExprents((Exprent exprent) => {
                List <Exprent> lst = exprent.GetAllExprents(true);
                lst.Add(exprent);
                foreach (Exprent expr in lst)
                {
                    if (expr.type == Exprent.Exprent_Var)
                    {
                        VarExprent newVar = (VarExprent)expr;
                        int?newVarIndex   = mapVarPaar.GetOrNullable(new VarVersionPair(newVar));
                        if (newVarIndex != null)
                        {
                            newVar.SetIndex(newVarIndex.Value);
                            newVar.SetVersion(0);
                        }
                    }
                    else if (expr.type == Exprent.Exprent_Const)
                    {
                        VarType maxType = mapExprentMaxTypes.GetOrNull(new VarVersionPair(expr.id, -1));
                        if (maxType != null && maxType.Equals(VarType.Vartype_Char))
                        {
                            ((ConstExprent)expr).SetConstType(maxType);
                        }
                    }
                }
                return(0);
            }
                                  );
            if (previousVersionsProcessor != null)
            {
                Dictionary <int, int> oldIndices = previousVersionsProcessor.GetMapOriginalVarIndices
                                                       ();
                this.mapOriginalVarIndices = new Dictionary <int, int>(mapOriginalVarIndices.Count
                                                                       );
                foreach (KeyValuePair <int, int> entry in mapOriginalVarIndices)
                {
                    int value    = entry.Value;
                    int?oldValue = oldIndices.GetOrNullable(value);
                    value = oldValue != null ? oldValue.Value : value;
                    Sharpen.Collections.Put(this.mapOriginalVarIndices, entry.Key, value);
                }
            }
            else
            {
                this.mapOriginalVarIndices = mapOriginalVarIndices;
            }
        }
示例#14
0
        public virtual void Init()
        {
            DecompilerContext.SetProperty(DecompilerContext.Current_Class, classStruct);
            DecompilerContext.SetProperty(DecompilerContext.Current_Class_Wrapper, this);
            DecompilerContext.GetLogger().StartClass(classStruct.qualifiedName);
            int maxSec = System.Convert.ToInt32(DecompilerContext.GetProperty(IFernflowerPreferences
                                                                              .Max_Processing_Method).ToString());
            bool testMode = DecompilerContext.GetOption(IFernflowerPreferences.Unit_Test_Mode
                                                        );

            foreach (StructMethod mt in classStruct.GetMethods())
            {
                DecompilerContext.GetLogger().StartMethod(mt.GetName() + " " + mt.GetDescriptor()
                                                          );
                MethodDescriptor md      = MethodDescriptor.ParseDescriptor(mt.GetDescriptor());
                VarProcessor     varProc = new VarProcessor(mt, md);
                DecompilerContext.StartMethod(varProc);
                VarNamesCollector vc      = varProc.GetVarNamesCollector();
                CounterContainer  counter = DecompilerContext.GetCounterContainer();
                RootStatement     root    = null;
                bool isError = false;
                try
                {
                    if (mt.ContainsCode())
                    {
                        if (maxSec == 0 || testMode)
                        {
                            root = MethodProcessorRunnable.CodeToJava(mt, md, varProc);
                        }
                        else
                        {
                            MethodProcessorRunnable mtProc = new MethodProcessorRunnable(mt, md, varProc, DecompilerContext
                                                                                         .GetCurrentContext());
                            Thread mtThread = new Thread(o => mtProc.Run())
                            {
                                Name = "Java decompiler"
                            };
                            long stopAt = Runtime.CurrentTimeMillis() + maxSec * 1000L;
                            mtThread.Start();
                            while (!mtProc.IsFinished())
                            {
                                try
                                {
                                    lock (mtProc.Lock)
                                    {
                                        Thread.Sleep(200);
                                    }
                                }
                                catch (Exception e)
                                {
                                    KillThread(mtThread);
                                    throw;
                                }
                                if (Runtime.CurrentTimeMillis() >= stopAt)
                                {
                                    string message = "Processing time limit exceeded for method " + mt.GetName() + ", execution interrupted.";
                                    DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Error
                                                                               );
                                    KillThread(mtThread);
                                    isError = true;
                                    break;
                                }
                            }
                            if (!isError)
                            {
                                root = mtProc.GetResult();
                            }
                        }
                    }
                    else
                    {
                        bool thisVar    = !mt.HasModifier(ICodeConstants.Acc_Static);
                        int  paramCount = 0;
                        if (thisVar)
                        {
                            Sharpen.Collections.Put(varProc.GetThisVars(), new VarVersionPair(0, 0), classStruct
                                                    .qualifiedName);
                            paramCount = 1;
                        }
                        paramCount += [email protected];
                        int varIndex = 0;
                        for (int i = 0; i < paramCount; i++)
                        {
                            varProc.SetVarName(new VarVersionPair(varIndex, 0), vc.GetFreeName(varIndex));
                            if (thisVar)
                            {
                                if (i == 0)
                                {
                                    varIndex++;
                                }
                                else
                                {
                                    varIndex += md.@params[i - 1].stackSize;
                                }
                            }
                            else
                            {
                                varIndex += md.@params[i].stackSize;
                            }
                        }
                    }
                }
                catch (Exception t)
                {
                    string message = "Method " + mt.GetName() + " " + mt.GetDescriptor() + " couldn't be decompiled.";
                    DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Warn
                                                               , t);
                    isError = true;
                }
                MethodWrapper methodWrapper = new MethodWrapper(root, varProc, mt, counter);
                methodWrapper.decompiledWithErrors = isError;
                methods.AddWithKey(methodWrapper, InterpreterUtil.MakeUniqueKey(mt.GetName(), mt.
                                                                                GetDescriptor()));
                if (!isError)
                {
                    // rename vars so that no one has the same name as a field
                    VarNamesCollector namesCollector = new VarNamesCollector();
                    classStruct.GetFields().ForEach((StructField f) => namesCollector.AddName(f.GetName
                                                                                                  ()));
                    varProc.RefreshVarNames(namesCollector);
                    // if debug information present and should be used
                    if (DecompilerContext.GetOption(IFernflowerPreferences.Use_Debug_Var_Names))
                    {
                        StructLocalVariableTableAttribute attr = mt.GetLocalVariableAttr();
                        if (attr != null)
                        {
                            // only param names here
                            varProc.SetDebugVarNames(attr.GetMapParamNames());
                            // the rest is here
                            methodWrapper.GetOrBuildGraph().IterateExprents((Exprent exprent) => {
                                List <Exprent> lst = exprent.GetAllExprents(true);
                                lst.Add(exprent);
                                lst.Where(e => e.type == Exprent.Exprent_Var).ToList().ForEach((Exprent
                                                                                                e) => {
                                    VarExprent varExprent = (VarExprent)e;
                                    string name           = varExprent.GetDebugName(mt);
                                    if (name != null)
                                    {
                                        varProc.SetVarName(varExprent.GetVarVersionPair(), name);
                                    }
                                }
                                                                                               );
                                return(0);
                            }
                                                                            );
                        }
                    }
                }
                DecompilerContext.GetLogger().EndMethod();
            }
            DecompilerContext.GetLogger().EndClass();
        }
示例#15
0
        private static bool BuildIff(Statement stat, SSAConstructorSparseEx ssa)
        {
            if (stat.type == Statement.Type_If && stat.GetExprents() == null)
            {
                IfStatement   statement          = (IfStatement)stat;
                Exprent       ifHeadExpr         = statement.GetHeadexprent();
                HashSet <int> ifHeadExprBytecode = (ifHeadExpr == null ? null : ifHeadExpr.bytecode
                                                    );
                if (statement.iftype == IfStatement.Iftype_Ifelse)
                {
                    Statement ifStatement   = statement.GetIfstat();
                    Statement elseStatement = statement.GetElsestat();
                    if (ifStatement.GetExprents() != null && ifStatement.GetExprents().Count == 1 &&
                        elseStatement.GetExprents() != null && elseStatement.GetExprents().Count == 1 &&
                        ifStatement.GetAllSuccessorEdges().Count == 1 && elseStatement.GetAllSuccessorEdges
                            ().Count == 1 && ifStatement.GetAllSuccessorEdges()[0].GetDestination() == elseStatement
                        .GetAllSuccessorEdges()[0].GetDestination())
                    {
                        Exprent ifExpr   = ifStatement.GetExprents()[0];
                        Exprent elseExpr = elseStatement.GetExprents()[0];
                        if (ifExpr.type == Exprent.Exprent_Assignment && elseExpr.type == Exprent.Exprent_Assignment)
                        {
                            AssignmentExprent ifAssign   = (AssignmentExprent)ifExpr;
                            AssignmentExprent elseAssign = (AssignmentExprent)elseExpr;
                            if (ifAssign.GetLeft().type == Exprent.Exprent_Var && elseAssign.GetLeft().type ==
                                Exprent.Exprent_Var)
                            {
                                VarExprent ifVar   = (VarExprent)ifAssign.GetLeft();
                                VarExprent elseVar = (VarExprent)elseAssign.GetLeft();
                                if (ifVar.GetIndex() == elseVar.GetIndex() && ifVar.IsStack())
                                {
                                    // ifVar.getIndex() >= VarExprent.STACK_BASE) {
                                    bool found = false;
                                    foreach (KeyValuePair <VarVersionPair, FastSparseSetFactory <int> .FastSparseSet <int> > ent
                                             in ssa.GetPhi())
                                    {
                                        if (ent.Key.var == ifVar.GetIndex())
                                        {
                                            if (ent.Value.Contains(ifVar.GetVersion()) && ent.Value.Contains(elseVar.GetVersion
                                                                                                                 ()))
                                            {
                                                found = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (found)
                                    {
                                        List <Exprent> data     = new List <Exprent>(statement.GetFirst().GetExprents());
                                        List <Exprent> operands = Sharpen.Arrays.AsList(statement.GetHeadexprent().GetCondition
                                                                                            (), ifAssign.GetRight(), elseAssign.GetRight());
                                        data.Add(new AssignmentExprent(ifVar, new FunctionExprent(FunctionExprent.Function_Iif
                                                                                                  , operands, ifHeadExprBytecode), ifHeadExprBytecode));
                                        statement.SetExprents(data);
                                        if ((statement.GetAllSuccessorEdges().Count == 0))
                                        {
                                            StatEdge ifEdge = ifStatement.GetAllSuccessorEdges()[0];
                                            StatEdge edge   = new StatEdge(ifEdge.GetType(), statement, ifEdge.GetDestination()
                                                                           );
                                            statement.AddSuccessor(edge);
                                            if (ifEdge.closure != null)
                                            {
                                                ifEdge.closure.AddLabeledEdge(edge);
                                            }
                                        }
                                        SequenceHelper.DestroyAndFlattenStatement(statement);
                                        return(true);
                                    }
                                }
                            }
                        }
                        else if (ifExpr.type == Exprent.Exprent_Exit && elseExpr.type == Exprent.Exprent_Exit)
                        {
                            ExitExprent ifExit   = (ExitExprent)ifExpr;
                            ExitExprent elseExit = (ExitExprent)elseExpr;
                            if (ifExit.GetExitType() == elseExit.GetExitType() && ifExit.GetValue() != null &&
                                elseExit.GetValue() != null && ifExit.GetExitType() == ExitExprent.Exit_Return)
                            {
                                // throw is dangerous, because of implicit casting to a common superclass
                                // e.g. throws IOException and throw true?new RuntimeException():new IOException(); won't work
                                if (ifExit.GetExitType() == ExitExprent.Exit_Throw && !ifExit.GetValue().GetExprType
                                        ().Equals(elseExit.GetValue().GetExprType()))
                                {
                                    // note: getExprType unreliable at this point!
                                    return(false);
                                }
                                // avoid flattening to 'iff' if any of the branches is an 'iff' already
                                if (IsIff(ifExit.GetValue()) || IsIff(elseExit.GetValue()))
                                {
                                    return(false);
                                }
                                List <Exprent> data = new List <Exprent>(statement.GetFirst().GetExprents());
                                data.Add(new ExitExprent(ifExit.GetExitType(), new FunctionExprent(FunctionExprent
                                                                                                   .Function_Iif, Sharpen.Arrays.AsList(statement.GetHeadexprent().GetCondition(),
                                                                                                                                        ifExit.GetValue(), elseExit.GetValue()), ifHeadExprBytecode), ifExit.GetRetType(
                                                             ), ifHeadExprBytecode));
                                statement.SetExprents(data);
                                StatEdge  retEdge = ifStatement.GetAllSuccessorEdges()[0];
                                Statement closure = retEdge.closure == statement?statement.GetParent() : retEdge
                                                        .closure;

                                statement.AddSuccessor(new StatEdge(StatEdge.Type_Break, statement, retEdge.GetDestination
                                                                        (), closure));
                                SequenceHelper.DestroyAndFlattenStatement(statement);
                                return(true);
                            }
                        }
                    }
                }
            }
            return(false);
        }
示例#16
0
        public virtual void SetVarDefinitions()
        {
            VarNamesCollector vc = varproc.GetVarNamesCollector();

            foreach (KeyValuePair <int, Statement> en in mapVarDefStatements)
            {
                Statement stat  = en.Value;
                int       index = en.Key;
                if (implDefVars.Contains(index))
                {
                    // already implicitly defined
                    continue;
                }
                varproc.SetVarName(new VarVersionPair(index, 0), vc.GetFreeName(index));
                // special case for
                if (stat.type == Statement.Type_Do)
                {
                    DoStatement dstat = (DoStatement)stat;
                    if (dstat.GetLooptype() == DoStatement.Loop_For)
                    {
                        if (dstat.GetInitExprent() != null && SetDefinition(dstat.GetInitExprent(), index
                                                                            ))
                        {
                            continue;
                        }
                        else
                        {
                            List <Exprent> lstSpecial = Sharpen.Arrays.AsList(dstat.GetConditionExprent(), dstat
                                                                              .GetIncExprent());
                            foreach (VarExprent var in GetAllVars(lstSpecial))
                            {
                                if (var.GetIndex() == index)
                                {
                                    stat = stat.GetParent();
                                    break;
                                }
                            }
                        }
                    }
                }
                Statement      first = FindFirstBlock(stat, index);
                List <Exprent> lst;
                if (first == null)
                {
                    lst = stat.GetVarDefinitions();
                }
                else if (first.GetExprents() == null)
                {
                    lst = first.GetVarDefinitions();
                }
                else
                {
                    lst = first.GetExprents();
                }
                bool defset = false;
                // search for the first assignment to var [index]
                int addindex = 0;
                foreach (Exprent expr in lst)
                {
                    if (SetDefinition(expr, index))
                    {
                        defset = true;
                        break;
                    }
                    else
                    {
                        bool foundvar = false;
                        foreach (Exprent exp in expr.GetAllExprents(true))
                        {
                            if (exp.type == Exprent.Exprent_Var && ((VarExprent)exp).GetIndex() == index)
                            {
                                foundvar = true;
                                break;
                            }
                        }
                        if (foundvar)
                        {
                            break;
                        }
                    }
                    addindex++;
                }
                if (!defset)
                {
                    VarExprent var = new VarExprent(index, varproc.GetVarType(new VarVersionPair(index
                                                                                                 , 0)), varproc);
                    var.SetDefinition(true);
                    lst.Add(addindex, var);
                }
            }
        }
示例#17
0
 public VarVersionPair(VarExprent var)
 {
     this.var     = var.GetIndex();
     this.version = var.GetVersion();
 }
        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);
                    }
                }
            }
        }
示例#19
0
 public virtual void SetMonitor(VarExprent monitor)
 {
     this.monitor = monitor;
 }
示例#20
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);
                }
            }
        }
示例#21
0
        private static int IsArrayInitializer(List <Exprent> list, int index)
        {
            Exprent current = list[index];

            if (current.type == Exprent.Exprent_Assignment)
            {
                AssignmentExprent @as = (AssignmentExprent)current;
                if (@as.GetRight().type == Exprent.Exprent_New && @as.GetLeft().type == Exprent.Exprent_Var)
                {
                    NewExprent newExpr = (NewExprent)@as.GetRight();
                    if (newExpr.GetExprType().arrayDim > 0 && newExpr.GetLstDims().Count == 1 && (newExpr
                                                                                                  .GetLstArrayElements().Count == 0) && newExpr.GetLstDims()[0].type == Exprent.Exprent_Const)
                    {
                        int size = (int)((ConstExprent)newExpr.GetLstDims()[0]).GetValue();
                        if (size == 0)
                        {
                            return(0);
                        }
                        VarExprent arrVar = (VarExprent)@as.GetLeft();
                        Dictionary <int, Exprent> mapInit = new Dictionary <int, Exprent>();
                        int i = 1;
                        while (index + i < list.Count && i <= size)
                        {
                            bool    found = false;
                            Exprent expr  = list[index + i];
                            if (expr.type == Exprent.Exprent_Assignment)
                            {
                                AssignmentExprent aas = (AssignmentExprent)expr;
                                if (aas.GetLeft().type == Exprent.Exprent_Array)
                                {
                                    ArrayExprent arrExpr = (ArrayExprent)aas.GetLeft();
                                    if (arrExpr.GetArray().type == Exprent.Exprent_Var && arrVar.Equals(arrExpr.GetArray
                                                                                                            ()) && arrExpr.GetIndex().type == Exprent.Exprent_Const)
                                    {
                                        // TODO: check for a number type. Failure extremely improbable, but nevertheless...
                                        int constValue = ((ConstExprent)arrExpr.GetIndex()).GetIntValue();
                                        if (constValue < size && !mapInit.ContainsKey(constValue))
                                        {
                                            if (!aas.GetRight().ContainsExprent(arrVar))
                                            {
                                                Sharpen.Collections.Put(mapInit, constValue, aas.GetRight());
                                                found = true;
                                            }
                                        }
                                    }
                                }
                            }
                            if (!found)
                            {
                                break;
                            }
                            i++;
                        }
                        double fraction = ((double)mapInit.Count) / size;
                        if ((arrVar.IsStack() && fraction > 0) || (size <= 7 && fraction >= 0.3) || (size
                                                                                                     > 7 && fraction >= 0.7))
                        {
                            List <Exprent> lstRet     = new List <Exprent>();
                            VarType        arrayType  = newExpr.GetNewType().DecreaseArrayDim();
                            ConstExprent   defaultVal = ExprProcessor.GetDefaultArrayValue(arrayType);
                            for (int j = 0; j < size; j++)
                            {
                                lstRet.Add(defaultVal.Copy());
                            }
                            int dims = newExpr.GetNewType().arrayDim;
                            foreach (KeyValuePair <int, Exprent> ent in mapInit)
                            {
                                Exprent tempExpr = ent.Value;
                                lstRet[ent.Key] = tempExpr;
                                if (tempExpr.type == Exprent.Exprent_New)
                                {
                                    NewExprent tempNewExpr = (NewExprent)tempExpr;
                                    if (dims > 1 && !(tempNewExpr.GetLstArrayElements().Count == 0))
                                    {
                                        tempNewExpr.SetDirectArrayInit(true);
                                    }
                                }
                            }
                            newExpr.SetLstArrayElements(lstRet);
                            return(mapInit.Count);
                        }
                    }
                }
            }
            return(0);
        }