Пример #1
0
        public static void Register(ITypeResolver typeResolver)
        {
            // Registering GetHashCode
            var tokenResolutions = new List <object>();

            tokenResolutions.Add(
                new SynthesizedThisMethod(
                    SynthesizedGetSizeMethod.Name,
                    typeResolver.System.System_Object,
                    typeResolver.GetIntTypeByByteSize(LlvmWriter.PointerSize),
                    true));
            tokenResolutions.Add(typeResolver.System.System_Byte.ToPointerType());

            var locals = new List <IType>();

            locals.Add(typeResolver.System.System_Byte.ToPointerType());
            locals.Add(typeResolver.System.System_Int32);
            locals.Add(typeResolver.System.System_Byte.ToPointerType());
            locals.Add(typeResolver.System.System_Int32);
            locals.Add(typeResolver.System.System_Int32);

            var parameters = new List <IParameter>();

            parameters.Add(typeResolver.System.System_Object.ToParameter());

            MethodBodyBank.Register(Name, ByteCode, tokenResolutions, locals, parameters);
        }
Пример #2
0
        public static void Register(ITypeResolver typeResolver)
        {
            var codeList = new List <object>();

            codeList.AddRange(
                new object[]
            {
                Code.Ldarg_0,
            });

            codeList.AppendInt(Code.Castclass, 1);
            codeList.AppendInt(Code.Ldfld, 2);
            codeList.Add(Code.Ret);

            var arrayType = typeResolver.System.System_Byte.ToArrayType(1);

            var tokenResolutions = new List <object>();

            tokenResolutions.Add(arrayType);
            tokenResolutions.Add(arrayType.GetFieldByName("rank", typeResolver));

            var locals = new List <IType>();

            var parameters = new List <IParameter>();

            MethodBodyBank.Register(Name, codeList.ToArray(), tokenResolutions, locals, parameters);
        }
Пример #3
0
        public static void Register(ITypeResolver typeResolver)
        {
            var codeBuilder = new IlCodeBuilder();

            codeBuilder.LoadArgument(0);
            codeBuilder.Add(Code.Call, 1);
            codeBuilder.Add(Code.Dup);
            codeBuilder.LoadArgument(0);
            codeBuilder.Add(Code.Stfld, 2);
            codeBuilder.Add(Code.Ret);

            var parameters = new List <IParameter>();

            parameters.Add(typeResolver.System.System_Int32.ToParameter());

            var tokenResolutions = new List <object>();

            tokenResolutions.Add(
                new SynthesizedStaticMethod(
                    string.Empty,
                    typeResolver.System.System_String,
                    typeResolver.System.System_String,
                    parameters,
                    (llvmWriter, opCode) => llvmWriter.WriteNewMethodBody(opCode, typeResolver.System.System_String, enableStringFastAllocation: true)));
            tokenResolutions.Add(typeResolver.System.System_String.GetFieldByName("m_stringLength", typeResolver));

            var locals = new List <IType>();

            MethodBodyBank.Register(Name, codeBuilder.GetCode(), tokenResolutions, locals, parameters);
        }
Пример #4
0
        public static void Register(ITypeResolver typeResolver)
        {
            var codeList = new IlCodeBuilder();

            codeList.LoadArgument(0);
            codeList.Add(Code.Castclass, 1);
            codeList.Add(Code.Ldfld, 2);

            var label1 = codeList.Branch(Code.Brtrue, Code.Brtrue_S);

            codeList.LoadArgument(1);

            var label2 = codeList.Branch(Code.Brtrue, Code.Brtrue_S);

            codeList.LoadConstant(0);
            codeList.Add(Code.Ret);

            codeList.Add(label1);
            codeList.Add(label2);

            codeList.LoadArgument(0);
            codeList.Add(Code.Castclass, 3);
            codeList.Add(Code.Ldfld, 4);

            // Rank - index - 1
            codeList.LoadArgument(0);
            codeList.Add(Code.Castclass, 1);
            codeList.Add(Code.Ldfld, 2);
            codeList.LoadArgument(1);
            codeList.Add(Code.Sub);
            codeList.LoadConstant(1);
            codeList.Add(Code.Sub);

            codeList.Add(Code.Ldelem_I4);

            codeList.Add(Code.Ret);

            var arrayType      = typeResolver.System.System_Byte.ToArrayType(1);
            var arrayTypeMulti = typeResolver.System.System_Byte.ToArrayType(2);

            // Registering GetHashCode
            var tokenResolutions = new List <object>();

            tokenResolutions.Add(arrayType);
            tokenResolutions.Add(arrayType.GetFieldByName("rank", typeResolver));
            tokenResolutions.Add(arrayTypeMulti);
            tokenResolutions.Add(arrayTypeMulti.GetFieldByName("lowerBounds", typeResolver));

            var locals = new List <IType>();

            var parameters = new List <IParameter>();

            parameters.Add(typeResolver.System.System_Int32.ToParameter());

            MethodBodyBank.Register(Name, codeList.GetCode(), tokenResolutions, locals, parameters);
        }
Пример #5
0
        private static IEnumerable <IType> GetAllRequiredTypesForMethod(
            IMethod method,
            ReadingTypesContext readingTypesContext)
        {
            DicoverGenericSpecializedTypesAndAdditionalTypes(
                method.ReturnType,
                readingTypesContext);

            foreach (var param in method.GetParameters())
            {
                DicoverGenericSpecializedTypesAndAdditionalTypes(
                    param.ParameterType,
                    readingTypesContext);
            }

            if (method.DeclaringType.IsInterface)
            {
                yield break;
            }

            var methodWithCustomBodyOrDefault = MethodBodyBank.GetMethodWithCustomBodyOrDefault(method, _codeWriter);
            var methodBody = methodWithCustomBodyOrDefault.GetMethodBody(MetadataGenericContext.DiscoverFrom(method));

            if (methodBody != null)
            {
                foreach (var localVar in methodBody.LocalVariables)
                {
                    DicoverGenericSpecializedTypesAndAdditionalTypes(
                        localVar.LocalType,
                        readingTypesContext);
                    if (localVar.LocalType.IsStructureType() && !localVar.LocalType.IsPointer && !localVar.LocalType.IsByRef)
                    {
                        yield return(localVar.LocalType);
                    }
                }

                var usedStructTypes = new NamespaceContainer <IType>();
                methodWithCustomBodyOrDefault.DiscoverRequiredTypesAndMethodsInMethodBody(
                    readingTypesContext.GenericTypeSpecializations,
                    readingTypesContext.GenericMethodSpecializations,
                    usedStructTypes,
                    readingTypesContext.AdditionalTypesToProcess,
                    new Queue <IMethod>());
                foreach (var usedStructType in usedStructTypes)
                {
                    yield return(usedStructType);
                }
            }
        }
Пример #6
0
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="typeResolver">
        /// </param>
        public SynthesizedEnumToStringMethod(IType type, ITypeResolver typeResolver)
            : base("ToString", type, typeResolver.System.System_String, isOverride: true)
        {
            object[] code;
            IList<object> tokenResolutions;
            IList<IType> locals;
            IList<IParameter> parameters;
            EnumGen.GetEnumToStringMethod(type, typeResolver, out code, out tokenResolutions, out locals, out parameters);

            this._methodBody = new SynthesizedMethodBodyDecorator(
                null,
                locals,
                MethodBodyBank.Transform(code).ToArray());

            this._parameters = parameters;
            this._tokenResolutions = tokenResolutions;
        }
Пример #7
0
        public static void Register(ICodeWriter codeWriter)
        {
            // Registering GetHashCode
            var tokenResolutions = new List <object>();

            tokenResolutions.Add(codeWriter.ResolveType("System.Byte").ToPointerType());
            tokenResolutions.Add(new SynthesizedStaticMethod(
                                     "",
                                     codeWriter.ResolveType("System.Array"),
                                     codeWriter.ResolveType("System.Int32"),
                                     new[] { codeWriter.ResolveType("System.Array") },
                                     (llvmWriter, opCode) =>
            {
                // get element size
                llvmWriter.WriteArrayGetElementSize(opCode);
            }));
            tokenResolutions.Add(new SynthesizedStaticMethod(
                                     "",
                                     codeWriter.ResolveType("System.Array"),
                                     codeWriter.ResolveType("System.Void"),
                                     new[] { codeWriter.ResolveType("System.Byte").ToPointerType(), codeWriter.ResolveType("System.Byte").ToPointerType(), codeWriter.ResolveType("System.Int32") },
                                     (llvmWriter, opCode) =>
            {
                // copy data
                var firstByteOfSourceArray = opCode.OpCodeOperands[0].Result;
                var firstByteOfDestArray   = opCode.OpCodeOperands[1].Result;
                var len = opCode.OpCodeOperands[2].Result;
                llvmWriter.WriteMemCopy(firstByteOfSourceArray, firstByteOfDestArray, len);
            }));
            tokenResolutions.Add(codeWriter.ResolveType("System.Byte"));
            tokenResolutions.Add(codeWriter.ResolveType("System.Byte").ToArrayType(1));

            var locals = new List <IType>();

            locals.Add(codeWriter.ResolveType("System.Int32"));

            var parameters = new List <IType>();

            parameters.Add(codeWriter.ResolveType("System.Array"));
            parameters.Add(codeWriter.ResolveType("System.Int32"));
            parameters.Add(codeWriter.ResolveType("System.Array"));
            parameters.Add(codeWriter.ResolveType("System.Int32"));
            parameters.Add(codeWriter.ResolveType("System.Int32"));

            MethodBodyBank.Register(ArrayCopyGen.Name, ArrayCopyGen.ByteCode, tokenResolutions, locals, parameters);
        }
        public static void Register(ITypeResolver typeResolver)
        {
            // Registering UnsafeCastToStackPointerGen
            var tokenResolutions = new List <object>();

            tokenResolutions.Add(
                IlReader.Constructors(typeResolver.System.System_IntPtr, typeResolver)
                .First(
                    c =>
                    c.GetParameters().Count() == 1 &&
                    c.GetParameters().First().ParameterType.TypeEquals(typeResolver.System.System_Void.ToPointerType())));

            var locals = new List <IType>();

            // params will be taken from method
            MethodBodyBank.Register(Name, ByteCode, tokenResolutions, locals, null);
        }
Пример #9
0
        public static void Register(ITypeResolver typeResolver)
        {
            var arrayType = typeResolver.System.System_Byte.ToArrayType(1);

            // Registering GetHashCode
            var tokenResolutions = new List <object>();

            tokenResolutions.Add(typeResolver.System.System_Byte.ToPointerType());
            tokenResolutions.Add(arrayType.GetFieldByName("elementSize", typeResolver));
            tokenResolutions.Add(
                new SynthesizedStaticMethod(
                    string.Empty,
                    typeResolver.System.System_Array,
                    typeResolver.System.System_Void,
                    new[]
            {
                typeResolver.System.System_Byte.ToPointerType().ToParameter(),
                typeResolver.System.System_Byte.ToPointerType().ToParameter(),
                typeResolver.System.System_Int32.ToParameter()
            },
                    (llvmWriter, opCode) =>
            {
                // copy data
                var firstByteOfSourceArray = opCode.OpCodeOperands[0].Result;
                var firstByteOfDestArray   = opCode.OpCodeOperands[1].Result;
                var len = opCode.OpCodeOperands[2].Result;
                llvmWriter.WriteMemCopy(firstByteOfSourceArray, firstByteOfDestArray, len);
            }));
            tokenResolutions.Add(typeResolver.System.System_Byte);
            tokenResolutions.Add(arrayType);

            var locals = new List <IType>();

            locals.Add(typeResolver.System.System_Int32);

            var parameters = new List <IParameter>();

            parameters.Add(typeResolver.System.System_Array.ToParameter());
            parameters.Add(typeResolver.System.System_Int32.ToParameter());
            parameters.Add(typeResolver.System.System_Array.ToParameter());
            parameters.Add(typeResolver.System.System_Int32.ToParameter());
            parameters.Add(typeResolver.System.System_Int32.ToParameter());

            MethodBodyBank.Register(Name, ByteCode, tokenResolutions, locals, parameters);
        }
Пример #10
0
        public static void Register(ITypeResolver typeResolver)
        {
            // Registering GetHashCode
            var tokenResolutions = new List <object>();

            tokenResolutions.Add(
                new SynthesizedThisMethod(
                    SynthesizedGetSizeMethod.Name,
                    typeResolver.System.System_Object,
                    typeResolver.GetIntTypeByByteSize(LlvmWriter.PointerSize),
                    true));
            tokenResolutions.Add(typeResolver.System.System_Byte.ToPointerType());
            tokenResolutions.Add(
                new SynthesizedStaticMethod(
                    string.Empty,
                    typeResolver.System.System_Object,
                    typeResolver.System.System_Byte.ToPointerType(),
                    new[] { typeResolver.System.System_Int32.ToParameter() },
                    (llvmWriter, opCode) => llvmWriter.WriteAllocateMemory(opCode, opCode.OpCodeOperands[0].Result, false)));
            tokenResolutions.Add(
                new SynthesizedStaticMethod(
                    string.Empty,
                    typeResolver.System.System_Object,
                    typeResolver.System.System_Void,
                    new[]
            {
                typeResolver.System.System_Byte.ToPointerType().ToParameter(),
                typeResolver.System.System_Byte.ToPointerType().ToParameter(),
                typeResolver.System.System_Int32.ToParameter()
            },
                    (llvmWriter, opCode) => llvmWriter.WriteMemCopy(
                        opCode.OpCodeOperands[0].Result,
                        opCode.OpCodeOperands[1].Result,
                        opCode.OpCodeOperands[2].Result)));
            tokenResolutions.Add(typeResolver.System.System_Object);

            var locals = new List <IType>();

            locals.Add(typeResolver.System.System_Byte.ToPointerType());
            locals.Add(typeResolver.System.System_Int32);

            var parameters = new List <IParameter>();

            MethodBodyBank.Register(Name, ByteCode, tokenResolutions, locals, parameters);
        }
Пример #11
0
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="typeResolver">
        /// </param>
        public SynthesizedMultiDimArrayGetMethod(IType type, ITypeResolver typeResolver)
            : base("Get", type, type.GetElementType())
        {
            object[]           code;
            IList <object>     tokenResolutions;
            IList <IType>      locals;
            IList <IParameter> parameters;

            ArrayMultiDimensionGen.GetMultiDimensionArrayGet(type, typeResolver, out code, out tokenResolutions, out locals, out parameters);

            this._methodBody = new SynthesizedMethodBodyDecorator(
                null,
                locals,
                MethodBodyBank.Transform(code).ToArray());

            this._parameters       = parameters;
            this._tokenResolutions = tokenResolutions;
        }
Пример #12
0
        public static void Register(ITypeResolver typeResolver)
        {
            // Registering GetHashCode
            var tokenResolutions = new List <object>();

            tokenResolutions.Add(
                new SynthesizedThisMethod(
                    SynthesizedGetTypeMethod.Name,
                    typeResolver.System.System_Object,
                    typeResolver.System.System_Type,
                    true));

            var locals = new List <IType>();

            var parameters = new List <IParameter>();

            MethodBodyBank.Register(Name, ByteCode, tokenResolutions, locals, parameters);
        }
Пример #13
0
        public static void Register(ICodeWriter codeWriter)
        {
            // Registering GetHashCode
            var tokenResolutions = new List <object>();

            tokenResolutions.Add(new SynthesizedThisMethod("GetType", codeWriter.ResolveType("System.Object"), codeWriter.ResolveType("System.Type"), true));
            tokenResolutions.Add(new SynthesizedThisMethod("get_Size", codeWriter.ResolveType("System.Type"), codeWriter.ResolveType("System.Int32"), true));
            tokenResolutions.Add(codeWriter.ResolveType("System.Byte").ToPointerType());

            var locals = new List <IType>();

            locals.Add(codeWriter.ResolveType("System.Int32"));
            locals.Add(codeWriter.ResolveType("System.Int32"));
            locals.Add(codeWriter.ResolveType("System.Int32"));
            locals.Add(codeWriter.ResolveType("System.Byte").ToPointerType());

            var parameters = new List <IType>();

            MethodBodyBank.Register(GetHashCodeGen.Name, GetHashCodeGen.ByteCode, tokenResolutions, locals, parameters);
        }
Пример #14
0
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="typeResolver">
        /// </param>
        public SynthesizedMultiDimArrayCtorMethod(IType arrayType, ITypeResolver typeResolver)
            : base(arrayType, ".ctor")
        {
            this.typeResolver = typeResolver;

            object[]           code;
            IList <object>     tokenResolutions;
            IList <IType>      locals;
            IList <IParameter> parameters;

            ArrayMultiDimensionGen.GetMultiDimensionArrayCtor(arrayType, typeResolver, out code, out tokenResolutions, out locals, out parameters);

            this._methodBody = new SynthesizedMethodBodyDecorator(
                null,
                locals,
                MethodBodyBank.Transform(code).ToArray());

            this._parameters       = parameters;
            this._tokenResolutions = tokenResolutions;
        }
Пример #15
0
        public static void Register(ITypeResolver typeResolver)
        {
            var codeList = new List <object>();

            codeList.Add(Code.Ldnull);
            codeList.AppendInt(Code.Castclass, 1);
            codeList.AppendInt(Code.Ldflda, 2);
            codeList.Add(Code.Ret);

            // Registering UnsafeCastToStackPointerGen
            var tokenResolutions = new List <object>();
            var stringType       = typeResolver.System.System_String;

            tokenResolutions.Add(stringType);
            tokenResolutions.Add(stringType.GetFieldByName("m_firstChar", typeResolver));

            var locals = new List <IType>();

            var parameters = new List <IParameter>();

            MethodBodyBank.Register(Name, codeList.ToArray(), tokenResolutions, locals, parameters);
        }
Пример #16
0
        public static void Register(ICodeWriter codeWriter)
        {
            // Registering GetHashCode
            var tokenResolutions = new List <object>();

            tokenResolutions.Add(new SynthesizedThisMethod("GetType", codeWriter.ResolveType("System.Object"), codeWriter.ResolveType("System.Type"), true));
            tokenResolutions.Add(new SynthesizedThisMethod("get_Size", codeWriter.ResolveType("System.Type"), codeWriter.ResolveType("System.Int32"), true));
            tokenResolutions.Add(codeWriter.ResolveType("System.Byte").ToPointerType());
            tokenResolutions.Add(new SynthesizedStaticMethod(
                                     "",
                                     codeWriter.ResolveType("System.Object"),
                                     codeWriter.ResolveType("System.Byte").ToPointerType(),
                                     new[] { codeWriter.ResolveType("System.Int32") },
                                     (llvmWriter, opCode) =>
            {
                // write method allocation
                llvmWriter.WriteAllocateMemory(opCode, opCode.OpCodeOperands[0].Result, false);
            }));
            tokenResolutions.Add(new SynthesizedStaticMethod(
                                     "",
                                     codeWriter.ResolveType("System.Object"),
                                     codeWriter.ResolveType("System.Void"),
                                     new[] { codeWriter.ResolveType("System.Byte").ToPointerType(), codeWriter.ResolveType("System.Byte").ToPointerType(), codeWriter.ResolveType("System.Int32") },
                                     (llvmWriter, opCode) =>
            {
                // write method copy
                llvmWriter.WriteMemCopy(opCode.OpCodeOperands[0].Result, opCode.OpCodeOperands[1].Result, opCode.OpCodeOperands[2].Result);
            }));
            tokenResolutions.Add(codeWriter.ResolveType("System.Object"));

            var locals = new List <IType>();

            locals.Add(codeWriter.ResolveType("System.Byte").ToPointerType());
            locals.Add(codeWriter.ResolveType("System.Int32"));

            var parameters = new List <IType>();

            MethodBodyBank.Register(MemberwiseCloneGen.Name, MemberwiseCloneGen.ByteCode, tokenResolutions, locals, parameters);
        }
        public static void Register(ITypeResolver typeResolver)
        {
            var codeList = new IlCodeBuilder();

            // get TypeCode of TypedReference
            codeList.LoadArgument(0);
            codeList.Add(Code.Ldflda, 2);
            // IntPtr.m_value
            codeList.Add(Code.Ldfld, 3);
            codeList.Add(Code.Conv_I4);

            // switch
            var @switch = codeList.Switch();

            // goto default case
            //var defaultCaseLabel1 = codeList.Branch(Code.Br, Code.Br_S);

            // TODO: do not support Structs for now
            var defaultCaseLabel1 = codeList.CreateLabel();

            codeList.Add(Code.Newobj, 20);
            codeList.Add(Code.Throw);

            // case 0(TypeCode.Empty) -> Default
            @switch.Labels.Add(defaultCaseLabel1);

            // case 1(TypeCode.Object) -> Default
            @switch.Labels.Add(defaultCaseLabel1);

            // case 2(TypeCode.DBNull) -> Default
            @switch.Labels.Add(defaultCaseLabel1);

            // case 3(TypeCode.Boolean)
            @switch.Labels.Add(codeList.CreateLabel());
            // get Value of TypedReference
            codeList.LoadArgument(0);
            codeList.Add(Code.Ldflda, 1);
            // IntPtr.m_value
            codeList.Add(Code.Ldfld, 3);
            codeList.LoadArgument(1);
            codeList.Add(Code.Unbox, 6);
            codeList.Add(Code.Stind_I1);
            codeList.Add(Code.Ret);

            // case 4(TypeCode.Char)
            @switch.Labels.Add(codeList.CreateLabel());
            // get Value of TypedReference
            codeList.LoadArgument(0);
            codeList.Add(Code.Ldflda, 1);
            // IntPtr.m_value
            codeList.Add(Code.Ldfld, 3);
            codeList.LoadArgument(1);
            codeList.Add(Code.Unbox, 7);
            codeList.Add(Code.Stind_I2);
            codeList.Add(Code.Ret);

            // case 5(TypeCode.SByte)
            @switch.Labels.Add(codeList.CreateLabel());
            // get Value of TypedReference
            codeList.LoadArgument(0);
            codeList.Add(Code.Ldflda, 1);
            // IntPtr.m_value
            codeList.Add(Code.Ldfld, 3);
            codeList.LoadArgument(1);
            codeList.Add(Code.Unbox, 8);
            codeList.Add(Code.Stind_I1);
            codeList.Add(Code.Ret);

            // case 6(TypeCode.Byte)
            @switch.Labels.Add(codeList.CreateLabel());
            // get Value of TypedReference
            codeList.LoadArgument(0);
            codeList.Add(Code.Ldflda, 1);
            // IntPtr.m_value
            codeList.Add(Code.Ldfld, 3);
            codeList.LoadArgument(1);
            codeList.Add(Code.Unbox, 9);
            codeList.Add(Code.Stind_I1);
            codeList.Add(Code.Ret);

            // case 7(TypeCode.Int16)
            @switch.Labels.Add(codeList.CreateLabel());
            // get Value of TypedReference
            codeList.LoadArgument(0);
            codeList.Add(Code.Ldflda, 1);
            // IntPtr.m_value
            codeList.Add(Code.Ldfld, 3);
            codeList.LoadArgument(1);
            codeList.Add(Code.Unbox, 10);
            codeList.Add(Code.Stind_I2);
            codeList.Add(Code.Ret);

            // case 8(TypeCode.UInt16)
            @switch.Labels.Add(codeList.CreateLabel());
            // get Value of TypedReference
            codeList.LoadArgument(0);
            codeList.Add(Code.Ldflda, 1);
            // IntPtr.m_value
            codeList.Add(Code.Ldfld, 3);
            codeList.LoadArgument(1);
            codeList.Add(Code.Unbox, 11);
            codeList.Add(Code.Stind_I2);
            codeList.Add(Code.Ret);

            // case 9(TypeCode.Int32)
            @switch.Labels.Add(codeList.CreateLabel());
            // get Value of TypedReference
            codeList.LoadArgument(0);
            codeList.Add(Code.Ldflda, 1);
            // IntPtr.m_value
            codeList.Add(Code.Ldfld, 3);
            codeList.LoadArgument(1);
            codeList.Add(Code.Unbox, 12);
            codeList.Add(Code.Stind_I4);
            codeList.Add(Code.Ret);

            // case 10(TypeCode.UInt32)
            @switch.Labels.Add(codeList.CreateLabel());
            // get Value of TypedReference
            codeList.LoadArgument(0);
            codeList.Add(Code.Ldflda, 1);
            // IntPtr.m_value
            codeList.Add(Code.Ldfld, 3);
            codeList.LoadArgument(1);
            codeList.Add(Code.Unbox, 13);
            codeList.Add(Code.Stind_I4);
            codeList.Add(Code.Ret);

            // case 11(TypeCode.Int64)
            @switch.Labels.Add(codeList.CreateLabel());
            // get Value of TypedReference
            codeList.LoadArgument(0);
            codeList.Add(Code.Ldflda, 1);
            // IntPtr.m_value
            codeList.Add(Code.Ldfld, 3);
            codeList.LoadArgument(1);
            codeList.Add(Code.Unbox, 14);
            codeList.Add(Code.Stind_I8);
            codeList.Add(Code.Ret);

            // case 12(TypeCode.UInt64)
            @switch.Labels.Add(codeList.CreateLabel());
            // get Value of TypedReference
            codeList.LoadArgument(0);
            codeList.Add(Code.Ldflda, 1);
            // IntPtr.m_value
            codeList.Add(Code.Ldfld, 3);
            codeList.LoadArgument(1);
            codeList.Add(Code.Unbox, 15);
            codeList.Add(Code.Stind_I8);
            codeList.Add(Code.Ret);

            // case 13(TypeCode.Single)
            @switch.Labels.Add(codeList.CreateLabel());
            // get Value of TypedReference
            codeList.LoadArgument(0);
            codeList.Add(Code.Ldflda, 1);
            // IntPtr.m_value
            codeList.Add(Code.Ldfld, 3);
            codeList.LoadArgument(1);
            codeList.Add(Code.Unbox, 16);
            codeList.Add(Code.Stind_R4);
            codeList.Add(Code.Ret);

            // case 14(TypeCode.Double)
            @switch.Labels.Add(codeList.CreateLabel());
            // get Value of TypedReference
            codeList.LoadArgument(0);
            codeList.Add(Code.Ldflda, 1);
            // IntPtr.m_value
            codeList.Add(Code.Ldfld, 3);
            codeList.LoadArgument(1);
            codeList.Add(Code.Unbox, 17);
            codeList.Add(Code.Stind_R8);
            codeList.Add(Code.Ret);

            // case 15(TypeCode.Decimal)
            @switch.Labels.Add(codeList.CreateLabel());
            // get Value of TypedReference
            codeList.LoadArgument(0);
            codeList.Add(Code.Ldflda, 1);
            // IntPtr.m_value
            codeList.Add(Code.Ldfld, 3);
            codeList.LoadArgument(1);
            codeList.Add(Code.Unbox, 18);
            codeList.Add(Code.Ret);

            // case 16(TypeCode.DateTime)
            @switch.Labels.Add(codeList.CreateLabel());
            // get Value of TypedReference
            codeList.LoadArgument(0);
            codeList.Add(Code.Ldflda, 1);
            // IntPtr.m_value
            codeList.Add(Code.Ldfld, 3);
            codeList.LoadArgument(1);
            codeList.Add(Code.Unbox, 19);
            codeList.Add(Code.Ret);

            // case 17 -> Default
            @switch.Labels.Add(codeList.CreateLabel());
            // throw NotSupportedException
            codeList.Add(Code.Newobj, 20);
            codeList.Add(Code.Throw);

            // case 18(TypeCode.String) -> Default
            @switch.Labels.Add(defaultCaseLabel1);

            // default:
            codeList.Add(defaultCaseLabel1);

            // get Value of TypedReference (default case)
            codeList.LoadArgument(0);
            codeList.Add(Code.Ldflda, 1);
            // IntPtr.m_value
            codeList.Add(Code.Ldfld, 3);
            codeList.Add(Code.Castclass, 4);
            codeList.LoadArgument(1);
            codeList.Add(Code.Stind_Ref);

            codeList.Add(Code.Ret);

            var typedReferenceType = typeResolver.System.System_TypedReference;
            var intPtrType         = typeResolver.System.System_IntPtr;

            var tokenResolutions = new List <object>();

            tokenResolutions.Add(typedReferenceType.GetFieldByName("Value", typeResolver));
            tokenResolutions.Add(typedReferenceType.GetFieldByName("Type", typeResolver));
            tokenResolutions.Add(intPtrType.GetFieldByName("m_value", typeResolver));
            tokenResolutions.Add(typeResolver.System.System_Object.ToPointerType());
            tokenResolutions.Add(typeResolver.System.System_Object);
            tokenResolutions.Add(typeResolver.System.System_Boolean);
            tokenResolutions.Add(typeResolver.System.System_Char);
            tokenResolutions.Add(typeResolver.System.System_SByte);
            tokenResolutions.Add(typeResolver.System.System_Byte);
            tokenResolutions.Add(typeResolver.System.System_Int16);
            tokenResolutions.Add(typeResolver.System.System_UInt16);
            tokenResolutions.Add(typeResolver.System.System_Int32);
            tokenResolutions.Add(typeResolver.System.System_UInt32);
            tokenResolutions.Add(typeResolver.System.System_Int64);
            tokenResolutions.Add(typeResolver.System.System_UInt64);
            tokenResolutions.Add(typeResolver.System.System_Single);
            tokenResolutions.Add(typeResolver.System.System_Double);
            tokenResolutions.Add(typeResolver.System.System_Decimal);
            tokenResolutions.Add(typeResolver.System.System_DateTime);
            tokenResolutions.Add(
                IlReader.Constructors(typeResolver.System.System_NotSupportedException, typeResolver).First(c => !c.GetParameters().Any()));

            var locals = new List <IType>();

            var parameters = new List <IParameter>();

            parameters.Add(typeResolver.System.System_Void.ToPointerType().ToParameter());
            parameters.Add(typeResolver.System.System_Object.ToParameter());

            MethodBodyBank.Register(Name, codeList.GetCode(), tokenResolutions, locals, parameters);
        }
Пример #18
0
        /// <summary>
        /// </summary>
        /// <param name="ilReader">
        /// </param>
        /// <param name="codeWriter">
        /// </param>
        /// <param name="type">
        /// </param>
        /// <param name="genericDefinition">
        /// </param>
        /// <param name="genericMethodSpecializatons">
        /// </param>
        /// <param name="mode">
        /// </param>
        /// <param name="processGenericMethodsOnly">
        /// </param>
        private static void ConvertIType(
            IlReader ilReader,
            ICodeWriter codeWriter,
            IType type,
            IType genericDefinition,
            IEnumerable <IMethod> genericMethodSpecializatons,
            ConvertingMode mode,
            bool processGenericMethodsOnly = false)
        {
            Debug.WriteLine("Converting {0}, Mode: {1}", type, mode);

            var typeSpecialization = type.IsGenericType && !type.IsGenericTypeDefinition ? type : null;

            var genericContext = new MetadataGenericContext();

            genericContext.TypeDefinition       = genericDefinition;
            genericContext.TypeSpecialization   = typeSpecialization;
            genericContext.MethodDefinition     = null;
            genericContext.MethodSpecialization = null;

            if (mode == ConvertingMode.Declaration)
            {
                if (!codeWriter.IsProcessed(type))
                {
                    WriteTypeDefinition(codeWriter, type, genericContext);
                }

                codeWriter.WritePostDeclarations(type);

                codeWriter.WriteBeforeConstructors();
            }

            if (mode == ConvertingMode.Definition)
            {
                codeWriter.DisableWrite(true);

                if (!processGenericMethodsOnly)
                {
                    // pre process step to get all used undefined structures
                    foreach (var ctor in IlReader.Constructors(type))
                    {
                        IConstructor genericCtor = null;
                        if (type.IsGenericType && !type.IsInterface && !type.IsDelegate)
                        {
                            // find the same constructor in generic class
                            Debug.Assert(genericDefinition != null);
                            genericCtor = IlReader.Constructors(genericDefinition).First(gm => ctor.IsMatchingGeneric(gm));
                        }

                        genericContext.MethodDefinition     = genericCtor;
                        genericContext.MethodSpecialization = null;

                        codeWriter.WriteConstructorStart(ctor, genericContext);

                        foreach (var ilCode in ilReader.OpCodes(genericCtor ?? ctor, genericContext))
                        {
                            codeWriter.Write(ilCode);
                        }

                        codeWriter.WriteConstructorEnd(ctor, genericContext);
                    }
                }

                codeWriter.DisableWrite(false);

                // Actual Write
                codeWriter.WriteRequiredTypesForBody();
                codeWriter.WriteStoredText();
            }

            if (mode == ConvertingMode.Declaration)
            {
                codeWriter.WriteAfterConstructors();
                codeWriter.WriteBeforeMethods();
            }

            if (mode == ConvertingMode.Definition)
            {
                codeWriter.DisableWrite(true);

                // pre process step to get all used undefined structures
                foreach (var method in IlReader.MethodsOriginal(type).Select(m => MethodBodyBank.GetMethodBodyOrDefault(m, codeWriter)))
                {
                    IMethod genericMethod = null;
                    if (type.IsGenericType && !type.IsInterface && !type.IsDelegate)
                    {
                        // find the same method in generic class
                        genericMethod = IlReader.MethodsOriginal(genericDefinition).First(gm => method.IsMatchingGeneric(gm.ToSpecialization(genericContext)));
                    }

                    if (!method.IsGenericMethodDefinition && !processGenericMethodsOnly)
                    {
                        genericContext.MethodDefinition     = genericMethod;
                        genericContext.MethodSpecialization = genericMethod != null ? method : null;

                        codeWriter.WriteMethodStart(method, genericContext);

                        foreach (var ilCode in ilReader.OpCodes(genericMethod ?? method, genericContext))
                        {
                            codeWriter.Write(ilCode);
                        }

                        codeWriter.WriteMethodEnd(method, genericContext);
                    }
                    else
                    {
                        // write all specializations of a method
                        if (genericMethodSpecializatons != null)
                        {
                            foreach (var methodSpec in genericMethodSpecializatons)
                            {
                                if (!methodSpec.IsMatchingGeneric(method))
                                {
                                    continue;
                                }

                                genericContext.MethodDefinition     = method;
                                genericContext.MethodSpecialization = methodSpec;

                                codeWriter.WriteMethodStart(methodSpec, genericContext);

                                foreach (var ilCode in ilReader.OpCodes(genericMethod ?? method, genericContext))
                                {
                                    codeWriter.Write(ilCode);
                                }

                                codeWriter.WriteMethodEnd(methodSpec, genericContext);
                            }
                        }
                    }
                }

                codeWriter.DisableWrite(false);

                // Actual Write
                codeWriter.WriteRequiredTypesForBody();
                codeWriter.WriteStoredText();
            }

            if (mode == ConvertingMode.Declaration)
            {
                codeWriter.WriteAfterMethods();
                codeWriter.WriteTypeEnd(type);
            }
        }
Пример #19
0
        /// <summary>
        /// </summary>
        /// <param name="ilReader">
        /// </param>
        /// <param name="codeWriter">
        /// </param>
        /// <param name="type">
        /// </param>
        /// <param name="typeDefinition">
        /// </param>
        /// <param name="genericMethodSpecializatons">
        /// </param>
        /// <param name="mode">
        /// </param>
        /// <param name="processGenericMethodsOnly">
        /// </param>
        private static void ConvertIType(
            IlReader ilReader,
            ICodeWriter codeWriter,
            IType type,
            IEnumerable <IMethod> genericMethodSpecializatons,
            ConvertingMode mode,
            bool processGenericMethodsOnly = false)
        {
            if (VerboseOutput)
            {
                Trace.WriteLine(string.Format("Converting {0}, Mode: {1}", type, mode));
            }

            var typeDefinition     = type.IsGenericType ? type.GetTypeDefinition() : null;
            var typeSpecialization = type.IsGenericType && !type.IsGenericTypeDefinition ? type : null;
            var genericTypeContext = typeDefinition != null || typeSpecialization != null
                                         ? MetadataGenericContext.Create(typeDefinition, typeSpecialization)
                                         : null;

            if (mode == ConvertingMode.Declaration)
            {
                if (!codeWriter.IsProcessed(type))
                {
                    WriteTypeDefinition(codeWriter, type, genericTypeContext);
                }

                codeWriter.WritePostDeclarationsAndInternalDefinitions(type);

                codeWriter.WriteBeforeConstructors();
            }

            if (mode == ConvertingMode.Definition)
            {
                codeWriter.DisableWrite(true);

                if (!processGenericMethodsOnly)
                {
                    // pre process step to get all used undefined structures
                    foreach (var ctor in IlReader.Constructors(type, codeWriter))
                    {
                        codeWriter.WriteConstructorStart(ctor, genericTypeContext);

                        foreach (var ilCode in ilReader.OpCodes(type.IsGenericType ? ctor.GetMethodDefinition() : ctor, genericTypeContext))
                        {
                            codeWriter.Write(ilCode);
                        }

                        codeWriter.WriteConstructorEnd(ctor, genericTypeContext);
                    }
                }

                codeWriter.DisableWrite(false);

                // Actual Write
                codeWriter.WriteRequiredTypesForBody();
                codeWriter.WriteStoredText();
            }

            if (mode == ConvertingMode.Declaration)
            {
                codeWriter.WriteAfterConstructors();
                codeWriter.WriteBeforeMethods();
            }

            if (mode == ConvertingMode.Definition)
            {
                codeWriter.DisableWrite(true);

                // pre process step to get all used undefined structures
                foreach (
                    var method in
                    IlReader.Methods(type, codeWriter, true).Select(m => MethodBodyBank.GetMethodWithCustomBodyOrDefault(m, codeWriter)))
                {
                    if (!method.IsGenericMethodDefinition && !processGenericMethodsOnly)
                    {
                        var genericMethodContext = method.IsGenericMethod
                                                       ? MetadataGenericContext.Create(typeDefinition, typeSpecialization, method.GetMethodDefinition(), method)
                                                       : genericTypeContext;

                        codeWriter.WriteMethodStart(method, genericMethodContext);

                        foreach (var ilCode in ilReader.OpCodes(type.IsGenericType ? method.GetMethodDefinition() : method, genericMethodContext))
                        {
                            codeWriter.Write(ilCode);
                        }

                        codeWriter.WriteMethodEnd(method, genericMethodContext);
                    }

                    if (method.IsGenericMethodDefinition || method.IsGenericMethod)
                    {
                        // write all specializations of a method
                        if (genericMethodSpecializatons != null)
                        {
                            var methodDefinition = method.GetMethodDefinition();
                            foreach (
                                var methodSpec in
                                genericMethodSpecializatons.Where(
                                    methodSpec => methodSpec.IsMatchingGeneric(methodDefinition) && (!methodSpec.Equals(method) || processGenericMethodsOnly)))
                            {
                                var genericMethodContext = MetadataGenericContext.Create(typeDefinition, typeSpecialization, method, methodSpec);

                                codeWriter.WriteMethodStart(methodSpec, genericMethodContext);

                                foreach (var ilCode in ilReader.OpCodes(methodDefinition ?? method, genericMethodContext))
                                {
                                    codeWriter.Write(ilCode);
                                }

                                codeWriter.WriteMethodEnd(methodSpec, genericMethodContext);
                            }
                        }
                    }
                }

                codeWriter.DisableWrite(false);

                // Actual Write
                codeWriter.WriteRequiredTypesForBody();
                codeWriter.WriteStoredText();
            }

            if (mode == ConvertingMode.Declaration)
            {
                codeWriter.WriteAfterMethods();
                codeWriter.WriteTypeEnd(type);
            }
        }
Пример #20
0
        public static void Register(ITypeResolver typeResolver)
        {
            var codeList = new IlCodeBuilder();

            // set Type of TypedReference
            codeList.LoadArgument(1);
            codeList.Add(Code.Ldflda, 2);

            // Load element typeCode
            codeList.LoadArgument(0);
            codeList.Add(Code.Castclass, 4);
            codeList.Add(Code.Ldfld, 5);

            // Save typeCode into TypedReference TypeCode
            codeList.Add(Code.Conv_I);
            codeList.Add(Code.Stfld, 3);

            // Calculate data index
            // check if it 1-dim array
            codeList.LoadArgument(2);
            codeList.LoadConstant(1);
            codeList.Add(Code.Sub);
            var labelGotoMultiDimArray = codeList.Branch(Code.Brtrue, Code.Brtrue_S);

            // set Value of TypedReference
            codeList.LoadArgument(1);
            codeList.Add(Code.Ldflda, 1);

            // Load reference to an array (do not load reference to field data)
            codeList.LoadArgument(0);
            codeList.Add(Code.Castclass, 4);

            // Load elementSize
            codeList.LoadArgument(0);
            codeList.Add(Code.Castclass, 4);
            codeList.Add(Code.Ldfld, 6);
            codeList.Add(Code.Dup);
            codeList.SaveLocal(0);

            // Load index
            codeList.LoadArgument(3);
            codeList.Add(Code.Ldind_I4);

            // multiply it
            codeList.Add(Code.Mul);

            // load address of an element
            codeList.Add(Code.Ldelema, 7);

            // align index
            codeList.LoadLocal(0);
            // elementSize - 1
            codeList.LoadConstant(1);
            codeList.Add(Code.Sub);
            codeList.Add(Code.Dup);
            codeList.SaveLocal(0);

            // size + align - 1
            codeList.Add(Code.Add);

            // size &= ~(align - 1)
            codeList.LoadLocal(0);
            codeList.LoadConstant(-1);
            codeList.Add(Code.Xor);
            codeList.Add(Code.And);

            // Save address into TypedReference Value
            codeList.Add(Code.Conv_I);
            codeList.Add(Code.Stfld, 3);
            codeList.Add(Code.Ret);

            // for multiarray
            codeList.Add(labelGotoMultiDimArray);

            // *indeces += count;
            codeList.LoadArgument(3);
            codeList.LoadArgument(2);
            codeList.Add(Code.Conv_I);
            codeList.LoadConstant(4);
            codeList.Add(Code.Mul);
            codeList.Add(Code.Add);
            codeList.SaveArgument(3);

            // init multiplier
            // Load elementSize
            codeList.LoadArgument(0);
            codeList.Add(Code.Castclass, 4);
            codeList.Add(Code.Ldfld, 6);
            codeList.SaveLocal(0);

            // calculate first index
            codeList.LoadArgument(3);
            codeList.LoadConstant(4);
            codeList.Add(Code.Sub);
            codeList.Add(Code.Dup);
            codeList.SaveArgument(3);
            codeList.Add(Code.Ldind_I4);
            codeList.LoadArgument(0);
            codeList.Add(Code.Castclass, 9);
            codeList.Add(Code.Ldfld, 10);
            codeList.LoadConstant(0);
            codeList.Add(Code.Ldelem_I4);
            codeList.Add(Code.Sub);
            codeList.LoadLocal(0);
            codeList.Add(Code.Mul);
            codeList.SaveLocal(1);

            // init 'i' (index)
            codeList.LoadConstant(1);
            codeList.SaveLocal(2);

            var labelLoopStart = codeList.Branch(Code.Br, Code.Br_S);
            // loop start

            var labelLoopBack = codeList.CreateLabel();

            codeList.LoadLocal(0);
            codeList.LoadArgument(0);
            codeList.Add(Code.Castclass, 9);
            codeList.Add(Code.Ldfld, 11);
            codeList.LoadLocal(2);
            codeList.LoadConstant(1);
            codeList.Add(Code.Sub);
            codeList.Add(Code.Ldelem_I4);
            codeList.Add(Code.Mul);
            codeList.SaveLocal(0);
            codeList.LoadLocal(1);
            codeList.LoadArgument(3);
            codeList.LoadConstant(4);
            codeList.Add(Code.Sub);
            codeList.Add(Code.Dup);
            codeList.SaveArgument(3);
            codeList.Add(Code.Ldind_I4);
            codeList.LoadArgument(0);
            codeList.Add(Code.Castclass, 9);
            codeList.Add(Code.Ldfld, 10);
            codeList.LoadLocal(2);
            codeList.Add(Code.Ldelem_I4);
            codeList.Add(Code.Sub);
            codeList.LoadLocal(0);
            codeList.Add(Code.Mul);
            codeList.Add(Code.Add);
            codeList.SaveLocal(1);
            codeList.LoadLocal(2);
            codeList.LoadConstant(1);
            codeList.Add(Code.Add);
            codeList.SaveLocal(2);

            codeList.Add(labelLoopStart);

            codeList.LoadLocal(2);
            codeList.LoadArgument(2);

            codeList.Branch(Code.Blt, Code.Blt_S, labelLoopBack);

            // set Value of TypedReference
            codeList.LoadArgument(1);
            codeList.Add(Code.Ldflda, 1);

            // align index (array offset) (Local.0) and save it to TypedReferenece
            // Load reference to an array (do not load reference to field data)
            codeList.LoadArgument(0);
            codeList.Add(Code.Castclass, 9);
            codeList.LoadLocal(1);
            // load address of an element
            codeList.Add(Code.Ldelema, 7);

            // elementSize
            codeList.LoadArgument(0);
            codeList.Add(Code.Castclass, 4);
            codeList.Add(Code.Ldfld, 6);

            // elementSize - 1
            codeList.LoadConstant(1);
            codeList.Add(Code.Sub);
            codeList.Add(Code.Dup);
            codeList.SaveLocal(2);

            // size + align - 1
            codeList.Add(Code.Add);

            // size &= ~(align - 1)
            codeList.LoadLocal(2);
            codeList.LoadConstant(-1);
            codeList.Add(Code.Xor);
            codeList.Add(Code.And);

            // Save address into TypedReference Value
            codeList.Add(Code.Conv_I);
            codeList.Add(Code.Stfld, 3);

            codeList.Add(Code.Ret);

            var typedReferenceType = typeResolver.System.System_TypedReference;
            var intPtrType         = typeResolver.System.System_IntPtr;
            var byteType           = typeResolver.System.System_Byte;
            var arrayType          = byteType.ToArrayType(1);
            var multiArrayType     = byteType.ToArrayType(2);

            var tokenResolutions = new List <object>();

            tokenResolutions.Add(typedReferenceType.GetFieldByName("Value", typeResolver));
            tokenResolutions.Add(typedReferenceType.GetFieldByName("Type", typeResolver));
            tokenResolutions.Add(intPtrType.GetFieldByName("m_value", typeResolver));
            tokenResolutions.Add(arrayType);
            tokenResolutions.Add(arrayType.GetFieldByName("typeCode", typeResolver));
            tokenResolutions.Add(arrayType.GetFieldByName("elementSize", typeResolver));
            tokenResolutions.Add(byteType);
            tokenResolutions.Add(arrayType.GetFieldByName("rank", typeResolver));
            tokenResolutions.Add(multiArrayType);
            tokenResolutions.Add(multiArrayType.GetFieldByName("lowerBounds", typeResolver));
            tokenResolutions.Add(multiArrayType.GetFieldByName("lengths", typeResolver));

            var locals = new List <IType>();

            locals.Add(typeResolver.System.System_Int32);
            locals.Add(typeResolver.System.System_Int32);
            locals.Add(typeResolver.System.System_Int32);

            var parameters = new List <IParameter>();

            parameters.Add(typeResolver.System.System_Void.ToPointerType().ToParameter());
            parameters.Add(typeResolver.System.System_Int32.ToParameter());
            parameters.Add(typeResolver.System.System_Int32.ToPointerType().ToParameter());

            MethodBodyBank.Register(Name, codeList.GetCode(), tokenResolutions, locals, parameters);
        }