Exemple #1
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);
 }
Exemple #2
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 });
        }
Exemple #3
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 #4
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);
        }
Exemple #5
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);
        }