public override void VisitIter(IterDefinition iter)
{
currentRoutine = currentIter = iter;
ilGenerator = iter.Constructor.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Stfld, iter.Self);
int index = 2;
foreach (Argument arg in iter.Arguments) {
if (arg.Mode == ArgumentMode.Once) {
LocalVariable local =
(LocalVariable) iter.LocalVariables[arg.Name];
local.Declare(ilGenerator);
local.EmitStorePrefix(ilGenerator);
ilGenerator.Emit(OpCodes.Ldarg, index++);
local.EmitStore(ilGenerator);
}
}
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Stfld, iter.CurrentPosition);
ilGenerator.Emit(OpCodes.Ret);
ilGenerator = iter.Creator.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
index = 1;
foreach (Argument arg in iter.Arguments) {
if (arg.Mode == ArgumentMode.Once) {
ilGenerator.Emit(OpCodes.Ldarg, index++);
}
}
ConstructorData constructor =
(ConstructorData) iter.BoundType.Constructors[0];
ilGenerator.Emit(OpCodes.Newobj, constructor.ConstructorInfo);
ilGenerator.Emit(OpCodes.Ret);
ilGenerator = iter.MethodBuilder.GetILGenerator();
EmitVoid(iter.ReturnType.RawType);
ilGenerator.Emit(OpCodes.Ret);
foreach (MethodBuilder bridgeMethod in iter.BridgeMethods) {
ilGenerator = bridgeMethod.GetILGenerator();
ilGenerator.Emit(OpCodes.Jmp, iter.Creator);
}
ilGenerator = iter.MoveNext.GetILGenerator();
returnLabel = ilGenerator.DefineLabel();
localVariableStack = new IterLocalVariableStack(iter.TypeBuilder);
localVariableStack.Push(iter.LocalVariables);
foreach (Argument arg in iter.MoveNextArguments) {
if (arg.Mode == ArgumentMode.Out) {
ilGenerator.Emit(OpCodes.Ldarg, arg.Index);
Type argType = arg.RawType.GetElementType();
EmitVoid(argType);
EmitStind(argType);
}
}
Label[] resumePoints = new Label[iter.ResumePoints.Count];
int i = 0;
foreach (ResumePoint resumePoint in iter.ResumePoints) {
resumePoint.Label = ilGenerator.DefineLabel();
resumePoints[i++] = resumePoint.Label;
}
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldfld, iter.CurrentPosition);
ilGenerator.Emit(OpCodes.Switch, resumePoints);
ilGenerator.MarkLabel(resumePoints[0]);
iter.StatementList.Accept(this);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.MarkLabel(returnLabel);
ilGenerator.Emit(OpCodes.Ret);
if (iter.GetCurrent != null) {
ilGenerator = iter.GetCurrent.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldfld, iter.Current);
ilGenerator.Emit(OpCodes.Ret);
}
nestedTypes.Add(iter.TypeBuilder);
currentRoutine = currentIter = null;
}