protected override QilNode VisitLength(QilUnary ndSetLen) {
Label lblOnEnd = this.helper.DefineLabel();
OptimizerPatterns patt = OptimizerPatterns.Read(ndSetLen);
if (CachesResult(ndSetLen.Child)) {
NestedVisitEnsureStack(ndSetLen.Child);
this.helper.CallCacheCount(this.iterNested.Storage.ItemStorageType);
}
else {
// length = 0;
this.helper.Emit(OpCodes.Ldc_I4_0);
StartNestedIterator(ndSetLen.Child, lblOnEnd);
// foreach (item in expr) {
Visit(ndSetLen.Child);
// Pop values of SetLength expression from the stack if necessary
this.iterCurr.EnsureNoCache();
this.iterCurr.DiscardStack();
// length++;
this.helper.Emit(OpCodes.Ldc_I4_1);
this.helper.Emit(OpCodes.Add);
if (patt.MatchesPattern(OptimizerPatternName.MaxPosition)) {
// Short-circuit rest of loop if max position has been exceeded
this.helper.Emit(OpCodes.Dup);
this.helper.LoadInteger((int) patt.GetArgument(OptimizerPatternArgument.MaxPosition));
this.helper.Emit(OpCodes.Bgt, lblOnEnd);
}
// }
this.iterCurr.LoopToEnd(lblOnEnd);
EndNestedIterator(ndSetLen.Child);
}
this.iterCurr.Storage = StorageDescriptor.Stack(typeof(int), false);
return ndSetLen;
}