예제 #1
0
 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();
 }
예제 #2
0
 protected EmittingContextBase(MyILGenerator il)
 {
     this.il = il;
     variables = new Dictionary<string, LocalBuilder>();
 }
예제 #3
0
 public ForLoopEmitter(MyILGenerator il, LocalBuilder lengthVar)
 {
     this.il = il;
     this.lengthVar = lengthVar;
     EmitLoopBeginning();
 }
예제 #4
0
 protected override void EmitLoadCount(MyILGenerator il, Action<MyILGenerator> emitLoad)
 {
     emitLoad(il);
     il.Callvirt(getCountMethod);
 }
예제 #5
0
 protected abstract void EmitLoadAsString(MyILGenerator il, Action<MyILGenerator> emitLoad);
예제 #6
0
 protected abstract void EmitLoadCount(MyILGenerator il, Action<MyILGenerator> emitLoad);
 public ProxyMethodEmittingContext(MyILGenerator il, ProxyClassFieldCache fieldCache)
     : base(il)
 {
     this.fieldCache = fieldCache;
 }
예제 #8
0
 private static void EmitAddIf(MyILGenerator il, ref bool haveSizeOnStack)
 {
     if (haveSizeOnStack)
         il.Add();
     else
         haveSizeOnStack = true;
 }
예제 #9
0
 protected override void EmitLoadCount(MyILGenerator il, Action<MyILGenerator> emitLoad)
 {
     emitLoad(il);
     il.Ldlen();
     il.Conv_I4();
 }
예제 #10
0
 protected override void EmitCreateCollection(MyILGenerator il, LocalBuilder lengthVar)
 {
     il.Ldloc(lengthVar);
     il.Newarr(ElementType);
 }
예제 #11
0
 public ForLoopEmitter(MyILGenerator il, LocalBuilder lengthVar)
 {
     this.il        = il;
     this.lengthVar = lengthVar;
     EmitLoopBeginning();
 }
예제 #12
0
 protected override void EmitParseFromString(MyILGenerator il)
 {
 }
예제 #13
0
 protected override void EmitLoadAsString(MyILGenerator il, Action<MyILGenerator> emitLoad)
 {
     emitLoad(il);
 }
예제 #14
0
 protected abstract void EmitParseFromString(MyILGenerator il);
예제 #15
0
        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;
        }
예제 #16
0
        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();
        }
예제 #17
0
 protected override void EmitLoadAsString(MyILGenerator il, Action<MyILGenerator> emitLoad)
 {
     emitLoad(il);
     il.Callvirt(GetAssemblyQualifiedNameMethod);
 }
예제 #18
0
        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();
        }
예제 #19
0
 protected override void EmitParseFromString(MyILGenerator il)
 {
     il.Call(GetTypeMethod);
 }
예제 #20
0
 protected abstract void EmitCreateCollection(MyILGenerator il, LocalBuilder lengthVar);
예제 #21
0
 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;
 }