XamlDocument Compile(IXamlTypeBuilder <IXamlILEmitter> builder, IXamlType context, string xaml) { var parsed = XDocumentXamlParser.Parse(xaml); var compiler = new XamlILCompiler( Configuration, new XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult>(), true) { EnableIlVerification = true }; compiler.Transform(parsed); compiler.Compile(parsed, builder, context, "Populate", "Build", "XamlNamespaceInfo", "http://example.com/", null); return(parsed); }
public static Func <IServiceProvider, object> Compile(string xaml) { // Enforce everything to load foreach (var xt in typeof(BenchCompiler).Assembly.GetTypes()) { xt.GetCustomAttributes(); xt.GetInterfaces(); foreach (var p in xt.GetProperties()) { p.GetCustomAttributes(); } } typeof(IXamlParentStackProviderV1).Assembly.GetCustomAttributes(); var typeSystem = new SreTypeSystem(); var configuration = BenchmarksXamlXConfiguration.Configure(typeSystem); var parsed = XDocumentXamlParser.Parse(xaml); var compiler = new XamlILCompiler( configuration, new XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult>(), true); compiler.Transform(parsed); var parsedTsType = ((IXamlAstValueNode)parsed.Root).Type.GetClrType(); #if !NETCOREAPP var path = Path.GetDirectoryName(typeof(BenchCompiler).Assembly.GetModules()[0].FullyQualifiedName); var da = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(Guid.NewGuid().ToString("N")), AssemblyBuilderAccess.RunAndSave, path); #else var da = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(Guid.NewGuid().ToString("N")), AssemblyBuilderAccess.Run); #endif var dm = da.DefineDynamicModule("testasm.dll"); var t = dm.DefineType(Guid.NewGuid().ToString("N"), TypeAttributes.Public); var ctb = dm.DefineType(t.Name + "Context", TypeAttributes.Public); var contextTypeDef = compiler.CreateContextType(((SreTypeSystem)typeSystem).CreateTypeBuilder(ctb)); var parserTypeBuilder = ((SreTypeSystem)typeSystem).CreateTypeBuilder(t); compiler.Compile(parsed, parserTypeBuilder, contextTypeDef, "Populate", "Build", "XamlNamespaceInfo", "https://github.com/kekekeks/Xaml", null); var created = t.CreateType(); #if !NETCOREAPP dm.CreateGlobalFunctions(); // Useful for debugging the actual MSIL, don't remove lock (s_asmLock) da.Save("testasm.dll"); #endif var isp = Expression.Parameter(typeof(IServiceProvider)); return(Expression.Lambda <Func <IServiceProvider, object> >( Expression.Convert(Expression.Call( created.GetMethod("Build"), isp), typeof(object)), isp).Compile()); }
static void Main(string[] args) { var target = Path.GetFullPath(args[0]); var refsPath = target + ".refs"; var refs = File.ReadAllLines(refsPath).Concat(new[] { target }); var typeSystem = new CecilTypeSystem(refs, target); var asm = typeSystem.GetAssembly(typeSystem.FindAssembly("Benchmarks")); var config = Benchmarks.BenchmarksXamlXConfiguration.Configure(typeSystem); var loadBench = asm.MainModule.Types.First(t => t.Name == "LoadBenchmark"); var baseMethod = loadBench.Methods.First(m => m.Name == "LoadXamlPrecompiled"); var ct = new TypeDefinition("_XamlRuntime", "XamlContext", TypeAttributes.Class, asm.MainModule.TypeSystem.Object); asm.MainModule.Types.Add(ct); var ctb = typeSystem.CreateTypeBuilder(ct); var compiler = new XamlILCompiler( config, new XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult>(), true); var contextTypeDef = compiler.CreateContextType(ctb); asm.MainModule.Types.Add(ct); foreach (var lb in asm.MainModule.Types) { if (lb == loadBench) { continue; } var bt = lb; while (bt != null && bt != loadBench) { bt = bt.BaseType?.Resolve(); } if (bt != loadBench) { continue; } var loadMethod = lb.Methods.FirstOrDefault(m => m.Name == "LoadXamlPrecompiled"); if (loadMethod != null) { lb.Methods.Remove(loadMethod); } var resource = asm.MainModule.Resources.OfType <EmbeddedResource>() .First(r => r.Name == lb.FullName + ".xml"); var xml = Encoding.UTF8.GetString(resource.GetResourceData()); while (xml[0] > 128) { xml = xml.Substring(1); } var parsed = XamlX.Parsers.XamlParser.Parse(xml); compiler.Transform(parsed); compiler.Compile(parsed, typeSystem.CreateTypeBuilder(lb), contextTypeDef, "PopulateXamlPrecompiled", "LoadXamlPrecompiled", "XamlXmlInfo", resource.Name, null); loadMethod = lb.Methods.First(m => m.Name == "LoadXamlPrecompiled"); loadMethod.ReturnType = asm.MainModule.TypeSystem.Object; loadMethod.Overrides.Add(baseMethod); loadMethod.Body.OptimizeMacros(); loadMethod.Attributes = (baseMethod.Attributes | MethodAttributes.NewSlot) ^ MethodAttributes.NewSlot; loadMethod.HasThis = true; for (var c = 0; c < loadMethod.Body.Instructions.Count; c++) { if (loadMethod.Body.Instructions[c].OpCode == OpCodes.Ldarg_0) { loadMethod.Body.Instructions[c] = Instruction.Create(OpCodes.Ldarg_1); } } } asm.Write(target); }