예제 #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));
                }
            }
        }
예제 #2
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();
                }
            }
        }