예제 #1
0
        public static void GetAccessorTrampolines(
            IntPtr memberInfo,
            int accessorMemberType,
            out IntPtr reader,
            out IntPtr readerPointer,
            out IntPtr writer,
            out IntPtr writerPointer,
            out IntPtr exception)
        {
            exception = IntPtr.Zero;
            reader = IntPtr.Zero;
            readerPointer = IntPtr.Zero;
            writer = IntPtr.Zero;
            writerPointer = IntPtr.Zero;
            Exception e = null;
            Delegate readerObject = null;
            var readerPtr = IntPtr.Zero;
            Delegate writerObject = null;
            var writerPtr = IntPtr.Zero;

#if ENABLE_TASK_HACK
            var task = Task.Factory.StartNew(() =>
            {
#endif
            try
            {
                var type = (AccessorMemberTypes) accessorMemberType;
                Delegate rdr;
                IntPtr innerReaderPtr;
                Delegate wtr;
                IntPtr innerWriterPtr;

                switch (type)
                {
                    case AccessorMemberTypes.Field:
                        var fieldInfo = (FieldInfo) UnboxObject(memberInfo);
                        TrampolineCompiler.CompileField(fieldInfo, out rdr, out innerReaderPtr, out wtr, out innerWriterPtr);
                        break;
                    case AccessorMemberTypes.Property:
                        var propertyInfo = (PropertyInfo) UnboxObject(memberInfo);
                        TrampolineCompiler.CompileProperty(propertyInfo, out rdr, out innerReaderPtr, out wtr, out innerWriterPtr);
                        break;
                    case AccessorMemberTypes.Indexer:
                        var indexerInfo = (PropertyInfo) UnboxObject(memberInfo);
                        TrampolineCompiler.CompileIndexer(indexerInfo, out rdr, out innerReaderPtr, out wtr, out innerWriterPtr);
                        break;
                    // ReSharper disable once RedundantCaseLabel
                    case AccessorMemberTypes.Undefined:
                    default:
                        throw new ArgumentException("Invalid accessor member type", nameof(accessorMemberType));
                }

                readerObject = rdr;
                readerPtr = innerReaderPtr;
                writerObject = wtr;
                writerPtr = innerWriterPtr;
            }
            catch (TargetInvocationException ex)
            {
#if DEBUG
                Log.Exception(ex);
#endif
                e = ex.InnerException;
            }
            catch (Exception ex)
            {
#if DEBUG
                Log.Exception(ex);
#endif
                e = ex;
            }
#if ENABLE_TASK_HACK
            });
            Task.WaitAny(task);
#endif
            reader = BoxObject(readerObject);
            readerPointer = readerPtr;
            writer = BoxObject(writerObject);
            writerPointer = writerPtr;
            exception = BoxObject(e);
        }
예제 #2
0
        public static void GetDelegateTrampoline(
            IntPtr methodInfo,
            IntPtr args,
            int nArgs,
            out IntPtr functionPointer,
            out IntPtr result,
            out int typeCode,
            out IntPtr exception)
        {
            result = IntPtr.Zero;
            typeCode = (int)TypeCode.Empty;
            exception = IntPtr.Zero;
            Exception e = null;
            object invocationResult = null;
            var pointer = IntPtr.Zero;

#if ENABLE_TASK_HACK
            var task = Task.Factory.StartNew(() =>
            {
#endif
            try
            {

                var methodBase = (MethodBase)UnboxObject(methodInfo);
                var argTypes = nArgs == 0 ? EmptyTypeArray : UnboxTypeArgs(args, nArgs);
                if (methodBase is MethodInfo realMethodInfo)
                {
                    invocationResult = TrampolineCompiler.CompileMethodInfo(
                        realMethodInfo,
                        out var ptr,
                        argTypes);
                    pointer = ptr;
                }
                else
                {
                    var constructorInfo = (ConstructorInfo) methodBase;
                    invocationResult = TrampolineCompiler.CompileConstructor(constructorInfo, out var ptr);
                    pointer = ptr;
                }
            }
            catch (TargetInvocationException ex)
            {
#if DEBUG
                Log.Exception(ex);
#endif
                e = ex.InnerException;
            }
            catch (Exception ex)
            {
#if DEBUG
                Log.Exception(ex);
#endif
                e = ex;
            }
#if ENABLE_TASK_HACK
            });
            Task.WaitAny(task);
#endif

            functionPointer = pointer;
            result = BoxObject(invocationResult);
            typeCode = invocationResult.GetFullTypeCode();
            exception = BoxObject(e);
        }