Пример #1
0
        /// <summary>
        /// Checks all Methods that returns Task or Task`1 if their naming is according to the convention.
        /// </summary>
        /// <param name="builder"></param>
        public void CheckAsyncMethodsNomenclature(Builder builder)
        {
            var task        = new __Task();
            var taskGeneric = new __Task_1();
            var methods     = builder
                              .GetTypes(SearchContext.Module)
                              .SelectMany(x => x.Methods)
                              .Where(x =>
            {
                if (x.IsGenerated)
                {
                    return(false);
                }

                if (x.Name.EndsWith("Action"))
                {
                    return(false);
                }

                if (x.Name.EndsWith("Async"))
                {
                    return(false);
                }

                if (x.ReturnType == __Task.Type || x.ReturnType == __Task_1.Type)
                {
                    return(true);
                }

                return(false);
            });

            foreach (var item in methods)
            {
                this.Log(LogTypes.Warning, item, $"The method '{item.Name}' in '{item.OriginType.Fullname}' is async, but does not have an 'Async' suffix.");
            }
        }
        private void InterceptMethods(Builder builder, IEnumerable <BuilderType> attributes)
        {
            if (!attributes.Any())
            {
                return;
            }

            var stopwatch = Stopwatch.StartNew();

            var iMethodInterceptor            = new __IMethodInterceptor(builder);
            var asyncTaskMethodBuilder        = new __AsyncTaskMethodBuilder(builder);
            var asyncTaskMethodBuilderGeneric = new __AsyncTaskMethodBuilder_1(builder);
            var syncRoot  = new __ISyncRoot(builder);
            var task      = new __Task(builder);
            var exception = new __Exception(builder);

            var methods = builder
                          .FindMethodsByAttributes(attributes)
                          .GroupBy(x => new MethodKey(x.Method, x.AsyncMethod))
                          .Select(x => new MethodBuilderInfo(x.Key, x.Select(y => new MethodBuilderInfoItem(y, iMethodInterceptor))))
                          .ToArray();

            foreach (var method in methods)
            {
                this.LogInfo($"Implementing interceptors in method {method.Key.Method}");

                var targetedMethod   = method.Key.AsyncMethod == null ? method.Key.Method : method.Key.AsyncMethod;
                var attributedMethod = method.Key.Method;

                method.AddThisReferenceToAsyncMethod();

                var typeInstance     = method.GetAsyncMethodTypeInstace();
                var interceptorField = new Field[method.Item.Length];

                if (method.RequiresSyncRootField)
                {
                    foreach (var ctors in targetedMethod.DeclaringType.GetRelevantConstructors())
                    {
                        ctors.NewCode().Assign(method.SyncRoot).NewObj(builder.GetType(typeof(object)).Import().ParameterlessContructor).Insert(InsertionPosition.Beginning);
                    }
                }

                targetedMethod
                .NewCode()
                .Context(x =>
                {
                    for (int i = 0; i < method.Item.Length; i++)
                    {
                        var item            = method.Item[i];
                        var name            = $"<{targetedMethod.Name}>_attrib{i}_{item.Attribute.Identification}";
                        interceptorField[i] = targetedMethod.DeclaringType.CreateField(targetedMethod.Modifiers.GetPrivate(), item.Interface.Type, name);

                        x.Load(interceptorField[i]).IsNull().Then(y =>
                        {
                            y.Assign(interceptorField[i]).NewObj(item.Attribute);
                            if (item.HasSyncRootInterface)
                            {
                                y.Load(interceptorField[i]).As(syncRoot.Type).Call(syncRoot.SyncRoot, method.SyncRoot);
                            }
                        });
                        item.Attribute.Remove();
                    }
                })
                .Try(x =>
                {
                    for (int i = 0; i < method.Item.Length; i++)
                    {
                        var item = method.Item[i];
                        x.Load(interceptorField[i]).As(item.Interface.Type).Call(item.Interface.OnEnter, attributedMethod.DeclaringType, typeInstance, attributedMethod, x.GetParametersArray());
                    }

                    x.OriginalBody();

                    // Special case for async methods
                    if (method.Key.AsyncMethod != null && method.Key.Method.ReturnType.Fullname == task.Type.Fullname)     // Task return
                    {
                        var exceptionVar = x.CreateVariable(exception.Type);

                        x.Assign(exceptionVar).Set(
                            x.NewCode().Call(method.Key.AsyncMethod.DeclaringType.GetField("<>t__builder"), asyncTaskMethodBuilder.GetTask)
                            .Call(task.GetException));

                        x.Load(exceptionVar).IsNotNull().Then(y =>
                        {
                            for (int i = 0; i < method.Item.Length; i++)
                            {
                                y.Load(interceptorField[i]).Callvirt(method.Item[i].Interface.OnException, exceptionVar);
                            }
                        });
                    }
                    else if (method.Key.AsyncMethod != null)     // Task<> return
                    {
                        var exceptionVar = x.CreateVariable(exception.Type);
                        var taskArgument = method.Key.Method.ReturnType.GetGenericArgument(0);

                        x.Assign(exceptionVar).Set(
                            x.NewCode().Call(method.Key.AsyncMethod.DeclaringType.GetField("<>t__builder"), asyncTaskMethodBuilderGeneric.GetTask.MakeGeneric(taskArgument))
                            .Call(task.GetException));

                        x.Load(exceptionVar).IsNotNull().Then(y =>
                        {
                            for (int i = 0; i < method.Item.Length; i++)
                            {
                                y.Load(interceptorField[i]).Callvirt(method.Item[i].Interface.OnException, exceptionVar);
                            }
                        });
                    }
                })
                .Catch(exception.Type, x =>
                {
                    if (method.Key.AsyncMethod == null)
                    {
                        for (int i = 0; i < method.Item.Length; i++)
                        {
                            x.Load(interceptorField[i]).As(method.Item[i].Interface.Type).Call(method.Item[i].Interface.OnException, x.Exception);
                        }
                    }

                    x.Rethrow();
                })
                .Finally(x =>
                {
                    for (int i = 0; i < method.Item.Length; i++)
                    {
                        x.Load(interceptorField[i]).As(method.Item[i].Interface.Type).Call(method.Item[i].Interface.OnExit);
                    }
                })
                .EndTry()
                .Return()
                .Replace();
            }
            ;

            stopwatch.Stop();
            this.LogInfo($"Implementing method interceptors took {stopwatch.Elapsed.TotalMilliseconds}ms");
        }
Пример #3
0
        public Task <UdpReceiveResult> ReceiveAsync()
        {
            // workaround...
            int malloc_bytearray_paddingleft = 4;



            ConsoleExtensions.trace("enter UdpClient ReceiveAsync");

            var buff = stackalloc byte[0xfff];

            socket_h.sockaddr_in sender;
            var sizeof_sender = sizeof(socket_h.sockaddr_in);

            //ConsoleExtensions.trace("before recvfrom");

            // http://pubs.opengroup.org/onlinepubs/009695399/functions/recvfrom.html
            // Upon successful completion, recvfrom() shall return the length of the message in bytes.
            var recvfromret = s.recvfrom(buff, 0xfff, 0, (socket_h.sockaddr *) & sender, &sizeof_sender);

            // sent by?

            //I/xNativeActivity(24024): X:\jsc.svn\examples\c\android\Test\NDKUdpClient\NDKUdpClient\xNativeActivity.cs:167 recvfrom:  116 errno: 22 Invalid argument
            //I/xNativeActivity(24024): X:\jsc.svn\examples\c\android\Test\NDKUdpClient\NDKUdpClient\xNativeActivity.cs:168 SenderAddrSize:  16 errno: 22 Invalid argument
            ConsoleExtensions.tracei("recvfrom: ", recvfromret);
            //tracei("sockaddr_in: ", sizeof_sender);

            buff[recvfromret] = 0;


            //Task<UdpReceiveResult>

            // lets fill up GC. collect when thread shuts down?
            //var Buffer = new byte[recvfromret];


            // what about digitally signing the buffer?
            //var le_bytes = (byte*)stdlib_h.malloc(stdlib_h.malloc_bytearray_paddingleft + recvfromret);
            var le_bytes = (byte *)stdlib_h.malloc(malloc_bytearray_paddingleft + recvfromret);


            // I/xNativeActivity(12673): [2781936] \UdpClient.cs:110 recvfrom:  3
            //I/xNativeActivity(12673): [2781936] \UdpClient.cs:138 bytesLength:  50331648
            ConsoleExtensions.trace("set le_ipointer");
            var le_ipointer = (int *)le_bytes;

            *le_ipointer = recvfromret;

            //int32_5 = ((int*)byte_4);
            //*int32_5 = num3;

            {
                ConsoleExtensions.trace("get le_ipointer");
                var lei = *le_ipointer;
                ConsoleExtensions.tracei("lei: ", lei);
            }


            // Z:\jsc.svn\examples\c\Test\TestPointerOffset\Class1.cs

            #region ___bytes
            // byte_7 = ((unsigned char*)(&(byte_4[1])));
            var ___bytes = le_bytes + malloc_bytearray_paddingleft;
            for (int i = 0; i < recvfromret; i++)
            {
                var byte0 = buff[i];

                ConsoleExtensions.tracei("set byte0: ", byte0);

                //Buffer[i] = buff[i];
                ___bytes[i] = byte0;
            }
            #endregion

            {
                ConsoleExtensions.trace("get le_ipointer");
                var lei = *le_ipointer;
                ConsoleExtensions.tracei("lei: ", lei);
            }


            var bytes = __cast(___bytes);

            {
                ConsoleExtensions.trace("---");

                var byte0 = bytes[0];
                ConsoleExtensions.tracei("byte0: ", byte0);

                var bytesLength = bytes.Length;
                ConsoleExtensions.tracei("bytesLength: ", bytesLength);
            }

            // ptr?

            //{

            //    var xbytes = __cast(bytes);
            //    var xlebytes = xbytes - 4;
            //    var ile = (int*)xlebytes;
            //    ConsoleExtensions.tracei("ile: ", *ile);

            //}


            //I/xNativeActivity( 2541): [2777960] \UdpClient.cs:199 set task_Result_Buffer:  -192277436
            //I/xNativeActivity( 2541): [2777960] \UdpClient.cs:202 Result.Buffer.Length:  2
            //I/xNativeActivity( 2541): [2777960] \UdpClient.cs:211 got task_Result
            //I/xNativeActivity( 2541): [2777960] \UdpClient.cs:229 got task_Result_Buffer:  -867631102

            ConsoleExtensions.tracei64("set task_Result_Buffer: ", (long)__cast(bytes));


            //var Result = new UdpReceiveResult(bytes, null);
            var Result = new __UdpReceiveResult(bytes, null);

            //result13 = ScriptCoreLib_Shared_BCLImplementation_System_Net_Sockets___UdpReceiveResult__ctor_6000072(__new_ScriptCoreLib_Shared_BCLImplementation_System_Net_Sockets___UdpReceiveResult(1), byteArray11, NULL);
            //    ScriptCoreLibAndroidNDK_Library_ConsoleExtensions_tracei64("Result: ", (long long)result13, "z:\x5c""jsc.svn\x5c""core\x5c""ScriptCoreLibAndroidNDK\x5c""ScriptCoreLibAndroidNDK\x5c""BCLImplementation\x5c""System\x5c""Net\x5c""Sockets\x5c""UdpClient.cs", 212);


            // \UdpClient.cs:210 Result:  0
            ConsoleExtensions.tracei64("Result: ", (long)(object)Result);


            //typedef struct tag_ScriptCoreLib_Shared_BCLImplementation_System_Net_Sockets___UdpReceiveResult
            //{
            //    struct tag_ScriptCoreLibJava_BCLImplementation_System_Net___IPEndPoint* _RemoteEndPoint_k__BackingField;
            //    unsigned char* _Buffer_k__BackingField;
            //} ScriptCoreLib_Shared_BCLImplementation_System_Net_Sockets___UdpReceiveResult, *LPScriptCoreLib_Shared_BCLImplementation_System_Net_Sockets___UdpReceiveResult;


            //ConsoleExtensions.tracei("Result.Buffer.Length: ", Result.Buffer.Length);

            //var task = new __Task<UdpReceiveResult>();
            var task = new __Task <__UdpReceiveResult>();

            //typedef struct tag_ScriptCoreLibNative_BCLImplementation_System___Task_1
            //{
            //    void* _Result_k__BackingField;
            //} ScriptCoreLibNative_BCLImplementation_System___Task_1, *LPScriptCoreLibNative_BCLImplementation_System___Task_1;

            task.Result = (__UdpReceiveResult)(object)Result;


            var task_Result = task.Result;

            ConsoleExtensions.trace("got task_Result, crash?");

            ConsoleExtensions.tracei64("task_Result: ", (long)(object)task_Result);


            //Task<UdpReceiveResult> t = new __Task<UdpReceiveResult> { Result = Result };

            //     ScriptCoreLibAndroidNDK_Library_ConsoleExtensions_tracei("t.Result.Buffer.Length: ", (int)((signed int)(/* ldlen */ *(int*)(&(ScriptCoreLib_Shared_BCLImplementation_System_Net_Sockets___UdpReceiveResult_get_Buffer((ScriptCoreLib_Shared_BCLImplementation_System_Net_Sockets___UdpReceiveResult*)(&result18))[-4])))), "z:\x5c""jsc.svn\x5c""core\x5c""ScriptCoreLibAndroidNDK\x5c""ScriptCoreLibAndroidNDK\x5c""BCLImplementation\x5c""System\x5c""Net\x5c""Sockets\x5c""UdpClient.cs", 211);

            // struct??
            //if (task_Result == null)
            //{
            //}
            //else
            {
                //  byteArray19 = ScriptCoreLib_Shared_BCLImplementation_System_Net_Sockets___UdpReceiveResult_get_Buffer((ScriptCoreLib_Shared_BCLImplementation_System_Net_Sockets___UdpReceiveResult*)(&result18));


                var task_Result_Buffer = task_Result.Buffer;

                // \UdpClient.cs:226 got task_Result_Buffer:  848560130
                ConsoleExtensions.tracei64("got task_Result_Buffer: ", (long)__cast(task_Result_Buffer));

                ConsoleExtensions.tracei("t.Result.Buffer.Length: ", task_Result_Buffer.Length);
                //  t.Result.Buffer.Length:  2
            }

            return((Task <UdpReceiveResult>)(object) task);
        }
Пример #4
0
        private void ImplementTimedCache(Builder builder)
        {
            if (!builder.TypeExists(__TimedCacheAttribute.TypeName))
            {
                return;
            }

            var timedCacheAttribute = new __TimedCacheAttribute(builder);
            var methods             = builder.FindMethodsByAttribute(timedCacheAttribute.Type.Fullname);

            if (!methods.Any())
            {
                return;
            }

            var task   = new __Task(builder);
            var task_1 = new __Task_1(builder);

            foreach (var method in methods)
            {
                this.Log($"Implementing TimedCache in method {method.Method.Name}");

                if (method.Method.ReturnType.Fullname == "System.Void")
                {
                    this.Log(LogTypes.Warning, method.Method, "TimedCacheAttribute does not support void return types");
                    continue;
                }

                var keyName          = "<>timedcache_key";
                var timecacheVarName = "<>timedcache";

                if (method.AsyncMethod == null && method.Method.ReturnType.Inherits(task.Type.Fullname))
                {
                    this.Log(LogTypes.Error, method.Method, $"- TimedCacheAttribute for method {method.Method.Name} will not be implemented. Methods that returns 'Task' without async are not supported.");
                }
                else if (method.AsyncMethod == null)
                {
                    method.Method.NewCode()
                    .Context(x =>
                    {
                        var timedCache     = x.CreateVariable(timecacheVarName, method.Attribute.Type);
                        var key            = x.CreateVariable(keyName, timedCacheAttribute.CreateKey);
                        var returnVariable = x.GetReturnVariable();

                        x.Assign(timedCache).NewObj(method);

                        // Create a cache key
                        x.Call(timedCacheAttribute.CreateKey, method.Method.Fullname, x.GetParametersArray())
                        .StoreLocal(key);

                        // check
                        x.Load(timedCache).Call(timedCacheAttribute.HasCache, key)
                        .IsTrue().Then(y =>
                        {
                            y.Load(timedCache).Call(timedCacheAttribute.GetCache, key)
                            .As(method.Method.ReturnType)
                            .StoreLocal(returnVariable)
                            .Return();
                        });

                        x.OriginalBodyNewMethod().StoreLocal(returnVariable);

                        // Set the cache
                        x.Load(timedCache).Call(timedCacheAttribute.SetCache, key, returnVariable);

                        x.Load(returnVariable).Return();
                    })
                    .Replace();
                }
                else if (method.AsyncMethod != null)
                {
                    method.Method.NewCode()
                    .Context(x =>
                    {
                        var taskReturnType = method.Method.ReturnType.GetGenericArgument(0);
                        var timedCache     = x.CreateVariable(timecacheVarName, method.Attribute.Type);
                        var cacheKey       = x.CreateVariable(typeof(string));

                        x.Assign(cacheKey).Set(x.NewCode().Call(timedCacheAttribute.CreateKey, method.Method.Fullname, x.GetParametersArray()));
                        x.Assign(timedCache).NewObj(method);
                        x.Load(timedCache).Call(timedCacheAttribute.HasCache, cacheKey)
                        .IsTrue().Then(y =>
                        {
                            y.Call(task_1.FromResult.MakeGeneric(taskReturnType), y.NewCode().Call(timedCache, timedCacheAttribute.GetCache, cacheKey).As(taskReturnType))
                            .Return();
                        });
                    }).Insert(InsertionPosition.Beginning);

                    method.Method.NewCode()
                    .Context(x =>
                    {
                        var taskReturnType = method.Method.ReturnType.GetGenericArgument(0);
                        var returnVariable = x.GetReturnVariable();
                        x.LoadVariable(2).Call(timedCacheAttribute.SetCache, x.NewCode().LoadVariable(3), x.NewCode().Call(returnVariable, task_1.GetResult.MakeGeneric(taskReturnType)));
                    }).Insert(InsertionPosition.End);
                }

                method.Attribute.Remove();
            }
        }
Пример #5
0
        private void ImplementMethodCache(Builder builder)
        {
            var methods = builder.FindMethodsByAttribute("Cauldron.Interception.CacheAttribute");

            if (!methods.Any())
            {
                return;
            }

            var task   = new __Task(builder);
            var task_1 = new __Task_1(builder);

            foreach (var method in methods)
            {
                this.LogInfo($"Implementing Cache for method {method.Method.Name}");

                if (method.Method.ReturnType.Fullname == "System.Void")
                {
                    this.LogWarning("CacheAttribute does not support void return types");
                    continue;
                }

                var cacheField = $"<{method.Method.Name}>m__MethodCache_{method.Identification}";

                if (method.AsyncMethod == null && method.Method.ReturnType.Inherits(task.Type.Fullname))
                {
                    this.LogWarning($"- CacheAttribute for method {method.Method.Name} will not be implemented. Methods that returns 'Task' without async are not supported.");
                }
                else if (method.AsyncMethod == null)
                {
                    method.Method.NewCode()
                    .Context(x =>
                    {
                        var cache          = method.Method.DeclaringType.CreateField(method.Method.Modifiers.GetPrivate(), method.Method.ReturnType, cacheField);
                        var returnVariable = x.GetReturnVariable();

                        x.Load(cache).IsNull().Then(y =>
                        {
                            y.OriginalBody().StoreLocal(returnVariable).Return();
                        })
                        .Load(cache).Return();
                    })
                    .Replace();
                }
                else if (method.AsyncMethod != null)
                {
                    method.Method.NewCode()
                    .Context(x =>
                    {
                        var taskReturnType = method.Method.ReturnType.GetGenericArgument(0);
                        var cache          = method.Method.DeclaringType.CreateField(method.Method.Modifiers.GetPrivate(), taskReturnType, cacheField);

                        x.Load(cache).IsNotNull().Then(y =>
                        {
                            y.Call(task_1.FromResult.MakeGeneric(taskReturnType), cache).Return();
                        });
                    }).Insert(InsertionPosition.Beginning);

                    method.Method.NewCode()
                    .Context(x =>
                    {
                        var taskReturnType = method.Method.ReturnType.GetGenericArgument(0);
                        var cache          = method.Method.DeclaringType.GetField(cacheField);
                        var returnVariable = x.GetReturnVariable();
                        x.Assign(cache).Set(x.NewCode().Call(returnVariable, task_1.GetResult.MakeGeneric(taskReturnType)));
                    }).Insert(InsertionPosition.End);
                }

                method.Attribute.Remove();
            }
        }
        private void InterceptSimpleMethods(Builder builder, IEnumerable <BuilderType> attributes)
        {
            if (!attributes.Any())
            {
                return;
            }

            using (new StopwatchLog(this, "method simple"))
            {
                var asyncTaskMethodBuilder        = new __AsyncTaskMethodBuilder();
                var asyncTaskMethodBuilderGeneric = new __AsyncTaskMethodBuilder_1();
                var syncRoot  = new __ISyncRoot();
                var task      = new __Task();
                var exception = new __Exception();

                var methods = builder
                              .FindMethodsByAttributes(attributes)
                              .Where(x => !x.Method.IsPropertyGetterSetter)
                              .GroupBy(x => new MethodKey(x.Method, x.AsyncMethod))
                              .Select(x => new MethodBuilderInfo <MethodBuilderInfoItem <__ISimpleMethodInterceptor> >(x.Key, x.Select(y => new MethodBuilderInfoItem <__ISimpleMethodInterceptor>(y, __ISimpleMethodInterceptor.Instance))))
                              .OrderBy(x => x.Key.Method.DeclaringType.Fullname)
                              .ToArray();

                foreach (var method in methods)
                {
                    if (method.Item == null || method.Item.Length == 0)
                    {
                        continue;
                    }

                    this.Log($"Implementing method interceptors: {method.Key.Method.DeclaringType.Name.PadRight(40, ' ')} {method.Key.Method.Name}({string.Join(", ", method.Key.Method.Parameters.Select(x => x.Name))})");

                    var targetedMethod   = method.Key.AsyncMethod ?? method.Key.Method;
                    var attributedMethod = method.Key.Method;

                    var typeInstance     = method.Key.Method.AsyncMethodHelper.Instance;
                    var interceptorField = new Field[method.Item.Length];

                    if (method.RequiresSyncRootField)
                    {
                        if (method.SyncRoot.IsStatic)
                        {
                            targetedMethod.AsyncOriginType.CreateStaticConstructor().NewCode()
                            .Assign(method.SyncRoot).NewObj(builder.GetType(typeof(object)).Import().ParameterlessContructor)
                            .Insert(InsertionPosition.Beginning);
                        }
                        else
                        {
                            foreach (var ctors in targetedMethod.AsyncOriginType.GetRelevantConstructors().Where(x => x.Name == ".ctor"))
                            {
                                ctors.NewCode().Assign(method.SyncRoot).NewObj(builder.GetType(typeof(object)).Import().ParameterlessContructor).Insert(InsertionPosition.Beginning);
                            }
                        }
                    }

                    var coder = targetedMethod
                                .NewCode()
                                .Context(x =>
                    {
                        for (int i = 0; i < method.Item.Length; i++)
                        {
                            var item            = method.Item[i];
                            var name            = $"<{targetedMethod.Name}>_attrib{i}_{item.Attribute.Identification}";
                            interceptorField[i] = targetedMethod.AsyncOriginType.CreateField(targetedMethod.Modifiers.GetPrivate(), item.Interface.ToBuilderType, name);
                            interceptorField[i].CustomAttributes.AddNonSerializedAttribute();

                            x.Load(interceptorField[i]).IsNull().Then(y =>
                            {
                                y.Assign(interceptorField[i]).NewObj(item.Attribute);
                                if (item.HasSyncRootInterface)
                                {
                                    y.Load(interceptorField[i]).As(__ISyncRoot.Type).Call(syncRoot.SyncRoot, method.SyncRoot);
                                }

                                ImplementAssignMethodAttribute(builder, method.Item[i].AssignMethodAttributeInfos, interceptorField[i], item.Attribute.Attribute.Type, x);
                            });

                            x.Load(interceptorField[i]).Call(item.Interface.OnEnter, attributedMethod.OriginType, typeInstance, attributedMethod, x.GetParametersArray());

                            item.Attribute.Remove();
                        }
                    });

                    var position = coder.GetFirstOrDefaultPosition(x => x.OpCode == OpCodes.Stelem_Ref);

                    if (position == null)
                    {
                        coder.Insert(InsertionPosition.Beginning);
                    }
                    else
                    {
                        coder.Insert(InsertionAction.After, position);
                    }
                }
                ;
            }
        }