JP2009048259A - プログラム変換方法及び変換用プログラム - Google Patents
プログラム変換方法及び変換用プログラム Download PDFInfo
- Publication number
- JP2009048259A JP2009048259A JP2007211434A JP2007211434A JP2009048259A JP 2009048259 A JP2009048259 A JP 2009048259A JP 2007211434 A JP2007211434 A JP 2007211434A JP 2007211434 A JP2007211434 A JP 2007211434A JP 2009048259 A JP2009048259 A JP 2009048259A
- Authority
- JP
- Japan
- Prior art keywords
- global variable
- unprocessed
- source code
- function
- unprocessed global
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Landscapes
- Devices For Executing Special Programs (AREA)
Abstract
【課題】グローバル変数をローカル変数に変換する処理をソースコードに対して行うことにより、プログラムの保守性を高め、メモリ参照命令数を削減する。
【解決手段】ソースコードから抽出された変換対象領域内に関数呼び出し元がある場合に、呼び出し先関数内で選択されたグローバル変数が使用されているか否かを判定し、使用されている場合には、関数呼び出し元に、当該グローバル変数の代替変数を宣言し、当該グローバル変数を使用するソースコード内の呼び出し先関数の全てに対して、前記代替変数を当該グローバル変数に対応する引数として追加するとともに、呼び出し先関数内における当該グローバル変数の使用を追加した引数の使用に置き換えた新たな関数を作成し、展開されたソースコード内の関数呼び出し元を新たな関数を呼び出せるように修正し、この処理が終了したら、当該グローバル変数を展開されたソースコードから削除する。
【選択図】図3
【解決手段】ソースコードから抽出された変換対象領域内に関数呼び出し元がある場合に、呼び出し先関数内で選択されたグローバル変数が使用されているか否かを判定し、使用されている場合には、関数呼び出し元に、当該グローバル変数の代替変数を宣言し、当該グローバル変数を使用するソースコード内の呼び出し先関数の全てに対して、前記代替変数を当該グローバル変数に対応する引数として追加するとともに、呼び出し先関数内における当該グローバル変数の使用を追加した引数の使用に置き換えた新たな関数を作成し、展開されたソースコード内の関数呼び出し元を新たな関数を呼び出せるように修正し、この処理が終了したら、当該グローバル変数を展開されたソースコードから削除する。
【選択図】図3
Description
本発明は、計算機の利用技術、特に、プログラムのソースコードを修正されたソースコードに変換するプログラム変換方法及び変換用プログラムに関する。
大部分のプログラミング言語においては、特定の型のデータを収容する単位として、名前によって識別され、それに値を与えることができる変数という概念がサポートされているが、この変数は、大別して、グローバル変数とローカル変数の2種類に分けられる。
グローバル変数は、プログラム処理の中のすべてのモジュールで値が有効な変数であって、使用される関数の外で宣言されるものであるが、このようなグローバル変数がプログラムのソースコード内で多用されている場合には、プログラムのソースコードを広い範囲に渡ってチェックしなければグローバル変数の正当性を確認することができないので、プログラムのソースコードの保守のし易さに問題がある。
また、グローバル変数は、使用される関数の外で定義されるので、値が定義されていれば、関数を呼び出す前にメモリへのストアが必要となるが、呼び出し先関数が条件付き関数の場合には、条件判定の結果、グローバル変数を参照する必要のないことがあるので、呼び出し先関数を呼び出す前のメモリ・ストアは、冗長なメモリ参照となる可能性がある。
従来、関数の呼び出し関係を解析し、グローバル変数を用いて値を渡している部分をローカル変数とし、関数の引数として追加するものがある(特許文献1)。また、プログラム内のグローバル変数の分布とプログラム・モジュール間の呼び出し関係とに基づいてグローバル変数の散らばり具合を表す評価値を求めるものもある(特許文献2)。
特開2002−99425号公報
特開平6−266550号公報
しかしながら、特許文献1に記載されたものは、コンパイラの処理途中の中間コードに対して変換を行うものであって、プログラムのソースコードの保守性につながるものではない。また、特許文献2に記載されたものは、求めた評価値をプログラムの保守担当者の割り当て時やプログラム再設計時などの基礎データとするというものであって、グローバル変数の存在がプログラムのソースコードの保守性に大きな影響があることを示唆してはいるが、プログラムのソースコードの保守性を高めるものではない。
本発明は、このような従来の技術の問題点に鑑みてなされたものであり、グローバル変数をローカル変数に変換する処理をプログラムのソースコードに対して行うことにより、プログラムのソースコードの保守性を高めることができると共に、実行されるメモリ参照命令数を削減することができるプログラム変換方法及び変換用プログラムを提供することを目的とする。
上記課題を解決するために、本発明のプログラム変換方法は、
グローバル変数を用いているプログラムのソースコードを計算機システムの主記憶装置に展開するソースコード展開ステップと、
前記展開されたソースコード内に未処理のグローバル変数が存在するか否かを判定する未処理グローバル変数判定ステップと、
前記展開されたソースコード内に前記未処理のグローバル変数が存在する場合、前記展開されたソースコードから変換対象領域を抽出する変換対象領域抽出ステップと、
前記未処理のグローバル変数を1つ選択する未処理グローバル変数選択ステップと、
前記抽出された変換対象領域内に未処理の関数呼び出し元がある場合、呼び出し先関数内で前記選択された未処理のグローバル変数が使用されているか否かを判定する未処理文探索ステップと、
前記呼び出し先関数内で前記選択された未処理のグローバル変数が使用されている場合、前記関数呼び出し元に前記選択された未処理のグローバル変数の代替変数を宣言する代替変数宣言ステップと、
前記選択された未処理のグローバル変数を使用する前記展開されたソースコード内の前記呼び出し先関数の全てに対して、前記代替変数を前記選択された未処理のグローバル変数に対応する引数として追加するとともに、前記呼び出し先関数内における前記選択された未処理のグローバル変数の使用を前記追加した引数の使用に置き換えた新たな関数を作成する引数追加・新関数作成ステップと、
前記展開されたソースコード内の前記関数呼び出し元を前記新たな関数を呼び出せるように修正する呼び出し元修正ステップと、
前記選択された未処理のグローバル変数を前記展開されたソースコードから削除する未処理グローバル変数削除ステップと、
前記呼び出し先関数内で前記選択された未処理のグローバル変数が使用されていない場合、又は、前記選択された未処理のグローバル変数の削除が終了した場合、前記選択された未処理のグローバル変数を処理済みとする未処理グローバル変数処理済み化ステップと、
前記未処理グローバル変数選択ステップ、前記未処理文探索ステップ、前記代替変数宣言ステップ、前記引数追加・新関数作成ステップ、前記呼び出し元修正ステップ、前記未処理グローバル変数削除ステップ及び前記未処理グローバル変数処理済み化ステップを、前記未処理のグローバル変数が存在する間、繰り返し実行することを指示する繰り返し実行指示ステップと、
前記未処理のグローバル変数が存在しなくなったとき、前記展開されたソースコードを前記代替変数宣言ステップ、前記引数追加・新関数作成ステップ、前記呼び出し元修正ステップ及び前記未処理グローバル変数削除ステップによって修正したソースコードを、変換後ソースコードとして前記主記憶装置から前記計算機システムの外部記憶装置に格納する変換後ソースコード格納ステップと、を含むことを特徴とする。
グローバル変数を用いているプログラムのソースコードを計算機システムの主記憶装置に展開するソースコード展開ステップと、
前記展開されたソースコード内に未処理のグローバル変数が存在するか否かを判定する未処理グローバル変数判定ステップと、
前記展開されたソースコード内に前記未処理のグローバル変数が存在する場合、前記展開されたソースコードから変換対象領域を抽出する変換対象領域抽出ステップと、
前記未処理のグローバル変数を1つ選択する未処理グローバル変数選択ステップと、
前記抽出された変換対象領域内に未処理の関数呼び出し元がある場合、呼び出し先関数内で前記選択された未処理のグローバル変数が使用されているか否かを判定する未処理文探索ステップと、
前記呼び出し先関数内で前記選択された未処理のグローバル変数が使用されている場合、前記関数呼び出し元に前記選択された未処理のグローバル変数の代替変数を宣言する代替変数宣言ステップと、
前記選択された未処理のグローバル変数を使用する前記展開されたソースコード内の前記呼び出し先関数の全てに対して、前記代替変数を前記選択された未処理のグローバル変数に対応する引数として追加するとともに、前記呼び出し先関数内における前記選択された未処理のグローバル変数の使用を前記追加した引数の使用に置き換えた新たな関数を作成する引数追加・新関数作成ステップと、
前記展開されたソースコード内の前記関数呼び出し元を前記新たな関数を呼び出せるように修正する呼び出し元修正ステップと、
前記選択された未処理のグローバル変数を前記展開されたソースコードから削除する未処理グローバル変数削除ステップと、
前記呼び出し先関数内で前記選択された未処理のグローバル変数が使用されていない場合、又は、前記選択された未処理のグローバル変数の削除が終了した場合、前記選択された未処理のグローバル変数を処理済みとする未処理グローバル変数処理済み化ステップと、
前記未処理グローバル変数選択ステップ、前記未処理文探索ステップ、前記代替変数宣言ステップ、前記引数追加・新関数作成ステップ、前記呼び出し元修正ステップ、前記未処理グローバル変数削除ステップ及び前記未処理グローバル変数処理済み化ステップを、前記未処理のグローバル変数が存在する間、繰り返し実行することを指示する繰り返し実行指示ステップと、
前記未処理のグローバル変数が存在しなくなったとき、前記展開されたソースコードを前記代替変数宣言ステップ、前記引数追加・新関数作成ステップ、前記呼び出し元修正ステップ及び前記未処理グローバル変数削除ステップによって修正したソースコードを、変換後ソースコードとして前記主記憶装置から前記計算機システムの外部記憶装置に格納する変換後ソースコード格納ステップと、を含むことを特徴とする。
上記構成によれば、プログラムのソースコードからグローバル変数を取り除くことができることから、その独立性が高くなり、保守性を高めることができる。また、このことから、プログラムのソースコードの流用性が向上し、プログラムの生産効率を上げることが期待できる。さらに、本発明のプログラム変換方法によって変換されたプログラムのソースコードをコンパイルすると、冗長なメモリ参照の少ないオブジェクト・プログラムができ上がる。
また、前記未処理グローバル変数判定ステップは、前記展開されたソースコード内から未処理のグローバル変数を探索して未処理グローバル変数リストを作成する未処理グローバル変数リスト作成ステップと、前記作成された未処理グローバル変数リストを主記憶装置上に保持させる未処理グローバル変数リスト保持ステップと、を含み、前記保持された未処理グローバル変数リストに基づいて、前記展開されたソースコード内に未処理のグローバル変数が存在するか否かを判定し、前記未処理グローバル変数処理済み化ステップは、前記未処理グローバル変数リストに対して前記処理済みの処理を行うことを特徴とする。
また、上記構成によれば、最初に、展開されたソースコード内から未処理のグローバル変数を探索して未処理グローバル変数リストを作成し、以後の未処理のグローバル変数の探索処理や処理の終了したグローバル変数の処理済み化をこの未処理グローバル変数リストに基づいて行うため、未処理のグローバル変数の探索処理を短時間で済ませることができる。
また、本発明の変換用プログラムは、上記プログラム変換方法の各ステップをコンピュータに実行させることができる。
上記構成によれば、本発明の変換用プログラムをコンピュータにインストールすることによって、このコンピュータを、プログラムのソースコードを修正されたソースコードに変換するプログラム変換方法を実現するものとして構築することができる。
以下図面を用いて本発明の実施形態を説明する。
<計算機システム>
図1は、本発明のプログラム変換方法を実施するための計算機システムの模式図であり、CPU1、キーボード2、ディスプレイ3、プリンタ4、主記憶装置5及び外部記憶装置6は、計算機システムの内部バス7によって相互接続されている。
図1は、本発明のプログラム変換方法を実施するための計算機システムの模式図であり、CPU1、キーボード2、ディスプレイ3、プリンタ4、主記憶装置5及び外部記憶装置6は、計算機システムの内部バス7によって相互接続されている。
主記憶装置5には、展開されたソースコード51、抽出された変換対象領域情報51’、修正されたソースコード52、プログラム変換の過程で用いる未処理グローバル変数リスト53及び変換用プログラム54が記憶され、外部記憶装置6には、変換前ソースコード61及び変換後ソースコード62が格納される。これら各種のソースコード及びリストの詳細については後述する。
<変換概念>
図2は、本発明のプログラム変換方法の処理概念図であり、外部記憶装置6に格納された変換前ソースコード61を主記憶装置5にソースコード51として展開し(ステップS21)、この展開されたソースコード51から変換対象領域を抽出し(ステップS22)、抽出した変換対象領域内のソースコード52の未処理文のそれぞれについて、必要な文の修正を行い(ステップS23)、全ての未処理文についての処理が終了すると(ステップS24:YES)、修正されたソースコード52を変換後ソースコード62として外部記憶装置5に格納する(ステップS25)。
図2は、本発明のプログラム変換方法の処理概念図であり、外部記憶装置6に格納された変換前ソースコード61を主記憶装置5にソースコード51として展開し(ステップS21)、この展開されたソースコード51から変換対象領域を抽出し(ステップS22)、抽出した変換対象領域内のソースコード52の未処理文のそれぞれについて、必要な文の修正を行い(ステップS23)、全ての未処理文についての処理が終了すると(ステップS24:YES)、修正されたソースコード52を変換後ソースコード62として外部記憶装置5に格納する(ステップS25)。
[変換手順]
次に、本発明のプログラム変換方法について、図3の処理フローを用いて詳細に説明する。
次に、本発明のプログラム変換方法について、図3の処理フローを用いて詳細に説明する。
変換前ソースコード61を外部記憶装置6から読み出し、主記憶装置5の作業エリア上にソースコード51として展開し(ステップS31)、次いで、この展開されたソースコード51の中からグローバル変数を探索し、このグローバル変数を列挙した未処理グローバル変数リスト53を作成する(ステップS32)。この未処理グローバル変数リスト53は、主記憶装置5の作業エリア上に保持される。
図4に、未処理グローバル変数リスト53の一例を示す。この例は、グローバル変数名と処理フラグからなるもので、未処理のグローバル変数については未処理であることを示す“○”フラグを立て、処理の終了したグローバル変数については処理済みであることを示す“×”フラグを立てる例であるが、未処理のグローバル変数名のみのリストとし、処理が済んだグローバル変数については、その変数名を未処理グローバル変数リストから消去するものであってもよい。
次いで、保持された未処理グローバル変数リスト53に基づいて、展開されたソースコード51の中に未処理のグローバル変数が存在するか否かを判定し(ステップS33)、未処理のグローバル変数がないと判定された場合(ステップS33:NO)には、展開されたソースコード51の修正が全て終了したと判断し、修正されたソースコード52を変換後ソースコード62として外部記憶装置6に格納する(ステップS42)。この場合、変換後ソースコードのファイル名は、変換前ソースコードのファイル名と異なる方が好ましい。修正されたソースコード52を変換後ソースコード62として外部記憶装置6に格納した後、処理を終了する。
未処理のグローバル変数があると判定された場合(ステップS33:YES)には、展開されたソースコード51の中から変換の対象とする領域を抽出する(ステップS34)。この抽出は、展開されたソースコードの中から変換の対象となるものだけを選択するために行われるものである。抽出された変換対象領域の情報も、主記憶装置5の作業エリア上に保持される。この抽出作業は、典型的には、関数の呼び出し関係をグラフ化したコールグラフを作成し、主記憶装置5の作業エリア上に保持する作業であるが、コールグラフの詳細については後述する。
展開されたソースコード51の中から変換の対象とする領域を抽出した後、保持された未処理グローバル変数リスト53から未処理のグローバル変数を1つ取り出し(ステップS35)、抽出された変換対象領域情報52’の中にある未処理の関数呼び出しについて、呼び出し先関数が未処理グローバル変数リスト53から取り出された未処理のグローバル変数を使用するものであるか否かを判定する(ステップS36)。
呼び出し先関数のいずれもが取り出された未処理のグローバル変数を使用するものではないと判定された場合(ステップS36:NO)には、取り出された未処理のグローバル変数についての処理が終了したと判断し、保持された未処理グローバル変数リスト53において、取り出された未処理のグローバル変数を処理済みとする(ステップS37)。この処理の後は、保持された未処理グローバル変数リスト53に基づいて、展開されたソースコード51の中に更なる未処理のグローバル変数が存在するか否かの判定を行う処理(ステップS33)に戻る。
呼び出し先関数が未処理のグローバル変数を使用するものであると判定された場合(ステップS36:YES)には、展開されたソースコード51の中にある関数呼び出し元に、取り出された未処理のグローバル変数をローカル変数に代替する宣言文を挿入する(ステップS38)。その具体例は、例えば、“Gl”をグローバル変数名とし、“lo”をローカル変数名とすると、“lo=Gl”というものになる。
この宣言文の挿入の後、取り出された未処理のグローバル変数を使用する展開されたソースコード51の中にある全ての呼び出し先関数に対して、代替変数であるローカル変数を、取り出された未処理のグローバル変数に対応する引数として追加するとともに、呼び出し先関数内におけるグローバル変数の使用を追加した引数の使用に置き換えた新たな関数を作成する(ステップS39)。その具体例は、例えば、次のものである。
修正前の呼び出し先関数とその関数内でのグローバル変数の使用が、例えば、
int kingaku(int x)
{
int tanka;
if (x > Gl
tanka = Gl;
else
tanka = x;
return tanka;
}
とすると、新たな関数は、
int kingaku(int x, lo)
{
int tanka;
if (x > lo
tanka = lo;
else
tanka = x;
return tanka;
}
となる。
int kingaku(int x)
{
int tanka;
if (x > Gl
tanka = Gl;
else
tanka = x;
return tanka;
}
とすると、新たな関数は、
int kingaku(int x, lo)
{
int tanka;
if (x > lo
tanka = lo;
else
tanka = x;
return tanka;
}
となる。
新たな関数の作成が終了すると、関数呼び出し元のソースコードを、作成された新たな関数を呼び出せるように修正する(ステップS40)。その具体例は、先の例の関数を呼び出すとして、呼び出し元の旧文が、例えば、“soukei = soukei + kingaku(a(i))”であったとすると、“soukei = soukei + kingaku(a(i), lo)”という文に修正するというものである。
関数呼び出し元の修正が終了した後は、展開されたソースコード51の中にある取り出された未処理のグローバル変数を削除する(ステップS41)。
これらの処理が終了すると、保持された未処理グローバル変数リスト53において、取り出された未処理のグローバル変数を処理済みとし(ステップS37)、続いて、保持された未処理グローバル変数リスト53に基づいて、展開されたソースコード51の中に未処理のグローバル変数が存在するか否かを判定する処理(ステップS33)に戻る。
[実現手段]
次に、本発明のプログラム変換方法を実現するための機能手段とこれら機能手段間の制御の流れ及び処理されるデータとの関係について、図5の模式図を用いて説明する。なお、図中、太線は、データ関係を示し、点線は、制御順序を示す。
次に、本発明のプログラム変換方法を実現するための機能手段とこれら機能手段間の制御の流れ及び処理されるデータとの関係について、図5の模式図を用いて説明する。なお、図中、太線は、データ関係を示し、点線は、制御順序を示す。
変換前ソースコード展開手段m1は、図3のステップS31を実行するための手段であり、この手段m1によって、外部記憶装置5に格納された変換前ソースコード61が読み出され、主記憶装置5の作業エリア上に展開される。手段m1による処理が終了すると、未処理グローバル変数リスト作成手段m2が動作を開始する。
未処理グローバル変数リスト作成手段m2は、図3のステップS32を実行するための手段であり、この手段m2によって、主記憶装置5の作業エリア上に展開されたソースコード51の中からグローバル変数が探し出され、未処理グローバル変数リスト53が作成される。この未処理グローバル変数リスト53は、主記憶装置5の作業エリア上に保持される。手段m2による処理が終了すると、未処理グローバル変数有無判定手段m3が動作を開始する。
未処理グローバル変数有無判定手段m3は、図3のステップS33を実行するための手段であり、この手段m3によって、保持された未処理グローバル変数リスト53に未処理のグローバル変数が存在するか否かが判定される。手段m3による処理が終了すると、変換対象領域抽出手段m4又は変換後ソースコード格納手段m12のいずれかが動作を開始する。
変換対象領域抽出手段m4は、図3のステップS34を実行するための手段であり、この手段m4によって、主記憶装置5の作業エリア上に展開されたソースコード51から変換の対象となる情報を取り出す。手段m4による処理が終了すると、未処理グローバル変数取り出し手段m5が動作を開始する。
未処理グローバル変数取り出し手段m5は、図3のステップS35を実行するための手段であり、未処理グローバル変数有無判定手段m4が保持された未処理グローバル変数リスト53に未処理のグローバル変数が存在すると判定した場合に動作を開始する。この手段m5によって、保持された未処理グローバル変数リストから未処理グローバル変数が順に1つ取り出される。手段m5による処理が終了すると、未処理グローバル変数使用関数の組み探索手段m6が動作を開始する。
変換後ソースコード格納手段m12は、図3のステップS42を実行するための手段であり、未処理グローバル変数有無判定手段m4が保持された未処理グローバル変数リスト53に未処理のグローバル変数がないと判定した場合に動作を開始する。保持された未処理グローバル変数リスト53に未処理のグローバル変数がないということは、展開されたソースコード51の修正が全て終了したことを意味する。この手段m12によって、修正されたソースコード52が変換後ソースコード62として外部記憶装置6に格納される。手段m12による処理が終了すると、プログラム変換処理が終了する。
未処理グローバル変数使用関数の組み探索手段m6は、図3のステップS36を実行するための手段であり、この手段m6によって、抽出された変換対象領域情報52’の中にある未処理の関数呼び出しについて、呼び出し先関数が未処理グローバル変数リスト53から取り出された未処理のグローバル変数を使用するものであるか否かが判定される。手段m6による処理が終了すると、未処理グローバル変数の代替変数宣言手段m7又は未処理グローバル変数処理済み化手段m11のいずれかが動作を開始する。
未処理グローバル変数の代替変数宣言手段m7は、図3のステップS38を実行するための手段であり、この手段m7によって、展開されたソースコード51の中にある関数呼び出し元に、取り出された未処理のグローバル変数をローカル変数に代替する宣言文が挿入される。手段m7による処理が終了すると、引数追加・新関数作成手段m8が動作を開始する。
引数追加・新関数作成手段m8は、図3のステップS39を実行するためのものであり、この手段m8によって、取り出された未処理のグローバル変数を使用する展開されたソースコード51の中にある全ての呼び出し先関数に対して、代替変数であるローカル変数を、取り出された未処理のグローバル変数に対応する引数として追加されるとともに、呼び出し先関数内におけるグローバル変数の使用を追加した引数の使用に置き換えた新たな関数が作成される。手段m8による処理が終了すると、関数読み出し元修正手段m9が動作を開始する。
関数読み出し元修正手段m9は、図3のステップS40を実行するための手段であり、この手段m9によって、関数呼び出し元のソースコードが、作成された新たな関数を呼び出せるように修正される。手段m9による処理が終了すると、未処理グローバル変数削除手段m10が動作を開始する。
未処理グローバル変数削除手段m10は、図3のステップS41を実行するための手段であり、この手段m10によって、処理対象として取り出された未処理のグローバル変数が展開されたソースコード51から削除される。手段m10による処理が終了すると、未処理グローバル変数処理済み化手段m11が動作を開始する。
未処理グローバル変数処理済み化手段m11は、図3のステップS37を実行するためのものであり、この手段m11によって、処理対象として取り出された未処理のグローバル変数が保持された未処理グローバル変数リスト53において処理済みとされる。手段m11による処理が終了すると、未処理グローバル変数有無判定手段m3が再び動作を開始する。
なお、上で説明した機能手段の全てが、変換用プログラムがコンピュータに読み込まれ、実行されることにより実現される機能実現手段であることはいうまでもない。
[参考例]
以上で、本発明のプログラム変換方法についての説明を終了するが、本発明のプログラム変換方法をソースコードがC言語で書かれたプログラムの変換に適用した場合の参考例について、図6〜図9を用いて説明する。
以上で、本発明のプログラム変換方法についての説明を終了するが、本発明のプログラム変換方法をソースコードがC言語で書かれたプログラムの変換に適用した場合の参考例について、図6〜図9を用いて説明する。
図6は、本発明のプログラム変換方法をソースコードがC言語で書かれたプログラムの変換に適用した場合の参考例のメイン処理フロー図である。
最初に、主記憶装置5に展開されたソースコード51を解析して、このソースコード51に存在するグローバル変数の列挙を行い、未処理グローバル変数リスト53を作成する(ステップS61)。この未処理グローバル変数リスト53は、主記憶装置5の作業エリア上に保持される。これらの処理は、図3のステップS31〜S32に対応する処理である。未処理グローバル変数リストのフォームは、図4に示したものでよい。
続いて、保持された未処理グローバル変数リスト53に基づいて、未処理のグローバル変数が存在するか否かを判定し(ステップS62)、未処理のグローバル変数が存在しないと判定された場合(ステップS62:存在しない)には、展開されたソースコード51の修正が全て終了したと判断し、修正されたソースコード52を変換後ソースコード62として外部記憶装置6に格納し、処理を終了する。この処理は、図3のステップS33:NO、ステップS41に対応する処理である。
未処理のグローバル変数が存在すると判定された場合(ステップS62:存在する)には、展開されたソースコードを解析し、関数の呼び出し関係をグラフ化したコールグラフを作成する(ステップS63)。このコールグラフは、未処理グローバル変数リスト53と同様に、主記憶装置5の作業エリア上に保持される。この処理は、図3のステップS34に対応する処理である。コールグラフは、図8の『変換前のソースコードのコールグラフ』に示されるように、関数呼び出し元“int main(int arge, char *argv[]”と呼び出し先関数“void CountOne(void)”、“void CountN(int nAdd)”及び“void Print(int nNum)”との呼び出し関係を示すものである。コールグラフの概念自体は既知のものなので、ここでは、詳しく説明をしない。
コールグラフを作成・保持した後、保持された未処理グローバル変数リスト53から未処理のグローバル変数を1つ取り出し(ステップS64)、取り出された未処理のグローバル変数を使用している関数を含む最小の部分コールグラフを、保持されたコールグラフに基づいて作成する(ステップS65)。この最小の部分コールグラフも、コールグラフと同様に、主記憶装置5の作業エリア上に保持される。これらの処理は、図3のステップS35〜S36に対応する処理である。最小の部分コールグラフは、図8の『変換前のソースコードの該グローバル変数を含む最小部分コールグラフ』に示されるように、関数呼び出し元“int main(int arge, char *argv[]”と取り出された未処理のグローバル変数の使用を含む呼び出し先関数“void CountOne(void)”及び“void CountN(int nAdd)”との呼び出し関係を示すものである。
最小の部分コールグラフを作成・保持した後、この最小の部分コールグラフの根の数を調べる(ステップS66)。これは、取り出された未処理のグローバル変数の使用を含む呼び出し先関数が複数の関数呼び出し元から呼び出されることがあるので、その呼び出し元の数を調べるためである。その後の処理は、最小の部分コールグラフの根が1つか2つ以上で若干異なる。
最小の部分コールグラフの根の数が1つの場合には、最小の部分コールグラフの根の関数、つまり、関数呼び出し元において、取り出された未処理のグローバル変数の代替変数を宣言する(ステップS67)。この代替変数の宣言によって、関数呼び出し元において、取り出された未処理のグローバル変数が呼び出し先関数に追加される引数であるローカル変数に置き換えられる。この処理は、図3のステップS38に対応する処理である。この具体例は、図9に(1)と示されるものである。この例では、ローカル変数“int cnv_g_nCount”に“0”が代入されている。この処理の後、ステップS72に移る。
最小の部分コールグラフの根の数が2つ以上の場合には、最小の部分コールグラフの根、つまり、関数呼び出し元がクラス間をまたがるものであるか否かが判定される(ステップS68)。またがらない場合(ステップS68:またがらない)については図7に示されるとおりであり、後述する。
最小の部分コールグラフの根、つまり、関数呼び出し元がクラス間をまたがるものである場合(ステップS68:またがる)には、クラスを1つ選択し、そのクラスについて、取り出された未処理のグローバル変数に対応するメンバ変数を宣言する(ステップS69)。メンバ変数とは、オブジェクトの状態を表す属性を保持するためのフィールドであって、クラスの中、且つメソッドの外側に記述されるものである。メンバ変数は、当該クラス内の任意のメソッドから参照可能であるだけなく、他のクラスから生成されたオブジェクトからもアクセスが可能なものである。
選択されたクラス内の未処理のグローバル変数の使用を静的メンバ変数に置き換え、この静的メンバ変数を参照できる静的メンバ関数を追加する(ステップS70)。静的メンバ変数とは、修飾子“static”が指定されているメンバ変数のことを意味し、インスタンス毎に確保される変数となるので、インスタンス変数とも呼ばれるものである。また、静的メンバ関数とは、クラスをスコープとするグローバル関数のような存在であって、全てのオブジェクトに共有される関数なので、オブジェクトが無くても、クラス名を指定すればアクセスすることができるものである。
ステップS70の置き換え・関数追加の後、最小の部分コールグラフの未修整の根、つまり、関数呼び出し元について、取り出された未処理のグローバル変数の代替変数を宣言し、先に説明した静的メンバ変数を参照できるようにする(ステップS71)。代替変数の宣言については、ステップS67で説明したとおりである。
関数呼び出し元において、取り出された未処理のグローバル変数の代替変数を宣言した後、最小の部分コールグラフの根以外の未修整の関数、つまり、呼び出し先関数の全てに対して、取り出された未処理のグローバル変数に対応する引数を追加するとともに、その関数内における取り出された未処理のグローバル変数の使用を先に説明した引数、つまり、ローカル変数の使用に置き換えた新たな関数を作成する(ステップS72)。この処理は、図3のS39に対応する処理である。この具体例は、図9に(2)及び(3)と示されるものである。この例は、旧呼び出し先関数
void CountOne(void)
{
g_nCount +;
}
が、新呼び出し先関数
void CountOne(int *cnv_g_nCount)
{
(*cnv_g_nCount) ++;
}
に修正されるとともに、旧呼び出し先関数
void CountN(int nAdd)
{
g_nCount + = nAdd;
}
が、新呼び出し先関数
void CountN(int nAdd,int *cnv_g_nCount)
{
(*cnv_g_nCount) + = nAdd;
}
に修正されたことを示している。“*cnv_g_nCount”は、引数として追加されたローカル変数である。“*”(アスタリスク)は、ポインタ型の変数であることを意味する
続けて、最小の部分コールグラフ内の関数呼び出しを、ステップS72において作成した新たな関数を呼び出せるように修正する(ステップS73)。この処理は、図3のS40に対応する処理である。その具体例は、図9に(4)と示されるものである。この例は、関数呼び出し元の“CountOne()”及び“CountN(10)”が、それぞれ、“CountOne(&env_g_nCount)”及び“CountN(10, &env_g_nCount)”に修正された様子を示している。なお、“&”(アンパサンド)も、ポインタ型の変数であることを意味している。
void CountOne(void)
{
g_nCount +;
}
が、新呼び出し先関数
void CountOne(int *cnv_g_nCount)
{
(*cnv_g_nCount) ++;
}
に修正されるとともに、旧呼び出し先関数
void CountN(int nAdd)
{
g_nCount + = nAdd;
}
が、新呼び出し先関数
void CountN(int nAdd,int *cnv_g_nCount)
{
(*cnv_g_nCount) + = nAdd;
}
に修正されたことを示している。“*cnv_g_nCount”は、引数として追加されたローカル変数である。“*”(アスタリスク)は、ポインタ型の変数であることを意味する
続けて、最小の部分コールグラフ内の関数呼び出しを、ステップS72において作成した新たな関数を呼び出せるように修正する(ステップS73)。この処理は、図3のS40に対応する処理である。その具体例は、図9に(4)と示されるものである。この例は、関数呼び出し元の“CountOne()”及び“CountN(10)”が、それぞれ、“CountOne(&env_g_nCount)”及び“CountN(10, &env_g_nCount)”に修正された様子を示している。なお、“&”(アンパサンド)も、ポインタ型の変数であることを意味している。
関数呼び出し元を修正した後、関数呼び出し元に宣言されている未処理のグローバル変数を削除する(ステップS74)。この処理は、図3のステップS41に対応する処理である。その具体例は、図9に(5)と示されるものである。この例は、変換前のソースコードに記述されていた“int g_nCount = 0;”が変換後には削除されている様子を示している。なお、“int g_nCount”がグローバル変数であることはいうまでもない。
関数呼び出し元に宣言されている未処理のグローバル変数を削除した(ステップS74)後、保持された未処理グローバル変数リスト53に基づいて、次の未処理のグローバル変数が存在するか否かを判定する処理(ステップS62)に戻る。なお、この処理に先立って、未処理グローバル変数リスト53上の処理の済んだ未処理のグローバル変数を処理済みとする処理が行われることはいうまでもない。
最後に、図6の“ステップS68:またがる場合”について、図7のコールバック関数用処理フローを用いて説明する。コールバック関数とは、C言語及びC++言語などにおいて、関数呼び出しの際に、関数のアドレスをパラメータとして渡すことで、呼び出した関数から自身の提供する関数を呼び出すようにすることがあるが、この際の呼び出した関数から実行される関数のことを意味する。
このコールバック関数用処理では、最小のコールバックグラフの根、つまり、関数呼び出し元の中に、コールバック関数でない関数が幾つあるかを調べる(ステップS81)。2つ以上ある場合(ステップS81:2つ以上)には、取り出された未処理のグローバル変数についての処理は不可能なので、処理の対象外として、処理を終了する。
最小の部分コールグラフの根、つまり、関数呼び出し元の中に、コールバック関数でない関数が1つである場合(ステップS81:1つ)には、コールバック関数でない関数において、取り出された未処理のグローバル変数の代替宣言を行うとともに、この関数を、最小の部分コールグラフの根、つまり、関数呼び出し元内の全てのコールバック関数に対して、強制的に宣言した代替変数への参照をメッセージとして送信できるように修正する(ステップS83)。
ステップS83における処理後、最小の部分コールグラフの根、つまり、関数呼び出し元内の全てのコールバック関数について、“当該グローバル変数の代替変数の参照を受けるメッセージを処理する”処理を追加する(ステップS84)。
この追加処理の後、最小の部分コールグラフの根以外の未修整の関数、つまり、呼び出し先関数の全てに対して、取り出された未処理のグローバル変数に対応する引数を追加するとともに、その関数内における取り出された未処理のグローバル変数の使用を先に説明した引数、つまり、ローカル変数の使用に置き換えた新たな関数を作成する(ステップS85)。
これらの処理が終了した後、図6のステップS73及びS74と同様の処理が行われ(ステップS86、S87)、コールバック関数用処理が終了する。このコールバック関数用処理の終了後、図6の保持された未処理グローバル変数リスト53に基づいて、次の未処理のグローバル変数が存在するか否かを判定する処理(ステップS62)に戻る。
以上、本発明の一実施形態を説明したが、上記実施形態はあくまでも説明のためのものであり、本発明の範囲を制限するものではない。したがって、当業者であればこれらの各要素若しくは全要素をこれと均等なものに置換した実施形態を採用することが可能であるが、これらの実施形態も本発明の範囲に含まれる。
1:CPU、2:キーボード、3:ディスプレイ、4:プリンタ、5:主記憶装置、6:外部記憶装置、m1:変換前ソースコード展開手段、m2:未処理グローバル変数リスト作成手段、m3:未処理グローバル変数有無判定手段、m4:未処理グローバル変数取り出し手段、m5:未処理関数呼び出し・未処理グローバル変数使用の呼び出し先関数探索手段、m6:引数追加・新関数作成手段、m7:呼び出し元修正手段、m8:グローバル変数処理済み化手段、m9:変換後ソースコード格納手段
Claims (3)
- グローバル変数を用いているプログラムのソースコードを計算機システムの主記憶装置に展開するソースコード展開ステップと、
前記展開されたソースコード内に未処理のグローバル変数が存在するか否かを判定する未処理グローバル変数判定ステップと、
前記展開されたソースコード内に前記未処理のグローバル変数が存在する場合、前記展開されたソースコードから変換対象領域を抽出する変換対象領域抽出ステップと、
前記未処理のグローバル変数を1つ選択する未処理グローバル変数選択ステップと、
前記抽出された変換対象領域内に未処理の関数呼び出し元がある場合、呼び出し先関数内で前記選択された未処理のグローバル変数が使用されているか否かを判定する未処理文探索ステップと、
前記呼び出し先関数内で前記選択された未処理のグローバル変数が使用されている場合、前記関数呼び出し元に前記選択された未処理のグローバル変数の代替変数を宣言する代替変数宣言ステップと、
前記選択された未処理のグローバル変数を使用する前記展開されたソースコード内の前記呼び出し先関数の全てに対して、前記代替変数を前記選択された未処理のグローバル変数に対応する引数として追加するとともに、前記呼び出し先関数内における前記選択された未処理のグローバル変数の使用を前記追加した引数の使用に置き換えた新たな関数を作成する引数追加・新関数作成ステップと、
前記展開されたソースコード内の前記関数呼び出し元を前記新たな関数を呼び出せるように修正する呼び出し元修正ステップと、
前記選択された未処理のグローバル変数を前記展開されたソースコードから削除する未処理グローバル変数削除ステップと、
前記呼び出し先関数内で前記選択された未処理のグローバル変数が使用されていない場合、又は、前記選択された未処理のグローバル変数の削除が終了した場合、前記選択された未処理のグローバル変数を処理済みとする未処理グローバル変数処理済み化ステップと、
前記未処理グローバル変数選択ステップ、前記未処理文探索ステップ、前記代替変数宣言ステップ、前記引数追加・新関数作成ステップ、前記呼び出し元修正ステップ、前記未処理グローバル変数削除ステップ及び前記未処理グローバル変数処理済み化ステップを、前記未処理のグローバル変数が存在する間、繰り返し実行することを指示する繰り返し実行指示ステップと、
前記未処理のグローバル変数が存在しなくなったとき、前記展開されたソースコードを前記代替変数宣言ステップ、前記引数追加・新関数作成ステップ、前記呼び出し元修正ステップ及び前記未処理グローバル変数削除ステップによって修正したソースコードを、変換後ソースコードとして前記主記憶装置から前記計算機システムの外部記憶装置に格納する変換後ソースコード格納ステップと、
を含むことを特徴とするプログラム変換方法。 - 前記未処理グローバル変数判定ステップは、前記展開されたソースコード内から未処理のグローバル変数を探索して未処理グローバル変数リストを作成する未処理グローバル変数リスト作成ステップと、前記作成された未処理グローバル変数リストを主記憶装置上に保持させる未処理グローバル変数リスト保持ステップと、を含み、前記保持された未処理グローバル変数リストに基づいて、前記展開されたソースコード内に未処理のグローバル変数が存在するか否かを判定し、前記未処理グローバル変数処理済み化ステップは、前記未処理グローバル変数リストに対して前記処理済みの処理を行うことを特徴とする請求項1に記載のプログラム変換方法。
- 請求項1または2記載のプログラム変換方法の各ステップをコンピュータに実行させることを特徴とする変換用プログラム。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
JP2007211434A JP2009048259A (ja) | 2007-08-14 | 2007-08-14 | プログラム変換方法及び変換用プログラム |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
JP2007211434A JP2009048259A (ja) | 2007-08-14 | 2007-08-14 | プログラム変換方法及び変換用プログラム |
Publications (1)
Publication Number | Publication Date |
---|---|
JP2009048259A true JP2009048259A (ja) | 2009-03-05 |
Family
ID=40500441
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
JP2007211434A Pending JP2009048259A (ja) | 2007-08-14 | 2007-08-14 | プログラム変換方法及び変換用プログラム |
Country Status (1)
Country | Link |
---|---|
JP (1) | JP2009048259A (ja) |
Cited By (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
KR20100108054A (ko) * | 2009-03-27 | 2010-10-06 | 삼성전자주식회사 | 복수의 프로세서들을 포함하는 시스템 장치 및 그 변수 선언 및 사용 방법 |
KR101588027B1 (ko) * | 2014-10-10 | 2016-01-25 | (주)씽크포비엘 | 소프트웨어 현지화를 위한 테스트 케이스 생성 장치 및 방법 |
CN109992935A (zh) * | 2019-03-15 | 2019-07-09 | 同盾控股有限公司 | 一种源代码保护方法及装置 |
JP2020087033A (ja) * | 2018-11-27 | 2020-06-04 | 株式会社日立システムズ | プログラム生成装置、及びプログラム生成方法 |
CN114064114A (zh) * | 2021-11-19 | 2022-02-18 | 云控智行科技有限公司 | 一种动态库生成方法及装置 |
-
2007
- 2007-08-14 JP JP2007211434A patent/JP2009048259A/ja active Pending
Cited By (8)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
KR20100108054A (ko) * | 2009-03-27 | 2010-10-06 | 삼성전자주식회사 | 복수의 프로세서들을 포함하는 시스템 장치 및 그 변수 선언 및 사용 방법 |
KR101592974B1 (ko) | 2009-03-27 | 2016-02-12 | 삼성전자주식회사 | 복수의 프로세서들을 포함하는 시스템 장치 및 그 변수 선언 및 사용 방법 |
KR101588027B1 (ko) * | 2014-10-10 | 2016-01-25 | (주)씽크포비엘 | 소프트웨어 현지화를 위한 테스트 케이스 생성 장치 및 방법 |
JP2020087033A (ja) * | 2018-11-27 | 2020-06-04 | 株式会社日立システムズ | プログラム生成装置、及びプログラム生成方法 |
JP7059165B2 (ja) | 2018-11-27 | 2022-04-25 | 株式会社日立システムズ | プログラム生成装置、及びプログラム生成方法 |
CN109992935A (zh) * | 2019-03-15 | 2019-07-09 | 同盾控股有限公司 | 一种源代码保护方法及装置 |
CN109992935B (zh) * | 2019-03-15 | 2021-05-25 | 同盾控股有限公司 | 一种源代码保护方法及装置 |
CN114064114A (zh) * | 2021-11-19 | 2022-02-18 | 云控智行科技有限公司 | 一种动态库生成方法及装置 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US10223082B2 (en) | Analysis of dynamic elements in bounded time | |
JP5019578B2 (ja) | 記憶装置に記憶されたコンテンツのバージョンを更新する方法およびシステム | |
US8185878B2 (en) | Program maintenance support device, program maintenance supporting method, and program for the same | |
JP2009048259A (ja) | プログラム変換方法及び変換用プログラム | |
US6519768B1 (en) | Instruction translation method | |
JP2021184246A (ja) | 命令変換支援プログラム、命令変換支援方法および情報処理装置 | |
JP2009104252A (ja) | デバッグ支援装置およびデバッグ支援方法 | |
JPH0934698A (ja) | ソフトウェア生成方法及び開発支援方法 | |
JP7059757B2 (ja) | Api処理方法、端末、api処理プログラム | |
CN112487019A (zh) | 用于OpenGauss数据库的解析动态SQL的方法及*** | |
JP2009053767A (ja) | プログラム解析装置、および、プログラム解析方法 | |
JP2005063121A (ja) | ソースコード変換装置、及びソースコード変換方法、ソースコード変換プログラム、記憶媒体 | |
JP2609820B2 (ja) | プログラム管理方法 | |
JP3260264B2 (ja) | 高水準言語レベルでのパッチ作成・運用方法 | |
US20030200529A1 (en) | Symbolic assembly language | |
JP7423895B2 (ja) | ラダー図プログラム作成支援装置、ラダー図プログラム作成支援方法、およびラダー図プログラム作成支援プログラム | |
JP2006323609A (ja) | プログラマブルコントローラ | |
JP2001236243A (ja) | デバッグ方法、および、デバッグ用プログラムを記録した記録媒体 | |
JP5109808B2 (ja) | 追加実行可能情報生成装置、情報処理装置、及びプログラム | |
JP2016151973A (ja) | 制御コントロールシステム、その開発支援装置、制御装置 | |
JPH05265742A (ja) | プログラムパッチ方式 | |
CN116737162A (zh) | 一种代码编译方法、装置、电子设备及介质 | |
JP3942546B2 (ja) | 処理プログラム | |
JP2607975B2 (ja) | デバック方式 | |
JP2022119668A (ja) | コード変更方法及びコード変更プログラム |