public XmlQueryStaticData(XmlWriterSettings defaultWriterSettings, IList <WhitespaceRule> whitespaceRules, StaticDataManager staticData)
        {
            Debug.Assert(defaultWriterSettings != null && staticData != null);
            _defaultWriterSettings = defaultWriterSettings;
            _whitespaceRules       = whitespaceRules;
            _names = staticData.Names;
            _prefixMappingsList = staticData.PrefixMappingsList;
            _filters            = staticData.NameFilters;
            _types       = staticData.XmlTypes;
            _collations  = staticData.Collations;
            _globalNames = staticData.GlobalNames;
            _earlyBound  = staticData.EarlyBound;

#if DEBUG
            // Round-trip check
            byte[] data;
            Type[]? ebTypes;
            this.GetObjectData(out data, out ebTypes);
            XmlQueryStaticData copy = new XmlQueryStaticData(data, ebTypes);

            _defaultWriterSettings = copy._defaultWriterSettings;
            _whitespaceRules       = copy._whitespaceRules;
            _names = copy._names;
            _prefixMappingsList = copy._prefixMappingsList;
            _filters            = copy._filters;
            _types       = copy._types;
            _collations  = copy._collations;
            _globalNames = copy._globalNames;
            _earlyBound  = copy._earlyBound;
#endif
        }
Beispiel #2
0
        /// <summary>
        /// Constructor.
        /// </summary>
        public XmlQueryStaticData(XmlWriterSettings defaultWriterSettings, IList<WhitespaceRule> whitespaceRules, StaticDataManager staticData)
        {
            Debug.Assert(defaultWriterSettings != null && staticData != null);
            _defaultWriterSettings = defaultWriterSettings;
            _whitespaceRules = whitespaceRules;
            _names = staticData.Names;
            _prefixMappingsList = staticData.PrefixMappingsList;
            _filters = staticData.NameFilters;
            _types = staticData.XmlTypes;
            _collations = staticData.Collations;
            _globalNames = staticData.GlobalNames;
            _earlyBound = staticData.EarlyBound;

#if DEBUG
            // Round-trip check
            byte[] data;
            Type[] ebTypes;
            this.GetObjectData(out data, out ebTypes);
            XmlQueryStaticData copy = new XmlQueryStaticData(data, ebTypes);

            _defaultWriterSettings = copy._defaultWriterSettings;
            _whitespaceRules = copy._whitespaceRules;
            _names = copy._names;
            _prefixMappingsList = copy._prefixMappingsList;
            _filters = copy._filters;
            _types = copy._types;
            _collations = copy._collations;
            _globalNames = copy._globalNames;
            _earlyBound = copy._earlyBound;
#endif
        }
        //-----------------------------------------------
        // Constructors
        //-----------------------------------------------

        /// <summary>
        /// This constructor is internal so that external users cannot construct it (and therefore we do not have to test it separately).
        /// </summary>
        internal XmlQueryRuntime(XmlQueryStaticData data, object defaultDataSource, XmlResolver dataSources, XsltArgumentList argList, XmlSequenceWriter seqWrt)
        {
            Debug.Assert(data != null);
            string[]             names   = data.Names;
            Int32Pair[]          filters = data.Filters;
            WhitespaceRuleLookup wsRules;
            int i;

            // Early-Bound Library Objects
            wsRules       = (data.WhitespaceRules != null && data.WhitespaceRules.Count != 0) ? new WhitespaceRuleLookup(data.WhitespaceRules) : null;
            _ctxt         = new XmlQueryContext(this, defaultDataSource, dataSources, argList, wsRules);
            _xsltLib      = null;
            _earlyInfo    = data.EarlyBound;
            _earlyObjects = (_earlyInfo != null) ? new object[_earlyInfo.Length] : null;

            // Global variables and parameters
            _globalNames  = data.GlobalNames;
            _globalValues = (_globalNames != null) ? new object[_globalNames.Length] : null;

            // Names
            _nameTableQuery = _ctxt.QueryNameTable;
            _atomizedNames  = null;

            if (names != null)
            {
                // Atomize all names in "nameTableQuery".  Use names from the default data source's
                // name table when possible.
                XmlNameTable nameTableDefault = _ctxt.DefaultNameTable;
                _atomizedNames = new string[names.Length];

                if (nameTableDefault != _nameTableQuery && nameTableDefault != null)
                {
                    // Ensure that atomized names from the default data source are added to the
                    // name table used in this query
                    for (i = 0; i < names.Length; i++)
                    {
                        string name = nameTableDefault.Get(names[i]);
                        _atomizedNames[i] = _nameTableQuery.Add(name ?? names[i]);
                    }
                }
                else
                {
                    // Enter names into nametable used in this query
                    for (i = 0; i < names.Length; i++)
                    {
                        _atomizedNames[i] = _nameTableQuery.Add(names[i]);
                    }
                }
            }

            // Name filters
            _filters = null;
            if (filters != null)
            {
                // Construct name filters.  Each pair of integers in the filters[] array specifies the
                // (localName, namespaceUri) of the NameFilter to be created.
                _filters = new XmlNavigatorFilter[filters.Length];

                for (i = 0; i < filters.Length; i++)
                {
                    _filters[i] = XmlNavNameFilter.Create(_atomizedNames[filters[i].Left], _atomizedNames[filters[i].Right]);
                }
            }

            // Prefix maping lists
            _prefixMappingsList = data.PrefixMappingsList;

            // Xml types
            _types = data.Types;

            // Xml collations
            _collations = data.Collations;

            // Document ordering
            _docOrderCmp = new DocumentOrderComparer();

            // Indexes
            _indexes = null;

            // Output construction
            _stkOutput = new Stack <XmlQueryOutput>(16);
            _output    = new XmlQueryOutput(this, seqWrt);
        }
Beispiel #4
0
 /// <summary>
 /// Constructor.
 /// </summary>
 public XmlILCommand(ExecuteDelegate delExec, XmlQueryStaticData staticData)
 {
     Debug.Assert(delExec != null && staticData != null);
     _delExec = delExec;
     _staticData = staticData;
 }
Beispiel #5
0
        /// <summary>
        /// Given the logical query plan (QilExpression) generate a physical query plan (MSIL) that can be executed.
        /// </summary>
        // SxS Note: The way the trace file names are created (hardcoded) is NOT SxS safe. However the files are
        // created only for internal tracing purposes. In addition XmlILTrace class is not compiled into retail 
        // builds. As a result it is fine to suppress the FxCop SxS warning.
        public XmlILCommand Generate(QilExpression query, TypeBuilder typeBldr)
        {
            _qil = query;

            bool useLRE = (
                !_qil.IsDebug &&
                (typeBldr == null)
#if DEBUG
                && !XmlILTrace.IsEnabled // Dump assembly to disk; can't do this when using LRE
#endif
            );
            bool emitSymbols = _qil.IsDebug;

            // In debug code, ensure that input QIL is correct
            QilValidationVisitor.Validate(_qil);

#if DEBUG
            // Trace Qil before optimization
            XmlILTrace.WriteQil(this.qil, "qilbefore.xml");

            // Trace optimizations
            XmlILTrace.TraceOptimizations(this.qil, "qilopt.xml");
#endif

            // Optimize and annotate the Qil graph
            _optVisitor = new XmlILOptimizerVisitor(_qil, !_qil.IsDebug);
            _qil = _optVisitor.Optimize();

            // In debug code, ensure that output QIL is correct
            QilValidationVisitor.Validate(_qil);

#if DEBUG
            // Trace Qil after optimization
            XmlILTrace.WriteQil(this.qil, "qilafter.xml");
#endif

            // Create module in which methods will be generated
            if (typeBldr != null)
            {
                _module = new XmlILModule(typeBldr);
            }
            else
            {
                _module = new XmlILModule(useLRE, emitSymbols);
            }

            // Create a code generation helper for the module; enable optimizations if IsDebug is false
            _helper = new GenerateHelper(_module, _qil.IsDebug);

            // Create helper methods
            CreateHelperFunctions();

            // Create metadata for the Execute function, which is the entry point to the query
            // public static void Execute(XmlQueryRuntime);
            MethodInfo methExec = _module.DefineMethod("Execute", typeof(void), new Type[] { }, new string[] { }, XmlILMethodAttributes.NonUser);

            // Create metadata for the root expression
            // public void Root()
            Debug.Assert(_qil.Root != null);
            XmlILMethodAttributes methAttrs = (_qil.Root.SourceLine == null) ? XmlILMethodAttributes.NonUser : XmlILMethodAttributes.None;
            MethodInfo methRoot = _module.DefineMethod("Root", typeof(void), new Type[] { }, new string[] { }, methAttrs);

            // Declare all early bound function objects
            foreach (EarlyBoundInfo info in _qil.EarlyBoundTypes)
            {
                _helper.StaticData.DeclareEarlyBound(info.NamespaceUri, info.EarlyBoundType);
            }

            // Create metadata for each QilExpression function that has at least one caller
            CreateFunctionMetadata(_qil.FunctionList);

            // Create metadata for each QilExpression global variable and parameter
            CreateGlobalValueMetadata(_qil.GlobalVariableList);
            CreateGlobalValueMetadata(_qil.GlobalParameterList);

            // Generate Execute method
            GenerateExecuteFunction(methExec, methRoot);

            // Visit the QilExpression graph
            _xmlIlVisitor = new XmlILVisitor();
            _xmlIlVisitor.Visit(_qil, _helper, methRoot);

            // Collect all static information required by the runtime
            XmlQueryStaticData staticData = new XmlQueryStaticData(
                _qil.DefaultWriterSettings,
                _qil.WhitespaceRules,
                _helper.StaticData
            );

            // Create static constructor that initializes XmlQueryStaticData instance at runtime
            if (typeBldr != null)
            {
                CreateTypeInitializer(staticData);

                // Finish up creation of the type
                _module.BakeMethods();

                return null;
            }
            else
            {
                // Finish up creation of the type
                _module.BakeMethods();

                // Create delegate over "Execute" method
                ExecuteDelegate delExec = (ExecuteDelegate)_module.CreateDelegate("Execute", typeof(ExecuteDelegate));
                return new XmlILCommand(delExec, staticData);
            }
        }
Beispiel #6
0
        /// <summary>
        /// Create static constructor that initializes XmlQueryStaticData instance at runtime.
        /// </summary>
        public void CreateTypeInitializer(XmlQueryStaticData staticData)
        {
            byte[] data;
            Type[] ebTypes;
            FieldInfo fldInitData, fldData, fldTypes;
            ConstructorInfo cctor;

            staticData.GetObjectData(out data, out ebTypes);
            fldInitData = _module.DefineInitializedData("__" + XmlQueryStaticData.DataFieldName, data);
            fldData = _module.DefineField(XmlQueryStaticData.DataFieldName, typeof(object));
            fldTypes = _module.DefineField(XmlQueryStaticData.TypesFieldName, typeof(Type[]));

            cctor = _module.DefineTypeInitializer();
            _helper.MethodBegin(cctor, null, false);

            // s_data = new byte[s_initData.Length] { s_initData };
            _helper.LoadInteger(data.Length);
            _helper.Emit(OpCodes.Newarr, typeof(byte));
            _helper.Emit(OpCodes.Dup);
            _helper.Emit(OpCodes.Ldtoken, fldInitData);
            _helper.Call(XmlILMethods.InitializeArray);
            _helper.Emit(OpCodes.Stsfld, fldData);

            if (ebTypes != null)
            {
                // Type[] types = new Type[s_ebTypes.Length];
                LocalBuilder locTypes = _helper.DeclareLocal("$$$types", typeof(Type[]));
                _helper.LoadInteger(ebTypes.Length);
                _helper.Emit(OpCodes.Newarr, typeof(Type));
                _helper.Emit(OpCodes.Stloc, locTypes);

                for (int idx = 0; idx < ebTypes.Length; idx++)
                {
                    // types[idx] = ebTypes[idx];
                    _helper.Emit(OpCodes.Ldloc, locTypes);
                    _helper.LoadInteger(idx);
                    _helper.LoadType(ebTypes[idx]);
                    _helper.Emit(OpCodes.Stelem_Ref);
                }

                // s_types = types;
                _helper.Emit(OpCodes.Ldloc, locTypes);
                _helper.Emit(OpCodes.Stsfld, fldTypes);
            }

            _helper.MethodEnd();
        }
Beispiel #7
0
        //-----------------------------------------------
        // Constructors
        //-----------------------------------------------

        /// <summary>
        /// This constructor is internal so that external users cannot construct it (and therefore we do not have to test it separately).
        /// </summary>
        internal XmlQueryRuntime(XmlQueryStaticData data, object defaultDataSource, XmlResolver dataSources, XsltArgumentList argList, XmlSequenceWriter seqWrt)
        {
            Debug.Assert(data != null);
            string[] names = data.Names;
            Int32Pair[] filters = data.Filters;
            WhitespaceRuleLookup wsRules;
            int i;

            // Early-Bound Library Objects
            wsRules = (data.WhitespaceRules != null && data.WhitespaceRules.Count != 0) ? new WhitespaceRuleLookup(data.WhitespaceRules) : null;
            _ctxt = new XmlQueryContext(this, defaultDataSource, dataSources, argList, wsRules);
            _xsltLib = null;
            _earlyInfo = data.EarlyBound;
            _earlyObjects = (_earlyInfo != null) ? new object[_earlyInfo.Length] : null;

            // Global variables and parameters
            _globalNames = data.GlobalNames;
            _globalValues = (_globalNames != null) ? new object[_globalNames.Length] : null;

            // Names
            _nameTableQuery = _ctxt.QueryNameTable;
            _atomizedNames = null;

            if (names != null)
            {
                // Atomize all names in "nameTableQuery".  Use names from the default data source's
                // name table when possible.
                XmlNameTable nameTableDefault = _ctxt.DefaultNameTable;
                _atomizedNames = new string[names.Length];

                if (nameTableDefault != _nameTableQuery && nameTableDefault != null)
                {
                    // Ensure that atomized names from the default data source are added to the
                    // name table used in this query
                    for (i = 0; i < names.Length; i++)
                    {
                        string name = nameTableDefault.Get(names[i]);
                        _atomizedNames[i] = _nameTableQuery.Add(name ?? names[i]);
                    }
                }
                else
                {
                    // Enter names into nametable used in this query
                    for (i = 0; i < names.Length; i++)
                        _atomizedNames[i] = _nameTableQuery.Add(names[i]);
                }
            }

            // Name filters
            _filters = null;
            if (filters != null)
            {
                // Construct name filters.  Each pair of integers in the filters[] array specifies the
                // (localName, namespaceUri) of the NameFilter to be created.
                _filters = new XmlNavigatorFilter[filters.Length];

                for (i = 0; i < filters.Length; i++)
                    _filters[i] = XmlNavNameFilter.Create(_atomizedNames[filters[i].Left], _atomizedNames[filters[i].Right]);
            }

            // Prefix maping lists
            _prefixMappingsList = data.PrefixMappingsList;

            // Xml types
            _types = data.Types;

            // Xml collations
            _collations = data.Collations;

            // Document ordering
            _docOrderCmp = new DocumentOrderComparer();

            // Indexes
            _indexes = null;

            // Output construction
            _stkOutput = new Stack<XmlQueryOutput>(16);
            _output = new XmlQueryOutput(this, seqWrt);
        }
 public XmlILCommand(System.Xml.Xsl.ExecuteDelegate delExec, XmlQueryStaticData staticData)
 {
     this.delExec = delExec;
     this.staticData = staticData;
 }