예제 #1
0
        public override void TestExceptionHandlerOverhead(int iterations)
        {
            var @class   = Runtime.GetExportedClass <ExceptionTester>();
            var selector = new Selector(typeof(ExceptionTester).GetMethod("NoThrow"));
            var encoding = new RuntimeMethodEncoding(typeof(ExceptionTester).GetMethod("NoThrow"));

            for (int i = 0; i < iterations; i++)
            {
                try
                {
                    @class.InvokeVoidFast(selector, encoding, 10L, 20L, 30L, 40L, 50L);
                }
                catch { Console.WriteLine("Should not catch exception!"); }
            }
        }
예제 #2
0
        /// <summary>
        /// Create instance RuntimeMethodEncoding class from instance of Objective-C NSMethodSignature class.
        /// </summary>
        /// <param name="methodSignature">Objective-C NSMethodSignature class instance.</param>
        /// <returns>RuntimeMethodEncoding intialized from NSMethodSignature encoding.</returns>
        public static RuntimeMethodEncoding FromNSMethodSignature(RuntimeObject methodSignature)
        {
            if (methodSignature == RuntimeObject.Null)
            {
                return(null);
            }

            var argumentsCount = methodSignature.InvokeUInt32("numberOfArguments");
            var signatureTypes = new Type[argumentsCount + 1];

            signatureTypes[0] = DecodeType(( char )Marshal.ReadByte(methodSignature.InvokeIntPtr("methodReturnType")));

            for (int i = 0; i < argumentsCount; i++)
            {
                signatureTypes[i + 1] = DecodeType(( char )Marshal.ReadByte(methodSignature.InvokeIntPtr("getArgumentTypeAtIndex:", i)));
            }

            var result = new RuntimeMethodEncoding(signatureTypes);

            Tracer.Information("Generate encoding from NSSignature: {0}", result);

            return(result);
        }
예제 #3
0
        public override void TestExceptionRethrow(int iterations)
        {
            var @class   = Runtime.GetExportedClass <ExceptionTester>();
            var selector = new Selector(typeof(ExceptionTester).GetMethod("Throw"));
            var encoding = new RuntimeMethodEncoding(typeof(ExceptionTester).GetMethod("Throw"));

            var exceptionCatched = true;

            for (int i = 0; i < iterations; i++)
            {
                try
                {
                    @class.InvokeVoidFast(selector, encoding, 10L, 20L, 30L, 40L, 50L);
                    exceptionCatched = false;
                }
                catch { }
            }

            if (!exceptionCatched)
            {
                Console.WriteLine("Should catch exception!");
            }
        }
예제 #4
0
        /// <summary>
        /// Creates encoding for exported method or constructor.
        /// </summary>
        /// <param name="method">MethodInfo or ConstructorInfo to get signature from</param>
        /// <param name="options">Options to produce encoding</param>
        /// <returns>String representation of encoding.</returns>
        public static string GetEncoding(MethodBase method, Options options)
        {
            IEnumerable <Type> parameters = new[] { method is MethodInfo ? (( MethodInfo )method).ReturnType : typeof(RuntimeObject) };

            var actualArguments = method.GetParameters().Select(x => x.ParameterType);

            if ((options & Options.StripExceptionParameters) != 0)
            {
                actualArguments = actualArguments.Skip(4);
            }

            if ((options & Options.TransitionMethod) == 0)
            {
                parameters = parameters.Concat(new[] { typeof(RuntimeObject), typeof(Selector) });
            }

            parameters = parameters.Concat(actualArguments);

            var result = new RuntimeMethodEncoding(parameters.ToArray()).Encoding;

            Tracer.Information("Generate encoding {0} for {1}", result, method);

            return(result);
        }
예제 #5
0
 /// <summary>
 /// Sends vararg message to receiver using cached method's encoding to perform better.
 /// </summary>
 /// <param name="selector">Selector of method to invoke.</param>
 /// <param name="encoding">Parsed encoding string used to properly convert/marshal primitive types.</param>
 /// <param name="arguments">Arguments to pass.</param>
 /// <returns>System.Single result</returns>
 public float InvokeFloatFast(Selector selector, RuntimeMethodEncoding encoding, params object[] arguments)
 {
     return(( float )Convert.ToDouble(InvokeFast(selector, encoding, arguments)));
 }
예제 #6
0
 /// <summary>
 /// Sends vararg message to receiver using cached method's encoding to perform better.
 /// </summary>
 /// <param name="selector">Selector of method to invoke.</param>
 /// <param name="encoding">Parsed encoding string used to properly convert/marshal primitive types.</param>
 /// <param name="arguments">Arguments to pass.</param>
 public void InvokeVoidFast(Selector selector, RuntimeMethodEncoding encoding, params object[] arguments)
 {
     InvokeIntPtrFast(selector, encoding, arguments);
 }
예제 #7
0
        /// <summary>
        /// Initializes new instance of RuntimePropertyEncoding class with Objective-C property encoding.
        /// </summary>
        /// <param name="encoding">Objective-C property encoding</param>
        public RuntimePropertyEncoding(string encoding)
        {
            int index  = 0;
            var buffer = new StringBuilder();

            while (index < encoding.Length)
            {
                while (encoding[index] == ' ')
                {
                    index++;
                }

                switch (encoding[index])
                {
                case 'T':
                {
                    var isQuoted = false;

                    index++;

                    if (encoding[index] == '{')
                    {
                        index++;
                        int bracesCount = 1;

                        while (index < encoding.Length && bracesCount > 0)
                        {
                            if (encoding[index] == '{')
                            {
                                bracesCount++;
                            }
                            else if (encoding[index] == '}')
                            {
                                bracesCount--;
                            }

                            index++;
                        }

                        break;
                    }
                    else
                    {
                        PropertyType = RuntimeMethodEncoding.DecodeType(encoding[index++]);
                    }

                    if (index < encoding.Length && encoding[index] == '"')
                    {
                        isQuoted = true;
                        index++;
                    }

                    buffer.Length = 0;
                    while (index < encoding.Length && encoding[index] != ',')
                    {
                        buffer.Append(encoding[index++]);

                        if (isQuoted && encoding[index] == '"')
                        {
                            index++;
                            break;
                        }
                    }
                }
                break;

                case 'G':
                    index++;

                    buffer.Length = 0;
                    while (index < encoding.Length && encoding[index] != ',')
                    {
                        buffer.Append(encoding[index++]);
                    }

                    Getter = buffer.ToString();

                    break;

                case 'S':
                    index++;

                    buffer.Length = 0;
                    while (index < encoding.Length && encoding[index] != ',')
                    {
                        buffer.Append(encoding[index++]);
                    }

                    Setter = buffer.ToString();

                    break;

                case 'V':
                    index++;

                    buffer.Length = 0;
                    while (index < encoding.Length && encoding[index] != ',')
                    {
                        buffer.Append(encoding[index++]);
                    }

                    break;

                case 'P':
                    index++;
                    break;

                case 'D':
                    index++;
                    break;

                case 'C':
                    IsCopy = true;
                    index++;
                    break;

                case 'R':
                    IsReadonly = true;
                    index++;
                    break;

                case '&':
                    IsRetain = true;
                    index++;
                    break;
                }

                if (index == encoding.Length)
                {
                    break;
                }

                if (encoding[index] == ',')
                {
                    index++;
                    continue;
                }

                Debugger.Break();
            }
        }
예제 #8
0
 /// <summary>
 /// Sends vararg message to receiver using cached method's encoding to perform better.
 /// </summary>
 /// <param name="selector">Selector of method to invoke.</param>
 /// <param name="encoding">Parsed encoding string used to properly convert/marshal primitive types.</param>
 /// <param name="arguments">Arguments to pass.</param>
 /// <returns>IntPtr result</returns>
 public IntPtr InvokeIntPtrFast(Selector selector, RuntimeMethodEncoding encoding, params object[] arguments)
 {
     return(Runtime.TruncateUnnecessaryAddressBits(InvokeRawFast(selector, encoding, arguments)));
 }
예제 #9
0
 /// <summary>
 /// Sends vararg message to receiver using cached method's encoding to perform better.
 /// </summary>
 /// <param name="selector">Selector of method to invoke.</param>
 /// <param name="encoding">Parsed encoding string used to properly convert/marshal primitive types.</param>
 /// <param name="arguments">Arguments to pass.</param>
 /// <returns>RuntimeObject result</returns>
 public RuntimeObject InvokeObjectFast(Selector selector, RuntimeMethodEncoding encoding, params object[] arguments)
 {
     return(new RuntimeObject(InvokeIntPtrFast(selector, encoding, arguments)));
 }
예제 #10
0
 /// <summary>
 /// Sends vararg message to receiver using cached method's encoding to perform better.
 /// </summary>
 /// <param name="selector">Selector of method to invoke.</param>
 /// <param name="encoding">Parsed encoding string used to properly convert/marshal primitive types.</param>
 /// <param name="arguments">Arguments to pass.</param>
 /// <returns>System.Boolean result</returns>
 public bool InvokeBoolFast(Selector selector, RuntimeMethodEncoding encoding, params object[] arguments)
 {
     return((( int )InvokeRawFast(selector, encoding, arguments)) == 0 ? false : true);
 }
예제 #11
0
 /// <summary>
 /// Sends vararg message to receiver using cached method's encoding to perform better.
 /// </summary>
 /// <param name="selector">Selector of method to invoke.</param>
 /// <param name="encoding">Parsed encoding string used to properly convert/marshal primitive types.</param>
 /// <param name="arguments">Arguments to pass.</param>
 /// <returns>System.String result</returns>
 public string InvokeStringFast(Selector selector, RuntimeMethodEncoding encoding, params object[] arguments)
 {
     return(( string )InvokeFast(selector, encoding, arguments));
 }
예제 #12
0
 /// <summary>
 /// Sends vararg message to receiver using cached method's encoding to perform better returning raw value from objc_msgSend.
 /// </summary>
 /// <param name="selector">Selector of method to invoke.</param>
 /// <param name="encoding">Parsed encoding string used to properly convert/marshal primitive types.</param>
 /// <param name="arguments">Arguments to pass.</param>
 /// <returns>Raw value from objc_msgSend</returns>
 public long InvokeRawFast(Selector selector, RuntimeMethodEncoding encoding, params object[] arguments)
 {
     return(Runtime.InvokeRawFast(this, selector, encoding, arguments));
 }
예제 #13
0
 /// <summary>
 /// Sends vararg message to receiver using cached method's encoding to perform better.
 /// </summary>
 /// <param name="selector">Selector of method to invoke.</param>
 /// <param name="encoding">Parsed encoding string used to properly convert/marshal primitive types.</param>
 /// <param name="arguments">Arguments to pass.</param>
 /// <returns>System.Double result</returns>
 public double InvokeDoubleFast(Selector selector, RuntimeMethodEncoding encoding, params object[] arguments)
 {
     return(Convert.ToDouble(InvokeFast(selector, encoding, arguments)));
 }
예제 #14
0
 /// <summary>
 /// Sends vararg message to receiver using cached method's encoding to perform better.
 /// </summary>
 /// <param name="selector">Selector of method to invoke.</param>
 /// <param name="encoding">Parsed encoding string used to properly convert/marshal primitive types.</param>
 /// <param name="arguments">Arguments to pass.</param>
 /// <returns>System.Char result</returns>
 public char InvokeCharFast(Selector selector, RuntimeMethodEncoding encoding, params object[] arguments)
 {
     return(( char )InvokeRawFast(selector, encoding, arguments));
 }
예제 #15
0
 /// <summary>
 /// Sends vararg message to receiver using cached method's encoding to perform better.
 /// </summary>
 /// <param name="selector">Selector of method to invoke.</param>
 /// <param name="encoding">Parsed encoding string used to properly convert/marshal primitive types.</param>
 /// <param name="arguments">Arguments to pass.</param>
 /// <returns>System.UInt64 result</returns>
 public ulong InvokeUInt64Fast(Selector selector, RuntimeMethodEncoding encoding, params object[] arguments)
 {
     return(( ulong )InvokeRawFast(selector, encoding, arguments));
 }
예제 #16
0
 /// <summary>
 /// Sends vararg message to receiver using cached method's encoding to perform better.
 /// </summary>
 /// <param name="selector">Selector of method to invoke.</param>
 /// <param name="encoding">Parsed encoding string used to properly convert/marshal primitive types.</param>
 /// <param name="arguments">Arguments to pass.</param>
 /// <returns>System.UInt16 result</returns>
 public ushort InvokeUInt16Fast(Selector selector, RuntimeMethodEncoding encoding, params object[] arguments)
 {
     return(( ushort )InvokeRawFast(selector, encoding, arguments));
 }
예제 #17
0
 /// <summary>
 /// Sends vararg message to receiver using cached method's encoding to perform better.
 /// </summary>
 /// <param name="selector">Selector of method to invoke.</param>
 /// <param name="encoding">Parsed encoding string used to properly convert/marshal primitive types.</param>
 /// <param name="arguments">Arguments to pass.</param>
 /// <returns>System.UInt8 result</returns>
 public byte InvokeUInt8Fast(Selector selector, RuntimeMethodEncoding encoding, params object[] arguments)
 {
     return(( byte )InvokeRawFast(selector, encoding, arguments));
 }
예제 #18
0
 /// <summary>
 /// Sends vararg message to receiver using cached method's encoding to perform better.
 /// </summary>
 /// <param name="selector">Selector of method to invoke.</param>
 /// <param name="encoding">Parsed encoding string used to properly convert/marshal primitive types.</param>
 /// <param name="arguments">Arguments to pass.</param>
 /// <returns>System.Int32 result</returns>
 public int InvokeInt32Fast(Selector selector, RuntimeMethodEncoding encoding, params object[] arguments)
 {
     return(( int )InvokeRawFast(selector, encoding, arguments));
 }