Python-checkins
Threads by month
- ----- 2025 -----
- 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
- 525 discussions
https://github.com/python/cpython/commit/0a6412f9cc9e694e76299cfbd73ec969b7…
commit: 0a6412f9cc9e694e76299cfbd73ec969b7d47af6
branch: main
author: Filipe Laíns 🇵🇸 <lains(a)riseup.net>
committer: FFY00 <filipe.lains(a)gmail.com>
date: 2025-01-20T17:03:44Z
summary:
GH-129064: deprecate sysconfig.expand_makefile_vars (#129082)
files:
A Misc/NEWS.d/next/Library/2025-01-20-16-02-38.gh-issue-129064.JXasgJ.rst
M Doc/deprecations/pending-removal-in-3.16.rst
M Lib/sysconfig/__init__.py
M Lib/test/test_sysconfig.py
diff --git a/Doc/deprecations/pending-removal-in-3.16.rst b/Doc/deprecations/pending-removal-in-3.16.rst
index 41b30defdba0bc..58f7c01bf39469 100644
--- a/Doc/deprecations/pending-removal-in-3.16.rst
+++ b/Doc/deprecations/pending-removal-in-3.16.rst
@@ -80,6 +80,12 @@ Pending removal in Python 3.16
has been deprecated since Python 3.13.
Use the :envvar:`PYTHONLEGACYWINDOWSFSENCODING` environment variable instead.
+* :mod:`sysconfig`:
+
+ * The ``~sysconfig.expand_makefile_vars`` function
+ has been deprecated since Python 3.14.
+ Use the ``vars`` argument of :func:`sysconfig.get_paths` instead.
+
* :mod:`tarfile`:
* The undocumented and unused :attr:`!TarFile.tarfile` attribute
diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py
index ec9bb705925cdb..86dd391aa173b5 100644
--- a/Lib/sysconfig/__init__.py
+++ b/Lib/sysconfig/__init__.py
@@ -716,6 +716,15 @@ def expand_makefile_vars(s, vars):
variable expansions; if 'vars' is the output of 'parse_makefile()',
you're fine. Returns a variable-expanded version of 's'.
"""
+
+ import warnings
+ warnings.warn(
+ 'sysconfig.expand_makefile_vars is deprecated and will be removed in '
+ 'Python 3.16. Use sysconfig.get_paths(vars=...) instead.',
+ DeprecationWarning,
+ stacklevel=2,
+ )
+
import re
_findvar1_rx = r"\$\(([A-Za-z][A-Za-z0-9_]*)\)"
diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py
index ce504dc21af85f..a5676027eb7438 100644
--- a/Lib/test/test_sysconfig.py
+++ b/Lib/test/test_sysconfig.py
@@ -711,5 +711,24 @@ def test_parse_makefile(self):
})
+class DeprecationTests(unittest.TestCase):
+ def deprecated(self, removal_version, deprecation_msg=None, attribute_msg=None):
+ if sys.version_info >= removal_version:
+ return self.assertRaises(AttributeError, msg=attribute_msg)
+ else:
+ return self.assertWarns(DeprecationWarning, msg=deprecation_msg)
+
+ def test_expand_makefile_vars(self):
+ with self.deprecated(
+ removal_version=(3, 16),
+ deprecation_msg=(
+ 'sysconfig.expand_makefile_vars is deprecated and will be removed in '
+ 'Python 3.16. Use sysconfig.get_paths(vars=...) instead.',
+ ),
+ attribute_msg="module 'sysconfig' has no attribute 'expand_makefile_vars'",
+ ):
+ sysconfig.expand_makefile_vars('', {})
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/Misc/NEWS.d/next/Library/2025-01-20-16-02-38.gh-issue-129064.JXasgJ.rst b/Misc/NEWS.d/next/Library/2025-01-20-16-02-38.gh-issue-129064.JXasgJ.rst
new file mode 100644
index 00000000000000..5939fdc8ef3469
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-01-20-16-02-38.gh-issue-129064.JXasgJ.rst
@@ -0,0 +1,2 @@
+Deprecate ``sysconfig.expand_makefile_vars``, in favor of using
+:func:`sysconfig.get_paths` with the ``vars`` argument.
1
0
Jan. 20, 2025
https://github.com/python/cpython/commit/38a99568763604ccec5d5027f0658100ad…
commit: 38a99568763604ccec5d5027f0658100ad76876f
branch: main
author: Thomas Grainger <tagrain(a)gmail.com>
committer: kumaraditya303 <kumaraditya(a)python.org>
date: 2025-01-20T22:23:55+05:30
summary:
gh-128308: pass `**kwargs` to asyncio task_factory (#128768)
Co-authored-by: Kumar Aditya <kumaraditya(a)python.org>
files:
A Misc/NEWS.d/next/Library/2025-01-13-07-54-32.gh-issue-128308.kYSDRF.rst
M Doc/library/asyncio-eventloop.rst
M Lib/asyncio/base_events.py
M Lib/asyncio/events.py
M Lib/test/test_asyncio/test_base_events.py
M Lib/test/test_asyncio/test_eager_task_factory.py
M Lib/test/test_asyncio/test_free_threading.py
M Lib/test/test_asyncio/test_taskgroups.py
diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst
index 3bf38a2212c0e0..15ef33e195904d 100644
--- a/Doc/library/asyncio-eventloop.rst
+++ b/Doc/library/asyncio-eventloop.rst
@@ -392,9 +392,9 @@ Creating Futures and Tasks
If *factory* is ``None`` the default task factory will be set.
Otherwise, *factory* must be a *callable* with the signature matching
- ``(loop, coro, context=None)``, where *loop* is a reference to the active
+ ``(loop, coro, **kwargs)``, where *loop* is a reference to the active
event loop, and *coro* is a coroutine object. The callable
- must return a :class:`asyncio.Future`-compatible object.
+ must pass on all *kwargs*, and return a :class:`asyncio.Task`-compatible object.
.. method:: loop.get_task_factory()
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index 85018797db33bb..ed852421e44212 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -458,25 +458,18 @@ def create_future(self):
"""Create a Future object attached to the loop."""
return futures.Future(loop=self)
- def create_task(self, coro, *, name=None, context=None):
+ def create_task(self, coro, **kwargs):
"""Schedule a coroutine object.
Return a task object.
"""
self._check_closed()
- if self._task_factory is None:
- task = tasks.Task(coro, loop=self, name=name, context=context)
- if task._source_traceback:
- del task._source_traceback[-1]
- else:
- if context is None:
- # Use legacy API if context is not needed
- task = self._task_factory(self, coro)
- else:
- task = self._task_factory(self, coro, context=context)
-
- task.set_name(name)
+ if self._task_factory is not None:
+ return self._task_factory(self, coro, **kwargs)
+ task = tasks.Task(coro, loop=self, **kwargs)
+ if task._source_traceback:
+ del task._source_traceback[-1]
try:
return task
finally:
@@ -490,9 +483,10 @@ def set_task_factory(self, factory):
If factory is None the default task factory will be set.
If factory is a callable, it should have a signature matching
- '(loop, coro)', where 'loop' will be a reference to the active
- event loop, 'coro' will be a coroutine object. The callable
- must return a Future.
+ '(loop, coro, **kwargs)', where 'loop' will be a reference to the active
+ event loop, 'coro' will be a coroutine object, and **kwargs will be
+ arbitrary keyword arguments that should be passed on to Task.
+ The callable must return a Task.
"""
if factory is not None and not callable(factory):
raise TypeError('task factory must be a callable or None')
diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py
index 2ee9870e80f20b..2e45b4fe6fa2dd 100644
--- a/Lib/asyncio/events.py
+++ b/Lib/asyncio/events.py
@@ -329,7 +329,7 @@ def create_future(self):
# Method scheduling a coroutine object: create a task.
- def create_task(self, coro, *, name=None, context=None):
+ def create_task(self, coro, **kwargs):
raise NotImplementedError
# Methods for interacting with threads.
diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
index 102c9be0ecf031..8cf1f6891faf97 100644
--- a/Lib/test/test_asyncio/test_base_events.py
+++ b/Lib/test/test_asyncio/test_base_events.py
@@ -833,8 +833,8 @@ async def test():
loop.close()
def test_create_named_task_with_custom_factory(self):
- def task_factory(loop, coro):
- return asyncio.Task(coro, loop=loop)
+ def task_factory(loop, coro, **kwargs):
+ return asyncio.Task(coro, loop=loop, **kwargs)
async def test():
pass
diff --git a/Lib/test/test_asyncio/test_eager_task_factory.py b/Lib/test/test_asyncio/test_eager_task_factory.py
index dcf9ff716ad399..10450c11b68279 100644
--- a/Lib/test/test_asyncio/test_eager_task_factory.py
+++ b/Lib/test/test_asyncio/test_eager_task_factory.py
@@ -302,6 +302,18 @@ async def run():
self.run_coro(run())
+ def test_name(self):
+ name = None
+ async def coro():
+ nonlocal name
+ name = asyncio.current_task().get_name()
+
+ async def main():
+ task = self.loop.create_task(coro(), name="test name")
+ self.assertEqual(name, "test name")
+ await task
+
+ self.run_coro(coro())
class AsyncTaskCounter:
def __init__(self, loop, *, task_class, eager):
diff --git a/Lib/test/test_asyncio/test_free_threading.py b/Lib/test/test_asyncio/test_free_threading.py
index 8f4bba5f3b97d9..05106a2c2fe3f6 100644
--- a/Lib/test/test_asyncio/test_free_threading.py
+++ b/Lib/test/test_asyncio/test_free_threading.py
@@ -112,8 +112,8 @@ class TestPyFreeThreading(TestFreeThreading, TestCase):
all_tasks = staticmethod(asyncio.tasks._py_all_tasks)
current_task = staticmethod(asyncio.tasks._py_current_task)
- def factory(self, loop, coro, context=None):
- return asyncio.tasks._PyTask(coro, loop=loop, context=context)
+ def factory(self, loop, coro, **kwargs):
+ return asyncio.tasks._PyTask(coro, loop=loop, **kwargs)
@unittest.skipUnless(hasattr(asyncio.tasks, "_c_all_tasks"), "requires _asyncio")
@@ -121,16 +121,16 @@ class TestCFreeThreading(TestFreeThreading, TestCase):
all_tasks = staticmethod(getattr(asyncio.tasks, "_c_all_tasks", None))
current_task = staticmethod(getattr(asyncio.tasks, "_c_current_task", None))
- def factory(self, loop, coro, context=None):
- return asyncio.tasks._CTask(coro, loop=loop, context=context)
+ def factory(self, loop, coro, **kwargs):
+ return asyncio.tasks._CTask(coro, loop=loop, **kwargs)
class TestEagerPyFreeThreading(TestPyFreeThreading):
- def factory(self, loop, coro, context=None):
- return asyncio.tasks._PyTask(coro, loop=loop, context=context, eager_start=True)
+ def factory(self, loop, coro, eager_start=True, **kwargs):
+ return asyncio.tasks._PyTask(coro, loop=loop, **kwargs, eager_start=eager_start)
@unittest.skipUnless(hasattr(asyncio.tasks, "_c_all_tasks"), "requires _asyncio")
class TestEagerCFreeThreading(TestCFreeThreading, TestCase):
- def factory(self, loop, coro, context=None):
- return asyncio.tasks._CTask(coro, loop=loop, context=context, eager_start=True)
+ def factory(self, loop, coro, eager_start=True, **kwargs):
+ return asyncio.tasks._CTask(coro, loop=loop, **kwargs, eager_start=eager_start)
diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py
index 870fa8dbbf2714..7859b33532fa27 100644
--- a/Lib/test/test_asyncio/test_taskgroups.py
+++ b/Lib/test/test_asyncio/test_taskgroups.py
@@ -1040,6 +1040,18 @@ class MyKeyboardInterrupt(KeyboardInterrupt):
self.assertIsNotNone(exc)
self.assertListEqual(gc.get_referrers(exc), no_other_refs())
+ async def test_name(self):
+ name = None
+
+ async def asyncfn():
+ nonlocal name
+ name = asyncio.current_task().get_name()
+
+ async with asyncio.TaskGroup() as tg:
+ tg.create_task(asyncfn(), name="example name")
+
+ self.assertEqual(name, "example name")
+
class TestTaskGroup(BaseTestTaskGroup, unittest.IsolatedAsyncioTestCase):
loop_factory = asyncio.EventLoop
diff --git a/Misc/NEWS.d/next/Library/2025-01-13-07-54-32.gh-issue-128308.kYSDRF.rst b/Misc/NEWS.d/next/Library/2025-01-13-07-54-32.gh-issue-128308.kYSDRF.rst
new file mode 100644
index 00000000000000..efa613876a35fd
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-01-13-07-54-32.gh-issue-128308.kYSDRF.rst
@@ -0,0 +1 @@
+Support the *name* keyword argument for eager tasks in :func:`asyncio.loop.create_task`, :func:`asyncio.create_task` and :func:`asyncio.TaskGroup.create_task`, by passing on all *kwargs* to the task factory set by :func:`asyncio.loop.set_task_factory`.
1
0
https://github.com/python/cpython/commit/6c914bf85cc3a07e22e4618d0b5607c158…
commit: 6c914bf85cc3a07e22e4618d0b5607c158e3cf66
branch: main
author: Diego Russo <diego.russo(a)arm.com>
committer: hugovk <1324225+hugovk(a)users.noreply.github.com>
date: 2025-01-20T18:51:09+02:00
summary:
Move to public Linux arm64 hosted runners (#128964)
Co-authored-by: Hugo van Kemenade <1324225+hugovk(a)users.noreply.github.com>
files:
M .github/actionlint.yaml
M .github/workflows/build.yml
M .github/workflows/jit.yml
M .pre-commit-config.yaml
diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml
index 3701f7297ffeb2..af125266ae7813 100644
--- a/.github/actionlint.yaml
+++ b/.github/actionlint.yaml
@@ -1,5 +1,5 @@
self-hosted-runner:
- labels: ["ubuntu-24.04-aarch64", "windows-aarch64"]
+ labels: ["windows-aarch64"]
config-variables: null
@@ -7,4 +7,4 @@ paths:
.github/workflows/**/*.yml:
ignore:
- 1st argument of function call is not assignable
- - SC2(015|038|086|091|097|098|129|155)
\ No newline at end of file
+ - SC2(015|038|086|091|097|098|129|155)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 8a70cde3d8bc13..6667512369716d 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -244,17 +244,13 @@ jobs:
- true
os:
- ubuntu-24.04
- - ubuntu-24.04-aarch64
- is-fork: # only used for the exclusion trick
- - ${{ github.repository_owner != 'python' }}
+ - ubuntu-24.04-arm
exclude:
- - os: ubuntu-24.04-aarch64
- is-fork: true
# Do not test BOLT with free-threading, to conserve resources
- bolt: true
free-threading: true
# BOLT currently crashes during instrumentation on aarch64
- - os: ubuntu-24.04-aarch64
+ - os: ubuntu-24.04-arm
bolt: true
uses: ./.github/workflows/reusable-ubuntu.yml
with:
diff --git a/.github/workflows/jit.yml b/.github/workflows/jit.yml
index 9b84998a55666d..6f214ad4bc6978 100644
--- a/.github/workflows/jit.yml
+++ b/.github/workflows/jit.yml
@@ -83,8 +83,7 @@ jobs:
runner: ubuntu-24.04
- target: aarch64-unknown-linux-gnu/gcc
architecture: aarch64
- # Forks don't have access to our paid AArch64 runners. These jobs are skipped below:
- runner: ${{ github.repository_owner == 'python' && 'ubuntu-24.04-aarch64' || 'ubuntu-24.04' }}
+ runner: ubuntu-24.04-arm
steps:
- uses: actions/checkout@v4
with:
@@ -123,8 +122,7 @@ jobs:
./python.exe -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3
- name: Native Linux
- # Forks don't have access to our paid AArch64 runners. Skip those:
- if: runner.os == 'Linux' && (matrix.architecture == 'x86_64' || github.repository_owner == 'python')
+ if: runner.os == 'Linux'
run: |
sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh ${{ matrix.llvm }}
export PATH="$(llvm-config-${{ matrix.llvm }} --bindir):$PATH"
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 74b56f060342bf..fb44c27704d455 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -56,7 +56,7 @@ repos:
- id: check-readthedocs
- repo: https://github.com/rhysd/actionlint
- rev: v1.7.6
+ rev: v1.7.7
hooks:
- id: actionlint
1
0
https://github.com/python/cpython/commit/6e02096e2f9a18671d608f79dd61c5757d…
commit: 6e02096e2f9a18671d608f79dd61c5757deca4e8
branch: main
author: Peter Bierma <zintensitydev(a)gmail.com>
committer: encukou <encukou(a)gmail.com>
date: 2025-01-20T17:45:08+01:00
summary:
gh-118915: C API: Document compiler flag macros (GH-129028)
files:
M Doc/c-api/veryhigh.rst
diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst
index 9f02bdb5896563..1ef4181d52eb10 100644
--- a/Doc/c-api/veryhigh.rst
+++ b/Doc/c-api/veryhigh.rst
@@ -348,8 +348,20 @@ the same library that the Python runtime is using.
.. versionchanged:: 3.8
Added *cf_feature_version* field.
+ The available compiler flags are accessible as macros:
-.. c:var:: int CO_FUTURE_DIVISION
+ .. c:namespace:: NULL
- This bit can be set in *flags* to cause division operator ``/`` to be
- interpreted as "true division" according to :pep:`238`.
+ .. c:macro:: PyCF_ALLOW_TOP_LEVEL_AWAIT
+ PyCF_ONLY_AST
+ PyCF_OPTIMIZED_AST
+ PyCF_TYPE_COMMENTS
+
+ See :ref:`compiler flags <ast-compiler-flags>` in documentation of the
+ :py:mod:`!ast` Python module, which exports these constants under
+ the same names.
+
+ .. c:var:: int CO_FUTURE_DIVISION
+
+ This bit can be set in *flags* to cause division operator ``/`` to be
+ interpreted as "true division" according to :pep:`238`.
1
0
[3.12] Docs C API: Clarify what happens when null bytes are passed to `PyUnicode_AsUTF8` (GH-127458) (#129081)
by vstinner Jan. 20, 2025
by vstinner Jan. 20, 2025
Jan. 20, 2025
https://github.com/python/cpython/commit/e6cb31a098a5036519fe270b4d73b2b0e8…
commit: e6cb31a098a5036519fe270b4d73b2b0e8e774ba
branch: 3.12
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: vstinner <vstinner(a)python.org>
date: 2025-01-20T16:06:18Z
summary:
[3.12] Docs C API: Clarify what happens when null bytes are passed to `PyUnicode_AsUTF8` (GH-127458) (#129081)
Docs C API: Clarify what happens when null bytes are passed to `PyUnicode_AsUTF8` (GH-127458)
(cherry picked from commit e792f4bc2e712bb6e2143599d2b88dd339de83e6)
Co-authored-by: Peter Bierma <zintensitydev(a)gmail.com>
Co-authored-by: Stan U. <89152624+StanFromIreland(a)users.noreply.github.com>
Co-authored-by: Tomas R. <tomas.roun8(a)gmail.com>
Co-authored-by: Victor Stinner <vstinner(a)python.org>
files:
M Doc/c-api/unicode.rst
diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index 9b49569ad271b0..f2263610f6fa76 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -1032,6 +1032,15 @@ These are the UTF-8 codec APIs:
As :c:func:`PyUnicode_AsUTF8AndSize`, but does not store the size.
+ .. warning::
+
+ This function does not have any special behavior for
+ `null characters <https://en.wikipedia.org/wiki/Null_character>`_ embedded within
+ *unicode*. As a result, strings containing null characters will remain in the returned
+ string, which some C functions might interpret as the end of the string, leading to
+ truncation. If truncation is an issue, it is recommended to use :c:func:`PyUnicode_AsUTF8AndSize`
+ instead.
+
.. versionadded:: 3.3
.. versionchanged:: 3.7
1
0
[3.13] Docs C API: Clarify what happens when null bytes are passed to `PyUnicode_AsUTF8` (GH-127458) (#129080)
by vstinner Jan. 20, 2025
by vstinner Jan. 20, 2025
Jan. 20, 2025
https://github.com/python/cpython/commit/22e9faf08a4b2a90c62c3486d118383913…
commit: 22e9faf08a4b2a90c62c3486d1183839132d4231
branch: 3.13
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: vstinner <vstinner(a)python.org>
date: 2025-01-20T16:04:53Z
summary:
[3.13] Docs C API: Clarify what happens when null bytes are passed to `PyUnicode_AsUTF8` (GH-127458) (#129080)
Docs C API: Clarify what happens when null bytes are passed to `PyUnicode_AsUTF8` (GH-127458)
(cherry picked from commit e792f4bc2e712bb6e2143599d2b88dd339de83e6)
Co-authored-by: Peter Bierma <zintensitydev(a)gmail.com>
Co-authored-by: Stan U. <89152624+StanFromIreland(a)users.noreply.github.com>
Co-authored-by: Tomas R. <tomas.roun8(a)gmail.com>
Co-authored-by: Victor Stinner <vstinner(a)python.org>
files:
M Doc/c-api/unicode.rst
diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index 30592980968942..22e134c9f08ea8 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -1054,6 +1054,15 @@ These are the UTF-8 codec APIs:
As :c:func:`PyUnicode_AsUTF8AndSize`, but does not store the size.
+ .. warning::
+
+ This function does not have any special behavior for
+ `null characters <https://en.wikipedia.org/wiki/Null_character>`_ embedded within
+ *unicode*. As a result, strings containing null characters will remain in the returned
+ string, which some C functions might interpret as the end of the string, leading to
+ truncation. If truncation is an issue, it is recommended to use :c:func:`PyUnicode_AsUTF8AndSize`
+ instead.
+
.. versionadded:: 3.3
.. versionchanged:: 3.7
1
0
Docs C API: Clarify what happens when null bytes are passed to `PyUnicode_AsUTF8` (#127458)
by vstinner Jan. 20, 2025
by vstinner Jan. 20, 2025
Jan. 20, 2025
https://github.com/python/cpython/commit/e792f4bc2e712bb6e2143599d2b88dd339…
commit: e792f4bc2e712bb6e2143599d2b88dd339de83e6
branch: main
author: Peter Bierma <zintensitydev(a)gmail.com>
committer: vstinner <vstinner(a)python.org>
date: 2025-01-20T16:54:29+01:00
summary:
Docs C API: Clarify what happens when null bytes are passed to `PyUnicode_AsUTF8` (#127458)
Co-authored-by: Stan U. <89152624+StanFromIreland(a)users.noreply.github.com>
Co-authored-by: Tomas R. <tomas.roun8(a)gmail.com>
Co-authored-by: Victor Stinner <vstinner(a)python.org>
files:
M Doc/c-api/unicode.rst
diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index f19b86a8dbfb66..94110d48ed7d85 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -1054,6 +1054,15 @@ These are the UTF-8 codec APIs:
As :c:func:`PyUnicode_AsUTF8AndSize`, but does not store the size.
+ .. warning::
+
+ This function does not have any special behavior for
+ `null characters <https://en.wikipedia.org/wiki/Null_character>`_ embedded within
+ *unicode*. As a result, strings containing null characters will remain in the returned
+ string, which some C functions might interpret as the end of the string, leading to
+ truncation. If truncation is an issue, it is recommended to use :c:func:`PyUnicode_AsUTF8AndSize`
+ instead.
+
.. versionadded:: 3.3
.. versionchanged:: 3.7
1
0
[3.13] gh-129044: Update glossary entry for 'loader' to reflect current import system (GH-129073) (#129077)
by AA-Turner Jan. 20, 2025
by AA-Turner Jan. 20, 2025
Jan. 20, 2025
https://github.com/python/cpython/commit/2f8eefe97ab03ecf92f85918a2b4cb23be…
commit: 2f8eefe97ab03ecf92f85918a2b4cb23be7ee04c
branch: 3.13
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: AA-Turner <9087854+AA-Turner(a)users.noreply.github.com>
date: 2025-01-20T15:51:52Z
summary:
[3.13] gh-129044: Update glossary entry for 'loader' to reflect current import system (GH-129073) (#129077)
gh-129044: Update glossary entry for 'loader' to reflect current import system (GH-129073)
(cherry picked from commit e1fa2fcc7c1bf5291a7f71300b7828b49be9ab72)
Co-authored-by: nikalinov <92603661+nikalinov(a)users.noreply.github.com>
Co-authored-by: Adam Turner <9087854+AA-Turner(a)users.noreply.github.com>
files:
M Doc/glossary.rst
M Doc/tools/.nitignore
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index d8488ca99246d2..858c2b39ee5e33 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -801,9 +801,11 @@ Glossary
processed.
loader
- An object that loads a module. It must define a method named
- :meth:`load_module`. A loader is typically returned by a
- :term:`finder`. See also:
+ An object that loads a module.
+ It must define the :meth:`!exec_module` and :meth:`!create_module` methods
+ to implement the :class:`~importlib.abc.Loader` interface.
+ A loader is typically returned by a :term:`finder`.
+ See also:
* :ref:`finders-and-loaders`
* :class:`importlib.abc.Loader`
diff --git a/Doc/tools/.nitignore b/Doc/tools/.nitignore
index 8485766034ca77..9e36087ff10c3e 100644
--- a/Doc/tools/.nitignore
+++ b/Doc/tools/.nitignore
@@ -12,7 +12,6 @@ Doc/c-api/stable.rst
Doc/c-api/type.rst
Doc/c-api/typeobj.rst
Doc/extending/extending.rst
-Doc/glossary.rst
Doc/library/ast.rst
Doc/library/asyncio-extending.rst
Doc/library/asyncio-policy.rst
1
0
https://github.com/python/cpython/commit/f0f7b978be84c432139da1b107825aa2dc…
commit: f0f7b978be84c432139da1b107825aa2dc536854
branch: main
author: Mark Shannon <mark(a)hotpy.org>
committer: markshannon <mark(a)hotpy.org>
date: 2025-01-20T15:49:15Z
summary:
GH-128939: Refactor JIT optimize structs (GH-128940)
files:
M Include/internal/pycore_optimizer.h
M Lib/test/test_capi/test_opt.py
M Lib/test/test_generated_cases.py
M Modules/_testinternalcapi.c
M Python/optimizer_analysis.c
M Python/optimizer_bytecodes.c
M Python/optimizer_cases.c.h
M Python/optimizer_symbols.c
M Tools/cases_generator/optimizer_generator.py
diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h
index a02b9ab4291bfc..03ce4d4491acd7 100644
--- a/Include/internal/pycore_optimizer.h
+++ b/Include/internal/pycore_optimizer.h
@@ -148,15 +148,6 @@ extern PyTypeObject _PyDefaultOptimizer_Type;
extern PyTypeObject _PyUOpExecutor_Type;
extern PyTypeObject _PyUOpOptimizer_Type;
-/* Symbols */
-/* See explanation in optimizer_symbols.c */
-
-struct _Py_UopsSymbol {
- int flags; // 0 bits: Top; 2 or more bits: Bottom
- PyTypeObject *typ; // Borrowed reference
- PyObject *const_val; // Owned reference (!)
- unsigned int type_version; // currently stores type version
-};
#define UOP_FORMAT_TARGET 0
#define UOP_FORMAT_JUMP 1
@@ -193,16 +184,63 @@ static inline uint16_t uop_get_error_target(const _PyUOpInstruction *inst)
// handle before rejoining the rest of the program.
#define MAX_CHAIN_DEPTH 4
-typedef struct _Py_UopsSymbol _Py_UopsSymbol;
+/* Symbols */
+/* See explanation in optimizer_symbols.c */
+
+
+typedef enum _JitSymType {
+ JIT_SYM_UNKNOWN_TAG = 1,
+ JIT_SYM_NULL_TAG = 2,
+ JIT_SYM_NON_NULL_TAG = 3,
+ JIT_SYM_BOTTOM_TAG = 4,
+ JIT_SYM_TYPE_VERSION_TAG = 5,
+ JIT_SYM_KNOWN_CLASS_TAG = 6,
+ JIT_SYM_KNOWN_VALUE_TAG = 7,
+ JIT_SYM_TUPLE_TAG = 8,
+} JitSymType;
+
+typedef struct _jit_opt_known_class {
+ uint8_t tag;
+ uint32_t version;
+ PyTypeObject *type;
+} JitOptKnownClass;
+
+typedef struct _jit_opt_known_version {
+ uint8_t tag;
+ uint32_t version;
+} JitOptKnownVersion;
+
+typedef struct _jit_opt_known_value {
+ uint8_t tag;
+ PyObject *value;
+} JitOptKnownValue;
+
+#define MAX_SYMBOLIC_TUPLE_SIZE 7
+
+typedef struct _jit_opt_tuple {
+ uint8_t tag;
+ uint8_t length;
+ uint16_t items[MAX_SYMBOLIC_TUPLE_SIZE];
+} JitOptTuple;
+
+typedef union _jit_opt_symbol {
+ uint8_t tag;
+ JitOptKnownClass cls;
+ JitOptKnownValue value;
+ JitOptKnownVersion version;
+ JitOptTuple tuple;
+} JitOptSymbol;
+
+
struct _Py_UOpsAbstractFrame {
// Max stacklen
int stack_len;
int locals_len;
- _Py_UopsSymbol **stack_pointer;
- _Py_UopsSymbol **stack;
- _Py_UopsSymbol **locals;
+ JitOptSymbol **stack_pointer;
+ JitOptSymbol **stack;
+ JitOptSymbol **locals;
};
typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
@@ -210,10 +248,10 @@ typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
typedef struct ty_arena {
int ty_curr_number;
int ty_max_number;
- _Py_UopsSymbol arena[TY_ARENA_SIZE];
+ JitOptSymbol arena[TY_ARENA_SIZE];
} ty_arena;
-struct _Py_UOpsContext {
+typedef struct _JitOptContext {
char done;
char out_of_space;
bool contradiction;
@@ -225,46 +263,47 @@ struct _Py_UOpsContext {
// Arena for the symbolic types.
ty_arena t_arena;
- _Py_UopsSymbol **n_consumed;
- _Py_UopsSymbol **limit;
- _Py_UopsSymbol *locals_and_stack[MAX_ABSTRACT_INTERP_SIZE];
-};
-
-typedef struct _Py_UOpsContext _Py_UOpsContext;
-
-extern bool _Py_uop_sym_is_null(_Py_UopsSymbol *sym);
-extern bool _Py_uop_sym_is_not_null(_Py_UopsSymbol *sym);
-extern bool _Py_uop_sym_is_const(_Py_UopsSymbol *sym);
-extern PyObject *_Py_uop_sym_get_const(_Py_UopsSymbol *sym);
-extern _Py_UopsSymbol *_Py_uop_sym_new_unknown(_Py_UOpsContext *ctx);
-extern _Py_UopsSymbol *_Py_uop_sym_new_not_null(_Py_UOpsContext *ctx);
-extern _Py_UopsSymbol *_Py_uop_sym_new_type(
- _Py_UOpsContext *ctx, PyTypeObject *typ);
-extern _Py_UopsSymbol *_Py_uop_sym_new_const(_Py_UOpsContext *ctx, PyObject *const_val);
-extern _Py_UopsSymbol *_Py_uop_sym_new_null(_Py_UOpsContext *ctx);
-extern bool _Py_uop_sym_has_type(_Py_UopsSymbol *sym);
-extern bool _Py_uop_sym_matches_type(_Py_UopsSymbol *sym, PyTypeObject *typ);
-extern bool _Py_uop_sym_matches_type_version(_Py_UopsSymbol *sym, unsigned int version);
-extern void _Py_uop_sym_set_null(_Py_UOpsContext *ctx, _Py_UopsSymbol *sym);
-extern void _Py_uop_sym_set_non_null(_Py_UOpsContext *ctx, _Py_UopsSymbol *sym);
-extern void _Py_uop_sym_set_type(_Py_UOpsContext *ctx, _Py_UopsSymbol *sym, PyTypeObject *typ);
-extern bool _Py_uop_sym_set_type_version(_Py_UOpsContext *ctx, _Py_UopsSymbol *sym, unsigned int version);
-extern void _Py_uop_sym_set_const(_Py_UOpsContext *ctx, _Py_UopsSymbol *sym, PyObject *const_val);
-extern bool _Py_uop_sym_is_bottom(_Py_UopsSymbol *sym);
-extern int _Py_uop_sym_truthiness(_Py_UopsSymbol *sym);
-extern PyTypeObject *_Py_uop_sym_get_type(_Py_UopsSymbol *sym);
-
-
-extern void _Py_uop_abstractcontext_init(_Py_UOpsContext *ctx);
-extern void _Py_uop_abstractcontext_fini(_Py_UOpsContext *ctx);
+ JitOptSymbol **n_consumed;
+ JitOptSymbol **limit;
+ JitOptSymbol *locals_and_stack[MAX_ABSTRACT_INTERP_SIZE];
+} JitOptContext;
+
+extern bool _Py_uop_sym_is_null(JitOptSymbol *sym);
+extern bool _Py_uop_sym_is_not_null(JitOptSymbol *sym);
+extern bool _Py_uop_sym_is_const(JitOptSymbol *sym);
+extern PyObject *_Py_uop_sym_get_const(JitOptSymbol *sym);
+extern JitOptSymbol *_Py_uop_sym_new_unknown(JitOptContext *ctx);
+extern JitOptSymbol *_Py_uop_sym_new_not_null(JitOptContext *ctx);
+extern JitOptSymbol *_Py_uop_sym_new_type(
+ JitOptContext *ctx, PyTypeObject *typ);
+extern JitOptSymbol *_Py_uop_sym_new_const(JitOptContext *ctx, PyObject *const_val);
+extern JitOptSymbol *_Py_uop_sym_new_null(JitOptContext *ctx);
+extern bool _Py_uop_sym_has_type(JitOptSymbol *sym);
+extern bool _Py_uop_sym_matches_type(JitOptSymbol *sym, PyTypeObject *typ);
+extern bool _Py_uop_sym_matches_type_version(JitOptSymbol *sym, unsigned int version);
+extern void _Py_uop_sym_set_null(JitOptContext *ctx, JitOptSymbol *sym);
+extern void _Py_uop_sym_set_non_null(JitOptContext *ctx, JitOptSymbol *sym);
+extern void _Py_uop_sym_set_type(JitOptContext *ctx, JitOptSymbol *sym, PyTypeObject *typ);
+extern bool _Py_uop_sym_set_type_version(JitOptContext *ctx, JitOptSymbol *sym, unsigned int version);
+extern void _Py_uop_sym_set_const(JitOptContext *ctx, JitOptSymbol *sym, PyObject *const_val);
+extern bool _Py_uop_sym_is_bottom(JitOptSymbol *sym);
+extern int _Py_uop_sym_truthiness(JitOptSymbol *sym);
+extern PyTypeObject *_Py_uop_sym_get_type(JitOptSymbol *sym);
+extern bool _Py_uop_sym_is_immortal(JitOptSymbol *sym);
+extern JitOptSymbol *_Py_uop_sym_new_tuple(JitOptContext *ctx, int size, JitOptSymbol **args);
+extern JitOptSymbol *_Py_uop_sym_tuple_getitem(JitOptContext *ctx, JitOptSymbol *sym, int item);
+extern int _Py_uop_sym_tuple_length(JitOptSymbol *sym);
+
+extern void _Py_uop_abstractcontext_init(JitOptContext *ctx);
+extern void _Py_uop_abstractcontext_fini(JitOptContext *ctx);
extern _Py_UOpsAbstractFrame *_Py_uop_frame_new(
- _Py_UOpsContext *ctx,
+ JitOptContext *ctx,
PyCodeObject *co,
int curr_stackentries,
- _Py_UopsSymbol **args,
+ JitOptSymbol **args,
int arg_len);
-extern int _Py_uop_frame_pop(_Py_UOpsContext *ctx);
+extern int _Py_uop_frame_pop(JitOptContext *ctx);
PyAPI_FUNC(PyObject *) _Py_uop_symbols_test(PyObject *self, PyObject *ignored);
diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py
index a74b8fdd3923b7..9cfc6c142da6cd 100644
--- a/Lib/test/test_capi/test_opt.py
+++ b/Lib/test/test_capi/test_opt.py
@@ -1465,6 +1465,25 @@ def f(l: complex, r: complex) -> None:
with self.subTest(l=l, r=r, x=x, y=y):
script_helper.assert_python_ok("-c", s)
+ def test_symbols_flow_through_tuples(self):
+ def testfunc(n):
+ for _ in range(n):
+ a = 1
+ b = 2
+ t = a, b
+ x, y = t
+ r = x + y
+ return r
+
+ res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
+ self.assertEqual(res, 3)
+ self.assertIsNotNone(ex)
+ uops = get_opnames(ex)
+ self.assertIn("_BINARY_OP_ADD_INT", uops)
+ self.assertNotIn("_GUARD_BOTH_INT", uops)
+ self.assertNotIn("_GUARD_NOS_INT", uops)
+ self.assertNotIn("_GUARD_TOS_INT", uops)
+
def test_decref_escapes(self):
class Convert9999ToNone:
def __del__(self):
diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py
index 7a50a29bb0126c..aa92145266961a 100644
--- a/Lib/test/test_generated_cases.py
+++ b/Lib/test/test_generated_cases.py
@@ -1842,8 +1842,8 @@ def test_overridden_abstract_args(self):
"""
output = """
case OP: {
- _Py_UopsSymbol *arg1;
- _Py_UopsSymbol *out;
+ JitOptSymbol *arg1;
+ JitOptSymbol *out;
arg1 = stack_pointer[-1];
out = EGGS(arg1);
stack_pointer[-1] = out;
@@ -1851,7 +1851,7 @@ def test_overridden_abstract_args(self):
}
case OP2: {
- _Py_UopsSymbol *out;
+ JitOptSymbol *out;
out = sym_new_not_null(ctx);
stack_pointer[-1] = out;
break;
@@ -1876,14 +1876,14 @@ def test_no_overridden_case(self):
"""
output = """
case OP: {
- _Py_UopsSymbol *out;
+ JitOptSymbol *out;
out = sym_new_not_null(ctx);
stack_pointer[-1] = out;
break;
}
case OP2: {
- _Py_UopsSymbol *out;
+ JitOptSymbol *out;
out = NULL;
stack_pointer[-1] = out;
break;
diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c
index aae09f620b8898..e77df5b57b0504 100644
--- a/Modules/_testinternalcapi.c
+++ b/Modules/_testinternalcapi.c
@@ -27,7 +27,7 @@
#include "pycore_instruction_sequence.h" // _PyInstructionSequence_New()
#include "pycore_long.h" // _PyLong_Sign()
#include "pycore_object.h" // _PyObject_IsFreed()
-#include "pycore_optimizer.h" // _Py_UopsSymbol, etc.
+#include "pycore_optimizer.h" // JitOptSymbol, etc.
#include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal()
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
#include "pycore_pylifecycle.h" // _PyInterpreterConfig_AsDict()
diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c
index 0ef15c630e91db..b9ac30ea04e4e8 100644
--- a/Python/optimizer_analysis.c
+++ b/Python/optimizer_analysis.c
@@ -368,13 +368,17 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
#define sym_truthiness _Py_uop_sym_truthiness
#define frame_new _Py_uop_frame_new
#define frame_pop _Py_uop_frame_pop
+#define sym_new_tuple _Py_uop_sym_new_tuple
+#define sym_tuple_getitem _Py_uop_sym_tuple_getitem
+#define sym_tuple_length _Py_uop_sym_tuple_length
+#define sym_is_immortal _Py_uop_sym_is_immortal
static int
optimize_to_bool(
_PyUOpInstruction *this_instr,
- _Py_UOpsContext *ctx,
- _Py_UopsSymbol *value,
- _Py_UopsSymbol **result_ptr)
+ JitOptContext *ctx,
+ JitOptSymbol *value,
+ JitOptSymbol **result_ptr)
{
if (sym_matches_type(value, &PyBool_Type)) {
REPLACE_OP(this_instr, _NOP, 0, 0);
@@ -460,8 +464,8 @@ optimize_uops(
)
{
- _Py_UOpsContext context;
- _Py_UOpsContext *ctx = &context;
+ JitOptContext context;
+ JitOptContext *ctx = &context;
uint32_t opcode = UINT16_MAX;
int curr_space = 0;
int max_space = 0;
@@ -486,7 +490,7 @@ optimize_uops(
int oparg = this_instr->oparg;
opcode = this_instr->opcode;
- _Py_UopsSymbol **stack_pointer = ctx->frame->stack_pointer;
+ JitOptSymbol **stack_pointer = ctx->frame->stack_pointer;
#ifdef Py_DEBUG
if (get_lltrace() >= 3) {
diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c
index 4d96ada5acf00f..881a607ca2aa29 100644
--- a/Python/optimizer_bytecodes.c
+++ b/Python/optimizer_bytecodes.c
@@ -6,8 +6,6 @@
#define op(name, ...) /* NAME is ignored */
-typedef struct _Py_UopsSymbol _Py_UopsSymbol;
-typedef struct _Py_UOpsContext _Py_UOpsContext;
typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
/* Shortened forms for convenience */
@@ -32,13 +30,17 @@ typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
#define sym_is_bottom _Py_uop_sym_is_bottom
#define frame_new _Py_uop_frame_new
#define frame_pop _Py_uop_frame_pop
+#define sym_new_tuple _Py_uop_sym_new_tuple
+#define sym_tuple_getitem _Py_uop_sym_tuple_getitem
+#define sym_tuple_length _Py_uop_sym_tuple_length
+#define sym_is_immortal _Py_uop_sym_is_immortal
extern int
optimize_to_bool(
_PyUOpInstruction *this_instr,
- _Py_UOpsContext *ctx,
- _Py_UopsSymbol *value,
- _Py_UopsSymbol **result_ptr);
+ JitOptContext *ctx,
+ JitOptSymbol *value,
+ JitOptSymbol **result_ptr);
extern void
eliminate_pop_guard(_PyUOpInstruction *this_instr, bool exit);
@@ -50,17 +52,17 @@ dummy_func(void) {
PyCodeObject *co;
int oparg;
- _Py_UopsSymbol *flag;
- _Py_UopsSymbol *left;
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *value;
- _Py_UopsSymbol *res;
- _Py_UopsSymbol *iter;
- _Py_UopsSymbol *top;
- _Py_UopsSymbol *bottom;
+ JitOptSymbol *flag;
+ JitOptSymbol *left;
+ JitOptSymbol *right;
+ JitOptSymbol *value;
+ JitOptSymbol *res;
+ JitOptSymbol *iter;
+ JitOptSymbol *top;
+ JitOptSymbol *bottom;
_Py_UOpsAbstractFrame *frame;
_Py_UOpsAbstractFrame *new_frame;
- _Py_UOpsContext *ctx;
+ JitOptContext *ctx;
_PyUOpInstruction *this_instr;
_PyBloomFilter *dependencies;
int modified;
@@ -85,7 +87,7 @@ dummy_func(void) {
op(_LOAD_FAST_AND_CLEAR, (-- value)) {
value = GETLOCAL(oparg);
- _Py_UopsSymbol *temp = sym_new_null(ctx);
+ JitOptSymbol *temp = sym_new_null(ctx);
GETLOCAL(oparg) = temp;
}
@@ -365,7 +367,7 @@ dummy_func(void) {
}
op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right -- )) {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
if (sym_is_const(left) && sym_is_const(right) &&
sym_matches_type(left, &PyUnicode_Type) && sym_matches_type(right, &PyUnicode_Type)) {
PyObject *temp = PyUnicode_Concat(sym_get_const(left), sym_get_const(right));
@@ -949,6 +951,22 @@ dummy_func(void) {
res = sym_new_const(ctx, Py_True);
}
+ op(_BUILD_TUPLE, (values[oparg] -- tup)) {
+ tup = sym_new_tuple(ctx, oparg, values);
+ }
+
+ op(_UNPACK_SEQUENCE_TWO_TUPLE, (seq -- val1, val0)) {
+ val0 = sym_tuple_getitem(ctx, seq, 0);
+ val1 = sym_tuple_getitem(ctx, seq, 1);
+ }
+
+ op(_UNPACK_SEQUENCE_TUPLE, (seq -- values[oparg])) {
+ for (int i = 0; i < oparg; i++) {
+ values[i] = sym_tuple_getitem(ctx, seq, i);
+ }
+ }
+
+
// END BYTECODES //
}
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h
index 1f2b29c947434f..fa0b4ed4345320 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -26,7 +26,7 @@
/* _MONITOR_RESUME is not a viable micro-op for tier 2 */
case _LOAD_FAST_CHECK: {
- _Py_UopsSymbol *value;
+ JitOptSymbol *value;
value = GETLOCAL(oparg);
// We guarantee this will error - just bail and don't optimize it.
if (sym_is_null(value)) {
@@ -39,7 +39,7 @@
}
case _LOAD_FAST: {
- _Py_UopsSymbol *value;
+ JitOptSymbol *value;
value = GETLOCAL(oparg);
stack_pointer[0] = value;
stack_pointer += 1;
@@ -48,9 +48,9 @@
}
case _LOAD_FAST_AND_CLEAR: {
- _Py_UopsSymbol *value;
+ JitOptSymbol *value;
value = GETLOCAL(oparg);
- _Py_UopsSymbol *temp = sym_new_null(ctx);
+ JitOptSymbol *temp = sym_new_null(ctx);
GETLOCAL(oparg) = temp;
stack_pointer[0] = value;
stack_pointer += 1;
@@ -61,7 +61,7 @@
/* _LOAD_CONST is not a viable micro-op for tier 2 */
case _LOAD_CONST_MORTAL: {
- _Py_UopsSymbol *value;
+ JitOptSymbol *value;
PyObject *val = PyTuple_GET_ITEM(co->co_consts, this_instr->oparg);
int opcode = _Py_IsImmortal(val) ? _LOAD_CONST_INLINE_BORROW : _LOAD_CONST_INLINE;
REPLACE_OP(this_instr, opcode, 0, (uintptr_t)val);
@@ -73,7 +73,7 @@
}
case _LOAD_CONST_IMMORTAL: {
- _Py_UopsSymbol *value;
+ JitOptSymbol *value;
PyObject *val = PyTuple_GET_ITEM(co->co_consts, this_instr->oparg);
REPLACE_OP(this_instr, _LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)val);
value = sym_new_const(ctx, val);
@@ -84,7 +84,7 @@
}
case _LOAD_SMALL_INT: {
- _Py_UopsSymbol *value;
+ JitOptSymbol *value;
PyObject *val = PyLong_FromLong(this_instr->oparg);
value = sym_new_const(ctx, val);
stack_pointer[0] = value;
@@ -94,7 +94,7 @@
}
case _STORE_FAST: {
- _Py_UopsSymbol *value;
+ JitOptSymbol *value;
value = stack_pointer[-1];
GETLOCAL(oparg) = value;
stack_pointer += -1;
@@ -109,7 +109,7 @@
}
case _PUSH_NULL: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_null(ctx);
stack_pointer[0] = res;
stack_pointer += 1;
@@ -124,7 +124,7 @@
}
case _END_SEND: {
- _Py_UopsSymbol *val;
+ JitOptSymbol *val;
val = sym_new_not_null(ctx);
stack_pointer[-2] = val;
stack_pointer += -1;
@@ -133,22 +133,22 @@
}
case _UNARY_NEGATIVE: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-1] = res;
break;
}
case _UNARY_NOT: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-1] = res;
break;
}
case _TO_BOOL: {
- _Py_UopsSymbol *value;
- _Py_UopsSymbol *res;
+ JitOptSymbol *value;
+ JitOptSymbol *res;
value = stack_pointer[-1];
if (!optimize_to_bool(this_instr, ctx, value, &res)) {
res = sym_new_type(ctx, &PyBool_Type);
@@ -158,8 +158,8 @@
}
case _TO_BOOL_BOOL: {
- _Py_UopsSymbol *value;
- _Py_UopsSymbol *res;
+ JitOptSymbol *value;
+ JitOptSymbol *res;
value = stack_pointer[-1];
if (!optimize_to_bool(this_instr, ctx, value, &res)) {
sym_set_type(value, &PyBool_Type);
@@ -170,8 +170,8 @@
}
case _TO_BOOL_INT: {
- _Py_UopsSymbol *value;
- _Py_UopsSymbol *res;
+ JitOptSymbol *value;
+ JitOptSymbol *res;
value = stack_pointer[-1];
if (!optimize_to_bool(this_instr, ctx, value, &res)) {
sym_set_type(value, &PyLong_Type);
@@ -182,8 +182,8 @@
}
case _TO_BOOL_LIST: {
- _Py_UopsSymbol *value;
- _Py_UopsSymbol *res;
+ JitOptSymbol *value;
+ JitOptSymbol *res;
value = stack_pointer[-1];
if (!optimize_to_bool(this_instr, ctx, value, &res)) {
sym_set_type(value, &PyList_Type);
@@ -194,8 +194,8 @@
}
case _TO_BOOL_NONE: {
- _Py_UopsSymbol *value;
- _Py_UopsSymbol *res;
+ JitOptSymbol *value;
+ JitOptSymbol *res;
value = stack_pointer[-1];
if (!optimize_to_bool(this_instr, ctx, value, &res)) {
sym_set_const(value, Py_None);
@@ -206,8 +206,8 @@
}
case _TO_BOOL_STR: {
- _Py_UopsSymbol *value;
- _Py_UopsSymbol *res;
+ JitOptSymbol *value;
+ JitOptSymbol *res;
value = stack_pointer[-1];
if (!optimize_to_bool(this_instr, ctx, value, &res)) {
res = sym_new_type(ctx, &PyBool_Type);
@@ -218,22 +218,22 @@
}
case _REPLACE_WITH_TRUE: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_const(ctx, Py_True);
stack_pointer[-1] = res;
break;
}
case _UNARY_INVERT: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-1] = res;
break;
}
case _GUARD_BOTH_INT: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (sym_matches_type(left, &PyLong_Type)) {
@@ -263,9 +263,9 @@
}
case _BINARY_OP_MULTIPLY_INT: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
- _Py_UopsSymbol *res;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
+ JitOptSymbol *res;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (sym_is_const(left) && sym_is_const(right) &&
@@ -296,9 +296,9 @@
}
case _BINARY_OP_ADD_INT: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
- _Py_UopsSymbol *res;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
+ JitOptSymbol *res;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (sym_is_const(left) && sym_is_const(right) &&
@@ -329,9 +329,9 @@
}
case _BINARY_OP_SUBTRACT_INT: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
- _Py_UopsSymbol *res;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
+ JitOptSymbol *res;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (sym_is_const(left) && sym_is_const(right) &&
@@ -362,8 +362,8 @@
}
case _GUARD_BOTH_FLOAT: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (sym_matches_type(left, &PyFloat_Type)) {
@@ -393,9 +393,9 @@
}
case _BINARY_OP_MULTIPLY_FLOAT: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
- _Py_UopsSymbol *res;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
+ JitOptSymbol *res;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (sym_is_const(left) && sym_is_const(right) &&
@@ -427,9 +427,9 @@
}
case _BINARY_OP_ADD_FLOAT: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
- _Py_UopsSymbol *res;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
+ JitOptSymbol *res;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (sym_is_const(left) && sym_is_const(right) &&
@@ -461,9 +461,9 @@
}
case _BINARY_OP_SUBTRACT_FLOAT: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
- _Py_UopsSymbol *res;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
+ JitOptSymbol *res;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (sym_is_const(left) && sym_is_const(right) &&
@@ -495,8 +495,8 @@
}
case _GUARD_BOTH_UNICODE: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (sym_matches_type(left, &PyUnicode_Type) &&
@@ -509,9 +509,9 @@
}
case _BINARY_OP_ADD_UNICODE: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
- _Py_UopsSymbol *res;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
+ JitOptSymbol *res;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (sym_is_const(left) && sym_is_const(right) &&
@@ -536,11 +536,11 @@
}
case _BINARY_OP_INPLACE_ADD_UNICODE: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
right = stack_pointer[-1];
left = stack_pointer[-2];
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
if (sym_is_const(left) && sym_is_const(right) &&
sym_matches_type(left, &PyUnicode_Type) && sym_matches_type(right, &PyUnicode_Type)) {
PyObject *temp = PyUnicode_Concat(sym_get_const(left), sym_get_const(right));
@@ -567,7 +567,7 @@
}
case _BINARY_OP_EXTEND: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2] = res;
stack_pointer += -1;
@@ -576,7 +576,7 @@
}
case _BINARY_SUBSCR: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2] = res;
stack_pointer += -1;
@@ -585,7 +585,7 @@
}
case _BINARY_SLICE: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-3] = res;
stack_pointer += -2;
@@ -600,7 +600,7 @@
}
case _BINARY_SUBSCR_LIST_INT: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2] = res;
stack_pointer += -1;
@@ -609,7 +609,7 @@
}
case _BINARY_SUBSCR_STR_INT: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2] = res;
stack_pointer += -1;
@@ -618,7 +618,7 @@
}
case _BINARY_SUBSCR_TUPLE_INT: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2] = res;
stack_pointer += -1;
@@ -627,7 +627,7 @@
}
case _BINARY_SUBSCR_DICT: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2] = res;
stack_pointer += -1;
@@ -636,7 +636,7 @@
}
case _BINARY_SUBSCR_CHECK_FUNC: {
- _Py_UopsSymbol *getitem;
+ JitOptSymbol *getitem;
getitem = sym_new_not_null(ctx);
stack_pointer[0] = getitem;
stack_pointer += 1;
@@ -645,9 +645,9 @@
}
case _BINARY_SUBSCR_INIT_CALL: {
- _Py_UopsSymbol *getitem;
- _Py_UopsSymbol *sub;
- _Py_UopsSymbol *container;
+ JitOptSymbol *getitem;
+ JitOptSymbol *sub;
+ JitOptSymbol *container;
_Py_UOpsAbstractFrame *new_frame;
getitem = stack_pointer[-1];
sub = stack_pointer[-2];
@@ -657,7 +657,7 @@
(void)getitem;
new_frame = NULL;
ctx->done = true;
- stack_pointer[-3] = (_Py_UopsSymbol *)new_frame;
+ stack_pointer[-3] = (JitOptSymbol *)new_frame;
stack_pointer += -2;
assert(WITHIN_STACK_BOUNDS());
break;
@@ -700,14 +700,14 @@
}
case _CALL_INTRINSIC_1: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-1] = res;
break;
}
case _CALL_INTRINSIC_2: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2] = res;
stack_pointer += -1;
@@ -716,8 +716,8 @@
}
case _RETURN_VALUE: {
- _Py_UopsSymbol *retval;
- _Py_UopsSymbol *res;
+ JitOptSymbol *retval;
+ JitOptSymbol *res;
retval = stack_pointer[-1];
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
@@ -744,14 +744,14 @@
}
case _GET_AITER: {
- _Py_UopsSymbol *iter;
+ JitOptSymbol *iter;
iter = sym_new_not_null(ctx);
stack_pointer[-1] = iter;
break;
}
case _GET_ANEXT: {
- _Py_UopsSymbol *awaitable;
+ JitOptSymbol *awaitable;
awaitable = sym_new_not_null(ctx);
stack_pointer[0] = awaitable;
stack_pointer += 1;
@@ -760,7 +760,7 @@
}
case _GET_AWAITABLE: {
- _Py_UopsSymbol *iter;
+ JitOptSymbol *iter;
iter = sym_new_not_null(ctx);
stack_pointer[-1] = iter;
break;
@@ -775,7 +775,7 @@
}
case _YIELD_VALUE: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_unknown(ctx);
stack_pointer[-1] = res;
break;
@@ -788,7 +788,7 @@
}
case _LOAD_COMMON_CONSTANT: {
- _Py_UopsSymbol *value;
+ JitOptSymbol *value;
value = sym_new_not_null(ctx);
stack_pointer[0] = value;
stack_pointer += 1;
@@ -797,7 +797,7 @@
}
case _LOAD_BUILD_CLASS: {
- _Py_UopsSymbol *bc;
+ JitOptSymbol *bc;
bc = sym_new_not_null(ctx);
stack_pointer[0] = bc;
stack_pointer += 1;
@@ -816,8 +816,8 @@
}
case _UNPACK_SEQUENCE: {
- _Py_UopsSymbol *seq;
- _Py_UopsSymbol **values;
+ JitOptSymbol *seq;
+ JitOptSymbol **values;
seq = stack_pointer[-1];
values = &stack_pointer[-1];
/* This has to be done manually */
@@ -831,10 +831,12 @@
}
case _UNPACK_SEQUENCE_TWO_TUPLE: {
- _Py_UopsSymbol *val1;
- _Py_UopsSymbol *val0;
- val1 = sym_new_not_null(ctx);
- val0 = sym_new_not_null(ctx);
+ JitOptSymbol *seq;
+ JitOptSymbol *val1;
+ JitOptSymbol *val0;
+ seq = stack_pointer[-1];
+ val0 = sym_tuple_getitem(ctx, seq, 0);
+ val1 = sym_tuple_getitem(ctx, seq, 1);
stack_pointer[-1] = val1;
stack_pointer[0] = val0;
stack_pointer += 1;
@@ -843,10 +845,12 @@
}
case _UNPACK_SEQUENCE_TUPLE: {
- _Py_UopsSymbol **values;
+ JitOptSymbol *seq;
+ JitOptSymbol **values;
+ seq = stack_pointer[-1];
values = &stack_pointer[-1];
- for (int _i = oparg; --_i >= 0;) {
- values[_i] = sym_new_not_null(ctx);
+ for (int i = 0; i < oparg; i++) {
+ values[i] = sym_tuple_getitem(ctx, seq, i);
}
stack_pointer += -1 + oparg;
assert(WITHIN_STACK_BOUNDS());
@@ -854,7 +858,7 @@
}
case _UNPACK_SEQUENCE_LIST: {
- _Py_UopsSymbol **values;
+ JitOptSymbol **values;
values = &stack_pointer[-1];
for (int _i = oparg; --_i >= 0;) {
values[_i] = sym_new_not_null(ctx);
@@ -865,8 +869,8 @@
}
case _UNPACK_EX: {
- _Py_UopsSymbol *seq;
- _Py_UopsSymbol **values;
+ JitOptSymbol *seq;
+ JitOptSymbol **values;
seq = stack_pointer[-1];
values = &stack_pointer[-1];
/* This has to be done manually */
@@ -903,7 +907,7 @@
}
case _LOAD_LOCALS: {
- _Py_UopsSymbol *locals;
+ JitOptSymbol *locals;
locals = sym_new_not_null(ctx);
stack_pointer[0] = locals;
stack_pointer += 1;
@@ -914,7 +918,7 @@
/* _LOAD_FROM_DICT_OR_GLOBALS is not a viable micro-op for tier 2 */
case _LOAD_NAME: {
- _Py_UopsSymbol *v;
+ JitOptSymbol *v;
v = sym_new_not_null(ctx);
stack_pointer[0] = v;
stack_pointer += 1;
@@ -923,8 +927,8 @@
}
case _LOAD_GLOBAL: {
- _Py_UopsSymbol **res;
- _Py_UopsSymbol *null = NULL;
+ JitOptSymbol **res;
+ JitOptSymbol *null = NULL;
res = &stack_pointer[0];
res[0] = sym_new_not_null(ctx);
null = sym_new_null(ctx);
@@ -939,7 +943,7 @@
}
case _GUARD_GLOBALS_VERSION_PUSH_KEYS: {
- _Py_UopsSymbol *globals_keys;
+ JitOptSymbol *globals_keys;
uint16_t version = (uint16_t)this_instr->operand0;
globals_keys = sym_new_unknown(ctx);
(void)version;
@@ -950,7 +954,7 @@
}
case _GUARD_BUILTINS_VERSION_PUSH_KEYS: {
- _Py_UopsSymbol *builtins_keys;
+ JitOptSymbol *builtins_keys;
uint16_t version = (uint16_t)this_instr->operand0;
builtins_keys = sym_new_unknown(ctx);
(void)version;
@@ -961,8 +965,8 @@
}
case _LOAD_GLOBAL_MODULE_FROM_KEYS: {
- _Py_UopsSymbol *res;
- _Py_UopsSymbol *null = NULL;
+ JitOptSymbol *res;
+ JitOptSymbol *null = NULL;
res = sym_new_not_null(ctx);
null = sym_new_null(ctx);
stack_pointer[-1] = res;
@@ -973,8 +977,8 @@
}
case _LOAD_GLOBAL_BUILTINS_FROM_KEYS: {
- _Py_UopsSymbol *res;
- _Py_UopsSymbol *null = NULL;
+ JitOptSymbol *res;
+ JitOptSymbol *null = NULL;
res = sym_new_not_null(ctx);
null = sym_new_null(ctx);
stack_pointer[-1] = res;
@@ -997,14 +1001,14 @@
}
case _LOAD_FROM_DICT_OR_DEREF: {
- _Py_UopsSymbol *value;
+ JitOptSymbol *value;
value = sym_new_not_null(ctx);
stack_pointer[-1] = value;
break;
}
case _LOAD_DEREF: {
- _Py_UopsSymbol *value;
+ JitOptSymbol *value;
value = sym_new_not_null(ctx);
stack_pointer[0] = value;
stack_pointer += 1;
@@ -1023,7 +1027,7 @@
}
case _BUILD_STRING: {
- _Py_UopsSymbol *str;
+ JitOptSymbol *str;
str = sym_new_not_null(ctx);
stack_pointer[-oparg] = str;
stack_pointer += 1 - oparg;
@@ -1032,8 +1036,10 @@
}
case _BUILD_TUPLE: {
- _Py_UopsSymbol *tup;
- tup = sym_new_not_null(ctx);
+ JitOptSymbol **values;
+ JitOptSymbol *tup;
+ values = &stack_pointer[-oparg];
+ tup = sym_new_tuple(ctx, oparg, values);
stack_pointer[-oparg] = tup;
stack_pointer += 1 - oparg;
assert(WITHIN_STACK_BOUNDS());
@@ -1041,7 +1047,7 @@
}
case _BUILD_LIST: {
- _Py_UopsSymbol *list;
+ JitOptSymbol *list;
list = sym_new_not_null(ctx);
stack_pointer[-oparg] = list;
stack_pointer += 1 - oparg;
@@ -1062,7 +1068,7 @@
}
case _BUILD_SET: {
- _Py_UopsSymbol *set;
+ JitOptSymbol *set;
set = sym_new_not_null(ctx);
stack_pointer[-oparg] = set;
stack_pointer += 1 - oparg;
@@ -1071,7 +1077,7 @@
}
case _BUILD_MAP: {
- _Py_UopsSymbol *map;
+ JitOptSymbol *map;
map = sym_new_not_null(ctx);
stack_pointer[-oparg*2] = map;
stack_pointer += 1 - oparg*2;
@@ -1104,7 +1110,7 @@
/* _INSTRUMENTED_LOAD_SUPER_ATTR is not a viable micro-op for tier 2 */
case _LOAD_SUPER_ATTR_ATTR: {
- _Py_UopsSymbol *attr_st;
+ JitOptSymbol *attr_st;
attr_st = sym_new_not_null(ctx);
stack_pointer[-3] = attr_st;
stack_pointer += -2;
@@ -1113,8 +1119,8 @@
}
case _LOAD_SUPER_ATTR_METHOD: {
- _Py_UopsSymbol *attr;
- _Py_UopsSymbol *self_or_null;
+ JitOptSymbol *attr;
+ JitOptSymbol *self_or_null;
attr = sym_new_not_null(ctx);
self_or_null = sym_new_not_null(ctx);
stack_pointer[-3] = attr;
@@ -1125,9 +1131,9 @@
}
case _LOAD_ATTR: {
- _Py_UopsSymbol *owner;
- _Py_UopsSymbol *attr;
- _Py_UopsSymbol *self_or_null = NULL;
+ JitOptSymbol *owner;
+ JitOptSymbol *attr;
+ JitOptSymbol *self_or_null = NULL;
owner = stack_pointer[-1];
(void)owner;
attr = sym_new_not_null(ctx);
@@ -1140,7 +1146,7 @@
}
case _GUARD_TYPE_VERSION: {
- _Py_UopsSymbol *owner;
+ JitOptSymbol *owner;
owner = stack_pointer[-1];
uint32_t type_version = (uint32_t)this_instr->operand0;
assert(type_version);
@@ -1174,9 +1180,9 @@
}
case _LOAD_ATTR_INSTANCE_VALUE: {
- _Py_UopsSymbol *owner;
- _Py_UopsSymbol *attr;
- _Py_UopsSymbol *null = NULL;
+ 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);
@@ -1191,8 +1197,8 @@
}
case _CHECK_ATTR_MODULE_PUSH_KEYS: {
- _Py_UopsSymbol *owner;
- _Py_UopsSymbol *mod_keys;
+ JitOptSymbol *owner;
+ JitOptSymbol *mod_keys;
owner = stack_pointer[-1];
uint32_t dict_version = (uint32_t)this_instr->operand0;
(void)dict_version;
@@ -1222,9 +1228,9 @@
}
case _LOAD_ATTR_MODULE_FROM_KEYS: {
- _Py_UopsSymbol *owner;
- _Py_UopsSymbol *attr;
- _Py_UopsSymbol *null = NULL;
+ JitOptSymbol *owner;
+ JitOptSymbol *attr;
+ JitOptSymbol *null = NULL;
owner = stack_pointer[-2];
uint16_t index = (uint16_t)this_instr->operand0;
(void)index;
@@ -1263,8 +1269,8 @@
}
case _CHECK_ATTR_WITH_HINT: {
- _Py_UopsSymbol *owner;
- _Py_UopsSymbol *dict;
+ JitOptSymbol *owner;
+ JitOptSymbol *dict;
owner = stack_pointer[-1];
dict = sym_new_not_null(ctx);
(void)owner;
@@ -1275,10 +1281,10 @@
}
case _LOAD_ATTR_WITH_HINT: {
- _Py_UopsSymbol *dict;
- _Py_UopsSymbol *owner;
- _Py_UopsSymbol *attr;
- _Py_UopsSymbol *null = NULL;
+ 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;
@@ -1295,9 +1301,9 @@
}
case _LOAD_ATTR_SLOT: {
- _Py_UopsSymbol *owner;
- _Py_UopsSymbol *attr;
- _Py_UopsSymbol *null = NULL;
+ 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);
@@ -1316,9 +1322,9 @@
}
case _LOAD_ATTR_CLASS: {
- _Py_UopsSymbol *owner;
- _Py_UopsSymbol *attr;
- _Py_UopsSymbol *null = NULL;
+ JitOptSymbol *owner;
+ JitOptSymbol *attr;
+ JitOptSymbol *null = NULL;
owner = stack_pointer[-1];
PyObject *descr = (PyObject *)this_instr->operand0;
attr = sym_new_not_null(ctx);
@@ -1333,7 +1339,7 @@
}
case _LOAD_ATTR_PROPERTY_FRAME: {
- _Py_UopsSymbol *owner;
+ JitOptSymbol *owner;
_Py_UOpsAbstractFrame *new_frame;
owner = stack_pointer[-1];
PyObject *fget = (PyObject *)this_instr->operand0;
@@ -1341,7 +1347,7 @@
(void)owner;
new_frame = NULL;
ctx->done = true;
- stack_pointer[-1] = (_Py_UopsSymbol *)new_frame;
+ stack_pointer[-1] = (JitOptSymbol *)new_frame;
break;
}
@@ -1370,9 +1376,9 @@
}
case _COMPARE_OP: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
- _Py_UopsSymbol *res;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
+ JitOptSymbol *res;
right = stack_pointer[-1];
left = stack_pointer[-2];
(void)left;
@@ -1394,9 +1400,9 @@
}
case _COMPARE_OP_FLOAT: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
- _Py_UopsSymbol *res;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
+ JitOptSymbol *res;
right = stack_pointer[-1];
left = stack_pointer[-2];
(void)left;
@@ -1409,9 +1415,9 @@
}
case _COMPARE_OP_INT: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
- _Py_UopsSymbol *res;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
+ JitOptSymbol *res;
right = stack_pointer[-1];
left = stack_pointer[-2];
(void)left;
@@ -1424,9 +1430,9 @@
}
case _COMPARE_OP_STR: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
- _Py_UopsSymbol *res;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
+ JitOptSymbol *res;
right = stack_pointer[-1];
left = stack_pointer[-2];
(void)left;
@@ -1439,9 +1445,9 @@
}
case _IS_OP: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
- _Py_UopsSymbol *res;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
+ JitOptSymbol *res;
right = stack_pointer[-1];
left = stack_pointer[-2];
(void)left;
@@ -1454,9 +1460,9 @@
}
case _CONTAINS_OP: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
- _Py_UopsSymbol *res;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
+ JitOptSymbol *res;
right = stack_pointer[-1];
left = stack_pointer[-2];
(void)left;
@@ -1469,7 +1475,7 @@
}
case _CONTAINS_OP_SET: {
- _Py_UopsSymbol *b;
+ JitOptSymbol *b;
b = sym_new_not_null(ctx);
stack_pointer[-2] = b;
stack_pointer += -1;
@@ -1478,7 +1484,7 @@
}
case _CONTAINS_OP_DICT: {
- _Py_UopsSymbol *b;
+ JitOptSymbol *b;
b = sym_new_not_null(ctx);
stack_pointer[-2] = b;
stack_pointer += -1;
@@ -1487,8 +1493,8 @@
}
case _CHECK_EG_MATCH: {
- _Py_UopsSymbol *rest;
- _Py_UopsSymbol *match;
+ JitOptSymbol *rest;
+ JitOptSymbol *match;
rest = sym_new_not_null(ctx);
match = sym_new_not_null(ctx);
stack_pointer[-2] = rest;
@@ -1497,14 +1503,14 @@
}
case _CHECK_EXC_MATCH: {
- _Py_UopsSymbol *b;
+ JitOptSymbol *b;
b = sym_new_not_null(ctx);
stack_pointer[-1] = b;
break;
}
case _IMPORT_NAME: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2] = res;
stack_pointer += -1;
@@ -1513,7 +1519,7 @@
}
case _IMPORT_FROM: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[0] = res;
stack_pointer += 1;
@@ -1526,14 +1532,14 @@
/* _POP_JUMP_IF_TRUE is not a viable micro-op for tier 2 */
case _IS_NONE: {
- _Py_UopsSymbol *b;
+ JitOptSymbol *b;
b = sym_new_not_null(ctx);
stack_pointer[-1] = b;
break;
}
case _GET_LEN: {
- _Py_UopsSymbol *len;
+ JitOptSymbol *len;
len = sym_new_not_null(ctx);
stack_pointer[0] = len;
stack_pointer += 1;
@@ -1542,7 +1548,7 @@
}
case _MATCH_CLASS: {
- _Py_UopsSymbol *attrs;
+ JitOptSymbol *attrs;
attrs = sym_new_not_null(ctx);
stack_pointer[-3] = attrs;
stack_pointer += -2;
@@ -1551,7 +1557,7 @@
}
case _MATCH_MAPPING: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[0] = res;
stack_pointer += 1;
@@ -1560,7 +1566,7 @@
}
case _MATCH_SEQUENCE: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[0] = res;
stack_pointer += 1;
@@ -1569,7 +1575,7 @@
}
case _MATCH_KEYS: {
- _Py_UopsSymbol *values_or_none;
+ JitOptSymbol *values_or_none;
values_or_none = sym_new_not_null(ctx);
stack_pointer[0] = values_or_none;
stack_pointer += 1;
@@ -1578,14 +1584,14 @@
}
case _GET_ITER: {
- _Py_UopsSymbol *iter;
+ JitOptSymbol *iter;
iter = sym_new_not_null(ctx);
stack_pointer[-1] = iter;
break;
}
case _GET_YIELD_FROM_ITER: {
- _Py_UopsSymbol *iter;
+ JitOptSymbol *iter;
iter = sym_new_not_null(ctx);
stack_pointer[-1] = iter;
break;
@@ -1594,7 +1600,7 @@
/* _FOR_ITER is not a viable micro-op for tier 2 */
case _FOR_ITER_TIER_TWO: {
- _Py_UopsSymbol *next;
+ JitOptSymbol *next;
next = sym_new_not_null(ctx);
stack_pointer[0] = next;
stack_pointer += 1;
@@ -1615,7 +1621,7 @@
}
case _ITER_NEXT_LIST: {
- _Py_UopsSymbol *next;
+ JitOptSymbol *next;
next = sym_new_not_null(ctx);
stack_pointer[0] = next;
stack_pointer += 1;
@@ -1634,7 +1640,7 @@
}
case _ITER_NEXT_TUPLE: {
- _Py_UopsSymbol *next;
+ JitOptSymbol *next;
next = sym_new_not_null(ctx);
stack_pointer[0] = next;
stack_pointer += 1;
@@ -1653,8 +1659,8 @@
}
case _ITER_NEXT_RANGE: {
- _Py_UopsSymbol *iter;
- _Py_UopsSymbol *next;
+ JitOptSymbol *iter;
+ JitOptSymbol *next;
iter = stack_pointer[-1];
next = sym_new_type(ctx, &PyLong_Type);
(void)iter;
@@ -1671,9 +1677,9 @@
}
case _LOAD_SPECIAL: {
- _Py_UopsSymbol *owner;
- _Py_UopsSymbol *attr;
- _Py_UopsSymbol *self_or_null;
+ JitOptSymbol *owner;
+ JitOptSymbol *attr;
+ JitOptSymbol *self_or_null;
owner = stack_pointer[-1];
(void)owner;
attr = sym_new_not_null(ctx);
@@ -1686,7 +1692,7 @@
}
case _WITH_EXCEPT_START: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[0] = res;
stack_pointer += 1;
@@ -1695,8 +1701,8 @@
}
case _PUSH_EXC_INFO: {
- _Py_UopsSymbol *prev_exc;
- _Py_UopsSymbol *new_exc;
+ JitOptSymbol *prev_exc;
+ JitOptSymbol *new_exc;
prev_exc = sym_new_not_null(ctx);
new_exc = sym_new_not_null(ctx);
stack_pointer[-1] = prev_exc;
@@ -1715,9 +1721,9 @@
}
case _LOAD_ATTR_METHOD_WITH_VALUES: {
- _Py_UopsSymbol *owner;
- _Py_UopsSymbol *attr;
- _Py_UopsSymbol *self = NULL;
+ JitOptSymbol *owner;
+ JitOptSymbol *attr;
+ JitOptSymbol *self = NULL;
owner = stack_pointer[-1];
PyObject *descr = (PyObject *)this_instr->operand0;
(void)descr;
@@ -1731,9 +1737,9 @@
}
case _LOAD_ATTR_METHOD_NO_DICT: {
- _Py_UopsSymbol *owner;
- _Py_UopsSymbol *attr;
- _Py_UopsSymbol *self = NULL;
+ JitOptSymbol *owner;
+ JitOptSymbol *attr;
+ JitOptSymbol *self = NULL;
owner = stack_pointer[-1];
PyObject *descr = (PyObject *)this_instr->operand0;
(void)descr;
@@ -1747,14 +1753,14 @@
}
case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: {
- _Py_UopsSymbol *attr;
+ JitOptSymbol *attr;
attr = sym_new_not_null(ctx);
stack_pointer[-1] = attr;
break;
}
case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT: {
- _Py_UopsSymbol *attr;
+ JitOptSymbol *attr;
attr = sym_new_not_null(ctx);
stack_pointer[-1] = attr;
break;
@@ -1765,9 +1771,9 @@
}
case _LOAD_ATTR_METHOD_LAZY_DICT: {
- _Py_UopsSymbol *owner;
- _Py_UopsSymbol *attr;
- _Py_UopsSymbol *self = NULL;
+ JitOptSymbol *owner;
+ JitOptSymbol *attr;
+ JitOptSymbol *self = NULL;
owner = stack_pointer[-1];
PyObject *descr = (PyObject *)this_instr->operand0;
(void)descr;
@@ -1781,11 +1787,11 @@
}
case _MAYBE_EXPAND_METHOD: {
- _Py_UopsSymbol **args;
- _Py_UopsSymbol *self_or_null;
- _Py_UopsSymbol *callable;
- _Py_UopsSymbol *func;
- _Py_UopsSymbol *maybe_self;
+ JitOptSymbol **args;
+ JitOptSymbol *self_or_null;
+ JitOptSymbol *callable;
+ JitOptSymbol *func;
+ JitOptSymbol *maybe_self;
args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
@@ -1805,8 +1811,8 @@
/* _MONITOR_CALL is not a viable micro-op for tier 2 */
case _PY_FRAME_GENERAL: {
- _Py_UopsSymbol *self_or_null;
- _Py_UopsSymbol *callable;
+ JitOptSymbol *self_or_null;
+ JitOptSymbol *callable;
_Py_UOpsAbstractFrame *new_frame;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
@@ -1822,15 +1828,15 @@
break;
}
new_frame = frame_new(ctx, co, 0, NULL, 0);
- stack_pointer[0] = (_Py_UopsSymbol *)new_frame;
+ stack_pointer[0] = (JitOptSymbol *)new_frame;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
break;
}
case _CHECK_FUNCTION_VERSION: {
- _Py_UopsSymbol *self_or_null;
- _Py_UopsSymbol *callable;
+ JitOptSymbol *self_or_null;
+ JitOptSymbol *callable;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
uint32_t func_version = (uint32_t)this_instr->operand0;
@@ -1853,8 +1859,8 @@
}
case _EXPAND_METHOD: {
- _Py_UopsSymbol **method;
- _Py_UopsSymbol **self;
+ JitOptSymbol **method;
+ JitOptSymbol **self;
method = &stack_pointer[-2 - oparg];
self = &stack_pointer[-1 - oparg];
method[0] = sym_new_not_null(ctx);
@@ -1867,7 +1873,7 @@
}
case _CALL_NON_PY_GENERAL: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
@@ -1876,8 +1882,8 @@
}
case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS: {
- _Py_UopsSymbol *null;
- _Py_UopsSymbol *callable;
+ JitOptSymbol *null;
+ JitOptSymbol *callable;
null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
sym_set_null(null);
@@ -1886,9 +1892,9 @@
}
case _INIT_CALL_BOUND_METHOD_EXACT_ARGS: {
- _Py_UopsSymbol *callable;
- _Py_UopsSymbol *func;
- _Py_UopsSymbol *self;
+ JitOptSymbol *callable;
+ JitOptSymbol *func;
+ JitOptSymbol *self;
callable = stack_pointer[-2 - oparg];
(void)callable;
func = sym_new_not_null(ctx);
@@ -1908,8 +1914,8 @@
}
case _CHECK_FUNCTION_EXACT_ARGS: {
- _Py_UopsSymbol *self_or_null;
- _Py_UopsSymbol *callable;
+ JitOptSymbol *self_or_null;
+ JitOptSymbol *callable;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
assert(sym_matches_type(callable, &PyFunction_Type));
@@ -1933,9 +1939,9 @@
}
case _INIT_CALL_PY_EXACT_ARGS: {
- _Py_UopsSymbol **args;
- _Py_UopsSymbol *self_or_null;
- _Py_UopsSymbol *callable;
+ JitOptSymbol **args;
+ JitOptSymbol *self_or_null;
+ JitOptSymbol *callable;
_Py_UOpsAbstractFrame *new_frame;
args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg];
@@ -1963,7 +1969,7 @@
} else {
new_frame = frame_new(ctx, co, 0, NULL, 0);
}
- stack_pointer[0] = (_Py_UopsSymbol *)new_frame;
+ stack_pointer[0] = (JitOptSymbol *)new_frame;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
break;
@@ -2008,7 +2014,7 @@
}
case _CALL_TYPE_1: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-3] = res;
stack_pointer += -2;
@@ -2017,7 +2023,7 @@
}
case _CALL_STR_1: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-3] = res;
stack_pointer += -2;
@@ -2026,7 +2032,7 @@
}
case _CALL_TUPLE_1: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-3] = res;
stack_pointer += -2;
@@ -2035,11 +2041,11 @@
}
case _CHECK_AND_ALLOCATE_OBJECT: {
- _Py_UopsSymbol **args;
- _Py_UopsSymbol *null;
- _Py_UopsSymbol *callable;
- _Py_UopsSymbol *self;
- _Py_UopsSymbol *init;
+ JitOptSymbol **args;
+ JitOptSymbol *null;
+ JitOptSymbol *callable;
+ JitOptSymbol *self;
+ JitOptSymbol *init;
args = &stack_pointer[-oparg];
null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
@@ -2057,9 +2063,9 @@
}
case _CREATE_INIT_FRAME: {
- _Py_UopsSymbol **args;
- _Py_UopsSymbol *init;
- _Py_UopsSymbol *self;
+ JitOptSymbol **args;
+ JitOptSymbol *init;
+ JitOptSymbol *self;
_Py_UOpsAbstractFrame *init_frame;
args = &stack_pointer[-oparg];
init = stack_pointer[-1 - oparg];
@@ -2069,7 +2075,7 @@
(void)args;
init_frame = NULL;
ctx->done = true;
- stack_pointer[-2 - oparg] = (_Py_UopsSymbol *)init_frame;
+ stack_pointer[-2 - oparg] = (JitOptSymbol *)init_frame;
stack_pointer += -1 - oparg;
assert(WITHIN_STACK_BOUNDS());
break;
@@ -2082,7 +2088,7 @@
}
case _CALL_BUILTIN_CLASS: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
@@ -2091,7 +2097,7 @@
}
case _CALL_BUILTIN_O: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
@@ -2100,7 +2106,7 @@
}
case _CALL_BUILTIN_FAST: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
@@ -2109,7 +2115,7 @@
}
case _CALL_BUILTIN_FAST_WITH_KEYWORDS: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
@@ -2118,7 +2124,7 @@
}
case _CALL_LEN: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
@@ -2127,7 +2133,7 @@
}
case _CALL_ISINSTANCE: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
@@ -2142,7 +2148,7 @@
}
case _CALL_METHOD_DESCRIPTOR_O: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
@@ -2151,7 +2157,7 @@
}
case _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
@@ -2160,7 +2166,7 @@
}
case _CALL_METHOD_DESCRIPTOR_NOARGS: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
@@ -2169,7 +2175,7 @@
}
case _CALL_METHOD_DESCRIPTOR_FAST: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
@@ -2180,10 +2186,10 @@
/* _INSTRUMENTED_CALL_KW is not a viable micro-op for tier 2 */
case _MAYBE_EXPAND_METHOD_KW: {
- _Py_UopsSymbol **func;
- _Py_UopsSymbol **maybe_self;
- _Py_UopsSymbol **args;
- _Py_UopsSymbol *kwnames_out;
+ JitOptSymbol **func;
+ JitOptSymbol **maybe_self;
+ JitOptSymbol **args;
+ JitOptSymbol *kwnames_out;
func = &stack_pointer[-3 - oparg];
maybe_self = &stack_pointer[-2 - oparg];
args = &stack_pointer[-1 - oparg];
@@ -2200,10 +2206,10 @@
/* _DO_CALL_KW is not a viable micro-op for tier 2 */
case _PY_FRAME_KW: {
- _Py_UopsSymbol *kwnames;
- _Py_UopsSymbol **args;
- _Py_UopsSymbol *self_or_null;
- _Py_UopsSymbol *callable;
+ JitOptSymbol *kwnames;
+ JitOptSymbol **args;
+ JitOptSymbol *self_or_null;
+ JitOptSymbol *callable;
_Py_UOpsAbstractFrame *new_frame;
kwnames = stack_pointer[-1];
args = &stack_pointer[-1 - oparg];
@@ -2215,7 +2221,7 @@
(void)kwnames;
new_frame = NULL;
ctx->done = true;
- stack_pointer[-3 - oparg] = (_Py_UopsSymbol *)new_frame;
+ stack_pointer[-3 - oparg] = (JitOptSymbol *)new_frame;
stack_pointer += -2 - oparg;
assert(WITHIN_STACK_BOUNDS());
break;
@@ -2230,8 +2236,8 @@
}
case _EXPAND_METHOD_KW: {
- _Py_UopsSymbol **method;
- _Py_UopsSymbol **self;
+ JitOptSymbol **method;
+ JitOptSymbol **self;
method = &stack_pointer[-3 - oparg];
self = &stack_pointer[-2 - oparg];
method[0] = sym_new_not_null(ctx);
@@ -2244,7 +2250,7 @@
}
case _CALL_KW_NON_PY: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-3 - oparg] = res;
stack_pointer += -2 - oparg;
@@ -2255,8 +2261,8 @@
/* _INSTRUMENTED_CALL_FUNCTION_EX is not a viable micro-op for tier 2 */
case _MAKE_CALLARGS_A_TUPLE: {
- _Py_UopsSymbol *tuple;
- _Py_UopsSymbol *kwargs_out = NULL;
+ JitOptSymbol *tuple;
+ JitOptSymbol *kwargs_out = NULL;
tuple = sym_new_not_null(ctx);
kwargs_out = sym_new_not_null(ctx);
stack_pointer[-1 - (oparg & 1)] = tuple;
@@ -2267,14 +2273,14 @@
/* _DO_CALL_FUNCTION_EX is not a viable micro-op for tier 2 */
case _MAKE_FUNCTION: {
- _Py_UopsSymbol *func;
+ JitOptSymbol *func;
func = sym_new_not_null(ctx);
stack_pointer[-1] = func;
break;
}
case _SET_FUNCTION_ATTRIBUTE: {
- _Py_UopsSymbol *func_out;
+ JitOptSymbol *func_out;
func_out = sym_new_not_null(ctx);
stack_pointer[-2] = func_out;
stack_pointer += -1;
@@ -2283,7 +2289,7 @@
}
case _RETURN_GENERATOR: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
ctx->frame->stack_pointer = stack_pointer;
frame_pop(ctx);
stack_pointer = ctx->frame->stack_pointer;
@@ -2307,7 +2313,7 @@
}
case _BUILD_SLICE: {
- _Py_UopsSymbol *slice;
+ JitOptSymbol *slice;
slice = sym_new_not_null(ctx);
stack_pointer[-2 - ((oparg == 3) ? 1 : 0)] = slice;
stack_pointer += -1 - ((oparg == 3) ? 1 : 0);
@@ -2316,21 +2322,21 @@
}
case _CONVERT_VALUE: {
- _Py_UopsSymbol *result;
+ JitOptSymbol *result;
result = sym_new_not_null(ctx);
stack_pointer[-1] = result;
break;
}
case _FORMAT_SIMPLE: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-1] = res;
break;
}
case _FORMAT_WITH_SPEC: {
- _Py_UopsSymbol *res;
+ JitOptSymbol *res;
res = sym_new_not_null(ctx);
stack_pointer[-2] = res;
stack_pointer += -1;
@@ -2339,8 +2345,8 @@
}
case _COPY: {
- _Py_UopsSymbol *bottom;
- _Py_UopsSymbol *top;
+ JitOptSymbol *bottom;
+ JitOptSymbol *top;
bottom = stack_pointer[-1 - (oparg-1)];
assert(oparg > 0);
top = bottom;
@@ -2351,9 +2357,9 @@
}
case _BINARY_OP: {
- _Py_UopsSymbol *right;
- _Py_UopsSymbol *left;
- _Py_UopsSymbol *res;
+ JitOptSymbol *right;
+ JitOptSymbol *left;
+ JitOptSymbol *res;
right = stack_pointer[-1];
left = stack_pointer[-2];
bool lhs_int = sym_matches_type(left, &PyLong_Type);
@@ -2426,10 +2432,10 @@
}
case _SWAP: {
- _Py_UopsSymbol *top_in;
- _Py_UopsSymbol *bottom_in;
- _Py_UopsSymbol *top_out;
- _Py_UopsSymbol *bottom_out;
+ JitOptSymbol *top_in;
+ JitOptSymbol *bottom_in;
+ JitOptSymbol *top_out;
+ JitOptSymbol *bottom_out;
top_in = stack_pointer[-1];
bottom_in = stack_pointer[-2 - (oparg-2)];
bottom_out = bottom_in;
@@ -2458,7 +2464,7 @@
/* _INSTRUMENTED_POP_JUMP_IF_NOT_NONE is not a viable micro-op for tier 2 */
case _GUARD_IS_TRUE_POP: {
- _Py_UopsSymbol *flag;
+ JitOptSymbol *flag;
flag = stack_pointer[-1];
if (sym_is_const(flag)) {
PyObject *value = sym_get_const(flag);
@@ -2475,7 +2481,7 @@
}
case _GUARD_IS_FALSE_POP: {
- _Py_UopsSymbol *flag;
+ JitOptSymbol *flag;
flag = stack_pointer[-1];
if (sym_is_const(flag)) {
PyObject *value = sym_get_const(flag);
@@ -2492,7 +2498,7 @@
}
case _GUARD_IS_NONE_POP: {
- _Py_UopsSymbol *flag;
+ JitOptSymbol *flag;
flag = stack_pointer[-1];
if (sym_is_const(flag)) {
PyObject *value = sym_get_const(flag);
@@ -2517,7 +2523,7 @@
}
case _GUARD_IS_NOT_NONE_POP: {
- _Py_UopsSymbol *flag;
+ JitOptSymbol *flag;
flag = stack_pointer[-1];
if (sym_is_const(flag)) {
PyObject *value = sym_get_const(flag);
@@ -2575,7 +2581,7 @@
}
case _LOAD_CONST_INLINE: {
- _Py_UopsSymbol *value;
+ JitOptSymbol *value;
PyObject *ptr = (PyObject *)this_instr->operand0;
value = sym_new_const(ctx, ptr);
stack_pointer[0] = value;
@@ -2585,7 +2591,7 @@
}
case _LOAD_CONST_INLINE_BORROW: {
- _Py_UopsSymbol *value;
+ JitOptSymbol *value;
PyObject *ptr = (PyObject *)this_instr->operand0;
value = sym_new_const(ctx, ptr);
stack_pointer[0] = value;
@@ -2595,15 +2601,15 @@
}
case _POP_TOP_LOAD_CONST_INLINE_BORROW: {
- _Py_UopsSymbol *value;
+ JitOptSymbol *value;
value = sym_new_not_null(ctx);
stack_pointer[-1] = value;
break;
}
case _LOAD_CONST_INLINE_WITH_NULL: {
- _Py_UopsSymbol *value;
- _Py_UopsSymbol *null;
+ JitOptSymbol *value;
+ JitOptSymbol *null;
PyObject *ptr = (PyObject *)this_instr->operand0;
value = sym_new_const(ctx, ptr);
null = sym_new_null(ctx);
@@ -2615,8 +2621,8 @@
}
case _LOAD_CONST_INLINE_BORROW_WITH_NULL: {
- _Py_UopsSymbol *value;
- _Py_UopsSymbol *null;
+ JitOptSymbol *value;
+ JitOptSymbol *null;
PyObject *ptr = (PyObject *)this_instr->operand0;
value = sym_new_const(ctx, ptr);
null = sym_new_null(ctx);
@@ -2632,8 +2638,8 @@
}
case _LOAD_GLOBAL_MODULE: {
- _Py_UopsSymbol *res;
- _Py_UopsSymbol *null = NULL;
+ JitOptSymbol *res;
+ JitOptSymbol *null = NULL;
res = sym_new_not_null(ctx);
null = sym_new_null(ctx);
stack_pointer[0] = res;
@@ -2644,8 +2650,8 @@
}
case _LOAD_GLOBAL_BUILTINS: {
- _Py_UopsSymbol *res;
- _Py_UopsSymbol *null = NULL;
+ JitOptSymbol *res;
+ JitOptSymbol *null = NULL;
res = sym_new_not_null(ctx);
null = sym_new_null(ctx);
stack_pointer[0] = res;
@@ -2656,8 +2662,8 @@
}
case _LOAD_ATTR_MODULE: {
- _Py_UopsSymbol *attr;
- _Py_UopsSymbol *null = NULL;
+ JitOptSymbol *attr;
+ JitOptSymbol *null = NULL;
attr = sym_new_not_null(ctx);
null = sym_new_null(ctx);
stack_pointer[-1] = attr;
diff --git a/Python/optimizer_symbols.c b/Python/optimizer_symbols.c
index 40cbf95e3d6d39..dcde8e7ce81577 100644
--- a/Python/optimizer_symbols.c
+++ b/Python/optimizer_symbols.c
@@ -28,11 +28,6 @@
- Bottom: IS_NULL and NOT_NULL flags set, type and const_val NULL.
*/
-// Flags for below.
-#define IS_NULL 1 << 0
-#define NOT_NULL 1 << 1
-#define NO_SPACE 1 << 2
-
#ifdef Py_DEBUG
static inline int get_lltrace(void) {
char *uop_debug = Py_GETENV("PYTHON_OPT_DEBUG");
@@ -48,187 +43,254 @@ static inline int get_lltrace(void) {
#define DPRINTF(level, ...)
#endif
-static _Py_UopsSymbol NO_SPACE_SYMBOL = {
- .flags = IS_NULL | NOT_NULL | NO_SPACE,
- .typ = NULL,
- .const_val = NULL,
- .type_version = 0,
+
+static JitOptSymbol NO_SPACE_SYMBOL = {
+ .tag = JIT_SYM_BOTTOM_TAG
};
-_Py_UopsSymbol *
-out_of_space(_Py_UOpsContext *ctx)
+JitOptSymbol *
+out_of_space(JitOptContext *ctx)
{
ctx->done = true;
ctx->out_of_space = true;
return &NO_SPACE_SYMBOL;
}
-static _Py_UopsSymbol *
-sym_new(_Py_UOpsContext *ctx)
+static JitOptSymbol *
+sym_new(JitOptContext *ctx)
{
- _Py_UopsSymbol *self = &ctx->t_arena.arena[ctx->t_arena.ty_curr_number];
+ JitOptSymbol *self = &ctx->t_arena.arena[ctx->t_arena.ty_curr_number];
if (ctx->t_arena.ty_curr_number >= ctx->t_arena.ty_max_number) {
OPT_STAT_INC(optimizer_failure_reason_no_memory);
DPRINTF(1, "out of space for symbolic expression type\n");
return NULL;
}
ctx->t_arena.ty_curr_number++;
- self->flags = 0;
- self->typ = NULL;
- self->const_val = NULL;
- self->type_version = 0;
-
+ self->tag = JIT_SYM_UNKNOWN_TAG;
return self;
}
static inline void
-sym_set_flag(_Py_UopsSymbol *sym, int flag)
-{
- sym->flags |= flag;
-}
-
-static inline void
-sym_set_bottom(_Py_UOpsContext *ctx, _Py_UopsSymbol *sym)
+sym_set_bottom(JitOptContext *ctx, JitOptSymbol *sym)
{
- sym_set_flag(sym, IS_NULL | NOT_NULL);
- sym->typ = NULL;
- Py_CLEAR(sym->const_val);
+ sym->tag = JIT_SYM_BOTTOM_TAG;
ctx->done = true;
ctx->contradiction = true;
}
bool
-_Py_uop_sym_is_bottom(_Py_UopsSymbol *sym)
+_Py_uop_sym_is_bottom(JitOptSymbol *sym)
{
- if ((sym->flags & IS_NULL) && (sym->flags & NOT_NULL)) {
- assert(sym->flags == (IS_NULL | NOT_NULL));
- assert(sym->typ == NULL);
- assert(sym->const_val == NULL);
- return true;
- }
- return false;
+ return sym->tag == JIT_SYM_BOTTOM_TAG;
}
bool
-_Py_uop_sym_is_not_null(_Py_UopsSymbol *sym)
-{
- return sym->flags == NOT_NULL;
+_Py_uop_sym_is_not_null(JitOptSymbol *sym) {
+ return sym->tag == JIT_SYM_NON_NULL_TAG || sym->tag > JIT_SYM_BOTTOM_TAG;
}
bool
-_Py_uop_sym_is_null(_Py_UopsSymbol *sym)
+_Py_uop_sym_is_const(JitOptSymbol *sym)
{
- return sym->flags == IS_NULL;
+ return sym->tag == JIT_SYM_KNOWN_VALUE_TAG;
}
bool
-_Py_uop_sym_is_const(_Py_UopsSymbol *sym)
+_Py_uop_sym_is_null(JitOptSymbol *sym)
{
- return sym->const_val != NULL;
+ return sym->tag == JIT_SYM_NULL_TAG;
}
+
PyObject *
-_Py_uop_sym_get_const(_Py_UopsSymbol *sym)
+_Py_uop_sym_get_const(JitOptSymbol *sym)
{
- return sym->const_val;
+ if (sym->tag == JIT_SYM_KNOWN_VALUE_TAG) {
+ return sym->value.value;
+ }
+ return NULL;
}
void
-_Py_uop_sym_set_type(_Py_UOpsContext *ctx, _Py_UopsSymbol *sym, PyTypeObject *typ)
+_Py_uop_sym_set_type(JitOptContext *ctx, JitOptSymbol *sym, PyTypeObject *typ)
{
- assert(typ != NULL && PyType_Check(typ));
- if (sym->flags & IS_NULL) {
- sym_set_bottom(ctx, sym);
- return;
- }
- if (sym->typ != NULL) {
- if (sym->typ != typ) {
+ JitSymType tag = sym->tag;
+ switch(tag) {
+ case JIT_SYM_NULL_TAG:
sym_set_bottom(ctx, sym);
return;
- }
- }
- else {
- sym_set_flag(sym, NOT_NULL);
- sym->typ = typ;
+ case JIT_SYM_KNOWN_CLASS_TAG:
+ if (sym->cls.type != typ) {
+ sym_set_bottom(ctx, sym);
+ }
+ return;
+ case JIT_SYM_TYPE_VERSION_TAG:
+ if (sym->version.version == typ->tp_version_tag) {
+ sym->tag = JIT_SYM_KNOWN_CLASS_TAG;
+ sym->cls.type = typ;
+ sym->cls.version = typ->tp_version_tag;
+ }
+ else {
+ sym_set_bottom(ctx, sym);
+ }
+ return;
+ case JIT_SYM_KNOWN_VALUE_TAG:
+ if (Py_TYPE(sym->value.value) != typ) {
+ Py_CLEAR(sym->value.value);
+ sym_set_bottom(ctx, sym);
+ }
+ return;
+ case JIT_SYM_TUPLE_TAG:
+ if (typ != &PyTuple_Type) {
+ sym_set_bottom(ctx, sym);
+ }
+ return;
+ case JIT_SYM_BOTTOM_TAG:
+ return;
+ case JIT_SYM_NON_NULL_TAG:
+ case JIT_SYM_UNKNOWN_TAG:
+ sym->tag = JIT_SYM_KNOWN_CLASS_TAG;
+ sym->cls.version = 0;
+ sym->cls.type = typ;
+ return;
}
}
bool
-_Py_uop_sym_set_type_version(_Py_UOpsContext *ctx, _Py_UopsSymbol *sym, unsigned int version)
+_Py_uop_sym_set_type_version(JitOptContext *ctx, JitOptSymbol *sym, unsigned int version)
{
- // if the type version was already set, then it must be different and we should set it to bottom
- if (sym->type_version) {
- sym_set_bottom(ctx, sym);
- return false;
+ JitSymType tag = sym->tag;
+ switch(tag) {
+ case JIT_SYM_NULL_TAG:
+ sym_set_bottom(ctx, sym);
+ return false;
+ case JIT_SYM_KNOWN_CLASS_TAG:
+ if (sym->cls.type->tp_version_tag != version) {
+ sym_set_bottom(ctx, sym);
+ return false;
+ }
+ else {
+ sym->cls.version = version;
+ return true;
+ }
+ case JIT_SYM_KNOWN_VALUE_TAG:
+ Py_CLEAR(sym->value.value);
+ sym_set_bottom(ctx, sym);
+ return false;
+ case JIT_SYM_TUPLE_TAG:
+ sym_set_bottom(ctx, sym);
+ return false;
+ case JIT_SYM_TYPE_VERSION_TAG:
+ if (sym->version.version == version) {
+ return true;
+ }
+ sym_set_bottom(ctx, sym);
+ return false;
+ case JIT_SYM_BOTTOM_TAG:
+ return false;
+ case JIT_SYM_NON_NULL_TAG:
+ case JIT_SYM_UNKNOWN_TAG:
+ sym->tag = JIT_SYM_TYPE_VERSION_TAG;
+ sym->version.version = version;
+ return true;
}
- sym->type_version = version;
- return true;
+ Py_UNREACHABLE();
+}
+
+static void make_const(JitOptSymbol *sym, PyObject *val)
+{
+ sym->tag = JIT_SYM_KNOWN_VALUE_TAG;
+ sym->value.value = Py_NewRef(val);
}
void
-_Py_uop_sym_set_const(_Py_UOpsContext *ctx, _Py_UopsSymbol *sym, PyObject *const_val)
+_Py_uop_sym_set_const(JitOptContext *ctx, JitOptSymbol *sym, PyObject *const_val)
{
- assert(const_val != NULL);
- if (sym->flags & IS_NULL) {
- sym_set_bottom(ctx, sym);
- }
- PyTypeObject *typ = Py_TYPE(const_val);
- if (sym->typ != NULL && sym->typ != typ) {
- sym_set_bottom(ctx, sym);
- }
- if (sym->const_val != NULL) {
- if (sym->const_val != const_val) {
- // TODO: What if they're equal?
+ JitSymType tag = sym->tag;
+ switch(tag) {
+ case JIT_SYM_NULL_TAG:
sym_set_bottom(ctx, sym);
- }
- }
- else {
- sym_set_flag(sym, NOT_NULL);
- sym->typ = typ;
- sym->const_val = Py_NewRef(const_val);
+ return;
+ case JIT_SYM_KNOWN_CLASS_TAG:
+ if (sym->cls.type != Py_TYPE(const_val)) {
+ sym_set_bottom(ctx, sym);
+ return;
+ }
+ make_const(sym, const_val);
+ return;
+ case JIT_SYM_KNOWN_VALUE_TAG:
+ if (sym->value.value != const_val) {
+ Py_CLEAR(sym->value.value);
+ sym_set_bottom(ctx, sym);
+ }
+ return;
+ case JIT_SYM_TUPLE_TAG:
+ sym_set_bottom(ctx, sym);
+ return;
+ case JIT_SYM_TYPE_VERSION_TAG:
+ if (sym->version.version != Py_TYPE(const_val)->tp_version_tag) {
+ sym_set_bottom(ctx, sym);
+ return;
+ }
+ make_const(sym, const_val);
+ return;
+ case JIT_SYM_BOTTOM_TAG:
+ return;
+ case JIT_SYM_NON_NULL_TAG:
+ case JIT_SYM_UNKNOWN_TAG:
+ make_const(sym, const_val);
+ return;
}
}
void
-_Py_uop_sym_set_null(_Py_UOpsContext *ctx, _Py_UopsSymbol *sym)
+_Py_uop_sym_set_null(JitOptContext *ctx, JitOptSymbol *sym)
{
- if (_Py_uop_sym_is_not_null(sym)) {
+ if (sym->tag == JIT_SYM_UNKNOWN_TAG) {
+ sym->tag = JIT_SYM_NULL_TAG;
+ }
+ else if (sym->tag > JIT_SYM_NULL_TAG) {
sym_set_bottom(ctx, sym);
}
- sym_set_flag(sym, IS_NULL);
}
void
-_Py_uop_sym_set_non_null(_Py_UOpsContext *ctx, _Py_UopsSymbol *sym)
+_Py_uop_sym_set_non_null(JitOptContext *ctx, JitOptSymbol *sym)
{
- if (_Py_uop_sym_is_null(sym)) {
+ if (sym->tag == JIT_SYM_UNKNOWN_TAG) {
+ sym->tag = JIT_SYM_NON_NULL_TAG;
+ }
+ else if (sym->tag == JIT_SYM_NULL_TAG) {
sym_set_bottom(ctx, sym);
}
- sym_set_flag(sym, NOT_NULL);
}
-_Py_UopsSymbol *
-_Py_uop_sym_new_unknown(_Py_UOpsContext *ctx)
+JitOptSymbol *
+_Py_uop_sym_new_unknown(JitOptContext *ctx)
{
- return sym_new(ctx);
+ JitOptSymbol *res = sym_new(ctx);
+ if (res == NULL) {
+ return out_of_space(ctx);
+ }
+ return res;
}
-_Py_UopsSymbol *
-_Py_uop_sym_new_not_null(_Py_UOpsContext *ctx)
+JitOptSymbol *
+_Py_uop_sym_new_not_null(JitOptContext *ctx)
{
- _Py_UopsSymbol *res = _Py_uop_sym_new_unknown(ctx);
+ JitOptSymbol *res = sym_new(ctx);
if (res == NULL) {
return out_of_space(ctx);
}
- sym_set_flag(res, NOT_NULL);
+ res->tag = JIT_SYM_NON_NULL_TAG;
return res;
}
-_Py_UopsSymbol *
-_Py_uop_sym_new_type(_Py_UOpsContext *ctx, PyTypeObject *typ)
+JitOptSymbol *
+_Py_uop_sym_new_type(JitOptContext *ctx, PyTypeObject *typ)
{
- _Py_UopsSymbol *res = sym_new(ctx);
+ JitOptSymbol *res = sym_new(ctx);
if (res == NULL) {
return out_of_space(ctx);
}
@@ -237,11 +299,11 @@ _Py_uop_sym_new_type(_Py_UOpsContext *ctx, PyTypeObject *typ)
}
// Adds a new reference to const_val, owned by the symbol.
-_Py_UopsSymbol *
-_Py_uop_sym_new_const(_Py_UOpsContext *ctx, PyObject *const_val)
+JitOptSymbol *
+_Py_uop_sym_new_const(JitOptContext *ctx, PyObject *const_val)
{
assert(const_val != NULL);
- _Py_UopsSymbol *res = sym_new(ctx);
+ JitOptSymbol *res = sym_new(ctx);
if (res == NULL) {
return out_of_space(ctx);
}
@@ -249,10 +311,10 @@ _Py_uop_sym_new_const(_Py_UOpsContext *ctx, PyObject *const_val)
return res;
}
-_Py_UopsSymbol *
-_Py_uop_sym_new_null(_Py_UOpsContext *ctx)
+JitOptSymbol *
+_Py_uop_sym_new_null(JitOptContext *ctx)
{
- _Py_UopsSymbol *null_sym = _Py_uop_sym_new_unknown(ctx);
+ JitOptSymbol *null_sym = sym_new(ctx);
if (null_sym == NULL) {
return out_of_space(ctx);
}
@@ -261,64 +323,105 @@ _Py_uop_sym_new_null(_Py_UOpsContext *ctx)
}
PyTypeObject *
-_Py_uop_sym_get_type(_Py_UopsSymbol *sym)
+_Py_uop_sym_get_type(JitOptSymbol *sym)
{
- if (_Py_uop_sym_is_bottom(sym)) {
- return NULL;
- }
- return sym->typ;
+ JitSymType tag = sym->tag;
+ switch(tag) {
+ case JIT_SYM_NULL_TAG:
+ case JIT_SYM_TYPE_VERSION_TAG:
+ case JIT_SYM_BOTTOM_TAG:
+ case JIT_SYM_NON_NULL_TAG:
+ case JIT_SYM_UNKNOWN_TAG:
+ return NULL;
+ case JIT_SYM_KNOWN_CLASS_TAG:
+ return sym->cls.type;
+ case JIT_SYM_KNOWN_VALUE_TAG:
+ return Py_TYPE(sym->value.value);
+ case JIT_SYM_TUPLE_TAG:
+ return &PyTuple_Type;
+ }
+ Py_UNREACHABLE();
}
unsigned int
-_Py_uop_sym_get_type_version(_Py_UopsSymbol *sym)
+_Py_uop_sym_get_type_version(JitOptSymbol *sym)
{
- return sym->type_version;
+ JitSymType tag = sym->tag;
+ switch(tag) {
+ case JIT_SYM_NULL_TAG:
+ case JIT_SYM_BOTTOM_TAG:
+ case JIT_SYM_NON_NULL_TAG:
+ case JIT_SYM_UNKNOWN_TAG:
+ return 0;
+ case JIT_SYM_TYPE_VERSION_TAG:
+ return sym->version.version;
+ case JIT_SYM_KNOWN_CLASS_TAG:
+ return sym->cls.version;
+ case JIT_SYM_KNOWN_VALUE_TAG:
+ return Py_TYPE(sym->value.value)->tp_version_tag;
+ case JIT_SYM_TUPLE_TAG:
+ return PyTuple_Type.tp_version_tag;
+ }
+ Py_UNREACHABLE();
}
bool
-_Py_uop_sym_has_type(_Py_UopsSymbol *sym)
+_Py_uop_sym_has_type(JitOptSymbol *sym)
{
- if (_Py_uop_sym_is_bottom(sym)) {
- return false;
- }
- return sym->typ != NULL;
+ JitSymType tag = sym->tag;
+ switch(tag) {
+ case JIT_SYM_NULL_TAG:
+ case JIT_SYM_TYPE_VERSION_TAG:
+ case JIT_SYM_BOTTOM_TAG:
+ case JIT_SYM_NON_NULL_TAG:
+ case JIT_SYM_UNKNOWN_TAG:
+ return false;
+ case JIT_SYM_KNOWN_CLASS_TAG:
+ case JIT_SYM_KNOWN_VALUE_TAG:
+ case JIT_SYM_TUPLE_TAG:
+ return true;
+ }
+ Py_UNREACHABLE();
}
bool
-_Py_uop_sym_matches_type(_Py_UopsSymbol *sym, PyTypeObject *typ)
+_Py_uop_sym_matches_type(JitOptSymbol *sym, PyTypeObject *typ)
{
assert(typ != NULL && PyType_Check(typ));
return _Py_uop_sym_get_type(sym) == typ;
}
bool
-_Py_uop_sym_matches_type_version(_Py_UopsSymbol *sym, unsigned int version)
+_Py_uop_sym_matches_type_version(JitOptSymbol *sym, unsigned int version)
{
return _Py_uop_sym_get_type_version(sym) == version;
}
-
int
-_Py_uop_sym_truthiness(_Py_UopsSymbol *sym)
-{
- /* There are some non-constant values for
- * which `bool(val)` always evaluates to
- * True or False, such as tuples with known
- * length, but unknown contents, or bound-methods.
- * This function will need updating
- * should we support those values.
- */
- if (_Py_uop_sym_is_bottom(sym)) {
- return -1;
- }
- if (!_Py_uop_sym_is_const(sym)) {
- return -1;
- }
- PyObject *value = _Py_uop_sym_get_const(sym);
+_Py_uop_sym_truthiness(JitOptSymbol *sym)
+{
+ switch(sym->tag) {
+ case JIT_SYM_NULL_TAG:
+ case JIT_SYM_TYPE_VERSION_TAG:
+ case JIT_SYM_BOTTOM_TAG:
+ case JIT_SYM_NON_NULL_TAG:
+ case JIT_SYM_UNKNOWN_TAG:
+ return -1;
+ case JIT_SYM_KNOWN_CLASS_TAG:
+ /* TODO :
+ * Instances of some classes are always
+ * true. We should return 1 in those cases */
+ return -1;
+ case JIT_SYM_KNOWN_VALUE_TAG:
+ break;
+ case JIT_SYM_TUPLE_TAG:
+ return sym->tuple.length != 0;
+ }
+ PyObject *value = sym->value.value;
+ /* Only handle a few known safe types */
if (value == Py_None) {
return 0;
}
- /* Only handle a few known safe types */
PyTypeObject *tp = Py_TYPE(value);
if (tp == &PyLong_Type) {
return !_PyLong_IsZero((PyLongObject *)value);
@@ -332,13 +435,84 @@ _Py_uop_sym_truthiness(_Py_UopsSymbol *sym)
return -1;
}
+static JitOptSymbol *
+allocation_base(JitOptContext *ctx)
+{
+ return ctx->t_arena.arena;
+}
+
+JitOptSymbol *
+_Py_uop_sym_new_tuple(JitOptContext *ctx, int size, JitOptSymbol **args)
+{
+ JitOptSymbol *res = sym_new(ctx);
+ if (res == NULL) {
+ return out_of_space(ctx);
+ }
+ if (size > MAX_SYMBOLIC_TUPLE_SIZE) {
+ res->tag = JIT_SYM_KNOWN_CLASS_TAG;
+ res->cls.type = &PyTuple_Type;
+ }
+ else {
+ res->tag = JIT_SYM_TUPLE_TAG;
+ res->tuple.length = size;
+ for (int i = 0; i < size; i++) {
+ res->tuple.items[i] = (uint16_t)(args[i] - allocation_base(ctx));
+ }
+ }
+ return res;
+}
+
+JitOptSymbol *
+_Py_uop_sym_tuple_getitem(JitOptContext *ctx, JitOptSymbol *sym, int item)
+{
+ assert(item >= 0);
+ if (sym->tag == JIT_SYM_KNOWN_VALUE_TAG) {
+ PyObject *tuple = sym->value.value;
+ if (PyTuple_CheckExact(tuple) && item < PyTuple_GET_SIZE(tuple)) {
+ return _Py_uop_sym_new_const(ctx, PyTuple_GET_ITEM(tuple, item));
+ }
+ }
+ else if (sym->tag == JIT_SYM_TUPLE_TAG && item < sym->tuple.length) {
+ return allocation_base(ctx) + sym->tuple.items[item];
+ }
+ return _Py_uop_sym_new_unknown(ctx);
+}
+
+int
+_Py_uop_sym_tuple_length(JitOptSymbol *sym)
+{
+ if (sym->tag == JIT_SYM_KNOWN_VALUE_TAG) {
+ PyObject *tuple = sym->value.value;
+ if (PyTuple_CheckExact(tuple)) {
+ return PyTuple_GET_SIZE(tuple);
+ }
+ }
+ else if (sym->tag == JIT_SYM_TUPLE_TAG) {
+ return sym->tuple.length;
+ }
+ return -1;
+}
+
+// Return true if known to be immortal.
+bool
+_Py_uop_sym_is_immortal(JitOptSymbol *sym)
+{
+ if (sym->tag == JIT_SYM_KNOWN_VALUE_TAG) {
+ return _Py_IsImmortal(sym->value.value);
+ }
+ if (sym->tag == JIT_SYM_KNOWN_CLASS_TAG) {
+ return sym->cls.type == &PyBool_Type;
+ }
+ return false;
+}
+
// 0 on success, -1 on error.
_Py_UOpsAbstractFrame *
_Py_uop_frame_new(
- _Py_UOpsContext *ctx,
+ JitOptContext *ctx,
PyCodeObject *co,
int curr_stackentries,
- _Py_UopsSymbol **args,
+ JitOptSymbol **args,
int arg_len)
{
assert(ctx->curr_frame_depth < MAX_ABSTRACT_FRAME_DEPTH);
@@ -363,14 +537,14 @@ _Py_uop_frame_new(
}
for (int i = arg_len; i < co->co_nlocalsplus; i++) {
- _Py_UopsSymbol *local = _Py_uop_sym_new_unknown(ctx);
+ JitOptSymbol *local = _Py_uop_sym_new_unknown(ctx);
frame->locals[i] = local;
}
// Initialize the stack as well
for (int i = 0; i < curr_stackentries; i++) {
- _Py_UopsSymbol *stackvar = _Py_uop_sym_new_unknown(ctx);
+ JitOptSymbol *stackvar = _Py_uop_sym_new_unknown(ctx);
frame->stack[i] = stackvar;
}
@@ -378,7 +552,7 @@ _Py_uop_frame_new(
}
void
-_Py_uop_abstractcontext_fini(_Py_UOpsContext *ctx)
+_Py_uop_abstractcontext_fini(JitOptContext *ctx)
{
if (ctx == NULL) {
return;
@@ -386,13 +560,17 @@ _Py_uop_abstractcontext_fini(_Py_UOpsContext *ctx)
ctx->curr_frame_depth = 0;
int tys = ctx->t_arena.ty_curr_number;
for (int i = 0; i < tys; i++) {
- Py_CLEAR(ctx->t_arena.arena[i].const_val);
+ JitOptSymbol *sym = &ctx->t_arena.arena[i];
+ if (sym->tag == JIT_SYM_KNOWN_VALUE_TAG) {
+ Py_CLEAR(sym->value.value);
+ }
}
}
void
-_Py_uop_abstractcontext_init(_Py_UOpsContext *ctx)
+_Py_uop_abstractcontext_init(JitOptContext *ctx)
{
+ static_assert(sizeof(JitOptSymbol) <= 2*sizeof(uint64_t));
ctx->limit = ctx->locals_and_stack + MAX_ABSTRACT_INTERP_SIZE;
ctx->n_consumed = ctx->locals_and_stack;
#ifdef Py_DEBUG // Aids debugging a little. There should never be NULL in the abstract interpreter.
@@ -410,7 +588,7 @@ _Py_uop_abstractcontext_init(_Py_UOpsContext *ctx)
}
int
-_Py_uop_frame_pop(_Py_UOpsContext *ctx)
+_Py_uop_frame_pop(JitOptContext *ctx)
{
_Py_UOpsAbstractFrame *frame = ctx->frame;
ctx->n_consumed = frame->locals;
@@ -431,26 +609,25 @@ do { \
} \
} while (0)
-static _Py_UopsSymbol *
-make_bottom(_Py_UOpsContext *ctx)
+static JitOptSymbol *
+make_bottom(JitOptContext *ctx)
{
- _Py_UopsSymbol *sym = _Py_uop_sym_new_unknown(ctx);
- _Py_uop_sym_set_null(ctx, sym);
- _Py_uop_sym_set_non_null(ctx, sym);
+ JitOptSymbol *sym = sym_new(ctx);
+ sym->tag = JIT_SYM_BOTTOM_TAG;
return sym;
}
PyObject *
_Py_uop_symbols_test(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))
{
- _Py_UOpsContext context;
- _Py_UOpsContext *ctx = &context;
+ JitOptContext context;
+ JitOptContext *ctx = &context;
_Py_uop_abstractcontext_init(ctx);
PyObject *val_42 = NULL;
PyObject *val_43 = NULL;
// Use a single 'sym' variable so copy-pasting tests is easier.
- _Py_UopsSymbol *sym = _Py_uop_sym_new_unknown(ctx);
+ JitOptSymbol *sym = _Py_uop_sym_new_unknown(ctx);
if (sym == NULL) {
goto fail;
}
@@ -510,6 +687,7 @@ _Py_uop_symbols_test(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))
TEST_PREDICATE(_Py_uop_sym_is_const(sym), "42 is not a constant");
TEST_PREDICATE(_Py_uop_sym_get_const(sym) != NULL, "42 as constant is NULL");
TEST_PREDICATE(_Py_uop_sym_get_const(sym) == val_42, "42 as constant isn't 42");
+ TEST_PREDICATE(_Py_uop_sym_is_immortal(sym), "42 is not immortal");
_Py_uop_sym_set_type(ctx, sym, &PyLong_Type); // Should be a no-op
TEST_PREDICATE(_Py_uop_sym_matches_type(sym, &PyLong_Type), "(42 and 42) isn't an int");
@@ -518,6 +696,9 @@ _Py_uop_symbols_test(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))
_Py_uop_sym_set_type(ctx, sym, &PyFloat_Type); // Should make it bottom
TEST_PREDICATE(_Py_uop_sym_is_bottom(sym), "(42 and float) isn't bottom");
+ sym = _Py_uop_sym_new_type(ctx, &PyBool_Type);
+ TEST_PREDICATE(_Py_uop_sym_is_immortal(sym), "a bool is not immortal");
+
sym = _Py_uop_sym_new_type(ctx, &PyLong_Type);
if (sym == NULL) {
goto fail;
@@ -534,15 +715,37 @@ _Py_uop_symbols_test(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))
sym = _Py_uop_sym_new_const(ctx, PyLong_FromLong(0));
TEST_PREDICATE(_Py_uop_sym_truthiness(sym) == 0, "bool(0) is not False");
+ JitOptSymbol *i1 = _Py_uop_sym_new_type(ctx, &PyFloat_Type);
+ JitOptSymbol *i2 = _Py_uop_sym_new_const(ctx, val_43);
+ JitOptSymbol *array[2] = { i1, i2 };
+ sym = _Py_uop_sym_new_tuple(ctx, 2, array);
+ TEST_PREDICATE(
+ _Py_uop_sym_matches_type(_Py_uop_sym_tuple_getitem(ctx, sym, 0), &PyFloat_Type),
+ "tuple item does not match value used to create tuple"
+ );
+ TEST_PREDICATE(
+ _Py_uop_sym_get_const(_Py_uop_sym_tuple_getitem(ctx, sym, 1)) == val_43,
+ "tuple item does not match value used to create tuple"
+ );
+ PyObject *pair[2] = { val_42, val_43 };
+ PyObject *tuple = _PyTuple_FromArray(pair, 2);
+ sym = _Py_uop_sym_new_const(ctx, tuple);
+ TEST_PREDICATE(
+ _Py_uop_sym_get_const(_Py_uop_sym_tuple_getitem(ctx, sym, 1)) == val_43,
+ "tuple item does not match value used to create tuple"
+ );
+
_Py_uop_abstractcontext_fini(ctx);
Py_DECREF(val_42);
Py_DECREF(val_43);
+ Py_DECREF(tuple);
Py_RETURN_NONE;
fail:
_Py_uop_abstractcontext_fini(ctx);
Py_XDECREF(val_42);
Py_XDECREF(val_43);
+ Py_DECREF(tuple);
return NULL;
}
diff --git a/Tools/cases_generator/optimizer_generator.py b/Tools/cases_generator/optimizer_generator.py
index 2928440fecca0c..5cfec4bfecbf07 100644
--- a/Tools/cases_generator/optimizer_generator.py
+++ b/Tools/cases_generator/optimizer_generator.py
@@ -36,10 +36,10 @@ def validate_uop(override: Uop, uop: Uop) -> None:
def type_name(var: StackItem) -> str:
if var.is_array():
- return f"_Py_UopsSymbol **"
+ return f"JitOptSymbol **"
if var.type:
return var.type
- return f"_Py_UopsSymbol *"
+ return f"JitOptSymbol *"
def declare_variables(uop: Uop, out: CWriter, skip_inputs: bool) -> None:
@@ -151,11 +151,11 @@ def write_uop(
var.defined = False
storage = emitter.emit_tokens(override, storage, None)
out.start_line()
- storage.flush(out, cast_type="_Py_UopsSymbol *")
+ storage.flush(out, cast_type="JitOptSymbol *")
else:
emit_default(out, uop, stack)
out.start_line()
- stack.flush(out, cast_type="_Py_UopsSymbol *")
+ stack.flush(out, cast_type="JitOptSymbol *")
except StackError as ex:
raise analysis_error(ex.args[0], prototype.body[0]) # from None
1
0
gh-129044: Update glossary entry for 'loader' to reflect current import system (#129073)
by AA-Turner Jan. 20, 2025
by AA-Turner Jan. 20, 2025
Jan. 20, 2025
https://github.com/python/cpython/commit/e1fa2fcc7c1bf5291a7f71300b7828b49b…
commit: e1fa2fcc7c1bf5291a7f71300b7828b49be9ab72
branch: main
author: nikalinov <92603661+nikalinov(a)users.noreply.github.com>
committer: AA-Turner <9087854+AA-Turner(a)users.noreply.github.com>
date: 2025-01-20T15:46:09Z
summary:
gh-129044: Update glossary entry for 'loader' to reflect current import system (#129073)
Co-authored-by: Adam Turner <9087854+AA-Turner(a)users.noreply.github.com>
files:
M Doc/glossary.rst
M Doc/tools/.nitignore
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index 33e77c9de211eb..e3a14601398e89 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -811,9 +811,11 @@ Glossary
processed.
loader
- An object that loads a module. It must define a method named
- :meth:`load_module`. A loader is typically returned by a
- :term:`finder`. See also:
+ An object that loads a module.
+ It must define the :meth:`!exec_module` and :meth:`!create_module` methods
+ to implement the :class:`~importlib.abc.Loader` interface.
+ A loader is typically returned by a :term:`finder`.
+ See also:
* :ref:`finders-and-loaders`
* :class:`importlib.abc.Loader`
diff --git a/Doc/tools/.nitignore b/Doc/tools/.nitignore
index 6940c95ab2c9a1..ad24fe82f754fc 100644
--- a/Doc/tools/.nitignore
+++ b/Doc/tools/.nitignore
@@ -12,7 +12,6 @@ Doc/c-api/stable.rst
Doc/c-api/type.rst
Doc/c-api/typeobj.rst
Doc/extending/extending.rst
-Doc/glossary.rst
Doc/library/ast.rst
Doc/library/asyncio-extending.rst
Doc/library/asyncio-subprocess.rst
1
0