private ConstructorBuilder CreateConstructor(MethodAttributes attributes, Type[] parameterTypes, Action <Type, TracingILGenerator> emitter) { var builder = this.DefineConstructor(attributes, parameterTypes); emitter(this._typeBuilder.BaseType, this.GetILGenerator(builder, parameterTypes)); #if DEBUG if (SerializerDebugging.TraceEnabled) { SerializerDebugging.FlushTraceData(); } #endif // DEBUG return(builder); }
public void DefineUnpackingContext(string name, IList <KeyValuePair <string, Type> > fields, out Type type, out ConstructorInfo constructor) { this._unpackingContextType = this._host.DefineType( this._typeBuilder.FullName + "_" + name, TypeAttributes.Class | TypeAttributes.UnicodeClass | TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit ); var parameterTypes = fields.Select(kv => kv.Value).ToArray(); var ctor = this._unpackingContextType.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, parameterTypes ); var il = this.GetILGenerator(ctor, parameterTypes); try { // call object.ctor il.EmitLdargThis(); il.EmitCallConstructor(Metadata._Object.Ctor); for (var i = 0; i < fields.Count; i++) { var field = this._unpackingContextType.DefineField(fields[i].Key, fields[i].Value, FieldAttributes.Public); il.EmitLdargThis(); il.EmitAnyLdarg(i + 1); il.EmitStfld(field); } il.EmitRet(); } finally { il.FlushTrace(); #if DEBUG SerializerDebugging.FlushTraceData(); #endif // DEBUG } #if !NETSTANDARD1_1 && !NETSTANDARD1_3 && !NETSTANDARD2_0 type = this._unpackingContextType.CreateType(); #else type = this._unpackingContextType.CreateTypeInfo().AsType(); #endif // !NETSTANDARD1_1 && !NETSTANDARD1_3 && !NETSTANDARD2_0 constructor = type.GetConstructors().Single(); }
private static void EmitMethodEpilogue(TContext context, ILConstruct construct) { try { if (construct != null) { construct.Evaluate(context.IL); } context.IL.EmitRet(); } finally { context.IL.FlushTrace(); SerializerDebugging.FlushTraceData(); } }
private MethodDefinition EndMethod(ILConstruct body) { ILMethodConctext lastMethod; try { if (body != null) { body.Evaluate(this.IL); } this.IL.EmitRet(); } finally { this.IL.FlushTrace(); SerializerDebugging.FlushTraceData(); lastMethod = this._ilGeneratorStack.Pop(); } return(new MethodDefinition(lastMethod.Method, null, lastMethod.ParameterTypes)); }
public IEnumerable <SerializerCodeGenerationResult> Generate() { Contract.Assert(this._declaringTypes != null, "_declaringTypes != null"); using (var provider = CodeDomProvider.CreateProvider(this._configuration.Language)) { var options = new CodeGeneratorOptions { BlankLinesBetweenMembers = true, ElseOnClosing = false, IndentString = this._configuration.CodeIndentString, VerbatimOrder = false }; var directory = Path.Combine( this._configuration.OutputDirectory, this._configuration.Namespace.Replace(Type.Delimiter, Path.DirectorySeparatorChar) ); var sink = this._configuration.CodeGenerationSink ?? CodeGenerationSink.ForIndividualFile(); var result = new List <SerializerCodeGenerationResult>(this._declaringTypes.Count); var extension = "." + provider.FileExtension; foreach (var declaringType in this._declaringTypes) { Contract.Assert(declaringType.Value.TypeParameters.Count == 0, declaringType.Value.TypeParameters.Count + "!= 0"); var cn = new CodeNamespace(this._configuration.Namespace); cn.Types.Add(declaringType.Value); var cu = new CodeCompileUnit(); cu.Namespaces.Add(cn); var codeInfo = new SerializerCodeInformation(declaringType.Value.Name, directory, extension); sink.AssignTextWriter(codeInfo); result.Add( new SerializerCodeGenerationResult( declaringType.Key, codeInfo.FilePath, String.IsNullOrEmpty(cn.Name) ? declaringType.Value.Name : cn.Name + "." + declaringType.Value.Name, cn.Name, declaringType.Value.Name ) ); #if DEBUG if (SerializerDebugging.DumpEnabled) { SerializerDebugging.TraceEmitEvent("Compile {0}", declaringType.Value.Name); } #endif // DEBUG using (var writer = #if DEBUG SerializerDebugging.DumpEnabled ? new TeeTextWriter(codeInfo.TextWriter ?? NullTextWriter.Instance, SerializerDebugging.ILTraceWriter) : #endif // DEBUG codeInfo.TextWriter ?? NullTextWriter.Instance ) { provider.GenerateCodeFromCompileUnit(cu, writer, options); writer.WriteLine(); writer.Flush(); #if DEBUG if (SerializerDebugging.DumpEnabled) { SerializerDebugging.TraceEmitEvent("Compile {0}", declaringType.Value.Name); SerializerDebugging.FlushTraceData(); } #endif // DEBUG } } return(result); } }