Exemplo n.º 1
0
        public NamedInstructionBlockChain CreateObjectVariable()
        {
            var typeReference = _referenceFinder.GetTypeReference(typeof(object));
            var variable      = _creator.CreateVariable(typeReference);

            _method.Body.Variables.Add(variable);
            return(new NamedInstructionBlockChain(variable, typeReference));
        }
        public NamedInstructionBlockChain CreateMethodArgumentsArray()
        {
            //  argument values
            var argumentsTypeReference = _referenceFinder.GetTypeReference(typeof(object[]));
            var argumentsArrayVariable = _creator.CreateVariable(argumentsTypeReference);
            var createObjectArrayWithMethodArgumentsBlock =
                _creator.CreateObjectArrayWithMethodArguments(argumentsArrayVariable,
                                                              _referenceFinder.GetTypeReference(typeof(object)));

            var blockChain = new NamedInstructionBlockChain(argumentsArrayVariable,
                                                            argumentsTypeReference);

            blockChain.Add(createObjectArrayWithMethodArgumentsBlock);
            return(blockChain);
        }
        private IList <Instruction> LoadValueOnStack(TypeReference parameterType, object value, ModuleDefinition module)
        {
            if (parameterType.IsPrimitive || (parameterType.FullName == "System.String"))
            {
                return new List <Instruction> {
                           LoadPrimitiveConstOnStack(parameterType.MetadataType, value)
                }
            }
            ;

            if (parameterType.IsValueType) // enum
            {
                var enumUnderlyingType = GetEnumUnderlyingType(parameterType.Resolve());

                return(new List <Instruction> {
                    LoadPrimitiveConstOnStack(enumUnderlyingType.MetadataType, value)
                });
            }

            if (parameterType.FullName == "System.Type")
            {
                var typeName      = value.ToString();
                var typeReference = module.GetType(typeName, true);

                var typeTypeRef     = _referenceFinder.GetTypeReference(typeof(Type));
                var methodReference = _referenceFinder.GetMethodReference(typeTypeRef, md => md.Name == "GetTypeFromHandle");

                var instructions = new List <Instruction>
                {
                    _processor.Create(OpCodes.Ldtoken, typeReference),
                    _processor.Create(OpCodes.Call, methodReference)
                };

                return(instructions);
            }

            throw new NotSupportedException("Parametertype: " + parameterType);
        }
        public InstructionBlock ReadParameterArray(VariableDefinition executionArgs)
        {
            var instructions = new List <Instruction>();

            var argsAsReturned = CreateVariable(_referenceFinder.GetTypeReference(typeof(Object[])));

            instructions.AddRange(CreateInstanceMethodCallInstructions(executionArgs, argsAsReturned,
                                                                       _referenceFinder.GetMethodReference(executionArgs.VariableType, md => md.Name == "get_Arguments")));

            for (int i = 0; i < _method.Parameters.Count; ++i)
            {
                var p = _method.Parameters[i];
                if (p.ParameterType.IsByReference)
                {
                    instructions.Add(_processor.Create(OpCodes.Ldarg, i + 1));
                }
                instructions.Add(_processor.Create(OpCodes.Ldloc, argsAsReturned));
                instructions.Add(_processor.Create(OpCodes.Ldc_I4, i));
                instructions.Add(_processor.Create(OpCodes.Ldelem_Ref));
                instructions.AddRange(CecilExtensions.StoreTypeInArgument(_processor, p));
            }

            return(new InstructionBlock("ReadParameterArray: ", instructions));
        }
        private IList <Instruction> LoadValueOnStack(TypeReference parameterType, object value)
        {
            if (parameterType.IsArray(out var elementType) && value is CustomAttributeArgument[] args)
            {
                elementType   = elementType.CleanEnumsInTypeRef();
                parameterType = parameterType.CleanEnumsInTypeRef();

                var array = CreateVariable(parameterType);
                var createArrayInstructions = new List <Instruction>()
                {
                    _processor.Create(OpCodes.Ldc_I4, args.Length),
                    _processor.Create(OpCodes.Newarr, elementType),
                    _processor.Create(OpCodes.Stloc, array)
                };

                var stelem = elementType.GetStElemCode();

                for (var i = 0; i < args.Length; ++i)
                {
                    var parameter = args[i];
                    createArrayInstructions.Add(_processor.Create(OpCodes.Ldloc, array));
                    createArrayInstructions.Add(_processor.Create(OpCodes.Ldc_I4, i));
                    createArrayInstructions.AddRange(LoadValueOnStack(elementType, parameter.Value));
                    createArrayInstructions.Add(_processor.Create(stelem));
                }

                createArrayInstructions.Add(_processor.Create(OpCodes.Ldloc, array));
                return(createArrayInstructions);
            }

            if (parameterType.IsEnum(out var enumUnderlyingType))
            {
                enumUnderlyingType = enumUnderlyingType.CleanEnumsInTypeRef();
                return(new List <Instruction>(LoadPrimitiveConstOnStack(enumUnderlyingType.MetadataType, value)));
            }

            if (parameterType.IsPrimitive || (parameterType.FullName == typeof(String).FullName))
            {
                return(new List <Instruction>(LoadPrimitiveConstOnStack(parameterType.MetadataType, value)));
            }

            if (parameterType.FullName == typeof(Type).FullName)
            {
                var typeVal       = (TypeReference)value;
                var typeReference = typeVal.CleanEnumsInTypeRef();

                var typeTypeRef     = _referenceFinder.GetTypeReference(typeof(Type));
                var methodReference = _referenceFinder.GetMethodReference(typeTypeRef, md => md.Name == nameof(Type.GetTypeFromHandle));

                var instructions = new List <Instruction>
                {
                    _processor.Create(OpCodes.Ldtoken, typeReference),
                    _processor.Create(OpCodes.Call, methodReference)
                };

                return(instructions);
            }

            if (parameterType.FullName == typeof(Object).FullName && value is CustomAttributeArgument arg)
            {
                var valueType = arg.Type;
                if (arg.Value is TypeReference)
                {
                    valueType = _referenceFinder.GetTypeReference(typeof(Type));
                }
                var isEnum = valueType.IsEnum(out _);
                valueType = valueType.CleanEnumsInTypeRef();
                var instructions = LoadValueOnStack(valueType, arg.Value);
                if (valueType.IsValueType || (!valueType.IsArray && isEnum))
                {
                    instructions.Add(_processor.Create(OpCodes.Box, valueType));
                }
                return(instructions);
            }

            throw new NotSupportedException("Parametertype: " + parameterType);
        }
        private IList <Instruction> LoadValueOnStack(TypeReference parameterType, object value)
        {
            if (parameterType.IsPrimitive || (parameterType.FullName == "System.String"))
            {
                return new List <Instruction> {
                           LoadPrimitiveConstOnStack(parameterType.MetadataType, value)
                }
            }
            ;

            if (parameterType.IsValueType) // enum
            {
                var enumUnderlyingType = GetEnumUnderlyingType(parameterType.Resolve());

                return(new List <Instruction> {
                    LoadPrimitiveConstOnStack(enumUnderlyingType.MetadataType, value)
                });
            }

            if (parameterType.FullName == "System.Type")
            {
                var typeReference   = (TypeReference)value;
                var typeTypeRef     = _referenceFinder.GetTypeReference(typeof(Type));
                var methodReference = _referenceFinder.GetMethodReference(typeTypeRef, md => md.Name == "GetTypeFromHandle");

                var instructions = new List <Instruction>
                {
                    _processor.Create(OpCodes.Ldtoken, typeReference),
                    _processor.Create(OpCodes.Call, methodReference)
                };

                return(instructions);
            }

            if (parameterType.FullName == typeof(Object).FullName && value is CustomAttributeArgument arg)
            {
                var valueType = _referenceFinder.GetTypeReference(arg.Value.GetType());
                if (arg.Value is TypeReference)
                {
                    valueType = _referenceFinder.GetTypeReference(typeof(Type));
                }
                var instructions = LoadValueOnStack(valueType, arg.Value);
                instructions.Add(_processor.Create(OpCodes.Box, valueType));
                return(instructions);
            }

            if (parameterType.IsArray && value is CustomAttributeArgument[] args)
            {
                var array                   = CreateVariable(parameterType);
                var elementType             = ((ArrayType)parameterType).ElementType;
                var createArrayInstructions = new List <Instruction>()
                {
                    _processor.Create(OpCodes.Ldc_I4, args.Length),
                    _processor.Create(OpCodes.Newarr, elementType),
                    _processor.Create(OpCodes.Stloc, array)
                };

                OpCode stelem;
                if (elementType.IsValueType)
                {
                    stelem = elementType.MetadataType.GetStElemCode();
                }
                else
                {
                    stelem = OpCodes.Stelem_Ref;
                }

                for (int i = 0; i < args.Length; ++i)
                {
                    var parameter = args[i];
                    createArrayInstructions.Add(_processor.Create(OpCodes.Ldloc, array));
                    createArrayInstructions.Add(_processor.Create(OpCodes.Ldc_I4, i));
                    createArrayInstructions.AddRange(LoadValueOnStack(elementType, parameter.Value));
                    createArrayInstructions.Add(_processor.Create(stelem));
                }

                createArrayInstructions.Add(_processor.Create(OpCodes.Ldloc, array));
                return(createArrayInstructions);
            }

            throw new NotSupportedException("Parametertype: " + parameterType);
        }