internal void EndSet(int i, Type stackType) { Debug.Assert(_paramTypes[i].IsByRef); var argType = _paramTypes[i].GetElementType(); ProxyCodes.Convert(_il, stackType, argType, false); ProxyCodes.Stind(_il, argType); }
/// <summary> 添加方法实现 </summary> /// <param name="mi"></param> /// <returns></returns> private MethodBuilder AddMethodImpl(MethodInfo mi) { var parameters = mi.GetParameters(); var paramTypes = ParamTypes(parameters, false); var mdb = _tb.DefineMethod(mi.Name, MethodAttributes.Public | MethodAttributes.Virtual, mi.ReturnType, paramTypes); if (mi.ContainsGenericParameters) { var ts = mi.GetGenericArguments(); var ss = new string[ts.Length]; for (var i = 0; i < ts.Length; i++) { ss[i] = ts[i].Name; } var genericParameters = mdb.DefineGenericParameters(ss); for (var i = 0; i < genericParameters.Length; i++) { genericParameters[i].SetGenericParameterAttributes(ts[i].GetTypeInfo().GenericParameterAttributes); } } var il = mdb.GetILGenerator(); var args = new ParametersArray(il, paramTypes); // object[] args = new object[paramCount]; il.Emit(OpCodes.Nop); var argsArr = new GenericArray <object>(il, ParamTypes(parameters, true).Length); for (var i = 0; i < parameters.Length; i++) { // args[i] = argi; if (parameters[i].IsOut) { continue; } argsArr.BeginSet(i); args.Get(i); argsArr.EndSet(parameters[i].ParameterType); } // object[] packed = new object[PackedArgs.PackedTypes.Length]; var packedArr = new GenericArray <object>(il, PackedArgs.PackedTypes.Length); // packed[PackedArgs.DispatchProxyPosition] = this; packedArr.BeginSet(PackedArgs.DispatchProxyPosition); il.Emit(OpCodes.Ldarg_0); packedArr.EndSet(typeof(ProxyExecutor)); // packed[PackedArgs.DeclaringTypePosition] = typeof(iface); var typeGetTypeFromHandle = typeof(Type).GetRuntimeMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) }); _assembly.GetTokenForMethod(mi, out var declaringType, out var methodToken); packedArr.BeginSet(PackedArgs.DeclaringTypePosition); il.Emit(OpCodes.Ldtoken, declaringType); il.Emit(OpCodes.Call, typeGetTypeFromHandle); packedArr.EndSet(typeof(object)); // packed[PackedArgs.MethodTokenPosition] = iface method token; packedArr.BeginSet(PackedArgs.MethodTokenPosition); il.Emit(OpCodes.Ldc_I4, methodToken); packedArr.EndSet(typeof(int)); // 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); var genericTypes = mi.GetGenericArguments(); var typeArr = new GenericArray <Type>(il, genericTypes.Length); for (var i = 0; i < genericTypes.Length; ++i) { typeArr.BeginSet(i); il.Emit(OpCodes.Ldtoken, genericTypes[i]); il.Emit(OpCodes.Call, typeGetTypeFromHandle); typeArr.EndSet(typeof(Type)); } typeArr.Load(); packedArr.EndSet(typeof(Type[])); } for (var i = 0; i < parameters.Length; i++) { if (!parameters[i].ParameterType.IsByRef) { continue; } args.BeginSet(i); argsArr.Get(i); args.EndSet(i, typeof(object)); } var invokeMethod = SDelegateInvoke; if (mi.ReturnType == typeof(Task)) { invokeMethod = SDelegateInvokeAsync; } if (IsGenericTask(mi.ReturnType)) { var returnTypes = mi.ReturnType.GetGenericArguments(); invokeMethod = SDelegateinvokeAsyncT.MakeGenericMethod(returnTypes); } // Call AsyncDispatchProxyGenerator.Invoke(object[]), InvokeAsync or InvokeAsyncT il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, _fields[InvokeActionFieldAndCtorParameterIndex]); packedArr.Load(); il.Emit(OpCodes.Callvirt, invokeMethod); if (mi.ReturnType != typeof(void)) { ProxyCodes.Convert(il, typeof(object), mi.ReturnType, false); } else { il.Emit(OpCodes.Pop); } il.Emit(OpCodes.Ret); _tb.DefineMethodOverride(mdb, mi); return(mdb); }
internal void EndSet(Type stackType) { ProxyCodes.Convert(_il, stackType, typeof(T), false); _il.Emit(OpCodes.Stelem_Ref); }