/// <summary> /// Inits il generator, RootType must have been read first /// </summary> void InitEmitter() { dm = new DynamicMethod("dyn_instantiator", MethodAttributes.Family | MethodAttributes.FamANDAssem | MethodAttributes.NewSlot, CallingConventions.Standard, typeof(void), new Type[] { typeof(object), typeof(Interface) }, RootType, true); il = dm.GetILGenerator(256); il.DeclareLocal(typeof(GraphicObject)); il.Emit(OpCodes.Nop); //set local GraphicObject to root object passed as 1st argument il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Stloc_0); CompilerServices.emitSetCurInterface(il); }
/// <summary> /// Parse child node an generate corresponding msil /// </summary> void readChildren(IMLReader reader, Type crowType, bool templateLoading = false) { MethodInfo miAddChild = null; bool endTagReached = false; while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.EndElement: endTagReached = true; break; case XmlNodeType.Element: //Templates if (reader.Name == "Template" || reader.Name == "ItemTemplate") { reader.Skip(); continue; } if (miAddChild == null) { if (typeof(Group).IsAssignableFrom(crowType)) { miAddChild = typeof(Group).GetMethod("AddChild"); } else if (typeof(Container).IsAssignableFrom(crowType)) { miAddChild = typeof(Container).GetMethod("SetChild"); } else if (typeof(TemplatedContainer).IsAssignableFrom(crowType) && !templateLoading) { miAddChild = typeof(TemplatedContainer).GetProperty("Content").GetSetMethod(); } else if (typeof(TemplatedGroup).IsAssignableFrom(crowType) && !templateLoading) { miAddChild = typeof(TemplatedGroup).GetMethod("AddItem", BindingFlags.Instance | BindingFlags.Public); } else if (typeof(TemplatedControl).IsAssignableFrom(crowType)) { miAddChild = typeof(TemplatedControl).GetMethod("loadTemplate", BindingFlags.Instance | BindingFlags.NonPublic); } else if (typeof(PrivateContainer).IsAssignableFrom(crowType)) { miAddChild = typeof(PrivateContainer).GetMethod("SetChild", BindingFlags.Instance | BindingFlags.NonPublic); } } //push current instance on stack for parenting //loc_0 will be used for child reader.il.Emit(OpCodes.Ldloc_0); Type t = Type.GetType("Crow." + reader.Name); if (t == null) { Assembly a = Assembly.GetEntryAssembly(); foreach (Type expT in a.GetExportedTypes()) { if (expT.Name == reader.Name) { t = expT; } } } if (t == null) { throw new Exception(reader.Name + " type not found"); } reader.il.Emit(OpCodes.Newobj, t.GetConstructors() [0]); //TODO:search parameterless ctor reader.il.Emit(OpCodes.Stloc_0); //child is now loc_0 CompilerServices.emitSetCurInterface(il); reader.emitLoader(t); reader.il.Emit(OpCodes.Ldloc_0); //load child on stack for parenting if (miAddChild == null) { System.Diagnostics.Debugger.Break(); } reader.il.Emit(OpCodes.Callvirt, miAddChild); reader.il.Emit(OpCodes.Stloc_0); //reset local to current go reader.il.Emit(OpCodes.Ldloc_0); //save current go onto the stack if child has to be added break; } if (endTagReached) { break; } } }