Iterators are joined together, are nested within each other, and reference each other. This internal class contains detailed information about iteration next labels, caching, iterator item location, etc.
示例#1
0
        /// <summary>
        /// Set this iterator to be the same as the specified iterator.
        /// </summary>
        public void SetIterator(IteratorDescriptor iterInfo)
        {
            if (iterInfo.HasLabelNext)
            {
                this.lblNext = iterInfo.GetLabelNext();
                this.hasNext = true;
            }

            this.storage = iterInfo.Storage;
        }
示例#2
0
        /// <summary>
        /// Set this iterator to be the same as the specified iterator.
        /// </summary>
        public void SetIterator(IteratorDescriptor iterInfo)
        {
            if (iterInfo.HasLabelNext)
            {
                _lblNext = iterInfo.GetLabelNext();
                _hasNext = true;
            }

            _storage = iterInfo.Storage;
        }
        /// <summary>
        /// Set this iterator to be the same as the specified iterator.
        /// </summary>
        public void SetIterator(IteratorDescriptor iterInfo) {
            if (iterInfo.HasLabelNext) {
                this.lblNext = iterInfo.GetLabelNext();
                this.hasNext = true;
            }

            this.storage = iterInfo.Storage;
        }
 /// <summary>
 /// Internal helper initializor.
 /// </summary>
 private void Init(IteratorDescriptor iterParent, GenerateHelper helper) {
     this.helper = helper;
     this.iterParent = iterParent;
 }
 /// <summary>
 /// Create an IteratorDescriptor that is nested in a parent iterator.
 /// </summary>
 public IteratorDescriptor(IteratorDescriptor iterParent) {
     Init(iterParent, iterParent.helper);
 }
示例#6
0
 /// <summary>
 /// Internal helper initializor.
 /// </summary>
 private void Init(IteratorDescriptor iterParent, GenerateHelper helper)
 {
     _helper     = helper;
     _iterParent = iterParent;
 }
示例#7
0
 /// <summary>
 /// Create an IteratorDescriptor that is nested in a parent iterator.
 /// </summary>
 public IteratorDescriptor(IteratorDescriptor iterParent)
 {
     Init(iterParent, iterParent._helper);
 }
示例#8
0
        /// <summary>
        /// Create IteratorDescriptor for each global value.  This pre-visit is necessary because a global early
        /// in the list may reference a global later in the list and therefore expect its IteratorDescriptor to already
        /// be initialized.
        /// </summary>
        private void PrepareGlobalValues(QilList globalIterators)
        {
            MethodInfo methGlobal;
            IteratorDescriptor iterInfo;

            foreach (QilIterator iter in globalIterators)
            {
                Debug.Assert(iter.NodeType == QilNodeType.Let || iter.NodeType == QilNodeType.Parameter);

                // Get metadata for method which computes this global's value
                methGlobal = XmlILAnnotation.Write(iter).FunctionBinding;
                Debug.Assert(methGlobal != null, "Metadata for global value should have already been computed");

                // Create an IteratorDescriptor for this global value
                iterInfo = new IteratorDescriptor(_helper);

                // Iterator items will be stored in a global location
                iterInfo.Storage = StorageDescriptor.Global(methGlobal, GetItemStorageType(iter), !iter.XmlType.IsSingleton);

                // Associate IteratorDescriptor with parameter
                XmlILAnnotation.Write(iter).CachedIteratorDescriptor = iterInfo;
            }
        }
示例#9
0
        /// <summary>
        /// End construction of the current iterator.
        /// </summary>
        private void EndNestedIterator(QilNode nd)
        {
            Debug.Assert(_iterCurr.Storage.Location == ItemLocation.None ||
                         _iterCurr.Storage.ItemStorageType == GetItemStorageType(nd) ||
                         _iterCurr.Storage.ItemStorageType == typeof(XPathItem) ||
                         nd.XmlType.TypeCode == XmlTypeCode.None,
                         "QilNodeType " + nd.NodeType + " cannot be stored using type " + _iterCurr.Storage.ItemStorageType + ".");

            // If the nested iterator was constructed in branching mode,
            if (_iterCurr.IsBranching)
            {
                // Then if branching hasn't already taken place, do so now
                if (_iterCurr.Storage.Location != ItemLocation.None)
                {
                    _iterCurr.EnsureItemStorageType(nd.XmlType, typeof(bool));
                    _iterCurr.EnsureStackNoCache();

                    if (_iterCurr.CurrentBranchingContext == BranchingContext.OnTrue)
                        _helper.Emit(OpCodes.Brtrue, _iterCurr.LabelBranch);
                    else
                        _helper.Emit(OpCodes.Brfalse, _iterCurr.LabelBranch);

                    _iterCurr.Storage = StorageDescriptor.None();
                }
            }

            // Save current iterator as nested iterator
            _iterNested = _iterCurr;

            // Update current iterator to be parent iterator
            _iterCurr = _iterCurr.ParentIterator;
        }
示例#10
0
        /// <summary>
        /// Start construction of a new nested iterator.  If this.iterCurr == null, then the new iterator
        /// is a top-level, or root iterator.  Otherwise, the new iterator will be nested within the
        /// current iterator.
        /// </summary>
        private void StartNestedIterator(QilNode nd)
        {
            IteratorDescriptor iterParent = _iterCurr;

            // Create a new, nested iterator
            if (iterParent == null)
            {
                // Create a "root" iterator info that has no parernt
                _iterCurr = new IteratorDescriptor(_helper);
            }
            else
            {
                // Create a nested iterator
                _iterCurr = new IteratorDescriptor(iterParent);
            }

            _iterNested = null;
        }
示例#11
0
        /// <summary>
        /// Generate code for the specified function.
        /// </summary>
        private void Function(QilFunction ndFunc)
        {
            MethodInfo methFunc;
            int paramId;
            IteratorDescriptor iterInfo;
            bool useWriter;

            // Annotate each function parameter with a IteratorDescriptor
            foreach (QilIterator iter in ndFunc.Arguments)
            {
                Debug.Assert(iter.NodeType == QilNodeType.Parameter);

                // Create an IteratorDescriptor for this parameter
                iterInfo = new IteratorDescriptor(_helper);

                // Add one to parameter index, as 0th parameter is always "this"
                paramId = XmlILAnnotation.Write(iter).ArgumentPosition + 1;

                // The ParameterInfo for each argument should be set as its location
                iterInfo.Storage = StorageDescriptor.Parameter(paramId, GetItemStorageType(iter), !iter.XmlType.IsSingleton);

                // Associate IteratorDescriptor with Let iterator
                XmlILAnnotation.Write(iter).CachedIteratorDescriptor = iterInfo;
            }

            methFunc = XmlILAnnotation.Write(ndFunc).FunctionBinding;
            useWriter = (XmlILConstructInfo.Read(ndFunc).ConstructMethod == XmlILConstructMethod.Writer);

            // Generate query code from QilExpression tree
            _helper.MethodBegin(methFunc, ndFunc.SourceLine, useWriter);

            foreach (QilIterator iter in ndFunc.Arguments)
            {
                // DebugInfo: Sequence point just before generating code for the bound expression
                if (_qil.IsDebug && iter.SourceLine != null)
                    _helper.DebugSequencePoint(iter.SourceLine);

                // Calculate default value of this parameter
                if (iter.Binding != null)
                {
                    Debug.Assert(iter.XmlType == TypeFactory.ItemS, "IlGen currently only supports default values in parameters of type item*.");
                    paramId = (iter.Annotation as XmlILAnnotation).ArgumentPosition + 1;

                    // runtime.MatchesXmlType(param, XmlTypeCode.QName);
                    Label lblLocalComputed = _helper.DefineLabel();
                    _helper.LoadQueryRuntime();
                    _helper.LoadParameter(paramId);
                    _helper.LoadInteger((int)XmlTypeCode.QName);
                    _helper.Call(XmlILMethods.SeqMatchesCode);

                    _helper.Emit(OpCodes.Brfalse, lblLocalComputed);

                    // Compute default value of this parameter
                    StartNestedIterator(iter);
                    NestedVisitEnsureStack(iter.Binding, GetItemStorageType(iter), /*isCached:*/!iter.XmlType.IsSingleton);
                    EndNestedIterator(iter);

                    _helper.SetParameter(paramId);
                    _helper.MarkLabel(lblLocalComputed);
                }
            }

            StartNestedIterator(ndFunc);

            // If function did not push results to writer, then function will return value(s) (rather than void)
            if (useWriter)
                NestedVisit(ndFunc.Definition);
            else
                NestedVisitEnsureStack(ndFunc.Definition, GetItemStorageType(ndFunc), !ndFunc.XmlType.IsSingleton);

            EndNestedIterator(ndFunc);

            _helper.MethodEnd();
        }
示例#12
0
        /// <summary>
        /// Set this iterator to be the same as the specified iterator.
        /// </summary>
        public void SetIterator(IteratorDescriptor iterInfo)
        {
            if (iterInfo.HasLabelNext)
            {
                _lblNext = iterInfo.GetLabelNext();
                _hasNext = true;
            }

            _storage = iterInfo.Storage;
        }
示例#13
0
 /// <summary>
 /// Internal helper initializor.
 /// </summary>
 private void Init(IteratorDescriptor iterParent, GenerateHelper helper)
 {
     _helper = helper;
     _iterParent = iterParent;
 }
示例#14
0
 /// <summary>
 /// Internal helper initializor.
 /// </summary>
 private void Init(IteratorDescriptor iterParent, GenerateHelper helper)
 {
     this.helper     = helper;
     this.iterParent = iterParent;
 }