Learn · concepts

ASM (Java バイトコード) とは何?ライブラリ解説

ASMは、実行時にJVMバイトコードの読み書きを行うためのJavaライブラリです。以下に、その機能、仕組み、そしてMinecraftのMODがそれを利用する理由について説明します.

TRtrolPublished 1 min read

MinecraftMOD開発におけるASMとは?

ASMは、JVMのバイトコードを読み書きするためのJavaライブラリです。ソースコードではなくコンパイルされた.classファイルを対象とするため、再コンパイルすることなくクラスを検査したり書き換えたりすることができます。MinecraftのMODは、ゲームがすでにコンパイルされた後、ロード時にゲームをパッチ適用できるため、ASMに依存しています。

バイトコードパッチングの存在意義

Minecraftのゲームは、ソースではなくコンパイルされたバイトコードとして配布されています。そのため、MOD開発者はソースコードを変更してゲーム全体を再コンパイルすることはできません。なぜなら、ソースコードが存在しないからです。コードを所有していないものを修正する唯一の方法は、Java仮想マシンが実際に実行する命令セットであるバイトコードレベルで介入することです。ASMは、その作業のための実用的なツールです。

ASMの仕組み

ASMは、コンパイルされたクラスをプログラムが編集できる形に変換します。.classファイルは単なるバイトコードであり、Java仮想マシンが実行する命令です。ASMは、そのバイトコードを解析し、メソッドとフィールドをあなたに渡し、命令の追加、削除、または変更を許可します。その後、新しい有効なクラスを書き出します。

通常のJavaでは、これを行うことはできません。コンパイラは、ソースコードを一度バイトコードに変換し、その後、バイトコードは固定されます。ASMは、通常記述するソースコードの層より下の、バイトコードレベルで介入します。

訪問者パターンとツリーAPI

ASMはClassReaderでクラスを読み込み、ClassWriterで書き込みます。その間、コードはクラスのパーツを走査し、変更する内容を決定します。アプローチは2つあります。

ビジターアプローチは、クラスを要素ごとに1つずつ処理します。高速でメモリ使用量が少ないという利点があり、クラス全体を一度に保持しないからです。一方、ツリーアプローチは、クラスを自由に歩き回り、編集できるオブジェクトにロードします。大規模な変更には理解しやすくなりますが、より多くのメモリを使用します。

アプローチ仕組み最適
ビジターAPIクラスのイベントを読み取りながらストリーム処理メモリ使用量を抑えつつ、小規模で高速な編集
ツリーAPIクラスの編集可能なオブジェクトモデルを構築大規模または複雑な書き換え

MinecraftのModがASMを使用する理由

Modは、書き換えられないコンパイル済みのゲームコードを変更する必要があります。ゲームはコンパイルされたクラスとして提供されるため、唯一の侵入経路はバイトコードレベルであり、ASMがそれを実現します。Modは、ゲームメソッドにフックを挿入したり、呼び出しをリダイレクトしたり、フィールドを追加したりするなど、起動時に様々な操作を実行できます。

ほとんどのMod開発者は、ASMを直接呼び出すことはありません。ASMの上に構築された高レベルのフレームワークであるMixinを使用し、簡単なアノテーションをASMのバイトコード編集に変換します。変更内容を記述した小さなJavaクラスを作成するだけで、フレームワークがASMを使って低レベルの作業を代行してくれます。特にFabric Modは、このチェーンに依存しています.

ASMを直接触る必要がある場合

mod作者として、生のASMを直接書くことはほとんどありません。ローダー、オブスクレータ、あるいはクラス全体を書き換えるパッチャーなど、アノテーションでは表現できないほど詳細な制御が必要なツールに現れる場合です。普段のmodであれば、アノテーション層があれば十分であり、ミスが起こりにくいです.

よくある質問