Exemplo n.º 1
0
    void AddRpc(TypeDefinition newType, MethodDefinition irpc)
    {
        var tag = irpc.CustomAttributes.FirstOrDefault(x => x.AttributeType.Name == "TAG");

        if (tag is null)
        {
            return;
        }
        var cmdx = tag.ConstructorArguments.First().Value;
        var cmd  = 0;

        switch (cmdx)
        {
        case Mono.Cecil.CustomAttributeArgument args:
            cmd = (int)args.Value;
            break;

        default:
            cmd = (int)cmdx;
            break;
        }


        var method = new MethodDefinition(irpc.Name, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, irpc.ReturnType);

        var il = method.Body.GetILProcessor();

        var parameters = irpc.Parameters;
        var paramTypes = ParamTypes(parameters.ToArray(), false);

        for (int i = 0; i < paramTypes.Length; i++)
        {
            method.Parameters.Add(new ParameterDefinition(parameters[i].Name, parameters[i].Attributes, paramTypes[i]));
        }

        if (irpc.ContainsGenericParameter)
        {
            throw new Exception($"not have generic parameter{irpc.FullName}");
        }

        var returntype = irpc.ReturnType;

        if (returntype.IsGenericInstance)
        {
            var genreturntype = returntype as GenericInstanceType;

            if (genreturntype.Name != "Task`1")
            {
                throw new Exception($"return type error:{genreturntype.FullName}");
            }

            if (genreturntype.GenericArguments[0].Name == "IResult")
            {
                ParametersArray args = new ParametersArray(this, il, paramTypes);

                il.Emit(OpCodes.Nop);
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, obj);
                il.Emit(OpCodes.Ldc_I4, cmd);

                GenericArray <object> argsArr = new GenericArray <object>(this, il, ParamTypes(parameters.ToArray(), true).Length);

                for (int i = 0; i < parameters.Count; i++)
                {
                    // args[i] = argi;
                    if (!parameters[i].IsOut)
                    {
                        argsArr.BeginSet(i);
                        args.Get(i);
                        argsArr.EndSet(parameters[i].ParameterType);
                    }
                }
                argsArr.Load();

                var asyncAction = obj.FieldType.Resolve().Methods.First(p => p.Name == "AsyncFunc");

                il.Emit(OpCodes.Callvirt, ModuleDefinition.ImportReference(asyncAction));
                il.Emit(OpCodes.Ret);
                newType.Methods.Add(method);
            }
            else
            {
                ParametersArray args = new ParametersArray(this, il, paramTypes);

                il.Emit(OpCodes.Nop);
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, obj);
                il.Emit(OpCodes.Ldc_I4, cmd);

                GenericArray <object> argsArr = new GenericArray <object>(this, il, ParamTypes(parameters.ToArray(), true).Length);

                for (int i = 0; i < parameters.Count; i++)
                {
                    // args[i] = argi;
                    if (!parameters[i].IsOut)
                    {
                        argsArr.BeginSet(i);
                        args.Get(i);
                        argsArr.EndSet(parameters[i].ParameterType);
                    }
                }
                argsArr.Load();

                var genericAsyncFunc = obj.FieldType.Resolve().Methods.First(p => p.Name == "AsyncFunc" && p.CallingConvention == MethodCallingConvention.Generic);

                il.Emit(OpCodes.Callvirt, ModuleDefinition.ImportReference(MakeGenericInstanceMethod(genericAsyncFunc, genreturntype.GenericArguments.ToArray())));
                il.Emit(OpCodes.Ret);
                newType.Methods.Add(method);
            }
        }
        else if (returntype.FullName == "System.Void")
        {
            ParametersArray args = new ParametersArray(this, il, paramTypes);

            il.Emit(OpCodes.Nop);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, obj);
            il.Emit(OpCodes.Ldc_I4, cmd);

            GenericArray <object> argsArr = new GenericArray <object>(this, il, ParamTypes(parameters.ToArray(), true).Length);

            for (int i = 0; i < parameters.Count; i++)
            {
                // args[i] = argi;
                if (!parameters[i].IsOut)
                {
                    argsArr.BeginSet(i);
                    args.Get(i);
                    argsArr.EndSet(parameters[i].ParameterType);
                }
            }
            argsArr.Load();

            var Action = obj.FieldType.Resolve().Methods.First(p => p.Name == "Action");

            il.Emit(OpCodes.Callvirt, ModuleDefinition.ImportReference(Action));
            il.Emit(OpCodes.Nop);
            il.Emit(OpCodes.Ret);
            newType.Methods.Add(method);
        }
        else if (returntype.FullName == "System.Threading.Tasks.Task")
        {
            ParametersArray args = new ParametersArray(this, il, paramTypes);

            il.Emit(OpCodes.Nop);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, obj);
            il.Emit(OpCodes.Ldc_I4, cmd);

            GenericArray <object> argsArr = new GenericArray <object>(this, il, ParamTypes(parameters.ToArray(), true).Length);

            for (int i = 0; i < parameters.Count; i++)
            {
                // args[i] = argi;
                if (!parameters[i].IsOut)
                {
                    argsArr.BeginSet(i);
                    args.Get(i);
                    argsArr.EndSet(parameters[i].ParameterType);
                }
            }
            argsArr.Load();

            var asyncAction = obj.FieldType.Resolve().Methods.First(p => p.Name == "AsyncAction");

            il.Emit(OpCodes.Callvirt, ModuleDefinition.ImportReference(asyncAction));
            il.Emit(OpCodes.Ret);
            newType.Methods.Add(method);
        }
        else
        {
            ParametersArray args = new ParametersArray(this, il, paramTypes);
            il.Emit(OpCodes.Nop);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, obj);
            il.Emit(OpCodes.Ldc_I4, cmd);

            il.Emit(OpCodes.Ldtoken, irpc.ReturnType);
            var ptype = ModuleDefinition.ImportReference(GetMethodInfo.GetTypeofHandler());
            il.Emit(OpCodes.Call, ptype);


            GenericArray <object> argsArr = new GenericArray <object>(this, il, ParamTypes(parameters.ToArray(), true).Length);

            for (int i = 0; i < parameters.Count; i++)
            {
                // args[i] = argi;
                if (!parameters[i].IsOut)
                {
                    argsArr.BeginSet(i);
                    args.Get(i);
                    argsArr.EndSet(parameters[i].ParameterType);
                }
            }
            argsArr.Load();

            var func = obj.FieldType.Resolve().Methods.First(p => p.Name == "Func");
            il.Emit(OpCodes.Callvirt, ModuleDefinition.ImportReference(func));

            var res = new VariableDefinition(irpc.ReturnType);
            method.Body.Variables.Add(res);
            Convert(il, ModuleDefinition.ImportReference(typeof(object)), irpc.ReturnType, false);
            il.Emit(OpCodes.Stloc, res);
            il.Emit(OpCodes.Ldloc, res);

            il.Emit(OpCodes.Ret);
            newType.Methods.Add(method);
        }
    }
Exemplo n.º 2
0
            private void AddMethodImpl(MethodInfo mi)
            {
                ParameterInfo[] parameters = mi.GetParameters();
                Type[]          paramTypes = ParamTypes(parameters, false);

                MethodBuilder mdb = _tb.DefineMethod(mi.Name, MethodAttributes.Public | MethodAttributes.Virtual, mi.ReturnType, paramTypes);

                if (mi.ContainsGenericParameters)
                {
                    Type[]   ts = mi.GetGenericArguments();
                    string[] ss = new string[ts.Length];
                    for (int i = 0; i < ts.Length; i++)
                    {
                        ss[i] = ts[i].Name;
                    }
                    GenericTypeParameterBuilder[] genericParameters = mdb.DefineGenericParameters(ss);
                    for (int i = 0; i < genericParameters.Length; i++)
                    {
                        genericParameters[i].SetGenericParameterAttributes(ts[i].GetTypeInfo().GenericParameterAttributes);
                    }
                }
                ILGenerator il = mdb.GetILGenerator();

                ParametersArray args = new ParametersArray(il, paramTypes);

                // object[] args = new object[paramCount];
                il.Emit(OpCodes.Nop);
                GenericArray <object> argsArr = new GenericArray <object>(il, ParamTypes(parameters, true).Length);

                for (int i = 0; i < parameters.Length; i++)
                {
                    // args[i] = argi;
                    if (!parameters[i].IsOut)
                    {
                        argsArr.BeginSet(i);
                        args.Get(i);
                        argsArr.EndSet(parameters[i].ParameterType);
                    }
                }

                // object[] packed = new object[PackedArgs.PackedTypes.Length];
                GenericArray <object> packedArr = new GenericArray <object>(il, PackedArgs.PackedTypes.Length);

                // packed[PackedArgs.DispatchProxyPosition] = this;
                packedArr.BeginSet(PackedArgs.DispatchProxyPosition);
                il.Emit(OpCodes.Ldarg_0);
                packedArr.EndSet(typeof(DispatchProxy));

                // packed[PackedArgs.DeclaringTypePosition] = typeof(iface);
                MethodInfo Type_GetTypeFromHandle = typeof(Type).GetRuntimeMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) });

                _assembly.GetTokenForMethod(mi, out Type declaringType, out int methodToken);
                packedArr.BeginSet(PackedArgs.DeclaringTypePosition);
                il.Emit(OpCodes.Ldtoken, declaringType);
                il.Emit(OpCodes.Call, Type_GetTypeFromHandle);
                packedArr.EndSet(typeof(object));

                // packed[PackedArgs.MethodTokenPosition] = iface method token;
                packedArr.BeginSet(PackedArgs.MethodTokenPosition);
                il.Emit(OpCodes.Ldc_I4, methodToken);
                packedArr.EndSet(typeof(Int32));

                // packed[PackedArgs.ArgsPosition] = args;
                packedArr.BeginSet(PackedArgs.ArgsPosition);
                argsArr.Load();
                packedArr.EndSet(typeof(object[]));

                // packed[PackedArgs.GenericTypesPosition] = mi.GetGenericArguments();
                if (mi.ContainsGenericParameters)
                {
                    packedArr.BeginSet(PackedArgs.GenericTypesPosition);
                    Type[] genericTypes         = mi.GetGenericArguments();
                    GenericArray <Type> typeArr = new GenericArray <Type>(il, genericTypes.Length);
                    for (int i = 0; i < genericTypes.Length; ++i)
                    {
                        typeArr.BeginSet(i);
                        il.Emit(OpCodes.Ldtoken, genericTypes[i]);
                        il.Emit(OpCodes.Call, Type_GetTypeFromHandle);
                        typeArr.EndSet(typeof(Type));
                    }
                    typeArr.Load();
                    packedArr.EndSet(typeof(Type[]));
                }

                // Call static DispatchProxyHelper.Invoke(object[])
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, _fields[InvokeActionFieldAndCtorParameterIndex]);                 // delegate
                packedArr.Load();
                il.Emit(OpCodes.Call, s_delegateInvoke);

                for (int i = 0; i < parameters.Length; i++)
                {
                    if (parameters[i].ParameterType.IsByRef)
                    {
                        args.BeginSet(i);
                        argsArr.Get(i);
                        args.EndSet(i, typeof(object));
                    }
                }

                if (mi.ReturnType != typeof(void))
                {
                    packedArr.Get(PackedArgs.ReturnValuePosition);
                    Convert(il, typeof(object), mi.ReturnType, false);
                }

                il.Emit(OpCodes.Ret);

                _tb.DefineMethodOverride(mdb, mi);
            }
Exemplo n.º 3
0
    void AddRpc(TypeDefinition newType, MethodDefinition irpc)
    {
        var tag = irpc.CustomAttributes.FirstOrDefault(x => x.AttributeType.Name == "TAG");

        if (tag is null)
        {
            return;
        }

        var cmd = (int)tag.ConstructorArguments.First().Value;

        var method = new MethodDefinition(irpc.Name, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, irpc.ReturnType);

        var il = method.Body.GetILProcessor();

        var parameters = irpc.Parameters;
        var paramTypes = ParamTypes(parameters.ToArray(), false);

        foreach (var param in paramTypes)
        {
            method.Parameters.Add(new ParameterDefinition(param));
        }

        if (irpc.ContainsGenericParameter)
        {
            throw new Exception($"not have generic parameter{irpc.FullName}");
            //var ts = irpc.GenericParameters;
            //for (int i = 0; i < ts.Count; i++)
            //{
            //    method.GenericParameters.Add(ts[i]);
            //}
        }

        ParametersArray args = new ParametersArray(this, il, paramTypes);

        il.Emit(OpCodes.Nop);
        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Ldc_I4, cmd);
        il.Emit(OpCodes.Ldtoken, irpc.ReturnType);

        var ptype = ModuleDefinition.ImportReference(GetMethodInfo.GetTypeofHandler());

        il.Emit(OpCodes.Call, ModuleDefinition.ImportReference(ptype));


        GenericArray <System.Object> argsArr = new GenericArray <System.Object>(this, il, ParamTypes(parameters.ToArray(), true).Length);

        for (int i = 0; i < parameters.Count; i++)
        {
            // args[i] = argi;
            if (!parameters[i].IsOut)
            {
                argsArr.BeginSet(i);
                args.Get(i);
                argsArr.EndSet(parameters[i].ParameterType);
            }
        }
        argsArr.Load();

        il.Emit(OpCodes.Call, _methodcall);

        if (irpc.ReturnType.Name == "Void")
        {
            il.Emit(OpCodes.Pop);
        }
        else
        {
            var res = new VariableDefinition(irpc.ReturnType);
            method.Body.Variables.Add(res);
            Convert(il, ModuleDefinition.ImportReference(typeof(System.Object)), irpc.ReturnType, false);
            il.Emit(OpCodes.Stloc, res);
            il.Emit(OpCodes.Ldloc, res);
        }
        il.Emit(OpCodes.Ret);
        newType.Methods.Add(method);
    }