Ejemplo n.º 1
0
        public virtual LocalVariableInfo NewLocal(NewType localVariableType)
        {
            LocalBuilder lb = gen.DeclareLocal(localVariableType.Type);

            while (indexToTypeList.Count <= lb.LocalIndex)
            {
                indexToTypeList.Add(null);
            }
            indexToTypeList[lb.LocalIndex] = lb.LocalType;
            return(lb);
        }
Ejemplo n.º 2
0
 private Dictionary <VariableReference, LocalBuilder> AddVariables(IILGenerator generator,
                                                                   IEnumerable <VariableReference> variables)
 {
     return(variables.ToDictionary(
                variable => variable,
                variable => generator.DeclareLocal(_typeResolver.Resolve(variable.VariableType))));
 }
Ejemplo n.º 3
0
        public LocalBuilder DeclareLocal(Type localType)
        {
            ArgumentUtility.CheckNotNull("localType", localType);

            var emittableOperand = _emittableOperandProvider.GetEmittableType(localType);

            return(_innerILGenerator.DeclareLocal(emittableOperand));
        }
Ejemplo n.º 4
0
        private static void CreateInitValueType(Type targetType, IILGenerator gen)
        {
            var _var = gen.DeclareLocal(targetType);

            gen
            .Ldloca_S(_var)
            .Initobj(targetType)
            .Ldloc_0();
        }
Ejemplo n.º 5
0
        private static void AddMethodImplementation(TypeBuilder typeBuilder, Type interfaceType, MethodInfo methodInfo, FieldBuilder handlerFieldBuilder)
        {
            string methodName = $"{interfaceType.Name}.{methodInfo.Name}";

            ParameterInfo[] parameters     = methodInfo.GetParameters();
            Type[]          ParameterTypes = parameters.Select(p => p.ParameterType).ToArray();
            MethodBuilder   methodBuilder  = typeBuilder.DefineMethod(methodName, Private | Final | HideBySig | NewSlot | Virtual, methodInfo.ReturnType, ParameterTypes);

            for (int i = 0; i < parameters.Length; i++)
            {
                ParameterInfo parameter = parameters[i];
                methodBuilder.DefineParameter(i + 1, parameter.Attributes, parameter.Name);
            }

            IILGenerator il = CreateILGenerator(methodBuilder.GetILGenerator());
            LocalBuilder parametersLocal       = il.DeclareLocal(typeof(object[]));
            LocalBuilder resultLocal           = il.DeclareLocal(typeof(object));
            bool         hasReturnValue        = methodInfo.ReturnType == typeof(void);
            int          parametersLocalLength = parameters.Length;

            il.Emit(Ldc_I4, parametersLocalLength);
            il.Emit(Newarr, typeof(object));
            il.Emit(Stloc, parametersLocal);

            for (int i = 0; i < parameters.Length; i++)
            {
                ParameterInfo parameterInfo     = parameters[i];
                Type          parameterType     = parameterInfo.ParameterType;
                TypeInfo      parameterTypeInfo = parameterType.GetTypeInfo();

                il.Emit(Ldloc, parametersLocal);
                il.Emit(Ldc_I4, i);
                il.Emit(Ldarg, i + 1);

                if (parameterType.IsByRef)
                {
                    Type     elementType     = parameterType.GetElementType();
                    TypeInfo elementTypeInfo = elementType.GetTypeInfo();

                    if (elementTypeInfo.IsClass)
                    {
                        il.Emit(Ldind_Ref);
                    }
                    else if (ldindOpCodes.TryGetValue(elementType, out var opCode))
                    {
                        il.Emit(opCode);
                    }
                    else
                    {
                        il.Emit(Ldobj, elementType);
                    }
                }
                else if (!parameterTypeInfo.IsClass)
                {
                    il.Emit(Box, parameterType);
                }

                il.Emit(Stelem_Ref);
            }

            il.Emit(Ldarg_0);
            il.Emit(Ldfld, handlerFieldBuilder);
            il.Emit(Call, typeof(MethodBase).GetMethod(nameof(MethodBase.GetCurrentMethod)));
            il.Emit(Ldloc, parametersLocal);
            il.Emit(Callvirt, typeof(IProxyHandler).GetMethod(nameof(IProxyHandler.HandleMethod)));
            il.Emit(Stloc, resultLocal);

            for (int i = 0; i < parameters.Length; i++)
            {
                ParameterInfo parameterInfo     = parameters[i];
                Type          parameterType     = parameterInfo.ParameterType;
                TypeInfo      parameterTypeInfo = parameterType.GetTypeInfo();

                if (parameterType.IsByRef)
                {
                    Type     elementType     = parameterType.GetElementType();
                    TypeInfo elementTypeInfo = elementType.GetTypeInfo();

                    il.Emit(Ldarg, i + 1);
                    il.Emit(Ldloc, parametersLocal);
                    il.Emit(Ldc_I4, i);
                    il.Emit(Ldelem_Ref);

                    if (elementTypeInfo.IsClass)
                    {
                        il.Emit(Castclass, elementType);
                        il.Emit(Stind_Ref);
                    }
                    else
                    {
                        il.Emit(Unbox_Any, elementType);

                        if (stindOpCodes.TryGetValue(elementType, out var opCode))
                        {
                            il.Emit(opCode);
                        }
                        else
                        {
                            il.Emit(Stobj, elementType);
                        }
                    }
                }
            }

            if (methodInfo.ReturnType != typeof(void))
            {
                il.Emit(Ldloc, resultLocal);

                if (!methodInfo.ReturnType.GetTypeInfo().IsClass)
                {
                    il.Emit(Unbox_Any, methodInfo.ReturnType);
                }
            }

            il.Emit(Ret);

            typeBuilder.DefineMethodOverride(methodBuilder, methodInfo);
        }