Beispiel #1
0
        private static void InternalWriteHeader(
            CodeTextWriter twHeader,
            PreparedInformations prepared,
            ITypeInformation targetType,
            MemberScopes memberScope,
            IReadOnlyDictionary <ITypeInformation, ITypeInformation[]> typesByDeclaring)
        {
            if (typesByDeclaring.TryGetValue(targetType, out var types))
            {
                foreach (var type in types)
                {
                    // The nested types have to declare before outer types.
                    if (!type.Equals(targetType))
                    {
                        InternalWriteHeader(
                            twHeader,
                            prepared,
                            type,
                            memberScope,
                            typesByDeclaring);
                    }

                    // Write value type and object reference type.
                    TypeWriter.WriteTypeDefinitions(
                        twHeader,
                        type);

                    // Write type members.
                    TypeWriter.WriteMemberDefinitions(
                        twHeader,
                        type,
                        field => true,
                        method =>
                        // Except type initializer
                        !(method.IsConstructor && method.IsStatic) &&
                        prepared.Functions.ContainsKey(method));

                    // TODO: The internal or private members can separate into the internal headers.
                    //field => field.CLanguageMemberScope == memberScope,
                    //method => (method.CLanguageMemberScope == memberScope) && prepared.Functions.ContainsKey(method));
                }
            }
        }
Beispiel #2
0
        public static void InternalConvertToPrototypes(
            CodeTextWriter tw,
            ITypeInformation[] types,
            Func <ITypeInformation, bool> predictType,
            Func <IFieldInformation, bool> predictField,
            Func <IMethodInformation, bool> predictMethod)
        {
            tw.WriteLine("#ifdef __cplusplus");
            tw.WriteLine("extern \"C\" {");
            tw.WriteLine("#endif");
            tw.SplitLine();

            tw.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
            tw.WriteLine("// [2-1] Types:");
            tw.SplitLine();

            // Output prototypes.
            foreach (var type in types.
                     Where(type => predictType(type)))
            {
                // Unfortunately the enum type at C language has not the underlying type.
                // IL2C emits the enum types using not C language syntax.
                if (type.IsEnum)
                {
                    tw.WriteLine(
                        "typedef {0} {1};",
                        type.ElementType.CLanguageTypeName,
                        type.MangledName);
                }
                // The delegate derived types are same as System.MulticastDelegate.
                else if (type.IsDelegate)
                {
                    tw.WriteLine(
                        "typedef System_MulticastDelegate {0};",
                        type.MangledName);
                }
                else
                {
                    tw.WriteLine(
                        "typedef struct {0} {0};",
                        type.MangledName);
                }
            }
            tw.SplitLine();

            // Output value type and object reference type.
            foreach (var type in types.
                     Where(predictType))
            {
                TypeWriter.InternalConvertType(
                    tw,
                    type);
            }
            tw.SplitLine();

            tw.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
            tw.WriteLine("// [2-2] Public static fields:");
            tw.SplitLine();

            foreach (var type in types.
                     Where(type => !type.IsEnum))
            {
                foreach (var field in type.Fields
                         .Where(field => field.IsPublic && field.IsStatic && predictField(field)))
                {
                    tw.WriteLine(
                        "extern {0};",
                        field.GetCLanguageStaticPrototype(false));
                }

                tw.SplitLine();
            }

            tw.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
            tw.WriteLine("// [2-3] Methods:");
            tw.SplitLine();

            foreach (var type in types.
                     Where(type => !type.IsEnum))
            {
                var methods = type.DeclaredMethods.
                              Where(predictMethod).
                              ToArray();

                if (methods.Length >= 1)
                {
                    tw.WriteLine(
                        "// [2-4] Member methods: {0}",
                        type.FriendlyName);
                    tw.SplitLine();

                    foreach (var method in type.DeclaredMethods.
                             Where(predictMethod))
                    {
                        tw.WriteLine(
                            "extern {0}{1};",
                            method.IsStatic ?
                            "/* static */ " :
                            method.IsVirtual ?
                            (method.IsReuseSlot ? "/* override */ " : "/* virtual */ ") :
                            string.Empty,
                            method.CLanguageFunctionPrototype);
                    }
                    tw.SplitLine();
                }
            }

            tw.WriteLine("#ifdef __cplusplus");
            tw.WriteLine("}");
            tw.WriteLine("#endif");
            tw.SplitLine();
        }
Beispiel #3
0
        private static void InternalWriteSourceCode(
            CodeTextWriter twSource,
            IExtractContextHost extractContext,
            PreparedInformations prepared,
            ITypeInformation targetType,
            DebugInformationOptions debugInformationOption,
            IReadOnlyDictionary <ITypeInformation, ITypeInformation[]> typesByDeclaring)
        {
            // TODO: invalid sequence for multiple nested types.
            if (typesByDeclaring.TryGetValue(targetType, out var types))
            {
                foreach (var type in types)
                {
                    // The nested types have to declare before outer types.
                    if (!type.Equals(targetType))
                    {
                        InternalWriteSourceCode(
                            twSource,
                            extractContext,
                            prepared,
                            type,
                            debugInformationOption,
                            typesByDeclaring);
                    }

                    twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
                    twSource.WriteLine(
                        "// [9-1] Type: {0}",
                        targetType.FriendlyName);
                    twSource.SplitLine();

                    twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
                    twSource.WriteLine("// [9-2] File scope prototypes:");
                    twSource.SplitLine();

                    // Write type members.
                    TypeWriter.WriteMemberDefinitions(
                        twSource,
                        type,
                        field => field.CLanguageMemberScope == MemberScopes.File,
                        method => (method.CLanguageMemberScope == MemberScopes.File) && prepared.Functions.ContainsKey(method));

                    // All static fields except enum and native value.
                    if (!type.IsEnum)
                    {
                        var staticFields = type.Fields.
                                           Where(field => field.IsStatic && (field.NativeValue == null)).
                                           ToArray();
                        if (staticFields.Length >= 1)
                        {
                            twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
                            twSource.WriteLine("// [9-3] Static field handlers:");
                            twSource.SplitLine();

                            var staticFieldsName = type.MangledUniqueName + "_STATIC_FIELDS";

                            twSource.WriteLine(
                                "static volatile uintptr_t {0}_initializerCount__ = 0;",
                                staticFieldsName);
                            twSource.SplitLine();
                            twSource.WriteLine(
                                "static struct {0}_DECL__ /* IL2C_STATIC_FIELDS */",
                                staticFieldsName);
                            twSource.WriteLine("{");

                            var objrefStaticFields = staticFields.
                                                     Where(field => field.FieldType.IsReferenceType).
                                                     ToArray();
                            var valueTypeStaticFields = staticFields.
                                                        Where(field => field.FieldType.IsValueType && field.FieldType.IsRequiredTraverse).
                                                        ToArray();
                            var otherStaticFields = new HashSet <IFieldInformation>(staticFields.
                                                                                    Except(objrefStaticFields).
                                                                                    Except(valueTypeStaticFields));

                            using (var _ = twSource.Shift())
                            {
                                twSource.WriteLine("IL2C_STATIC_FIELDS* pNext__;");
                                twSource.WriteLine("const uint16_t objRefCount__;");
                                twSource.WriteLine("const uint16_t valueCount__;");

                                if (objrefStaticFields.Length >= 1)
                                {
                                    twSource.WriteLine("//-------------------- objref");
                                    foreach (var field in objrefStaticFields)
                                    {
                                        twSource.WriteLine(
                                            "{0} {1};",
                                            field.FieldType.CLanguageTypeName,
                                            field.MangledName);
                                    }
                                }

                                if (valueTypeStaticFields.Length >= 1)
                                {
                                    twSource.WriteLine("//-------------------- value type");
                                    foreach (var field in valueTypeStaticFields)
                                    {
                                        twSource.WriteLine(
                                            "{0} {1};",
                                            field.FieldType.CLanguageTypeName,
                                            field.MangledName);
                                    }
                                }
                            }

                            twSource.WriteLine(
                                "}} {0}__ = {{ NULL, {1}, {2} }};",
                                staticFieldsName,
                                objrefStaticFields.Length,
                                valueTypeStaticFields.Length);
                            twSource.SplitLine();

                            foreach (var field in otherStaticFields)
                            {
                                twSource.WriteLine(
                                    "static {0} {1};",
                                    field.FieldType.CLanguageTypeName,
                                    field.MangledUniqueName);
                            }
                            twSource.SplitLine();

                            foreach (var field in staticFields)
                            {
                                twSource.WriteLine(
                                    "{0}* {1}_HANDLER__(void)",
                                    field.FieldType.CLanguageTypeName,
                                    field.MangledUniqueName);
                                twSource.WriteLine("{");

                                using (var _ = twSource.Shift())
                                {
                                    // TODO: Have to guard race condition for the multi threading feature.
                                    twSource.WriteLine(
                                        "if (il2c_unlikely__({0}_initializerCount__ != *il2c_initializer_count))",
                                        staticFieldsName);
                                    twSource.WriteLine("{");
                                    using (var __ = twSource.Shift())
                                    {
                                        twSource.WriteLine(
                                            "{0}_initializerCount__ = *il2c_initializer_count;",
                                            staticFieldsName);
                                        twSource.WriteLine(
                                            "il2c_register_static_fields(&{0}__);",
                                            staticFieldsName);

                                        var typeInitializer = type.DeclaredMethods.
                                                              FirstOrDefault(method => method.IsConstructor && method.IsStatic);
                                        if (typeInitializer != null)
                                        {
                                            twSource.WriteLine(
                                                "{0}();",
                                                typeInitializer.CLanguageFunctionFullName);
                                        }
                                    }
                                    twSource.WriteLine("}");

                                    if (otherStaticFields.Contains(field))
                                    {
                                        twSource.WriteLine(
                                            "return &{0};",
                                            field.MangledUniqueName);
                                    }
                                    else
                                    {
                                        twSource.WriteLine(
                                            "return &{0}__.{1};",
                                            staticFieldsName,
                                            field.MangledName);
                                    }
                                }

                                twSource.WriteLine("}");
                                twSource.SplitLine();
                            }
                        }
                    }

                    twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
                    twSource.WriteLine("// [9-4] Type: {0}", type.FriendlyName);
                    twSource.SplitLine();

                    // All methods and constructor exclude type initializer
                    foreach (var method in type.DeclaredMethods.
                             Where(method => prepared.Functions.ContainsKey(method)))
                    {
                        FunctionWriter.InternalConvertFromMethod(
                            twSource,
                            extractContext,
                            prepared,
                            method,
                            debugInformationOption);
                    }

                    if (type.IsClass || type.IsValueType)
                    {
                        TypeHelperWriter.InternalConvertTypeHelper(
                            twSource,
                            type);
                    }
                    else if (type.IsInterface)
                    {
                        TypeHelperWriter.InternalConvertTypeHelperForInterface(
                            twSource,
                            type);
                    }

                    twSource.SplitLine();
                }
            }
        }