日本ソフトウェア科学会第 30 回大会 (2013 年度) 講演論文集

COINS による例外処理機構を持つ言語処理系開発支援
産一 傑

川端 英之

北村 俊明

COINS はコンパイラインフラストラクチャとして様々な言語処理系の開発や最適化アルゴリズムの研究などに広く活用されている．しかしながら，COINS には例外処理機構を持つ言語の処理系のための機構が備えられていない．
例外処理機構は，例外的事象への対処の記述を容易にし，より見通しの良いコーディングを可能にする．本研究では，
COINS に対して例外処理に対応する機能を導入した．具体的には，COINS の持つ高水準中間表現 HIR よりも上位に，try-catch 文，throw 文等の例外処理構文を表現できる高水準中間表現 EHIR を導入し，さらに EHIR から
HIR への中間表現のトランスレータ EHIR-to-HIR を実装した．例外処理機構は，sigsetjmp() ，siglongjmp()を用いた Stack Cutting により実現している．また，シグナル処理を例外処理に統合して扱えるようにした．これ
によってユーザは，EHIR を生成するフロントエンドを用意すれば標準的な例外処理構文を用いた言語処理系を開発できるようになる．

イラを開発することができる．

1 はじめにCOINS を用いることにより，様々な言語に対す

COINS (COmpiler INfraStructure) [1] は，言語処る処理系を開発することができる．しかしながら，理系の開発や最適化アルゴリズムの研究などに広く利COINS には例外処理構文を直接的に扱うために必要用されているコンパイラインフラストラクチャである．

となる機能が備わっていない．例えば，HIR 及び LIR

COINS には，高水準中間表現 HIR (High-level In-の中間表現には例外処理構文を表すものがない．また，

termediate Representation) と低水準中間表現 LIR

例外処理のための変換器，コード生成器も COINS に(Low-level Intermediate Representation) の 2 つのは実装されていない．そのため，例外処理構文を持つ

中間表現があり，それぞれの中間表現に対する変換や言語のためのコンパイラの開発に COINS を用いる

最適化，並列化をするモジュールが備えられている．

ことは必ずしも容易とは言えない．

COINS は，これらの中間表現とモジュールによって

ここで，例外処理の記述及び実行時の制御の流れ

コンパイラを構成する機能を提供している．言語処理について例を用いて説明する．例外処理機構を持つ系開発者は，COINS の持つ中間表現に変換するフロ

様々なプログラミング言語の例外処理構文には，投げントエンドを設計し，必要なモジュールを呼び出すドられた例外を捕捉し例外に対する処理を記述するた

ライバを構築することで，新しい言語のためのコンパ

めの構文や，例外をプログラマが明示的に投げるたSuguru Sanichi, 広島市立大学大学院情報科学研究科,
Graduate School of Information Sciences, Hiroshima
City University.
Hideyuki Kawabata, 広島市立大学大学院情報科学研
究科, Graduate School of Information Sciences, Hiroshima City University.
Toshiaki Kitamura, 広島市立大学大学院情報科学研究科,
Graduate School of Information Sciences, Hiroshima
City University.

めの構文がある．例えば，Java では図 1 のような例
外処理記述ができる． 図 1 のプログラムは，int 型の一次元配列 n[] に対してメソッド f を再帰的に呼び出して一次元配列 n[] の個々の要素の積を求める．
図 1 のプログラムを実行すると，計算の進行に従い

n[i] が 0 でない間，メソッド f に対応するフレーム
かコールスタックに積まれる．そして，n[i] が 0 の

文，throw 文等の例外処理構文を表現できる高水準中!""#$%&''"'&()%*"+,""#"""'-&-.$"./-"01./-23"/4"./-".5"-6789'":;<=$*)-.8/"+>""#""""""".01/2.3??@5"+
A""#"""""""""""""-6789"/*9":;<=$*)-.8/15B
C""#"""""""D"*%'*".01.??@5+
E""#"""""""""""""7*-F7/"/2@3B
G""#"""""""D"*%'*"+
H""#"""""""""""""7*-F7/"/2@3"?"/2.3"I"01/4".J!5B
K""#"""""""D!@#"""D!!#")FL%.$"'-&-.$"M8.N"(&./"1O-7./P23"&7P'5"+!,#"""""""./-23"/"?"+K4@4G4E4C4A4>4,4!DB!>#"""""""./-"7*'F%-"?"@"B!A#"""""""-7;"+"!C#"""""""""""7*'F%-"?"01/4"/Q%*/P-6J!5B!E#"""""""D$&-$6"1<=$*)-.8/"*5"+!G#"""""""""""""""O;'-*(Q8F-Q)7./-%/1R"7*'F%-"#"@"R5B!H#"""""""D!K#"""D,@#D

間表現 EHIR を導入する．さらに EHIR から HIR
へ中間表現を変換するトランスレータ EHIR-to-HIRを導入する．EHIR-to-HIR を設計するにあたっては，

EHIR で表現された例外処理記述を既存の HIR へ変換する必要がある．そこで，例外処理を実現するアルゴリズムを HIR へ盛り込む形で変換する方法をとる．
すなわち，COINS において HIR より下流には手を加えずに例外処理への対応を組み込む方式とする．

COINS の例外処理構文を扱うための機能は，例外処理構文を持つ Java のフロントエンドの実装 [1] において検討されたが，COINS への実装には至っていない．本研究で導入されるモジュールを用いれば，例
外処理構文を EHIR を用いることで直接表現でき，

EHIR で表現された例外処理記述を HIR へ変換することができる．そしてユーザは，EHIR を生成する

図1

Java による例外処理記述の例

フロントエンドと EHIR-to-HIR ，COINS が提供するモジュールを呼び出すドライバを構築するだけで，時，例外 MyException が投げられる．この例外は，標準的な例外処理構文を持った言語のためのコンパイ

main で定義されている try-catch 文の catch 節，すラを開発できるようになる．

なわち 17 行目によってハンドルされる．この例のよ

本稿では以下，第 2 章では，具体的な例外処理構

うに，例外処理においては，コールスタックを必要に文と例外処理の実現方法について述べる．次に，第 3応じて遡って，投げられた例外に対応する例外ハンド

章では，COINS 及び EHIR ，EHIR-to-HIR についラを探し，大域ジャンプにより制御をそこに移すといて述べ，第 4 章で EHIR ，EHIR-to-HIR を導入しう実行時制御が必要となる．これらは，ソースコー

た COINS を使用した例と既存ソフトウェアを使用

ド上でユーザが ( try-catch 文等を用いずに) 記述すしたものとの比較について述べる．最後に，第 6 章

ることは不可能ではないが，例外処理構文があれば，で EHIR と EHIR-to-HIR の課題と本稿のまとめを

複数の例外に対する例外処理をまとめて記述できる述べる．

ため，見通しの良いコーディングが可能となる．さらに，例外処理構文によって例外処理が容易に記述でき

2 例外処理構文と例外処理の実現方法

るため，堅牢なプログラムの設計を行い易い．

本章では，例外処理機構を持つ様々なプログラミン

しかしながら，現在の COINS を用いて例外処理

グ言語における例外処理構文と例外処理の実現方法

構文を持つ言語処理系を開発しようとすれば，中間表について述べる．そして，例外処理の実現方法の特徴

現の追加，中間表現を用いるモジュールに対する機能

から COINS への例外処理を扱う機能の導入方法を追加等の大幅な修正をしなければならない．これら

検討する．

は，COINS を用いて言語処理系を開発するユーザにとっては，大きな負担となる．

2. 1 例外とその処理本研究では，COINS に対して例外処理構文を直接例外とは，プログラムの実行中に発生する例外的事的に扱うための機能を導入する．具体的には，COINS

象を指す．例外には，実行時に発生し，コンパイラにの持つ高水準中間表現 HIR よりも上位に，try-catch

よって予め例外の発生を静的に把握できない例外（実行時例外と呼ぶ）と，プログラマが明示的に例外を発タックに積まれたスタックフレームを超えて大域脱出生させるユーザ定義例外がある．

をする．複数の try-catch 節を扱う場合は，setjmp()

プログラム実行中に生じる例外的事象への対処には，UNIX でプロセス間における非同期イベントのによって保存した実行コンテキストをスタックを用いて管理することになる．

授受に用いられるシグナル処理も挙げられる．プロセ

setjmp 法による例外処理の実現方式は，C 言語のスにシグナルが送られると，予め用意したシグナルハ

標準ライブラリ関数である setjmp() ，longjmp()

ンドラに制御が移され処理される．シグナルハンドラを用いるため可搬性が高い．しかし，setjmp() によを用いて、シグナルをユーザ定義例外にマッピングする実行コンテキストの保存処理を，try 節に制御が移ることにより，シグナル処理を例外処理として記述する度に行う必要があるため，正常時，すなわち例外

ることもできる．例えば，C 言語に例外処理機構を実が発生せずに過ぎる場合における実行速度に与える現するためのマクロライブラリ Exceptions4c [2] は，

オーバヘッドがかかる．

この方法でシグナル処理を例外処理に統合している．

2. 2. 2 Stack Unwinding
Stack Unwinding は，コールスタック中のスタッ

2. 2 例外処理の実現方法

クフレームを例外ハンドラが定義されている環境に達

例外処理に対応した高水準言語では，Java におけするまで 1 つずつ遡る方式である．Stack Unwinding

る try-catch 文に類似の構文により，例外処理制御を用いた具体的な例外処理の実現方法を以下に 2 つが記述されることが多い．try-catch 文のように例外

述べる．

処理を実現するには，例外発生時の処理の中断、及Native-code Stack Unwinding 適 切 な 例 外び、適切なハンドラ（ catch 節）への制御の転送がハンドラが定義されている環境までスタック必要となる。代表的な例外処理制御の実現方法としフレームを遡る処理を，特殊な手立てを用いずて，Stack Unwinding と Stack Cutting が挙げられに関数呼び出しからのリターンの連続によってる．以下，それぞれについて述べる．

行う方法である．この場合は，手続きの呼び出し

2. 2. 1 Stack Cutting

先（ callee ）において例外が発生したか否かをStack Cutting とは，適切な例外ハンドラが定義さ手続きの呼び出し元（ caller ）へ伝える手立てれている環境に対応するフレームまでまとめてコールが必要となる．単純には，例外発生の有無を示

スタックに積まれたフレームを除去する方式である．

すためのフラグを，参照渡しによって caller とこの方式では，スタックポインタやプログラムカウン

callee で共有すればよい．caller では，例外に対タ等の実行コンテキストを適当なタイミングで保存するフラグを調べることで例外が発生したかどしておき，例外発生時には、保存しておいた実行コン

うか判断できる．Native-code Stack Unwinding

テキストを復元することで，例外ハンドラへの非局

は，参考文献 [6] において 2 返戻値法と呼ばれて所ジャンプを実現する．Stack Cutting の実現方法といる．

しては，具体的には，C 言語の標準ライブラリ関数

2 返戻値法は，手続き間の例外の受け渡しのである，setjmp() ，longjmp() を用いた setjmp 法

ための引数の追加と例外に対する分岐制御だけ[6] が挙げられる．

で実現できる．そのため 2 返戻値法は，特殊なラ

setjmp 法では，try 節の処理を行う前に setjmp()

イブラリ等を用いることなく実現でき，可搬性がで例外が発生する以前の状態のコンテキストバッファ

高い．しかし，全ての手続き呼び出し箇所に例外をカーネルメモリ上のスタックなどに保存しておく．

発生の有無を検査するコードを挿入する必要がプログラマが明示的に例外を投げる際は，setjmp() がある．その結果として，手続きが正常に実行され保存したコンテキストバッファを用いて、longjmp()

た際にも例外発生の検査が行われ実行速度に与呼び出しにより、例外発生以前の状態までコールス

えるオーバヘッドが大きくかかる．

Runtime Stack Unwinding こ の 方 法 で は ，き間の例外の受け渡しのための引数の追加と例外発プログラムが例外を発生させた時，Stack Un-

生の有無を検査するコードを挿入するだけで実現でwinding を行うランタイムライブラリへの呼びきるため，setjmp 法と同様に HIR での変換で容易出しを行う．ランタイムライブラリは，例外が発に実現できると考えられる．しかし，全ての手続き呼生した時点のアドレスに基づき同一の実行環境

び出し箇所に例外発生の有無を検査するコードを挿（スタックフレーム）において適切なハンドラを入するので，例外の有無に関わらず実行速度に与える

探し，もしあれば実行する．適切なハンドラが見オーバヘッドは大きくかかる．また、実行時例外の一

つからなければ，呼び出し元の手続きのさらに部についてはこの方法では、対処が難しい。例えば、

呼び出し元に遡って適切なハンドラを探す．この0 除算など、Java における unchecked な例外の扱い

方法に近い実現方法として表引き法 [6] が挙げら

は、大域脱出なしでは実現が容易ではない（シグナルれる．

ハンドラとの例外情報の授受を大域変数で行うには、表引き法は，例外が発生した時点でのアドレスに対応する例外ハンドラを，表の検索により得

多重割り込み時に備えた値参照の競合の排除が必要となる）。

て，ジャンプする方法である．参照する表はコン

setjmp 法の実行速度に与えるオーバヘッドは，Java

パイル時に生成される．この表には，各手続きをにおいては 2 返戻値法より僅かに大きくかかること呼び出す時のアドレス，対応する例外ハンドラがが知られている [5]．しかし，C 言語の標準ライブラ

記述されているアドレスなどが収められる．

リ関数で実現できるので，可搬性が高い。そして、表引き法では，setjmp 法や 2 返戻値法と異な

setjmp()、longjmp() の呼び出しを挿入するだけでり，関数からのリターン時に例外の有無を判定し実現できるため、2 返戻値法と同様に HIR での変換がたり，実行コンテキストを保存したりする必要が容易にできると考えられる。HIR に例外処理構文の表ない．そのため，正常時の実行速度に影響を与え

現を追加した高水準中間表現 EHIR を設計し，EHIR

るオーバヘッドはかからない．しかし，アーキテ

から HIR へ変換するトランスレータ EHIR-to-HIR

クチャごとに生成される表の記法や例外に関連を COINS へ導入する．EHIR 及び EHIR-to-HIR をする情報が異なるため，可搬性は高いとは言え

COINS へ導入することでユーザは，EHIR を生成すない．

るフロントエンドを生成するだけで例外処理構文を持
つ言語のためのコンパイラを開発することができる．

2. 3 例外処理の実現方法に対する設計方針

EHIR-to-HIR では，EHIR で表現された例外処理構

前節で述べたそれぞれの例外処理の実現方法から文を HIR で setjmp 法による例外処理制御をする記実行速度に与えるオーバヘッドの低さ，実行環境に依述へ変換する．そして，実行コンテキストを管理する

らない可搬性の高さ，短期間で実装できる容易さを考ためのスタック及び longjmp() を行うシグナルハン

慮した COINS への例外処理を扱う機能の導入方法

ドラを HIR の変換時に盛り込めば，容易に実装するを検討する．

ことができると考えられる．

実行速度にかかるオーバヘッドを最も低く抑えら

なお，シグナルハンドラ内からの longjmp() を単れることができる方法は，表引き法である．しかし表純に用いた場合に，リエントラント問題が発生する．

引き法は可搬性がない．そのため，ターゲットとなる

そこで，参考文献 [6] の setjmp 法に対して使用するラアーキテクチャなどによって変換モジュールを用意しイブラリ関数を sigsetjmp() 及び、siglongjmp()

なければならず，COINS のいたるところに改良を施変更する．これにより，シグナルをマスクし非同期さなければならない．

の例外による割り込みを防ぐことができる．よって

2 返戻値法は，分岐制御など標準的な制御で実現でEHIR-to-HIR では，EHIR から HIR へ変換する

きるため可搬性が最も高い方法である．そして，手続際に sigsetjmp() ，siglongjmp() を用いた StackCutting により，例外処理制御を実現する．

例外処理機構を持つ
命令型言語

3 COINS への例外処理の導入
本章では，COINS の構成と COINS に導入する

フロントエンド
命令型言語

EHIR 及び EHIR-to-HIR について述べる．
例外処理機構を持つ高水準中間表現
EHIR

フロントエンド

3. 1 概要
コンパイラインフラストラクチャである COINS(図 2) は，命令型言語を入力として受け，フロントエ

EHIR-to-HIR
高水準中間表現 HIR

ンドによって抽象構文木から HIR を生成する．生成された HIR は，最適化モジュールを用いて適宜最適

高水準中間表現 HIR

HIR 最適化

HIR-to-LIR化したり，変換モジュールを用いて LIR へ変換する

HIR 最適化ことができる．同様に LIR も，最適化モジュールを

HIR-to-LIR

低水準中間表現 LIR

用いて適宜最適化したり，コード生成器を用いて目的

低水準中間表現 LIRとするコードを生成することができる．

EHIR 及び EHIR-to-HIR を導入した COINS (図LIR 最適化

コード生成器LIR 最適化

コード生成器3) は，例外処理制御のための構文を持つ命令型言語
目的コード

を入力を受け，フロントエンドによって抽象構文木か

目的コード

ら HIR でなく EHIR を生成する．生成された EHIR
は，EHIR-to-HIR を用いて HIR 変換される．変換

図2

COINS の構成

図3

EHIR 及びされた HIR は，最適化モジュールを用いて適宜最適

EHIR-to-HIR を導入した

化したり，変換モジュールを用いて LIR へ変換する

COINS の構成

ことができる．同様に LIR も，最適化モジュールを用いて適宜最適化したり，コード生成器を用いて目的< Stmt > ::= < TryStmt > | < ThrowStmt > | ...

とするコードを生成することができる．

< ThrowStmt > ::= ( throw < Exp > )throw 文< IrList > ::= ( list < CatchClause >+ ) | ...

catch 節を収めるリスト

3. 2 EHIR の仕様
例外処理機構を持つプログラミング言語を設計す< TryStmt > ::= ( try < Stmt > < IrList > [ ﬁnally < Stmt > ] ) try-catch 文< CatchClause > ::= ( catch < Exp > < Stmt > )catch 節< ExceptionType > ::= ( exception <ExpListExp> )例外を定義する文図4

EHIR における例外処理制御のための構文

るには，以下のような構文の導入が一般的であると考えられる．

行う try-catch 文 を表現する．TryStmt は，try• 例外処理制御を行うための構文節を表すための Stmt，複数の catch 節を表すた• 例外をプログラマが明示的に投げるための構文

めの IrList，finally 節を表すための Stmt で構• 例外宣言のための構文成される．catch 節を表す CatchClause は，例

そこで，これらを表現できるような図 4 に示す構文外を表す Exp と，例外を捕捉した際に実行され規則を HIR に追加した EHIR を設計する．以下，図る処理を表す Stmt で構成される．CatchClause

4 に示しているそれぞれの構文要素について以下で説は，EHIR を格納する IrList にまとめることで，明する．Stmt，Exp は，それぞれ文と式を意味する．

複数の catch 節を表すことができる．

また，IrList，ExpListExp は，それぞれ EHIR，式

try 節や finally 節は，Stmt を生成し TryStmt

を要素とするリストである．

へ付加する．catch 節は，CatchClause に例外仮TryStmt 図 4 の TryStmt は，例外処理制御を

引数や例外処理を付加し，IrList にまとめてからTryStmt へ付加する．

EHIR-to-HIR は、独立したモジュールとして、ドThrowStmt 図 4 の ThrowStmt は，例外をプ

ライバと共にパッケージ coins.ehir2hir に実装した。

ログラマが明示的に投げる throw 文を表現する．

EHIR-to-HIR の実装にあたっては、HIR 用の既存のThrowStmt は，プログラマが明示的に投げる例

イテレータを用いた走査では実現が困難であったた

外を Exp として表現する．投げる 例外は，Exp

め、EHIR を走査するための新たなイテレータを設で表されるが ExceptionType で表現された例外

計し、用いた。また、いわゆる checked 例外のためを基本的に付加する．

の静的検査器も EHIR-to-HIR へ組み込んだ。

ExceptionType 図 4 の ExceptionType は，例
外宣言文を表現する．Java では，言語が提供す4 本システムの使用例：例外処理付き C 言語

る例外クラスのサブクラスを定義することによ本研究で導入した EHIR 及び EHIR-to-HIR の有り，独自の例外クラスを宣言することができる．

効性を示すために、例外処理構文を持つ C 言語の設親となる例外，宣言する例外が対応するシグナル計を行った。また、C 言語で例外処理を実現するこの指定など予め決められた要素を指定することとができるライブラリである Exceptions4c を用いた

で，例外の宣言を表現する．ExceptionType は，

C 言語と本システムによる例外処理構文を持つ C 言

それぞれの要素を ExpListExp でまとめて表現

語の比較を行う。

する．

4. 1 概要
3. 3 EHIR-to-HIR トランスレータ

COINS には，C 言語用のフロントエンドが備えら

EHIR から HIR への変換は，図 4 に示した構文

れている．この C 言語のフロントエンドに対して，

によって表現される例外処理制御記述を HIR の構

例外処理構文を扱えるように改良を加え，例外処理構

文のみを用いて表現し直すことにより実現される．

文を持つ C 言語を設計した．例外処理構文を持つ C

この変換を行うトランスレータ EHIR-to-HIR は，

言語では，try-catch 文，throw 文，例外宣言を記述

sigsetjmp()，siglongjmp() を用いた Stack Cut-

することができる．例外宣言では，親となる例外の指ting により例外処理制御を HIR で表現に置き換定又はその例外に対応づけるシグナルの指定ができ，える．単純な setjmp 法とは異なり，sigsetjmp()，さらに例外を表すデータ構造に埋め込まれるエラー

siglongjmp() を用いることで，シグナルを送出するメッセージを設定することができる．

非同期に発生する例外に対しても統合して扱えるよ
うにする．

一方で Exceptions4c は，C 言語で例外処理を実現することができるライブラリであり，マクロによっ

EHIR-to-HIR には，catch 節で捕捉されないユーて実現される．Exceptions4c が提供するマクロには，

ザ定義例外を try 節内で投げられていないか，同じ又例外処理構文である try-catch 文，throw 文や C#には包含する例外仮引数を持つ catch 節が記述されていおける with 文，using 文がある．また Exceptions4c

ないかなどを静的に検査する機能を持たせる（ Javaはシグナルに対応された独自の例外を提供しており，などにおける checked exception の導入）．

これらの例外を用いて新たに例外を宣言することや，
非同期に発生する例外を捕捉することも可能である．

3. 4 COINS 内の EHIR と EHIR-to-HIRの構成

4. 2 プログラム記述例

本研究で新たに COINS に導入した、EHIR 及び例外処理構文を持つ C 言語のプログラム記述例を，

EHIR-to-HIR に関連するモジュールについて述べる．

図 5 に示す．図 5 の 4 から 9 行目は例外の宣言であEHIR は、HIR のサブクラスの位置づけとなるよる．宣言された例外は，図 6 に示すように階層関係をうに設計し、パッケージ coins.ir.ehir に実装した。

構成している．図 6 中，個々の例外は，エッジで結ばれた上位の例外のサブクラスに位置づけられ，catch!"#$%&'&()*+,-./0

節において例外仮引数の階層関係に属し，例外仮引数!"#"11'&()*+,-./0

より同位，下位の例外のみ捕捉される．
例えば，図 5 の 17 行目で throw 文によってプログラマが明示的に SIGILL Exception1 を投げている．投げられた SIGILL Exception1 は，22 行目の!"#$%&'&()*+,-./2!"#$%&'&()*+,-./3!"#"11'&()*+,-./2

catch 節で捕捉され，23 行目の処理が実行される．また，26 行目では，ゼロ除算が実行されるので，シグナ!"#"11'&()*+,-./3

ル SIGFPE がこのプロセスに送出される．SIGFPEに対応した例外は，図 6 の SIGFPE Exception1 とそ の サ ブ ク ラ ス に あ た る SIGFPE Exception2 と

SIGFPE Exception3 である．よってゼロ除算による

図6

プログラムで生成された例外の階層関係

例外は，30 行目の catch 節で捕捉され，31 行目の処る。それによって、Exceptions4c が提供する例外を理が実行される．

用いて新たに例外を宣言することや，非同期に発生する例外を捕捉することも可能である．

!""#"$%&'()*+",-.*(%/012
3""#"$%&'()*+",-.*%4012
5""#"$%&'()*+",-%6&7(0128""#"
9""#"+:'+;.%4&<=>?@ABCB:'+;.%4&3DEF%G%*+"/H"I+J4ED=>?@ABKL
M""#"+:'+;.%4&<=>?@ABCB:'+;.%4&5DEN%61."O;+J7&*ED=>?@ABCB:'+;.%4&3KL
P""#"+:'+;.%4&<=>?@ABCB:'+;.%4&8DEQ+R."O;+J7&*ED=>?@ABCB:'+;.%4&3KL
S""#"+:'+;.%4&<=>?>QQCB:'+;.%4&3DET&*+U&+*"O;+J7.%4&3ED=>?>QQKL
V""#"+:'+;.%4&<=>?>QQCB:'+;.%4&5DET&*+U&+*"O;+J7.%4&5ED=>?>QQCB:'+;.%4&3KL
W""#"+:'+;.%4&<=>?>QQCB:'+;.%4&8DET&*+U&+*"O;+J7.%4&8ED=>?>QQCB:'+;.%4&5KL
3!#"33#"%&."X7%&<KY
35#"""%&."7Z3D/Z5D'Z!L38#"""*4)/(+"*L"
39#""".JHY"""
3M#""""""""""*Z7[/L
3P#"""""""""".JHY
3S#""""""""""""""""".1J4\<E.+-.ED=>?>QQCB:'+;.%4&3KL
3V#""""""""""]'7.'1<=>?>QQCB:'+;.%4&8KY
3W#""""""""""""""""";J%&.R<E^1+"=>?>QQCB:'+;.%4&8"\7-"'7)61."%&-%*+_&EKL
5!#""""""""""]'7.'1<=>?>QQCB:'+;.%4&5KY
53#""""""""""""""""";J%&.R<E^1+"=>?>QQCB:'+;.%4&5"\7-"'7)61."%&-%*+_&EKL
55#""""""""""]'7.'1<=>?>QQCB:'+;.%4&3KY
58#""""""""""""""""";J%&.R<E^1+"=>?>QQCB:'+;.%4&3"\7-"'7)61."%&-%*+_&EKL
59#""""""""""]U&7((HY
5M#""""""""""""""""";J%&.R<E%&-%*+"_&EKL
5P#"""""""""""""""""*Z/['L
5S#""""""""""]
5V#"""]'7.'1<=>?>QQCB:'+;.%4&3KY
5W#"""""""""";J%&.R<E^1+"=>?>QQCB:'+;.%4&3"\7-"'7)61."4).-%*+_&EKL
8!#"""]'7.'1<=>?@ABCB:'+;.%4&8KY
83#""""";J%&.R<E^1+"=>?@ABCB:'+;.%4&8"\7-"'7)61."4).-%*+_&EKL"
85#"""]'7.'1<=>?@ABCB:'+;.%4&3KY
88#""""";J%&.R<E^1+"=>?@ABCB:'+;.%4&3"\7-"'7)61."4).-%*+_&EKL
89#"""]
8M#"""J+.)J&"!L
8P#]

本システムを導入した COINS を用いた C 言語でも Exceptions4c を用いた C 言語と同様な記述及び例外処理制御を行うことができる．そして，独自の例
外をシグナルにマッピングさせることもできる．さらに，EHIR-to-HIR では、Exceptions4c では行われない静的な例外検査を行うことができる。

5 考察
本研究では，COINS に対して例外処理構文を表現できる EHIR および EHIR-to-HIR を導入した．そして第 4 章では，EHIR 及び HIR を用いて例外処理構文を持つ C 言語を設計できることを示した．ここでは，COINS に同様な機能を持たせるためのその他の方式について議論し，本研究の実装方法について考察する．

1. 本研究の方法で実装した場合 EHIR で表現された例外処理記述は，EHIR-to-HIR を用いることによって HIR レベルで表現される．つまり，

COINS において HIR より下流には手を加えず
図5

例外処理を拡張した C 言語のプログラム例に例外処理への対応をすることができる．EHIR
を用いずに，ユーザが作成するフロントエンドの
出力を HIR にしたままで同様な言語処理系を開

4. 3 Exceptions4c との比較

発することももちろん不可能ではない．しかし

Exceptions4c は例外処理制御を実現させるマクロながら，setjmp 法等による例外処理制御を HIRやシグナルにマッピングした独自の例外を提供していで表現するフロントエンドは，EHIR-to-HIR 全

体に相当する複雑で規模の大きいものになることが予想される．

へ導入した．

EHIR-to-HIR で用いる例外処理を実現する方法

2. EHIR から HIR を経由せず LIR へ変換する方と し て ，sigsetjmp() ，siglongjmp() を 用 い た法について考える．この方法の場合、HIR 用の

setjmp 法 を 用 い た ．EHIR-to-HIR は ，変 換 時 に

既存の最適化モジュールについても手を施さなけ

siglongjmp() を行うシグナルハンドラの生成も行う

れば，それらを EHIR に対して適応することがことで非同期に発生する例外への対応を可能とした．

できなくなってしまう．また，EHIR で表現されさらに EHIR-to-HIR には，EHIR で表現された例

た例外処理制御を LIR で表現する変換器は，複外に対して静的な例外検査を行う機能を持たせた．

雑になるものと考えられる．

3. 例外処理構文を表現できる低水準中間表現 ELIR開発したシステムを用いて例外処理構文を持つ C
言語を設計し，その有効性を確認した．

を新たに設計して、EHIR を ELIR へ変換する

謝辞 COINS について情報を提供して下さった電場合を考える．この場合，関連する多数の各変

気通信大学名誉教授の渡邊担先生，島根大学総合理工

換，最適化モジュール，コード生成器に対しても学研究科の鈴木貢先生に感謝します．

手を加える必要があり、その改変作業は単純ではないことが予想される．ただし、ELIR における

参 考 文 献

例外処理構文の表現は，LLVM [3] の中間表現と[ 1 ] COINS コ ン パ イ ラ・イ ン フ ラ ス ト ラ ク チャ:
http://coins-compiler.sourceforge.jp/[ 2 ] Exceptions4c: http://code.google.com/p/exceptions4c/[ 3 ] The LLVM Compiler Infrastructure: http://llvm.org/[ 4 ] Norman Ramsey, Simon Peyton Jones: A Single
Intermediate Language That Supports Multiple Implementations of Exceptions, ACM SIGPLAN Notices, Vol.35, Issue 5, pp.285–298, May 2000.
[ 5 ] 千葉雄司: Java2C トランスレータにおける例外処理の実現, 情報処理学会論文誌：プログラミング, Vol.
42, No. SIG 11(PRO 12), pp.14–24 Nov. 2001.
[ 6 ] 千葉雄司: C 言語への変換による Java アプリケー
ションの高速化に関する研究, 慶応義塾大学理工学研究
科学位論文, Jan 2003.
[ 7 ] 住井英二郎, 大根田裕一, 米澤明憲: 例外処理機構を備えた命令型言語の CPS 変換とその定式化, 情報処理学会論文誌：プログラミング, Vol. 45, No.SIG 12(PRO23), pp.67–82, Nov. 2004.
[ 8 ] 舞田 純一, 中井 央, 佐藤 聡: COINS を用いるためのコンパイラ自動生成の一方式, 情報処理学会論文
誌: プログラミング, Vol.48, No.SIG10(PRO33), pp.
34–49, June 2007.

同様なものと考えられ，その有効性については検討の余地がある．
以上のことから，本研究の方法が開発コストと効果の観点から妥当であったと考えられる．
今後の課題として，EHIR を任意の要素を持つ例
外をユーザが宣言をすることができるようにすること，マルチスレッドに対応した EHIR-to-HIR の設計が挙げられる．

6 まとめ
本研究では，COINS に対して例外処理に対応する機能を導入した。COINS に対して HIR よりも上位に例外処理構文を直接表現することができる高水準中
間表現 EHIR を設計した．さらに，EHIR から HIRへ変換するトランスレータ EHIR-to-HIR を COINS