5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

GHC Source Pluginによるシンボルの削除

Last updated at Posted at 2021-12-09

目的

Haskellのパッケージに含まれるあるシンボルをパッケージに外に見せたくない場合に、
逆に見せたいシンボルを列挙して対応していませんか?

今回紹介する方法はGHC Source Pluginを使ってシンボルをパッケージ外に出さない方法を紹介します。

動機の確認

シンボルをパッケージ外に出さない方法を紹介する前になぜそのようなことをやりたいのか確認しておきます。

C++の関数をHaskellで呼び出せるようにinline-c-cppでラッパを作りたい場合に基本的には外に見えるようにしたいが
inline_c_ffi_適当な番号というinline-c-cppの内部関数が生成されました。

inline-c-cppのtemplate haskellに渡すデータは次のようなファイルなのですが、

module モジュール名 where

関数1
関数2
関数3

template haskellによって次のような関数が生成されていました。

module モジュール名 where

関数1
inline_c_ffi_23232
関数2
inline_c_ffi_23233
関数3
inline_c_ffi_23234

生成する関数は数千に及んだため複数のファイルでinline_c_ffi_適当な番号の番号が衝突する問題が発生し、
すべて外に見えるようにするわけにはいかなくなりました。

下記のように列挙してもいいですが、コードも読みにくくなるので、GHC Source Pluginで隠すことにしました。

module モジュール名(
 関数1
 関数2
 関数3
) where

関数1
関数2
関数3

やり方

今回修正するのはdesugarというCore言語にする前のtypeCheckResultActionというモジュールからエクスポートする関数を削除する方法で考えました。

typeCheckResultActionTcGblEnvというトップレベルのモジュールを返す関数になっています。
そこからエクスポートしたくない関数を除外すれば完了です。

image.png

次のようなコードになります。

{-# LANGUAGE CPP #-}

module GHC.NotExport.Plugin (plugin) where

#if MIN_VERSION_ghc(9,0,0)
import GHC.Driver.Plugins
import GHC.Types.Avail
import GHC.Types.Name
import GHC.Tc.Types
import GHC.Utils.Outputable
#else
import GhcPlugins
import Plugins
import TcRnTypes
import Avail
#endif

import Data.List (isPrefixOf)

plugin :: Plugin
plugin =
  defaultPlugin
    { typeCheckResultAction = notExportPlugins,
      pluginRecompile = purePlugin
    }

notExportPlugins cmdOptions modSummary env = do
  let updated_tcg_exports = filter (\v -> not (isPrefixOf "inline_c_ffi" ((showSDocUnsafe . ppr . nameOccName . availName) v))) $ tcg_exports env
  return env {tcg_exports = updated_tcg_exports}

このあとghc-optionsで上記のモジュールを渡せばinline_c_ffiで始まる関数がエクスポートされなくなります。

 ghc-options:         -fplugin GHC.NotExport.Plugin

まとめ

GHC Source Pluginを使って特定のパターンの関数をエクスポートしないようにするプラグインを作りました。hasktorchというlibtorchをラップしているライブラリで実際に使用中です。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?