Ejemplo n.º 1
0
        // ReSharper restore StaticMemberInGenericType

        private static void SerializeValue(PropertyInfo propInfo,
                                           Emit <Action <T, StringBuilder, StringBuilder> > serializationEmitter)
        {
            var isString = propInfo.PropertyType == typeof(string);

            using (var stringLocal = serializationEmitter.DeclareLocal <string>())
            {
                serializationEmitter.LoadConstant(isString ? @"'{0}', " : "{0}, ");
                serializationEmitter.LoadArgument(0); // instance
                serializationEmitter.CallVirtual(propInfo.GetGetMethod());
                if (isString)
                {
                    serializationEmitter.Call(stringEscape);
                    serializationEmitter.LoadConstant(Environment.NewLine);
                    serializationEmitter.LoadConstant(@"\n");
                    serializationEmitter.CallVirtual(stringReplace);
                }
                else
                {
                    serializationEmitter.Box(propInfo.PropertyType);
                }
                serializationEmitter.Call(stringFormat);
                serializationEmitter.StoreLocal(stringLocal);

                // Append to hotfix builder
                serializationEmitter.LoadArgument(1); // hotfixBuilder
                serializationEmitter.LoadLocal(stringLocal);
                serializationEmitter.Call(stringBuilderAppend);
                serializationEmitter.Pop();

                if (isString)
                {
                    // Append to locale builder if (localeBuilder != null)
                    var skipLocaleBuilderMark = serializationEmitter.DefineLabel();
                    serializationEmitter.LoadArgument(2); // instanceBuilder
                    serializationEmitter.LoadNull();
                    serializationEmitter.CompareEqual();
                    serializationEmitter.BranchIfTrue(skipLocaleBuilderMark);
                    serializationEmitter.LoadArgument(2); // instanceBuilder
                    serializationEmitter.LoadLocal(stringLocal);
                    serializationEmitter.Call(stringBuilderAppend);
                    serializationEmitter.Pop();
                    serializationEmitter.MarkLabel(skipLocaleBuilderMark);
                }
            }
        }
Ejemplo n.º 2
0
        public Emit <Func <int> > EmitByteCode(CompilerContext context, Emit <Func <int> > emiter)
        {
            var thenLabel = emiter.DefineLabel();
            var elseLabel = emiter.DefineLabel();
            var endLabel  = emiter.DefineLabel();

            Condition.EmitByteCode(context, emiter);
            emiter.BranchIfTrue(thenLabel);
            emiter.Branch(elseLabel);
            emiter.MarkLabel(thenLabel);
            ThenStmt.EmitByteCode(context, emiter);
            emiter.Branch(endLabel);
            emiter.MarkLabel(elseLabel);
            ElseStmt.EmitByteCode(context, emiter);
            emiter.Branch(endLabel);
            emiter.MarkLabel(endLabel);
            return(emiter);
        }
Ejemplo n.º 3
0
        private static void SerializeValueArray(PropertyInfo propInfo,
                                                Emit <Action <T, StringBuilder, StringBuilder> > serializationEmitter)
        {
            var loopBodyLabel      = serializationEmitter.DefineLabel();
            var loopConditionLabel = serializationEmitter.DefineLabel();

            var elementType = propInfo.PropertyType.GetElementType();
            var isString    = elementType == typeof(string);

            using (var stringLocal = serializationEmitter.DeclareLocal <string>())
                using (var iterationLocal = serializationEmitter.DeclareLocal <int>())
                {
                    serializationEmitter.LoadConstant(0);
                    serializationEmitter.StoreLocal(iterationLocal);
                    serializationEmitter.Branch(loopConditionLabel);
                    serializationEmitter.MarkLabel(loopBodyLabel);

                    serializationEmitter.LoadConstant(isString ? @"'{0}', " : "{0}, ");
                    serializationEmitter.LoadArgument(0); // instance
                    serializationEmitter.CallVirtual(propInfo.GetGetMethod());
                    serializationEmitter.LoadLocal(iterationLocal);
                    serializationEmitter.LoadElement(elementType);
                    if (isString)
                    {
                        serializationEmitter.Call(stringEscape);
                        serializationEmitter.LoadConstant(Environment.NewLine);
                        serializationEmitter.LoadConstant(@"\n");
                        serializationEmitter.CallVirtual(stringReplace);
                    }
                    else
                    {
                        serializationEmitter.Box(elementType);
                    }
                    serializationEmitter.Call(stringFormat);
                    serializationEmitter.StoreLocal(stringLocal);

                    // Append to hotfix builder
                    serializationEmitter.LoadArgument(1); // hotfixBuilder
                    serializationEmitter.LoadLocal(stringLocal);
                    serializationEmitter.Call(stringBuilderAppend);
                    serializationEmitter.Pop();

                    if (isString)
                    {
                        // Append to locale builder if (localeBuilder != null)
                        var localeBuilderMarker = serializationEmitter.DefineLabel();
                        serializationEmitter.LoadArgument(2); // instanceBuilder
                        serializationEmitter.LoadNull();
                        serializationEmitter.CompareEqual();
                        serializationEmitter.BranchIfTrue(localeBuilderMarker);
                        serializationEmitter.LoadArgument(2); // instanceBuilder
                        serializationEmitter.LoadLocal(stringLocal);
                        serializationEmitter.Call(stringBuilderAppend);
                        serializationEmitter.Pop();
                        serializationEmitter.MarkLabel(localeBuilderMarker);
                    }

                    serializationEmitter.LoadLocal(iterationLocal);
                    serializationEmitter.LoadConstant(1);
                    serializationEmitter.Add();
                    serializationEmitter.StoreLocal(iterationLocal);

                    serializationEmitter.MarkLabel(loopConditionLabel);
                    serializationEmitter.LoadLocal(iterationLocal);
                    serializationEmitter.LoadArgument(0); // instance
                    serializationEmitter.CallVirtual(propInfo.GetGetMethod());
                    serializationEmitter.LoadLength(elementType);
                    serializationEmitter.Convert <int>();
                    serializationEmitter.CompareLessThan();
                    serializationEmitter.BranchIfTrue(loopBodyLabel);
                }
        }
Ejemplo n.º 4
0
        void ReadObject(Type objType)
        {
            var done         = Emit.DefineLabel();
            var doneSkipChar = Emit.DefineLabel();

            if (!objType.IsValueType)
            {
                ExpectRawCharOrNull(
                    '{',
                    () => { },
                    () =>
                {
                    Emit.LoadNull();
                    Emit.CastClass(objType);
                    Emit.Branch(doneSkipChar);
                }
                    );
            }
            else
            {
                ExpectChar('{');
            }

            using (var loc = Emit.DeclareLocal(objType))
            {
                Action loadObj;
                if (objType.IsValueType)
                {
                    Emit.LoadLocalAddress(loc);     // objType*
                    Emit.InitializeObject(objType); // --empty--

                    loadObj = () => Emit.LoadLocalAddress(loc);
                }
                else
                {
                    Emit.NewObject(objType.GetConstructor(Type.EmptyTypes));    // objType
                    Emit.StoreLocal(loc);                                       // --empty--

                    loadObj = () => Emit.LoadLocal(loc);
                }

                var loopStart = Emit.DefineLabel();

                var setterLookup = typeof(SetterLookup <>).MakeGenericType(objType);

                var setters = (Dictionary <string, MemberInfo>)setterLookup.GetMethod("GetSetters", BindingFlags.Public | BindingFlags.Static).Invoke(null, new object[0]);

                var tryGetValue = typeof(Dictionary <string, int>).GetMethod("TryGetValue");

                var order     = setterLookup.GetField("Lookup", BindingFlags.Public | BindingFlags.Static);
                var orderInst = (Dictionary <string, int>)order.GetValue(null);
                var labels    = setters.ToDictionary(d => d.Key, d => Emit.DefineLabel());

                var inOrderLabels = labels.OrderBy(l => orderInst[l.Key]).Select(l => l.Value).ToArray();

                ConsumeWhiteSpace();        // --empty--
                loadObj();                  // objType(*?)
                RawPeekChar();              // objType(*?) int
                Emit.LoadConstant('}');     // objType(*?) int '}'
                Emit.BranchIfEqual(done);   // objType(*?)
                Emit.LoadField(order);      // objType(*?) Dictionary<string, int> string
                Build(typeof(string));      // obType(*?) Dictionary<string, int> string
                ConsumeWhiteSpace();        // objType(*?) Dictionary<string, int> string
                ExpectChar(':');            // objType(*?) Dictionary<string, int> string
                ConsumeWhiteSpace();        // objType(*?) Dictionary<string, int> string

                var readingMember = Emit.DefineLabel();
                Emit.MarkLabel(readingMember);  // objType(*?) Dictionary<string, int> string

                using (var oLoc = Emit.DeclareLocal <int>())
                {
                    var isMember = Emit.DefineLabel();

                    Emit.LoadLocalAddress(oLoc);    // objType(*?) Dictionary<string, int> string int*
                    Emit.Call(tryGetValue);         // objType(*?) bool
                    Emit.BranchIfTrue(isMember);    // objType(*?)

                    Emit.Pop();                     // --empty--
                    SkipObjectMember();             // --empty--
                    Emit.Branch(loopStart);         // --empty--

                    Emit.MarkLabel(isMember);       // objType(*?)
                    Emit.LoadLocal(oLoc);           // objType(*?) int
                    Emit.Switch(inOrderLabels);     // objType(*?)

                    // fallthrough case
                    ThrowExpected("a member name"); // --empty--
                }

                foreach (var kv in labels)
                {
                    var label      = kv.Value;
                    var member     = setters[kv.Key];
                    var memberType = member.ReturnType();

                    Emit.MarkLabel(label);      // objType(*?)
                    Build(member.ReturnType()); // objType(*?) memberType

                    if (member is FieldInfo)
                    {
                        Emit.StoreField((FieldInfo)member);             // --empty--
                    }
                    else
                    {
                        Emit.Call(((PropertyInfo)member).SetMethod);    // --empty--
                    }

                    Emit.Branch(loopStart);     // --empty--
                }

                var nextItem = Emit.DefineLabel();

                Emit.MarkLabel(loopStart);      // --empty--
                ConsumeWhiteSpace();            // --empty--
                loadObj();                      // objType(*?)
                RawPeekChar();                  // objType(*?) int
                Emit.Duplicate();               // objType(*?) int int
                Emit.LoadConstant(',');         // objType(*?) int int ','
                Emit.BranchIfEqual(nextItem);   // objType(*?) int
                Emit.LoadConstant('}');         // objType(*?) int '}'
                Emit.BranchIfEqual(done);       // objType(*?)

                // didn't get what we expected
                ThrowExpected(",", "}");

                Emit.MarkLabel(nextItem);           // objType(*?) int
                Emit.Pop();                         // objType(*?)
                Emit.LoadArgument(0);               // objType(*?) TextReader
                Emit.CallVirtual(TextReader_Read);  // objType(*?) int
                Emit.Pop();                         // objType(*?)
                ConsumeWhiteSpace();
                Emit.LoadField(order);              // objType(*?) Dictionary<string, int> string
                Build(typeof(string));              // objType(*?) Dictionary<string, int> string
                ConsumeWhiteSpace();                // objType(*?) Dictionary<string, int> string
                ExpectChar(':');                    // objType(*?) Dictionary<string, int> string
                ConsumeWhiteSpace();                // objType(*?) Dictionary<string, int> string
                Emit.Branch(readingMember);         // objType(*?) Dictionary<string, int> string
            }

            Emit.MarkLabel(done);               // objType(*?)
            Emit.LoadArgument(0);               // objType(*?) TextReader
            Emit.CallVirtual(TextReader_Read);  // objType(*?) int
            Emit.Pop();                         // objType(*?)

            Emit.MarkLabel(doneSkipChar);       // objType(*?)
        }
Ejemplo n.º 5
0
        public static Emit <Func <IEnumerable <object>, IEnumerable <T> > > GenerateMapper <T>()
        {
            Type type = typeof(T);
            Emit <Func <IEnumerable <object>, IEnumerable <T> > > emit = null;

            if (_mappers.ContainsKey(type.FullName))
            {
                emit = (Emit <Func <IEnumerable <object>, IEnumerable <T> > >)_mappers[type.FullName];
            }
            else
            {
                ConstructorInfo listConstructor = typeof(List <T>).GetConstructor(new Type[] { });
                MethodInfo      listAdd         = typeof(List <T>).GetMethod("Add", new Type[] { typeof(T) });

                Emit <Func <IEnumerable <object>, IEnumerable <T> > > emiter = Emit <Func <IEnumerable <object>, IEnumerable <T> > > .NewDynamicMethod(type.Name + "Mapper");


                var enumeratorLocal = emiter.DeclareLocal <IEnumerator <object> >("enumerator");
                var listLocal       = emiter.DeclareLocal <List <T> >("list");
                var cacheLocal      = emiter.DeclareLocal <IDictionary <object, object> >("cache");


                var loopFinishedLabel    = emiter.DefineLabel("loopFinished");
                var loopCheckLabel       = emiter.DefineLabel("loopCheck");
                var loopBeginLabel       = emiter.DefineLabel("loopBegin");
                var finallyFinishedLabel = emiter.DefineLabel("finallyFinished");
                var isNullLabel          = emiter.DefineLabel("isNull");


                emiter.NewObject(listConstructor);
                emiter.StoreLocal(listLocal);
                emiter.NewObject(DictionaryConstructor_Object_Object);
                emiter.StoreLocal(cacheLocal);

                emiter.LoadArgument(0);
                emiter.CallVirtual(IEnumerable_Object_GetEnumerator);
                emiter.StoreLocal(enumeratorLocal);

                //try {
                var exceptionBlock = emiter.BeginExceptionBlock();
                emiter.Branch(loopCheckLabel);

                emiter.MarkLabel(loopBeginLabel);

                emiter.LoadLocal(listLocal);
                emiter.LoadLocal(enumeratorLocal);
                emiter.CallVirtual(IEnumerator_Object_GetCurrent);
                emiter.CastClass <IDictionary <string, object> >();
                emiter.LoadLocal(cacheLocal);
                emiter.LoadConstant("");
                emiter.Call(GenerateRowMapper(type)); // var rowResult = rowMapper ( row, cache, depthString = "" );
                emiter.Duplicate();
                emiter.LoadNull();
                emiter.BranchIfEqual(isNullLabel);


                emiter.CastClass(typeof(T));
                emiter.Call(listAdd); // listLocal.Add((T)rowResult);
                emiter.Branch(loopCheckLabel);

                emiter.MarkLabel(isNullLabel);
                emiter.Pop();
                emiter.Pop();


                emiter.MarkLabel(loopCheckLabel);
                emiter.LoadLocal(enumeratorLocal);
                emiter.CallVirtual(IEnumerator_MoveNext);
                emiter.BranchIfTrue(loopBeginLabel);
                emiter.Leave(loopFinishedLabel);
                //}
                //finallY {
                var finallyBlock = emiter.BeginFinallyBlock(exceptionBlock);
                emiter.LoadNull();
                emiter.LoadLocal(enumeratorLocal);
                emiter.CompareEqual();
                emiter.BranchIfTrue(finallyFinishedLabel);
                emiter.LoadLocal(enumeratorLocal);
                emiter.CallVirtual(IEnumerator_Dispose);
                emiter.MarkLabel(finallyFinishedLabel);
                emiter.EndFinallyBlock(finallyBlock);
                emiter.EndExceptionBlock(exceptionBlock);
                //}

                emiter.MarkLabel(loopFinishedLabel);
                emiter.LoadLocal(listLocal);
                emiter.Return(); // return listLocal;
                _mapperDelegates.Add(type.FullName, emiter.CreateDelegate());
                _mappers.Add(type.FullName, emiter);
                emit = emiter;
            }
            return(emit);
        }
Ejemplo n.º 6
0
 public override void Emit <T>(Emit <T> emitter)
 {
     emitter.BranchIfTrue(_label);
 }