Example #1
0
 public static void WriteHeader(
     CodeTextWriter twHeader,
     TranslateContext translateContext,
     PreparedInformations prepared)
 {
     InternalWriteHeader(
         twHeader, translateContext, prepared, true);
 }
Example #2
0
 public static void WriteSourceCode(
     CodeTextWriter twSource,
     TranslateContext translateContext,
     PreparedInformations prepared,
     DebugInformationOptions debugInformationOption = DebugInformationOptions.Full)
 {
     InternalWriteSourceCode(
         twSource, translateContext, prepared, debugInformationOption, true);
 }
Example #3
0
        public static string[] WriteSourceCode(
            CodeTextStorage storage,
            TranslateContext translateContext,
            PreparedInformations prepared,
            bool enableBundler,
            DebugInformationOptions debugInformationOption)
        {
            var sourceFilePaths = new List <string>();

            var assemblyName = translateContext.Assembly.Name;

            // Write assembly level common internal header.
            HeaderWriter.WriteCommonInternalHeader(
                storage,
                translateContext,
                prepared,
                assemblyName);

            // Write assembly level common internal source code.
            sourceFilePaths.Add(
                SourceCodeWriter.WriteCommonInternalSourceCode(
                    storage,
                    translateContext,
                    prepared,
                    assemblyName));

            // Write source code bundler.
            if (enableBundler)
            {
                SourceCodeWriter.WriteBundlerSourceCode(
                    storage,
                    prepared,
                    assemblyName);
            }

            using (var _ = storage.EnterScope(assemblyName, false))
            {
                // Write source codes.
                sourceFilePaths.AddRange(
                    SourceCodeWriter.WriteSourceCodes(
                        storage,
                        translateContext,
                        prepared,
                        debugInformationOption));
            }

            return(sourceFilePaths.ToArray());
        }
Example #4
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));
                }
            }
        }
Example #5
0
        internal static void InternalWriteHeader(
            CodeTextWriter twHeader,
            TranslateContext translateContext,
            PreparedInformations prepared,
            bool includeAssemblyHeader)
        {
            IExtractContext extractContext = translateContext;

            var assemblyName = Utilities.GetMangledName(extractContext.Assembly.FriendlyName);

            twHeader.WriteLine("#ifndef __{0}_H__", assemblyName);
            twHeader.WriteLine("#define __{0}_H__", assemblyName);
            twHeader.SplitLine();
            twHeader.WriteLine("#pragma once");
            twHeader.SplitLine();
            twHeader.WriteLine("#include <il2c.h>");

            if (includeAssemblyHeader)
            {
                twHeader.SplitLine();
                foreach (var fileName in extractContext.EnumerateRequiredIncludeFileNames())
                {
                    twHeader.WriteLine("#include <{0}>", fileName);
                }
            }

            // All types exclude privates
            PrototypeWriter.InternalConvertToPrototypes(
                twHeader,
                prepared.Types,
                type => type.IsCLanguagePublicScope,
                field => field.IsPublic || field.IsFamily || field.IsFamilyOrAssembly,
                method => (method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly) &&
                prepared.Functions.ContainsKey(method));

            twHeader.SplitLine();
            twHeader.WriteLine("#endif");
            twHeader.SplitLine();
        }
Example #6
0
        public static void WriteBundlerSourceCode(
            CodeTextStorage storage,
            PreparedInformations prepared,
            string assemblyName)
        {
            using (var twSource = storage.CreateSourceCodeWriter(assemblyName + "_bundle"))
            {
                var assemblyMangledName = Utilities.GetMangledName(assemblyName);

                twSource.WriteLine(
                    "// [15-3] This is {0} native code translated by IL2C, do not edit.",
                    assemblyName);
                twSource.SplitLine();
                twSource.WriteLine(
                    "// This is the bundler source code for {0},",
                    assemblyName);
                twSource.WriteLine(
                    "// you can use it if you wanna compile only one source file.");
                twSource.SplitLine();

                twSource.WriteLine(
                    "#include \"{0}_internal.c\"",
                    assemblyName);

                foreach (var type in prepared.Types.
                         Where(type => type.DeclaringType == null))
                {
                    twSource.WriteLine(
                        "#include \"{0}/{1}/{2}.c\"",
                        assemblyName,
                        Utilities.GetCLanguageScopedPath(type.ScopeName),
                        type.Name);
                }

                twSource.SplitLine();
                twSource.Flush();
            }
        }
Example #7
0
        public static void WriteHeader(
            CodeTextStorage storage,
            TranslateContext translateContext,
            PreparedInformations prepared)
        {
            var assemblyName = translateContext.Assembly.Name;

            // Write assembly level common header.
            HeaderWriter.WriteCommonHeader(
                storage,
                translateContext,
                prepared,
                assemblyName);

            using (var _ = storage.EnterScope(assemblyName, false))
            {
                // Write public headers.
                HeaderWriter.WriteHeaders(
                    storage,
                    translateContext,
                    prepared);
            }
        }
Example #8
0
        public static void WriteHeaders(
            CodeTextStorage storage,
            TranslateContext translateContext,
            PreparedInformations prepared)
        {
            IExtractContext extractContext      = translateContext;
            var             assemblyName        = translateContext.Assembly.Name;
            var             assemblyMangledName = translateContext.Assembly.MangledName;

            var typesByDeclaring = prepared.Types.
                                   GroupBy(type => type.DeclaringType ?? type).
                                   ToDictionary(
                g => g.Key,
                g => g.OrderByDependant(translateContext.Assembly).ToArray());

            foreach (var g in prepared.Types.
                     Where(type => type.DeclaringType == null).
                     GroupBy(type => type.ScopeName))
            {
                using (var _ = storage.EnterScope(g.Key))
                {
                    foreach (var type in g)
                    {
                        using (var twHeader = storage.CreateHeaderWriter(type.Name))
                        {
                            var scopeName = Utilities.GetMangledName(type.ScopeName);

                            twHeader.WriteLine(
                                "// [14-1] This is {0} native code translated by IL2C, do not edit.",
                                assemblyName);
                            twHeader.SplitLine();

                            twHeader.WriteLine(
                                "#include <{0}.h>",
                                assemblyName);
                            twHeader.SplitLine();

                            twHeader.WriteLine("#ifdef __cplusplus");
                            twHeader.WriteLine("extern \"C\" {");
                            twHeader.WriteLine("#endif");
                            twHeader.SplitLine();

                            twHeader.WriteLine("///////////////////////////////////////////////////////////////////////////");
                            twHeader.WriteLine("// [14-2] Type pre definitions:");
                            twHeader.SplitLine();

                            // All types exclude privates
                            WriteTypePreDefinitions(
                                twHeader,
                                type,
                                typesByDeclaring);

                            twHeader.WriteLine("///////////////////////////////////////////////////////////////////////////");
                            twHeader.WriteLine("// [14-3] Type body definitions:");
                            twHeader.SplitLine();

                            twHeader.WriteLine(
                                "#ifdef {0}_DECL_TYPE_BODY__",
                                assemblyMangledName);
                            twHeader.SplitLine();

                            InternalWriteHeader(
                                twHeader,
                                prepared,
                                type,
                                MemberScopes.Public,
                                typesByDeclaring);

                            twHeader.WriteLine("#endif");
                            twHeader.SplitLine();

                            twHeader.WriteLine("#ifdef __cplusplus");
                            twHeader.WriteLine("}");
                            twHeader.WriteLine("#endif");
                            twHeader.SplitLine();

                            twHeader.Flush();
                        }
                    }
                }
            }
        }
Example #9
0
        public static void WriteCommonInternalHeader(
            CodeTextStorage storage,
            TranslateContext translateContext,
            PreparedInformations prepared,
            string assemblyName)
        {
            IExtractContext extractContext               = translateContext;
            var             annotatedAssemblyName        = assemblyName + "_internal";
            var             annotatedAssemblyMangledName = Utilities.GetMangledName(annotatedAssemblyName);

            using (var twHeader = storage.CreateHeaderWriter(annotatedAssemblyName))
            {
                twHeader.WriteLine(
                    "// [13-1] This is {0} native code translated by IL2C, do not edit.",
                    assemblyName);
                twHeader.SplitLine();

                twHeader.WriteLine(
                    "#ifndef __{0}_H__",
                    annotatedAssemblyMangledName);
                twHeader.WriteLine(
                    "#define __{0}_H__",
                    annotatedAssemblyMangledName);
                twHeader.SplitLine();
                twHeader.WriteLine("#pragma once");
                twHeader.SplitLine();

                twHeader.WriteLine("#include <{0}.h>", assemblyName);
                twHeader.SplitLine();

                var constStrings = extractContext.
                                   ExtractConstStrings().
                                   ToArray();
                if (constStrings.Length >= 1)
                {
                    twHeader.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
                    twHeader.WriteLine("// [9-1-1] Const strings:");
                    twHeader.SplitLine();

                    foreach (var(symbolName, _) in constStrings)
                    {
                        twHeader.WriteLine(
                            "extern System_String* const {0};",
                            symbolName);
                    }
                    twHeader.SplitLine();
                }

                var declaredValues = extractContext.
                                     ExtractDeclaredValues().
                                     ToArray();
                if (declaredValues.Length >= 1)
                {
                    twHeader.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
                    twHeader.WriteLine("// [12-1-1] Declared values:");
                    twHeader.SplitLine();

                    foreach (var information in declaredValues)
                    {
                        foreach (var declaredFields in information.DeclaredFields)
                        {
                            twHeader.WriteLine(
                                "// {0}",
                                declaredFields.FriendlyName);
                        }

                        var targetType = (information.HintTypes.Length == 1) ?
                                         information.HintTypes[0] :
                                         extractContext.MetadataContext.ByteType.MakeArray();
                        Debug.Assert(targetType.IsArray);

                        var elementType = targetType.ElementType.ResolveToRuntimeType();
                        var values      = Utilities.ResourceDataToSpecificArray(information.ResourceData, elementType);

                        var lhs = targetType.GetCLanguageTypeName(information.SymbolName, true);
                        twHeader.WriteLine(
                            "extern const {0};",
                            lhs);
                    }
                    twHeader.SplitLine();
                }

                twHeader.WriteLine("#endif");
                twHeader.Flush();
            }
        }
Example #10
0
        public static void WriteCommonHeader(
            CodeTextStorage storage,
            TranslateContext translateContext,
            PreparedInformations prepared,
            string assemblyName)
        {
            IExtractContext extractContext      = translateContext;
            var             assemblyMangledName = Utilities.GetMangledName(assemblyName);

            using (var twHeader = storage.CreateHeaderWriter(assemblyName))
            {
                twHeader.WriteLine(
                    "// [13-1] This is {0} native code translated by IL2C, do not edit.",
                    assemblyName);
                twHeader.SplitLine();

                twHeader.WriteLine(
                    "#ifndef __{0}_H__",
                    assemblyMangledName);
                twHeader.WriteLine(
                    "#define __{0}_H__",
                    assemblyMangledName);
                twHeader.SplitLine();
                twHeader.WriteLine("#pragma once");
                twHeader.SplitLine();

                // Write assembly references.
                var assemblies = extractContext.EnumerateRegisteredTypes().
                                 SelectMany(entry => entry.Value).
                                 Distinct().
                                 OrderByDependant(translateContext.Assembly).
                                 Select(type => type.DeclaringModule.DeclaringAssembly).
                                 Where(assembly => !assembly.Equals(translateContext.Assembly)).
                                 Distinct().
                                 ToArray();
                if (assemblies.Length >= 1)
                {
                    twHeader.WriteLine("///////////////////////////////////////////////////////////////////////////");
                    twHeader.WriteLine("// [13-2] Assembly references:");
                    twHeader.SplitLine();

                    foreach (var assembly in assemblies)
                    {
                        twHeader.WriteLine("#include <{0}.h>", assembly.Name);
                    }
                    twHeader.SplitLine();
                }

                // Write native headers from the NativeType/NativeMethod/NativeValue attributes.
                var importFileNames = extractContext.EnumerateRequiredImportIncludeFileNames().ToArray();
                if (importFileNames.Length >= 1)
                {
                    twHeader.WriteLine("///////////////////////////////////////////////////////////////////////////");
                    twHeader.WriteLine("// [13-3] Import native headers:");
                    twHeader.SplitLine();

                    foreach (var fileName in importFileNames)
                    {
                        twHeader.WriteLine("#include <{0}>", fileName);
                    }
                    twHeader.SplitLine();
                }

                var types = prepared.Types.
                            Where(type => type.DeclaringType == null).
                            OrderByDependant(translateContext.Assembly).
                            ToArray();
                if (types.Length >= 1)
                {
                    // Write pre definitions of type.
                    twHeader.WriteLine("///////////////////////////////////////////////////////////////////////////");
                    twHeader.WriteLine("// [13-4] Type pre definitions:");
                    twHeader.SplitLine();

                    foreach (var type in types)
                    {
                        twHeader.WriteLine(
                            "#include \"{0}/{1}/{2}.h\"",
                            assemblyName,
                            Utilities.GetCLanguageScopedPath(type.ScopeName),
                            type.Name);
                    }
                    twHeader.SplitLine();

                    // Write body definitions of type.
                    twHeader.WriteLine("///////////////////////////////////////////////////////////////////////////");
                    twHeader.WriteLine("// [13-5] Type body definitions:");
                    twHeader.SplitLine();

                    twHeader.WriteLine(
                        "#define {0}_DECL_TYPE_BODY__ 1",
                        assemblyMangledName);
                    twHeader.SplitLine();

                    foreach (var type in types)
                    {
                        twHeader.WriteLine(
                            "#include \"{0}/{1}/{2}.h\"",
                            assemblyName,
                            Utilities.GetCLanguageScopedPath(type.ScopeName),
                            type.Name);
                    }
                    twHeader.SplitLine();
                }

                twHeader.WriteLine("#endif");
                twHeader.Flush();
            }
        }
Example #11
0
        public static string[] WriteSourceCodes(
            CodeTextStorage storage,
            TranslateContext translateContext,
            PreparedInformations prepared,
            DebugInformationOptions debugInformationOption)
        {
            IExtractContextHost extractContext = translateContext;
            var assemblyName = extractContext.Assembly.Name;

            var typesByDeclaring = prepared.Types.
                                   GroupBy(type => type.DeclaringType ?? type).
                                   ToDictionary(
                g => g.Key,
                g => g.OrderByDependant(translateContext.Assembly).ToArray());

            var sourceFiles = new List <string>();

            foreach (var targetType in prepared.Types.
                     Where(type => type.DeclaringType == null))
            {
                using (var _ = storage.EnterScope(targetType.ScopeName))
                {
                    using (var twSource = storage.CreateSourceCodeWriter(targetType.Name))
                    {
                        twSource.WriteLine(
                            "// [15-2] This is {0} native code translated by IL2C, do not edit.",
                            assemblyName);
                        twSource.SplitLine();

                        twSource.WriteLine(
                            "#include <{0}.h>",
                            assemblyName);
                        twSource.WriteLine(
                            "#include <{0}_internal.h>",
                            assemblyName);
                        twSource.SplitLine();

                        // Write assembly references at the file scope.
                        InternalWriteAssemblyReferences(
                            twSource,
                            translateContext,
                            extractContext,
                            targetType);

                        twSource.WriteLine("#ifdef __cplusplus");
                        twSource.WriteLine("extern \"C\" {");
                        twSource.WriteLine("#endif");
                        twSource.SplitLine();

                        InternalWriteSourceCode(
                            twSource,
                            extractContext,
                            prepared,
                            targetType,
                            debugInformationOption,
                            typesByDeclaring);

                        twSource.WriteLine("#ifdef __cplusplus");
                        twSource.WriteLine("}");
                        twSource.WriteLine("#endif");
                        twSource.SplitLine();

                        twSource.Flush();

                        sourceFiles.Add(twSource.RelatedPath);
                    }
                }
            }

            return(sourceFiles.ToArray());
        }
Example #12
0
        public static string[] WriteSourceCodes(
            CodeTextStorage storage,
            TranslateContext translateContext,
            PreparedInformations prepared,
            DebugInformationOptions debugInformationOption)
        {
            IExtractContextHost extractContext = translateContext;
            var assemblyName = extractContext.Assembly.Name;

            var typesByDeclaring = prepared.Types.
                                   GroupBy(type => type.DeclaringType ?? type).
                                   ToDictionary(
                g => g.Key,
                g => g.OrderByDependant(translateContext.Assembly).ToArray());

            var sourceFiles = new List <string>();

            foreach (var targetType in prepared.Types.
                     Where(type => type.DeclaringType == null))
            {
                using (var _ = storage.EnterScope(targetType.ScopeName))
                {
                    using (var twSource = storage.CreateSourceCodeWriter(targetType.Name))
                    {
                        // HACK: Unreal Engine 4 needs include directive with same file name as header extension (ex: foo.c --> foo.h) at first line.
                        if (extractContext.TargetPlatform == TargetPlatforms.UE4)
                        {
                            twSource.WriteLine(
                                "#include \"{0}.h\"   // [16-1] Needs for Unreal Engine 4.",
                                targetType.Name);
                            twSource.SplitLine();
                        }

                        twSource.WriteLine(
                            "// [15-2] This is {0} native code translated by IL2C, do not edit.",
                            assemblyName);
                        twSource.SplitLine();

                        twSource.WriteLine(
                            "#include <{0}.h>",
                            assemblyName);
                        twSource.WriteLine(
                            "#include <{0}_internal.h>",
                            assemblyName);
                        twSource.SplitLine();

                        // Write assembly references at the file scope.
                        InternalWriteAssemblyReferences(
                            twSource,
                            translateContext,
                            extractContext,
                            targetType);

                        twSource.WriteLine("#ifdef __cplusplus");
                        twSource.WriteLine("extern \"C\" {");
                        twSource.WriteLine("#endif");
                        twSource.SplitLine();

                        InternalWriteSourceCode(
                            twSource,
                            extractContext,
                            prepared,
                            targetType,
                            debugInformationOption,
                            typesByDeclaring);

                        twSource.WriteLine("#ifdef __cplusplus");
                        twSource.WriteLine("}");
                        twSource.WriteLine("#endif");
                        twSource.SplitLine();

                        twSource.Flush();

                        sourceFiles.Add(twSource.RelatedPath);
                    }

                    // HACK: Unreal Engine 4 needs include directive with same file name as header extension (ex: foo.c --> foo.h) at first line.
                    if (extractContext.TargetPlatform == TargetPlatforms.UE4)
                    {
                        using (var twUE4Header = storage.CreateHeaderWriter(targetType.Name))
                        {
                            twUE4Header.WriteLine(
                                "// [16-2] This is {0} native code translated by IL2C, do not edit.",
                                assemblyName);
                            twUE4Header.WriteLine(
                                "// It's a dummy header file for helping and using only Unreal Engine 4.",
                                assemblyName);

                            twUE4Header.Flush();
                        }
                    }
                }
            }

            return(sourceFiles.ToArray());
        }
Example #13
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();
                }
            }
        }
Example #14
0
        public static void InternalConvertFromMethod(
            CodeTextWriter tw,
            IExtractContextHost extractContext,
            PreparedInformations preparedFunctions,
            IMethodInformation method,
            DebugInformationOptions debugInformationOption = DebugInformationOptions.None)
        {
            if (method.IsVirtual)
            {
                if (method.IsAbstract)
                {
                    if (!method.DeclaringType.IsInterface)
                    {
                        InternalConvertFromAbstractFunction(
                            tw,
                            method);
                    }
                    return;
                }
            }

            // internalcall or DllImport
            if (method.IsExtern)
            {
                // DllImport
                var pinvokeInfo = method.PInvokeInfo;
                if (pinvokeInfo != null)
                {
                    InternalConvertFromPInvokeFunction(
                        tw,
                        method,
                        pinvokeInfo);
                    return;
                }

                // Specialize delegate type methods:
                if (method.DeclaringType.IsDelegate && !method.DeclaringType.IsAbstract)
                {
                    // Delegate constructor
                    if (method.IsConstructor)
                    {
                        // Ignore. We have to use the "il2c_new_delegate()" instead this constructor translated body.
                        return;
                    }

                    // Delegate "Invoke"
                    if (method.Name == "Invoke")
                    {
                        InternalConvertFromDelegateInvoker(
                            tw,
                            extractContext,
                            method);
                        return;
                    }
                }

                throw new InvalidProgramSequenceException(
                          "Unknown internallcall method declaration. Name={0}",
                          method.FriendlyName);
            }

            if (!preparedFunctions.Functions.TryGetValue(method, out var preparedMethod))
            {
                return;
            }

            InternalConvertFromFunction(
                tw,
                extractContext,
                preparedMethod,
                debugInformationOption);
        }
Example #15
0
        internal static void InternalWriteSourceCode(
            CodeTextWriter twSource,
            TranslateContext translateContext,
            PreparedInformations prepared,
            DebugInformationOptions debugInformationOption,
            bool includeAssemblyHeader)
        {
            IExtractContextHost extractContext = translateContext;

            if (includeAssemblyHeader)
            {
                foreach (var fileName in extractContext.EnumerateRequiredPrivateIncludeFileNames())
                {
                    twSource.WriteLine("#include \"{0}\"", fileName);
                }

                twSource.WriteLine("#include \"{0}.h\"", extractContext.Assembly.Name);
                twSource.SplitLine();
            }

            WriteConstStrings(twSource, translateContext);
            WriteDeclaredValues(twSource, translateContext);

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

            // All types exclude publics and internals (for file scope prototypes)
            PrototypeWriter.InternalConvertToPrototypes(
                twSource,
                prepared.Types,
                type => !type.IsCLanguagePublicScope,
                field => !(field.IsPublic || field.IsFamily || field.IsFamilyOrAssembly),
                method => (method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly) &&
                prepared.Functions.ContainsKey(method));

            twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
            twSource.WriteLine("// [9-3] Declare static fields:");
            twSource.SplitLine();

            foreach (var type in prepared.Types.
                     Where(type => !type.IsEnum))
            {
                // All static fields
                foreach (var field in type.Fields.
                         Where(field => field.IsStatic))
                {
                    twSource.WriteLine(
                        "{0};",
                        field.GetCLanguageStaticPrototype(true));
                }
                twSource.SplitLine();
            }

            foreach (var type in prepared.Types)
            {
                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)
                {
                    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();
        }
Example #16
0
        public static string WriteCommonInternalSourceCode(
            CodeTextStorage storage,
            TranslateContext translateContext,
            PreparedInformations prepared,
            string assemblyName)
        {
            IExtractContext extractContext = translateContext;

            using (var twSource = storage.CreateSourceCodeWriter(assemblyName + "_internal"))
            {
                var assemblyMangledName = Utilities.GetMangledName(assemblyName);

                twSource.WriteLine(
                    "// [15-1] This is {0} native code translated by IL2C, do not edit.",
                    assemblyName);
                twSource.SplitLine();

                twSource.WriteLine(
                    "#include <{0}.h>",
                    assemblyName);
                twSource.WriteLine(
                    "#include <{0}_internal.h>",
                    assemblyName);
                twSource.SplitLine();

                var constStrings = extractContext.
                                   ExtractConstStrings().
                                   ToArray();
                if (constStrings.Length >= 1)
                {
                    twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
                    twSource.WriteLine("// [9-1-2] Const strings:");
                    twSource.SplitLine();

                    foreach (var(symbolName, value) in constStrings)
                    {
                        twSource.WriteLine(
                            "IL2C_CONST_STRING({0}, {1});",
                            symbolName,
                            Utilities.GetCLanguageExpression(value));
                    }

                    twSource.SplitLine();
                }

                var declaredValues = extractContext.
                                     ExtractDeclaredValues().
                                     ToArray();
                if (declaredValues.Length >= 1)
                {
                    twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
                    twSource.WriteLine("// [12-1-2] Declared values:");
                    twSource.SplitLine();

                    foreach (var information in declaredValues)
                    {
                        foreach (var declaredFields in information.DeclaredFields)
                        {
                            twSource.WriteLine(
                                "// {0}",
                                declaredFields.FriendlyName);
                        }

                        var targetType = (information.HintTypes.Length == 1) ?
                                         information.HintTypes[0] :
                                         extractContext.MetadataContext.ByteType.MakeArray();
                        Debug.Assert(targetType.IsArray);

                        var elementType = targetType.ElementType.ResolveToRuntimeType();
                        var values      = Utilities.ResourceDataToSpecificArray(information.ResourceData, elementType);

                        var lhs = targetType.GetCLanguageTypeName(information.SymbolName, true);
                        twSource.WriteLine(
                            "const {0} =",
                            lhs);
                        using (var _ = twSource.Shift())
                        {
                            twSource.WriteLine(
                                "{0};",
                                Utilities.GetCLanguageExpression(values));
                        }
                    }

                    twSource.SplitLine();
                }

                twSource.Flush();

                return(twSource.RelatedPath);
            }
        }
Example #17
0
        public static void InternalConvertFromMethod(
            CodeTextWriter tw,
            IExtractContextHost extractContext,
            PreparedInformations preparedFunctions,
            IMethodInformation method,
            DebugInformationOptions debugInformationOption = DebugInformationOptions.None)
        {
            if (method.IsVirtual)
            {
                if (method.IsAbstract)
                {
                    if (!method.DeclaringType.IsInterface)
                    {
                        InternalConvertFromAbstractFunction(
                            tw,
                            method);
                    }
                    return;
                }
            }

            // internalcall or DllImport
            if (method.IsExtern)
            {
                // Specialize delegate type methods:
                if (method.DeclaringType.IsDelegate && !method.DeclaringType.IsAbstract)
                {
                    // Delegate constructor
                    if (method.IsConstructor)
                    {
                        // Ignore. We have to use the "il2c_new_delegate()" instead this constructor translated body.
                        return;
                    }

                    // Delegate "Invoke"
                    if (method.Name == "Invoke")
                    {
                        InternalConvertFromDelegateInvoker(
                            tw,
                            extractContext,
                            method);
                        return;
                    }
                }

                // InternalCall or DllImport
                InternalConvertFromInternalCallFunction(
                    tw,
                    method);
                return;
            }

            if (!preparedFunctions.Functions.TryGetValue(method, out var preparedMethod))
            {
                return;
            }

            InternalConvertFromFunction(
                tw,
                extractContext,
                preparedMethod,
                debugInformationOption);
        }