예제 #1
0
        public void OnPreGenerateDelegate(DelegateBridgeBindingInfo bindingInfo)
        {
            var typeDB = _runtime.GetTypeDB();
            var method = bindingInfo.reflect;

            foreach (var delegateType in bindingInfo.types)
            {
                typeDB.AddDelegate(delegateType, method);
            }
        }
        public DelegateCodeGen(CodeGenerator cg, DelegateBridgeBindingInfo delegateBindingInfo, int index)
        {
            this.cg = cg;
            this.delegateBindingInfo = delegateBindingInfo;
            var inputParameters = GetInputParameters(delegateBindingInfo.parameters);
            var nargs           = inputParameters.Length;
            var retName         = this.cg.bindingManager.GetUniqueName(delegateBindingInfo.parameters, "ret");
            var firstArgument   = typeof(ScriptDelegate) + " fn";
            var returnTypeName  = this.cg.bindingManager.GetCSTypeFullName(delegateBindingInfo.returnType);
            var delegateName    = CodeGenerator.NameOfDelegates + index;
            var arglist         = this.cg.bindingManager.GetCSArglistDecl(delegateBindingInfo.parameters);

            foreach (var target in delegateBindingInfo.types)
            {
                this.cg.cs.AppendLine("[{0}(typeof({1}))]",
                                      this.cg.bindingManager.GetCSTypeFullName(typeof(JSDelegateAttribute)),
                                      this.cg.bindingManager.GetCSTypeFullName(target));
                this.cg.bindingManager.Info("emitting delegate decl: {0}", target);
            }
            if (!string.IsNullOrEmpty(arglist))
            {
                arglist = ", " + arglist;
            }
            this.cg.cs.AppendLine($"public static unsafe {returnTypeName} {delegateName}({firstArgument}{arglist})");
            this.cg.cs.AppendLine("{");
            this.cg.cs.AddTabLevel();
            this.cg.cs.AppendLine("var ctx = fn.ctx;");

            if (nargs > 0)
            {
                var getContext = false;
                this.cg.cs.AppendLine("var argv = stackalloc JSValue[{0}];", nargs);
                for (var i = 0; i < nargs; i++)
                {
                    var parameter = inputParameters[i];
                    if (parameter.ParameterType.IsByRef)
                    {
                        if (parameter.IsOut)
                        {
                            var pusher = "JSApi.JS_NewObject(ctx)";
                            this.cg.cs.AppendLine("argv[{0}] = {1};", i, pusher);
                            CheckParameterException(i);
                        }
                        else
                        {
                            var pusher       = "JSApi.JS_NewObject(ctx)";
                            var value_pusher = this.cg.AppendValuePusher(parameter.ParameterType, parameter.Name);
                            this.cg.cs.AppendLine("argv[{0}] = {1};", i, pusher);
                            CheckParameterException(i);
                            if (!getContext)
                            {
                                getContext = true;
                                cg.cs.AppendLine("var context = ScriptEngine.GetContext(ctx);");
                            }
                            cg.cs.AppendLine("JSApi.JS_SetProperty(ctx, argv[{0}], context.GetAtom(\"value\"), {1});", i, value_pusher);
                        }
                    }
                    else
                    {
                        var pusher = this.cg.AppendValuePusher(parameter.ParameterType, parameter.Name);
                        this.cg.cs.AppendLine("argv[{0}] = {1};", i, pusher);
                        CheckParameterException(i);
                    }
                }
                this.cg.cs.AppendLine("var rval = fn.Invoke(ctx, {0}, argv);", nargs);
            }
            else
            {
                this.cg.cs.AppendLine("var rval = fn.Invoke(ctx);");
            }

            CheckReturnValue(nargs);
            _WriteBackParameters(nargs, inputParameters);

            if (delegateBindingInfo.returnType != typeof(void))
            {
                this.cg.cs.AppendLine($"{this.cg.bindingManager.GetCSTypeFullName(delegateBindingInfo.returnType)} {retName};");
                var getter = this.cg.bindingManager.GetScriptObjectGetter(delegateBindingInfo.returnType, "ctx", "rval", retName);

                this.cg.cs.AppendLine("var succ = {0};", getter);
                FreeRVal();
                FreeArgs(nargs);

                this.cg.cs.AppendLine("if (succ)");
                this.cg.cs.AppendLine("{");
                this.cg.cs.AddTabLevel();
                this.cg.cs.AppendLine($"return {retName};");
                this.cg.cs.DecTabLevel();
                this.cg.cs.AppendLine("}");
                this.cg.cs.AppendLine("else");
                this.cg.cs.AppendLine("{");
                this.cg.cs.AddTabLevel();
                this.cg.cs.AppendLine($"throw new Exception(\"js exception caught\");");
                this.cg.cs.DecTabLevel();
                this.cg.cs.AppendLine("}");
            }
            else
            {
                FreeRVal();
                FreeArgs(nargs);
            }
        }
예제 #3
0
 public void OnPostGenerateDelegate(DelegateBridgeBindingInfo bindingInfo)
 {
 }
예제 #4
0
 public virtual void OnPostGenerateDelegate(BindingManager bindingManager, DelegateBridgeBindingInfo bindingInfo)
 {
 }