private void GenerateContainerIterator(QilNode nd, LocalBuilder locIter, Label lblOnEndNested,
MethodInfo methNext, Type itemStorageType) {
Label lblCall;
// Define labels that will be used
lblCall = this.helper.DefineLabel();
// iter.MoveNext(input);
// goto LabelCall;
this.iterCurr.EnsureNoStackNoCache(nd.XmlType.IsNode ? "$$$navInput" : "$$$itemInput");
this.helper.Emit(OpCodes.Ldloca, locIter);
this.iterCurr.PushValue();
this.helper.EmitUnconditionalBranch(OpCodes.Br, lblCall);
// LabelNext:
// iterSet.MoveNext(null);
this.helper.MarkLabel(lblOnEndNested);
this.helper.Emit(OpCodes.Ldloca, locIter);
this.helper.Emit(OpCodes.Ldnull);
// LabelCall:
// result = iter.MoveNext(input);
this.helper.MarkLabel(lblCall);
this.helper.Call(methNext);
// If this iterator always returns a single node, then NoMoreNodes will never be returned
if (nd.XmlType.IsSingleton) {
// if (result == IteratorResult.NeedInputNode) goto LabelNextInput;
this.helper.LoadInteger((int) IteratorResult.NeedInputNode);
this.helper.Emit(OpCodes.Beq, this.iterNested.GetLabelNext());
this.iterCurr.Storage = StorageDescriptor.Current(locIter, itemStorageType);
}
else {
// switch (iter.MoveNext(input)) {
// case IteratorResult.NoMoreNodes: goto LabelNextCtxt;
// case IteratorResult.NeedInputNode: goto LabelNextInput;
// }
this.helper.Emit(OpCodes.Switch, new Label[] {this.iterCurr.GetLabelNext(), this.iterNested.GetLabelNext()});
this.iterCurr.SetIterator(lblOnEndNested, StorageDescriptor.Current(locIter, itemStorageType));
}
}