static void EmitWriteToString(ILGenerator gen) { // Stack behavior: ..., (object)value => ..., (string)result //System.Func<object, StringTemplate, object> write = ( value, self ) => //{ // StringWriter buf = new StringWriter(); // IStringTemplateWriter sw = self.Group.GetStringTemplateWriter( buf ); // int n = chunk.WriteAttribute( self, value, sw ); // if ( n > 0 ) // return buf.ToString(); // return value; //}; var value = gen.DeclareLocal(typeof(object)); var buf = gen.DeclareLocal(typeof(StringWriter)); var sw = gen.DeclareLocal(typeof(IStringTemplateWriter)); var preserveValue = gen.DefineLabel(); var endOfWrite = gen.DefineLabel(); gen.Emit(OpCodes.Stloc, value); gen.Emit(OpCodes.Newobj, typeof(StringWriter)); gen.Emit(OpCodes.Stloc, buf); EmitLoadSelf(gen); gen.Emit(OpCodes.Call, GetFuncMethodInfo(( StringTemplate self ) => self.Group)); gen.Emit(OpCodes.Ldloc, buf); gen.Emit(OpCodes.Call, GetFuncMethodInfo((StringTemplateGroup group, System.IO.TextWriter writer) => group.GetStringTemplateWriter(writer))); gen.Emit(OpCodes.Stloc, sw); EmitLoadChunk(gen); EmitLoadSelf(gen); gen.Emit(OpCodes.Ldloc, value); gen.Emit(OpCodes.Ldloc, sw); gen.Emit(OpCodes.Call, GetFuncMethodInfo((ASTExpr chunk, StringTemplate self, object o, IStringTemplateWriter writer) => chunk.WriteAttribute(self, o, writer))); gen.Emit(OpCodes.Ldc_I4_0); gen.Emit(OpCodes.Ble, preserveValue); gen.Emit(OpCodes.Ldloc, buf); gen.Emit(OpCodes.Call, GetFuncMethodInfo(( StringWriter writer ) => writer.ToString())); gen.Emit(OpCodes.Br_S, endOfWrite); gen.MarkLabel(preserveValue); gen.Emit(OpCodes.Ldloc, value); gen.MarkLabel(endOfWrite); }