示例#1
0
 private static bool IsMonitorExit(Exprent first)
 {
     if (first.type == Exprent.Exprent_Monitor)
     {
         MonitorExprent expr = (MonitorExprent)first;
         return(expr.GetMonType() == MonitorExprent.Monitor_Exit && expr.GetValue().type ==
                Exprent.Exprent_Var && !((VarExprent)expr.GetValue()).IsStack());
     }
     return(false);
 }
示例#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 });
        }