説明

動的型付け言語で記述されたソースコードを静的型付け言語で記述されたターゲットコードに変換し、実行する方法、並びにそのコンピュータ・プログラム及びコンピュータ・システム

【課題】動的型付け言語で記述されたソースコードを静的型付け言語のターゲットコードに変換する方法を提供する。
【解決手段】ソースコードからターゲットコードを記憶装置中に生成するステップであって、ソースコード中の呼び出し元で用いる関数/メソッドのシグネチャをバッファに格納するステップを含み、上記呼び出し元を生成するために必要なクラスであって、静的型付け言語のインタフェースを担当する当該クラス(以下、インタフェース担当クラス)の生成は、上記呼び出し元の関数/メソッド呼び出しのターゲットコードが実行される直前まで遅延される、上記生成するステップと、上記バッファに格納された全てのシグネチャに対応する1つのインタフェース担当クラスを上記記憶装置中に生成し、ロードするステップとを含む。上記バッファ中の全てのシグネチャは、上記1つのインタフェース担当クラスの生成に応じて削除される。

【発明の詳細な説明】
【技術分野】
【0001】
本発明は、動的型付け言語で記述されたソースコードを静的型付け言語で記述されたターゲットコードに変換し、実行する方法、並びにそのコンピュータ・プログラム及びコンピュータ・システムに関する。
【背景技術】
【0002】
近年、Webサーバ等において、例えばPHP及びRubyのような動的型付け言語が広く使用されている。当該スクリプトは、通常、インタプリタ方式で実行されることが多い。しかし、応用によっては、高速な実行を可能にするために、当該スクリプトを例えばJava(商標)仮想マシン(JavaVM)上で直接的に動作するバイトコードに変換して実行したい場合がある。このような場合に、動的型付け言語で記述されたソースコードをJava(商標)のような静的型付け言語で記述されたターゲットコードに変換する際に、メソッド/関数の呼び出し元を効率的に実行することは難しい。特に、現実的には、ソースコードの実行時に、上記スクリプト・ファイルをコンパイルしていくことが必要であり、そのコンパイルの効率的な方法が問題となる。この問題は、主に下記の2つの理由により生じている。第1に、Java(商標)のような静的型付け言語には、単独で定義される関数が存在しない。そのために、動的型付け言語の関数/メソッドごとにJava(商標)のクラスを用意する必要があるためである。第2に、動的型付け言語のプログラムにおいては一般に、呼び出し元の関数/メソッドを変換する際に、その呼び出し先の型を特定できないためである。Java(商標)のReflection APIのようなリフレクション機構を使用すれば、簡単に変換できる。しかしながら、当該リフレクション機構は、実行時に、リフレクションによる大きなオーバヘッドを生じさせる。
【発明の概要】
【発明が解決しようとする課題】
【0003】
上記リフレクション機構の使用を避けるために使われる方法として、動的型付け言語の関数/メソッドの実体ごとに実装を担当するクラスを用意し、固定のインタフェースを担当する特定のクラスを通じて呼び出せるようにする方法がある。しかしながら、当該方法では、呼び出し先の関数/メソッドの実装のために、関数/メソッドごとの数多くのクラスを用意しなければならない。そのため、上記クラス自体を記述するのに必要なメタ情報のために余分なメモリが積算されてしまい、結果としてJavaVMなどの実行系の大きなメモリ領域を消費してしまうという不都合がある。
【0004】
そこで、動的型付け言語で記述されたソースコードを静的型付け言語で記述されたターゲットコードに変換し、実行する際に、メモリ消費を抑える方法が求められている。
【課題を解決するための手段】
【0005】
本発明は、動的型付け言語で記述されたソースコードを静的型付け言語で記述されたターゲットコードに変換する方法を提供する。当該方法は、コンピュータに下記ステップを実行させることを含む。当該ステップは、
上記ソースコードから上記ターゲットコードを記憶装置中に生成するステップであって、上記ソースコード中の呼び出し元で用いる関数/メソッドのシグネチャをバッファに格納するステップをさらに含み、上記呼び出し元を生成するために必要なクラスであって、静的型付け言語のインタフェースを担当する当該クラス(以下、インタフェース担当クラスともいう)の生成は、上記呼び出し元の関数/メソッド呼び出しのターゲットコードが実行される直前まで遅延される、上記生成するステップと、
上記バッファに格納された全てのシグネチャに対応する1つのインタフェース担当クラスを上記記憶装置中に生成し、ロードするステップであって、当該生成に応じて上記バッファ中の全てのシグネチャが削除される、上記生成し、ロードするステップと
を含む。
【0006】
本発明の1つの実施態様では、上記方法がコンピュータは、コンピュータに下記ステップをさらに実行させることを含む。当該ステップは、
上記ソースコードに対応するターゲットコード中の関数/メソッドの呼び出し命令が実行されるときに、上記呼び出し元で用いられている関数/メソッドのシグネチャに対応するクラスであって、動的型付け言語における呼び出し先の関数/メソッドに対応する実装を担当する当該クラス(以下、実装担当クラスともいう)を上記記憶装置中に生成し、ロードするステップを含む。
【0007】
本発明はまた、動的型付け言語で記述されたソースコードを静的型付け言語で記述されたターゲットコードに変換するコンピュータを提供する。当該コンピュータは、
上記ソースコードから上記ターゲットコードを記憶装置中に生成する生成部であって、当該生成部は上記ソースコード中の呼び出し元で用いる関数/メソッドのシグネチャをバッファに格納し、及び上記呼び出し元を生成するために必要なクラスであって、静的型付け言語のインタフェースを担当する当該クラス(インタフェース担当クラス)の生成は、上記呼び出し元の関数/メソッド呼び出しのターゲットコードが実行される直前まで遅延される、上記生成部と、
上記バッファに格納された全てのシグネチャに対応する1つのインタフェース担当クラスを上記記憶装置中に生成し、ロードする第1の処理部であって、当該生成に応じて上記バッファ中の全てのシグネチャが削除される、上記第1の処理部と
を含む。
【0008】
本発明の1つの実施態様では、上記コンピュータは、上記ソースコードに対応するターゲットコード中の関数/メソッドの呼び出し命令が実行されるときに、上記呼び出し元で用いられている関数/メソッドのシグネチャに対応するクラスであって、動的型付け言語における呼び出し先の関数/メソッドに対応する実装を担当する当該クラス(実装担当クラス)を生成し、ロードする第2の処理部をさらに含む。
【0009】
本発明の1つの実施態様では、上記シグネチャをバッファに格納することが、上記ソースコード内の同じ変換単位中に現れる呼び出し元の関数/メソッドのシグネチャに加えて、上記ソースコード内の別の変換単位中に現れる関数/メソッドのシグネチャを上記バッファ中に格納することをさらに含む。
【0010】
本発明の1つの実施態様では、上記ソースコードから上記ターゲットコードを生成することが、上記ソースコード中の呼び出し元の関数/メソッド呼び出しの生成処理を含む。
【0011】
本発明の1つの実施態様では、上記関数/メソッド呼び出しの生成処理が、
上記呼び出している関数/メソッドに対応するインタフェース担当クラスが生成済みかどうかを検査すること、
当該インタフェース担当クラスが生成済みでない場合に、上記呼び出している関数/メソッドのシグネチャを呼出関数リストに追加すること、
上記バッファに対応付けられた名前により、未生成のインタフェース担当クラスで型付けされた対象オブジェクトに対する関数/メソッド呼び出しのコードを上記記憶装置中に生成すること
を含む。
【0012】
本発明の1つの実施態様では、上記関数/メソッド呼び出しの生成処理が、
上記呼び出している関数/メソッドに対応するインタフェース担当クラスが生成済みかどうかを検査すること、
当該インタフェース担当クラスが生成済みである場合に、当該生成済みのインタフェース担当クラスで型付けされた対象オブジェクトに対する上記関数/メソッド呼び出しのコードを上記記憶装置中に生成すること
をさらに含む。
【0013】
本発明の1つの実施態様では、上記ソースコードから上記ターゲットコードを生成することが、上記ソースコード中の呼び出し元の関数/メソッド宣言の生成処理を含む。
【0014】
本発明の1つの実施態様では、上記関数/メソッド宣言の生成処理が、
宣言されている関数/メソッドに対応するシグネチャがバッファ中にあるか、又はインタフェース担当クラスが生成済みであるか否かを検査すること、
上記宣言されている関数/メソッドに対応するシグネチャがバッファ中にない場合で、且つ、上記インタフェース担当クラスが生成済みでない場合に、宣言している関数/メソッドのシグネチャを宣言関数リストに追加すること
を含む。
【0015】
本発明の1つの実施態様では、上記関数/メソッド宣言の生成処理が、
宣言されている関数/メソッドに対応するシグネチャがバッファ中にあるか、又はインタフェース担当クラスが生成済みであるか否かを検査すること、
上記宣言されている関数/メソッドに対応するシグネチャがバッファ中にない場合、又は、上記インタフェース担当クラスが生成済みでない場合に、対応するインタフェース担当クラスの名前を宣言インタフェース・リストに追加すること
を含む。
【0016】
本発明の1つの実施態様では、上記関数/メソッド宣言の生成処理が、
上記宣言されている関数/メソッドの処理のスクリプトのバイトコードを上記記憶装置中に生成すること、
上記生成したバイトコードを宣言している関数/メソッドに対応させるコードを上記記憶装置中に生成することをさらに含む。
【0017】
本発明の1つの実施態様では、上記インタフェース担当クラスを生成し、ロードすることが、
宣言関数リストが空であるか否かを検査すること、
上記宣言関数リストが空でない場合に、宣言インタフェース・リスト中に、バッファに対応付けられたインタフェース担当クラスの名前があるか否かを検査すること、
上記バッファに対応付けられたインタフェース担当クラスの名前がある場合に、宣言関数リスト及び呼出関数リスト中のシグネチャを上記バッファに追加すること
をさらに含む。
【0018】
本発明の1つの実施態様では、上記インタフェース担当クラスを生成し、ロードすることが、
上記追加されたシグネチャから1つのインタフェース担当クラスを上記記憶装置中に生成し、ロードすること、
上記ロードされたインタフェース担当クラスの名前を宣言インタフェース・リストに追加すること
をさらに含む。
【0019】
本発明の1つの実施態様では、上記インタフェース担当クラスを生成し、ロードすることが、
宣言関数リストが空であるか否かを検査すること、
上記宣言関数リストが空でない場合に、宣言インタフェース・リスト中に、バッファに対応付けられたインタフェース担当クラスの名前があるか否かを検査すること、
上記バッファに対応付けられたインタフェース担当クラスの名前がない場合に、宣言関数リスト中のシグネチャから、上記バッファとは独立した統合インタフェース担当クラスを生成及びロードすること、
上記ロードされたインタフェース担当クラスの名前を宣言インタフェース・リストに追加すること
をさらに含む。
【0020】
本発明の1つの実施態様では、上記インタフェース担当クラスを生成し、ロードすることが、
宣言関数リストが空であるか否かを検査すること、
上記宣言関数リストが空である場合に、上記呼出関数リスト中のシグネチャを上記バッファに追加すること
をさらに含む。
【0021】
本発明の1つの実施態様では、上記実装担当クラスを生成し、ロードすることが、上記ソースコードの変換単位に実装が存在しないシグネチャを持つ関数のダミーの実装を上記実装担当クラス中に用意することをさらに含む。
【0022】
本発明の1つの実施態様では、上記コンピュータは、上記変換されたターゲットコードを実行する実行部をさらに含む。
【0023】
本発明の1つの実施態様では、上記実行することが、
上記バッファ中のシグネチャ全てに対応する統合インタフェース担当クラスが利用されている場合に、当該ロードを要求すること、
当該要求に応じて、バッファ中の全てのシグネチャから1つの統合インタフェース担当クラスを生成し、ロードすること
をさらに含む。
【0024】
本発明はさらに、コンピュータに、上記方法のいずれか1つに記載の方法の各ステップを実行させるコンピュータ・プログラムを提供する。
【発明の効果】
【0025】
本発明の実施態様によれば、動的型付け言語で記述されたソースコードを静的型付け言語のターゲットコードに変換し、実行する際に、メモリ消費量を抑えることができ、ひいては効率的なシステム構築を可能にする。
【図面の簡単な説明】
【0026】
【図1A】変換の対象となりうるPHP言語で記述されたPHPソースコード(start.php、funcs.php)の例を示す。
【図1B】図1AのPHPソースコード(start.php)から、1スクリプト・ファイル1クラス方式により生成されるJava(商標)クラス(Bytecode_start_php)の概要を示す。
【図1C】図1AのPHPソースコード(funcs.php)から、1スクリプト・ファイル1クラス方式により生成されるJava(商標)クラス(Bytecode_funcs_php)の概要を示す。
【図2A】図1AのPHPソースコード(start.php)から1関数1クラス方式により生成されるJava(商標)の実装を担当するクラス(Bytecode_start_php)の概要を示す。
【図2B】図1AのPHPソースコード(funcs.php)から1関数1クラス方式により生成されるJava(商標)の実装を担当するクラス群(Bytecode_funcs_php、Bytecode_funcs_php_foo、Bytecode_funcs_php_bar)の概要を示す。
【図2C】図1AのPHPソースコード(start.php)から1関数1クラス方式により生成される実装担当クラス、及びソースコードのターゲットコードへの変換並びにその実行の各ステップを示す。
【図3A】図1AのPHPソースコードから1関数1インタフェース方式により生成される実装担当クラス並びにインタフェース担当クラス、及びソースコードのターゲットコードへの変換並びにその実行の各ステップを示す。
【図3B】図1AのPHPソースコードから1関数1インタフェース方式により生成される、foo()用のインタフェース担当クラス及びbar()用のインタフェース担当クラスの概要を示す。
【図3C】図1AのPHPソースコードから1関数1インタフェース方式により生成される実装担当クラスBytecode_start_phpの概要を示す。
【図3D】図1AのPHPソースコードから1関数1インタフェース方式により生成される実装担当クラスBytecode_funcs_phpの概要を示す。
【図4A】図1AのPHPソースコードから複数関数1インタフェース方式により生成される実装担当クラス並びにインタフェース担当クラス、及びソースコードのターゲットコードへの変換並びにその実行の各ステップを示す。
【図4B】図1AのPHPソースコードから複数関数1インタフェース方式により生成される、foo()及びbar()共用の統合インタフェース担当クラスの概要を示す。
【図4C】図1AのPHPソースコードから複数関数1インタフェース方式により生成される実装担当クラスBytecode_start_phpの概要を示す。
【図4D】図1AのPHPソースコードから複数関数1インタフェース方式により生成される実装担当クラスBytecode_funcs_phpの概要を示す。
【図5】1関数1クラス方式(図2A〜図2C)、1関数1インタフェース方式(図3A〜図3D)及び複数関数1インタフェース方式(図4A〜図4C)により生成されるインタフェース担当クラスの違いを示す。
【図6A】1関数1インタフェース方式に従うバイトコード生成処理のフロー図を示す。
【図6B】図6Aの関数/メソッド呼び出しの生成処理(ステップ614)及び関数/メソッド宣言の生成処理(ステップ616)の詳細なフロー図を示す。
【図6C】複数関数1インタフェース方式に従うバイトコード生成処理のフロー図を示す。
【図6D】図6Cの関数/メソッド呼び出しの生成処理(ステップ654)及び関数/メソッド宣言の生成処理(ステップ656)の詳細な処理フロー図を示す。
【図6E】図6Cのステップ643におけるバッファの処理の詳細な処理フロー図を示す。
【図6F】図6Cのステップ645−2における未ロードの統合インタフェース担当クラスの生成及びロードの詳細な処理フローを示す。
【図7】本発明の実施態様における、シグネチャ・インタフェース登録のデータ構造を示す。
【図8A】変換対象となりうるPHP言語で記述されたPHPソースコード(start.php、caller.php及びfuncs.php)があり、関数/メソッド呼び出しより先に関数/メソッド宣言がなされた例を示す。
【図8B】図8Aに示すソースコードを複数関数1インタフェース方式により生成される実装担当クラス並びにインタフェース担当クラス、及びソースコードのターゲットコードへの変換及び実行の各ステップを示す。
【図9A】変換対象となりうるPHP言語で記述されたPHPソースコード(start.php、foo.php、bar.php)があり、未定の関数が現れる例を示す。
【図9B】図9Aに示すソースコードを複数関数1インタフェース方式により生成される実装担当クラス並びにインタフェース担当クラス、及びソースコードのターゲットコードへの変換並びにその実行の各ステップを示す。
【図10A】CRM(Customer Relationship Management)アプリケーションに対して、インタフェース担当クラスの数を削減した結果による効果の例を示す。
【図10B】図10Aに示すPHPソースコードにおける関数/メソッドの呼び出し元と呼び出し先との関係、及びファイル取り込み指示命令と指示されたファイルとの関係を示す。
【図10C】図10Aに示すPHPソースコードをJava(商標)のバイトコードに変換した場合の変換及び実行ステップ、並びに各関数/メソッドの生成、宣言及び呼び出し実行の時系列を示す。
【図10D】図10Aに示すPHPソースコードを1関数1クラス方式により変換した場合の実装担当クラスを、図10Cに記載の時系列とともに示す。
【図10E】図10Aに示すPHPソースコードを1関数1インタフェース方式により変換した場合の実装担当クラスを、図10Cに記載の時系列とともに示す。
【図10F】図10Aに示すPHPソースコードを複数関数1インタフェース方式により変換した場合の実装担当クラスを、図10Cに記載の時系列とともに示す。
【図11A】本発明の実施態様における、動的型付け言語で記述されたソースコードを静的型付け言語で記述されたターゲットコードに変換するためのシステム図を示す。
【図11B】本発明の実施態様における、変換された結果としての実行オブジェクトと実行ヘルパーとの関係を示す。
【図11C】本発明の実施態様における、バイトコード生成部及びシグネチャ・インタフェース登録部を示す図である。
【図12】本発明の実施態様における、図11Aのシステムが備えているコンピュータ・ハードウェアのブロック図を示す。
【図13A】図2Cの変換及び実行ステップにおける処理の包含関係を示す。
【図13B】図3Aの変換及び実行ステップにおける処理の包含関係を示す。
【図13C】図4Aの変換及び実行ステップにおける処理の包含関係を示す。
【図13D】図8Bの変換及び実行ステップにおける処理の包含関係を示す。
【図13E】図9Bの変換及び実行ステップにおける処理の包含関係を示す。
【発明を実施するための形態】
【0027】
特許請求の範囲及び明細書において用いている語について以下に説明をする。
【0028】
本発明の実施態様において、「動的型付け言語」とは、変数の型がプログラミング時及びコンパイル時には決まらず、実行時になって決まる言語をいう。動的型付け言語は、例えばスクリプトで記述される。動的型付け言語は、例えばPHP、Ruby、JavaScript(商標)、Python、及びVisualBasic(商標)であるが、これらに限定されない。
本発明の実施態様において、「ソースコード」とは、動的型付け言語で記述されたプログラム・コードであって、変換の対象となるコードをいう。ソースコードは、スクリプトで記述されたコードであってもよい。
本発明の実施態様において、「静的型付け言語」とは、変数の型がプログラミング時又はコンパイル時に予め決まっている言語をいう。静的型付け言語は、例えば.NET、Java(商標)、及びC++であるが、これらに限定されない。
本発明の実施態様において、「ターゲットコード」とは、ソースコードを変換して得られる目的コードである。ターゲットコードは、中間コード又は機械語を含む。例えばJava(商標)の場合、中間コードはバイトコードである。
本発明の実施態様において、「関数/メソッド」とは、言語によっても多少の違いはあるが、変換元の動的型付け言語及び変換先の動的型付け言語における関数/メソッドの定義がそのまま適用される。例えば、オブジェクト指向の定義では、関数とはメソッドの実装であり、メソッドとはオブジェクトに送られてきたメッセージを処理するものである。
本発明の実施態様において、「呼び出し元」とは、関数/メソッドを呼び出す側をいう。
本発明の実施態様において、「呼び出し先」とは、関数/メソッドを呼び出される側をいう。
本発明の実施態様において、「シグネチャ」とは、変換対象である呼び出し元で関数/メソッドを指定するシグネチャであり、関数/メソッドの名前と引数(パラメータ)の数をいう。動的型付け言語のシグネチャであるので、変数の型は不要である。また、静的型付け言語でもオプションであるような言語の場合には、型があってもよい。
本発明の実施態様において、「インタフェースを担当するクラス」(インタフェース担当クラス)とは、ソースコード中の呼び出し元を生成するために必要であり、静的型付け言語のインタフェース担当クラスをいう。また、インタフェース担当クラスでは、関数/メソッドのみ定義され、その動作を具体的に実現するコードが実装されていない。例えばJava(商標)の場合、インタフェースがインタフェース担当クラスに該当する。インタフェース担当クラスの生成は、本発明の実施態様において、ソースコード中の呼び出し元の関数/メソッド呼び出し命令が実行されるまで生成されず、すなわちソースコード中の呼び出し元の関数/メソッド呼び出しのターゲットコードが実行される直前まで遅延される。言い換えれば、インタフェース担当クラスは、呼び出しのターゲットコードが実行される直前又はそれより前に生成される。呼び出しのターゲットコードが実行される前とは、例えばJava(商標)の場合仮想マシンの実装に依存する。当該呼び出しのターゲットコードは、呼び出し元を含むコードであり、例えばJava(商標)の場合はメソッド本体である。
本発明の実施態様において、「実装を担当するクラス」(実装担当クラス)とは、ソースコード中の呼び出し元で用いられている関数/メソッドのシグネチャに対応し、動的型付け言語における呼び出し先の関数/メソッドに対応する実装を担当するクラスをいう。また、実装担当クラスでは、関数/メソッド及び変数の動作を具体的に実現するコードが実装されている。例えばJava(商標)の場合、抽象的クラスでなく、インタフェースで定義された関数/メソッドを全て実装するクラスが実装担当クラスに該当する。実装担当クラスからは、実行に必要なインスタンスが生成されプログラムが実行される。実装担当クラスの生成は、本発明の実施態様において、ソースコードに対応するターゲットコード中の関数/メソッドの呼び出し命令が実行されるときに行われる。
本発明の実施態様において、「変換、実行」とは、動的型付け言語のソースコードから静的型付け言語のターゲットコードに変換し、当該変換されたターゲットコードを実行することをいう。本発明の実施態様において、当該「変換」をコンパイルともいう。当該実行において、インタフェース担当クラスと、実装担当クラスとが使用される。
【0029】
以下、図面に従って、本発明の実施態様を説明する。本実施態様は、本発明の好適な態様を説明するためのものであり、本発明の範囲をここで示すものに限定する意図はないことを理解されたい。また、以下の図を通して、特に断らない限り、同一の符号は、同一の対象を指す。
【0030】
以下では、動的型付け言語としてPHP、静的型付け言語としてJava(商標)を取り上げるが、本発明はこれらに限定されるものでない。
【0031】
図1Aは、変換の対象となりうるPHP言語で記述されたPHPソースコード(start.php、funcs.php)の例を示す。
上記PHPソースコードは、2つのソースコードのファイルstart.php(101)及びfuncs.php(102)で構成されている。矢印103は、ファイルstart.php(101)のソースコード中の取り込み命令includeと、当該取り込み命令で指定されたファイルfuncs.php(102)との対応関係を示す。矢印104は、呼び出し元の関数foo()と呼び出し先の宣言及び定義された関数の対応関係を示す。同様に、矢印105は、呼び出し元の関数bar()と呼び出し先の宣言及び定義された関数の対応関係を示す。なお、これらのファイルを動的型付け言語で記述されたファイルという意味で、スクリプト・ファイルと呼ぶこともある。
【0032】
次に、図1AのPHPソースコード(start.php、funcs.php)を用いて、当該ソースコードをバイトコードに変換する際の従来技術の問題点を述べる。
PHPのような動的型付け言語で記述されたソースコードを、Java(商標)のような静的型付け言語のバイトコードに変換し、実行する際に、シンボル・テーブルのふるまいの違いが問題になる。シンボルとは、変数、クラス、メソッド、関数の名前を特定する文字列である。シンボル・テーブルとは、当該シンボルとシンボルが指す変数又はクラスなどの実体との対応を格納したテーブルである。特に、変換先の言語であるJava(商標)のクラス数の削減のために、PHPで記述された複数の関数/メソッドの実装を1つのコンパイル単位であるJava(商標)のクラスに収めようとすると、その効率的な実装方法は自明でない。
例えば、図1Aの2つのPHPソースコードの各ファイル(101、102)がJava(商標)の各クラスに対応するようにコンパイルする例を考えてみる。
PHPのソースコード中の1つの関数/メソッド当たり、Java(商標)の1つのクラスを割り当てる方式を考えてみる。当該方法を、以下、1関数1クラス方式という。1関数1クラス方式については、図2A〜図2Cにおいて詳述する。1関数1クラス方式では、非常に多くのクラスの生成と、そのロードが必要である。そのために、メモリフットプリントの増加乃至はクラス管理上のオーバヘッドの問題が生じる。
一方、PHPのソースコード中の1つのスクリプト・ファイル当たり、Java(商標)の1つのクラスを割り当てる方式を考えてみる。当該方法を、以下、1スクリプト・ファイル1クラス方式という。1スクリプト・ファイル1クラス方式においては、図1B及び図1Cに示されるように、PHPソースコード(start.php(101)及びfuncs.php(102))それぞれに対応して、Java(商標)の2つの実装担当Bytecode_start_php(111、図1B)及びBytecode_funcs_php(112、図1C)というをそれぞれ生成する。なお、当該Javaクラスの名前は適当に付けられたものである。
【0033】
図1Bは、図1AのPHPソースコード(start.php)から、1スクリプト・ファイル1クラス方式により生成されるJava(商標)クラス(Bytecode_start_php)(111)の概要を示す。
図1Cは、図1AのPHPソースコード(funcs.php)から、1スクリプト・ファイル1クラス方式により生成されるJava(商標)クラス(Bytecode_funcs_php)(112)の概要を示す。
図1B及び図1Cでは、Java(商標)クラス(Bytecode_start_php、Bytecode_funcs_php)(111、112)を可読性のためにJava(商標)のソースコードで示す。しかし、実際には、上記Java(商標)クラス(Bytecode_start_php、Bytecode_funcs_php)(111、112)は、同等のJavaバイトコードで記述されている。
【0034】
実行は、図1BのJava(商標)クラスBytecode_start_php(111)のメソッドexecuteScript()の呼び出し(A02)から始まる。同図3行目(A03)のinclude命令は、ファイルfuncs.php(102)を指定し取り込むことの命令である。図1CのJava(商標)クラスBytecode_funcs_php(112)は、図1Aに示すファイルfuncs.php(102)に対応する。上記include命令(A03)により、図1CのJava(商標)クラスBytecode_funcs_php(112)の2行目(B02)のメソッドexecuteScript()が呼び出される。なお、図1Cの8行目(B08)の「PHPValue」は、PHPプログラムで扱われる値を保持するためのクラスを示す。
【0035】
図1Bにおいて問題となるのは、4行目(A04)及び5行目(A05)のfoo()及びbar()の呼び出しの実装である。PHPプログラムでは、関数/メソッド宣言を含むスクリプトの実行(図1Cの3行目及び4行目)により、初めてその宣言されている名前で呼び出される関数/メソッドの実装が確定する。従って、各関数を静的(static)メソッドとして実装して、図1Bのfoo()又はbar()の呼び出しを、静的メソッド呼び出し(例えばinvokestatic命令)により単純に呼び出すようにすることは一般にはできない。なぜならば、それまでの実行状況により、どのような関数/メソッドが実際の呼び出し対象となるかは変わってくるためである。ある特定の呼び出し先を仮定して呼び出しコードを生成してしまうと、別のリクエストの処理の際に異なる関数宣言がなされた場合などに対応できなくなる。さらに、上記例の場合などにおいて、呼び出し元のスクリプト・ファイルstart.php(101)に対応する実装担当クラス(111)を実際に動作させてみるまで、すなわちinclude先のfuncs.phpを読み込んで動作させてみるまで呼び出し先が分からないことも多い。このような問題は、Java(商標)のリフレクション機構を使用するか、或いは実直に宣言のたびにクラス・ロードを行うことにより対応可能にはなる。しかしながら、これらは、莫大な実行時オーバヘッドを伴う。
【0036】
これらは、本質的には、PHP、Ruby等のスクリプト言語と、Java(商標)言語との間で、シンボル解決の作法が違う点に起因している。Java(商標)では、あるシンボルに対応するクラス又はメソッドの実体の定義のありかが、クラス・パスを通して暗黙的に特定のクラス・ファイルに定まる。また、Java(商標)では、Servletなどの標準的なサーバ側アプリケーションのプログラムは、その対応関係が複数のリクエスト処理に渡って同じであることを前提にして書かれるようになっている。一方、PHP、Ruby等では、各リクエスト処理のたびに、あるシンボルへの実体の対応を行うステップを踏むようになっており、それらアプリケーションのプログラムもそのように書かれる。あるシンボルへの実体の対応を行うステップを踏むとは、上記例のdeclare function相当である。
【0037】
図2A〜図2Cは、1関数1クラス方式を示す。
Java(商標)の上記リフレクション機構を使用しない典型的な方法は、Java(商標)のメソッド呼び出し機構を利用するものである。当該メソッド呼び出し機構を利用する方法では、PHPFunctionなどの固定のインタフェース(又は抽象クラス)によりインタフェースを担当するクラスを決め、PHPの関数ごとに当該インタフェースを実装(implements)する1つの実装担当クラスを生成する。そして、関数/メソッド呼び出しは、図2Aに示すように常に当該インタフェースを通して行うようにする方法である。しかしながら、1関数1クラス方式により生成されるバイトコードは、図2Bに示すように、1つのスクリプトであるfuncs.phpから実装担当クラスが多数できてしまう。
1関数1クラス方式を図1Aに示したPHPソースコード(start.php、funcs.php)に適用した例を図2A〜図2Cに示す。
【0038】
図2Aは、図1AのPHPソースコード(start.php)から1関数1クラス方式により生成されるJava(商標)の実装担当クラス(Bytecode_start_php)の概要を示す。当該クラスの名前は適当に付けられたものである。また、当該実装担当クラスを可読性のためにJava(商標)のソースコードで示す。しかし、実際には、上記Java(商標)の実装担当クラス(Bytecode_start_php)(201)は、同等のJava(商標)バイトコードで記述されている。
実装担当クラス(Bytecode_start_php)(201)は、PHPのファイルstart.php(101)に対応して生成されたバイトコードである。
図2Aの5行目(C05)のconstant_Helloは、変換前の元のPHPプログラム(図1Aの101を参照)の”Hello”に相当する文字列リテラルを表すコンスタントであり、クラス変数などとして実装されている。関数呼び出しの実装bar()の引数は、元のPHPプログラム(101)に応じて様々なものをとることができ、また、その返り値も様々な使われ方がされる。しかしながら、これらは本発明には直接的に関係しないので、ここではその説明を省略する。
【0039】
図2Bは、図1AのPHPソースコード(funcs.php)から1関数1クラス方式により生成されるJava(商標)の実装担当クラス群(Bytecode_funcs_php、Bytecode_funcs_php_foo、Bytecode_funcs_php_bar)の概要を示す。当該実装担当クラス群は、それぞれ別のクラス・ファイルである。当該クラスの名前は適当に付けられたものである。また、当該実装担当クラスを可読性のためにJava(商標)のソースコードで示す。しかし、実際には、上記Java(商標)の実装担当クラス群(202、203、204)は、同等のJava(商標)バイトコードで記述されている。
図2Bに示すように、1関数1クラス方式による変換では、PHPの1つのファイルfuncs.php(102)に対応して、Java(商標)の3つの実装担当クラスBytecode_funcs_php(202)、Bytecode_funcs_php_foo(203)及びBytecode_funcs_php_bar(204)が生成される。すなわち、1つのスクリプト・ファイルから多数の実装担当クラスが生成される。多数の実装担当クラスの生成及びロードには多くのメモリが必要である。そのために、多数の実装担当クラスを生成し及びロードすることは、メモリフットプリントの増加乃至はクラス管理上のオーバヘッドの問題を生じる。
【0040】
図2Cは、図1AのPHPソースコード(start.php)から1関数1クラス方式により生成される実装担当クラス、及びソースコードのターゲットコードへの変換並びにその実行の各ステップを示す。
図2Cにおいて、左側が変換及び実行の各ステップ(E01〜E12)を示す。同右側が、1関数1クラス方式により生成される実装担当クラス(211、212、213及び214)を示す。すなわち、1関数1クラス方式では、ソースコード中の関数ごとに、1つのクラスが用意されている。さらに、同右側は、実装担当クラス(211)の関数executeScript()実装内容の一部として固定インタフェースを通じてinvoke()を呼び出している様子(215)を示す。実装担当クラスは、ボックス(211、212、213及び214、215)で示される。実装担当クラスの左側に付された矢印内の番号(E02及びE05)は上記ステップのステップ番号に対応する。
図2Cの実装を担当するクラスは、共通インタフェースを担当するクラスを拡張(extends)又は実装(implements)している。共通インタフェースとは、言語システム側で、予め準備して共通に使えるインタフェースである(図2Bの11行目(D11)と21行目(D21)のPHPFunction、及び図2Cの2行目(E02)のthe common interface)。
【0041】
以下、変換及び実行ステップについて説明する。
1行目(E01)では、PHPのファイルstart.php(101)の取り込み命令includeが指示されている。そのサブステップとして2〜12行目(E02〜E12)のステップが実行される。
2行目(E02)では、PHPのファイルstart.php(図1Aの101)中の関数foo()、bar()の呼び出し元の実装担当クラスの生成及びロードが指示されている。該指示に従い矢印(E02)で示されるように、start.phpに対応する実装担当クラスBytecode_start_php(211)が、共通インタフェースで型付けされた対象オブジェクトに対するメソッド呼出しをともなって生成される。該クラスのコードは図2Aに示され、C04行目とC05行目では、共通インタフェースPHPFunctionが、ソースコード上は明記されていないが、バイトコード上はメソッドinvoke()を備えたインタフェースとして指定されている。
3行目(E03)では、ロードされた上記クラスBytecode_start_php(211)の実行が指示される。具体的には、図2Aに示す実装担当クラスBytecode_start_php(201)のステップC02〜C06が実行され、先ずステップC02の命令executeScript()が実行される。
4行目(E04)では、図2AのステップC03の取り込み命令includeが実行され、指定されたファイル funcs.php(図1Aの102)が取り込まれる。
5行目(E05)では、上記指定されたファイル funcs.phpに対応する実装担当クラスの生成及びロードが指示される。該指示に従って、矢印E05に示すようにfuncs.phpに対応する実装担当クラスBytecode_funcs_php(212)が生成及びロードされる。
6行目(E06)では、上記実装担当クラスBytecode_funcs_php(212)の実行が指示される。具体的には、図2Bに示されるBytecode_funcs_php(202)の2行目(D02)のexecuteScript()の実行が行われる。
7行目(E07)では、引き続き、図2Bの3行目(D03)、4行目(D04)の関数foo()及びbar()に対する宣言を行う。該宣言によって各関数の関数名foo及びbarと各関数の実装担当クラスBytecode_funcs_php_foo(203)、Bytecode_funcs_php_bar(204)から作られた関数オブジェクト(実体)が対応付けられる。
8行目(E08)では、上記関数オブジェクトの関数テーブルへの登録を指示する。関数テーブルには、関数シグネチャと関数実体のオブジェクト(例えば、実装を担当するクラスのオブジェクト)との対応付けが記録される。これによって、関数呼び出しと、実際の処理を行う関数オブジェクト(実体)とが対応付けられて、Bytecode_funcs_php(202)の実行が終了する。そしてし、処理は実装担当クラスBytecode_start_php(201)のステップC04に戻る。
9行目(E09)では、上記Bytecode_start_php(201)のステップC04の実行、すなわち関数名fooによる関数foo()の呼び出しが指示される。
10行目(E10)では、上記関数foo()の呼び出しに対応して、E08で関数テーブルへ登録された関数foo()の実行が行われる。
11行目(E11)及び12行目(E12)では、関数bar()に対して上記9行目(E09)、10行目(E10)と同様な実行が行われる。
【0042】
図3A〜図3Cは、各関数に対応する1つのインタフェースを用意する方式(以下、1関数1インタフェース方式)により生成されるインタフェース担当クラスの数の増大を示す。
1関数1インタフェース方式では、各関数/メソッドの呼び出し元ごとに対応するインタフェース担当クラスを用意する。これによって、ターゲットコードにおいて複数の関数/メソッドの実装を1つのJava(商標)クラスにまとめることが可能になる。1関数1インタフェース方式では、PHPの関数/メソッドの実装担当クラスは、必要な関数/メソッドに対応するインタフェース担当クラス(図3Aの301及び302を参照)を全て実装している。また、PHPの関数/メソッドの呼び出し部分は、それに対応するインタフェース担当クラスを通じて呼び出しを行う(図3Aの304を参照)。インタフェース担当クラスを通じての呼び出しは例えばinvoke interfaceであり、当該invoke interfaceは図3Aの304を実際のバイトコードにした場合の例である。
【0043】
図3Aは、図1AのPHPソースコードから1関数1インタフェース方式により生成される実装担当クラス並びにインタフェース担当クラス、及びソースコードのターゲットコードへの変換並びにその実行の各ステップを示す。
図3Aにおいて、左側が変換及び実行の各ステップ(F01〜F13)を示す。同右側が、1関数1インタフェース方式により生成される実装担当クラス(303及び304)及びインタフェース担当クラス(301及び302)を示す。さらに、同右側は、実装担当クラス(303)の実装内容の一部として、インタフェース担当クラスを通じて関数foo()及びbar()を呼び出している様子(307)を示す。すなわち、1関数1インタフェース方式では、呼び出し元の関数/メソッドごとにインタフェース担当クラスが(301、302)用意されており、該インタフェース担当クラス(301、302)に対応して実装担当クラス(303、304)が生成される。実装担当クラス及びインタフェース担当クラスの左側に付された矢印内の番号(F02、F03及びF06)は上記ステップのステップ番号に対応する。
矢印(305及び306)は、実装担当クラス(304)が2つのインタフェース担当クラス(301及び302)を実装していることを示す。
【0044】
図3Bは、図1AのPHPソースコードから1関数1インタフェース方式により生成される、foo()用のインタフェース担当クラス及びbar()用のインタフェース担当クラスの概要を示す。
図3Aのインタフェース担当クラス(301)の概要を、インタフェース担当クラス(311)として示す。同様に、図3Aのインタフェース担当クラス(302)の概要を、インタフェース担当クラス(312)として示す。
インタフェース担当クラス(311)は、foo()用のインタフェース担当クラスである。インタフェース担当クラス(312)は、bar()用のインタフェース担当クラスである。インタフェース担当クラス(311及び312)は、可読性のためにJava(商標)のソースコードで示されている。
【0045】
図3Cは、図1AのPHPソースコードから1関数1インタフェース方式により生成される実装担当クラスの概要を示す。
図3Aの実装担当クラス(303)の概要を、実装担当クラス(321)として示す。実装担当クラス(321)は、PHPソースコード(start.php)(101)に対応する。実装担当クラス(321)は、可読性のためにJava(商標)のソースコードで示されている。
【0046】
図3Dは、図1AのPHPソースコードから1関数1インタフェース方式により生成される実装担当クラスの概要を示す。
図3Aの実装担当クラス(304)の概要を、実装担当クラス(322)として示す。実装担当クラス(322)は、PHPソースコード(funcs.php)(102)に対応する。実装担当クラス(322)は、可読性のためにJava(商標)のソースコードで示されている。
【0047】
以下、図3Aの変換及び実行ステップについて説明する。
1行目(F01)では、PHPソースコードのスクリプト・ファイルstart.php(101)の取り込み命令includeが指示されている。そのサブステップとして2〜13行目(F02〜F13)の各ステップが実行される。
2行目(F02)は、PHPのファイルstart.php(101)中の関数foo()及びbar()の呼び出し元の実装担当クラスの生成及びロードが指示されている。該指示に従い、矢印(F02)で示すようにstart.php(101)に対応する実装担当クラスBytecode_start_php(303)が生成される。該Bytecode_start_php(303)のコードは図3Cの321に示されている。
3行目(F03)では、上記関数foo()及びbar()のそれぞれの呼び出し用のインタフェース担当クラスの生成及びロードが指示されている。該指示に従い、矢印(F03)で示すように、2つのインタフェース担当クラス(301及び302)が生成及びロードされる。なお、該インタフェース担当クラス(301、302)のコードはそれぞれ図3Bの311及び312に示されている。
4行目(F04)では、ロードされている呼び出し元の実装担当クラス(303)の実行が指示されている。それによって、図3Cの実装担当クラスのコード(321)に示されているように、実装担当クラスのステップH02のスクリプト実行命令executeScript()が実行される。
5行目(F05)では、上記ステップH02のスクリプト実行命令executeScript()の実行に応じて、ステップH03の取り込み命令includeが実行され、そして指定されたファイルfuncs.php が取り込まれることを示す。ここで、これまでのstart.php(101)に対応する実装担当クラスBytecode_start_php(303)の実行は中断され、そして新たに取り込まれたPHPファイルfuncs.php(102)に対応する実装担当クラス(304)の生成及びロードに移る。
6行目(F06)では、取り込まれたファイルfuncs.phpに対応する実装担当クラスBytecode_funcs_php(304)のバイトコードの生成及びロードが指示される。該指示に従い、矢印(F06)で示すようにファイルfuncs.phpに対応する実装担当クラス(304)が生成及びロードされる。なお、該実装担当クラス(304)のコードは、図3Dの322に示されている。各インタフェース担当クラスFunction_foo及びFunction_barが実装されて生成される。
7行目(F07)では、上記funcs.phpに対応する実装担当クラス(304、図3Dの322)の実行が指示され、図3Dに示すステップ(I02)のスクリプト実行命令 executeScriptが実行される。以下、9行目(F09)まで当該実装担当クラス(304)の実行が続く。
8行目(F08)では、スクリプト実行命令executeScriptの実行に引き続き、ステップ(I03及びI04)の関数宣言命令declareFunctionが実行されることを示す。上記関数宣言命令declareFunctionの実行によって、関数呼び出しfoo()及びbar()を実行するためのインスタンスが、実装担当クラス(304、図3Dの322)自身から生成される。
9行目(F09)では、関数foo()及びbar()の実行コンテキストへの登録(declareFunction())が行われる。具体的には、上記生成されたインスタンスと関数呼び出しfoo()及びbar()の関数名foo及びbarとが、関数テーブルに対応付けて登録される。関数呼び出しがあると関数テーブルからインスタンスを検索し、該インスタンスが有するメソッドfoo()及びbar()を利用して関数呼び出しを処理するためである。以上で、実装担当クラスBytecode_funcs_php(304)の実行が完了する。そして中断していた実装担当クラスBytecode_start_php(303)の実行に戻る。
10行目(F10)では、変換後のJavaバイトコードを使って関数foo()の呼び出しが行われる。具体的には、中断していた実装担当クラスBytecode_start_php(303)のステップH04(図3Cの321)で示されるように、呼び出し関数名fooから関数テーブルが検索され、対応付けていたインスタンスが見つけられる。
11行目(F11)では、関数foo()の実行を行う。具体的には、上記見つけられたインスタンスが備えているメソッドfoo()(関数foo()に対応)を呼び出し実行することで目的を実現している。このとき、インタフェース担当クラスFunction_foo(301、図3Bの311)で定義されている型に合わせるためインスタンスのキャストが行われる。
12行目(F12)では、変換後のJavaバイトコードを使って関数bar()の呼び出しが行われる。具体的には、中断していた実装担当クラスBytecode_start_php(303)のステップH05(図3Cの321)で示されるように、呼び出し関数名barから関数テーブルが検索され、対応付けていたインスタンスが見つけられる。
13行目(F13)では、関数bar()の実行を行う。具体的には、上記見つけられたインスタンスが備えているメソッドbar()(関数bar()に対応)を呼び出し実行することで目的を実現している。このとき、インタフェース担当クラスFunction_bar(302、図3Bの312)で定義されている型に合わせるためインスタンスのキャストが行われる。
なお、本来はこれに加えて様々なパラメータ数に対応する工夫が必要だがここでは発明に直接関係ないので省略する。
【0048】
以上に説明したように、1関数1インタフェース方式では、呼び出し関数/メソッド毎にインタフェース担当クラスを生成してロードする必要がある。そのために、1関数1インタフェース方式では、上記1関数1クラス方式とは異なり、1関数/メソッドごとに実装担当クラスを用意する必要がなくなる。一方で、1関数1インタフェース方式では、1関数/メソッド毎にインタフェース担当クラスを用意する必要が生じる。従って、結局のところ、全体として多くのインタフェース担当クラスを生成する必要がある。ここで、インタフェース担当クラスは基本的にクラスと同じ特性を持ち、大量のものである。よって、1関数1インタフェース方式は1関数1クラス方式と比べて変わりないといえる。
【0049】
図4A〜図4Dは、本発明の実施態様に従う、複数の呼び出し関数/メソッドを1つの統合インタフェース担当クラスにまとめる方式(以下、複数関数1インタフェース方式)の説明を行う。当該複数関数1インタフェース方式では、単一のコンパイル単位(例えば、ファイル単位)で、生成及びロードされるインタフェース担当クラスを1つの統合インタフェース担当クラスにまとめる。それによって、インタフェース担当クラスの数を削減することが可能であり、消費メモリ量の削減に貢献する。当該統合されたインタフェース担当クラスを、以下において統合インタフェース担当クラスという。
複数関数1インタフェース方式では、ソースコードの複数の関数/メソッドの実装を1つの実装担当クラス中にまとめつつ、インタフェース担当クラスを実装担当クラスとは無関係に、投機的にまとめる。投機的とは、ソースコード中の関数の呼び出しに出会ったときという意味であり、その点においてソースコードに依存する。投機的にインタフェース担当クラスをまとめることによって、生成に必要なインタフェース担当クラスの数を減少させることが可能である。
本発明の実施態様において、動的型付け言語中の呼び出し元の関数/メソッドを、1関数1クラス方式のように静的型付け言語の1クラスに直接対応させるのではなく、静的型付け言語のインタフェース担当クラス(抽象クラス)に対応させる。それによって、呼び出し先の実装担当クラスが未定の場合或いは実行時に変化する場合であっても、効率的な呼び出し元のバイトコードの生成が可能になる。
【0050】
図4Aは、図1AのPHPソースコードから複数関数1インタフェース方式により生成される実装担当クラス並びに統合インタフェース担当クラス、及びソースコードのターゲットコードへの変換並びにその実行の各ステップを示す。
図4Aにおいて、左側が変換及び実行の各ステップ(J01〜J18)を示す。同右側が、複数関数1インタフェース方式により生成される実装担当クラス(403及び404)及び統合インタフェース担当クラス(402)を示す。すなわち、複数関数1インタフェース方式では、複数の関数/メソッドの呼び出し元に対して1つの統合インタフェース担当クラス(402)を生成し、統合インタフェース担当クラス(402)を実装した実装担当クラス(404)が生成される。さらに、同右側は、実装担当クラス(403)の実装内容の一部として統合インタフェースを通じて関数foo()及びbar()を呼び出している様子(406)を示す。実装担当クラス(403及び404)及び統合インタフェース担当クラス(402)の左側に付された矢印内の番号(J02、J03、J05及びJ09)は上記ステップのステップ番号に対応する。
バッファ(401)は、個々の呼び出し元の関数/メソッドのシグネチャを一時的に格納するのに用いる記憶部である。1つの統合インタフェース担当クラスが、当該バッファに格納されていた1以上のシグネチャを用いて生成される。すなわち、統合インタフェース担当クラスは呼び出し元ごとに生成されるのではなく、同じコンパイル単位(例えばスクリプト・ファイル単位)で生成される。バッファ(401)は、図11Aで説明するバイトコード生成部(1106)内、又は他のJava(商標)仮想マシン中のメモリ内に備えてもよい。本発明の実施態様において、バッファは統合インタフェース担当クラスを使用するために使用される。
複数関数1インタフェース方式では、複数の関数/メソッドの呼び出し元に対し、最初は関数/メソッドのシグネチャをバッファに記憶するのみで(401)、直ぐには統合インタフェース担当クラスの生成を行わない。統合インタフェース担当クラスの名前がバッファに対応付けて決められており、当該バッファにコンパイル単位で関数/メソッドのシグネチャが保存される。例えば、同じコンパイル単位(ソースコードファイルなど)中で現れる呼び出し元で使われるその他のシグネチャに加え、スクリプトをインクルードする処理などの解析によって得られる別のコンパイル単位中に現れるシグネチャもバッファにいれておいてよい。例えば、foo()及びbar()以外の関数/メソッドがあればその関数/メソッドのシグネチャをバッファにいれてもよい。呼出元の実装担当クラス(403)を実行する際になって初めて、上記バッファ(401)に格納された全てのシグネチャに対応する1つの統合インタフェース担当クラス(402)を記憶装置中に生成する。そして、当該関数/メソッドの呼び出しが実行されるときに、該1つの統合インタフェース担当クラス(402)を実装する実装担当クラス(404)を生成する。
【0051】
図4Bは、図1AのPHPソースコードから複数関数1インタフェース方式により生成される、foo()及びbar()共用の統合インタフェース担当クラスの概要を示す。
図4Aの統合インタフェース担当クラス(402)の概要を、統合インタフェース担当クラス(411)として示す。統合インタフェース担当クラス(411)は、foo()及びbar()の両方についてのインタフェース担当クラスである。インタフェース担当クラス(411)は、可読性のためにJava(商標)のソースコードで示されている。
【0052】
図4Cは、図1AのPHPソースコードから複数関数1インタフェース方式により生成される実装担当クラスBytecode_start_phpの概要を示す。
図4Aの実装担当クラス(403)の概要を、実装担当クラス(421)として示す。実装担当クラス(421)は、PHPソースコード(start.php)(101)に対応する。実装担当クラス(421)は、可読性のためにJava(商標)のソースコードで示されている。
【0053】
図4Dは、図1AのPHPソースコードから複数関数1インタフェース方式により生成される実装担当クラスBytecode_funcs_phpの概要を示す。
図4Aの実装担当クラス(404)の概要を、実装担当クラス(422)として示す。実装担当クラス(422)は、PHPソースコード(funcs.php)(102)に対応する。実装担当クラス(422)は、可読性のためにJava(商標)のソースコードで示されている。
【0054】
以下、図4Aの変換及び実行ステップについて説明する。
1行目(J01)では、PHPソースコードのスクリプト・ファイルstart.php(図1Aの101)の取り込み命令includeが指示されている。そのサブステップとして2〜18行目(J02〜J18)の各ステップが実行される。
2行目(J02)は、PHPのファイルstart.php(図1Aの101)中の関数foo()及びbar()の呼び出し元の実装担当クラスの生成が指示されている。該指示に従い、矢印(J02)で示すようにstart.php(図1Aの101)に対応する実装担当クラスBytecode_start_php(403)が生成される。Bytecode_start_php(403)のバイトコードは図4Cの421に示されている。
3行目(J03)では、上記関数呼び出しfoo()及びbar()のそれぞれのシグネチャがバッファ(401)に格納されることが指示される。該指示に従い、矢印(J03)で示すように、バッファ(401)に各シグネチャが格納される。これは、インタフェース担当クラスの生成とロードを呼び出し元の実装コードを実際に実行する段階まで遅らせるためである。
4行目(J04)では、上記実装担当クラスBytecode_start_php(403)がJava(商標)仮想マシン上へロードされる。
5行目(J05)では、上記関数呼び出しfoo()及びbar()のそれぞれのシグネチャをバッファ(401)からの取り出し、並びに統合インタフェース担当クラス(402)の生成及びロードが指示されている。該指示に従って、矢印(J05)に示すように統合インタフェース担当クラス(402)が生成される。なお、統合インタフェース担当クラス(402)のコードは図4Bの411に示されている。
このように、呼び出し元の実装コードを生成するタイミング(2行目(J02))ではなく、ロードするタイミング(4行目(J04))や、好ましくは実行する段階になってクラス・ローダ(図11Aの1107)を通じてクラス(インタフェース)のロードが要求されるため、その時点で初めてバッファに溜まっているシグネチャのメソッドを全て備えたインタフェース担当クラスの生成及びロードがされる。インタフェース担当クラスが既にある場合には、ロードだけされる。
6行目(J06)では、ロードされている呼び出し元の実装担当クラス(403)の実行が指示されている。それによって、図4Cの実装担当クラスのコード(421)に示されているように、実装担当クラスのステップL02のスクリプト実行命令executeScript()が実行される。
7行目(J07)では、上記ステップL02に引き続き、ステップL03の取り込み命令includeの実行が指示されている。そして、指定されたファイルfuncs.php(102)が取り込まれる。ここで、これまでのstart.php(101)に対応する実装担当クラスBytecode_start_php(403)の実行は中断され、新たに取り込まれたPHPファイルfuncs.php(102)に対応する実装担当クラス(404)の生成、ロード、及び実行に移る。
8行目(J08)では、funcs.php(102)で定義されている関数foo()及びbar()について、関数呼び出しfoo()及びbar()に対応するインタフェース担当クラス又は統合インタフェース担当クラス(402)が存在するか確認する。当該インタフェース担当クラスがなければ、それら関数呼び出しfoo()及びbar()を備えた新たな統合インタフェースを、ここで生成及びロードするが、ここでは該当しない。
9行目(J09)では、取り込まれたファイルfuncs.php(図1Aの102)に対応する実装担当クラスのバイトコード(404、図4Dの422)の生成及びロードが指示されている。該指示に従い、矢印(J09)で示すようにファイルfuncs.php(図1Aの102)に対応する実装担当クラス(404)が生成及びロードされる。なお、該実装担当クラス(404)のコードは、図4Dの422に示されている。該実装担当クラス(404)は、統合インタフェース担当クラスCallsite_start_php(411)を実装するものとして宣言して生成される。
ここで、ソース言語の関数の実装担当クラスのロードは、それらの関数の実行が必要になるまで遅延する。なお、すべてのコードの生成、ロード及び実行によりスクリプトの解釈実行を行う場合にはexecuteScript()のようなコードをすぐに実行する必要があるために遅延は意味をもたないが、インタプリタ方式による実行などを混在させる場合には、例えばexecuteScript()のようなコードを生成せずに、funcs.phpで定義されている関数登録のみ行うことも可能である。実装担当クラスのロードを遅延する理由は、実装担当クラスのロードがそのクラスが実装しているインタフェース担当クラスのロードを必要とするためであり、インタフェース担当クラスのロードを遅延できたほうがより多くのシグネチャをまとめて持たせることができて得策だからである。実装担当クラスをロードするときに(クラス・ローダがクラスをロードしようとすると、参照されていたりする別のクラスがある場合、解決しようとするときにその要求があることが分かる)に、まだ他のインタフェースに定義されていない関数/メソッドのシグネチャをシグネチャ・バッファに追加する。なお、実装がバッファ内のシグネチャの実装も利用もしない場合は、別個にシグネチャのリストを用意してもよい。実装担当クラス内にまだ使われていない関数(に相当する実装)が定義されていた場合には、その関数のシグネチャを備えた1つの統合インタフェース担当クラスを用意し、その上で当該統合インタフェース担当クラスの生成及びロードを行う。
10行目(J10)では、上記funcs.phpに対応する実装担当クラス(404)の実行が指示されており、図4Dに示すステップ(M02)のスクリプト実行命令 executeScriptが実行される。
11行目(J11)では、上記ステップ(M02)に続いて、ステップ(M03及びM04)の関数宣言命令declareFunctionが実行される。上記関数宣言命令declareFunctionの実行によって、関数呼び出しfoo()及びbar()を実行するためのインスタンスが実装担当クラス(404、図4Dの422)自身から生成される。
12行目(J12)では、上記生成されたインスタンスと関数呼び出しfoo()及びbar()の関数名foo及びbarが関数テーブルに対応付けて登録される。関数呼び出しがあると関数テーブルからインスタンスを検索し、該インスタンスが有するメソッドfoo()及びbar()を利用して関数呼び出しを処理するためである。以上で実装担当クラス(404)の実行は終了し、制御は実装担当クラス(402、図4Cの421)の分岐したステップ(L03)の次のステップ(L04及びL05)へ進む。
13行目(J13)では、上記ステップ(L04)により、関数foo()の呼び出し(invoke foo())が実行される。
14行目(J14)では、上記ステップ(L04)の準備段階として、呼び出し関数名fooから関数テーブルを検索し、対応付けていたインスタンスが見つけられる。
15行目(J15)では、該インスタンスが備えているメソッドfoo()(関数foo()に対応)を呼び出し実行することで目的を実現している。このとき統合インタフェース担当クラスCallsite_start_php(402、図4Bの411)で定義されている型に合わせるためインスタンスのキャストが行われる。
16行目(J16)では、上記ステップ(L05)により、関数bar()の呼び出し(invoke bar())が実行される。
17行目(J17)では、上記ステップ(L05)の準備段階として、呼び出し関数名barから関数テーブルを検索し、対応付けていたインスタンスが見つけられる。
18行目(J18)では、該インスタンスが備えているメソッドbar()(関数bar()に対応)を呼び出し実行することで目的を実現している。このとき統合インタフェース担当クラスCallsite_start_php(402、図4Bの411)で定義されている型に合わせるためインスタンスのキャストが行われる。
以上で、PHPスクリプトをJava(商標)のバイトコードに変換し、実行するステップは終了する。
【0055】
図5は、1関数1クラス方式(図2A〜図2C)、1関数1インタフェース方式(図3A〜図3D)及び複数関数1インタフェース方式(図4A〜図4D)により生成されるインタフェース担当クラスの違いを示す。
501は、1関数1クラス方式(図2A〜図2C)により生成される実装担当クラス(211、212、213及び214)である。
502は、1関数1インタフェース方式(図3A〜図3D)により生成されるインタフェース担当クラス(301、302)及び当該インタフェース担当クラス(301、302)の実装(305、306)を担当するクラス(304)を示す。
503は、複数関数1インタフェース方式(図4A〜図4D)により生成される統合インタフェース担当クラス(402)及び当該統合インタフェース担当クラス(402)の実装(405)を担当するクラス(404)を示す。
1関数1インタフェース方式により生成されるインタフェース担当クラスの数は2である。一方、複数関数1インタフェース方式により生成される統合インタフェース担当クラスの数は1である。
なお、上記例では、2つの関数/メソッドの例で説明した。しかしながら、実際には多数の関数/メソッドに対して、複数関数1インタフェース方式を適用することが可能である。よって、複数関数1インタフェース方式を適用することで、インタフェース担当クラスの数は1つにまとめられることから、生成及びロードされるJava(商標)のインタフェース担当クラスの数を減らすことが可能になる。
【0056】
図6A〜図6Bは1関数1インタフェース方式に従うバイトコード生成処理のフロー図であり、図6C、図6D及び図6Eは、複数関数1インタフェース方式に従うバイトコード生成処理のフロー図を示す。
【0057】
図6A及び図6Bは、1関数1インタフェース方式(図3A〜図3D)に従うバイトコード生成処理のフロー図を示す。
図6Aの左側の処理フロー(ステップ601〜605)は、1関数1インタフェース方式に従い、動的型付け言語で記述されたソースコードから、既にキャッシュされたものがない場合に静的型付け言語であるJava(商標)で記述されたバイトコードを生成してキャッシュする処理を示すメインのフローである。バイトコードの生成は、下記図11Aに示すバイトコード生成部(1106)によって行われる。
ステップ601では、バイトコード生成部は、動的型付け言語で記述されたソースコードを静的型付け言語で記述されたターゲットコードに変換する処理を開始する。以下、動的型付け言語としてPHP言語、静的型付け言語としてJava(商標)の場合を説明するが、これらの言語に限られるものではない。ソースコードはPHP言語の場合PHP言語で記述されたスクリプトであり、ターゲットコードはJava(商標)言語の場合バイトコードである。
ステップ602では、バイトコード生成部は、上記スクリプトからバイトコードを生成し、当該生成したバイトコードを記憶装置に格納する。ステップ602の詳細な内容は別途、下記ステップ611〜619、ステップ621〜626、及びステップ631〜638に示す。
ステップ603では、バイトコード生成部は、宣言インタフェース・リスト(図11Cの1135)のインタフェースを持つ実装担当クラスとして、生成されたバイトコードのJava(商標)の仮想マシンへのロードを実行する。ここで、宣言インタフェース・リスト(1135)とは、インタフェース担当クラス名の集合であり、上記図6Bのステップ634において追加されるインタフェースのリストである。なお、後述するように、本発明の実施態様である複数関数1インタフェース方式においても宣言インタフェース・リスト(1135)は使用される。しかしながら、複数関数1インタフェース方式で使用される宣言関数リスト(図11Cの1136)及び呼出関数リスト(図11Cの1137)は、1関数1インタフェース方式において使用されない。
なお、実装担当クラスの生成及びロードは、ステップ602及びステップ603において行われ、実装担当クラスが生成されるのは、スクリプト・ファイルがメモリ内に取り込まれバイトコードへ変換されるときである。
ステップ604では、Java(商標)プログラム実行部(以下、プログラム実行部)(図11Aの1118)は、生成したバイトコードを実行する。ステップ604の詳細な内容は別途、下記ステップ604−1〜604−7に示す。
ステップ605で、プログラム実行部(又はPHPランタイム・ヘルパー(図11Aの1105))は、上記スクリプトの処理を終了する。
【0058】
図6Aのステップ602の具体的な処理を、図6Aの中央の処理フロー(ステップ611〜619)に従い説明する。
ステップ611では、バイトコード生成部は、スクリプトのバイトコードを生成する処理(602)を開始する。
ステップ612では、バイトコード生成部は、PHPスクリプト中の各命令を識別し、下記に示すステップ613、又はステップ613及び615の判定処理を繰り返す。
ステップ613では、バイトコード生成部は、上記識別された命令が関数/メソッド呼び出しか否かを判定する。当該命令が関数/メソッド呼び出しである場合(YES)、ステップ614に進む。一方、当該命令が関数/メソッド呼び出しでない場合(NO)、ステップ615に進む。
ステップ614では、バイトコード生成部は、関数/メソッド呼び出しの生成処理を実行する。当該生成処理が終了することに応じて、ステップ618へ進む。ステップ614の処理の詳細な内容は別途、下記ステップ621〜626に示す。
ステップ615では、バイトコード生成部は、上記識別された命令が関数/メソッド呼び出しでない場合、当該命令が関数/メソッド宣言か否かを判定する。当該命令が関数/メソッド宣言である場合(YES)、ステップ616へ進む。一方、当該命令が関数/メソッド宣言でない場合(NO)、ステップ617に進む。
ステップ616では、バイトコード生成部は、関数/メソッド宣言の生成処理を実行する。当該生成処理が終了することに応じて、ステップ618へ進む。ステップ616の処理の詳細な内容は別途、下記ステップ631〜638に示す。
ステップ617では、バイトコード生成部は、上記識別された命令が関数/メソッド呼び出し且つ関数/メソッド宣言でない場合、当該命令に対応するバイトコードの生成処理を実行する。当該バイトコードの生成処理の具体的な内容は、本発明の実施態様に直接関係しないのでここではその詳細は省略する。
ステップ618では、バイトコード生成部は、未処理の命令の有無を判定する。未処理の命令がある場合、ステップ612に戻り上記判定を繰り返す。未処理の命令がない場合、ステップ619に進む。
ステップ619では、バイトコード生成部は、上記スクリプトのバイトコードの生成処理(611)を終了し、処理の分岐元のステップ602へ戻る。
【0059】
図6Aのステップ604の具体的な処理を図6Aの左側の処理フロー(ステップ604−1〜604−7)に示すが、説明の都合上、図6Bの説明の後にステップ604−1〜604−7の説明をする。
【0060】
図6Bは、図6Aの関数/メソッド呼び出しの生成処理(ステップ614)及び関数/メソッド宣言の生成処理(ステップ616)の詳細なフロー図を示す。
ステップ614の詳細な処理内容を、図6Bの左側の処理フロー(ステップ621〜626)に従い説明する。
ステップ621では、バイトコード生成部は、ソースコード中の呼び出し元の関数/メソッド呼び出しの生成処理を開始する。
ステップ622では、バイトコード生成部は、上記呼び出している関数/メソッドに対応するインタフェース担当クラスが生成済みであるか否かを検査する。インタフェース担当クラスが生成済みであるか否かは、シグネチャ・インタフェース登録のデータ構造を使用して判断される。なお、当該データ構造は、図7のデータ構造と基本的に同じであるが、インタフェース担当クラス名が行毎に異なる。
ステップ623では、バイトコード生成部は、上記呼び出している関数/メソッドに対応するインタフェース担当クラスが生成済みでない場合(NO)、ステップ625に進む。一方、上記呼び出している関数/メソッドに対応するインタフェースが生成済みの場合(YES)、ステップ624に進む。
ステップ625では、バイトコード生成部は、上記呼び出している関数/メソッドに対応するインタフェース担当クラスが生成済みでないので、当該インタフェース担当クラスを、一意になるように適当な名前で生成し、必要に応じてJavaVMへロードできるようにしておく。なお、一意になるような名前付けは、例えば番号付けにより行われる。この際、シグネチャとインタフェース名の組を、図7のデータ構造中に登録する。ロード終了後、該ステップは、ステップ624に進む。
ステップ624では、バイトコード生成部は、上記呼び出している関数/メソッドに対応するインタフェース担当クラスを通じた関数/メソッド呼び出しのコードを生成する。当該生成されたコードが、ステップ604−1〜604−7で実行されるバイトコードである。当該関数/メソッド呼び出しコードが生成されると、当該ステップは、ステップ626に進む。なお、ステップ624は、図3CのH04及びH05に相当し、図3AのF02の一環として、F03の直後に行われる。
ステップ626では、バイトコード生成部は、上記関数/メソッド呼び出しの生成処理(621)を終了し、処理の分岐元のステップ614へ戻る。
【0061】
次に、上記ステップ616の詳細な処理内容を、図6Bの右側の処理フローに従い説明する。
ステップ631では、バイトコード生成部は、ソースコードの関数/メソッド宣言の生成処理(616)を開始する。
ステップ632では、バイトコード生成部は、宣言されている関数/メソッドに対応するインタフェース担当クラスが生成済みであるか否かを検査する。
当該検査は、各関数定義の関数シグネチャが下記図7のシグネチャ・インタフェース登録のデータ構造中にあるか否かで判断される。
ステップ633では、バイトコード生成部は、上記宣言されている関数/メソッドに対応するインタフェース担当クラスが生成済みでない場合(NO)、ステップ635に進む。一方、当該インタフェース担当クラスが生成済みの場合(YES)、ステップ634に進む。
ステップ635では、バイトコード生成部は、上記宣言している関数/メソッドに対応するインタフェース担当クラスを、一意になるように(番号付けするなど)適当な名前で生成し、ロードする。この際、シグネチャとインタフェース名の組を、図7のデータ構造中に登録する。当該ロードが終了することに応じて、ステップ634に進む。
ステップ634では、バイトコード生成部は、上記生成されたインタフェース担当クラスに対応するインタフェース名を宣言インタフェース・リストに追加する。ここで、宣言インタフェース・リストとは、宣言された関数/メソッドに対応する呼び出し元のインタフェース名(インタフェース担当クラス名)をリスト形式で保持するデータ構造をいう。
ステップ636では、バイトコード生成部は、上記宣言されている関数/メソッドの処理(関数/メソッドの本体)のスクリプトのバイトコードをメモリ中(図11Aの1101)に生成する。当該生成されたバイトコードが、ステップ604−1〜604−7で実行されるバイトコードである。当該バイトコードの生成処理の具体的な内容は、既に説明した図6Aのステップ611への再帰となる。
ステップ637では、バイトコード生成部は、上記生成したバイトコードを宣言している関数/メソッド名に対応させるコードをメモリ(1101)中に生成する。当該生成されたコードが、ステップ604−1〜604−7で実行されるバイトコードである。ステップ637で生成されるコードは、シンボル・テーブル(図11Aの1109)へ登録されるコードである。当該コードは、図3CのH04及びH05のlookupFunction()のような形で参照されるコードである。すなわち、ステップ637で生成されるコードは、ステップ636で生成されるバイトコード中の関数の実装を関数名に結びつけるコードである。
ステップ638では、バイトコード生成部は、上記関数/メソッド宣言の生成処理(631)を終了し、処理の分岐元のステップ616へ戻る。
【0062】
図6Aのステップ604の具体的な処理を、図6Aの右側の処理フロー(ステップ604−1〜604−7)に従い説明する。
ステップ604−1では、Java(商標)プログラム実行部(以下、プログラム実行部)は、ステップ602の一環としてステップ624、ステップ636及びステップ637で生成され、ステップ603でVMにロードされたバイトコードの実行を開始する。
ステップ604−2では、プログラム実行部は、上記生成されたバイトコードの各インストラクションを読み取る。
ステップ604−3では、プログラム実行部は、上記読み取ったインストラクションが“include”又は“include”相当の処理であるかどうかを判定する。
ステップ604−4では、プログラム実行部は、上記読み取ったインストラクションが“include”又は“include”相当の処理である場合、スクリプトの処理を行う。
ステップ604−5では、プログラム実行部は、上記読み取ったインストラクションが“include”且つ“include”相当の処理でない場合、その他のインストラクションの処理を行う。当該その他のインストラクションの処理は本発明の本質ではないのでここではその説明を省略する。
ステップ604−6では、バイトコードの各インストラクションの読み取りが全て終了するまで、ステップ604−2に戻る。
ステップ604−7では、バイトコードの実行を終了し、処理の分岐元のステップ604に戻る。
【0063】
図6C、図6D及び図6Eは、複数関数1インタフェース方式(図4A〜図4D)に従うバイトコード生成処理のフロー図を示す。
図6Cの左側のフロー(ステップ641〜646)は、複数関数1インタフェース方式に従い、動的型付け言語で記述されたソースコードから、既にキャッシュされたものがない場合に静的型付け言語であるJava(商標)で記述されたバイトコードを生成してキャッシュする処理を示すメインのフローである。バイトコードの生成は、下記図11Aに示すバイトコード生成部(1106)によって行われる。
なお、図6Cの各ステップにおいて、図6Aの1関数1インタフェース方式と異なる又は追加されたステップを網掛けで示す(ステップ643及びステップ645−2)。
ステップ641では、バイトコード生成部は、動的型付け言語で記述されたソースコードを静的型付け言語で記述されたターゲットコードに変換する処理を開始する。以下、動的型付け言語としてPHP言語、静的型付け言語としてJava(商標)の場合を説明するが、これらの言語に限られるものではない。ソースコードはPHP言語の場合PHP言語で記述されたスクリプトであり、ターゲットコードはJava(商標)言語の場合バイトコードである。
ステップ642では、バイトコード生成部は、上記スクリプトからバイトコードを生成し、当該生成したバイトコードを記憶装置に格納する。ステップ642の詳細な内容は別途、下記ステップ651〜659、ステップ661〜667、及びステップ671〜678に示す。
ステップ643では、バイトコード生成部は、バッファの処理を実行する。当該バッファの処理は、生成した実装担当クラスにおいて、バッファ中のシグネチャの関数を宣言している場合に限り、バッファをクリアにする処理である。当該処理を行うために、宣言関数リスト(図11Cの1136)及び呼出関数リスト(図11Cの1137)を設ける。当該処理では、宣言関数リスト及び呼出関数リストを見ながら、条件的にバッファ(図11Cの1133)中のシグネチャから統合インタフェース担当クラスを生成及びロード(図6E、688)するか、または、宣言関数リスト(1136)中のシグネチャからインタフェースを生成及びロード(図6Eの686)するか、または、インタフェースを生成しない(図6Eの682から683のパス)。バッファ処理の詳細な内容を別途、下記ステップ681〜689に示す。ステップ643は複数関数1インタフェース方式に特徴的なものであり、図6Aに示す1関数1インタフェース方式にない。
ステップ644では、バイトコード生成部は、宣言インタフェース・リストのインタフェースを持つクラスとして、生成されたバイトコードをJava(商標)仮想マシンへロードし、実行する。ここで、宣言インタフェース・リストとは、バッファと同じようにシグネチャの集合であり、上記「実装がバッファ内のシグネチャの実装も利用もしない場合は、別個にシグネチャのリストを用意してもよい」において別個に用意されるシグネチャのリストである。
なお、実装担当クラスの生成及びロードは、ステップ642〜644において行われ、実装担当クラスが生成されるのは、スクリプト・ファイルがメモリ内に取り込まれバイトコードへ変換されるときである。実装担当クラスは、ソースコードのスクリプト・ファイル毎に、対応する実装担当クラスが生成される。
ステップ645では、プログラム実行部(図11Aの1118)は、生成したバイトコードを実行する。ステップ645の詳細な内容は別途、下記ステップ6645−1〜645−8に示す。
ステップ646で、プログラム実行部(又はPHPランタイム・ヘルパー(図11Aの1105))は、上記スクリプトの処理を終了する。
【0064】
上記ステップ642の具体的な処理を、図6Cの真ん中の処理フロー(ステップ651〜659)に従い説明する。当該処理フロー(ステップ651〜659)は図6Aに記載の処理フロー(611〜619)と、関数/メソッド呼び出しの生成処理(ステップ654)及び関数/メソッド宣言の生成処理(ステップ656)の詳細な処理内容が異なる以外、基本的に同じである。
ステップ651では、バイトコード生成部は、スクリプトのバイトコードを生成する処理(642)を開始する。
ステップ652では、バイトコード生成部は、PHPスクリプト中の各命令を識別し、下記に示すステップ653、又はステップ653及びステップ655の判定処理を繰り返す。
ステップ653では、バイトコード生成部は、上記識別された命令が関数/メソッド呼び出しか否かを判定する。当該命令が関数/メソッド呼び出しである場合(YES)、ステップ654に進む。一方、当該命令が関数/メソッド呼び出しでない場合(NO)、ステップ655に進む。
ステップ654では、バイトコード生成部は、関数/メソッド呼び出しの生成処理を実行する。当該生成処理が終了することに応じて、ステップ658へ進む。ステップ654の処理の詳細な内容は別途、下記ステップ661〜667に示す。
ステップ655では、バイトコード生成部は、上記識別された命令が関数/メソッド呼び出しでない場合、当該命令が関数/メソッド宣言か否かを判定する。当該命令が関数/メソッド宣言である場合(YES)、ステップ656へ進む。一方、当該命令が関数/メソッド宣言でない場合(NO)、ステップ657に進む。
ステップ656では、バイトコード生成部は、関数/メソッド宣言の生成処理を実行する。当該生成処理が終了することに応じて、ステップ658へ進む。ステップ656の処理の詳細な内容は別途、下記ステップ671〜678に示す。
ステップ657では、バイトコード生成部は、上記識別された命令が関数/メソッド呼び出し且つ関数/メソッド宣言でない場合、当該命令に対応するバイトコードの生成処理を実行する。当該バイトコードの生成処理の具体的な内容は、本発明の実施態様に直接関係しないのでここではその詳細は省略する。
ステップ658では、バイトコード生成部は、未処理の命令の有無を判定する。未処理の命令がある場合、ステップ652に戻り上記判定を繰り返す。未処理の命令がない場合、ステップ659に進む。
ステップ659では、バイトコード生成部は、上記スクリプトのバイトコードの生成処理(651)を終了し、処理の分岐元のステップ642へ戻る。
【0065】
図6Cのステップ645の具体的な処理を図6Cの右側の処理フロー(ステップ645−1〜645−8)に示すが、説明の都合上、図6Eの説明の後にステップ645−1〜645−8の説明をする。
【0066】
図6Dは、図6Cの関数/メソッド呼び出しの生成処理(ステップ654)及び関数/メソッド宣言の生成処理(ステップ656)の詳細な処理フロー図を示す。
なお、図6Dの各ステップにおいて、図6Bの1関数1インタフェース方式と異なる又は追加されたステップを網掛けで示す(ステップ665、666、672、673及び675)。
ステップ654の詳細な処理内容を、図6Dの左側の処理フロー(ステップ661〜667)に従い説明する。
ステップ661では、バイトコード生成部は、ソースコード中の呼び出し元の関数/メソッド呼び出しの生成処理を開始する。
ステップ662では、バイトコード生成部は、上記呼び出している関数/メソッドに対応するインタフェース担当クラスが生成済みであるか否かを検査する。インタフェース担当クラスが生成済みであるか否かは、図7のシグネチャ・インタフェース登録のデータ構造を使用して判断される。
ステップ663では、バイトコード生成部は、上記呼び出している関数/メソッドに対応するインタフェース担当クラスが生成済みでない場合(NO)、ステップ665に進む。一方、上記呼び出している関数/メソッドに対応するインタフェースが生成済みの場合(YES)、ステップ664に進む。
ステップ665では、バイトコード生成部は、上記呼び出している関数/メソッドのシグネチャを呼出関数リスト(図11Cの1137)に追加する。ここで、呼出関数リストとは、呼び出し元に現れる(呼出対象の)関数のシグネチャをリスト形式で保存するデータ構造をいう。呼出関数リスト(1137)は、バイトコード生成部の一部として実装される。
ステップ666では、バイトコード生成部は、バッファに対応付けられた名前により、未生成のインタフェース担当クラスで型付けされた対象オブジェクトに対する関数/メソッド呼び出しコードを生成する。当該関数/メソッド呼び出しコードの生成自体は、名前を用いるだけであるので、この時点では実際に当該インタフェース担当クラスが存在する必要はない。当該コードを実行する段階になって、インタフェースなどのシンボル名の解決がクラス・ローダ(図11Aの1107)によって行われ、そのタイミングで実際の統合インタフェース担当クラスをバッファの全てのシグネチャから生成する。当該関数/メソッド呼び出しコードが生成されると、当該ステップは、ステップ667に進む。
ステップ664では、バイトコード生成部は、上記呼び出している関数/メソッドに対応するインタフェース担当クラスを通じた関数/メソッド呼び出しコードを生成する。当該生成されたコードが、ステップ645−1〜645−8で実行されるバイトコードである。当該関数/メソッド呼び出しコードが生成されると、当該ステップは、ステップ667に進む。なお、ステップ664で生成されるコードは、図4CのL04及びL05に相当し、図4AのJ02の一環として、J03と並行して又は前後に行われる。
ステップ667では、バイトコード生成部は、上記関数/メソッド呼び出しの生成処理(661)を終了し、処理の分岐元のステップ654へ戻る。
【0067】
図6Cのステップ656の詳細な処理内容を、図6Dの右側の処理フローに従い説明する。
ステップ671では、バイトコード生成部は、ソースコードの関数/メソッド宣言の生成処理(656)を開始する。
ステップ672では、バイトコード生成部は、宣言されている関数/メソッドに対応するシグネチャがバッファ中にあるか、又は、インタフェース担当クラスが生成済みであるか否かを検査する。インタフェース担当クラスが生成済みであるか否かの検査は、各関数定義の関数シグネチャが下記図7のシグネチャ・インタフェース登録のデータ構造中にあるか否かで判断される。
ステップ673では、バイトコード生成部は、当該シグネチャが既出でない場合、すなわち上記宣言されている関数/メソッドに対応するシグネチャがバッファ中にない場合で、且つ、インタフェース担当クラスが生成済みでない場合(NO)にステップ675に進む。一方、当該シグネチャが既出の場合、すなわち当該シグネチャがバッファ中にある場合、又は、当該インタフェース担当クラスが生成済みのいずれかの場合(YES)に、ステップ674に進む。
ステップ675では、バイトコード生成部は、上記宣言している関数/メソッドのシグネチャを宣言関数リストに追加する。追加したら、ステップ676に進む。
ステップ674では、バイトコード生成部は、対応するインタフェース担当クラスの名前(以下、インタフェース担当クラス名)を宣言インタフェース・リスト(図11Cの1135)に追加する。当該対応するインタフェース担当クラスの名前は、バッファに対応付けられた名前(バッファ中の場合)、又は図7の対応表から得られるインタフェース名(インタフェース生成済みの場合)により得られる。ここで、宣言インタフェース・リスト(1135)とは、宣言された関数/メソッドに対応する呼び出し元のインタフェース担当クラス名をリスト形式で保持するデータ構造をいう。
ステップ676では、バイトコード生成部は、上記宣言されている関数/メソッドの処理(関数/メソッドの本体)のスクリプトのバイトコードをメモリ(図11Aの1101)中に生成する。当該生成されたバイトコードが、ステップ645−1〜645−8で実行されるバイトコードである。当該バイトコードの生成処理の具体的な内容は、既に説明した図6Cのステップ651(スクリプトのバイトコードの生成)への再帰となる。
ステップ677では、バイトコード生成部は、上記生成したバイトコードを宣言している関数/メソッドに対応させるコードをメモリ(1101)中に生成する。当該生成されたコードが、ステップ645−1〜645−8で実行されるバイトコードである。ステップ677で生成されるコードは、シンボル・テーブル(図11Aの1109)へ登録されるコードである。当該コードは、図4CのL04及びL05のlookupFunction()のような形で参照されるコードである。すなわち、ステップ677で生成されるコードは、ステップ676で生成されるバイトコード中の関数の実装を関数名に結びつけるコードである。
ステップ678では、バイトコード生成部は、上記関数/メソッド宣言の生成処理(671)を終了し、処理の分岐元のステップ656へ戻る。
【0068】
図6Eは、図6Cのステップ643におけるバッファの処理の詳細な処理フロー図を示す。
ステップ681では、バイトコード生成部は、バッファの処理を開始する。
ステップ682では、バイトコード生成部は、宣言関数リストが空か否かの判定を行う。
宣言関数リストが空である場合、当該処理はステップ683に進む。一方、宣言関数リストが空でない場合、当該処理はステップ684に進む。
ステップ683では、バイトコード生成部は、呼出関数リスト中、及び、好ましくはinclude処理などの静的解析などによって得られる他の変換単位中に現れるシグネチャをバッファに追加する。当該シグネチャを追加後、バッファをクリアすることなく(バッファはそのまま)、該処理はステップ689に進む。
宣言関数リストが空でない場合、当該処理はステップ684に進む。
ステップ684では、バイトコード生成部は、宣言インタフェース・リスト中にバッファに対応付けられたインタフェース担当クラス名があるか否かを調べる。
ステップ685では、上記バッファに対応付けられたインタフェース担当クラス名がない場合、該処理はステップ686に進む。一方、上記バッファに対応付けられたインタフェース担当クラス名がある場合、該処理はステップ687に進む。
ステップ686では、バイトコード生成部は、上記バッファに対応付けられたインタフェース担当クラス名がある場合、宣言関数リスト中のシグネチャから、バッファ中のインタフェース担当クラスとは別途のバッファとは独立したインタフェース担当クラスを生成及びロードする。当該バッファとは独立したインタフェース担当クラスを生成及びロードする処理は、任意的なステップである。しかし、宣言されているセットと同じセットのシグネチャをもつ統合インタフェース担当クラスの方がダミーの実装が少なくてすむことから、当該ステップがあることが好ましい場合が多い。そのため、バッファ中にあるシグネチャはそのままにできる場合に限り、宣言されているものだけからなる統合インタフェース担当クラスを、バッファ中のシグネチャからの統合インタフェース担当クラスとは別途に生成する。上記バッファとは独立した統合インタフェース担当クラスを生成する際に、シグネチャと上記バッファとは独立した統合インタフェース担当クラスの名前の組を、図7のデータ構造中に登録する。また、当該ロードした上記バッファとは独立した統合インタフェース担当クラスの名前を宣言インタフェース・リストに追加する。追加後、当該処理はステップ683に進む。
ステップ687では、バイトコード生成部は、上記バッファに対応付けられたインタフェース担当クラス名がない場合、宣言関数リスト及び呼出関数リスト中のシグネチャをバッファに追加する。
ステップ688では、バイトコード生成部は、バッファ中のシグネチャから1つの統合インタフェース担当クラスを生成及びロードする。当該バッファは、スクリプト・ファイル単位中に現れる呼び出し元の関数/メソッドのシグネチャを格納している。当該1つの統合インタフェース担当クラスを生成する際に、シグネチャと当該1つの統合インタフェース担当クラスの名前の組を、図7のデータ構造中に登録する。また、当該ロードした統合インタフェース担当クラスの名前を宣言インタフェース・リストに追加する。統合インタフェース担当クラスの生成後に、バイトコード生成部は、バッファをクリアにする。すなわち、バッファ中のシグネチャを削除する。クリア後、当該処理はステップ689に進む。なお、バッファの処理において、ステップ686を経ることなく、バッファ中のシグネチャからの統合インタフェース担当クラスを生成するステップ688を経る場合がある。
ステップ689では、バイトコード生成部は、バッファの処理(681)を終了し、処理の分岐元のステップ643(図6C)へ戻る。
【0069】
図6Cのステップ645の具体的な処理を、図6Cの右側の処理フロー(ステップ645−1〜645−8)に従い説明する。
ステップ645−1では、Java(商標)プログラム実行部(以下、プログラム実行部)(図11Aの1118)は、ステップ664、676及び677で生成されたバイトコードの実行を開始する。
ステップ645−2では、プログラム実行部は、未ロードの統合インタフェース担当クラスを生成し、及びロードする。ステップ645−2の処理の詳細な内容は別途、下記ステップ691〜694に示す。
ステップ645−3では、プログラム実行部は、上記生成されたバイトコードの各インストラクションを読み取る。
ステップ645−4では、プログラム実行部は、上記読み取ったインストラクションが“include”又は“include”相当の処理であるかどうかを判定する。
ステップ645−5では、プログラム実行部は、上記読み取ったインストラクションが“include”又は“include”相当の処理である場合、スクリプトの処理を行う。当該スクリプトの処理は、ステップ641のスクリプトの処理に戻ることである。
ステップ645−6では、プログラム実行部は、上記読み取ったインストラクションが“include”且つ“include”相当の処理でない場合、その他のインストラクションの処理を行う。当該その他のインストラクションの処理は本発明の本質ではないのでここではその説明を省略する。
ステップ645−7では、バイトコードの各インストラクションの読み取りが全て終了するまで、ステップ645−3に戻る。
ステップ645−8では、バイトコードの実行を終了し、処理の分岐元のステップ645に戻る。
【0070】
図6Fは、図6Cのステップ645−2における未ロードの統合インタフェース担当クラスの生成及びロードの詳細な処理フローを示す。
ステップ691では、未ロードの統合インタフェース担当クラスの生成及びロードの実行を開始する。
ステップ692では、インタフェース担当クラス生成部(図11Cの1132)は、クラス・ローダによりバッファ中のシグネチャ全てに対応する統合インタフェース担当クラスが利用されていればそのロードが要求される。
ステップ693では、インタフェース担当クラス生成部は、上記ロード要求がある場合、ステップ694に進む。一方、プログラム実行部は、上記ロード要求がない場合にステップ695に進む。
ステップ694では、インタフェース担当クラス生成部は、ロード要求であることに応じて、バッファ中の全てのシグネチャから1つの統合インタフェース担当クラスを生成及びロードする。当該インタフェース担当クラスの生成後に、インタフェース担当クラス生成部は、バッファをクリアにする。すなわち、バッファ中のシグネチャを削除する。クリア後、当該処理は、ステップ695に進む。
ステップ695では、インタフェース担当クラス生成部は、未ロードの統合インタフェース担当クラスの生成及びロードの実行を終了し、処理の分岐元のステップ645−2に戻る。
【0071】
本発明の実施態様従う上記処理フロー(ステップ641〜695)を、図1Aに示したPHP言語で記述されたソースコードに適用した例を以下に説明する。
スクリプト・ファイルstart.php(101)から処理が始まるとする。
最初に、スクリプト・ファイルstart.php(101)について、「スクリプトの処理」(641)が行われる。そして、スクリプト・ファイルstart.php(101)の実行の過程(645)において、funcs.phpの「スクリプトの処理」(645−5)が行われる。
A.スクリプト・ファイルstart.php(101)に対するスクリプトの処理
スクリプト・ファイルstart.php(101)を実行するために必要な実装担当クラスをバイトコードで生成する(ステップ642)。当該生成されたバイトコードは、例えば図4Cに示す通りである。
スクリプト・ファイルstart.php(101)には関数宣言がない。そのために、対応する実装担当クラスBytecode_start_php(421)にスクリプト自体の実行のためのインタフェースPHPScript以外のインタフェース担当クラスの実装の宣言はない。呼び出し元である実装担当クラスBytecode_start_php(421)のコードでは、インタフェース担当クラスCallsite_start_phpを使って、呼び出しコードを実現している。統合インタフェース担当クラスCallsite_start_phpの名前は適当に付けた名前であり、現在のバッファ中のシグネチャのメソッドを備えることになる統合インタフェース担当クラスの名前でもある。この段階において、上記インタフェース担当クラス自身は生成もロードもされていない。その代わりに、関数/メソッド・シグネチャの「foo(0)」と「bar(1)」のシグネチャがシグネチャ・バッファに入れられる。なお、実施態様の説明において、簡単のために例えば、シグネチャを名前と引数の数のみを用いるとする。
B.start.phpの実行
生成及びロードされたstart.phpの実装担当クラスBytecode_start_php(図4C、421)のexecuteScript()を呼び出し、このスクリプトを実行する(ステップ645)。元の”include”相当のincludeScript()補助関数(図4CのL03)が呼ばれ、渡された引数が “funcs.php”であるから、スクリプト・ファイルfuncs.php(図1A、102)が実行されることになる。funcs.php(102)に相当する実装担当クラスはまだ生成及びロードされていないので、funcs.php(102)に対するスクリプトの処理が必要である。
C.funcs.phpに対するスクリプトの処理
スクリプト・ファイルfuncs.php(102)を実行するために必要な実装担当クラスを生成及びロードするために、スクリプトのバイトコードを生成する処理(ステップ642)を実行する。その結果として得られるバイトコードは、図4Dに示す通りである(422)。funcs.php(102)において、未出シグネチャの関数の宣言はないので、バッファにはこれ以上特に追加しない。funcs.php(102)には関数が宣言されており、それらのシグネチャはまだバッファにあるために、それに対応するインタフェース担当クラスCallsite_start_phpを実装するように宣言が実行される。
【0072】
図7は、本発明の実施態様における、シグネチャ・インタフェース登録のデータ構造を示す。
テーブル(701)は、ロード済みとしてPHPの関数/メソッドを登録するためのデータ構造である。当該データ構造は、シグネチャ・インタフェース登録部(図11Cの1131)に記憶される。当該テーブル(701)は、PHPの関数/メソッドのシグネチャとJava(商標)のメソッド・シグネチャとの組を含む。当該メソッド・シグネチャは、該メソッドが属するインタフェース担当クラス名と該関数/メソッドのシグネチャとの組で構成される。なお、本発明の実施態様では、ソースコードは変数等が予め型付けられていない動的型付け言語で記述されるので、当該関数のシグネチャは関数名及び引数の数のみでよい。
図6Eのステップ683において、PHPの関数/メソッドのシグネチャ及びJava(商標)のメソッド・シグネチャのいずれかがバッファに格納されればよい。この理由は、PHPの関数/メソッドのシグネチャから、対応するJava(商標)のメソッド・シグネチャを、当該データ構造を使用して検索可能であり、一方、Java(商標)のメソッド・シグネチャから、対応するPHPの関数/メソッドのシグネチャを、当該データ構造を使用して検索可能なようにできるからである。
【0073】
図8A〜図8Bは、関数/メソッド呼び出しより先に関数/メソッド宣言がなされた例を示す。
図8Aは、変換対象となりうるPHP言語で記述されたPHPソースコード(start.php、caller.php及びfuncs.php)があり、関数/メソッド呼び出し(caller.php)の処理よりも先に関数/メソッド宣言(funcs.php)の処理がなされた例を示す。
上記PHPソースコードは、3つのソースコードのファイルstart.php(801)、funcs.php(803)及びcaller.php(802)で構成されている。
当該3つのファイルの関係は、下記の通りである。ファイルstart.php(801)中の取り込み命令include(“funcs.php”)は、取り込むべきファイルとしてファイルfuncs.php(803)を指定している(矢印804)。また、同ファイルstart.php(801)中の取り込み命令include(“caller.php”)は、取り込むべきファイルとしてファイルcaller.php(802)を指定している(矢印805)。さらにcaller.php(802)の関数/メソッドfoo()は、ファイルfuncs.php(803)の宣言及び定義function foo(){}に対応している(矢印806)。
本発明の実施態様では、図4A〜図4Dの実施態様と異なり、PHPの関数呼び出しファイルcaller.php(802)の処理、すなわち関数foo()呼び出しのためのインタフェース担当クラスの生成よりも、ファイルfuncs.php(803)中の関数/メソッド宣言の処理が先に実行される。関数呼び出しファイルcaller.php(802)の処理より、宣言ファイルfuncs.php(803)の処理が先に実行される場合、当該実行の時点で関数のシグネチャがバッファに溜まっているPHPの関数と宣言されているPHPの関数とをまとめた統合インタフェース担当クラスを生成及びロードする。この統合インタフェース担当クラスを実装(implements)するようにして、宣言ファイル(funcs.php)実装を担当するJavaクラスを生成及びロードする。これによって、PHP関数の宣言を含んだコード実行が先に来た場合においても、図8Bのように、複数の関数に対応するメソッドが1つの統合インタフェース担当クラスにまとめられる。
【0074】
図8Bは、図8Aに示すソースコードを複数関数1インタフェース方式により生成される実装担当クラス並びにインタフェース担当クラス、及びソースコードのターゲットコードへの変換及び実行の各ステップを示す。
図8Bにおいて、左側が変換及び実行の各ステップ(N01〜N19)を示す。同右側が、複数関数1インタフェース方式により生成される実装担当クラス(812、813及び814)及び1つの統合インタフェース担当クラス(811)を示す。すなわち、複数関数1インタフェース方式では、複数の関数/メソッドの呼び出し元に対して1つの統合インタフェース担当クラス(811)が用意されており、統合インタフェース担当クラス(811)に対応して実装担当クラス(813)が生成される。さらに、同右側は、実装担当クラス(814)の実装内容として統合インタフェース担当クラス(811)を通じて関数foo()を呼び出している様子(815)を示す。実装担当クラス(812、813及び814)、及び統合インタフェース担当クラス(811)の左側に付された矢印内の番号(N02、N06、NO08及びN14)は上記ステップのステップ番号に対応する。
【0075】
以下、図8Bの変換及び実行ステップについて説明する。
1行目(N01)では、PHPソースコードのスクリプト・ファイルstart.php(図8Aの801)の取り込み命令includeが指示されている。そのサブステップとして2〜19行目(N02〜N19)の各ステップが実行される。
2行目(N02)では、PHPスクリプト・ファイルstart.php(図8Aの801)の実装担当クラス(812)の生成及びロードが行われる。矢印(N02)は該実装担当クラス(812)の生成を示している。
3行目(N03)では、ロードされた該実装担当クラス(812)のバイトコードが実行される。
4行目(N04)では、該実装担当クラス(812)の実行により、スクリプト・ファイルstart.php(図8Aの801)の最初の命令includeに対応するバイトコードが指示するファイルfuncs.phpが取り込まれる。ここで、これまでのstart.php(801)に対応する実装担当クラスBytecode_start_php(812)の実行は中断され、新たに取り込まれたPHPファイルfuncs.php(803)に対応する実装担当クラスBytecode_funcs_php(813)の生成及びロードの実行に移る。
5行目(N05)から9行目(N09)までにおいて、funcs.php(803)に対応する実装担当クラスBytecode_funcs_php(813)が生成され、ロードされる。
6行目(N06)では、funcs.php(803)に対応する実装担当クラスBytecode_funcs_php(813)が生成される。矢印(N06)は該実装担当クラスBytecode_funcs_php(813)の生成を示している。この段階において、統合インタフェース担当クラスは未だ生成されていないのでロードはされない。
7行目(N07)では、ロードもバッファリングもされていない関数呼び出しfoo()及びbar()に対応するインタフェース担当クラス又はシグネチャの有無を確認する。
8行目(N08)では、関数宣言されているfoo()及びbar()のシグネチャを利用して1つの統合インタフェース担当クラス(811)を生成する。矢印(N08)は該統合インタフェース担当クラス(811)の生成を示している。この場合、関数呼び出しファイルcaller.php(図8Aの802)の処理より、宣言ファイルfuncs.php(図8Aの803)の処理が先に実行されるので、その時点でバッファに溜まっている呼び出し元の関数のシグネチャと(本実施態様では0個)、宣言されている関数のシグネチャとから1つの統合インタフェース担当クラス(811)を生成及びロードする。
9行目(N09)では、上記ステップ(N06)で生成されたfuncs.phpに対応する実装担当クラス(813)をロードする。この場合、ステップ(N08)のインタフェース担当クラス(811)の生成方法からも分かるように、インタフェース担当クラス(811)で定義された関数は既に実装担当クラス(813)で実装されている(816)。これにより、PHP関数の宣言を含んだコード実行が先に来た場合においては、関数宣言を行っているスクリプトに対応する実装担当クラスの生成及びロードの時点でバッファにたまっているPHP関数と、宣言されているPHP関数とから、好ましくは重複の有無に基づき選択的にまとめた、複数の関数/メソッド呼び出しに対応する1つの統合インタフェース担当クラスが生成される。
10行目(N10)では、上記funcs.phpに対応する実装担当クラス(813)を実行する。
11行目(N11)では、上記実行に従って、関数foo()及びbar()の関数宣言が実行される。この内容は例えば、図4AのステップJ11と基本的に同じである。
12行目(N12)では、関数foo()及びbar()の実体を関数テーブルに登録する。図4AのステップJ12と基本的に同じである。
13行目(N13)では、スクリプト・ファイルstart.php(図8Aの801)の実装担当クラス(812)へ制御権が戻り、2つめの取り込み命令includeが指示するファイルcaller.php(図8Aの802)が取り込まれる。
14行目(N14)では、ファイルcaller.php(図8Aの802)に対応する実装担当クラス関数(814)が生成及びロードされる。矢印(N14)は該実装担当クラス関数(814)の生成を示している。
15行目(N15)では、呼び出し元の関数foo()に対するインタフェース担当クラスが既にロードされているか、又は該呼び出し元の関数foo()のシグネチャがバッファに格納されているかを確認する。
16行目(N16)では、上記caller.phpに対応する実装担当クラス(814)を実行する。
17行目(N17)では、ステップ(N16)の実行によってバイトコードによる関数foo()の呼び出し(invoke)が実行される。
18行目(N18)では、呼び出し関数名fooから関数テーブルを検索し、対応付けていたインスタンスが見つけられる。
19行目(N19)では、該インスタンスが備えているメソッドfoo()(関数foo()に対応)を呼び出し実行することで目的を実現している。このとき統合インタフェース担当クラス(811)で定義されている型に合わせるためインスタンスのキャストが行われる。
【0076】
図8Bの例では、1つのスクリプト(funcs.php)分だけが1つの統合インタフェース担当クラスにまとめられている。しかしながら、funcs.php中でまた別の関数を呼び出している場合など、それ以外の関数も全てが1つの上記統合インタフェース担当クラスにまとめられることになる。ただし、コンパイル処理対象のスクリプトに関数宣言又は新たな関数/メソッドの呼び出しがない場合には、その必要がないため、インタフェース担当クラスはまだ生成されない。将来的に、コンパイル処理対象のスクリプトに関数宣言又は新たな関数/メソッドの呼び出しに出会ったときに、インタフェース担当クラスが生成される。
【0077】
図9A〜図9Bは、あるスクリプトで宣言されているPHP関数が、あるインタフェース担当クラスを網羅していない例を示す。
図9Aは、変換対象となりうるPHP言語で記述されたPHPソースコード(start.php、foo.php、bar.php)があり、未定の関数が現れる例を示す。
上記PHPソースコードは、3つのソースコードのスクリプト・ファイルstart.php(901)、foo.php(902)及びbar.php(903)で構成されている。
当該3つのファイルの関係は、下記の通りである。ファイルstart.php(901)の取り込み命令include(“foo.php”)は、取り込むべきファイルとしてファイルfoo.php(902)を指定している(矢印904)。また、同ファイルstart.php(901)の取り込み命令include(“bar.php”)は、取り込むべきファイルとしてファイルbar.php(903)を指定している(矢印906)。さらに、start.php(901)の呼び出し元の関数/メソッドfoo()は、ファイルfoo.php(902)の宣言及び定義function foo(){}に対応している(矢印905)。また、関数/メソッドbar()は、ファイルbar.php(903)の宣言及び定義function bar(){}に対応している(矢印907)。
本発明の実施態様において、投機的にインタフェースが統合されて、インタフェース担当クラスが生成される。そのため、例えば図9Aに示すようなファイル start.php(901)中の関数呼び出しfoo()及びbar()に対応して生成されるインタフェース担当クラスでは、関数のfoo()及びbar()の全てが定義される。これに対して、例えば、取り込まれたファイルfoo.php(902)では、関数foo()の宣言はあるが、関数bar()の宣言がないケースがでてくる。また、例えば、取り込まれたファイルbar.php(903)では、関数bar()の宣言はあるが、関数foo()の宣言がないケースがでてくる。このような場合の対処法として、各スクリプト・ファイル用の実装担当クラスに、宣言のない関数に対して中身がほぼ空の、擬似実装を持たせる。このように、本実施態様では、あるコンパイル単位の実装担当クラスに含まれる関数/メソッドのシグネチャを含むインタフェース担当クラスは、当該実装担当クラスが実装するものとして宣言し、元のコンパイル単位に実装が存在しないシグネチャを持つ関数のダミーの実装を上記実装担当クラス中に用意する。
【0078】
図9Bは、図9Aに示すソースコードを複数関数1インタフェース方式により生成される実装担当クラス並びにインタフェース担当クラス、及びソースコードのターゲットコードへの変換並びにその実行の各ステップを示す。
図9Bにおいて、左側が変換及び実行の各ステップ(O01〜O22)を示す。同右側が、複数関数1インタフェース方式により生成される実装担当クラス(913、915及び917)及び統合インタフェース担当クラス(912)を示す。すなわち、複数関数1インタフェース方式では、複数の関数/メソッドの呼び出し元に対して1つの統合インタフェース担当クラス(912)が用意されており、統合インタフェース担当クラス(912)に対応して実装担当クラス(915及び917)が生成される。さらに、同右側は、実装担当クラス(913)の実装内容としてインタフェースを通じて関数foo()及びbar()を呼び出している様子(914)を示す。同様に、同右側は、実装担当クラス(915)の実装内容としてインタフェースを通じて関数dummy()を呼び出している様子(916)を示す。また、同右側は、実装担当クラス(917)の実装内容としてインタフェースを通じて関数dummy()を呼び出している様子(918)を示す。実装担当クラス(913、915及び917)、統合インタフェース担当クラス(912)及びバッファの左側に付された矢印内の番号(O03、O04、O05、O08及びO16)は上記ステップのステップ番号に対応する。
【0079】
以下、図9Bの変換及び実行ステップについて説明する。
1行目(O01)では、PHPソースコードのスクリプト・ファイルstart.php(901)の取り込み命令includeが指示されている。そのサブステップとして2〜22行目(O02〜O22)の各ステップが実行される。
2行目(O02)では、PHPのファイルstart.php(図9Aの901)中の関数foo()及びbar()の呼び出し元の実装担当クラスの生成が指示されている。該指示に従い、矢印(O04)で示すようにstart.php(図9Aの901)に対応する実装担当クラスBytecode_start_php(913)が生成される。
3行目(O03)では、上記関数呼び出しfoo()及びbar()のそれぞれのシグネチャがバッファ(911)に格納が指示される。該指示に従い、矢印(O03)で示すように、バッファ(911)に各シグネチャが格納される。
4行目(O04)では、上記実装担当クラスBytecode_start_php(913)がJava(商標)仮想マシン上へロードされる。
5行目(O05)では、上記関数呼び出しfoo()及びbar()のそれぞれのシグネチャをバッファ(911)から取り出し、統合インタフェース担当クラス(912)の生成及びロードが指示されている。該指示に従って、矢印(O05)に示すように統合インタフェース担当クラス(912)が生成される。
このように、呼び出し元の実装コードを生成するタイミング(2行目(O02))ではなく、ロードするタイミング(4行目(O04))や、好ましくは実行する段階になって、クラス・ローダ(図11Aの1107)を通じてクラス(インタフェース)のロードが要求されるため、その時点で初めてバッファに溜まっているシグネチャのメソッドを全て備えたインタフェース担当クラスを生成及びロードする。インタフェース担当クラスが既にある場合には、ロードだけされる。
6行目(O06)では、ロードされている呼び出し元の実装担当クラス(913)の実行が指示されている。
7行目(O07)では、上記実行で取り込み命令includeの実行が指示されている。そして、指定されたファイルfoo.php(図9Aの902)が取り込まれる。
8行目(O08)では、取り込まれたファイルfoo.php(図9Aの902)に対応する実装担当クラスのバイトコード(915)の生成及びロードが指示されている。該指示に従い、矢印(O08)で示すようにファイルfoo.php(902)に対応する実装担当クラス(915)が生成及びロードされる。該実装担当クラス(915)は、統合インタフェース担当クラス(912)を実装して生成される必要がある(実装919)。なぜならば、統合インタフェース担当クラス(912)で定義されている関数foo()及びbar()は、Java(商標)の規則によって、実装担当クラス(915)において必ず実装されなければならないからである。しかし、該実装担当クラス(915)に対応するファイルfoo.php(902)は、関数foo()しか宣言されておらず、関数bar()の宣言はない。そこで、関数bar()の中身がほぼ空の、擬似実装であるdummy()(916)をもたせることにより対処する。
9行目(O09)では、上記foo.phpに対応する実装担当クラス(915)の実行が指示されている。
10行目(O10)では、上記実行によって関数宣言命令declareFunctionが実行される。上記関数宣言命令declareFunctionの実行によって、関数呼び出しfoo()を実行するためのインスタンスが実装担当クラス自身から生成される。
11行目(O11)では、上記生成されたインスタンスと関数呼び出しfoo()の関数名fooが関数テーブルに対応付けて登録される。関数呼び出しがあると関数テーブルからインスタンスを検索し、該インスタンスが有するメソッドfoo()及びbar()を利用して関数呼び出しを処理するためである。以上で実装担当クラス(915)の実行は終了し、制御は実装担当クラス(913)へ戻る。
12行目(O12)では、上記実装担当クラス(913)の実行により、関数foo()の呼び出し(invoke foo())が実行される。
13行目(O13)では、上記実行により、呼び出し関数名fooから関数テーブルを検索し、対応付けていたインスタンスが見つけられる。
14行目(O14)では、該インスタンスが備えているメソッドfoo()(関数foo()に対応)を呼び出し実行する。
15行目(O15)では、上記実行が完了するとスクリプト・ファイルbar.php(図9Aの903)の取り込み命令includeが実行される。
16行目(O16)では、取り込まれたファイルbar.php(図9Aの903)に対応する実装担当クラスのバイトコード(917)の生成及びロードが指示されている。該指示に従い、矢印(O16)で示すようにファイルbar.php(903)に対応する実装担当クラス(917)が生成及びロードされる。該実装担当クラス(917)は、統合インタフェース担当クラス(912)を実装して生成される必要がある(実装920)。なぜならば、統合インタフェース担当クラス(912)で定義されている関数foo()及びbar()は、Java(商標)の規則によって、実装担当クラス(917)において必ず実装されなければならないからである。しかし、該実装担当クラス(917)に対応するファイルbar.php(903)は、関数foo()しか宣言されておらず、関数bar()の宣言はない。そこで、関数foo()の中身がほぼ空の、擬似実装であるdummy()(918)をもたせることにより対処する。
17行目(O17)では、上記bar.phpに対応する実装担当クラス(917)の実行が指示されている。
18行目(O18)では、上記実行によって関数宣言命令declareFunctionが実行される。上記関数宣言命令declareFunctionの実行によって、関数呼び出しbar()を実行するためのインスタンスが実装担当クラス自身から生成される。
19行目(O19)では、上記生成されたインスタンスと関数呼び出しbar()の関数名barが関数テーブルに対応付けて登録される。関数呼び出しがあると関数テーブルからインスタンスを検索し、該インスタンスが有するメソッドfoo()及びbar()を利用して関数呼び出しを処理するためである。以上で実装担当クラス(915)の実行は終了し、制御は実装担当クラス(913)へ戻る。
20行目(O20)では、上記実装担当クラス(913)の実行により、関数bar()の呼び出し(invoke bar())が実行される。
21行目(O21)では、上記実行により、呼び出し関数名barから関数テーブルを検索し、対応付けていたインスタンスが見つけられる。
22行目(O22)では、該インスタンスが備えているメソッドbar()(関数bar()に対応)を呼び出し実行する。
以上で、PHPスクリプトをJava(商標)のバイトコードに変換し、実行するステップは終了する。
【0080】
図10A〜図10Eは、CRM(Custumer Relationship Management)アプリケーションに対して、インタフェース担当クラスの数を削減した結果による効果の例を示す。
当該例は、実在のPHPアプリケーションから抜粋したコードについて、既存の手法と本発明の実施態様による手法とを適用してJavaバイトコードを生成する例である。
【0081】
図10Aは、CRM(Custumer Relationship Manegement)アプリケーションから抜粋したPHPソースコードの複数のファイル例を示す。
PHPソースコードは、index.php(1001)、entryPoint.php(1002)、utils.php(1003)、Application.php(1004)、Controller.php(1005)、ControllerFactory.php(1006)及びEmployees/controller.php(1007)から構成されている。
【0082】
図10Bは、図10Aに示すPHPソースコードにおける関数/メソッドの呼び出し元と呼び出し先との関係、及びファイル取り込み指示命令と指示されたファイルとの関係を示す。
矢印1007は、PHPスクリプト・ファイルindex.php(1001)における1行目の取り込み命令require_onceで指定されたファイルentryPoint.phpが、ファイルentryPoint.php(1002)であることを示す。
矢印1008は、PHPスクリプト・ファイルindex.php(1001)におけるオブジェクトの生成を指令する命令newApplication();での関数Application()は、ファイルApplication.php(1004)の関数宣言functionApplication(){}に対応していることを示す。
他の矢印(1009〜1021)についても同様であるので、ここではその説明を省略する。
【0083】
図10Cは、図10Aに示すPHPソースコードをJava(商標)のバイトコードに変換した場合の変換及び実行ステップ、並びに各関数/メソッドの生成、宣言及び呼び出し実行の時系列を示す。
図10Cにおいて、左側が変換及び実行の各ステップ(P01〜P30)を示す。同右側が、図10Aに示すPHPコードの関数について、呼び出し、宣言、及び実行されるタイミングを各ステップ(P01〜P30)に併せて、経時的に示したものである。例えば、関数Application()は、2行目(P02)において呼び出され、14行目(P14)において宣言され、そして15行目(P15)において実行される。その他の関数startSession()、execute()、Insert_charset_header()、Controller()、setup()、getController()、EmployeesController()、pre_editview()、及びexecute()についても同様であるので、ここではその説明を省略する。
【0084】
図10Dは、図10Aに示すPHPソースコードを1関数1クラス方式により変換した場合の実装担当クラスを、図10Cに記載の時系列とともに示す。
実装担当クラス(1041〜1057)は、図10Aに示すPHPの各ファイル(1001〜1007)に対応して生成されたバイトコードである。実装担当クラスの左側に付された矢印内の番号(P01、P03、P04、P06、P07、P08及びP22)は、図10Cの変換及び実行ステップのステップ番号に対応する。
【0085】
図10Eは、図10Aに示すPHPソースコードを1関数1インタフェース方式により変換した場合の実装担当クラスを、図10Cに記載の時系列とともに示す。
実装担当クラス(1070〜1076)及びインタフェース担当クラス(1061〜1069)は、図10Aに示すPHPソースコードを1関数1インタフェース方式により変換して生成されるバイトコードである。実装担当クラス及びインタフェース担当クラスの左側に付された矢印内の番号(P01、P02、P03、P04、P06、P07、P08及びP22)は、図10Cの変換及び実行ステップのステップ番号に対応する。
【0086】
図10Fは、図10Aに示すPHPソースコードを複数関数1インタフェース方式により変換した場合の実装担当クラスを、図10Cに記載の時系列とともに示す。
実装担当クラス(1081〜1085)及びインタフェース担当クラス(1086〜1092)は、図10Aに示すPHPソースコードを1関数1インタフェース方式により変換して生成されるバイトコードである。実装担当クラス、インタフェース担当クラス及び各バッファ処理の左側に付された矢印内の番号(P01、P02、P03、P04、P06、P07、P08及びP22)は、図10Cの変換及び実行ステップのステップ番号に対応する。
ここで、図10Eに示す1関数1インタフェース方式と図10Fに示す複数関数1インタフェース方式との違いを説明する。図10Eにおいて、例えば、矢印(P02)で3つのインタフェース担当クラス(1061、1062及び1063)が生成されている。一方、図10Fにおいて、矢印(P06)で、1つの統合インタフェース担当クラス(1082)が生成されている。統合インタフェース担当クラス(1082)は、1関数1インタフェース方式における3つのインタフェース担当クラス(1061、1062及び1063)に対応するものである。これによって、3つのインタフェース担当クラス(1061、1062及び1063)が1つの統合インタフェース担当クラス(1082)に統合されていることがわかる。
同様に、図10Eにおいて、矢印(P07)では2つのインタフェース担当クラス(1066及び1067)が生成されており、また矢印(P22)では2つのインタフェース担当クラス(1068及び1069)が生成されている。一方、図10Fにおいて、図10Eの矢印(P07)に対応する矢印(P08)では図10Eの2つのインタフェース担当クラス(1066及び1067)をまとめた1つの統合インタフェース担当クラス(1084)が生成されており、同様に、図10Eの矢印(P22)に対応する矢印(P22)では図10Eの2つのインタフェース担当クラス(1068及び1069)をまとめた1つの統合インタフェース担当クラス(1085)が生成されている。
このように、図10Fの複数関数1インタフェース方式によると、図10Eの1関数1インタフェース方式と比べて、インタフェース担当クラスの数は9つから5つに減少している。
【0087】
図11Aは、本発明の実施態様における、動的型付け言語で記述されたソースコードを静的型付け言語で記述されたターゲットコードに変換するためのシステム図を示す。
図11Aに示すように、本システムは、メモリ(1101)及び記憶装置(1102)を備えている。記憶装置(1102)はハードディスク・ドライブ又はシリコン・ディスク・ドライブでありうる。Java(商標)仮想マシン(1103)が、上記メモリ(1101)上で実装されうる。記憶装置は、PHPで記述されたスクリプト・ファイル(1104)を格納する。Java(商標)仮想マシン(1103)上には、PHPランタイム・ヘルパー(1105)、バイトコード生成部(1106)、クラス・ローダ(1107)、実行可能なオブジェクト・テーブル(1108)及びシンボル・テーブル(1109)を実装している。
本システムは、記憶装置(1102)に記憶されたPHP言語などの動的型付け言語で記述されたソースコード(例えば、PHPのスクリプト)(1104)を、Java(商標)などの静的型付け言語で記述されたターゲットコード(例えば、Java(商標)のクラス・ファイル(図11Aの1112))に変換及びロードして、Java(商標)仮想マシン上で実行する。
【0088】
本システムの動作を、図11Aに従い説明する。
バイトコード生成部(1106)は、記憶装置(1102)からPHPのスクリプト・ファイル(1104)をソースコードとして読み込み及び構文解析する(1110)。
バイトコード生成部(1106)は、図6C及び図6Dで示した処理フローに従って当該ソースコードをバイトコードに変換し(1111)、そしてJavaクラス・ファイル(1112)を生成する。
引き続き、クラス・ローダ(1107)が、上記生成されたJavaクラス・ファイル(1112)をロード(1113)する。そして、クラス・ローダ(1107)はまた、クラス(1115)を得る(1114)。クラス(1115)はインタフェース担当クラス又は実装担当クラスである。さらに、本システムの言語実行系は、指定されたPHP又はその他の言語のスクリプトを実行する過程で、他のスクリプトも実行する。
例えば、言語実行系は、Webサーバに従属して動作し、アクセスされたURLに対応するスクリプトを実行する。高速な実行を可能にするために、スクリプトは、Java(商標)仮想マシン上で直接動作するバイトコードにコンパイルされ、ロードされて実行される。典型的には、コンパイルされた結果はJava(商標)のクラスとして表現されそのクラスから生成したオブジェクト(実行オブジェクト、Executable Object)へのメソッド呼び出しとしてスクリプトの実行がなされることになる。コンパイルやロードのコストは高いため、別のアクセス時には既にロードされた実行オブジェクトやクラスはキャッシュされ、再利用されるのが通常である。
PHPランタイム・ヘルパー(1105)の動きを、図11Aに記載のステップ1〜4に従い説明する。
ステップ1では、PHPランタイム・ヘルパー(1105)は、記憶装置(1102)内のPHPスクリプト・ファイル(1104)に対応する実行オブジェクト又はクラスのキャッシュが有効であるかどうかをチェックする。キャッシュが有効であるかどうかは、例えば、ファイルの更新時刻がキャッシュに登録されているものと同一であることにより確認する。キャッシュが有効であれば、それらを使ってスクリプトの実行をプログラム実行部(1118)に行わせるために、バイトコードの生成は行わない。キャッシュが有効でない場合にのみステップ2に進む。キャッシュが有効な場合には、ステップ2を飛ばして、ステップ3に進む。
ステップ2では、PHPランタイム・ヘルパー(1105)は、バイトコード生成部(1106)にスクリプトの処理(図6Cステップ641〜646)を依頼する。この依頼に基づき、バイトコード生成部(1106)はスクリプト・ファイルに対応するバイトコードを生成及びロードして得られるクラスをPHPランタイム・ヘルパー(1105)に渡す。PHPランタイム・ヘルパー(1105)は、得られたクラスをインスタンス化して実行オブジェクトを生成し、キャッシュに置く。
ステップ3では、PHPランタイム・ヘルパー(1105)は、現在の実行スコープ(ウェブサーバの1リクエストの処理の間など)で有効なシンボル・テーブル(1109)に実行オブジェクトを登録する。
ステップ4では、PHPランタイム・ヘルパー(1105)は、シンボル・テーブル(1109)から実行オブジェクトを見つけて実行する。具体的には、実行オブジェクトのexecuteScript()などのメソッドを呼び出してJava仮想マシン(1103)に実行を依頼する。
【0089】
図11Bは、本発明の実施態様における、変換された結果としての実行可能なオブジェクトと実行ヘルパーとの関係を示す図である。
実行ヘルパー(1121)は、例えばPHPランタイム・ヘルパーである。実行ヘルパー(1121)は、スクリプトの実行に係わる処理に共通の処理が多くあるために、これらの共通の処理を補助するモジュールである。共通の処理とは、例えば値同士の足し算などの基本的な演算処理、及び既に出てきているinclude()の処理である。
実行ヘルパー(1121)は、実行可能なオブジェクト(1122)を呼び出し(1123)、また実行可能なオブジェクト(1122)からPHP命令を作動するように指示を受け(1124)、作動を支援する。プログラム実行部(1118)は、バイトコード生成部(1106)によってPHPスクリプトから変換されたバイトコードをPHPランタイム・ヘルパーに処理の一部を委譲しながらスクリプトの実行をする。プログラム実行部(1118)は、通常のJava(商標)プログラムの実行部であり、インタプリタ(1119)及びJITコンパイラ(1120)からなる。インタプリタ(1119)又はJITコンパイラ(1120)により生成されたコードは、CPU(図12の1202)において実行される。
【0090】
図11Cは、本発明の実施態様における、バイトコード生成部及びシグネチャ・インタフェース登録部を示す図である。
Java(商標)仮想マシン(1103)は、シグネチャ・インタフェース登録部(1131)及びバイトコード生成部(1106)を含む。
シグネチャ・インタフェース登録部(1131)は、図7のシグネチャ・インタフェース登録のデータ構造を格納する記憶装置である。
バイトコード生成部(1106)は、インタフェース担当クラス生成部(1132)、バッファ(1133)及び実装担当クラス生成部(1134)を備えている。
インタフェース担当クラス生成部(1132)は、統合インタフェース担当クラスを生成する(図6Eのステップ688、及び図6Fのステップ694)。
バッファ(1134)は、シグネチャを格納する場所である。
実装担当クラス生成部(1134)は、宣言インタフェース・リスト(1135)、宣言関数リスト(1136)及び呼出関数リスト(1137)を備えている。宣言インタフェース・リスト(1135)とは、宣言された関数/メソッドに対応する呼び出し元のインタフェース担当クラス名をリスト形式で保持するデータ構造をいい。例えば、図6Bのステップ634又は図6Dのステップ674において追加されるインタフェース担当クラス名のリストである。宣言関数リスト(1136)は、生成した実装担当クラスにおいて、バッファ(1133)中のシグネチャの関数を宣言している場合に限り、バッファ(1133)をクリアにする処理において使用される。呼出関数リスト(1137)は、呼び出し元に現れる(呼出対象の)関数のシグネチャをリスト形式で保存するデータ構造をいう。
【0091】
図12は、本発明の実施態様における、図11Aのシステムが備えているコンピュータ・ハードウェアのブロック図を示す。
コンピュータ・システム(1201)は、CPU(1202)とメイン・メモリ(1203)と含み、これらはバス(1204)に接続されている。CPU(1202)は好ましくは、32ビット又は64ビットのアーキテクチャに基づくものであり、例えば、インテル社のXeon(商標)シリーズ、Core(商標)シリーズ、Atom(商標)シリーズ、Pentium(商標)シリーズ、Celeron(商標)シリーズ、AMD社のPhenom(商標)シリーズ、Athlon(商標)シリーズ、Turion(商標)シリーズ及びSempron(商標)などを使用することができる。バス(1204)には、ディスプレイ・コントローラ(1205)を介して、TFTモニタなどのディスプレイ(1206)が接続されている。ディスプレイ(1206)は、コンピュータ・システムの管理のために、通信回線を介してネットワークに接続されたコンピュータ・システムについての情報と、そのコンピュータ・システム上で動作中のソフトウェアについての情報を、適当なグラフィック・インターフェースで表示するために使用される。バス(1204)にはまた、IDE又はS−ATAコントローラ(1207)を介して、ハードディスク又はシリコン・ディスク(1208)と、CD−ROM、DVDドライブ又はBDドライブ(1209)が接続されている。
【0092】
ハードディスク(1208)には、オペレーティング・システム、アプリケーション・プログラム及びデータが、メイン・メモリにロード可能に記憶されている。
【0093】
CD−ROM、DVD又はBDドライブ(1209)は、必要に応じて、CD−ROM、DVD−ROM又はBDからプログラムをハードディスクに追加導入するために使用される。バス(1204)にはさらに、キーボード・マウスコントローラ(1210)を介して、キーボード(1211)及びマウス(1212)が接続されている。
【0094】
通信インタフェース(1214)は、例えばイーサネット(商標)・プロトコルに従う。通信インタフェース(1214)は、通信コントローラ(1213)を介してバス(1204)に接続され、コンピュータ・システム及び通信回線(1215)を物理的に接続する役割を担い、コンピュータ・システムのオペレーティング・システムの通信機能のTCP/IP通信プロトコルに対して、ネットワーク・インターフェース層を提供する。なお、通信回線は、有線LAN環境、或いは例えばIEEE802.11a/b/g/nなどの無線LAN接続規格に基づく無線LAN環境であってもよい。
【0095】
図13A〜図13Eは、図2C、図3A、図4A、図8B及び図9Bにおいて示されている変換及び実行ステップにおける処理の包含関係を示す。
各図において処理の包含関係はインデントによって示されているが、さらに理解を容易にするために、当該包含関係が枠線によって示されている。
【0096】
図13Aは、図2Cの変換及び実行ステップにおける処理の包含関係を示す。
1行目(E01)に、取り込み命令includeが指示されており、そのサブステップとして2〜12行目(E02〜E12)の各ステップが実行されることがわかる。2〜12行目(E02〜E12)の処理の包含関係についても上記と同様である。
【0097】
図13Bは、図3Aの変換及び実行ステップにおける処理の包含関係を示す。
1行目(F01)に、取り込み命令includeが指示されており、そのサブステップとして2〜13行目(F02〜F13)の各ステップが実行されることがわかる。2〜13行目(F02〜F13)の処理の包含関係についても上記と同様である。
【0098】
図13Cは、図4Aの変換及び実行ステップにおける処理の包含関係を示す。
1行目(J01)に、取り込み命令includeが指示されており、そのサブステップとして2〜18行目(J02〜J18)の各ステップが実行されることがわかる。2〜18行目(J02〜J18)の処理の包含関係についても上記と同様である。
【0099】
図13Dは、図8Bの変換及び実行ステップにおける処理の包含関係を示す。
1行目(N01)に、取り込み命令includeが指示されており、そのサブステップとして2〜19行目(N02〜N19)の各ステップが実行されることがわかる。2〜19行目(N02〜N19)の処理の包含関係についても上記と同様である。
【0100】
図13Eは、図9Bの変換及び実行ステップにおける処理の包含関係を示す。
1行目(O01)に、取り込み命令includeが指示されており、そのサブステップとして2〜22行目(O02〜O22)の各ステップが実行されることがわかる。2〜22行目(O02〜O22)の処理の包含関係についても上記と同様である。
【0101】
実施例1
オープンソースのCRMアプリケーションであるSugar CRM 5.0.0c (http://www.sugarcrm.com/)の場合において、1関数1クラス方式において生成されるインタフェース担当クラスの数は2864個であり、一方、本発明の実施態様である複数関数1インタフェース方式において生成されるインタフェース担当クラスの数は941個であった。よって、複数関数1インタフェース方式では、1関数1クラス方式に比べて、1923個のインタフェース担当クラスの数が削減された。
上記結果より、本発明の実施態様である複数関数1インタフェース方式では、従来のコンパイル方法に比べて、動作の遅いリフレクション機構を用いることなく、生成されるインタフェース担当クラスの数を削減することができる。特に、本発明の実施態様である複数関数1インタフェース方式において、ソースプログラムにおいて単一のコンパイル単位(例えば、ファイル単位)に宣言される関数/メソッドの数が多いほどインタフェース担当クラスの数を削減できることから、本発明の効果が大きく奏されている。

【特許請求の範囲】
【請求項1】
動的型付け言語で記述されたソースコードを静的型付け言語で記述されたターゲットコードに変換する方法であって、当該方法はコンピュータに下記ステップを実行させることを含み、当該ステップは、
前記ソースコードから前記ターゲットコードを記憶装置中に生成するステップであって、前記ソースコード中の呼び出し元で用いる関数/メソッドのシグネチャをバッファに格納するステップを含み、前記呼び出し元を生成するために必要なクラスであって、静的型付け言語のインタフェースを担当する当該クラス(以下、インタフェース担当クラス)の生成は、前記呼び出し元の関数/メソッド呼び出しのターゲットコードが実行される直前まで遅延される、前記生成するステップと、
前記バッファに格納された全てのシグネチャに対応する1つのインタフェース担当クラスを前記記憶装置中に生成し、ロードするステップであって、当該生成に応じて前記バッファ中の全てのシグネチャが削除される、前記生成し、ロードするステップと
を含む、前記方法。
【請求項2】
前記方法はコンピュータに下記ステップをさらに実行させることを含み、当該ステップは、
前記ソースコードに対応するターゲットコード中の関数/メソッドの呼び出し命令が実行されるときに、前記呼び出し元で用いられている関数/メソッドのシグネチャに対応するクラスであって、動的型付け言語における呼び出し先の関数/メソッドに対応する実装を担当する当該クラス(以下、実装担当クラス)を前記記憶装置中に生成し、ロードするステップを含む、請求項1に記載の方法。
【請求項3】
前記シグネチャをバッファに格納するステップが、前記ソースコード内の同じ変換単位中に現れる呼び出し元の関数/メソッドのシグネチャに加えて、前記ソースコード内の別の変換単位中に現れる関数/メソッドのシグネチャを前記バッファ中に格納するステップをさらに含む、請求項1に記載の方法。
【請求項4】
前記ソースコードから前記ターゲットコードを生成するステップが、前記ソースコード中の呼び出し元の関数/メソッド呼び出しの生成処理を含む、請求項1に記載の方法。
【請求項5】
前記関数/メソッド呼び出しの生成処理が、
前記呼び出している関数/メソッドに対応するインタフェース担当クラスが生成済みかどうかを検査するステップと、
当該インタフェース担当クラスが生成済みでない場合に、前記呼び出している関数/メソッドのシグネチャを呼出関数リストに追加するステップと、
前記バッファに対応付けられた名前により、未生成のインタフェース担当クラスで型付けされた対象オブジェクトに対する関数/メソッド呼び出しのコードを前記記憶装置中に生成するステップと
を含む、請求項4に記載の方法。
【請求項6】
前記関数/メソッド呼び出しの生成処理が、
前記呼び出している関数/メソッドに対応するインタフェース担当クラスが生成済みかどうかを検査するステップと、
当該インタフェース担当クラスが生成済みである場合に、当該生成済みのインタフェース担当クラスで型付けされた対象オブジェクトに対する前記関数/メソッド呼び出しのコードを前記記憶装置中に生成するステップと
を含む、請求項4に記載の方法。
【請求項7】
前記ソースコードから前記ターゲットコードを生成するステップが、前記ソースコード中の呼び出し元の関数/メソッド宣言の生成処理を含む、請求項1に記載の方法。
【請求項8】
前記関数/メソッド宣言の生成処理が、
宣言されている関数/メソッドに対応するシグネチャがバッファ中にあるか、又はインタフェース担当クラスが生成済みであるか否かを検査するステップと、
前記宣言されている関数/メソッドに対応するシグネチャがバッファ中にない場合で、且つ、前記インタフェース担当クラスが生成済みでない場合に、宣言している関数/メソッドのシグネチャを宣言関数リストに追加するステップと
を含む、請求項7に記載の方法。
【請求項9】
前記関数/メソッド宣言の生成処理が、
宣言されている関数/メソッドに対応するシグネチャがバッファ中にあるか、又はインタフェース担当クラスが生成済みであるか否かを検査するステップと、
前記宣言されている関数/メソッドに対応するシグネチャがバッファ中にない場合、又は、前記インタフェース担当クラスが生成済みでない場合に、対応するインタフェース担当クラスの名前を宣言インタフェース・リストに追加するステップと
を含む、請求項7に記載の方法。
【請求項10】
前記関数/メソッド宣言の生成処理が、
前記宣言されている関数/メソッドの処理のスクリプトのバイトコードを前記記憶装置中に生成するステップと、
前記生成したバイトコードを宣言している関数/メソッドに対応させるコードを前記記憶装置中に生成するステップと
をさらに含む、請求項8又は9に記載の方法。
【請求項11】
前記インタフェース担当クラスを生成し、ロードするステップが、
宣言関数リストが空であるか否かを検査するステップと、
前記宣言関数リストが空でない場合に、宣言インタフェース・リスト中に、バッファに対応付けられたインタフェース担当クラスの名前があるか否かを検査するステップと、
前記バッファに対応付けられたインタフェース担当クラスの名前がある場合に、宣言関数リスト及び呼出関数リスト中のシグネチャを前記バッファに追加するステップと
をさらに含む、請求項10に記載の方法。
【請求項12】
前記インタフェース担当クラスを生成し、ロードするステップが、
前記追加されたシグネチャから1つのインタフェース担当クラスを前記記憶装置中に生成し、ロードするステップと、
前記ロードされたインタフェース担当クラスの名前を宣言インタフェース・リストに追加するステップと
をさらに含む、請求項11に記載の方法。
【請求項13】
前記インタフェース担当クラスを生成し、ロードするステップが、
宣言関数リストが空であるか否かを検査するステップと、
前記宣言関数リストが空でない場合に、宣言インタフェース・リスト中に、バッファに対応付けられたインタフェース担当クラスの名前があるか否かを検査するステップと、
前記バッファに対応付けられたインタフェース担当クラスの名前がない場合に、宣言関数リスト中のシグネチャから、前記バッファとは独立した統合インタフェース担当クラスを生成及びロードするステップと、
前記ロードされたインタフェース担当クラスの名前を宣言インタフェース・リストに追加するステップと
をさらに含む、請求項10に記載の方法。
【請求項14】
前記インタフェース担当クラスを生成し、ロードするステップが、
宣言関数リストが空であるか否かを検査するステップと、
前記宣言関数リストが空である場合に、前記呼出関数リスト中のシグネチャを前記バッファに追加するステップと
をさらに含む、請求項10に記載の方法。
【請求項15】
前記実装担当クラスを生成し、ロードするステップが、
前記ソースコードの変換単位に実装が存在しないシグネチャを持つ関数のダミーの実装を上記実装担当クラス中に用意するステップ
をさらに含む、請求項2に記載の方法。
【請求項16】
前記方法はコンピュータに下記ステップをさらに実行させることを含み、当該ステップは、
前記変換されたターゲットコードを実行するステップをさらに含む、請求項1〜15のいずれか1項に記載の方法。
【請求項17】
前記実行するステップが、
前記バッファ中のシグネチャ全てに対応する統合インタフェース担当クラスがに利用されている場合に、当該ロードを要求するステップと、
当該要求に応じて、バッファ中の全てのシグネチャから1つの統合インタフェース担当クラスを生成し、ロードするステップと
をさらに含む、請求項16に記載の方法。
【請求項18】
動的型付け言語で記述されたソースコードを静的型付け言語で記述されたターゲットコードに変換するコンピュータであって、
前記ソースコードから前記ターゲットコードを記憶装置中に生成する生成部であって、当該生成部は前記ソースコード中の呼び出し元で用いる関数/メソッドのシグネチャをバッファに格納し、及び前記呼び出し元を生成するために必要なクラスであって、静的型付け言語のインタフェースを担当する当該クラス(以下、インタフェース担当クラス)の生成は、前記呼び出し元の関数/メソッド呼び出しのターゲットコードが実行される直前まで遅延される、前記生成部と、
前記バッファに格納された全てのシグネチャに対応する1つのインタフェース担当クラスを前記記憶装置中に生成し、ロードする第1の処理部であって、当該生成に応じて前記バッファ中の全てのシグネチャが削除される、前記第1の処理部と
を含む、前記コンピュータ。
【請求項19】
前記ソースコードに対応するターゲットコード中の関数/メソッドの呼び出し命令が実行されるときに、前記呼び出し元で用いられている関数/メソッドのシグネチャに対応するクラスであって、動的型付け言語における呼び出し先の関数/メソッドに対応する実装を担当する当該クラス(実装担当クラス)を生成し、ロードする第2の処理部をさらに含む、請求項18に記載のコンピュータ。
【請求項20】
コンピュータに、請求項1〜17のいずれか1項に記載の方法の各ステップを実行させるコンピュータ・プログラム。

【図1A】
image rotate

【図1B】
image rotate

【図1C】
image rotate

【図2A】
image rotate

【図2B】
image rotate

【図2C】
image rotate

【図3A】
image rotate

【図3B】
image rotate

【図3C】
image rotate

【図3D】
image rotate

【図4A】
image rotate

【図4B】
image rotate

【図4C】
image rotate

【図4D】
image rotate

【図5】
image rotate

【図6A】
image rotate

【図6B】
image rotate

【図6C】
image rotate

【図6D】
image rotate

【図6E】
image rotate

【図6F】
image rotate

【図7】
image rotate

【図8A】
image rotate

【図8B】
image rotate

【図9A】
image rotate

【図9B】
image rotate

【図10A】
image rotate

【図10B】
image rotate

【図10C】
image rotate

【図10D】
image rotate

【図10E】
image rotate

【図10F】
image rotate

【図11A】
image rotate

【図11B】
image rotate

【図11C】
image rotate

【図12】
image rotate

【図13A】
image rotate

【図13B】
image rotate

【図13C】
image rotate

【図13D】
image rotate

【図13E】
image rotate


【公開番号】特開2011−113394(P2011−113394A)
【公開日】平成23年6月9日(2011.6.9)
【国際特許分類】
【出願番号】特願2009−270506(P2009−270506)
【出願日】平成21年11月27日(2009.11.27)
【出願人】(390009531)インターナショナル・ビジネス・マシーンズ・コーポレーション (4,084)
【氏名又は名称原語表記】INTERNATIONAL BUSINESS MASCHINES CORPORATION
【復代理人】
【識別番号】100085545
【弁理士】
【氏名又は名称】松井 光夫
【復代理人】
【識別番号】100118599
【弁理士】
【氏名又は名称】村上 博司
【Fターム(参考)】