예제 #1
0
    internal override void Walk()
    {
        CCTypeSet cts = Stack.Peek(0);

        Stack.Peek(1).CheckInt();
        CCTypeSet mv = null;

        foreach (CCType tos in cts)
        {
            tos.xType.CheckExtends(owner);
            CCTypeSet sv = new CCTypeSet(tos.GetEmbedded(eltType));
            if (mv == null)
            {
                mv = sv;
            }
            else
            {
                mv = CCTypeSet.Merge(mv, sv);
            }
        }
        if (mv != null)
        {
            next.MergeStack(Stack.Pop(2).Push(mv));
        }
    }
예제 #2
0
    internal override void Walk()
    {
        CCTypeSet cts = Stack.Peek(0);

        Stack.Peek(1).CheckInt();
        CCTypeSet mv = null;

        foreach (CCType tos in cts)
        {
            tos.xType.CheckExtends(owner);
            CCType tos2 = tos.GetEmbedded(
                owner.GetArrayElementType());
            CCTypeSet vt = new CCTypeSet(tos2);
            if (vt != null)
            {
                if (mv == null)
                {
                    mv = vt;
                }
                else
                {
                    mv = CCTypeSet.Merge(mv, vt);
                }
            }
        }
        if (mv != null)
        {
            next.MergeStack(Stack.Pop(2).Push(mv));
        }
    }
예제 #3
0
    public override bool Equals(object other)
    {
        if (object.ReferenceEquals(this, other))
        {
            return(true);
        }
        CCTypeSet ss = other as CCTypeSet;

        if (ss == null)
        {
            return(false);
        }
        if (GetHashCode() != ss.GetHashCode())
        {
            return(false);
        }
        int n = types.Count;

        if (n != ss.types.Count)
        {
            return(false);
        }
        SortedSet <CCType> .Enumerator e = ss.types.GetEnumerator();
        foreach (CCType t in types)
        {
            if (!e.MoveNext() || !t.Equals(e.Current))
            {
                return(false);
            }
        }
        return(true);
    }
예제 #4
0
    internal override void Walk()
    {
        CCTypeSet cts1 = Stack.Peek(1);
        CCTypeSet cts2 = Stack.Peek(0);

        next.MergeStack(Stack.Pop(2).Push(cts2).Push(cts1));
    }
예제 #5
0
    internal override void Walk()
    {
        CCTypeSet cts = Stack.Peek(0);

        Stack.Peek(1).CheckInt();
        CCTypeSet mv = null;

        foreach (CCType tos in cts)
        {
            tos.xType.CheckExtends(owner);
            CCType    tos2 = tos.GetEmbedded(owner);
            CCStruct  cs   = CCStruct.Lookup(tos2);
            CCTypeSet vt   = cs.Get(owner.fieldInverseMapping[off]);
            if (vt != null)
            {
                if (mv == null)
                {
                    mv = vt;
                }
                else
                {
                    mv = CCTypeSet.Merge(mv, vt);
                }
            }
        }
        if (mv != null)
        {
            next.MergeStack(Stack.Pop(2).Push(mv));
        }
    }
예제 #6
0
    internal CCTypeSet Get(int index)
    {
        CCTypeSet cts = locals[index];

        if (cts.MayBeNull)
        {
            throw new Exception("potentially reading uninitialized local variable");
        }
        return(cts);
    }
예제 #7
0
    internal override void Walk()
    {
        CCTypeSet cts = Stack.Peek(0);

        foreach (CCType tos in cts)
        {
            tos.xType.CheckExtends(owner);
        }
        next.MergeStack(Stack.Pop().Push(CCTypeSet.BOOL));
    }
예제 #8
0
    /*
     * Merge two type sets into an aggregate set. If one of the sets
     * is a subset of the other, then that other subset is returned;
     * if the two sets are equal, then the ss1 instance is returned.
     *
     * This method traps on any attempt at merging incompatible type
     * sets (ones with basic types).
     */
    internal static CCTypeSet Merge(CCTypeSet ss1, CCTypeSet ss2)
    {
        string    err;
        CCTypeSet cts = MergeNF(ss1, ss2, out err);

        if (cts == null)
        {
            throw new Exception(err);
        }
        return(cts);
    }
예제 #9
0
    internal void DoPutLocal(int num, XType ltype)
    {
        int       index = cfi.fi.fieldInverseMapping[num];
        CCTypeSet cts   = Stack.Peek(0);

        if (ltype != null)
        {
            cts.CheckSubTypeOf(ltype);
        }
        PropagateNext(Stack.Pop(), Locals.Set(index, cts));
    }
예제 #10
0
    internal override void Walk()
    {
        CCTypeSet cts = Stack.Peek(0);

        Stack.Peek(1).CheckInt();
        Stack.Peek(2).CheckInt();
        foreach (CCType tos in cts)
        {
            tos.xType.CheckExtends(owner);
        }
        next.MergeStack(Stack.Pop(3));
    }
예제 #11
0
    internal CCTypeSet[] GetTopElements(int depth)
    {
        CCTypeSet[] ctss = new CCTypeSet[depth];
        StackElt    e    = tos;

        for (int j = 0; j < depth; j++)
        {
            ctss[depth - 1 - j] = e.cts;
            e = e.upper;
        }
        return(ctss);
    }
예제 #12
0
    internal void DoPutLocalIndexed(int off, int len, XType ltype)
    {
        int index = cfi.fi.fieldInverseMapping[off];

        Stack.Peek(0).CheckInt();
        CCTypeSet cts = Stack.Peek(1);

        if (ltype != null)
        {
            cts.CheckSubTypeOf(ltype);
        }
        PropagateNext(Stack.Pop().Pop(), Locals.Set(index, cts));
    }
예제 #13
0
 internal StackElt(StackElt upper, CCTypeSet cts)
 {
     this.upper = upper;
     this.cts   = cts;
     if (upper == null)
     {
         rank = 0;
     }
     else
     {
         rank = upper.rank + 1;
     }
 }
예제 #14
0
    internal FunctionNative(string debugName,
                            XType[] tParams, XType[] tRets)
        : base(debugName)
    {
        this.tParams = tParams;
        int n = tRets.Length;

        ctsRets = new CCTypeSet[n];
        for (int i = 0; i < n; i++)
        {
            ctsRets[i] = new CCTypeSet(new CCType(tRets[i]));
        }
    }
예제 #15
0
    /*
     * Merge two type sets into an aggregate set. If one of the sets
     * is a subset of the other, then that other subset is returned;
     * if the two sets are equal, then the ss1 instance is returned.
     *
     * If merging is not possible (incompatible basic types), then
     * null is returned, and err is set to an appropriate error
     * message. Otherwise, the merged type is returned, and err is
     * set to null.
     */
    internal static CCTypeSet MergeNF(CCTypeSet ss1, CCTypeSet ss2,
                                      out string err)
    {
        err = null;
        if (ss2.IsSubsetOf(ss1))
        {
            return(ss1);
        }
        if (ss1.IsSubsetOf(ss2))
        {
            return(ss2);
        }

        /*
         * Handling of restricted types relies on the following
         * features:
         *
         *  - A CCTypeSet that contains a restricted type can
         *    only contain that restricted type, none other.
         *
         *  - Restricted types cannot have allocation nodes,
         *    variants, or be std::type.
         *
         *  - The tests with IsSubsetOf() above have already
         *    ruled out the case of two identical restricted types.
         */
        if (ss1.types.Count == 1 && ss2.types.Count == 1)
        {
            CCType ct1 = ss1.types.Min;
            CCType ct2 = ss2.types.Min;
            if (ct1.xType.IsRestricted || ct2.xType.IsRestricted)
            {
                err = string.Format("forbidden type merging between {0} and {1}", ct1, ct2);
                return(null);
            }
        }

        CCTypeSet ss3 = new CCTypeSet();

        foreach (CCType t in ss1.types)
        {
            ss3.types.Add(t);
            ss3.xTypes.Add(t.xType);
        }
        foreach (CCType t in ss2.types)
        {
            ss3.types.Add(t);
            ss3.xTypes.Add(t.xType);
        }
        return(ss3);
    }
예제 #16
0
    internal override void Walk()
    {
        CCTypeSet cts = Stack.Peek(0);
        CCTypeSet sv  = Stack.Peek(1);

        foreach (CCType tos in cts)
        {
            tos.xType.CheckExtends(owner);
            CCType   tos2 = tos.GetEmbedded(owner);
            CCStruct cs   = CCStruct.Lookup(tos2);
            cs.Merge(owner.fieldInverseMapping[off], sv);
        }
        next.MergeStack(Stack.Pop(2));
    }
예제 #17
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);
    }
예제 #18
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);
        }
    }
예제 #19
0
    internal override void Walk()
    {
        CCTypeSet cts = Stack.Peek(0);

        Stack.Peek(1).CheckInt();
        CCTypeSet sv = Stack.Peek(2);

        foreach (CCType tos in cts)
        {
            tos.xType.CheckExtends(owner);
            CCType   tos2 = tos.GetEmbedded(owner);
            CCStruct cs   = CCStruct.Lookup(tos2);
            cs.Merge(0, sv);
        }
        next.MergeStack(Stack.Pop(3));
    }
예제 #20
0
    CCStruct(CCType owner)
    {
        owner.xType.Close();
        this.owner = owner;
        XType[] fti  = owner.xType.GetFieldInitTypes();
        int     size = fti.Length;

        fields   = new CCTypeSet[size];
        regNodes = new SortedSet <CCNode> [size];
        for (int i = 0; i < fti.Length; i++)
        {
            if (fti[i] == null)
            {
                continue;
            }
            fields[i] = new CCTypeSet(new CCType(fti[i]));
        }
    }
예제 #21
0
    internal void Merge(int index, CCTypeSet cts)
    {
        /*
         * Escape analysis: we must not write in a field of
         * a structure a value that pertains to a descendent
         * allocator node.
         */
        CCNodeEntry oa = owner.allocationNode;

        if (oa != null)
        {
            foreach (CCType ct in cts)
            {
                if (oa.IsDescendentOf(ct.allocationNode))
                {
                    continue;
                }
                throw new Exception(string.Format("reference to local instance of type {0} may escape through writing in field of type {1}", ct, owner));
            }
        }

        CCTypeSet octs = fields[index];
        CCTypeSet ncts;

        if (octs == null)
        {
            ncts = cts;
        }
        else
        {
            ncts = CCTypeSet.Merge(octs, cts);
        }
        if (!object.ReferenceEquals(octs, ncts))
        {
            SortedSet <CCNode> rn = regNodes[index];
            if (rn != null)
            {
                foreach (CCNode node in rn)
                {
                    node.MarkUpdate();
                }
            }
        }
    }
예제 #22
0
 internal bool IsSubsetOf(CCTypeSet ss)
 {
     if (object.ReferenceEquals(this, ss))
     {
         return(true);
     }
     if (types.Count > ss.types.Count)
     {
         return(false);
     }
     foreach (CCType t in types)
     {
         if (!ss.types.Contains(t))
         {
             return(false);
         }
     }
     return(true);
 }
예제 #23
0
    internal override void Walk()
    {
        /*
         * For all possible types of the TOS:
         *
         *  1. Verify that the accessor is usable on that type.
         *
         *  2. Obtain the right CCStruct, and get the types
         *     that may be thus obtained. The "right CCStruct"
         *     is the one for the CCType that matches the
         *     element type, and the allocation node and variant
         *     of the type found on the stack.
         *
         *  3. Merge all resulting types.
         */
        CCTypeSet cts = Stack.Peek(0);
        CCTypeSet mv  = null;

        foreach (CCType tos in cts)
        {
            tos.xType.CheckExtends(owner);
            CCType    tos2 = tos.GetEmbedded(owner);
            CCStruct  cs   = CCStruct.Lookup(tos2);
            CCTypeSet vt   = cs.Get(owner.fieldInverseMapping[off]);
            if (vt != null)
            {
                if (mv == null)
                {
                    mv = vt;
                }
                else
                {
                    mv = CCTypeSet.Merge(mv, vt);
                }
            }
        }
        if (mv != null)
        {
            next.MergeStack(Stack.Pop().Push(mv));
        }
    }
예제 #24
0
    /*
     * Check that all values in this set are for std::type with
     * a specific type target (i.e. "types of types").
     */
    internal CCTypeSet ToNewInstance()
    {
        CCTypeSet r = new CCTypeSet();

        foreach (CCType ct in types)
        {
            if (ct.xType != XType.XTYPE)
            {
                throw new Exception(string.Format("instance allocation expects a std::type instance, got {0} instead", ct.xType.Name));
            }
            if (ct.ofType == null)
            {
                throw new Exception("instance allocation needs a specific type target, but got a generic std::type");
            }
            if (ct.ofType == XType.XTYPE)
            {
                throw new Exception("cannot dynamically allocate new std::type instances");
            }
            r.types.Add(new CCType(ct.ofType, null, 0, false));
            r.xTypes.Add(ct.ofType);
        }
        return(r);
    }
예제 #25
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));
    }
예제 #26
0
 internal CCStack Push(CCTypeSet cts)
 {
     return(new CCStack(new StackElt(tos, cts)));
 }
예제 #27
0
    internal override void Walk()
    {
        CCTypeSet cts = Stack.Peek(0);

        next.MergeStack(Stack.Pop().Push(cts.ToNewInstance()));
    }
예제 #28
0
    internal override void Walk()
    {
        CCTypeSet cts = Stack.Peek(1);

        next.MergeStack(Stack.Push(cts));
    }
예제 #29
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));
    }