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

        g.addr = off;
        return(g);
    }
Beispiel #2
0
    internal CCNodeOpcode GetNode(int off)
    {
        CCNodeOpcode node = cfi.GetNode(off);

        if (node == null)
        {
            node = new CCNodeOpcode(cfi, off);
            cfi.SetNode(off, node);
        }
        return(node);
    }
Beispiel #3
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);
 }
Beispiel #4
0
    internal GOp ToGOp(int addr)
    {
        CCNodeOpcode node = nodes[addr];

        if (node.Stack == null)
        {
            GOp g = new GOpZero();
            g.addr = addr;
            return(g);
        }
        return(fi.ToGOp(addr, node));
    }
Beispiel #5
0
 internal override GOp ToGOp(CCNodeOpcode node)
 {
     throw new Exception("special interpreter-only opcode encountered");
 }
Beispiel #6
0
 internal override void BuildTree(CCNodeOpcode node)
 {
     throw new Exception("special interpreter-only opcode encountered");
 }
Beispiel #7
0
 internal override GOp ToGOp(CCNodeOpcode node)
 {
     return(node.ToGOpConst(v));
 }
Beispiel #8
0
 internal void BuildTree(int off, CCNodeOpcode node)
 {
     code[off].BuildTree(node);
 }
Beispiel #9
0
 internal override GOp ToGOp(CCNodeOpcode node)
 {
     return(node.ToGOpJumpUncond(JumpDisp));
 }
Beispiel #10
0
 internal void SetNode(int addr, CCNodeOpcode node)
 {
     nodes[addr] = node;
 }
Beispiel #11
0
 internal override void BuildTree(CCNodeOpcode node)
 {
     node.DoRefLocal(num);
 }
Beispiel #12
0
 internal override GOp ToGOp(CCNodeOpcode node)
 {
     return(node.ToGOpPutLocalIndexed(off, len, ltype));
 }
Beispiel #13
0
 internal override void BuildTree(CCNodeOpcode node)
 {
     node.DoPutLocalIndexed(off, len, ltype);
 }
Beispiel #14
0
 /*
  * Specialize the opcode for code generation.
  */
 internal abstract GOp ToGOp(CCNodeOpcode node);
Beispiel #15
0
 internal override GOp ToGOp(CCNodeOpcode node)
 {
     return(node.ToGOpPutLocal(num, ltype));
 }
Beispiel #16
0
 internal override void BuildTree(CCNodeOpcode node)
 {
     node.DoPutLocal(num, ltype);
 }
Beispiel #17
0
 /*
  * Perform tree-building on the provided node.
  */
 internal abstract void BuildTree(CCNodeOpcode node);
Beispiel #18
0
 internal override void BuildTree(CCNodeOpcode node)
 {
     node.DoCall(fname);
 }
Beispiel #19
0
 internal override GOp ToGOp(CCNodeOpcode node)
 {
     return(node.ToGOpCall(fname));
 }
Beispiel #20
0
 internal override GOp ToGOp(CCNodeOpcode node)
 {
     return(node.ToGOpRefLocal(num));
 }
Beispiel #21
0
 internal void BuildTree(int addr, CCNodeOpcode node)
 {
     fi.BuildTree(addr, node);
 }
Beispiel #22
0
 internal void PropagateBranch(int disp,
                               CCStack nstack, CCLocals nlocals)
 {
     branch = Propagate(addr + 1 + disp, branch, nstack, nlocals);
 }
Beispiel #23
0
 internal override void BuildTree(CCNodeOpcode node)
 {
     node.DoRefLocalIndexed(off, len);
 }
Beispiel #24
0
 internal override void BuildTree(CCNodeOpcode node)
 {
     node.DoJumpUncond(JumpDisp);
 }
Beispiel #25
0
 internal void PropagateNext(CCStack nstack, CCLocals nlocals)
 {
     next = Propagate(addr + 1, next, nstack, nlocals);
 }
Beispiel #26
0
 internal override GOp ToGOp(CCNodeOpcode node)
 {
     return(node.ToGOpRefLocalIndexed(off, len));
 }
Beispiel #27
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);
            }
        }
    }
Beispiel #28
0
 internal override void BuildTree(CCNodeOpcode node)
 {
     node.DoRet();
 }
Beispiel #29
0
 internal override GOp ToGOp(CCNodeOpcode node)
 {
     return(node.ToGOpRet());
 }
Beispiel #30
0
 internal override void BuildTree(CCNodeOpcode node)
 {
     node.DoConst(v);
 }