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