The Labs \ Source Viewer \ SSCLI \ System.Xml.Xsl.IlGen \ XmlILConstructors

  1. //------------------------------------------------------------------------------
  2. // <copyright file="GenerateHelper.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. using System;
  16. using System.Globalization;
  17. using System.Xml;
  18. using System.Xml.XPath;
  19. using System.Xml.Schema;
  20. using System.Text;
  21. using System.IO;
  22. using System.Collections;
  23. using System.Collections.Generic;
  24. using System.Reflection;
  25. using System.Reflection.Emit;
  26. using System.Security;
  27. using System.Diagnostics;
  28. using System.Diagnostics.SymbolStore;
  29. using System.Xml.Xsl.Qil;
  30. using System.Xml.Xsl.Runtime;
  31. namespace System.Xml.Xsl.IlGen
  32. {
  33.     using Res = System.Xml.Utils.Res;
  34.    
  35.     /// <summary>
  36.     /// List of all XmlIL runtime constructors.
  37.     /// </summary>
  38.     internal class XmlILStorageMethods
  39.     {
  40.         // Aggregates
  41.         public MethodInfo AggAvg;
  42.         public MethodInfo AggAvgResult;
  43.         public MethodInfo AggCreate;
  44.         public MethodInfo AggIsEmpty;
  45.         public MethodInfo AggMax;
  46.         public MethodInfo AggMaxResult;
  47.         public MethodInfo AggMin;
  48.         public MethodInfo AggMinResult;
  49.         public MethodInfo AggSum;
  50.         public MethodInfo AggSumResult;
  51.        
  52.         // Sequences
  53.         public Type SeqType;
  54.         public FieldInfo SeqEmpty;
  55.         public MethodInfo SeqReuse;
  56.         public MethodInfo SeqReuseSgl;
  57.         public MethodInfo SeqAdd;
  58.         public MethodInfo SeqSortByKeys;
  59.        
  60.         // IList<>
  61.         public Type IListType;
  62.         public MethodInfo IListCount;
  63.         public MethodInfo IListItem;
  64.        
  65.         // XPathItem
  66.         public MethodInfo ValueAs;
  67.        
  68.         // ToAtomicValue
  69.         public MethodInfo ToAtomicValue;
  70.        
  71.         public XmlILStorageMethods(Type storageType)
  72.         {
  73.             // Aggregates
  74.             if (storageType == typeof(int) || storageType == typeof(long) || storageType == typeof(decimal) || storageType == typeof(double)) {
  75.                
  76.                 Type aggType = Type.GetType("System.Xml.Xsl.Runtime." + storageType.Name + "Aggregator");
  77.                 AggAvg = XmlILMethods.GetMethod(aggType, "Average");
  78.                 AggAvgResult = XmlILMethods.GetMethod(aggType, "get_AverageResult");
  79.                 AggCreate = XmlILMethods.GetMethod(aggType, "Create");
  80.                 AggIsEmpty = XmlILMethods.GetMethod(aggType, "get_IsEmpty");
  81.                 AggMax = XmlILMethods.GetMethod(aggType, "Maximum");
  82.                 AggMaxResult = XmlILMethods.GetMethod(aggType, "get_MaximumResult");
  83.                 AggMin = XmlILMethods.GetMethod(aggType, "Minimum");
  84.                 AggMinResult = XmlILMethods.GetMethod(aggType, "get_MinimumResult");
  85.                 AggSum = XmlILMethods.GetMethod(aggType, "Sum");
  86.                 AggSumResult = XmlILMethods.GetMethod(aggType, "get_SumResult");
  87.             }
  88.            
  89.             // Sequences
  90.             if (storageType == typeof(XPathNavigator)) {
  91.                 SeqType = typeof(XmlQueryNodeSequence);
  92.                 SeqAdd = XmlILMethods.GetMethod(SeqType, "AddClone");
  93.             }
  94.             else if (storageType == typeof(XPathItem)) {
  95.                 SeqType = typeof(XmlQueryItemSequence);
  96.                 SeqAdd = XmlILMethods.GetMethod(SeqType, "AddClone");
  97.             }
  98.             else {
  99.                 SeqType = typeof(XmlQuerySequence<>).MakeGenericType(storageType);
  100.                 SeqAdd = XmlILMethods.GetMethod(SeqType, "Add");
  101.             }
  102.            
  103.             SeqEmpty = SeqType.GetField("Empty");
  104.             SeqReuse = XmlILMethods.GetMethod(SeqType, "CreateOrReuse", SeqType);
  105.             SeqReuseSgl = XmlILMethods.GetMethod(SeqType, "CreateOrReuse", SeqType, storageType);
  106.             SeqSortByKeys = XmlILMethods.GetMethod(SeqType, "SortByKeys");
  107.            
  108.             // IList<>
  109.             IListType = typeof(IList<>).MakeGenericType(storageType);
  110.             IListItem = XmlILMethods.GetMethod(IListType, "get_Item");
  111.             IListCount = XmlILMethods.GetMethod(typeof(ICollection<>).MakeGenericType(storageType), "get_Count");
  112.            
  113.             // XPathItem.ValueAsXXX
  114.             if (storageType == typeof(string))
  115.                 ValueAs = XmlILMethods.GetMethod(typeof(XPathItem), "get_Value");
  116.             else if (storageType == typeof(int))
  117.                 ValueAs = XmlILMethods.GetMethod(typeof(XPathItem), "get_ValueAsInt");
  118.             else if (storageType == typeof(long))
  119.                 ValueAs = XmlILMethods.GetMethod(typeof(XPathItem), "get_ValueAsLong");
  120.             else if (storageType == typeof(DateTime))
  121.                 ValueAs = XmlILMethods.GetMethod(typeof(XPathItem), "get_ValueAsDateTime");
  122.             else if (storageType == typeof(double))
  123.                 ValueAs = XmlILMethods.GetMethod(typeof(XPathItem), "get_ValueAsDouble");
  124.             else if (storageType == typeof(bool))
  125.                 ValueAs = XmlILMethods.GetMethod(typeof(XPathItem), "get_ValueAsBoolean");
  126.            
  127.             // XmlILStorageConverter.XXXToAtomicValue
  128.             if (storageType == typeof(byte[]))
  129.                 ToAtomicValue = XmlILMethods.GetMethod(typeof(XmlILStorageConverter), "BytesToAtomicValue");
  130.             else if (storageType != typeof(XPathItem) && storageType != typeof(XPathNavigator))
  131.                 ToAtomicValue = XmlILMethods.GetMethod(typeof(XmlILStorageConverter), storageType.Name + "ToAtomicValue");
  132.         }
  133.     }
  134.    
  135.     /// <summary>
  136.     /// List of all XmlIL runtime constructors.
  137.     /// </summary>
  138.     static internal class XmlILConstructors
  139.     {
  140.         public static readonly ConstructorInfo DecFromParts = GetConstructor(typeof(decimal), typeof(int), typeof(int), typeof(int), typeof(bool), typeof(byte));
  141.         public static readonly ConstructorInfo DecFromInt32 = GetConstructor(typeof(decimal), typeof(int));
  142.         public static readonly ConstructorInfo DecFromInt64 = GetConstructor(typeof(decimal), typeof(long));
  143.         public static readonly ConstructorInfo Debuggable = GetConstructor(typeof(DebuggableAttribute), typeof(DebuggableAttribute.DebuggingModes));
  144.         public static readonly ConstructorInfo NonUserCode = GetConstructor(typeof(DebuggerNonUserCodeAttribute));
  145.         public static readonly ConstructorInfo QName = GetConstructor(typeof(XmlQualifiedName), typeof(string), typeof(string));
  146.         public static readonly ConstructorInfo StepThrough = GetConstructor(typeof(DebuggerStepThroughAttribute));
  147.         public static readonly ConstructorInfo Transparent = GetConstructor(typeof(SecurityTransparentAttribute));
  148.        
  149.         private static ConstructorInfo GetConstructor(Type className)
  150.         {
  151.             ConstructorInfo constrInfo = className.GetConstructor(new Type[] {});
  152.             Debug.Assert(constrInfo != null, "Constructor " + className + " cannot be null.");
  153.             return constrInfo;
  154.         }
  155.        
  156.         private static ConstructorInfo GetConstructor(Type className, params Type[] args)
  157.         {
  158.             ConstructorInfo constrInfo = className.GetConstructor(args);
  159.             Debug.Assert(constrInfo != null, "Constructor " + className + " cannot be null.");
  160.             return constrInfo;
  161.         }
  162.     }
  163.    
  164.    
  165.     /// <summary>
  166.     /// List of all XmlIL runtime methods.
  167.     /// </summary>
  168.     static internal class XmlILMethods
  169.     {
  170.         // Iterators
  171.         public static readonly MethodInfo AncCreate = GetMethod(typeof(AncestorIterator), "Create");
  172.         public static readonly MethodInfo AncNext = GetMethod(typeof(AncestorIterator), "MoveNext");
  173.         public static readonly MethodInfo AncDOCreate = GetMethod(typeof(AncestorDocOrderIterator), "Create");
  174.         public static readonly MethodInfo AncDONext = GetMethod(typeof(AncestorDocOrderIterator), "MoveNext");
  175.         public static readonly MethodInfo AttrContentCreate = GetMethod(typeof(AttributeContentIterator), "Create");
  176.         public static readonly MethodInfo AttrContentNext = GetMethod(typeof(AttributeContentIterator), "MoveNext");
  177.         public static readonly MethodInfo AttrCreate = GetMethod(typeof(AttributeIterator), "Create");
  178.         public static readonly MethodInfo AttrNext = GetMethod(typeof(AttributeIterator), "MoveNext");
  179.         public static readonly MethodInfo ContentCreate = GetMethod(typeof(ContentIterator), "Create");
  180.         public static readonly MethodInfo ContentNext = GetMethod(typeof(ContentIterator), "MoveNext");
  181.         public static readonly MethodInfo ContentMergeCreate = GetMethod(typeof(ContentMergeIterator), "Create");
  182.         public static readonly MethodInfo ContentMergeNext = GetMethod(typeof(ContentMergeIterator), "MoveNext");
  183.         public static readonly MethodInfo DescCreate = GetMethod(typeof(DescendantIterator), "Create");
  184.         public static readonly MethodInfo DescNext = GetMethod(typeof(DescendantIterator), "MoveNext");
  185.         public static readonly MethodInfo DescMergeCreate = GetMethod(typeof(DescendantMergeIterator), "Create");
  186.         public static readonly MethodInfo DescMergeNext = GetMethod(typeof(DescendantMergeIterator), "MoveNext");
  187.         public static readonly MethodInfo DiffCreate = GetMethod(typeof(DifferenceIterator), "Create");
  188.         public static readonly MethodInfo DiffNext = GetMethod(typeof(DifferenceIterator), "MoveNext");
  189.         public static readonly MethodInfo DodMergeCreate = GetMethod(typeof(DodSequenceMerge), "Create");
  190.         public static readonly MethodInfo DodMergeAdd = GetMethod(typeof(DodSequenceMerge), "AddSequence");
  191.         public static readonly MethodInfo DodMergeSeq = GetMethod(typeof(DodSequenceMerge), "MergeSequences");
  192.         public static readonly MethodInfo ElemContentCreate = GetMethod(typeof(ElementContentIterator), "Create");
  193.         public static readonly MethodInfo ElemContentNext = GetMethod(typeof(ElementContentIterator), "MoveNext");
  194.         public static readonly MethodInfo FollSibCreate = GetMethod(typeof(FollowingSiblingIterator), "Create");
  195.         public static readonly MethodInfo FollSibNext = GetMethod(typeof(FollowingSiblingIterator), "MoveNext");
  196.         public static readonly MethodInfo FollSibMergeCreate = GetMethod(typeof(FollowingSiblingMergeIterator), "Create");
  197.         public static readonly MethodInfo FollSibMergeNext = GetMethod(typeof(FollowingSiblingMergeIterator), "MoveNext");
  198.         public static readonly MethodInfo IdCreate = GetMethod(typeof(IdIterator), "Create");
  199.         public static readonly MethodInfo IdNext = GetMethod(typeof(IdIterator), "MoveNext");
  200.         public static readonly MethodInfo InterCreate = GetMethod(typeof(IntersectIterator), "Create");
  201.         public static readonly MethodInfo InterNext = GetMethod(typeof(IntersectIterator), "MoveNext");
  202.         public static readonly MethodInfo KindContentCreate = GetMethod(typeof(NodeKindContentIterator), "Create");
  203.         public static readonly MethodInfo KindContentNext = GetMethod(typeof(NodeKindContentIterator), "MoveNext");
  204.         public static readonly MethodInfo NmspCreate = GetMethod(typeof(NamespaceIterator), "Create");
  205.         public static readonly MethodInfo NmspNext = GetMethod(typeof(NamespaceIterator), "MoveNext");
  206.         public static readonly MethodInfo NodeRangeCreate = GetMethod(typeof(NodeRangeIterator), "Create");
  207.         public static readonly MethodInfo NodeRangeNext = GetMethod(typeof(NodeRangeIterator), "MoveNext");
  208.         public static readonly MethodInfo ParentCreate = GetMethod(typeof(ParentIterator), "Create");
  209.         public static readonly MethodInfo ParentNext = GetMethod(typeof(ParentIterator), "MoveNext");
  210.         public static readonly MethodInfo PrecCreate = GetMethod(typeof(PrecedingIterator), "Create");
  211.         public static readonly MethodInfo PrecNext = GetMethod(typeof(PrecedingIterator), "MoveNext");
  212.         public static readonly MethodInfo PreSibCreate = GetMethod(typeof(PrecedingSiblingIterator), "Create");
  213.         public static readonly MethodInfo PreSibNext = GetMethod(typeof(PrecedingSiblingIterator), "MoveNext");
  214.         public static readonly MethodInfo PreSibDOCreate = GetMethod(typeof(PrecedingSiblingDocOrderIterator), "Create");
  215.         public static readonly MethodInfo PreSibDONext = GetMethod(typeof(PrecedingSiblingDocOrderIterator), "MoveNext");
  216.         public static readonly MethodInfo SortKeyCreate = GetMethod(typeof(XmlSortKeyAccumulator), "Create");
  217.         public static readonly MethodInfo SortKeyDateTime = GetMethod(typeof(XmlSortKeyAccumulator), "AddDateTimeSortKey");
  218.         public static readonly MethodInfo SortKeyDecimal = GetMethod(typeof(XmlSortKeyAccumulator), "AddDecimalSortKey");
  219.         public static readonly MethodInfo SortKeyDouble = GetMethod(typeof(XmlSortKeyAccumulator), "AddDoubleSortKey");
  220.         public static readonly MethodInfo SortKeyEmpty = GetMethod(typeof(XmlSortKeyAccumulator), "AddEmptySortKey");
  221.         public static readonly MethodInfo SortKeyFinish = GetMethod(typeof(XmlSortKeyAccumulator), "FinishSortKeys");
  222.         public static readonly MethodInfo SortKeyInt = GetMethod(typeof(XmlSortKeyAccumulator), "AddIntSortKey");
  223.         public static readonly MethodInfo SortKeyInteger = GetMethod(typeof(XmlSortKeyAccumulator), "AddIntegerSortKey");
  224.         public static readonly MethodInfo SortKeyKeys = GetMethod(typeof(XmlSortKeyAccumulator), "get_Keys");
  225.         public static readonly MethodInfo SortKeyString = GetMethod(typeof(XmlSortKeyAccumulator), "AddStringSortKey");
  226.         public static readonly MethodInfo UnionCreate = GetMethod(typeof(UnionIterator), "Create");
  227.         public static readonly MethodInfo UnionNext = GetMethod(typeof(UnionIterator), "MoveNext");
  228.         public static readonly MethodInfo XPFollCreate = GetMethod(typeof(XPathFollowingIterator), "Create");
  229.         public static readonly MethodInfo XPFollNext = GetMethod(typeof(XPathFollowingIterator), "MoveNext");
  230.         public static readonly MethodInfo XPFollMergeCreate = GetMethod(typeof(XPathFollowingMergeIterator), "Create");
  231.         public static readonly MethodInfo XPFollMergeNext = GetMethod(typeof(XPathFollowingMergeIterator), "MoveNext");
  232.         public static readonly MethodInfo XPPrecCreate = GetMethod(typeof(XPathPrecedingIterator), "Create");
  233.         public static readonly MethodInfo XPPrecNext = GetMethod(typeof(XPathPrecedingIterator), "MoveNext");
  234.         public static readonly MethodInfo XPPrecDOCreate = GetMethod(typeof(XPathPrecedingDocOrderIterator), "Create");
  235.         public static readonly MethodInfo XPPrecDONext = GetMethod(typeof(XPathPrecedingDocOrderIterator), "MoveNext");
  236.         public static readonly MethodInfo XPPrecMergeCreate = GetMethod(typeof(XPathPrecedingMergeIterator), "Create");
  237.         public static readonly MethodInfo XPPrecMergeNext = GetMethod(typeof(XPathPrecedingMergeIterator), "MoveNext");
  238.        
  239.         // XmlQueryRuntime
  240.         public static readonly MethodInfo AddNewIndex = GetMethod(typeof(XmlQueryRuntime), "AddNewIndex");
  241.         public static readonly MethodInfo ChangeTypeXsltArg = GetMethod(typeof(XmlQueryRuntime), "ChangeTypeXsltArgument", typeof(int), typeof(object), typeof(Type));
  242.         public static readonly MethodInfo ChangeTypeXsltResult = GetMethod(typeof(XmlQueryRuntime), "ChangeTypeXsltResult");
  243.         public static readonly MethodInfo CompPos = GetMethod(typeof(XmlQueryRuntime), "ComparePosition");
  244.         public static readonly MethodInfo Context = GetMethod(typeof(XmlQueryRuntime), "get_ExternalContext");
  245.         public static readonly MethodInfo CreateCollation = GetMethod(typeof(XmlQueryRuntime), "CreateCollation");
  246.         public static readonly MethodInfo DocOrder = GetMethod(typeof(XmlQueryRuntime), "DocOrderDistinct");
  247.         public static readonly MethodInfo EndRtfConstr = GetMethod(typeof(XmlQueryRuntime), "EndRtfConstruction");
  248.         public static readonly MethodInfo EndSeqConstr = GetMethod(typeof(XmlQueryRuntime), "EndSequenceConstruction");
  249.         public static readonly MethodInfo FindIndex = GetMethod(typeof(XmlQueryRuntime), "FindIndex");
  250.         public static readonly MethodInfo GenId = GetMethod(typeof(XmlQueryRuntime), "GenerateId");
  251.         public static readonly MethodInfo GetAtomizedName = GetMethod(typeof(XmlQueryRuntime), "GetAtomizedName");
  252.         public static readonly MethodInfo GetCollation = GetMethod(typeof(XmlQueryRuntime), "GetCollation");
  253.         public static readonly MethodInfo GetEarly = GetMethod(typeof(XmlQueryRuntime), "GetEarlyBoundObject");
  254.         public static readonly MethodInfo GetNameFilter = GetMethod(typeof(XmlQueryRuntime), "GetNameFilter");
  255.         public static readonly MethodInfo GetOutput = GetMethod(typeof(XmlQueryRuntime), "get_Output");
  256.         public static readonly MethodInfo GetGlobalValue = GetMethod(typeof(XmlQueryRuntime), "GetGlobalValue");
  257.         public static readonly MethodInfo GetTypeFilter = GetMethod(typeof(XmlQueryRuntime), "GetTypeFilter");
  258.         public static readonly MethodInfo GlobalComputed = GetMethod(typeof(XmlQueryRuntime), "IsGlobalComputed");
  259.         public static readonly MethodInfo ItemMatchesCode = GetMethod(typeof(XmlQueryRuntime), "MatchesXmlType", typeof(XPathItem), typeof(XmlTypeCode));
  260.         public static readonly MethodInfo ItemMatchesType = GetMethod(typeof(XmlQueryRuntime), "MatchesXmlType", typeof(XPathItem), typeof(int));
  261.         public static readonly MethodInfo QNameEqualLit = GetMethod(typeof(XmlQueryRuntime), "IsQNameEqual", typeof(XPathNavigator), typeof(int), typeof(int));
  262.         public static readonly MethodInfo QNameEqualNav = GetMethod(typeof(XmlQueryRuntime), "IsQNameEqual", typeof(XPathNavigator), typeof(XPathNavigator));
  263.         public static readonly MethodInfo RtfConstr = GetMethod(typeof(XmlQueryRuntime), "TextRtfConstruction");
  264.         public static readonly MethodInfo SendMessage = GetMethod(typeof(XmlQueryRuntime), "SendMessage");
  265.         public static readonly MethodInfo SeqMatchesCode = GetMethod(typeof(XmlQueryRuntime), "MatchesXmlType", typeof(IList<XPathItem>), typeof(XmlTypeCode));
  266.         public static readonly MethodInfo SeqMatchesType = GetMethod(typeof(XmlQueryRuntime), "MatchesXmlType", typeof(IList<XPathItem>), typeof(int));
  267.         public static readonly MethodInfo SetGlobalValue = GetMethod(typeof(XmlQueryRuntime), "SetGlobalValue");
  268.         public static readonly MethodInfo StartRtfConstr = GetMethod(typeof(XmlQueryRuntime), "StartRtfConstruction");
  269.         public static readonly MethodInfo StartSeqConstr = GetMethod(typeof(XmlQueryRuntime), "StartSequenceConstruction");
  270.         public static readonly MethodInfo TagAndMappings = GetMethod(typeof(XmlQueryRuntime), "ParseTagName", typeof(string), typeof(int));
  271.         public static readonly MethodInfo TagAndNamespace = GetMethod(typeof(XmlQueryRuntime), "ParseTagName", typeof(string), typeof(string));
  272.         public static readonly MethodInfo ThrowException = GetMethod(typeof(XmlQueryRuntime), "ThrowException");
  273.         public static readonly MethodInfo XsltLib = GetMethod(typeof(XmlQueryRuntime), "get_XsltFunctions");
  274.        
  275.         // XmlQueryContext
  276.         public static readonly MethodInfo GetDataSource = GetMethod(typeof(XmlQueryContext), "GetDataSource");
  277.         public static readonly MethodInfo GetDefaultDataSource = GetMethod(typeof(XmlQueryContext), "get_DefaultDataSource");
  278.         public static readonly MethodInfo GetParam = GetMethod(typeof(XmlQueryContext), "GetParameter");
  279.         public static readonly MethodInfo InvokeXsltLate = GetMethod(typeof(XmlQueryContext), "InvokeXsltLateBoundFunction");
  280.        
  281.         // XmlILIndex
  282.         public static readonly MethodInfo IndexAdd = GetMethod(typeof(XmlILIndex), "Add");
  283.         public static readonly MethodInfo IndexLookup = GetMethod(typeof(XmlILIndex), "Lookup");
  284.        
  285.         // XPathItem
  286.         public static readonly MethodInfo ItemIsNode = GetMethod(typeof(XPathItem), "get_IsNode");
  287.         public static readonly MethodInfo Value = GetMethod(typeof(XPathItem), "get_Value");
  288.         public static readonly MethodInfo ValueAsAny = GetMethod(typeof(XPathItem), "ValueAs", typeof(Type), typeof(IXmlNamespaceResolver));
  289.        
  290.         // XPathNavigator
  291.         public static readonly MethodInfo NavClone = GetMethod(typeof(XPathNavigator), "Clone");
  292.         public static readonly MethodInfo NavLocalName = GetMethod(typeof(XPathNavigator), "get_LocalName");
  293.         public static readonly MethodInfo NavMoveAttr = GetMethod(typeof(XPathNavigator), "MoveToAttribute", typeof(string), typeof(string));
  294.         public static readonly MethodInfo NavMoveId = GetMethod(typeof(XPathNavigator), "MoveToId");
  295.         public static readonly MethodInfo NavMoveParent = GetMethod(typeof(XPathNavigator), "MoveToParent");
  296.         public static readonly MethodInfo NavMoveRoot = GetMethod(typeof(XPathNavigator), "MoveToRoot");
  297.         public static readonly MethodInfo NavMoveTo = GetMethod(typeof(XPathNavigator), "MoveTo");
  298.         public static readonly MethodInfo NavNmsp = GetMethod(typeof(XPathNavigator), "get_NamespaceURI");
  299.         public static readonly MethodInfo NavPrefix = GetMethod(typeof(XPathNavigator), "get_Prefix");
  300.         public static readonly MethodInfo NavSamePos = GetMethod(typeof(XPathNavigator), "IsSamePosition");
  301.         public static readonly MethodInfo NavType = GetMethod(typeof(XPathNavigator), "get_NodeType");
  302.        
  303.         // XmlQueryOutput methods
  304.         public static readonly MethodInfo StartElemLitName = GetMethod(typeof(XmlQueryOutput), "WriteStartElement", typeof(string), typeof(string), typeof(string));
  305.         public static readonly MethodInfo StartElemLocName = GetMethod(typeof(XmlQueryOutput), "WriteStartElementLocalName", typeof(string));
  306.         public static readonly MethodInfo EndElemStackName = GetMethod(typeof(XmlQueryOutput), "WriteEndElement");
  307.         public static readonly MethodInfo StartAttrLitName = GetMethod(typeof(XmlQueryOutput), "WriteStartAttribute", typeof(string), typeof(string), typeof(string));
  308.         public static readonly MethodInfo StartAttrLocName = GetMethod(typeof(XmlQueryOutput), "WriteStartAttributeLocalName", typeof(string));
  309.         public static readonly MethodInfo EndAttr = GetMethod(typeof(XmlQueryOutput), "WriteEndAttribute");
  310.         public static readonly MethodInfo Text = GetMethod(typeof(XmlQueryOutput), "WriteString");
  311.         public static readonly MethodInfo NoEntText = GetMethod(typeof(XmlQueryOutput), "WriteRaw", typeof(string));
  312.        
  313.         public static readonly MethodInfo StartTree = GetMethod(typeof(XmlQueryOutput), "StartTree");
  314.         public static readonly MethodInfo EndTree = GetMethod(typeof(XmlQueryOutput), "EndTree");
  315.        
  316.         public static readonly MethodInfo StartElemLitNameUn = GetMethod(typeof(XmlQueryOutput), "WriteStartElementUnchecked", typeof(string), typeof(string), typeof(string));
  317.         public static readonly MethodInfo StartElemLocNameUn = GetMethod(typeof(XmlQueryOutput), "WriteStartElementUnchecked", typeof(string));
  318.         public static readonly MethodInfo StartContentUn = GetMethod(typeof(XmlQueryOutput), "StartElementContentUnchecked");
  319.         public static readonly MethodInfo EndElemLitNameUn = GetMethod(typeof(XmlQueryOutput), "WriteEndElementUnchecked", typeof(string), typeof(string), typeof(string));
  320.         public static readonly MethodInfo EndElemLocNameUn = GetMethod(typeof(XmlQueryOutput), "WriteEndElementUnchecked", typeof(string));
  321.         public static readonly MethodInfo StartAttrLitNameUn = GetMethod(typeof(XmlQueryOutput), "WriteStartAttributeUnchecked", typeof(string), typeof(string), typeof(string));
  322.         public static readonly MethodInfo StartAttrLocNameUn = GetMethod(typeof(XmlQueryOutput), "WriteStartAttributeUnchecked", typeof(string));
  323.         public static readonly MethodInfo EndAttrUn = GetMethod(typeof(XmlQueryOutput), "WriteEndAttributeUnchecked");
  324.         public static readonly MethodInfo NamespaceDeclUn = GetMethod(typeof(XmlQueryOutput), "WriteNamespaceDeclarationUnchecked");
  325.         public static readonly MethodInfo TextUn = GetMethod(typeof(XmlQueryOutput), "WriteStringUnchecked");
  326.         public static readonly MethodInfo NoEntTextUn = GetMethod(typeof(XmlQueryOutput), "WriteRawUnchecked");
  327.        
  328.         public static readonly MethodInfo StartRoot = GetMethod(typeof(XmlQueryOutput), "WriteStartRoot");
  329.         public static readonly MethodInfo EndRoot = GetMethod(typeof(XmlQueryOutput), "WriteEndRoot");
  330.         public static readonly MethodInfo StartElemCopyName = GetMethod(typeof(XmlQueryOutput), "WriteStartElementComputed", typeof(XPathNavigator));
  331.         public static readonly MethodInfo StartElemMapName = GetMethod(typeof(XmlQueryOutput), "WriteStartElementComputed", typeof(string), typeof(int));
  332.         public static readonly MethodInfo StartElemNmspName = GetMethod(typeof(XmlQueryOutput), "WriteStartElementComputed", typeof(string), typeof(string));
  333.         public static readonly MethodInfo StartElemQName = GetMethod(typeof(XmlQueryOutput), "WriteStartElementComputed", typeof(XmlQualifiedName));
  334.         public static readonly MethodInfo StartAttrCopyName = GetMethod(typeof(XmlQueryOutput), "WriteStartAttributeComputed", typeof(XPathNavigator));
  335.         public static readonly MethodInfo StartAttrMapName = GetMethod(typeof(XmlQueryOutput), "WriteStartAttributeComputed", typeof(string), typeof(int));
  336.         public static readonly MethodInfo StartAttrNmspName = GetMethod(typeof(XmlQueryOutput), "WriteStartAttributeComputed", typeof(string), typeof(string));
  337.         public static readonly MethodInfo StartAttrQName = GetMethod(typeof(XmlQueryOutput), "WriteStartAttributeComputed", typeof(XmlQualifiedName));
  338.         public static readonly MethodInfo NamespaceDecl = GetMethod(typeof(XmlQueryOutput), "WriteNamespaceDeclaration");
  339.         public static readonly MethodInfo StartComment = GetMethod(typeof(XmlQueryOutput), "WriteStartComment");
  340.         public static readonly MethodInfo CommentText = GetMethod(typeof(XmlQueryOutput), "WriteCommentString");
  341.         public static readonly MethodInfo EndComment = GetMethod(typeof(XmlQueryOutput), "WriteEndComment");
  342.         public static readonly MethodInfo StartPI = GetMethod(typeof(XmlQueryOutput), "WriteStartProcessingInstruction");
  343.         public static readonly MethodInfo PIText = GetMethod(typeof(XmlQueryOutput), "WriteProcessingInstructionString");
  344.         public static readonly MethodInfo EndPI = GetMethod(typeof(XmlQueryOutput), "WriteEndProcessingInstruction");
  345.         public static readonly MethodInfo WriteItem = GetMethod(typeof(XmlQueryOutput), "WriteItem");
  346.         public static readonly MethodInfo CopyOf = GetMethod(typeof(XmlQueryOutput), "XsltCopyOf");
  347.         public static readonly MethodInfo StartCopy = GetMethod(typeof(XmlQueryOutput), "StartCopy");
  348.         public static readonly MethodInfo EndCopy = GetMethod(typeof(XmlQueryOutput), "EndCopy");
  349.        
  350.         // Datatypes
  351.         public static readonly MethodInfo DecAdd = GetMethod(typeof(decimal), "Add");
  352.         public static readonly MethodInfo DecCmp = GetMethod(typeof(decimal), "Compare", typeof(decimal), typeof(decimal));
  353.         public static readonly MethodInfo DecEq = GetMethod(typeof(decimal), "Equals", typeof(decimal), typeof(decimal));
  354.         public static readonly MethodInfo DecSub = GetMethod(typeof(decimal), "Subtract");
  355.         public static readonly MethodInfo DecMul = GetMethod(typeof(decimal), "Multiply");
  356.         public static readonly MethodInfo DecDiv = GetMethod(typeof(decimal), "Divide");
  357.         public static readonly MethodInfo DecRem = GetMethod(typeof(decimal), "Remainder");
  358.         public static readonly MethodInfo DecNeg = GetMethod(typeof(decimal), "Negate");
  359.         public static readonly MethodInfo QNameEq = GetMethod(typeof(XmlQualifiedName), "Equals");
  360.         public static readonly MethodInfo StrEq = GetMethod(typeof(string), "Equals", typeof(string), typeof(string));
  361.         public static readonly MethodInfo StrCat2 = GetMethod(typeof(string), "Concat", typeof(string), typeof(string));
  362.         public static readonly MethodInfo StrCat3 = GetMethod(typeof(string), "Concat", typeof(string), typeof(string), typeof(string));
  363.         public static readonly MethodInfo StrCat4 = GetMethod(typeof(string), "Concat", typeof(string), typeof(string), typeof(string), typeof(string));
  364.         public static readonly MethodInfo StrCmp = GetMethod(typeof(string), "CompareOrdinal", typeof(string), typeof(string));
  365.         public static readonly MethodInfo StrLen = GetMethod(typeof(string), "get_Length");
  366.        
  367.         // XsltConvert
  368.         public static readonly MethodInfo DblToDec = GetMethod(typeof(XsltConvert), "ToDecimal", typeof(double));
  369.         public static readonly MethodInfo DblToInt = GetMethod(typeof(XsltConvert), "ToInt", typeof(double));
  370.         public static readonly MethodInfo DblToLng = GetMethod(typeof(XsltConvert), "ToLong", typeof(double));
  371.         public static readonly MethodInfo DblToStr = GetMethod(typeof(XsltConvert), "ToString", typeof(double));
  372.         public static readonly MethodInfo DecToDbl = GetMethod(typeof(XsltConvert), "ToDouble", typeof(decimal));
  373.         public static readonly MethodInfo DTToStr = GetMethod(typeof(XsltConvert), "ToString", typeof(DateTime));
  374.         public static readonly MethodInfo IntToDbl = GetMethod(typeof(XsltConvert), "ToDouble", typeof(int));
  375.         public static readonly MethodInfo LngToDbl = GetMethod(typeof(XsltConvert), "ToDouble", typeof(long));
  376.         public static readonly MethodInfo StrToDbl = GetMethod(typeof(XsltConvert), "ToDouble", typeof(string));
  377.         public static readonly MethodInfo StrToDT = GetMethod(typeof(XsltConvert), "ToDateTime", typeof(string));
  378.        
  379.         public static readonly MethodInfo ItemToBool = GetMethod(typeof(XsltConvert), "ToBoolean", typeof(XPathItem));
  380.         public static readonly MethodInfo ItemToDbl = GetMethod(typeof(XsltConvert), "ToDouble", typeof(XPathItem));
  381.         public static readonly MethodInfo ItemToStr = GetMethod(typeof(XsltConvert), "ToString", typeof(XPathItem));
  382.         public static readonly MethodInfo ItemToNode = GetMethod(typeof(XsltConvert), "ToNode", typeof(XPathItem));
  383.         public static readonly MethodInfo ItemToNodes = GetMethod(typeof(XsltConvert), "ToNodeSet", typeof(XPathItem));
  384.        
  385.         public static readonly MethodInfo ItemsToBool = GetMethod(typeof(XsltConvert), "ToBoolean", typeof(IList<XPathItem>));
  386.         public static readonly MethodInfo ItemsToDbl = GetMethod(typeof(XsltConvert), "ToDouble", typeof(IList<XPathItem>));
  387.         public static readonly MethodInfo ItemsToNode = GetMethod(typeof(XsltConvert), "ToNode", typeof(IList<XPathItem>));
  388.         public static readonly MethodInfo ItemsToNodes = GetMethod(typeof(XsltConvert), "ToNodeSet", typeof(IList<XPathItem>));
  389.         public static readonly MethodInfo ItemsToStr = GetMethod(typeof(XsltConvert), "ToString", typeof(IList<XPathItem>));
  390.        
  391.         // StringConcat
  392.         public static readonly MethodInfo StrCatCat = GetMethod(typeof(StringConcat), "Concat");
  393.         public static readonly MethodInfo StrCatClear = GetMethod(typeof(StringConcat), "Clear");
  394.         public static readonly MethodInfo StrCatResult = GetMethod(typeof(StringConcat), "GetResult");
  395.         public static readonly MethodInfo StrCatDelim = GetMethod(typeof(StringConcat), "set_Delimiter");
  396.        
  397.         // XmlILStorageConverter
  398.         public static readonly MethodInfo NavsToItems = GetMethod(typeof(XmlILStorageConverter), "NavigatorsToItems");
  399.         public static readonly MethodInfo ItemsToNavs = GetMethod(typeof(XmlILStorageConverter), "ItemsToNavigators");
  400.        
  401.         // XmlQueryNodeSequence
  402.         public static readonly MethodInfo SetDod = GetMethod(typeof(XmlQueryNodeSequence), "set_IsDocOrderDistinct");
  403.        
  404.         // Miscellaneous
  405.         public static readonly MethodInfo GetTypeFromHandle = GetMethod(typeof(Type), "GetTypeFromHandle");
  406.         public static readonly Dictionary<Type, XmlILStorageMethods> StorageMethods;
  407.        
  408.         static XmlILMethods()
  409.         {
  410.             StorageMethods = new Dictionary<Type, XmlILStorageMethods>();
  411.             StorageMethods[typeof(string)] = new XmlILStorageMethods(typeof(string));
  412.             StorageMethods[typeof(bool)] = new XmlILStorageMethods(typeof(bool));
  413.             StorageMethods[typeof(int)] = new XmlILStorageMethods(typeof(int));
  414.             StorageMethods[typeof(long)] = new XmlILStorageMethods(typeof(long));
  415.             StorageMethods[typeof(decimal)] = new XmlILStorageMethods(typeof(decimal));
  416.             StorageMethods[typeof(double)] = new XmlILStorageMethods(typeof(double));
  417.             StorageMethods[typeof(float)] = new XmlILStorageMethods(typeof(float));
  418.             StorageMethods[typeof(DateTime)] = new XmlILStorageMethods(typeof(DateTime));
  419.             StorageMethods[typeof(byte[])] = new XmlILStorageMethods(typeof(byte[]));
  420.             StorageMethods[typeof(XmlQualifiedName)] = new XmlILStorageMethods(typeof(XmlQualifiedName));
  421.             StorageMethods[typeof(TimeSpan)] = new XmlILStorageMethods(typeof(TimeSpan));
  422.             StorageMethods[typeof(XPathItem)] = new XmlILStorageMethods(typeof(XPathItem));
  423.             StorageMethods[typeof(XPathNavigator)] = new XmlILStorageMethods(typeof(XPathNavigator));
  424.         }
  425.        
  426.         public static MethodInfo GetMethod(Type className, string methName)
  427.         {
  428.             MethodInfo methInfo = className.GetMethod(methName);
  429.             Debug.Assert(methInfo != null, "Method " + className.Name + "." + methName + " cannot be null.");
  430.             return methInfo;
  431.         }
  432.        
  433.         public static MethodInfo GetMethod(Type className, string methName, params Type[] args)
  434.         {
  435.             MethodInfo methInfo = className.GetMethod(methName, args);
  436.             Debug.Assert(methInfo != null, "Method " + methName + " cannot be null.");
  437.             return methInfo;
  438.         }
  439.     }
  440.    
  441.    
  442.     /// <summary>
  443.     /// When named nodes are constructed, there are several possible ways for their names to be created.
  444.     /// </summary>
  445.     internal enum GenerateNameType
  446.     {
  447.         LiteralLocalName,
  448.         // Local name is a literal string; namespace is null
  449.         LiteralName,
  450.         // All parts of the name are literal strings
  451.         CopiedName,
  452.         // Name should be copied from a navigator
  453.         TagNameAndMappings,
  454.         // Tagname contains prefix:localName and prefix is mapped to a namespace
  455.         TagNameAndNamespace,
  456.         // Tagname contains prefix:localName and namespace is provided
  457.         QName,
  458.         // Name is computed QName (no prefix available)
  459.         StackName
  460.         // Element name has already been pushed onto XmlQueryOutput stack
  461.     }
  462.    
  463.     /// <summary>
  464.     /// Contains helper methods used during the code generation phase.
  465.     /// </summary>
  466.     internal class GenerateHelper
  467.     {
  468.         private MethodInfo methInfo;
  469.         private ILGenerator ilgen;
  470.         private LocalBuilder locXOut;
  471.         private XmlILModule module;
  472.         private bool isDebug, initWriters;
  473.         private StaticDataManager staticData;
  474.         private ISourceLineInfo lastSourceInfo;
  475.         private MethodInfo methSyncToNav;
  476.        
  477.         #if DEBUG
  478.         private int lblNum;
  479.         private Hashtable symbols;
  480.         private int numLocals;
  481.         private string sourceFile;
  482.         private TextWriter writerDump;
  483.         #endif
  484.        
  485.         /// <summary>
  486.         /// Cache metadata used during code-generation phase.
  487.         /// </summary>
  488.         public GenerateHelper(XmlILModule module, bool isDebug)
  489.         {
  490.             this.isDebug = isDebug;
  491.             this.module = module;
  492.             this.staticData = new StaticDataManager();
  493.            
  494.             #if DEBUG
  495.             if (XmlILTrace.IsEnabled)
  496.                 XmlILTrace.PrepareTraceWriter("dump.il");
  497.             #endif
  498.         }
  499.        
  500.         /// <summary>
  501.         /// Begin generating code within a new method.
  502.         /// </summary>
  503.         public void MethodBegin(MethodInfo methInfo, ISourceLineInfo sourceInfo, bool initWriters)
  504.         {
  505.             this.methInfo = methInfo;
  506.             this.ilgen = XmlILModule.DefineMethodBody(methInfo);
  507.             this.lastSourceInfo = null;
  508.            
  509.             #if DEBUG
  510.             if (XmlILTrace.IsEnabled) {
  511.                 this.numLocals = 0;
  512.                 this.symbols = new Hashtable();
  513.                 this.lblNum = 0;
  514.                 this.sourceFile = null;
  515.                
  516.                 this.writerDump = XmlILTrace.GetTraceWriter("dump.il");
  517.                 this.writerDump.WriteLine(".method {0}()", methInfo.Name);
  518.                 this.writerDump.WriteLine("{");
  519.             }
  520.             #endif
  521.            
  522.             if (this.isDebug) {
  523.                 DebugStartScope();
  524.                
  525.                 // DebugInfo: Sequence point just before generating code for this function
  526.                 if (sourceInfo != null) {
  527.                     MarkSequencePoint(sourceInfo);
  528.                     Emit(OpCodes.Nop);
  529.                 }
  530.             }
  531.            
  532.             this.initWriters = false;
  533.             if (initWriters) {
  534.                 EnsureWriter();
  535.                 LoadQueryRuntime();
  536.                 Call(XmlILMethods.GetOutput);
  537.                 Emit(OpCodes.Stloc, this.locXOut);
  538.             }
  539.         }
  540.        
  541.         /// <summary>
  542.         /// Generate "ret" instruction and branch fixup jump table.
  543.         /// </summary>
  544.         public void MethodEnd()
  545.         {
  546.             Emit(OpCodes.Ret);
  547.            
  548.             #if DEBUG
  549.             if (XmlILTrace.IsEnabled) {
  550.                 this.writerDump.WriteLine("}");
  551.                 this.writerDump.WriteLine("");
  552.                 this.writerDump.Close();
  553.             }
  554.             #endif
  555.            
  556.             if (this.isDebug)
  557.                 DebugEndScope();
  558.         }
  559.        
  560.        
  561.         //-----------------------------------------------
  562.         // Helper Global Methods
  563.         //-----------------------------------------------
  564.        
  565.         /// <summary>
  566.         /// Call a static method which attempts to reuse a navigator.
  567.         /// </summary>
  568.         public void CallSyncToNavigator()
  569.         {
  570.             // Get helper method from module
  571.             if (this.methSyncToNav == null)
  572.                 this.methSyncToNav = this.module.FindMethod("SyncToNavigator");
  573.            
  574.             Call(this.methSyncToNav);
  575.         }
  576.        
  577.         //-----------------------------------------------
  578.         // StaticDataManager
  579.         //-----------------------------------------------
  580.        
  581.         /// <summary>
  582.         /// This internal class manages literal names, literal types, and storage for global variables.
  583.         /// </summary>
  584.         public StaticDataManager StaticData {
  585.             get { return this.staticData; }
  586.         }
  587.        
  588.        
  589.         //-----------------------------------------------
  590.         // Constants
  591.         //-----------------------------------------------
  592.        
  593.         /// <summary>
  594.         /// Generate the optimal Ldc_I4 instruction based on intVal.
  595.         /// </summary>
  596.         public void LoadInteger(int intVal)
  597.         {
  598.             OpCode opcode;
  599.            
  600.             if (intVal >= -1 && intVal < 9) {
  601.                 switch (intVal) {
  602.                     case -1:
  603.                         opcode = OpCodes.Ldc_I4_M1;
  604.                         break;
  605.                     case 0:
  606.                         opcode = OpCodes.Ldc_I4_0;
  607.                         break;
  608.                     case 1:
  609.                         opcode = OpCodes.Ldc_I4_1;
  610.                         break;
  611.                     case 2:
  612.                         opcode = OpCodes.Ldc_I4_2;
  613.                         break;
  614.                     case 3:
  615.                         opcode = OpCodes.Ldc_I4_3;
  616.                         break;
  617.                     case 4:
  618.                         opcode = OpCodes.Ldc_I4_4;
  619.                         break;
  620.                     case 5:
  621.                         opcode = OpCodes.Ldc_I4_5;
  622.                         break;
  623.                     case 6:
  624.                         opcode = OpCodes.Ldc_I4_6;
  625.                         break;
  626.                     case 7:
  627.                         opcode = OpCodes.Ldc_I4_7;
  628.                         break;
  629.                     case 8:
  630.                         opcode = OpCodes.Ldc_I4_8;
  631.                         break;
  632.                     default:
  633.                         Debug.Assert(false);
  634.                         return;
  635.                 }
  636.                 Emit(opcode);
  637.             }
  638.             else if (intVal >= -128 && intVal <= 127)
  639.                 Emit(OpCodes.Ldc_I4_S, (sbyte)intVal);
  640.             else
  641.                 Emit(OpCodes.Ldc_I4, intVal);
  642.         }
  643.        
  644.         public void LoadBoolean(bool boolVal)
  645.         {
  646.             Emit(boolVal ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
  647.         }
  648.        
  649.         public void LoadType(Type clrTyp)
  650.         {
  651.             Emit(OpCodes.Ldtoken, clrTyp);
  652.             Call(XmlILMethods.GetTypeFromHandle);
  653.         }
  654.        
  655.        
  656.         //-----------------------------------------------
  657.         // Local variables
  658.         //-----------------------------------------------
  659.        
  660.         /// <summary>
  661.         /// Generate a new local variable. Add a numeric suffix to name that ensures that all
  662.         /// local variable names will be unique (for readability).
  663.         /// </summary>
  664.         public LocalBuilder DeclareLocal(string name, Type type)
  665.         {
  666.             LocalBuilder locBldr = this.ilgen.DeclareLocal(type);
  667.             #if DEBUG
  668.             if (XmlILTrace.IsEnabled) {
  669.                 // Set name for internal MS debugging. This is not the user-defined name--that will be set later
  670.                 if (this.isDebug)
  671.                     locBldr.SetLocalSymInfo(name + this.numLocals.ToString(CultureInfo.InvariantCulture));
  672.                
  673.                 this.symbols.Add(locBldr, name + this.numLocals.ToString(CultureInfo.InvariantCulture));
  674.                 this.numLocals++;
  675.             }
  676.             #endif
  677.             return locBldr;
  678.         }
  679.        
  680.         public void LoadQueryRuntime()
  681.         {
  682.             Emit(OpCodes.Ldarg_0);
  683.         }
  684.        
  685.         public void LoadQueryContext()
  686.         {
  687.             Emit(OpCodes.Ldarg_0);
  688.             Call(XmlILMethods.Context);
  689.         }
  690.        
  691.         public void LoadXsltLibrary()
  692.         {
  693.             Emit(OpCodes.Ldarg_0);
  694.             Call(XmlILMethods.XsltLib);
  695.         }
  696.        
  697.         public void LoadQueryOutput()
  698.         {
  699.             Emit(OpCodes.Ldloc, this.locXOut);
  700.         }
  701.        
  702.        
  703.         //-----------------------------------------------
  704.         // Parameters
  705.         //-----------------------------------------------
  706.        
  707.         public void LoadParameter(int paramPos)
  708.         {
  709.             switch (paramPos) {
  710.                 case 0:
  711.                     Emit(OpCodes.Ldarg_0);
  712.                     break;
  713.                 case 1:
  714.                     Emit(OpCodes.Ldarg_1);
  715.                     break;
  716.                 case 2:
  717.                     Emit(OpCodes.Ldarg_2);
  718.                     break;
  719.                 case 3:
  720.                     Emit(OpCodes.Ldarg_3);
  721.                     break;
  722.                 default:
  723.                     if (paramPos <= 255) {
  724.                         Emit(OpCodes.Ldarg_S, (byte)paramPos);
  725.                     }
  726.                     else if (paramPos <= ushort.MaxValue) {
  727.                         Emit(OpCodes.Ldarg, paramPos);
  728.                     }
  729.                     else {
  730.                         throw new XslTransformException(Res.XmlIl_TooManyParameters);
  731.                     }
  732.                     break;
  733.             }
  734.         }
  735.        
  736.         public void SetParameter(object paramId)
  737.         {
  738.             int paramPos = (int)paramId;
  739.            
  740.             if (paramPos <= 255) {
  741.                 Emit(OpCodes.Starg_S, (byte)paramPos);
  742.             }
  743.             else if (paramPos <= ushort.MaxValue) {
  744.                 Emit(OpCodes.Starg, (int)paramPos);
  745.             }
  746.             else {
  747.                 throw new XslTransformException(Res.XmlIl_TooManyParameters);
  748.             }
  749.         }
  750.        
  751.         //-----------------------------------------------
  752.         // Labels
  753.         //-----------------------------------------------
  754.        
  755.         /// <summary>
  756.         /// Branch to lblBranch and anchor lblMark. If lblBranch = lblMark, then no need
  757.         /// to generate a "br" to the next instruction.
  758.         /// </summary>
  759.         public void BranchAndMark(Label lblBranch, Label lblMark)
  760.         {
  761.             if (!lblBranch.Equals(lblMark)) {
  762.                 EmitUnconditionalBranch(OpCodes.Br, lblBranch);
  763.             }
  764.             MarkLabel(lblMark);
  765.         }
  766.        
  767.        
  768.         //-----------------------------------------------
  769.         // Comparison
  770.         //-----------------------------------------------
  771.        
  772.         /// <summary>
  773.         /// Compare the top value on the stack with the specified i4 using the specified relational
  774.         /// comparison opcode, and branch to lblBranch if the result is true.
  775.         /// </summary>
  776.         public void TestAndBranch(int i4, Label lblBranch, OpCode opcodeBranch)
  777.         {
  778.             switch (i4) {
  779.                 case 0:
  780.                     // Beq or Bne can be shortened to Brfalse or Brtrue if comparing to 0
  781.                     if (opcodeBranch.Value == OpCodes.Beq.Value)
  782.                         opcodeBranch = OpCodes.Brfalse;
  783.                     else if (opcodeBranch.Value == OpCodes.Beq_S.Value)
  784.                         opcodeBranch = OpCodes.Brfalse_S;
  785.                     else if (opcodeBranch.Value == OpCodes.Bne_Un.Value)
  786.                         opcodeBranch = OpCodes.Brtrue;
  787.                     else if (opcodeBranch.Value == OpCodes.Bne_Un_S.Value)
  788.                         opcodeBranch = OpCodes.Brtrue_S;
  789.                     else
  790.                         goto default;
  791.                     break;
  792.                 default:
  793.                    
  794.                     // Cannot use shortcut, so push integer onto the stack
  795.                     LoadInteger(i4);
  796.                     break;
  797.             }
  798.            
  799.             Emit(opcodeBranch, lblBranch);
  800.         }
  801.        
  802.         /// <summary>
  803.         /// Assume a branch instruction has already been issued. If isTrueBranch is true, then the
  804.         /// true path is linked to lblBranch. Otherwise, the false path is linked to lblBranch.
  805.         /// Convert this "branching" boolean logic into an explicit push of 1 or 0 onto the stack.
  806.         /// </summary>
  807.         public void ConvBranchToBool(Label lblBranch, bool isTrueBranch)
  808.         {
  809.             Label lblDone = DefineLabel();
  810.            
  811.             Emit(isTrueBranch ? OpCodes.Ldc_I4_0 : OpCodes.Ldc_I4_1);
  812.             EmitUnconditionalBranch(OpCodes.Br_S, lblDone);
  813.             MarkLabel(lblBranch);
  814.             Emit(isTrueBranch ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
  815.             MarkLabel(lblDone);
  816.         }
  817.        
  818.        
  819.         //-----------------------------------------------
  820.         // Frequently used method and function calls
  821.         //-----------------------------------------------
  822.        
  823.         public void TailCall(MethodInfo meth)
  824.         {
  825.             Emit(OpCodes.Tailcall);
  826.             Call(meth);
  827.             Emit(OpCodes.Ret);
  828.         }
  829.        
  830.         public void Call(MethodInfo meth)
  831.         {
  832.             OpCode opcode = meth.IsVirtual || meth.IsAbstract ? OpCodes.Callvirt : OpCodes.Call;
  833.            
  834.             #if DEBUG
  835.             if (XmlILTrace.IsEnabled) {
  836.                 StringBuilder strBldr = new StringBuilder();
  837.                 bool isFirst = true;
  838.                 string retType = "";
  839.                
  840.                 if (!(meth is MethodBuilder)) {
  841.                     foreach (ParameterInfo paramInfo in meth.GetParameters()) {
  842.                         if (isFirst)
  843.                             isFirst = false;
  844.                         else
  845.                             strBldr.Append(", ");
  846.                         strBldr.Append(paramInfo.ParameterType.Name);
  847.                     }
  848.                     retType = meth.ReturnType.Name;
  849.                 }
  850.                
  851.                 this.writerDump.WriteLine(" {0, -10} {1} {2}({3})", new object[] {opcode.Name, retType, meth.Name, strBldr.ToString()});
  852.             }
  853.             #endif
  854.             this.ilgen.Emit(opcode, meth);
  855.            
  856.             if (this.lastSourceInfo != null) {
  857.                 MarkSequencePoint(SourceLineInfo.NoSource);
  858.             }
  859.         }
  860.        
  861.         public void CallToken(MethodInfo meth)
  862.         {
  863.             MethodBuilder methBldr = this.methInfo as MethodBuilder;
  864.            
  865.             if (methBldr != null) {
  866.                 // Using regular reflection emit, so get a token for the specified method.
  867.                 // The token is only valid within scope of this method's body.
  868.                 OpCode opcode = meth.IsVirtual || meth.IsAbstract ? OpCodes.Callvirt : OpCodes.Call;
  869.                
  870.                 this.ilgen.Emit(opcode, ((ModuleBuilder)methBldr.GetModule()).GetMethodToken(meth).Token);
  871.                
  872.                 if (this.lastSourceInfo != null) {
  873.                     MarkSequencePoint(SourceLineInfo.NoSource);
  874.                 }
  875.             }
  876.             else {
  877.                 // Using LCG, so no need to workaround
  878.                 Call(meth);
  879.             }
  880.         }
  881.        
  882.         public void Construct(ConstructorInfo constr)
  883.         {
  884.             Emit(OpCodes.Newobj, constr);
  885.         }
  886.        
  887.         public void CallConcatStrings(int cStrings)
  888.         {
  889.             switch (cStrings) {
  890.                 case 0:
  891.                     Emit(OpCodes.Ldstr, "");
  892.                     break;
  893.                 case 1:
  894.                     break;
  895.                 case 2:
  896.                     Call(XmlILMethods.StrCat2);
  897.                     break;
  898.                 case 3:
  899.                     Call(XmlILMethods.StrCat3);
  900.                     break;
  901.                 case 4:
  902.                     Call(XmlILMethods.StrCat4);
  903.                     break;
  904.                 default:
  905.                     Debug.Assert(false, "Shouldn't be called");
  906.                     break;
  907.             }
  908.         }
  909.        
  910.         /// <summary>
  911.         /// Assume that an object reference is on the IL stack. Change the static Clr type from "clrTypeSrc" to "clrTypeDst"
  912.         /// </summary>
  913.         public void TreatAs(Type clrTypeSrc, Type clrTypeDst)
  914.         {
  915.             // If source = destination, then no-op
  916.             if (clrTypeSrc == clrTypeDst)
  917.                 return;
  918.            
  919.             if (clrTypeSrc.IsValueType) {
  920.                 // If source is a value type, then destination may only be typeof(object), so box
  921.                 Debug.Assert(clrTypeDst == typeof(object), "Invalid cast, since value types do not allow inheritance.");
  922.                 Emit(OpCodes.Box, clrTypeSrc);
  923.             }
  924.             else if (clrTypeDst.IsValueType) {
  925.                 // If destination type is value type, then source may only be typeof(object), so unbox
  926.                 Debug.Assert(clrTypeSrc == typeof(object), "Invalid cast, since value types do not allow inheritance.");
  927.                 Emit(OpCodes.Unbox, clrTypeDst);
  928.                 Emit(OpCodes.Ldobj, clrTypeDst);
  929.             }
  930.             else if (clrTypeDst != typeof(object)) {
  931.                 // If source is not a value type, and destination type is typeof(object), then no-op
  932.                 // Otherwise, use Castclass to change the static type
  933.                 Debug.Assert(clrTypeSrc.IsAssignableFrom(clrTypeDst) || clrTypeDst.IsAssignableFrom(clrTypeSrc), "Invalid cast, since source type and destination type are not in same inheritance hierarchy.");
  934.                 Emit(OpCodes.Castclass, clrTypeDst);
  935.             }
  936.         }
  937.        
  938.        
  939.         //-----------------------------------------------
  940.         // Datatype methods
  941.         //-----------------------------------------------
  942.        
  943.         public void ConstructLiteralDecimal(decimal dec)
  944.         {
  945.             if (dec >= (decimal)int.MinValue && dec <= (decimal)int.MaxValue && decimal.Truncate(dec) == dec) {
  946.                 // Decimal can be constructed from a 32-bit integer
  947.                 LoadInteger((int)dec);
  948.                 Construct(XmlILConstructors.DecFromInt32);
  949.             }
  950.             else {
  951.                 int[] bits = Decimal.GetBits(dec);
  952.                
  953.                 LoadInteger(bits[0]);
  954.                 LoadInteger(bits[1]);
  955.                 LoadInteger(bits[2]);
  956.                 LoadBoolean(bits[3] < 0);
  957.                 LoadInteger(bits[3] >> 16);
  958.                 Construct(XmlILConstructors.DecFromParts);
  959.             }
  960.         }
  961.        
  962.         public void ConstructLiteralQName(string localName, string namespaceName)
  963.         {
  964.             Emit(OpCodes.Ldstr, localName);
  965.             Emit(OpCodes.Ldstr, namespaceName);
  966.             Construct(XmlILConstructors.QName);
  967.         }
  968.        
  969.         public void CallArithmeticOp(QilNodeType opType, XmlTypeCode code)
  970.         {
  971.             MethodInfo meth = null;
  972.            
  973.             switch (code) {
  974.                 case XmlTypeCode.Int:
  975.                 case XmlTypeCode.Integer:
  976.                 case XmlTypeCode.Double:
  977.                 case XmlTypeCode.Float:
  978.                     switch (opType) {
  979.                         case QilNodeType.Add:
  980.                             Emit(OpCodes.Add);
  981.                             break;
  982.                         case QilNodeType.Subtract:
  983.                             Emit(OpCodes.Sub);
  984.                             break;
  985.                         case QilNodeType.Multiply:
  986.                             Emit(OpCodes.Mul);
  987.                             break;
  988.                         case QilNodeType.Divide:
  989.                             Emit(OpCodes.Div);
  990.                             break;
  991.                         case QilNodeType.Modulo:
  992.                             Emit(OpCodes.Rem);
  993.                             break;
  994.                         case QilNodeType.Negate:
  995.                             Emit(OpCodes.Neg);
  996.                             break;
  997.                         default:
  998.                             Debug.Assert(false, opType + " must be an arithmetic operation.");
  999.                             break;
  1000.                     }
  1001.                     break;
  1002.                 case XmlTypeCode.Decimal:
  1003.                    
  1004.                     switch (opType) {
  1005.                         case QilNodeType.Add:
  1006.                             meth = XmlILMethods.DecAdd;
  1007.                             break;
  1008.                         case QilNodeType.Subtract:
  1009.                             meth = XmlILMethods.DecSub;
  1010.                             break;
  1011.                         case QilNodeType.Multiply:
  1012.                             meth = XmlILMethods.DecMul;
  1013.                             break;
  1014.                         case QilNodeType.Divide:
  1015.                             meth = XmlILMethods.DecDiv;
  1016.                             break;
  1017.                         case QilNodeType.Modulo:
  1018.                             meth = XmlILMethods.DecRem;
  1019.                             break;
  1020.                         case QilNodeType.Negate:
  1021.                             meth = XmlILMethods.DecNeg;
  1022.                             break;
  1023.                         default:
  1024.                             Debug.Assert(false, opType + " must be an arithmetic operation.");
  1025.                             break;
  1026.                     }
  1027.                    
  1028.                     Call(meth);
  1029.                     break;
  1030.                 default:
  1031.                    
  1032.                     Debug.Assert(false, "The " + opType + " arithmetic operation cannot be performed on values of type " + code + ".");
  1033.                     break;
  1034.             }
  1035.         }
  1036.        
  1037.         public void CallCompareEquals(XmlTypeCode code)
  1038.         {
  1039.             MethodInfo meth = null;
  1040.            
  1041.             switch (code) {
  1042.                 case XmlTypeCode.String:
  1043.                     meth = XmlILMethods.StrEq;
  1044.                     break;
  1045.                 case XmlTypeCode.QName:
  1046.                     meth = XmlILMethods.QNameEq;
  1047.                     break;
  1048.                 case XmlTypeCode.Decimal:
  1049.                     meth = XmlILMethods.DecEq;
  1050.                     break;
  1051.                 default:
  1052.                     Debug.Assert(false, "Type " + code + " does not support the equals operation.");
  1053.                     break;
  1054.             }
  1055.            
  1056.             Call(meth);
  1057.         }
  1058.        
  1059.         public void CallCompare(XmlTypeCode code)
  1060.         {
  1061.             MethodInfo meth = null;
  1062.            
  1063.             switch (code) {
  1064.                 case XmlTypeCode.String:
  1065.                     meth = XmlILMethods.StrCmp;
  1066.                     break;
  1067.                 case XmlTypeCode.Decimal:
  1068.                     meth = XmlILMethods.DecCmp;
  1069.                     break;
  1070.                 default:
  1071.                     Debug.Assert(false, "Type " + code + " does not support the equals operation.");
  1072.                     break;
  1073.             }
  1074.            
  1075.             Call(meth);
  1076.         }
  1077.        
  1078.        
  1079.         //-----------------------------------------------
  1080.         // XmlQueryRuntime function calls
  1081.         //-----------------------------------------------
  1082.        
  1083.         public void CallStartRtfConstruction(string baseUri)
  1084.         {
  1085.             EnsureWriter();
  1086.             LoadQueryRuntime();
  1087.             Emit(OpCodes.Ldstr, baseUri);
  1088.             Emit(OpCodes.Ldloca, this.locXOut);
  1089.             Call(XmlILMethods.StartRtfConstr);
  1090.         }
  1091.        
  1092.         public void CallEndRtfConstruction()
  1093.         {
  1094.             LoadQueryRuntime();
  1095.             Emit(OpCodes.Ldloca, this.locXOut);
  1096.             Call(XmlILMethods.EndRtfConstr);
  1097.         }
  1098.        
  1099.         public void CallStartSequenceConstruction()
  1100.         {
  1101.             EnsureWriter();
  1102.             LoadQueryRuntime();
  1103.             Emit(OpCodes.Ldloca, this.locXOut);
  1104.             Call(XmlILMethods.StartSeqConstr);
  1105.         }
  1106.        
  1107.         public void CallEndSequenceConstruction()
  1108.         {
  1109.             LoadQueryRuntime();
  1110.             Emit(OpCodes.Ldloca, this.locXOut);
  1111.             Call(XmlILMethods.EndSeqConstr);
  1112.         }
  1113.        
  1114.         public void CallGetEarlyBoundObject(int idxObj, Type clrType)
  1115.         {
  1116.             LoadQueryRuntime();
  1117.             LoadInteger(idxObj);
  1118.             Call(XmlILMethods.GetEarly);
  1119.             TreatAs(typeof(object), clrType);
  1120.         }
  1121.        
  1122.         public void CallGetAtomizedName(int idxName)
  1123.         {
  1124.             LoadQueryRuntime();
  1125.             LoadInteger(idxName);
  1126.             Call(XmlILMethods.GetAtomizedName);
  1127.         }
  1128.        
  1129.         public void CallGetNameFilter(int idxFilter)
  1130.         {
  1131.             LoadQueryRuntime();
  1132.             LoadInteger(idxFilter);
  1133.             Call(XmlILMethods.GetNameFilter);
  1134.         }
  1135.        
  1136.         public void CallGetTypeFilter(XPathNodeType nodeType)
  1137.         {
  1138.             LoadQueryRuntime();
  1139.             LoadInteger((int)nodeType);
  1140.             Call(XmlILMethods.GetTypeFilter);
  1141.         }
  1142.        
  1143.         public void CallParseTagName(GenerateNameType nameType)
  1144.         {
  1145.             if (nameType == GenerateNameType.TagNameAndMappings) {
  1146.                 Call(XmlILMethods.TagAndMappings);
  1147.             }
  1148.             else {
  1149.                 Debug.Assert(nameType == GenerateNameType.TagNameAndNamespace);
  1150.                 Call(XmlILMethods.TagAndNamespace);
  1151.             }
  1152.         }
  1153.        
  1154.         public void CallGetGlobalValue(int idxValue, Type clrType)
  1155.         {
  1156.             LoadQueryRuntime();
  1157.             LoadInteger(idxValue);
  1158.             Call(XmlILMethods.GetGlobalValue);
  1159.             TreatAs(typeof(object), clrType);
  1160.         }
  1161.        
  1162.         public void CallSetGlobalValue(Type clrType)
  1163.         {
  1164.             TreatAs(clrType, typeof(object));
  1165.             Call(XmlILMethods.SetGlobalValue);
  1166.         }
  1167.        
  1168.         public void CallGetCollation(int idxName)
  1169.         {
  1170.             LoadQueryRuntime();
  1171.             LoadInteger(idxName);
  1172.             Call(XmlILMethods.GetCollation);
  1173.         }
  1174.        
  1175.         private void EnsureWriter()
  1176.         {
  1177.             // If write variable has not yet been initialized, do it now
  1178.             if (!this.initWriters) {
  1179.                 this.locXOut = DeclareLocal("$$$xwrtChk", typeof(XmlQueryOutput));
  1180.                 this.initWriters = true;
  1181.             }
  1182.         }
  1183.        
  1184.        
  1185.         //-----------------------------------------------
  1186.         // XmlQueryContext function calls
  1187.         //-----------------------------------------------
  1188.        
  1189.         public void CallGetParameter(string localName, string namespaceUri)
  1190.         {
  1191.             LoadQueryContext();
  1192.             Emit(OpCodes.Ldstr, localName);
  1193.             Emit(OpCodes.Ldstr, namespaceUri);
  1194.             Call(XmlILMethods.GetParam);
  1195.         }
  1196.        
  1197.         //-----------------------------------------------
  1198.         // XmlQueryOutput function calls
  1199.         //-----------------------------------------------
  1200.        
  1201.         public void CallStartTree(XPathNodeType rootType)
  1202.         {
  1203.             LoadQueryOutput();
  1204.             LoadInteger((int)rootType);
  1205.             Call(XmlILMethods.StartTree);
  1206.         }
  1207.        
  1208.         public void CallEndTree()
  1209.         {
  1210.             LoadQueryOutput();
  1211.             Call(XmlILMethods.EndTree);
  1212.         }
  1213.        
  1214.         public void CallWriteStartRoot()
  1215.         {
  1216.             // Call XmlQueryOutput.WriteStartRoot
  1217.             LoadQueryOutput();
  1218.             Call(XmlILMethods.StartRoot);
  1219.         }
  1220.        
  1221.         public void CallWriteEndRoot()
  1222.         {
  1223.             // Call XmlQueryOutput.WriteEndRoot
  1224.             LoadQueryOutput();
  1225.             Call(XmlILMethods.EndRoot);
  1226.         }
  1227.        
  1228.         public void CallWriteStartElement(GenerateNameType nameType, bool callChk)
  1229.         {
  1230.             MethodInfo meth = null;
  1231.            
  1232.             // If runtime checks need to be made,
  1233.             if (callChk) {
  1234.                 // Then call XmlQueryOutput.WriteStartElement
  1235.                 switch (nameType) {
  1236.                     case GenerateNameType.LiteralLocalName:
  1237.                         meth = XmlILMethods.StartElemLocName;
  1238.                         break;
  1239.                     case GenerateNameType.LiteralName:
  1240.                         meth = XmlILMethods.StartElemLitName;
  1241.                         break;
  1242.                     case GenerateNameType.CopiedName:
  1243.                         meth = XmlILMethods.StartElemCopyName;
  1244.                         break;
  1245.                     case GenerateNameType.TagNameAndMappings:
  1246.                         meth = XmlILMethods.StartElemMapName;
  1247.                         break;
  1248.                     case GenerateNameType.TagNameAndNamespace:
  1249.                         meth = XmlILMethods.StartElemNmspName;
  1250.                         break;
  1251.                     case GenerateNameType.QName:
  1252.                         meth = XmlILMethods.StartElemQName;
  1253.                         break;
  1254.                     default:
  1255.                         Debug.Assert(false, nameType + " is invalid here.");
  1256.                         break;
  1257.                 }
  1258.             }
  1259.             else {
  1260.                 // Else call XmlQueryOutput.WriteStartElementUnchecked
  1261.                 switch (nameType) {
  1262.                     case GenerateNameType.LiteralLocalName:
  1263.                         meth = XmlILMethods.StartElemLocNameUn;
  1264.                         break;
  1265.                     case GenerateNameType.LiteralName:
  1266.                         meth = XmlILMethods.StartElemLitNameUn;
  1267.                         break;
  1268.                     default:
  1269.                         Debug.Assert(false, nameType + " is invalid here.");
  1270.                         break;
  1271.                 }
  1272.             }
  1273.            
  1274.             Call(meth);
  1275.         }
  1276.        
  1277.         public void CallWriteEndElement(GenerateNameType nameType, bool callChk)
  1278.         {
  1279.             MethodInfo meth = null;
  1280.            
  1281.             // If runtime checks need to be made,
  1282.             if (callChk) {
  1283.                 // Then call XmlQueryOutput.WriteEndElement
  1284.                 meth = XmlILMethods.EndElemStackName;
  1285.             }
  1286.             else {
  1287.                 // Else call XmlQueryOutput.WriteEndElementUnchecked
  1288.                 switch (nameType) {
  1289.                     case GenerateNameType.LiteralLocalName:
  1290.                         meth = XmlILMethods.EndElemLocNameUn;
  1291.                         break;
  1292.                     case GenerateNameType.LiteralName:
  1293.                         meth = XmlILMethods.EndElemLitNameUn;
  1294.                         break;
  1295.                     default:
  1296.                         Debug.Assert(false, nameType + " is invalid here.");
  1297.                         break;
  1298.                 }
  1299.             }
  1300.            
  1301.             Call(meth);
  1302.         }
  1303.        
  1304.         public void CallStartElementContent()
  1305.         {
  1306.             LoadQueryOutput();
  1307.             Call(XmlILMethods.StartContentUn);
  1308.         }
  1309.        
  1310.         public void CallWriteStartAttribute(GenerateNameType nameType, bool callChk)
  1311.         {
  1312.             MethodInfo meth = null;
  1313.            
  1314.             // If runtime checks need to be made,
  1315.             if (callChk) {
  1316.                 // Then call XmlQueryOutput.WriteStartAttribute
  1317.                 switch (nameType) {
  1318.                     case GenerateNameType.LiteralLocalName:
  1319.                         meth = XmlILMethods.StartAttrLocName;
  1320.                         break;
  1321.                     case GenerateNameType.LiteralName:
  1322.                         meth = XmlILMethods.StartAttrLitName;
  1323.                         break;
  1324.                     case GenerateNameType.CopiedName:
  1325.                         meth = XmlILMethods.StartAttrCopyName;
  1326.                         break;
  1327.                     case GenerateNameType.TagNameAndMappings:
  1328.                         meth = XmlILMethods.StartAttrMapName;
  1329.                         break;
  1330.                     case GenerateNameType.TagNameAndNamespace:
  1331.                         meth = XmlILMethods.StartAttrNmspName;
  1332.                         break;
  1333.                     case GenerateNameType.QName:
  1334.                         meth = XmlILMethods.StartAttrQName;
  1335.                         break;
  1336.                     default:
  1337.                         Debug.Assert(false, nameType + " is invalid here.");
  1338.                         break;
  1339.                 }
  1340.             }
  1341.             else {
  1342.                 // Else call XmlQueryOutput.WriteStartAttributeUnchecked
  1343.                 switch (nameType) {
  1344.                     case GenerateNameType.LiteralLocalName:
  1345.                         meth = XmlILMethods.StartAttrLocNameUn;
  1346.                         break;
  1347.                     case GenerateNameType.LiteralName:
  1348.                         meth = XmlILMethods.StartAttrLitNameUn;
  1349.                         break;
  1350.                     default:
  1351.                         Debug.Assert(false, nameType + " is invalid here.");
  1352.                         break;
  1353.                 }
  1354.             }
  1355.            
  1356.             Call(meth);
  1357.         }
  1358.        
  1359.         public void CallWriteEndAttribute(bool callChk)
  1360.         {
  1361.             LoadQueryOutput();
  1362.            
  1363.             // If runtime checks need to be made,
  1364.             if (callChk) {
  1365.                 // Then call XmlQueryOutput.WriteEndAttribute
  1366.                 Call(XmlILMethods.EndAttr);
  1367.             }
  1368.             else {
  1369.                 // Else call XmlQueryOutput.WriteEndAttributeUnchecked
  1370.                 Call(XmlILMethods.EndAttrUn);
  1371.             }
  1372.         }
  1373.        
  1374.         public void CallWriteNamespaceDecl(bool callChk)
  1375.         {
  1376.             // If runtime checks need to be made,
  1377.             if (callChk) {
  1378.                 // Then call XmlQueryOutput.WriteNamespaceDeclaration
  1379.                 Call(XmlILMethods.NamespaceDecl);
  1380.             }
  1381.             else {
  1382.                 // Else call XmlQueryOutput.WriteNamespaceDeclarationUnchecked
  1383.                 Call(XmlILMethods.NamespaceDeclUn);
  1384.             }
  1385.         }
  1386.        
  1387.         public void CallWriteString(bool disableOutputEscaping, bool callChk)
  1388.         {
  1389.             // If runtime checks need to be made,
  1390.             if (callChk) {
  1391.                 // Then call XmlQueryOutput.WriteString, or XmlQueryOutput.WriteRaw
  1392.                 if (disableOutputEscaping)
  1393.                     Call(XmlILMethods.NoEntText);
  1394.                 else
  1395.                     Call(XmlILMethods.Text);
  1396.             }
  1397.             else {
  1398.                 // Else call XmlQueryOutput.WriteStringUnchecked, or XmlQueryOutput.WriteRawUnchecked
  1399.                 if (disableOutputEscaping)
  1400.                     Call(XmlILMethods.NoEntTextUn);
  1401.                 else
  1402.                     Call(XmlILMethods.TextUn);
  1403.             }
  1404.         }
  1405.        
  1406.         public void CallWriteStartPI()
  1407.         {
  1408.             Call(XmlILMethods.StartPI);
  1409.         }
  1410.        
  1411.         public void CallWriteEndPI()
  1412.         {
  1413.             LoadQueryOutput();
  1414.             Call(XmlILMethods.EndPI);
  1415.         }
  1416.        
  1417.         public void CallWriteStartComment()
  1418.         {
  1419.             LoadQueryOutput();
  1420.             Call(XmlILMethods.StartComment);
  1421.         }
  1422.        
  1423.         public void CallWriteEndComment()
  1424.         {
  1425.             LoadQueryOutput();
  1426.             Call(XmlILMethods.EndComment);
  1427.         }
  1428.        
  1429.        
  1430.         //-----------------------------------------------
  1431.         // Item caching methods
  1432.         //-----------------------------------------------
  1433.        
  1434.         public void CallCacheCount(Type itemStorageType)
  1435.         {
  1436.             XmlILStorageMethods meth = XmlILMethods.StorageMethods[itemStorageType];
  1437.             Call(meth.IListCount);
  1438.         }
  1439.        
  1440.         public void CallCacheItem(Type itemStorageType)
  1441.         {
  1442.             Call(XmlILMethods.StorageMethods[itemStorageType].IListItem);
  1443.         }
  1444.        
  1445.        
  1446.         //-----------------------------------------------
  1447.         // XPathItem properties and methods
  1448.         //-----------------------------------------------
  1449.        
  1450.         public void CallValueAs(Type clrType)
  1451.         {
  1452.             MethodInfo meth;
  1453.            
  1454.             meth = XmlILMethods.StorageMethods[clrType].ValueAs;
  1455.             if (meth == null) {
  1456.                 // Call (Type) item.ValueAs(Type, null)
  1457.                 LoadType(clrType);
  1458.                 Emit(OpCodes.Ldnull);
  1459.                 Call(XmlILMethods.ValueAsAny);
  1460.                
  1461.                 // Unbox or down-cast
  1462.                 TreatAs(typeof(object), clrType);
  1463.             }
  1464.             else {
  1465.                 // Call strongly typed ValueAs method
  1466.                 Call(meth);
  1467.             }
  1468.         }
  1469.        
  1470.        
  1471.         //-----------------------------------------------
  1472.         // XmlSortKeyAccumulator methods
  1473.         //-----------------------------------------------
  1474.        
  1475.         public void AddSortKey(XmlQueryType keyType)
  1476.         {
  1477.             MethodInfo meth = null;
  1478.            
  1479.             if (keyType == null) {
  1480.                 meth = XmlILMethods.SortKeyEmpty;
  1481.             }
  1482.             else {
  1483.                 Debug.Assert(keyType.IsAtomicValue, "Sort key must have atomic value type.");
  1484.                
  1485.                 switch (keyType.TypeCode) {
  1486.                     case XmlTypeCode.String:
  1487.                         meth = XmlILMethods.SortKeyString;
  1488.                         break;
  1489.                     case XmlTypeCode.Decimal:
  1490.                         meth = XmlILMethods.SortKeyDecimal;
  1491.                         break;
  1492.                     case XmlTypeCode.Integer:
  1493.                         meth = XmlILMethods.SortKeyInteger;
  1494.                         break;
  1495.                     case XmlTypeCode.Int:
  1496.                         meth = XmlILMethods.SortKeyInt;
  1497.                         break;
  1498.                     case XmlTypeCode.Boolean:
  1499.                         meth = XmlILMethods.SortKeyInt;
  1500.                         break;
  1501.                     case XmlTypeCode.Double:
  1502.                         meth = XmlILMethods.SortKeyDouble;
  1503.                         break;
  1504.                     case XmlTypeCode.DateTime:
  1505.                         meth = XmlILMethods.SortKeyDateTime;
  1506.                         break;
  1507.                     case XmlTypeCode.None:
  1508.                        
  1509.                         // Empty sequence, so this path will never actually be taken
  1510.                         Emit(OpCodes.Pop);
  1511.                         meth = XmlILMethods.SortKeyEmpty;
  1512.                         break;
  1513.                     case XmlTypeCode.AnyAtomicType:
  1514.                        
  1515.                         Debug.Assert(false, "Heterogenous sort key is not allowed.");
  1516.                         return;
  1517.                     default:
  1518.                        
  1519.                         Debug.Assert(false, "Sorting over datatype " + keyType.TypeCode + " is not allowed.");
  1520.                         break;
  1521.                 }
  1522.             }
  1523.            
  1524.             Call(meth);
  1525.         }
  1526.        
  1527.        
  1528.         //-----------------------------------------------
  1529.         // Debugging information output
  1530.         //-----------------------------------------------
  1531.        
  1532.         /// <summary>
  1533.         /// Begin a new variable debugging scope.
  1534.         /// </summary>
  1535.         public void DebugStartScope()
  1536.         {
  1537.             this.ilgen.BeginScope();
  1538.         }
  1539.        
  1540.         /// <summary>
  1541.         /// End a new debugging scope.
  1542.         /// </summary>
  1543.         public void DebugEndScope()
  1544.         {
  1545.             this.ilgen.EndScope();
  1546.         }
  1547.        
  1548.         /// <summary>
  1549.         /// Correlate the current IL generation position with the current source position.
  1550.         /// </summary>
  1551.         public void DebugSequencePoint(ISourceLineInfo sourceInfo)
  1552.         {
  1553.             Debug.Assert(this.isDebug && this.lastSourceInfo != null);
  1554.             Debug.Assert(sourceInfo != null);
  1555.            
  1556.             Emit(OpCodes.Nop);
  1557.             MarkSequencePoint(sourceInfo);
  1558.         }
  1559.        
  1560.         private string lastUriString = null;
  1561.         private string lastFileName = null;
  1562.        
  1563.         private string GetFileName(string uriString)
  1564.         {
  1565.             if ((object)uriString == (object)lastUriString) {
  1566.                 return lastFileName;
  1567.             }
  1568.            
  1569.             Uri uri;
  1570.            
  1571.             if (uriString.Length != 0 && Uri.TryCreate(uriString, UriKind.Absolute, out uri) && uri.IsFile) {
  1572.                 lastFileName = uri.LocalPath;
  1573.             }
  1574.             else {
  1575.                 lastFileName = uriString;
  1576.             }
  1577.             lastUriString = uriString;
  1578.             return lastFileName;
  1579.         }
  1580.        
  1581.         private void MarkSequencePoint(ISourceLineInfo sourceInfo)
  1582.         {
  1583.             Debug.Assert(this.isDebug);
  1584.            
  1585.             // Do not emit adjacent 0xfeefee sequence points, as that slows down stepping in the debugger
  1586.             if (sourceInfo.IsNoSource && this.lastSourceInfo != null && this.lastSourceInfo.IsNoSource) {
  1587.                 return;
  1588.             }
  1589.            
  1590.             string sourceFile = GetFileName(sourceInfo.Uri);
  1591.            
  1592.             #if DEBUG
  1593.             if (XmlILTrace.IsEnabled) {
  1594.                 if (sourceInfo.IsNoSource)
  1595.                     this.writerDump.WriteLine("//[no source]");
  1596.                 else {
  1597.                     if (sourceFile != this.sourceFile) {
  1598.                         this.sourceFile = sourceFile;
  1599.                         this.writerDump.WriteLine("// Source File '{0}'", this.sourceFile);
  1600.                     }
  1601.                     this.writerDump.WriteLine("//[{0},{1} -- {2},{3}]", sourceInfo.StartLine, sourceInfo.StartPos, sourceInfo.EndLine, sourceInfo.EndPos);
  1602.                 }
  1603.             }
  1604.             #endif
  1605.             ISymbolDocumentWriter symDoc = this.module.AddSourceDocument(sourceFile);
  1606.             this.ilgen.MarkSequencePoint(symDoc, sourceInfo.StartLine, sourceInfo.StartPos, sourceInfo.EndLine, sourceInfo.EndPos);
  1607.             this.lastSourceInfo = sourceInfo;
  1608.         }
  1609.        
  1610.        
  1611.         //-----------------------------------------------
  1612.         // Pass through to ILGenerator
  1613.         //-----------------------------------------------
  1614.        
  1615.         public Label DefineLabel()
  1616.         {
  1617.             Label lbl = this.ilgen.DefineLabel();
  1618.            
  1619.             #if DEBUG
  1620.             if (XmlILTrace.IsEnabled)
  1621.                 this.symbols.Add(lbl, ++this.lblNum);
  1622.             #endif
  1623.            
  1624.             return lbl;
  1625.         }
  1626.        
  1627.         public void MarkLabel(Label lbl)
  1628.         {
  1629.             if (this.lastSourceInfo != null) {
  1630.                 DebugSequencePoint(SourceLineInfo.NoSource);
  1631.             }
  1632.            
  1633.             #if DEBUG
  1634.             if (XmlILTrace.IsEnabled)
  1635.                 this.writerDump.WriteLine("Label {0}:", this.symbols[lbl]);
  1636.             #endif
  1637.            
  1638.             this.ilgen.MarkLabel(lbl);
  1639.         }
  1640.        
  1641.         public void Emit(OpCode opcode)
  1642.         {
  1643.             #if DEBUG
  1644.             if (XmlILTrace.IsEnabled)
  1645.                 this.writerDump.WriteLine(" {0}", opcode.Name);
  1646.             #endif
  1647.             this.ilgen.Emit(opcode);
  1648.         }
  1649.        
  1650.         public void Emit(OpCode opcode, byte byteVal)
  1651.         {
  1652.             #if DEBUG
  1653.             if (XmlILTrace.IsEnabled)
  1654.                 this.writerDump.WriteLine(" {0, -10} {1}", opcode.Name, byteVal);
  1655.             #endif
  1656.             this.ilgen.Emit(opcode, byteVal);
  1657.         }
  1658.        
  1659.         public void Emit(OpCode opcode, ConstructorInfo constrInfo)
  1660.         {
  1661.             #if DEBUG
  1662.             if (XmlILTrace.IsEnabled)
  1663.                 this.writerDump.WriteLine(" {0, -10} {1}", opcode.Name, constrInfo);
  1664.             #endif
  1665.             this.ilgen.Emit(opcode, constrInfo);
  1666.         }
  1667.        
  1668.         public void Emit(OpCode opcode, double dblVal)
  1669.         {
  1670.             #if DEBUG
  1671.             if (XmlILTrace.IsEnabled)
  1672.                 this.writerDump.WriteLine(" {0, -10} {1}", opcode.Name, dblVal);
  1673.             #endif
  1674.             this.ilgen.Emit(opcode, dblVal);
  1675.         }
  1676.        
  1677.         public void Emit(OpCode opcode, float fltVal)
  1678.         {
  1679.             #if DEBUG
  1680.             if (XmlILTrace.IsEnabled)
  1681.                 this.writerDump.WriteLine(" {0, -10} {1}", opcode.Name, fltVal);
  1682.             #endif
  1683.             this.ilgen.Emit(opcode, fltVal);
  1684.         }
  1685.        
  1686.         public void Emit(OpCode opcode, FieldInfo fldInfo)
  1687.         {
  1688.             #if DEBUG
  1689.             if (XmlILTrace.IsEnabled)
  1690.                 this.writerDump.WriteLine(" {0, -10} {1}", opcode.Name, fldInfo.Name);
  1691.             #endif
  1692.             this.ilgen.Emit(opcode, fldInfo);
  1693.         }
  1694.        
  1695.         public void Emit(OpCode opcode, short shrtVal)
  1696.         {
  1697.             Debug.Assert(opcode.OperandType == OperandType.ShortInlineI);
  1698.             #if DEBUG
  1699.             if (XmlILTrace.IsEnabled)
  1700.                 this.writerDump.WriteLine(" {0, -10} {1}", opcode.Name, shrtVal);
  1701.             #endif
  1702.             this.ilgen.Emit(opcode, shrtVal);
  1703.         }
  1704.        
  1705.         public void Emit(OpCode opcode, int intVal)
  1706.         {
  1707.             Debug.Assert(opcode.OperandType == OperandType.InlineI || opcode.OperandType == OperandType.InlineVar);
  1708.             #if DEBUG
  1709.             if (XmlILTrace.IsEnabled)
  1710.                 this.writerDump.WriteLine(" {0, -10} {1}", opcode.Name, intVal);
  1711.             #endif
  1712.             this.ilgen.Emit(opcode, intVal);
  1713.         }
  1714.        
  1715.         public void Emit(OpCode opcode, long longVal)
  1716.         {
  1717.             Debug.Assert(opcode.OperandType == OperandType.InlineI8);
  1718.             #if DEBUG
  1719.             if (XmlILTrace.IsEnabled)
  1720.                 this.writerDump.WriteLine(" {0, -10} {1}", opcode.Name, longVal);
  1721.             #endif
  1722.             this.ilgen.Emit(opcode, longVal);
  1723.         }
  1724.        
  1725.         public void Emit(OpCode opcode, Label lblVal)
  1726.         {
  1727.             Debug.Assert(!opcode.Equals(OpCodes.Br) && !opcode.Equals(OpCodes.Br_S), "Use EmitUnconditionalBranch and be careful not to emit unverifiable code.");
  1728.             #if DEBUG
  1729.             if (XmlILTrace.IsEnabled)
  1730.                 this.writerDump.WriteLine(" {0, -10} Label {1}", opcode.Name, this.symbols[lblVal]);
  1731.             #endif
  1732.             this.ilgen.Emit(opcode, lblVal);
  1733.         }
  1734.        
  1735.         public void Emit(OpCode opcode, Label[] arrLabels)
  1736.         {
  1737.             #if DEBUG
  1738.             if (XmlILTrace.IsEnabled) {
  1739.                 this.writerDump.Write(" {0, -10} (Label {1}", opcode.Name, arrLabels.Length != 0 ? this.symbols[arrLabels[0]].ToString() : "");
  1740.                 for (int i = 1; i < arrLabels.Length; i++) {
  1741.                     this.writerDump.Write(", Label {0}", this.symbols[arrLabels[i]]);
  1742.                 }
  1743.                 this.writerDump.WriteLine(")");
  1744.             }
  1745.             #endif
  1746.             this.ilgen.Emit(opcode, arrLabels);
  1747.         }
  1748.        
  1749.         public void Emit(OpCode opcode, LocalBuilder locBldr)
  1750.         {
  1751.             #if DEBUG
  1752.             if (XmlILTrace.IsEnabled)
  1753.                 this.writerDump.WriteLine(" {0, -10} {1} ({2})", opcode.Name, this.symbols[locBldr], locBldr.LocalType.Name);
  1754.             #endif
  1755.             this.ilgen.Emit(opcode, locBldr);
  1756.         }
  1757.        
  1758.         public void Emit(OpCode opcode, MethodInfo methInfo)
  1759.         {
  1760.             Debug.Assert(!opcode.Equals(OpCodes.Call) && !opcode.Equals(OpCodes.Callvirt), "Use Call so that debug information will be output correctly.");
  1761.             #if DEBUG
  1762.             if (XmlILTrace.IsEnabled)
  1763.                 this.writerDump.WriteLine(" {0, -10} {1}", opcode.Name, methInfo.Name);
  1764.             #endif
  1765.             this.ilgen.Emit(opcode, methInfo);
  1766.         }
  1767.        
  1768.         public void Emit(OpCode opcode, sbyte sbyteVal)
  1769.         {
  1770.             #if DEBUG
  1771.             if (XmlILTrace.IsEnabled)
  1772.                 this.writerDump.WriteLine(" {0, -10} {1}", opcode.Name, sbyteVal);
  1773.             #endif
  1774.             this.ilgen.Emit(opcode, sbyteVal);
  1775.         }
  1776.        
  1777.         public void Emit(OpCode opcode, string strVal)
  1778.         {
  1779.             #if DEBUG
  1780.             if (XmlILTrace.IsEnabled)
  1781.                 this.writerDump.WriteLine(" {0, -10} \"{1}\"", opcode.Name, strVal);
  1782.             #endif
  1783.             this.ilgen.Emit(opcode, strVal);
  1784.         }
  1785.        
  1786.         public void Emit(OpCode opcode, Type typVal)
  1787.         {
  1788.             #if DEBUG
  1789.             if (XmlILTrace.IsEnabled)
  1790.                 this.writerDump.WriteLine(" {0, -10} {1}", opcode.Name, typVal);
  1791.             #endif
  1792.             this.ilgen.Emit(opcode, typVal);
  1793.         }
  1794.        
  1795.         /// <summary>
  1796.         /// Unconditional branch opcodes (OpCode.Br, OpCode.Br_S) can lead to unverifiable code in the following cases:
  1797.         ///
  1798.         /// # DEAD CODE CASE
  1799.         /// ldc_i4 1 # Stack depth == 1
  1800.         /// br Label2
  1801.         /// Label1:
  1802.         /// nop # Dead code, so IL rules assume stack depth == 0. This causes a verification error,
  1803.         /// # since next instruction has depth == 1
  1804.         /// Label2:
  1805.         /// pop # Stack depth == 1
  1806.         /// ret
  1807.         ///
  1808.         /// # LATE BRANCH CASE
  1809.         /// ldc_i4 1 # Stack depth == 1
  1810.         /// br Label2
  1811.         /// Label1:
  1812.         /// nop # Not dead code, but since branch comes from below, IL rules assume stack depth = 0.
  1813.         /// # This causes a verification error, since next instruction has depth == 1
  1814.         /// Label2:
  1815.         /// pop # Stack depth == 1
  1816.         /// ret
  1817.         /// Label3:
  1818.         /// br Label1 # Stack depth == 1
  1819.         ///
  1820.         /// This method works around the above limitations by using Brtrue or Brfalse in the following way:
  1821.         ///
  1822.         /// ldc_i4 1 # Since this test is always true, this is a way of creating a path to the code that
  1823.         /// brtrue Label # follows the brtrue instruction.
  1824.         ///
  1825.         /// ldc_i4 1 # Since this test is always false, this is a way of creating a path to the code that
  1826.         /// brfalse Label # starts at Label.
  1827.         ///
  1828.         /// 1. If opcode == Brtrue or Brtrue_S, then 1 will be pushed and brtrue instruction will be generated.
  1829.         /// 2. If opcode == Brfalse or Brfalse_S, then 1 will be pushed and brfalse instruction will be generated.
  1830.         /// 3. If opcode == Br or Br_S, then a br instruction will be generated.
  1831.         /// </summary>
  1832.         public void EmitUnconditionalBranch(OpCode opcode, Label lblTarget)
  1833.         {
  1834.             if (!opcode.Equals(OpCodes.Br) && !opcode.Equals(OpCodes.Br_S)) {
  1835.                 Debug.Assert(opcode.Equals(OpCodes.Brtrue) || opcode.Equals(OpCodes.Brtrue_S) || opcode.Equals(OpCodes.Brfalse) || opcode.Equals(OpCodes.Brfalse_S));
  1836.                 Emit(OpCodes.Ldc_I4_1);
  1837.             }
  1838.            
  1839.             #if DEBUG
  1840.             if (XmlILTrace.IsEnabled)
  1841.                 this.writerDump.WriteLine(" {0, -10} Label {1}", opcode.Name, this.symbols[lblTarget]);
  1842.             #endif
  1843.             this.ilgen.Emit(opcode, lblTarget);
  1844.         }
  1845.     }
  1846. }

Developer Fusion