Exemplo n.º 1
0
    internal void DoGetLocal(int num)
    {
        int     index  = cfi.fi.fieldInverseMapping[num];
        CCStack nstack = Stack.Push(Locals.Get(index));

        PropagateNext(nstack);
    }
Exemplo n.º 2
0
    internal override void Walk()
    {
        Stack.CheckMultipleSubTypeOf(tParams);
        CCStack nstack = Stack.Pop(tParams.Length).Push(ctsRets);

        next.MergeStack(nstack);
    }
Exemplo n.º 3
0
    internal void DoGetLocalIndexed(int off, int len)
    {
        Stack.Peek(0).CheckInt();
        int     index  = cfi.fi.fieldInverseMapping[off];
        CCStack nstack = Stack.Pop().Push(Locals.Get(index));

        PropagateNext(nstack);
    }
Exemplo n.º 4
0
    internal override CCNode Enter(CCStack stack,
                                   CCNodeEntry parent, CCNode next)
    {
        CCNode node = new CCNodeNative(this, tParams, ctsRets, next);

        node.MergeStack(stack);
        return(node);
    }
Exemplo n.º 5
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);
 }
Exemplo n.º 6
0
    internal void DoJumpIf(int disp)
    {
        /*
         * Check that the top stack element is std::bool.
         * Remove it for the successor opcodes.
         */
        CCTypeSet cts = Stack.Peek(0);

        cts.CheckBool();
        CCStack nstack = Stack.Pop();

        PropagateNext(nstack);
        PropagateBranch(disp, nstack);
    }
Exemplo n.º 7
0
    static GStackElt MakeTOS(CCStack src)
    {
        if (src == null)
        {
            return(null);
        }
        GStackElt tos = null;
        GStackElt r   = null;
        int       num = 0;
        IEnumerator <CCTypeSet> iter = src.EnumerateFromTop();

        for (;;)
        {
            if (!iter.MoveNext())
            {
                break;
            }
            XTypeSet ss = new XTypeSet();
            foreach (CCType ct in iter.Current)
            {
                ss.Add(ct.xType);
            }
            if (ss.Count == 0)
            {
                throw new Exception(string.Format("internal error: no element in CCStack at depth {0}", num));
            }
            GStackElt r2 = new GStackElt(null, ss);
            if (r == null)
            {
                tos = r2;
            }
            else
            {
                r.upper = r2;
            }
            r = r2;
            num++;
        }

        /*
         * We assembled the GStack in reverse order, so all
         * ranks are wrong and we must fix them.
         */
        for (r = tos; r != null; r = r.upper)
        {
            r.rank = --num;
        }

        return(tos);
    }
Exemplo n.º 8
0
 internal void MergeStack(CCStack stack2)
 {
     if (Stack == null)
     {
         Stack = stack2;
         MarkUpdate();
     }
     else
     {
         CCStack nstack = CCStack.Merge(Stack, stack2);
         if (nstack != Stack)
         {
             Stack = nstack;
             MarkUpdate();
         }
     }
 }
Exemplo n.º 9
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);
    }
Exemplo n.º 10
0
    internal static CCNode BuildTree(Function f, params CCTypeSet[] args)
    {
        CCStack stack = new CCStack();

        foreach (CCTypeSet cts in args)
        {
            stack = stack.Push(cts);
        }
        CCNode start = f.Enter(stack, null, new CCNodeExit());

        for (;;)
        {
            int n = TO_EXPLORE.Count;
            if (n == 0)
            {
                break;
            }
            CCNode node = TO_EXPLORE[n - 1];
            TO_EXPLORE.RemoveAt(n - 1);
            node.update = false;
            node.Walk();
        }
        return(start);
    }
Exemplo n.º 11
0
 internal override CCNode Enter(CCStack stack,
                                CCNodeEntry parent, CCNode next)
 {
     return(CCNodeEntry.EnterFunction(this, stack, parent, next));
 }
Exemplo n.º 12
0
 internal void PropagateBranch(int disp, CCStack nstack)
 {
     PropagateBranch(disp, nstack, Locals);
 }
Exemplo n.º 13
0
 internal void PropagateNext(CCStack nstack, CCLocals nlocals)
 {
     next = Propagate(addr + 1, next, nstack, nlocals);
 }
Exemplo n.º 14
0
 internal void PropagateNext(CCStack nstack)
 {
     PropagateNext(nstack, Locals);
 }
Exemplo n.º 15
0
    internal static CCStack Merge(CCStack s1, CCStack s2)
    {
        if (object.ReferenceEquals(s1, s2))
        {
            return(s1);
        }
        int n1 = s1.Depth;
        int n2 = s2.Depth;

        if (n1 != n2)
        {
            throw new Exception(string.Format("stack merge depth mismatch ({0} / {1})", n1, n2));
        }

        /*
         * Find the common root (it may be null). We retain in
         * 'root' the topmost element at which the two stacks have
         * equal contents.
         */
        StackElt e1 = s1.tos, e2 = s2.tos;
        StackElt root = null;

        for (;;)
        {
            /*
             * When we have reached the same StackElt instance,
             * no further divergence may occur.
             */
            if (object.ReferenceEquals(e1, e2))
            {
                if (root == null)
                {
                    root = e1;
                }
                break;
            }
            if (e1.cts.Equals(e2.cts))
            {
                if (root == null)
                {
                    root = e1;
                }
            }
            else
            {
                root = null;
            }
            e1 = e1.upper;
            e2 = e2.upper;
        }

        int rootRank = (root == null) ? -1 : root.rank;

        /*
         * If the root has maximal rank, then the two stacks are
         * identical.
         */
        if (rootRank == n1 - 1)
        {
            return(s1);
        }

        /*
         * Everything above the root must be instantiated anew. We
         * create the instances in a top-down fashion, fixing links
         * on the way.
         */
        StackElt tos = null;
        StackElt e3  = null;

        e1 = s1.tos;
        e2 = s2.tos;
        for (int i = n1 - 1; i > rootRank; i--)
        {
            StackElt e4 = new StackElt(null,
                                       CCTypeSet.Merge(e1.cts, e2.cts));
            e4.rank = i;
            if (e3 == null)
            {
                tos = e4;
            }
            else
            {
                e3.upper = e4;
            }
            e3 = e4;
            e1 = e1.upper;
            e2 = e2.upper;
        }
        e3.upper = root;

        return(new CCStack(tos));
    }
Exemplo n.º 16
0
 internal virtual CCNode Enter(CCStack stack,
                               CCNodeEntry parent, CCNode next)
 {
     throw new Exception(string.Format("native function {0} cannot be compiled", DebugName));
 }
Exemplo n.º 17
0
 internal void PropagateBranch(int disp,
                               CCStack nstack, CCLocals nlocals)
 {
     branch = Propagate(addr + 1 + disp, branch, nstack, nlocals);
 }
Exemplo n.º 18
0
    internal void DoCall(string name)
    {
        /*
         * Make sure the next node exists. We also set its locals
         * to the current locals (the called function cannot
         * change our locals). Note that the stack is not set;
         * this will be done only when (if) one of the called
         * functions returns.
         */
        if (next == null)
        {
            next = GetNode(addr + 1);
        }
        next.MergeLocals(Locals);

        /*
         * Find all functions registered with the specified name.
         * If none is found, then we want a specific error message
         * (this is probably a typographic error in the function
         * name).
         */
        List <FunctionRegistration> r1 = Function.LookupAll(name);

        if (r1.Count == 0)
        {
            throw new Exception(string.Format("no such function: {0}", name));
        }

        /*
         * Find all functions that may match the types on the
         * stack.
         */
        List <FunctionRegistration> r2 =
            new List <FunctionRegistration>();
        int maxNum = 0;

        foreach (FunctionRegistration fr in r1)
        {
            if (Stack.MayMatch(fr.types))
            {
                r2.Add(fr);
                maxNum = Math.Max(maxNum, fr.types.Length);
            }
        }

        /*
         * For all combinations of types that may occur on the
         * stack, try to resolve the call; if any fails, then
         * report it as an error.
         * While doing so, we accumulate, for each reachable
         * function, the types that may appear on entry of
         * that function.
         */
        CCType[] combo = new CCType[maxNum];
        CCTypeSet.ComboEnumerator ce = new CCTypeSet.ComboEnumerator(
            Stack.GetTopElements(maxNum));
        XType[] xts = new XType[maxNum];
        SortedDictionary <Function, CCStack> targets =
            new SortedDictionary <Function, CCStack>();
        CCStack root  = Stack.Pop(maxNum);
        GStack  gtail = GStack.Make(root);

        calls = new List <DCall>();
        for (;;)
        {
            if (!ce.Next(combo))
            {
                break;
            }
            for (int i = 0; i < maxNum; i++)
            {
                xts[i] = combo[i].xType;
            }
            Function f      = Function.Resolve(name, r2, xts);
            CCStack  nstack = root.Push(combo);
            CCStack  ostack;
            if (targets.TryGetValue(f, out ostack))
            {
                targets[f] = CCStack.Merge(ostack, nstack);
            }
            else
            {
                targets[f] = nstack;
            }
            calls.Add(new DCall(GStack.Make(xts, gtail), f));
        }

        /*
         * We now have a complete list of reachable functions,
         * each with a corresponding entry stack; we know that
         * the call will always resolve to a single function. If
         * we are updating, we reuse the previous functions from
         * the dispatch variable if available. Note that an update
         * can only add new functions, not remove existing ones.
         */
        if (dispatch == null)
        {
            dispatch = new SortedDictionary <Function, CCNode>();
        }
        foreach (Function f in targets.Keys)
        {
            CCStack stack = targets[f];
            CCNode  onode;
            if (dispatch.TryGetValue(f, out onode))
            {
                onode.MergeStack(stack);
            }
            else
            {
                dispatch[f] = f.Enter(stack, cfi.Entry, next);
            }
        }
    }
Exemplo n.º 19
0
 internal static GStack Make(CCStack src)
 {
     return(new GStack(MakeTOS(src)));
 }