コード例 #1
0
        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);
        }