Ejemplo n.º 1
0
        // 写入绑定代码
        protected void WriteCSMethodBinding(MethodBaseBindingInfo <T> bindingInfo, T method, string argc, bool isVararg)
        {
            // 是否接管 cs 绑定代码生成
            var transform = cg.bindingManager.GetTypeTransform(method.DeclaringType);

            if (transform != null && transform.OnBinding(BindingPoints.METHOD_BINDING_FULL, method, cg))
            {
                return;
            }

            var isExtension = BindingManager.IsExtensionMethod(method);
            // var isRaw = method.IsDefined(typeof(JSCFunctionAttribute));
            var parameters = method.GetParameters();
            var in_params  = new List <ParameterInfo>();
            var out_params = new List <ParameterInfo>();

            SplitParamters(parameters, isExtension ? 1 : 0, in_params, out_params);
            var caller     = this.cg.AppendGetThisCS(method);
            var returnType = GetReturnType(method);

            // if (isRaw)
            // {
            //     do
            //     {
            //         if (!isExtension)
            //         {
            //             if (returnType == typeof(int) && in_params.Count == 1)
            //             {
            //                 var p = in_params[0];
            //                 if (p.ParameterType == typeof(IntPtr) && !p.IsOut)
            //                 {
            //                     cg.cs.AppendLine($"return {caller}.{method.Name}(ctx);");
            //                     return;
            //                 }
            //             }
            //             cg.bindingManager.Error($"invalid JSCFunction definition: {method}");
            //             break;
            //         }
            //         cg.bindingManager.Error($"Extension as JSCFunction is not supported: {method}");
            //     } while (false);
            // }

            if (returnType == null || returnType == typeof(void))
            {
                // 方法本身没有返回值
                this.BeginInvokeBinding();
                cg.cs.AppendLine($"{this.GetInvokeBinding(caller, method, isVararg, isExtension, argc, parameters)};");
                this.EndInvokeBinding();
                var backVars = out_params.Count > 0 ? _WriteBackParametersByRef(isExtension, out_params, null) : null;

                if (!method.IsStatic && method.DeclaringType.IsValueType) // struct 非静态方法 检查 Mutable 属性
                {
                    if (!string.IsNullOrEmpty(caller))
                    {
                        cg.cs.AppendLine($"js_rebind_this(ctx, this_obj, {caller});");
                    }
                }

                if (string.IsNullOrEmpty(backVars))
                {
                    this.InvokeVoidReturn();
                }
                else
                {
                    cg.cs.AppendLine("return {0};", backVars);
                }
            }
            else
            {
                var retVar   = "ret"; // cs return value var name
                var retJsVar = "ret_js";
                this.BeginInvokeBinding();
                cg.cs.AppendLine($"var {retVar} = {this.GetInvokeBinding(caller, method, isVararg, isExtension, argc, parameters)};");
                this.EndInvokeBinding();

                var retPusher = cg.AppendMethodReturnValuePusher(method, returnType, retVar);
                cg.cs.AppendLine("var {0} = {1};", retJsVar, retPusher);
                cg.cs.AppendLine("if (JSApi.JS_IsException({0}))", retJsVar);
                using (cg.cs.Block())
                {
                    cg.cs.AppendLine("return {0};", retJsVar);
                }
                var backVars = out_params.Count > 0 ? _WriteBackParametersByRef(isExtension, out_params, retJsVar) : retJsVar;
                cg.cs.AppendLine("return {0};", backVars);
            }
        }
Ejemplo n.º 2
0
        // 写入绑定代码
        protected void WriteCSMethodBinding(MethodBaseBindingInfo <T> bindingInfo, T method, string argc, bool isVararg)
        {
            // 是否接管 cs 绑定代码生成
            var transform = cg.bindingManager.GetTypeTransform(method.DeclaringType);

            if (transform != null && transform.OnBinding(BindingPoints.METHOD_BINDING_FULL, method, cg))
            {
                return;
            }

            var parameters  = method.GetParameters();
            var isExtension = method.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute));
            var isRaw       = method.IsDefined(typeof(JSCFunctionAttribute));

            if (isExtension)
            {
                ArrayUtility.RemoveAt(ref parameters, 0);
            }
            var parametersByRef = new List <ParameterInfo>();
            var caller          = this.cg.AppendGetThisCS(method);
            var returnType      = GetReturnType(method);

            if (isRaw)
            {
                do
                {
                    if (!isExtension)
                    {
                        if (returnType == typeof(int) && parameters.Length == 1)
                        {
                            var p = parameters[0];
                            if (p.ParameterType == typeof(IntPtr) && !p.IsOut)
                            {
                                cg.cs.AppendLine($"return {caller}.{method.Name}(ctx);");
                                return;
                            }
                        }
                        cg.bindingManager.Error($"invalid JSCFunction definition: {method}");
                        break;
                    }
                    cg.bindingManager.Error($"Extension as JSCFunction is not supported: {method}");
                } while (false);
            }

            if (returnType == null || returnType == typeof(void))
            {
                // 方法本身没有返回值
                this.BeginInvokeBinding();
                cg.cs.AppendLine($"{this.GetInvokeBinding(caller, method, isVararg, isExtension, argc, parameters, parametersByRef)};");
                this.EndInvokeBinding();
                if (parametersByRef.Count > 0)
                {
                    _WriteBackParametersByRef(isExtension, parametersByRef);
                }
                if (!method.IsStatic && method.DeclaringType.IsValueType) // struct 非静态方法 检查 Mutable 属性
                {
                    if (!string.IsNullOrEmpty(caller))
                    {
                        cg.cs.AppendLine($"js_rebind_this(ctx, this_obj, {caller});");
                    }
                }
                this.InvokeVoidReturn();
            }
            else
            {
                this.BeginInvokeBinding();
                cg.cs.AppendLine($"var ret = {this.GetInvokeBinding(caller, method, isVararg, isExtension, argc, parameters, parametersByRef)};");
                this.EndInvokeBinding();
                if (parametersByRef.Count > 0)
                {
                    _WriteBackParametersByRef(isExtension, parametersByRef);
                }
                var pusher = cg.AppendMethodReturnValuePusher(method, returnType, "ret");
                cg.cs.AppendLine("return {0};", pusher);
            }
        }