internal GOp ToGOp(int off, CCNodeOpcode node) { GOp g = code[off].ToGOp(node); g.addr = off; return(g); }
internal CCNodeOpcode GetNode(int off) { CCNodeOpcode node = cfi.GetNode(off); if (node == null) { node = new CCNodeOpcode(cfi, off); cfi.SetNode(off, node); } return(node); }
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); }
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)); }
internal override GOp ToGOp(CCNodeOpcode node) { throw new Exception("special interpreter-only opcode encountered"); }
internal override void BuildTree(CCNodeOpcode node) { throw new Exception("special interpreter-only opcode encountered"); }
internal override GOp ToGOp(CCNodeOpcode node) { return(node.ToGOpConst(v)); }
internal void BuildTree(int off, CCNodeOpcode node) { code[off].BuildTree(node); }
internal override GOp ToGOp(CCNodeOpcode node) { return(node.ToGOpJumpUncond(JumpDisp)); }
internal void SetNode(int addr, CCNodeOpcode node) { nodes[addr] = node; }
internal override void BuildTree(CCNodeOpcode node) { node.DoRefLocal(num); }
internal override GOp ToGOp(CCNodeOpcode node) { return(node.ToGOpPutLocalIndexed(off, len, ltype)); }
internal override void BuildTree(CCNodeOpcode node) { node.DoPutLocalIndexed(off, len, ltype); }
/* * Specialize the opcode for code generation. */ internal abstract GOp ToGOp(CCNodeOpcode node);
internal override GOp ToGOp(CCNodeOpcode node) { return(node.ToGOpPutLocal(num, ltype)); }
internal override void BuildTree(CCNodeOpcode node) { node.DoPutLocal(num, ltype); }
/* * Perform tree-building on the provided node. */ internal abstract void BuildTree(CCNodeOpcode node);
internal override void BuildTree(CCNodeOpcode node) { node.DoCall(fname); }
internal override GOp ToGOp(CCNodeOpcode node) { return(node.ToGOpCall(fname)); }
internal override GOp ToGOp(CCNodeOpcode node) { return(node.ToGOpRefLocal(num)); }
internal void BuildTree(int addr, CCNodeOpcode node) { fi.BuildTree(addr, node); }
internal void PropagateBranch(int disp, CCStack nstack, CCLocals nlocals) { branch = Propagate(addr + 1 + disp, branch, nstack, nlocals); }
internal override void BuildTree(CCNodeOpcode node) { node.DoRefLocalIndexed(off, len); }
internal override void BuildTree(CCNodeOpcode node) { node.DoJumpUncond(JumpDisp); }
internal void PropagateNext(CCStack nstack, CCLocals nlocals) { next = Propagate(addr + 1, next, nstack, nlocals); }
internal override GOp ToGOp(CCNodeOpcode node) { return(node.ToGOpRefLocalIndexed(off, len)); }
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); } } }
internal override void BuildTree(CCNodeOpcode node) { node.DoRet(); }
internal override GOp ToGOp(CCNodeOpcode node) { return(node.ToGOpRet()); }
internal override void BuildTree(CCNodeOpcode node) { node.DoConst(v); }