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 }
/// <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); }
/// <summary> /// Constructor. /// </summary> public XmlILCommand(ExecuteDelegate delExec, XmlQueryStaticData staticData) { Debug.Assert(delExec != null && staticData != null); _delExec = delExec; _staticData = staticData; }
/// <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); } }
/// <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(); }
//----------------------------------------------- // 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; }