public XmlCommand Generate(QilExpression query, AssemblyName asmName) {
MethodInfo methRoot, methExec;
bool useLRE, emitSymbols;
ExecuteDelegate delExec;
XmlILMethodAttributes methAttrs;
this.qil = query;
useLRE = !this.qil.IsDebug && (asmName == null);
emitSymbols = this.qil.IsDebug;
// In debug code, ensure that input QIL is correct
QilValidationVisitor.Validate(this.qil);
// Trace Qil before optimization
XmlILTrace.WriteQil(this.qil, "qilbefore.xml");
// Trace optimizations
XmlILTrace.TraceOptimizations(this.qil, "qilopt.xml");
if (XmlILTrace.IsEnabled) {
// Dump assembly to disk; can't do this when using LRE
useLRE = false;
}
// Optimize and annotate the Qil graph
this.optVisitor = new XmlILOptimizerVisitor(this.qil, !this.qil.IsDebug);
this.qil = this.optVisitor.Optimize();
// In debug code, ensure that output QIL is correct
QilValidationVisitor.Validate(this.qil);
// Trace Qil after optimization
XmlILTrace.WriteQil(this.qil, "qilafter.xml");
// Create module in which methods will be generated
this.module = new XmlILModule(useLRE, emitSymbols, asmName);
// Create a code generation helper for the module; enable optimizations if IsDebug is false
this.helper = new GenerateHelper(this.module, this.qil.IsDebug);
// Create helper methods
CreateHelperFunctions();
// Create metadata for the root expression
// public void Root()
Debug.Assert(this.qil.Root != null);
methAttrs = (this.qil.Root.SourceLine == null) ? XmlILMethodAttributes.NonUser : XmlILMethodAttributes.None;
methRoot = this.module.DefineMethod("Root", typeof(void), new Type[] {}, new string[] {}, methAttrs);
// Create metadata for each QilExpression function that has at least one caller
CreateFunctionMetadata(this.qil.FunctionList);
// Create metadata for each QilExpression global variable and parameter
CreateGlobalValueMetadata(this.qil.GlobalVariableList);
CreateGlobalValueMetadata(this.qil.GlobalParameterList);
// Create Execute method
methExec = CreateExecuteFunction(methRoot);
// Visit the QilExpression graph
this.xmlIlVisitor = new XmlILVisitor();
this.xmlIlVisitor.Visit(this.qil, this.helper, methRoot);
this.module.BakeMethods();
// Create delegate over "Execute" method
delExec = (ExecuteDelegate) this.module.CreateDelegate("Execute", typeof(ExecuteDelegate));
return new XmlILCommand(delExec, this.qil, this.helper.StaticData);
}