private bool RemapParameterToLoadStack(APC pc, ref Parameter param, out bool isLoadResult, out int loadStackOffset, out bool isOld, out APC lookupPC) { if (pc.SubroutineContext == null) { isLoadResult = false; loadStackOffset = 0; isOld = false; lookupPC = pc; return(false); } if (pc.Block.Subroutine.IsRequires) { isLoadResult = false; isOld = false; lookupPC = pc; for (LispList <Edge <CFGBlock, EdgeTag> > list = pc.SubroutineContext; list != null; list = list.Tail) { EdgeTag edgeTag = list.Head.Tag; if (edgeTag == EdgeTag.Entry) { param = RemapParameter(param, list.Head.From, pc.Block); loadStackOffset = 0; return(false); } if (edgeTag.Is(EdgeTag.BeforeMask)) { int stackDepth = this.parent.LocalStackDepth(pc); loadStackOffset = this.parent.MetaDataProvider.ParameterStackIndex(param) + stackDepth; return(true); } } throw new InvalidOperationException(); } if (pc.Block.Subroutine.IsEnsuresOrOldValue) { isOld = true; for (LispList <Edge <CFGBlock, EdgeTag> > ctx = pc.SubroutineContext; ctx != null; ctx = ctx.Tail) { EdgeTag tag = ctx.Head.Tag; if (tag == EdgeTag.Exit) { param = RemapParameter(param, ctx.Head.From, pc.Block); isLoadResult = false; loadStackOffset = 0; lookupPC = pc; return(false); } if (tag == EdgeTag.AfterCall) { loadStackOffset = this.parent.MetaDataProvider.ParameterStackIndex(param); isLoadResult = false; lookupPC = new APC(ctx.Head.From, 0, ctx.Tail); return(true); } if (tag == EdgeTag.AfterNewObj) { if (this.parent.MetaDataProvider.ParameterIndex(param) == 0) { loadStackOffset = this.parent.LocalStackDepth(pc); isLoadResult = true; lookupPC = pc; isOld = false; return(false); } loadStackOffset = this.parent.MetaDataProvider.ParameterIndex(param); isLoadResult = false; lookupPC = new APC(ctx.Head.From, 0, ctx.Tail); return(true); } if (tag == EdgeTag.OldManifest) { param = RemapParameter(param, ctx.Tail.Head.From, pc.Block); isOld = false; isLoadResult = false; loadStackOffset = 0; lookupPC = pc; return(false); } } throw new InvalidOperationException(); } if (pc.Block.Subroutine.IsInvariant) { for (LispList <Edge <CFGBlock, EdgeTag> > list = pc.SubroutineContext; list != null; list = list.Tail) { EdgeTag tag = list.Head.Tag; if (tag == EdgeTag.Entry || tag == EdgeTag.Exit) { Method method; if (pc.TryGetContainingMethod(out method)) { param = this.parent.MetaDataProvider.This(method); isLoadResult = false; loadStackOffset = 0; isOld = tag == EdgeTag.Exit; lookupPC = pc; return(false); } isLoadResult = false; loadStackOffset = 0; isOld = false; lookupPC = pc; return(false); } if (tag == EdgeTag.AfterCall) { Method calledMethod; bool isNewObj; bool isVirtual; list.Head.From.IsMethodCallBlock(out calledMethod, out isNewObj, out isVirtual); int count = this.parent.MetaDataProvider.Parameters(calledMethod).Count; loadStackOffset = count; isLoadResult = false; isOld = true; lookupPC = new APC(list.Head.From, 0, list.Tail); return(true); } if (tag == EdgeTag.AfterNewObj) { isLoadResult = true; loadStackOffset = this.parent.LocalStackDepth(pc); isOld = false; lookupPC = pc; return(false); } if (tag.Is(EdgeTag.BeforeMask)) { throw new InvalidOperationException("this should never happen"); } } throw new InvalidOperationException("this should never happen"); } isLoadResult = false; loadStackOffset = 0; isOld = false; lookupPC = pc; return(false); }