haskell - 使用 GHC API 将 Haskell 源代码编译为 CORE 和 CORE 为二进制

标签 haskell compilation ghc ghc-api

理念

你好!我想创建一个程序,它将生成 Haskell Core 并使用 GHC API 将其进一步编译成可执行文件。但在我开始之前,我想构建一个非常基本的示例,展示我们如何将 Haskell 源代码编译成 CORE,然后编译成二进制文件。

问题

我已经阅读了很多文档并尝试了 GHC Api 的许多方法,但现在没有成功。我从 Official GHC Api introduction 开始并成功编译了示例。示例显示了以下函数的用法:parseModule , typecheckModule , desugarModule , getNamesInScopegetModuleGraph但不包括最后的编译步骤。另一方面,api中有一些函数,其名称看起来与问题有关,如HscMain.{hscCompileOneShot, hscCompileBatch}GHC.{compileToCoreModule, compileCoreToObj} .我尝试使用它们,但出现运行时错误,如下例所示:

import GHC
import GHC.Paths ( libdir )
import DynFlags
targetFile = "Test.hs"

main :: IO ()
main = do
   res <- example
   return ()

example = 
    defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
      runGhc (Just libdir) $ do
        dflags <- getSessionDynFlags
        let dflags' = foldl xopt_set dflags
                            [Opt_Cpp, Opt_ImplicitPrelude, Opt_MagicHash]
        setSessionDynFlags dflags'
        coreMod <- compileToCoreModule targetFile
        compileCoreToObj False coreMod "foo" "bar"
        return () 

可以用 ghc -package ghc Main.hs 编译并在运行时导致以下错误:
Main: panic! (the 'impossible' happened)
  (GHC version 7.8.3 for x86_64-unknown-linux):
    expectJust mkStubPaths

这当然可能是错误 API 使用的结果,特别是因为行 compileCoreToObj False coreMod "foo" "bar" ,其中字符串只是随机字符串,因为文档没有太多关于它们的说明。如果我们查看来源,似乎第一个是输出名称,第二个是“extCore_filename”,无论它可能是什么。

另一个令人担忧的事情是 compileCoreToObj 旁边的文档中的注释。功能:

[...] This has only so far been tested with a single self-contained module.



但我希望它不会带来任何进一步的问题。

问题

创建此解决方案的最佳方法是什么?我们如何创建一个最小的工作示例,它将加载 haskell 源,将它们编译到 CORE 中,然后将核心编译为最终的可执行文件(使用 GHC API)。需要中间步骤来进一步替换自定义 CORE。

作为一个附带问题 - 目前是否可以为 GHC 提供外部核心文件,或者此功能尚未实现,我将不得不使用 GHC.Api 手动构建核心(相关:Compiling to GHC Core)

更新

我终于能够创建一个小示例,允许加载模块并将其编译为 .hi.o文件。这不是问题的解决方案,因为它不允许我替换 CORE 并且它还没有将目标文件链接到可执行文件中:
import GHC
import GHC.Paths ( libdir )
import DynFlags
import Linker
import Module
targetFile = "Test.hs"

main :: IO ()
main = do
   res <- example
   return ()

example = 
    defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
      runGhc (Just libdir) $ do
        dflags <- getSessionDynFlags
        let dflags2 = dflags { ghcLink   = LinkBinary
                             , hscTarget = HscAsm
                             }
        let dflags' = foldl xopt_set dflags2
                            [Opt_Cpp, Opt_ImplicitPrelude, Opt_MagicHash]
        setSessionDynFlags dflags'
        setTargets =<< sequence [guessTarget "Test.hs" Nothing]

        load LoadAllTargets
        return ()

最佳答案

在这里生成核心的文本表示不是问题,因为它可以通过多种方式进行。您可以使用 -fext-core生成标志.hcr文件并使用例如extcore .还有其他可以转储核心的软件包,例如 ghc-coreghc-core-html .

这里的主要问题是将 ghc-core 加载到 ghc 中。 .据我所知,它受到支持,但现在不支持,因为人们对使用它的兴趣不大,而且随着时间的推移它变得过时了。

我们可以在这里尝试的最好的事情是深入挖掘 ghc内部,找到使用 ghc-core 的地方并尝试在那里修改它。也许我们也可以尝试创建一个 ghc plugin并用它修改核心。

关于haskell - 使用 GHC API 将 Haskell 源代码编译为 CORE 和 CORE 为二进制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28059669/

相关文章:

image - Juicy Pixels 提示内存不足

scala - 函数式编程是否可以减少冯·诺依曼瓶颈?

algorithm - 查询球体表面近点的快速算法/数据结构是什么?

c - 从引导扇区到 C++ 内核

Java 编译错误 : class Appletprac is public, 应在名为 Appletprac.java 的文件中声明

haskell - 在 GHC.Prim 中,为什么指针操作会因未经检查的异常而失败?

haskell - “ExceptT ResourceT”与 'ResourceT ExceptT'

Haskell 存在量化详解

algorithm - 算法复杂度计算估计的基本操作的性能特征

haskell - 在需要 LANGUAGE CPP 的模块上运行 ghci