Example #1
0
 public override string GeneratedIdentifier(string id)
 {
     return(CppGenerator.GenId(id));
 }
Example #2
0
        public void GenerateMethodInvocation(Method method)
        {
            GenerateMethodInitialization(method);
            NewLine();

            var paramsToMarshal    = method.Parameters.Where(p => !p.IsImplicit);
            var numParamsToMarshal = paramsToMarshal.Count();

            var argsId = "0";

            if (numParamsToMarshal > 0)
            {
                argsId = GeneratedIdentifier("args");
                WriteLine($"void* {argsId}[{numParamsToMarshal}];");
            }

            var contexts = new List <MarshalContext>();

            int paramIndex = 0;

            foreach (var param in paramsToMarshal)
            {
                var ctx = new MarshalContext(Context)
                {
                    ArgName        = param.Name,
                    Parameter      = param,
                    ParameterIndex = paramIndex
                };
                contexts.Add(ctx);

                var marshal = new CppMarshalNativeToManaged(EmbedOptions, ctx);
                param.Visit(marshal);

                if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
                {
                    Write(marshal.Context.SupportBefore);
                }

                WriteLine($"{argsId}[{paramIndex++}] = {marshal.Context.Return};");
            }

            var exceptionId = GeneratedIdentifier("exception");

            WriteLine($"MonoObject* {exceptionId} = 0;");

            var resultId = GeneratedIdentifier("result");

            WriteLine($"MonoObject* {resultId};");

            var methodId   = GeneratedIdentifier("method");
            var instanceId = method.IsStatic ? "0" : GeneratedIdentifier("instance");

            if (method.IsVirtual)
            {
                var virtualMethodId = GeneratedIdentifier("virtual_method");
                WriteLine($"MonoMethod* {virtualMethodId} = mono_object_get_virtual_method({instanceId}, {methodId});");
                methodId = virtualMethodId;
            }

            var @class = method.Namespace as Class;

            if (@class.IsValueType && !method.IsStatic)
            {
                var unboxedId = CppGenerator.GenId("unboxed");
                WriteLine($"void* {unboxedId} = mono_object_unbox({instanceId});");
                instanceId = unboxedId;
            }

            WriteLine("{0} = mono_runtime_invoke({1}, {2}, {3}, &{4});", resultId,
                      methodId, instanceId, argsId, exceptionId);
            NewLine();

            WriteLine($"if ({exceptionId})");
            WriteStartBraceIndent();

            if (method.IsConstructor)
            {
                WriteLine("delete this;");
            }

            WriteLine($"mono_embeddinator_throw_exception({exceptionId});");

            if (method.IsConstructor)
            {
                WriteLine("return;");
            }

            WriteCloseBraceIndent();

            foreach (var marshalContext in contexts)
            {
                if (!string.IsNullOrWhiteSpace(marshalContext.SupportAfter))
                {
                    Write(marshalContext.SupportAfter);
                }
            }
        }