Example #1
0
    internal GOp ToGOp(int off, CCNodeOpcode node)
    {
        GOp g = code[off].ToGOp(node);

        g.addr = off;
        return(g);
    }
Example #2
0
    /*
     * Merge the provided GFunctionInterpreted into this one. If the
     * merge is not possible, this instance is not modified, and
     * false is returned.
     */
    bool Merge(GFunctionInterpreted gf)
    {
        /*
         * Normally, Merge() is not invoked for a distinct function,
         * but an extra test here is cheap.
         */
        if (fi != gf.fi)
        {
            return(false);
        }

        /*
         * We first test the frames, but do not complete their
         * merge until the operation is confirmed.
         */
        if (!frame.CanMerge(gf.frame))
        {
            return(false);
        }

        /*
         * Since the two GFunctionInterpreted relate to the same
         * interpreted function, all opcodes are naturally
         * compatible, except possibly the Call opcodes, which
         * must be checked.
         */
        GOp[] spec3 = new GOp[spec.Length];
        for (int i = 0; i < spec.Length; i++)
        {
            GOp g1 = spec[i];
            GOp g2 = gf.spec[i];
            if ((g1 is GOpCall) && (g2 is GOpCall))
            {
                GOpCall g3 = ((GOpCall)g1).Merge((GOpCall)g2);
                if (g3 == null)
                {
                    return(false);
                }
                spec3[i] = g3;
            }
            else
            {
                if (g1 is GOpZero)
                {
                    spec3[i] = g2;
                }
                else
                {
                    spec3[i] = g1;
                }
            }
        }
        spec = spec3;
        AdjustJumps();

        /*
         * Merge the frames.
         */
        frame.Merge(gf.frame);
        return(true);
    }
Example #3
0
 internal void Add(GOp g)
 {
     code.Add(g);
 }
Example #4
0
    GFunctionInterpreted(CCFunctionInterpreted cfi)
        : base(cfi.fi)
    {
        this.fi = cfi.fi;

        /*
         * Specialize opcodes. In this step:
         *
         *  - For each source opcode, we create an appropriate GOp
         *    instance. Type specialization for local fields
         *    happens here.
         *
         *  - Unreachable opcodes (whose entry stack is null) yield
         *    a GOpZero.
         */
        List <GOp> specOps = new List <GOp>();
        int        srcLen  = cfi.nodes.Length;

        for (int i = 0; i < srcLen; i++)
        {
            GOp g = cfi.ToGOp(i);
            if (g == null)
            {
                throw new Exception("NYI (GOp)");
            }
            specOps.Add(g);
        }
        spec = specOps.ToArray();

        AdjustJumps();

        /*
         * Compute local frame elements:
         *
         *  - For local fields, only putlocal and putlocalindexed
         *    matter; we check that each local has a single storage
         *    type.
         *
         *  - For local instances, we use reflocal and
         *    reflocalindexed.
         */
        frame = new GOpFrame(this);
        for (int i = 0; i < spec.Length; i++)
        {
            var pl = spec[i] as GOpPutLocal;
            if (pl != null)
            {
                frame.AddLocalVariable(pl.off, pl.ltype);
            }
            var pli = spec[i] as GOpPutLocalIndexed;
            if (pli != null)
            {
                frame.AddLocalVariableArray(
                    pli.off, pli.len, pli.ltype);
            }
            var rl = spec[i] as GOpRefLocal;
            if (rl != null)
            {
                frame.AddLocalInstance(rl.off, rl.ltype);
            }
            var rli = spec[i] as GOpRefLocalIndexed;
            if (rli != null)
            {
                frame.AddLocalInstanceArray(
                    rli.off, rli.len, rli.ltype);
            }
        }
    }