制御フロー コードのこの部分には主に次のバイトコード命令が含まれます。次のすべてのバイトコード命令にはパラメータがあります:
import dis def test_control01(): a = 1 if a > 1: print("a > 1") elif a < 1: print("a < 1") else: print("a == 1") if __name__ == '__main__': dis.dis(test_control01)
6 0 LOAD_CONST 1 (1)2 STORE_FAST
4 LOAD_FAST 3 22
9 12 LOAD_GLOBAL 0 (print)
14 LOAD_CONST 2 (' a > 1')
16 CALL_FUNCTION 1
18 POP_TOP
20 JUMP_FORWARD 26 (~48)
10 >> 22 LOAD_FAST 0 (a)
24 LOAD_CONST 1 (1)
26 Compare_op 0 (& lt;)
28 POP_JUMP_IF_FALSE 40
11 30 Load_global 0 (印刷)
32 load_const 3( 'a&lt; 1')## 34 call_function 1
36 pop_top
38 jump_forward 8(48)
13&gt;&gt; CALL_FUNCTION 1
46 POP_TOP
48 LOAD_CONST 0 (なし)
50 RETURN_VALUE
上記をシミュレーションしてみましょう。バイトコード実行プロセスが開始されました。カウンターを使用して現在のバイトコードの実行位置を示します:
バイトコードの実行が開始される前のスタック スペースとカウンタのステータスは次のとおりです:最初のバイトコード LOAD_CONST を実行します。実行後、カウンタ = 2 になります。このバイトコードは 1 バイトを占め、パラメータ スタックは 1 バイトであるため、次回実行されるバイトコードの位置はバイトコード内になります。下位 3 つの位置、対応するsubscript は 2 なので、counter = 2 となります。
次に、2 番目のバイトコード STORE_FAST を実行します。a を 1 に指定します。同じ STORE_FAST オペコードとオペランドがそれぞれ 1 バイトを占有するため、このワードが実行されます。セクションコード後のスタックスペース、カウンター = 4。
次に、LOAD_FAST は a が指すオブジェクト (1) をスタックにロードします。このとき、counter = 6 となり、LOAD_CONST は定数 1 をスタックにロードします。カウンタ = 8 の場合、これら 2 つの命令を実行した後のスタック スペースの変化は、次の図に示すようになります。この命令には、パラメータが比較の記号を表します。ここでは > 1 を比較しており、比較結果はスタックにプッシュされます。COMPARE_OP が最初にスタックの 2 つの入力をポップアップするため、比較結果は false ですスペースがあるので、これを実行した後の命令後のスタックスペースとカウンタの値は以下の通りです:
次の命令はPOP_JUMP_IF_FALSEです。前のバイトコードと同じように、このバイトコードはスタックの一番上で false をポップし、ジャンプして、カウンターの値をパラメーターの値に直接プログラムします。ここでのパラメーターは 22 なので、カウンター = 22 になります。この命令を実行した後、
22 にジャンプしたため、次に実行される命令は LOAD_FAST で、変数 a をスタック領域にロードします。定数 1 をスタック領域に追加します これら 2 回の実行後、状況は次のようになります:
今度は POP_JUMP_IF_FALSE を実行しますが、今回の結果も false です。したがって、POP_JUMP_IF_FALSE の実行を続けます。今回のパラメータは 40 で、counter の値を 40 に直接設定します。
次に、LOAD_GLOBAL はグローバル変数印刷関数 counter をロードして 42 になり、LOAD_CONST は文字列 "a == 1" をスタック領域にロードし、counter = 44、ステータスは次のとおりです:
CALL_FUNCTION このバイトコードには 1 つのパラメータがあり、関数を呼び出すためのパラメータの数を示します。print 関数のパラメータは 1 つだけなので、ここでは 1 です。 「a== 1」という文字列を出力しますが、ここで注意が必要なのは、print関数はNoneを返すため、CALL_FUNCTION実行後のステータスは次のようになります。
#この時点で上記の関数はほぼ実行されていますが、以降のいくつかのバイトコードは非常に単純なので説明は省略します。
以上がPython仮想マシンのバイトコードの制御フローを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。