>  기사  >  백엔드 개발  >  Python 가상 머신 바이트코드의 제어 흐름을 구현하는 방법

Python 가상 머신 바이트코드의 제어 흐름을 구현하는 방법

王林
王林앞으로
2023-05-26 12:13:201580검색

제어 흐름 구현

코드의 이 부분은 주로 다음 바이트코드 명령어와 관련됩니다. 다음 바이트코드 명령어는 모두 매개변수를 갖습니다.

  • JUMP_FORWARD는 현재 실행 중인 바이트코드를 대체합니다. 명령 위치로 이동한 후 해당 결과로 점프하여 실행을 계속합니다.

  • 스택의 최상위 요소가 true인 경우 바이트코드 실행 위치를 수신된 매개변수 값으로 변경하라는 명령은 "POP_JUMP_IF_TRUE"입니다. 스택에서 맨 위 요소를 팝합니다.

  • POP_JUMP_IF_FALSE, 이 명령어는 POP_JUMP_IF_TRUE와 동일하며 유일한 차이점은 스택의 최상위 요소가 true인지 확인하는 것입니다.

  • JUMP_IF_TRUE_OR_POP, 스택의 최상위 요소가 true이면 바이트코드 실행 위치가 매개변수에 해당하는 값으로 설정되며 스택의 최상위 요소를 팝할 필요가 없습니다. 스택의 맨 위 요소가 false인 경우 해당 요소를 팝해야 합니다.

  • JUMP_IF_FALSE_OR_POP, 스택의 최상위 요소가 false와 같아야 한다는 점을 제외하면 JUMP_IF_TRUE_OR_POP과 동일합니다.

  • JUMP_ABSOLUTE는 바이트코드의 실행 위치를 매개변수의 값으로 직접 설정합니다.

일반적으로 이러한 점프 명령어를 사용하면 Python 인터프리터가 바이트코드 실행 시 특정 조건에 따라 실행 흐름을 변경하고 루프 및 조건문과 같은 기본 언어 구조를 구현할 수 있습니다.

이제 위의 다양한 명령어의 실행 과정을 깊이 이해하기 위해 예를 사용합니다.

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__ == &#39;__main__&#39;:
    dis.dis(test_control01)
的의 출력 결과는 다음과 같습니다.

6 0 load_const 1 (1)

2 Store_fast 0 (A)
8 4 load_fast 0 (a)
6 load_const 1 (1)
8 Compare_op 4 ( & gt ;) o 10 pop_jump_if_false 22

9 12 load_global 0 (인쇄)
14 load_const 2 ('a & gt; 1')
16 call_function 1
18 POP_TOP
20 jump_Forward 26 (4 8로)
10 & gt; gt; 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 T 36 POP_TOP
38 JUMP_FORWARD 8 (48까지)

13 & gt; & gt; 40 load_global 0 (인쇄)
42 load_const 4 ('a == 1')
44 Call_function 1
46 POP_TOP
& G t; 48 load_const 0 (없음)
                                                                                                                이제 위의 바이트코드 실행 프로세스를 시뮬레이션해 보겠습니다. 이제 카운터를 사용하여 현재 바이트코드의 실행 위치를 나타냅니다.

바이트코드가 실행을 시작하기 전, 스택 공간 및 상태 카운터는 다음과 같습니다:



이제 첫 번째 바이트코드 LOAD_CONST를 실행합니다. 실행 후 카운터 = 2입니다. 이 바이트코드가 1바이트를 차지하고 매개변수 스택이 1바이트이므로 다음에 실행되는 바이트코드의 위치는 해당 바이트코드 위치의 하위 3개가 됩니다. 아래 첨자는 2이므로 카운터 = 2입니다.

Python 가상 머신 바이트코드의 제어 흐름을 구현하는 방법

이제 두 번째 바이트코드 STORE_FAST를 실행하고 1을 가리키도록 합니다. 동일한 STORE_FAST opcode와 피연산자가 각각 1바이트를 차지하므로 이 바이트코드를 실행한 후 스택 공간에 데이터가 없습니다(카운터 = 4).

Python 가상 머신 바이트코드의 제어 흐름을 구현하는 방법

다음으로 LOAD_FAST는 a가 가리키는 객체인 1을 스택에 로드합니다. 이때 counter = 6입니다. LOAD_CONST는 이때 counter = 8을 로드합니다. 이 두 명령을 실행한 후 스택 공간의 변화는 아래 그림과 같습니다.

Python 가상 머신 바이트코드의 제어 흐름을 구현하는 방법

다음 명령은 COMPARE_OP입니다. 여기서는 비교 기호를 나타내는 매개변수가 있습니다. 1, 비교 결과가 스택에 푸시됩니다. COMPARE_OP가 먼저 스택 공간의 두 입력을 팝하므로 비교 결과는 거짓입니다. 따라서 이 명령어를 실행한 후 스택의 값이 반환됩니다. space와 counter는 다음과 같습니다:

Python 가상 머신 바이트코드의 제어 흐름을 구현하는 방법

다음 명령어는 POP_JUMP_IF_FALSE입니다. 이전 바이트코드의 의미에 따르면 이 바이트코드는 스택 상단에 false를 팝하고 점프하며 카운터 값을 직접 프로그래밍합니다. 여기서 그의 매개변수 값은 22이므로 카운터 = 22입니다. 이 명령어를 실행한 후 결과는 다음과 같습니다.

Python 가상 머신 바이트코드의 제어 흐름을 구현하는 방법

이제 22로 점프했기 때문에 실행할 다음 명령어는 LOAD_FAST입니다. 변수 a를 스택 공간에 로드하고 LOAD_CONST는 상수 1을 스택 공간에 로드합니다. 이 두 실행을 실행한 후 변경 사항은 다음과 같습니다.

Python 가상 머신 바이트코드의 제어 흐름을 구현하는 방법

다시 POP_JUMP_IF_FALSE를 실행하면 이번에도 결과는 false입니다. 따라서 POP_JUMP_IF_FALSE를 계속 실행하세요. 이번에는 매개변수가 40이고 카운터 값을 직접 40으로 설정합니다.

Python 가상 머신 바이트코드의 제어 흐름을 구현하는 방법

다음으로 LOAD_GLOBAL은 전역 변수 인쇄 함수 카운터를 로드하여 42가 되고, LOAD_CONST는 문자열 "a == 1"을 스택 공간, 카운터 = 44에 로드하고 상태는 다음과 같습니다.

Python 가상 머신 바이트코드의 제어 흐름을 구현하는 방법

CALL_FUNCTION 섹션 코드에는 함수 호출을 위한 매개변수 수를 나타내는 매개변수가 있습니다. 여기서는 인쇄 함수에 매개변수가 하나만 있고 "a== 1"이라는 문자열을 출력하므로 여기서는 1입니다. 따라서 CALL_FUNCTION을 실행한 후 상태는 다음과 같습니다.

Python 가상 머신 바이트코드의 제어 흐름을 구현하는 방법

이 시점에서 위 함수는 거의 실행되었으므로 다음 몇 바이트 코드는 매우 간단하므로 다시 설명하지 않습니다. .

위 내용은 Python 가상 머신 바이트코드의 제어 흐름을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제