System.Xml.Xsl.IlGen.XmlILVisitor.GenerateContainerIterator C# (CSharp) Method

GenerateContainerIterator() private method

Generate boiler-plate code that calls MoveNext on an Xml iterator that controls a nested iterator. Iterator should have already been created by calling code.
... goto LabelCall; LabelNext: navCtxt = null; LabelCall: switch (iter.MoveNext(navCtxt)) { case IteratorState.NoMoreNodes: goto LabelNextCtxt; case IteratorState.NextInputNode: goto LabelNextNested; }
private GenerateContainerIterator ( QilNode nd, LocalBuilder locIter, Label lblOnEndNested, MethodInfo methNext, Type itemStorageType ) : void
nd QilNode
locIter System.Reflection.Emit.LocalBuilder
lblOnEndNested System.Reflection.Emit.Label
methNext System.Reflection.MethodInfo
itemStorageType System.Type
return void
        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));
            }
        }
XmlILVisitor