(57)【要約】【課題】  インタプリタの解釈対象であるバイトコードを機器に最適な形式に変換する。具体的には、オペランド長が異なるだけで、処理の意味が同じであるオペコードに対し、処理を共通化する。あるいは、オペランドに対し、所定の計算が必要になるものについては、前もって変換時に所定の計算を行っておき、解釈実行時には所定の計算を不要とする。【解決手段】  バイトコードをプロセッサのメモリアクセスアライメント規約に適合した中間コードに変換するバイトコード変換装置において、前記バイトコードからオペコード及びオペランドを読み出す手段と、オペコードが、命令の意味は同じで、オペランド長が異なる、オペコードの組の一つに該当するかどうか判定する手段と、前記オペランド長が異なるオペランドを同一のプロセッサ命令でアクセスできるよう、前記オペランドを中間コード中に配置する第一の配置手段とを備える。【選択図】  図１
2007094828.tif 000002
【特許請求の範囲】
【請求項１】
バイトコードをプロセッサのメモリアクセスアライメント規約に適合した中間コードに変換するバイトコード変換装置において、前記バイトコードからオペコード及びオペランドを読み出す読み出し手段と、前記読み出し手段によって読み出したオペコードが、前記バイトコードで規定されたオペコードの中で、オペコードの命令の意味は同じで、オペランド長が異なる、オペコードの組の一つに該当するかどうか判定する第一の判定手段と、前記オペランド長が異なるオペランドを同一のプロセッサ命令でアクセスできるよう、前記オペランドを中間コード中に配置する第一の配置手段とを備えたことを特徴とするバイトコード変換装置。
【請求項２】
前記中間コード中に配置されたオペランドの長さが、前記読み出し手段が読み出した、元のオペランドの長さより大きい場合、前記配置手段は、オペランドの符号の有無を見て、中間コード中のオペランドをプロセッサがアクセスした時に、元のオペランドと比較して符号に変化がないように、中間コード中のオペランドの拡張部分を埋めることを特徴とする請求項１記載のバイトコード変換装置。
【請求項３】
前記プロセッサの負の数の表現方式が２の補数である場合、中間コード中に配置されたオペランドの長さが、元のオペランドの長さより大きい場合、前記配置手段は、オペランドが符号なしでアクセスされるものである場合、中間コード中のオペランドの拡張部分をビット０で埋め、オペランドが符号ありでアクセスされ、かつ、元のオペランドの最上位ビットが１である場合、中間コード中のオペランドの拡張部分をビット１で埋めることを特徴とする請求項１記載のバイトコード変換装置。
【請求項４】
バイトコードを中間コードに変換するバイトコード変換装置において、前記バイトコードからオペコード及びオペランドを読み出す読み出し手段と、前記読み出し手段によって読み出した、元のオペコードが、そのオペランドが所定の計算を経て利用されることを前提にしているオペコードが否かを判定する第二の判定手段と、前記読み出し手段によって読み出した、元のオペランドに対して行った前記所定の計算結果を、中間コード中に配置する第二の配置手段を備えたことを特徴とするバイトコード変換装置。
【請求項５】
前記所定の計算が、元のオペランドに定数を乗するものである場合、かつ変換された中間コード中のオペランドの長さが、オペランドの取り得る値に前記定数を乗じたものを格納できる程十分大きい場合、前記第二の配置手段は、前記元のオペランドに前記定数を乗じたものを中間コード中に配置することを特徴とする請求項４のバイトコード変換装置。
【請求項６】
前記オペランドはインデックスであり、前記インデックスが指すデータが、スタック上に置かれ、前記インデックスはスタックのインデックスである場合、前記第二の配置手段は、前記元のオペランドにスタックの一要素の長さを乗じたものを中間コード中に配置することを特徴とする請求項５記載のバイトコード変換装置。
【請求項７】
前記オペランドはインデックスであり、前記インデックスは、前記インデックスが指すデータを指すポインタの配列のインデックスである場合、前記第二の配置手段は、前記元のオペランドにポインタの長さを乗じたものを中間コード中に配置することを特徴とする請求項５記載のバイトコード変換装置。
【請求項８】
前記読み出し手段によって読み出した、元のオペコードを第一のオペコードあるいは第二のオペコードに変換して配置する第三の配置手段と、前記所定の計算を前記オペランドに対して施した結果、第一の変換オペランド幅に収まるか否かを判定する第三の判定手段と、第一の変換オペランド幅より長い幅を持つ第二の変換オペランド幅を備えた中間コード中のフィールドに、前記元のオペランドに対して行った前記所定の計算結果を、配置する第四の配置手段とを備え、前記第三の判定手段が、前記所定の計算結果が第一の変換オペランド幅に収まると判定した場合は、前記第三の配置手段は、前記元のオペコードを第一のオペコードに変換して配置すると共に、前記第二の配置手段が、前記元のオペランドに対する前記所定の計算結果を、中間コード中の第一の変換オペランド幅を持つフィールドに配置し、前記第三の判定手段が、前記所定の計算結果が第一の変換オペランド幅に収まらないと判定した場合は、前記第三の配置手段は、前記元のオペコードを第二のオペコードに変換して配置すると共に、前記第四の配置手段が、前記元のオペランドに対する前記所定の計算結果を、中間コード中の第二の変換オペランド幅を持つフィールドに配置することを特徴とする請求項４記載のバイトコード変換装置。
【請求項９】
バイトコードを中間コードに変換するバイトコード変換装置において、前記バイトコードからオペコード及びオペランドを読み出す読み出し手段と、前記読み出し手段によって読み出した、元のオペコードを第一のオペコードあるいは第二のオペコードに変換して配置する第三の配置手段と、前記読み出し手段によって読み出した、元のオペランドを中間コード上でのオペランドに変換する変換手段と、前記変換手段が変換したオペランドが第一の変換オペランド幅に収まるか否かを判定する第三の判定手段と、前記変換手段が変換したオペランドを、第一の変換オペランド幅を持つ中間コードのフィールドに配置する第五の配置手段と、前記変換手段が変換したオペランドを、第一の変換オペランド幅より長い幅を持つ第二の変換オペランド幅を持つ中間コードのフィールドに配置する第六の配置手段とを備え、前記第三の判定手段が、前記変換手段が変換したオペランドが第一の変換オペランド幅に収まると判定した場合、前記第三の配置手段が元のオペコードを第一のオペコードに変換して配置すると共に、前記第五の配置手段が、前記変換手段が変換したオペランドを第一の変換オペランド幅を持つ中間コードのフィールドに配置し、前記第三の判定手段が、前記変換手段が変換したオペランドが第一の変換オペランド幅に収まらないと判定した場合、前記第三の配置手段が元のオペコードを第二のオペコードに変換して配置すると共に、前記第六の配置手段が、前記変換手段が変換したオペランドを第二の変換オペランド幅を持つ中間コードのフィールドに配置することを特徴とするバイトコード変換装置。
【請求項１０】
バイトコードをプロセッサのメモリアクセスアライメント規約に適合した中間コードに変換するバイトコード変換方法において、前記バイトコードからオペコード及びオペランドを読み出す読み出し工程と、前記読み出し工程によって読み出したオペコードが、前記バイトコードで規定されたオペコードの中で、オペコードの命令の意味は同じで、オペランド長が異なる、オペコードの組の一つに該当するかどうか判定する第一の判定工程と、前記オペランド長が異なるオペランドを同一のプロセッサ命令でアクセスできるよう、前記オペランドを中間コード中に配置する第一の配置工程とを備えたことを特徴とするバイトコード変換方法。
【請求項１１】
前記中間コード中に配置されたオペランドの長さが、前記読み出し工程が読み出した、元のオペランドの長さより大きい場合、前記配置工程は、オペランドの符号の有無を見て、中間コード中のオペランドをプロセッサがアクセスした時に、元のオペランドと比較して符号に変化がないように、中間コード中のオペランドの拡張部分を埋めることを特徴とする請求項１０記載のバイトコード変換方法。
【請求項１２】
前記プロセッサの負の数の表現方式が２の補数である場合、中間コード中に配置されたオペランドの長さが、元のオペランドの長さより大きい場合、前記配置工程は、オペランドが符号なしでアクセスされるものである場合、中間コード中のオペランドの拡張部分をビット０で埋め、オペランドが符号ありでアクセスされ、かつ、元のオペランドの最上位ビットが１である場合、中間コード中のオペランドの拡張部分をビット１で埋めることを特徴とする請求項１０記載のバイトコード変換方法。
【請求項１３】
バイトコードを中間コードに変換するバイトコード変換方法において、前記バイトコードからオペコード及びオペランドを読み出す読み出し工程と、前記読み出し工程によって読み出した、元のオペコードが、そのオペランドが所定の計算を経て利用されることを前提にしているオペコードが否かを判定する第二の判定工程と、前記読み出し工程によって読み出した、元のオペランドに対して行った前記所定の計算結果を、中間コード中に配置する第二の配置工程を備えたことを特徴とするバイトコード変換方法。
【請求項１４】
前記所定の計算が、元のオペランドに定数を乗するものである場合、かつ変換された中間コード中のオペランドの長さが、オペランドの取り得る値に前記定数を乗じたものを格納できる程十分大きい場合、前記第二の配置工程は、前記元のオペランドに前記定数を乗じたものを中間コード中に配置することを特徴とする請求項１３のバイトコード変換方法。
【請求項１５】
前記オペランドはインデックスであり、前記インデックスが指すデータが、スタック上に置かれ、前記インデックスはスタックのインデックスである場合、前記第二の配置工程は、前記元のオペランドにスタックの一要素の長さを乗じたものを中間コード中に配置することを特徴とする請求項１４記載のバイトコード変換方法。
【請求項１６】
前記オペランドはインデックスであり、前記インデックスは、前記インデックスが指すデータを指すポインタの配列のインデックスである場合、前記第二の配置工程は、前記元のオペランドにポインタの長さを乗じたものを中間コード中に配置することを特徴とする請求項１４記載のバイトコード変換方法。
【請求項１７】
前記読み出し工程によって読み出した、元のオペコードを第一のオペコードあるいは第二のオペコードに変換して配置する第三の配置工程と、前記所定の計算を前記オペランドに対して施した結果、第一の変換オペランド幅に収まるか否かを判定する第三の判定工程と、第一の変換オペランド幅より長い幅を持つ第二の変換オペランド幅を備えた中間コード中のフィールドに、前記元のオペランドに対して行った前記所定の計算結果を、配置する第四の配置工程とを備え、前記第三の判定工程が、前記所定の計算結果が第一の変換オペランド幅に収まると判定した場合は、前記第三の配置工程は、前記元のオペコードを第一のオペコードに変換して配置すると共に、前記第二の配置工程が、前記オペランドに対する前記所定の計算結果を、中間コード中の第一の変換オペランド幅を持つフィールドに配置し、前記第三の判定工程が、前記所定の計算結果が第一の変換オペランド幅に収まらないと判定した場合は、前記第三の配置工程は、前記元のオペコードを第二のオペコードに変換して配置すると共に、前記第四の配置工程が、前記オペランドに対する前記所定の計算結果を、中間コード中の第二の変換オペランド幅を持つフィールドに配置することを特徴とする請求項１３記載のバイトコード変換方法。
【請求項１８】
バイトコードを中間コードに変換するバイトコード変換方法において、前記バイトコードからオペコード及びオペランドを読み出す読み出し工程と、前記読み出し工程によって読み出した、元のオペコードを第一のオペコードあるいは第二のオペコードに変換して配置する第三の配置工程と、前記読み出し工程によって読み出した、元のオペランドを中間コード上でのオペランドに変換する変換工程と、前記変換工程が変換したオペランドが第一の変換オペランド幅に収まるか否かを判定する第三の判定工程と、前記変換工程が変換したオペランドを第一の変換オペランド幅を持つ中間コードのフィールドに配置する第五の配置工程と、前記変換工程が変換したオペランドを第一の変換オペランド幅より長い幅を持つ第二の変換オペランド幅を持つ中間コードのフィールドに配置する第六の配置工程とを備え、前記第三の判定工程が、前記変換工程が変換したオペランドが第一の変換オペランド幅に収まると判定した場合、前記第三の配置工程が元のオペコードを第一のオペコードに変換して配置すると共に、前記第五の配置工程が、前記変換工程が変換したオペランドを第一の変換オペランド幅を持つ中間コードのフィールドに配置し、前記第三の判定工程が、前記変換工程が変換したオペランドが第一の変換オペランド幅に収まらないと判定した場合、前記第三の配置工程が元のオペコードを第二のオペコードに変換して配置すると共に、前記第六の配置工程が、前記変換工程が変換したオペランドを第二の変換オペランド幅を持つ中間コードのフィールドに配置することを特徴とするバイトコード変換方法。
【請求項１９】
請求項１０乃至１８のいずれかに記載のバイトコード変換方法を実現するためのプログラム。
【請求項２０】
請求項１９に記載のプログラムを記録させた記憶媒体。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、インタプリタの解釈対象であるバイトコードを機器に最適な形式に変換する装置、方法、プログラム、並びに記憶媒体に関する。
【背景技術】
【０００２】
従来から、バイトコードを解釈対象とするインタプリタが存在する。
【０００３】
バイトコードはインタプリタが解釈する、命令であるオペコードと、そのパラメータであるオペランドの組み合わせが連なったものであり、オペコードやオペランドがバイト単位でコーディングされていることから、その名がある。
【０００４】
一般的に、オペコードやオペランドの長さが短い方が、フェッチ、デコード、及び命令の実行が速くなる。従って、最小のオペコード長は、１ｂｙｔｅであるインタプリタ言語もある。
【０００５】
特に、Ｊａｖａ（登録商標）言語（Ｊａｖａ（登録商標）はＳｕｎ Ｍｉｃｒｏｓｙｓｔｅｍｓ，Ｉｎｃ．の米国並びに他の国における登録商標である）に関しては、バイトコードが格納されたクラスファイルがネットワーク経由で通信されることを鑑み、バイトコードサイズをできるだけ小さくするために、全てのオペコードの長さが１ｂｙｔｅとなっている。
【０００６】
また、Ｊａｖａ（登録商標）言語のオペランドに関しては、それぞれ、オペランドなしのもの、１ｂｙｔｅのもの、２ｂｙｔｅのもの、それ以上のもの、があり、できるだけオペランド長が短くなるように、工夫されている。
【０００７】
現在までに、インタプリタの解釈動作の高速化を目的とした最適化手法も、各種、提案されている。
【０００８】
その中の代表的なものが、Ｊｕｓｔ Ｉｎ Ｔｉｍｅ（ＪＩＴ）コンパイラであり、これは実行時に、バイトコードを機器の中央演算装置（ＣＰＵ）が直接実行できるネイティブコードにコンパイルし、これを実行するものである。
【０００９】
ＪＩＴコンパイラを使用した場合の欠点は、変換後のネイティブコードのサイズが大きくなり、メモリ消費量が多くなることである。ＰＣやワークステーションのように、メモリを大量に搭載している機器ならば問題はないが、メモリが少ない組込み機器において、ＪＩＴコンパイラを採用することは難しい。
【００１０】
かくして、特に組込み機器分野において、いかに消費メモリ量を少なくしたままで、高速動作を行えるインタプリタが求められている。
【００１１】
この目的を達するため、特開平１１−１７５３４９にて開示された技術が存在する。当該公報においては、バイトコードを、各バイトコードに対応する処理ルーチンのアドレスをオペコードとする中間コードに変換し、この中間コードを固定長にすることで、ＣＰＵの中間コード処理速度を、バイトコード処理速度よりも向上させている。
【特許文献１】特開平１１−１７５３４９号公報
【発明の開示】
【発明が解決しようとする課題】
【００１２】
しかしながら、従来技術では、高速化を図る点において、不十分である。
【００１３】
例えば、Ｊａｖａ（登録商標）バイトコードのオペコードの中には、そのオペランド長が異なる（１ｂｙｔｅあるいは２ｂｙｔｅ）だけで、処理の意味としては、同じものが存在する。（例えば、ｂｉｐｕｓｈとｓｉｐｕｓｈの関係）
これらは、共通化できる処理であり、共通化すれば、中間コードの処理ルーチンが一つ減る。その結果、全体の処理ルーチンのサイズも小さくなり、ＣＰＵがキャッシュミスを起こす確率も小さくなる。キャッシュサイズが比較的小さい、組込み機器向けＣＰＵにとっては、重要である。
【００１４】
また、Ｊａｖａ（登録商標）バイトコードのオペランドの中には、所定の計算によって意味を持つような数、言い換えれば、オペランドに所定の計算を施すことによって、そのオペランドに関連付けられ、メモリに格納されたデータへのアクセスが可能になる、あるいはメモリ使用率や速度の面でアクセス効率が向上するものが存在する。
【００１５】
そのようなオペランドとして、ローカル変数のインデックスあるいはコンスタントプールのインデックスを意味するオペランドが存在する。
【００１６】
前記インデックスから、前記インデックスが指すデータにアクセスする際、インタプリタは、式「ベースアドレス＋インデックス＊定数」によって、データのアドレスを求める。ここで、前記定数は、スタックの１要素のバイト長であったり、ＣＰＵのポインタのバイト長であったりする。
【００１７】
この計算は繰り返し現れるので、中間コード処理ルーチンから取り除くことができれば、処理速度は向上する。
【００１８】
特開平１１−１７５３４９においては、中間コード処理ルーチンの中で、オペランドを４倍し（定数表、各要素のサイズは１ワード＝４バイト）、オペランドを４倍する必要のなかったオペランドについては、１／４倍して、元に戻すということを行っているが、そもそも中間コードへの変換時に、必要なオペランドが４倍され、必要のないオペランドはそのままになっていれば、前記のような処理は一切、不要になる。前記公知資料においては、ＰｏｗｅｒＰＣプロセッサを用いる場合、１／４倍することは負担にならない旨、記述されているが、プロセッサがそのようなものばかりであるとは限らず、無駄な処理はさせない方がよい。
【課題を解決するための手段】
【００１９】
前記課題を解決するために、
請求項１記載のバイトコード変換装置は、バイトコードをプロセッサのメモリアクセスアライメント規約に適合した中間コードに変換するバイトコード変換装置において、前記バイトコードからオペコード及びオペランドを読み出す読み出し手段と、前記読み出し手段によって読み出したオペコードが、前記バイトコードで規定されたオペコードの中で、オペコードの命令の意味は同じで、オペランド長が異なる、オペコードの組の一つに該当するかどうか判定する第一の判定手段と、前記オペランド長が異なるオペランドを同一のプロセッサ命令でアクセスできるよう、前記オペランドを中間コード中に配置する第一の配置手段とを備えたことを特徴とする。
【００２０】
請求項２記載のバイトコード変換装置は、請求項１記載のバイトコード変換装置において、前記中間コード中に配置されたオペランドの長さが、前記読み出し手段が読み出した、元のオペランドの長さより大きい場合、前記配置手段は、オペランドの符号の有無を見て、中間コード中のオペランドをプロセッサがアクセスした時に、元のオペランドと比較して符号に変化がないように、中間コード中のオペランドの拡張部分を埋めることを特徴とする。
【００２１】
請求項３記載のバイトコード変換装置は、請求項１記載のバイトコード変換装置において、前記プロセッサの負の数の表現方式が２の補数である場合、中間コード中に配置されたオペランドの長さが、元のオペランドの長さより大きい場合、前記配置手段は、オペランドが符号なしでアクセスされるものである場合、中間コード中のオペランドの拡張部分をビット０で埋め、オペランドが符号ありでアクセスされ、かつ、元のオペランドの最上位ビットが１である場合、中間コード中のオペランドの拡張部分をビット１で埋めることを特徴とする。
【００２２】
請求項４記載のバイトコード変換装置は、バイトコードを中間コードに変換するバイトコード変換装置において、前記バイトコードからオペコード及びオペランドを読み出す読み出し手段と、前記読み出し手段によって読み出した、元のオペコードが、そのオペランドが所定の計算を経て利用されることを前提にしているオペコードが否かを判定する第二の判定手段と、前記読み出し手段によって読み出した、元のオペランドに対して行った前記所定の計算結果を、中間コード中に配置する第二の配置手段を備えたことを特徴とする。
【００２３】
請求項５記載のバイトコード変換装置は、請求項４記載のバイトコード変換装置において、前記所定の計算が、元のオペランドに定数を乗するものである場合、かつ変換された中間コード中のオペランドの長さが、オペランドの取り得る値に前記定数を乗じたものを格納できる程十分大きい場合、前記第二の配置手段は、前記元のオペランドに前記定数を乗じたものを中間コード中に配置することを特徴とする。
【００２４】
請求項６記載のバイトコード変換装置は、請求項５記載のバイトコード変換装置において、前記オペランドはインデックスであり、前記インデックスが指すデータが、スタック上に置かれ、前記インデックスはスタックのインデックスである場合、前記第二の配置手段は、前記元のオペランドにスタックの一要素の長さを乗じたものを中間コード中に配置することを特徴とする。
【００２５】
請求項７記載のバイトコード変換装置は、請求項５記載のバイトコード変換装置において、前記オペランドはインデックスであり、前記インデックスは、前記インデックスが指すデータを指すポインタの配列のインデックスである場合、前記第二の配置手段は、前記元のオペランドにポインタの長さを乗じたものを中間コード中に配置することを特徴とする。
【００２６】
請求項８記載のバイトコード変換装置は、請求項４記載のバイトコード変換装置において、前記読み出し手段によって読み出した、元のオペコードを第一のオペコードあるいは第二のオペコードに変換して配置する第三の配置手段と、前記所定の計算を前記オペランドに対して施した結果、第一の変換オペランド幅に収まるか否かを判定する第三の判定手段と、第一の変換オペランド幅より長い幅を持つ第二の変換オペランド幅を備えた中間コード中のフィールドに、前記元のオペランドに対して行った前記所定の計算結果を、配置する第四の配置手段とを備え、前記第三の判定手段が、前記所定の計算結果が第一の変換オペランド幅に収まると判定した場合は、前記第三の配置手段は、前記元のオペコードを第一のオペコードに変換して配置すると共に、前記第二の配置手段が、前記元のオペランドに対する前記所定の計算結果を、中間コード中の第一の変換オペランド幅を持つフィールドに配置し、前記第三の判定手段が、前記所定の計算結果が第一の変換オペランド幅に収まらないと判定した場合は、前記第三の配置手段は、前記元のオペコードを第二のオペコードに変換して配置すると共に、前記第四の配置手段が、前記元のオペランドに対する前記所定の計算結果を、中間コード中の第二の変換オペランド幅を持つフィールドに配置することを特徴とする。
【００２７】
請求項９記載のバイトコード変換装置は、バイトコードを中間コードに変換するバイトコード変換装置において、前記バイトコードからオペコード及びオペランドを読み出す読み出し手段と、前記読み出し手段によって読み出した、元のオペコードを第一のオペコードあるいは第二のオペコードに変換して配置する第三の配置手段と、前記読み出し手段によって読み出した、元のオペランドを中間コード上でのオペランドに変換する変換手段と、前記変換手段が変換したオペランドが第一の変換オペランド幅に収まるか否かを判定する第三の判定手段と、前記変換手段が変換したオペランドを第一の変換オペランド幅を持つ中間コードのフィールドに配置する第五の配置手段と、前記変換手段が変換したオペランドを第一の変換オペランド幅より長い幅を持つ第二の変換オペランド幅を持つ中間コードのフィールドに配置する第六の配置手段とを備え、前記第三の判定手段が、前記変換手段が変換したオペランドが第一の変換オペランド幅に収まると判定した場合、前記第三の配置手段が元のオペコードを第一のオペコードに変換して配置すると共に、前記第五の配置手段が、前記変換手段が変換したオペランドを第一の変換オペランド幅を持つ中間コードのフィールドに配置し、前記第三の判定手段が、前記変換手段が変換したオペランドが第一の変換オペランド幅に収まらないと判定した場合、前記第三の配置手段が元のオペコードを第二のオペコードに変換して配置すると共に、前記第六の配置手段が、前記変換手段が変換したオペランドを第二の変換オペランド幅を持つ中間コードのフィールドに配置することを特徴とする。
【００２８】
請求項１０記載のバイトコード変換方法は、バイトコードをプロセッサのメモリアクセスアライメント規約に適合した中間コードに変換するバイトコード変換方法において、前記バイトコードからオペコード及びオペランドを読み出す読み出し工程と、前記読み出し工程によって読み出したオペコードが、前記バイトコードで規定されたオペコードの中で、オペコードの命令の意味は同じで、オペランド長が異なる、オペコードの組の一つに該当するかどうか判定する第一の判定工程と、前記オペランド長が異なるオペランドを同一のプロセッサ命令でアクセスできるよう、前記オペランドを中間コード中に配置する第一の配置工程とを備えたことを特徴とする。
【００２９】
請求項１１記載のバイトコード変換方法は、請求項１０記載のバイトコード変換方法において、前記中間コード中に配置されたオペランドの長さが、前記読み出し工程が読み出した、元のオペランドの長さより大きい場合、前記配置工程は、オペランドの符号の有無を見て、中間コード中のオペランドをプロセッサがアクセスした時に、元のオペランドと比較して符号に変化がないように、中間コード中のオペランドの拡張部分を埋めることを特徴とする。
【００３０】
請求項１２記載のバイトコード変換方法は、請求項１０記載のバイトコード変換方法において、前記プロセッサの負の数の表現方式が２の補数である場合、中間コード中に配置されたオペランドの長さが、元のオペランドの長さより大きい場合、前記配置工程は、オペランドが符号なしでアクセスされるものである場合、中間コード中のオペランドの拡張部分をビット０で埋め、オペランドが符号ありでアクセスされ、かつ、元のオペランドの最上位ビットが１である場合、中間コード中のオペランドの拡張部分をビット１で埋めることを特徴とする。
【００３１】
請求項１３記載のバイトコード変換方法は、バイトコードを中間コードに変換するバイトコード変換方法において、前記バイトコードからオペコード及びオペランドを読み出す読み出し工程と、前記読み出し工程によって読み出した、元のオペコードが、そのオペランドが所定の計算を経て利用されることを前提にしているオペコードが否かを判定する第二の判定工程と、前記読み出し工程によって読み出した、元のオペランドに対して行った前記所定の計算結果を、中間コード中に配置する第二の配置工程を備えたことを特徴とする。
【００３２】
請求項１４記載のバイトコード変換方法は、請求項１３記載のバイトコード変換方法において、前記所定の計算が、元のオペランドに定数を乗するものである場合、かつ変換された中間コード中のオペランドの長さが、オペランドの取り得る値に前記定数を乗じたものを格納できる程十分大きい場合、前記第二の配置工程は、前記元のオペランドに前記定数を乗じたものを中間コード中に配置することを特徴とする。
【００３３】
請求項１５記載のバイトコード変換方法は、請求項１４記載のバイトコード変換方法において、前記オペランドはインデックスであり、前記インデックスが指すデータが、スタック上に置かれ、前記インデックスはスタックのインデックスである場合、前記第二の配置工程は、前記元のオペランドにスタックの一要素の長さを乗じたものを中間コード中に配置することを特徴とする。
【００３４】
請求項１６記載のバイトコード変換方法は、請求項１４記載のバイトコード変換方法において、前記オペランドはインデックスであり、前記インデックスは、前記インデックスが指すデータを指すポインタの配列のインデックスである場合、前記第二の配置工程は、前記元のオペランドにポインタの長さを乗じたものを中間コード中に配置することを特徴とする。
【００３５】
請求項１７記載のバイトコード変換方法は、請求項１３記載のバイトコード変換方法において、前記読み出し工程によって読み出した、元のオペコードを第一のオペコードあるいは第二のオペコードに変換して配置する第三の配置工程と、前記所定の計算を前記オペランドに対して施した結果、第一の変換オペランド幅に収まるか否かを判定する第三の判定工程と、第一の変換オペランド幅より長い幅を持つ第二の変換オペランド幅を備えた中間コード中のフィールドに、前記元のオペランドに対して行った前記所定の計算結果を、配置する第四の配置工程とを備え、前記第三の判定工程が、前記所定の計算結果が第一の変換オペランド幅に収まると判定した場合は、前記第三の配置工程は、前記元のオペコードを第一のオペコードに変換して配置すると共に、前記第二の配置工程が、前記オペランドに対する前記所定の計算結果を、中間コード中の第一の変換オペランド幅を持つフィールドに配置し、前記第三の判定工程が、前記所定の計算結果が第一の変換オペランド幅に収まらないと判定した場合は、前記第三の配置工程は、前記元のオペコードを第二のオペコードに変換して配置すると共に、前記第四の配置工程が、前記オペランドに対する前記所定の計算結果を、中間コード中の第二の変換オペランド幅を持つフィールドに配置することを特徴とする。
【００３６】
請求項１８記載のバイトコード変換方法は、バイトコードを中間コードに変換するバイトコード変換方法において、前記バイトコードからオペコード及びオペランドを読み出す読み出し工程と、前記読み出し工程によって読み出した、元のオペコードを第一のオペコードあるいは第二のオペコードに変換して配置する第三の配置工程と、前記読み出し工程によって読み出した、元のオペランドを中間コード上でのオペランドに変換する変換工程と、前記変換工程が変換したオペランドが第一の変換オペランド幅に収まるか否かを判定する第三の判定工程と、前記変換工程が変換したオペランドを第一の変換オペランド幅を持つ中間コードのフィールドに配置する第五の配置工程と、前記変換工程が変換したオペランドを第一の変換オペランド幅より長い幅を持つ第二の変換オペランド幅を持つ中間コードのフィールドに配置する第六の配置工程とを備え、前記第三の判定工程が、前記変換工程が変換したオペランドが第一の変換オペランド幅に収まると判定した場合、前記第三の配置工程が元のオペコードを第一のオペコードに変換して配置すると共に、前記第五の配置工程が、前記変換工程が変換したオペランドを第一の変換オペランド幅を持つ中間コードのフィールドに配置し、前記第三の判定工程が、前記変換工程が変換したオペランドが第一の変換オペランド幅に収まらないと判定した場合、前記第三の配置工程が元のオペコードを第二のオペコードに変換して配置すると共に、前記第六の配置工程が、前記変換工程が変換したオペランドを第二の変換オペランド幅を持つ中間コードのフィールドに配置することを特徴とする。
【発明の効果】
【００３７】
以上説明してきたように、本発明の請求項１によれば、バイトコードをプロセッサのメモリアクセスアライメント規約に適合した中間コードに変換するバイトコード変換装置において、前記バイトコードからオペコード及びオペランドを読み出す読み出し手段と、前記読み出し手段によって読み出したオペコードが、前記バイトコードで規定されたオペコードの中で、オペコードの命令の意味は同じで、オペランド長が異なる、オペコードの組の一つに該当するかどうか判定する第一の判定手段と、前記オペランド長が異なるオペランドを同一のプロセッサ命令でアクセスできるよう、前記オペランドを中間コード中に配置する第一の配置手段とを備えたことを特徴とすることにより、中間コードの処理ルーチンを共通化でき、処理ルーチンの数を減らすことができる。
【００３８】
請求項１０も同様の効果を持つ。
【００３９】
請求項２によれば、請求項１記載のバイトコード変換装置において、前記中間コード中に配置されたオペランドの長さが、前記読み出し手段が読み出した、元のオペランドの長さより大きい場合、前記配置手段は、オペランドの符号の有無を見て、中間コード中のオペランドをプロセッサがアクセスした時に、元のオペランドと比較して符号に変化がないように、中間コード中のオペランドの拡張部分を埋めることを特徴とすることにより、オペランド長が異なっても、同一のメモリアクセス命令で、オペランドを読み出すことができ、中間コードの処理ルーチンの共通化に寄与する。
【００４０】
請求項３、１１、１２も同様の効果を持つ。
【００４１】
請求項４によれば、バイトコードを中間コードに変換するバイトコード変換装置において、前記バイトコードからオペコード及びオペランドを読み出す読み出し手段と、前記読み出し手段によって読み出した、元のオペコードが、そのオペランドが所定の計算を経て利用されることを前提にしているオペコードが否かを判定する第二の判定手段と、前記読み出し手段によって読み出した、元のオペランドに対して行った前記所定の計算結果を、中間コード中に配置する第二の配置手段を備えたことを特徴とすることにより、中間コードの解釈、実行時に前記所定の計算が不要になり、処理速度を向上させることができる。
【００４２】
請求項５、６、７、１３、１４、１５、１６も同様の効果を持つ。
【００４３】
請求項８によれば、請求項４記載のバイトコード変換装置において、前記読み出し手段によって読み出した、元のオペコードを第一のオペコードあるいは第二のオペコードに変換して配置する第三の配置手段と、前記所定の計算を前記オペランドに対して施した結果、第一の変換オペランド幅に収まるか否かを判定する第三の判定手段と、第一の変換オペランド幅より長い幅を持つ第二の変換オペランド幅を備えた中間コード中のフィールドに、前記元のオペランドに対して行った前記所定の計算結果を、配置する第四の配置手段とを備え、前記第三の判定手段が、前記所定の計算結果が第一の変換オペランド幅に収まると判定した場合は、前記第三の配置手段は、前記元のオペコードを第一のオペコードに変換して配置すると共に、前記第二の配置手段が、前記元のオペランドに対する前記所定の計算結果を、中間コード中の第一の変換オペランド幅を持つフィールドに配置し、前記第三の判定手段が、前記所定の計算結果が第一の変換オペランド幅に収まらないと判定した場合は、前記第三の配置手段は、前記元のオペコードを第二のオペコードに変換して配置すると共に、前記第四の配置手段が、前記元のオペランドに対する前記所定の計算結果を、中間コード中の第二の変換オペランド幅を持つフィールドに配置することを特徴とすることにより、前記元のオペランドに所定の計算を施した結果、短い変換オペランド幅に収まらない場合でも、それより長い変換オペランド幅を持つ、第二のオペコードを定義し、そのオペランドフィールドに所定の計算結果を配置することができ、どちらの場合でも前記所定の計算を前もって行っておくことができ、処理速度を向上させることができる。
【００４４】
請求項９によれば、バイトコードを中間コードに変換するバイトコード変換装置において、前記バイトコードからオペコード及びオペランドを読み出す読み出し手段と、前記読み出し手段によって読み出した、元のオペコードを第一のオペコードあるいは第二のオペコードに変換して配置する第三の配置手段と、前記読み出し手段によって読み出した、元のオペランドを中間コード上でのオペランドに変換する変換手段と、前記変換手段が変換したオペランドが第一の変換オペランド幅に収まるか否かを判定する第三の判定手段と、前記変換手段が変換したオペランドを第一の変換オペランド幅を持つ中間コードのフィールドに配置する第五の配置手段と、前記変換手段が変換したオペランドを第一の変換オペランド幅より長い幅を持つ第二の変換オペランド幅を持つ中間コードのフィールドに配置する第六の配置手段とを備え、前記第三の判定手段が、前記変換手段が変換したオペランドが第一の変換オペランド幅に収まると判定した場合、前記第三の配置手段が元のオペコードを第一のオペコードに変換して配置すると共に、前記第五の配置手段が、前記変換手段が変換したオペランドを第一の変換オペランド幅を持つ中間コードのフィールドに配置し、前記第三の判定手段が、前記変換手段が変換したオペランドが第一の変換オペランド幅に収まらないと判定した場合、前記第三の配置手段が元のオペコードを第二のオペコードに変換して配置すると共に、前記第六の配置手段が、前記変換手段が変換したオペランドを第二の変換オペランド幅を持つ中間コードのフィールドに配置することを特徴とすることにより、前記元のオペランドに変換を施した結果、短い変換オペランド幅に収まらない場合でも、それより長い変換オペランド幅を持つ、第二のオペコードを定義し、そのオペランドフィールドに変換結果を配置することができ、どちらの場合でも前記変換を前もって行っておくことができ、処理速度を向上させることができる。
【発明を実施するための最良の形態】
【００４５】
以下、本発明の実施の形態について、図を用いて説明する。
【００４６】
図１は本発明の一実施例のハードウエア構成を示したブロック図であり、同図において、１０１は、中央演算装置であるところのＣＰＵであり、装置全体の制御を行う。バイトコードの変換及び実行もここで行う。１０２はメモリであり、演算の結果、バイトコード、及びバイトコードが変換された中間コード等がここに格納される。１０３はハードディスク（ＨＤ）であり、各種データが格納される。バイトコードあるいは前記中間コードはここに格納されることもある。１０４はディスプレイであり、演算の結果等が表示される。１０５は、ネットワークインタフェースであり、ネットワーク１０６とのインタフェースを担うものである。ここで、ネットワーク１０６は有線、無線を問わず、電気、光、赤外線、いずれの方式も問わない。以下では、上記構成を持つ機器を、単に機器と呼ぶことにする。また、上記機器に限らず、ＰＣやワークステーション、あるいはもっと広い意味での演算手段を備えた装置であって、インタプリタが動作し、バイトコードを実行できるような装置を、以下、コンピュータと呼ぶことにする。
【００４７】
図２は、Ｊａｖａ（登録商標）言語におけるデータの変遷と、データの変換手段を示したブロック図である。他のインタプリタ言語においても、同様な構成を取り得る。
【００４８】
２０１は、Ｊａｖａ（登録商標）ソースであり、人間あるいはコンピュータが、人間の読める形式で記述したプログラムである。
【００４９】
２０２はＪａｖａ（登録商標）コンパイラであり、Ｊａｖａ（登録商標）ソース２０２をコンパイルし、Ｊａｖａ（登録商標）バイトコード２０３に変換する。
【００５０】
Ｊａｖａ（登録商標）バイトコード２０３は、コンピュータ上のインタプリタが実行するのに最適なように、かつ、ネットワーク１０６を経由して、取り込む際にも、通信の負担が軽くなるように、設計されている。しかし、Ｊａｖａ（登録商標）言語の特徴であるコンピュータアーキテクチャ独立を達成するために、バイトコードのフォーマットもコンピュータアーキテクチャ独立になっている。つまり、そのオペコードとオペランドはバイト単位でアライメントされている。
【００５１】
このＪａｖａ（登録商標）バイトコード２０３はＪａｖａ（登録商標）インタプリタ２０４によって解釈、実行される。
【００５２】
通常のコンピュータは２０１から２０４までを備えるが、本発明では、それらに加えて以下の要素を持つ。
【００５３】
バイトコード変換手段２０５はＪａｖａ（登録商標）バイトコード２０３を中間コード２０６に変換する。
【００５４】
中間コード２０６はＣＰＵ１０１が直接実行できるネイティブコードではない。しかし、ＣＰＵ１０１のアーキテクチャを考慮し、Ｊａｖａ（登録商標）バイトコード２０３よりも実行が速くなるよう、変換されたものである。例えば、ＣＰＵ１０１の一例として、ＭＩＰＳ ＲＩＳＣアーキテクチャ（ＭＩＰＳはＭＩＰＳ Ｔｅｃｈｎｏｌｏｇｉｅｓ，Ｉｎｃ．の登録商標である。ＲＩＳＣはＲｅｄｕｃｅｄ Ｉｎｓｔｒｕｃｔｉｏｎ Ｓｅｔ Ｃｏｍｐｕｔｅｒの略）を備えた３２ビットプロセッサの場合、メモリからデータを読み出す命令として、ＬＷ（Ｌｏａｄ Ｗｏｒｄ）、ＬＨ（Ｌｏａｄ Ｈａｌｆｗｏｒｄ）、ＬＨＵ（Ｌｏａｄ Ｈａｌｆｗｏｒｄ Ｕｎｓｉｇｎｅｄ）、ＬＢ（Ｌｏａｄ Ｂｙｔｅ）、ＬＢＵ（Ｌｏａｄ Ｂｙｔｅ Ｕｎｓｉｇｎｅｄ）がある。ＬＷは４バイトを、ＬＨ、ＬＨＵは２バイトを、ＬＢ、ＬＢＵは１バイトをそれぞれ読み出す命令である。しかし、ＬＷ、ＬＨ、ＬＨＵに関しては、どのメモリアドレスからもデータを読み出せるという訳ではない。ＬＷは４バイトアラインされたアドレス（つまりアドレスのＬＳＢ（Ｌｅａｓｔ Ｓｉｇｎｉｆｉｃａｎｔ Ｂｙｔｅ）が１６進表示で、０、４、８、Ｃのいずれかになっている）に対して実行される必要がある。ＬＨ及びＬＨＵは２バイトアラインされたアドレス（つまり、アドレスのＬＳＢが偶数になっている）に対して実行される必要がある。以上のようなメモリアライメント規則に違反すれば、ＣＰＵ例外が発生し、以降のプログラムが正常に実行できない。これはＭＩＰＳ（登録商標） ＣＰＵ（ＭＩＰＳ（登録商標） ＲＩＳＣアーキテクチャを備えたＣＰＵを単にこう呼ぶことにする）だけでなく、ＲＩＳＣ ＣＰＵ一般にあてはまる規則である。
【００５５】
従って、前記規則に違反しないよう、プログラムが設計されている必要がある。前述したように、Ｊａｖａ（登録商標）バイトコード２０３はバイト単位でアライメントされている。そうなると、ＲＩＳＣ ＣＰＵ上で動作するＪａｖａ（登録商標）インタプリタ２０４ではＪａｖａ（登録商標）バイトコード２０３のオペコードあるいはオペランドはバイト単位でアクセスすることが基本となる。これでは速度を向上させることができない。もし、オペコードあるいはオペランドが２バイトであると初めから分かっているなら、２バイトを一度に読み込んだ方が速いのは当然である。
【００５６】
これをＭＩＰＳ（登録商標）命令（ＭＩＰＳ（登録商標） ＲＩＳＣアーキテクチャの命令を単にこう呼ぶことにする）の例で比較すると、連続する２バイトがビッグエンディアン規則で配置された符号なし１６ビットの値を示すものである時、これをバイト単位でアクセスするなら、
LBU    $2,0($address)
LBU    $3,1($address)
SLL    $2,$2,8
OR    $2,$2,$3
（ここで、$2,$3はレジスタ名。$addressはアクセスされるアドレスが格納されているレジスタ。ＬＢＵは符号なし１バイトをメモリから読み出す命令で、結果を第１レジスタに入れる。読み出すアドレスは「オフセット（レジスタ）」の形式で表現されている時、レジスタに格納されているアドレス＋オフセットのアドレスになる。他のロード及びストア命令も同様である。ＳＬＬ（Ｓｈｉｆｔ Ｌｅｆｔ Ｌｏｇｉｃａｌ）は第２レジスタの内容を指定ビット数、左シフトして第１レジスタに格納する命令。ＯＲは第２及び第３レジスタの内容を論理和して、第１レジスタに格納する命令。）となり、４つの命令が必要になる。
【００５７】
一方、ハーフワード（２バイト）単位でアクセスするなら、アドレスが偶数番地でなければならないという制限はあるが、
LHU    $2,0($address)
という一つの命令で済む利点がある。
【００５８】
従って、中間コード２０６が前記利点を生かすように、配置されていれば、その実行速度が速くなることが望める。これはもちろん、ＭＩＰＳ（登録商標） ＣＰＵに限ったことではなく、同様のメモリアクセス方式を採っているＣＰＵならば、応用可能である。
【００５９】
中間コードインタプリタ２０７は上記のように配置された中間コード２０６を実行するものである。
【００６０】
図３は、Ｊａｖａ（登録商標）インタプリタ２０４の中のバイトコード処理ルーチンの動作フローを示したフローチャートである。
【００６１】
同図において、まず、Ｊａｖａ（登録商標）バイトコード２０３の中の実行しようとしているメソッドのコードから実行すべき次のオペコード（メソッドに最初に入った時は、最初のオペコード）を読み出す（ステップＳ３０１）。以下、この読み出したオペコードがどのオペコードに該当するかを判断して、該当するオペコードの処理ルーチンに飛んで、その処理ルーチンを実行する。例えば、オペコードがａｃｏｎｓｔ＿ｎｕｌｌである場合は（ステップＳ３０３）、ａｃｏｎｓｔ＿ｎｕｌｌの処理ルーチンを実行する（ステップＳ３０４）。これを実際のプログラムで実現する時は、Ｃ言語の場合は、ｓｗｉｔｃｈ文が使用される。一般的なＣ言語コンパイラは、ジャンプ先の多いｓｗｉｔｃｈ文を、ジャンプ先のアドレスを格納したテーブルを参照してジャンプするような実行コードに出力するので、実際には、図３に示したように、オペコードの比較が数多くなされるわけではない。
【００６２】
しかしながら、これでも改善できる点は残っている。一般的に、インタプリタでは、オペコードの解釈及びその処理ルーチンの実行を、何度も繰り返すため、このループをいかに短い時間で終了させるかが高速化のポイントとなる。
【００６３】
単にＣ言語のｓｗｉｔｃｈ文を使用した場合、各オペコード処理ルーチンの終了後、必ずループの先頭にジャンプし、そこで、次のオペコードを読み出し（ステップＳ３０１）、オペコード処理ルーチンアドレス格納テーブルにアクセスすることになる。
【００６４】
ここで、必ずループの先頭にジャンプする動作が無駄であるため、これを削除することが可能である。つまり、各オペコード処理ルーチンの終了後、引き続き、次のオペコードを読み出し、オペコード処理ルーチンアドレス格納テーブルにアクセスし、次のオペコードの処理ルーチンにジャンプすれば、少しは、全体の処理が高速化される。しかし、Ｊａｖａ（登録商標）バイトコード２０３をそのままの形で実行しようとすると、限界がある。
【００６５】
図４はＪａｖａ（登録商標）バイトコード２０３の一部及びそれを変換した中間コード２０６のデータフォーマットを示した図である。
【００６６】
ここで、Ｊａｖａ（登録商標）バイトコード２０３の一部はｉｌｏａｄ＿１及びｉｌｏａｄ＿２の２つの命令からなり、それぞれ１バイトの命令なので、計２バイトの長さを持つ。特開平１１−１７５３４９に開示された方法と同様に、バイトコード変換手段２０５は一つのオペコードとそのオペランドの組を最低４バイトに展開した中間コード２０６を作成する。ここでは、ｉｌｏａｄ＿１及びｉｌｏａｄ＿２がそれぞれ４バイトに展開され、８バイトになる。一つのオペコード及びオペランド（ｉｌｏａｄ＿１あるいはｉｌｏａｄ＿２の場合は、オペランドは存在しない）を展開した４バイトの内、上位２バイトには中間コードインタプリタ２０７における当該オペコードの処理ルーチンのアドレスが格納される。下位２バイトには、オペランドか、その変換結果が格納される。ｉｌｏａｄ＿１あるいはｉｌｏａｄ＿２の場合は、オペランドがないので、下位２ｂｙｔｅはＮＵＬＬ（つまり０）になっている。
【００６７】
ここで、ＣＰＵ１０１が３２ビットＣＰＵである場合、オペコード処理ルーチンのアドレスも３２ビットとなるので、２バイト幅に収まりきらないことになるが、中間コードインタプリタ２０７の中間コード処理ルーチン（Ｊａｖａ（登録商標）インタプリタ２０４で言うなら、図３に示したバイトコード処理ルーチンに当たる、メインループ部分）の全体が２バイトのアドレスが表現できる範囲、つまり６４ＫＢの範囲に収まるのであれば、中間コード処理ルーチンの先頭、あるいは、中間地点のアドレス等、他の適当な箇所をベースアドレスとして、そこからのオフセットを、前記上位２バイトに格納すればよい。
【００６８】
一つのオペコード及びオペランドの組を最低４バイトに展開した時は、オペランド格納部分も考慮して、処理ルーチンのアドレスを２バイトに収めた方がよいが、もし、一つのオペコード及びオペランドの組を最低８バイトに展開した時は、処理ルーチンのアドレスを上位４バイトに格納することが可能である。その場合の展開例を図２４に示す。このようにすれば、３２ビットＣＰＵの場合、処理ルーチンのアドレスをそのまま格納できるので、前記２バイトに格納した時のように、上位２バイトに格納されたオフセットを読み出し、前記ベースアドレスを加算して、処理ルーチンのアドレスを求めるという処理が不要になるので、さらに処理が速くなる。
【００６９】
バイトコード変換手段２０５におけるバイトコードを変換する動作であるバイトコード変換ルーチンの動作フローを図７のフローチャートに示す。全体の流れとしては、図３のバイトコード処理ルーチンのフローと同様、処理すべき次のオペコードを読み出し、そのオペコードに該当する変換ルーチンのアドレスにジャンプし、変換ルーチンを実行するという流れになる。図７においては、ＣＰＵ１０１がメモリ１０２あるいはＨＤ１０３に格納されたＪａｖａ（登録商標）バイトコード２０３を読み出し、そのＪａｖａ（登録商標）バイトコード２０３の中のメソッドのオペコードを順次読み出し、変換していく。
【００７０】
ここで、バイトコード変換ルーチン自体は、いつ実行されるのかという点については、中間コードインタプリタ２０７が走る以前に、既にバイトコード変換ルーチンが実行され、変換結果の中間コードがメモリ１０２あるいはＨＤ１０３に格納されていることにしてもよいし、中間コードインタプリタ２０７の実行中、あるＪａｖａ（登録商標）クラスをロードした時に、そのクラスの全てのメソッドについて変換するようにしてもよいし、あるメソッドを実行する直前に、そのメソッドについて変換するようにしてもよいし、あるいは、メソッドの実行頻度を調べて、実行頻度が高いメソッドについて変換するようにしてもよく、いずれかは問わない。
【００７１】
次に、前記図４のように変換された中間コード２０６に対する、中間コードインタプリタ２０７の処理プログラムの一例について、ＭＩＰＳ（登録商標）命令を用いて以下に記述する。図４のように、ｉｌｏａｄ＿１（インデックス１のローカル変数をＪａｖａ（登録商標）スタックにプッシュする命令）を変換した、中間コード２０６に対しては、（つまりこれがｉｌｏａｄ＿１に対する中間コード処理ルーチンである。）
LW    $2,4($locals)；ローカル変数読み出し
ADDIU    $stack,$stack,4
LHU    $3,4($pc)；次のオペコードのオフセットを読み出す
SW    $2,-4($stack)；スタックに書き込み
ADDU    $3,$3,$base
ADDIU    $pc,$pc,4；ＰＣの更新
JR    $3；次の処理ルーチンにジャンプ
（ここで、$localsはローカル変数の先頭アドレスを格納したレジスタ。$stackは現在のＪａｖａ（登録商標）スタックのアドレスを格納したレジスタ。$pcは中間コード２０６中の実行アドレスを格納したレジスタであり、$pcの値は処理ルーチン先頭では中間コード２０６のｉｌｏａｄ＿１の処理ルーチンアドレスを格納した上位２バイトのうちのＭＳＢを指すアドレスとなっている。$baseは中間コード２０６の中間コード処理ルーチンの前記ベースアドレスを格納したレジスタ。ＡＤＤＩＵ（Ａｄｄ Ｉｍｅｄｉａｔｅ Ｕｎｓｉｇｎｅｄ）は第２レジスタと第３オペランド即値を加算して第１レジスタに格納する命令。ＳＷ（Ｓｔｏｒｅ Ｗｏｒｄ）は第１レジスタに格納されているワードを指定アドレスのメモリに格納する命令。ＡＤＤＵ（Ａｄｄ Ｕｎｓｉｇｎｅｄ）は第２及び第３レジスタの内容を加算して、第１レジスタに格納する命令。ＪＲ（Ｊｕｍｐ Ｒｅｇｉｓｔｅｒ）はレジスタ内容のアドレスにジャンプする命令である。）の７命令で済む。
【００７２】
次に、ｂｉｐｕｓｈ（オペランドに指定されたバイトをスタックにプッシュする命令）のバイトコード変換例について図５を用いて説明する。
【００７３】
Ｊａｖａ（登録商標）バイトコード２０３においては、ｂｉｐｕｓｈ命令は図５に示したようにオペランド１バイトが続き、全体で２バイトの長さを持つ。これは２通りの中間コード２０６に変換される。オペランドのバイトが正の数である場合は、第３バイトが０になり、オペランドが負の数である場合は、第３バイトが１６進表示でＦＦになる。（ＣＰＵ１０１が負の数を表示するのに２の補数表現を用いる場合）このようにした理由は、後述するが、ｓｉｐｕｓｈ（オペランドに指定されたｓｈｏｒｔの値をスタックにプッシュする命令）と処理を共通化するためである。
【００７４】
中間コード２０６の上位２バイトはｂｉｓｐｕｓｈ＿ｓｉｐｕｓｈの処理ルーチンのアドレスが入る。ｂｉｐｕｓｈとｓｉｐｕｓｈの処理ルーチンを共通化できるので、このような処理ルーチンの名前にしている。
【００７５】
中間コード２０６のＬＳＢにはオペランドのバイトがそのまま入る。
【００７６】
ｂｉｐｕｓｈのバイトコード変換ルーチンの動作フローを図８のフローチャートを用いて説明する。
【００７７】
同図において、変換すべきＪａｖａ（登録商標）バイトコード２０３のオペコードがｂｉｐｕｓｈであった時、ＣＰＵ１０１はまず変換先中間コード２０６の上位２バイトにｂｉｐｕｓｈ＿ｓｉｐｕｓｈ処理ルーチンアドレスをセットする（ステップＳ８０１）。
【００７８】
次に、Ｊａｖａ（登録商標）バイトコード２０３からオペランドであるｂｙｔｅを読み出す（ステップＳ８０２）。
【００７９】
前記ｂｙｔｅが負の数であるかどうかをチェックし（ステップＳ８０３）、負の数でない場合は、中間コード２０６の第３バイトに０をセットする（ステップＳ８０４）。負の数である場合は、中間コード２０６の第３バイトに０ｘＦＦ（０ｘは１６進表示であることを示す）をセットする（ステップＳ８０５）。
【００８０】
次いで、中間コード２０６の第４バイトに前記ｂｙｔｅをそのまま格納して（ステップＳ８０６）、終了する。
【００８１】
次に、ｓｉｐｕｓｈのバイトコード変換例について図６を用いて説明する。
【００８２】
Ｊａｖａ（登録商標）バイトコード２０３においては、ｓｉｐｕｓｈ命令は図６に示したようにオペランド２バイトが続き、全体で３バイトの長さを持つ。
【００８３】
中間コード２０６の上位２バイトはｂｉｓｐｕｓｈ＿ｓｉｐｕｓｈの処理ルーチンのアドレスが入る。
【００８４】
中間コード２０６の下位２バイトにはオペランドの２バイトがそのまま入る。
【００８５】
ｓｉｐｕｓｈのバイトコード変換ルーチンの動作フローを図９のフローチャートを用いて説明する。
【００８６】
同図において、変換すべきＪａｖａ（登録商標）バイトコード２０３のオペコードがｓｉｐｕｓｈであった時、ＣＰＵ１０１はまず変換先中間コード２０６の上位２バイトにｂｉｐｕｓｈ＿ｓｉｐｕｓｈ処理ルーチンアドレスをセットする（ステップＳ９０１）。
【００８７】
次に、Ｊａｖａ（登録商標）バイトコード２０３から第１オペランドであるｓｈｏｒｔ＿ｈを読み出す（ステップＳ９０２）。
【００８８】
中間コード２０６の第３バイトに前記ｓｈｏｒｔ＿ｈを書き込む（ステップＳ９０３）。
【００８９】
Ｊａｖａ（登録商標）バイトコード２０３から第２オペランドであるｓｈｏｒｔ＿ｌを読み出す（ステップＳ９０４）。
【００９０】
中間コード２０６の第４バイトに前記ｓｈｏｒｔ＿ｌを書き込んで（ステップＳ９０５）終了する。
【００９１】
次に、前記図５あるいは図６のように変換された中間コード２０６に対する、中間コードインタプリタ２０７の処理プログラム（ｂｉｐｕｓｈ＿ｓｉｐｕｓｈ処理ルーチン）の一例についてＭＩＰＳ（登録商標）命令を用いて以下に記述する。
【００９２】
LH    $2,2($pc)；オペランド読み出し
ADDIU    $stack,$stack,4
LHU    $3,4($pc)；次のオペコードのオフセットを読み出す
SW    $2,-4($stack)；スタックに書き込み
ADDU    $3,$3,$base
ADDIU    $pc,$pc,4；ＰＣの更新
JR    $3；次の処理ルーチンにジャンプ
ｂｉｐｕｓｈにおいてもｓｉｐｕｓｈにおいても、そのオペランド読み出しは１行目の
LH    $2,2($pc)
になる。これは、ｂｉｐｕｓｈの変換時に、オペランドのｂｙｔｅを中間コード２０６のオペランドを格納する下位２バイトのうちのＬＳＢに格納し、さらに符号を考慮して第３バイトを適当な値で埋めたことによるものである。
【００９３】
このように、ｂｉｐｕｓｈとｓｉｐｕｓｈで処理が共通化され、同一処理ルーチンでまかなえ、処理ルーチンが１個節約できるという効果がある。これは、中間コード処理ルーチンの全体のサイズ削減につながるものであり、ＣＰＵ１０１のキャッシュが少ない場合、特に好ましい効果である。
【００９４】
なお、ここでは、ＣＰＵ１０１のメモリへのバイト配置がビッグエンディアンであることを前提として、中間コード２０６及び処理ルーチンを示したが、エンディアンの如何に関わらず、本発明の実施は同様になされ得る。以下、同様である。
【００９５】
次に、ｉｌｏａｄ（オペランドにローカル変数のインデックスが指定され、指定インデックスのローカル変数をＪａｖａ（登録商標）スタックにプッシュする命令）のバイトコード変換例について図１０を用いて説明する。
【００９６】
Ｊａｖａ（登録商標）バイトコード２０３においては、ｉｌｏａｄ命令は図１０に示したようにオペランド１バイト（ｉｎｄｅｘ）が続き、全体で２バイトの長さを持つ。このオペランドは前述した通り、ローカル変数のインデックスを意味する。
【００９７】
中間コード２０６の上位２バイトはｉｌｏａｄの処理ルーチンのアドレスが入る。
【００９８】
中間コード２０６の下位２バイトには前記ｉｎｄｅｘを４倍した結果が入る。元のｉｎｄｅｘは１バイトなので、その取り得る値は０〜２５５である。これを４倍しても十分、２バイト幅に収まる値となる。
【００９９】
図１１に、Ｊａｖａ（登録商標）スタックにおけるローカル変数の格納方法を示す。同図で示すように、本発明の機器におけるＪａｖａ（登録商標）スタックは４バイト幅である。これは、Ｊａｖａ（登録商標）言語の仕様上、４バイトにするのが、最も自然であるからであるが、他のバイト幅にできないというわけではない。
【０１００】
ＣＰＵ１０１があるメソッドを実行中のＪａｖａ（登録商標）スタックの様子が図１１である。そのメソッドのフレームにおけるローカル変数の先頭アドレスから、ローカル変数が順番にＪａｖａ（登録商標）スタックに積まれている。先頭にはインデックス０のローカル変数、先頭＋４番地にはインデックス１のローカル変数、先頭＋８番地にはインデックス２のローカル変数が格納される。以下、同様である。
【０１０１】
ｉｌｏａｄのバイトコード変換ルーチンの動作フローを図１２のフローチャートを用いて説明する。
【０１０２】
同図において、変換すべきＪａｖａ（登録商標）バイトコード２０３のオペコードがｉｌｏａｄであった時、ＣＰＵ１０１はまず変換先中間コード２０６の上位２バイトにｉｌｏａｄ処理ルーチンアドレスをセットする（ステップＳ１２０１）。
【０１０３】
次に、Ｊａｖａ（登録商標）バイトコード２０３から第１オペランドであるｉｎｄｅｘを読み出す（ステップＳ１２０２）。
【０１０４】
前記ｉｎｄｅｘを４倍する（ステップＳ１２０３）。そして、中間コード２０６の下位２バイトに前記ｉｎｄｅｘを４倍した結果を書き込んで（ステップＳ１２０４）、終了する。
【０１０５】
次に、前記図１０のように変換された中間コード２０６に対する、中間コードインタプリタ２０７の処理プログラム（ｉｌｏａｄ処理ルーチン）の一例についてＭＩＰＳ（登録商標）命令を用いて以下に記述する。
【０１０６】
LHU    $2,2($pc)；オペランド読み出し
ADDU    $2,$2,$locals；ローカル変数の格納アドレスを求める
LW    $2,0($2)            ；ローカル変数を読み出す
ADDIU    $stack,$stack,4
LHU    $3,4($pc)；次のオペコードのオフセットを読み出す
SW    $2,-4($stack)；スタックに書き込み
ADDU    $3,$3,$base
ADDIU    $pc,$pc,4；ＰＣの更新
JR    $3；次の処理ルーチンにジャンプ
このように、ｉｌｏａｄ処理ルーチンにおいては、前もってｉｎｄｅｘを４倍しておけば、ローカル変数の格納アドレスを求める際に、４倍する必要がなくなり、処理速度が向上する。
【０１０７】
本発明においては、中間コード２０６の各オペコード及びオペランドの組の変換データが最低４バイト長となっており、オペランドには最低２バイトを格納できるので、以上のことが可能になっている。
【０１０８】
なお、ここでｉｎｄｅｘを４倍したのは、ローカル変数のアドレスは、
ローカル変数アドレス＝ローカル変数先頭アドレス＋インデックス＊Ｊａｖａ（登録商標）スタックバイト幅
として求められ、本発明の機器においては、Ｊａｖａ（登録商標）スタックが４バイト幅になっているためである。Ｊａｖａ（登録商標）スタックのバイト幅が異なっていれば、前もって乗じておくのは、そのバイト幅ということになる。
【０１０９】
次に、ｌｄｃ（オペランドにコンスタントプールのインデックスが指定され、指定インデックスが指すコンスタント値（ｉｎｔかｆｌｏａｄかＳｔｒｉｎｇリテラルである）をＪａｖａ（登録商標）スタックにプッシュする命令）のバイトコード変換例について図１３を用いて説明する。
【０１１０】
Ｊａｖａ（登録商標）バイトコード２０３においては、ｌｄｃ命令は図１３に示したようにオペランド１バイト（ｉｎｄｅｘ）が続き、全体で２バイトの長さを持つ。このオペランドは前述した通り、コンスタントプールのインデックスを意味する。
【０１１１】
中間コード２０６の上位２バイトはｌｄｃの処理ルーチンのアドレスが入る。
【０１１２】
中間コード２０６の下位２バイトには前記ｉｎｄｅｘを４倍した結果が入る。元のｉｎｄｅｘは１バイトなので、その取り得る値は０〜２５５である。これを４倍しても十分、２バイト幅に収まる値となる。
【０１１３】
図１４に、コンスタントプールデータがメモリ１０２上に展開されている様子を示す。コンスタントプールはＪａｖａ（登録商標）クラスファイル中に格納されている。コンスタントプールはサイズ削減とコンピュータアーキテクチャ独立を達成するため、これもまたバイトアライメントされて、前記Ｊａｖａ（登録商標）クラスファイル中に格納されている。従って、そのデータ構造はそのままではＣＰＵ１０１がアクセスしにくいものであり、通常、ＣＰＵ１０１はアクセス速度が上がるように、コンスタントプールをメモリ１０２上に展開する。
【０１１４】
その一例を示したのが、図１４である。各コンスタントプールデータはメモリ１０２中に確保され、各々のデータを指すポインタを配列の中に格納するようになっている。このようにしておけば、コンスタントプールのインデックスが指定された時に、即座にデータそのものにアクセスできる。
【０１１５】
図１４におけるコンスタントプールのデータを指すポインタの配列は４バイト幅となっている。これはＣＰＵ１０１のポインタの幅である。
【０１１６】
ｌｄｃのバイトコード変換ルーチンの動作フローを図１５のフローチャートを用いて説明する。
【０１１７】
同図において、変換すべきＪａｖａ（登録商標）バイトコード２０３のオペコードがｌｄｃであった時、ＣＰＵ１０１はまず変換先中間コード２０６の上位２バイトにｌｄｃ処理ルーチンアドレスをセットする（ステップＳ１５０１）。
【０１１８】
次に、Ｊａｖａ（登録商標）バイトコード２０３から第１オペランドであるｉｎｄｅｘを読み出す（ステップＳ１５０２）。
【０１１９】
前記ｉｎｄｅｘを４倍する（ステップＳ１５０３）。そして、中間コード２０６の下位２バイトに前記ｉｎｄｅｘを４倍した結果を書き込んで（ステップＳ１５０４）、終了する。
【０１２０】
以上のようにすると、前記図１３のように変換された中間コード２０６に対する中間コードインタプリタ２０７の処理プログラム（ｌｄｃ処理ルーチン）においては、ｉｌｏａｄ処理ルーチンの項で説明したのと同様、前もってｉｎｄｅｘを４倍しておけば、コンスタントプールデータの格納アドレスを求める際に、４倍する必要がなくなり、処理速度が向上する。
【０１２１】
なお、ここでｉｎｄｅｘを４倍したのは、コンスタントプールデータのアドレスは、
コンスタントプールデータアドレス＝コンスタントプールデータポインタ配列先頭アドレス＋インデックス＊ポインタ幅
として求められ、ＣＰＵ１０１においては、ポインタ幅が４バイトになっているためである。ポインタ幅が異なるＣＰＵ１０１においては、前もって乗じておくのは、ポインタ幅ということになる。
【０１２２】
次に、ｌｄｃ＿ｗ（オペランドにコンスタントプールのインデックスが２バイトで指定され、指定インデックスが指すコンスタント値（ｉｎｔかｆｌｏａｄかＳｔｒｉｎｇリテラルである）をＪａｖａ（登録商標）スタックにプッシュする命令）のバイトコード変換例について図１６を用いて説明する。
【０１２３】
Ｊａｖａ（登録商標）バイトコード２０３においては、ｌｄｃ＿ｗ命令は図１６に示したようにオペランド２バイト（ｉｎｄｅｘ＿ｈ及びｉｎｄｅｘ＿ｌ）が続き、全体で３バイトの長さを持つ。このオペランドは前述した通り、コンスタントプールのインデックスを意味する。インデックスはｉｎｄｅｘ＿ｈ＊２５６＋ｉｎｄｅｘ＿ｌで計算される。
【０１２４】
このオペコードの変換結果である中間コード２０６は２通りに分かれる。
【０１２５】
一方は、中間コード２０６の長さが４バイト長であり、下位２バイトに前記インデックスの４倍値が格納されたものである。インデックスの４倍値が２バイト長に収まる場合に、この変換方法が採られる。
【０１２６】
もう一方は、中間コード２０６の長さが８バイト長であり、下位４バイトに前記インデックスの４倍値が格納されたものである。インデックスの４倍値が２バイト長に収まらない場合に、この変換方法が採られる。
【０１２７】
なお、インデックスが４倍される理由は、ｌｄｃの場合と同じく、これもコンスタントプールデータのアドレスを求める処理が必須であり、ＣＰＵ１０１のポインタ幅が４バイトであるためである。
【０１２８】
当然、両者の間で処理ルーチンを変えなければいけないため、前者の処理ルーチンをｌｄｃ＿ｗ＿Ａ処理ルーチン、後者をｌｄｃ＿ｗ＿Ｂ処理ルーチンとしている。従って、前者の中間コード２０６の上位２バイトにはｌｄｃ＿ｗ＿Ａ処理ルーチンのアドレスが格納され、後者の中間コード２０６の上位２バイトにはｌｄｃ＿ｗ＿Ｂ処理ルーチンのアドレスが格納されている。
【０１２９】
ｌｄｃ＿ｗのバイトコード変換ルーチンの動作フローを図１７のフローチャートを用いて説明する。
【０１３０】
同図において、変換すべきＪａｖａ（登録商標）バイトコード２０３のオペコードがｌｄｃ＿ｗであった時、ＣＰＵ１０１はまず、Ｊａｖａ（登録商標）バイトコード２０３のオペランドｉｎｄｅｘ＿ｈ及びｉｎｄｅｘ＿ｌを読み出す（ステップＳ１７０１）。
【０１３１】
前述の式に基づいて、インデックスを計算する（ステップＳ１７０２）。次いで、これを４倍する（ステップＳ１７０３）。
【０１３２】
次に、前記４倍値が２バイト長に収まるか否かを判断し（ステップＳ１７０４）、収まる場合は、ｌｄｃ＿ｗ＿Ａの処理ルーチンのアドレスを４バイト長の中間コード２０６の中の上位２バイトに書き込む（ステップＳ１７０５）。その後、前記４倍値を下位２バイトに書き込んで（ステップＳ１７０６）、終了する。
【０１３３】
前記４倍値が２バイト長に収まらない場合は、ｌｄｃ＿ｗ＿Ｂ処理ルーチンのアドレスを８バイト長の中間コード２０６の中の上位２バイトに書き込む（ステップＳ１７０７）。そして、第１ワードの下位２バイトには０を書き込む（ステップＳ１７０８）。この下位２バイトにはアクセスしないので、実は値は何でも良い。この書き込みを省略してもよい。最後に、第２ワードに前記４倍値を書き込んで（ステップＳ１７０９）、終了する。
【０１３４】
以上のようにすると、前記図１６のように変換された中間コード２０６に対する中間コードインタプリタ２０７の処理プログラム（ｌｄｃ＿ｗ＿Ａまたはｌｄｃ＿ｗ＿Ｂ処理ルーチン）においては、ｌｄｃ＿ｗ処理ルーチンの項で説明したのと同様、前もってｉｎｄｅｘを４倍しておけば、コンスタントプールデータの格納アドレスを求める際に、４倍する必要がなくなり、処理速度が向上する。
【０１３５】
ｌｄｃ＿ｗ以外にも、オペランドが２バイト長である他のオペコードに対して、同様のバイトコード変換が行える。
【０１３６】
つまり、オペランドが２バイト長であり、それが中間コード２０６の処理時に必ず所定の計算が必要になるものであり、該所定の計算を前もって行っておくとすると、２バイト長に収まりきらない可能性がある場合は、４バイトの中間コード２０６を備える処理ルーチンと８バイトの中間コード２０６を備える処理ルーチンを持つというものである。
【０１３７】
このようにした場合、処理ルーチンの種類が増える。しかし、Ｊａｖａ（登録商標）バイトコード２０３の場合はオペコードが１バイトであったため、２５６種類以上のオペコードは持てず、最適化のためにオペコードの種類を増やすには制限があったが、本発明においては、オペコードが２バイトのアドレスになっているため、６４ＫＢに処理ルーチン全体が収まるのであれば、処理ルーチンの種類を増やすことは問題ない。
【０１３８】
次に、ｇｏｔｏ（オペランドにオフセットが２バイトで指定され、現在のＪａｖａ（登録商標）バイトコード２０３の実行アドレスに指定オフセットを加えたアドレスにジャンプする命令）のバイトコード変換例について図１８を用いて説明する。
【０１３９】
Ｊａｖａ（登録商標）バイトコード２０３においては、ｇｏｔｏ命令は図１８に示したようにオペランド２バイト（ｏｆｆｓｅｔ＿ｈ及びｏｆｆｓｅｔ＿ｌ）が続き、全体で３バイトの長さを持つ。このオペランドは前述した通り、Ｊａｖａ（登録商標）バイトコード２０３上でのオフセットを意味する。オフセットはｏｆｆｓｅｔ＿ｈ＊２５６＋ｏｆｆｓｅｔ＿ｌで計算される。
【０１４０】
このオペコードの変換結果である中間コード２０６は２通りに分かれる。
【０１４１】
一方は、中間コード２０６の長さが４バイト長であり、下位２バイトに中間コード２０６上でのオフセットが格納されたものである。このオフセットが２バイト長に収まる場合に、この変換方法が採られる。
【０１４２】
もう一方は、中間コード２０６の長さが８バイト長であり、下位４バイトに中間コード２０６上でのオフセットが格納されたものである。このオフセットが２バイト長に収まらない場合に、この変換方法が採られる。
【０１４３】
今まで見てきたように、Ｊａｖａ（登録商標）バイトコード２０３の各オペコード及びオペランドの組は最低４バイト長の中間コード２０６に変換される。従って、当然Ｊａｖａ（登録商標）バイトコード２０３におけるジャンプの際のオフセットよりも中間コード２０６におけるジャンプの際のオフセットの方が大きくなる。つまり２バイト長に収まりきらない可能性があるのでこのようにする必要が生じる。
【０１４４】
当然、両者の間で処理ルーチンを変えなければいけないため、前者の処理ルーチンをｇｏｔｏ＿Ａ処理ルーチン、後者をｇｏｔｏ＿Ｂ処理ルーチンとしている。従って、前者の中間コード２０６の上位２バイトにはｇｏｔｏ＿Ａ処理ルーチンのアドレスが格納され、後者の中間コード２０６の上位２バイトにはｇｏｔｏ＿Ｂ処理ルーチンのアドレスが格納されている。
【０１４５】
ｇｏｔｏのバイトコード変換ルーチンの動作フローを図１９のフローチャートを用いて説明する。
【０１４６】
同図において、変換すべきＪａｖａ（登録商標）バイトコード２０３のオペコードがｇｏｔｏであった時、ＣＰＵ１０１はまず、Ｊａｖａ（登録商標）バイトコード２０３のオペランドｏｆｆｓｅｔ＿ｈ及びｏｆｆｓｅｔ＿ｌを読み出す（ステップＳ１９０１）。
【０１４７】
前述の式に基づいて、オフセットを計算する（ステップＳ１９０２）。
【０１４８】
次に、前記オフセットの指すＪａｖａ（登録商標）バイトコード２０３のオペコードの位置が、中間コード２０６上でのオフセットでいくつになるか求まるまで待機する（ステップＳ１９０３）。
【０１４９】
すでに中間コード２０６の配置が決定した、後方にジャンプするのであれば、中間コード２０６上でのオフセットが即座に求まるので、待機する必要は無いが、前方にジャンプするのであれば、まだ中間コード２０６の配置が決定していないため、（例えば前記ｌｄｃ＿ｗのように４バイト長に変換されるか、８バイト長に変換されるか、オペランドを見てみないと分からないものがある）、中間コード２０６上でのオフセットを求めることはできない。
【０１５０】
従って、このオフセットの決定を保留し、ｇｏｔｏの次のバイトコードの変換を先に進めておく。そして、当該オペコードの中間コード２０６上でのオフセットが確定した時点で、ステップＳ１９０４以降を実行する。
【０１５１】
オフセットが確定すると、該中間コード２０６上でのオフセットが２バイト長に収まるか否かを判定し（ステップＳ１９０４）、収まる場合はｇｏｔｏ＿Ａの処理ルーチンのアドレスを４バイト長の中間コード２０６の上位２バイトに書き込む（ステップＳ１９０５）。次いで、前記のようにして求めた中間コード２０６上のオフセットを下位２バイトに書き込んで（ステップＳ１９０６）、終了する。
【０１５２】
中間コード２０６上でのオフセットが２バイト長に収まらない場合は、ｇｏｔｏ＿Ｂの処理ルーチンのアドレスを８バイト長の中間コード２０６の第一ワード上位２バイトに書き込む（ステップＳ１９０７）。
【０１５３】
次いで、第一ワード下位２バイトに０を書き込む（ステップＳ１９０８）。この処理は、ステップＳ１７０８で説明したのと同様、必須なものではない。
【０１５４】
最後に、第２ワードに中間コード２０６のオフセットの値を書き込んで（ステップＳ１９０９）、終了する。
【０１５５】
このように、ｇｏｔｏからはｇｏｔｏ＿Ａとｇｏｔｏ＿Ｂという２通りの処理に変換されるが、ｇｏｔｏと同様のＪａｖａ（登録商標）バイトコード２０３の処理にｇｏｔｏ＿ｗというものがある。これはジャンプ先のオフセットを表すオペランドが４バイト長になっている。ｇｏｔｏ＿ｗを変換する際は、ｇｏｔｏ＿Ｂに変換しておけばよい。何故なら、ＣＰＵ１０１は３２ビットアドレスなので、オフセットが４バイト長であれば、どのアドレスへのジャンプも表現できるからである。従って、ｇｏｔｏ、ｇｏｔｏ＿ｗの場合は、ｇｏｔｏ＿Ａまたはｇｏｔｏ＿Ｂのいずれかに変換されることになり、処理ルーチンの数は増えないことになる。
【０１５６】
次に、ｉｎｖｏｋｅｉｎｔｅｒｆａｃｅ（オペランドにコンスタントプールのメソッドをさすインデックスが２バイトで指定され、そのメソッドをコールする命令）のバイトコード変換例について図２０を用いて説明する。
【０１５７】
Ｊａｖａ（登録商標）バイトコード２０３においては、ｉｎｖｏｋｅｉｎｔｅｒｆａｃｅ命令は図２０に示したようにオペランド４バイト（ｉｎｄｅｘ＿ｈ、ｉｎｄｅｘ＿ｌ、ｃｏｕｎｔ、０）が続き、全体で５バイトの長さを持つ。このｉｎｄｅｘ＿ｈおよびｉｎｄｅｘ＿ｌオペランドは前述した通り、コンスタントプール中のメソッドを指すインデックスを意味する。インデックスはｉｎｄｅｘ＿ｈ＊２５６＋ｉｎｄｅｘ＿ｌで計算される。
【０１５８】
これは８バイト長の中間コード２０６に変換される。第１ワード上位２バイトにｉｎｖｏｋｅｉｎｔｅｒｆａｃｅの処理ルーチンのアドレスが入り、第１ワード第３バイトにｃｏｕｎｔ、第４バイトに０がそれぞれ入る。第２ワードには前記インデックスの４倍値が入る。
【０１５９】
ここでは、中間コード２０６が４バイト長のものと８バイト長のもの、２通り備える必要はない。他のオペランド（ｃｏｕｎｔ及び０）があるので、４バイト長に収めることは不可能であるからである。従って、インデックス格納に第２ワード全体使用することができ、２バイト長に収まるかどうかの判定も不要になる。
【０１６０】
ｉｎｖｏｋｅｉｎｔｅｒｆａｃｅのバイトコード変換ルーチンの動作フローを図２１のフローチャートを用いて説明する。
【０１６１】
同図において、変換すべきＪａｖａ（登録商標）バイトコード２０３のオペコードがｉｎｖｏｋｅｉｎｔｅｒｆａｃｅであった時、ＣＰＵ１０１はまず、中間コード２０６上のｉｎｖｏｋｅｉｎｔｅｒｆａｃｅ処理ルーチンのアドレスを８バイト長の中間コード２０６の中の第１ワード上位２バイトにセットする（ステップＳ２１０１）。
【０１６２】
次いで、Ｊａｖａ（登録商標）バイトコード２０３のオペランドｉｎｄｅｘ＿ｈ及びｉｎｄｅｘ＿ｌを読み出す（ステップＳ２１０２）。
【０１６３】
前述の式に基づいて、インデックスを計算し、さらにこれを４倍する（ステップＳ２１０３）。
【０１６４】
次に、中間コード２０６の第１ワード下位２バイトにオペランドｃｏｕｎｔ及び０を書き込む（ステップＳ２１０４）。
【０１６５】
最後に、第２ワードに前記インデックスの４倍値を書き込んで（ステップＳ２１０５）、終了する。
【０１６６】
次に、ｎｅｗａｒｒａｙ（オペランドに型が示され、その型の要素を持つ配列を作成する命令）のバイトコード変換例を、図２２を用いて説明する。
【０１６７】
Ｊａｖａ（登録商標）バイトコード２０３においては、ｎｅｗａｒｒａｙ命令は図２２に示したようにオペランド１バイト（ａｔｙｐｅ）が続き、全体で２バイトの長さを持つ。このａｔｙｐｅオペランドは前述した通り、作成しようとする配列の要素の型を意味する。具体的には、型がｂｏｏｌｅａｎの場合は、値が４、ｃｈａｒの場合は５、ｆｌｏａｔの場合は６、ｄｏｕｂｌｅの場合は７、ｂｙｔｅの場合は８、ｓｈｏｒｔの場合は９、ｉｎｔの場合は１０、ｌｏｎｇの場合は１１である。
【０１６８】
この命令は４バイト長の中間コード２０６に変換される。上位２バイトにｎｅｗａｒｒａｙの処理ルーチンのアドレスが入り、下位２バイトにはａｔｙｐｅ−４の値が入る。ａｔｙｐｅ−４の取り得る値の範囲を考えると、これが２バイト長に収まることは自明である。
【０１６９】
ｎｅｗａｒｒａｙのバイトコード変換ルーチンの動作フローを図２３のフローチャートを用いて説明する。
【０１７０】
同図において、変換すべきＪａｖａ（登録商標）バイトコード２０３のオペコードがｎｅｗａｒｒａｙであった時、ＣＰＵ１０１はまず、中間コード２０６上のｎｅｅｗａｒｒａｙ処理ルーチンのアドレスを４バイト長の中間コード２０６の中の上位２バイトにセットする（ステップＳ２３０１）。
【０１７１】
次いで、Ｊａｖａ（登録商標）バイトコード２０３のオペランドａｔｙｐｅを読み出す（ステップＳ２３０２）。
【０１７２】
ａｔｙｐｅ−４を計算する（ステップＳ２３０３）。
【０１７３】
最後に、下位２バイトに前記ａｔｙｐｅ−４の値を書き込んで（ステップＳ２３０４）、終了する。
【０１７４】
何故、ａｔｙｐｅ−４の値を求めておくのかという理由については、以下の条件が成立する時、処理速度が速くなるからである。つまり、各型の情報（型の長さ等）が配列に格納されており、各型の情報が格納されている順番は、前述した各型のａｔｙｐｅの値の順番と同一になっており、さらに、ｂｏｏｌｅａｎ型に対応する情報が配列の先頭に格納されているという条件の下では、各型の情報にアクセスする際、通常ではａｔｙｐｅ−４の計算が必須になるが、前もってこれを行っておけば、実行時には不要になるからである。
【０１７５】
前記のｂｏｏｌｅａｎ型に対応する情報が配列の先頭からオフセット４の所に配置されれば、ａｔｙｐｅ−４の値を求めて中間コード２０６中に格納する手順は不要になるが、配列に余分な領域が必要になる。
【０１７６】
以上、本発明の実施例を説明してきた。前記実施例では主にＪａｖａ（登録商標）バイトコード２０３の一つのオペコード及びオペランドの組を最低４バイトの中間コード２０６に変換する例について、説明したが、本発明の応用例はこれにとどまるものではない。図２４を用いて説明したように、最低８バイトあるいはそれ以上のバイト長を持つ中間コード２０６にも変換できる。最低８バイト長にした場合は、オペランド格納場所に余裕ができるので、前記ｌｄｃ＿ｗ等のように、２通りに中間コード２０６を分けるということの必要性は低くなるであろう。
【０１７７】
また、前記実施例はＪａｖａ（登録商標）言語におけるバイトコード並びにその変換方法について詳しく説明してきたが、本発明の言わんとする所は、Ｊａｖａ（登録商標）言語のみにとどまるものではなく、同様のバイトコード構造を持つ他の言語にも応用可能なものである。さらには、バイトコード構造さえ持てばよいのであるから、ソースコード記述法を定めた言語でさえなくともよく、あらかじめオペコードとオペランドが定義されたバイナリデータ列であっても、本発明は応用可能である。
【０１７８】
また、本発明の処理手順を実行させるためのプログラム及びこれを記録した記憶媒体も、本発明の範疇に入ることは明らかである。
【図面の簡単な説明】
【０１７９】
【図１】ハードウエア構成を示したブロック図である。
【図２】Ｊａｖａ（登録商標）言語におけるデータとデータ変換及び解釈、実行手段を示したブロック図である。
【図３】バイトコード処理ルーチンのフローチャートである。
【図４】ｉｌｏａｄ＿１及びｉｌｏａｄ＿２の変換前と変換後のデータフォーマットを示した図である。
【図５】ｂｉｐｕｓｈの変換前と変換後のデータフォーマットを示した図である。
【図６】ｓｉｐｕｓｈの変換前と変換後のデータフォーマットを示した図である。
【図７】バイトコード変換ルーチンのフローチャートである。
【図８】バイトコード変換ルーチンにおけるｂｉｐｕｓｈ処理ルーチンのフローチャートである。
【図９】バイトコード変換ルーチンにおけるｓｉｐｕｓｈ処理ルーチンのフローチャートである。
【図１０】ｉｌｏａｄの変換前と変換後のデータフォーマットを示した図である。
【図１１】Ｊａｖａ（登録商標）スタックにおけるローカル変数の格納を示した図である。
【図１２】バイトコード変換ルーチンにおけるｉｌｏａｄ処理ルーチンのフローチャートである。
【図１３】ｌｄｃの変換前と変換後のデータフォーマットを示した図である。
【図１４】コンスタントプールデータのメモリ中の展開の様子を示した図である。
【図１５】バイトコード変換ルーチンにおけるｌｄｃ処理ルーチンのフローチャートである。
【図１６】ｌｄｃ＿ｗの変換前と変換後のデータフォーマットを示した図である。
【図１７】バイトコード変換ルーチンにおけるｌｄｃ＿ｗ処理ルーチンのフローチャートである。
【図１８】ｇｏｔｏの変換前と変換後のデータフォーマットを示した図である。
【図１９】バイトコード変換ルーチンにおけるｇｏｔｏ処理ルーチンのフローチャートである。
【図２０】ｉｎｖｏｋｅｉｎｔｅｒｆａｃｅの変換前と変換後のデータフォーマットを示した図である。
【図２１】バイトコード変換ルーチンにおけるｉｎｖｏｋｅｉｎｔｅｒｆａｃｅ処理ルーチンのフローチャートである。
【図２２】ｎｅｗａｒｒａｙの変換前と変換後のデータフォーマットを示した図である。
【図２３】バイトコード変換ルーチンにおけるｎｅｗａｒｒａｙ処理ルーチンのフローチャートである。
【図２４】ｉｌｏａｄ＿１及びｉｌｏａｄ＿２の変換前と変換後のデータフォーマットを示した図である。
【符号の説明】
【０１８０】
１０１  ＣＰＵ
１０２  メモリ
１０３  ハードディスク
１０４  ディスプレイ
１０５  ネットワークインタフェース
１０６  ネットワーク
２０１  ソース
２０２  コンパイラ
２０３  バイトコード
２０４  インタプリタ
２０５  バイトコード変換手段
２０６  中間コード
２０７  中間コードインタプリタ
【図１】
2007094828.tif 000003
【図２】
2007094828.tif 000004
【図３】
2007094828.tif 000005
【図４】
2007094828.tif 000006
【図５】
2007094828.tif 000007
【図６】
2007094828.tif 000008
【図７】
2007094828.tif 000009
【図８】
2007094828.tif 000010
【図９】
2007094828.tif 000011
【図１０】
2007094828.tif 000012
【図１１】
2007094828.tif 000013
【図１２】
2007094828.tif 000014
【図１３】
2007094828.tif 000015
【図１４】
2007094828.tif 000016
【図１５】
2007094828.tif 000017
【図１６】
2007094828.tif 000018
【図１７】
2007094828.tif 000019
【図１８】
2007094828.tif 000020
【図１９】
2007094828.tif 000021
【図２０】
2007094828.tif 000022
【図２１】
2007094828.tif 000023
【図２２】
2007094828.tif 000024
【図２３】
2007094828.tif 000025
【図２４】
2007094828.tif 000026