Exemplo n.º 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);
        }
Exemplo n.º 2
0
        public override bool VisitClassDecl(Class @class)
        {
            var instanceId = CGenerator.GenId(string.Format("{0}_instance", Context.ArgName));

            Context.SupportBefore.WriteLine("MonoObject* {0} = mono_gchandle_get_target({1}->_handle);",
                                            instanceId, Context.ArgName);
            Context.Return.Write("{0}", instanceId);
            return(true);
        }
Exemplo n.º 3
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_m2n_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 => string.Format("\"{0}\"", n)));

                var unit = decl.TranslationUnit;

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

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

            throw new System.NotImplementedException();
        }
Exemplo n.º 4
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);
        }
Exemplo n.º 5
0
        public bool VisitPrimitiveType(PrimitiveType primitive)
        {
            switch (primitive)
            {
            case PrimitiveType.Void:
                return(true);

            case PrimitiveType.Bool:
            case PrimitiveType.WideChar:
            case PrimitiveType.Char:
            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);
            }

            throw new System.NotSupportedException();
        }
Exemplo n.º 6
0
 public string GeneratedIdentifier(string id)
 {
     return(CGenerator.GenId(id));
 }
Exemplo n.º 7
0
        public override bool VisitManagedArrayType(ManagedArrayType array,
                                                   TypeQualifiers quals)
        {
            var support = Context.SupportBefore;

            var arrayId = CGenerator.GenId(string.Format("{0}_array",
                                                         Context.ArgName));

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

            var arraySizeId = CGenerator.GenId(string.Format("{0}_array_size",
                                                             Context.ArgName));

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

            var typePrinter = CTypePrinter;

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

            typePrinter.PrintScopeKind = CppTypePrintScopeKind.Qualified;
            var arrayElementName = array.Array.Type.Visit(typePrinter);
            var elementSize      = string.Format("sizeof({0})", arrayElementName);

            var nativeArrayId = CGenerator.GenId(string.Format("{0}_native_array",
                                                               Context.ArgName));

            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(string.Format("{0}_element_class",
                                                                Context.ArgName));

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

            var elementSizeId = CGenerator.GenId(string.Format("{0}_array_element_size",
                                                               Context.ArgName));

            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(string.Format("{0}_array_element",
                                                           Context.ArgName));

            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(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);
        }
Exemplo n.º 8
0
        public override bool VisitManagedArrayType(ManagedArrayType array,
                                                   TypeQualifiers quals)
        {
            var support = Context.SupportBefore;

            var contextId      = CGenerator.GenId("mono_context");
            var arrayId        = CGenerator.GenId(string.Format("{0}_array", Context.ArgName));
            var elementClassId = CGenerator.GenId(string.Format("{0}_element_class",
                                                                Context.ArgName));

            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(string.Format("{0}_array_element",
                                                           Context.ArgName));

            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(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);
        }