Exemple #1
0
        /// <inheritdoc />
        protected override void GenerateImplementation(IntrospectiveMethodInfo method, string symbolName, string uniqueMemberIdentifier)
        {
            var definition = GenerateInvokerDefinition(method);

            GenerateImplementationForDefinition(definition, symbolName, uniqueMemberIdentifier);

            TargetType.DefineMethodOverride(definition.GetWrappedMember(), method.GetWrappedMember());
        }
Exemple #2
0
        /// <inheritdoc />
        protected override void GenerateImplementation(IntrospectiveMethodInfo member, string symbolName, string uniqueMemberIdentifier)
        {
            var generatedMethods = new List <IntrospectiveMethodInfo>();

            // Generate permutation definitions
            var permutations = _permutationGenerator.Generate(member);

            for (int i = 0; i < permutations.Count; ++i)
            {
                var permutation = permutations[i];
                var method      = TargetType.DefineMethod
                                  (
                    $"{uniqueMemberIdentifier}_{i}",
                    Public | Final | Virtual | HideBySig | NewSlot,
                    CallingConventions.Standard,
                    member.ReturnType,
                    permutation.ToArray()
                                  );

                var methodInfo = new IntrospectiveMethodInfo(method, member.ReturnType, permutation, member);
                generatedMethods.Add(methodInfo);
            }

            // Generate native implementations for the permutations
            foreach (var permutation in generatedMethods)
            {
                var uniqueIdentifier = Guid.NewGuid().ToString().Replace("-", "_");
                var memberIdentifier = $"{member.Name}_{uniqueIdentifier}";

                uniqueMemberIdentifier = memberIdentifier;

                if (permutation.RequiresLowering())
                {
                    _loweredMethodGenerator.GenerateImplementationForDefinition(permutation, symbolName, uniqueMemberIdentifier);
                }
                else
                {
                    _methodGenerator.GenerateImplementationForDefinition(permutation, symbolName, uniqueMemberIdentifier);
                }
            }

            // Generate a definition for the top-level method
            var topLevelMethod = TargetType.DefineMethod
                                 (
                symbolName,
                Public | Final | Virtual | HideBySig | NewSlot,
                member.ReturnType,
                member.ParameterTypes.ToArray()
                                 );

            GenerateTopLevelMethodImplementation(member, topLevelMethod, permutations, generatedMethods);
            TargetType.DefineMethodOverride(topLevelMethod, member.GetWrappedMember());
        }
Exemple #3
0
        private void GeneratePropertyGetter
        (
            [NotNull] IntrospectivePropertyInfo property,
            [NotNull] FieldInfo propertyFieldBuilder,
            [NotNull] PropertyBuilder propertyBuilder
        )
        {
            var wrappedProperty = property.GetWrappedMember();
            var actualGetMethod = wrappedProperty.GetGetMethod();
            var getterMethod    = TargetType.DefineMethod
                                  (
                actualGetMethod.Name,
                PropertyMethodAttributes,
                actualGetMethod.CallingConvention,
                actualGetMethod.ReturnType,
                Type.EmptyTypes
                                  );

            MethodInfo underlyingMethod;

            if (property.PropertyType.IsPointer)
            {
                underlyingMethod = typeof(Marshal).GetMethods().First
                                   (
                    m =>
                    m.Name == nameof(Marshal.ReadIntPtr) &&
                    m.GetParameters().Length == 1
                                   );
            }
            else if (property.PropertyType.IsValueType)
            {
                underlyingMethod = typeof(Marshal).GetMethods().First
                                   (
                    m =>
                    m.Name == nameof(Marshal.PtrToStructure) &&
                    m.GetParameters().Length == 1 &&
                    m.IsGenericMethod
                                   )
                                   .MakeGenericMethod(property.PropertyType);
            }
            else
            {
                throw new NotSupportedException
                      (
                          $"The type \"{property.PropertyType.FullName}\" is not supported. Only value types or pointers are supported."
                      );
            }

            var getterIL = getterMethod.GetILGenerator();

            if (Options.HasFlagFast(GenerateDisposalChecks))
            {
                EmitDisposalCheck(getterIL);
            }

            GenerateSymbolPush(getterIL, propertyFieldBuilder);

            getterIL.EmitCallDirect(underlyingMethod);
            getterIL.EmitReturn();

            propertyBuilder.SetGetMethod(getterMethod);
            TargetType.DefineMethodOverride(getterMethod, actualGetMethod);
        }
Exemple #4
0
        private void GeneratePropertySetter
        (
            [NotNull] IntrospectivePropertyInfo property,
            [NotNull] FieldInfo propertyFieldBuilder,
            [NotNull] PropertyBuilder propertyBuilder
        )
        {
            var wrappedProperty = property.GetWrappedMember();
            var actualSetMethod = wrappedProperty.GetSetMethod();
            var setterMethod    = TargetType.DefineMethod
                                  (
                actualSetMethod.Name,
                PropertyMethodAttributes,
                actualSetMethod.CallingConvention,
                typeof(void),
                actualSetMethod.GetParameters().Select(p => p.ParameterType).ToArray()
                                  );

            MethodInfo underlyingMethod;

            if (property.PropertyType.IsPointer)
            {
                underlyingMethod = typeof(Marshal).GetMethods().First
                                   (
                    m =>
                    m.Name == nameof(Marshal.WriteIntPtr) &&
                    m.GetParameters().Length == 3
                                   );
            }
            else if (property.PropertyType.IsValueType)
            {
                underlyingMethod = typeof(Marshal).GetMethods().First
                                   (
                    m =>
                    m.Name == nameof(Marshal.StructureToPtr) &&
                    m.GetParameters().Length == 3 &&
                    m.IsGenericMethod
                                   )
                                   .MakeGenericMethod(property.PropertyType);
            }
            else
            {
                throw new NotSupportedException
                      (
                          $"The type \"{property.PropertyType.FullName}\" is not supported. Only value types or pointers are supported."
                      );
            }

            var setterIL = setterMethod.GetILGenerator();

            if (Options.HasFlagFast(GenerateDisposalChecks))
            {
                EmitDisposalCheck(setterIL);
            }

            if (property.PropertyType.IsPointer)
            {
                var explicitConvertToIntPtrFunc = typeof(IntPtr).GetMethods().First
                                                  (
                    m =>
                    m.Name == "op_Explicit"
                                                  );

                GenerateSymbolPush(setterIL, propertyFieldBuilder);
                setterIL.EmitConstantInt(0);

                setterIL.EmitLoadArgument(1);
                setterIL.EmitCallDirect(explicitConvertToIntPtrFunc);
            }
            else
            {
                setterIL.EmitLoadArgument(1);
                GenerateSymbolPush(setterIL, propertyFieldBuilder);
                setterIL.EmitConstantInt(0);
            }

            setterIL.EmitCallDirect(underlyingMethod);
            setterIL.EmitReturn();

            propertyBuilder.SetSetMethod(setterMethod);
            TargetType.DefineMethodOverride(setterMethod, actualSetMethod);
        }
        private void GeneratePropertySetter
        (
            [NotNull] IntrospectivePropertyInfo property,
            [NotNull] FieldInfo propertyFieldBuilder,
            [NotNull] PropertyBuilder propertyBuilder
        )
        {
            var wrappedProperty = property.GetWrappedMember();
            var actualSetMethod = wrappedProperty.GetSetMethod();
            var setterMethod    = TargetType.DefineMethod
                                  (
                actualSetMethod.Name,
                PropertyMethodAttributes,
                actualSetMethod.CallingConvention,
                typeof(void),
                actualSetMethod.GetParameters().Select(p => p.ParameterType).ToArray()
                                  );

            MethodInfo underlyingMethod;

            if (property.PropertyType.IsPointer)
            {
                underlyingMethod = typeof(Marshal).GetMethods().First
                                   (
                    m =>
                    m.Name == nameof(Marshal.WriteIntPtr) &&
                    m.GetParameters().Length == 3
                                   );
            }
            else if (property.PropertyType.IsValueType)
            {
                underlyingMethod = typeof(Marshal).GetMethods().First
                                   (
                    m =>
                    m.Name == nameof(Marshal.StructureToPtr) &&
                    m.GetParameters().Length == 3 &&
                    m.IsGenericMethod
                                   )
                                   .MakeGenericMethod(property.PropertyType);
            }
            else
            {
                throw new NotSupportedException(
                          string.Format
                          (
                              "{0} Type is not supported. Only ValueType property or Pointer Property is supported.",
                              property.PropertyType.FullName
                          )
                          );
            }

            var setterIL = setterMethod.GetILGenerator();

            if (Options.HasFlagFast(GenerateDisposalChecks))
            {
                EmitDisposalCheck(setterIL);
            }

            if (property.PropertyType.IsPointer)
            {
                var explicitConvertToIntPtrFunc = typeof(IntPtr).GetMethods().First
                                                  (
                    m =>
                    m.Name == "op_Explicit"
                                                  );

                GenerateSymbolPush(setterIL, propertyFieldBuilder);                 // Push Symbol address to stack
                setterIL.Emit(OpCodes.Ldc_I4, 0);                                   // Push 0 offset to stack

                setterIL.Emit(OpCodes.Ldarg_1);                                     // Push value to stack
                setterIL.EmitCall(OpCodes.Call, explicitConvertToIntPtrFunc, null); // Explicit Convert Pointer to IntPtr object
            }
            else
            {
                setterIL.Emit(OpCodes.Ldarg_1);
                GenerateSymbolPush(setterIL, propertyFieldBuilder);
                setterIL.Emit(OpCodes.Ldc_I4, 0); // false for deleting structure that is already stored in pointer
            }

            setterIL.EmitCall
            (
                OpCodes.Call,
                underlyingMethod,
                null
            );

            setterIL.Emit(OpCodes.Ret);

            propertyBuilder.SetSetMethod(setterMethod);
            TargetType.DefineMethodOverride(setterMethod, actualSetMethod);
        }