Есть ли ограничение на размер модуля Python? - PullRequest
7 голосов
/ 20 апреля 2019

Есть ли ограничение на размер модуля Python?

Мне кажется, что инструкция байт-кода Python POP_JUMP_IF_FALSE принимает 1-байтовый операнд, сообщая ей индекс инструкции для перехода.

Цитирование некоторых соответствующих кодов CPython из ceval.c (комментарий мой):

case TARGET(POP_JUMP_IF_FALSE): {
    PREDICTED(POP_JUMP_IF_FALSE);
    PyObject *cond = POP();
    int err;
    if (cond == Py_True) {
        Py_DECREF(cond);
        FAST_DISPATCH();
    }
    if (cond == Py_False) {
        Py_DECREF(cond);
        JUMPTO(oparg);  # <--- this
        FAST_DISPATCH();
    }

Означает ли это, что модуль Python не может содержать более 255 инструкций байт-кода?Что мне здесь не хватает?

1 Ответ

2 голосов
/ 21 апреля 2019

Примечание: я не эксперт в Python и определенно не интерпретирую байт-код, это то, что я обнаружил после экспериментов.

Примечание: я использую Python3.7.3 если вы используете другую версию, вы можете получить другой вывод дизассемблирования (кредит указывает на @dunes для указания этого).

# module.py
x = 0
while True:
  if x == 0:
    continue

выдаст следующие инструкции: (через python3 -m dis module.py)

  1           0 LOAD_CONST               0 (0)
              2 STORE_NAME               0 (x)

  2           4 SETUP_LOOP              14 (to 20)

  3     >>    6 LOAD_NAME                0 (x)
              8 LOAD_CONST               0 (0)
             10 COMPARE_OP               2 (==)
             12 POP_JUMP_IF_FALSE        6

  4          14 JUMP_ABSOLUTE            6
             16 JUMP_ABSOLUTE            6
             18 POP_BLOCK
        >>   20 LOAD_CONST               1 (None)
             22 RETURN_VALUE

По смещению 12 находится инструкция POP_JUMP_IF_FALSE.После добавления целой пачки кода вверху файла (я просто повторял x = 0 много раз):

271        1080 SETUP_LOOP              20 (to 1102)

272     >> 1082 LOAD_NAME                0 (x)
           1084 LOAD_CONST               0 (0)
           1086 COMPARE_OP               2 (==)
           1088 EXTENDED_ARG             4
           1090 POP_JUMP_IF_FALSE     1082

273        1092 EXTENDED_ARG             4
           1094 JUMP_ABSOLUTE         1082
           1096 EXTENDED_ARG             4
           1098 JUMP_ABSOLUTE         1082
           1100 POP_BLOCK
        >> 1102 LOAD_CONST               1 (None)
           1104 RETURN_VALUE

Компилятор добавил инструкцию EXTENDED_ARG со смещением 1088который допускает больший операнд.

...