Exemplo n.º 1
0
        /// <summary>
        /// Generates the MSIL byte code for the .GetTypes() method override which returns a list of given URIs.
        /// </summary>
        /// <param name="processor">A IL processor.</param>
        /// <param name="uris">List of URIs to be returned.</param>
        /// <returns>On success, a non-empty enumeration of instructions.</returns>
        private IEnumerable <Instruction> GenerateGetTypesInstructions(ILProcessor processor, IList <string> uris)
        {
            if (uris.Count == 0)
            {
                yield break;
            }

            // A reference to the item type constructor, however not yet imported from the assembly where it is defined.
            MethodReference ctorref = ClassType.Resolve().TryGetConstructor(typeof(string).FullName);

            if (ctorref == null)
            {
                yield break;
            }

            // A reference to the imported item type constructor.
            MethodReference ctor = Generator.Assembly.MainModule.ImportReference(ctorref);

            if (ctor == null)
            {
                yield break;
            }

            // IL_0000: nop
            // IL_0001: ldc.i4.1
            // IL_0002: newarr [Platform]Platform.Class
            // IL_0007: stloc.1
            // IL_0008: ldloc.1
            // IL_0009: ldc.i4.0
            // IL_000a: ldstr "http://schema.org/Thing"
            // IL_000f: newobj instance void [Platform]Platform.Class::.ctor(string)
            // IL_0014: stelem.ref
            // IL_0015: ldloc.1
            // IL_0016: stloc.0
            // IL_0017: br.s IL_0019 <-- NOTE: references to the next instruction!?
            // IL_0019: ldloc.0
            // IL_001a: ret

            Instruction ldloc = processor.Create(OpCodes.Ldloc_0);

            yield return(processor.Create(OpCodes.Nop));

            // Define the a new array on the stack.
            yield return(processor.CreateLdc_I4(uris.Count));

            yield return(processor.Create(OpCodes.Newarr, ClassType));

            yield return(processor.Create(OpCodes.Stloc_1));

            // Define the array items.
            for (int i = 0; i < uris.Count; i++)
            {
                string uri = uris[i];

                yield return(processor.Create(OpCodes.Ldloc_1));

                yield return(processor.CreateLdc_I4(i));

                yield return(processor.Create(OpCodes.Ldstr, uri));

                yield return(processor.Create(OpCodes.Newobj, ctor));

                yield return(processor.Create(OpCodes.Stelem_Ref));
            }

            // Return a reference to the array.
            yield return(processor.Create(OpCodes.Ldloc_1));

            yield return(processor.Create(OpCodes.Stloc_0));

            yield return(processor.Create(OpCodes.Br_S, ldloc));

            yield return(ldloc);

            yield return(processor.Create(OpCodes.Ret));
        }
        private IEnumerable <Instruction> GetLdX(ILProcessor processor, CustomAttributeArgument defaultValue)
        {
            MetadataType valueType = defaultValue.Type.MetadataType;

            if (valueType == MetadataType.String)
            {
                yield return(processor.Create(OpCodes.Ldstr, (string)defaultValue.Value));
            }
            else if (valueType == MetadataType.Boolean)
            {
                yield return(processor.CreateLdc_I4((bool)defaultValue.Value ? 1 : 0));
            }
            else if (valueType == MetadataType.Int16 || valueType == MetadataType.Int32)
            {
                yield return(processor.CreateLdc_I4((int)defaultValue.Value));
            }
            else if (valueType == MetadataType.UInt16 || valueType == MetadataType.UInt32)
            {
                yield return(processor.CreateLdc_I4((uint)defaultValue.Value));
            }
            else if (valueType == MetadataType.Int64)
            {
                long v = (long)defaultValue.Value;

                if (Int32.MinValue <= v && v <= Int32.MaxValue)
                {
                    yield return(processor.CreateLdc_I4((int)v));

                    yield return(processor.Create(OpCodes.Conv_I8));
                }
                else
                {
                    yield return(processor.Create(OpCodes.Ldc_I8, (long)defaultValue.Value));
                }
            }
            else if (valueType == MetadataType.UInt64)
            {
                ulong v = (ulong)defaultValue.Value;

                if (UInt32.MinValue <= v && v >= UInt32.MaxValue)
                {
                    yield return(processor.CreateLdc_I4((uint)v));

                    yield return(processor.Create(OpCodes.Conv_I8));
                }
                else
                {
                    yield return(processor.Create(OpCodes.Ldc_I8, (ulong)defaultValue.Value));
                }
            }
            else if (valueType == MetadataType.Single)
            {
                yield return(processor.Create(OpCodes.Ldobj, (float)defaultValue.Value));
            }
            else if (valueType == MetadataType.Double)
            {
                yield return(processor.Create(OpCodes.Ldobj, (double)defaultValue.Value));
            }
            else
            {
                throw new Exception("Unsupported data type for default value: {0}" + defaultValue.Value.GetType());
            }
        }