loc = l;
}
- public static bool CheckContext (EmitContext ec, Location loc)
+ public static bool CheckContext (EmitContext ec, Location loc, bool isYieldBreak)
{
if (ec.InFinally) {
Report.Error (1625, loc, "Cannot yield in the body of a " +
Report.Error (1629, loc, "Unsafe code may not appear in iterators");
return false;
}
- if (ec.InCatch){
- Report.Error (1631, loc, "Cannot yield a value in the body of a catch clause");
- return false;
- }
AnonymousContainer am = ec.CurrentAnonymousMethod;
if ((am != null) && !am.IsIterator){
return false;
}
- if (ec.CurrentBranching.InTryWithCatch ()) {
- Report.Error (1626, loc, "Cannot yield a value in the body of a " +
+ if (ec.CurrentBranching.InTryWithCatch () && (!isYieldBreak || !ec.InCatch)) {
+ if (!ec.InCatch)
+ Report.Error (1626, loc, "Cannot yield a value in the body of a " +
"try block with a catch clause");
+ else
+ Report.Error (1631, loc, "Cannot yield a value in the body of a catch clause");
return false;
}
return true;
if (expr == null)
return false;
- if (!CheckContext (ec, loc))
+ if (!CheckContext (ec, loc, false))
return false;
Iterator iterator = ec.CurrentIterator;
public override bool Resolve (EmitContext ec)
{
- if (!Yield.CheckContext (ec, loc))
+ if (!Yield.CheckContext (ec, loc, true))
return false;
ec.CurrentBranching.CurrentUsageVector.Goto ();
TypeContainer container;
TypeExpr current_type;
Type this_type;
- InternalParameters parameters;
- InternalParameters original_parameters;
+ Parameters parameters;
+ Parameters original_parameters;
IMethodData orig_method;
MethodInfo dispose_method;
Expression generic_enumerator_type;
Expression generic_enumerable_type;
TypeArguments generic_args;
+ EmitContext ec;
protected enum State {
Uninitialized = -2,
resume_points.Add (entry_point);
entry_point.Define (ig);
- ec.EmitTopBlock (orig_method, original_block, parameters);
+ ec.EmitTopBlock (orig_method, original_block);
EmitYieldBreak (ig);
//
// Our constructor
//
- public Iterator (IMethodData m_container, TypeContainer container, GenericMethod generic,
- InternalParameters parameters, int modifiers)
- : base (container.NamespaceEntry, container,
+ public Iterator (IMethodData m_container, DeclSpace parent, GenericMethod generic,
+ int modifiers)
+ : base (parent.NamespaceEntry, parent,
MakeProxyName (m_container.MethodName.Name, generic, m_container.Location),
(modifiers & Modifiers.UNSAFE) | Modifiers.PRIVATE, null)
{
this.orig_method = m_container;
this.generic_method = generic;
- this.container = container;
- this.original_parameters = parameters;
+ this.container = parent.PartialContainer;
+ this.original_parameters = m_container.ParameterInfo;
this.original_block = orig_method.Block;
- this.block = new ToplevelBlock (orig_method.Block, parameters.Parameters, orig_method.Location);
+ this.block = new ToplevelBlock (orig_method.Block, parameters, orig_method.Location);
if (generic != null) {
ArrayList constraints = new ArrayList ();
public bool DefineIterator ()
{
- ec = new EmitContext (this, Location, null, null, ModFlags);
+ ec = new EmitContext (this, this, Location, null, null, ModFlags);
ec.CurrentAnonymousMethod = move_next_method;
ec.InIterator = true;
if (it.IsGenericParameter && (it.DeclaringMethod != null)) {
int pos = it.GenericParameterPosition;
it = CurrentTypeParameters [pos].Type;
- } else if (it.IsGenericInstance) {
+ } else if (it.IsGenericType) {
Type[] args = it.GetGenericArguments ();
TypeArguments inflated = new TypeArguments (Location);
TypeExpr et_expr = InflateType (it.GetElementType ());
int rank = it.GetArrayRank ();
- Type et = et_expr.ResolveAsTypeTerminal (ec).Type;
+ Type et = et_expr.ResolveAsTypeTerminal (ec, false).Type;
it = et.MakeArrayType (rank);
}
te, param.Name, param.ModFlags, param.OptAttributes, param.Location);
}
- InternalParameters InflateParameters (Parameters parameters, EmitContext ec)
+ Parameters InflateParameters (Parameters parameters, EmitContext ec)
{
- Parameter[] fixed_params = null;
- if (parameters.FixedParameters != null) {
- fixed_params = new Parameter [parameters.FixedParameters.Length];
- for (int i = 0; i < fixed_params.Length; i++)
- fixed_params [i] = InflateParameter (parameters.FixedParameters [i]);
- }
-
- Parameters new_params;
- if (parameters.ArrayParameter != null) {
- Parameter array_param = InflateParameter (parameters.ArrayParameter);
- new_params = new Parameters (fixed_params, array_param);
- } else
- new_params = new Parameters (fixed_params, parameters.HasArglist);
-
- Type [] types = new_params.GetParameterInfo (ec);
- return new InternalParameters (types, new_params);
+ int count = parameters.FixedParameters.Length;
+ if (count == 0)
+ return Parameters.EmptyReadOnlyParameters;
+ Parameter[] fixed_params = new Parameter [count];
+ for (int i = 0; i < count; i++)
+ fixed_params [i] = InflateParameter (parameters.FixedParameters [i]);
+
+ return new Parameters (fixed_params, parameters.HasArglist);
}
- protected override TypeExpr [] GetClassBases (out TypeExpr base_class)
+ public override TypeExpr [] GetClassBases (out TypeExpr base_class)
{
iterator_type_expr = InflateType (original_iterator_type);
else
current_type = new TypeExpression (TypeBuilder, Location);
- parameters = InflateParameters (original_parameters.Parameters, ec);
+ if (IsGeneric) {
+ foreach (TypeParameter tparam in TypeParameters)
+ tparam.InflateConstraints (current_type.Type);
+ }
+
+ parameters = InflateParameters (original_parameters, ec);
+ if (!parameters.Resolve (ec)) {
+ // TODO:
+ }
Define_Fields ();
Define_Current (false);
foreach (TypeParameter tparam in generic_method.TypeParameters)
new_args.Add (new TypeParameterExpr (tparam, Location));
ConstructedType ct = new ConstructedType (CurrentType, new_args, Location);
- proxy_type = ct.ResolveAsTypeTerminal (ec);
+ proxy_type = ct.ResolveAsTypeTerminal (ec, false);
} else
proxy_type = current_type;
{
pc_field = new Field (
this, TypeManager.system_int32_expr, Modifiers.PRIVATE, "$PC",
- null, null, Location);
+ null, Location);
AddField (pc_field);
current_field = new Field (
this, iterator_type_expr, Modifiers.PRIVATE, "$current",
- null, null, Location);
+ null, Location);
AddField (current_field);
}
"this", Parameter.Modifier.NONE,
null, Location));
list.Add (new Parameter (
- TypeManager.system_boolean_expr, "initialized",
+ TypeManager.bool_type, "initialized",
Parameter.Modifier.NONE, null, Location));
- Parameter[] old_fixed = parameters.Parameters.FixedParameters;
- if (old_fixed != null)
- list.AddRange (old_fixed);
+ Parameter[] old_fixed = parameters.FixedParameters;
+ list.AddRange (old_fixed);
Parameter[] fixed_params = new Parameter [list.Count];
list.CopyTo (fixed_params);
- ctor_params = new Parameters (fixed_params, parameters.Parameters.ArrayParameter);
+ ctor_params = new Parameters (fixed_params);
ctor = new Constructor (
this, MemberName.Name, Modifiers.PUBLIC, ctor_params,
Location);
AddConstructor (ctor);
- ctor.Block = new ToplevelBlock (block, parameters.Parameters, Location);
+ ctor.Block = new ToplevelBlock (block, parameters, Location);
int first = IsStatic ? 2 : 3;
MemberName name = new MemberName (left, "Current", null, Location);
ToplevelBlock get_block = new ToplevelBlock (
- block, parameters.Parameters, Location);
+ block, parameters, Location);
get_block.AddStatement (new If (
new Binary (
Method get_enumerator = new Method (
this, null, type, 0, false, name,
Parameters.EmptyReadOnlyParameters, null);
- AddMethod (get_enumerator);
+
+ //
+ // We call append instead of add, as we need to make sure that
+ // this method is resolved after the MoveNext method, as that one
+ // triggers the computation of the AnonymousMethod Scope, which is
+ // required during the code generation of the enumerator
+ //
+ AppendMethod (get_enumerator);
get_enumerator.Block = new ToplevelBlock (
- block, parameters.Parameters, Location);
+ block, parameters, Location);
get_enumerator.Block.SetHaveAnonymousMethods (Location, move_next_method);
Expression ce = new MemberAccess (
new SimpleName ("System.Threading.Interlocked", Location),
- "CompareExchange", Location);
+ "CompareExchange");
Expression pc = new FieldExpression (this, pc_field);
Expression before = new IntLiteral ((int) State.Running, Location);
{
ec.CurrentAnonymousMethod = iterator.move_next_method;
- iterator.cc.EmitParameter (ec, name);
+ LocalTemporary dummy = null;
+
+ iterator.cc.EmitParameter (ec, name, false, false, ref dummy);
}
}
public override void Emit (EmitContext ec)
{
- ec.EmitThis ();
+ ec.EmitThis (false);
}
}
Iterator iterator;
public MoveNextMethod (Iterator iterator, Location loc)
- : base (iterator.parameters.Parameters, iterator.original_block, loc)
+ : base (iterator.parameters, iterator.original_block, loc)
{
this.iterator = iterator;
}
get { return iterator; }
}
+ public void ComputeHost ()
+ {
+ ComputeMethodHost ();
+ }
+
public override bool IsIterator {
get { return true; }
}
protected override void DoEmit (EmitContext ec)
{
+ iterator.move_next_method.ComputeHost ();
ec.CurrentAnonymousMethod = iterator.move_next_method;
ec.InIterator = true;
AddMethod (reset);
reset.Block = new ToplevelBlock (Location);
- reset.Block = new ToplevelBlock (block, parameters.Parameters, Location);
+ reset.Block = new ToplevelBlock (block, parameters, Location);
reset.Block.SetHaveAnonymousMethods (Location, move_next_method);
reset.Block.AddStatement (Create_ThrowNotSupported ());
Parameters.EmptyReadOnlyParameters, null);
AddMethod (dispose);
- dispose.Block = new ToplevelBlock (block, parameters.Parameters, Location);
+ dispose.Block = new ToplevelBlock (block, parameters, Location);
dispose.Block.SetHaveAnonymousMethods (Location, move_next_method);
dispose.Block.AddStatement (new DisposeMethod (this, Location));
return true;
}
- if (!ret.IsGenericInstance)
+ if (!ret.IsGenericType)
return false;
Type[] args = TypeManager.GetTypeArguments (ret);