// 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); } } }
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); }
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); } }
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(*?) }
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); }
public override void Emit <T>(Emit <T> emitter) { emitter.BranchIfTrue(_label); }