インライン定義

特殊な機構ですが、インライン定義というのがあります。形式は単純で、ワード定義、またはメソッド定義の内容を、"inline{"と"}"で囲うだけです。"inline{"の方はワードですので、次のワードとの間に空白が必要ですが、後の"}"は区切り文字として使われますので、前のワードとくっついていても大丈夫です。ただし、iMopsでは仕様が変わって、最後のカッコも空白で切り離さないとエラーになります。
: MyWord ( -- ) inline{ [コード] } ;
とか、
:m MyMethod: ( -- ) inline{ [コード] } ;m
という感じです。

形式的制限として、まず第1に、ワードやメソッドの定義が丸ごとinlineになっていなければなりません。コンパイル用のインライン部分と実行用の部分が二つ書かれているコードも、ソースコードの中にはあります。同じことをインラインとその外と二度書いているものです。しかし、現在のPowerMopsでは、インライン定義の形でも直ちに実行できるので、必要ありません。多分、過去のいつかの時点では、二重にする理由があったのでしょう。現時点で二重に定義されていても害はないようです。

第2に、コードは一行で書き切る必要があります。改行が入るとエラーになります。

第3に、ワードないしメソッド名の直後(コメントは別)に"inline{"が来なければなりません。これはつまり、インライン定義では、局所変数やテンポラリオブジェクトは使えないということを意味します。

さて、以上が形式的制限ですが、インライン定義というのは、一体どんな意味があるのかを説明します。

端的には、インライン定義されたワードやメソッドの呼び出すワード等がコンパイルされるときには、実際には呼び出しがコンパイルされるのではなく、その部分に定義内容をなすコードが展開されるということです。つまり、インライン定義されたワードにその都度処理を渡すのではなくて、呼び出し側に内容を詰め込んでしまうのです。

実際のコードの実行においては、関数(サブルーチン)の呼び出しには、普通いくらか余分な手間がかかります(いわゆる呼び出しのオーバーヘッド)。インライン定義の狙いは、その手間を省いて処理を高速化することです。

しかし、呼び出された先毎にコード内容が展開されるのですから、コードサイズは全体として普通に呼び出すより大きくなります。この点と、上のような高速化の目的とから、次のような実質的なインライン定義利用のガイドラインが出てきます。

インラインにされるコードはごく短いものであること
内容は変数の操作や演算やビット処理のような原始的な作業を行うものであり、システムコールなどの外部呼び出しにつながる部分は含まないこと
頻繁に繰り返し呼び出される可能性が高いものであること
具体例としては、基本変数オブジェクトの値の出し入れによく使われています。

現在のPowerMopsのワード(サブルーチン)呼び出しの超過負担(オーバーヘッド)は非常に小さく抑えられているので、インライン定義を頻繁に用いる価値はあまりないのではないかと思います。

なお、iMopsでインライン定義を書くとき、内部に数値リテラル(数字のこと)を用いたい場合には、数字の頭に、10進法表示なら#、16進法なら$、のマークを付加しなければなりません。数字との間には空白は無いようにします。例えば、
: ... inline{ ... #123 ... $ABC ... } ;
などのような感じです。

関連項目:






最終更新:2019年05月31日 16:38