3

たとえば、メソッドの場合

public int f() {
    int k = 1;
    for (int i = 0; i < 10; i++) {
        k += 2;
    }
    return k;
}

javac次のバイトコードを生成します。

public int f();
Code:
   0: iconst_1
   1: istore_1
   2: iconst_0
   3: istore_2
   4: iload_2
   5: bipush        10
   7: if_icmpge     19
  10: iinc          1, 2
  13: iinc          2, 1
  16: goto          4
  19: iload_1
  20: ireturn

ラベル 4 では、前の命令が 3 か 16 かに関係なく、スタックのサイズは同じ (0) です。

Javaコードから生成されたバイトコードには一般的に当てはまりますか?

4

2 に答える 2

4

Antimony の回答への参照については、 JVM 仕様 §4.9.2 を参照してください。構造上の制約(Holger さん、ありがとうございます!):

  • ...
  • 命令が複数の異なる実行パスに沿って実行できる場合、オペランド スタックは、実行されるパスに関係なく、命令の実行前に同じ深さ (§2.6.2) を持っている必要があります。

この回答の最初のバージョンでは、§4.10.2.1 を引用しました。属性を含まないクラス ファイルStackMapTable(バージョン番号 49.0 以下)用の型推論による検証のプロセス:

...検証者は、プログラムの任意の時点で、その時点に到達するためにどのコードパスが使用されても、次のすべてが真であることを保証します。

  • オペランド スタックは常に同じサイズで、同じ型の値が含まれます。
  • ...
于 2016-04-26T08:30:11.320 に答える
3

はい。バイトコード検証では、制御フローに関係なく、任意の命令でスタック サイズが一定であることを強制します。(また、型に互換性があることも強制します)。したがって、これはコンパイルされた Java から派生したバイトコードだけでなく、有効なバイトコードにも当てはまります。

于 2016-04-26T02:47:14.457 に答える