internal void CheckAllocNode(CCNodeEntry node) { for (StackElt e = tos; e != null; e = e.upper) { e.cts.CheckAllocNode(node); } }
internal override CCNode Enter(CCStack stack, CCNodeEntry parent, CCNode next) { CCNode node = new CCNodeNative(this, tParams, ctsRets, next); node.MergeStack(stack); return(node); }
internal CCType(XType xType, CCNodeEntry allocationNode, int variant, bool constant) { this.xType = xType; this.allocationNode = allocationNode; this.variant = variant; this.constant = constant; }
CCType() { this.xType = null; this.allocationNode = null; this.variant = 0; this.constant = false; this.ofType = null; }
internal bool IsDescendentOf(CCNodeEntry other) { if (other == null) { return(true); } for (CCNodeEntry n = this; n != null; n = n.parent) { if (object.ReferenceEquals(n, other)) { return(true); } } return(false); }
internal void CheckAllocNode(CCNodeEntry node) { foreach (CCType ct in types) { CCNodeEntry e = ct.allocationNode; if (e == null) { continue; } if (e.IsDescendentOf(node)) { throw new Exception(string.Format("reference to local instance of type {0} may escape function node {1}", ct, node)); } } }
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); }
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(); } } } }
internal override CCNode Enter(CCStack stack, CCNodeEntry parent, CCNode next) { return(CCNodeEntry.EnterFunction(this, stack, parent, next)); }
internal virtual CCNode Enter(CCStack stack, CCNodeEntry parent, CCNode next) { throw new Exception(string.Format("native function {0} cannot be compiled", DebugName)); }
internal CCNodeEntry(CCNodeEntry parent, CCFunctionInterpreted cfi) : base(cfi, 0) { this.parent = parent; }