X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fcodegen.cs;h=79dee5e3a56b419fade9e0c1bbdc2e4ac0a2c7bf;hb=394140f5a495ff5fc718249c1406735a001edf85;hp=5b6baef98c63e6d87b5bc63b9378942674b6ecfd;hpb=1cc9ff62ac0eae82c4d1def4ce9b6f6bb098ff95;p=mono.git diff --git a/mcs/mcs/codegen.cs b/mcs/mcs/codegen.cs index 5b6baef98c6..79dee5e3a56 100644 --- a/mcs/mcs/codegen.cs +++ b/mcs/mcs/codegen.cs @@ -51,16 +51,6 @@ namespace Mono.CSharp /// public LocalBuilder return_value; - /// - /// The location where return has to jump to return the - /// value - /// - public Label ReturnLabel; - - /// - /// If we already defined the ReturnLabel - /// - public bool HasReturnLabel; /// /// Current loop begin and end labels. @@ -87,15 +77,17 @@ namespace Mono.CSharp DynamicSiteClass dynamic_site_container; - TypeSpec[] stack_types; + Label? return_label; public EmitContext (IMemberContext rc, ILGenerator ig, TypeSpec return_type) { this.member_context = rc; this.ig = ig; - this.return_type = return_type; + if (rc.Module.Compiler.Settings.Checked) + flags |= Options.CheckedScope; + #if STATIC ig.__CleverExceptionBlockAssistance (); #endif @@ -127,6 +119,12 @@ namespace Mono.CSharp get { return member_context.CurrentMemberDefinition; } } + public bool HasReturnLabel { + get { + return return_label.HasValue; + } + } + public bool IsStatic { get { return member_context.IsStatic; } } @@ -165,27 +163,26 @@ namespace Mono.CSharp } } - public int StackHeight { - get { -#if STATIC - return ig.__StackHeight; -#else - throw new NotImplementedException (); -#endif - } - } - // - // Enabled when tracking stack types during emit phase + // The label where we have to jump before leaving the context // - bool TrackStackTypes { + public Label ReturnLabel { get { - return (flags & Options.AsyncBody) != 0; + return return_label.Value; } } #endregion + public void AssertEmptyStack () + { +#if STATIC + if (ig.__StackHeight != 0) + throw new InternalErrorException ("Await yields with non-empty stack in `{0}", + member_context.GetSignatureForError ()); +#endif + } + /// /// This is called immediately before emitting an IL opcode to tell the symbol /// writer to which source line this opcode belongs. @@ -256,6 +253,14 @@ namespace Mono.CSharp return dynamic_site_container; } + public Label CreateReturnLabel () + { + if (!return_label.HasValue) + return_label = DefineLabel (); + + return return_label.Value; + } + public LocalBuilder DeclareLocal (TypeSpec type, bool pinned) { if (IsAnonymousStoreyMutateRequired) @@ -288,88 +293,26 @@ namespace Mono.CSharp public void Emit (OpCode opcode) { ig.Emit (opcode); - - if (TrackStackTypes) { - switch (opcode.StackBehaviourPush) { - case StackBehaviour.Push0: - // Nothing - break; - case StackBehaviour.Pushi: - SetStackType (Module.Compiler.BuiltinTypes.Int); - break; - case StackBehaviour.Pushi8: - SetStackType (Module.Compiler.BuiltinTypes.Long); - break; - case StackBehaviour.Pushr4: - SetStackType (Module.Compiler.BuiltinTypes.Float); - break; - case StackBehaviour.Pushr8: - SetStackType (Module.Compiler.BuiltinTypes.Double); - break; - case StackBehaviour.Push1: - if (opcode.StackBehaviourPop == StackBehaviour.Pop1) { - // nothing - } else if (opcode.StackBehaviourPop == StackBehaviour.Pop1_pop1) { - // nothing - } else { - throw new NotImplementedException (opcode.Name); - } - break; - case StackBehaviour.Push1_push1: - if (opcode.StackBehaviourPop == StackBehaviour.Pop1) { - SetStackType (stack_types[StackHeight - 2]); - } else { - throw new NotImplementedException (opcode.Name); - } - break; - default: - throw new NotImplementedException (opcode.Name); - } - } } - public void Emit (OpCode opcode, LocalBuilder local, TypeSpec type) + public void Emit (OpCode opcode, LocalBuilder local) { ig.Emit (opcode, local); - - if (TrackStackTypes) { - if (opcode.StackBehaviourPush == StackBehaviour.Push0) { - // Nothing - } else if (opcode.StackBehaviourPush == StackBehaviour.Push1) { - SetStackType (type); - } else if (opcode.StackBehaviourPush == StackBehaviour.Pushi) { - SetStackType (ReferenceContainer.MakeType (Module, type)); - } else { - throw new NotImplementedException (opcode.Name); - } - } } public void Emit (OpCode opcode, string arg) { ig.Emit (opcode, arg); - - if (TrackStackTypes) { - SetStackType (Module.Compiler.BuiltinTypes.String); - } } public void Emit (OpCode opcode, double arg) { ig.Emit (opcode, arg); - - if (TrackStackTypes) { - SetStackType (Module.Compiler.BuiltinTypes.Double); - } } public void Emit (OpCode opcode, float arg) { ig.Emit (opcode, arg); - - if (TrackStackTypes) { - SetStackType (Module.Compiler.BuiltinTypes.Float); - } } public void Emit (OpCode opcode, Label label) @@ -388,29 +331,6 @@ namespace Mono.CSharp type = CurrentAnonymousMethod.Storey.Mutator.Mutate (type); ig.Emit (opcode, type.GetMetaInfo ()); - - if (TrackStackTypes) { - switch (opcode.StackBehaviourPush) { - case StackBehaviour.Push0: - // Nothing - break; - case StackBehaviour.Pushi: - SetStackType (ReferenceContainer.MakeType (Module, type)); - break; - case StackBehaviour.Push1: - SetStackType (type); - break; - default: - if (opcode == OpCodes.Box) { - SetStackType (Module.Compiler.BuiltinTypes.Object); - } else if (opcode == OpCodes.Castclass) { - SetStackType (type); - } else { - throw new NotImplementedException (opcode.Name); - } - break; - } - } } public void Emit (OpCode opcode, FieldSpec field) @@ -419,22 +339,6 @@ namespace Mono.CSharp field = field.Mutate (CurrentAnonymousMethod.Storey.Mutator); ig.Emit (opcode, field.GetMetaInfo ()); - - if (TrackStackTypes) { - switch (opcode.StackBehaviourPush) { - case StackBehaviour.Push0: - // nothing - break; - case StackBehaviour.Push1: - SetStackType (field.MemberType); - break; - case StackBehaviour.Pushi: - SetStackType (ReferenceContainer.MakeType (Module, field.MemberType)); - break; - default: - throw new NotImplementedException (); - } - } } public void Emit (OpCode opcode, MethodSpec method) @@ -446,20 +350,6 @@ namespace Mono.CSharp ig.Emit (opcode, (ConstructorInfo) method.GetMetaInfo ()); else ig.Emit (opcode, (MethodInfo) method.GetMetaInfo ()); - - if (TrackStackTypes) { - // - // Don't bother with ldftn/Ldvirtftn they can never appear on open stack - // - if (method.IsConstructor) { - if (opcode == OpCodes.Newobj) - SetStackType (method.DeclaringType); - } else { - if (method.ReturnType.Kind != MemberKind.Void) { - SetStackType (method.ReturnType); - } - } - } } // TODO: REMOVE breaks mutator @@ -488,10 +378,6 @@ namespace Mono.CSharp ig.Emit (OpCodes.Newobj, ac.GetConstructor ()); } - - if (TrackStackTypes) { - SetStackType (ac); - } } public void EmitArrayAddress (ArrayContainer ac) @@ -501,20 +387,12 @@ namespace Mono.CSharp ac = (ArrayContainer) ac.Mutate (CurrentAnonymousMethod.Storey.Mutator); ig.Emit (OpCodes.Call, ac.GetAddressMethod ()); - - if (TrackStackTypes) { - SetStackType (ReferenceContainer.MakeType (Module, ac.Element)); - } } else { var type = IsAnonymousStoreyMutateRequired ? CurrentAnonymousMethod.Storey.Mutator.Mutate (ac.Element) : ac.Element; ig.Emit (OpCodes.Ldelema, type.GetMetaInfo ()); - - if (TrackStackTypes) { - SetStackType (ReferenceContainer.MakeType (Module, type)); - } } } @@ -528,11 +406,6 @@ namespace Mono.CSharp ac = (ArrayContainer) ac.Mutate (CurrentAnonymousMethod.Storey.Mutator); ig.Emit (OpCodes.Call, ac.GetGetMethod ()); - - if (TrackStackTypes) { - SetStackType (ac.Element); - } - return; } @@ -599,10 +472,6 @@ namespace Mono.CSharp } break; } - - if (TrackStackTypes) { - SetStackType (type); - } } // @@ -669,10 +538,6 @@ namespace Mono.CSharp public void EmitInt (int i) { EmitIntConstant (i); - - if (TrackStackTypes) { - SetStackType (Module.Compiler.BuiltinTypes.Int); - } } void EmitIntConstant (int i) @@ -738,10 +603,6 @@ namespace Mono.CSharp } else { ig.Emit (OpCodes.Ldc_I8, l); } - - if (TrackStackTypes) { - SetStackType (Module.Compiler.BuiltinTypes.Long); - } } // @@ -804,20 +665,11 @@ namespace Mono.CSharp } break; } - - if (TrackStackTypes) { - // TODO: test for async when `this' can be used inside structs - SetStackType (type); - } } public void EmitNull () { ig.Emit (OpCodes.Ldnull); - - if (TrackStackTypes) { - SetStackType (Module.Compiler.BuiltinTypes.Object); - } } public void EmitArgumentAddress (int pos) @@ -829,13 +681,6 @@ namespace Mono.CSharp ig.Emit (OpCodes.Ldarga, pos); else ig.Emit (OpCodes.Ldarga_S, (byte) pos); - - if (TrackStackTypes) { - // - // Should never be reached, all parameters are hoisted into class - // - throw new NotImplementedException (); - } } public void EmitArgumentLoad (int pos) @@ -855,13 +700,6 @@ namespace Mono.CSharp ig.Emit (OpCodes.Ldarg_S, (byte) pos); break; } - - if (TrackStackTypes) { - // - // Should never be reached, all parameters are hoisted into class - // - throw new NotImplementedException (); - } } public void EmitArgumentStore (int pos) @@ -930,24 +768,6 @@ namespace Mono.CSharp public void EmitThis () { ig.Emit (OpCodes.Ldarg_0); - - if (TrackStackTypes) { - // - // Using CurrentTypeOnStack as a placeholder for CurrentType to allow - // optimizations based on `this' presence - // - SetStackType (InternalType.CurrentTypeOnStack); - } - } - - // - // Returns actual stack types when stack types tracing is enabled - // - public TypeSpec[] GetStackTypes () - { - TypeSpec[] types = new TypeSpec[StackHeight]; - Array.Copy (stack_types, types, types.Length); - return types; } /// @@ -994,20 +814,6 @@ namespace Mono.CSharp s.Push (b); } - void SetStackType (TypeSpec type) - { - if (type == null) - throw new ArgumentNullException ("type"); - - if (stack_types == null) { - stack_types = new TypeSpec[8]; - } else if (StackHeight > stack_types.Length) { - Array.Resize (ref stack_types, stack_types.Length * 2); - } - - stack_types[StackHeight - 1] = type; - } - /// /// ReturnValue creates on demand the LocalBuilder for the /// return value from the function. By default this is not @@ -1024,10 +830,6 @@ namespace Mono.CSharp { if (return_value == null){ return_value = DeclareLocal (return_type, false); - if (!HasReturnLabel){ - ReturnLabel = DefineLabel (); - HasReturnLabel = true; - } } return return_value; @@ -1073,15 +875,15 @@ namespace Mono.CSharp { Expression instance_copy = null; - if (!HasAwaitArguments) { + if (!HasAwaitArguments && ec.HasSet (BuilderContext.Options.AsyncBody)) { HasAwaitArguments = Arguments != null && Arguments.ContainsEmitWithAwait (); - if (HasAwaitArguments) { - if (InstanceExpressionOnStack) - throw new NotSupportedException (); + if (HasAwaitArguments && InstanceExpressionOnStack) { + throw new NotSupportedException (); } } OpCode call_op; + LocalTemporary lt = null; if (method.IsStatic) { call_op = OpCodes.Call; @@ -1102,7 +904,7 @@ namespace Mono.CSharp if (DuplicateArguments) { ec.Emit (OpCodes.Dup); if (Arguments != null && Arguments.Count != 0) { - var lt = new LocalTemporary (instance_on_stack_type); + lt = new LocalTemporary (instance_on_stack_type); lt.Store (ec); instance_copy = lt; } @@ -1111,12 +913,11 @@ namespace Mono.CSharp } if (Arguments != null && !InstanceExpressionOnStack) { - EmittedArguments = Arguments.Emit (ec, DuplicateArguments || HasAwaitArguments); + EmittedArguments = Arguments.Emit (ec, DuplicateArguments, HasAwaitArguments); if (EmittedArguments != null) { if (instance_copy != null) { EmitCallInstance (ec, instance_copy, method.DeclaringType, call_op); - var lt = instance_copy as LocalTemporary; if (lt != null) lt.Release (ec); } @@ -1157,7 +958,7 @@ namespace Mono.CSharp // // Push the instance expression // - if ((instance_type.IsStruct && (callOpcode == OpCodes.Callvirt || (callOpcode == OpCodes.Call && declaringType == instance_type))) || + if ((instance_type.IsStruct && (callOpcode == OpCodes.Callvirt || (callOpcode == OpCodes.Call && declaringType.IsStruct))) || instance_type.IsGenericParameter || declaringType.IsNullableType) { // // If the expression implements IMemoryLocation, then