示例#1
0
 internal CCNodeOpcode Propagate(int addr2, CCNodeOpcode node,
                                 CCStack nstack, CCLocals nlocals)
 {
     if (node == null)
     {
         node = GetNode(addr2);
     }
     node.MergeStack(nstack);
     node.MergeLocals(nlocals);
     return(node);
 }
示例#2
0
    internal static CCLocals Merge(CCLocals l1, CCLocals l2)
    {
        string   err;
        CCLocals ccl = MergeNF(l1, l2, out err);

        if (ccl == null)
        {
            throw new Exception(err);
        }
        return(ccl);
    }
示例#3
0
    internal CCLocals Set(int index, CCTypeSet cts)
    {
        CCTypeSet octs = locals[index];

        if (!cts.IsSubsetOf(octs))
        {
            CCLocals r = new CCLocals(locals.Length);
            Array.Copy(locals, 0, r.locals, 0, locals.Length);
            r.locals[index] = cts;
            return(r);
        }
        else
        {
            return(this);
        }
    }
示例#4
0
 internal void MergeLocals(CCLocals locals2)
 {
     if (Locals == null)
     {
         Locals = locals2;
         MarkUpdate();
     }
     else
     {
         CCLocals nlocals = CCLocals.Merge(Locals, locals2);
         if (Locals != nlocals)
         {
             Locals = nlocals;
             MarkUpdate();
         }
     }
 }
示例#5
0
    internal static CCNodeEntry EnterFunction(FunctionInterpreted fi,
                                              CCStack stack, CCNodeEntry parent, CCNode next)
    {
        if (Compiler.PrintFunctions != null)
        {
            fi.Print(Compiler.PrintFunctions, 1);
        }

        CCLocals locals            = new CCLocals(fi.numLocalFieldsCoalesced);
        CCFunctionInterpreted cfi  = new CCFunctionInterpreted(fi, next);
        CCNodeEntry           node = new CCNodeEntry(parent, cfi);

        cfi.SetNode(0, node);
        node.MergeStack(stack);
        node.MergeLocals(locals);

        /*
         * All instances allocated locally by this function must
         * have instantiable types.
         */
        foreach (XType xt in fi.localEmbedTypes)
        {
            xt.Close();
        }

        /*
         * Infinite recursion detection: if the same function is
         * already present several times in the ancestry,
         * complains. (TODO: make the threshold configurable)
         */
        int rc = 0;

        for (CCNodeEntry e = parent; e != null; e = e.parent)
        {
            if (e.cfi.fi == fi)
            {
                if (++rc >= 5)
                {
                    throw new Exception(string.Format("possible infinite recursion on function {0}", fi.DebugName));
                }
            }
        }

        return(node);
    }
示例#6
0
 internal void PropagateBranch(int disp,
                               CCStack nstack, CCLocals nlocals)
 {
     branch = Propagate(addr + 1 + disp, branch, nstack, nlocals);
 }
示例#7
0
 internal void PropagateBranch(int disp, CCLocals nlocals)
 {
     PropagateBranch(disp, Stack, nlocals);
 }
示例#8
0
 internal void PropagateNext(CCStack nstack, CCLocals nlocals)
 {
     next = Propagate(addr + 1, next, nstack, nlocals);
 }
示例#9
0
 internal void PropagateNext(CCLocals nlocals)
 {
     PropagateNext(Stack, nlocals);
 }
示例#10
0
    internal static CCLocals MergeNF(
        CCLocals l1, CCLocals l2, out string err)
    {
        err = null;
        if (object.ReferenceEquals(l1, l2))
        {
            return(l1);
        }
        int n = l1.locals.Length;

        if (n != l2.locals.Length)
        {
            err = string.Format("internal error: mismatch on number of locals ({0} / {1})", n, l2.locals.Length);
            return(null);
        }

        /*
         * Merge entries one by one. The destination is lazily
         * updated to avoid allocation when not needed.
         */
        bool r1ok = true, r2ok = true;

        CCTypeSet[] nlocals = null;
        for (int i = 0; i < n; i++)
        {
            CCTypeSet cts1 = l1.locals[i];
            CCTypeSet cts2 = l2.locals[i];
            if (cts1.Equals(cts2))
            {
                if (nlocals != null)
                {
                    nlocals[i] = cts1;
                }
            }
            else if (cts1.IsSubsetOf(cts2))
            {
                r1ok = false;
                if (r2ok)
                {
                    continue;
                }
                if (nlocals != null)
                {
                    nlocals[i] = cts2;
                }
            }
            else if (cts2.IsSubsetOf(cts1))
            {
                r2ok = false;
                if (r1ok)
                {
                    continue;
                }
                if (nlocals != null)
                {
                    nlocals[i] = cts1;
                }
            }
            else
            {
                if (nlocals == null)
                {
                    r1ok    = false;
                    r2ok    = false;
                    nlocals = new CCTypeSet[n];
                    Array.Copy(l1.locals, 0, nlocals, 0, i);
                }
                CCTypeSet cts = CCTypeSet.MergeNF(
                    cts1, cts2, out err);
                if (cts == null)
                {
                    return(null);
                }
                nlocals[i] = cts;
            }
        }

        if (r1ok)
        {
            return(l1);
        }
        if (r2ok)
        {
            return(l2);
        }
        return(new CCLocals(nlocals));
    }