public ForeachLoopEmitter(MyILGenerator il, Type elementType, Action<MyILGenerator> emitLoadCollection) { this.il = il; this.emitLoadCollection = emitLoadCollection; enumerableType = typeof(IEnumerable<>).MakeGenericType(elementType); enumeratorType = typeof(IEnumerator<>).MakeGenericType(elementType); EmitLoopBeginning(); }
protected EmittingContextBase(MyILGenerator il) { this.il = il; variables = new Dictionary<string, LocalBuilder>(); }
public ForLoopEmitter(MyILGenerator il, LocalBuilder lengthVar) { this.il = il; this.lengthVar = lengthVar; EmitLoopBeginning(); }
protected override void EmitLoadCount(MyILGenerator il, Action<MyILGenerator> emitLoad) { emitLoad(il); il.Callvirt(getCountMethod); }
protected abstract void EmitLoadAsString(MyILGenerator il, Action<MyILGenerator> emitLoad);
protected abstract void EmitLoadCount(MyILGenerator il, Action<MyILGenerator> emitLoad);
public ProxyMethodEmittingContext(MyILGenerator il, ProxyClassFieldCache fieldCache) : base(il) { this.fieldCache = fieldCache; }
private static void EmitAddIf(MyILGenerator il, ref bool haveSizeOnStack) { if (haveSizeOnStack) il.Add(); else haveSizeOnStack = true; }
protected override void EmitLoadCount(MyILGenerator il, Action<MyILGenerator> emitLoad) { emitLoad(il); il.Ldlen(); il.Conv_I4(); }
protected override void EmitCreateCollection(MyILGenerator il, LocalBuilder lengthVar) { il.Ldloc(lengthVar); il.Newarr(ElementType); }
protected override void EmitParseFromString(MyILGenerator il) { }
protected override void EmitLoadAsString(MyILGenerator il, Action<MyILGenerator> emitLoad) { emitLoad(il); }
protected abstract void EmitParseFromString(MyILGenerator il);
private static MethodBuilder CreateEncodeDeferredMethod(HandlerClassBuildingContext classContext, Type pureRetvalType) { const int taskArgIndex = 1; var methodBuilder = classContext.Builder.DefineMethod("EncodeDeferred", MethodAttributes.Private | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot, typeof(byte[]), new[] {typeof(Task<>).MakeGenericType(pureRetvalType)}); var il = new MyILGenerator(methodBuilder.GetILGenerator()); var emittingContext = new HandlerMethodEmittingContext(il, classContext.Fields); il.Ldarg(taskArgIndex); il.Call(TaskMethods.GetResult(pureRetvalType)); EmitEncodeDirect(emittingContext, new HandlerParameterCodec[0], pureRetvalType); il.Ret(); return methodBuilder; }
private static void CreateMethodDelegate(HandlerClassBuildingContext classContext) { const int implementationArgIndex = 1; const int dataArgIndex = 2; const int offsetArgIndex = 3; var methodBuilder = classContext.Builder.DefineMethod("Handle", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, typeof(Task<byte[]>), new[] { typeof(object), typeof(byte[]), typeof(int) }); var il = new MyILGenerator(methodBuilder.GetILGenerator()); var emittingContext = new HandlerMethodEmittingContext(il, classContext.Fields); var serviceDescriptionChain = classContext.ServiceDescriptionChain; il.Ldarg(implementationArgIndex); // stack_0 = (TServiceImplementation) arg_1 il.Castclass(serviceDescriptionChain.First().Type); for (int i = 0; i < serviceDescriptionChain.Count - 1; i++) { var current = serviceDescriptionChain[i]; var next = serviceDescriptionChain[i + 1]; il.Callvirt(current.Type.GetProperty(next.Name).GetGetMethod()); // stack_0 = stack_0.Property } var methodDescription = classContext.MethodDescription; var genericArgumentMap = methodDescription.GenericParameters .Zip(classContext.GenericTypeParameterBuilders, (p, a) => new KeyValuePair<string, Type>(p.Name, a)) .ToDictionary(x => x.Key, x => x.Value); var parameterDescriptions = methodDescription.Parameters.Select(x => x.DeepSubstituteGenerics(genericArgumentMap)).ToArray(); var retvalType = methodDescription.ReturnType.DeepSubstituteGenerics(genericArgumentMap); var allParameterCodecs = parameterDescriptions.Select((x, i) => new HandlerParameterCodec(emittingContext, x)).ToArray(); var requestParameterCodecs = allParameterCodecs.Where(x => x.IsRequestParameter).ToArray(); var responseParameterCodecs = allParameterCodecs.Where(x => x.IsResponseParameter).ToArray(); if (requestParameterCodecs.Any()) { il.Ldarg(dataArgIndex); // remainingBytes = dataArray.Length - offset il.Ldlen(); il.Ldarg(offsetArgIndex); il.Sub(); il.Stloc(emittingContext.RemainingBytesVar); var pinnedVar = il.PinArray(typeof(byte), 2); // var pinned dataPointer = pin(dataArray) il.Ldloc(pinnedVar); // data = dataPointer + offset il.Ldarg(offsetArgIndex); il.Add(); il.Stloc(emittingContext.DataPointerVar); } foreach (var codec in allParameterCodecs) codec.EmitDecodeAndPrepare(); // ReSharper disable CoVariantArrayConversion var resolvedMethodInfo = classContext.GenericTypeParameterBuilders.Any() ? methodDescription.MethodInfo.MakeGenericMethod(classContext.GenericTypeParameterBuilders) : methodDescription.MethodInfo; il.Callvirt(resolvedMethodInfo); // stack_0 = stack_0.Method(stack_1, stack_2, ...) // ReSharper restore CoVariantArrayConversion switch (methodDescription.RemotingType) { case MethodRemotingType.Direct: EmitProcessAndEncodeDirect(emittingContext, responseParameterCodecs, retvalType); break; case MethodRemotingType.AsyncVoid: EmitProcessAndEncodeAsyncVoid(emittingContext); break; case MethodRemotingType.AsyncWithRetval: EmitProcessAndEncodeAsyncWithRetval(classContext, emittingContext, retvalType.GetGenericArguments()[0]); break; default: throw new ArgumentOutOfRangeException(); } il.Ret(); }
protected override void EmitLoadAsString(MyILGenerator il, Action<MyILGenerator> emitLoad) { emitLoad(il); il.Callvirt(GetAssemblyQualifiedNameMethod); }
private static void CreateConstructor(HandlerClassBuildingContext classContext) { const int thisArgIndex = 0; const int codecContainerArgIndex = 1; var constructorBuilder = classContext.Builder.DefineConstructor( MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, new[] { typeof(ICodecContainer) }); var baseConstructor = typeof(object).GetConstructor(Type.EmptyTypes); var il = new MyILGenerator(constructorBuilder.GetILGenerator()); il.Ldarg(thisArgIndex); il.Call(baseConstructor); il.Ldarg(thisArgIndex); il.Ldarg(codecContainerArgIndex); il.Stfld(classContext.Fields.CodecContainer); foreach (var manualCodecField in classContext.Fields.GetAllManualCodecFields()) { il.Ldarg(thisArgIndex); il.Ldarg(codecContainerArgIndex); il.Call(CodecContainerMethods.GetManualCodecFor(manualCodecField.FieldType.GenericTypeArguments[0])); il.Stfld(manualCodecField); } il.Ret(); }
protected override void EmitParseFromString(MyILGenerator il) { il.Call(GetTypeMethod); }
protected abstract void EmitCreateCollection(MyILGenerator il, LocalBuilder lengthVar);
protected override void EmitCreateCollection(MyILGenerator il, LocalBuilder lengthVar) { il.Newobj(collectionConstructor); }
public ManualCodecEmittingContext(MyILGenerator il, int codecContainerArgumentIndex) : base(il) { this.codecContainerArgumentIndex = codecContainerArgumentIndex; }
public HandlerMethodEmittingContext(MyILGenerator il, HandlerClassFieldCache fieldCache) : base(il) { this.fieldCache = fieldCache; }