Unexpected bytecode difference
I have encountered the following difference between Python 3 and 2: (py3)
compile('xxx', '<>', 'eval').co_code b'e\x00S\x00'
(py2)
compile('xxx', '<>', 'eval').co_code 'e\x00\x00S'
Note that 'S' (the code for RETURN_VALUE) and a zero byte are swapped in Python 2 compared to Python 3. Is this change documented somewhere?
Python bytecode format changed deeply in Python 3.6. It now uses regular units of 2 bytes, instead of 1 or 3 bytes depending if the instruction has an argument. See for example https://bugs.python.org/issue26647 "wordcode". But CALL_FUNCTION bytecode also evolved. Victor 2018-01-20 0:46 GMT+01:00 Alexander Belopolsky <alexander.belopolsky@gmail.com>:
I have encountered the following difference between Python 3 and 2:
(py3)
compile('xxx', '<>', 'eval').co_code b'e\x00S\x00'
(py2)
compile('xxx', '<>', 'eval').co_code 'e\x00\x00S'
Note that 'S' (the code for RETURN_VALUE) and a zero byte are swapped in Python 2 compared to Python 3. Is this change documented somewhere? _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/victor.stinner%40gmail.co...
As a general rule, you should not expect the bytecode to be the same between different versions of CPython, including minor version changes. For example, the instructions for dictionary literals are different in 3.4, 3.5, and 3.6. On Fri, Jan 19, 2018 at 6:54 PM, Victor Stinner <victor.stinner@gmail.com> wrote:
Python bytecode format changed deeply in Python 3.6. It now uses regular units of 2 bytes, instead of 1 or 3 bytes depending if the instruction has an argument.
See for example https://bugs.python.org/issue26647 "wordcode".
But CALL_FUNCTION bytecode also evolved.
Victor
2018-01-20 0:46 GMT+01:00 Alexander Belopolsky < alexander.belopolsky@gmail.com>:
I have encountered the following difference between Python 3 and 2:
(py3)
compile('xxx', '<>', 'eval').co_code b'e\x00S\x00'
(py2)
compile('xxx', '<>', 'eval').co_code 'e\x00\x00S'
Note that 'S' (the code for RETURN_VALUE) and a zero byte are swapped in Python 2 compared to Python 3. Is this change documented somewhere? _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/ victor.stinner%40gmail.com
Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/ joe%40quantopian.com
Presumably because Python 3 switched to wordcode. Applying dis.dis() to these code objects results in the same output.
dis.dis(c) 0 LOAD_NAME 0 (0) 3 RETURN_VALUE
On Fri, Jan 19, 2018 at 3:46 PM, Alexander Belopolsky < alexander.belopolsky@gmail.com> wrote:
I have encountered the following difference between Python 3 and 2:
(py3)
compile('xxx', '<>', 'eval').co_code b'e\x00S\x00'
(py2)
compile('xxx', '<>', 'eval').co_code 'e\x00\x00S'
Note that 'S' (the code for RETURN_VALUE) and a zero byte are swapped in Python 2 compared to Python 3. Is this change documented somewhere? _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/ guido%40python.org
-- --Guido van Rossum (python.org/~guido)
On Fri, Jan 19, 2018 at 7:01 PM, Guido van Rossum <guido@python.org> wrote:
Presumably because Python 3 switched to wordcode. Applying dis.dis() to these code objects results in the same output.
dis.dis(c) 0 LOAD_NAME 0 (0) 3 RETURN_VALUE
I expected these changes to be documented at <https://docs.python.org/3/library/dis.html>, but the EXTENDED_ARG section, for example, is the same in the 2 and 3 versions and says that the default argument is two bytes.
It seems like the EXTENDED_ARG doc wasn't updated. Victor 2018-01-20 1:07 GMT+01:00 Alexander Belopolsky <alexander.belopolsky@gmail.com>:
On Fri, Jan 19, 2018 at 7:01 PM, Guido van Rossum <guido@python.org> wrote:
Presumably because Python 3 switched to wordcode. Applying dis.dis() to these code objects results in the same output.
dis.dis(c) 0 LOAD_NAME 0 (0) 3 RETURN_VALUE
I expected these changes to be documented at <https://docs.python.org/3/library/dis.html>, but the EXTENDED_ARG section, for example, is the same in the 2 and 3 versions and says that the default argument is two bytes. _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/victor.stinner%40gmail.co...
On Fri, Jan 19, 2018 at 7:18 PM, Victor Stinner <victor.stinner@gmail.com> wrote:
It seems like the EXTENDED_ARG doc wasn't updated.
I've opened <https://bugs.python.org/issue32625> to update the dis module documentation. I have also found a patch (mkfu4.patch) attached to issue 27095 where EXTENDED_ARG is described as .. opcode:: EXTENDED_ARG (ext) EXTENDED_ARG adds ``*ext* * 256`` to the next instruction's argument. This is used for arguments exceeding a byte in size, and can be chained to create 4-byte arguments. I am not sure this is correct. First, multiple EXTENDED_ARG codes seem to add ext * 256 ** i or bit-append ext to arg. Second, it looks like this mechanism allows forming arguments of arbitrary bit length, not just 4-byte arguments.
participants (4)
-
Alexander Belopolsky
-
Guido van Rossum
-
Joe Jevnik
-
Victor Stinner