Пример #1
0
        private BIR.BIR ProduceBIR(Configuration config)
        {
            BIR.BIR bir = null;
            using (var section = CreateSection("Producing BIR"))
            {
                // Assemble the producers
                var producers = new List <IBIRProducer>();
                producers.Add(new Clang(Context));

                // Run the producers
                foreach (var producer in producers)
                {
                    if ((bir = producer.Produce(config)) != null)
                    {
                        break;
                    }
                }
                if (bir == null)
                {
                    return(null);
                }

                // Let the producers visit the final BIR
                foreach (var producer in producers)
                {
                    producer.Visit(config, bir);
                }

                section.Done();
            }
            return(bir);
        }
Пример #2
0
        /// <summary>
        /// Transform the Clang AST to BIR
        /// </summary>
        private BIR.BIR TransformClangASTtoBIR(Configuration config, CXIndex index, TranslationUnit tu)
        {
            BIR.BIR bir = null;
            using (var section = CreateSection("Transforming Clang AST to BIR"))
            {
                using (var parser = new ClangParser(Context, index, tu))
                {
                    bir = parser.ProduceBIR(config);
                }

                if (bir != null)
                {
                    section.Done();
                }
            }
            return(bir);
        }
Пример #3
0
        private bool ConsumeBIR(Configuration config, BIR.BIR bir)
        {
            bool success = true;

            using (var section = CreateSection("Consuming BIR"))
            {
                // Assemble the consumers
                var consumers = new List <IBIRConsumer>();
                consumers.Add(new BifrostPlugin(Context));

                // Let the producers visit the final BIR
                foreach (var consumer in consumers)
                {
                    success &= consumer.Consume(config, bir);
                }

                section.Done();
            }
            return(success);
        }
Пример #4
0
        /// <inheritDoc />
        public bool Consume(Configuration config, BIR.BIR bir)
        {
            using (var section = CreateSection("Generating Bifrost C++ plugin"))
            {
                var pluginH   = GetPluginH();
                var pluginCpp = GetPluginCpp();

                // Create the macros
                var macros = CreateMacros(config, bir);

                // Expand the includes
                pluginH = ExpandIncludes(pluginH);

                // Expand selected macros
                pluginH   = ExpandMacros(pluginH, macros);
                pluginCpp = ExpandMacros(pluginCpp, macros);

                // Write plugin to disk and format it
                WriteOutputs(config, pluginH, pluginCpp, macros);
                section.Done();
            }
            return(true);
        }
Пример #5
0
 /// <inheritDoc />
 public void Visit(Configuration config, BIR.BIR bir)
 {
 }
Пример #6
0
        /// <summary>
        /// Create the necessary macros
        /// </summary>
        private Dictionary <string, string> CreateMacros(Configuration config, BIR.BIR bir)
        {
            var pluginName      = IO.MakeValidIdentifier(config.Plugin.Name);
            var pluginNamespace = IO.MakeValidIdentifier(string.IsNullOrEmpty(config.Plugin.Namespace) ? pluginName.ToLower() : config.Plugin.Namespace);
            var pluginCppFile   = $"{pluginName}.cpp";
            var pluginHFile     = $"{pluginName}.h";

            var pluginIdentifier               = new List <string>();
            var pluginStringToIdentifier       = new List <string>();
            var pluginIdentifierToFunctionName = new List <string>();
            var pluginIdentifierToModule       = new List <string>();

            var includes = new HashSet <string>();

            var module             = new List <string>();
            var moduleToString     = new List <string>();
            var hookModuleToModule = new Dictionary <string, string>();

            var dslDefines = new List <(string, string)>();

            foreach (var hook in bir.Hooks)
            {
                // Identifiers
                pluginIdentifier.Add($"{hook.Identifier}");
                pluginStringToIdentifier.Add($"{{\"{hook.Identifier}\", Plugin::Identifier::{hook.Identifier}}}");

                switch (hook.HookType)
                {
                case BIR.BIR.HookTypeEnum.CFunction:
                    pluginIdentifierToFunctionName.Add($"\"{hook.CFunctionName}\"");
                    break;

                case BIR.BIR.HookTypeEnum.MethodFunction:
                    pluginIdentifierToFunctionName.Add($"\"\"");
                    break;

                case BIR.BIR.HookTypeEnum.VTable:
                    pluginIdentifierToFunctionName.Add($"\"\"");
                    break;
                }

                // Includes
                foreach (var include in hook.Inputs)
                {
                    includes.Add($"#include <{include}>");
                }

                // Modules
                var moduleIdentifier = "";
                if (hookModuleToModule.ContainsKey(hook.Module))
                {
                    moduleIdentifier = hookModuleToModule[hook.Module];
                }
                else
                {
                    moduleIdentifier = IO.MakeValidIdentifier(hook.Module);
                    hookModuleToModule.Add(hook.Module, moduleIdentifier);

                    module.Add(moduleIdentifier);
                    moduleToString.Add(hook.Module);
                }
                pluginIdentifierToModule.Add($"Module::{moduleIdentifier}");

                // DSL
                var postfix = $"{pluginNamespace}__{hook.Identifier}";
                dslDefines.Add((null, $"\n// {hook.Identifier}"));
                dslDefines.Add(($"_bf_func_decl_ret_{postfix}", hook.ReturnType));
                dslDefines.Add(($"_bf_func_decl_args_{postfix}", string.Join(", ", hook.Parameters.Select(p => p.Type + " " + p.Name))));

                dslDefines.Add(($"_bf_func_{postfix}", $"(({hook.ReturnType} (*)(" + string.Join(", ", hook.Parameters.Select(p => p.Type)) +
                                $"))::{pluginNamespace}::Plugin::Get().GetHook<::{pluginNamespace}::Plugin::Identifier::{hook.Identifier}>()->GetOriginal())"));
                dslDefines.Add(($"_bf_args_{postfix}", string.Join(", ", hook.Parameters.Select(p => p.Name))));

                for (int i = 0; i < hook.Parameters.Count; ++i)
                {
                    dslDefines.Add(($"_bf_arg_{i + 1}_{postfix}", hook.Parameters[i].Name));
                }
            }

            var dslDef = string.Join("\n", dslDefines.Select(s => s.Item1 == null ? s.Item2 : $"#define {s.Item1} {s.Item2}"));

            return(new Dictionary <string, string>()
            {
                ["BIFROST_PLUGIN_H_FILE"] = pluginHFile,
                ["BIFROST_PLUGIN_CPP_FILE"] = pluginCppFile,
                ["BIFROST_PLUGIN_NAME"] = pluginName,
                ["BIFROST_PLUGIN_BASE"] = $"::{pluginNamespace}::Plugin",
                ["BIFROST_PLUGIN_INCLUDE"] = $"#include \"{pluginHFile}\"",

                ["BIFROST_NAMESPACE"] = pluginNamespace,
                ["BIFROST_PLUGIN_IDENTIFIER"] = string.Join(",", pluginIdentifier) + ",",
                ["BIFROST_PLUGIN_IDENTIFIER_TO_STRING"] = "\"" + string.Join("\",\"", pluginIdentifier) + "\",",
                ["BIFROST_PLUGIN_STRING_TO_IDENTIFIER"] = string.Join(",", pluginStringToIdentifier),
                ["BIFROST_PLUGIN_IDENTIFIER_TO_FUNCTION_NAME"] = string.Join(",", pluginIdentifierToFunctionName) + ",",

                ["BIFROST_PLUGIN_MODULE"] = string.Join(",", module) + ",",
                ["BIFROST_PLUGIN_MODULE_TO_STRING"] = "L\"" + string.Join("\",L\"", moduleToString) + "\",",
                ["BIFROST_PLUGIN_IDENTIFIER_TO_MODULE"] = string.Join(",", pluginIdentifierToModule) + ",",

                ["BIFROST_PLUGIN_DSL_DEF"] = dslDef,

                ["BIFROST_PLUGIN_INCLUDES"] = string.Join("\n", includes)
            });
        }