Пример #1
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);
    }
Пример #2
0
    /*
     * Build the function if possible; this is for an automatic
     * builder. If the function is empty, or there are outstanding
     * control-flow structures, then this method returns null.
     *
     * When a non-null function is returned, this builder is
     * automatically cleared and made ready to accumulate new
     * instructions.
     */
    internal Function BuildAuto()
    {
        if (cfPtr != -1 || code.Count == 0)
        {
            return(null);
        }
        if (jumpToLast || code[code.Count - 1].MayFallThrough)
        {
            Ret();
        }
        Function f = new FunctionInterpreted(debugName,
                                             0, null, 0, IZERO, code.ToArray());

        code.Clear();
        numLocalFields = 0;
        fieldMapping.Clear();
        jumpToLast = true;
        return(f);
    }
Пример #3
0
 internal CCFunctionInterpreted(FunctionInterpreted fi, CCNode next)
 {
     this.fi   = fi;
     nodes     = new CCNodeOpcode[fi.CodeLength];
     this.next = next;
 }
Пример #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);
            }
        }
    }