Python-checkins
Threads by month
- ----- 2025 -----
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
January 2025
- 1 participants
- 705 discussions
[3.12] GH-128131: Completely support random read access of uncompressed unencrypted files in ZipFile (GH-128143) (#129092)
by jaraco Jan. 20, 2025
by jaraco Jan. 20, 2025
Jan. 20, 2025
https://github.com/python/cpython/commit/03bce18992fd49f5f87697a21c0390fc60…
commit: 03bce18992fd49f5f87697a21c0390fc6082bfc7
branch: 3.12
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: jaraco <jaraco(a)jaraco.com>
date: 2025-01-20T20:40:28Z
summary:
[3.12] GH-128131: Completely support random read access of uncompressed unencrypted files in ZipFile (GH-128143) (#129092)
GH-128131: Completely support random read access of uncompressed unencrypted files in ZipFile (GH-128143)
(cherry picked from commit dda02eb7be62bf0af850a7521c77c90ea997df6c)
Co-authored-by: 5ec1cff <56485584+5ec1cff(a)users.noreply.github.com>
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot](a)users.noreply.github.com>
Co-authored-by: Bénédikt Tran <10796600+picnixz(a)users.noreply.github.com>
files:
A Misc/NEWS.d/next/Library/2024-12-21-03-20-12.gh-issue-128131.QpPmNt.rst
M Lib/test/test_zipfile/test_core.py
M Lib/zipfile/__init__.py
diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py
index adb74345486b65..03520e57303c9d 100644
--- a/Lib/test/test_zipfile/test_core.py
+++ b/Lib/test/test_zipfile/test_core.py
@@ -1,3 +1,4 @@
+import _pyio
import array
import contextlib
import importlib.util
@@ -3440,5 +3441,87 @@ def test_too_short(self):
b"zzz", zipfile._strip_extra(b"zzz", (self.ZIP64_EXTRA,)))
+class StatIO(_pyio.BytesIO):
+ """Buffer which remembers the number of bytes that were read."""
+
+ def __init__(self):
+ super().__init__()
+ self.bytes_read = 0
+
+ def read(self, size=-1):
+ bs = super().read(size)
+ self.bytes_read += len(bs)
+ return bs
+
+
+class StoredZipExtFileRandomReadTest(unittest.TestCase):
+ """Tests whether an uncompressed, unencrypted zip entry can be randomly
+ seek and read without reading redundant bytes."""
+ def test_stored_seek_and_read(self):
+
+ sio = StatIO()
+ # 20000 bytes
+ txt = b'0123456789' * 2000
+
+ # The seek length must be greater than ZipExtFile.MIN_READ_SIZE
+ # as `ZipExtFile._read2()` reads in blocks of this size and we
+ # need to seek out of the buffered data
+ read_buffer_size = zipfile.ZipExtFile.MIN_READ_SIZE
+ self.assertGreaterEqual(10002, read_buffer_size) # for forward seek test
+ self.assertGreaterEqual(5003, read_buffer_size) # for backward seek test
+ # The read length must be less than MIN_READ_SIZE, since we assume that
+ # only 1 block is read in the test.
+ read_length = 100
+ self.assertGreaterEqual(read_buffer_size, read_length) # for read() calls
+
+ with zipfile.ZipFile(sio, "w", compression=zipfile.ZIP_STORED) as zipf:
+ zipf.writestr("foo.txt", txt)
+
+ # check random seek and read on a file
+ with zipfile.ZipFile(sio, "r") as zipf:
+ with zipf.open("foo.txt", "r") as fp:
+ # Test this optimized read hasn't rewound and read from the
+ # start of the file (as in the case of the unoptimized path)
+
+ # forward seek
+ old_count = sio.bytes_read
+ forward_seek_len = 10002
+ current_pos = 0
+ fp.seek(forward_seek_len, os.SEEK_CUR)
+ current_pos += forward_seek_len
+ self.assertEqual(fp.tell(), current_pos)
+ self.assertEqual(fp._left, fp._compress_left)
+ arr = fp.read(read_length)
+ current_pos += read_length
+ self.assertEqual(fp.tell(), current_pos)
+ self.assertEqual(arr, txt[current_pos - read_length:current_pos])
+ self.assertEqual(fp._left, fp._compress_left)
+ read_count = sio.bytes_read - old_count
+ self.assertLessEqual(read_count, read_buffer_size)
+
+ # backward seek
+ old_count = sio.bytes_read
+ backward_seek_len = 5003
+ fp.seek(-backward_seek_len, os.SEEK_CUR)
+ current_pos -= backward_seek_len
+ self.assertEqual(fp.tell(), current_pos)
+ self.assertEqual(fp._left, fp._compress_left)
+ arr = fp.read(read_length)
+ current_pos += read_length
+ self.assertEqual(fp.tell(), current_pos)
+ self.assertEqual(arr, txt[current_pos - read_length:current_pos])
+ self.assertEqual(fp._left, fp._compress_left)
+ read_count = sio.bytes_read - old_count
+ self.assertLessEqual(read_count, read_buffer_size)
+
+ # eof flags test
+ fp.seek(0, os.SEEK_END)
+ fp.seek(12345, os.SEEK_SET)
+ current_pos = 12345
+ arr = fp.read(read_length)
+ current_pos += read_length
+ self.assertEqual(arr, txt[current_pos - read_length:current_pos])
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py
index 3e1cca472865b5..91b2e032e5f2d9 100644
--- a/Lib/zipfile/__init__.py
+++ b/Lib/zipfile/__init__.py
@@ -1140,13 +1140,15 @@ def seek(self, offset, whence=os.SEEK_SET):
self._offset = buff_offset
read_offset = 0
# Fast seek uncompressed unencrypted file
- elif self._compress_type == ZIP_STORED and self._decrypter is None and read_offset > 0:
+ elif self._compress_type == ZIP_STORED and self._decrypter is None and read_offset != 0:
# disable CRC checking after first seeking - it would be invalid
self._expected_crc = None
# seek actual file taking already buffered data into account
read_offset -= len(self._readbuffer) - self._offset
self._fileobj.seek(read_offset, os.SEEK_CUR)
self._left -= read_offset
+ self._compress_left -= read_offset
+ self._eof = self._left <= 0
read_offset = 0
# flush read buffer
self._readbuffer = b''
diff --git a/Misc/NEWS.d/next/Library/2024-12-21-03-20-12.gh-issue-128131.QpPmNt.rst b/Misc/NEWS.d/next/Library/2024-12-21-03-20-12.gh-issue-128131.QpPmNt.rst
new file mode 100644
index 00000000000000..f4c4ebce10729c
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-12-21-03-20-12.gh-issue-128131.QpPmNt.rst
@@ -0,0 +1,2 @@
+Completely support random access of uncompressed unencrypted read-only
+zip files obtained by :meth:`ZipFile.open <zipfile.ZipFile.open>`.
1
0
[3.12] doc: fix venv creating for the local Python using uv (GH-129094) (#129097)
by hugovk Jan. 20, 2025
by hugovk Jan. 20, 2025
Jan. 20, 2025
https://github.com/python/cpython/commit/728c6b89a66b7cb431a99fef835674ddbd…
commit: 728c6b89a66b7cb431a99fef835674ddbd765d37
branch: 3.12
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: hugovk <1324225+hugovk(a)users.noreply.github.com>
date: 2025-01-20T21:13:23+02:00
summary:
[3.12] doc: fix venv creating for the local Python using uv (GH-129094) (#129097)
Co-authored-by: Filipe Laíns 🇵🇸 <lains(a)riseup.net>
files:
M Doc/Makefile
diff --git a/Doc/Makefile b/Doc/Makefile
index 1a66642a4a03ed..b8896da4a91869 100644
--- a/Doc/Makefile
+++ b/Doc/Makefile
@@ -172,7 +172,7 @@ venv:
else \
echo "Creating venv in $(VENVDIR)"; \
if $(UV) --version >/dev/null 2>&1; then \
- $(UV) venv $(VENVDIR); \
+ $(UV) venv --python=$(PYTHON) $(VENVDIR); \
VIRTUAL_ENV=$(VENVDIR) $(UV) pip install -r $(REQUIREMENTS); \
else \
$(PYTHON) -m venv $(VENVDIR); \
1
0
[3.13] doc: fix venv creating for the local Python using uv (GH-129094) (#129096)
by hugovk Jan. 20, 2025
by hugovk Jan. 20, 2025
Jan. 20, 2025
https://github.com/python/cpython/commit/207708246327c8b179529020007cedd94b…
commit: 207708246327c8b179529020007cedd94b19cd86
branch: 3.13
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: hugovk <1324225+hugovk(a)users.noreply.github.com>
date: 2025-01-20T21:13:12+02:00
summary:
[3.13] doc: fix venv creating for the local Python using uv (GH-129094) (#129096)
Co-authored-by: Filipe Laíns 🇵🇸 <lains(a)riseup.net>
files:
M Doc/Makefile
diff --git a/Doc/Makefile b/Doc/Makefile
index 1a66642a4a03ed..b8896da4a91869 100644
--- a/Doc/Makefile
+++ b/Doc/Makefile
@@ -172,7 +172,7 @@ venv:
else \
echo "Creating venv in $(VENVDIR)"; \
if $(UV) --version >/dev/null 2>&1; then \
- $(UV) venv $(VENVDIR); \
+ $(UV) venv --python=$(PYTHON) $(VENVDIR); \
VIRTUAL_ENV=$(VENVDIR) $(UV) pip install -r $(REQUIREMENTS); \
else \
$(PYTHON) -m venv $(VENVDIR); \
1
0
Jan. 20, 2025
https://github.com/python/cpython/commit/da36bccdac6d45bda6f83563410567c04f…
commit: da36bccdac6d45bda6f83563410567c04f4b288c
branch: main
author: Filipe Laíns 🇵🇸 <lains(a)riseup.net>
committer: hugovk <1324225+hugovk(a)users.noreply.github.com>
date: 2025-01-20T21:04:05+02:00
summary:
doc: fix venv creating for the local Python using uv (#129094)
files:
M Doc/Makefile
diff --git a/Doc/Makefile b/Doc/Makefile
index 1a66642a4a03ed..b8896da4a91869 100644
--- a/Doc/Makefile
+++ b/Doc/Makefile
@@ -172,7 +172,7 @@ venv:
else \
echo "Creating venv in $(VENVDIR)"; \
if $(UV) --version >/dev/null 2>&1; then \
- $(UV) venv $(VENVDIR); \
+ $(UV) venv --python=$(PYTHON) $(VENVDIR); \
VIRTUAL_ENV=$(VENVDIR) $(UV) pip install -r $(REQUIREMENTS); \
else \
$(PYTHON) -m venv $(VENVDIR); \
1
0
[3.13] GH-128131: Completely support random read access of uncompressed unencrypted files in ZipFile (GH-128143) (#129091)
by jaraco Jan. 20, 2025
by jaraco Jan. 20, 2025
Jan. 20, 2025
https://github.com/python/cpython/commit/03b2ecf41c6f4cc57aac3dd147b8b5dedc…
commit: 03b2ecf41c6f4cc57aac3dd147b8b5dedcafcd3d
branch: 3.13
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: jaraco <jaraco(a)jaraco.com>
date: 2025-01-20T18:28:52Z
summary:
[3.13] GH-128131: Completely support random read access of uncompressed unencrypted files in ZipFile (GH-128143) (#129091)
GH-128131: Completely support random read access of uncompressed unencrypted files in ZipFile (GH-128143)
(cherry picked from commit dda02eb7be62bf0af850a7521c77c90ea997df6c)
Co-authored-by: 5ec1cff <56485584+5ec1cff(a)users.noreply.github.com>
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot](a)users.noreply.github.com>
Co-authored-by: Bénédikt Tran <10796600+picnixz(a)users.noreply.github.com>
files:
A Misc/NEWS.d/next/Library/2024-12-21-03-20-12.gh-issue-128131.QpPmNt.rst
M Lib/test/test_zipfile/test_core.py
M Lib/zipfile/__init__.py
diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py
index 4ff9f9c34237c6..4b56f6a380f219 100644
--- a/Lib/test/test_zipfile/test_core.py
+++ b/Lib/test/test_zipfile/test_core.py
@@ -1,3 +1,4 @@
+import _pyio
import array
import contextlib
import importlib.util
@@ -3454,5 +3455,87 @@ def test_too_short(self):
b"zzz", zipfile._Extra.strip(b"zzz", (self.ZIP64_EXTRA,)))
+class StatIO(_pyio.BytesIO):
+ """Buffer which remembers the number of bytes that were read."""
+
+ def __init__(self):
+ super().__init__()
+ self.bytes_read = 0
+
+ def read(self, size=-1):
+ bs = super().read(size)
+ self.bytes_read += len(bs)
+ return bs
+
+
+class StoredZipExtFileRandomReadTest(unittest.TestCase):
+ """Tests whether an uncompressed, unencrypted zip entry can be randomly
+ seek and read without reading redundant bytes."""
+ def test_stored_seek_and_read(self):
+
+ sio = StatIO()
+ # 20000 bytes
+ txt = b'0123456789' * 2000
+
+ # The seek length must be greater than ZipExtFile.MIN_READ_SIZE
+ # as `ZipExtFile._read2()` reads in blocks of this size and we
+ # need to seek out of the buffered data
+ read_buffer_size = zipfile.ZipExtFile.MIN_READ_SIZE
+ self.assertGreaterEqual(10002, read_buffer_size) # for forward seek test
+ self.assertGreaterEqual(5003, read_buffer_size) # for backward seek test
+ # The read length must be less than MIN_READ_SIZE, since we assume that
+ # only 1 block is read in the test.
+ read_length = 100
+ self.assertGreaterEqual(read_buffer_size, read_length) # for read() calls
+
+ with zipfile.ZipFile(sio, "w", compression=zipfile.ZIP_STORED) as zipf:
+ zipf.writestr("foo.txt", txt)
+
+ # check random seek and read on a file
+ with zipfile.ZipFile(sio, "r") as zipf:
+ with zipf.open("foo.txt", "r") as fp:
+ # Test this optimized read hasn't rewound and read from the
+ # start of the file (as in the case of the unoptimized path)
+
+ # forward seek
+ old_count = sio.bytes_read
+ forward_seek_len = 10002
+ current_pos = 0
+ fp.seek(forward_seek_len, os.SEEK_CUR)
+ current_pos += forward_seek_len
+ self.assertEqual(fp.tell(), current_pos)
+ self.assertEqual(fp._left, fp._compress_left)
+ arr = fp.read(read_length)
+ current_pos += read_length
+ self.assertEqual(fp.tell(), current_pos)
+ self.assertEqual(arr, txt[current_pos - read_length:current_pos])
+ self.assertEqual(fp._left, fp._compress_left)
+ read_count = sio.bytes_read - old_count
+ self.assertLessEqual(read_count, read_buffer_size)
+
+ # backward seek
+ old_count = sio.bytes_read
+ backward_seek_len = 5003
+ fp.seek(-backward_seek_len, os.SEEK_CUR)
+ current_pos -= backward_seek_len
+ self.assertEqual(fp.tell(), current_pos)
+ self.assertEqual(fp._left, fp._compress_left)
+ arr = fp.read(read_length)
+ current_pos += read_length
+ self.assertEqual(fp.tell(), current_pos)
+ self.assertEqual(arr, txt[current_pos - read_length:current_pos])
+ self.assertEqual(fp._left, fp._compress_left)
+ read_count = sio.bytes_read - old_count
+ self.assertLessEqual(read_count, read_buffer_size)
+
+ # eof flags test
+ fp.seek(0, os.SEEK_END)
+ fp.seek(12345, os.SEEK_SET)
+ current_pos = 12345
+ arr = fp.read(read_length)
+ current_pos += read_length
+ self.assertEqual(arr, txt[current_pos - read_length:current_pos])
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py
index 8b636094fad3ca..82e307f78e8e3d 100644
--- a/Lib/zipfile/__init__.py
+++ b/Lib/zipfile/__init__.py
@@ -1163,13 +1163,15 @@ def seek(self, offset, whence=os.SEEK_SET):
self._offset = buff_offset
read_offset = 0
# Fast seek uncompressed unencrypted file
- elif self._compress_type == ZIP_STORED and self._decrypter is None and read_offset > 0:
+ elif self._compress_type == ZIP_STORED and self._decrypter is None and read_offset != 0:
# disable CRC checking after first seeking - it would be invalid
self._expected_crc = None
# seek actual file taking already buffered data into account
read_offset -= len(self._readbuffer) - self._offset
self._fileobj.seek(read_offset, os.SEEK_CUR)
self._left -= read_offset
+ self._compress_left -= read_offset
+ self._eof = self._left <= 0
read_offset = 0
# flush read buffer
self._readbuffer = b''
diff --git a/Misc/NEWS.d/next/Library/2024-12-21-03-20-12.gh-issue-128131.QpPmNt.rst b/Misc/NEWS.d/next/Library/2024-12-21-03-20-12.gh-issue-128131.QpPmNt.rst
new file mode 100644
index 00000000000000..f4c4ebce10729c
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-12-21-03-20-12.gh-issue-128131.QpPmNt.rst
@@ -0,0 +1,2 @@
+Completely support random access of uncompressed unencrypted read-only
+zip files obtained by :meth:`ZipFile.open <zipfile.ZipFile.open>`.
1
0
Jan. 20, 2025
https://github.com/python/cpython/commit/5d57959d7da8cfcef8df072a6ad53795c6…
commit: 5d57959d7da8cfcef8df072a6ad53795c60546aa
branch: main
author: Wulian <1055917385(a)qq.com>
committer: jaraco <jaraco(a)jaraco.com>
date: 2025-01-20T13:12:29-05:00
summary:
gh-91279: ZipFile.writestr now respect SOURCE_DATE_EPOCH (#124435)
files:
A Misc/NEWS.d/next/Library/2024-12-30-19-53-14.gh-issue-91279.EeOJk1.rst
M Doc/whatsnew/3.14.rst
M Lib/test/test_zipfile/test_core.py
M Lib/zipfile/__init__.py
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index 7f149d5c03dfbb..0dcecd4944f2f6 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -730,6 +730,12 @@ zipinfo
(Contributed by Bénédikt Tran in :gh:`123424`.)
+* :meth:`zipfile.ZipFile.writestr` now respect ``SOURCE_DATE_EPOCH`` that
+ distributions can set centrally and have build tools consume this in order
+ to produce reproducible output.
+
+ (Contributed by Jiahao Li in :gh:`91279`.)
+
.. Add improved modules above alphabetically, not here at the end.
Optimizations
diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py
index 02e28d4004c01a..ab5fb650084327 100644
--- a/Lib/test/test_zipfile/test_core.py
+++ b/Lib/test/test_zipfile/test_core.py
@@ -20,7 +20,7 @@
from random import randint, random, randbytes
from test import archiver_tests
-from test.support import script_helper
+from test.support import script_helper, os_helper
from test.support import (
findfile, requires_zlib, requires_bz2, requires_lzma,
captured_stdout, captured_stderr, requires_subprocess,
@@ -1784,6 +1784,35 @@ def test_writestr_extended_local_header_issue1202(self):
zinfo.flag_bits |= zipfile._MASK_USE_DATA_DESCRIPTOR # Include an extended local header.
orig_zip.writestr(zinfo, data)
+ def test_write_with_source_date_epoch(self):
+ with os_helper.EnvironmentVarGuard() as env:
+ # Set the SOURCE_DATE_EPOCH environment variable to a specific timestamp
+ env['SOURCE_DATE_EPOCH'] = "1735715999"
+
+ with zipfile.ZipFile(TESTFN, "w") as zf:
+ zf.writestr("test_source_date_epoch.txt", "Testing SOURCE_DATE_EPOCH")
+
+ with zipfile.ZipFile(TESTFN, "r") as zf:
+ zip_info = zf.getinfo("test_source_date_epoch.txt")
+ get_time = time.localtime(int(os.environ['SOURCE_DATE_EPOCH']))[:6]
+ # Compare each element of the date_time tuple
+ # Allow for a 1-second difference
+ for z_time, g_time in zip(zip_info.date_time, get_time):
+ self.assertAlmostEqual(z_time, g_time, delta=1)
+
+ def test_write_without_source_date_epoch(self):
+ if 'SOURCE_DATE_EPOCH' in os.environ:
+ del os.environ['SOURCE_DATE_EPOCH']
+
+ with zipfile.ZipFile(TESTFN, "w") as zf:
+ zf.writestr("test_no_source_date_epoch.txt", "Testing without SOURCE_DATE_EPOCH")
+
+ with zipfile.ZipFile(TESTFN, "r") as zf:
+ zip_info = zf.getinfo("test_no_source_date_epoch.txt")
+ current_time = time.localtime()[:6]
+ for z_time, c_time in zip(zip_info.date_time, current_time):
+ self.assertAlmostEqual(z_time, c_time, delta=1)
+
def test_close(self):
"""Check that the zipfile is closed after the 'with' block."""
with zipfile.ZipFile(TESTFN2, "w") as zipfp:
diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py
index 24531c1c2b7804..49c40032d848f1 100644
--- a/Lib/zipfile/__init__.py
+++ b/Lib/zipfile/__init__.py
@@ -614,7 +614,11 @@ def _for_archive(self, archive: ZipFile) -> Self:
Return self.
"""
- self.date_time = time.localtime(time.time())[:6]
+ # gh-91279: Set the SOURCE_DATE_EPOCH to a specific timestamp
+ epoch = os.environ.get('SOURCE_DATE_EPOCH')
+ get_time = int(epoch) if epoch else time.time()
+ self.date_time = time.localtime(get_time)[:6]
+
self.compress_type = archive.compression
self.compress_level = archive.compresslevel
if self.filename.endswith('/'): # pragma: no cover
diff --git a/Misc/NEWS.d/next/Library/2024-12-30-19-53-14.gh-issue-91279.EeOJk1.rst b/Misc/NEWS.d/next/Library/2024-12-30-19-53-14.gh-issue-91279.EeOJk1.rst
new file mode 100644
index 00000000000000..30ee2ea5efd069
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-12-30-19-53-14.gh-issue-91279.EeOJk1.rst
@@ -0,0 +1,3 @@
+:meth:`zipfile.ZipFile.writestr` now respect ``SOURCE_DATE_EPOCH`` that
+distributions can set centrally and have build tools consume this in order
+to produce reproducible output.
1
0
GH-128131: Completely support random read access of uncompressed unencrypted files in ZipFile (#128143)
by jaraco Jan. 20, 2025
by jaraco Jan. 20, 2025
Jan. 20, 2025
https://github.com/python/cpython/commit/dda02eb7be62bf0af850a7521c77c90ea9…
commit: dda02eb7be62bf0af850a7521c77c90ea997df6c
branch: main
author: 5ec1cff <56485584+5ec1cff(a)users.noreply.github.com>
committer: jaraco <jaraco(a)jaraco.com>
date: 2025-01-20T13:04:43-05:00
summary:
GH-128131: Completely support random read access of uncompressed unencrypted files in ZipFile (#128143)
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot](a)users.noreply.github.com>
Co-authored-by: Bénédikt Tran <10796600+picnixz(a)users.noreply.github.com>
files:
A Misc/NEWS.d/next/Library/2024-12-21-03-20-12.gh-issue-128131.QpPmNt.rst
M Lib/test/test_zipfile/test_core.py
M Lib/zipfile/__init__.py
diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py
index 79e7337606b4bc..02e28d4004c01a 100644
--- a/Lib/test/test_zipfile/test_core.py
+++ b/Lib/test/test_zipfile/test_core.py
@@ -1,3 +1,4 @@
+import _pyio
import array
import contextlib
import importlib.util
@@ -3491,5 +3492,87 @@ def test_too_short(self):
b"zzz", zipfile._Extra.strip(b"zzz", (self.ZIP64_EXTRA,)))
+class StatIO(_pyio.BytesIO):
+ """Buffer which remembers the number of bytes that were read."""
+
+ def __init__(self):
+ super().__init__()
+ self.bytes_read = 0
+
+ def read(self, size=-1):
+ bs = super().read(size)
+ self.bytes_read += len(bs)
+ return bs
+
+
+class StoredZipExtFileRandomReadTest(unittest.TestCase):
+ """Tests whether an uncompressed, unencrypted zip entry can be randomly
+ seek and read without reading redundant bytes."""
+ def test_stored_seek_and_read(self):
+
+ sio = StatIO()
+ # 20000 bytes
+ txt = b'0123456789' * 2000
+
+ # The seek length must be greater than ZipExtFile.MIN_READ_SIZE
+ # as `ZipExtFile._read2()` reads in blocks of this size and we
+ # need to seek out of the buffered data
+ read_buffer_size = zipfile.ZipExtFile.MIN_READ_SIZE
+ self.assertGreaterEqual(10002, read_buffer_size) # for forward seek test
+ self.assertGreaterEqual(5003, read_buffer_size) # for backward seek test
+ # The read length must be less than MIN_READ_SIZE, since we assume that
+ # only 1 block is read in the test.
+ read_length = 100
+ self.assertGreaterEqual(read_buffer_size, read_length) # for read() calls
+
+ with zipfile.ZipFile(sio, "w", compression=zipfile.ZIP_STORED) as zipf:
+ zipf.writestr("foo.txt", txt)
+
+ # check random seek and read on a file
+ with zipfile.ZipFile(sio, "r") as zipf:
+ with zipf.open("foo.txt", "r") as fp:
+ # Test this optimized read hasn't rewound and read from the
+ # start of the file (as in the case of the unoptimized path)
+
+ # forward seek
+ old_count = sio.bytes_read
+ forward_seek_len = 10002
+ current_pos = 0
+ fp.seek(forward_seek_len, os.SEEK_CUR)
+ current_pos += forward_seek_len
+ self.assertEqual(fp.tell(), current_pos)
+ self.assertEqual(fp._left, fp._compress_left)
+ arr = fp.read(read_length)
+ current_pos += read_length
+ self.assertEqual(fp.tell(), current_pos)
+ self.assertEqual(arr, txt[current_pos - read_length:current_pos])
+ self.assertEqual(fp._left, fp._compress_left)
+ read_count = sio.bytes_read - old_count
+ self.assertLessEqual(read_count, read_buffer_size)
+
+ # backward seek
+ old_count = sio.bytes_read
+ backward_seek_len = 5003
+ fp.seek(-backward_seek_len, os.SEEK_CUR)
+ current_pos -= backward_seek_len
+ self.assertEqual(fp.tell(), current_pos)
+ self.assertEqual(fp._left, fp._compress_left)
+ arr = fp.read(read_length)
+ current_pos += read_length
+ self.assertEqual(fp.tell(), current_pos)
+ self.assertEqual(arr, txt[current_pos - read_length:current_pos])
+ self.assertEqual(fp._left, fp._compress_left)
+ read_count = sio.bytes_read - old_count
+ self.assertLessEqual(read_count, read_buffer_size)
+
+ # eof flags test
+ fp.seek(0, os.SEEK_END)
+ fp.seek(12345, os.SEEK_SET)
+ current_pos = 12345
+ arr = fp.read(read_length)
+ current_pos += read_length
+ self.assertEqual(arr, txt[current_pos - read_length:current_pos])
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py
index 052ef47b8f6598..24531c1c2b7804 100644
--- a/Lib/zipfile/__init__.py
+++ b/Lib/zipfile/__init__.py
@@ -1184,13 +1184,15 @@ def seek(self, offset, whence=os.SEEK_SET):
self._offset = buff_offset
read_offset = 0
# Fast seek uncompressed unencrypted file
- elif self._compress_type == ZIP_STORED and self._decrypter is None and read_offset > 0:
+ elif self._compress_type == ZIP_STORED and self._decrypter is None and read_offset != 0:
# disable CRC checking after first seeking - it would be invalid
self._expected_crc = None
# seek actual file taking already buffered data into account
read_offset -= len(self._readbuffer) - self._offset
self._fileobj.seek(read_offset, os.SEEK_CUR)
self._left -= read_offset
+ self._compress_left -= read_offset
+ self._eof = self._left <= 0
read_offset = 0
# flush read buffer
self._readbuffer = b''
diff --git a/Misc/NEWS.d/next/Library/2024-12-21-03-20-12.gh-issue-128131.QpPmNt.rst b/Misc/NEWS.d/next/Library/2024-12-21-03-20-12.gh-issue-128131.QpPmNt.rst
new file mode 100644
index 00000000000000..f4c4ebce10729c
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-12-21-03-20-12.gh-issue-128131.QpPmNt.rst
@@ -0,0 +1,2 @@
+Completely support random access of uncompressed unencrypted read-only
+zip files obtained by :meth:`ZipFile.open <zipfile.ZipFile.open>`.
1
0
[3.13] gh-128588: gh-128550: remove eager tasks optimization that missed and introduced incorrect cancellations (GH-129063) (#129089)
by kumaraditya303 Jan. 20, 2025
by kumaraditya303 Jan. 20, 2025
Jan. 20, 2025
https://github.com/python/cpython/commit/a1c48a750cc52332b0ed16ea8ffa07c18e…
commit: a1c48a750cc52332b0ed16ea8ffa07c18eaee201
branch: 3.13
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: kumaraditya303 <kumaraditya(a)python.org>
date: 2025-01-20T17:36:50Z
summary:
[3.13] gh-128588: gh-128550: remove eager tasks optimization that missed and introduced incorrect cancellations (GH-129063) (#129089)
gh-128588: gh-128550: remove eager tasks optimization that missed and introduced incorrect cancellations (GH-129063)
(cherry picked from commit ed6934e71e55d398df8263f4697f58e4a3815f69)
Co-authored-by: Thomas Grainger <tagrain(a)gmail.com>
Co-authored-by: Kumar Aditya <kumaraditya(a)python.org>
files:
A Misc/NEWS.d/next/Library/2025-01-20-13-12-39.gh-issue-128550.AJ5TOL.rst
M Lib/asyncio/taskgroups.py
M Lib/test/test_asyncio/test_taskgroups.py
diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py
index 8af199d6dcc41a..8fda6c8d55e16c 100644
--- a/Lib/asyncio/taskgroups.py
+++ b/Lib/asyncio/taskgroups.py
@@ -197,14 +197,12 @@ def create_task(self, coro, *, name=None, context=None):
else:
task = self._loop.create_task(coro, name=name, context=context)
- # optimization: Immediately call the done callback if the task is
+ # Always schedule the done callback even if the task is
# already done (e.g. if the coro was able to complete eagerly),
- # and skip scheduling a done callback
- if task.done():
- self._on_task_done(task)
- else:
- self._tasks.add(task)
- task.add_done_callback(self._on_task_done)
+ # otherwise if the task completes with an exception then it will cancel
+ # the current task too early. gh-128550, gh-128588
+ self._tasks.add(task)
+ task.add_done_callback(self._on_task_done)
try:
return task
finally:
diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py
index e52061aac923cc..ad61cb46c7c07c 100644
--- a/Lib/test/test_asyncio/test_taskgroups.py
+++ b/Lib/test/test_asyncio/test_taskgroups.py
@@ -1032,6 +1032,56 @@ class MyKeyboardInterrupt(KeyboardInterrupt):
self.assertListEqual(gc.get_referrers(exc), [])
+ async def test_cancels_task_if_created_during_creation(self):
+ # regression test for gh-128550
+ ran = False
+ class MyError(Exception):
+ pass
+
+ exc = None
+ try:
+ async with asyncio.TaskGroup() as tg:
+ async def third_task():
+ raise MyError("third task failed")
+
+ async def second_task():
+ nonlocal ran
+ tg.create_task(third_task())
+ with self.assertRaises(asyncio.CancelledError):
+ await asyncio.sleep(0) # eager tasks cancel here
+ await asyncio.sleep(0) # lazy tasks cancel here
+ ran = True
+
+ tg.create_task(second_task())
+ except* MyError as excs:
+ exc = excs.exceptions[0]
+
+ self.assertTrue(ran)
+ self.assertIsInstance(exc, MyError)
+
+
+ async def test_cancellation_does_not_leak_out_of_tg(self):
+ class MyError(Exception):
+ pass
+
+ async def throw_error():
+ raise MyError
+
+ try:
+ async with asyncio.TaskGroup() as tg:
+ tg.create_task(throw_error())
+ except* MyError:
+ pass
+ else:
+ self.fail("should have raised one MyError in group")
+
+ # if this test fails this current task will be cancelled
+ # outside the task group and inside unittest internals
+ # we yield to the event loop with sleep(0) so that
+ # cancellation happens here and error is more understandable
+ await asyncio.sleep(0)
+
+
class TestTaskGroup(BaseTestTaskGroup, unittest.IsolatedAsyncioTestCase):
loop_factory = asyncio.EventLoop
diff --git a/Misc/NEWS.d/next/Library/2025-01-20-13-12-39.gh-issue-128550.AJ5TOL.rst b/Misc/NEWS.d/next/Library/2025-01-20-13-12-39.gh-issue-128550.AJ5TOL.rst
new file mode 100644
index 00000000000000..f59feac795ea18
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-01-20-13-12-39.gh-issue-128550.AJ5TOL.rst
@@ -0,0 +1 @@
+Removed an incorrect optimization relating to eager tasks in :class:`asyncio.TaskGroup` that resulted in cancellations being missed.
1
0
gh-128588: gh-128550: remove eager tasks optimization that missed and introduced incorrect cancellations (#129063)
by kumaraditya303 Jan. 20, 2025
by kumaraditya303 Jan. 20, 2025
Jan. 20, 2025
https://github.com/python/cpython/commit/ed6934e71e55d398df8263f4697f58e4a3…
commit: ed6934e71e55d398df8263f4697f58e4a3815f69
branch: main
author: Thomas Grainger <tagrain(a)gmail.com>
committer: kumaraditya303 <kumaraditya(a)python.org>
date: 2025-01-20T17:13:01Z
summary:
gh-128588: gh-128550: remove eager tasks optimization that missed and introduced incorrect cancellations (#129063)
Co-authored-by: Kumar Aditya <kumaraditya(a)python.org>
files:
A Misc/NEWS.d/next/Library/2025-01-20-13-12-39.gh-issue-128550.AJ5TOL.rst
M Lib/asyncio/taskgroups.py
M Lib/test/test_asyncio/test_taskgroups.py
diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py
index 8af199d6dcc41a..8fda6c8d55e16c 100644
--- a/Lib/asyncio/taskgroups.py
+++ b/Lib/asyncio/taskgroups.py
@@ -197,14 +197,12 @@ def create_task(self, coro, *, name=None, context=None):
else:
task = self._loop.create_task(coro, name=name, context=context)
- # optimization: Immediately call the done callback if the task is
+ # Always schedule the done callback even if the task is
# already done (e.g. if the coro was able to complete eagerly),
- # and skip scheduling a done callback
- if task.done():
- self._on_task_done(task)
- else:
- self._tasks.add(task)
- task.add_done_callback(self._on_task_done)
+ # otherwise if the task completes with an exception then it will cancel
+ # the current task too early. gh-128550, gh-128588
+ self._tasks.add(task)
+ task.add_done_callback(self._on_task_done)
try:
return task
finally:
diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py
index 7859b33532fa27..0d69a436fdb840 100644
--- a/Lib/test/test_asyncio/test_taskgroups.py
+++ b/Lib/test/test_asyncio/test_taskgroups.py
@@ -1053,6 +1053,56 @@ async def asyncfn():
self.assertEqual(name, "example name")
+ async def test_cancels_task_if_created_during_creation(self):
+ # regression test for gh-128550
+ ran = False
+ class MyError(Exception):
+ pass
+
+ exc = None
+ try:
+ async with asyncio.TaskGroup() as tg:
+ async def third_task():
+ raise MyError("third task failed")
+
+ async def second_task():
+ nonlocal ran
+ tg.create_task(third_task())
+ with self.assertRaises(asyncio.CancelledError):
+ await asyncio.sleep(0) # eager tasks cancel here
+ await asyncio.sleep(0) # lazy tasks cancel here
+ ran = True
+
+ tg.create_task(second_task())
+ except* MyError as excs:
+ exc = excs.exceptions[0]
+
+ self.assertTrue(ran)
+ self.assertIsInstance(exc, MyError)
+
+
+ async def test_cancellation_does_not_leak_out_of_tg(self):
+ class MyError(Exception):
+ pass
+
+ async def throw_error():
+ raise MyError
+
+ try:
+ async with asyncio.TaskGroup() as tg:
+ tg.create_task(throw_error())
+ except* MyError:
+ pass
+ else:
+ self.fail("should have raised one MyError in group")
+
+ # if this test fails this current task will be cancelled
+ # outside the task group and inside unittest internals
+ # we yield to the event loop with sleep(0) so that
+ # cancellation happens here and error is more understandable
+ await asyncio.sleep(0)
+
+
class TestTaskGroup(BaseTestTaskGroup, unittest.IsolatedAsyncioTestCase):
loop_factory = asyncio.EventLoop
diff --git a/Misc/NEWS.d/next/Library/2025-01-20-13-12-39.gh-issue-128550.AJ5TOL.rst b/Misc/NEWS.d/next/Library/2025-01-20-13-12-39.gh-issue-128550.AJ5TOL.rst
new file mode 100644
index 00000000000000..f59feac795ea18
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-01-20-13-12-39.gh-issue-128550.AJ5TOL.rst
@@ -0,0 +1 @@
+Removed an incorrect optimization relating to eager tasks in :class:`asyncio.TaskGroup` that resulted in cancellations being missed.
1
0
GH-128914: Remove conditional stack effects from `bytecodes.c` and the code generators (GH-128918)
by markshannon Jan. 20, 2025
by markshannon Jan. 20, 2025
Jan. 20, 2025
https://github.com/python/cpython/commit/ab61d3f4303d14a413bc9ae6557c730ffd…
commit: ab61d3f4303d14a413bc9ae6557c730ffdf7579e
branch: main
author: Mark Shannon <mark(a)hotpy.org>
committer: markshannon <mark(a)hotpy.org>
date: 2025-01-20T17:09:23Z
summary:
GH-128914: Remove conditional stack effects from `bytecodes.c` and the code generators (GH-128918)
files:
A Misc/NEWS.d/next/Core_and_Builtins/2025-01-17-10-17-01.gh-issue-128914.dn6RaW.rst
M Doc/library/dis.rst
M Include/internal/pycore_code.h
M Include/internal/pycore_magic_number.h
M Include/internal/pycore_opcode_metadata.h
M Include/internal/pycore_uop_ids.h
M Include/internal/pycore_uop_metadata.h
M Include/opcode_ids.h
M Lib/_opcode_metadata.py
M Lib/dis.py
M Lib/inspect.py
M Lib/opcode.py
M Lib/test/test__opcode.py
M Lib/test/test_capi/test_opt.py
M Lib/test/test_compile.py
M Lib/test/test_dis.py
M Lib/test/test_generated_cases.py
M Lib/test/test_monitoring.py
M Lib/test/test_opcache.py
M Objects/frameobject.c
M Objects/object.c
M Programs/test_frozenmain.h
M Python/bytecodes.c
M Python/codegen.c
M Python/executor_cases.c.h
M Python/flowgraph.c
M Python/generated_cases.c.h
M Python/instrumentation.c
M Python/opcode_targets.h
M Python/optimizer.c
M Python/optimizer_analysis.c
M Python/optimizer_bytecodes.c
M Python/optimizer_cases.c.h
M Python/specialize.c
M Tools/cases_generator/analyzer.py
M Tools/cases_generator/generators_common.py
M Tools/cases_generator/lexer.py
M Tools/cases_generator/opcode_metadata_generator.py
M Tools/cases_generator/optimizer_generator.py
M Tools/cases_generator/parsing.py
M Tools/cases_generator/stack.py
M Tools/cases_generator/tier1_generator.py
M Tools/cases_generator/tier2_generator.py
M Tools/scripts/summarize_stats.py
diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
index f8f4188d27b472..225ef321aed3b8 100644
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -75,7 +75,8 @@ the following command can be used to display the disassembly of
>>> dis.dis(myfunc)
2 RESUME 0
<BLANKLINE>
- 3 LOAD_GLOBAL 1 (len + NULL)
+ 3 LOAD_GLOBAL 0 (len)
+ PUSH_NULL
LOAD_FAST 0 (alist)
CALL 1
RETURN_VALUE
@@ -207,6 +208,7 @@ Example:
...
RESUME
LOAD_GLOBAL
+ PUSH_NULL
LOAD_FAST
CALL
RETURN_VALUE
@@ -1215,11 +1217,20 @@ iterations of the loop.
.. opcode:: LOAD_ATTR (namei)
- If the low bit of ``namei`` is not set, this replaces ``STACK[-1]`` with
- ``getattr(STACK[-1], co_names[namei>>1])``.
+ Replaces ``STACK[-1]`` with ``getattr(STACK[-1], co_names[namei>>1])``.
- If the low bit of ``namei`` is set, this will attempt to load a method named
- ``co_names[namei>>1]`` from the ``STACK[-1]`` object. ``STACK[-1]`` is popped.
+ .. versionchanged:: 3.12
+ If the low bit of ``namei`` is set, then a ``NULL`` or ``self`` is
+ pushed to the stack before the attribute or unbound method respectively.
+
+ .. versionchanged:: 3.14
+ Reverted change from 3.12. The low bit of ``namei`` has no special meaning.
+
+
+.. opcode:: LOAD_METHOD (namei)
+
+ Attempt to load a method named ``co_names[namei>>1]`` from the ``STACK[-1]`` object.
+ ``STACK[-1]`` is popped.
This bytecode distinguishes two cases: if ``STACK[-1]`` has a method with the
correct name, the bytecode pushes the unbound method and ``STACK[-1]``.
``STACK[-1]`` will be used as the first argument (``self``) by :opcode:`CALL`
@@ -1227,9 +1238,7 @@ iterations of the loop.
Otherwise, ``NULL`` and the object returned by
the attribute lookup are pushed.
- .. versionchanged:: 3.12
- If the low bit of ``namei`` is set, then a ``NULL`` or ``self`` is
- pushed to the stack before the attribute or unbound method respectively.
+ .. versionadded:: 3.14
.. opcode:: LOAD_SUPER_ATTR (namei)
@@ -1926,12 +1935,6 @@ but are replaced by real opcodes or removed before bytecode is generated.
This opcode is now a pseudo-instruction.
-.. opcode:: LOAD_METHOD
-
- Optimized unbound method lookup. Emitted as a ``LOAD_ATTR`` opcode
- with a flag set in the arg.
-
-
.. _opcode_collections:
Opcode collections
diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h
index 01d41446fdb0cf..f5eddab6e90e41 100644
--- a/Include/internal/pycore_code.h
+++ b/Include/internal/pycore_code.h
@@ -334,6 +334,8 @@ extern void _Py_Specialize_LoadSuperAttr(_PyStackRef global_super, _PyStackRef c
_Py_CODEUNIT *instr, int load_method);
extern void _Py_Specialize_LoadAttr(_PyStackRef owner, _Py_CODEUNIT *instr,
PyObject *name);
+extern void _Py_Specialize_LoadMethod(_PyStackRef owner, _Py_CODEUNIT *instr,
+ PyObject *name);
extern void _Py_Specialize_StoreAttr(_PyStackRef owner, _Py_CODEUNIT *instr,
PyObject *name);
extern void _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins,
diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h
index 1dd155abf3babf..0d94b6d81d2936 100644
--- a/Include/internal/pycore_magic_number.h
+++ b/Include/internal/pycore_magic_number.h
@@ -267,6 +267,7 @@ Known values:
Python 3.14a4 3612 (Add POP_ITER and INSTRUMENTED_POP_ITER)
Python 3.14a4 3613 (Add LOAD_CONST_MORTAL instruction)
Python 3.14a5 3614 (Add BINARY_OP_EXTEND)
+ Python 3.14a5 3615 (Remove conditional stack effects)
Python 3.15 will start with 3650
@@ -279,7 +280,7 @@ PC/launcher.c must also be updated.
*/
-#define PYC_MAGIC_NUMBER 3614
+#define PYC_MAGIC_NUMBER 3615
/* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
(little-endian) and then appending b'\r\n'. */
#define PYC_MAGIC_NUMBER_TOKEN \
diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h
index f7c23ad634d6be..396b3a58ad08ec 100644
--- a/Include/internal/pycore_opcode_metadata.h
+++ b/Include/internal/pycore_opcode_metadata.h
@@ -76,7 +76,7 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
case BUILD_SET:
return oparg;
case BUILD_SLICE:
- return 2 + ((oparg == 3) ? 1 : 0);
+ return oparg;
case BUILD_STRING:
return oparg;
case BUILD_TUPLE:
@@ -100,7 +100,7 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
case CALL_BUILTIN_O:
return 2 + oparg;
case CALL_FUNCTION_EX:
- return 3 + (oparg & 1);
+ return 4;
case CALL_INTRINSIC_1:
return 1;
case CALL_INTRINSIC_2:
@@ -245,6 +245,8 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
return 0;
case INSTRUMENTED_LOAD_SUPER_ATTR:
return 0;
+ case INSTRUMENTED_LOAD_SUPER_METHOD:
+ return 0;
case INSTRUMENTED_NOT_TAKEN:
return 0;
case INSTRUMENTED_POP_ITER:
@@ -295,12 +297,6 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
return 1;
case LOAD_ATTR_INSTANCE_VALUE:
return 1;
- case LOAD_ATTR_METHOD_LAZY_DICT:
- return 1;
- case LOAD_ATTR_METHOD_NO_DICT:
- return 1;
- case LOAD_ATTR_METHOD_WITH_VALUES:
- return 1;
case LOAD_ATTR_MODULE:
return 1;
case LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
@@ -347,6 +343,14 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
return 0;
case LOAD_LOCALS:
return 0;
+ case LOAD_METHOD:
+ return 1;
+ case LOAD_METHOD_LAZY_DICT:
+ return 1;
+ case LOAD_METHOD_NO_DICT:
+ return 1;
+ case LOAD_METHOD_WITH_VALUES:
+ return 1;
case LOAD_NAME:
return 0;
case LOAD_SMALL_INT:
@@ -357,7 +361,9 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
return 3;
case LOAD_SUPER_ATTR_ATTR:
return 3;
- case LOAD_SUPER_ATTR_METHOD:
+ case LOAD_SUPER_METHOD:
+ return 3;
+ case LOAD_SUPER_METHOD_METHOD:
return 3;
case MAKE_CELL:
return 0;
@@ -716,6 +722,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
return 0;
case INSTRUMENTED_LOAD_SUPER_ATTR:
return 0;
+ case INSTRUMENTED_LOAD_SUPER_METHOD:
+ return 0;
case INSTRUMENTED_NOT_TAKEN:
return 0;
case INSTRUMENTED_POP_ITER:
@@ -757,23 +765,17 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
case LIST_EXTEND:
return 1 + (oparg-1);
case LOAD_ATTR:
- return 1 + (oparg & 1);
+ return 1;
case LOAD_ATTR_CLASS:
- return 1 + (oparg & 1);
+ return 1;
case LOAD_ATTR_CLASS_WITH_METACLASS_CHECK:
- return 1 + (oparg & 1);
+ return 1;
case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN:
return 1;
case LOAD_ATTR_INSTANCE_VALUE:
- return 1 + (oparg & 1);
- case LOAD_ATTR_METHOD_LAZY_DICT:
- return 2;
- case LOAD_ATTR_METHOD_NO_DICT:
- return 2;
- case LOAD_ATTR_METHOD_WITH_VALUES:
- return 2;
+ return 1;
case LOAD_ATTR_MODULE:
- return 1 + (oparg & 1);
+ return 1;
case LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
return 1;
case LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
@@ -781,9 +783,9 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
case LOAD_ATTR_PROPERTY:
return 0;
case LOAD_ATTR_SLOT:
- return 1 + (oparg & 1);
+ return 1;
case LOAD_ATTR_WITH_HINT:
- return 1 + (oparg & 1);
+ return 1;
case LOAD_BUILD_CLASS:
return 1;
case LOAD_CLOSURE:
@@ -811,13 +813,21 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
case LOAD_FROM_DICT_OR_GLOBALS:
return 1;
case LOAD_GLOBAL:
- return 1 + (oparg & 1);
+ return 1;
case LOAD_GLOBAL_BUILTIN:
- return 1 + (oparg & 1);
+ return 1;
case LOAD_GLOBAL_MODULE:
- return 1 + (oparg & 1);
+ return 1;
case LOAD_LOCALS:
return 1;
+ case LOAD_METHOD:
+ return 2;
+ case LOAD_METHOD_LAZY_DICT:
+ return 2;
+ case LOAD_METHOD_NO_DICT:
+ return 2;
+ case LOAD_METHOD_WITH_VALUES:
+ return 2;
case LOAD_NAME:
return 1;
case LOAD_SMALL_INT:
@@ -825,10 +835,12 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
case LOAD_SPECIAL:
return 2;
case LOAD_SUPER_ATTR:
- return 1 + (oparg & 1);
+ return 1;
case LOAD_SUPER_ATTR_ATTR:
return 1;
- case LOAD_SUPER_ATTR_METHOD:
+ case LOAD_SUPER_METHOD:
+ return 2;
+ case LOAD_SUPER_METHOD_METHOD:
return 2;
case MAKE_CELL:
return 0;
@@ -1058,7 +1070,7 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
return 0;
}
case BUILD_SLICE: {
- *effect = -1 - ((oparg == 3) ? 1 : 0);
+ *effect = 1 - oparg;
return 0;
}
case BUILD_STRING: {
@@ -1114,7 +1126,7 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
return 0;
}
case CALL_FUNCTION_EX: {
- *effect = Py_MAX(0, -2 - (oparg & 1));
+ *effect = 0;
return 0;
}
case CALL_INTRINSIC_1: {
@@ -1415,6 +1427,10 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
*effect = 0;
return 0;
}
+ case INSTRUMENTED_LOAD_SUPER_METHOD: {
+ *effect = 0;
+ return 0;
+ }
case INSTRUMENTED_NOT_TAKEN: {
*effect = 0;
return 0;
@@ -1496,15 +1512,15 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
return 0;
}
case LOAD_ATTR: {
- *effect = Py_MAX(1, (oparg & 1));
+ *effect = 1;
return 0;
}
case LOAD_ATTR_CLASS: {
- *effect = Py_MAX(0, (oparg & 1));
+ *effect = 0;
return 0;
}
case LOAD_ATTR_CLASS_WITH_METACLASS_CHECK: {
- *effect = Py_MAX(0, (oparg & 1));
+ *effect = 0;
return 0;
}
case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN: {
@@ -1512,23 +1528,11 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
return 0;
}
case LOAD_ATTR_INSTANCE_VALUE: {
- *effect = Py_MAX(0, (oparg & 1));
- return 0;
- }
- case LOAD_ATTR_METHOD_LAZY_DICT: {
- *effect = 1;
- return 0;
- }
- case LOAD_ATTR_METHOD_NO_DICT: {
- *effect = 1;
- return 0;
- }
- case LOAD_ATTR_METHOD_WITH_VALUES: {
- *effect = 1;
+ *effect = 0;
return 0;
}
case LOAD_ATTR_MODULE: {
- *effect = Py_MAX(1, (oparg & 1));
+ *effect = 1;
return 0;
}
case LOAD_ATTR_NONDESCRIPTOR_NO_DICT: {
@@ -1544,11 +1548,11 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
return 0;
}
case LOAD_ATTR_SLOT: {
- *effect = Py_MAX(0, (oparg & 1));
+ *effect = 0;
return 0;
}
case LOAD_ATTR_WITH_HINT: {
- *effect = Py_MAX(1, (oparg & 1));
+ *effect = 1;
return 0;
}
case LOAD_BUILD_CLASS: {
@@ -1604,21 +1608,37 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
return 0;
}
case LOAD_GLOBAL: {
- *effect = Py_MAX(1, 1 + (oparg & 1));
+ *effect = 1;
return 0;
}
case LOAD_GLOBAL_BUILTIN: {
- *effect = Py_MAX(1, 1 + (oparg & 1));
+ *effect = 1;
return 0;
}
case LOAD_GLOBAL_MODULE: {
- *effect = Py_MAX(1, 1 + (oparg & 1));
+ *effect = 1;
return 0;
}
case LOAD_LOCALS: {
*effect = 1;
return 0;
}
+ case LOAD_METHOD: {
+ *effect = 1;
+ return 0;
+ }
+ case LOAD_METHOD_LAZY_DICT: {
+ *effect = 1;
+ return 0;
+ }
+ case LOAD_METHOD_NO_DICT: {
+ *effect = 1;
+ return 0;
+ }
+ case LOAD_METHOD_WITH_VALUES: {
+ *effect = 1;
+ return 0;
+ }
case LOAD_NAME: {
*effect = 1;
return 0;
@@ -1632,14 +1652,18 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
return 0;
}
case LOAD_SUPER_ATTR: {
- *effect = Py_MAX(0, -2 + (oparg & 1));
+ *effect = 0;
return 0;
}
case LOAD_SUPER_ATTR_ATTR: {
*effect = -2;
return 0;
}
- case LOAD_SUPER_ATTR_METHOD: {
+ case LOAD_SUPER_METHOD: {
+ *effect = 0;
+ return 0;
+ }
+ case LOAD_SUPER_METHOD_METHOD: {
*effect = -1;
return 0;
}
@@ -1934,6 +1958,7 @@ enum InstructionFormat {
INSTR_FMT_IXC00 = 9,
INSTR_FMT_IXC000 = 10,
INSTR_FMT_IXC0000 = 11,
+ INSTR_FMT_IXC00000000 = 12,
};
#define IS_VALID_OPCODE(OP) \
@@ -1953,9 +1978,8 @@ enum InstructionFormat {
#define HAS_EXIT_FLAG (1024)
#define HAS_PURE_FLAG (2048)
#define HAS_PASSTHROUGH_FLAG (4096)
-#define HAS_OPARG_AND_1_FLAG (8192)
-#define HAS_ERROR_NO_POP_FLAG (16384)
-#define HAS_NO_SAVE_IP_FLAG (32768)
+#define HAS_ERROR_NO_POP_FLAG (8192)
+#define HAS_NO_SAVE_IP_FLAG (16384)
#define OPCODE_HAS_ARG(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ARG_FLAG))
#define OPCODE_HAS_CONST(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_CONST_FLAG))
#define OPCODE_HAS_NAME(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_NAME_FLAG))
@@ -1969,7 +1993,6 @@ enum InstructionFormat {
#define OPCODE_HAS_EXIT(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_EXIT_FLAG))
#define OPCODE_HAS_PURE(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_PURE_FLAG))
#define OPCODE_HAS_PASSTHROUGH(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_PASSTHROUGH_FLAG))
-#define OPCODE_HAS_OPARG_AND_1(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_OPARG_AND_1_FLAG))
#define OPCODE_HAS_ERROR_NO_POP(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ERROR_NO_POP_FLAG))
#define OPCODE_HAS_NO_SAVE_IP(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_NO_SAVE_IP_FLAG))
@@ -2023,7 +2046,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
[CALL_BUILTIN_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_BUILTIN_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [CALL_FUNCTION_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_FUNCTION_EX] = { true, INSTR_FMT_IX, HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[CALL_INTRINSIC_1] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_INTRINSIC_2] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_ISINSTANCE] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
@@ -2096,6 +2119,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
[INSTRUMENTED_JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
[INSTRUMENTED_LINE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
[INSTRUMENTED_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IXC, 0 },
+ [INSTRUMENTED_LOAD_SUPER_METHOD] = { true, INSTR_FMT_IXC, 0 },
[INSTRUMENTED_NOT_TAKEN] = { true, INSTR_FMT_IX, 0 },
[INSTRUMENTED_POP_ITER] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
[INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
@@ -2113,18 +2137,15 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
[LIST_APPEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
[LIST_EXTEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_ATTR] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG },
- [LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG },
+ [LOAD_ATTR_CLASS] = { true, INSTR_FMT_IXC00000000, HAS_EXIT_FLAG },
+ [LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = { true, INSTR_FMT_IXC00000000, HAS_EXIT_FLAG },
[LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG },
- [LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
- [LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
- [LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG },
- [LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
- [LOAD_ATTR_MODULE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
- [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG },
- [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+ [LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IXC00000000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+ [LOAD_ATTR_MODULE] = { true, INSTR_FMT_IXC00000000, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IXC00000000, HAS_EXIT_FLAG },
+ [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IXC00000000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
[LOAD_ATTR_PROPERTY] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
- [LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+ [LOAD_ATTR_SLOT] = { true, INSTR_FMT_IXC00000000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
[LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
[LOAD_BUILD_CLASS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_COMMON_CONSTANT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
@@ -2139,15 +2160,20 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
[LOAD_FROM_DICT_OR_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[LOAD_FROM_DICT_OR_GLOBALS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[LOAD_GLOBAL] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [LOAD_GLOBAL_BUILTIN] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
- [LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [LOAD_GLOBAL_BUILTIN] = { true, INSTR_FMT_IXC000, HAS_DEOPT_FLAG },
+ [LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IXC000, HAS_DEOPT_FLAG },
[LOAD_LOCALS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_METHOD] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_METHOD_LAZY_DICT] = { true, INSTR_FMT_IXC00000000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+ [LOAD_METHOD_NO_DICT] = { true, INSTR_FMT_IXC00000000, HAS_EXIT_FLAG },
+ [LOAD_METHOD_WITH_VALUES] = { true, INSTR_FMT_IXC00000000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
[LOAD_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_SMALL_INT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
[LOAD_SPECIAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [LOAD_SUPER_ATTR_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_SUPER_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_SUPER_METHOD_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[MAKE_CELL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[MAKE_FUNCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[MAP_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
@@ -2327,9 +2353,6 @@ _PyOpcode_macro_expansion[256] = {
[LOAD_ATTR_CLASS] = { .nuops = 2, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _LOAD_ATTR_CLASS, 4, 5 } } },
[LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = { .nuops = 3, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _GUARD_TYPE_VERSION, 2, 3 }, { _LOAD_ATTR_CLASS, 4, 5 } } },
[LOAD_ATTR_INSTANCE_VALUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_MANAGED_OBJECT_HAS_VALUES, 0, 0 }, { _LOAD_ATTR_INSTANCE_VALUE, 1, 3 } } },
- [LOAD_ATTR_METHOD_LAZY_DICT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_METHOD_LAZY_DICT, 1, 3 }, { _LOAD_ATTR_METHOD_LAZY_DICT, 4, 5 } } },
- [LOAD_ATTR_METHOD_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_METHOD_NO_DICT, 4, 5 } } },
- [LOAD_ATTR_METHOD_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, 0, 0 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_METHOD_WITH_VALUES, 4, 5 } } },
[LOAD_ATTR_MODULE] = { .nuops = 2, .uops = { { _CHECK_ATTR_MODULE_PUSH_KEYS, 2, 1 }, { _LOAD_ATTR_MODULE_FROM_KEYS, 1, 3 } } },
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_NONDESCRIPTOR_NO_DICT, 4, 5 } } },
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, 0, 0 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, 4, 5 } } },
@@ -2350,11 +2373,15 @@ _PyOpcode_macro_expansion[256] = {
[LOAD_GLOBAL_BUILTIN] = { .nuops = 3, .uops = { { _GUARD_GLOBALS_VERSION, 1, 1 }, { _GUARD_BUILTINS_VERSION_PUSH_KEYS, 1, 2 }, { _LOAD_GLOBAL_BUILTINS_FROM_KEYS, 1, 3 } } },
[LOAD_GLOBAL_MODULE] = { .nuops = 2, .uops = { { _GUARD_GLOBALS_VERSION_PUSH_KEYS, 1, 1 }, { _LOAD_GLOBAL_MODULE_FROM_KEYS, 1, 3 } } },
[LOAD_LOCALS] = { .nuops = 1, .uops = { { _LOAD_LOCALS, 0, 0 } } },
+ [LOAD_METHOD] = { .nuops = 1, .uops = { { _LOAD_METHOD, 0, 0 } } },
+ [LOAD_METHOD_LAZY_DICT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_METHOD_LAZY_DICT, 1, 3 }, { _LOAD_METHOD_LAZY_DICT, 4, 5 } } },
+ [LOAD_METHOD_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_METHOD_NO_DICT, 4, 5 } } },
+ [LOAD_METHOD_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, 0, 0 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_METHOD_WITH_VALUES, 4, 5 } } },
[LOAD_NAME] = { .nuops = 1, .uops = { { _LOAD_NAME, 0, 0 } } },
[LOAD_SMALL_INT] = { .nuops = 1, .uops = { { _LOAD_SMALL_INT, 0, 0 } } },
[LOAD_SPECIAL] = { .nuops = 1, .uops = { { _LOAD_SPECIAL, 0, 0 } } },
[LOAD_SUPER_ATTR_ATTR] = { .nuops = 1, .uops = { { _LOAD_SUPER_ATTR_ATTR, 0, 0 } } },
- [LOAD_SUPER_ATTR_METHOD] = { .nuops = 1, .uops = { { _LOAD_SUPER_ATTR_METHOD, 0, 0 } } },
+ [LOAD_SUPER_METHOD_METHOD] = { .nuops = 1, .uops = { { _LOAD_SUPER_METHOD_METHOD, 0, 0 } } },
[MAKE_CELL] = { .nuops = 1, .uops = { { _MAKE_CELL, 0, 0 } } },
[MAKE_FUNCTION] = { .nuops = 1, .uops = { { _MAKE_FUNCTION, 0, 0 } } },
[MAP_ADD] = { .nuops = 1, .uops = { { _MAP_ADD, 0, 0 } } },
@@ -2524,6 +2551,7 @@ const char *_PyOpcode_OpName[266] = {
[INSTRUMENTED_JUMP_FORWARD] = "INSTRUMENTED_JUMP_FORWARD",
[INSTRUMENTED_LINE] = "INSTRUMENTED_LINE",
[INSTRUMENTED_LOAD_SUPER_ATTR] = "INSTRUMENTED_LOAD_SUPER_ATTR",
+ [INSTRUMENTED_LOAD_SUPER_METHOD] = "INSTRUMENTED_LOAD_SUPER_METHOD",
[INSTRUMENTED_NOT_TAKEN] = "INSTRUMENTED_NOT_TAKEN",
[INSTRUMENTED_POP_ITER] = "INSTRUMENTED_POP_ITER",
[INSTRUMENTED_POP_JUMP_IF_FALSE] = "INSTRUMENTED_POP_JUMP_IF_FALSE",
@@ -2549,9 +2577,6 @@ const char *_PyOpcode_OpName[266] = {
[LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = "LOAD_ATTR_CLASS_WITH_METACLASS_CHECK",
[LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN",
[LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE",
- [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT",
- [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT",
- [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES",
[LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE",
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
@@ -2575,12 +2600,17 @@ const char *_PyOpcode_OpName[266] = {
[LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN",
[LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE",
[LOAD_LOCALS] = "LOAD_LOCALS",
+ [LOAD_METHOD] = "LOAD_METHOD",
+ [LOAD_METHOD_LAZY_DICT] = "LOAD_METHOD_LAZY_DICT",
+ [LOAD_METHOD_NO_DICT] = "LOAD_METHOD_NO_DICT",
+ [LOAD_METHOD_WITH_VALUES] = "LOAD_METHOD_WITH_VALUES",
[LOAD_NAME] = "LOAD_NAME",
[LOAD_SMALL_INT] = "LOAD_SMALL_INT",
[LOAD_SPECIAL] = "LOAD_SPECIAL",
[LOAD_SUPER_ATTR] = "LOAD_SUPER_ATTR",
[LOAD_SUPER_ATTR_ATTR] = "LOAD_SUPER_ATTR_ATTR",
- [LOAD_SUPER_ATTR_METHOD] = "LOAD_SUPER_ATTR_METHOD",
+ [LOAD_SUPER_METHOD] = "LOAD_SUPER_METHOD",
+ [LOAD_SUPER_METHOD_METHOD] = "LOAD_SUPER_METHOD_METHOD",
[MAKE_CELL] = "MAKE_CELL",
[MAKE_FUNCTION] = "MAKE_FUNCTION",
[MAP_ADD] = "MAP_ADD",
@@ -2663,7 +2693,9 @@ const uint8_t _PyOpcode_Caches[256] = {
[STORE_ATTR] = 4,
[LOAD_GLOBAL] = 4,
[LOAD_SUPER_ATTR] = 1,
+ [LOAD_SUPER_METHOD] = 1,
[LOAD_ATTR] = 9,
+ [LOAD_METHOD] = 9,
[COMPARE_OP] = 1,
[CONTAINS_OP] = 1,
[JUMP_BACKWARD] = 1,
@@ -2786,6 +2818,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
[INSTRUMENTED_JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD,
[INSTRUMENTED_LINE] = INSTRUMENTED_LINE,
[INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
+ [INSTRUMENTED_LOAD_SUPER_METHOD] = INSTRUMENTED_LOAD_SUPER_METHOD,
[INSTRUMENTED_NOT_TAKEN] = INSTRUMENTED_NOT_TAKEN,
[INSTRUMENTED_POP_ITER] = INSTRUMENTED_POP_ITER,
[INSTRUMENTED_POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE,
@@ -2807,9 +2840,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
[LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = LOAD_ATTR,
[LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = LOAD_ATTR,
[LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR,
- [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR,
- [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR,
- [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR,
[LOAD_ATTR_MODULE] = LOAD_ATTR,
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = LOAD_ATTR,
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = LOAD_ATTR,
@@ -2832,12 +2862,17 @@ const uint8_t _PyOpcode_Deopt[256] = {
[LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL,
[LOAD_GLOBAL_MODULE] = LOAD_GLOBAL,
[LOAD_LOCALS] = LOAD_LOCALS,
+ [LOAD_METHOD] = LOAD_METHOD,
+ [LOAD_METHOD_LAZY_DICT] = LOAD_METHOD,
+ [LOAD_METHOD_NO_DICT] = LOAD_METHOD,
+ [LOAD_METHOD_WITH_VALUES] = LOAD_METHOD,
[LOAD_NAME] = LOAD_NAME,
[LOAD_SMALL_INT] = LOAD_SMALL_INT,
[LOAD_SPECIAL] = LOAD_SPECIAL,
[LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
[LOAD_SUPER_ATTR_ATTR] = LOAD_SUPER_ATTR,
- [LOAD_SUPER_ATTR_METHOD] = LOAD_SUPER_ATTR,
+ [LOAD_SUPER_METHOD] = LOAD_SUPER_METHOD,
+ [LOAD_SUPER_METHOD_METHOD] = LOAD_SUPER_METHOD,
[MAKE_CELL] = MAKE_CELL,
[MAKE_FUNCTION] = MAKE_FUNCTION,
[MAP_ADD] = MAP_ADD,
@@ -2906,8 +2941,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
#endif // NEED_OPCODE_METADATA
#define EXTRA_CASES \
- case 118: \
- case 119: \
case 120: \
case 121: \
case 122: \
@@ -2941,7 +2974,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
case 231: \
case 232: \
case 233: \
- case 234: \
;
struct pseudo_targets {
uint8_t as_sequence;
diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h
index 066165a2c810d5..2bf8542bdb67a9 100644
--- a/Include/internal/pycore_uop_ids.h
+++ b/Include/internal/pycore_uop_ids.h
@@ -159,6 +159,7 @@ extern "C" {
#define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD
#define _INSTRUMENTED_LINE INSTRUMENTED_LINE
#define _INSTRUMENTED_LOAD_SUPER_ATTR INSTRUMENTED_LOAD_SUPER_ATTR
+#define _INSTRUMENTED_LOAD_SUPER_METHOD INSTRUMENTED_LOAD_SUPER_METHOD
#define _INSTRUMENTED_NOT_TAKEN INSTRUMENTED_NOT_TAKEN
#define _INSTRUMENTED_POP_JUMP_IF_FALSE INSTRUMENTED_POP_JUMP_IF_FALSE
#define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE
@@ -180,127 +181,122 @@ extern "C" {
#define _LIST_EXTEND LIST_EXTEND
#define _LOAD_ATTR 410
#define _LOAD_ATTR_CLASS 411
-#define _LOAD_ATTR_CLASS_0 412
-#define _LOAD_ATTR_CLASS_1 413
#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
-#define _LOAD_ATTR_INSTANCE_VALUE 414
-#define _LOAD_ATTR_INSTANCE_VALUE_0 415
-#define _LOAD_ATTR_INSTANCE_VALUE_1 416
-#define _LOAD_ATTR_METHOD_LAZY_DICT 417
-#define _LOAD_ATTR_METHOD_NO_DICT 418
-#define _LOAD_ATTR_METHOD_WITH_VALUES 419
-#define _LOAD_ATTR_MODULE 420
-#define _LOAD_ATTR_MODULE_FROM_KEYS 421
-#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 422
-#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 423
-#define _LOAD_ATTR_PROPERTY_FRAME 424
-#define _LOAD_ATTR_SLOT 425
-#define _LOAD_ATTR_SLOT_0 426
-#define _LOAD_ATTR_SLOT_1 427
-#define _LOAD_ATTR_WITH_HINT 428
+#define _LOAD_ATTR_INSTANCE_VALUE 412
+#define _LOAD_ATTR_MODULE 413
+#define _LOAD_ATTR_MODULE_FROM_KEYS 414
+#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 415
+#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 416
+#define _LOAD_ATTR_PROPERTY_FRAME 417
+#define _LOAD_ATTR_SLOT 418
+#define _LOAD_ATTR_WITH_HINT 419
#define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS
-#define _LOAD_BYTECODE 429
+#define _LOAD_BYTECODE 420
#define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT
#define _LOAD_CONST LOAD_CONST
#define _LOAD_CONST_IMMORTAL LOAD_CONST_IMMORTAL
-#define _LOAD_CONST_INLINE 430
-#define _LOAD_CONST_INLINE_BORROW 431
-#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 432
-#define _LOAD_CONST_INLINE_WITH_NULL 433
+#define _LOAD_CONST_INLINE 421
+#define _LOAD_CONST_INLINE_BORROW 422
+#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 423
+#define _LOAD_CONST_INLINE_WITH_NULL 424
#define _LOAD_CONST_MORTAL LOAD_CONST_MORTAL
#define _LOAD_DEREF LOAD_DEREF
-#define _LOAD_FAST 434
-#define _LOAD_FAST_0 435
-#define _LOAD_FAST_1 436
-#define _LOAD_FAST_2 437
-#define _LOAD_FAST_3 438
-#define _LOAD_FAST_4 439
-#define _LOAD_FAST_5 440
-#define _LOAD_FAST_6 441
-#define _LOAD_FAST_7 442
+#define _LOAD_FAST 425
+#define _LOAD_FAST_0 426
+#define _LOAD_FAST_1 427
+#define _LOAD_FAST_2 428
+#define _LOAD_FAST_3 429
+#define _LOAD_FAST_4 430
+#define _LOAD_FAST_5 431
+#define _LOAD_FAST_6 432
+#define _LOAD_FAST_7 433
#define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR
#define _LOAD_FAST_CHECK LOAD_FAST_CHECK
#define _LOAD_FAST_LOAD_FAST LOAD_FAST_LOAD_FAST
#define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF
#define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS
-#define _LOAD_GLOBAL 443
-#define _LOAD_GLOBAL_BUILTINS 444
-#define _LOAD_GLOBAL_BUILTINS_FROM_KEYS 445
-#define _LOAD_GLOBAL_MODULE 446
-#define _LOAD_GLOBAL_MODULE_FROM_KEYS 447
+#define _LOAD_GLOBAL 434
+#define _LOAD_GLOBAL_BUILTINS 435
+#define _LOAD_GLOBAL_BUILTINS_FROM_KEYS 436
+#define _LOAD_GLOBAL_MODULE 437
+#define _LOAD_GLOBAL_MODULE_FROM_KEYS 438
#define _LOAD_LOCALS LOAD_LOCALS
+#define _LOAD_METHOD 439
+#define _LOAD_METHOD_LAZY_DICT 440
+#define _LOAD_METHOD_NO_DICT 441
+#define _LOAD_METHOD_WITH_VALUES 442
#define _LOAD_NAME LOAD_NAME
-#define _LOAD_SMALL_INT 448
-#define _LOAD_SMALL_INT_0 449
-#define _LOAD_SMALL_INT_1 450
-#define _LOAD_SMALL_INT_2 451
-#define _LOAD_SMALL_INT_3 452
+#define _LOAD_SMALL_INT 443
+#define _LOAD_SMALL_INT_0 444
+#define _LOAD_SMALL_INT_1 445
+#define _LOAD_SMALL_INT_2 446
+#define _LOAD_SMALL_INT_3 447
#define _LOAD_SPECIAL LOAD_SPECIAL
#define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR
-#define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD
-#define _MAKE_CALLARGS_A_TUPLE 453
+#define _LOAD_SUPER_METHOD_METHOD LOAD_SUPER_METHOD_METHOD
+#define _MAKE_CALLARGS_A_TUPLE 448
#define _MAKE_CELL MAKE_CELL
#define _MAKE_FUNCTION MAKE_FUNCTION
-#define _MAKE_WARM 454
+#define _MAKE_WARM 449
#define _MAP_ADD MAP_ADD
#define _MATCH_CLASS MATCH_CLASS
#define _MATCH_KEYS MATCH_KEYS
#define _MATCH_MAPPING MATCH_MAPPING
#define _MATCH_SEQUENCE MATCH_SEQUENCE
-#define _MAYBE_EXPAND_METHOD 455
-#define _MAYBE_EXPAND_METHOD_KW 456
-#define _MONITOR_CALL 457
-#define _MONITOR_JUMP_BACKWARD 458
-#define _MONITOR_RESUME 459
+#define _MAYBE_EXPAND_METHOD 450
+#define _MAYBE_EXPAND_METHOD_KW 451
+#define _MONITOR_CALL 452
+#define _MONITOR_JUMP_BACKWARD 453
+#define _MONITOR_RESUME 454
#define _NOP NOP
#define _POP_EXCEPT POP_EXCEPT
-#define _POP_JUMP_IF_FALSE 460
-#define _POP_JUMP_IF_TRUE 461
+#define _POP_JUMP_IF_FALSE 455
+#define _POP_JUMP_IF_TRUE 456
#define _POP_TOP POP_TOP
-#define _POP_TOP_LOAD_CONST_INLINE_BORROW 462
+#define _POP_TOP_LOAD_CONST_INLINE_BORROW 457
#define _PUSH_EXC_INFO PUSH_EXC_INFO
-#define _PUSH_FRAME 463
+#define _PUSH_FRAME 458
#define _PUSH_NULL PUSH_NULL
-#define _PY_FRAME_GENERAL 464
-#define _PY_FRAME_KW 465
-#define _QUICKEN_RESUME 466
-#define _REPLACE_WITH_TRUE 467
+#define _PY_FRAME_GENERAL 459
+#define _PY_FRAME_KW 460
+#define _QUICKEN_RESUME 461
+#define _REPLACE_WITH_TRUE 462
#define _RESUME_CHECK RESUME_CHECK
#define _RETURN_GENERATOR RETURN_GENERATOR
#define _RETURN_VALUE RETURN_VALUE
-#define _SAVE_RETURN_OFFSET 468
-#define _SEND 469
-#define _SEND_GEN_FRAME 470
+#define _SAVE_RETURN_OFFSET 463
+#define _SEND 464
+#define _SEND_GEN_FRAME 465
#define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS
#define _SET_ADD SET_ADD
#define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE
#define _SET_UPDATE SET_UPDATE
-#define _START_EXECUTOR 471
-#define _STORE_ATTR 472
-#define _STORE_ATTR_INSTANCE_VALUE 473
-#define _STORE_ATTR_SLOT 474
-#define _STORE_ATTR_WITH_HINT 475
+#define _START_EXECUTOR 466
+#define _STORE_ATTR 467
+#define _STORE_ATTR_INSTANCE_VALUE 468
+#define _STORE_ATTR_SLOT 469
+#define _STORE_ATTR_WITH_HINT 470
#define _STORE_DEREF STORE_DEREF
-#define _STORE_FAST 476
-#define _STORE_FAST_0 477
-#define _STORE_FAST_1 478
-#define _STORE_FAST_2 479
-#define _STORE_FAST_3 480
-#define _STORE_FAST_4 481
-#define _STORE_FAST_5 482
-#define _STORE_FAST_6 483
-#define _STORE_FAST_7 484
+#define _STORE_FAST 471
+#define _STORE_FAST_0 472
+#define _STORE_FAST_1 473
+#define _STORE_FAST_2 474
+#define _STORE_FAST_3 475
+#define _STORE_FAST_4 476
+#define _STORE_FAST_5 477
+#define _STORE_FAST_6 478
+#define _STORE_FAST_7 479
#define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST
#define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST
#define _STORE_GLOBAL STORE_GLOBAL
#define _STORE_NAME STORE_NAME
-#define _STORE_SLICE 485
-#define _STORE_SUBSCR 486
+#define _STORE_SLICE 480
+#define _STORE_SUBSCR 481
#define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT
#define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT
#define _SWAP SWAP
-#define _TIER2_RESUME_CHECK 487
-#define _TO_BOOL 488
+#define _TIER2_RESUME_CHECK 482
+#define _TO_BOOL 483
#define _TO_BOOL_BOOL TO_BOOL_BOOL
#define _TO_BOOL_INT TO_BOOL_INT
#define _TO_BOOL_LIST TO_BOOL_LIST
@@ -310,13 +306,13 @@ extern "C" {
#define _UNARY_NEGATIVE UNARY_NEGATIVE
#define _UNARY_NOT UNARY_NOT
#define _UNPACK_EX UNPACK_EX
-#define _UNPACK_SEQUENCE 489
+#define _UNPACK_SEQUENCE 484
#define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST
#define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE
#define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE
#define _WITH_EXCEPT_START WITH_EXCEPT_START
#define _YIELD_VALUE YIELD_VALUE
-#define MAX_UOP_ID 489
+#define MAX_UOP_ID 484
#ifdef __cplusplus
}
diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h
index 7b28667a26e94d..6cc825ed62ed95 100644
--- a/Include/internal/pycore_uop_metadata.h
+++ b/Include/internal/pycore_uop_metadata.h
@@ -127,8 +127,8 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_GUARD_GLOBALS_VERSION] = HAS_DEOPT_FLAG,
[_GUARD_GLOBALS_VERSION_PUSH_KEYS] = HAS_DEOPT_FLAG,
[_GUARD_BUILTINS_VERSION_PUSH_KEYS] = HAS_DEOPT_FLAG,
- [_LOAD_GLOBAL_MODULE_FROM_KEYS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
- [_LOAD_GLOBAL_BUILTINS_FROM_KEYS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_LOAD_GLOBAL_MODULE_FROM_KEYS] = HAS_DEOPT_FLAG,
+ [_LOAD_GLOBAL_BUILTINS_FROM_KEYS] = HAS_DEOPT_FLAG,
[_DELETE_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_MAKE_CELL] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_DELETE_DEREF] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
@@ -148,26 +148,21 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_DICT_MERGE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_MAP_ADD] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_LOAD_SUPER_ATTR_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
- [_LOAD_SUPER_ATTR_METHOD] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_SUPER_METHOD_METHOD] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_METHOD] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_LOAD_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_GUARD_TYPE_VERSION] = HAS_EXIT_FLAG,
[_GUARD_TYPE_VERSION_AND_LOCK] = HAS_EXIT_FLAG,
[_CHECK_MANAGED_OBJECT_HAS_VALUES] = HAS_DEOPT_FLAG,
- [_LOAD_ATTR_INSTANCE_VALUE_0] = HAS_DEOPT_FLAG,
- [_LOAD_ATTR_INSTANCE_VALUE_1] = HAS_DEOPT_FLAG,
- [_LOAD_ATTR_INSTANCE_VALUE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_OPARG_AND_1_FLAG,
+ [_LOAD_ATTR_INSTANCE_VALUE] = HAS_DEOPT_FLAG,
[_CHECK_ATTR_MODULE_PUSH_KEYS] = HAS_DEOPT_FLAG,
- [_LOAD_ATTR_MODULE_FROM_KEYS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_ATTR_MODULE_FROM_KEYS] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
[_CHECK_ATTR_WITH_HINT] = HAS_EXIT_FLAG,
[_LOAD_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG,
- [_LOAD_ATTR_SLOT_0] = HAS_DEOPT_FLAG,
- [_LOAD_ATTR_SLOT_1] = HAS_DEOPT_FLAG,
- [_LOAD_ATTR_SLOT] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_OPARG_AND_1_FLAG,
+ [_LOAD_ATTR_SLOT] = HAS_DEOPT_FLAG,
[_CHECK_ATTR_CLASS] = HAS_EXIT_FLAG,
- [_LOAD_ATTR_CLASS_0] = 0,
- [_LOAD_ATTR_CLASS_1] = 0,
- [_LOAD_ATTR_CLASS] = HAS_ARG_FLAG | HAS_OPARG_AND_1_FLAG,
- [_LOAD_ATTR_PROPERTY_FRAME] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_CLASS] = 0,
+ [_LOAD_ATTR_PROPERTY_FRAME] = HAS_DEOPT_FLAG,
[_GUARD_DORV_NO_DICT] = HAS_EXIT_FLAG,
[_STORE_ATTR_INSTANCE_VALUE] = HAS_ESCAPES_FLAG,
[_STORE_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
@@ -208,12 +203,12 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_PUSH_EXC_INFO] = 0,
[_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = HAS_DEOPT_FLAG,
[_GUARD_KEYS_VERSION] = HAS_DEOPT_FLAG,
- [_LOAD_ATTR_METHOD_WITH_VALUES] = HAS_ARG_FLAG,
- [_LOAD_ATTR_METHOD_NO_DICT] = HAS_ARG_FLAG,
- [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = HAS_ARG_FLAG,
- [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = HAS_ARG_FLAG,
+ [_LOAD_METHOD_WITH_VALUES] = 0,
+ [_LOAD_METHOD_NO_DICT] = 0,
+ [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = 0,
+ [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = 0,
[_CHECK_ATTR_METHOD_LAZY_DICT] = HAS_DEOPT_FLAG,
- [_LOAD_ATTR_METHOD_LAZY_DICT] = HAS_ARG_FLAG,
+ [_LOAD_METHOD_LAZY_DICT] = 0,
[_MAYBE_EXPAND_METHOD] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
[_PY_FRAME_GENERAL] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_CHECK_FUNCTION_VERSION] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
@@ -258,7 +253,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_EXPAND_METHOD_KW] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
[_CHECK_IS_NOT_PY_CALLABLE_KW] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
[_CALL_KW_NON_PY] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
- [_MAKE_CALLARGS_A_TUPLE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_MAKE_CALLARGS_A_TUPLE] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_MAKE_FUNCTION] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_SET_FUNCTION_ATTRIBUTE] = HAS_ARG_FLAG,
[_RETURN_GENERATOR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
@@ -285,9 +280,9 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_LOAD_CONST_INLINE_WITH_NULL] = HAS_PURE_FLAG,
[_LOAD_CONST_INLINE_BORROW_WITH_NULL] = HAS_PURE_FLAG,
[_CHECK_FUNCTION] = HAS_DEOPT_FLAG,
- [_LOAD_GLOBAL_MODULE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
- [_LOAD_GLOBAL_BUILTINS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
- [_LOAD_ATTR_MODULE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_LOAD_GLOBAL_MODULE] = HAS_DEOPT_FLAG,
+ [_LOAD_GLOBAL_BUILTINS] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_MODULE] = HAS_DEOPT_FLAG,
[_DYNAMIC_EXIT] = HAS_ESCAPES_FLAG,
[_START_EXECUTOR] = HAS_ESCAPES_FLAG,
[_MAKE_WARM] = 0,
@@ -457,22 +452,13 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_LIST_EXTEND] = "_LIST_EXTEND",
[_LOAD_ATTR] = "_LOAD_ATTR",
[_LOAD_ATTR_CLASS] = "_LOAD_ATTR_CLASS",
- [_LOAD_ATTR_CLASS_0] = "_LOAD_ATTR_CLASS_0",
- [_LOAD_ATTR_CLASS_1] = "_LOAD_ATTR_CLASS_1",
[_LOAD_ATTR_INSTANCE_VALUE] = "_LOAD_ATTR_INSTANCE_VALUE",
- [_LOAD_ATTR_INSTANCE_VALUE_0] = "_LOAD_ATTR_INSTANCE_VALUE_0",
- [_LOAD_ATTR_INSTANCE_VALUE_1] = "_LOAD_ATTR_INSTANCE_VALUE_1",
- [_LOAD_ATTR_METHOD_LAZY_DICT] = "_LOAD_ATTR_METHOD_LAZY_DICT",
- [_LOAD_ATTR_METHOD_NO_DICT] = "_LOAD_ATTR_METHOD_NO_DICT",
- [_LOAD_ATTR_METHOD_WITH_VALUES] = "_LOAD_ATTR_METHOD_WITH_VALUES",
[_LOAD_ATTR_MODULE] = "_LOAD_ATTR_MODULE",
[_LOAD_ATTR_MODULE_FROM_KEYS] = "_LOAD_ATTR_MODULE_FROM_KEYS",
[_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "_LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
[_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
[_LOAD_ATTR_PROPERTY_FRAME] = "_LOAD_ATTR_PROPERTY_FRAME",
[_LOAD_ATTR_SLOT] = "_LOAD_ATTR_SLOT",
- [_LOAD_ATTR_SLOT_0] = "_LOAD_ATTR_SLOT_0",
- [_LOAD_ATTR_SLOT_1] = "_LOAD_ATTR_SLOT_1",
[_LOAD_ATTR_WITH_HINT] = "_LOAD_ATTR_WITH_HINT",
[_LOAD_BUILD_CLASS] = "_LOAD_BUILD_CLASS",
[_LOAD_COMMON_CONSTANT] = "_LOAD_COMMON_CONSTANT",
@@ -502,6 +488,10 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_LOAD_GLOBAL_MODULE] = "_LOAD_GLOBAL_MODULE",
[_LOAD_GLOBAL_MODULE_FROM_KEYS] = "_LOAD_GLOBAL_MODULE_FROM_KEYS",
[_LOAD_LOCALS] = "_LOAD_LOCALS",
+ [_LOAD_METHOD] = "_LOAD_METHOD",
+ [_LOAD_METHOD_LAZY_DICT] = "_LOAD_METHOD_LAZY_DICT",
+ [_LOAD_METHOD_NO_DICT] = "_LOAD_METHOD_NO_DICT",
+ [_LOAD_METHOD_WITH_VALUES] = "_LOAD_METHOD_WITH_VALUES",
[_LOAD_NAME] = "_LOAD_NAME",
[_LOAD_SMALL_INT] = "_LOAD_SMALL_INT",
[_LOAD_SMALL_INT_0] = "_LOAD_SMALL_INT_0",
@@ -510,7 +500,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_LOAD_SMALL_INT_3] = "_LOAD_SMALL_INT_3",
[_LOAD_SPECIAL] = "_LOAD_SPECIAL",
[_LOAD_SUPER_ATTR_ATTR] = "_LOAD_SUPER_ATTR_ATTR",
- [_LOAD_SUPER_ATTR_METHOD] = "_LOAD_SUPER_ATTR_METHOD",
+ [_LOAD_SUPER_METHOD_METHOD] = "_LOAD_SUPER_METHOD_METHOD",
[_MAKE_CALLARGS_A_TUPLE] = "_MAKE_CALLARGS_A_TUPLE",
[_MAKE_CELL] = "_MAKE_CELL",
[_MAKE_FUNCTION] = "_MAKE_FUNCTION",
@@ -845,8 +835,10 @@ int _PyUop_num_popped(int opcode, int oparg)
return 2;
case _LOAD_SUPER_ATTR_ATTR:
return 3;
- case _LOAD_SUPER_ATTR_METHOD:
+ case _LOAD_SUPER_METHOD_METHOD:
return 3;
+ case _LOAD_METHOD:
+ return 1;
case _LOAD_ATTR:
return 1;
case _GUARD_TYPE_VERSION:
@@ -855,10 +847,6 @@ int _PyUop_num_popped(int opcode, int oparg)
return 0;
case _CHECK_MANAGED_OBJECT_HAS_VALUES:
return 0;
- case _LOAD_ATTR_INSTANCE_VALUE_0:
- return 1;
- case _LOAD_ATTR_INSTANCE_VALUE_1:
- return 1;
case _LOAD_ATTR_INSTANCE_VALUE:
return 1;
case _CHECK_ATTR_MODULE_PUSH_KEYS:
@@ -869,18 +857,10 @@ int _PyUop_num_popped(int opcode, int oparg)
return 0;
case _LOAD_ATTR_WITH_HINT:
return 2;
- case _LOAD_ATTR_SLOT_0:
- return 1;
- case _LOAD_ATTR_SLOT_1:
- return 1;
case _LOAD_ATTR_SLOT:
return 1;
case _CHECK_ATTR_CLASS:
return 0;
- case _LOAD_ATTR_CLASS_0:
- return 1;
- case _LOAD_ATTR_CLASS_1:
- return 1;
case _LOAD_ATTR_CLASS:
return 1;
case _LOAD_ATTR_PROPERTY_FRAME:
@@ -965,9 +945,9 @@ int _PyUop_num_popped(int opcode, int oparg)
return 0;
case _GUARD_KEYS_VERSION:
return 0;
- case _LOAD_ATTR_METHOD_WITH_VALUES:
+ case _LOAD_METHOD_WITH_VALUES:
return 1;
- case _LOAD_ATTR_METHOD_NO_DICT:
+ case _LOAD_METHOD_NO_DICT:
return 1;
case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
return 1;
@@ -975,7 +955,7 @@ int _PyUop_num_popped(int opcode, int oparg)
return 1;
case _CHECK_ATTR_METHOD_LAZY_DICT:
return 0;
- case _LOAD_ATTR_METHOD_LAZY_DICT:
+ case _LOAD_METHOD_LAZY_DICT:
return 1;
case _MAYBE_EXPAND_METHOD:
return 2 + oparg;
@@ -1066,7 +1046,7 @@ int _PyUop_num_popped(int opcode, int oparg)
case _CALL_KW_NON_PY:
return 3 + oparg;
case _MAKE_CALLARGS_A_TUPLE:
- return 1 + (oparg & 1);
+ return 2;
case _MAKE_FUNCTION:
return 1;
case _SET_FUNCTION_ATTRIBUTE:
@@ -1074,7 +1054,7 @@ int _PyUop_num_popped(int opcode, int oparg)
case _RETURN_GENERATOR:
return 0;
case _BUILD_SLICE:
- return 2 + ((oparg == 3) ? 1 : 0);
+ return oparg;
case _CONVERT_VALUE:
return 1;
case _FORMAT_SIMPLE:
diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h
index 06b207b347e504..e931e76bdb193a 100644
--- a/Include/opcode_ids.h
+++ b/Include/opcode_ids.h
@@ -14,55 +14,55 @@ extern "C" {
#define BINARY_SLICE 1
#define BINARY_SUBSCR 2
#define BINARY_OP_INPLACE_ADD_UNICODE 3
-#define CHECK_EG_MATCH 4
-#define CHECK_EXC_MATCH 5
-#define CLEANUP_THROW 6
-#define DELETE_SUBSCR 7
-#define END_ASYNC_FOR 8
-#define END_FOR 9
-#define END_SEND 10
-#define EXIT_INIT_CHECK 11
-#define FORMAT_SIMPLE 12
-#define FORMAT_WITH_SPEC 13
-#define GET_AITER 14
-#define GET_ANEXT 15
-#define GET_ITER 16
+#define CALL_FUNCTION_EX 4
+#define CHECK_EG_MATCH 5
+#define CHECK_EXC_MATCH 6
+#define CLEANUP_THROW 7
+#define DELETE_SUBSCR 8
+#define END_ASYNC_FOR 9
+#define END_FOR 10
+#define END_SEND 11
+#define EXIT_INIT_CHECK 12
+#define FORMAT_SIMPLE 13
+#define FORMAT_WITH_SPEC 14
+#define GET_AITER 15
+#define GET_ANEXT 16
#define RESERVED 17
-#define GET_LEN 18
-#define GET_YIELD_FROM_ITER 19
-#define INTERPRETER_EXIT 20
-#define LOAD_BUILD_CLASS 21
-#define LOAD_LOCALS 22
-#define MAKE_FUNCTION 23
-#define MATCH_KEYS 24
-#define MATCH_MAPPING 25
-#define MATCH_SEQUENCE 26
-#define NOP 27
-#define NOT_TAKEN 28
-#define POP_EXCEPT 29
-#define POP_ITER 30
-#define POP_TOP 31
-#define PUSH_EXC_INFO 32
-#define PUSH_NULL 33
-#define RETURN_GENERATOR 34
-#define RETURN_VALUE 35
-#define SETUP_ANNOTATIONS 36
-#define STORE_SLICE 37
-#define STORE_SUBSCR 38
-#define TO_BOOL 39
-#define UNARY_INVERT 40
-#define UNARY_NEGATIVE 41
-#define UNARY_NOT 42
-#define WITH_EXCEPT_START 43
-#define BINARY_OP 44
-#define BUILD_LIST 45
-#define BUILD_MAP 46
-#define BUILD_SET 47
-#define BUILD_SLICE 48
-#define BUILD_STRING 49
-#define BUILD_TUPLE 50
-#define CALL 51
-#define CALL_FUNCTION_EX 52
+#define GET_ITER 18
+#define GET_LEN 19
+#define GET_YIELD_FROM_ITER 20
+#define INTERPRETER_EXIT 21
+#define LOAD_BUILD_CLASS 22
+#define LOAD_LOCALS 23
+#define MAKE_FUNCTION 24
+#define MATCH_KEYS 25
+#define MATCH_MAPPING 26
+#define MATCH_SEQUENCE 27
+#define NOP 28
+#define NOT_TAKEN 29
+#define POP_EXCEPT 30
+#define POP_ITER 31
+#define POP_TOP 32
+#define PUSH_EXC_INFO 33
+#define PUSH_NULL 34
+#define RETURN_GENERATOR 35
+#define RETURN_VALUE 36
+#define SETUP_ANNOTATIONS 37
+#define STORE_SLICE 38
+#define STORE_SUBSCR 39
+#define TO_BOOL 40
+#define UNARY_INVERT 41
+#define UNARY_NEGATIVE 42
+#define UNARY_NOT 43
+#define WITH_EXCEPT_START 44
+#define BINARY_OP 45
+#define BUILD_LIST 46
+#define BUILD_MAP 47
+#define BUILD_SET 48
+#define BUILD_SLICE 49
+#define BUILD_STRING 50
+#define BUILD_TUPLE 51
+#define CALL 52
#define CALL_INTRINSIC_1 53
#define CALL_INTRINSIC_2 54
#define CALL_KW 55
@@ -100,34 +100,36 @@ extern "C" {
#define LOAD_FROM_DICT_OR_DEREF 87
#define LOAD_FROM_DICT_OR_GLOBALS 88
#define LOAD_GLOBAL 89
-#define LOAD_NAME 90
-#define LOAD_SMALL_INT 91
-#define LOAD_SPECIAL 92
-#define LOAD_SUPER_ATTR 93
-#define MAKE_CELL 94
-#define MAP_ADD 95
-#define MATCH_CLASS 96
-#define POP_JUMP_IF_FALSE 97
-#define POP_JUMP_IF_NONE 98
-#define POP_JUMP_IF_NOT_NONE 99
-#define POP_JUMP_IF_TRUE 100
-#define RAISE_VARARGS 101
-#define RERAISE 102
-#define SEND 103
-#define SET_ADD 104
-#define SET_FUNCTION_ATTRIBUTE 105
-#define SET_UPDATE 106
-#define STORE_ATTR 107
-#define STORE_DEREF 108
-#define STORE_FAST 109
-#define STORE_FAST_LOAD_FAST 110
-#define STORE_FAST_STORE_FAST 111
-#define STORE_GLOBAL 112
-#define STORE_NAME 113
-#define SWAP 114
-#define UNPACK_EX 115
-#define UNPACK_SEQUENCE 116
-#define YIELD_VALUE 117
+#define LOAD_METHOD 90
+#define LOAD_NAME 91
+#define LOAD_SMALL_INT 92
+#define LOAD_SPECIAL 93
+#define LOAD_SUPER_ATTR 94
+#define LOAD_SUPER_METHOD 95
+#define MAKE_CELL 96
+#define MAP_ADD 97
+#define MATCH_CLASS 98
+#define POP_JUMP_IF_FALSE 99
+#define POP_JUMP_IF_NONE 100
+#define POP_JUMP_IF_NOT_NONE 101
+#define POP_JUMP_IF_TRUE 102
+#define RAISE_VARARGS 103
+#define RERAISE 104
+#define SEND 105
+#define SET_ADD 106
+#define SET_FUNCTION_ATTRIBUTE 107
+#define SET_UPDATE 108
+#define STORE_ATTR 109
+#define STORE_DEREF 110
+#define STORE_FAST 111
+#define STORE_FAST_LOAD_FAST 112
+#define STORE_FAST_STORE_FAST 113
+#define STORE_GLOBAL 114
+#define STORE_NAME 115
+#define SWAP 116
+#define UNPACK_EX 117
+#define UNPACK_SEQUENCE 118
+#define YIELD_VALUE 119
#define RESUME 149
#define BINARY_OP_ADD_FLOAT 150
#define BINARY_OP_ADD_INT 151
@@ -178,21 +180,21 @@ extern "C" {
#define LOAD_ATTR_CLASS_WITH_METACLASS_CHECK 196
#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 197
#define LOAD_ATTR_INSTANCE_VALUE 198
-#define LOAD_ATTR_METHOD_LAZY_DICT 199
-#define LOAD_ATTR_METHOD_NO_DICT 200
-#define LOAD_ATTR_METHOD_WITH_VALUES 201
-#define LOAD_ATTR_MODULE 202
-#define LOAD_ATTR_NONDESCRIPTOR_NO_DICT 203
-#define LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 204
-#define LOAD_ATTR_PROPERTY 205
-#define LOAD_ATTR_SLOT 206
-#define LOAD_ATTR_WITH_HINT 207
-#define LOAD_CONST_IMMORTAL 208
-#define LOAD_CONST_MORTAL 209
-#define LOAD_GLOBAL_BUILTIN 210
-#define LOAD_GLOBAL_MODULE 211
+#define LOAD_ATTR_MODULE 199
+#define LOAD_ATTR_NONDESCRIPTOR_NO_DICT 200
+#define LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 201
+#define LOAD_ATTR_PROPERTY 202
+#define LOAD_ATTR_SLOT 203
+#define LOAD_ATTR_WITH_HINT 204
+#define LOAD_CONST_IMMORTAL 205
+#define LOAD_CONST_MORTAL 206
+#define LOAD_GLOBAL_BUILTIN 207
+#define LOAD_GLOBAL_MODULE 208
+#define LOAD_METHOD_LAZY_DICT 209
+#define LOAD_METHOD_NO_DICT 210
+#define LOAD_METHOD_WITH_VALUES 211
#define LOAD_SUPER_ATTR_ATTR 212
-#define LOAD_SUPER_ATTR_METHOD 213
+#define LOAD_SUPER_METHOD_METHOD 213
#define RESUME_CHECK 214
#define SEND_GEN 215
#define STORE_ATTR_INSTANCE_VALUE 216
@@ -209,10 +211,11 @@ extern "C" {
#define UNPACK_SEQUENCE_LIST 227
#define UNPACK_SEQUENCE_TUPLE 228
#define UNPACK_SEQUENCE_TWO_TUPLE 229
-#define INSTRUMENTED_END_FOR 235
-#define INSTRUMENTED_POP_ITER 236
-#define INSTRUMENTED_END_SEND 237
-#define INSTRUMENTED_LOAD_SUPER_ATTR 238
+#define INSTRUMENTED_END_FOR 234
+#define INSTRUMENTED_POP_ITER 235
+#define INSTRUMENTED_END_SEND 236
+#define INSTRUMENTED_LOAD_SUPER_ATTR 237
+#define INSTRUMENTED_LOAD_SUPER_METHOD 238
#define INSTRUMENTED_FOR_ITER 239
#define INSTRUMENTED_CALL_KW 240
#define INSTRUMENTED_CALL_FUNCTION_EX 241
@@ -241,9 +244,9 @@ extern "C" {
#define SETUP_WITH 264
#define STORE_FAST_MAYBE_NULL 265
-#define HAVE_ARGUMENT 43
+#define HAVE_ARGUMENT 44
#define MIN_SPECIALIZED_OPCODE 150
-#define MIN_INSTRUMENTED_OPCODE 235
+#define MIN_INSTRUMENTED_OPCODE 234
#ifdef __cplusplus
}
diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py
index 7dd528ef74df33..a32e6fe953b782 100644
--- a/Lib/_opcode_metadata.py
+++ b/Lib/_opcode_metadata.py
@@ -59,7 +59,9 @@
],
"LOAD_SUPER_ATTR": [
"LOAD_SUPER_ATTR_ATTR",
- "LOAD_SUPER_ATTR_METHOD",
+ ],
+ "LOAD_SUPER_METHOD": [
+ "LOAD_SUPER_METHOD_METHOD",
],
"LOAD_ATTR": [
"LOAD_ATTR_INSTANCE_VALUE",
@@ -70,12 +72,14 @@
"LOAD_ATTR_CLASS_WITH_METACLASS_CHECK",
"LOAD_ATTR_PROPERTY",
"LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN",
- "LOAD_ATTR_METHOD_WITH_VALUES",
- "LOAD_ATTR_METHOD_NO_DICT",
- "LOAD_ATTR_METHOD_LAZY_DICT",
"LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
"LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
],
+ "LOAD_METHOD": [
+ "LOAD_METHOD_WITH_VALUES",
+ "LOAD_METHOD_NO_DICT",
+ "LOAD_METHOD_LAZY_DICT",
+ ],
"COMPARE_OP": [
"COMPARE_OP_FLOAT",
"COMPARE_OP_INT",
@@ -171,21 +175,21 @@
'LOAD_ATTR_CLASS_WITH_METACLASS_CHECK': 196,
'LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN': 197,
'LOAD_ATTR_INSTANCE_VALUE': 198,
- 'LOAD_ATTR_METHOD_LAZY_DICT': 199,
- 'LOAD_ATTR_METHOD_NO_DICT': 200,
- 'LOAD_ATTR_METHOD_WITH_VALUES': 201,
- 'LOAD_ATTR_MODULE': 202,
- 'LOAD_ATTR_NONDESCRIPTOR_NO_DICT': 203,
- 'LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES': 204,
- 'LOAD_ATTR_PROPERTY': 205,
- 'LOAD_ATTR_SLOT': 206,
- 'LOAD_ATTR_WITH_HINT': 207,
- 'LOAD_CONST_IMMORTAL': 208,
- 'LOAD_CONST_MORTAL': 209,
- 'LOAD_GLOBAL_BUILTIN': 210,
- 'LOAD_GLOBAL_MODULE': 211,
+ 'LOAD_ATTR_MODULE': 199,
+ 'LOAD_ATTR_NONDESCRIPTOR_NO_DICT': 200,
+ 'LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES': 201,
+ 'LOAD_ATTR_PROPERTY': 202,
+ 'LOAD_ATTR_SLOT': 203,
+ 'LOAD_ATTR_WITH_HINT': 204,
+ 'LOAD_CONST_IMMORTAL': 205,
+ 'LOAD_CONST_MORTAL': 206,
+ 'LOAD_GLOBAL_BUILTIN': 207,
+ 'LOAD_GLOBAL_MODULE': 208,
+ 'LOAD_METHOD_LAZY_DICT': 209,
+ 'LOAD_METHOD_NO_DICT': 210,
+ 'LOAD_METHOD_WITH_VALUES': 211,
'LOAD_SUPER_ATTR_ATTR': 212,
- 'LOAD_SUPER_ATTR_METHOD': 213,
+ 'LOAD_SUPER_METHOD_METHOD': 213,
'RESUME_CHECK': 214,
'SEND_GEN': 215,
'STORE_ATTR_INSTANCE_VALUE': 216,
@@ -212,54 +216,54 @@
'ENTER_EXECUTOR': 255,
'BINARY_SLICE': 1,
'BINARY_SUBSCR': 2,
- 'CHECK_EG_MATCH': 4,
- 'CHECK_EXC_MATCH': 5,
- 'CLEANUP_THROW': 6,
- 'DELETE_SUBSCR': 7,
- 'END_ASYNC_FOR': 8,
- 'END_FOR': 9,
- 'END_SEND': 10,
- 'EXIT_INIT_CHECK': 11,
- 'FORMAT_SIMPLE': 12,
- 'FORMAT_WITH_SPEC': 13,
- 'GET_AITER': 14,
- 'GET_ANEXT': 15,
- 'GET_ITER': 16,
- 'GET_LEN': 18,
- 'GET_YIELD_FROM_ITER': 19,
- 'INTERPRETER_EXIT': 20,
- 'LOAD_BUILD_CLASS': 21,
- 'LOAD_LOCALS': 22,
- 'MAKE_FUNCTION': 23,
- 'MATCH_KEYS': 24,
- 'MATCH_MAPPING': 25,
- 'MATCH_SEQUENCE': 26,
- 'NOP': 27,
- 'NOT_TAKEN': 28,
- 'POP_EXCEPT': 29,
- 'POP_ITER': 30,
- 'POP_TOP': 31,
- 'PUSH_EXC_INFO': 32,
- 'PUSH_NULL': 33,
- 'RETURN_GENERATOR': 34,
- 'RETURN_VALUE': 35,
- 'SETUP_ANNOTATIONS': 36,
- 'STORE_SLICE': 37,
- 'STORE_SUBSCR': 38,
- 'TO_BOOL': 39,
- 'UNARY_INVERT': 40,
- 'UNARY_NEGATIVE': 41,
- 'UNARY_NOT': 42,
- 'WITH_EXCEPT_START': 43,
- 'BINARY_OP': 44,
- 'BUILD_LIST': 45,
- 'BUILD_MAP': 46,
- 'BUILD_SET': 47,
- 'BUILD_SLICE': 48,
- 'BUILD_STRING': 49,
- 'BUILD_TUPLE': 50,
- 'CALL': 51,
- 'CALL_FUNCTION_EX': 52,
+ 'CALL_FUNCTION_EX': 4,
+ 'CHECK_EG_MATCH': 5,
+ 'CHECK_EXC_MATCH': 6,
+ 'CLEANUP_THROW': 7,
+ 'DELETE_SUBSCR': 8,
+ 'END_ASYNC_FOR': 9,
+ 'END_FOR': 10,
+ 'END_SEND': 11,
+ 'EXIT_INIT_CHECK': 12,
+ 'FORMAT_SIMPLE': 13,
+ 'FORMAT_WITH_SPEC': 14,
+ 'GET_AITER': 15,
+ 'GET_ANEXT': 16,
+ 'GET_ITER': 18,
+ 'GET_LEN': 19,
+ 'GET_YIELD_FROM_ITER': 20,
+ 'INTERPRETER_EXIT': 21,
+ 'LOAD_BUILD_CLASS': 22,
+ 'LOAD_LOCALS': 23,
+ 'MAKE_FUNCTION': 24,
+ 'MATCH_KEYS': 25,
+ 'MATCH_MAPPING': 26,
+ 'MATCH_SEQUENCE': 27,
+ 'NOP': 28,
+ 'NOT_TAKEN': 29,
+ 'POP_EXCEPT': 30,
+ 'POP_ITER': 31,
+ 'POP_TOP': 32,
+ 'PUSH_EXC_INFO': 33,
+ 'PUSH_NULL': 34,
+ 'RETURN_GENERATOR': 35,
+ 'RETURN_VALUE': 36,
+ 'SETUP_ANNOTATIONS': 37,
+ 'STORE_SLICE': 38,
+ 'STORE_SUBSCR': 39,
+ 'TO_BOOL': 40,
+ 'UNARY_INVERT': 41,
+ 'UNARY_NEGATIVE': 42,
+ 'UNARY_NOT': 43,
+ 'WITH_EXCEPT_START': 44,
+ 'BINARY_OP': 45,
+ 'BUILD_LIST': 46,
+ 'BUILD_MAP': 47,
+ 'BUILD_SET': 48,
+ 'BUILD_SLICE': 49,
+ 'BUILD_STRING': 50,
+ 'BUILD_TUPLE': 51,
+ 'CALL': 52,
'CALL_INTRINSIC_1': 53,
'CALL_INTRINSIC_2': 54,
'CALL_KW': 55,
@@ -297,38 +301,41 @@
'LOAD_FROM_DICT_OR_DEREF': 87,
'LOAD_FROM_DICT_OR_GLOBALS': 88,
'LOAD_GLOBAL': 89,
- 'LOAD_NAME': 90,
- 'LOAD_SMALL_INT': 91,
- 'LOAD_SPECIAL': 92,
- 'LOAD_SUPER_ATTR': 93,
- 'MAKE_CELL': 94,
- 'MAP_ADD': 95,
- 'MATCH_CLASS': 96,
- 'POP_JUMP_IF_FALSE': 97,
- 'POP_JUMP_IF_NONE': 98,
- 'POP_JUMP_IF_NOT_NONE': 99,
- 'POP_JUMP_IF_TRUE': 100,
- 'RAISE_VARARGS': 101,
- 'RERAISE': 102,
- 'SEND': 103,
- 'SET_ADD': 104,
- 'SET_FUNCTION_ATTRIBUTE': 105,
- 'SET_UPDATE': 106,
- 'STORE_ATTR': 107,
- 'STORE_DEREF': 108,
- 'STORE_FAST': 109,
- 'STORE_FAST_LOAD_FAST': 110,
- 'STORE_FAST_STORE_FAST': 111,
- 'STORE_GLOBAL': 112,
- 'STORE_NAME': 113,
- 'SWAP': 114,
- 'UNPACK_EX': 115,
- 'UNPACK_SEQUENCE': 116,
- 'YIELD_VALUE': 117,
- 'INSTRUMENTED_END_FOR': 235,
- 'INSTRUMENTED_POP_ITER': 236,
- 'INSTRUMENTED_END_SEND': 237,
- 'INSTRUMENTED_LOAD_SUPER_ATTR': 238,
+ 'LOAD_METHOD': 90,
+ 'LOAD_NAME': 91,
+ 'LOAD_SMALL_INT': 92,
+ 'LOAD_SPECIAL': 93,
+ 'LOAD_SUPER_ATTR': 94,
+ 'LOAD_SUPER_METHOD': 95,
+ 'MAKE_CELL': 96,
+ 'MAP_ADD': 97,
+ 'MATCH_CLASS': 98,
+ 'POP_JUMP_IF_FALSE': 99,
+ 'POP_JUMP_IF_NONE': 100,
+ 'POP_JUMP_IF_NOT_NONE': 101,
+ 'POP_JUMP_IF_TRUE': 102,
+ 'RAISE_VARARGS': 103,
+ 'RERAISE': 104,
+ 'SEND': 105,
+ 'SET_ADD': 106,
+ 'SET_FUNCTION_ATTRIBUTE': 107,
+ 'SET_UPDATE': 108,
+ 'STORE_ATTR': 109,
+ 'STORE_DEREF': 110,
+ 'STORE_FAST': 111,
+ 'STORE_FAST_LOAD_FAST': 112,
+ 'STORE_FAST_STORE_FAST': 113,
+ 'STORE_GLOBAL': 114,
+ 'STORE_NAME': 115,
+ 'SWAP': 116,
+ 'UNPACK_EX': 117,
+ 'UNPACK_SEQUENCE': 118,
+ 'YIELD_VALUE': 119,
+ 'INSTRUMENTED_END_FOR': 234,
+ 'INSTRUMENTED_POP_ITER': 235,
+ 'INSTRUMENTED_END_SEND': 236,
+ 'INSTRUMENTED_LOAD_SUPER_ATTR': 237,
+ 'INSTRUMENTED_LOAD_SUPER_METHOD': 238,
'INSTRUMENTED_FOR_ITER': 239,
'INSTRUMENTED_CALL_KW': 240,
'INSTRUMENTED_CALL_FUNCTION_EX': 241,
@@ -356,5 +363,5 @@
'STORE_FAST_MAYBE_NULL': 265,
}
-HAVE_ARGUMENT = 43
-MIN_INSTRUMENTED_OPCODE = 235
+HAVE_ARGUMENT = 44
+MIN_INSTRUMENTED_OPCODE = 234
diff --git a/Lib/dis.py b/Lib/dis.py
index 109c986bbe3d7d..5a34e228079481 100644
--- a/Lib/dis.py
+++ b/Lib/dis.py
@@ -42,7 +42,9 @@
FOR_ITER = opmap['FOR_ITER']
SEND = opmap['SEND']
LOAD_ATTR = opmap['LOAD_ATTR']
+LOAD_METHOD = opmap['LOAD_METHOD']
LOAD_SUPER_ATTR = opmap['LOAD_SUPER_ATTR']
+LOAD_SUPER_METHOD = opmap['LOAD_SUPER_METHOD']
CALL_INTRINSIC_1 = opmap['CALL_INTRINSIC_1']
CALL_INTRINSIC_2 = opmap['CALL_INTRINSIC_2']
LOAD_COMMON_CONSTANT = opmap['LOAD_COMMON_CONSTANT']
@@ -580,16 +582,14 @@ def get_argval_argrepr(self, op, arg, offset):
argval, argrepr = _get_const_info(deop, arg, self.co_consts)
elif deop in hasname:
if deop == LOAD_GLOBAL:
- argval, argrepr = _get_name_info(arg//2, get_name)
- if (arg & 1) and argrepr:
- argrepr = f"{argrepr} + NULL"
- elif deop == LOAD_ATTR:
- argval, argrepr = _get_name_info(arg//2, get_name)
- if (arg & 1) and argrepr:
+ argval, argrepr = _get_name_info(arg, get_name)
+ elif deop == LOAD_ATTR or deop == LOAD_METHOD:
+ argval, argrepr = _get_name_info(arg, get_name)
+ if deop == LOAD_METHOD and argrepr:
argrepr = f"{argrepr} + NULL|self"
- elif deop == LOAD_SUPER_ATTR:
+ elif deop == LOAD_SUPER_ATTR or deop == LOAD_SUPER_METHOD:
argval, argrepr = _get_name_info(arg//4, get_name)
- if (arg & 1) and argrepr:
+ if deop == LOAD_SUPER_METHOD and argrepr:
argrepr = f"{argrepr} + NULL|self"
else:
argval, argrepr = _get_name_info(arg, get_name)
diff --git a/Lib/inspect.py b/Lib/inspect.py
index facad478103668..3d9ff07a3cfb7b 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -1511,7 +1511,7 @@ def getclosurevars(func):
for instruction in dis.get_instructions(code):
opname = instruction.opname
name = instruction.argval
- if opname == "LOAD_ATTR":
+ if opname == "LOAD_ATTR" or opname == "LOAD_METHOD":
unbound_names.add(name)
elif opname == "LOAD_GLOBAL":
global_names.add(name)
diff --git a/Lib/opcode.py b/Lib/opcode.py
index 4ee0d64026bd0a..d87149e95b5a33 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -72,12 +72,21 @@
"LOAD_SUPER_ATTR": {
"counter": 1,
},
+ "LOAD_SUPER_METHOD": {
+ "counter": 1,
+ },
"LOAD_ATTR": {
"counter": 1,
"version": 2,
"keys_version": 2,
"descr": 4,
},
+ "LOAD_METHOD": {
+ "counter": 1,
+ "version": 2,
+ "keys_version": 2,
+ "descr": 4,
+ },
"STORE_ATTR": {
"counter": 1,
"version": 2,
diff --git a/Lib/test/test__opcode.py b/Lib/test/test__opcode.py
index 95e09500df51d0..4b11e83ae59a78 100644
--- a/Lib/test/test__opcode.py
+++ b/Lib/test/test__opcode.py
@@ -65,8 +65,7 @@ def check_function(self, func, expected):
class StackEffectTests(unittest.TestCase):
def test_stack_effect(self):
self.assertEqual(stack_effect(dis.opmap['POP_TOP']), -1)
- self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 0), -1)
- self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 1), -1)
+ self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 2), -1)
self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 3), -2)
self.assertRaises(ValueError, stack_effect, 30000)
# All defined opcodes
diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py
index 9cfc6c142da6cd..6a2f7726222f9b 100644
--- a/Lib/test/test_capi/test_opt.py
+++ b/Lib/test/test_capi/test_opt.py
@@ -711,7 +711,7 @@ def testfunc(n):
assert ex is not None
uops = get_opnames(ex)
assert "_LOAD_GLOBAL_BUILTINS" not in uops
- assert "_LOAD_CONST_INLINE_BORROW_WITH_NULL" in uops
+ assert "_LOAD_CONST_INLINE_BORROW" in uops
"""))
self.assertEqual(result[0].rc, 0, result)
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index b5cf2ad18fe60b..f4123d2a85f52b 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -2157,7 +2157,7 @@ def test_method_call(self):
source = "(\n lhs \n . \n rhs \n )()"
code = compile(source, "<test>", "exec")
self.assertOpcodeSourcePositionIs(
- code, "LOAD_ATTR", line=4, end_line=4, column=5, end_column=8
+ code, "LOAD_METHOD", line=4, end_line=4, column=5, end_column=8
)
self.assertOpcodeSourcePositionIs(
code, "CALL", line=4, end_line=5, column=5, end_column=10
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index da57aad2f84fbd..6fdcdbb0d9a3ad 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -113,7 +113,8 @@ def _f(a):
dis_f = """\
%3d RESUME 0
-%3d LOAD_GLOBAL 1 (print + NULL)
+%3d LOAD_GLOBAL 0 (print)
+ PUSH_NULL
LOAD_FAST 0 (a)
CALL 1
POP_TOP
@@ -127,13 +128,14 @@ def _f(a):
dis_f_with_offsets = """\
%3d 0 RESUME 0
-%3d 2 LOAD_GLOBAL 1 (print + NULL)
- 12 LOAD_FAST 0 (a)
- 14 CALL 1
- 22 POP_TOP
+%3d 2 LOAD_GLOBAL 0 (print)
+ 12 PUSH_NULL
+ 14 LOAD_FAST 0 (a)
+ 16 CALL 1
+ 24 POP_TOP
-%3d 24 LOAD_SMALL_INT 1
- 26 RETURN_VALUE
+%3d 26 LOAD_SMALL_INT 1
+ 28 RETURN_VALUE
""" % (_f.__code__.co_firstlineno,
_f.__code__.co_firstlineno + 1,
_f.__code__.co_firstlineno + 2)
@@ -141,7 +143,8 @@ def _f(a):
dis_f_with_positions_format = f"""\
%-14s RESUME 0
-%-14s LOAD_GLOBAL 1 (print + NULL)
+%-14s LOAD_GLOBAL 0 (print)
+%-14s PUSH_NULL
%-14s LOAD_FAST 0 (a)
%-14s CALL 1
%-14s POP_TOP
@@ -152,7 +155,8 @@ def _f(a):
dis_f_co_code = """\
RESUME 0
- LOAD_GLOBAL 1
+ LOAD_GLOBAL 0
+ PUSH_NULL
LOAD_FAST 0
CALL 1
POP_TOP
@@ -168,7 +172,8 @@ def bug708901():
dis_bug708901 = """\
%3d RESUME 0
-%3d LOAD_GLOBAL 1 (range + NULL)
+%3d LOAD_GLOBAL 0 (range)
+ PUSH_NULL
LOAD_SMALL_INT 1
%3d LOAD_SMALL_INT 10
@@ -276,7 +281,8 @@ def wrap_func_w_kwargs():
dis_kw_names = """\
%3d RESUME 0
-%3d LOAD_GLOBAL 1 (func_w_kwargs + NULL)
+%3d LOAD_GLOBAL 0 (func_w_kwargs)
+ PUSH_NULL
LOAD_SMALL_INT 1
LOAD_SMALL_INT 2
LOAD_SMALL_INT 5
@@ -463,7 +469,7 @@ def foo(a: int, b: str) -> str:
STORE_FAST 0 (e)
%4d L4: LOAD_FAST 0 (e)
- LOAD_ATTR 2 (__traceback__)
+ LOAD_ATTR 1 (__traceback__)
STORE_FAST 1 (tb)
L5: POP_EXCEPT
LOAD_CONST 0 (None)
@@ -814,7 +820,8 @@ def foo(x):
%4d RESUME 0
-%4d LOAD_GLOBAL 1 (list + NULL)
+%4d LOAD_GLOBAL 0 (list)
+ PUSH_NULL
LOAD_FAST 0 (x)
BUILD_TUPLE 1
LOAD_CONST 1 (<code object <genexpr> at 0x..., file "%s", line %d>)
@@ -897,14 +904,15 @@ def loop_test():
LOAD_SMALL_INT 3
BINARY_OP 5 (*)
GET_ITER
- L1: FOR_ITER_LIST 14 (to L2)
+ L1: FOR_ITER_LIST 15 (to L2)
STORE_FAST 0 (i)
-%3d LOAD_GLOBAL_MODULE 1 (load_test + NULL)
+%3d LOAD_GLOBAL_MODULE 0 (load_test)
+ PUSH_NULL
LOAD_FAST 0 (i)
CALL_PY_GENERAL 1
POP_TOP
- JUMP_BACKWARD 16 (to L1)
+ JUMP_BACKWARD 17 (to L1)
%3d L2: END_FOR
POP_ITER
@@ -1705,203 +1713,215 @@ def _prepare_test_cases():
Instruction = dis.Instruction
expected_opinfo_outer = [
- Instruction(opname='MAKE_CELL', opcode=94, arg=0, argval='a', argrepr='a', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='MAKE_CELL', opcode=94, arg=1, argval='b', argrepr='b', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='MAKE_CELL', opcode=96, arg=0, argval='a', argrepr='a', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='MAKE_CELL', opcode=96, arg=1, argval='b', argrepr='b', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=4, start_offset=4, starts_line=True, line_number=1, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=(3, 4), argrepr='(3, 4)', offset=6, start_offset=6, starts_line=True, line_number=2, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='a', argrepr='a', offset=8, start_offset=8, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=1, argval='b', argrepr='b', offset=10, start_offset=10, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
- Instruction(opname='BUILD_TUPLE', opcode=50, arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
+ Instruction(opname='BUILD_TUPLE', opcode=51, arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
- Instruction(opname='MAKE_FUNCTION', opcode=23, arg=None, argval=None, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
- Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=105, arg=8, argval=8, argrepr='closure', offset=18, start_offset=18, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
- Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=105, arg=1, argval=1, argrepr='defaults', offset=20, start_offset=20, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
- Instruction(opname='STORE_FAST', opcode=109, arg=2, argval='f', argrepr='f', offset=22, start_offset=22, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print + NULL', offset=24, start_offset=24, starts_line=True, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_DEREF', opcode=82, arg=0, argval='a', argrepr='a', offset=34, start_offset=34, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_DEREF', opcode=82, arg=1, argval='b', argrepr='b', offset=36, start_offset=36, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=81, arg=1, argval='', argrepr="''", offset=38, start_offset=38, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=1, argval=1, argrepr='', offset=40, start_offset=40, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='BUILD_LIST', opcode=45, arg=0, argval=0, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='BUILD_MAP', opcode=46, arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=81, arg=2, argval='Hello world!', argrepr="'Hello world!'", offset=46, start_offset=46, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=7, argval=7, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=83, arg=2, argval='f', argrepr='f', offset=58, start_offset=58, starts_line=True, line_number=8, label=None, positions=None, cache_info=None),
- Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=8, label=None, positions=None, cache_info=None),
+ Instruction(opname='MAKE_FUNCTION', opcode=24, arg=None, argval=None, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
+ Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=107, arg=8, argval=8, argrepr='closure', offset=18, start_offset=18, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
+ Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=107, arg=1, argval=1, argrepr='defaults', offset=20, start_offset=20, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
+ Instruction(opname='STORE_FAST', opcode=111, arg=2, argval='f', argrepr='f', offset=22, start_offset=22, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=0, argval='print', argrepr='print', offset=24, start_offset=24, starts_line=True, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=34, start_offset=34, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=0, argval='a', argrepr='a', offset=36, start_offset=36, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=1, argval='b', argrepr='b', offset=38, start_offset=38, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=1, argval='', argrepr="''", offset=40, start_offset=40, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=1, argval=1, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='BUILD_LIST', opcode=46, arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='BUILD_MAP', opcode=47, arg=0, argval=0, argrepr='', offset=46, start_offset=46, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=2, argval='Hello world!', argrepr="'Hello world!'", offset=48, start_offset=48, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=52, arg=7, argval=7, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=58, start_offset=58, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=2, argval='f', argrepr='f', offset=60, start_offset=60, starts_line=True, line_number=8, label=None, positions=None, cache_info=None),
+ Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=62, start_offset=62, starts_line=False, line_number=8, label=None, positions=None, cache_info=None),
]
expected_opinfo_f = [
Instruction(opname='COPY_FREE_VARS', opcode=60, arg=2, argval=2, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='MAKE_CELL', opcode=94, arg=0, argval='c', argrepr='c', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='MAKE_CELL', opcode=94, arg=1, argval='d', argrepr='d', offset=4, start_offset=4, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='MAKE_CELL', opcode=96, arg=0, argval='c', argrepr='c', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='MAKE_CELL', opcode=96, arg=1, argval='d', argrepr='d', offset=4, start_offset=4, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=6, start_offset=6, starts_line=True, line_number=2, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=1, argval=(5, 6), argrepr='(5, 6)', offset=8, start_offset=8, starts_line=True, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=3, argval='a', argrepr='a', offset=10, start_offset=10, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=4, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='c', argrepr='c', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=1, argval='d', argrepr='d', offset=16, start_offset=16, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='BUILD_TUPLE', opcode=50, arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='BUILD_TUPLE', opcode=51, arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='MAKE_FUNCTION', opcode=23, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=105, arg=8, argval=8, argrepr='closure', offset=24, start_offset=24, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=105, arg=1, argval=1, argrepr='defaults', offset=26, start_offset=26, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='STORE_FAST', opcode=109, arg=2, argval='inner', argrepr='inner', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_DEREF', opcode=82, arg=3, argval='a', argrepr='a', offset=40, start_offset=40, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_DEREF', opcode=82, arg=4, argval='b', argrepr='b', offset=42, start_offset=42, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_DEREF', opcode=82, arg=0, argval='c', argrepr='c', offset=44, start_offset=44, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_DEREF', opcode=82, arg=1, argval='d', argrepr='d', offset=46, start_offset=46, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=4, argval=4, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=83, arg=2, argval='inner', argrepr='inner', offset=58, start_offset=58, starts_line=True, line_number=6, label=None, positions=None, cache_info=None),
- Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=6, label=None, positions=None, cache_info=None),
+ Instruction(opname='MAKE_FUNCTION', opcode=24, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=107, arg=8, argval=8, argrepr='closure', offset=24, start_offset=24, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=107, arg=1, argval=1, argrepr='defaults', offset=26, start_offset=26, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='STORE_FAST', opcode=111, arg=2, argval='inner', argrepr='inner', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=0, argval='print', argrepr='print', offset=30, start_offset=30, starts_line=True, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=40, start_offset=40, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=3, argval='a', argrepr='a', offset=42, start_offset=42, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=4, argval='b', argrepr='b', offset=44, start_offset=44, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=0, argval='c', argrepr='c', offset=46, start_offset=46, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=1, argval='d', argrepr='d', offset=48, start_offset=48, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=52, arg=4, argval=4, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=58, start_offset=58, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=2, argval='inner', argrepr='inner', offset=60, start_offset=60, starts_line=True, line_number=6, label=None, positions=None, cache_info=None),
+ Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=62, start_offset=62, starts_line=False, line_number=6, label=None, positions=None, cache_info=None),
]
expected_opinfo_inner = [
Instruction(opname='COPY_FREE_VARS', opcode=60, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=2, start_offset=2, starts_line=True, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print + NULL', offset=4, start_offset=4, starts_line=True, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_DEREF', opcode=82, arg=2, argval='a', argrepr='a', offset=14, start_offset=14, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_DEREF', opcode=82, arg=3, argval='b', argrepr='b', offset=16, start_offset=16, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_DEREF', opcode=82, arg=4, argval='c', argrepr='c', offset=18, start_offset=18, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_DEREF', opcode=82, arg=5, argval='d', argrepr='d', offset=20, start_offset=20, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST_LOAD_FAST', opcode=86, arg=1, argval=('e', 'f'), argrepr='e, f', offset=22, start_offset=22, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=6, argval=6, argrepr='', offset=24, start_offset=24, starts_line=False, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=32, start_offset=32, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=None, argrepr='None', offset=34, start_offset=34, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=36, start_offset=36, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=0, argval='print', argrepr='print', offset=4, start_offset=4, starts_line=True, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=2, argval='a', argrepr='a', offset=16, start_offset=16, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=3, argval='b', argrepr='b', offset=18, start_offset=18, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=4, argval='c', argrepr='c', offset=20, start_offset=20, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=5, argval='d', argrepr='d', offset=22, start_offset=22, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST_LOAD_FAST', opcode=86, arg=1, argval=('e', 'f'), argrepr='e, f', offset=24, start_offset=24, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=52, arg=6, argval=6, argrepr='', offset=26, start_offset=26, starts_line=False, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=34, start_offset=34, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=None, argrepr='None', offset=36, start_offset=36, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=38, start_offset=38, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
]
expected_opinfo_jumpy = [
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=1, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='range', argrepr='range + NULL', offset=2, start_offset=2, starts_line=True, line_number=3, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=10, argval=10, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='GET_ITER', opcode=16, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='FOR_ITER', opcode=69, arg=32, argval=92, argrepr='to L4', offset=24, start_offset=24, starts_line=False, line_number=3, label=1, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='STORE_FAST', opcode=109, arg=0, argval='i', argrepr='i', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=52, start_offset=52, starts_line=True, line_number=5, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=4, argval=4, argrepr='', offset=54, start_offset=54, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
- Instruction(opname='COMPARE_OP', opcode=56, arg=18, argval='<', argrepr='bool(<)', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=3, argval=70, argrepr='to L2', offset=60, start_offset=60, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=64, start_offset=64, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD', opcode=74, arg=23, argval=24, argrepr='to L1', offset=66, start_offset=66, starts_line=True, line_number=6, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=70, start_offset=70, starts_line=True, line_number=7, label=2, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=6, argval=6, argrepr='', offset=72, start_offset=72, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='COMPARE_OP', opcode=56, arg=148, argval='>', argrepr='bool(>)', offset=74, start_offset=74, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=3, argval=88, argrepr='to L3', offset=78, start_offset=78, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=82, start_offset=82, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD', opcode=74, arg=32, argval=24, argrepr='to L1', offset=84, start_offset=84, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=8, label=3, positions=None, cache_info=None),
- Instruction(opname='JUMP_FORWARD', opcode=76, arg=13, argval=118, argrepr='to L5', offset=90, start_offset=90, starts_line=False, line_number=8, label=None, positions=None, cache_info=None),
- Instruction(opname='END_FOR', opcode=9, arg=None, argval=None, argrepr='', offset=92, start_offset=92, starts_line=True, line_number=3, label=4, positions=None, cache_info=None),
- Instruction(opname='POP_ITER', opcode=30, arg=None, argval=None, argrepr='', offset=94, start_offset=94, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=96, start_offset=96, starts_line=True, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=106, start_offset=106, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=108, start_offset=108, starts_line=False, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=116, start_offset=116, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST_CHECK', opcode=85, arg=0, argval='i', argrepr='i', offset=118, start_offset=118, starts_line=True, line_number=11, label=5, positions=None, cache_info=None),
- Instruction(opname='TO_BOOL', opcode=39, arg=None, argval=None, argrepr='', offset=120, start_offset=120, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=40, argval=212, argrepr='to L8', offset=128, start_offset=128, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=132, start_offset=132, starts_line=False, line_number=11, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=134, start_offset=134, starts_line=True, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=144, start_offset=144, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=146, start_offset=146, starts_line=False, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=154, start_offset=154, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=156, start_offset=156, starts_line=True, line_number=13, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=1, argval=1, argrepr='', offset=158, start_offset=158, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
- Instruction(opname='BINARY_OP', opcode=44, arg=23, argval=23, argrepr='-=', offset=160, start_offset=160, starts_line=False, line_number=13, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]),
- Instruction(opname='STORE_FAST', opcode=109, arg=0, argval='i', argrepr='i', offset=172, start_offset=172, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=174, start_offset=174, starts_line=True, line_number=14, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=6, argval=6, argrepr='', offset=176, start_offset=176, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
- Instruction(opname='COMPARE_OP', opcode=56, arg=148, argval='>', argrepr='bool(>)', offset=178, start_offset=178, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=3, argval=192, argrepr='to L6', offset=182, start_offset=182, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=186, start_offset=186, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD', opcode=74, arg=37, argval=118, argrepr='to L5', offset=188, start_offset=188, starts_line=True, line_number=15, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=192, start_offset=192, starts_line=True, line_number=16, label=6, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=4, argval=4, argrepr='', offset=194, start_offset=194, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
- Instruction(opname='COMPARE_OP', opcode=56, arg=18, argval='<', argrepr='bool(<)', offset=196, start_offset=196, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=3, argval=210, argrepr='to L7', offset=200, start_offset=200, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=204, start_offset=204, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD', opcode=74, arg=46, argval=118, argrepr='to L5', offset=206, start_offset=206, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='JUMP_FORWARD', opcode=76, arg=11, argval=234, argrepr='to L9', offset=210, start_offset=210, starts_line=True, line_number=17, label=7, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=212, start_offset=212, starts_line=True, line_number=19, label=8, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=81, arg=1, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=222, start_offset=222, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=224, start_offset=224, starts_line=False, line_number=19, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=232, start_offset=232, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
- Instruction(opname='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=234, start_offset=234, starts_line=True, line_number=20, label=9, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=1, argval=1, argrepr='', offset=236, start_offset=236, starts_line=True, line_number=21, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=0, argval=0, argrepr='', offset=238, start_offset=238, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
- Instruction(opname='BINARY_OP', opcode=44, arg=11, argval=11, argrepr='/', offset=240, start_offset=240, starts_line=False, line_number=21, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=252, start_offset=252, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=254, start_offset=254, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='COPY', opcode=59, arg=1, argval=1, argrepr='', offset=256, start_offset=256, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SPECIAL', opcode=92, arg=1, argval=1, argrepr='__exit__', offset=258, start_offset=258, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='SWAP', opcode=114, arg=2, argval=2, argrepr='', offset=260, start_offset=260, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='SWAP', opcode=114, arg=3, argval=3, argrepr='', offset=262, start_offset=262, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SPECIAL', opcode=92, arg=0, argval=0, argrepr='__enter__', offset=264, start_offset=264, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=0, argval=0, argrepr='', offset=266, start_offset=266, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='STORE_FAST', opcode=109, arg=1, argval='dodgy', argrepr='dodgy', offset=274, start_offset=274, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=276, start_offset=276, starts_line=True, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=81, arg=2, argval='Never reach this', argrepr="'Never reach this'", offset=286, start_offset=286, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=288, start_offset=288, starts_line=False, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=296, start_offset=296, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=298, start_offset=298, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=300, start_offset=300, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=302, start_offset=302, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=3, argval=3, argrepr='', offset=304, start_offset=304, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=312, start_offset=312, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=314, start_offset=314, starts_line=True, line_number=28, label=10, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=81, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=324, start_offset=324, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=326, start_offset=326, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=334, start_offset=334, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=336, start_offset=336, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=338, start_offset=338, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=32, arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='WITH_EXCEPT_START', opcode=43, arg=None, argval=None, argrepr='', offset=342, start_offset=342, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='TO_BOOL', opcode=39, arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=360, argrepr='to L11', offset=352, start_offset=352, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=356, start_offset=356, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=102, arg=2, argval=2, argrepr='', offset=358, start_offset=358, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=360, start_offset=360, starts_line=False, line_number=25, label=11, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=362, start_offset=362, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=364, start_offset=364, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=366, start_offset=366, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=368, start_offset=368, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=75, arg=29, argval=314, argrepr='to L10', offset=370, start_offset=370, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=372, start_offset=372, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=374, start_offset=374, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=376, start_offset=376, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=32, arg=None, argval=None, argrepr='', offset=378, start_offset=378, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=380, start_offset=380, starts_line=True, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='CHECK_EXC_MATCH', opcode=5, arg=None, argval=None, argrepr='', offset=390, start_offset=390, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=15, argval=426, argrepr='to L12', offset=392, start_offset=392, starts_line=False, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=396, start_offset=396, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=398, start_offset=398, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=400, start_offset=400, starts_line=True, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=81, arg=4, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=410, start_offset=410, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=412, start_offset=412, starts_line=False, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=420, start_offset=420, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=422, start_offset=422, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=75, arg=56, argval=314, argrepr='to L10', offset=424, start_offset=424, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=426, start_offset=426, starts_line=True, line_number=22, label=12, positions=None, cache_info=None),
- Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=428, start_offset=428, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=430, start_offset=430, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=432, start_offset=432, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=32, arg=None, argval=None, argrepr='', offset=434, start_offset=434, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=436, start_offset=436, starts_line=True, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=81, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=446, start_offset=446, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=448, start_offset=448, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=456, start_offset=456, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=458, start_offset=458, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=460, start_offset=460, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=462, start_offset=462, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=464, start_offset=464, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=0, argval='range', argrepr='range', offset=2, start_offset=2, starts_line=True, line_number=3, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=10, argval=10, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=3, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='GET_ITER', opcode=18, arg=None, argval=None, argrepr='', offset=24, start_offset=24, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='FOR_ITER', opcode=69, arg=33, argval=96, argrepr='to L4', offset=26, start_offset=26, starts_line=False, line_number=3, label=1, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='STORE_FAST', opcode=111, arg=0, argval='i', argrepr='i', offset=30, start_offset=30, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print', offset=32, start_offset=32, starts_line=True, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=44, start_offset=44, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=46, start_offset=46, starts_line=False, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=54, start_offset=54, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=56, start_offset=56, starts_line=True, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=4, argval=4, argrepr='', offset=58, start_offset=58, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='COMPARE_OP', opcode=56, arg=18, argval='<', argrepr='bool(<)', offset=60, start_offset=60, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=99, arg=3, argval=74, argrepr='to L2', offset=64, start_offset=64, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=29, arg=None, argval=None, argrepr='', offset=68, start_offset=68, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=74, arg=24, argval=26, argrepr='to L1', offset=70, start_offset=70, starts_line=True, line_number=6, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=74, start_offset=74, starts_line=True, line_number=7, label=2, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=6, argval=6, argrepr='', offset=76, start_offset=76, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='COMPARE_OP', opcode=56, arg=148, argval='>', argrepr='bool(>)', offset=78, start_offset=78, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_TRUE', opcode=102, arg=3, argval=92, argrepr='to L3', offset=82, start_offset=82, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=29, arg=None, argval=None, argrepr='', offset=86, start_offset=86, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=74, arg=33, argval=26, argrepr='to L1', offset=88, start_offset=88, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=92, start_offset=92, starts_line=True, line_number=8, label=3, positions=None, cache_info=None),
+ Instruction(opname='JUMP_FORWARD', opcode=76, arg=14, argval=124, argrepr='to L5', offset=94, start_offset=94, starts_line=False, line_number=8, label=None, positions=None, cache_info=None),
+ Instruction(opname='END_FOR', opcode=10, arg=None, argval=None, argrepr='', offset=96, start_offset=96, starts_line=True, line_number=3, label=4, positions=None, cache_info=None),
+ Instruction(opname='POP_ITER', opcode=31, arg=None, argval=None, argrepr='', offset=98, start_offset=98, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print', offset=100, start_offset=100, starts_line=True, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=110, start_offset=110, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=112, start_offset=112, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=114, start_offset=114, starts_line=False, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=122, start_offset=122, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST_CHECK', opcode=85, arg=0, argval='i', argrepr='i', offset=124, start_offset=124, starts_line=True, line_number=11, label=5, positions=None, cache_info=None),
+ Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=126, start_offset=126, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=99, arg=41, argval=220, argrepr='to L8', offset=134, start_offset=134, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=29, arg=None, argval=None, argrepr='', offset=138, start_offset=138, starts_line=False, line_number=11, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print', offset=140, start_offset=140, starts_line=True, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=150, start_offset=150, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=152, start_offset=152, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=154, start_offset=154, starts_line=False, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=162, start_offset=162, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=164, start_offset=164, starts_line=True, line_number=13, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=1, argval=1, argrepr='', offset=166, start_offset=166, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
+ Instruction(opname='BINARY_OP', opcode=45, arg=23, argval=23, argrepr='-=', offset=168, start_offset=168, starts_line=False, line_number=13, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]),
+ Instruction(opname='STORE_FAST', opcode=111, arg=0, argval='i', argrepr='i', offset=180, start_offset=180, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=182, start_offset=182, starts_line=True, line_number=14, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=6, argval=6, argrepr='', offset=184, start_offset=184, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
+ Instruction(opname='COMPARE_OP', opcode=56, arg=148, argval='>', argrepr='bool(>)', offset=186, start_offset=186, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=99, arg=3, argval=200, argrepr='to L6', offset=190, start_offset=190, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=29, arg=None, argval=None, argrepr='', offset=194, start_offset=194, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=74, arg=38, argval=124, argrepr='to L5', offset=196, start_offset=196, starts_line=True, line_number=15, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=200, start_offset=200, starts_line=True, line_number=16, label=6, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=4, argval=4, argrepr='', offset=202, start_offset=202, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
+ Instruction(opname='COMPARE_OP', opcode=56, arg=18, argval='<', argrepr='bool(<)', offset=204, start_offset=204, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_TRUE', opcode=102, arg=3, argval=218, argrepr='to L7', offset=208, start_offset=208, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=29, arg=None, argval=None, argrepr='', offset=212, start_offset=212, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=74, arg=47, argval=124, argrepr='to L5', offset=214, start_offset=214, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='JUMP_FORWARD', opcode=76, arg=12, argval=244, argrepr='to L9', offset=218, start_offset=218, starts_line=True, line_number=17, label=7, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print', offset=220, start_offset=220, starts_line=True, line_number=19, label=8, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=230, start_offset=230, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=1, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=232, start_offset=232, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=234, start_offset=234, starts_line=False, line_number=19, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=242, start_offset=242, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
+ Instruction(opname='NOP', opcode=28, arg=None, argval=None, argrepr='', offset=244, start_offset=244, starts_line=True, line_number=20, label=9, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=1, argval=1, argrepr='', offset=246, start_offset=246, starts_line=True, line_number=21, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=0, argval=0, argrepr='', offset=248, start_offset=248, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
+ Instruction(opname='BINARY_OP', opcode=45, arg=11, argval=11, argrepr='/', offset=250, start_offset=250, starts_line=False, line_number=21, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=262, start_offset=262, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=264, start_offset=264, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='COPY', opcode=59, arg=1, argval=1, argrepr='', offset=266, start_offset=266, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SPECIAL', opcode=93, arg=1, argval=1, argrepr='__exit__', offset=268, start_offset=268, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='SWAP', opcode=116, arg=2, argval=2, argrepr='', offset=270, start_offset=270, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='SWAP', opcode=116, arg=3, argval=3, argrepr='', offset=272, start_offset=272, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SPECIAL', opcode=93, arg=0, argval=0, argrepr='__enter__', offset=274, start_offset=274, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=52, arg=0, argval=0, argrepr='', offset=276, start_offset=276, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='STORE_FAST', opcode=111, arg=1, argval='dodgy', argrepr='dodgy', offset=284, start_offset=284, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print', offset=286, start_offset=286, starts_line=True, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=296, start_offset=296, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=2, argval='Never reach this', argrepr="'Never reach this'", offset=298, start_offset=298, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=300, start_offset=300, starts_line=False, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=308, start_offset=308, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=310, start_offset=310, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=312, start_offset=312, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=314, start_offset=314, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=52, arg=3, argval=3, argrepr='', offset=316, start_offset=316, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=324, start_offset=324, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print', offset=326, start_offset=326, starts_line=True, line_number=28, label=10, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=336, start_offset=336, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=338, start_offset=338, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=340, start_offset=340, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=348, start_offset=348, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=350, start_offset=350, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=352, start_offset=352, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=354, start_offset=354, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='WITH_EXCEPT_START', opcode=44, arg=None, argval=None, argrepr='', offset=356, start_offset=356, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=358, start_offset=358, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_TRUE', opcode=102, arg=2, argval=374, argrepr='to L11', offset=366, start_offset=366, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=29, arg=None, argval=None, argrepr='', offset=370, start_offset=370, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=104, arg=2, argval=2, argrepr='', offset=372, start_offset=372, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=374, start_offset=374, starts_line=False, line_number=25, label=11, positions=None, cache_info=None),
+ Instruction(opname='POP_EXCEPT', opcode=30, arg=None, argval=None, argrepr='', offset=376, start_offset=376, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=378, start_offset=378, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=380, start_offset=380, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=382, start_offset=382, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=75, arg=30, argval=326, argrepr='to L10', offset=384, start_offset=384, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=386, start_offset=386, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_EXCEPT', opcode=30, arg=None, argval=None, argrepr='', offset=388, start_offset=388, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=104, arg=1, argval=1, argrepr='', offset=390, start_offset=390, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=392, start_offset=392, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=394, start_offset=394, starts_line=True, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='CHECK_EXC_MATCH', opcode=6, arg=None, argval=None, argrepr='', offset=404, start_offset=404, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=99, arg=16, argval=442, argrepr='to L12', offset=406, start_offset=406, starts_line=False, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=29, arg=None, argval=None, argrepr='', offset=410, start_offset=410, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=412, start_offset=412, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print', offset=414, start_offset=414, starts_line=True, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=424, start_offset=424, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=4, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=426, start_offset=426, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=428, start_offset=428, starts_line=False, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=436, start_offset=436, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_EXCEPT', opcode=30, arg=None, argval=None, argrepr='', offset=438, start_offset=438, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=75, arg=58, argval=326, argrepr='to L10', offset=440, start_offset=440, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=104, arg=0, argval=0, argrepr='', offset=442, start_offset=442, starts_line=True, line_number=22, label=12, positions=None, cache_info=None),
+ Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=444, start_offset=444, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_EXCEPT', opcode=30, arg=None, argval=None, argrepr='', offset=446, start_offset=446, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=104, arg=1, argval=1, argrepr='', offset=448, start_offset=448, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=450, start_offset=450, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print', offset=452, start_offset=452, starts_line=True, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=462, start_offset=462, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=464, start_offset=464, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=466, start_offset=466, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=474, start_offset=474, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=104, arg=0, argval=0, argrepr='', offset=476, start_offset=476, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=478, start_offset=478, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_EXCEPT', opcode=30, arg=None, argval=None, argrepr='', offset=480, start_offset=480, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=104, arg=1, argval=1, argrepr='', offset=482, start_offset=482, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
]
# One last piece of inspect fodder to check the default line number handling
@@ -1909,7 +1929,7 @@ def simple(): pass
expected_opinfo_simple = [
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=simple.__code__.co_firstlineno, label=None, positions=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=None, argrepr='None', offset=2, start_offset=2, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None),
- Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=4, start_offset=4, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None),
+ Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=4, start_offset=4, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None),
]
@@ -2133,7 +2153,7 @@ def f(opcode, oparg, offset, *init_args):
args = (offset, co_consts, names, varname_from_oparg, labels_map)
self.assertEqual(f(opcode.opmap["POP_TOP"], None, *args), (None, ''))
self.assertEqual(f(opcode.opmap["LOAD_CONST"], 1, *args), (1, '1'))
- self.assertEqual(f(opcode.opmap["LOAD_GLOBAL"], 2, *args), ('a', 'a'))
+ self.assertEqual(f(opcode.opmap["LOAD_GLOBAL"], 1, *args), ('a', 'a'))
self.assertEqual(f(opcode.opmap["JUMP_BACKWARD"], 11, *args), (24, 'to L1'))
self.assertEqual(f(opcode.opmap["COMPARE_OP"], 3, *args), ('<', '<'))
self.assertEqual(f(opcode.opmap["SET_FUNCTION_ATTRIBUTE"], 2, *args), (2, 'kwdefaults'))
diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py
index aa92145266961a..4b17bd5c797375 100644
--- a/Lib/test/test_generated_cases.py
+++ b/Lib/test/test_generated_cases.py
@@ -59,14 +59,14 @@ class TestEffects(unittest.TestCase):
def test_effect_sizes(self):
stack = Stack()
inputs = [
- x := StackItem("x", None, "", "1"),
- y := StackItem("y", None, "", "oparg"),
- z := StackItem("z", None, "", "oparg*2"),
+ x := StackItem("x", None, "1"),
+ y := StackItem("y", None, "oparg"),
+ z := StackItem("z", None, "oparg*2"),
]
outputs = [
- StackItem("x", None, "", "1"),
- StackItem("b", None, "", "oparg*4"),
- StackItem("c", None, "", "1"),
+ StackItem("x", None, "1"),
+ StackItem("b", None, "oparg*4"),
+ StackItem("c", None, "1"),
]
stack.pop(z)
stack.pop(y)
@@ -104,20 +104,6 @@ def test_push_one(self):
"""
self.check(input, output)
- def test_cond_push(self):
- input = """
- inst(OP, (a -- b, c if (oparg))) {
- SPAM();
- }
- """
- output = """
- case OP: {
- *effect = ((oparg) ? 1 : 0);
- return 0;
- }
- """
- self.check(input, output)
-
def test_ops_pass_two(self):
input = """
op(A, (-- val1)) {
@@ -138,25 +124,6 @@ def test_ops_pass_two(self):
"""
self.check(input, output)
- def test_ops_pass_two_cond_push(self):
- input = """
- op(A, (-- val1, val2)) {
- val1 = 0;
- val2 = 1;
- }
- op(B, (val1, val2 -- val1, val2, val3 if (oparg))) {
- val3 = SPAM();
- }
- macro(OP) = A + B;
- """
- output = """
- case OP: {
- *effect = Py_MAX(2, 2 + ((oparg) ? 1 : 0));
- return 0;
- }
- """
- self.check(input, output)
-
def test_pop_push_array(self):
input = """
inst(OP, (values[oparg] -- values[oparg], above)) {
@@ -938,90 +905,6 @@ def test_array_error_if(self):
"""
self.run_cases_test(input, output)
- def test_cond_effect(self):
- input = """
- inst(OP, (aa, input if ((oparg & 1) == 1), cc -- xx, output if (oparg & 2), zz)) {
- output = SPAM(oparg, aa, cc, input);
- INPUTS_DEAD();
- xx = 0;
- zz = 0;
- }
- """
- output = """
- TARGET(OP) {
- frame->instr_ptr = next_instr;
- next_instr += 1;
- INSTRUCTION_STATS(OP);
- _PyStackRef aa;
- _PyStackRef input = PyStackRef_NULL;
- _PyStackRef cc;
- _PyStackRef xx;
- _PyStackRef output = PyStackRef_NULL;
- _PyStackRef zz;
- cc = stack_pointer[-1];
- if ((oparg & 1) == 1) { input = stack_pointer[-1 - (((oparg & 1) == 1) ? 1 : 0)]; }
- aa = stack_pointer[-2 - (((oparg & 1) == 1) ? 1 : 0)];
- output = SPAM(oparg, aa, cc, input);
- xx = 0;
- zz = 0;
- stack_pointer[-2 - (((oparg & 1) == 1) ? 1 : 0)] = xx;
- if (oparg & 2) stack_pointer[-1 - (((oparg & 1) == 1) ? 1 : 0)] = output;
- stack_pointer[-1 - (((oparg & 1) == 1) ? 1 : 0) + ((oparg & 2) ? 1 : 0)] = zz;
- stack_pointer += -(((oparg & 1) == 1) ? 1 : 0) + ((oparg & 2) ? 1 : 0);
- assert(WITHIN_STACK_BOUNDS());
- DISPATCH();
- }
- """
- self.run_cases_test(input, output)
-
- def test_macro_cond_effect(self):
- input = """
- op(A, (left, middle, right --)) {
- USE(left, middle, right);
- INPUTS_DEAD();
- }
- op(B, (-- deep, extra if (oparg), res)) {
- deep = -1;
- res = 0;
- extra = 1;
- INPUTS_DEAD();
- }
- macro(M) = A + B;
- """
- output = """
- TARGET(M) {
- frame->instr_ptr = next_instr;
- next_instr += 1;
- INSTRUCTION_STATS(M);
- _PyStackRef left;
- _PyStackRef middle;
- _PyStackRef right;
- _PyStackRef deep;
- _PyStackRef extra = PyStackRef_NULL;
- _PyStackRef res;
- // A
- {
- right = stack_pointer[-1];
- middle = stack_pointer[-2];
- left = stack_pointer[-3];
- USE(left, middle, right);
- }
- // B
- {
- deep = -1;
- res = 0;
- extra = 1;
- }
- stack_pointer[-3] = deep;
- if (oparg) stack_pointer[-2] = extra;
- stack_pointer[-2 + ((oparg) ? 1 : 0)] = res;
- stack_pointer += -1 + ((oparg) ? 1 : 0);
- assert(WITHIN_STACK_BOUNDS());
- DISPATCH();
- }
- """
- self.run_cases_test(input, output)
-
def test_macro_push_push(self):
input = """
op(A, (-- val1)) {
diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py
index 364381e7dce00a..7ac2910cfb7854 100644
--- a/Lib/test/test_monitoring.py
+++ b/Lib/test/test_monitoring.py
@@ -1588,11 +1588,11 @@ def whilefunc(n=0):
('branch right', 'whilefunc', 1, 3)])
self.check_events(func, recorders = BRANCH_OFFSET_RECORDERS, expected = [
- ('branch left', 'func', 28, 32),
- ('branch right', 'func', 44, 58),
- ('branch left', 'func', 28, 32),
- ('branch left', 'func', 44, 50),
- ('branch right', 'func', 28, 70)])
+ ('branch left', 'func', 30, 34),
+ ('branch right', 'func', 46, 60),
+ ('branch left', 'func', 30, 34),
+ ('branch left', 'func', 46, 52),
+ ('branch right', 'func', 30, 72)])
def test_except_star(self):
@@ -1762,7 +1762,8 @@ def _exec_super(self, codestr, optimized=False):
return self._exec(co)
def _has_load_super_attr(self, co):
- has = any(instr.opname == "LOAD_SUPER_ATTR" for instr in dis.get_instructions(co))
+ has = any(instr.opname in ("LOAD_SUPER_ATTR", "LOAD_SUPER_METHOD")
+ for instr in dis.get_instructions(co))
if not has:
has = any(
isinstance(c, types.CodeType) and self._has_load_super_attr(c)
diff --git a/Lib/test/test_opcache.py b/Lib/test/test_opcache.py
index 4d7304b1c9abb6..1895a5001fd318 100644
--- a/Lib/test/test_opcache.py
+++ b/Lib/test/test_opcache.py
@@ -868,7 +868,7 @@ def write(items):
pass
type(item).m = lambda self: None
- opname = "LOAD_ATTR_METHOD_LAZY_DICT"
+ opname = "LOAD_METHOD_LAZY_DICT"
self.assert_races_do_not_crash(opname, get_items, read, write)
@requires_specialization_ft
@@ -899,7 +899,7 @@ def write(items):
pass
type(item).m = lambda self: None
- opname = "LOAD_ATTR_METHOD_NO_DICT"
+ opname = "LOAD_METHOD_NO_DICT"
self.assert_races_do_not_crash(opname, get_items, read, write)
@requires_specialization_ft
@@ -929,7 +929,7 @@ def write(items):
pass
type(item).m = lambda self: None
- opname = "LOAD_ATTR_METHOD_WITH_VALUES"
+ opname = "LOAD_METHOD_WITH_VALUES"
self.assert_races_do_not_crash(opname, get_items, read, write)
@requires_specialization_ft
@@ -1424,8 +1424,9 @@ def __init__(self):
A()
self.assert_specialized(A.__init__, "LOAD_SUPER_ATTR_ATTR")
- self.assert_specialized(A.__init__, "LOAD_SUPER_ATTR_METHOD")
+ self.assert_specialized(A.__init__, "LOAD_SUPER_METHOD_METHOD")
self.assert_no_opcode(A.__init__, "LOAD_SUPER_ATTR")
+ self.assert_no_opcode(A.__init__, "LOAD_SUPER_METHOD")
# Temporarily replace super() with something else.
real_super = super
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-01-17-10-17-01.gh-issue-128914.dn6RaW.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-01-17-10-17-01.gh-issue-128914.dn6RaW.rst
new file mode 100644
index 00000000000000..63f71590363273
--- /dev/null
+++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-01-17-10-17-01.gh-issue-128914.dn6RaW.rst
@@ -0,0 +1,3 @@
+:opcode:`LOAD_ATTR` no longer pushes an extra ``NULL`` to the stack.
+:opcode:`LOAD_METHOD` has been added. ``LOAD_METHOD`` is equivalent to
+``LOAD_ATTR; PUSH_NULL`` but is optimized for use in method calls.
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 4f0040df4f3017..bf5067bba58f71 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -1261,27 +1261,18 @@ mark_stacks(PyCodeObject *code_obj, int len)
stacks[next_i] = next_stack;
break;
case LOAD_GLOBAL:
- {
- int j = oparg;
next_stack = push_value(next_stack, Object);
- if (j & 1) {
- next_stack = push_value(next_stack, Null);
- }
stacks[next_i] = next_stack;
break;
- }
case LOAD_ATTR:
- {
assert(top_of_stack(next_stack) == Object);
- int j = oparg;
- if (j & 1) {
- next_stack = pop_value(next_stack);
- next_stack = push_value(next_stack, Object);
- next_stack = push_value(next_stack, Null);
- }
stacks[next_i] = next_stack;
break;
- }
+ case LOAD_METHOD:
+ assert(top_of_stack(next_stack) == Object);
+ next_stack = push_value(next_stack, Null);
+ stacks[next_i] = next_stack;
+ break;
case SWAP:
{
int n = oparg;
diff --git a/Objects/object.c b/Objects/object.c
index 51b6016b9c191c..0a15c1e1de5499 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -1551,7 +1551,7 @@ _PyObject_NextNotImplemented(PyObject *self)
/* Specialized version of _PyObject_GenericGetAttrWithDict
- specifically for the LOAD_METHOD opcode.
+ specifically for the loading methods
Return 1 if a method is found, 0 if it's a regular attribute
from __dict__ or something returned by using a descriptor
diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h
index 4f6933ac0ddcd6..be05fae1a6d831 100644
--- a/Programs/test_frozenmain.h
+++ b/Programs/test_frozenmain.h
@@ -1,18 +1,18 @@
// Auto-generated by Programs/freeze_test_frozenmain.py
unsigned char M_test_frozenmain[] = {
227,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,
- 0,0,0,0,0,243,168,0,0,0,149,0,91,0,81,0,
- 72,0,113,0,91,0,81,0,72,1,113,1,90,2,33,0,
- 81,1,51,1,0,0,0,0,0,0,31,0,90,2,33,0,
- 81,2,90,0,79,6,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,51,2,0,0,0,0,0,0,
- 31,0,90,1,79,8,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,33,0,51,0,0,0,0,0,
- 0,0,81,3,2,0,0,0,113,5,81,4,16,0,69,20,
- 0,0,113,6,90,2,33,0,81,5,90,6,12,0,81,6,
- 90,5,90,6,2,0,0,0,12,0,49,4,51,1,0,0,
- 0,0,0,0,31,0,74,22,0,0,9,0,30,0,81,0,
- 35,0,41,7,78,122,18,70,114,111,122,101,110,32,72,101,
+ 0,0,0,0,0,243,168,0,0,0,149,0,92,0,81,0,
+ 72,0,115,0,92,0,81,0,72,1,115,1,91,2,34,0,
+ 81,1,52,1,0,0,0,0,0,0,32,0,91,2,34,0,
+ 81,2,91,0,79,3,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,52,2,0,0,0,0,0,0,
+ 32,0,91,1,79,4,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,34,0,52,0,0,0,0,0,
+ 0,0,81,3,2,0,0,0,115,5,81,4,18,0,69,20,
+ 0,0,115,6,91,2,34,0,81,5,91,6,13,0,81,6,
+ 91,5,91,6,2,0,0,0,13,0,50,4,52,1,0,0,
+ 0,0,0,0,32,0,74,22,0,0,10,0,31,0,81,0,
+ 36,0,41,7,78,122,18,70,114,111,122,101,110,32,72,101,
108,108,111,32,87,111,114,108,100,122,8,115,121,115,46,97,
114,103,118,218,6,99,111,110,102,105,103,41,5,218,12,112,
114,111,103,114,97,109,95,110,97,109,101,218,10,101,120,101,
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index c0ef767a9dd68b..398f1d564fad4a 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -348,8 +348,8 @@ dummy_func(
DECREF_INPUTS();
}
- pure inst(PUSH_NULL, (-- res)) {
- res = PyStackRef_NULL;
+ pure inst(PUSH_NULL, (-- null)) {
+ null = PyStackRef_NULL;
}
no_save_ip inst(END_FOR, (value -- )) {
@@ -1658,7 +1658,7 @@ dummy_func(
specializing op(_SPECIALIZE_LOAD_GLOBAL, (counter/1 -- )) {
#if ENABLE_SPECIALIZATION_FT
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
next_instr = this_instr;
_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name);
DISPATCH_SAME_OPARG();
@@ -1669,11 +1669,10 @@ dummy_func(
}
// res[1] because we need a pointer to res to pass it to _PyEval_LoadGlobalStackRef
- op(_LOAD_GLOBAL, ( -- res[1], null if (oparg & 1))) {
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
+ op(_LOAD_GLOBAL, ( -- res[1])) {
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
_PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res);
ERROR_IF(PyStackRef_IsNull(*res), error);
- null = PyStackRef_NULL;
}
macro(LOAD_GLOBAL) =
@@ -1711,7 +1710,7 @@ dummy_func(
assert(DK_IS_UNICODE(builtins_keys));
}
- op(_LOAD_GLOBAL_MODULE_FROM_KEYS, (index/1, globals_keys: PyDictKeysObject* -- res, null if (oparg & 1))) {
+ op(_LOAD_GLOBAL_MODULE_FROM_KEYS, (index/1, globals_keys: PyDictKeysObject* -- res)) {
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(globals_keys);
PyObject *res_o = FT_ATOMIC_LOAD_PTR_RELAXED(entries[index].me_value);
DEAD(globals_keys);
@@ -1725,10 +1724,9 @@ dummy_func(
res = PyStackRef_FromPyObjectSteal(res_o);
#endif
STAT_INC(LOAD_GLOBAL, hit);
- null = PyStackRef_NULL;
}
- op(_LOAD_GLOBAL_BUILTINS_FROM_KEYS, (index/1, builtins_keys: PyDictKeysObject* -- res, null if (oparg & 1))) {
+ op(_LOAD_GLOBAL_BUILTINS_FROM_KEYS, (index/1, builtins_keys: PyDictKeysObject* -- res)) {
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(builtins_keys);
PyObject *res_o = FT_ATOMIC_LOAD_PTR_RELAXED(entries[index].me_value);
DEAD(builtins_keys);
@@ -1742,7 +1740,6 @@ dummy_func(
res = PyStackRef_FromPyObjectSteal(res_o);
#endif
STAT_INC(LOAD_GLOBAL, hit);
- null = PyStackRef_NULL;
}
macro(LOAD_GLOBAL_MODULE) =
@@ -2012,17 +2009,27 @@ dummy_func(
GO_TO_INSTRUCTION(LOAD_SUPER_ATTR);
}
+ inst(INSTRUMENTED_LOAD_SUPER_METHOD, (unused/1 -- )) {
+ // cancel out the decrement that will happen in LOAD_SUPER_ATTR; we
+ // don't want to specialize instrumented instructions
+ PAUSE_ADAPTIVE_COUNTER(this_instr[1].counter);
+ GO_TO_INSTRUCTION(LOAD_SUPER_METHOD);
+ }
+
family(LOAD_SUPER_ATTR, INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR) = {
LOAD_SUPER_ATTR_ATTR,
- LOAD_SUPER_ATTR_METHOD,
+ };
+
+
+ family(LOAD_SUPER_METHOD, INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR) = {
+ LOAD_SUPER_METHOD_METHOD,
};
specializing op(_SPECIALIZE_LOAD_SUPER_ATTR, (counter/1, global_super_st, class_st, unused -- global_super_st, class_st, unused)) {
#if ENABLE_SPECIALIZATION_FT
- int load_method = oparg & 1;
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
next_instr = this_instr;
- _Py_Specialize_LoadSuperAttr(global_super_st, class_st, next_instr, load_method);
+ _Py_Specialize_LoadSuperAttr(global_super_st, class_st, next_instr, 0);
DISPATCH_SAME_OPARG();
}
OPCODE_DEFERRED_INC(LOAD_SUPER_ATTR);
@@ -2030,12 +2037,24 @@ dummy_func(
#endif /* ENABLE_SPECIALIZATION_FT */
}
- tier1 op(_LOAD_SUPER_ATTR, (global_super_st, class_st, self_st -- attr, null if (oparg & 1))) {
+ specializing op(_SPECIALIZE_LOAD_SUPER_METHOD, (counter/1, global_super_st, class_st, unused -- global_super_st, class_st, unused)) {
+ #if ENABLE_SPECIALIZATION_FT
+ if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
+ next_instr = this_instr;
+ _Py_Specialize_LoadSuperAttr(global_super_st, class_st, next_instr, 1);
+ DISPATCH_SAME_OPARG();
+ }
+ OPCODE_DEFERRED_INC(LOAD_SUPER_METHOD);
+ ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
+ #endif /* ENABLE_SPECIALIZATION_FT */
+ }
+
+ tier1 op(_LOAD_SUPER_ATTR, (global_super_st, class_st, self_st -- attr)) {
PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
- if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
+ if (opcode >= MIN_INSTRUMENTED_OPCODE) {
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_CALL,
@@ -2049,7 +2068,7 @@ dummy_func(
// handle any case whose performance we care about
PyObject *stack[] = {class, self};
PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
- if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
+ if (opcode >= MIN_INSTRUMENTED_OPCODE) {
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
if (super == NULL) {
_Py_call_instrumentation_exc2(
@@ -2072,12 +2091,13 @@ dummy_func(
Py_DECREF(super);
ERROR_IF(attr_o == NULL, error);
attr = PyStackRef_FromPyObjectSteal(attr_o);
- null = PyStackRef_NULL;
}
macro(LOAD_SUPER_ATTR) = _SPECIALIZE_LOAD_SUPER_ATTR + _LOAD_SUPER_ATTR;
+ macro(LOAD_SUPER_METHOD) = _SPECIALIZE_LOAD_SUPER_METHOD + _LOAD_SUPER_ATTR + PUSH_NULL;
+
- inst(LOAD_SUPER_ATTR_ATTR, (unused/1, global_super_st, class_st, self_st -- attr_st, unused if (0))) {
+ inst(LOAD_SUPER_ATTR_ATTR, (unused/1, global_super_st, class_st, self_st -- attr_st)) {
PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
@@ -2093,7 +2113,7 @@ dummy_func(
attr_st = PyStackRef_FromPyObjectSteal(attr);
}
- inst(LOAD_SUPER_ATTR_METHOD, (unused/1, global_super_st, class_st, self_st -- attr, self_or_null)) {
+ inst(LOAD_SUPER_METHOD_METHOD, (unused/1, global_super_st, class_st, self_st -- attr, self_or_null)) {
PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
@@ -2132,17 +2152,20 @@ dummy_func(
LOAD_ATTR_CLASS_WITH_METACLASS_CHECK,
LOAD_ATTR_PROPERTY,
LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN,
- LOAD_ATTR_METHOD_WITH_VALUES,
- LOAD_ATTR_METHOD_NO_DICT,
- LOAD_ATTR_METHOD_LAZY_DICT,
LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES,
LOAD_ATTR_NONDESCRIPTOR_NO_DICT,
};
+ family(LOAD_METHOD, INLINE_CACHE_ENTRIES_LOAD_ATTR) = {
+ LOAD_METHOD_WITH_VALUES,
+ LOAD_METHOD_NO_DICT,
+ LOAD_METHOD_LAZY_DICT,
+ };
+
specializing op(_SPECIALIZE_LOAD_ATTR, (counter/1, owner -- owner)) {
#if ENABLE_SPECIALIZATION_FT
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
next_instr = this_instr;
_Py_Specialize_LoadAttr(owner, next_instr, name);
DISPATCH_SAME_OPARG();
@@ -2152,50 +2175,67 @@ dummy_func(
#endif /* ENABLE_SPECIALIZATION_FT */
}
- op(_LOAD_ATTR, (owner -- attr, self_or_null if (oparg & 1))) {
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
+ specializing op(_SPECIALIZE_LOAD_METHOD, (counter/1, owner -- owner)) {
+ #if ENABLE_SPECIALIZATION_FT
+ if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
+ next_instr = this_instr;
+ _Py_Specialize_LoadMethod(owner, next_instr, name);
+ DISPATCH_SAME_OPARG();
+ }
+ OPCODE_DEFERRED_INC(LOAD_METHOD);
+ ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
+ #endif /* ENABLE_SPECIALIZATION_FT */
+ }
+
+ op(_LOAD_METHOD, (owner -- attr, self_or_null)) {
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
PyObject *attr_o;
- if (oparg & 1) {
- /* Designed to work in tandem with CALL, pushes two values. */
- attr_o = NULL;
- int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o);
- if (is_meth) {
- /* We can bypass temporary bound method object.
- meth is unbound method and obj is self.
- meth | self | arg1 | ... | argN
- */
- assert(attr_o != NULL); // No errors on this branch
- self_or_null = owner; // Transfer ownership
- DEAD(owner);
- }
- else {
- /* meth is not an unbound method (but a regular attr, or
- something was returned by a descriptor protocol). Set
- the second element of the stack to NULL, to signal
- CALL that it's not a method call.
- meth | NULL | arg1 | ... | argN
+ /* Designed to work in tandem with CALL, pushes two values. */
+ attr_o = NULL;
+ int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o);
+ if (is_meth) {
+ /* We can bypass temporary bound method object.
+ meth is unbound method and obj is self.
+ meth | self | arg1 | ... | argN
*/
- DECREF_INPUTS();
- ERROR_IF(attr_o == NULL, error);
- self_or_null = PyStackRef_NULL;
- }
+ assert(attr_o != NULL); // No errors on this branch
+ self_or_null = owner; // Transfer ownership
+ DEAD(owner);
}
else {
- /* Classic, pushes one value. */
- attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
+ /* meth is not an unbound method (but a regular attr, or
+ something was returned by a descriptor protocol). Set
+ the second element of the stack to NULL, to signal
+ CALL that it's not a method call.
+ meth | NULL | arg1 | ... | argN
+ */
DECREF_INPUTS();
ERROR_IF(attr_o == NULL, error);
- /* We need to define self_or_null on all paths */
self_or_null = PyStackRef_NULL;
}
attr = PyStackRef_FromPyObjectSteal(attr_o);
}
+ op(_LOAD_ATTR, (owner -- attr)) {
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
+ PyObject *attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
+ DECREF_INPUTS();
+ ERROR_IF(attr_o == NULL, error);
+ attr = PyStackRef_FromPyObjectSteal(attr_o);
+ }
+
macro(LOAD_ATTR) =
_SPECIALIZE_LOAD_ATTR +
unused/8 +
_LOAD_ATTR;
+
+ macro(LOAD_METHOD) =
+ _SPECIALIZE_LOAD_METHOD +
+ unused/8 +
+ _LOAD_METHOD;
+
op(_GUARD_TYPE_VERSION, (type_version/2, owner -- owner)) {
PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
assert(type_version != 0);
@@ -2220,7 +2260,7 @@ dummy_func(
DEOPT_IF(!FT_ATOMIC_LOAD_UINT8(_PyObject_InlineValues(owner_o)->valid));
}
- split op(_LOAD_ATTR_INSTANCE_VALUE, (offset/1, owner -- attr, null if (oparg & 1))) {
+ op(_LOAD_ATTR_INSTANCE_VALUE, (offset/1, owner -- attr)) {
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
PyObject **value_ptr = (PyObject**)(((char *)owner_o) + offset);
PyObject *attr_o = FT_ATOMIC_LOAD_PTR_ACQUIRE(*value_ptr);
@@ -2233,7 +2273,6 @@ dummy_func(
attr = PyStackRef_FromPyObjectNew(attr_o);
#endif
STAT_INC(LOAD_ATTR, hit);
- null = PyStackRef_NULL;
DECREF_INPUTS();
}
@@ -2254,7 +2293,7 @@ dummy_func(
mod_keys = keys;
}
- op(_LOAD_ATTR_MODULE_FROM_KEYS, (index/1, owner, mod_keys: PyDictKeysObject * -- attr, null if (oparg & 1))) {
+ op(_LOAD_ATTR_MODULE_FROM_KEYS, (index/1, owner, mod_keys: PyDictKeysObject * -- attr)) {
assert(mod_keys->dk_kind == DICT_KEYS_UNICODE);
assert(index < FT_ATOMIC_LOAD_SSIZE_RELAXED(mod_keys->dk_nentries));
PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(mod_keys) + index;
@@ -2272,7 +2311,6 @@ dummy_func(
attr = PyStackRef_FromPyObjectSteal(attr_o);
#endif
STAT_INC(LOAD_ATTR, hit);
- null = PyStackRef_NULL;
PyStackRef_CLOSE(owner);
}
@@ -2292,7 +2330,7 @@ dummy_func(
dict = dict_o;
}
- op(_LOAD_ATTR_WITH_HINT, (hint/1, owner, dict: PyDictObject * -- attr, null if (oparg & 1))) {
+ op(_LOAD_ATTR_WITH_HINT, (hint/1, owner, dict: PyDictObject * -- attr)) {
PyObject *attr_o;
if (!LOCK_OBJECT(dict)) {
POP_INPUT(dict);
@@ -2304,7 +2342,7 @@ dummy_func(
POP_INPUT(dict);
DEOPT_IF(true);
}
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) {
UNLOCK_OBJECT(dict);
POP_INPUT(dict);
@@ -2326,7 +2364,6 @@ dummy_func(
attr = PyStackRef_FromPyObjectNew(attr_o);
UNLOCK_OBJECT(dict);
DEAD(dict);
- null = PyStackRef_NULL;
DECREF_INPUTS();
}
@@ -2337,7 +2374,7 @@ dummy_func(
_LOAD_ATTR_WITH_HINT +
unused/5;
- split op(_LOAD_ATTR_SLOT, (index/1, owner -- attr, null if (oparg & 1))) {
+ op(_LOAD_ATTR_SLOT, (index/1, owner -- attr)) {
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
PyObject **addr = (PyObject **)((char *)owner_o + index);
@@ -2350,7 +2387,6 @@ dummy_func(
attr = PyStackRef_FromPyObjectNew(attr_o);
#endif
STAT_INC(LOAD_ATTR, hit);
- null = PyStackRef_NULL;
DECREF_INPUTS();
}
@@ -2368,11 +2404,10 @@ dummy_func(
EXIT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(((PyTypeObject *)owner_o)->tp_version_tag) != type_version);
}
- split op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr, null if (oparg & 1))) {
+ op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr)) {
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
attr = PyStackRef_FromPyObjectNew(descr);
- null = PyStackRef_NULL;
DECREF_INPUTS();
}
@@ -2389,7 +2424,6 @@ dummy_func(
_LOAD_ATTR_CLASS;
op(_LOAD_ATTR_PROPERTY_FRAME, (fget/4, owner -- new_frame: _PyInterpreterFrame *)) {
- assert((oparg & 1) == 0);
assert(Py_IS_TYPE(fget, &PyFunction_Type));
PyFunctionObject *f = (PyFunctionObject *)fget;
PyCodeObject *code = (PyCodeObject *)f->func_code;
@@ -2412,10 +2446,8 @@ dummy_func(
_SAVE_RETURN_OFFSET +
_PUSH_FRAME;
- inst(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, (unused/1, type_version/2, func_version/2, getattribute/4, owner -- unused, unused if (0))) {
+ inst(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, (unused/1, type_version/2, func_version/2, getattribute/4, owner -- unused)) {
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
-
- assert((oparg & 1) == 0);
DEOPT_IF(tstate->interp->eval_frame);
PyTypeObject *cls = Py_TYPE(owner_o);
assert(type_version != 0);
@@ -2429,7 +2461,7 @@ dummy_func(
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize));
STAT_INC(LOAD_ATTR, hit);
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(
tstate, PyStackRef_FromPyObjectNew(f), 2, frame);
// Manipulate stack directly because we exit with DISPATCH_INLINED().
@@ -3348,8 +3380,7 @@ dummy_func(
DEOPT_IF(FT_ATOMIC_LOAD_UINT32_RELAXED(keys->dk_version) != keys_version);
}
- split op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self if (1))) {
- assert(oparg & 1);
+ op(_LOAD_METHOD_WITH_VALUES, (descr/4, owner -- attr, self)) {
/* Cached method object */
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
@@ -3359,15 +3390,14 @@ dummy_func(
DEAD(owner);
}
- macro(LOAD_ATTR_METHOD_WITH_VALUES) =
+ macro(LOAD_METHOD_WITH_VALUES) =
unused/1 +
_GUARD_TYPE_VERSION +
_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT +
_GUARD_KEYS_VERSION +
- _LOAD_ATTR_METHOD_WITH_VALUES;
+ _LOAD_METHOD_WITH_VALUES;
- op(_LOAD_ATTR_METHOD_NO_DICT, (descr/4, owner -- attr, self if (1))) {
- assert(oparg & 1);
+ op(_LOAD_METHOD_NO_DICT, (descr/4, owner -- attr, self)) {
assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
@@ -3377,14 +3407,13 @@ dummy_func(
DEAD(owner);
}
- macro(LOAD_ATTR_METHOD_NO_DICT) =
+ macro(LOAD_METHOD_NO_DICT) =
unused/1 +
_GUARD_TYPE_VERSION +
unused/2 +
- _LOAD_ATTR_METHOD_NO_DICT;
+ _LOAD_METHOD_NO_DICT;
- op(_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, (descr/4, owner -- attr, unused if (0))) {
- assert((oparg & 1) == 0);
+ op(_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, (descr/4, owner -- attr)) {
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
DECREF_INPUTS();
@@ -3398,8 +3427,7 @@ dummy_func(
_GUARD_KEYS_VERSION +
_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES;
- op(_LOAD_ATTR_NONDESCRIPTOR_NO_DICT, (descr/4, owner -- attr, unused if (0))) {
- assert((oparg & 1) == 0);
+ op(_LOAD_ATTR_NONDESCRIPTOR_NO_DICT, (descr/4, owner -- attr)) {
assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
@@ -3420,8 +3448,7 @@ dummy_func(
DEOPT_IF(dict != NULL);
}
- op(_LOAD_ATTR_METHOD_LAZY_DICT, (descr/4, owner -- attr, self if (1))) {
- assert(oparg & 1);
+ op(_LOAD_METHOD_LAZY_DICT, (descr/4, owner -- attr, self)) {
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
@@ -3430,12 +3457,12 @@ dummy_func(
DEAD(owner);
}
- macro(LOAD_ATTR_METHOD_LAZY_DICT) =
+ macro(LOAD_METHOD_LAZY_DICT) =
unused/1 +
_GUARD_TYPE_VERSION +
_CHECK_ATTR_METHOD_LAZY_DICT +
unused/1 +
- _LOAD_ATTR_METHOD_LAZY_DICT;
+ _LOAD_METHOD_LAZY_DICT;
// Cache layout: counter/1, func_version/2
// CALL_INTRINSIC_1/2, CALL_KW, and CALL_FUNCTION_EX aren't members!
@@ -4537,7 +4564,7 @@ dummy_func(
GO_TO_INSTRUCTION(CALL_FUNCTION_EX);
}
- op(_MAKE_CALLARGS_A_TUPLE, (func, unused, callargs, kwargs_in if (oparg & 1) -- func, unused, tuple, kwargs_out if (oparg & 1))) {
+ op(_MAKE_CALLARGS_A_TUPLE, (func, unused, callargs, kwargs_in -- func, unused, tuple, kwargs_out)) {
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
if (PyTuple_CheckExact(callargs_o)) {
tuple = callargs;
@@ -4561,7 +4588,7 @@ dummy_func(
}
}
- op(_DO_CALL_FUNCTION_EX, (func_st, unused, callargs_st, kwargs_st if (oparg & 1) -- result)) {
+ op(_DO_CALL_FUNCTION_EX, (func_st, unused, callargs_st, kwargs_st -- result)) {
PyObject *func = PyStackRef_AsPyObjectBorrow(func_st);
// DICT_MERGE is called before this opcode if there are kwargs.
@@ -4695,11 +4722,16 @@ dummy_func(
LLTRACE_RESUME_FRAME();
}
- inst(BUILD_SLICE, (start, stop, step if (oparg == 3) -- slice)) {
+ inst(BUILD_SLICE, (args[oparg] -- slice)) {
+ assert(oparg == 2 || oparg == 3);
+ _PyStackRef start = args[0];
+ _PyStackRef stop = args[1];
PyObject *start_o = PyStackRef_AsPyObjectBorrow(start);
PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop);
- PyObject *step_o = PyStackRef_AsPyObjectBorrow(step);
-
+ PyObject * step_o = NULL;
+ if (oparg == 3) {
+ step_o = PyStackRef_AsPyObjectBorrow(args[2]);
+ }
PyObject *slice_o = PySlice_New(start_o, stop_o, step_o);
DECREF_INPUTS();
ERROR_IF(slice_o == NULL, error);
@@ -5041,27 +5073,25 @@ dummy_func(
DEOPT_IF(func->func_version != func_version);
}
- tier2 op(_LOAD_GLOBAL_MODULE, (index/1 -- res, null if (oparg & 1))) {
+ tier2 op(_LOAD_GLOBAL_MODULE, (index/1 -- res)) {
PyDictObject *dict = (PyDictObject *)GLOBALS();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
PyObject *res_o = entries[index].me_value;
DEOPT_IF(res_o == NULL);
Py_INCREF(res_o);
res = PyStackRef_FromPyObjectSteal(res_o);
- null = PyStackRef_NULL;
}
- tier2 op(_LOAD_GLOBAL_BUILTINS, (index/1 -- res, null if (oparg & 1))) {
+ tier2 op(_LOAD_GLOBAL_BUILTINS, (index/1 -- res)) {
PyDictObject *dict = (PyDictObject *)BUILTINS();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
PyObject *res_o = entries[index].me_value;
DEOPT_IF(res_o == NULL);
Py_INCREF(res_o);
res = PyStackRef_FromPyObjectSteal(res_o);
- null = PyStackRef_NULL;
}
- tier2 op(_LOAD_ATTR_MODULE, (index/1, owner -- attr, null if (oparg & 1))) {
+ tier2 op(_LOAD_ATTR_MODULE, (index/1, owner -- attr)) {
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner_o)->md_dict;
assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE);
@@ -5072,7 +5102,6 @@ dummy_func(
STAT_INC(LOAD_ATTR, hit);
Py_INCREF(attr_o);
attr = PyStackRef_FromPyObjectSteal(attr_o);
- null = PyStackRef_NULL;
DECREF_INPUTS();
}
diff --git a/Python/codegen.c b/Python/codegen.c
index 61707ba677097c..b3f845569684de 100644
--- a/Python/codegen.c
+++ b/Python/codegen.c
@@ -348,8 +348,6 @@ codegen_addop_o(compiler *c, location loc,
RETURN_IF_ERROR_IN_SCOPE((C), ret); \
} while (0)
-#define LOAD_METHOD -1
-#define LOAD_SUPER_METHOD -2
#define LOAD_ZERO_SUPER_ATTR -3
#define LOAD_ZERO_SUPER_METHOD -4
@@ -366,20 +364,11 @@ codegen_addop_name(compiler *c, location loc,
if (arg < 0) {
return ERROR;
}
- if (opcode == LOAD_ATTR) {
- arg <<= 1;
- }
- if (opcode == LOAD_METHOD) {
- opcode = LOAD_ATTR;
- arg <<= 1;
- arg |= 1;
- }
if (opcode == LOAD_SUPER_ATTR) {
arg <<= 2;
arg |= 2;
}
if (opcode == LOAD_SUPER_METHOD) {
- opcode = LOAD_SUPER_ATTR;
arg <<= 2;
arg |= 3;
}
@@ -388,7 +377,7 @@ codegen_addop_name(compiler *c, location loc,
arg <<= 2;
}
if (opcode == LOAD_ZERO_SUPER_METHOD) {
- opcode = LOAD_SUPER_ATTR;
+ opcode = LOAD_SUPER_METHOD;
arg <<= 2;
arg |= 1;
}
@@ -3165,9 +3154,6 @@ codegen_nameop(compiler *c, location loc,
assert(op);
Py_DECREF(mangled);
- if (op == LOAD_GLOBAL) {
- arg <<= 1;
- }
ADDOP_I(c, loc, op, arg);
return SUCCESS;
@@ -4108,7 +4094,10 @@ codegen_call_helper_impl(compiler *c, location loc,
}
assert(have_dict);
}
- ADDOP_I(c, loc, CALL_FUNCTION_EX, nkwelts > 0);
+ if (nkwelts == 0) {
+ ADDOP(c, loc, PUSH_NULL);
+ }
+ ADDOP(c, loc, CALL_FUNCTION_EX);
return SUCCESS;
}
@@ -4841,8 +4830,10 @@ codegen_async_with(compiler *c, stmt_ty s, int pos)
SETUP_WITH E
<code to store to VAR> or POP_TOP
<code for BLOCK>
- LOAD_CONST (None, None, None)
- CALL_FUNCTION_EX 0
+ LOAD_CONST None
+ LOAD_CONST None
+ LOAD_CONST None
+ CALL 3
JUMP EXIT
E: WITH_EXCEPT_START (calls EXPR.__exit__)
POP_JUMP_IF_TRUE T:
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index e2eaca2c90fa76..049073162b6c5f 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -406,9 +406,9 @@
}
case _PUSH_NULL: {
- _PyStackRef res;
- res = PyStackRef_NULL;
- stack_pointer[0] = res;
+ _PyStackRef null;
+ null = PyStackRef_NULL;
+ stack_pointer[0] = null;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
break;
@@ -1957,17 +1957,14 @@
case _LOAD_GLOBAL: {
_PyStackRef *res;
- _PyStackRef null = PyStackRef_NULL;
oparg = CURRENT_OPARG();
res = &stack_pointer[0];
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
_PyFrame_SetStackPointer(frame, stack_pointer);
_PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (PyStackRef_IsNull(*res)) JUMP_TO_ERROR();
- null = PyStackRef_NULL;
- if (oparg & 1) stack_pointer[1] = null;
- stack_pointer += 1 + (oparg & 1);
+ stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
break;
}
@@ -2033,8 +2030,6 @@
case _LOAD_GLOBAL_MODULE_FROM_KEYS: {
PyDictKeysObject *globals_keys;
_PyStackRef res;
- _PyStackRef null = PyStackRef_NULL;
- oparg = CURRENT_OPARG();
globals_keys = (PyDictKeysObject *)stack_pointer[-1].bits;
uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(globals_keys);
@@ -2056,10 +2051,8 @@
res = PyStackRef_FromPyObjectSteal(res_o);
#endif
STAT_INC(LOAD_GLOBAL, hit);
- null = PyStackRef_NULL;
stack_pointer[0] = res;
- if (oparg & 1) stack_pointer[1] = null;
- stack_pointer += 1 + (oparg & 1);
+ stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
break;
}
@@ -2067,8 +2060,6 @@
case _LOAD_GLOBAL_BUILTINS_FROM_KEYS: {
PyDictKeysObject *builtins_keys;
_PyStackRef res;
- _PyStackRef null = PyStackRef_NULL;
- oparg = CURRENT_OPARG();
builtins_keys = (PyDictKeysObject *)stack_pointer[-1].bits;
uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(builtins_keys);
@@ -2090,10 +2081,8 @@
res = PyStackRef_FromPyObjectSteal(res_o);
#endif
STAT_INC(LOAD_GLOBAL, hit);
- null = PyStackRef_NULL;
stack_pointer[0] = res;
- if (oparg & 1) stack_pointer[1] = null;
- stack_pointer += 1 + (oparg & 1);
+ stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
break;
}
@@ -2519,6 +2508,8 @@
/* _INSTRUMENTED_LOAD_SUPER_ATTR is not a viable micro-op for tier 2 because it is instrumented */
+ /* _INSTRUMENTED_LOAD_SUPER_METHOD is not a viable micro-op for tier 2 because it is instrumented */
+
case _LOAD_SUPER_ATTR_ATTR: {
_PyStackRef self_st;
_PyStackRef class_st;
@@ -2556,7 +2547,7 @@
break;
}
- case _LOAD_SUPER_ATTR_METHOD: {
+ case _LOAD_SUPER_METHOD_METHOD: {
_PyStackRef self_st;
_PyStackRef class_st;
_PyStackRef global_super_st;
@@ -2605,58 +2596,62 @@
break;
}
- case _LOAD_ATTR: {
+ case _LOAD_METHOD: {
_PyStackRef owner;
_PyStackRef attr;
- _PyStackRef self_or_null = PyStackRef_NULL;
+ _PyStackRef self_or_null;
oparg = CURRENT_OPARG();
owner = stack_pointer[-1];
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
PyObject *attr_o;
- if (oparg & 1) {
- /* Designed to work in tandem with CALL, pushes two values. */
- attr_o = NULL;
- _PyFrame_SetStackPointer(frame, stack_pointer);
- int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- if (is_meth) {
- /* We can bypass temporary bound method object.
- meth is unbound method and obj is self.
- meth | self | arg1 | ... | argN
- */
- assert(attr_o != NULL); // No errors on this branch
- self_or_null = owner; // Transfer ownership
- }
- else {
- /* meth is not an unbound method (but a regular attr, or
- something was returned by a descriptor protocol). Set
- the second element of the stack to NULL, to signal
- CALL that it's not a method call.
- meth | NULL | arg1 | ... | argN
- */
- PyStackRef_CLOSE(owner);
- if (attr_o == NULL) JUMP_TO_ERROR();
- self_or_null = PyStackRef_NULL;
- }
+ /* Designed to work in tandem with CALL, pushes two values. */
+ attr_o = NULL;
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ if (is_meth) {
+ /* We can bypass temporary bound method object.
+ meth is unbound method and obj is self.
+ meth | self | arg1 | ... | argN
+ */
+ assert(attr_o != NULL); // No errors on this branch
+ self_or_null = owner; // Transfer ownership
}
else {
- /* Classic, pushes one value. */
- _PyFrame_SetStackPointer(frame, stack_pointer);
- attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
- stack_pointer = _PyFrame_GetStackPointer(frame);
+ /* meth is not an unbound method (but a regular attr, or
+ something was returned by a descriptor protocol). Set
+ the second element of the stack to NULL, to signal
+ CALL that it's not a method call.
+ meth | NULL | arg1 | ... | argN
+ */
PyStackRef_CLOSE(owner);
if (attr_o == NULL) JUMP_TO_ERROR();
- /* We need to define self_or_null on all paths */
self_or_null = PyStackRef_NULL;
}
attr = PyStackRef_FromPyObjectSteal(attr_o);
stack_pointer[-1] = attr;
- if (oparg & 1) stack_pointer[0] = self_or_null;
- stack_pointer += (oparg & 1);
+ stack_pointer[0] = self_or_null;
+ stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
break;
}
+ case _LOAD_ATTR: {
+ _PyStackRef owner;
+ _PyStackRef attr;
+ oparg = CURRENT_OPARG();
+ owner = stack_pointer[-1];
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyObject *attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ PyStackRef_CLOSE(owner);
+ if (attr_o == NULL) JUMP_TO_ERROR();
+ attr = PyStackRef_FromPyObjectSteal(attr_o);
+ stack_pointer[-1] = attr;
+ break;
+ }
+
case _GUARD_TYPE_VERSION: {
_PyStackRef owner;
owner = stack_pointer[-1];
@@ -2704,42 +2699,9 @@
break;
}
- case _LOAD_ATTR_INSTANCE_VALUE_0: {
- _PyStackRef owner;
- _PyStackRef attr;
- _PyStackRef null = PyStackRef_NULL;
- (void)null;
- owner = stack_pointer[-1];
- uint16_t offset = (uint16_t)CURRENT_OPERAND0();
- PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
- PyObject **value_ptr = (PyObject**)(((char *)owner_o) + offset);
- PyObject *attr_o = FT_ATOMIC_LOAD_PTR_ACQUIRE(*value_ptr);
- if (attr_o == NULL) {
- UOP_STAT_INC(uopcode, miss);
- JUMP_TO_JUMP_TARGET();
- }
- #ifdef Py_GIL_DISABLED
- if (!_Py_TryIncrefCompareStackRef(value_ptr, attr_o, &attr)) {
- if (true) {
- UOP_STAT_INC(uopcode, miss);
- JUMP_TO_JUMP_TARGET();
- }
- }
- #else
- attr = PyStackRef_FromPyObjectNew(attr_o);
- #endif
- STAT_INC(LOAD_ATTR, hit);
- null = PyStackRef_NULL;
- PyStackRef_CLOSE(owner);
- stack_pointer[-1] = attr;
- break;
- }
-
- case _LOAD_ATTR_INSTANCE_VALUE_1: {
+ case _LOAD_ATTR_INSTANCE_VALUE: {
_PyStackRef owner;
_PyStackRef attr;
- _PyStackRef null = PyStackRef_NULL;
- (void)null;
owner = stack_pointer[-1];
uint16_t offset = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
@@ -2760,17 +2722,11 @@
attr = PyStackRef_FromPyObjectNew(attr_o);
#endif
STAT_INC(LOAD_ATTR, hit);
- null = PyStackRef_NULL;
PyStackRef_CLOSE(owner);
stack_pointer[-1] = attr;
- stack_pointer[0] = null;
- stack_pointer += 1;
- assert(WITHIN_STACK_BOUNDS());
break;
}
- /* _LOAD_ATTR_INSTANCE_VALUE is split on (oparg & 1) */
-
case _CHECK_ATTR_MODULE_PUSH_KEYS: {
_PyStackRef owner;
PyDictKeysObject *mod_keys;
@@ -2799,8 +2755,6 @@
PyDictKeysObject *mod_keys;
_PyStackRef owner;
_PyStackRef attr;
- _PyStackRef null = PyStackRef_NULL;
- oparg = CURRENT_OPARG();
mod_keys = (PyDictKeysObject *)stack_pointer[-1].bits;
owner = stack_pointer[-2];
uint16_t index = (uint16_t)CURRENT_OPERAND0();
@@ -2828,12 +2782,8 @@
attr = PyStackRef_FromPyObjectSteal(attr_o);
#endif
STAT_INC(LOAD_ATTR, hit);
- null = PyStackRef_NULL;
PyStackRef_CLOSE(owner);
stack_pointer[-1] = attr;
- if (oparg & 1) stack_pointer[0] = null;
- stack_pointer += (oparg & 1);
- assert(WITHIN_STACK_BOUNDS());
break;
}
@@ -2860,7 +2810,6 @@
PyDictObject *dict;
_PyStackRef owner;
_PyStackRef attr;
- _PyStackRef null = PyStackRef_NULL;
oparg = CURRENT_OPARG();
dict = (PyDictObject *)stack_pointer[-1].bits;
owner = stack_pointer[-2];
@@ -2883,7 +2832,7 @@
JUMP_TO_JUMP_TARGET();
}
}
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) {
UNLOCK_OBJECT(dict);
stack_pointer += -1;
@@ -2916,20 +2865,16 @@
STAT_INC(LOAD_ATTR, hit);
attr = PyStackRef_FromPyObjectNew(attr_o);
UNLOCK_OBJECT(dict);
- null = PyStackRef_NULL;
PyStackRef_CLOSE(owner);
stack_pointer[-2] = attr;
- if (oparg & 1) stack_pointer[-1] = null;
- stack_pointer += -1 + (oparg & 1);
+ stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
break;
}
- case _LOAD_ATTR_SLOT_0: {
+ case _LOAD_ATTR_SLOT: {
_PyStackRef owner;
_PyStackRef attr;
- _PyStackRef null = PyStackRef_NULL;
- (void)null;
owner = stack_pointer[-1];
uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
@@ -2949,47 +2894,11 @@
attr = PyStackRef_FromPyObjectNew(attr_o);
#endif
STAT_INC(LOAD_ATTR, hit);
- null = PyStackRef_NULL;
PyStackRef_CLOSE(owner);
stack_pointer[-1] = attr;
break;
}
- case _LOAD_ATTR_SLOT_1: {
- _PyStackRef owner;
- _PyStackRef attr;
- _PyStackRef null = PyStackRef_NULL;
- (void)null;
- owner = stack_pointer[-1];
- uint16_t index = (uint16_t)CURRENT_OPERAND0();
- PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
- PyObject **addr = (PyObject **)((char *)owner_o + index);
- PyObject *attr_o = FT_ATOMIC_LOAD_PTR(*addr);
- if (attr_o == NULL) {
- UOP_STAT_INC(uopcode, miss);
- JUMP_TO_JUMP_TARGET();
- }
- #ifdef Py_GIL_DISABLED
- int increfed = _Py_TryIncrefCompareStackRef(addr, attr_o, &attr);
- if (!increfed) {
- UOP_STAT_INC(uopcode, miss);
- JUMP_TO_JUMP_TARGET();
- }
- #else
- attr = PyStackRef_FromPyObjectNew(attr_o);
- #endif
- STAT_INC(LOAD_ATTR, hit);
- null = PyStackRef_NULL;
- PyStackRef_CLOSE(owner);
- stack_pointer[-1] = attr;
- stack_pointer[0] = null;
- stack_pointer += 1;
- assert(WITHIN_STACK_BOUNDS());
- break;
- }
-
- /* _LOAD_ATTR_SLOT is split on (oparg & 1) */
-
case _CHECK_ATTR_CLASS: {
_PyStackRef owner;
owner = stack_pointer[-1];
@@ -3007,50 +2916,24 @@
break;
}
- case _LOAD_ATTR_CLASS_0: {
+ case _LOAD_ATTR_CLASS: {
_PyStackRef owner;
_PyStackRef attr;
- _PyStackRef null = PyStackRef_NULL;
- (void)null;
owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND0();
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
attr = PyStackRef_FromPyObjectNew(descr);
- null = PyStackRef_NULL;
PyStackRef_CLOSE(owner);
stack_pointer[-1] = attr;
break;
}
- case _LOAD_ATTR_CLASS_1: {
- _PyStackRef owner;
- _PyStackRef attr;
- _PyStackRef null = PyStackRef_NULL;
- (void)null;
- owner = stack_pointer[-1];
- PyObject *descr = (PyObject *)CURRENT_OPERAND0();
- STAT_INC(LOAD_ATTR, hit);
- assert(descr != NULL);
- attr = PyStackRef_FromPyObjectNew(descr);
- null = PyStackRef_NULL;
- PyStackRef_CLOSE(owner);
- stack_pointer[-1] = attr;
- stack_pointer[0] = null;
- stack_pointer += 1;
- assert(WITHIN_STACK_BOUNDS());
- break;
- }
-
- /* _LOAD_ATTR_CLASS is split on (oparg & 1) */
-
case _LOAD_ATTR_PROPERTY_FRAME: {
_PyStackRef owner;
_PyInterpreterFrame *new_frame;
- oparg = CURRENT_OPARG();
owner = stack_pointer[-1];
PyObject *fget = (PyObject *)CURRENT_OPERAND0();
- assert((oparg & 1) == 0);
assert(Py_IS_TYPE(fget, &PyFunction_Type));
PyFunctionObject *f = (PyFunctionObject *)fget;
PyCodeObject *code = (PyCodeObject *)f->func_code;
@@ -4056,14 +3939,12 @@
break;
}
- case _LOAD_ATTR_METHOD_WITH_VALUES: {
+ case _LOAD_METHOD_WITH_VALUES: {
_PyStackRef owner;
_PyStackRef attr;
- _PyStackRef self = PyStackRef_NULL;
- oparg = CURRENT_OPARG();
+ _PyStackRef self;
owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND0();
- assert(oparg & 1);
/* Cached method object */
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
@@ -4077,14 +3958,12 @@
break;
}
- case _LOAD_ATTR_METHOD_NO_DICT: {
+ case _LOAD_METHOD_NO_DICT: {
_PyStackRef owner;
_PyStackRef attr;
- _PyStackRef self = PyStackRef_NULL;
- oparg = CURRENT_OPARG();
+ _PyStackRef self;
owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND0();
- assert(oparg & 1);
assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
@@ -4101,10 +3980,8 @@
case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: {
_PyStackRef owner;
_PyStackRef attr;
- oparg = CURRENT_OPARG();
owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND0();
- assert((oparg & 1) == 0);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
PyStackRef_CLOSE(owner);
@@ -4116,10 +3993,8 @@
case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT: {
_PyStackRef owner;
_PyStackRef attr;
- oparg = CURRENT_OPARG();
owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND0();
- assert((oparg & 1) == 0);
assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
@@ -4143,14 +4018,12 @@
break;
}
- case _LOAD_ATTR_METHOD_LAZY_DICT: {
+ case _LOAD_METHOD_LAZY_DICT: {
_PyStackRef owner;
_PyStackRef attr;
- _PyStackRef self = PyStackRef_NULL;
- oparg = CURRENT_OPARG();
+ _PyStackRef self;
owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND0();
- assert(oparg & 1);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
@@ -5644,15 +5517,14 @@
/* _INSTRUMENTED_CALL_FUNCTION_EX is not a viable micro-op for tier 2 because it is instrumented */
case _MAKE_CALLARGS_A_TUPLE: {
- _PyStackRef kwargs_in = PyStackRef_NULL;
+ _PyStackRef kwargs_in;
_PyStackRef callargs;
_PyStackRef func;
_PyStackRef tuple;
- _PyStackRef kwargs_out = PyStackRef_NULL;
- oparg = CURRENT_OPARG();
- if (oparg & 1) { kwargs_in = stack_pointer[-(oparg & 1)]; }
- callargs = stack_pointer[-1 - (oparg & 1)];
- func = stack_pointer[-3 - (oparg & 1)];
+ _PyStackRef kwargs_out;
+ kwargs_in = stack_pointer[-1];
+ callargs = stack_pointer[-2];
+ func = stack_pointer[-4];
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
if (PyTuple_CheckExact(callargs_o)) {
tuple = callargs;
@@ -5675,8 +5547,8 @@
PyStackRef_CLOSE(callargs);
tuple = PyStackRef_FromPyObjectSteal(tuple_o);
}
- stack_pointer[-1 - (oparg & 1)] = tuple;
- if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_out;
+ stack_pointer[-2] = tuple;
+ stack_pointer[-1] = kwargs_out;
break;
}
@@ -5753,25 +5625,27 @@
}
case _BUILD_SLICE: {
- _PyStackRef step = PyStackRef_NULL;
- _PyStackRef stop;
- _PyStackRef start;
+ _PyStackRef *args;
_PyStackRef slice;
oparg = CURRENT_OPARG();
- if (oparg == 3) { step = stack_pointer[-((oparg == 3) ? 1 : 0)]; }
- stop = stack_pointer[-1 - ((oparg == 3) ? 1 : 0)];
- start = stack_pointer[-2 - ((oparg == 3) ? 1 : 0)];
+ args = &stack_pointer[-oparg];
+ assert(oparg == 2 || oparg == 3);
+ _PyStackRef start = args[0];
+ _PyStackRef stop = args[1];
PyObject *start_o = PyStackRef_AsPyObjectBorrow(start);
PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop);
- PyObject *step_o = PyStackRef_AsPyObjectBorrow(step);
+ PyObject * step_o = NULL;
+ if (oparg == 3) {
+ step_o = PyStackRef_AsPyObjectBorrow(args[2]);
+ }
PyObject *slice_o = PySlice_New(start_o, stop_o, step_o);
- PyStackRef_CLOSE(start);
- PyStackRef_CLOSE(stop);
- PyStackRef_XCLOSE(step);
+ for (int _i = oparg; --_i >= 0;) {
+ PyStackRef_CLOSE(args[_i]);
+ }
if (slice_o == NULL) JUMP_TO_ERROR();
slice = PyStackRef_FromPyObjectSteal(slice_o);
- stack_pointer[-2 - ((oparg == 3) ? 1 : 0)] = slice;
- stack_pointer += -1 - ((oparg == 3) ? 1 : 0);
+ stack_pointer[-oparg] = slice;
+ stack_pointer += 1 - oparg;
assert(WITHIN_STACK_BOUNDS());
break;
}
@@ -6138,8 +6012,6 @@
case _LOAD_GLOBAL_MODULE: {
_PyStackRef res;
- _PyStackRef null = PyStackRef_NULL;
- oparg = CURRENT_OPARG();
uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyDictObject *dict = (PyDictObject *)GLOBALS();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
@@ -6150,18 +6022,14 @@
}
Py_INCREF(res_o);
res = PyStackRef_FromPyObjectSteal(res_o);
- null = PyStackRef_NULL;
stack_pointer[0] = res;
- if (oparg & 1) stack_pointer[1] = null;
- stack_pointer += 1 + (oparg & 1);
+ stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
break;
}
case _LOAD_GLOBAL_BUILTINS: {
_PyStackRef res;
- _PyStackRef null = PyStackRef_NULL;
- oparg = CURRENT_OPARG();
uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyDictObject *dict = (PyDictObject *)BUILTINS();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
@@ -6172,10 +6040,8 @@
}
Py_INCREF(res_o);
res = PyStackRef_FromPyObjectSteal(res_o);
- null = PyStackRef_NULL;
stack_pointer[0] = res;
- if (oparg & 1) stack_pointer[1] = null;
- stack_pointer += 1 + (oparg & 1);
+ stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
break;
}
@@ -6183,8 +6049,6 @@
case _LOAD_ATTR_MODULE: {
_PyStackRef owner;
_PyStackRef attr;
- _PyStackRef null = PyStackRef_NULL;
- oparg = CURRENT_OPARG();
owner = stack_pointer[-1];
uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
@@ -6200,12 +6064,8 @@
STAT_INC(LOAD_ATTR, hit);
Py_INCREF(attr_o);
attr = PyStackRef_FromPyObjectSteal(attr_o);
- null = PyStackRef_NULL;
PyStackRef_CLOSE(owner);
stack_pointer[-1] = attr;
- if (oparg & 1) stack_pointer[0] = null;
- stack_pointer += (oparg & 1);
- assert(WITHIN_STACK_BOUNDS());
break;
}
diff --git a/Python/flowgraph.c b/Python/flowgraph.c
index 24561c1ee04db9..3f8d9db166ff98 100644
--- a/Python/flowgraph.c
+++ b/Python/flowgraph.c
@@ -1836,12 +1836,6 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
INSTR_SET_OP0(inst, NOP);
}
break;
- case LOAD_GLOBAL:
- if (nextop == PUSH_NULL && (oparg & 1) == 0) {
- INSTR_SET_OP1(inst, LOAD_GLOBAL, oparg | 1);
- INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
- }
- break;
case COMPARE_OP:
if (nextop == TO_BOOL) {
INSTR_SET_OP0(inst, NOP);
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index dc90f75f2645e1..ec3397e1cf6e5f 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -835,28 +835,30 @@
frame->instr_ptr = next_instr;
next_instr += 1;
INSTRUCTION_STATS(BUILD_SLICE);
- _PyStackRef start;
- _PyStackRef stop;
- _PyStackRef step = PyStackRef_NULL;
+ _PyStackRef *args;
_PyStackRef slice;
- if (oparg == 3) { step = stack_pointer[-((oparg == 3) ? 1 : 0)]; }
- stop = stack_pointer[-1 - ((oparg == 3) ? 1 : 0)];
- start = stack_pointer[-2 - ((oparg == 3) ? 1 : 0)];
+ args = &stack_pointer[-oparg];
+ assert(oparg == 2 || oparg == 3);
+ _PyStackRef start = args[0];
+ _PyStackRef stop = args[1];
PyObject *start_o = PyStackRef_AsPyObjectBorrow(start);
PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop);
- PyObject *step_o = PyStackRef_AsPyObjectBorrow(step);
+ PyObject * step_o = NULL;
+ if (oparg == 3) {
+ step_o = PyStackRef_AsPyObjectBorrow(args[2]);
+ }
PyObject *slice_o = PySlice_New(start_o, stop_o, step_o);
- PyStackRef_CLOSE(start);
- PyStackRef_CLOSE(stop);
- PyStackRef_XCLOSE(step);
+ for (int _i = oparg; --_i >= 0;) {
+ PyStackRef_CLOSE(args[_i]);
+ }
if (slice_o == NULL) {
- stack_pointer += -2 - ((oparg == 3) ? 1 : 0);
+ stack_pointer += -oparg;
assert(WITHIN_STACK_BOUNDS());
goto error;
}
slice = PyStackRef_FromPyObjectSteal(slice_o);
- stack_pointer[-2 - ((oparg == 3) ? 1 : 0)] = slice;
- stack_pointer += -1 - ((oparg == 3) ? 1 : 0);
+ stack_pointer[-oparg] = slice;
+ stack_pointer += 1 - oparg;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@@ -1710,18 +1712,18 @@
(void)this_instr;
_PyStackRef func;
_PyStackRef callargs;
- _PyStackRef kwargs_in = PyStackRef_NULL;
+ _PyStackRef kwargs_in;
_PyStackRef tuple;
- _PyStackRef kwargs_out = PyStackRef_NULL;
+ _PyStackRef kwargs_out;
_PyStackRef func_st;
_PyStackRef callargs_st;
- _PyStackRef kwargs_st = PyStackRef_NULL;
+ _PyStackRef kwargs_st;
_PyStackRef result;
// _MAKE_CALLARGS_A_TUPLE
{
- if (oparg & 1) { kwargs_in = stack_pointer[-(oparg & 1)]; }
- callargs = stack_pointer[-1 - (oparg & 1)];
- func = stack_pointer[-3 - (oparg & 1)];
+ kwargs_in = stack_pointer[-1];
+ callargs = stack_pointer[-2];
+ func = stack_pointer[-4];
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
if (PyTuple_CheckExact(callargs_o)) {
tuple = callargs;
@@ -1763,8 +1765,8 @@
assert(PyTuple_CheckExact(callargs));
PyObject *arg = PyTuple_GET_SIZE(callargs) > 0 ?
PyTuple_GET_ITEM(callargs, 0) : &_PyInstrumentation_MISSING;
- stack_pointer[-1 - (oparg & 1)] = callargs_st;
- if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_st;
+ stack_pointer[-2] = callargs_st;
+ stack_pointer[-1] = kwargs_st;
_PyFrame_SetStackPointer(frame, stack_pointer);
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_CALL,
@@ -1807,7 +1809,7 @@
Py_ssize_t nargs = PyTuple_GET_SIZE(callargs);
int code_flags = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_flags;
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(func));
- stack_pointer += -2 - (oparg & 1);
+ stack_pointer += -3;
assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer);
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit_Ex(
@@ -1828,8 +1830,8 @@
assert(PyTuple_CheckExact(callargs));
PyObject *kwargs = PyStackRef_AsPyObjectBorrow(kwargs_st);
assert(kwargs == NULL || PyDict_CheckExact(kwargs));
- stack_pointer[-1 - (oparg & 1)] = callargs_st;
- if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_st;
+ stack_pointer[-2] = callargs_st;
+ stack_pointer[-1] = kwargs_st;
_PyFrame_SetStackPointer(frame, stack_pointer);
result_o = PyObject_Call(func, callargs, kwargs);
stack_pointer = _PyFrame_GetStackPointer(frame);
@@ -1839,11 +1841,7 @@
stack_pointer = _PyFrame_GetStackPointer(frame);
PyStackRef_CLOSE(callargs_st);
PyStackRef_CLOSE(func_st);
- if (result_o == NULL) {
- stack_pointer += -3 - (oparg & 1);
- assert(WITHIN_STACK_BOUNDS());
- goto error;
- }
+ if (result_o == NULL) goto pop_4_error;
result = PyStackRef_FromPyObjectSteal(result_o);
}
// _CHECK_PERIODIC
@@ -1851,19 +1849,19 @@
_Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY();
QSBR_QUIESCENT_STATE(tstate);
if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) {
- stack_pointer[-3 - (oparg & 1)] = result;
- stack_pointer += -2 - (oparg & 1);
+ stack_pointer[-4] = result;
+ stack_pointer += -3;
assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer);
int err = _Py_HandlePending(tstate);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err != 0) goto error;
- stack_pointer += 2 + (oparg & 1);
+ stack_pointer += 3;
assert(WITHIN_STACK_BOUNDS());
}
}
- stack_pointer[-3 - (oparg & 1)] = result;
- stack_pointer += -2 - (oparg & 1);
+ stack_pointer[-4] = result;
+ stack_pointer += -3;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@@ -4850,6 +4848,18 @@
GO_TO_INSTRUCTION(LOAD_SUPER_ATTR);
}
+ TARGET(INSTRUMENTED_LOAD_SUPER_METHOD) {
+ _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
+ (void)this_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(INSTRUMENTED_LOAD_SUPER_METHOD);
+ /* Skip 1 cache entry */
+ // cancel out the decrement that will happen in LOAD_SUPER_ATTR; we
+ // don't want to specialize instrumented instructions
+ PAUSE_ADAPTIVE_COUNTER(this_instr[1].counter);
+ GO_TO_INSTRUCTION(LOAD_SUPER_METHOD);
+ }
+
TARGET(INSTRUMENTED_NOT_TAKEN) {
_Py_CODEUNIT* const prev_instr = frame->instr_ptr;
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
@@ -5307,7 +5317,6 @@
(void)this_instr;
_PyStackRef owner;
_PyStackRef attr;
- _PyStackRef self_or_null = PyStackRef_NULL;
// _SPECIALIZE_LOAD_ATTR
{
owner = stack_pointer[-1];
@@ -5315,7 +5324,7 @@
(void)counter;
#if ENABLE_SPECIALIZATION_FT
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
next_instr = this_instr;
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_LoadAttr(owner, next_instr, name);
@@ -5329,50 +5338,15 @@
/* Skip 8 cache entries */
// _LOAD_ATTR
{
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
- PyObject *attr_o;
- if (oparg & 1) {
- /* Designed to work in tandem with CALL, pushes two values. */
- attr_o = NULL;
- _PyFrame_SetStackPointer(frame, stack_pointer);
- int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- if (is_meth) {
- /* We can bypass temporary bound method object.
- meth is unbound method and obj is self.
- meth | self | arg1 | ... | argN
- */
- assert(attr_o != NULL); // No errors on this branch
- self_or_null = owner; // Transfer ownership
- }
- else {
- /* meth is not an unbound method (but a regular attr, or
- something was returned by a descriptor protocol). Set
- the second element of the stack to NULL, to signal
- CALL that it's not a method call.
- meth | NULL | arg1 | ... | argN
- */
- PyStackRef_CLOSE(owner);
- if (attr_o == NULL) goto pop_1_error;
- self_or_null = PyStackRef_NULL;
- }
- }
- else {
- /* Classic, pushes one value. */
- _PyFrame_SetStackPointer(frame, stack_pointer);
- attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- PyStackRef_CLOSE(owner);
- if (attr_o == NULL) goto pop_1_error;
- /* We need to define self_or_null on all paths */
- self_or_null = PyStackRef_NULL;
- }
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyObject *attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ PyStackRef_CLOSE(owner);
+ if (attr_o == NULL) goto pop_1_error;
attr = PyStackRef_FromPyObjectSteal(attr_o);
}
stack_pointer[-1] = attr;
- if (oparg & 1) stack_pointer[0] = self_or_null;
- stack_pointer += (oparg & 1);
- assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@@ -5383,7 +5357,6 @@
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
_PyStackRef owner;
_PyStackRef attr;
- _PyStackRef null = PyStackRef_NULL;
/* Skip 1 cache entry */
// _CHECK_ATTR_CLASS
{
@@ -5401,13 +5374,9 @@
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
attr = PyStackRef_FromPyObjectNew(descr);
- null = PyStackRef_NULL;
PyStackRef_CLOSE(owner);
}
stack_pointer[-1] = attr;
- if (oparg & 1) stack_pointer[0] = null;
- stack_pointer += (oparg & 1);
- assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@@ -5418,7 +5387,6 @@
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
_PyStackRef owner;
_PyStackRef attr;
- _PyStackRef null = PyStackRef_NULL;
/* Skip 1 cache entry */
// _CHECK_ATTR_CLASS
{
@@ -5442,13 +5410,9 @@
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
attr = PyStackRef_FromPyObjectNew(descr);
- null = PyStackRef_NULL;
PyStackRef_CLOSE(owner);
}
stack_pointer[-1] = attr;
- if (oparg & 1) stack_pointer[0] = null;
- stack_pointer += (oparg & 1);
- assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@@ -5464,7 +5428,6 @@
uint32_t func_version = read_u32(&this_instr[4].cache);
PyObject *getattribute = read_obj(&this_instr[6].cache);
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
- assert((oparg & 1) == 0);
DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR);
PyTypeObject *cls = Py_TYPE(owner_o);
assert(type_version != 0);
@@ -5477,7 +5440,7 @@
assert(code->co_argcount == 2);
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR);
STAT_INC(LOAD_ATTR, hit);
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(
tstate, PyStackRef_FromPyObjectNew(f), 2, frame);
// Manipulate stack directly because we exit with DISPATCH_INLINED().
@@ -5495,7 +5458,6 @@
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
_PyStackRef owner;
_PyStackRef attr;
- _PyStackRef null = PyStackRef_NULL;
/* Skip 1 cache entry */
// _GUARD_TYPE_VERSION
{
@@ -5527,143 +5489,10 @@
attr = PyStackRef_FromPyObjectNew(attr_o);
#endif
STAT_INC(LOAD_ATTR, hit);
- null = PyStackRef_NULL;
PyStackRef_CLOSE(owner);
}
/* Skip 5 cache entries */
stack_pointer[-1] = attr;
- if (oparg & 1) stack_pointer[0] = null;
- stack_pointer += (oparg & 1);
- assert(WITHIN_STACK_BOUNDS());
- DISPATCH();
- }
-
- TARGET(LOAD_ATTR_METHOD_LAZY_DICT) {
- _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
- next_instr += 10;
- INSTRUCTION_STATS(LOAD_ATTR_METHOD_LAZY_DICT);
- static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
- _PyStackRef owner;
- _PyStackRef attr;
- _PyStackRef self = PyStackRef_NULL;
- /* Skip 1 cache entry */
- // _GUARD_TYPE_VERSION
- {
- owner = stack_pointer[-1];
- uint32_t type_version = read_u32(&this_instr[2].cache);
- PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
- assert(type_version != 0);
- DEOPT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version, LOAD_ATTR);
- }
- // _CHECK_ATTR_METHOD_LAZY_DICT
- {
- uint16_t dictoffset = read_u16(&this_instr[4].cache);
- char *ptr = ((char *)PyStackRef_AsPyObjectBorrow(owner)) + MANAGED_DICT_OFFSET + dictoffset;
- PyObject *dict = FT_ATOMIC_LOAD_PTR_ACQUIRE(*(PyObject **)ptr);
- /* This object has a __dict__, just not yet created */
- DEOPT_IF(dict != NULL, LOAD_ATTR);
- }
- /* Skip 1 cache entry */
- // _LOAD_ATTR_METHOD_LAZY_DICT
- {
- PyObject *descr = read_obj(&this_instr[6].cache);
- assert(oparg & 1);
- STAT_INC(LOAD_ATTR, hit);
- assert(descr != NULL);
- assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
- attr = PyStackRef_FromPyObjectNew(descr);
- self = owner;
- }
- stack_pointer[-1] = attr;
- stack_pointer[0] = self;
- stack_pointer += 1;
- assert(WITHIN_STACK_BOUNDS());
- DISPATCH();
- }
-
- TARGET(LOAD_ATTR_METHOD_NO_DICT) {
- _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
- next_instr += 10;
- INSTRUCTION_STATS(LOAD_ATTR_METHOD_NO_DICT);
- static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
- _PyStackRef owner;
- _PyStackRef attr;
- _PyStackRef self = PyStackRef_NULL;
- /* Skip 1 cache entry */
- // _GUARD_TYPE_VERSION
- {
- owner = stack_pointer[-1];
- uint32_t type_version = read_u32(&this_instr[2].cache);
- PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
- assert(type_version != 0);
- DEOPT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version, LOAD_ATTR);
- }
- /* Skip 2 cache entries */
- // _LOAD_ATTR_METHOD_NO_DICT
- {
- PyObject *descr = read_obj(&this_instr[6].cache);
- assert(oparg & 1);
- assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
- STAT_INC(LOAD_ATTR, hit);
- assert(descr != NULL);
- assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
- attr = PyStackRef_FromPyObjectNew(descr);
- self = owner;
- }
- stack_pointer[-1] = attr;
- stack_pointer[0] = self;
- stack_pointer += 1;
- assert(WITHIN_STACK_BOUNDS());
- DISPATCH();
- }
-
- TARGET(LOAD_ATTR_METHOD_WITH_VALUES) {
- _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
- next_instr += 10;
- INSTRUCTION_STATS(LOAD_ATTR_METHOD_WITH_VALUES);
- static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
- _PyStackRef owner;
- _PyStackRef attr;
- _PyStackRef self = PyStackRef_NULL;
- /* Skip 1 cache entry */
- // _GUARD_TYPE_VERSION
- {
- owner = stack_pointer[-1];
- uint32_t type_version = read_u32(&this_instr[2].cache);
- PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
- assert(type_version != 0);
- DEOPT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version, LOAD_ATTR);
- }
- // _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT
- {
- PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
- assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_INLINE_VALUES);
- PyDictValues *ivs = _PyObject_InlineValues(owner_o);
- DEOPT_IF(!FT_ATOMIC_LOAD_UINT8(ivs->valid), LOAD_ATTR);
- }
- // _GUARD_KEYS_VERSION
- {
- uint32_t keys_version = read_u32(&this_instr[4].cache);
- PyTypeObject *owner_cls = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
- PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls;
- PyDictKeysObject *keys = owner_heap_type->ht_cached_keys;
- DEOPT_IF(FT_ATOMIC_LOAD_UINT32_RELAXED(keys->dk_version) != keys_version, LOAD_ATTR);
- }
- // _LOAD_ATTR_METHOD_WITH_VALUES
- {
- PyObject *descr = read_obj(&this_instr[6].cache);
- assert(oparg & 1);
- /* Cached method object */
- STAT_INC(LOAD_ATTR, hit);
- assert(descr != NULL);
- assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
- attr = PyStackRef_FromPyObjectNew(descr);
- self = owner;
- }
- stack_pointer[-1] = attr;
- stack_pointer[0] = self;
- stack_pointer += 1;
- assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@@ -5675,7 +5504,6 @@
_PyStackRef owner;
PyDictKeysObject *mod_keys;
_PyStackRef attr;
- _PyStackRef null = PyStackRef_NULL;
/* Skip 1 cache entry */
// _CHECK_ATTR_MODULE_PUSH_KEYS
{
@@ -5708,14 +5536,10 @@
attr = PyStackRef_FromPyObjectSteal(attr_o);
#endif
STAT_INC(LOAD_ATTR, hit);
- null = PyStackRef_NULL;
PyStackRef_CLOSE(owner);
}
/* Skip 5 cache entries */
stack_pointer[-1] = attr;
- if (oparg & 1) stack_pointer[0] = null;
- stack_pointer += (oparg & 1);
- assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@@ -5739,7 +5563,6 @@
// _LOAD_ATTR_NONDESCRIPTOR_NO_DICT
{
PyObject *descr = read_obj(&this_instr[6].cache);
- assert((oparg & 1) == 0);
assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
@@ -5784,7 +5607,6 @@
// _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES
{
PyObject *descr = read_obj(&this_instr[6].cache);
- assert((oparg & 1) == 0);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
PyStackRef_CLOSE(owner);
@@ -5818,7 +5640,6 @@
// _LOAD_ATTR_PROPERTY_FRAME
{
PyObject *fget = read_obj(&this_instr[6].cache);
- assert((oparg & 1) == 0);
assert(Py_IS_TYPE(fget, &PyFunction_Type));
PyFunctionObject *f = (PyFunctionObject *)fget;
PyCodeObject *code = (PyCodeObject *)f->func_code;
@@ -5866,7 +5687,6 @@
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
_PyStackRef owner;
_PyStackRef attr;
- _PyStackRef null = PyStackRef_NULL;
/* Skip 1 cache entry */
// _GUARD_TYPE_VERSION
{
@@ -5890,14 +5710,10 @@
attr = PyStackRef_FromPyObjectNew(attr_o);
#endif
STAT_INC(LOAD_ATTR, hit);
- null = PyStackRef_NULL;
PyStackRef_CLOSE(owner);
}
/* Skip 5 cache entries */
stack_pointer[-1] = attr;
- if (oparg & 1) stack_pointer[0] = null;
- stack_pointer += (oparg & 1);
- assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@@ -5909,7 +5725,6 @@
_PyStackRef owner;
PyDictObject *dict;
_PyStackRef attr;
- _PyStackRef null = PyStackRef_NULL;
/* Skip 1 cache entry */
// _GUARD_TYPE_VERSION
{
@@ -5939,7 +5754,7 @@
UNLOCK_OBJECT(dict);
DEOPT_IF(true, LOAD_ATTR);
}
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) {
UNLOCK_OBJECT(dict);
DEOPT_IF(true, LOAD_ATTR);
@@ -5957,14 +5772,10 @@
STAT_INC(LOAD_ATTR, hit);
attr = PyStackRef_FromPyObjectNew(attr_o);
UNLOCK_OBJECT(dict);
- null = PyStackRef_NULL;
PyStackRef_CLOSE(owner);
}
/* Skip 5 cache entries */
stack_pointer[-1] = attr;
- if (oparg & 1) stack_pointer[0] = null;
- stack_pointer += (oparg & 1);
- assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@@ -6265,14 +6076,13 @@
_Py_CODEUNIT* const this_instr = next_instr - 5;
(void)this_instr;
_PyStackRef *res;
- _PyStackRef null = PyStackRef_NULL;
// _SPECIALIZE_LOAD_GLOBAL
{
uint16_t counter = read_u16(&this_instr[1].cache);
(void)counter;
#if ENABLE_SPECIALIZATION_FT
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
next_instr = this_instr;
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name);
@@ -6289,15 +6099,13 @@
// _LOAD_GLOBAL
{
res = &stack_pointer[0];
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
_PyFrame_SetStackPointer(frame, stack_pointer);
_PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (PyStackRef_IsNull(*res)) goto error;
- null = PyStackRef_NULL;
}
- if (oparg & 1) stack_pointer[1] = null;
- stack_pointer += 1 + (oparg & 1);
+ stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@@ -6309,7 +6117,6 @@
static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size");
PyDictKeysObject *builtins_keys;
_PyStackRef res;
- _PyStackRef null = PyStackRef_NULL;
/* Skip 1 cache entry */
// _GUARD_GLOBALS_VERSION
{
@@ -6344,11 +6151,9 @@
res = PyStackRef_FromPyObjectSteal(res_o);
#endif
STAT_INC(LOAD_GLOBAL, hit);
- null = PyStackRef_NULL;
}
stack_pointer[0] = res;
- if (oparg & 1) stack_pointer[1] = null;
- stack_pointer += 1 + (oparg & 1);
+ stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@@ -6360,7 +6165,6 @@
static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size");
PyDictKeysObject *globals_keys;
_PyStackRef res;
- _PyStackRef null = PyStackRef_NULL;
/* Skip 1 cache entry */
// _GUARD_GLOBALS_VERSION_PUSH_KEYS
{
@@ -6387,11 +6191,9 @@
res = PyStackRef_FromPyObjectSteal(res_o);
#endif
STAT_INC(LOAD_GLOBAL, hit);
- null = PyStackRef_NULL;
}
stack_pointer[0] = res;
- if (oparg & 1) stack_pointer[1] = null;
- stack_pointer += 1 + (oparg & 1);
+ stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@@ -6416,6 +6218,198 @@
DISPATCH();
}
+ TARGET(LOAD_METHOD) {
+ frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_METHOD);
+ PREDICTED(LOAD_METHOD);
+ _Py_CODEUNIT* const this_instr = next_instr - 10;
+ (void)this_instr;
+ _PyStackRef owner;
+ _PyStackRef attr;
+ _PyStackRef self_or_null;
+ // _SPECIALIZE_LOAD_METHOD
+ {
+ owner = stack_pointer[-1];
+ uint16_t counter = read_u16(&this_instr[1].cache);
+ (void)counter;
+ #if ENABLE_SPECIALIZATION_FT
+ if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
+ next_instr = this_instr;
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ _Py_Specialize_LoadMethod(owner, next_instr, name);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ DISPATCH_SAME_OPARG();
+ }
+ OPCODE_DEFERRED_INC(LOAD_METHOD);
+ ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
+ #endif /* ENABLE_SPECIALIZATION_FT */
+ }
+ /* Skip 8 cache entries */
+ // _LOAD_METHOD
+ {
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
+ PyObject *attr_o;
+ /* Designed to work in tandem with CALL, pushes two values. */
+ attr_o = NULL;
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ if (is_meth) {
+ /* We can bypass temporary bound method object.
+ meth is unbound method and obj is self.
+ meth | self | arg1 | ... | argN
+ */
+ assert(attr_o != NULL); // No errors on this branch
+ self_or_null = owner; // Transfer ownership
+ }
+ else {
+ /* meth is not an unbound method (but a regular attr, or
+ something was returned by a descriptor protocol). Set
+ the second element of the stack to NULL, to signal
+ CALL that it's not a method call.
+ meth | NULL | arg1 | ... | argN
+ */
+ PyStackRef_CLOSE(owner);
+ if (attr_o == NULL) goto pop_1_error;
+ self_or_null = PyStackRef_NULL;
+ }
+ attr = PyStackRef_FromPyObjectSteal(attr_o);
+ }
+ stack_pointer[-1] = attr;
+ stack_pointer[0] = self_or_null;
+ stack_pointer += 1;
+ assert(WITHIN_STACK_BOUNDS());
+ DISPATCH();
+ }
+
+ TARGET(LOAD_METHOD_LAZY_DICT) {
+ _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_METHOD_LAZY_DICT);
+ static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
+ _PyStackRef owner;
+ _PyStackRef attr;
+ _PyStackRef self;
+ /* Skip 1 cache entry */
+ // _GUARD_TYPE_VERSION
+ {
+ owner = stack_pointer[-1];
+ uint32_t type_version = read_u32(&this_instr[2].cache);
+ PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
+ assert(type_version != 0);
+ DEOPT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version, LOAD_METHOD);
+ }
+ // _CHECK_ATTR_METHOD_LAZY_DICT
+ {
+ uint16_t dictoffset = read_u16(&this_instr[4].cache);
+ char *ptr = ((char *)PyStackRef_AsPyObjectBorrow(owner)) + MANAGED_DICT_OFFSET + dictoffset;
+ PyObject *dict = FT_ATOMIC_LOAD_PTR_ACQUIRE(*(PyObject **)ptr);
+ /* This object has a __dict__, just not yet created */
+ DEOPT_IF(dict != NULL, LOAD_METHOD);
+ }
+ /* Skip 1 cache entry */
+ // _LOAD_METHOD_LAZY_DICT
+ {
+ PyObject *descr = read_obj(&this_instr[6].cache);
+ STAT_INC(LOAD_ATTR, hit);
+ assert(descr != NULL);
+ assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
+ attr = PyStackRef_FromPyObjectNew(descr);
+ self = owner;
+ }
+ stack_pointer[-1] = attr;
+ stack_pointer[0] = self;
+ stack_pointer += 1;
+ assert(WITHIN_STACK_BOUNDS());
+ DISPATCH();
+ }
+
+ TARGET(LOAD_METHOD_NO_DICT) {
+ _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_METHOD_NO_DICT);
+ static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
+ _PyStackRef owner;
+ _PyStackRef attr;
+ _PyStackRef self;
+ /* Skip 1 cache entry */
+ // _GUARD_TYPE_VERSION
+ {
+ owner = stack_pointer[-1];
+ uint32_t type_version = read_u32(&this_instr[2].cache);
+ PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
+ assert(type_version != 0);
+ DEOPT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version, LOAD_METHOD);
+ }
+ /* Skip 2 cache entries */
+ // _LOAD_METHOD_NO_DICT
+ {
+ PyObject *descr = read_obj(&this_instr[6].cache);
+ assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
+ STAT_INC(LOAD_ATTR, hit);
+ assert(descr != NULL);
+ assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
+ attr = PyStackRef_FromPyObjectNew(descr);
+ self = owner;
+ }
+ stack_pointer[-1] = attr;
+ stack_pointer[0] = self;
+ stack_pointer += 1;
+ assert(WITHIN_STACK_BOUNDS());
+ DISPATCH();
+ }
+
+ TARGET(LOAD_METHOD_WITH_VALUES) {
+ _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_METHOD_WITH_VALUES);
+ static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
+ _PyStackRef owner;
+ _PyStackRef attr;
+ _PyStackRef self;
+ /* Skip 1 cache entry */
+ // _GUARD_TYPE_VERSION
+ {
+ owner = stack_pointer[-1];
+ uint32_t type_version = read_u32(&this_instr[2].cache);
+ PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
+ assert(type_version != 0);
+ DEOPT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version, LOAD_METHOD);
+ }
+ // _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT
+ {
+ PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
+ assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_INLINE_VALUES);
+ PyDictValues *ivs = _PyObject_InlineValues(owner_o);
+ DEOPT_IF(!FT_ATOMIC_LOAD_UINT8(ivs->valid), LOAD_METHOD);
+ }
+ // _GUARD_KEYS_VERSION
+ {
+ uint32_t keys_version = read_u32(&this_instr[4].cache);
+ PyTypeObject *owner_cls = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
+ PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls;
+ PyDictKeysObject *keys = owner_heap_type->ht_cached_keys;
+ DEOPT_IF(FT_ATOMIC_LOAD_UINT32_RELAXED(keys->dk_version) != keys_version, LOAD_METHOD);
+ }
+ // _LOAD_METHOD_WITH_VALUES
+ {
+ PyObject *descr = read_obj(&this_instr[6].cache);
+ /* Cached method object */
+ STAT_INC(LOAD_ATTR, hit);
+ assert(descr != NULL);
+ assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
+ attr = PyStackRef_FromPyObjectNew(descr);
+ self = owner;
+ }
+ stack_pointer[-1] = attr;
+ stack_pointer[0] = self;
+ stack_pointer += 1;
+ assert(WITHIN_STACK_BOUNDS());
+ DISPATCH();
+ }
+
TARGET(LOAD_NAME) {
frame->instr_ptr = next_instr;
next_instr += 1;
@@ -6495,7 +6489,6 @@
_PyStackRef class_st;
_PyStackRef self_st;
_PyStackRef attr;
- _PyStackRef null = PyStackRef_NULL;
// _SPECIALIZE_LOAD_SUPER_ATTR
{
class_st = stack_pointer[-2];
@@ -6503,11 +6496,10 @@
uint16_t counter = read_u16(&this_instr[1].cache);
(void)counter;
#if ENABLE_SPECIALIZATION_FT
- int load_method = oparg & 1;
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
next_instr = this_instr;
_PyFrame_SetStackPointer(frame, stack_pointer);
- _Py_Specialize_LoadSuperAttr(global_super_st, class_st, next_instr, load_method);
+ _Py_Specialize_LoadSuperAttr(global_super_st, class_st, next_instr, 0);
stack_pointer = _PyFrame_GetStackPointer(frame);
DISPATCH_SAME_OPARG();
}
@@ -6521,7 +6513,7 @@
PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
- if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
+ if (opcode >= MIN_INSTRUMENTED_OPCODE) {
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
_PyFrame_SetStackPointer(frame, stack_pointer);
int err = _Py_call_instrumentation_2args(
@@ -6541,7 +6533,7 @@
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
stack_pointer = _PyFrame_GetStackPointer(frame);
- if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
+ if (opcode >= MIN_INSTRUMENTED_OPCODE) {
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
if (super == NULL) {
_PyFrame_SetStackPointer(frame, stack_pointer);
@@ -6574,11 +6566,9 @@
stack_pointer = _PyFrame_GetStackPointer(frame);
if (attr_o == NULL) goto error;
attr = PyStackRef_FromPyObjectSteal(attr_o);
- null = PyStackRef_NULL;
}
stack_pointer[0] = attr;
- if (oparg & 1) stack_pointer[1] = null;
- stack_pointer += 1 + (oparg & 1);
+ stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@@ -6618,10 +6608,111 @@
DISPATCH();
}
- TARGET(LOAD_SUPER_ATTR_METHOD) {
+ TARGET(LOAD_SUPER_METHOD) {
frame->instr_ptr = next_instr;
next_instr += 2;
- INSTRUCTION_STATS(LOAD_SUPER_ATTR_METHOD);
+ INSTRUCTION_STATS(LOAD_SUPER_METHOD);
+ PREDICTED(LOAD_SUPER_METHOD);
+ _Py_CODEUNIT* const this_instr = next_instr - 2;
+ (void)this_instr;
+ _PyStackRef global_super_st;
+ _PyStackRef class_st;
+ _PyStackRef self_st;
+ _PyStackRef attr;
+ _PyStackRef null;
+ // _SPECIALIZE_LOAD_SUPER_METHOD
+ {
+ class_st = stack_pointer[-2];
+ global_super_st = stack_pointer[-3];
+ uint16_t counter = read_u16(&this_instr[1].cache);
+ (void)counter;
+ #if ENABLE_SPECIALIZATION_FT
+ if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
+ next_instr = this_instr;
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ _Py_Specialize_LoadSuperAttr(global_super_st, class_st, next_instr, 1);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ DISPATCH_SAME_OPARG();
+ }
+ OPCODE_DEFERRED_INC(LOAD_SUPER_METHOD);
+ ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
+ #endif /* ENABLE_SPECIALIZATION_FT */
+ }
+ // _LOAD_SUPER_ATTR
+ {
+ self_st = stack_pointer[-1];
+ PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
+ PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
+ PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
+ if (opcode >= MIN_INSTRUMENTED_OPCODE) {
+ PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ int err = _Py_call_instrumentation_2args(
+ tstate, PY_MONITORING_EVENT_CALL,
+ frame, this_instr, global_super, arg);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ if (err) {
+ PyStackRef_CLOSE(global_super_st);
+ PyStackRef_CLOSE(class_st);
+ PyStackRef_CLOSE(self_st);
+ goto pop_3_error;
+ }
+ }
+ // we make no attempt to optimize here; specializations should
+ // handle any case whose performance we care about
+ PyObject *stack[] = {class, self};
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ if (opcode >= MIN_INSTRUMENTED_OPCODE) {
+ PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
+ if (super == NULL) {
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ _Py_call_instrumentation_exc2(
+ tstate, PY_MONITORING_EVENT_C_RAISE,
+ frame, this_instr, global_super, arg);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ }
+ else {
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ int err = _Py_call_instrumentation_2args(
+ tstate, PY_MONITORING_EVENT_C_RETURN,
+ frame, this_instr, global_super, arg);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ if (err < 0) {
+ Py_CLEAR(super);
+ }
+ }
+ }
+ PyStackRef_CLOSE(global_super_st);
+ PyStackRef_CLOSE(class_st);
+ PyStackRef_CLOSE(self_st);
+ if (super == NULL) goto pop_3_error;
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2);
+ stack_pointer += -3;
+ assert(WITHIN_STACK_BOUNDS());
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyObject *attr_o = PyObject_GetAttr(super, name);
+ Py_DECREF(super);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ if (attr_o == NULL) goto error;
+ attr = PyStackRef_FromPyObjectSteal(attr_o);
+ }
+ // _PUSH_NULL
+ {
+ null = PyStackRef_NULL;
+ }
+ stack_pointer[0] = attr;
+ stack_pointer[1] = null;
+ stack_pointer += 2;
+ assert(WITHIN_STACK_BOUNDS());
+ DISPATCH();
+ }
+
+ TARGET(LOAD_SUPER_METHOD_METHOD) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(LOAD_SUPER_METHOD_METHOD);
static_assert(INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR == 1, "incorrect cache size");
_PyStackRef global_super_st;
_PyStackRef class_st;
@@ -6636,8 +6727,8 @@
PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
assert(oparg & 1);
- DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR);
- DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR);
+ DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_METHOD);
+ DEOPT_IF(!PyType_Check(class), LOAD_SUPER_METHOD);
STAT_INC(LOAD_SUPER_ATTR, hit);
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2);
PyTypeObject *cls = (PyTypeObject *)class;
@@ -7002,9 +7093,9 @@
frame->instr_ptr = next_instr;
next_instr += 1;
INSTRUCTION_STATS(PUSH_NULL);
- _PyStackRef res;
- res = PyStackRef_NULL;
- stack_pointer[0] = res;
+ _PyStackRef null;
+ null = PyStackRef_NULL;
+ stack_pointer[0] = null;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
diff --git a/Python/instrumentation.c b/Python/instrumentation.c
index 17e5346be5ed3d..b24e2887f42ecc 100644
--- a/Python/instrumentation.c
+++ b/Python/instrumentation.c
@@ -81,6 +81,8 @@ static const int8_t EVENT_FOR_OPCODE[256] = {
[INSTRUMENTED_CALL_FUNCTION_EX] = PY_MONITORING_EVENT_CALL,
[LOAD_SUPER_ATTR] = PY_MONITORING_EVENT_CALL,
[INSTRUMENTED_LOAD_SUPER_ATTR] = PY_MONITORING_EVENT_CALL,
+ [LOAD_SUPER_METHOD] = PY_MONITORING_EVENT_CALL,
+ [INSTRUMENTED_LOAD_SUPER_METHOD] = PY_MONITORING_EVENT_CALL,
[RESUME] = -1,
[YIELD_VALUE] = PY_MONITORING_EVENT_PY_YIELD,
[INSTRUMENTED_YIELD_VALUE] = PY_MONITORING_EVENT_PY_YIELD,
@@ -126,6 +128,7 @@ static const uint8_t DE_INSTRUMENT[256] = {
[INSTRUMENTED_END_FOR] = END_FOR,
[INSTRUMENTED_END_SEND] = END_SEND,
[INSTRUMENTED_LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
+ [INSTRUMENTED_LOAD_SUPER_METHOD] = LOAD_SUPER_METHOD,
[INSTRUMENTED_NOT_TAKEN] = NOT_TAKEN,
};
@@ -164,6 +167,8 @@ static const uint8_t INSTRUMENTED_OPCODES[256] = {
[INSTRUMENTED_POP_ITER] = INSTRUMENTED_POP_ITER,
[LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
[INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
+ [LOAD_SUPER_METHOD] = INSTRUMENTED_LOAD_SUPER_METHOD,
+ [INSTRUMENTED_LOAD_SUPER_METHOD] = INSTRUMENTED_LOAD_SUPER_METHOD,
[NOT_TAKEN] = INSTRUMENTED_NOT_TAKEN,
[INSTRUMENTED_NOT_TAKEN] = INSTRUMENTED_NOT_TAKEN,
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
index cb6c33f01d3598..2e35ae710b1430 100644
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -3,6 +3,7 @@ static void *opcode_targets[256] = {
&&TARGET_BINARY_SLICE,
&&TARGET_BINARY_SUBSCR,
&&TARGET_BINARY_OP_INPLACE_ADD_UNICODE,
+ &&TARGET_CALL_FUNCTION_EX,
&&TARGET_CHECK_EG_MATCH,
&&TARGET_CHECK_EXC_MATCH,
&&TARGET_CLEANUP_THROW,
@@ -15,8 +16,8 @@ static void *opcode_targets[256] = {
&&TARGET_FORMAT_WITH_SPEC,
&&TARGET_GET_AITER,
&&TARGET_GET_ANEXT,
- &&TARGET_GET_ITER,
&&TARGET_RESERVED,
+ &&TARGET_GET_ITER,
&&TARGET_GET_LEN,
&&TARGET_GET_YIELD_FROM_ITER,
&&TARGET_INTERPRETER_EXIT,
@@ -51,7 +52,6 @@ static void *opcode_targets[256] = {
&&TARGET_BUILD_STRING,
&&TARGET_BUILD_TUPLE,
&&TARGET_CALL,
- &&TARGET_CALL_FUNCTION_EX,
&&TARGET_CALL_INTRINSIC_1,
&&TARGET_CALL_INTRINSIC_2,
&&TARGET_CALL_KW,
@@ -89,10 +89,12 @@ static void *opcode_targets[256] = {
&&TARGET_LOAD_FROM_DICT_OR_DEREF,
&&TARGET_LOAD_FROM_DICT_OR_GLOBALS,
&&TARGET_LOAD_GLOBAL,
+ &&TARGET_LOAD_METHOD,
&&TARGET_LOAD_NAME,
&&TARGET_LOAD_SMALL_INT,
&&TARGET_LOAD_SPECIAL,
&&TARGET_LOAD_SUPER_ATTR,
+ &&TARGET_LOAD_SUPER_METHOD,
&&TARGET_MAKE_CELL,
&&TARGET_MAP_ADD,
&&TARGET_MATCH_CLASS,
@@ -146,8 +148,6 @@ static void *opcode_targets[256] = {
&&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,
- &&_unknown_opcode,
- &&_unknown_opcode,
&&TARGET_RESUME,
&&TARGET_BINARY_OP_ADD_FLOAT,
&&TARGET_BINARY_OP_ADD_INT,
@@ -198,9 +198,6 @@ static void *opcode_targets[256] = {
&&TARGET_LOAD_ATTR_CLASS_WITH_METACLASS_CHECK,
&&TARGET_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN,
&&TARGET_LOAD_ATTR_INSTANCE_VALUE,
- &&TARGET_LOAD_ATTR_METHOD_LAZY_DICT,
- &&TARGET_LOAD_ATTR_METHOD_NO_DICT,
- &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES,
&&TARGET_LOAD_ATTR_MODULE,
&&TARGET_LOAD_ATTR_NONDESCRIPTOR_NO_DICT,
&&TARGET_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES,
@@ -211,8 +208,11 @@ static void *opcode_targets[256] = {
&&TARGET_LOAD_CONST_MORTAL,
&&TARGET_LOAD_GLOBAL_BUILTIN,
&&TARGET_LOAD_GLOBAL_MODULE,
+ &&TARGET_LOAD_METHOD_LAZY_DICT,
+ &&TARGET_LOAD_METHOD_NO_DICT,
+ &&TARGET_LOAD_METHOD_WITH_VALUES,
&&TARGET_LOAD_SUPER_ATTR_ATTR,
- &&TARGET_LOAD_SUPER_ATTR_METHOD,
+ &&TARGET_LOAD_SUPER_METHOD_METHOD,
&&TARGET_RESUME_CHECK,
&&TARGET_SEND_GEN,
&&TARGET_STORE_ATTR_INSTANCE_VALUE,
@@ -233,11 +233,11 @@ static void *opcode_targets[256] = {
&&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,
- &&_unknown_opcode,
&&TARGET_INSTRUMENTED_END_FOR,
&&TARGET_INSTRUMENTED_POP_ITER,
&&TARGET_INSTRUMENTED_END_SEND,
&&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR,
+ &&TARGET_INSTRUMENTED_LOAD_SUPER_METHOD,
&&TARGET_INSTRUMENTED_FOR_ITER,
&&TARGET_INSTRUMENTED_CALL_KW,
&&TARGET_INSTRUMENTED_CALL_FUNCTION_EX,
diff --git a/Python/optimizer.c b/Python/optimizer.c
index 9beb47246eb3d6..b91caf11ffa962 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -1274,10 +1274,7 @@ uop_optimize(
for (int pc = 0; pc < length; pc++) {
int opcode = buffer[pc].opcode;
int oparg = buffer[pc].oparg;
- if (_PyUop_Flags[opcode] & HAS_OPARG_AND_1_FLAG) {
- buffer[pc].opcode = opcode + 1 + (oparg & 1);
- }
- else if (oparg < _PyUop_Replication[opcode]) {
+ if (oparg < _PyUop_Replication[opcode]) {
buffer[pc].opcode = opcode + oparg + 1;
}
else if (is_terminator(&buffer[pc])) {
diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c
index b9ac30ea04e4e8..05f9592e9a23fa 100644
--- a/Python/optimizer_analysis.c
+++ b/Python/optimizer_analysis.c
@@ -109,10 +109,10 @@ convert_global_to_const(_PyUOpInstruction *inst, PyObject *obj)
return NULL;
}
if (_Py_IsImmortal(res)) {
- inst->opcode = (inst->oparg & 1) ? _LOAD_CONST_INLINE_BORROW_WITH_NULL : _LOAD_CONST_INLINE_BORROW;
+ inst->opcode = _LOAD_CONST_INLINE_BORROW;
}
else {
- inst->opcode = (inst->oparg & 1) ? _LOAD_CONST_INLINE_WITH_NULL : _LOAD_CONST_INLINE;
+ inst->opcode = _LOAD_CONST_INLINE;
}
inst->operand0 = (uint64_t)res;
return res;
diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c
index 881a607ca2aa29..af834b6957be22 100644
--- a/Python/optimizer_bytecodes.c
+++ b/Python/optimizer_bytecodes.c
@@ -528,9 +528,8 @@ dummy_func(void) {
top_out = top_in;
}
- op(_LOAD_ATTR_INSTANCE_VALUE, (offset/1, owner -- attr, null if (oparg & 1))) {
+ op(_LOAD_ATTR_INSTANCE_VALUE, (offset/1, owner -- attr)) {
attr = sym_new_not_null(ctx);
- null = sym_new_null(ctx);
(void)offset;
(void)owner;
}
@@ -553,15 +552,19 @@ dummy_func(void) {
}
}
- op(_LOAD_ATTR, (owner -- attr, self_or_null if (oparg & 1))) {
+ op(_LOAD_ATTR, (owner -- attr)) {
+ (void)owner;
+ attr = sym_new_not_null(ctx);
+ }
+
+ op(_LOAD_METHOD, (owner -- attr, self_or_null)) {
(void)owner;
attr = sym_new_not_null(ctx);
self_or_null = sym_new_unknown(ctx);
}
- op(_LOAD_ATTR_MODULE_FROM_KEYS, (index/1, owner, mod_keys -- attr, null if (oparg & 1))) {
+ op(_LOAD_ATTR_MODULE_FROM_KEYS, (index/1, owner, mod_keys -- attr)) {
(void)index;
- null = sym_new_null(ctx);
attr = NULL;
if (this_instr[-1].opcode == _NOP) {
// Preceding _CHECK_ATTR_MODULE_PUSH_KEYS was removed: mod is const and dict is watched.
@@ -589,41 +592,38 @@ dummy_func(void) {
(void)owner;
}
- op(_LOAD_ATTR_WITH_HINT, (hint/1, owner, dict -- attr, null if (oparg & 1))) {
+ op(_LOAD_ATTR_WITH_HINT, (hint/1, owner, dict -- attr)) {
attr = sym_new_not_null(ctx);
- null = sym_new_null(ctx);
(void)hint;
(void)owner;
(void)dict;
}
- op(_LOAD_ATTR_SLOT, (index/1, owner -- attr, null if (oparg & 1))) {
+ op(_LOAD_ATTR_SLOT, (index/1, owner -- attr)) {
attr = sym_new_not_null(ctx);
- null = sym_new_null(ctx);
(void)index;
(void)owner;
}
- op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr, null if (oparg & 1))) {
+ op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr)) {
attr = sym_new_not_null(ctx);
- null = sym_new_null(ctx);
(void)descr;
(void)owner;
}
- op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self if (1))) {
+ op(_LOAD_METHOD_WITH_VALUES, (descr/4, owner -- attr, self)) {
(void)descr;
attr = sym_new_not_null(ctx);
self = owner;
}
- op(_LOAD_ATTR_METHOD_NO_DICT, (descr/4, owner -- attr, self if (1))) {
+ op(_LOAD_METHOD_NO_DICT, (descr/4, owner -- attr, self)) {
(void)descr;
attr = sym_new_not_null(ctx);
self = owner;
}
- op(_LOAD_ATTR_METHOD_LAZY_DICT, (descr/4, owner -- attr, self if (1))) {
+ op(_LOAD_METHOD_LAZY_DICT, (descr/4, owner -- attr, self)) {
(void)descr;
attr = sym_new_not_null(ctx);
self = owner;
@@ -819,7 +819,7 @@ dummy_func(void) {
Py_UNREACHABLE();
}
- op(_PUSH_FRAME, (new_frame: _Py_UOpsAbstractFrame * -- unused if (0))) {
+ op(_PUSH_FRAME, (new_frame: _Py_UOpsAbstractFrame * -- )) {
SYNC_SP();
ctx->frame->stack_pointer = stack_pointer;
ctx->frame = new_frame;
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h
index fa0b4ed4345320..cb4651a5d8093c 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -928,12 +928,9 @@
case _LOAD_GLOBAL: {
JitOptSymbol **res;
- JitOptSymbol *null = NULL;
res = &stack_pointer[0];
res[0] = sym_new_not_null(ctx);
- null = sym_new_null(ctx);
- if (oparg & 1) stack_pointer[1] = null;
- stack_pointer += 1 + (oparg & 1);
+ stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
break;
}
@@ -966,25 +963,15 @@
case _LOAD_GLOBAL_MODULE_FROM_KEYS: {
JitOptSymbol *res;
- JitOptSymbol *null = NULL;
res = sym_new_not_null(ctx);
- null = sym_new_null(ctx);
stack_pointer[-1] = res;
- if (oparg & 1) stack_pointer[0] = null;
- stack_pointer += (oparg & 1);
- assert(WITHIN_STACK_BOUNDS());
break;
}
case _LOAD_GLOBAL_BUILTINS_FROM_KEYS: {
JitOptSymbol *res;
- JitOptSymbol *null = NULL;
res = sym_new_not_null(ctx);
- null = sym_new_null(ctx);
stack_pointer[-1] = res;
- if (oparg & 1) stack_pointer[0] = null;
- stack_pointer += (oparg & 1);
- assert(WITHIN_STACK_BOUNDS());
break;
}
@@ -1109,6 +1096,8 @@
/* _INSTRUMENTED_LOAD_SUPER_ATTR is not a viable micro-op for tier 2 */
+ /* _INSTRUMENTED_LOAD_SUPER_METHOD is not a viable micro-op for tier 2 */
+
case _LOAD_SUPER_ATTR_ATTR: {
JitOptSymbol *attr_st;
attr_st = sym_new_not_null(ctx);
@@ -1118,7 +1107,7 @@
break;
}
- case _LOAD_SUPER_ATTR_METHOD: {
+ case _LOAD_SUPER_METHOD_METHOD: {
JitOptSymbol *attr;
JitOptSymbol *self_or_null;
attr = sym_new_not_null(ctx);
@@ -1130,21 +1119,31 @@
break;
}
- case _LOAD_ATTR: {
+ case _LOAD_METHOD: {
JitOptSymbol *owner;
JitOptSymbol *attr;
- JitOptSymbol *self_or_null = NULL;
+ JitOptSymbol *self_or_null;
owner = stack_pointer[-1];
(void)owner;
attr = sym_new_not_null(ctx);
self_or_null = sym_new_unknown(ctx);
stack_pointer[-1] = attr;
- if (oparg & 1) stack_pointer[0] = self_or_null;
- stack_pointer += (oparg & 1);
+ stack_pointer[0] = self_or_null;
+ stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
break;
}
+ case _LOAD_ATTR: {
+ JitOptSymbol *owner;
+ JitOptSymbol *attr;
+ owner = stack_pointer[-1];
+ (void)owner;
+ attr = sym_new_not_null(ctx);
+ stack_pointer[-1] = attr;
+ break;
+ }
+
case _GUARD_TYPE_VERSION: {
JitOptSymbol *owner;
owner = stack_pointer[-1];
@@ -1182,17 +1181,12 @@
case _LOAD_ATTR_INSTANCE_VALUE: {
JitOptSymbol *owner;
JitOptSymbol *attr;
- JitOptSymbol *null = NULL;
owner = stack_pointer[-1];
uint16_t offset = (uint16_t)this_instr->operand0;
attr = sym_new_not_null(ctx);
- null = sym_new_null(ctx);
(void)offset;
(void)owner;
stack_pointer[-1] = attr;
- if (oparg & 1) stack_pointer[0] = null;
- stack_pointer += (oparg & 1);
- assert(WITHIN_STACK_BOUNDS());
break;
}
@@ -1230,11 +1224,9 @@
case _LOAD_ATTR_MODULE_FROM_KEYS: {
JitOptSymbol *owner;
JitOptSymbol *attr;
- JitOptSymbol *null = NULL;
owner = stack_pointer[-2];
uint16_t index = (uint16_t)this_instr->operand0;
(void)index;
- null = sym_new_null(ctx);
attr = NULL;
if (this_instr[-1].opcode == _NOP) {
// Preceding _CHECK_ATTR_MODULE_PUSH_KEYS was removed: mod is const and dict is watched.
@@ -1243,8 +1235,7 @@
assert(PyModule_CheckExact(mod));
PyObject *dict = mod->md_dict;
stack_pointer[-2] = attr;
- if (oparg & 1) stack_pointer[-1] = null;
- stack_pointer += -1 + (oparg & 1);
+ stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
PyObject *res = convert_global_to_const(this_instr, dict);
if (res != NULL) {
@@ -1254,7 +1245,7 @@
else {
this_instr->opcode = _LOAD_ATTR_MODULE;
}
- stack_pointer += 1 - (oparg & 1);
+ stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
}
if (attr == NULL) {
@@ -1262,8 +1253,7 @@
attr = sym_new_not_null(ctx);
}
stack_pointer[-2] = attr;
- if (oparg & 1) stack_pointer[-1] = null;
- stack_pointer += -1 + (oparg & 1);
+ stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
break;
}
@@ -1284,18 +1274,15 @@
JitOptSymbol *dict;
JitOptSymbol *owner;
JitOptSymbol *attr;
- JitOptSymbol *null = NULL;
dict = stack_pointer[-1];
owner = stack_pointer[-2];
uint16_t hint = (uint16_t)this_instr->operand0;
attr = sym_new_not_null(ctx);
- null = sym_new_null(ctx);
(void)hint;
(void)owner;
(void)dict;
stack_pointer[-2] = attr;
- if (oparg & 1) stack_pointer[-1] = null;
- stack_pointer += -1 + (oparg & 1);
+ stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
break;
}
@@ -1303,17 +1290,12 @@
case _LOAD_ATTR_SLOT: {
JitOptSymbol *owner;
JitOptSymbol *attr;
- JitOptSymbol *null = NULL;
owner = stack_pointer[-1];
uint16_t index = (uint16_t)this_instr->operand0;
attr = sym_new_not_null(ctx);
- null = sym_new_null(ctx);
(void)index;
(void)owner;
stack_pointer[-1] = attr;
- if (oparg & 1) stack_pointer[0] = null;
- stack_pointer += (oparg & 1);
- assert(WITHIN_STACK_BOUNDS());
break;
}
@@ -1324,17 +1306,12 @@
case _LOAD_ATTR_CLASS: {
JitOptSymbol *owner;
JitOptSymbol *attr;
- JitOptSymbol *null = NULL;
owner = stack_pointer[-1];
PyObject *descr = (PyObject *)this_instr->operand0;
attr = sym_new_not_null(ctx);
- null = sym_new_null(ctx);
(void)descr;
(void)owner;
stack_pointer[-1] = attr;
- if (oparg & 1) stack_pointer[0] = null;
- stack_pointer += (oparg & 1);
- assert(WITHIN_STACK_BOUNDS());
break;
}
@@ -1720,10 +1697,10 @@
break;
}
- case _LOAD_ATTR_METHOD_WITH_VALUES: {
+ case _LOAD_METHOD_WITH_VALUES: {
JitOptSymbol *owner;
JitOptSymbol *attr;
- JitOptSymbol *self = NULL;
+ JitOptSymbol *self;
owner = stack_pointer[-1];
PyObject *descr = (PyObject *)this_instr->operand0;
(void)descr;
@@ -1736,10 +1713,10 @@
break;
}
- case _LOAD_ATTR_METHOD_NO_DICT: {
+ case _LOAD_METHOD_NO_DICT: {
JitOptSymbol *owner;
JitOptSymbol *attr;
- JitOptSymbol *self = NULL;
+ JitOptSymbol *self;
owner = stack_pointer[-1];
PyObject *descr = (PyObject *)this_instr->operand0;
(void)descr;
@@ -1770,10 +1747,10 @@
break;
}
- case _LOAD_ATTR_METHOD_LAZY_DICT: {
+ case _LOAD_METHOD_LAZY_DICT: {
JitOptSymbol *owner;
JitOptSymbol *attr;
- JitOptSymbol *self = NULL;
+ JitOptSymbol *self;
owner = stack_pointer[-1];
PyObject *descr = (PyObject *)this_instr->operand0;
(void)descr;
@@ -2262,11 +2239,11 @@
case _MAKE_CALLARGS_A_TUPLE: {
JitOptSymbol *tuple;
- JitOptSymbol *kwargs_out = NULL;
+ JitOptSymbol *kwargs_out;
tuple = sym_new_not_null(ctx);
kwargs_out = sym_new_not_null(ctx);
- stack_pointer[-1 - (oparg & 1)] = tuple;
- if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_out;
+ stack_pointer[-2] = tuple;
+ stack_pointer[-1] = kwargs_out;
break;
}
@@ -2315,8 +2292,8 @@
case _BUILD_SLICE: {
JitOptSymbol *slice;
slice = sym_new_not_null(ctx);
- stack_pointer[-2 - ((oparg == 3) ? 1 : 0)] = slice;
- stack_pointer += -1 - ((oparg == 3) ? 1 : 0);
+ stack_pointer[-oparg] = slice;
+ stack_pointer += 1 - oparg;
assert(WITHIN_STACK_BOUNDS());
break;
}
@@ -2639,37 +2616,26 @@
case _LOAD_GLOBAL_MODULE: {
JitOptSymbol *res;
- JitOptSymbol *null = NULL;
res = sym_new_not_null(ctx);
- null = sym_new_null(ctx);
stack_pointer[0] = res;
- if (oparg & 1) stack_pointer[1] = null;
- stack_pointer += 1 + (oparg & 1);
+ stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
break;
}
case _LOAD_GLOBAL_BUILTINS: {
JitOptSymbol *res;
- JitOptSymbol *null = NULL;
res = sym_new_not_null(ctx);
- null = sym_new_null(ctx);
stack_pointer[0] = res;
- if (oparg & 1) stack_pointer[1] = null;
- stack_pointer += 1 + (oparg & 1);
+ stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
break;
}
case _LOAD_ATTR_MODULE: {
JitOptSymbol *attr;
- JitOptSymbol *null = NULL;
attr = sym_new_not_null(ctx);
- null = sym_new_null(ctx);
stack_pointer[-1] = attr;
- if (oparg & 1) stack_pointer[0] = null;
- stack_pointer += (oparg & 1);
- assert(WITHIN_STACK_BOUNDS());
break;
}
diff --git a/Python/specialize.c b/Python/specialize.c
index fa022346bdea6a..eb599028cefafa 100644
--- a/Python/specialize.c
+++ b/Python/specialize.c
@@ -804,7 +804,7 @@ _Py_Specialize_LoadSuperAttr(_PyStackRef global_super_st, _PyStackRef cls_st, _P
SPECIALIZATION_FAIL(LOAD_SUPER_ATTR, SPEC_FAIL_SUPER_BAD_CLASS);
goto fail;
}
- uint8_t load_code = load_method ? LOAD_SUPER_ATTR_METHOD : LOAD_SUPER_ATTR_ATTR;
+ uint8_t load_code = load_method ? LOAD_SUPER_METHOD_METHOD : LOAD_SUPER_ATTR_ATTR;
specialize(instr, load_code);
return;
fail:
@@ -1109,7 +1109,7 @@ instance_has_key(PyObject *obj, PyObject *name, uint32_t *shared_keys_version)
static int
do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name,
bool shadow, uint32_t shared_keys_version,
- DescriptorClassification kind, PyObject *descr, unsigned int tp_version)
+ DescriptorClassification kind, PyObject *descr, unsigned int tp_version, bool load_method)
{
_PyAttrCache *cache = (_PyAttrCache *)(instr + 1);
PyTypeObject *type = Py_TYPE(owner);
@@ -1117,17 +1117,16 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
return -1;
}
- uint8_t oparg = FT_ATOMIC_LOAD_UINT8_RELAXED(instr->op.arg);
switch(kind) {
case OVERRIDING:
- SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR);
+ SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR);
return -1;
case METHOD:
{
if (shadow) {
goto try_instance;
}
- if (oparg & 1) {
+ if (load_method) {
if (specialize_attr_loadclassattr(owner, instr, name, descr,
tp_version, kind, true,
shared_keys_version)) {
@@ -1137,7 +1136,7 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
return -1;
}
}
- SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD);
+ SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_METHOD);
return -1;
}
case PROPERTY:
@@ -1146,28 +1145,28 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
assert(Py_TYPE(descr) == &PyProperty_Type);
PyObject *fget = ((_PyPropertyObject *)descr)->prop_get;
if (fget == NULL) {
- SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR);
+ SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR);
return -1;
}
if (!Py_IS_TYPE(fget, &PyFunction_Type)) {
- SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION);
+ SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION);
return -1;
}
- if (!function_check_args(fget, 1, LOAD_ATTR)) {
+ if (load_method) {
+ SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_ATTR_METHOD);
return -1;
}
- if (oparg & 1) {
- SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD);
+ if (!function_check_args(fget, 1, LOAD_ATTR)) {
return -1;
}
/* Don't specialize if PEP 523 is active */
if (_PyInterpreterState_GET()->eval_frame) {
- SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OTHER);
+ SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_OTHER);
return -1;
}
#ifdef Py_GIL_DISABLED
if (!_PyObject_HasDeferredRefcount(fget)) {
- SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_DESCR_NOT_DEFERRED);
+ SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_DESCR_NOT_DEFERRED);
return -1;
}
#endif
@@ -1180,6 +1179,10 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
}
case OBJECT_SLOT:
{
+ if (load_method) {
+ SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
+ return -1;
+ }
PyMemberDescrObject *member = (PyMemberDescrObject *)descr;
struct PyMemberDef *dmem = member->d_member;
Py_ssize_t offset = dmem->offset;
@@ -1204,6 +1207,10 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
}
case DUNDER_CLASS:
{
+ if (load_method) {
+ SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
+ return -1;
+ }
Py_ssize_t offset = offsetof(PyObject, ob_type);
assert(offset == (uint16_t)offset);
cache->index = (uint16_t)offset;
@@ -1212,16 +1219,20 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
return 0;
}
case OTHER_SLOT:
- SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NON_OBJECT_SLOT);
+ SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_NON_OBJECT_SLOT);
return -1;
case MUTABLE:
- SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_MUTABLE_CLASS);
+ SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_MUTABLE_CLASS);
return -1;
case GETSET_OVERRIDDEN:
- SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OVERRIDDEN);
+ SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_OVERRIDDEN);
return -1;
case GETATTRIBUTE_IS_PYTHON_FUNCTION:
{
+ if (load_method) {
+ SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
+ return -1;
+ }
#ifndef Py_GIL_DISABLED
// In free-threaded builds it's possible for tp_getattro to change
// after the call to analyze_descriptor. That is fine: the version
@@ -1233,10 +1244,6 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
if (!function_check_args(descr, 2, LOAD_ATTR)) {
return -1;
}
- if (oparg & 1) {
- SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD);
- return -1;
- }
uint32_t version = function_get_version(descr, LOAD_ATTR);
if (version == 0) {
return -1;
@@ -1270,7 +1277,7 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
if (shadow) {
goto try_instance;
}
- if ((oparg & 1) == 0) {
+ if (!load_method) {
if (specialize_attr_loadclassattr(owner, instr, name, descr,
tp_version, kind, false,
shared_keys_version)) {
@@ -1287,6 +1294,10 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
}
Py_UNREACHABLE();
try_instance:
+ if (load_method) {
+ SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
+ return -1;
+ }
if (specialize_dict_access(owner, instr, type, kind, name, tp_version,
LOAD_ATTR, LOAD_ATTR_INSTANCE_VALUE, LOAD_ATTR_WITH_HINT))
{
@@ -1296,7 +1307,7 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
}
static int
-specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name)
+specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name, bool load_method)
{
// 0 is not a valid version
uint32_t shared_keys_version = 0;
@@ -1305,7 +1316,7 @@ specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* na
unsigned int tp_version = 0;
PyTypeObject *type = Py_TYPE(owner);
DescriptorClassification kind = analyze_descriptor_load(type, name, &descr, &tp_version);
- int result = do_specialize_instance_load_attr(owner, instr, name, shadow, shared_keys_version, kind, descr, tp_version);
+ int result = do_specialize_instance_load_attr(owner, instr, name, shadow, shared_keys_version, kind, descr, tp_version, load_method);
Py_XDECREF(descr);
return result;
}
@@ -1333,7 +1344,40 @@ _Py_Specialize_LoadAttr(_PyStackRef owner_st, _Py_CODEUNIT *instr, PyObject *nam
fail = specialize_class_load_attr(owner, instr, name);
}
else {
- fail = specialize_instance_load_attr(owner, instr, name);
+ fail = specialize_instance_load_attr(owner, instr, name, false);
+ }
+
+ if (fail) {
+ unspecialize(instr);
+ }
+}
+
+void
+_Py_Specialize_LoadMethod(_PyStackRef owner_st, _Py_CODEUNIT *instr, PyObject *name)
+{
+ PyObject *owner = PyStackRef_AsPyObjectBorrow(owner_st);
+
+ assert(ENABLE_SPECIALIZATION_FT);
+ assert(_PyOpcode_Caches[LOAD_ATTR] == INLINE_CACHE_ENTRIES_LOAD_ATTR);
+ PyTypeObject *type = Py_TYPE(owner);
+ bool fail;
+ if (!_PyType_IsReady(type)) {
+ // We *might* not really need this check, but we inherited it from
+ // PyObject_GenericGetAttr and friends... and this way we still do the
+ // right thing if someone forgets to call PyType_Ready(type):
+ SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
+ fail = true;
+ }
+ else if (Py_TYPE(owner)->tp_getattro == PyModule_Type.tp_getattro) {
+ SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
+ fail = true;
+ }
+ else if (PyType_Check(owner)) {
+ SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
+ fail = true;
+ }
+ else {
+ fail = specialize_instance_load_attr(owner, instr, name, true);
}
if (fail) {
@@ -1575,7 +1619,7 @@ specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
#ifdef Py_GIL_DISABLED
if (!_PyObject_HasDeferredRefcount(descr)) {
- SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_DESCR_NOT_DEFERRED);
+ SPECIALIZATION_FAIL(is_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_DESCR_NOT_DEFERRED);
return 0;
}
#endif
@@ -1587,11 +1631,11 @@ specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
((PyHeapTypeObject *)owner_cls)->ht_cached_keys, name) < 0);
#endif
if (shared_keys_version == 0) {
- SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
+ SPECIALIZATION_FAIL(is_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
return 0;
}
write_u32(cache->keys_version, shared_keys_version);
- specialize(instr, is_method ? LOAD_ATTR_METHOD_WITH_VALUES : LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES);
+ specialize(instr, is_method ? LOAD_METHOD_WITH_VALUES : LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES);
}
else {
Py_ssize_t dictoffset;
@@ -1601,17 +1645,17 @@ specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
else {
dictoffset = owner_cls->tp_dictoffset;
if (dictoffset < 0 || dictoffset > INT16_MAX + MANAGED_DICT_OFFSET) {
- SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_RANGE);
+ SPECIALIZATION_FAIL(is_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_OUT_OF_RANGE);
return 0;
}
}
if (dictoffset == 0) {
- specialize(instr, is_method ? LOAD_ATTR_METHOD_NO_DICT : LOAD_ATTR_NONDESCRIPTOR_NO_DICT);
+ specialize(instr, is_method ? LOAD_METHOD_NO_DICT : LOAD_ATTR_NONDESCRIPTOR_NO_DICT);
}
else if (is_method) {
PyObject *dict = *(PyObject **) ((char *)owner + dictoffset);
if (dict) {
- SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NOT_MANAGED_DICT);
+ SPECIALIZATION_FAIL(is_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_NOT_MANAGED_DICT);
return 0;
}
/* Cache entries must be unsigned values, so we offset the
@@ -1620,10 +1664,10 @@ specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
dictoffset -= MANAGED_DICT_OFFSET;
assert(((uint16_t)dictoffset) == dictoffset);
cache->dict_offset = (uint16_t)dictoffset;
- specialize(instr, LOAD_ATTR_METHOD_LAZY_DICT);
+ specialize(instr, LOAD_METHOD_LAZY_DICT);
}
else {
- SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_CLASS_ATTR_SIMPLE);
+ SPECIALIZATION_FAIL(is_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_CLASS_ATTR_SIMPLE);
return 0;
}
}
diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py
index 4013b503502df6..1f15c3bb9c88af 100644
--- a/Tools/cases_generator/analyzer.py
+++ b/Tools/cases_generator/analyzer.py
@@ -25,7 +25,6 @@ class Properties:
side_exit: bool
pure: bool
tier: int | None = None
- oparg_and_1: bool = False
const_oparg: int = -1
needs_prev: bool = False
no_save_ip: bool = False
@@ -124,16 +123,14 @@ def size(self) -> int:
class StackItem:
name: str
type: str | None
- condition: str | None
size: str
peek: bool = False
used: bool = False
def __str__(self) -> str:
- cond = f" if ({self.condition})" if self.condition else ""
size = f"[{self.size}]" if self.size else ""
type = "" if self.type is None else f"{self.type} "
- return f"{type}{self.name}{size}{cond} {self.peek}"
+ return f"{type}{self.name}{size} {self.peek}"
def is_array(self) -> bool:
return self.size != ""
@@ -315,25 +312,19 @@ def override_error(
)
-def convert_stack_item(
- item: parser.StackEffect, replace_op_arg_1: str | None
-) -> StackItem:
- cond = item.cond
- if replace_op_arg_1 and OPARG_AND_1.match(item.cond):
- cond = replace_op_arg_1
- return StackItem(item.name, item.type, cond, item.size)
+def convert_stack_item(item: parser.StackEffect) -> StackItem:
+ return StackItem(item.name, item.type, item.size)
def analyze_stack(
- op: parser.InstDef | parser.Pseudo, replace_op_arg_1: str | None = None
-) -> StackEffect:
+ op: parser.InstDef | parser.Pseudo) -> StackEffect:
inputs: list[StackItem] = [
- convert_stack_item(i, replace_op_arg_1)
+ convert_stack_item(i)
for i in op.inputs
if isinstance(i, parser.StackEffect)
]
outputs: list[StackItem] = [
- convert_stack_item(i, replace_op_arg_1) for i in op.outputs
+ convert_stack_item(i) for i in op.outputs
]
# Mark variables with matching names at the base of the stack as "peek"
modified = False
@@ -756,40 +747,6 @@ def always_exits(op: parser.InstDef) -> bool:
return True
return False
-
-def stack_effect_only_peeks(instr: parser.InstDef) -> bool:
- stack_inputs = [s for s in instr.inputs if not isinstance(s, parser.CacheEffect)]
- if len(stack_inputs) != len(instr.outputs):
- return False
- if len(stack_inputs) == 0:
- return False
- if any(s.cond for s in stack_inputs) or any(s.cond for s in instr.outputs):
- return False
- return all(
- (s.name == other.name and s.type == other.type and s.size == other.size)
- for s, other in zip(stack_inputs, instr.outputs)
- )
-
-
-OPARG_AND_1 = re.compile("\\(*oparg *& *1")
-
-
-def effect_depends_on_oparg_1(op: parser.InstDef) -> bool:
- for effect in op.inputs:
- if isinstance(effect, parser.CacheEffect):
- continue
- if not effect.cond:
- continue
- if OPARG_AND_1.match(effect.cond):
- return True
- for effect in op.outputs:
- if not effect.cond:
- continue
- if OPARG_AND_1.match(effect.cond):
- return True
- return False
-
-
def compute_properties(op: parser.InstDef) -> Properties:
escaping_calls = find_escaping_api_calls(op)
has_free = (
@@ -863,29 +820,6 @@ def make_uop(
body=op.block.tokens,
properties=compute_properties(op),
)
- if effect_depends_on_oparg_1(op) and "split" in op.annotations:
- result.properties.oparg_and_1 = True
- for bit in ("0", "1"):
- name_x = name + "_" + bit
- properties = compute_properties(op)
- if properties.oparg:
- # May not need oparg anymore
- properties.oparg = any(
- token.text == "oparg" for token in op.block.tokens
- )
- rep = Uop(
- name=name_x,
- context=op.context,
- annotations=op.annotations,
- stack=analyze_stack(op, bit),
- caches=analyze_caches(inputs),
- deferred_refs=analyze_deferred_refs(op),
- output_stores=find_stores_outputs(op),
- body=op.block.tokens,
- properties=properties,
- )
- rep.replicates = result
- uops[name_x] = rep
for anno in op.annotations:
if anno.startswith("replicate"):
result.replicated = int(anno[10:-1])
diff --git a/Tools/cases_generator/generators_common.py b/Tools/cases_generator/generators_common.py
index f54afbb880d2fa..c441569b7e70dc 100644
--- a/Tools/cases_generator/generators_common.py
+++ b/Tools/cases_generator/generators_common.py
@@ -246,7 +246,7 @@ def decref_inputs(
if var.name == "null":
continue
close = "PyStackRef_CLOSE"
- if "null" in var.name or var.condition and var.condition != "1":
+ if "null" in var.name:
close = "PyStackRef_XCLOSE"
if var.size:
if var.size == "1":
@@ -255,9 +255,6 @@ def decref_inputs(
self.out.emit(f"for (int _i = {var.size}; --_i >= 0;) {{\n")
self.out.emit(f"{close}({var.name}[_i]);\n")
self.out.emit("}\n")
- elif var.condition:
- if var.condition != "0":
- self.out.emit(f"{close}({var.name});\n")
else:
self.out.emit(f"{close}({var.name});\n")
for input in storage.inputs:
@@ -668,8 +665,6 @@ def cflags(p: Properties) -> str:
flags.append("HAS_PURE_FLAG")
if p.no_save_ip:
flags.append("HAS_NO_SAVE_IP_FLAG")
- if p.oparg_and_1:
- flags.append("HAS_OPARG_AND_1_FLAG")
if flags:
return " | ".join(flags)
else:
diff --git a/Tools/cases_generator/lexer.py b/Tools/cases_generator/lexer.py
index bee2a185745f4d..303a1c02705a3b 100644
--- a/Tools/cases_generator/lexer.py
+++ b/Tools/cases_generator/lexer.py
@@ -222,7 +222,6 @@ def choice(*opts: str) -> str:
"register",
"replaced",
"pure",
- "split",
"replicate",
"tier1",
"tier2",
diff --git a/Tools/cases_generator/opcode_metadata_generator.py b/Tools/cases_generator/opcode_metadata_generator.py
index 453db6905d6842..9ef49bdc41dc99 100644
--- a/Tools/cases_generator/opcode_metadata_generator.py
+++ b/Tools/cases_generator/opcode_metadata_generator.py
@@ -51,7 +51,6 @@
"EXIT",
"PURE",
"PASSTHROUGH",
- "OPARG_AND_1",
"ERROR_NO_POP",
"NO_SAVE_IP",
]
diff --git a/Tools/cases_generator/optimizer_generator.py b/Tools/cases_generator/optimizer_generator.py
index 5cfec4bfecbf07..7ebeff716d2900 100644
--- a/Tools/cases_generator/optimizer_generator.py
+++ b/Tools/cases_generator/optimizer_generator.py
@@ -48,19 +48,13 @@ def declare_variables(uop: Uop, out: CWriter, skip_inputs: bool) -> None:
for var in reversed(uop.stack.inputs):
if var.used and var.name not in variables:
variables.add(var.name)
- if var.condition:
- out.emit(f"{type_name(var)}{var.name} = NULL;\n")
- else:
- out.emit(f"{type_name(var)}{var.name};\n")
+ out.emit(f"{type_name(var)}{var.name};\n")
for var in uop.stack.outputs:
if var.peek:
continue
if var.name not in variables:
variables.add(var.name)
- if var.condition:
- out.emit(f"{type_name(var)}{var.name} = NULL;\n")
- else:
- out.emit(f"{type_name(var)}{var.name};\n")
+ out.emit(f"{type_name(var)}{var.name};\n")
def decref_inputs(
diff --git a/Tools/cases_generator/parsing.py b/Tools/cases_generator/parsing.py
index 41b36b6a546360..b50bb627b6c41c 100644
--- a/Tools/cases_generator/parsing.py
+++ b/Tools/cases_generator/parsing.py
@@ -77,12 +77,11 @@ class Block(Node):
class StackEffect(Node):
name: str = field(compare=False) # __eq__ only uses type, cond, size
type: str = "" # Optional `:type`
- cond: str = "" # Optional `if (cond)`
size: str = "" # Optional `[size]`
# Note: size cannot be combined with type or cond
def __repr__(self) -> str:
- items = [self.name, self.type, self.cond, self.size]
+ items = [self.name, self.type, self.size]
while items and items[-1] == "":
del items[-1]
return f"StackEffect({', '.join(repr(item) for item in items)})"
@@ -278,22 +277,15 @@ def stack_effect(self) -> StackEffect | None:
type_text = self.require(lx.IDENTIFIER).text.strip()
if self.expect(lx.TIMES):
type_text += " *"
- cond_text = ""
- if self.expect(lx.IF):
- self.require(lx.LPAREN)
- if not (cond := self.expression()):
- raise self.make_syntax_error("Expected condition")
- self.require(lx.RPAREN)
- cond_text = cond.text.strip()
size_text = ""
if self.expect(lx.LBRACKET):
- if type_text or cond_text:
+ if type_text:
raise self.make_syntax_error("Unexpected [")
if not (size := self.expression()):
raise self.make_syntax_error("Expected expression")
self.require(lx.RBRACKET)
size_text = size.text.strip()
- return StackEffect(tkn.text, type_text, cond_text, size_text)
+ return StackEffect(tkn.text, type_text, size_text)
return None
@contextual
diff --git a/Tools/cases_generator/stack.py b/Tools/cases_generator/stack.py
index 5121837ed8334b..4e9a312ce34146 100644
--- a/Tools/cases_generator/stack.py
+++ b/Tools/cases_generator/stack.py
@@ -24,17 +24,7 @@ def maybe_parenthesize(sym: str) -> str:
def var_size(var: StackItem) -> str:
- if var.condition:
- # Special case simplifications
- if var.condition == "0":
- return "0"
- elif var.condition == "1":
- return var.get_size()
- elif var.condition == "oparg & 1" and not var.size:
- return f"({var.condition})"
- else:
- return f"(({var.condition}) ? {var.get_size()} : 0)"
- elif var.size:
+ if var.size:
return var.size
else:
return "1"
@@ -90,10 +80,6 @@ def size(self) -> str:
def name(self) -> str:
return self.item.name
- @property
- def condition(self) -> str | None:
- return self.item.condition
-
def is_array(self) -> bool:
return self.item.is_array()
@@ -274,16 +260,7 @@ def pop(self, var: StackItem) -> tuple[str, Local]:
self.defined.add(var.name)
cast = f"({var.type})" if (not indirect and var.type) else ""
bits = ".bits" if cast and self.extract_bits else ""
- assign = f"{var.name} = {cast}{indirect}stack_pointer[{self.base_offset.to_c()}]{bits};"
- if var.condition:
- if var.condition == "1":
- assign = f"{assign}\n"
- elif var.condition == "0":
- return "", Local.unused(var)
- else:
- assign = f"if ({var.condition}) {{ {assign} }}\n"
- else:
- assign = f"{assign}\n"
+ assign = f"{var.name} = {cast}{indirect}stack_pointer[{self.base_offset.to_c()}]{bits};\n"
return assign, Local.from_memory(var)
def push(self, var: Local) -> None:
@@ -303,10 +280,6 @@ def _do_emit(
) -> None:
cast = f"({cast_type})" if var.type else ""
bits = ".bits" if cast and extract_bits else ""
- if var.condition == "0":
- return
- if var.condition and var.condition != "1":
- out.emit(f"if ({var.condition}) ")
out.emit(f"stack_pointer[{base_offset.to_c()}]{bits} = {cast}{var.name};\n")
def _adjust_stack_pointer(self, out: CWriter, number: str) -> None:
diff --git a/Tools/cases_generator/tier1_generator.py b/Tools/cases_generator/tier1_generator.py
index 40562da99b20ea..95876c387bd745 100644
--- a/Tools/cases_generator/tier1_generator.py
+++ b/Tools/cases_generator/tier1_generator.py
@@ -37,10 +37,7 @@
def declare_variable(var: StackItem, out: CWriter) -> None:
type, null = type_and_null(var)
space = " " if type[-1].isalnum() else ""
- if var.condition:
- out.emit(f"{type}{space}{var.name} = {null};\n")
- else:
- out.emit(f"{type}{space}{var.name};\n")
+ out.emit(f"{type}{space}{var.name};\n")
def declare_variables(inst: Instruction, out: CWriter) -> None:
diff --git a/Tools/cases_generator/tier2_generator.py b/Tools/cases_generator/tier2_generator.py
index dd16a1a7eb28b5..abd9b8d7924299 100644
--- a/Tools/cases_generator/tier2_generator.py
+++ b/Tools/cases_generator/tier2_generator.py
@@ -39,14 +39,7 @@ def declare_variable(
required.remove(var.name)
type, null = type_and_null(var)
space = " " if type[-1].isalnum() else ""
- if var.condition:
- out.emit(f"{type}{space}{var.name} = {null};\n")
- if uop.replicates:
- # Replicas may not use all their conditional variables
- # So avoid a compiler warning with a fake use
- out.emit(f"(void){var.name};\n")
- else:
- out.emit(f"{type}{space}{var.name};\n")
+ out.emit(f"{type}{space}{var.name};\n")
def declare_variables(uop: Uop, out: CWriter) -> None:
@@ -215,9 +208,6 @@ def generate_tier2(
for name, uop in analysis.uops.items():
if uop.properties.tier == 1:
continue
- if uop.properties.oparg_and_1:
- out.emit(f"/* {uop.name} is split on (oparg & 1) */\n\n")
- continue
if uop.is_super():
continue
why_not_viable = uop.why_not_viable()
diff --git a/Tools/scripts/summarize_stats.py b/Tools/scripts/summarize_stats.py
index bc7ccfe33e777d..17478933eb68e5 100644
--- a/Tools/scripts/summarize_stats.py
+++ b/Tools/scripts/summarize_stats.py
@@ -284,7 +284,7 @@ def get_specialization_failure_kinds(self, opcode: str) -> dict[str, int]:
def kind_to_text(kind: int, opcode: str):
if kind <= 8:
return pretty(self._defines[kind][0])
- if opcode == "LOAD_SUPER_ATTR":
+ if opcode == "LOAD_SUPER_ATTR" or opcode == "LOAD_SUPER_METHOD":
opcode = "SUPER"
elif opcode.endswith("ATTR"):
opcode = "ATTR"
1
0