示例#1
0
        static void EmitTemplateInclude(ILGenerator gen, StringTemplateAST args)
        {
            var name = gen.DeclareLocal(typeof(string));

            var ldnull     = gen.DefineLabel();
            var endinclude = gen.DefineLabel();

            gen.Emit(OpCodes.Dup);
            gen.Emit(OpCodes.Brfalse_S, endinclude);   // the dup of a null object already loaded null back on the stack
            gen.Emit(OpCodes.Call, GetFuncMethodInfo <object, string>((o) => o.ToString()));
            // at this point, the name is the top item on the evaluation stack
            gen.Emit(OpCodes.Dup);
            gen.Emit(OpCodes.Brfalse_S, endinclude);
            gen.Emit(OpCodes.Stloc, name);

            // $value = chunk.GetTemplateInclude(self, name, args);
            EmitLoadChunk(gen);
            EmitLoadSelf(gen);
            gen.Emit(OpCodes.Ldloc, name);

            // TODO: handle args
            throw new System.NotImplementedException();

            //gen.Emit( OpCodes.Callvirt, typeof( ASTExpr ).GetMethod( "GetTemplateInclude", new System.Type[] { typeof( StringTemplate ), typeof( string ), typeof( StringTemplateAST ) } ) );

            //gen.MarkLabel( endinclude );
        }
示例#2
0
        static void EmitAddValueToList(ILGenerator gen, LocalBuilder local)
        {
            var label1 = gen.DefineLabel();
            var label2 = gen.DefineLabel();

            gen.Emit(OpCodes.Dup);
            gen.Emit(OpCodes.Brfalse_S, label1);
            gen.Emit(OpCodes.Ldloc, local);
            gen.Emit(OpCodes.Call, GetActionMethodInfo((object value, List <object> list) => list.Add(value)));
            gen.Emit(OpCodes.Br_S, label2);
            gen.MarkLabel(label1);
            gen.Emit(OpCodes.Pop);
            gen.MarkLabel(label2);
        }
示例#3
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);
        }
示例#4
0
        static public void emitMethod(List <MSIL.Instruction> Instructions, System.Reflection.Emit.ILGenerator ILGenerator)
        {
            Instructions = new List <MSIL.Instruction>(Instructions);
            Dictionary <int, System.Reflection.Emit.Label>        labels = new Dictionary <int, System.Reflection.Emit.Label>();
            Dictionary <int, System.Reflection.LocalVariableInfo> locals = new Dictionary <int, System.Reflection.LocalVariableInfo>();

            {
                HashSet <int> uniqueOffset = new HashSet <int>();
                for (int n = 0; n < Instructions.Count; n++)
                {
                    if (Instructions[n] == null)
                    {
                        continue;
                    }
                    int offset = Instructions[n].Offset;
                    if (uniqueOffset.Contains(offset))
                    {
                        Dictionary <int, MSIL.Instruction> instructionRemap = new Dictionary <int, MSIL.Instruction>();
                        // Conflicting offset we need to patch all of them
                        for (n = 0; n < Instructions.Count; n++)
                        {
                            int hash = Instructions[n].GetHashCode();
                            Instructions[n] = new MSIL.Instruction(Instructions[n].OpCode, Instructions[n].Data)
                            {
                                _Offset = n
                            };
                            instructionRemap.Add(hash, Instructions[n]);
                        }
                        for (n = 0; n < Instructions.Count; n++)
                        {
                            if (Instructions[n].Data != null && (Instructions[n].Data is MSIL.Instruction))
                            {
                                Instructions[n].Data = instructionRemap[(Instructions[n].Data as MSIL.Instruction).GetHashCode()];
                            }
                        }
                        break;
                    }
                    uniqueOffset.Add(offset);
                }
            }

            for (int n = 0; n < Instructions.Count; n++)
            {
                if (Instructions[n] == null)
                {
                    continue;
                }
                if (Instructions[n].Data != null && (Instructions[n].Data is MSIL.Instruction))
                {
                    int labelPos = (Instructions[n].Data as MSIL.Instruction).Offset;
                    System.Reflection.Emit.Label label;
                    if (!labels.TryGetValue(labelPos, out label))
                    {
                        label = ILGenerator.DefineLabel();
                        labels.Add(labelPos, label);
                    }
                    Instructions[n] = new MSIL.Instruction(Instructions[n].OpCode, label)
                    {
                        _Offset = Instructions[n]._Offset
                    };
                }
                else if (Instructions[n].Data != null && (Instructions[n].Data is System.Reflection.LocalVariableInfo))
                {
                    int localIndex = (Instructions[n].Data as System.Reflection.LocalVariableInfo).LocalIndex;
                    System.Reflection.LocalVariableInfo local;
                    if (!locals.TryGetValue(localIndex, out local))
                    {
                        local = ILGenerator.DeclareLocal((Instructions[n].Data as System.Reflection.LocalVariableInfo).LocalType, (Instructions[n].Data as System.Reflection.LocalVariableInfo).IsPinned);
                        locals.Add(localIndex, local);
                    }
                    Instructions[n] = new MSIL.Instruction(Instructions[n].OpCode, local)
                    {
                        _Offset = Instructions[n]._Offset
                    };
                }
            }

            for (int n = 0; n < Instructions.Count; n++)
            {
                System.Reflection.Emit.Label label;
                if (labels.TryGetValue(Instructions[n].Offset, out label))
                {
                    ILGenerator.MarkLabel(label);
                }
                Instructions[n].Emit(ILGenerator);
            }
        }