コード例 #1
0
        bool HandleSpecialCILType(CILType cilType)
        {
            var type = cilType.Type;

            if (type == typeof(string))
            {
                var argId      = CGenerator.GenId(Context.ArgName);
                var contextId  = CGenerator.GenId("mono_context");
                var stringText = Context.ArgName;

                var param   = Context.Parameter;
                var isByRef = param != null && (param.IsOut || param.IsInOut);
                if (isByRef)
                {
                    stringText = string.Format("({0}->len != 0) ? {0}->str : \"\"",
                                               Context.ArgName);

                    Context.SupportAfter.WriteLine("g_string_truncate({0}, 0);", Context.ArgName);
                    Context.SupportAfter.WriteLine("g_string_append({0}, mono_string_to_utf8(" +
                                                   "(MonoString*) {1}));", Context.ArgName, argId);
                }

                Context.SupportBefore.WriteLine("MonoString* {0} = mono_string_new({1}.domain, {2});",
                                                argId, contextId, stringText);
                Context.Return.Write("{0}{1}", isByRef ? "&" : string.Empty, argId);
                return(true);
            }

            return(false);
        }
コード例 #2
0
        public bool VisitPrimitiveType(PrimitiveType primitive)
        {
            var param = Context.Parameter;

            switch (primitive)
            {
            case PrimitiveType.Void:
                return(true);

            case PrimitiveType.Bool:
            case PrimitiveType.Char:
            case PrimitiveType.WideChar:
            case PrimitiveType.SChar:
            case PrimitiveType.UChar:
            case PrimitiveType.Short:
            case PrimitiveType.UShort:
            case PrimitiveType.Int:
            case PrimitiveType.UInt:
            case PrimitiveType.Long:
            case PrimitiveType.ULong:
            case PrimitiveType.LongLong:
            case PrimitiveType.ULongLong:
            case PrimitiveType.Float:
            case PrimitiveType.Double:
            case PrimitiveType.LongDouble:
            case PrimitiveType.Null:
            {
                var prefix = "&";
                if ((param != null && (param.IsInOut || param.IsOut)) ||
                    PrimitiveValuesByValue)
                {
                    prefix = string.Empty;
                }
                Context.Return.Write("{0}{1}", prefix, Context.ArgName);
                return(true);
            }

            case PrimitiveType.String:
            {
                var argId     = $"{CGenerator.GenId(Context.ArgName)}_{Context.ParameterIndex}";
                var contextId = CGenerator.GenId("mono_context");
                var @string   = Context.ArgName;

                var isByRef = param != null && (param.IsOut || param.IsInOut);
                if (isByRef)
                {
                    @string = $"{Context.ArgName}->str";
                    Context.SupportAfter.WriteLine("mono_embeddinator_marshal_string_to_gstring({0}, {1});",
                                                   Context.ArgName, argId);
                }

                Context.SupportBefore.WriteLine("MonoString* {0} = ({2}) ? mono_string_new({1}.domain, {2}) : 0;",
                                                argId, contextId, @string);
                Context.Return.Write("{0}{1}", isByRef ? "&" : string.Empty, argId);
                return(true);
            }
            }

            throw new System.NotImplementedException(primitive.ToString());
        }
コード例 #3
0
        public JavaGenerator(BindingContext context) : base(context)
        {
            TypePrinter = new JavaTypePrinter(Context);

            Passes = new PassBuilder <TranslationUnitPass>(Context);
            CGenerator.SetupPasses(Passes);
        }
コード例 #4
0
ファイル: CMarshal.cs プロジェクト: matthid/Embeddinator-4000
        public override bool VisitManagedArrayType(ManagedArrayType array,
            TypeQualifiers quals)
        {
            var support = Context.SupportBefore;

            var contextId = CGenerator.GenId("mono_context");
            var arrayId = CGenerator.GenId($"{Context.ArgName}_array");
            var elementClassId = CGenerator.GenId($"{Context.ArgName}_element_class");

            var managedArray = array.Array;
            var elementType = managedArray.Type;
            support.WriteLine("MonoClass* {0} = mono_class_get_element_class({1});",
                elementClassId, GenerateArrayTypeLookup(elementType, support));

            support.WriteLine("MonoArray* {0} = mono_array_new({1}.domain, {2}, {3}.array->len);",
                arrayId, contextId, elementClassId, Context.ArgName);

            var iteratorId = CGenerator.GenId("i");
            support.WriteLine("for (int {0} = 0; {0} < {1}.array->len; {0}++)",
                              iteratorId, Context.ArgName);
            support.WriteStartBraceIndent();

            var typePrinter = CTypePrinter;
            string elementTypeName = elementType.Visit(typePrinter);

            var elementId = CGenerator.GenId($"{Context.ArgName}_array_element");
            support.WriteLine("{0} {1} = g_array_index({2}.array, {0}, {3});",
                elementTypeName, elementId, Context.ArgName, iteratorId);

            var ctx = new MarshalContext(Context.Context)
            {
                ArgName = elementId,
            };

            var marshal = new CMarshalNativeToManaged (Options, ctx) { PrimitiveValuesByValue = true };
            elementType.Visit(marshal);

            if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
                support.Write(marshal.Context.SupportBefore.ToString());

            var isValueType = IsValueType(elementType);
            if (isValueType)
            {
                support.WriteLine("mono_array_set({0}, {1}, {2}, {3});",
                    arrayId, elementTypeName, iteratorId,
                    marshal.Context.Return.ToString());
            }
            else
            {
                support.WriteLine("mono_array_setref({0}, {1}, {2});",
                    arrayId, iteratorId, marshal.Context.Return.ToString());
            }

            support.WriteCloseBraceIndent();

            Context.Return.Write("{0}", arrayId);

            return true;
        }
コード例 #5
0
        public override bool VisitClassDecl(Class @class)
        {
            var instanceId = CGenerator.GenId($"{Context.ArgName}_instance");
            var handle     = CSources.GetMonoObjectField(Options, Context.ArgName, "_handle");

            Context.SupportBefore.WriteLine($"MonoObject* {instanceId} = mono_gchandle_get_target({handle});");
            Context.Return.Write("{0}", instanceId);
            return(true);
        }
コード例 #6
0
        public bool VisitPrimitiveType(PrimitiveType primitive)
        {
            switch (primitive)
            {
            case PrimitiveType.Void:
                return(true);

            case PrimitiveType.Bool:
            case PrimitiveType.WideChar:
            case PrimitiveType.Char:
            case PrimitiveType.SChar:
            case PrimitiveType.UChar:
            case PrimitiveType.Short:
            case PrimitiveType.UShort:
            case PrimitiveType.Int:
            case PrimitiveType.UInt:
            case PrimitiveType.Long:
            case PrimitiveType.ULong:
            case PrimitiveType.LongLong:
            case PrimitiveType.ULongLong:
            case PrimitiveType.Float:
            case PrimitiveType.Double:
            case PrimitiveType.LongDouble:
            case PrimitiveType.Null:
            {
                var typePrinter = CTypePrinter;
                var typeName    = Context.ReturnType.Visit(typePrinter);

                var valueId = Context.ArgName;

                if (UnboxPrimitiveValues)
                {
                    var unboxId = CGenerator.GenId("unbox");
                    Context.SupportBefore.WriteLine("void* {0} = mono_object_unbox({1});",
                                                    unboxId, Context.ArgName);
                    valueId = unboxId;
                }

                Context.Return.Write("*(({0}*){1})", typeName, valueId);
                return(true);
            }

            case PrimitiveType.String:
            {
                var stringId = CGenerator.GenId("string");
                Context.SupportBefore.WriteLine("char* {0} = mono_string_to_utf8(" +
                                                "(MonoString*) {1});", stringId, Context.ArgName);

                Context.Return.Write("{0}", stringId);
                return(true);
            }
            }

            throw new System.NotImplementedException(primitive.ToString());
        }
コード例 #7
0
        public static string GenerateArrayTypeLookup(Type type, TextGenerator gen)
        {
            type = type.Desugar();

            if (type is BuiltinType)
            {
                var builtinType = type as BuiltinType;
                return(GetMonoClassForPrimitiveType(builtinType.Type));
            }
            else if (type is CILType)
            {
                var cilType = type as CILType;

                if (cilType.Type == typeof(string))
                {
                    return("mono_get_string_class()");
                }

                return(string.Format("mono_embeddinator_search_class(\"{0}\", \"{1}\", \"{2}\")",
                                     cilType.Type.Assembly.GetName().Name, cilType.Type.Namespace,
                                     cilType.Type.Name));
            }
            else if (type is TagType)
            {
                var tagType = type as TagType;
                var decl    = tagType.Declaration;

                var @namespace = string.Empty;
                var ids        = string.Join(", ",
                                             decl.QualifiedName.Split('.').Select(n => $"\"{n}\""));

                var unit = decl.TranslationUnit;

                var classId       = $"class_{decl.QualifiedName}";
                var monoImageName = $"{CGenerator.AssemblyId(unit)}_image";
                gen.WriteLine("{0} = mono_class_from_name({1}, \"{2}\", \"{3}\");",
                              classId, monoImageName, @namespace, decl.ManagedQualifiedName());

                return(classId);
            }
            else if (type is ArrayType)
            {
                var arrayType = type as ArrayType;
                return("0");
            }

            throw new System.NotImplementedException();
        }
コード例 #8
0
        bool HandleSpecialCILType(CILType cilType)
        {
            var type = cilType.Type;

            if (type == typeof(string))
            {
                var stringId = CGenerator.GenId("string");
                Context.SupportBefore.WriteLine("char* {0} = mono_string_to_utf8(" +
                                                "(MonoString*) {1});", stringId, Context.ArgName);

                Context.Return.Write("{0}", stringId);
                return(true);
            }

            return(false);
        }
コード例 #9
0
ファイル: CMarshal.cs プロジェクト: matthid/Embeddinator-4000
        public void HandleRefOutNonDefaultIntegerEnum(Enumeration @enum)
        {
            // This deals with marshaling of managed enums with non-C default
            // backing types (ie. enum : short).

            // Unlike C++ or Objective-C, C enums always have the default integer
            // type size, so we need to create a local variable of the right type
            // for marshaling with the managed runtime and cast it back to the
            // correct type.

            var backingType = @enum.BuiltinType.Type;
            var typePrinter = new CppTypePrinter();
            var integerType = typePrinter.VisitPrimitiveType(backingType);
            var newArgName = CGenerator.GenId(Context.ArgName);
            Context.SupportBefore.WriteLine("{0} {1} = *(({0}*) {2});",
                integerType, newArgName, Context.ArgName);
            Context.Return.Write("&{0}", newArgName);
            Context.SupportAfter.WriteLine("*{0} = ({1}) {2};", Context.ArgName,
                @enum.QualifiedName, newArgName);
        }
コード例 #10
0
        public void GenerateAssemblyLoad()
        {
            var assemblyName     = Unit.FileName;
            var assemblyLookupId = GeneratedIdentifier($"lookup_assembly_{assemblyName.Replace('.', '_')}");

            PushBlock();
            WriteLine($"static void {assemblyLookupId}()");
            WriteStartBraceIndent();

            var monoImageName = string.Format("{0}_image", CGenerator.AssemblyId(Unit));

            WriteLine("if ({0})", monoImageName);
            WriteLineIndent("return;");

            WriteLine("{0} = mono_embeddinator_load_assembly(&{1}, \"{2}\");",
                      monoImageName, GeneratedIdentifier("mono_context"), assemblyName);

            WriteCloseBraceIndent();
            PopBlock(NewLineKind.BeforeNextBlock);
        }
コード例 #11
0
        public override void Process()
        {
            RemoveTypedefNodes();

            GenerateFilePreamble(CommentKind.BCPL, "Embeddinator-4000");

            PushBlock();
            WriteHeaders();
            PopBlock(NewLineKind.BeforeNextBlock);

            PushBlock();
            WriteLine("mono_embeddinator_context_t {0};", GeneratedIdentifier("mono_context"));
            WriteLine("MonoImage* {0}_image;", CGenerator.AssemblyId(Unit));
            PopBlock(NewLineKind.BeforeNextBlock);

            GenerateObjectDeclarations();

            GenerateGlobalMethods();

            VisitDeclContext(Unit);
        }
コード例 #12
0
        public static string GenerateMonoClassFromNameCall(Declaration decl)
        {
            var namespaces = Declaration.GatherNamespaces(decl.Namespace)
                             .Where(ns => !(ns is TranslationUnit));

            var @namespace = string.Join(".", namespaces);
            var ids        = string.Join(", ",
                                         decl.QualifiedName.Split('.').Select(n => string.Format("\"{0}\"", n)));

            var monoImageName = string.Format("{0}_image", CGenerator.AssemblyId(decl.TranslationUnit));
            var managedName   = decl.ManagedQualifiedName();

            var dotIndex = managedName.LastIndexOf(".", StringComparison.Ordinal);

            if (dotIndex > 0)
            {
                managedName = managedName.Substring(managedName.LastIndexOf(".", StringComparison.Ordinal) + 1);
            }

            return($"mono_class_from_name({monoImageName}, \"{@namespace}\", \"{managedName}\");");
        }
コード例 #13
0
        public void GenerateNativeDeclarations(TranslationUnit unit)
        {
            // Since the native declarations are targetting the generated C bindings,
            // we need to modify the AST to match the one generated by the C target.

            var passes = new PassBuilder <TranslationUnitPass>(Context);

            CGenerator.SetupPasses(passes);

            Context.Options.GeneratorKind = GeneratorKind.C;

            passes.RunPasses(pass =>
            {
                pass.Context = Context;
                pass.VisitASTContext(Context.ASTContext);
            });

            Context.Options.GeneratorKind = GeneratorKind.Java;

            var nativeGen = new JavaNative(Context, unit);

            Generators.Add(nativeGen);
        }
コード例 #14
0
ファイル: CSources.cs プロジェクト: matthid/Embeddinator-4000
        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 CMarshalNativeToManaged(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 = CGenerator.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("free(object);");
            }

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

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

            WriteCloseBraceIndent();

            foreach (var marshalContext in contexts)
            {
                if (!string.IsNullOrWhiteSpace(marshalContext.SupportAfter))
                {
                    Write(marshalContext.SupportAfter);
                }
            }
        }
コード例 #15
0
 public override string GeneratedIdentifier(string id)
 {
     return(CGenerator.GenId(id));
 }
コード例 #16
0
        public override bool VisitManagedArrayType(ManagedArrayType array,
                                                   TypeQualifiers quals)
        {
            var support = Context.SupportBefore;

            var arrayId = CGenerator.GenId($"{Context.ArgName}_array");

            support.WriteLine("MonoArray* {0} = (MonoArray*) {1};",
                              arrayId, Context.ArgName);

            var arraySizeId = CGenerator.GenId($"{Context.ArgName}_array_size");

            support.WriteLine("uintptr_t {0} = mono_array_length({1});",
                              arraySizeId, arrayId);

            var typePrinter = CTypePrinter;

            typePrinter.PrintScopeKind = TypePrintScopeKind.Local;
            var arrayTypedefName = array.Typedef.Visit(typePrinter);

            typePrinter.PrintScopeKind = TypePrintScopeKind.Qualified;
            var arrayElementName = array.Array.Type.Visit(typePrinter);
            var elementSize      = $"sizeof({arrayElementName})";

            var nativeArrayId = CGenerator.GenId($"{Context.ArgName}_native_array");

            support.WriteLine("{0} {1};", arrayTypedefName, nativeArrayId);
            support.WriteLine("{0}.array = g_array_sized_new(/*zero_terminated=*/FALSE," +
                              " /*clear_=*/TRUE, {1}, {2});", nativeArrayId, elementSize, arraySizeId);

            var elementClassId = CGenerator.GenId($"{Context.ArgName}_element_class");

            support.WriteLine("MonoClass* {0} = mono_class_get_element_class({1});",
                              elementClassId,
                              CMarshalNativeToManaged.GenerateArrayTypeLookup(array.Array.Type, support));

            var elementSizeId = CGenerator.GenId($"{Context.ArgName}_array_element_size");

            support.WriteLine("gint32 {0} = mono_class_array_element_size({1});",
                              elementSizeId, elementClassId);

            var iteratorId = CGenerator.GenId("i");

            support.WriteLine("for (int {0} = 0; {0} < {1}; {0}++)",
                              iteratorId, arraySizeId);
            support.WriteStartBraceIndent();

            var elementId = CGenerator.GenId($"{Context.ArgName}_array_element");

            var isValueType = CMarshalNativeToManaged.IsValueType(array.Array.Type);

            support.WriteLine("{5} {0} = {4}mono_array_addr_with_size({1}, {2}, {3});",
                              elementId, arrayId, elementSizeId, iteratorId,
                              isValueType ? string.Empty : "*(MonoObject**)",
                              isValueType ? "char*" : "MonoObject*");

            var ctx = new MarshalContext(Context.Context)
            {
                ArgName       = elementId,
                ReturnVarName = elementId,
                ReturnType    = array.Array.QualifiedType
            };

            var marshal = new CMarshalManagedToNative(Options, ctx)
            {
                UnboxPrimitiveValues = false
            };

            array.Array.QualifiedType.Visit(marshal);

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

            support.WriteLine("g_array_append_val({0}.array, {1});", nativeArrayId,
                              marshal.Context.Return.ToString());

            support.WriteCloseBraceIndent();

            Context.Return.Write("{0}", nativeArrayId);
            return(false);
        }
コード例 #17
0
 public static string GenParamId(MarshalContext ctx)
 {
     return($"{CGenerator.GenId(ctx.ArgName)}_{ctx.ParameterIndex}");
 }