Exemple #1
0
        public static void WriteHeader(
            TextWriter twHeader,
            TranslateContext translateContext,
            PreparedFunctions preparedFunctions,
            string indent)
        {
            IExtractContext extractContext = translateContext;

            var assemblyName   = extractContext.Assembly.Name.Name;
            var safeSymbolName = assemblyName.Replace('.', '_').Replace('-', '_');

            twHeader.WriteLine("#ifndef __MODULE_{0}__", safeSymbolName);
            twHeader.WriteLine("#define __MODULE_{0}__", safeSymbolName);
            twHeader.WriteLine();

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

            var types = extractContext.Assembly.Modules
                        .SelectMany(module => module.Types)
                        .SelectMany(type => new[] { type }.Concat(type.NestedTypes))
                        // All types exclude privates
                        .Where(type => type.IsValidDefinition() &&
                               (type.IsPublic || type.IsNestedPublic || type.IsNestedFamily || type.IsNestedFamilyOrAssembly))
                        .ToArray();

            InternalConvertToPrototypes(
                twHeader,
                types,
                extractContext,
                preparedFunctions,
                method => method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly,
                indent);

            twHeader.WriteLine();
            twHeader.WriteLine("#endif");
        }
Exemple #2
0
        private static void InternalConvertToPrototypes(
            TextWriter tw,
            TypeDefinition[] types,
            IExtractContext extractContext,
            PreparedFunctions preparedFunctions,
            Func <MethodDefinition, bool> predictMethod,
            string indent)
        {
            tw.WriteLine();
            tw.WriteLine("#ifdef __cplusplus");
            tw.WriteLine("extern \"C\" {");
            tw.WriteLine("#endif");

            tw.WriteLine();
            tw.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
            tw.WriteLine("// Types:");
            tw.WriteLine();

            // Output prototypes.
            foreach (var type in types.Where(type => !type.IsEnum))
            {
                var typeName = extractContext.GetCLanguageTypeName(type, TypeNameFlags.Dereferenced)
                               .ManglingSymbolName();
                tw.WriteLine(
                    "typedef struct {0} {0};",
                    typeName);
            }

            // Output value type and object reference type.
            foreach (var type in types)
            {
                tw.WriteLine();
                InternalConvertType(
                    tw,
                    extractContext,
                    type,
                    indent);
            }

            tw.WriteLine();
            tw.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
            tw.WriteLine("// Public static fields:");

            foreach (var type in types.Where(type => !type.IsEnum))
            {
                tw.WriteLine();

                foreach (var field in type.Fields
                         .Where(field => field.IsPublic && field.IsStatic))
                {
                    tw.WriteLine(
                        "extern {0};",
                        Utilities.GetStaticFieldPrototypeString(field, false, extractContext));
                }
            }

            tw.WriteLine();
            tw.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
            tw.WriteLine("// Methods:");

            foreach (var type in types.Where(type => !type.IsEnum))
            {
                var rawTypeName = type
                                  .GetFullMemberName()
                                  .ManglingSymbolName();
                var typeName = extractContext
                               .GetCLanguageTypeName(type, TypeNameFlags.Dereferenced)
                               .ManglingSymbolName();

                tw.WriteLine();
                tw.WriteLine(
                    "// {0}",
                    type.FullName);

                if (!type.IsInterface)
                {
                    tw.WriteLine(
                        "extern /* internalcall */ void __{0}_IL2C_MarkHandler__({1}* this__);",
                        rawTypeName,
                        typeName);
                }

                tw.WriteLine(
                    "extern /* internalcall */ void* __{0}_IL2C_RuntimeCast__({1}* this__, IL2C_RUNTIME_TYPE_DECL* type);",
                    rawTypeName,
                    typeName);

                // TODO: Support enum type methods
                foreach (var method in type.Methods
                         .Where(method =>
                                (!method.IsConstructor || !method.IsStatic) &&
                                predictMethod(method)))
                {
                    var preparedFunction = preparedFunctions.Functions[method];

                    var functionPrototype = Utilities.GetFunctionPrototypeString(
                        GetFunctionNameByFunctionType(preparedFunction),
                        preparedFunction.ReturnType,
                        preparedFunction.Parameters,
                        extractContext);

                    tw.WriteLine(
                        "extern {0}{1};",
                        method.IsVirtual ? "/* virtual */ " : string.Empty,
                        functionPrototype);
                }

                var virtualMethods = type
                                     .EnumerateOrderedOverridedMethods()
                                     .Where(predictMethod)
                                     .ToArray();
                foreach (var method in virtualMethods)
                {
                    var fullMethodName = type
                                         .GetFullMemberName(method, MethodNameTypes.Index)
                                         .ManglingSymbolName();
                    var functionParametersDeclaration = string.Join(
                        ", ",
                        method.GetSafeParameters()
                        .Select((parameter, index) => (index == 0)
                                ? string.Format(
                                    "/* {0} */ {1}",
                                    extractContext.GetCLanguageTypeName(type),
                                    parameter.Name)
                                : string.Format(
                                    "/* {0} */ {1}",
                                    extractContext.GetCLanguageTypeName(parameter.ParameterType),
                                    parameter.Name)));
                    tw.WriteLine(
                        "#define {0}({1}) \\",
                        fullMethodName,
                        functionParametersDeclaration);

                    var methodName = method
                                     .GetOverloadedMethodName()
                                     .ManglingSymbolName();
                    var functionParameters = string.Join(
                        ", ",
                        method.GetSafeParameters()
                        .Select(parameter => parameter.Name));

                    tw.WriteLine(
                        "{0}((this__)->vptr0__->{1}({2}))",
                        indent,
                        methodName,
                        functionParameters);
                }
            }

            tw.WriteLine();
            tw.WriteLine("#ifdef __cplusplus");
            tw.WriteLine("}");
            tw.WriteLine("#endif");
        }
Exemple #3
0
        public static void WriteSourceCode(
            TextWriter twSource,
            TranslateContext translateContext,
            PreparedFunctions preparedFunctions,
            string indent,
            DebugInformationOptions debugInformationOption = DebugInformationOptions.Full)
        {
            IExtractContext extractContext = translateContext;

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

            var assemblyName = extractContext.Assembly.Name.Name;

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

            twSource.WriteLine();
            twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
            twSource.WriteLine("// Const strings:");
            twSource.WriteLine();

            foreach (var kv in extractContext.ExtractConstStrings())
            {
                var escaped = Utilities.GetEscapedCString(kv.Value);
                twSource.WriteLine(
                    "IL2C_CONST_STRING({0}, L\"{1}\");",
                    kv.Key,
                    escaped);
            }

            var allTypes = extractContext.Assembly.Modules
                           .SelectMany(module => module.Types)
                           .SelectMany(type => new[] { type }.Concat(type.NestedTypes))
                           .Where(type => type.IsValidDefinition())
                           .ToArray();

            // All types exclude publics and internals (for file scope prototypes)
            var types = allTypes
                        .Where(type => !(type.IsPublic || type.IsNestedPublic || type.IsNestedFamily || type.IsNestedFamilyOrAssembly))
                        .ToArray();

            InternalConvertToPrototypes(
                twSource,
                types,
                extractContext,
                preparedFunctions,
                method => !(method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly),
                indent);

            twSource.WriteLine();
            twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
            twSource.WriteLine("// Static fields:");

            foreach (var type in allTypes.Where(type => !type.IsEnum))
            {
                twSource.WriteLine();

                // All static fields
                foreach (var field in type.Fields
                         .Where(field => field.IsStatic))
                {
                    twSource.WriteLine(
                        "{0};",
                        Utilities.GetStaticFieldPrototypeString(field, true, extractContext));
                }
            }

            twSource.WriteLine();
            twSource.WriteLine("//////////////////////////////////////////////////////////////////////////////////");
            twSource.WriteLine("// Methods:");

            foreach (var type in allTypes.Where(type => !type.IsEnum))
            {
                twSource.WriteLine();
                twSource.WriteLine("////////////////////////////////////////////////////////////");
                twSource.WriteLine("// Type: {0}", type.GetFullMemberName());

                // All methods and constructor exclude type initializer
                foreach (var method in type.Methods
                         .Where(method => !method.IsConstructor || !method.IsStatic))
                {
                    InternalConvertFromMethod(
                        twSource,
                        extractContext,
                        preparedFunctions,
                        method,
                        indent,
                        debugInformationOption);
                }

                if (type.IsClass || type.IsValueType)
                {
                    InternalConvertTypeHelper(
                        twSource,
                        extractContext,
                        type,
                        indent);
                }
                else if (type.IsInterface)
                {
                    InternalConvertTypeHelperForInterface(
                        twSource,
                        type,
                        indent);
                }
            }
        }
Exemple #4
0
        internal static void InternalConvertFromMethod(
            TextWriter tw,
            IExtractContext extractContext,
            PreparedFunctions preparedFunctions,
            MethodDefinition method,
            string indent,
            DebugInformationOptions debugInformationOption = DebugInformationOptions.None)
        {
            var methodName       = method.GetFullMemberName();
            var preparedFunction = preparedFunctions.Functions[method];

            // Write method body
            switch (preparedFunction.FunctionType)
            {
            case FunctionTypes.Standard:
                Debug.Assert(preparedFunction.PreparedILBodies != null);

                InternalConvertFromFunction(
                    tw,
                    extractContext,
                    preparedFunction,
                    indent,
                    debugInformationOption);
                break;

            case FunctionTypes.Virtual:
                if (preparedFunction.PreparedILBodies != null)
                {
                    InternalConvertFromFunction(
                        tw,
                        extractContext,
                        preparedFunction,
                        indent,
                        debugInformationOption);
                }
                else
                {
                    InternalConvertFromAbstractFunction(
                        tw,
                        extractContext,
                        preparedFunction,
                        indent);
                }
                break;

            case FunctionTypes.InterfaceVirtual:
                // Nothing to do
                break;

            case FunctionTypes.PInvoke:
                var pinvokeInfo = method.PInvokeInfo;
                if (pinvokeInfo == null)
                {
                    throw new InvalidProgramSequenceException(
                              "Missing DllImport attribute at P/Invoke entry: Method={0}",
                              methodName);
                }

                InternalConvertFromPInvokeFunction(
                    tw,
                    extractContext,
                    preparedFunction,
                    pinvokeInfo,
                    indent);
                break;
            }
        }