X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fcodegen.cs;h=429c3b9d3b0d1f23db2fb66109e2d5ab93f6ca03;hb=bd52e33266aee6ffbddf313a99db7fffc497a095;hp=7ab8f746f5309cba33a02f1c96e3a47c457e2c6a;hpb=27b3636cef92e3a8cb154d91e3e7abb9fafea0af;p=mono.git diff --git a/mcs/mcs/codegen.cs b/mcs/mcs/codegen.cs index 7ab8f746f53..429c3b9d3b0 100644 --- a/mcs/mcs/codegen.cs +++ b/mcs/mcs/codegen.cs @@ -262,9 +262,7 @@ namespace Mono.CSharp if (sf.IsHiddenLocation (loc)) return false; -#if NET_4_0 methodSymbols.MarkSequencePoint (ig.ILOffset, sf.SourceFileEntry, loc.Row, loc.Column, false); -#endif return true; } @@ -324,9 +322,7 @@ namespace Mono.CSharp if ((flags & Options.OmitDebugInfo) != 0) return; -#if NET_4_0 methodSymbols.StartBlock (CodeBlockEntry.Type.Lexical, ig.ILOffset); -#endif } public void BeginCompilerScope () @@ -334,9 +330,7 @@ namespace Mono.CSharp if ((flags & Options.OmitDebugInfo) != 0) return; -#if NET_4_0 methodSymbols.StartBlock (CodeBlockEntry.Type.CompilerGenerated, ig.ILOffset); -#endif } public void EndExceptionBlock () @@ -349,9 +343,7 @@ namespace Mono.CSharp if ((flags & Options.OmitDebugInfo) != 0) return; -#if NET_4_0 methodSymbols.EndBlock (ig.ILOffset); -#endif } public void CloseConditionalAccess (TypeSpec type) @@ -549,13 +541,10 @@ namespace Mono.CSharp switch (type.BuiltinType) { case BuiltinTypeSpec.Type.Bool: // - // Workaround MSIL limitation. Load bool element as single bit, - // bool array can actually store any byte value + // bool array can actually store any byte value in underlying byte slot + // and C# spec does not specify any normalization rule, except the result + // is undefined // - ig.Emit (OpCodes.Ldelem_U1); - ig.Emit (OpCodes.Ldc_I4_0); - ig.Emit (OpCodes.Cgt_Un); - break; case BuiltinTypeSpec.Type.Byte: ig.Emit (OpCodes.Ldelem_U1); break; @@ -771,12 +760,8 @@ namespace Mono.CSharp ig.Emit (OpCodes.Ldind_U1); break; case BuiltinTypeSpec.Type.SByte: - ig.Emit (OpCodes.Ldind_I1); - break; case BuiltinTypeSpec.Type.Bool: ig.Emit (OpCodes.Ldind_I1); - ig.Emit (OpCodes.Ldc_I4_0); - ig.Emit (OpCodes.Cgt_Un); break; case BuiltinTypeSpec.Type.ULong: case BuiltinTypeSpec.Type.Long: @@ -903,6 +888,9 @@ namespace Mono.CSharp ig.Emit (OpCodes.Stobj, type.GetMetaInfo ()); break; + case MemberKind.PointerType: + ig.Emit (OpCodes.Stind_I); + break; default: ig.Emit (OpCodes.Stind_Ref); break; @@ -1066,7 +1054,7 @@ namespace Mono.CSharp var ie = new InstanceEmitter (instance_copy, IsAddressCall (instance_copy, call_op, method.DeclaringType)); if (Arguments == null) { - ie.EmitLoad (ec); + ie.EmitLoad (ec, true); } } else if (!InstanceExpressionOnStack) { var ie = new InstanceEmitter (InstanceExpression, IsAddressCall (InstanceExpression, call_op, method.DeclaringType)); @@ -1228,7 +1216,7 @@ namespace Mono.CSharp instance_address = instance as LocalTemporary; if (instance_address == null) { - EmitLoad (ec); + EmitLoad (ec, false); ec.Emit (OpCodes.Dup); ec.EmitLoadFromPtr (instance.Type); @@ -1236,11 +1224,8 @@ namespace Mono.CSharp } else { instance.Emit (ec); } - - if (instance.Type.Kind == MemberKind.TypeParameter) - ec.Emit (OpCodes.Box, instance.Type); } else { - EmitLoad (ec); + EmitLoad (ec, !conditionalAccess); if (conditionalAccess) { conditional_access_dup = !IsInexpensiveLoad (); @@ -1250,6 +1235,9 @@ namespace Mono.CSharp } if (conditionalAccess) { + if (instance.Type.Kind == MemberKind.TypeParameter) + ec.Emit (OpCodes.Box, instance.Type); + ec.Emit (OpCodes.Brtrue_S, NullOperatorLabel); if (conditional_access_dup) @@ -1282,7 +1270,7 @@ namespace Mono.CSharp } } - public void EmitLoad (EmitContext ec) + public void EmitLoad (EmitContext ec, bool boxInstance) { var instance_type = instance.Type; @@ -1313,8 +1301,9 @@ namespace Mono.CSharp instance.Emit (ec); // Only to make verifier happy - if (RequiresBoxing ()) + if (boxInstance && RequiresBoxing ()) { ec.Emit (OpCodes.Box, instance_type); + } } public TypeSpec GetStackType (EmitContext ec) @@ -1342,6 +1331,9 @@ namespace Mono.CSharp return false; } + // + // Returns true for cheap race-free load, where we can avoid using dup + // bool IsInexpensiveLoad () { if (instance is Constant) @@ -1351,8 +1343,10 @@ namespace Mono.CSharp return false; var vr = instance as VariableReference; - if (vr != null) - return !vr.IsRef; + if (vr != null) { + // Load from captured local would be racy without dup + return !vr.IsRef && !vr.IsHoisted; + } if (instance is LocalTemporary) return true;