private void PropertyInitializationInConstructor
        (
            [NotNull] string symbolName,
            [NotNull] FieldInfo propertyFieldBuilder
        )
        {
            var loadSymbolMethod = typeof(NativeLibraryBase).GetMethod
                                   (
                "LoadSymbol",
                BindingFlags.NonPublic | BindingFlags.Instance
                                   );

            TargetTypeConstructorIL.Emit(OpCodes.Ldarg_0);
            TargetTypeConstructorIL.Emit(OpCodes.Ldarg_0);

            if (Options.HasFlagFast(UseLazyBinding))
            {
                var lambdaBuilder = GenerateSymbolLoadingLambda(symbolName);
                GenerateLazyLoadedField(lambdaBuilder, typeof(IntPtr));
            }
            else
            {
                TargetTypeConstructorIL.Emit(OpCodes.Ldstr, symbolName);
                TargetTypeConstructorIL.EmitCall(OpCodes.Call, loadSymbolMethod, null);
            }

            TargetTypeConstructorIL.Emit(OpCodes.Stfld, propertyFieldBuilder);
        }
        /// <summary>
        /// Augments the constructor of the hosting type with initialization logic for this method.
        /// </summary>
        /// <param name="entrypointName">The name of the native entry point.</param>
        /// <param name="delegateBuilderType">The type of the method delegate.</param>
        /// <param name="delegateField">The delegate field.</param>
        private void AugmentHostingTypeConstructor
        (
            [NotNull] string entrypointName,
            [NotNull] Type delegateBuilderType,
            [NotNull] FieldInfo delegateField
        )
        {
            var loadFunc = typeof(NativeLibraryBase).GetMethod
                           (
                "LoadFunction",
                BindingFlags.NonPublic | BindingFlags.Instance
                           ).MakeGenericMethod(delegateBuilderType);

            TargetTypeConstructorIL.Emit(OpCodes.Ldarg_0); // This is for storing field delegate, it needs the "this" reference
            TargetTypeConstructorIL.Emit(OpCodes.Ldarg_0);

            if (Options.HasFlagFast(UseLazyBinding))
            {
                var lambdaBuilder = GenerateFunctionLoadingLambda(delegateBuilderType, entrypointName);
                GenerateLazyLoadedField(lambdaBuilder, delegateBuilderType);
            }
            else
            {
                TargetTypeConstructorIL.Emit(OpCodes.Ldstr, entrypointName);
                TargetTypeConstructorIL.EmitCall(OpCodes.Call, loadFunc, null);
            }

            TargetTypeConstructorIL.Emit(OpCodes.Stfld, delegateField);
        }
Exemple #3
0
        protected void GenerateLazyLoadedObject([NotNull] MethodBuilder valueFactory, [NotNull] Type type)
        {
            var funcType = typeof(Func <>).MakeGenericType(type);
            var lazyType = typeof(Lazy <>).MakeGenericType(type);

            var funcConstructor = funcType.GetConstructors().First();
            var lazyConstructor = lazyType.GetConstructors().First
                                  (
                c =>
                c.GetParameters().Any() &&
                c.GetParameters().Length == 1 &&
                c.GetParameters().First().ParameterType == funcType
                                  );

            // Use the lambda instead of the function directly.
            TargetTypeConstructorIL.Emit(OpCodes.Ldftn, valueFactory);
            TargetTypeConstructorIL.Emit(OpCodes.Newobj, funcConstructor);
            TargetTypeConstructorIL.Emit(OpCodes.Newobj, lazyConstructor);
        }