Ejemplo n.º 1
0
        private Instruction SetCacheKeyLocalVariable(Instruction current, MethodDefinition methodDefinition,
                                                     ILProcessor processor, int cacheKeyIndex, int objectArrayIndex)
        {
            if (methodDefinition.IsSetter || methodDefinition.IsGetter)
            {
                return(current.AppendStloc(processor, cacheKeyIndex));
            }
            else
            {
                // Create object[] for string.format
                current =
                    current.AppendLdcI4(processor, methodDefinition.Parameters.Count)
                    .Append(processor.Create(OpCodes.Newarr, ModuleDefinition.TypeSystem.Object), processor)
                    .AppendStloc(processor, objectArrayIndex);

                // Set object[] values
                for (int i = 0; i < methodDefinition.Parameters.Count; i++)
                {
                    current =
                        current.AppendLdloc(processor, objectArrayIndex)
                        .AppendLdcI4(processor, i)
                        .AppendLdarg(processor, !methodDefinition.IsStatic ? i + 1 : i)
                        .AppendBoxIfNecessary(processor, methodDefinition.Parameters[i].ParameterType)
                        .Append(processor.Create(OpCodes.Stelem_Ref), processor);
                }

                // Call string.format
                return
                    (current.AppendLdloc(processor, objectArrayIndex)
                     .Append(processor.Create(OpCodes.Call,
                                              methodDefinition.Module.ImportMethod(References.StringFormatMethod)), processor)
                     .AppendStloc(processor, cacheKeyIndex));
            }
        }
Ejemplo n.º 2
0
        private static Instruction SetCacheKeyLocalVariable(BaseModuleWeaver weaver, Instruction current, MethodDefinition methodDefinition,
                                                            ILProcessor processor, int cacheKeyIndex, int objectArrayIndex)
        {
            if (methodDefinition.IsSetter || methodDefinition.IsGetter)
            {
                return(current.AppendStloc(processor, cacheKeyIndex));
            }
            else
            {
                // Create object[] for string.format
                int parameterCount = methodDefinition.Parameters.Count + methodDefinition.GenericParameters.Count;

                current = current
                          .AppendLdcI4(processor, parameterCount)
                          .Append(processor.Create(OpCodes.Newarr, weaver.ModuleDefinition.TypeSystem.Object), processor)
                          .AppendStloc(processor, objectArrayIndex);


                // Set object[] values
                for (int i = 0; i < methodDefinition.GenericParameters.Count; i++)
                {
                    current = current
                              .AppendLdloc(processor, objectArrayIndex)
                              .AppendLdcI4(processor, i)
                              .Append(processor.Create(OpCodes.Ldtoken, methodDefinition.GenericParameters[i]), processor)
                              .Append(processor.Create(OpCodes.Call, methodDefinition.Module.ImportMethod(ReferenceFinder.SystemTypeGetTypeFromHandleMethod)),
                                      processor)
                              .Append(processor.Create(OpCodes.Stelem_Ref), processor);
                }

                for (int i = 0; i < methodDefinition.Parameters.Count; i++)
                {
                    current = current
                              .AppendLdloc(processor, objectArrayIndex)
                              .AppendLdcI4(processor, methodDefinition.GenericParameters.Count + i)
                              .AppendLdarg(processor, !methodDefinition.IsStatic ? i + 1 : i)
                              .AppendBoxIfNecessary(processor, methodDefinition.Parameters[i].ParameterType)
                              .Append(processor.Create(OpCodes.Stelem_Ref), processor);
                }

                // Call string.format



                var ins = processor.Create(OpCodes.Call, methodDefinition.Module.ImportMethod(ReferenceFinder.StringFormatMethod));

                return(current
                       .AppendLdloc(processor, objectArrayIndex)
                       .Append(ins, processor)
                       .AppendStloc(processor, cacheKeyIndex));
            }
        }
Ejemplo n.º 3
0
        public static Instruction AppendLd(this Instruction instruction, ILProcessor processor, CustomAttributeArgument argument)
        {
            // Tested with the following types (see ECMA-334, 24.1.3 attribute parameter types)
            // bool, byte, char, double, float, int, long, sbyte, short, string, uint, ulong, ushort.
            // object
            // System.Type
            // An enum type, provided it has public accessibility and the types in which it is nested (if any) also have public accessibility (§17.2)
            // Single-dimensional arrays of the above types
            TypeReference argumentType = argument.Type;

            switch (argumentType.MetadataType)
            {
            case MetadataType.ValueType:
                if (argumentType.Resolve().IsEnum == false)
                {
                    throw new ArgumentException("Type Enum expected.", "argument");
                }

                // Get underlying Enum type
                argumentType = argument.Type.Resolve().Fields.First(field => field.Name == "value__").FieldType;
                break;

            case MetadataType.Object:
                return(instruction.AppendLd(processor, (CustomAttributeArgument)argument.Value));

            case MetadataType.Array:
                CustomAttributeArgument[] values = (CustomAttributeArgument[])argument.Value;

                instruction = instruction
                              .AppendLdcI4(processor, values.Length)
                              .Append(processor.Create(OpCodes.Newarr, argument.Type.GetElementType()), processor);

                TypeReference arrayType = argument.Type.GetElementType();

                for (int i = 0; i < values.Length; i++)
                {
                    instruction = instruction
                                  .AppendDup(processor)
                                  .AppendLdcI4(processor, i)
                                  .AppendLd(processor, values[i]);

                    if (arrayType == ReferenceFinder.Weaver.ModuleDefinition.TypeSystem.Object)
                    {
                        instruction = instruction.AppendBoxIfNecessary(processor, ((CustomAttributeArgument)values[i].Value).Type);
                    }
                    else if (argumentType.Resolve().IsEnum)
                    {
                        // Get underlying Enum type
                        arrayType = argument.Type.Resolve().Fields.First(field => field.Name == "value__").FieldType;
                    }

                    if (arrayType.IsValueType)
                    {
                        switch (arrayType.MetadataType)
                        {
                        case MetadataType.Boolean:
                        case MetadataType.SByte:
                        case MetadataType.Byte:
                            instruction = instruction.Append(processor.Create(OpCodes.Stelem_I1), processor);
                            break;

                        case MetadataType.Char:
                        case MetadataType.Int16:
                        case MetadataType.UInt16:
                            instruction = instruction.Append(processor.Create(OpCodes.Stelem_I2), processor);
                            break;

                        case MetadataType.Int32:
                        case MetadataType.UInt32:
                            instruction = instruction.Append(processor.Create(OpCodes.Stelem_I4), processor);
                            break;

                        case MetadataType.Int64:
                        case MetadataType.UInt64:
                            instruction = instruction.Append(processor.Create(OpCodes.Stelem_I8), processor);
                            break;

                        case MetadataType.Single:
                            instruction = instruction.Append(processor.Create(OpCodes.Stelem_R4), processor);
                            break;

                        case MetadataType.Double:
                            instruction = instruction.Append(processor.Create(OpCodes.Stelem_R8), processor);
                            break;

                        default:
                            throw new ArgumentException("Unrecognized array value type.", "argument");
                        }
                    }
                    else
                    {
                        instruction = instruction.Append(processor.Create(OpCodes.Stelem_Ref), processor);
                    }
                }

                return(instruction);
            }

            switch (argumentType.MetadataType)
            {
            case MetadataType.Boolean:
            case MetadataType.SByte:
                return(instruction.Append(processor.Create(OpCodes.Ldc_I4_S, Convert.ToSByte(argument.Value)), processor));

            case MetadataType.Int16:
                return(instruction.Append(processor.Create(OpCodes.Ldc_I4, Convert.ToInt16(argument.Value)), processor));

            case MetadataType.Int32:
                return(instruction.Append(processor.Create(OpCodes.Ldc_I4, Convert.ToInt32(argument.Value)), processor));

            case MetadataType.Int64:
                return(instruction.Append(processor.Create(OpCodes.Ldc_I8, Convert.ToInt64(argument.Value)), processor));

            case MetadataType.Byte:
                return(instruction.Append(processor.Create(OpCodes.Ldc_I4, Convert.ToInt32(argument.Value)), processor));

            case MetadataType.UInt16:
                unchecked
                {
                    return(instruction.Append(processor.Create(OpCodes.Ldc_I4, (Int16)(UInt16)argument.Value), processor));
                }

            case MetadataType.Char:
                return(instruction.Append(processor.Create(OpCodes.Ldc_I4, Convert.ToChar(argument.Value)), processor));

            case MetadataType.UInt32:
                unchecked
                {
                    return(instruction.Append(processor.Create(OpCodes.Ldc_I4, (Int32)(UInt32)argument.Value), processor));
                }

            case MetadataType.UInt64:
                unchecked
                {
                    return(instruction.Append(processor.Create(OpCodes.Ldc_I8, (Int64)(UInt64)argument.Value), processor));
                }

            case MetadataType.Single:
                return(instruction.Append(processor.Create(OpCodes.Ldc_R4, Convert.ToSingle(argument.Value)), processor));

            case MetadataType.Double:
                return(instruction.Append(processor.Create(OpCodes.Ldc_R8, Convert.ToDouble(argument.Value)), processor));

            case MetadataType.String:
                return(instruction.Append(processor.Create(OpCodes.Ldstr, (string)argument.Value), processor));

            case MetadataType.Class:
                if (argumentType.Resolve().IsDefinition == false)
                {
                    throw new ArgumentException("Type Type expected.", "argument");
                }

                return
                    (instruction
                     .Append(processor.Create(OpCodes.Ldtoken, (TypeReference)argument.Value), processor)
                     .Append(processor.Create(OpCodes.Call, ReferenceFinder.Weaver.ModuleDefinition.ImportMethod(
                                                  ReferenceFinder.SystemTypeGetTypeFromHandleMethod)), processor));

            default:
                throw new ArgumentException("Unrecognized attribute parameter type.", "argument");
            }
        }