diff --git a/RunSharpShared/CodeGen.Statements.cs b/RunSharpShared/CodeGen.Statements.cs index f344839..c69c8da 100644 --- a/RunSharpShared/CodeGen.Statements.cs +++ b/RunSharpShared/CodeGen.Statements.cs @@ -237,8 +237,10 @@ public void InvokeBase(params Operand[] args) void BeforeStatement() { - if (!_reachable) - throw new InvalidOperationException(Properties.Messages.ErrCodeNotReachable); + if (!IsReachable) + { + throw new InvalidOperationException(Properties.Messages.ErrCodeNotReachable + ", \r\n set unreachable at \r\n" + _unreachableFrom); + } #if !PHONE8 if (_cg != null && !_chainCalled && !_cg.Type.TypeBuilder.IsValueType) InvokeBase(); @@ -474,7 +476,7 @@ public void Break() if (brkBlock != null) { IL.Emit(useLeave ? OpCodes.Leave : OpCodes.Br, brkBlock.GetBreakTarget()); - _reachable = false; + IsReachable = false; return; } } @@ -505,7 +507,7 @@ public void Continue() if (cntBlock != null) { IL.Emit(useLeave ? OpCodes.Leave : OpCodes.Br, cntBlock.GetContinueTarget()); - _reachable = false; + IsReachable = false; return; } } @@ -538,7 +540,7 @@ public void Return() IL.Emit(OpCodes.Leave, _retLabel); } - _reachable = false; + IsReachable = false; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "'Operand' required as type to use provided implicit conversions")] @@ -569,7 +571,7 @@ public void Return(Operand value) IL.Emit(OpCodes.Stloc, _retVar); IL.Emit(OpCodes.Leave, _retLabel); } - _reachable = false; + IsReachable = false; } public void Throw() @@ -577,7 +579,7 @@ public void Throw() BeforeStatement(); IL.Emit(OpCodes.Rethrow); - _reachable = false; + IsReachable = false; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "'Operand' required as type to use provided implicit conversions")] @@ -587,7 +589,7 @@ public void Throw(Operand exception) EmitGetHelper(exception, TypeMapper.MapType(typeof(Exception)), false); IL.Emit(OpCodes.Throw); - _reachable = false; + IsReachable = false; } public void For(IStatement init, Operand test, IStatement iterator) @@ -835,7 +837,7 @@ protected override void BeginImpl() protected override void EndImpl() { G.IL.MarkLabel(_lbSkip); - G._reachable = true; + G.IsReachable = true; } } @@ -852,7 +854,7 @@ public ElseBlock(IfBlock ifBlk) protected override void BeginImpl() { - if (_canSkip = G._reachable) + if (_canSkip = G.IsReachable) { _lbSkip = G.IL.DefineLabel(); G.IL.Emit(OpCodes.Br, _lbSkip); @@ -865,7 +867,7 @@ protected override void EndImpl() if (_canSkip) { G.IL.MarkLabel(_lbSkip); - G._reachable = true; + G.IsReachable = true; } } } @@ -934,7 +936,7 @@ protected override void EndImpl() if (lbFalse.IsLabelExist) G.IL.MarkLabel(lbFalse.Value); - G._reachable = true; + G.IsReachable = true; } public Label GetBreakTarget() @@ -1009,7 +1011,7 @@ protected override void EndImpl() if (_endUsed) G.IL.MarkLabel(_lbEnd); - G._reachable = true; + G.IsReachable = true; } public Label GetBreakTarget() @@ -1048,24 +1050,24 @@ public void BeginCatchAll() { EndScope(); - if (G._reachable) + if (G.IsReachable) _endReachable = true; G.IL.BeginCatchBlock(_typeMapper.MapType(typeof(object))); G.IL.Emit(OpCodes.Pop); - G._reachable = true; + G.IsReachable = true; } public Operand BeginCatch(Type t) { EndScope(); - if (G._reachable) + if (G.IsReachable) _endReachable = true; G.IL.BeginCatchBlock(t); LocalBuilder lb = G.IL.DeclareLocal(t); G.IL.Emit(OpCodes.Stloc, lb); - G._reachable = true; + G.IsReachable = true; return new _Local(G, lb); } @@ -1075,7 +1077,7 @@ public void BeginFault() EndScope(); G.IL.BeginFaultBlock(); - G._reachable = true; + G.IsReachable = true; IsFinally = true; } @@ -1084,14 +1086,14 @@ public void BeginFinally() EndScope(); G.IL.BeginFinallyBlock(); - G._reachable = true; + G.IsReachable = true; IsFinally = true; } protected override void EndImpl() { G.IL.EndExceptionBlock(); - G._reachable = _endReachable; + G.IsReachable = _endReachable; } public bool IsFinally { get; set; } @@ -1178,7 +1180,7 @@ protected override void BeginImpl() _exp = G.IL.DeclareLocal(_govType); G.IL.Emit(OpCodes.Stloc, _exp); G.IL.Emit(OpCodes.Br, _lbDecision); - G._reachable = false; + G.IsReachable = false; } public void Case(IConvertible value) @@ -1196,7 +1198,7 @@ public void Case(IConvertible value) if (duplicate) throw new InvalidOperationException(Properties.Messages.ErrDuplicateCase); - if (G._reachable) + if (G.IsReachable) G.IL.Emit(OpCodes.Br, _lbEnd); EndScope(); @@ -1211,7 +1213,7 @@ public void Case(IConvertible value) { _cases[val] = lb; } - G._reachable = true; + G.IsReachable = true; } static int Diff(IConvertible val1, IConvertible val2) @@ -1276,7 +1278,7 @@ void EmitValue(IConvertible val) protected override void EndImpl() { - if (G._reachable) + if (G.IsReachable) { G.IL.Emit(OpCodes.Br, _lbEnd); _endReachable = true; @@ -1334,7 +1336,7 @@ protected override void EndImpl() if (_lbDefault != _lbEnd) G.IL.Emit(OpCodes.Br, _lbDefault); G.IL.MarkLabel(_lbEnd); - G._reachable = _endReachable; + G.IsReachable = _endReachable; } public Label GetBreakTarget() diff --git a/RunSharpShared/CodeGen.cs b/RunSharpShared/CodeGen.cs index 96ef6a6..8985288 100644 --- a/RunSharpShared/CodeGen.cs +++ b/RunSharpShared/CodeGen.cs @@ -72,8 +72,33 @@ public partial class CodeGen : ICodeGenContext #endif bool _chainCalled; - bool _reachable = true; - bool _hasRetVar, _hasRetLabel; + bool _isReachable = true; + StackTrace _unreachableFrom; + + public bool IsReachable + { + get + { + return _isReachable; + } + private set + { + _isReachable = value; + _unreachableFrom = value ? null : +#if !SILVERLIGHT + new StackTrace(1, true); +#else + new StackTrace(); +#endif + } + } + + public void ForceResetUnreachableState() + { + _isReachable = true; + } + + bool _hasRetVar, _hasRetLabel; LocalBuilder _retVar; Label _retLabel; readonly Stack _blocks = new Stack(); @@ -243,14 +268,14 @@ void EnsureReturnVariable() _hasRetVar = true; } - public bool IsCompleted => _blocks.Count == 0 && (!_isOwner || !_reachable) && _hasRetVar == _hasRetLabel; + public bool IsCompleted => _blocks.Count == 0 && (!_isOwner || !IsReachable) && _hasRetVar == _hasRetLabel; internal void Complete() { if (_blocks.Count > 0) throw new InvalidOperationException(Properties.Messages.ErrOpenBlocksRemaining); - if (_reachable) + if (IsReachable) { if (HasReturnValue) throw new InvalidOperationException(string.Format(null, Properties.Messages.ErrMethodMustReturnValue, Context)); @@ -567,7 +592,7 @@ public void Goto(Label label) IL.Emit(OpCodes.Br, label); } - #region Context explicit delegation +#region Context explicit delegation MemberInfo IMemberInfo.Member { get { return Context.Member; } } @@ -616,7 +641,7 @@ ILGenerator ICodeGenContext.GetILGenerator() bool ICodeGenContext.SupportsScopes { get { return Context.SupportsScopes; } } - #endregion +#endregion } } diff --git a/RunSharpShared/TypeInfo.cs b/RunSharpShared/TypeInfo.cs index 1b17589..679f522 100644 --- a/RunSharpShared/TypeInfo.cs +++ b/RunSharpShared/TypeInfo.cs @@ -26,6 +26,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using System; using System.Collections.Generic; +using System.Diagnostics; using System.Text; #if FEAT_IKVM using IKVM.Reflection; @@ -415,6 +416,10 @@ private IEnumerable SearchableTypes(Type t) { yield return @interface; } + foreach (Type baseType in SearchBaseTypes(TypeMapper.MapType(typeof(object)))) + { + yield return baseType; + } } else { @@ -487,7 +492,9 @@ public ApplicableFunction FindMethod(Type t, string name, Operand[] args, bool @ if (af != null) return af; } - +#if DEBUG + Debugger.Break(); +#endif var sb = new StringBuilder(); sb.Append(" " + t.Name + "." + name);