544099ee60f85f9b5462f64b19d52cabecc6d7f3e7dc75f037db0030e18c7d16
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +1 -0
- lib/python3.11/site-packages/llvmlite-0.41.1.dist-info/INSTALLER +1 -0
- lib/python3.11/site-packages/llvmlite-0.41.1.dist-info/LICENSE +24 -0
- lib/python3.11/site-packages/llvmlite-0.41.1.dist-info/METADATA +136 -0
- lib/python3.11/site-packages/llvmlite-0.41.1.dist-info/RECORD +81 -0
- lib/python3.11/site-packages/llvmlite-0.41.1.dist-info/WHEEL +5 -0
- lib/python3.11/site-packages/llvmlite-0.41.1.dist-info/top_level.txt +1 -0
- lib/python3.11/site-packages/llvmlite/tests/__pycache__/customize.cpython-311.pyc +0 -0
- lib/python3.11/site-packages/llvmlite/tests/__pycache__/refprune_proto.cpython-311.pyc +0 -0
- lib/python3.11/site-packages/llvmlite/tests/__pycache__/test_binding.cpython-311.pyc +0 -0
- lib/python3.11/site-packages/llvmlite/tests/__pycache__/test_ir.cpython-311.pyc +0 -0
- lib/python3.11/site-packages/llvmlite/tests/__pycache__/test_refprune.cpython-311.pyc +0 -0
- lib/python3.11/site-packages/llvmlite/tests/__pycache__/test_valuerepr.cpython-311.pyc +0 -0
- lib/python3.11/site-packages/llvmlite/tests/customize.py +407 -0
- lib/python3.11/site-packages/llvmlite/tests/refprune_proto.py +329 -0
- lib/python3.11/site-packages/llvmlite/tests/test_binding.py +2431 -0
- lib/python3.11/site-packages/llvmlite/tests/test_ir.py +0 -0
- lib/python3.11/site-packages/llvmlite/tests/test_refprune.py +526 -0
- lib/python3.11/site-packages/llvmlite/tests/test_valuerepr.py +60 -0
- lib/python3.11/site-packages/llvmlite/utils.py +29 -0
- lib/python3.11/site-packages/markupsafe/__init__.py +304 -0
- lib/python3.11/site-packages/markupsafe/__pycache__/__init__.cpython-311.pyc +0 -0
- lib/python3.11/site-packages/markupsafe/__pycache__/_native.cpython-311.pyc +0 -0
- lib/python3.11/site-packages/markupsafe/_native.py +63 -0
- lib/python3.11/site-packages/markupsafe/_speedups.c +320 -0
- lib/python3.11/site-packages/markupsafe/_speedups.cpython-311-darwin.so +0 -0
- lib/python3.11/site-packages/markupsafe/_speedups.pyi +9 -0
- lib/python3.11/site-packages/markupsafe/py.typed +0 -0
- lib/python3.11/site-packages/mlx/__pycache__/_reprlib_fix.cpython-311.pyc +0 -0
- lib/python3.11/site-packages/mlx/__pycache__/extension.cpython-311.pyc +0 -0
- lib/python3.11/site-packages/mlx/__pycache__/optimizers.cpython-311.pyc +0 -0
- lib/python3.11/site-packages/mlx/__pycache__/utils.cpython-311.pyc +0 -0
- lib/python3.11/site-packages/mlx/_reprlib_fix.py +20 -0
- lib/python3.11/site-packages/mlx/core.cpython-311-darwin.so +3 -0
- lib/python3.11/site-packages/mlx/extension.py +96 -0
- lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/Foundation.hpp +47 -0
- lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSArray.hpp +115 -0
- lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSAutoreleasePool.hpp +83 -0
- lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSBundle.hpp +374 -0
- lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSData.hpp +54 -0
- lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSDate.hpp +53 -0
- lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSDefines.hpp +45 -0
- lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSDictionary.hpp +128 -0
- lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSEnumerator.hpp +78 -0
- lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSError.hpp +173 -0
- lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSLock.hpp +118 -0
- lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSNotification.hpp +110 -0
- lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSNumber.hpp +501 -0
- lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSObjCRuntime.hpp +43 -0
- lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSObject.hpp +302 -0
.gitattributes
CHANGED
|
@@ -34,3 +34,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
lib/python3.11/site-packages/llvmlite/binding/libllvmlite.dylib filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
lib/python3.11/site-packages/llvmlite/binding/libllvmlite.dylib filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
lib/python3.11/site-packages/mlx/core.cpython-311-darwin.so filter=lfs diff=lfs merge=lfs -text
|
lib/python3.11/site-packages/llvmlite-0.41.1.dist-info/INSTALLER
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
pip
|
lib/python3.11/site-packages/llvmlite-0.41.1.dist-info/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Copyright (c) 2014-, Continuum Analytics, Inc.
|
| 2 |
+
All rights reserved.
|
| 3 |
+
|
| 4 |
+
Redistribution and use in source and binary forms, with or without
|
| 5 |
+
modification, are permitted provided that the following conditions are
|
| 6 |
+
met:
|
| 7 |
+
|
| 8 |
+
Redistributions of source code must retain the above copyright notice,
|
| 9 |
+
this list of conditions and the following disclaimer.
|
| 10 |
+
|
| 11 |
+
Redistributions in binary form must reproduce the above copyright
|
| 12 |
+
notice, this list of conditions and the following disclaimer in the
|
| 13 |
+
documentation and/or other materials provided with the distribution.
|
| 14 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| 15 |
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| 16 |
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| 17 |
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| 18 |
+
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| 19 |
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| 20 |
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| 21 |
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| 22 |
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| 23 |
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| 24 |
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
lib/python3.11/site-packages/llvmlite-0.41.1.dist-info/METADATA
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.1
|
| 2 |
+
Name: llvmlite
|
| 3 |
+
Version: 0.41.1
|
| 4 |
+
Summary: lightweight wrapper around basic LLVM functionality
|
| 5 |
+
Home-page: http://llvmlite.readthedocs.io
|
| 6 |
+
License: BSD
|
| 7 |
+
Project-URL: Source, https://github.com/numba/llvmlite
|
| 8 |
+
Classifier: Development Status :: 4 - Beta
|
| 9 |
+
Classifier: Intended Audience :: Developers
|
| 10 |
+
Classifier: Operating System :: OS Independent
|
| 11 |
+
Classifier: Programming Language :: Python
|
| 12 |
+
Classifier: Programming Language :: Python :: 3
|
| 13 |
+
Classifier: Programming Language :: Python :: 3.8
|
| 14 |
+
Classifier: Programming Language :: Python :: 3.9
|
| 15 |
+
Classifier: Programming Language :: Python :: 3.10
|
| 16 |
+
Classifier: Programming Language :: Python :: 3.11
|
| 17 |
+
Classifier: Topic :: Software Development :: Code Generators
|
| 18 |
+
Classifier: Topic :: Software Development :: Compilers
|
| 19 |
+
Requires-Python: >=3.8
|
| 20 |
+
License-File: LICENSE
|
| 21 |
+
|
| 22 |
+
========
|
| 23 |
+
llvmlite
|
| 24 |
+
========
|
| 25 |
+
|
| 26 |
+
.. image:: https://dev.azure.com/numba/numba/_apis/build/status/numba.llvmlite?branchName=main
|
| 27 |
+
:target: https://dev.azure.com/numba/numba/_build/latest?definitionId=2&branchName=main
|
| 28 |
+
:alt: Azure Pipelines
|
| 29 |
+
.. image:: https://codeclimate.com/github/numba/llvmlite/badges/gpa.svg
|
| 30 |
+
:target: https://codeclimate.com/github/numba/llvmlite
|
| 31 |
+
:alt: Code Climate
|
| 32 |
+
.. image:: https://coveralls.io/repos/github/numba/llvmlite/badge.svg
|
| 33 |
+
:target: https://coveralls.io/github/numba/llvmlite
|
| 34 |
+
:alt: Coveralls.io
|
| 35 |
+
.. image:: https://readthedocs.org/projects/llvmlite/badge/
|
| 36 |
+
:target: https://llvmlite.readthedocs.io
|
| 37 |
+
:alt: Readthedocs.io
|
| 38 |
+
|
| 39 |
+
A Lightweight LLVM Python Binding for Writing JIT Compilers
|
| 40 |
+
-----------------------------------------------------------
|
| 41 |
+
|
| 42 |
+
.. _llvmpy: https://github.com/llvmpy/llvmpy
|
| 43 |
+
|
| 44 |
+
llvmlite is a project originally tailored for Numba_'s needs, using the
|
| 45 |
+
following approach:
|
| 46 |
+
|
| 47 |
+
* A small C wrapper around the parts of the LLVM C++ API we need that are
|
| 48 |
+
not already exposed by the LLVM C API.
|
| 49 |
+
* A ctypes Python wrapper around the C API.
|
| 50 |
+
* A pure Python implementation of the subset of the LLVM IR builder that we
|
| 51 |
+
need for Numba.
|
| 52 |
+
|
| 53 |
+
Why llvmlite
|
| 54 |
+
============
|
| 55 |
+
|
| 56 |
+
The old llvmpy_ binding exposes a lot of LLVM APIs but the mapping of
|
| 57 |
+
C++-style memory management to Python is error prone. Numba_ and many JIT
|
| 58 |
+
compilers do not need a full LLVM API. Only the IR builder, optimizer,
|
| 59 |
+
and JIT compiler APIs are necessary.
|
| 60 |
+
|
| 61 |
+
Key Benefits
|
| 62 |
+
============
|
| 63 |
+
|
| 64 |
+
* The IR builder is pure Python code and decoupled from LLVM's
|
| 65 |
+
frequently-changing C++ APIs.
|
| 66 |
+
* Materializing a LLVM module calls LLVM's IR parser which provides
|
| 67 |
+
better error messages than step-by-step IR building through the C++
|
| 68 |
+
API (no more segfaults or process aborts).
|
| 69 |
+
* Most of llvmlite uses the LLVM C API which is small but very stable
|
| 70 |
+
(low maintenance when changing LLVM version).
|
| 71 |
+
* The binding is not a Python C-extension, but a plain DLL accessed using
|
| 72 |
+
ctypes (no need to wrestle with Python's compiler requirements and C++ 11
|
| 73 |
+
compatibility).
|
| 74 |
+
* The Python binding layer has sane memory management.
|
| 75 |
+
* llvmlite is faster than llvmpy thanks to a much simpler architecture
|
| 76 |
+
(the Numba_ test suite is twice faster than it was).
|
| 77 |
+
|
| 78 |
+
Compatibility
|
| 79 |
+
=============
|
| 80 |
+
|
| 81 |
+
llvmlite works with Python 3.8 and greater. We attempt to test with the latest
|
| 82 |
+
Python version, this can be checked by looking at the public CI builds.
|
| 83 |
+
|
| 84 |
+
As of version 0.41.0, llvmlite requires LLVM 14.x.x on all architectures
|
| 85 |
+
|
| 86 |
+
Historical compatibility table:
|
| 87 |
+
|
| 88 |
+
================= ========================
|
| 89 |
+
llvmlite versions compatible LLVM versions
|
| 90 |
+
================= ========================
|
| 91 |
+
0.41.0 - ... 14.x.x
|
| 92 |
+
0.40.0 - 0.40.1 11.x.x and 14.x.x (12.x.x and 13.x.x untested but may work)
|
| 93 |
+
0.37.0 - 0.39.1 11.x.x
|
| 94 |
+
0.34.0 - 0.36.0 10.0.x (9.0.x for ``aarch64`` only)
|
| 95 |
+
0.33.0 9.0.x
|
| 96 |
+
0.29.0 - 0.32.0 7.0.x, 7.1.x, 8.0.x
|
| 97 |
+
0.27.0 - 0.28.0 7.0.x
|
| 98 |
+
0.23.0 - 0.26.0 6.0.x
|
| 99 |
+
0.21.0 - 0.22.0 5.0.x
|
| 100 |
+
0.17.0 - 0.20.0 4.0.x
|
| 101 |
+
0.16.0 - 0.17.0 3.9.x
|
| 102 |
+
0.13.0 - 0.15.0 3.8.x
|
| 103 |
+
0.9.0 - 0.12.1 3.7.x
|
| 104 |
+
0.6.0 - 0.8.0 3.6.x
|
| 105 |
+
0.1.0 - 0.5.1 3.5.x
|
| 106 |
+
================= ========================
|
| 107 |
+
|
| 108 |
+
Documentation
|
| 109 |
+
=============
|
| 110 |
+
|
| 111 |
+
You'll find the documentation at http://llvmlite.pydata.org
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
Pre-built binaries
|
| 115 |
+
==================
|
| 116 |
+
|
| 117 |
+
We recommend you use the binaries provided by the Numba_ team for
|
| 118 |
+
the Conda_ package manager. You can find them in Numba's `anaconda.org
|
| 119 |
+
channel <https://anaconda.org/numba>`_. For example::
|
| 120 |
+
|
| 121 |
+
$ conda install --channel=numba llvmlite
|
| 122 |
+
|
| 123 |
+
(or, simply, the official llvmlite package provided in the Anaconda_
|
| 124 |
+
distribution)
|
| 125 |
+
|
| 126 |
+
.. _Numba: http://numba.pydata.org/
|
| 127 |
+
.. _Conda: http://conda.pydata.org/
|
| 128 |
+
.. _Anaconda: http://docs.continuum.io/anaconda/index.html
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
Other build methods
|
| 132 |
+
===================
|
| 133 |
+
|
| 134 |
+
If you don't want to use our pre-built packages, you can compile
|
| 135 |
+
and install llvmlite yourself. The documentation will teach you how:
|
| 136 |
+
http://llvmlite.pydata.org/en/latest/install/index.html
|
lib/python3.11/site-packages/llvmlite-0.41.1.dist-info/RECORD
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
llvmlite-0.41.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
| 2 |
+
llvmlite-0.41.1.dist-info/LICENSE,sha256=S5pyZLAROnsybuhPwkS3OZG1NbSDPkpW1YdQ8qciUNw,1298
|
| 3 |
+
llvmlite-0.41.1.dist-info/METADATA,sha256=ViL9FB2NBHKaVY4Ws8v41nBy-SKPB3-8PJ6HNIW8fTQ,4808
|
| 4 |
+
llvmlite-0.41.1.dist-info/RECORD,,
|
| 5 |
+
llvmlite-0.41.1.dist-info/WHEEL,sha256=eaDTbMedWofVq8IZjew9qeAkoA5Sw2MOU2ppdIRr1Jg,110
|
| 6 |
+
llvmlite-0.41.1.dist-info/top_level.txt,sha256=WJi8Gq92jA2wv_aV1Oshp9iZ-zMa43Kcmw80kWeGYGA,9
|
| 7 |
+
llvmlite/__init__.py,sha256=PiUSiFLCm0YX5rbHS4xOLGdqdPDC8j3etV3nmEaelzI,92
|
| 8 |
+
llvmlite/__pycache__/__init__.cpython-311.pyc,,
|
| 9 |
+
llvmlite/__pycache__/_version.cpython-311.pyc,,
|
| 10 |
+
llvmlite/__pycache__/utils.cpython-311.pyc,,
|
| 11 |
+
llvmlite/_version.py,sha256=fsnaBKvglYPJywrUAvzZsHhvixqEwJIDh0JKz4rwPtw,418
|
| 12 |
+
llvmlite/binding/__init__.py,sha256=zjhFN8Ucg5Y_14kwn1OEyiH_X-wEnzwS_WVmkPoSChk,382
|
| 13 |
+
llvmlite/binding/__pycache__/__init__.cpython-311.pyc,,
|
| 14 |
+
llvmlite/binding/__pycache__/analysis.cpython-311.pyc,,
|
| 15 |
+
llvmlite/binding/__pycache__/common.cpython-311.pyc,,
|
| 16 |
+
llvmlite/binding/__pycache__/context.cpython-311.pyc,,
|
| 17 |
+
llvmlite/binding/__pycache__/dylib.cpython-311.pyc,,
|
| 18 |
+
llvmlite/binding/__pycache__/executionengine.cpython-311.pyc,,
|
| 19 |
+
llvmlite/binding/__pycache__/ffi.cpython-311.pyc,,
|
| 20 |
+
llvmlite/binding/__pycache__/initfini.cpython-311.pyc,,
|
| 21 |
+
llvmlite/binding/__pycache__/linker.cpython-311.pyc,,
|
| 22 |
+
llvmlite/binding/__pycache__/module.cpython-311.pyc,,
|
| 23 |
+
llvmlite/binding/__pycache__/object_file.cpython-311.pyc,,
|
| 24 |
+
llvmlite/binding/__pycache__/options.cpython-311.pyc,,
|
| 25 |
+
llvmlite/binding/__pycache__/orcjit.cpython-311.pyc,,
|
| 26 |
+
llvmlite/binding/__pycache__/passmanagers.cpython-311.pyc,,
|
| 27 |
+
llvmlite/binding/__pycache__/targets.cpython-311.pyc,,
|
| 28 |
+
llvmlite/binding/__pycache__/transforms.cpython-311.pyc,,
|
| 29 |
+
llvmlite/binding/__pycache__/value.cpython-311.pyc,,
|
| 30 |
+
llvmlite/binding/analysis.py,sha256=BbCcAAGY0GLAEUek6ZogHkBAmFA9kvpS7333XyIrbhc,2253
|
| 31 |
+
llvmlite/binding/common.py,sha256=eCSnnY4sctgeqVwDv9PrH6jpMI45nJPmAz4rfjbPsf8,742
|
| 32 |
+
llvmlite/binding/context.py,sha256=l2vdKsJ038PfSKzaU17FCSDYWtByzIFYREmx93JwKW8,657
|
| 33 |
+
llvmlite/binding/dylib.py,sha256=ypfikOYKiWQZi8h00LhLBXwmPlJ5d86yLOUn01pDjmM,1300
|
| 34 |
+
llvmlite/binding/executionengine.py,sha256=rJrBP9n0Hm-lo53KRoRssFBLS8XOuIoAp_XWetiesS4,10713
|
| 35 |
+
llvmlite/binding/ffi.py,sha256=bQB6yudHJTlCGaCsnvrhNgWQzJYcvxwvULAo53j3oe4,11950
|
| 36 |
+
llvmlite/binding/initfini.py,sha256=zF9tJXmCONabkP0d_IqmiU6M_Wn8N8ArkwfXBxf1TDo,1595
|
| 37 |
+
llvmlite/binding/libllvmlite.dylib,sha256=M1fMZuZYLPJYUM6bH3EMvkFg-HGpDIu-ls_Yf-hX6jA,91363294
|
| 38 |
+
llvmlite/binding/linker.py,sha256=M4bAkoxVAUgxqai5S0_iCHS5EcNRPBX_9zldVqFLV90,489
|
| 39 |
+
llvmlite/binding/module.py,sha256=Zf9GcuCEFf1xtOmP-jXqKtJbj4dO8l9a2NEPKTwsimI,11174
|
| 40 |
+
llvmlite/binding/object_file.py,sha256=qZMTAi6gcVQq2e3KghHNxVH3Ivzr7zxDPecfiZ1Riy8,2664
|
| 41 |
+
llvmlite/binding/options.py,sha256=aDH4SFh6VZ11agtUJO9vAxhVhQkIGAByK9IHKeuRcAI,509
|
| 42 |
+
llvmlite/binding/orcjit.py,sha256=HUWDKicxrYK5s2trdrM_KEmkfvwifrP4E9MxmCb8JSM,11856
|
| 43 |
+
llvmlite/binding/passmanagers.py,sha256=zfn-iP-vi5j_1s8JPAnZjPpcahhz1IL98tSdZKCw40s,34412
|
| 44 |
+
llvmlite/binding/targets.py,sha256=5nxDn73pK_ElQu86EU994Qcd-k5Ja2U127T_oLrW_kk,14802
|
| 45 |
+
llvmlite/binding/transforms.py,sha256=C_Tp0XPV__aOHaVzLLL_QFa-yI9vkDx1gwZADk_KwG8,4947
|
| 46 |
+
llvmlite/binding/value.py,sha256=21-PwkBgAl26g0sqP2mI_lckSIDvq_LkgoLmzJE_8K4,18845
|
| 47 |
+
llvmlite/ir/__init__.py,sha256=rNPtrPLshsPJYO4GegWAU-rpbpiYo0xU-CQb3rt0JtE,258
|
| 48 |
+
llvmlite/ir/__pycache__/__init__.cpython-311.pyc,,
|
| 49 |
+
llvmlite/ir/__pycache__/_utils.cpython-311.pyc,,
|
| 50 |
+
llvmlite/ir/__pycache__/builder.cpython-311.pyc,,
|
| 51 |
+
llvmlite/ir/__pycache__/context.cpython-311.pyc,,
|
| 52 |
+
llvmlite/ir/__pycache__/instructions.cpython-311.pyc,,
|
| 53 |
+
llvmlite/ir/__pycache__/module.cpython-311.pyc,,
|
| 54 |
+
llvmlite/ir/__pycache__/transforms.cpython-311.pyc,,
|
| 55 |
+
llvmlite/ir/__pycache__/types.cpython-311.pyc,,
|
| 56 |
+
llvmlite/ir/__pycache__/values.cpython-311.pyc,,
|
| 57 |
+
llvmlite/ir/_utils.py,sha256=mkpyEMlQ9nHMcWmBMBsJm4S16Y0BfvxBf5brsdMmKio,2001
|
| 58 |
+
llvmlite/ir/builder.py,sha256=t6ZCvkwXd1jmb-CGoTW12kLOSTnwjfS_eY9JJs6ij3g,33479
|
| 59 |
+
llvmlite/ir/context.py,sha256=npgEbox0MzChmH7nfHpTdSsN_G4zU-XrpGx5AIYwafk,518
|
| 60 |
+
llvmlite/ir/instructions.py,sha256=UbiK1Ja7JqZuEj0l6sm7-p-zgfu-fXEbhWqrQB43hbw,31753
|
| 61 |
+
llvmlite/ir/module.py,sha256=pfpAh-73WMLptKqwgARwZ7aLMHpm88AcJA2GPfGvyVM,9074
|
| 62 |
+
llvmlite/ir/transforms.py,sha256=pV79pB20m4N_HLmBEksw5VVP8cxyf7AYGDCbS1E7fOQ,1552
|
| 63 |
+
llvmlite/ir/types.py,sha256=2GX-PIx_jDvt4GIfHkqiEkrJI_gPQqSktOsku2UZTgQ,16149
|
| 64 |
+
llvmlite/ir/values.py,sha256=5YlGc90Yc7QuzDMcptoXmvfCjcAvhSk4fSnAwF1vSas,33987
|
| 65 |
+
llvmlite/tests/__init__.py,sha256=TBHEOsEq-9M9rF94nES2HxefA-7GYwNE00Y7gTkHrD8,1378
|
| 66 |
+
llvmlite/tests/__main__.py,sha256=10_On1rLj4CX1xsBJ9TbjULvNSp_K0qk9U1N6azUTUw,40
|
| 67 |
+
llvmlite/tests/__pycache__/__init__.cpython-311.pyc,,
|
| 68 |
+
llvmlite/tests/__pycache__/__main__.cpython-311.pyc,,
|
| 69 |
+
llvmlite/tests/__pycache__/customize.cpython-311.pyc,,
|
| 70 |
+
llvmlite/tests/__pycache__/refprune_proto.cpython-311.pyc,,
|
| 71 |
+
llvmlite/tests/__pycache__/test_binding.cpython-311.pyc,,
|
| 72 |
+
llvmlite/tests/__pycache__/test_ir.cpython-311.pyc,,
|
| 73 |
+
llvmlite/tests/__pycache__/test_refprune.cpython-311.pyc,,
|
| 74 |
+
llvmlite/tests/__pycache__/test_valuerepr.cpython-311.pyc,,
|
| 75 |
+
llvmlite/tests/customize.py,sha256=85Af1gyZ5rtXXI3qpeTc2DXMrgETjv7hrLN-73A7Fhg,13268
|
| 76 |
+
llvmlite/tests/refprune_proto.py,sha256=I5g0jWHYlsLCOX3Ct9-fA5_udLfkipzuBAsEkrNsFIk,8677
|
| 77 |
+
llvmlite/tests/test_binding.py,sha256=Pvz7WxlxK_awXEXDAV30O4zTJ4PWY1-4SWwrRIGKMmA,80827
|
| 78 |
+
llvmlite/tests/test_ir.py,sha256=tAE8Yruj8r1q6c8dk5I-oIJjnSVTADIwWGDKHUVUEo0,105472
|
| 79 |
+
llvmlite/tests/test_refprune.py,sha256=oyk3HBLCOMPyRG-bj-omO3Ec_1lI66S8iNgZwl81Zs0,14235
|
| 80 |
+
llvmlite/tests/test_valuerepr.py,sha256=57MaGznJUnqCf0etajnOCoBRue5-nmFTx1bds_5atlE,1989
|
| 81 |
+
llvmlite/utils.py,sha256=BwgrA2JaYaZiHRafshoZBHiYSBskJQMG_K2F2jbW2-w,695
|
lib/python3.11/site-packages/llvmlite-0.41.1.dist-info/WHEEL
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Wheel-Version: 1.0
|
| 2 |
+
Generator: bdist_wheel (0.41.2)
|
| 3 |
+
Root-Is-Purelib: false
|
| 4 |
+
Tag: cp311-cp311-macosx_11_0_arm64
|
| 5 |
+
|
lib/python3.11/site-packages/llvmlite-0.41.1.dist-info/top_level.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
llvmlite
|
lib/python3.11/site-packages/llvmlite/tests/__pycache__/customize.cpython-311.pyc
ADDED
|
Binary file (20.1 kB). View file
|
|
|
lib/python3.11/site-packages/llvmlite/tests/__pycache__/refprune_proto.cpython-311.pyc
ADDED
|
Binary file (12.9 kB). View file
|
|
|
lib/python3.11/site-packages/llvmlite/tests/__pycache__/test_binding.cpython-311.pyc
ADDED
|
Binary file (159 kB). View file
|
|
|
lib/python3.11/site-packages/llvmlite/tests/__pycache__/test_ir.cpython-311.pyc
ADDED
|
Binary file (197 kB). View file
|
|
|
lib/python3.11/site-packages/llvmlite/tests/__pycache__/test_refprune.cpython-311.pyc
ADDED
|
Binary file (22.9 kB). View file
|
|
|
lib/python3.11/site-packages/llvmlite/tests/__pycache__/test_valuerepr.cpython-311.pyc
ADDED
|
Binary file (5.32 kB). View file
|
|
|
lib/python3.11/site-packages/llvmlite/tests/customize.py
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# XXX Ripped off from numba.tests; we should factor it out somewhere?
|
| 2 |
+
|
| 3 |
+
import collections
|
| 4 |
+
import contextlib
|
| 5 |
+
import cProfile
|
| 6 |
+
from io import StringIO
|
| 7 |
+
import gc
|
| 8 |
+
import os
|
| 9 |
+
import multiprocessing
|
| 10 |
+
import sys
|
| 11 |
+
import time
|
| 12 |
+
import unittest
|
| 13 |
+
import warnings
|
| 14 |
+
from unittest import result, runner, signals
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
# "unittest.main" is really the TestProgram class!
|
| 18 |
+
# (defined in a module named itself "unittest.main"...)
|
| 19 |
+
|
| 20 |
+
class NumbaTestProgram(unittest.main):
|
| 21 |
+
"""
|
| 22 |
+
A TestProgram subclass adding the following options:
|
| 23 |
+
* a -R option to enable reference leak detection
|
| 24 |
+
* a --profile option to enable profiling of the test run
|
| 25 |
+
|
| 26 |
+
Currently the options are only added in 3.4+.
|
| 27 |
+
"""
|
| 28 |
+
|
| 29 |
+
refleak = False
|
| 30 |
+
profile = False
|
| 31 |
+
multiprocess = False
|
| 32 |
+
|
| 33 |
+
def __init__(self, *args, **kwargs):
|
| 34 |
+
self.discovered_suite = kwargs.pop('suite', None)
|
| 35 |
+
# HACK to force unittest not to change warning display options
|
| 36 |
+
# (so that NumbaWarnings don't appear all over the place)
|
| 37 |
+
sys.warnoptions.append(':x')
|
| 38 |
+
super(NumbaTestProgram, self).__init__(*args, **kwargs)
|
| 39 |
+
|
| 40 |
+
def createTests(self):
|
| 41 |
+
if self.discovered_suite is not None:
|
| 42 |
+
self.test = self.discovered_suite
|
| 43 |
+
else:
|
| 44 |
+
super(NumbaTestProgram, self).createTests()
|
| 45 |
+
|
| 46 |
+
def _getParentArgParser(self):
|
| 47 |
+
# NOTE: this hook only exists on Python 3.4+. The options won't be
|
| 48 |
+
# added in earlier versions (which use optparse - 3.3 - or getopt()
|
| 49 |
+
# - 2.x).
|
| 50 |
+
parser = super(NumbaTestProgram, self)._getParentArgParser()
|
| 51 |
+
if self.testRunner is None:
|
| 52 |
+
parser.add_argument('-R', '--refleak', dest='refleak',
|
| 53 |
+
action='store_true',
|
| 54 |
+
help='Detect reference / memory leaks')
|
| 55 |
+
parser.add_argument('-m', '--multiprocess', dest='multiprocess',
|
| 56 |
+
action='store_true',
|
| 57 |
+
help='Parallelize tests')
|
| 58 |
+
parser.add_argument('--profile', dest='profile',
|
| 59 |
+
action='store_true',
|
| 60 |
+
help='Profile the test run')
|
| 61 |
+
return parser
|
| 62 |
+
|
| 63 |
+
def parseArgs(self, argv):
|
| 64 |
+
if sys.version_info < (3, 4):
|
| 65 |
+
# We want these options to work on all versions, emulate them.
|
| 66 |
+
if '-R' in argv:
|
| 67 |
+
argv.remove('-R')
|
| 68 |
+
self.refleak = True
|
| 69 |
+
if '-m' in argv:
|
| 70 |
+
argv.remove('-m')
|
| 71 |
+
self.multiprocess = True
|
| 72 |
+
super(NumbaTestProgram, self).parseArgs(argv)
|
| 73 |
+
if self.verbosity <= 0:
|
| 74 |
+
# We aren't interested in informational messages / warnings when
|
| 75 |
+
# running with '-q'.
|
| 76 |
+
self.buffer = True
|
| 77 |
+
|
| 78 |
+
def runTests(self):
|
| 79 |
+
if self.refleak:
|
| 80 |
+
self.testRunner = RefleakTestRunner
|
| 81 |
+
|
| 82 |
+
if not hasattr(sys, "gettotalrefcount"):
|
| 83 |
+
warnings.warn("detecting reference leaks requires a debug "
|
| 84 |
+
"build of Python, only memory leaks will be "
|
| 85 |
+
"detected")
|
| 86 |
+
|
| 87 |
+
elif self.testRunner is None:
|
| 88 |
+
self.testRunner = unittest.TextTestRunner
|
| 89 |
+
|
| 90 |
+
if self.multiprocess:
|
| 91 |
+
self.testRunner = ParallelTestRunner(self.testRunner,
|
| 92 |
+
verbosity=self.verbosity,
|
| 93 |
+
failfast=self.failfast,
|
| 94 |
+
buffer=self.buffer)
|
| 95 |
+
|
| 96 |
+
def run_tests_real():
|
| 97 |
+
super(NumbaTestProgram, self).runTests()
|
| 98 |
+
|
| 99 |
+
if self.profile:
|
| 100 |
+
filename = os.path.splitext(
|
| 101 |
+
os.path.basename(sys.modules['__main__'].__file__)
|
| 102 |
+
)[0] + '.prof'
|
| 103 |
+
p = cProfile.Profile(timer=time.perf_counter) # 3.3+
|
| 104 |
+
p.enable()
|
| 105 |
+
try:
|
| 106 |
+
p.runcall(run_tests_real)
|
| 107 |
+
finally:
|
| 108 |
+
p.disable()
|
| 109 |
+
print("Writing test profile data into %r" % (filename,))
|
| 110 |
+
p.dump_stats(filename)
|
| 111 |
+
else:
|
| 112 |
+
run_tests_real()
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
# Monkey-patch unittest so that individual test modules get our custom
|
| 116 |
+
# options for free.
|
| 117 |
+
unittest.main = NumbaTestProgram
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
# The reference leak detection code is liberally taken and adapted from
|
| 121 |
+
# Python's own Lib/test/regrtest.py.
|
| 122 |
+
|
| 123 |
+
def _refleak_cleanup():
|
| 124 |
+
# Collect cyclic trash and read memory statistics immediately after.
|
| 125 |
+
try:
|
| 126 |
+
func1 = sys.getallocatedblocks
|
| 127 |
+
except AttributeError:
|
| 128 |
+
def func1():
|
| 129 |
+
return 42
|
| 130 |
+
try:
|
| 131 |
+
func2 = sys.gettotalrefcount
|
| 132 |
+
except AttributeError:
|
| 133 |
+
def func2():
|
| 134 |
+
return 42
|
| 135 |
+
|
| 136 |
+
# Flush standard output, so that buffered data is sent to the OS and
|
| 137 |
+
# associated Python objects are reclaimed.
|
| 138 |
+
for stream in (sys.stdout, sys.stderr, sys.__stdout__, sys.__stderr__):
|
| 139 |
+
if stream is not None:
|
| 140 |
+
stream.flush()
|
| 141 |
+
|
| 142 |
+
sys._clear_type_cache()
|
| 143 |
+
# This also clears the various internal CPython freelists.
|
| 144 |
+
gc.collect()
|
| 145 |
+
return func1(), func2()
|
| 146 |
+
|
| 147 |
+
|
| 148 |
+
class ReferenceLeakError(RuntimeError):
|
| 149 |
+
pass
|
| 150 |
+
|
| 151 |
+
|
| 152 |
+
class IntPool(collections.defaultdict):
|
| 153 |
+
|
| 154 |
+
def __missing__(self, key):
|
| 155 |
+
return key
|
| 156 |
+
|
| 157 |
+
|
| 158 |
+
class RefleakTestResult(runner.TextTestResult):
|
| 159 |
+
|
| 160 |
+
warmup = 3
|
| 161 |
+
repetitions = 6
|
| 162 |
+
|
| 163 |
+
def _huntLeaks(self, test):
|
| 164 |
+
self.stream.flush()
|
| 165 |
+
|
| 166 |
+
repcount = self.repetitions
|
| 167 |
+
nwarmup = self.warmup
|
| 168 |
+
rc_deltas = [0] * (repcount - nwarmup)
|
| 169 |
+
alloc_deltas = [0] * (repcount - nwarmup)
|
| 170 |
+
# Preallocate ints likely to be stored in rc_deltas and alloc_deltas,
|
| 171 |
+
# to make sys.getallocatedblocks() less flaky.
|
| 172 |
+
_int_pool = IntPool()
|
| 173 |
+
for i in range(-200, 200):
|
| 174 |
+
_int_pool[i]
|
| 175 |
+
|
| 176 |
+
alloc_before = rc_before = 0
|
| 177 |
+
for i in range(repcount):
|
| 178 |
+
# Use a pristine, silent result object to avoid recursion
|
| 179 |
+
res = result.TestResult()
|
| 180 |
+
test.run(res)
|
| 181 |
+
# Poorly-written tests may fail when run several times.
|
| 182 |
+
# In this case, abort the refleak run and report the failure.
|
| 183 |
+
if not res.wasSuccessful():
|
| 184 |
+
self.failures.extend(res.failures)
|
| 185 |
+
self.errors.extend(res.errors)
|
| 186 |
+
raise AssertionError
|
| 187 |
+
del res
|
| 188 |
+
alloc_after, rc_after = _refleak_cleanup()
|
| 189 |
+
if i >= nwarmup:
|
| 190 |
+
rc_deltas[i - nwarmup] = _int_pool[rc_after - rc_before]
|
| 191 |
+
alloc_deltas[i -
|
| 192 |
+
nwarmup] = _int_pool[alloc_after -
|
| 193 |
+
alloc_before]
|
| 194 |
+
alloc_before, rc_before = alloc_after, rc_after
|
| 195 |
+
return rc_deltas, alloc_deltas
|
| 196 |
+
|
| 197 |
+
def addSuccess(self, test):
|
| 198 |
+
try:
|
| 199 |
+
rc_deltas, alloc_deltas = self._huntLeaks(test)
|
| 200 |
+
except AssertionError:
|
| 201 |
+
# Test failed when repeated
|
| 202 |
+
assert not self.wasSuccessful()
|
| 203 |
+
return
|
| 204 |
+
|
| 205 |
+
# These checkers return False on success, True on failure
|
| 206 |
+
def check_rc_deltas(deltas):
|
| 207 |
+
return any(deltas)
|
| 208 |
+
|
| 209 |
+
def check_alloc_deltas(deltas):
|
| 210 |
+
# At least 1/3rd of 0s
|
| 211 |
+
if 3 * deltas.count(0) < len(deltas):
|
| 212 |
+
return True
|
| 213 |
+
# Nothing else than 1s, 0s and -1s
|
| 214 |
+
if not set(deltas) <= set((1, 0, -1)):
|
| 215 |
+
return True
|
| 216 |
+
return False
|
| 217 |
+
|
| 218 |
+
failed = False
|
| 219 |
+
|
| 220 |
+
for deltas, item_name, checker in [
|
| 221 |
+
(rc_deltas, 'references', check_rc_deltas),
|
| 222 |
+
(alloc_deltas, 'memory blocks', check_alloc_deltas)]:
|
| 223 |
+
if checker(deltas):
|
| 224 |
+
msg = '%s leaked %s %s, sum=%s' % (
|
| 225 |
+
test, deltas, item_name, sum(deltas))
|
| 226 |
+
failed = True
|
| 227 |
+
try:
|
| 228 |
+
raise ReferenceLeakError(msg)
|
| 229 |
+
except Exception:
|
| 230 |
+
exc_info = sys.exc_info()
|
| 231 |
+
if self.showAll:
|
| 232 |
+
self.stream.write("%s = %r " % (item_name, deltas))
|
| 233 |
+
self.addFailure(test, exc_info)
|
| 234 |
+
|
| 235 |
+
if not failed:
|
| 236 |
+
super(RefleakTestResult, self).addSuccess(test)
|
| 237 |
+
|
| 238 |
+
|
| 239 |
+
class RefleakTestRunner(runner.TextTestRunner):
|
| 240 |
+
resultclass = RefleakTestResult
|
| 241 |
+
|
| 242 |
+
|
| 243 |
+
def _flatten_suite(test):
|
| 244 |
+
"""Expand suite into list of tests
|
| 245 |
+
"""
|
| 246 |
+
if isinstance(test, unittest.TestSuite):
|
| 247 |
+
tests = []
|
| 248 |
+
for x in test:
|
| 249 |
+
tests.extend(_flatten_suite(x))
|
| 250 |
+
return tests
|
| 251 |
+
else:
|
| 252 |
+
return [test]
|
| 253 |
+
|
| 254 |
+
|
| 255 |
+
class ParallelTestResult(runner.TextTestResult):
|
| 256 |
+
"""
|
| 257 |
+
A TestResult able to inject results from other results.
|
| 258 |
+
"""
|
| 259 |
+
|
| 260 |
+
def add_results(self, result):
|
| 261 |
+
"""
|
| 262 |
+
Add the results from the other *result* to this result.
|
| 263 |
+
"""
|
| 264 |
+
self.stream.write(result.stream.getvalue())
|
| 265 |
+
self.stream.flush()
|
| 266 |
+
self.testsRun += result.testsRun
|
| 267 |
+
self.failures.extend(result.failures)
|
| 268 |
+
self.errors.extend(result.errors)
|
| 269 |
+
self.skipped.extend(result.skipped)
|
| 270 |
+
self.expectedFailures.extend(result.expectedFailures)
|
| 271 |
+
self.unexpectedSuccesses.extend(result.unexpectedSuccesses)
|
| 272 |
+
|
| 273 |
+
|
| 274 |
+
class _MinimalResult(object):
|
| 275 |
+
"""
|
| 276 |
+
A minimal, picklable TestResult-alike object.
|
| 277 |
+
"""
|
| 278 |
+
|
| 279 |
+
__slots__ = (
|
| 280 |
+
'failures', 'errors', 'skipped', 'expectedFailures',
|
| 281 |
+
'unexpectedSuccesses', 'stream', 'shouldStop', 'testsRun')
|
| 282 |
+
|
| 283 |
+
def fixup_case(self, case):
|
| 284 |
+
"""
|
| 285 |
+
Remove any unpicklable attributes from TestCase instance *case*.
|
| 286 |
+
"""
|
| 287 |
+
# Python 3.3 doesn't reset this one.
|
| 288 |
+
case._outcomeForDoCleanups = None
|
| 289 |
+
|
| 290 |
+
def __init__(self, original_result):
|
| 291 |
+
for attr in self.__slots__:
|
| 292 |
+
setattr(self, attr, getattr(original_result, attr))
|
| 293 |
+
for case, _ in self.expectedFailures:
|
| 294 |
+
self.fixup_case(case)
|
| 295 |
+
for case, _ in self.errors:
|
| 296 |
+
self.fixup_case(case)
|
| 297 |
+
for case, _ in self.failures:
|
| 298 |
+
self.fixup_case(case)
|
| 299 |
+
|
| 300 |
+
|
| 301 |
+
class _FakeStringIO(object):
|
| 302 |
+
"""
|
| 303 |
+
A trivial picklable StringIO-alike for Python 2.
|
| 304 |
+
"""
|
| 305 |
+
|
| 306 |
+
def __init__(self, value):
|
| 307 |
+
self._value = value
|
| 308 |
+
|
| 309 |
+
def getvalue(self):
|
| 310 |
+
return self._value
|
| 311 |
+
|
| 312 |
+
|
| 313 |
+
class _MinimalRunner(object):
|
| 314 |
+
"""
|
| 315 |
+
A minimal picklable object able to instantiate a runner in a
|
| 316 |
+
child process and run a test case with it.
|
| 317 |
+
"""
|
| 318 |
+
|
| 319 |
+
def __init__(self, runner_cls, runner_args):
|
| 320 |
+
self.runner_cls = runner_cls
|
| 321 |
+
self.runner_args = runner_args
|
| 322 |
+
|
| 323 |
+
# Python 2 doesn't know how to pickle instance methods, so we use __call__
|
| 324 |
+
# instead.
|
| 325 |
+
|
| 326 |
+
def __call__(self, test):
|
| 327 |
+
# Executed in child process
|
| 328 |
+
kwargs = self.runner_args
|
| 329 |
+
# Force recording of output in a buffer (it will be printed out
|
| 330 |
+
# by the parent).
|
| 331 |
+
kwargs['stream'] = StringIO()
|
| 332 |
+
runner = self.runner_cls(**kwargs)
|
| 333 |
+
result = runner._makeResult()
|
| 334 |
+
# Avoid child tracebacks when Ctrl-C is pressed.
|
| 335 |
+
signals.installHandler()
|
| 336 |
+
signals.registerResult(result)
|
| 337 |
+
result.failfast = runner.failfast
|
| 338 |
+
result.buffer = runner.buffer
|
| 339 |
+
with self.cleanup_object(test):
|
| 340 |
+
test(result)
|
| 341 |
+
# HACK as cStringIO.StringIO isn't picklable in 2.x
|
| 342 |
+
result.stream = _FakeStringIO(result.stream.getvalue())
|
| 343 |
+
return _MinimalResult(result)
|
| 344 |
+
|
| 345 |
+
@contextlib.contextmanager
|
| 346 |
+
def cleanup_object(self, test):
|
| 347 |
+
"""
|
| 348 |
+
A context manager which cleans up unwanted attributes on a test case
|
| 349 |
+
(or any other object).
|
| 350 |
+
"""
|
| 351 |
+
vanilla_attrs = set(test.__dict__)
|
| 352 |
+
try:
|
| 353 |
+
yield test
|
| 354 |
+
finally:
|
| 355 |
+
spurious_attrs = set(test.__dict__) - vanilla_attrs
|
| 356 |
+
for name in spurious_attrs:
|
| 357 |
+
del test.__dict__[name]
|
| 358 |
+
|
| 359 |
+
|
| 360 |
+
class ParallelTestRunner(runner.TextTestRunner):
|
| 361 |
+
"""
|
| 362 |
+
A test runner which delegates the actual running to a pool of child
|
| 363 |
+
processes.
|
| 364 |
+
"""
|
| 365 |
+
|
| 366 |
+
resultclass = ParallelTestResult
|
| 367 |
+
|
| 368 |
+
def __init__(self, runner_cls, **kwargs):
|
| 369 |
+
runner.TextTestRunner.__init__(self, **kwargs)
|
| 370 |
+
self.runner_cls = runner_cls
|
| 371 |
+
self.runner_args = kwargs
|
| 372 |
+
|
| 373 |
+
def _run_inner(self, result):
|
| 374 |
+
# We hijack TextTestRunner.run()'s inner logic by passing this
|
| 375 |
+
# method as if it were a test case.
|
| 376 |
+
child_runner = _MinimalRunner(self.runner_cls, self.runner_args)
|
| 377 |
+
pool = multiprocessing.Pool()
|
| 378 |
+
imap = pool.imap_unordered
|
| 379 |
+
try:
|
| 380 |
+
for child_result in imap(child_runner, self._test_list):
|
| 381 |
+
result.add_results(child_result)
|
| 382 |
+
if child_result.shouldStop:
|
| 383 |
+
break
|
| 384 |
+
return result
|
| 385 |
+
finally:
|
| 386 |
+
# Kill the still active workers
|
| 387 |
+
pool.terminate()
|
| 388 |
+
pool.join()
|
| 389 |
+
|
| 390 |
+
def run(self, test):
|
| 391 |
+
self._test_list = _flatten_suite(test)
|
| 392 |
+
# This will call self._run_inner() on the created result object,
|
| 393 |
+
# and print out the detailed test results at the end.
|
| 394 |
+
return super(ParallelTestRunner, self).run(self._run_inner)
|
| 395 |
+
|
| 396 |
+
|
| 397 |
+
try:
|
| 398 |
+
import faulthandler
|
| 399 |
+
except ImportError:
|
| 400 |
+
pass
|
| 401 |
+
else:
|
| 402 |
+
try:
|
| 403 |
+
# May fail in IPython Notebook with UnsupportedOperation
|
| 404 |
+
faulthandler.enable()
|
| 405 |
+
except BaseException as e:
|
| 406 |
+
msg = "Failed to enable faulthandler due to:\n{err}"
|
| 407 |
+
warnings.warn(msg.format(err=e))
|
lib/python3.11/site-packages/llvmlite/tests/refprune_proto.py
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Contains tests and a prototype implementation for the fanout algorithm in
|
| 3 |
+
the LLVM refprune pass.
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
try:
|
| 7 |
+
from graphviz import Digraph
|
| 8 |
+
except ImportError:
|
| 9 |
+
pass
|
| 10 |
+
from collections import defaultdict
|
| 11 |
+
|
| 12 |
+
# The entry block. It's always the same.
|
| 13 |
+
ENTRY = "A"
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
# The following caseNN() functions returns a 3-tuple of
|
| 17 |
+
# (nodes, edges, expected).
|
| 18 |
+
# `nodes` maps BB nodes to incref/decref inside the block.
|
| 19 |
+
# `edges` maps BB nodes to their successor BB.
|
| 20 |
+
# `expected` maps BB-node with incref to a set of BB-nodes with the decrefs, or
|
| 21 |
+
# the value can be None, indicating invalid prune.
|
| 22 |
+
|
| 23 |
+
def case1():
|
| 24 |
+
edges = {
|
| 25 |
+
"A": ["B"],
|
| 26 |
+
"B": ["C", "D"],
|
| 27 |
+
"C": [],
|
| 28 |
+
"D": ["E", "F"],
|
| 29 |
+
"E": ["G"],
|
| 30 |
+
"F": [],
|
| 31 |
+
"G": ["H", "I"],
|
| 32 |
+
"I": ["G", "F"],
|
| 33 |
+
"H": ["J", "K"],
|
| 34 |
+
"J": ["L", "M"],
|
| 35 |
+
"K": [],
|
| 36 |
+
"L": ["Z"],
|
| 37 |
+
"M": ["Z", "O", "P"],
|
| 38 |
+
"O": ["Z"],
|
| 39 |
+
"P": ["Z"],
|
| 40 |
+
"Z": [],
|
| 41 |
+
}
|
| 42 |
+
nodes = defaultdict(list)
|
| 43 |
+
nodes["D"] = ["incref"]
|
| 44 |
+
nodes["H"] = ["decref"]
|
| 45 |
+
nodes["F"] = ["decref", "decref"]
|
| 46 |
+
expected = {"D": {"H", "F"}}
|
| 47 |
+
return nodes, edges, expected
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def case2():
|
| 51 |
+
edges = {
|
| 52 |
+
"A": ["B", "C"],
|
| 53 |
+
"B": ["C"],
|
| 54 |
+
"C": [],
|
| 55 |
+
}
|
| 56 |
+
nodes = defaultdict(list)
|
| 57 |
+
nodes["A"] = ["incref"]
|
| 58 |
+
nodes["B"] = ["decref"]
|
| 59 |
+
nodes["C"] = ["decref"]
|
| 60 |
+
expected = {"A": None}
|
| 61 |
+
return nodes, edges, expected
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
def case3():
|
| 65 |
+
nodes, edges, _ = case1()
|
| 66 |
+
# adds an invalid edge
|
| 67 |
+
edges["H"].append("F")
|
| 68 |
+
expected = {"D": None}
|
| 69 |
+
return nodes, edges, expected
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def case4():
|
| 73 |
+
nodes, edges, _ = case1()
|
| 74 |
+
# adds an invalid edge
|
| 75 |
+
edges["H"].append("E")
|
| 76 |
+
expected = {"D": None}
|
| 77 |
+
return nodes, edges, expected
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def case5():
|
| 81 |
+
nodes, edges, _ = case1()
|
| 82 |
+
# adds backedge to go before incref
|
| 83 |
+
edges["B"].append("I")
|
| 84 |
+
expected = {"D": None}
|
| 85 |
+
return nodes, edges, expected
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def case6():
|
| 89 |
+
nodes, edges, _ = case1()
|
| 90 |
+
# adds backedge to go before incref
|
| 91 |
+
edges["I"].append("B")
|
| 92 |
+
expected = {"D": None}
|
| 93 |
+
return nodes, edges, expected
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
def case7():
|
| 97 |
+
nodes, edges, _ = case1()
|
| 98 |
+
# adds forward jump outside
|
| 99 |
+
edges["I"].append("M")
|
| 100 |
+
expected = {"D": None}
|
| 101 |
+
return nodes, edges, expected
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
def case8():
|
| 105 |
+
edges = {
|
| 106 |
+
"A": ["B", "C"],
|
| 107 |
+
"B": ["C"],
|
| 108 |
+
"C": [],
|
| 109 |
+
}
|
| 110 |
+
nodes = defaultdict(list)
|
| 111 |
+
nodes["A"] = ["incref"]
|
| 112 |
+
nodes["C"] = ["decref"]
|
| 113 |
+
expected = {"A": {"C"}}
|
| 114 |
+
return nodes, edges, expected
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
def case9():
|
| 118 |
+
nodes, edges, _ = case8()
|
| 119 |
+
# adds back edge
|
| 120 |
+
edges["C"].append("B")
|
| 121 |
+
expected = {"A": None}
|
| 122 |
+
return nodes, edges, expected
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
def case10():
|
| 126 |
+
nodes, edges, _ = case8()
|
| 127 |
+
# adds back edge to A
|
| 128 |
+
edges["C"].append("A")
|
| 129 |
+
expected = {"A": {"C"}}
|
| 130 |
+
return nodes, edges, expected
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
def case11():
|
| 134 |
+
nodes, edges, _ = case8()
|
| 135 |
+
edges["C"].append("D")
|
| 136 |
+
edges["D"] = []
|
| 137 |
+
expected = {"A": {"C"}}
|
| 138 |
+
return nodes, edges, expected
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
def case12():
|
| 142 |
+
nodes, edges, _ = case8()
|
| 143 |
+
edges["C"].append("D")
|
| 144 |
+
edges["D"] = ["A"]
|
| 145 |
+
expected = {"A": {"C"}}
|
| 146 |
+
return nodes, edges, expected
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
def case13():
|
| 150 |
+
nodes, edges, _ = case8()
|
| 151 |
+
edges["C"].append("D")
|
| 152 |
+
edges["D"] = ["B"]
|
| 153 |
+
expected = {"A": None}
|
| 154 |
+
return nodes, edges, expected
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
def make_predecessor_map(edges):
|
| 158 |
+
d = defaultdict(set)
|
| 159 |
+
for src, outgoings in edges.items():
|
| 160 |
+
for dst in outgoings:
|
| 161 |
+
d[dst].add(src)
|
| 162 |
+
return d
|
| 163 |
+
|
| 164 |
+
|
| 165 |
+
class FanoutAlgorithm:
|
| 166 |
+
def __init__(self, nodes, edges, verbose=False):
|
| 167 |
+
self.nodes = nodes
|
| 168 |
+
self.edges = edges
|
| 169 |
+
self.rev_edges = make_predecessor_map(edges)
|
| 170 |
+
self.print = print if verbose else self._null_print
|
| 171 |
+
|
| 172 |
+
def run(self):
|
| 173 |
+
return self.find_fanout_in_function()
|
| 174 |
+
|
| 175 |
+
def _null_print(self, *args, **kwargs):
|
| 176 |
+
pass
|
| 177 |
+
|
| 178 |
+
def find_fanout_in_function(self):
|
| 179 |
+
got = {}
|
| 180 |
+
for cur_node in self.edges:
|
| 181 |
+
for incref in (x for x in self.nodes[cur_node] if x == "incref"):
|
| 182 |
+
decref_blocks = self.find_fanout(cur_node)
|
| 183 |
+
self.print(">>", cur_node, "===", decref_blocks)
|
| 184 |
+
got[cur_node] = decref_blocks
|
| 185 |
+
return got
|
| 186 |
+
|
| 187 |
+
def find_fanout(self, head_node):
|
| 188 |
+
decref_blocks = self.find_decref_candidates(head_node)
|
| 189 |
+
self.print("candidates", decref_blocks)
|
| 190 |
+
if not decref_blocks:
|
| 191 |
+
return None
|
| 192 |
+
if not self.verify_non_overlapping(
|
| 193 |
+
head_node, decref_blocks, entry=ENTRY
|
| 194 |
+
):
|
| 195 |
+
return None
|
| 196 |
+
return set(decref_blocks)
|
| 197 |
+
|
| 198 |
+
def verify_non_overlapping(self, head_node, decref_blocks, entry):
|
| 199 |
+
self.print("verify_non_overlapping".center(80, "-"))
|
| 200 |
+
# reverse walk for each decref_blocks
|
| 201 |
+
# they should end at head_node
|
| 202 |
+
todo = list(decref_blocks)
|
| 203 |
+
while todo:
|
| 204 |
+
cur_node = todo.pop()
|
| 205 |
+
visited = set()
|
| 206 |
+
|
| 207 |
+
workstack = [cur_node]
|
| 208 |
+
del cur_node
|
| 209 |
+
while workstack:
|
| 210 |
+
cur_node = workstack.pop()
|
| 211 |
+
self.print("cur_node", cur_node, "|", workstack)
|
| 212 |
+
if cur_node in visited:
|
| 213 |
+
continue # skip
|
| 214 |
+
if cur_node == entry:
|
| 215 |
+
# Entry node
|
| 216 |
+
self.print(
|
| 217 |
+
"!! failed because we arrived at entry", cur_node
|
| 218 |
+
)
|
| 219 |
+
return False
|
| 220 |
+
visited.add(cur_node)
|
| 221 |
+
# check all predecessors
|
| 222 |
+
self.print(
|
| 223 |
+
f" {cur_node} preds {self.get_predecessors(cur_node)}"
|
| 224 |
+
)
|
| 225 |
+
for pred in self.get_predecessors(cur_node):
|
| 226 |
+
if pred in decref_blocks:
|
| 227 |
+
# reject because there's a predecessor in decref_blocks
|
| 228 |
+
self.print(
|
| 229 |
+
"!! reject because predecessor in decref_blocks"
|
| 230 |
+
)
|
| 231 |
+
return False
|
| 232 |
+
if pred != head_node:
|
| 233 |
+
|
| 234 |
+
workstack.append(pred)
|
| 235 |
+
|
| 236 |
+
return True
|
| 237 |
+
|
| 238 |
+
def get_successors(self, node):
|
| 239 |
+
return tuple(self.edges[node])
|
| 240 |
+
|
| 241 |
+
def get_predecessors(self, node):
|
| 242 |
+
return tuple(self.rev_edges[node])
|
| 243 |
+
|
| 244 |
+
def has_decref(self, node):
|
| 245 |
+
return "decref" in self.nodes[node]
|
| 246 |
+
|
| 247 |
+
def walk_child_for_decref(
|
| 248 |
+
self, cur_node, path_stack, decref_blocks, depth=10
|
| 249 |
+
):
|
| 250 |
+
indent = " " * len(path_stack)
|
| 251 |
+
self.print(indent, "walk", path_stack, cur_node)
|
| 252 |
+
if depth <= 0:
|
| 253 |
+
return False # missing
|
| 254 |
+
if cur_node in path_stack:
|
| 255 |
+
if cur_node == path_stack[0]:
|
| 256 |
+
return False # reject interior node backedge
|
| 257 |
+
return True # skip
|
| 258 |
+
if self.has_decref(cur_node):
|
| 259 |
+
decref_blocks.add(cur_node)
|
| 260 |
+
self.print(indent, "found decref")
|
| 261 |
+
return True
|
| 262 |
+
|
| 263 |
+
depth -= 1
|
| 264 |
+
path_stack += (cur_node,)
|
| 265 |
+
found = False
|
| 266 |
+
for child in self.get_successors(cur_node):
|
| 267 |
+
if not self.walk_child_for_decref(
|
| 268 |
+
child, path_stack, decref_blocks
|
| 269 |
+
):
|
| 270 |
+
found = False
|
| 271 |
+
break
|
| 272 |
+
else:
|
| 273 |
+
found = True
|
| 274 |
+
|
| 275 |
+
self.print(indent, f"ret {found}")
|
| 276 |
+
return found
|
| 277 |
+
|
| 278 |
+
def find_decref_candidates(self, cur_node):
|
| 279 |
+
# Forward pass
|
| 280 |
+
self.print("find_decref_candidates".center(80, "-"))
|
| 281 |
+
path_stack = (cur_node,)
|
| 282 |
+
found = False
|
| 283 |
+
decref_blocks = set()
|
| 284 |
+
for child in self.get_successors(cur_node):
|
| 285 |
+
if not self.walk_child_for_decref(
|
| 286 |
+
child, path_stack, decref_blocks
|
| 287 |
+
):
|
| 288 |
+
found = False
|
| 289 |
+
break
|
| 290 |
+
else:
|
| 291 |
+
found = True
|
| 292 |
+
if not found:
|
| 293 |
+
return set()
|
| 294 |
+
else:
|
| 295 |
+
return decref_blocks
|
| 296 |
+
|
| 297 |
+
|
| 298 |
+
def check_once():
|
| 299 |
+
nodes, edges, expected = case13()
|
| 300 |
+
|
| 301 |
+
# Render graph
|
| 302 |
+
G = Digraph()
|
| 303 |
+
for node in edges:
|
| 304 |
+
G.node(node, shape="rect", label=f"{node}\n" + r"\l".join(nodes[node]))
|
| 305 |
+
for node, children in edges.items():
|
| 306 |
+
for child in children:
|
| 307 |
+
G.edge(node, child)
|
| 308 |
+
|
| 309 |
+
G.view()
|
| 310 |
+
|
| 311 |
+
algo = FanoutAlgorithm(nodes, edges, verbose=True)
|
| 312 |
+
got = algo.run()
|
| 313 |
+
assert expected == got
|
| 314 |
+
|
| 315 |
+
|
| 316 |
+
def check_all():
|
| 317 |
+
for k, fn in list(globals().items()):
|
| 318 |
+
if k.startswith("case"):
|
| 319 |
+
print(f"{fn}".center(80, "-"))
|
| 320 |
+
nodes, edges, expected = fn()
|
| 321 |
+
algo = FanoutAlgorithm(nodes, edges)
|
| 322 |
+
got = algo.run()
|
| 323 |
+
assert expected == got
|
| 324 |
+
print("ALL PASSED")
|
| 325 |
+
|
| 326 |
+
|
| 327 |
+
if __name__ == "__main__":
|
| 328 |
+
# check_once()
|
| 329 |
+
check_all()
|
lib/python3.11/site-packages/llvmlite/tests/test_binding.py
ADDED
|
@@ -0,0 +1,2431 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import ctypes
|
| 2 |
+
import threading
|
| 3 |
+
from ctypes import CFUNCTYPE, c_int, c_int32
|
| 4 |
+
from ctypes.util import find_library
|
| 5 |
+
import gc
|
| 6 |
+
import locale
|
| 7 |
+
import os
|
| 8 |
+
import platform
|
| 9 |
+
import re
|
| 10 |
+
import subprocess
|
| 11 |
+
import sys
|
| 12 |
+
import unittest
|
| 13 |
+
from contextlib import contextmanager
|
| 14 |
+
from tempfile import mkstemp
|
| 15 |
+
|
| 16 |
+
from llvmlite import ir
|
| 17 |
+
from llvmlite import binding as llvm
|
| 18 |
+
from llvmlite.binding import ffi
|
| 19 |
+
from llvmlite.tests import TestCase
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
# arvm7l needs extra ABI symbols to link successfully
|
| 23 |
+
if platform.machine() == 'armv7l':
|
| 24 |
+
llvm.load_library_permanently('libgcc_s.so.1')
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def no_de_locale():
|
| 28 |
+
cur = locale.setlocale(locale.LC_ALL)
|
| 29 |
+
try:
|
| 30 |
+
locale.setlocale(locale.LC_ALL, 'de_DE')
|
| 31 |
+
except locale.Error:
|
| 32 |
+
return True
|
| 33 |
+
else:
|
| 34 |
+
return False
|
| 35 |
+
finally:
|
| 36 |
+
locale.setlocale(locale.LC_ALL, cur)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
asm_sum = r"""
|
| 40 |
+
; ModuleID = '<string>'
|
| 41 |
+
source_filename = "asm_sum.c"
|
| 42 |
+
target triple = "{triple}"
|
| 43 |
+
%struct.glob_type = type {{ i64, [2 x i64]}}
|
| 44 |
+
|
| 45 |
+
@glob = global i32 0
|
| 46 |
+
@glob_b = global i8 0
|
| 47 |
+
@glob_f = global float 1.5
|
| 48 |
+
@glob_struct = global %struct.glob_type {{i64 0, [2 x i64] [i64 0, i64 0]}}
|
| 49 |
+
|
| 50 |
+
define i32 @sum(i32 %.1, i32 %.2) {{
|
| 51 |
+
%.3 = add i32 %.1, %.2
|
| 52 |
+
%.4 = add i32 0, %.3
|
| 53 |
+
ret i32 %.4
|
| 54 |
+
}}
|
| 55 |
+
"""
|
| 56 |
+
|
| 57 |
+
asm_sum2 = r"""
|
| 58 |
+
; ModuleID = '<string>'
|
| 59 |
+
target triple = "{triple}"
|
| 60 |
+
|
| 61 |
+
define i32 @sum(i32 %.1, i32 %.2) {{
|
| 62 |
+
%.3 = add i32 %.1, %.2
|
| 63 |
+
ret i32 %.3
|
| 64 |
+
}}
|
| 65 |
+
"""
|
| 66 |
+
|
| 67 |
+
asm_sum3 = r"""
|
| 68 |
+
; ModuleID = '<string>'
|
| 69 |
+
target triple = "{triple}"
|
| 70 |
+
|
| 71 |
+
define i64 @sum(i64 %.1, i64 %.2) {{
|
| 72 |
+
%.3 = add i64 %.1, %.2
|
| 73 |
+
%.4 = add i64 5, %.3
|
| 74 |
+
%.5 = add i64 -5, %.4
|
| 75 |
+
ret i64 %.5
|
| 76 |
+
}}
|
| 77 |
+
"""
|
| 78 |
+
|
| 79 |
+
asm_mul = r"""
|
| 80 |
+
; ModuleID = '<string>'
|
| 81 |
+
target triple = "{triple}"
|
| 82 |
+
@mul_glob = global i32 0
|
| 83 |
+
|
| 84 |
+
define i32 @mul(i32 %.1, i32 %.2) {{
|
| 85 |
+
%.3 = mul i32 %.1, %.2
|
| 86 |
+
ret i32 %.3
|
| 87 |
+
}}
|
| 88 |
+
"""
|
| 89 |
+
|
| 90 |
+
asm_square_sum = r"""
|
| 91 |
+
; ModuleID = '<string>'
|
| 92 |
+
target triple = "{triple}"
|
| 93 |
+
@mul_glob = global i32 0
|
| 94 |
+
|
| 95 |
+
declare i32 @sum(i32, i32)
|
| 96 |
+
define i32 @square_sum(i32 %.1, i32 %.2) {{
|
| 97 |
+
%.3 = call i32 @sum(i32 %.1, i32 %.2)
|
| 98 |
+
%.4 = mul i32 %.3, %.3
|
| 99 |
+
ret i32 %.4
|
| 100 |
+
}}
|
| 101 |
+
"""
|
| 102 |
+
|
| 103 |
+
asm_getversion = r"""
|
| 104 |
+
; ModuleID = '<string>'
|
| 105 |
+
target triple = "{triple}"
|
| 106 |
+
|
| 107 |
+
declare i8* @Py_GetVersion()
|
| 108 |
+
|
| 109 |
+
define void @getversion(i32 %.1, i32 %.2) {{
|
| 110 |
+
%1 = call i8* @Py_GetVersion()
|
| 111 |
+
ret void
|
| 112 |
+
}}
|
| 113 |
+
"""
|
| 114 |
+
|
| 115 |
+
if platform.python_implementation() == 'PyPy':
|
| 116 |
+
asm_getversion = asm_getversion.replace('Py_GetVersion', 'PyPy_GetVersion')
|
| 117 |
+
|
| 118 |
+
# `fadd` used on integer inputs
|
| 119 |
+
asm_parse_error = r"""
|
| 120 |
+
; ModuleID = '<string>'
|
| 121 |
+
target triple = "{triple}"
|
| 122 |
+
|
| 123 |
+
define i32 @sum(i32 %.1, i32 %.2) {{
|
| 124 |
+
%.3 = fadd i32 %.1, %.2
|
| 125 |
+
ret i32 %.3
|
| 126 |
+
}}
|
| 127 |
+
"""
|
| 128 |
+
|
| 129 |
+
# "%.bug" definition references itself
|
| 130 |
+
asm_verification_fail = r"""
|
| 131 |
+
; ModuleID = '<string>'
|
| 132 |
+
target triple = "{triple}"
|
| 133 |
+
|
| 134 |
+
define void @sum() {{
|
| 135 |
+
%.bug = add i32 1, %.bug
|
| 136 |
+
ret void
|
| 137 |
+
}}
|
| 138 |
+
"""
|
| 139 |
+
|
| 140 |
+
asm_sum_declare = r"""
|
| 141 |
+
; ModuleID = '<string>'
|
| 142 |
+
target triple = "{triple}"
|
| 143 |
+
|
| 144 |
+
declare i32 @sum(i32 %.1, i32 %.2)
|
| 145 |
+
"""
|
| 146 |
+
|
| 147 |
+
asm_double_inaccurate = r"""
|
| 148 |
+
; ModuleID = '<string>'
|
| 149 |
+
target triple = "{triple}"
|
| 150 |
+
|
| 151 |
+
define void @foo() {{
|
| 152 |
+
%const = fadd fp128 0xLF3CB1CCF26FBC178452FB4EC7F91DEAD, 0xL00000000000000000000000000000001
|
| 153 |
+
ret void
|
| 154 |
+
}}
|
| 155 |
+
""" # noqa E501
|
| 156 |
+
|
| 157 |
+
asm_double_locale = r"""
|
| 158 |
+
; ModuleID = '<string>'
|
| 159 |
+
target triple = "{triple}"
|
| 160 |
+
|
| 161 |
+
define void @foo() {{
|
| 162 |
+
%const = fadd double 0.0, 3.14
|
| 163 |
+
ret void
|
| 164 |
+
}}
|
| 165 |
+
"""
|
| 166 |
+
|
| 167 |
+
|
| 168 |
+
asm_inlineasm = r"""
|
| 169 |
+
; ModuleID = '<string>'
|
| 170 |
+
target triple = "{triple}"
|
| 171 |
+
|
| 172 |
+
define void @foo() {{
|
| 173 |
+
call void asm sideeffect "nop", ""()
|
| 174 |
+
ret void
|
| 175 |
+
}}
|
| 176 |
+
"""
|
| 177 |
+
|
| 178 |
+
asm_inlineasm2 = """
|
| 179 |
+
; ModuleID = '<string>'
|
| 180 |
+
target triple = "{triple}"
|
| 181 |
+
|
| 182 |
+
define void @inlineme() {{
|
| 183 |
+
ret void
|
| 184 |
+
}}
|
| 185 |
+
|
| 186 |
+
define i32 @caller(i32 %.1, i32 %.2) {{
|
| 187 |
+
entry:
|
| 188 |
+
%stack = alloca i32
|
| 189 |
+
store i32 %.1, i32* %stack
|
| 190 |
+
br label %main
|
| 191 |
+
main:
|
| 192 |
+
%loaded = load i32, i32* %stack
|
| 193 |
+
%.3 = add i32 %loaded, %.2
|
| 194 |
+
%.4 = add i32 0, %.3
|
| 195 |
+
call void @inlineme()
|
| 196 |
+
ret i32 %.4
|
| 197 |
+
}}
|
| 198 |
+
"""
|
| 199 |
+
|
| 200 |
+
asm_inlineasm3 = """
|
| 201 |
+
; ModuleID = 'test.c'
|
| 202 |
+
source_filename = "test.c"
|
| 203 |
+
target triple = "{triple}"
|
| 204 |
+
|
| 205 |
+
; Function Attrs: noinline nounwind optnone ssp uwtable
|
| 206 |
+
define void @inlineme() noinline !dbg !15 {{
|
| 207 |
+
ret void, !dbg !18
|
| 208 |
+
}}
|
| 209 |
+
|
| 210 |
+
; Function Attrs: noinline nounwind optnone ssp uwtable
|
| 211 |
+
define i32 @foo(i32 %0, i32 %1) !dbg !19 {{
|
| 212 |
+
%3 = alloca i32, align 4
|
| 213 |
+
%4 = alloca i32, align 4
|
| 214 |
+
store i32 %0, i32* %3, align 4
|
| 215 |
+
call void @llvm.dbg.declare(metadata i32* %3, metadata !23, metadata !DIExpression()), !dbg !24
|
| 216 |
+
store i32 %1, i32* %4, align 4
|
| 217 |
+
call void @llvm.dbg.declare(metadata i32* %4, metadata !25, metadata !DIExpression()), !dbg !26
|
| 218 |
+
call void @inlineme(), !dbg !27
|
| 219 |
+
%5 = load i32, i32* %3, align 4, !dbg !28
|
| 220 |
+
%6 = load i32, i32* %4, align 4, !dbg !29
|
| 221 |
+
%7 = add nsw i32 %5, %6, !dbg !30
|
| 222 |
+
ret i32 %7, !dbg !31
|
| 223 |
+
}}
|
| 224 |
+
|
| 225 |
+
; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
|
| 226 |
+
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
|
| 227 |
+
|
| 228 |
+
attributes #1 = {{ nofree nosync nounwind readnone speculatable willreturn }}
|
| 229 |
+
|
| 230 |
+
!llvm.module.flags = !{{!1, !2, !3, !4, !5, !6, !7, !8, !9, !10}}
|
| 231 |
+
!llvm.dbg.cu = !{{!11}}
|
| 232 |
+
!llvm.ident = !{{!14}}
|
| 233 |
+
|
| 234 |
+
!0 = !{{i32 2, !"SDK Version", [2 x i32] [i32 12, i32 3]}}
|
| 235 |
+
!1 = !{{i32 7, !"Dwarf Version", i32 4}}
|
| 236 |
+
!2 = !{{i32 2, !"Debug Info Version", i32 3}}
|
| 237 |
+
!3 = !{{i32 1, !"wchar_size", i32 4}}
|
| 238 |
+
!4 = !{{i32 1, !"branch-target-enforcement", i32 0}}
|
| 239 |
+
!5 = !{{i32 1, !"sign-return-address", i32 0}}
|
| 240 |
+
!6 = !{{i32 1, !"sign-return-address-all", i32 0}}
|
| 241 |
+
!7 = !{{i32 1, !"sign-return-address-with-bkey", i32 0}}
|
| 242 |
+
!8 = !{{i32 7, !"PIC Level", i32 2}}
|
| 243 |
+
!9 = !{{i32 7, !"uwtable", i32 1}}
|
| 244 |
+
!10 = !{{i32 7, !"frame-pointer", i32 1}}
|
| 245 |
+
!11 = distinct !DICompileUnit(language: DW_LANG_C99, file: !12, producer: "Apple clang version 13.1.6 (clang-1316.0.21.2.3)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !13, splitDebugInlining: false, nameTableKind: None, sysroot: "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk", sdk: "MacOSX.sdk")
|
| 246 |
+
!12 = !DIFile(filename: "test.c", directory: "/")
|
| 247 |
+
!13 = !{{}}
|
| 248 |
+
!14 = !{{!"Apple clang version 13.1.6 (clang-1316.0.21.2.3)"}}
|
| 249 |
+
!15 = distinct !DISubprogram(name: "inlineme", scope: !12, file: !12, line: 1, type: !16, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !11, retainedNodes: !13)
|
| 250 |
+
!16 = !DISubroutineType(types: !17)
|
| 251 |
+
!17 = !{{null}}
|
| 252 |
+
!18 = !DILocation(line: 1, column: 22, scope: !15)
|
| 253 |
+
!19 = distinct !DISubprogram(name: "foo", scope: !12, file: !12, line: 3, type: !20, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !11, retainedNodes: !13)
|
| 254 |
+
!20 = !DISubroutineType(types: !21)
|
| 255 |
+
!21 = !{{!22, !22, !22}}
|
| 256 |
+
!22 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
| 257 |
+
!23 = !DILocalVariable(name: "a", arg: 1, scope: !19, file: !12, line: 3, type: !22)
|
| 258 |
+
!24 = !DILocation(line: 3, column: 13, scope: !19)
|
| 259 |
+
!25 = !DILocalVariable(name: "b", arg: 2, scope: !19, file: !12, line: 3, type: !22)
|
| 260 |
+
!26 = !DILocation(line: 3, column: 20, scope: !19)
|
| 261 |
+
!27 = !DILocation(line: 4, column: 5, scope: !19)
|
| 262 |
+
!28 = !DILocation(line: 5, column: 12, scope: !19)
|
| 263 |
+
!29 = !DILocation(line: 5, column: 16, scope: !19)
|
| 264 |
+
!30 = !DILocation(line: 5, column: 14, scope: !19)
|
| 265 |
+
!31 = !DILocation(line: 5, column: 5, scope: !19)
|
| 266 |
+
""" # noqa E501
|
| 267 |
+
|
| 268 |
+
licm_asm = r"""
|
| 269 |
+
; ModuleID = "<string>"
|
| 270 |
+
target triple = "{triple}"
|
| 271 |
+
|
| 272 |
+
define double @licm(i32 %0) {{
|
| 273 |
+
%2 = alloca i32, align 4
|
| 274 |
+
%3 = alloca double, align 8
|
| 275 |
+
%4 = alloca i32, align 4
|
| 276 |
+
%5 = alloca double, align 8
|
| 277 |
+
store i32 %0, i32* %2, align 4
|
| 278 |
+
store double 0.000000e+00, double* %3, align 8
|
| 279 |
+
store i32 0, i32* %4, align 4
|
| 280 |
+
br label %6
|
| 281 |
+
|
| 282 |
+
6: ; preds = %14, %1
|
| 283 |
+
%7 = load i32, i32* %4, align 4
|
| 284 |
+
%8 = load i32, i32* %2, align 4
|
| 285 |
+
%9 = icmp slt i32 %7, %8
|
| 286 |
+
br i1 %9, label %10, label %17
|
| 287 |
+
|
| 288 |
+
10: ; preds = %6
|
| 289 |
+
store double 7.000000e+00, double* %5, align 8
|
| 290 |
+
%11 = load double, double* %5, align 8
|
| 291 |
+
%12 = load double, double* %3, align 8
|
| 292 |
+
%13 = fadd double %12, %11
|
| 293 |
+
store double %13, double* %3, align 8
|
| 294 |
+
br label %14
|
| 295 |
+
|
| 296 |
+
14: ; preds = %10
|
| 297 |
+
%15 = load i32, i32* %4, align 4
|
| 298 |
+
%16 = add nsw i32 %15, 1
|
| 299 |
+
store i32 %16, i32* %4, align 4
|
| 300 |
+
br label %6
|
| 301 |
+
|
| 302 |
+
17: ; preds = %6
|
| 303 |
+
%18 = load double, double* %3, align 8
|
| 304 |
+
ret double %18
|
| 305 |
+
}}
|
| 306 |
+
""" # noqa E501
|
| 307 |
+
|
| 308 |
+
asm_global_ctors = r"""
|
| 309 |
+
; ModuleID = "<string>"
|
| 310 |
+
target triple = "{triple}"
|
| 311 |
+
|
| 312 |
+
@A = global i32 undef
|
| 313 |
+
|
| 314 |
+
define void @ctor_A()
|
| 315 |
+
{{
|
| 316 |
+
store i32 10, i32* @A
|
| 317 |
+
ret void
|
| 318 |
+
}}
|
| 319 |
+
|
| 320 |
+
define void @dtor_A()
|
| 321 |
+
{{
|
| 322 |
+
store i32 20, i32* @A
|
| 323 |
+
ret void
|
| 324 |
+
}}
|
| 325 |
+
|
| 326 |
+
define i32 @foo()
|
| 327 |
+
{{
|
| 328 |
+
%.2 = load i32, i32* @A
|
| 329 |
+
%.3 = add i32 %.2, 2
|
| 330 |
+
ret i32 %.3
|
| 331 |
+
}}
|
| 332 |
+
|
| 333 |
+
@llvm.global_ctors = appending global [1 x {{i32, void ()*, i8*}}] [{{i32, void ()*, i8*}} {{i32 0, void ()* @ctor_A, i8* null}}]
|
| 334 |
+
@llvm.global_dtors = appending global [1 x {{i32, void ()*, i8*}}] [{{i32, void ()*, i8*}} {{i32 0, void ()* @dtor_A, i8* null}}]
|
| 335 |
+
""" # noqa E501
|
| 336 |
+
|
| 337 |
+
asm_ext_ctors = r"""
|
| 338 |
+
; ModuleID = "<string>"
|
| 339 |
+
target triple = "{triple}"
|
| 340 |
+
|
| 341 |
+
@A = external global i32
|
| 342 |
+
|
| 343 |
+
define void @ctor_A()
|
| 344 |
+
{{
|
| 345 |
+
store i32 10, i32* @A
|
| 346 |
+
ret void
|
| 347 |
+
}}
|
| 348 |
+
|
| 349 |
+
define void @dtor_A()
|
| 350 |
+
{{
|
| 351 |
+
store i32 20, i32* @A
|
| 352 |
+
ret void
|
| 353 |
+
}}
|
| 354 |
+
|
| 355 |
+
define i32 @foo()
|
| 356 |
+
{{
|
| 357 |
+
%.2 = load i32, i32* @A
|
| 358 |
+
%.3 = add i32 %.2, 2
|
| 359 |
+
ret i32 %.3
|
| 360 |
+
}}
|
| 361 |
+
|
| 362 |
+
@llvm.global_ctors = appending global [1 x {{i32, void ()*, i8*}}] [{{i32, void ()*, i8*}} {{i32 0, void ()* @ctor_A, i8* null}}]
|
| 363 |
+
@llvm.global_dtors = appending global [1 x {{i32, void ()*, i8*}}] [{{i32, void ()*, i8*}} {{i32 0, void ()* @dtor_A, i8* null}}]
|
| 364 |
+
""" # noqa E501
|
| 365 |
+
|
| 366 |
+
|
| 367 |
+
asm_nonalphanum_blocklabel = """; ModuleID = ""
|
| 368 |
+
target triple = "unknown-unknown-unknown"
|
| 369 |
+
target datalayout = ""
|
| 370 |
+
|
| 371 |
+
define i32 @"foo"()
|
| 372 |
+
{
|
| 373 |
+
"<>!*''#":
|
| 374 |
+
ret i32 12345
|
| 375 |
+
}
|
| 376 |
+
""" # noqa W291 # trailing space needed for match later
|
| 377 |
+
|
| 378 |
+
|
| 379 |
+
asm_null_constant = r"""
|
| 380 |
+
; ModuleID = '<string>'
|
| 381 |
+
target triple = "{triple}"
|
| 382 |
+
|
| 383 |
+
define void @foo(i64* %.1) {{
|
| 384 |
+
ret void
|
| 385 |
+
}}
|
| 386 |
+
|
| 387 |
+
define void @bar() {{
|
| 388 |
+
call void @foo(i64* null)
|
| 389 |
+
ret void
|
| 390 |
+
}}
|
| 391 |
+
"""
|
| 392 |
+
|
| 393 |
+
|
| 394 |
+
riscv_asm_ilp32 = [
|
| 395 |
+
'addi\tsp, sp, -16',
|
| 396 |
+
'sw\ta1, 8(sp)',
|
| 397 |
+
'sw\ta2, 12(sp)',
|
| 398 |
+
'fld\tft0, 8(sp)',
|
| 399 |
+
'fmv.w.x\tft1, a0',
|
| 400 |
+
'fcvt.d.s\tft1, ft1',
|
| 401 |
+
'fadd.d\tft0, ft1, ft0',
|
| 402 |
+
'fsd\tft0, 8(sp)',
|
| 403 |
+
'lw\ta0, 8(sp)',
|
| 404 |
+
'lw\ta1, 12(sp)',
|
| 405 |
+
'addi\tsp, sp, 16',
|
| 406 |
+
'ret'
|
| 407 |
+
]
|
| 408 |
+
|
| 409 |
+
|
| 410 |
+
riscv_asm_ilp32f = [
|
| 411 |
+
'addi\tsp, sp, -16',
|
| 412 |
+
'sw\ta0, 8(sp)',
|
| 413 |
+
'sw\ta1, 12(sp)',
|
| 414 |
+
'fld\tft0, 8(sp)',
|
| 415 |
+
'fcvt.d.s\tft1, fa0',
|
| 416 |
+
'fadd.d\tft0, ft1, ft0',
|
| 417 |
+
'fsd\tft0, 8(sp)',
|
| 418 |
+
'lw\ta0, 8(sp)',
|
| 419 |
+
'lw\ta1, 12(sp)',
|
| 420 |
+
'addi\tsp, sp, 16',
|
| 421 |
+
'ret'
|
| 422 |
+
]
|
| 423 |
+
|
| 424 |
+
|
| 425 |
+
riscv_asm_ilp32d = [
|
| 426 |
+
'fcvt.d.s\tft0, fa0',
|
| 427 |
+
'fadd.d\tfa0, ft0, fa1',
|
| 428 |
+
'ret'
|
| 429 |
+
]
|
| 430 |
+
|
| 431 |
+
|
| 432 |
+
asm_attributes = r"""
|
| 433 |
+
declare void @a_readonly_func(i8 *) readonly
|
| 434 |
+
|
| 435 |
+
declare i8* @a_arg0_return_func(i8* returned, i32*)
|
| 436 |
+
"""
|
| 437 |
+
|
| 438 |
+
|
| 439 |
+
# This produces the following output from objdump:
|
| 440 |
+
#
|
| 441 |
+
# $ objdump -D 632.elf
|
| 442 |
+
#
|
| 443 |
+
# 632.elf: file format elf64-x86-64
|
| 444 |
+
#
|
| 445 |
+
#
|
| 446 |
+
# Disassembly of section .text:
|
| 447 |
+
#
|
| 448 |
+
# 0000000000000000 <__arybo>:
|
| 449 |
+
# 0: 48 c1 e2 20 shl $0x20,%rdx
|
| 450 |
+
# 4: 48 09 c2 or %rax,%rdx
|
| 451 |
+
# 7: 48 89 d0 mov %rdx,%rax
|
| 452 |
+
# a: 48 c1 c0 3d rol $0x3d,%rax
|
| 453 |
+
# e: 48 31 d0 xor %rdx,%rax
|
| 454 |
+
# 11: 48 b9 01 20 00 04 80 movabs $0x7010008004002001,%rcx
|
| 455 |
+
# 18: 00 10 70
|
| 456 |
+
# 1b: 48 0f af c8 imul %rax,%rcx
|
| 457 |
+
|
| 458 |
+
issue_632_elf = \
|
| 459 |
+
"7f454c4602010100000000000000000001003e00010000000000000000000000000000" \
|
| 460 |
+
"0000000000e0000000000000000000000040000000000040000500010048c1e2204809" \
|
| 461 |
+
"c24889d048c1c03d4831d048b90120000480001070480fafc800000000000000000000" \
|
| 462 |
+
"0000000000000000000000000000002f0000000400f1ff000000000000000000000000" \
|
| 463 |
+
"00000000070000001200020000000000000000001f00000000000000002e7465787400" \
|
| 464 |
+
"5f5f617279626f002e6e6f74652e474e552d737461636b002e737472746162002e7379" \
|
| 465 |
+
"6d746162003c737472696e673e00000000000000000000000000000000000000000000" \
|
| 466 |
+
"0000000000000000000000000000000000000000000000000000000000000000000000" \
|
| 467 |
+
"00000000000000001f0000000300000000000000000000000000000000000000a80000" \
|
| 468 |
+
"0000000000380000000000000000000000000000000100000000000000000000000000" \
|
| 469 |
+
"000001000000010000000600000000000000000000000000000040000000000000001f" \
|
| 470 |
+
"000000000000000000000000000000100000000000000000000000000000000f000000" \
|
| 471 |
+
"01000000000000000000000000000000000000005f0000000000000000000000000000" \
|
| 472 |
+
"0000000000000000000100000000000000000000000000000027000000020000000000" \
|
| 473 |
+
"0000000000000000000000000000600000000000000048000000000000000100000002" \
|
| 474 |
+
"00000008000000000000001800000000000000"
|
| 475 |
+
|
| 476 |
+
|
| 477 |
+
issue_632_text = \
|
| 478 |
+
"48c1e2204809c24889d048c1c03d4831d048b90120000480001070480fafc8"
|
| 479 |
+
|
| 480 |
+
|
| 481 |
+
asm_tli_exp2 = r"""
|
| 482 |
+
; ModuleID = '<lambda>'
|
| 483 |
+
source_filename = "<string>"
|
| 484 |
+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
| 485 |
+
target triple = "x86_64-pc-windows-msvc"
|
| 486 |
+
|
| 487 |
+
declare float @llvm.exp2.f32(float %casted)
|
| 488 |
+
|
| 489 |
+
define float @foo(i16 %arg) {
|
| 490 |
+
entry:
|
| 491 |
+
%casted = sitofp i16 %arg to float
|
| 492 |
+
%ret = call float @llvm.exp2.f32(float %casted)
|
| 493 |
+
ret float %ret
|
| 494 |
+
}
|
| 495 |
+
""" # noqa E501
|
| 496 |
+
|
| 497 |
+
|
| 498 |
+
class BaseTest(TestCase):
|
| 499 |
+
|
| 500 |
+
def setUp(self):
|
| 501 |
+
llvm.initialize()
|
| 502 |
+
llvm.initialize_native_target()
|
| 503 |
+
llvm.initialize_native_asmprinter()
|
| 504 |
+
gc.collect()
|
| 505 |
+
self.old_garbage = gc.garbage[:]
|
| 506 |
+
gc.garbage[:] = []
|
| 507 |
+
|
| 508 |
+
def tearDown(self):
|
| 509 |
+
# Test that no uncollectable objects were created
|
| 510 |
+
# (llvmlite objects have a __del__ so a reference cycle could
|
| 511 |
+
# create some).
|
| 512 |
+
gc.collect()
|
| 513 |
+
self.assertEqual(gc.garbage, [])
|
| 514 |
+
# This will probably put any existing garbage in gc.garbage again
|
| 515 |
+
del self.old_garbage
|
| 516 |
+
|
| 517 |
+
def module(self, asm=asm_sum, context=None):
|
| 518 |
+
asm = asm.format(triple=llvm.get_default_triple())
|
| 519 |
+
mod = llvm.parse_assembly(asm, context)
|
| 520 |
+
return mod
|
| 521 |
+
|
| 522 |
+
def glob(self, name='glob', mod=None):
|
| 523 |
+
if mod is None:
|
| 524 |
+
mod = self.module()
|
| 525 |
+
return mod.get_global_variable(name)
|
| 526 |
+
|
| 527 |
+
def target_machine(self, *, jit):
|
| 528 |
+
target = llvm.Target.from_default_triple()
|
| 529 |
+
return target.create_target_machine(jit=jit)
|
| 530 |
+
|
| 531 |
+
|
| 532 |
+
class TestDependencies(BaseTest):
|
| 533 |
+
"""
|
| 534 |
+
Test DLL dependencies are within a certain expected set.
|
| 535 |
+
"""
|
| 536 |
+
|
| 537 |
+
@unittest.skipUnless(sys.platform.startswith('linux'),
|
| 538 |
+
"Linux-specific test")
|
| 539 |
+
@unittest.skipUnless(os.environ.get('LLVMLITE_DIST_TEST'),
|
| 540 |
+
"Distribution-specific test")
|
| 541 |
+
def test_linux(self):
|
| 542 |
+
lib_path = ffi.lib._name
|
| 543 |
+
env = os.environ.copy()
|
| 544 |
+
env['LANG'] = 'C'
|
| 545 |
+
p = subprocess.Popen(["objdump", "-p", lib_path],
|
| 546 |
+
stdout=subprocess.PIPE, env=env)
|
| 547 |
+
out, _ = p.communicate()
|
| 548 |
+
self.assertEqual(0, p.returncode)
|
| 549 |
+
# Parse library dependencies
|
| 550 |
+
lib_pat = re.compile(r'^([-_a-zA-Z0-9]+)\.so(?:\.\d+){0,3}$')
|
| 551 |
+
deps = set()
|
| 552 |
+
for line in out.decode().splitlines():
|
| 553 |
+
parts = line.split()
|
| 554 |
+
if parts and parts[0] == 'NEEDED':
|
| 555 |
+
dep = parts[1]
|
| 556 |
+
m = lib_pat.match(dep)
|
| 557 |
+
if len(parts) != 2 or not m:
|
| 558 |
+
self.fail("invalid NEEDED line: %r" % (line,))
|
| 559 |
+
deps.add(m.group(1))
|
| 560 |
+
# Sanity check that our dependencies were parsed ok
|
| 561 |
+
if 'libc' not in deps or 'libpthread' not in deps:
|
| 562 |
+
self.fail("failed parsing dependencies? got %r" % (deps,))
|
| 563 |
+
# Ensure all dependencies are expected
|
| 564 |
+
allowed = set(['librt', 'libdl', 'libpthread', 'libz', 'libm',
|
| 565 |
+
'libgcc_s', 'libc', 'ld-linux', 'ld64'])
|
| 566 |
+
if platform.python_implementation() == 'PyPy':
|
| 567 |
+
allowed.add('libtinfo')
|
| 568 |
+
|
| 569 |
+
for dep in deps:
|
| 570 |
+
if not dep.startswith('ld-linux-') and dep not in allowed:
|
| 571 |
+
self.fail("unexpected dependency %r in %r" % (dep, deps))
|
| 572 |
+
|
| 573 |
+
|
| 574 |
+
class TestRISCVABI(BaseTest):
|
| 575 |
+
"""
|
| 576 |
+
Test calling convention of floating point arguments of RISC-V
|
| 577 |
+
using different ABI.
|
| 578 |
+
"""
|
| 579 |
+
triple = "riscv32-unknown-linux"
|
| 580 |
+
|
| 581 |
+
def setUp(self):
|
| 582 |
+
super().setUp()
|
| 583 |
+
llvm.initialize_all_targets()
|
| 584 |
+
llvm.initialize_all_asmprinters()
|
| 585 |
+
|
| 586 |
+
def check_riscv_target(self):
|
| 587 |
+
try:
|
| 588 |
+
llvm.Target.from_triple(self.triple)
|
| 589 |
+
except RuntimeError as e:
|
| 590 |
+
if "No available targets are compatible with triple" in str(e):
|
| 591 |
+
self.skipTest("RISCV target unsupported by linked LLVM.")
|
| 592 |
+
else:
|
| 593 |
+
raise e
|
| 594 |
+
|
| 595 |
+
def riscv_target_machine(self, **kwarg):
|
| 596 |
+
lltarget = llvm.Target.from_triple(self.triple)
|
| 597 |
+
return lltarget.create_target_machine(**kwarg)
|
| 598 |
+
|
| 599 |
+
def fpadd_ll_module(self):
|
| 600 |
+
f64 = ir.DoubleType()
|
| 601 |
+
f32 = ir.FloatType()
|
| 602 |
+
fnty = ir.FunctionType(f64, (f32, f64))
|
| 603 |
+
module = ir.Module()
|
| 604 |
+
func = ir.Function(module, fnty, name="fpadd")
|
| 605 |
+
block = func.append_basic_block()
|
| 606 |
+
builder = ir.IRBuilder(block)
|
| 607 |
+
a, b = func.args
|
| 608 |
+
arg0 = builder.fpext(a, f64)
|
| 609 |
+
result = builder.fadd(arg0, b)
|
| 610 |
+
builder.ret(result)
|
| 611 |
+
|
| 612 |
+
llmod = llvm.parse_assembly(str(module))
|
| 613 |
+
llmod.verify()
|
| 614 |
+
return llmod
|
| 615 |
+
|
| 616 |
+
def break_up_asm(self, asm):
|
| 617 |
+
asm_list = []
|
| 618 |
+
for line in asm.splitlines():
|
| 619 |
+
s_line = line.strip()
|
| 620 |
+
if not (s_line.startswith(".") or s_line.startswith("fpadd")
|
| 621 |
+
or s_line == ""):
|
| 622 |
+
asm_list.append(s_line)
|
| 623 |
+
return asm_list
|
| 624 |
+
|
| 625 |
+
def test_rv32d_ilp32(self):
|
| 626 |
+
self.check_riscv_target()
|
| 627 |
+
llmod = self.fpadd_ll_module()
|
| 628 |
+
target = self.riscv_target_machine(features="+f,+d")
|
| 629 |
+
self.assertEqual(self.break_up_asm(target.emit_assembly(llmod)),
|
| 630 |
+
riscv_asm_ilp32)
|
| 631 |
+
|
| 632 |
+
def test_rv32d_ilp32f(self):
|
| 633 |
+
self.check_riscv_target()
|
| 634 |
+
llmod = self.fpadd_ll_module()
|
| 635 |
+
target = self.riscv_target_machine(features="+f,+d", abiname="ilp32f")
|
| 636 |
+
self.assertEqual(self.break_up_asm(target.emit_assembly(llmod)),
|
| 637 |
+
riscv_asm_ilp32f)
|
| 638 |
+
|
| 639 |
+
def test_rv32d_ilp32d(self):
|
| 640 |
+
self.check_riscv_target()
|
| 641 |
+
llmod = self.fpadd_ll_module()
|
| 642 |
+
target = self.riscv_target_machine(features="+f,+d", abiname="ilp32d")
|
| 643 |
+
self.assertEqual(self.break_up_asm(target.emit_assembly(llmod)),
|
| 644 |
+
riscv_asm_ilp32d)
|
| 645 |
+
|
| 646 |
+
|
| 647 |
+
class TestMisc(BaseTest):
|
| 648 |
+
"""
|
| 649 |
+
Test miscellaneous functions in llvm.binding.
|
| 650 |
+
"""
|
| 651 |
+
|
| 652 |
+
def test_parse_assembly(self):
|
| 653 |
+
self.module(asm_sum)
|
| 654 |
+
|
| 655 |
+
def test_parse_assembly_error(self):
|
| 656 |
+
with self.assertRaises(RuntimeError) as cm:
|
| 657 |
+
self.module(asm_parse_error)
|
| 658 |
+
s = str(cm.exception)
|
| 659 |
+
self.assertIn("parsing error", s)
|
| 660 |
+
self.assertIn("invalid operand type", s)
|
| 661 |
+
|
| 662 |
+
def test_nonalphanum_block_name(self):
|
| 663 |
+
mod = ir.Module()
|
| 664 |
+
ft = ir.FunctionType(ir.IntType(32), [])
|
| 665 |
+
fn = ir.Function(mod, ft, "foo")
|
| 666 |
+
bd = ir.IRBuilder(fn.append_basic_block(name="<>!*''#"))
|
| 667 |
+
bd.ret(ir.Constant(ir.IntType(32), 12345))
|
| 668 |
+
asm = str(mod)
|
| 669 |
+
self.assertEqual(asm, asm_nonalphanum_blocklabel)
|
| 670 |
+
|
| 671 |
+
def test_global_context(self):
|
| 672 |
+
gcontext1 = llvm.context.get_global_context()
|
| 673 |
+
gcontext2 = llvm.context.get_global_context()
|
| 674 |
+
assert gcontext1 == gcontext2
|
| 675 |
+
|
| 676 |
+
def test_dylib_symbols(self):
|
| 677 |
+
llvm.add_symbol("__xyzzy", 1234)
|
| 678 |
+
llvm.add_symbol("__xyzzy", 5678)
|
| 679 |
+
addr = llvm.address_of_symbol("__xyzzy")
|
| 680 |
+
self.assertEqual(addr, 5678)
|
| 681 |
+
addr = llvm.address_of_symbol("__foobar")
|
| 682 |
+
self.assertIs(addr, None)
|
| 683 |
+
|
| 684 |
+
def test_get_default_triple(self):
|
| 685 |
+
triple = llvm.get_default_triple()
|
| 686 |
+
self.assertIsInstance(triple, str)
|
| 687 |
+
self.assertTrue(triple)
|
| 688 |
+
|
| 689 |
+
def test_get_process_triple(self):
|
| 690 |
+
# Sometimes we get synonyms for PPC
|
| 691 |
+
def normalize_ppc(arch):
|
| 692 |
+
if arch == 'powerpc64le':
|
| 693 |
+
return 'ppc64le'
|
| 694 |
+
else:
|
| 695 |
+
return arch
|
| 696 |
+
|
| 697 |
+
triple = llvm.get_process_triple()
|
| 698 |
+
default = llvm.get_default_triple()
|
| 699 |
+
self.assertIsInstance(triple, str)
|
| 700 |
+
self.assertTrue(triple)
|
| 701 |
+
|
| 702 |
+
default_arch = normalize_ppc(default.split('-')[0])
|
| 703 |
+
triple_arch = normalize_ppc(triple.split('-')[0])
|
| 704 |
+
# Arch must be equal
|
| 705 |
+
self.assertEqual(default_arch, triple_arch)
|
| 706 |
+
|
| 707 |
+
def test_get_host_cpu_features(self):
|
| 708 |
+
features = llvm.get_host_cpu_features()
|
| 709 |
+
# Check the content of `features`
|
| 710 |
+
self.assertIsInstance(features, dict)
|
| 711 |
+
self.assertIsInstance(features, llvm.FeatureMap)
|
| 712 |
+
for k, v in features.items():
|
| 713 |
+
self.assertIsInstance(k, str)
|
| 714 |
+
self.assertTrue(k) # single feature string cannot be empty
|
| 715 |
+
self.assertIsInstance(v, bool)
|
| 716 |
+
self.assertIsInstance(features.flatten(), str)
|
| 717 |
+
|
| 718 |
+
re_term = r"[+\-][a-zA-Z0-9\._-]+"
|
| 719 |
+
regex = r"^({0}|{0}(,{0})*)?$".format(re_term)
|
| 720 |
+
# quick check for our regex
|
| 721 |
+
self.assertIsNotNone(re.match(regex, ""))
|
| 722 |
+
self.assertIsNotNone(re.match(regex, "+aa"))
|
| 723 |
+
self.assertIsNotNone(re.match(regex, "+a,-bb"))
|
| 724 |
+
# check CpuFeature.flatten()
|
| 725 |
+
if len(features) == 0:
|
| 726 |
+
self.assertEqual(features.flatten(), "")
|
| 727 |
+
else:
|
| 728 |
+
self.assertIsNotNone(re.match(regex, features.flatten()))
|
| 729 |
+
|
| 730 |
+
def test_get_host_cpu_name(self):
|
| 731 |
+
cpu = llvm.get_host_cpu_name()
|
| 732 |
+
self.assertIsInstance(cpu, str)
|
| 733 |
+
self.assertTrue(cpu)
|
| 734 |
+
|
| 735 |
+
def test_initfini(self):
|
| 736 |
+
code = """if 1:
|
| 737 |
+
from llvmlite import binding as llvm
|
| 738 |
+
|
| 739 |
+
llvm.initialize()
|
| 740 |
+
llvm.initialize_native_target()
|
| 741 |
+
llvm.initialize_native_asmprinter()
|
| 742 |
+
llvm.initialize_all_targets()
|
| 743 |
+
llvm.initialize_all_asmprinters()
|
| 744 |
+
llvm.shutdown()
|
| 745 |
+
"""
|
| 746 |
+
subprocess.check_call([sys.executable, "-c", code])
|
| 747 |
+
|
| 748 |
+
def test_set_option(self):
|
| 749 |
+
# We cannot set an option multiple times (LLVM would exit() the
|
| 750 |
+
# process), so run the code in a subprocess.
|
| 751 |
+
code = """if 1:
|
| 752 |
+
from llvmlite import binding as llvm
|
| 753 |
+
|
| 754 |
+
llvm.set_option("progname", "-debug-pass=Disabled")
|
| 755 |
+
"""
|
| 756 |
+
subprocess.check_call([sys.executable, "-c", code])
|
| 757 |
+
|
| 758 |
+
def test_version(self):
|
| 759 |
+
major, minor, patch = llvm.llvm_version_info
|
| 760 |
+
# one of these can be valid
|
| 761 |
+
valid = [(14, )]
|
| 762 |
+
self.assertIn((major,), valid)
|
| 763 |
+
self.assertIn(patch, range(10))
|
| 764 |
+
|
| 765 |
+
def test_check_jit_execution(self):
|
| 766 |
+
llvm.check_jit_execution()
|
| 767 |
+
|
| 768 |
+
@unittest.skipIf(no_de_locale(), "Locale not available")
|
| 769 |
+
def test_print_double_locale(self):
|
| 770 |
+
m = self.module(asm_double_locale)
|
| 771 |
+
expect = str(m)
|
| 772 |
+
# Change the locale so that comma is used as decimal-point
|
| 773 |
+
# to trigger the LLVM bug (llvmlite issue #80)
|
| 774 |
+
locale.setlocale(locale.LC_ALL, 'de_DE')
|
| 775 |
+
# The LLVM bug is trigged by print the module with double constant
|
| 776 |
+
got = str(m)
|
| 777 |
+
# Changing the locale should not affect the LLVM IR
|
| 778 |
+
self.assertEqual(expect, got)
|
| 779 |
+
|
| 780 |
+
def test_no_accidental_warnings(self):
|
| 781 |
+
code = "from llvmlite import binding"
|
| 782 |
+
flags = "-Werror"
|
| 783 |
+
cmdargs = [sys.executable, flags, "-c", code]
|
| 784 |
+
subprocess.check_call(cmdargs)
|
| 785 |
+
|
| 786 |
+
|
| 787 |
+
class TestModuleRef(BaseTest):
|
| 788 |
+
|
| 789 |
+
def test_str(self):
|
| 790 |
+
mod = self.module()
|
| 791 |
+
s = str(mod).strip()
|
| 792 |
+
self.assertTrue(s.startswith('; ModuleID ='), s)
|
| 793 |
+
|
| 794 |
+
def test_close(self):
|
| 795 |
+
mod = self.module()
|
| 796 |
+
str(mod)
|
| 797 |
+
mod.close()
|
| 798 |
+
with self.assertRaises(ctypes.ArgumentError):
|
| 799 |
+
str(mod)
|
| 800 |
+
mod.close()
|
| 801 |
+
|
| 802 |
+
def test_with(self):
|
| 803 |
+
mod = self.module()
|
| 804 |
+
str(mod)
|
| 805 |
+
with mod:
|
| 806 |
+
str(mod)
|
| 807 |
+
with self.assertRaises(ctypes.ArgumentError):
|
| 808 |
+
str(mod)
|
| 809 |
+
with self.assertRaises(RuntimeError):
|
| 810 |
+
with mod:
|
| 811 |
+
pass
|
| 812 |
+
|
| 813 |
+
def test_name(self):
|
| 814 |
+
mod = self.module()
|
| 815 |
+
mod.name = "foo"
|
| 816 |
+
self.assertEqual(mod.name, "foo")
|
| 817 |
+
mod.name = "bar"
|
| 818 |
+
self.assertEqual(mod.name, "bar")
|
| 819 |
+
|
| 820 |
+
def test_source_file(self):
|
| 821 |
+
mod = self.module()
|
| 822 |
+
self.assertEqual(mod.source_file, "asm_sum.c")
|
| 823 |
+
|
| 824 |
+
def test_data_layout(self):
|
| 825 |
+
mod = self.module()
|
| 826 |
+
s = mod.data_layout
|
| 827 |
+
self.assertIsInstance(s, str)
|
| 828 |
+
mod.data_layout = s
|
| 829 |
+
self.assertEqual(s, mod.data_layout)
|
| 830 |
+
|
| 831 |
+
def test_triple(self):
|
| 832 |
+
mod = self.module()
|
| 833 |
+
s = mod.triple
|
| 834 |
+
self.assertEqual(s, llvm.get_default_triple())
|
| 835 |
+
mod.triple = ''
|
| 836 |
+
self.assertEqual(mod.triple, '')
|
| 837 |
+
|
| 838 |
+
def test_verify(self):
|
| 839 |
+
# Verify successful
|
| 840 |
+
mod = self.module()
|
| 841 |
+
self.assertIs(mod.verify(), None)
|
| 842 |
+
# Verify failed
|
| 843 |
+
mod = self.module(asm_verification_fail)
|
| 844 |
+
with self.assertRaises(RuntimeError) as cm:
|
| 845 |
+
mod.verify()
|
| 846 |
+
s = str(cm.exception)
|
| 847 |
+
self.assertIn("%.bug = add i32 1, %.bug", s)
|
| 848 |
+
|
| 849 |
+
def test_get_function(self):
|
| 850 |
+
mod = self.module()
|
| 851 |
+
fn = mod.get_function("sum")
|
| 852 |
+
self.assertIsInstance(fn, llvm.ValueRef)
|
| 853 |
+
self.assertEqual(fn.name, "sum")
|
| 854 |
+
|
| 855 |
+
with self.assertRaises(NameError):
|
| 856 |
+
mod.get_function("foo")
|
| 857 |
+
|
| 858 |
+
# Check that fn keeps the module instance alive
|
| 859 |
+
del mod
|
| 860 |
+
str(fn.module)
|
| 861 |
+
|
| 862 |
+
def test_get_struct_type(self):
|
| 863 |
+
mod = self.module()
|
| 864 |
+
st_ty = mod.get_struct_type("struct.glob_type")
|
| 865 |
+
self.assertEqual(st_ty.name, "struct.glob_type")
|
| 866 |
+
# also match struct names of form "%struct.glob_type.{some_index}"
|
| 867 |
+
self.assertIsNotNone(re.match(
|
| 868 |
+
r'%struct\.glob_type(\.[\d]+)? = type { i64, \[2 x i64\] }',
|
| 869 |
+
str(st_ty)))
|
| 870 |
+
|
| 871 |
+
with self.assertRaises(NameError):
|
| 872 |
+
mod.get_struct_type("struct.doesnt_exist")
|
| 873 |
+
|
| 874 |
+
def test_get_global_variable(self):
|
| 875 |
+
mod = self.module()
|
| 876 |
+
gv = mod.get_global_variable("glob")
|
| 877 |
+
self.assertIsInstance(gv, llvm.ValueRef)
|
| 878 |
+
self.assertEqual(gv.name, "glob")
|
| 879 |
+
|
| 880 |
+
with self.assertRaises(NameError):
|
| 881 |
+
mod.get_global_variable("bar")
|
| 882 |
+
|
| 883 |
+
# Check that gv keeps the module instance alive
|
| 884 |
+
del mod
|
| 885 |
+
str(gv.module)
|
| 886 |
+
|
| 887 |
+
def test_global_variables(self):
|
| 888 |
+
mod = self.module()
|
| 889 |
+
it = mod.global_variables
|
| 890 |
+
del mod
|
| 891 |
+
globs = sorted(it, key=lambda value: value.name)
|
| 892 |
+
self.assertEqual(len(globs), 4)
|
| 893 |
+
self.assertEqual([g.name for g in globs],
|
| 894 |
+
["glob", "glob_b", "glob_f", "glob_struct"])
|
| 895 |
+
|
| 896 |
+
def test_functions(self):
|
| 897 |
+
mod = self.module()
|
| 898 |
+
it = mod.functions
|
| 899 |
+
del mod
|
| 900 |
+
funcs = list(it)
|
| 901 |
+
self.assertEqual(len(funcs), 1)
|
| 902 |
+
self.assertEqual(funcs[0].name, "sum")
|
| 903 |
+
|
| 904 |
+
def test_structs(self):
|
| 905 |
+
mod = self.module()
|
| 906 |
+
it = mod.struct_types
|
| 907 |
+
del mod
|
| 908 |
+
structs = list(it)
|
| 909 |
+
self.assertEqual(len(structs), 1)
|
| 910 |
+
self.assertIsNotNone(re.match(r'struct\.glob_type(\.[\d]+)?',
|
| 911 |
+
structs[0].name))
|
| 912 |
+
self.assertIsNotNone(re.match(
|
| 913 |
+
r'%struct\.glob_type(\.[\d]+)? = type { i64, \[2 x i64\] }',
|
| 914 |
+
str(structs[0])))
|
| 915 |
+
|
| 916 |
+
def test_link_in(self):
|
| 917 |
+
dest = self.module()
|
| 918 |
+
src = self.module(asm_mul)
|
| 919 |
+
dest.link_in(src)
|
| 920 |
+
self.assertEqual(
|
| 921 |
+
sorted(f.name for f in dest.functions), ["mul", "sum"])
|
| 922 |
+
dest.get_function("mul")
|
| 923 |
+
dest.close()
|
| 924 |
+
with self.assertRaises(ctypes.ArgumentError):
|
| 925 |
+
src.get_function("mul")
|
| 926 |
+
|
| 927 |
+
def test_link_in_preserve(self):
|
| 928 |
+
dest = self.module()
|
| 929 |
+
src2 = self.module(asm_mul)
|
| 930 |
+
dest.link_in(src2, preserve=True)
|
| 931 |
+
self.assertEqual(
|
| 932 |
+
sorted(f.name for f in dest.functions), ["mul", "sum"])
|
| 933 |
+
dest.close()
|
| 934 |
+
self.assertEqual(sorted(f.name for f in src2.functions), ["mul"])
|
| 935 |
+
src2.get_function("mul")
|
| 936 |
+
|
| 937 |
+
def test_link_in_error(self):
|
| 938 |
+
# Raise an error by trying to link two modules with the same global
|
| 939 |
+
# definition "sum".
|
| 940 |
+
dest = self.module()
|
| 941 |
+
src = self.module(asm_sum2)
|
| 942 |
+
with self.assertRaises(RuntimeError) as cm:
|
| 943 |
+
dest.link_in(src)
|
| 944 |
+
self.assertIn("symbol multiply defined", str(cm.exception))
|
| 945 |
+
|
| 946 |
+
def test_as_bitcode(self):
|
| 947 |
+
mod = self.module()
|
| 948 |
+
bc = mod.as_bitcode()
|
| 949 |
+
# Refer to http://llvm.org/docs/doxygen/html/ReaderWriter_8h_source.html#l00064 # noqa E501
|
| 950 |
+
# and http://llvm.org/docs/doxygen/html/ReaderWriter_8h_source.html#l00092 # noqa E501
|
| 951 |
+
bitcode_wrapper_magic = b'\xde\xc0\x17\x0b'
|
| 952 |
+
bitcode_magic = b'BC'
|
| 953 |
+
self.assertTrue(bc.startswith(bitcode_magic) or
|
| 954 |
+
bc.startswith(bitcode_wrapper_magic))
|
| 955 |
+
|
| 956 |
+
def test_parse_bitcode_error(self):
|
| 957 |
+
with self.assertRaises(RuntimeError) as cm:
|
| 958 |
+
llvm.parse_bitcode(b"")
|
| 959 |
+
self.assertIn("LLVM bitcode parsing error", str(cm.exception))
|
| 960 |
+
# for llvm < 9
|
| 961 |
+
if llvm.llvm_version_info[0] < 9:
|
| 962 |
+
self.assertIn("Invalid bitcode signature", str(cm.exception))
|
| 963 |
+
else:
|
| 964 |
+
self.assertIn(
|
| 965 |
+
"file too small to contain bitcode header", str(cm.exception),
|
| 966 |
+
)
|
| 967 |
+
|
| 968 |
+
def test_bitcode_roundtrip(self):
|
| 969 |
+
# create a new context to avoid struct renaming
|
| 970 |
+
context1 = llvm.create_context()
|
| 971 |
+
bc = self.module(context=context1).as_bitcode()
|
| 972 |
+
context2 = llvm.create_context()
|
| 973 |
+
mod = llvm.parse_bitcode(bc, context2)
|
| 974 |
+
self.assertEqual(mod.as_bitcode(), bc)
|
| 975 |
+
|
| 976 |
+
mod.get_function("sum")
|
| 977 |
+
mod.get_global_variable("glob")
|
| 978 |
+
|
| 979 |
+
def test_cloning(self):
|
| 980 |
+
m = self.module()
|
| 981 |
+
cloned = m.clone()
|
| 982 |
+
self.assertIsNot(cloned, m)
|
| 983 |
+
self.assertEqual(cloned.as_bitcode(), m.as_bitcode())
|
| 984 |
+
|
| 985 |
+
|
| 986 |
+
class JITTestMixin(object):
|
| 987 |
+
"""
|
| 988 |
+
Mixin for ExecutionEngine tests.
|
| 989 |
+
"""
|
| 990 |
+
|
| 991 |
+
def get_sum(self, ee, func_name="sum"):
|
| 992 |
+
ee.finalize_object()
|
| 993 |
+
cfptr = ee.get_function_address(func_name)
|
| 994 |
+
self.assertTrue(cfptr)
|
| 995 |
+
return CFUNCTYPE(c_int, c_int, c_int)(cfptr)
|
| 996 |
+
|
| 997 |
+
def test_run_code(self):
|
| 998 |
+
mod = self.module()
|
| 999 |
+
with self.jit(mod) as ee:
|
| 1000 |
+
cfunc = self.get_sum(ee)
|
| 1001 |
+
res = cfunc(2, -5)
|
| 1002 |
+
self.assertEqual(-3, res)
|
| 1003 |
+
|
| 1004 |
+
def test_close(self):
|
| 1005 |
+
ee = self.jit(self.module())
|
| 1006 |
+
ee.close()
|
| 1007 |
+
ee.close()
|
| 1008 |
+
with self.assertRaises(ctypes.ArgumentError):
|
| 1009 |
+
ee.finalize_object()
|
| 1010 |
+
|
| 1011 |
+
def test_with(self):
|
| 1012 |
+
ee = self.jit(self.module())
|
| 1013 |
+
with ee:
|
| 1014 |
+
pass
|
| 1015 |
+
with self.assertRaises(RuntimeError):
|
| 1016 |
+
with ee:
|
| 1017 |
+
pass
|
| 1018 |
+
with self.assertRaises(ctypes.ArgumentError):
|
| 1019 |
+
ee.finalize_object()
|
| 1020 |
+
|
| 1021 |
+
def test_module_lifetime(self):
|
| 1022 |
+
mod = self.module()
|
| 1023 |
+
ee = self.jit(mod)
|
| 1024 |
+
ee.close()
|
| 1025 |
+
mod.close()
|
| 1026 |
+
|
| 1027 |
+
def test_module_lifetime2(self):
|
| 1028 |
+
mod = self.module()
|
| 1029 |
+
ee = self.jit(mod)
|
| 1030 |
+
mod.close()
|
| 1031 |
+
ee.close()
|
| 1032 |
+
|
| 1033 |
+
def test_add_module(self):
|
| 1034 |
+
ee = self.jit(self.module())
|
| 1035 |
+
mod = self.module(asm_mul)
|
| 1036 |
+
ee.add_module(mod)
|
| 1037 |
+
with self.assertRaises(KeyError):
|
| 1038 |
+
ee.add_module(mod)
|
| 1039 |
+
self.assertFalse(mod.closed)
|
| 1040 |
+
ee.close()
|
| 1041 |
+
self.assertTrue(mod.closed)
|
| 1042 |
+
|
| 1043 |
+
def test_add_module_lifetime(self):
|
| 1044 |
+
ee = self.jit(self.module())
|
| 1045 |
+
mod = self.module(asm_mul)
|
| 1046 |
+
ee.add_module(mod)
|
| 1047 |
+
mod.close()
|
| 1048 |
+
ee.close()
|
| 1049 |
+
|
| 1050 |
+
def test_add_module_lifetime2(self):
|
| 1051 |
+
ee = self.jit(self.module())
|
| 1052 |
+
mod = self.module(asm_mul)
|
| 1053 |
+
ee.add_module(mod)
|
| 1054 |
+
ee.close()
|
| 1055 |
+
mod.close()
|
| 1056 |
+
|
| 1057 |
+
def test_remove_module(self):
|
| 1058 |
+
ee = self.jit(self.module())
|
| 1059 |
+
mod = self.module(asm_mul)
|
| 1060 |
+
ee.add_module(mod)
|
| 1061 |
+
ee.remove_module(mod)
|
| 1062 |
+
with self.assertRaises(KeyError):
|
| 1063 |
+
ee.remove_module(mod)
|
| 1064 |
+
self.assertFalse(mod.closed)
|
| 1065 |
+
ee.close()
|
| 1066 |
+
self.assertFalse(mod.closed)
|
| 1067 |
+
|
| 1068 |
+
def test_target_data(self):
|
| 1069 |
+
mod = self.module()
|
| 1070 |
+
ee = self.jit(mod)
|
| 1071 |
+
td = ee.target_data
|
| 1072 |
+
# A singleton is returned
|
| 1073 |
+
self.assertIs(ee.target_data, td)
|
| 1074 |
+
str(td)
|
| 1075 |
+
del mod, ee
|
| 1076 |
+
str(td)
|
| 1077 |
+
|
| 1078 |
+
def test_target_data_abi_enquiries(self):
|
| 1079 |
+
mod = self.module()
|
| 1080 |
+
ee = self.jit(mod)
|
| 1081 |
+
td = ee.target_data
|
| 1082 |
+
gv_i32 = mod.get_global_variable("glob")
|
| 1083 |
+
gv_i8 = mod.get_global_variable("glob_b")
|
| 1084 |
+
gv_struct = mod.get_global_variable("glob_struct")
|
| 1085 |
+
# A global is a pointer, it has the ABI size of a pointer
|
| 1086 |
+
pointer_size = 4 if sys.maxsize < 2 ** 32 else 8
|
| 1087 |
+
for g in (gv_i32, gv_i8, gv_struct):
|
| 1088 |
+
self.assertEqual(td.get_abi_size(g.type), pointer_size)
|
| 1089 |
+
|
| 1090 |
+
self.assertEqual(td.get_pointee_abi_size(gv_i32.type), 4)
|
| 1091 |
+
self.assertEqual(td.get_pointee_abi_alignment(gv_i32.type), 4)
|
| 1092 |
+
|
| 1093 |
+
self.assertEqual(td.get_pointee_abi_size(gv_i8.type), 1)
|
| 1094 |
+
self.assertIn(td.get_pointee_abi_alignment(gv_i8.type), (1, 2, 4))
|
| 1095 |
+
|
| 1096 |
+
self.assertEqual(td.get_pointee_abi_size(gv_struct.type), 24)
|
| 1097 |
+
self.assertIn(td.get_pointee_abi_alignment(gv_struct.type), (4, 8))
|
| 1098 |
+
|
| 1099 |
+
def test_object_cache_notify(self):
|
| 1100 |
+
notifies = []
|
| 1101 |
+
|
| 1102 |
+
def notify(mod, buf):
|
| 1103 |
+
notifies.append((mod, buf))
|
| 1104 |
+
|
| 1105 |
+
mod = self.module()
|
| 1106 |
+
ee = self.jit(mod)
|
| 1107 |
+
ee.set_object_cache(notify)
|
| 1108 |
+
|
| 1109 |
+
self.assertEqual(len(notifies), 0)
|
| 1110 |
+
cfunc = self.get_sum(ee)
|
| 1111 |
+
cfunc(2, -5)
|
| 1112 |
+
self.assertEqual(len(notifies), 1)
|
| 1113 |
+
# The right module object was found
|
| 1114 |
+
self.assertIs(notifies[0][0], mod)
|
| 1115 |
+
self.assertIsInstance(notifies[0][1], bytes)
|
| 1116 |
+
|
| 1117 |
+
notifies[:] = []
|
| 1118 |
+
mod2 = self.module(asm_mul)
|
| 1119 |
+
ee.add_module(mod2)
|
| 1120 |
+
cfunc = self.get_sum(ee, "mul")
|
| 1121 |
+
self.assertEqual(len(notifies), 1)
|
| 1122 |
+
# The right module object was found
|
| 1123 |
+
self.assertIs(notifies[0][0], mod2)
|
| 1124 |
+
self.assertIsInstance(notifies[0][1], bytes)
|
| 1125 |
+
|
| 1126 |
+
def test_object_cache_getbuffer(self):
|
| 1127 |
+
notifies = []
|
| 1128 |
+
getbuffers = []
|
| 1129 |
+
|
| 1130 |
+
def notify(mod, buf):
|
| 1131 |
+
notifies.append((mod, buf))
|
| 1132 |
+
|
| 1133 |
+
def getbuffer(mod):
|
| 1134 |
+
getbuffers.append(mod)
|
| 1135 |
+
|
| 1136 |
+
mod = self.module()
|
| 1137 |
+
ee = self.jit(mod)
|
| 1138 |
+
ee.set_object_cache(notify, getbuffer)
|
| 1139 |
+
|
| 1140 |
+
# First return None from getbuffer(): the object is compiled normally
|
| 1141 |
+
self.assertEqual(len(notifies), 0)
|
| 1142 |
+
self.assertEqual(len(getbuffers), 0)
|
| 1143 |
+
cfunc = self.get_sum(ee)
|
| 1144 |
+
self.assertEqual(len(notifies), 1)
|
| 1145 |
+
self.assertEqual(len(getbuffers), 1)
|
| 1146 |
+
self.assertIs(getbuffers[0], mod)
|
| 1147 |
+
sum_buffer = notifies[0][1]
|
| 1148 |
+
|
| 1149 |
+
# Recreate a new EE, and use getbuffer() to return the previously
|
| 1150 |
+
# compiled object.
|
| 1151 |
+
|
| 1152 |
+
def getbuffer_successful(mod):
|
| 1153 |
+
getbuffers.append(mod)
|
| 1154 |
+
return sum_buffer
|
| 1155 |
+
|
| 1156 |
+
notifies[:] = []
|
| 1157 |
+
getbuffers[:] = []
|
| 1158 |
+
# Use another source module to make sure it is ignored
|
| 1159 |
+
mod = self.module(asm_mul)
|
| 1160 |
+
ee = self.jit(mod)
|
| 1161 |
+
ee.set_object_cache(notify, getbuffer_successful)
|
| 1162 |
+
|
| 1163 |
+
self.assertEqual(len(notifies), 0)
|
| 1164 |
+
self.assertEqual(len(getbuffers), 0)
|
| 1165 |
+
cfunc = self.get_sum(ee)
|
| 1166 |
+
self.assertEqual(cfunc(2, -5), -3)
|
| 1167 |
+
self.assertEqual(len(notifies), 0)
|
| 1168 |
+
self.assertEqual(len(getbuffers), 1)
|
| 1169 |
+
|
| 1170 |
+
|
| 1171 |
+
class JITWithTMTestMixin(JITTestMixin):
|
| 1172 |
+
|
| 1173 |
+
def test_emit_assembly(self):
|
| 1174 |
+
"""Test TargetMachineRef.emit_assembly()"""
|
| 1175 |
+
target_machine = self.target_machine(jit=True)
|
| 1176 |
+
mod = self.module()
|
| 1177 |
+
ee = self.jit(mod, target_machine) # noqa F841 # Keeps pointers alive
|
| 1178 |
+
raw_asm = target_machine.emit_assembly(mod)
|
| 1179 |
+
self.assertIn("sum", raw_asm)
|
| 1180 |
+
target_machine.set_asm_verbosity(True)
|
| 1181 |
+
raw_asm_verbose = target_machine.emit_assembly(mod)
|
| 1182 |
+
self.assertIn("sum", raw_asm)
|
| 1183 |
+
self.assertNotEqual(raw_asm, raw_asm_verbose)
|
| 1184 |
+
|
| 1185 |
+
def test_emit_object(self):
|
| 1186 |
+
"""Test TargetMachineRef.emit_object()"""
|
| 1187 |
+
target_machine = self.target_machine(jit=True)
|
| 1188 |
+
mod = self.module()
|
| 1189 |
+
ee = self.jit(mod, target_machine) # noqa F841 # Keeps pointers alive
|
| 1190 |
+
code_object = target_machine.emit_object(mod)
|
| 1191 |
+
self.assertIsInstance(code_object, bytes)
|
| 1192 |
+
if sys.platform.startswith('linux'):
|
| 1193 |
+
# Sanity check
|
| 1194 |
+
self.assertIn(b"ELF", code_object[:10])
|
| 1195 |
+
|
| 1196 |
+
|
| 1197 |
+
class TestMCJit(BaseTest, JITWithTMTestMixin):
|
| 1198 |
+
"""
|
| 1199 |
+
Test JIT engines created with create_mcjit_compiler().
|
| 1200 |
+
"""
|
| 1201 |
+
|
| 1202 |
+
def jit(self, mod, target_machine=None):
|
| 1203 |
+
if target_machine is None:
|
| 1204 |
+
target_machine = self.target_machine(jit=True)
|
| 1205 |
+
return llvm.create_mcjit_compiler(mod, target_machine)
|
| 1206 |
+
|
| 1207 |
+
|
| 1208 |
+
# There are some memory corruption issues with OrcJIT on AArch64 - see Issue
|
| 1209 |
+
# #1000. Since OrcJIT is experimental, and we don't test regularly during
|
| 1210 |
+
# llvmlite development on non-x86 platforms, it seems safest to skip these
|
| 1211 |
+
# tests on non-x86 platforms.
|
| 1212 |
+
@unittest.skipUnless(platform.machine().startswith("x86"), "x86 only")
|
| 1213 |
+
class TestOrcLLJIT(BaseTest):
|
| 1214 |
+
|
| 1215 |
+
def jit(self, asm=asm_sum, func_name="sum", target_machine=None,
|
| 1216 |
+
add_process=False, func_type=CFUNCTYPE(c_int, c_int, c_int),
|
| 1217 |
+
suppress_errors=False):
|
| 1218 |
+
lljit = llvm.create_lljit_compiler(target_machine,
|
| 1219 |
+
use_jit_link=False,
|
| 1220 |
+
suppress_errors=suppress_errors)
|
| 1221 |
+
builder = llvm.JITLibraryBuilder()
|
| 1222 |
+
if add_process:
|
| 1223 |
+
builder.add_current_process()
|
| 1224 |
+
rt = builder\
|
| 1225 |
+
.add_ir(asm.format(triple=llvm.get_default_triple()))\
|
| 1226 |
+
.export_symbol(func_name)\
|
| 1227 |
+
.link(lljit, func_name)
|
| 1228 |
+
cfptr = rt[func_name]
|
| 1229 |
+
self.assertTrue(cfptr)
|
| 1230 |
+
self.assertEqual(func_name, rt.name)
|
| 1231 |
+
return lljit, rt, func_type(cfptr)
|
| 1232 |
+
|
| 1233 |
+
# From test_dylib_symbols
|
| 1234 |
+
def test_define_symbol(self):
|
| 1235 |
+
lljit = llvm.create_lljit_compiler()
|
| 1236 |
+
rt = llvm.JITLibraryBuilder().import_symbol("__xyzzy", 1234)\
|
| 1237 |
+
.export_symbol("__xyzzy").link(lljit, "foo")
|
| 1238 |
+
self.assertEqual(rt["__xyzzy"], 1234)
|
| 1239 |
+
|
| 1240 |
+
def test_lookup_undefined_symbol_fails(self):
|
| 1241 |
+
lljit = llvm.create_lljit_compiler()
|
| 1242 |
+
with self.assertRaisesRegex(RuntimeError, 'No such library'):
|
| 1243 |
+
lljit.lookup("foo", "__foobar")
|
| 1244 |
+
rt = llvm.JITLibraryBuilder().import_symbol("__xyzzy", 1234)\
|
| 1245 |
+
.export_symbol("__xyzzy").link(lljit, "foo")
|
| 1246 |
+
self.assertNotEqual(rt["__xyzzy"], 0)
|
| 1247 |
+
with self.assertRaisesRegex(RuntimeError,
|
| 1248 |
+
'Symbols not found.*__foobar'):
|
| 1249 |
+
lljit.lookup("foo", "__foobar")
|
| 1250 |
+
|
| 1251 |
+
def test_jit_link(self):
|
| 1252 |
+
if sys.platform == "win32":
|
| 1253 |
+
with self.assertRaisesRegex(RuntimeError,
|
| 1254 |
+
'JITLink .* Windows'):
|
| 1255 |
+
llvm.create_lljit_compiler(use_jit_link=True)
|
| 1256 |
+
else:
|
| 1257 |
+
self.assertIsNotNone(llvm.create_lljit_compiler(use_jit_link=True))
|
| 1258 |
+
|
| 1259 |
+
def test_run_code(self):
|
| 1260 |
+
(lljit, rt, cfunc) = self.jit()
|
| 1261 |
+
with lljit:
|
| 1262 |
+
res = cfunc(2, -5)
|
| 1263 |
+
self.assertEqual(-3, res)
|
| 1264 |
+
|
| 1265 |
+
def test_close(self):
|
| 1266 |
+
(lljit, rt, cfunc) = self.jit()
|
| 1267 |
+
lljit.close()
|
| 1268 |
+
lljit.close()
|
| 1269 |
+
with self.assertRaises(AssertionError):
|
| 1270 |
+
lljit.lookup("foo", "fn")
|
| 1271 |
+
|
| 1272 |
+
def test_with(self):
|
| 1273 |
+
(lljit, rt, cfunc) = self.jit()
|
| 1274 |
+
with lljit:
|
| 1275 |
+
pass
|
| 1276 |
+
with self.assertRaises(RuntimeError):
|
| 1277 |
+
with lljit:
|
| 1278 |
+
pass
|
| 1279 |
+
with self.assertRaises(AssertionError):
|
| 1280 |
+
lljit.lookup("foo", "fn")
|
| 1281 |
+
|
| 1282 |
+
def test_add_ir_module(self):
|
| 1283 |
+
(lljit, rt_sum, cfunc_sum) = self.jit()
|
| 1284 |
+
rt_mul = llvm.JITLibraryBuilder() \
|
| 1285 |
+
.add_ir(asm_mul.format(triple=llvm.get_default_triple())) \
|
| 1286 |
+
.export_symbol("mul") \
|
| 1287 |
+
.link(lljit, "mul")
|
| 1288 |
+
res = CFUNCTYPE(c_int, c_int, c_int)(rt_mul["mul"])(2, -5)
|
| 1289 |
+
self.assertEqual(-10, res)
|
| 1290 |
+
self.assertNotEqual(lljit.lookup("sum", "sum")["sum"], 0)
|
| 1291 |
+
self.assertNotEqual(lljit.lookup("mul", "mul")["mul"], 0)
|
| 1292 |
+
with self.assertRaises(RuntimeError):
|
| 1293 |
+
lljit.lookup("sum", "mul")
|
| 1294 |
+
with self.assertRaises(RuntimeError):
|
| 1295 |
+
lljit.lookup("mul", "sum")
|
| 1296 |
+
|
| 1297 |
+
def test_remove_module(self):
|
| 1298 |
+
(lljit, rt_sum, _) = self.jit()
|
| 1299 |
+
del rt_sum
|
| 1300 |
+
gc.collect()
|
| 1301 |
+
with self.assertRaises(RuntimeError):
|
| 1302 |
+
lljit.lookup("sum", "sum")
|
| 1303 |
+
lljit.close()
|
| 1304 |
+
|
| 1305 |
+
def test_lib_depends(self):
|
| 1306 |
+
(lljit, rt_sum, cfunc_sum) = self.jit()
|
| 1307 |
+
rt_mul = llvm.JITLibraryBuilder() \
|
| 1308 |
+
.add_ir(asm_square_sum.format(triple=llvm.get_default_triple())) \
|
| 1309 |
+
.export_symbol("square_sum") \
|
| 1310 |
+
.add_jit_library("sum") \
|
| 1311 |
+
.link(lljit, "square_sum")
|
| 1312 |
+
res = CFUNCTYPE(c_int, c_int, c_int)(rt_mul["square_sum"])(2, -5)
|
| 1313 |
+
self.assertEqual(9, res)
|
| 1314 |
+
|
| 1315 |
+
def test_target_data(self):
|
| 1316 |
+
(lljit, rt, _) = self.jit()
|
| 1317 |
+
td = lljit.target_data
|
| 1318 |
+
# A singleton is returned
|
| 1319 |
+
self.assertIs(lljit.target_data, td)
|
| 1320 |
+
str(td)
|
| 1321 |
+
del lljit
|
| 1322 |
+
str(td)
|
| 1323 |
+
|
| 1324 |
+
def test_global_ctors_dtors(self):
|
| 1325 |
+
# test issue #303
|
| 1326 |
+
# (https://github.com/numba/llvmlite/issues/303)
|
| 1327 |
+
shared_value = c_int32(0)
|
| 1328 |
+
lljit = llvm.create_lljit_compiler()
|
| 1329 |
+
builder = llvm.JITLibraryBuilder()
|
| 1330 |
+
rt = builder \
|
| 1331 |
+
.add_ir(asm_ext_ctors.format(triple=llvm.get_default_triple())) \
|
| 1332 |
+
.import_symbol("A", ctypes.addressof(shared_value)) \
|
| 1333 |
+
.export_symbol("foo") \
|
| 1334 |
+
.link(lljit, "foo")
|
| 1335 |
+
foo = rt["foo"]
|
| 1336 |
+
self.assertTrue(foo)
|
| 1337 |
+
self.assertEqual(CFUNCTYPE(c_int)(foo)(), 12)
|
| 1338 |
+
del rt
|
| 1339 |
+
self.assertNotEqual(shared_value.value, 20)
|
| 1340 |
+
|
| 1341 |
+
def test_lookup_current_process_symbol_fails(self):
|
| 1342 |
+
# An attempt to lookup a symbol in the current process (Py_GetVersion,
|
| 1343 |
+
# in this case) should fail with an appropriate error if we have not
|
| 1344 |
+
# enabled searching the current process for symbols.
|
| 1345 |
+
msg = 'Failed to materialize symbols:.*getversion'
|
| 1346 |
+
with self.assertRaisesRegex(RuntimeError, msg):
|
| 1347 |
+
self.jit(asm_getversion, "getversion", suppress_errors=True)
|
| 1348 |
+
|
| 1349 |
+
def test_lookup_current_process_symbol(self):
|
| 1350 |
+
self.jit(asm_getversion, "getversion", None, True)
|
| 1351 |
+
|
| 1352 |
+
def test_thread_safe(self):
|
| 1353 |
+
lljit = llvm.create_lljit_compiler()
|
| 1354 |
+
llvm_ir = asm_sum.format(triple=llvm.get_default_triple())
|
| 1355 |
+
|
| 1356 |
+
def compile_many(i):
|
| 1357 |
+
def do_work():
|
| 1358 |
+
tracking = []
|
| 1359 |
+
for c in range(50):
|
| 1360 |
+
tracking.append(llvm.JITLibraryBuilder()
|
| 1361 |
+
.add_ir(llvm_ir)
|
| 1362 |
+
.export_symbol("sum")
|
| 1363 |
+
.link(lljit, f"sum_{i}_{c}"))
|
| 1364 |
+
|
| 1365 |
+
return do_work
|
| 1366 |
+
|
| 1367 |
+
ths = [threading.Thread(target=compile_many(i))
|
| 1368 |
+
for i in range(os.cpu_count())]
|
| 1369 |
+
for th in ths:
|
| 1370 |
+
th.start()
|
| 1371 |
+
for th in ths:
|
| 1372 |
+
th.join()
|
| 1373 |
+
|
| 1374 |
+
def test_add_object_file(self):
|
| 1375 |
+
target_machine = self.target_machine(jit=False)
|
| 1376 |
+
mod = self.module()
|
| 1377 |
+
lljit = llvm.create_lljit_compiler(target_machine)
|
| 1378 |
+
rt = llvm.JITLibraryBuilder()\
|
| 1379 |
+
.add_object_img(target_machine.emit_object(mod))\
|
| 1380 |
+
.export_symbol("sum")\
|
| 1381 |
+
.link(lljit, "sum")
|
| 1382 |
+
sum = CFUNCTYPE(c_int, c_int, c_int)(rt["sum"])
|
| 1383 |
+
self.assertEqual(sum(2, 3), 5)
|
| 1384 |
+
|
| 1385 |
+
def test_add_object_file_from_filesystem(self):
|
| 1386 |
+
target_machine = self.target_machine(jit=False)
|
| 1387 |
+
mod = self.module()
|
| 1388 |
+
obj_bin = target_machine.emit_object(mod)
|
| 1389 |
+
temp_desc, temp_path = mkstemp()
|
| 1390 |
+
|
| 1391 |
+
try:
|
| 1392 |
+
with os.fdopen(temp_desc, "wb") as f:
|
| 1393 |
+
f.write(obj_bin)
|
| 1394 |
+
lljit = llvm.create_lljit_compiler(target_machine)
|
| 1395 |
+
rt = llvm.JITLibraryBuilder() \
|
| 1396 |
+
.add_object_file(temp_path) \
|
| 1397 |
+
.export_symbol("sum") \
|
| 1398 |
+
.link(lljit, "sum")
|
| 1399 |
+
sum = CFUNCTYPE(c_int, c_int, c_int)(rt["sum"])
|
| 1400 |
+
self.assertEqual(sum(2, 3), 5)
|
| 1401 |
+
finally:
|
| 1402 |
+
os.unlink(temp_path)
|
| 1403 |
+
|
| 1404 |
+
|
| 1405 |
+
class TestValueRef(BaseTest):
|
| 1406 |
+
|
| 1407 |
+
def test_str(self):
|
| 1408 |
+
mod = self.module()
|
| 1409 |
+
glob = mod.get_global_variable("glob")
|
| 1410 |
+
self.assertEqual(str(glob), "@glob = global i32 0")
|
| 1411 |
+
|
| 1412 |
+
def test_name(self):
|
| 1413 |
+
mod = self.module()
|
| 1414 |
+
glob = mod.get_global_variable("glob")
|
| 1415 |
+
self.assertEqual(glob.name, "glob")
|
| 1416 |
+
glob.name = "foobar"
|
| 1417 |
+
self.assertEqual(glob.name, "foobar")
|
| 1418 |
+
|
| 1419 |
+
def test_linkage(self):
|
| 1420 |
+
mod = self.module()
|
| 1421 |
+
glob = mod.get_global_variable("glob")
|
| 1422 |
+
linkage = glob.linkage
|
| 1423 |
+
self.assertIsInstance(glob.linkage, llvm.Linkage)
|
| 1424 |
+
glob.linkage = linkage
|
| 1425 |
+
self.assertEqual(glob.linkage, linkage)
|
| 1426 |
+
for linkage in ("internal", "external"):
|
| 1427 |
+
glob.linkage = linkage
|
| 1428 |
+
self.assertIsInstance(glob.linkage, llvm.Linkage)
|
| 1429 |
+
self.assertEqual(glob.linkage.name, linkage)
|
| 1430 |
+
|
| 1431 |
+
def test_visibility(self):
|
| 1432 |
+
mod = self.module()
|
| 1433 |
+
glob = mod.get_global_variable("glob")
|
| 1434 |
+
visibility = glob.visibility
|
| 1435 |
+
self.assertIsInstance(glob.visibility, llvm.Visibility)
|
| 1436 |
+
glob.visibility = visibility
|
| 1437 |
+
self.assertEqual(glob.visibility, visibility)
|
| 1438 |
+
for visibility in ("hidden", "protected", "default"):
|
| 1439 |
+
glob.visibility = visibility
|
| 1440 |
+
self.assertIsInstance(glob.visibility, llvm.Visibility)
|
| 1441 |
+
self.assertEqual(glob.visibility.name, visibility)
|
| 1442 |
+
|
| 1443 |
+
def test_storage_class(self):
|
| 1444 |
+
mod = self.module()
|
| 1445 |
+
glob = mod.get_global_variable("glob")
|
| 1446 |
+
storage_class = glob.storage_class
|
| 1447 |
+
self.assertIsInstance(glob.storage_class, llvm.StorageClass)
|
| 1448 |
+
glob.storage_class = storage_class
|
| 1449 |
+
self.assertEqual(glob.storage_class, storage_class)
|
| 1450 |
+
for storage_class in ("dllimport", "dllexport", "default"):
|
| 1451 |
+
glob.storage_class = storage_class
|
| 1452 |
+
self.assertIsInstance(glob.storage_class, llvm.StorageClass)
|
| 1453 |
+
self.assertEqual(glob.storage_class.name, storage_class)
|
| 1454 |
+
|
| 1455 |
+
def test_add_function_attribute(self):
|
| 1456 |
+
mod = self.module()
|
| 1457 |
+
fn = mod.get_function("sum")
|
| 1458 |
+
fn.add_function_attribute("nocapture")
|
| 1459 |
+
with self.assertRaises(ValueError) as raises:
|
| 1460 |
+
fn.add_function_attribute("zext")
|
| 1461 |
+
self.assertEqual(str(raises.exception), "no such attribute 'zext'")
|
| 1462 |
+
|
| 1463 |
+
def test_module(self):
|
| 1464 |
+
mod = self.module()
|
| 1465 |
+
glob = mod.get_global_variable("glob")
|
| 1466 |
+
self.assertIs(glob.module, mod)
|
| 1467 |
+
|
| 1468 |
+
def test_type(self):
|
| 1469 |
+
mod = self.module()
|
| 1470 |
+
glob = mod.get_global_variable("glob")
|
| 1471 |
+
tp = glob.type
|
| 1472 |
+
self.assertIsInstance(tp, llvm.TypeRef)
|
| 1473 |
+
|
| 1474 |
+
def test_type_name(self):
|
| 1475 |
+
mod = self.module()
|
| 1476 |
+
glob = mod.get_global_variable("glob")
|
| 1477 |
+
tp = glob.type
|
| 1478 |
+
self.assertEqual(tp.name, "")
|
| 1479 |
+
st = mod.get_global_variable("glob_struct")
|
| 1480 |
+
self.assertIsNotNone(re.match(r"struct\.glob_type(\.[\d]+)?",
|
| 1481 |
+
st.type.element_type.name))
|
| 1482 |
+
|
| 1483 |
+
def test_type_printing_variable(self):
|
| 1484 |
+
mod = self.module()
|
| 1485 |
+
glob = mod.get_global_variable("glob")
|
| 1486 |
+
tp = glob.type
|
| 1487 |
+
self.assertEqual(str(tp), 'i32*')
|
| 1488 |
+
|
| 1489 |
+
def test_type_printing_function(self):
|
| 1490 |
+
mod = self.module()
|
| 1491 |
+
fn = mod.get_function("sum")
|
| 1492 |
+
self.assertEqual(str(fn.type), "i32 (i32, i32)*")
|
| 1493 |
+
|
| 1494 |
+
def test_type_printing_struct(self):
|
| 1495 |
+
mod = self.module()
|
| 1496 |
+
st = mod.get_global_variable("glob_struct")
|
| 1497 |
+
self.assertTrue(st.type.is_pointer)
|
| 1498 |
+
self.assertIsNotNone(re.match(r'%struct\.glob_type(\.[\d]+)?\*',
|
| 1499 |
+
str(st.type)))
|
| 1500 |
+
self.assertIsNotNone(re.match(
|
| 1501 |
+
r"%struct\.glob_type(\.[\d]+)? = type { i64, \[2 x i64\] }",
|
| 1502 |
+
str(st.type.element_type)))
|
| 1503 |
+
|
| 1504 |
+
def test_close(self):
|
| 1505 |
+
glob = self.glob()
|
| 1506 |
+
glob.close()
|
| 1507 |
+
glob.close()
|
| 1508 |
+
|
| 1509 |
+
def test_is_declaration(self):
|
| 1510 |
+
defined = self.module().get_function('sum')
|
| 1511 |
+
declared = self.module(asm_sum_declare).get_function('sum')
|
| 1512 |
+
self.assertFalse(defined.is_declaration)
|
| 1513 |
+
self.assertTrue(declared.is_declaration)
|
| 1514 |
+
|
| 1515 |
+
def test_module_global_variables(self):
|
| 1516 |
+
mod = self.module(asm_sum)
|
| 1517 |
+
gvars = list(mod.global_variables)
|
| 1518 |
+
self.assertEqual(len(gvars), 4)
|
| 1519 |
+
for v in gvars:
|
| 1520 |
+
self.assertTrue(v.is_global)
|
| 1521 |
+
|
| 1522 |
+
def test_module_functions(self):
|
| 1523 |
+
mod = self.module()
|
| 1524 |
+
funcs = list(mod.functions)
|
| 1525 |
+
self.assertEqual(len(funcs), 1)
|
| 1526 |
+
func = funcs[0]
|
| 1527 |
+
self.assertTrue(func.is_function)
|
| 1528 |
+
self.assertEqual(func.name, 'sum')
|
| 1529 |
+
|
| 1530 |
+
with self.assertRaises(ValueError):
|
| 1531 |
+
func.instructions
|
| 1532 |
+
with self.assertRaises(ValueError):
|
| 1533 |
+
func.operands
|
| 1534 |
+
with self.assertRaises(ValueError):
|
| 1535 |
+
func.opcode
|
| 1536 |
+
|
| 1537 |
+
def test_function_arguments(self):
|
| 1538 |
+
mod = self.module()
|
| 1539 |
+
func = mod.get_function('sum')
|
| 1540 |
+
self.assertTrue(func.is_function)
|
| 1541 |
+
args = list(func.arguments)
|
| 1542 |
+
self.assertEqual(len(args), 2)
|
| 1543 |
+
self.assertTrue(args[0].is_argument)
|
| 1544 |
+
self.assertTrue(args[1].is_argument)
|
| 1545 |
+
self.assertEqual(args[0].name, '.1')
|
| 1546 |
+
self.assertEqual(str(args[0].type), 'i32')
|
| 1547 |
+
self.assertEqual(args[1].name, '.2')
|
| 1548 |
+
self.assertEqual(str(args[1].type), 'i32')
|
| 1549 |
+
|
| 1550 |
+
with self.assertRaises(ValueError):
|
| 1551 |
+
args[0].blocks
|
| 1552 |
+
with self.assertRaises(ValueError):
|
| 1553 |
+
args[0].arguments
|
| 1554 |
+
|
| 1555 |
+
def test_function_blocks(self):
|
| 1556 |
+
func = self.module().get_function('sum')
|
| 1557 |
+
blocks = list(func.blocks)
|
| 1558 |
+
self.assertEqual(len(blocks), 1)
|
| 1559 |
+
block = blocks[0]
|
| 1560 |
+
self.assertTrue(block.is_block)
|
| 1561 |
+
|
| 1562 |
+
def test_block_instructions(self):
|
| 1563 |
+
func = self.module().get_function('sum')
|
| 1564 |
+
insts = list(list(func.blocks)[0].instructions)
|
| 1565 |
+
self.assertEqual(len(insts), 3)
|
| 1566 |
+
self.assertTrue(insts[0].is_instruction)
|
| 1567 |
+
self.assertTrue(insts[1].is_instruction)
|
| 1568 |
+
self.assertTrue(insts[2].is_instruction)
|
| 1569 |
+
self.assertEqual(insts[0].opcode, 'add')
|
| 1570 |
+
self.assertEqual(insts[1].opcode, 'add')
|
| 1571 |
+
self.assertEqual(insts[2].opcode, 'ret')
|
| 1572 |
+
|
| 1573 |
+
def test_instruction_operands(self):
|
| 1574 |
+
func = self.module().get_function('sum')
|
| 1575 |
+
add = list(list(func.blocks)[0].instructions)[0]
|
| 1576 |
+
self.assertEqual(add.opcode, 'add')
|
| 1577 |
+
operands = list(add.operands)
|
| 1578 |
+
self.assertEqual(len(operands), 2)
|
| 1579 |
+
self.assertTrue(operands[0].is_operand)
|
| 1580 |
+
self.assertTrue(operands[1].is_operand)
|
| 1581 |
+
self.assertEqual(operands[0].name, '.1')
|
| 1582 |
+
self.assertEqual(str(operands[0].type), 'i32')
|
| 1583 |
+
self.assertEqual(operands[1].name, '.2')
|
| 1584 |
+
self.assertEqual(str(operands[1].type), 'i32')
|
| 1585 |
+
|
| 1586 |
+
def test_function_attributes(self):
|
| 1587 |
+
mod = self.module(asm_attributes)
|
| 1588 |
+
for func in mod.functions:
|
| 1589 |
+
attrs = list(func.attributes)
|
| 1590 |
+
if func.name == 'a_readonly_func':
|
| 1591 |
+
self.assertEqual(attrs, [b'readonly'])
|
| 1592 |
+
elif func.name == 'a_arg0_return_func':
|
| 1593 |
+
self.assertEqual(attrs, [])
|
| 1594 |
+
args = list(func.arguments)
|
| 1595 |
+
self.assertEqual(list(args[0].attributes), [b'returned'])
|
| 1596 |
+
self.assertEqual(list(args[1].attributes), [])
|
| 1597 |
+
|
| 1598 |
+
def test_value_kind(self):
|
| 1599 |
+
mod = self.module()
|
| 1600 |
+
self.assertEqual(mod.get_global_variable('glob').value_kind,
|
| 1601 |
+
llvm.ValueKind.global_variable)
|
| 1602 |
+
func = mod.get_function('sum')
|
| 1603 |
+
self.assertEqual(func.value_kind, llvm.ValueKind.function)
|
| 1604 |
+
block = list(func.blocks)[0]
|
| 1605 |
+
self.assertEqual(block.value_kind, llvm.ValueKind.basic_block)
|
| 1606 |
+
inst = list(block.instructions)[1]
|
| 1607 |
+
self.assertEqual(inst.value_kind, llvm.ValueKind.instruction)
|
| 1608 |
+
self.assertEqual(list(inst.operands)[0].value_kind,
|
| 1609 |
+
llvm.ValueKind.constant_int)
|
| 1610 |
+
self.assertEqual(list(inst.operands)[1].value_kind,
|
| 1611 |
+
llvm.ValueKind.instruction)
|
| 1612 |
+
|
| 1613 |
+
iasm_func = self.module(asm_inlineasm).get_function('foo')
|
| 1614 |
+
iasm_inst = list(list(iasm_func.blocks)[0].instructions)[0]
|
| 1615 |
+
self.assertEqual(list(iasm_inst.operands)[0].value_kind,
|
| 1616 |
+
llvm.ValueKind.inline_asm)
|
| 1617 |
+
|
| 1618 |
+
def test_is_constant(self):
|
| 1619 |
+
mod = self.module()
|
| 1620 |
+
self.assertTrue(mod.get_global_variable('glob').is_constant)
|
| 1621 |
+
constant_operands = 0
|
| 1622 |
+
for func in mod.functions:
|
| 1623 |
+
self.assertTrue(func.is_constant)
|
| 1624 |
+
for block in func.blocks:
|
| 1625 |
+
self.assertFalse(block.is_constant)
|
| 1626 |
+
for inst in block.instructions:
|
| 1627 |
+
self.assertFalse(inst.is_constant)
|
| 1628 |
+
for op in inst.operands:
|
| 1629 |
+
if op.is_constant:
|
| 1630 |
+
constant_operands += 1
|
| 1631 |
+
|
| 1632 |
+
self.assertEqual(constant_operands, 1)
|
| 1633 |
+
|
| 1634 |
+
def test_constant_int(self):
|
| 1635 |
+
mod = self.module()
|
| 1636 |
+
func = mod.get_function('sum')
|
| 1637 |
+
insts = list(list(func.blocks)[0].instructions)
|
| 1638 |
+
self.assertEqual(insts[1].opcode, 'add')
|
| 1639 |
+
operands = list(insts[1].operands)
|
| 1640 |
+
self.assertTrue(operands[0].is_constant)
|
| 1641 |
+
self.assertFalse(operands[1].is_constant)
|
| 1642 |
+
self.assertEqual(operands[0].get_constant_value(), 0)
|
| 1643 |
+
with self.assertRaises(ValueError):
|
| 1644 |
+
operands[1].get_constant_value()
|
| 1645 |
+
|
| 1646 |
+
mod = self.module(asm_sum3)
|
| 1647 |
+
func = mod.get_function('sum')
|
| 1648 |
+
insts = list(list(func.blocks)[0].instructions)
|
| 1649 |
+
posint64 = list(insts[1].operands)[0]
|
| 1650 |
+
negint64 = list(insts[2].operands)[0]
|
| 1651 |
+
self.assertEqual(posint64.get_constant_value(), 5)
|
| 1652 |
+
self.assertEqual(negint64.get_constant_value(signed_int=True), -5)
|
| 1653 |
+
|
| 1654 |
+
# Convert from unsigned arbitrary-precision integer to signed i64
|
| 1655 |
+
as_u64 = negint64.get_constant_value(signed_int=False)
|
| 1656 |
+
as_i64 = int.from_bytes(as_u64.to_bytes(8, 'little'), 'little',
|
| 1657 |
+
signed=True)
|
| 1658 |
+
self.assertEqual(as_i64, -5)
|
| 1659 |
+
|
| 1660 |
+
def test_constant_fp(self):
|
| 1661 |
+
mod = self.module(asm_double_locale)
|
| 1662 |
+
func = mod.get_function('foo')
|
| 1663 |
+
insts = list(list(func.blocks)[0].instructions)
|
| 1664 |
+
self.assertEqual(len(insts), 2)
|
| 1665 |
+
self.assertEqual(insts[0].opcode, 'fadd')
|
| 1666 |
+
operands = list(insts[0].operands)
|
| 1667 |
+
self.assertTrue(operands[0].is_constant)
|
| 1668 |
+
self.assertAlmostEqual(operands[0].get_constant_value(), 0.0)
|
| 1669 |
+
self.assertTrue(operands[1].is_constant)
|
| 1670 |
+
self.assertAlmostEqual(operands[1].get_constant_value(), 3.14)
|
| 1671 |
+
|
| 1672 |
+
mod = self.module(asm_double_inaccurate)
|
| 1673 |
+
func = mod.get_function('foo')
|
| 1674 |
+
inst = list(list(func.blocks)[0].instructions)[0]
|
| 1675 |
+
operands = list(inst.operands)
|
| 1676 |
+
with self.assertRaises(ValueError):
|
| 1677 |
+
operands[0].get_constant_value()
|
| 1678 |
+
self.assertAlmostEqual(operands[1].get_constant_value(round_fp=True), 0)
|
| 1679 |
+
|
| 1680 |
+
def test_constant_as_string(self):
|
| 1681 |
+
mod = self.module(asm_null_constant)
|
| 1682 |
+
func = mod.get_function('bar')
|
| 1683 |
+
inst = list(list(func.blocks)[0].instructions)[0]
|
| 1684 |
+
arg = list(inst.operands)[0]
|
| 1685 |
+
self.assertTrue(arg.is_constant)
|
| 1686 |
+
self.assertEqual(arg.get_constant_value(), 'i64* null')
|
| 1687 |
+
|
| 1688 |
+
|
| 1689 |
+
class TestTarget(BaseTest):
|
| 1690 |
+
|
| 1691 |
+
def test_from_triple(self):
|
| 1692 |
+
f = llvm.Target.from_triple
|
| 1693 |
+
with self.assertRaises(RuntimeError) as cm:
|
| 1694 |
+
f("foobar")
|
| 1695 |
+
self.assertIn("No available targets are compatible with",
|
| 1696 |
+
str(cm.exception))
|
| 1697 |
+
triple = llvm.get_default_triple()
|
| 1698 |
+
target = f(triple)
|
| 1699 |
+
self.assertEqual(target.triple, triple)
|
| 1700 |
+
target.close()
|
| 1701 |
+
|
| 1702 |
+
def test_create_target_machine(self):
|
| 1703 |
+
target = llvm.Target.from_triple(llvm.get_default_triple())
|
| 1704 |
+
# With the default settings
|
| 1705 |
+
target.create_target_machine('', '', 1, 'default', 'default')
|
| 1706 |
+
# With the host's CPU
|
| 1707 |
+
cpu = llvm.get_host_cpu_name()
|
| 1708 |
+
target.create_target_machine(cpu, '', 1, 'default', 'default')
|
| 1709 |
+
|
| 1710 |
+
def test_name(self):
|
| 1711 |
+
t = llvm.Target.from_triple(llvm.get_default_triple())
|
| 1712 |
+
u = llvm.Target.from_default_triple()
|
| 1713 |
+
self.assertIsInstance(t.name, str)
|
| 1714 |
+
self.assertEqual(t.name, u.name)
|
| 1715 |
+
|
| 1716 |
+
def test_description(self):
|
| 1717 |
+
t = llvm.Target.from_triple(llvm.get_default_triple())
|
| 1718 |
+
u = llvm.Target.from_default_triple()
|
| 1719 |
+
self.assertIsInstance(t.description, str)
|
| 1720 |
+
self.assertEqual(t.description, u.description)
|
| 1721 |
+
|
| 1722 |
+
def test_str(self):
|
| 1723 |
+
target = llvm.Target.from_triple(llvm.get_default_triple())
|
| 1724 |
+
s = str(target)
|
| 1725 |
+
self.assertIn(target.name, s)
|
| 1726 |
+
self.assertIn(target.description, s)
|
| 1727 |
+
|
| 1728 |
+
|
| 1729 |
+
class TestTargetData(BaseTest):
|
| 1730 |
+
|
| 1731 |
+
def target_data(self):
|
| 1732 |
+
return llvm.create_target_data("e-m:e-i64:64-f80:128-n8:16:32:64-S128")
|
| 1733 |
+
|
| 1734 |
+
def test_get_abi_size(self):
|
| 1735 |
+
td = self.target_data()
|
| 1736 |
+
glob = self.glob()
|
| 1737 |
+
self.assertEqual(td.get_abi_size(glob.type), 8)
|
| 1738 |
+
|
| 1739 |
+
def test_get_pointee_abi_size(self):
|
| 1740 |
+
td = self.target_data()
|
| 1741 |
+
|
| 1742 |
+
glob = self.glob()
|
| 1743 |
+
self.assertEqual(td.get_pointee_abi_size(glob.type), 4)
|
| 1744 |
+
|
| 1745 |
+
glob = self.glob("glob_struct")
|
| 1746 |
+
self.assertEqual(td.get_pointee_abi_size(glob.type), 24)
|
| 1747 |
+
|
| 1748 |
+
def test_get_struct_element_offset(self):
|
| 1749 |
+
td = self.target_data()
|
| 1750 |
+
glob = self.glob("glob_struct")
|
| 1751 |
+
|
| 1752 |
+
with self.assertRaises(ValueError):
|
| 1753 |
+
td.get_element_offset(glob.type, 0)
|
| 1754 |
+
|
| 1755 |
+
struct_type = glob.type.element_type
|
| 1756 |
+
self.assertEqual(td.get_element_offset(struct_type, 0), 0)
|
| 1757 |
+
self.assertEqual(td.get_element_offset(struct_type, 1), 8)
|
| 1758 |
+
|
| 1759 |
+
|
| 1760 |
+
class TestTargetMachine(BaseTest):
|
| 1761 |
+
|
| 1762 |
+
def test_add_analysis_passes(self):
|
| 1763 |
+
tm = self.target_machine(jit=False)
|
| 1764 |
+
pm = llvm.create_module_pass_manager()
|
| 1765 |
+
tm.add_analysis_passes(pm)
|
| 1766 |
+
|
| 1767 |
+
def test_target_data_from_tm(self):
|
| 1768 |
+
tm = self.target_machine(jit=False)
|
| 1769 |
+
td = tm.target_data
|
| 1770 |
+
mod = self.module()
|
| 1771 |
+
gv_i32 = mod.get_global_variable("glob")
|
| 1772 |
+
# A global is a pointer, it has the ABI size of a pointer
|
| 1773 |
+
pointer_size = 4 if sys.maxsize < 2 ** 32 else 8
|
| 1774 |
+
self.assertEqual(td.get_abi_size(gv_i32.type), pointer_size)
|
| 1775 |
+
|
| 1776 |
+
|
| 1777 |
+
class TestPassManagerBuilder(BaseTest):
|
| 1778 |
+
|
| 1779 |
+
def pmb(self):
|
| 1780 |
+
return llvm.PassManagerBuilder()
|
| 1781 |
+
|
| 1782 |
+
def test_old_api(self):
|
| 1783 |
+
# Test the create_pass_manager_builder() factory function
|
| 1784 |
+
pmb = llvm.create_pass_manager_builder()
|
| 1785 |
+
pmb.inlining_threshold = 2
|
| 1786 |
+
pmb.opt_level = 3
|
| 1787 |
+
|
| 1788 |
+
def test_close(self):
|
| 1789 |
+
pmb = self.pmb()
|
| 1790 |
+
pmb.close()
|
| 1791 |
+
pmb.close()
|
| 1792 |
+
|
| 1793 |
+
def test_opt_level(self):
|
| 1794 |
+
pmb = self.pmb()
|
| 1795 |
+
self.assertIsInstance(pmb.opt_level, int)
|
| 1796 |
+
for i in range(4):
|
| 1797 |
+
pmb.opt_level = i
|
| 1798 |
+
self.assertEqual(pmb.opt_level, i)
|
| 1799 |
+
|
| 1800 |
+
def test_size_level(self):
|
| 1801 |
+
pmb = self.pmb()
|
| 1802 |
+
self.assertIsInstance(pmb.size_level, int)
|
| 1803 |
+
for i in range(4):
|
| 1804 |
+
pmb.size_level = i
|
| 1805 |
+
self.assertEqual(pmb.size_level, i)
|
| 1806 |
+
|
| 1807 |
+
def test_inlining_threshold(self):
|
| 1808 |
+
pmb = self.pmb()
|
| 1809 |
+
with self.assertRaises(NotImplementedError):
|
| 1810 |
+
pmb.inlining_threshold
|
| 1811 |
+
for i in (25, 80, 350):
|
| 1812 |
+
pmb.inlining_threshold = i
|
| 1813 |
+
|
| 1814 |
+
def test_disable_unroll_loops(self):
|
| 1815 |
+
pmb = self.pmb()
|
| 1816 |
+
self.assertIsInstance(pmb.disable_unroll_loops, bool)
|
| 1817 |
+
for b in (True, False):
|
| 1818 |
+
pmb.disable_unroll_loops = b
|
| 1819 |
+
self.assertEqual(pmb.disable_unroll_loops, b)
|
| 1820 |
+
|
| 1821 |
+
def test_loop_vectorize(self):
|
| 1822 |
+
pmb = self.pmb()
|
| 1823 |
+
self.assertIsInstance(pmb.loop_vectorize, bool)
|
| 1824 |
+
for b in (True, False):
|
| 1825 |
+
pmb.loop_vectorize = b
|
| 1826 |
+
self.assertEqual(pmb.loop_vectorize, b)
|
| 1827 |
+
|
| 1828 |
+
def test_slp_vectorize(self):
|
| 1829 |
+
pmb = self.pmb()
|
| 1830 |
+
self.assertIsInstance(pmb.slp_vectorize, bool)
|
| 1831 |
+
for b in (True, False):
|
| 1832 |
+
pmb.slp_vectorize = b
|
| 1833 |
+
self.assertEqual(pmb.slp_vectorize, b)
|
| 1834 |
+
|
| 1835 |
+
def test_populate_module_pass_manager(self):
|
| 1836 |
+
pmb = self.pmb()
|
| 1837 |
+
pm = llvm.create_module_pass_manager()
|
| 1838 |
+
pmb.populate(pm)
|
| 1839 |
+
pmb.close()
|
| 1840 |
+
pm.close()
|
| 1841 |
+
|
| 1842 |
+
def test_populate_function_pass_manager(self):
|
| 1843 |
+
mod = self.module()
|
| 1844 |
+
pmb = self.pmb()
|
| 1845 |
+
pm = llvm.create_function_pass_manager(mod)
|
| 1846 |
+
pmb.populate(pm)
|
| 1847 |
+
pmb.close()
|
| 1848 |
+
pm.close()
|
| 1849 |
+
|
| 1850 |
+
|
| 1851 |
+
class PassManagerTestMixin(object):
|
| 1852 |
+
|
| 1853 |
+
def pmb(self):
|
| 1854 |
+
pmb = llvm.create_pass_manager_builder()
|
| 1855 |
+
pmb.opt_level = 2
|
| 1856 |
+
pmb.inlining_threshold = 300
|
| 1857 |
+
return pmb
|
| 1858 |
+
|
| 1859 |
+
def test_close(self):
|
| 1860 |
+
pm = self.pm()
|
| 1861 |
+
pm.close()
|
| 1862 |
+
pm.close()
|
| 1863 |
+
|
| 1864 |
+
|
| 1865 |
+
class TestModulePassManager(BaseTest, PassManagerTestMixin):
|
| 1866 |
+
|
| 1867 |
+
def pm(self):
|
| 1868 |
+
return llvm.create_module_pass_manager()
|
| 1869 |
+
|
| 1870 |
+
def test_run(self):
|
| 1871 |
+
pm = self.pm()
|
| 1872 |
+
self.pmb().populate(pm)
|
| 1873 |
+
mod = self.module()
|
| 1874 |
+
orig_asm = str(mod)
|
| 1875 |
+
pm.run(mod)
|
| 1876 |
+
opt_asm = str(mod)
|
| 1877 |
+
# Quick check that optimizations were run, should get:
|
| 1878 |
+
# define i32 @sum(i32 %.1, i32 %.2) local_unnamed_addr #0 {
|
| 1879 |
+
# %.X = add i32 %.2, %.1
|
| 1880 |
+
# ret i32 %.X
|
| 1881 |
+
# }
|
| 1882 |
+
# where X in %.X is 3 or 4
|
| 1883 |
+
opt_asm_split = opt_asm.splitlines()
|
| 1884 |
+
for idx, l in enumerate(opt_asm_split):
|
| 1885 |
+
if l.strip().startswith('ret i32'):
|
| 1886 |
+
toks = {'%.3', '%.4'}
|
| 1887 |
+
for t in toks:
|
| 1888 |
+
if t in l:
|
| 1889 |
+
break
|
| 1890 |
+
else:
|
| 1891 |
+
raise RuntimeError("expected tokens not found")
|
| 1892 |
+
othertoken = (toks ^ {t}).pop()
|
| 1893 |
+
|
| 1894 |
+
self.assertIn("%.3", orig_asm)
|
| 1895 |
+
self.assertNotIn(othertoken, opt_asm)
|
| 1896 |
+
break
|
| 1897 |
+
else:
|
| 1898 |
+
raise RuntimeError("expected IR not found")
|
| 1899 |
+
|
| 1900 |
+
def test_run_with_remarks_successful_inline(self):
|
| 1901 |
+
pm = self.pm()
|
| 1902 |
+
pm.add_function_inlining_pass(70)
|
| 1903 |
+
self.pmb().populate(pm)
|
| 1904 |
+
mod = self.module(asm_inlineasm2)
|
| 1905 |
+
(status, remarks) = pm.run_with_remarks(mod)
|
| 1906 |
+
self.assertTrue(status)
|
| 1907 |
+
# Inlining has happened? The remark will tell us.
|
| 1908 |
+
self.assertIn("Passed", remarks)
|
| 1909 |
+
self.assertIn("inlineme", remarks)
|
| 1910 |
+
|
| 1911 |
+
def test_run_with_remarks_failed_inline(self):
|
| 1912 |
+
pm = self.pm()
|
| 1913 |
+
pm.add_function_inlining_pass(0)
|
| 1914 |
+
self.pmb().populate(pm)
|
| 1915 |
+
mod = self.module(asm_inlineasm3)
|
| 1916 |
+
(status, remarks) = pm.run_with_remarks(mod)
|
| 1917 |
+
self.assertTrue(status)
|
| 1918 |
+
|
| 1919 |
+
# Inlining has not happened? The remark will tell us.
|
| 1920 |
+
self.assertIn("Missed", remarks)
|
| 1921 |
+
self.assertIn("inlineme", remarks)
|
| 1922 |
+
self.assertIn("noinline function attribute", remarks)
|
| 1923 |
+
|
| 1924 |
+
def test_run_with_remarks_inline_filter_out(self):
|
| 1925 |
+
pm = self.pm()
|
| 1926 |
+
pm.add_function_inlining_pass(70)
|
| 1927 |
+
self.pmb().populate(pm)
|
| 1928 |
+
mod = self.module(asm_inlineasm2)
|
| 1929 |
+
(status, remarks) = pm.run_with_remarks(mod, remarks_filter="nothing")
|
| 1930 |
+
self.assertTrue(status)
|
| 1931 |
+
self.assertEqual("", remarks)
|
| 1932 |
+
|
| 1933 |
+
def test_run_with_remarks_inline_filter_in(self):
|
| 1934 |
+
pm = self.pm()
|
| 1935 |
+
pm.add_function_inlining_pass(70)
|
| 1936 |
+
self.pmb().populate(pm)
|
| 1937 |
+
mod = self.module(asm_inlineasm2)
|
| 1938 |
+
(status, remarks) = pm.run_with_remarks(mod, remarks_filter="inlin.*")
|
| 1939 |
+
self.assertTrue(status)
|
| 1940 |
+
self.assertIn("Passed", remarks)
|
| 1941 |
+
self.assertIn("inlineme", remarks)
|
| 1942 |
+
|
| 1943 |
+
|
| 1944 |
+
class TestFunctionPassManager(BaseTest, PassManagerTestMixin):
|
| 1945 |
+
|
| 1946 |
+
def pm(self, mod=None):
|
| 1947 |
+
mod = mod or self.module()
|
| 1948 |
+
return llvm.create_function_pass_manager(mod)
|
| 1949 |
+
|
| 1950 |
+
def test_initfini(self):
|
| 1951 |
+
pm = self.pm()
|
| 1952 |
+
pm.initialize()
|
| 1953 |
+
pm.finalize()
|
| 1954 |
+
|
| 1955 |
+
def test_run(self):
|
| 1956 |
+
mod = self.module()
|
| 1957 |
+
fn = mod.get_function("sum")
|
| 1958 |
+
pm = self.pm(mod)
|
| 1959 |
+
self.pmb().populate(pm)
|
| 1960 |
+
mod.close()
|
| 1961 |
+
orig_asm = str(fn)
|
| 1962 |
+
pm.initialize()
|
| 1963 |
+
pm.run(fn)
|
| 1964 |
+
pm.finalize()
|
| 1965 |
+
opt_asm = str(fn)
|
| 1966 |
+
# Quick check that optimizations were run
|
| 1967 |
+
self.assertIn("%.4", orig_asm)
|
| 1968 |
+
self.assertNotIn("%.4", opt_asm)
|
| 1969 |
+
|
| 1970 |
+
def test_run_with_remarks(self):
|
| 1971 |
+
mod = self.module(licm_asm)
|
| 1972 |
+
fn = mod.get_function("licm")
|
| 1973 |
+
pm = self.pm(mod)
|
| 1974 |
+
pm.add_licm_pass()
|
| 1975 |
+
self.pmb().populate(pm)
|
| 1976 |
+
mod.close()
|
| 1977 |
+
|
| 1978 |
+
pm.initialize()
|
| 1979 |
+
(ok, remarks) = pm.run_with_remarks(fn)
|
| 1980 |
+
pm.finalize()
|
| 1981 |
+
self.assertTrue(ok)
|
| 1982 |
+
self.assertIn("Passed", remarks)
|
| 1983 |
+
self.assertIn("licm", remarks)
|
| 1984 |
+
|
| 1985 |
+
def test_run_with_remarks_filter_out(self):
|
| 1986 |
+
mod = self.module(licm_asm)
|
| 1987 |
+
fn = mod.get_function("licm")
|
| 1988 |
+
pm = self.pm(mod)
|
| 1989 |
+
pm.add_licm_pass()
|
| 1990 |
+
self.pmb().populate(pm)
|
| 1991 |
+
mod.close()
|
| 1992 |
+
|
| 1993 |
+
pm.initialize()
|
| 1994 |
+
(ok, remarks) = pm.run_with_remarks(fn, remarks_filter="nothing")
|
| 1995 |
+
pm.finalize()
|
| 1996 |
+
self.assertTrue(ok)
|
| 1997 |
+
self.assertEqual("", remarks)
|
| 1998 |
+
|
| 1999 |
+
def test_run_with_remarks_filter_in(self):
|
| 2000 |
+
mod = self.module(licm_asm)
|
| 2001 |
+
fn = mod.get_function("licm")
|
| 2002 |
+
pm = self.pm(mod)
|
| 2003 |
+
pm.add_licm_pass()
|
| 2004 |
+
self.pmb().populate(pm)
|
| 2005 |
+
mod.close()
|
| 2006 |
+
|
| 2007 |
+
pm.initialize()
|
| 2008 |
+
(ok, remarks) = pm.run_with_remarks(fn, remarks_filter="licm")
|
| 2009 |
+
pm.finalize()
|
| 2010 |
+
self.assertTrue(ok)
|
| 2011 |
+
self.assertIn("Passed", remarks)
|
| 2012 |
+
self.assertIn("licm", remarks)
|
| 2013 |
+
|
| 2014 |
+
|
| 2015 |
+
class TestPasses(BaseTest, PassManagerTestMixin):
|
| 2016 |
+
|
| 2017 |
+
def pm(self):
|
| 2018 |
+
return llvm.create_module_pass_manager()
|
| 2019 |
+
|
| 2020 |
+
def test_populate(self):
|
| 2021 |
+
pm = self.pm()
|
| 2022 |
+
pm.add_target_library_info("") # unspecified target triple
|
| 2023 |
+
pm.add_constant_merge_pass()
|
| 2024 |
+
pm.add_dead_arg_elimination_pass()
|
| 2025 |
+
pm.add_function_attrs_pass()
|
| 2026 |
+
pm.add_function_inlining_pass(225)
|
| 2027 |
+
pm.add_global_dce_pass()
|
| 2028 |
+
pm.add_global_optimizer_pass()
|
| 2029 |
+
pm.add_ipsccp_pass()
|
| 2030 |
+
pm.add_dead_code_elimination_pass()
|
| 2031 |
+
pm.add_cfg_simplification_pass()
|
| 2032 |
+
pm.add_gvn_pass()
|
| 2033 |
+
pm.add_instruction_combining_pass()
|
| 2034 |
+
pm.add_licm_pass()
|
| 2035 |
+
pm.add_sccp_pass()
|
| 2036 |
+
pm.add_sroa_pass()
|
| 2037 |
+
pm.add_type_based_alias_analysis_pass()
|
| 2038 |
+
pm.add_basic_alias_analysis_pass()
|
| 2039 |
+
pm.add_loop_rotate_pass()
|
| 2040 |
+
pm.add_region_info_pass()
|
| 2041 |
+
pm.add_scalar_evolution_aa_pass()
|
| 2042 |
+
pm.add_aggressive_dead_code_elimination_pass()
|
| 2043 |
+
pm.add_aa_eval_pass()
|
| 2044 |
+
pm.add_always_inliner_pass()
|
| 2045 |
+
pm.add_arg_promotion_pass(42)
|
| 2046 |
+
pm.add_break_critical_edges_pass()
|
| 2047 |
+
pm.add_dead_store_elimination_pass()
|
| 2048 |
+
pm.add_reverse_post_order_function_attrs_pass()
|
| 2049 |
+
pm.add_aggressive_instruction_combining_pass()
|
| 2050 |
+
pm.add_internalize_pass()
|
| 2051 |
+
pm.add_jump_threading_pass(7)
|
| 2052 |
+
pm.add_lcssa_pass()
|
| 2053 |
+
pm.add_loop_deletion_pass()
|
| 2054 |
+
pm.add_loop_extractor_pass()
|
| 2055 |
+
pm.add_single_loop_extractor_pass()
|
| 2056 |
+
pm.add_loop_strength_reduce_pass()
|
| 2057 |
+
pm.add_loop_simplification_pass()
|
| 2058 |
+
pm.add_loop_unroll_pass()
|
| 2059 |
+
pm.add_loop_unroll_and_jam_pass()
|
| 2060 |
+
pm.add_loop_unswitch_pass()
|
| 2061 |
+
pm.add_lower_atomic_pass()
|
| 2062 |
+
pm.add_lower_invoke_pass()
|
| 2063 |
+
pm.add_lower_switch_pass()
|
| 2064 |
+
pm.add_memcpy_optimization_pass()
|
| 2065 |
+
pm.add_merge_functions_pass()
|
| 2066 |
+
pm.add_merge_returns_pass()
|
| 2067 |
+
pm.add_partial_inlining_pass()
|
| 2068 |
+
pm.add_prune_exception_handling_pass()
|
| 2069 |
+
pm.add_reassociate_expressions_pass()
|
| 2070 |
+
pm.add_demote_register_to_memory_pass()
|
| 2071 |
+
pm.add_sink_pass()
|
| 2072 |
+
pm.add_strip_symbols_pass()
|
| 2073 |
+
pm.add_strip_dead_debug_info_pass()
|
| 2074 |
+
pm.add_strip_dead_prototypes_pass()
|
| 2075 |
+
pm.add_strip_debug_declare_pass()
|
| 2076 |
+
pm.add_strip_nondebug_symbols_pass()
|
| 2077 |
+
pm.add_tail_call_elimination_pass()
|
| 2078 |
+
pm.add_basic_aa_pass()
|
| 2079 |
+
pm.add_dependence_analysis_pass()
|
| 2080 |
+
pm.add_dot_call_graph_pass()
|
| 2081 |
+
pm.add_dot_cfg_printer_pass()
|
| 2082 |
+
pm.add_dot_dom_printer_pass()
|
| 2083 |
+
pm.add_dot_postdom_printer_pass()
|
| 2084 |
+
pm.add_globals_mod_ref_aa_pass()
|
| 2085 |
+
pm.add_iv_users_pass()
|
| 2086 |
+
pm.add_lazy_value_info_pass()
|
| 2087 |
+
pm.add_lint_pass()
|
| 2088 |
+
pm.add_module_debug_info_pass()
|
| 2089 |
+
pm.add_refprune_pass()
|
| 2090 |
+
|
| 2091 |
+
@unittest.skipUnless(platform.machine().startswith("x86"), "x86 only")
|
| 2092 |
+
def test_target_library_info_behavior(self):
|
| 2093 |
+
"""Test a specific situation that demonstrate TLI is affecting
|
| 2094 |
+
optimization. See https://github.com/numba/numba/issues/8898.
|
| 2095 |
+
"""
|
| 2096 |
+
def run(use_tli):
|
| 2097 |
+
mod = llvm.parse_assembly(asm_tli_exp2)
|
| 2098 |
+
target = llvm.Target.from_triple(mod.triple)
|
| 2099 |
+
tm = target.create_target_machine()
|
| 2100 |
+
pm = llvm.ModulePassManager()
|
| 2101 |
+
tm.add_analysis_passes(pm)
|
| 2102 |
+
if use_tli:
|
| 2103 |
+
pm.add_target_library_info(mod.triple)
|
| 2104 |
+
pm.add_instruction_combining_pass()
|
| 2105 |
+
pm.run(mod)
|
| 2106 |
+
return mod
|
| 2107 |
+
|
| 2108 |
+
# Run with TLI should suppress transformation of exp2 -> ldexpf
|
| 2109 |
+
mod = run(use_tli=True)
|
| 2110 |
+
self.assertIn("call float @llvm.exp2.f32", str(mod))
|
| 2111 |
+
|
| 2112 |
+
# Run without TLI will enable the transformation
|
| 2113 |
+
mod = run(use_tli=False)
|
| 2114 |
+
self.assertNotIn("call float @llvm.exp2.f32", str(mod))
|
| 2115 |
+
self.assertIn("call float @ldexpf", str(mod))
|
| 2116 |
+
|
| 2117 |
+
|
| 2118 |
+
class TestDylib(BaseTest):
|
| 2119 |
+
|
| 2120 |
+
def test_bad_library(self):
|
| 2121 |
+
with self.assertRaises(RuntimeError):
|
| 2122 |
+
llvm.load_library_permanently("zzzasdkf;jasd;l")
|
| 2123 |
+
|
| 2124 |
+
@unittest.skipUnless(platform.system() in ["Linux"],
|
| 2125 |
+
"test only works on Linux")
|
| 2126 |
+
def test_libm(self):
|
| 2127 |
+
libm = find_library("m")
|
| 2128 |
+
llvm.load_library_permanently(libm)
|
| 2129 |
+
|
| 2130 |
+
|
| 2131 |
+
class TestAnalysis(BaseTest):
|
| 2132 |
+
def build_ir_module(self):
|
| 2133 |
+
m = ir.Module()
|
| 2134 |
+
ft = ir.FunctionType(ir.IntType(32), [ir.IntType(32), ir.IntType(32)])
|
| 2135 |
+
fn = ir.Function(m, ft, "foo")
|
| 2136 |
+
bd = ir.IRBuilder(fn.append_basic_block())
|
| 2137 |
+
x, y = fn.args
|
| 2138 |
+
z = bd.add(x, y)
|
| 2139 |
+
bd.ret(z)
|
| 2140 |
+
return m
|
| 2141 |
+
|
| 2142 |
+
def test_get_function_cfg_on_ir(self):
|
| 2143 |
+
mod = self.build_ir_module()
|
| 2144 |
+
foo = mod.get_global('foo')
|
| 2145 |
+
dot_showing_inst = llvm.get_function_cfg(foo)
|
| 2146 |
+
dot_without_inst = llvm.get_function_cfg(foo, show_inst=False)
|
| 2147 |
+
inst = "%.5 = add i32 %.1, %.2"
|
| 2148 |
+
self.assertIn(inst, dot_showing_inst)
|
| 2149 |
+
self.assertNotIn(inst, dot_without_inst)
|
| 2150 |
+
|
| 2151 |
+
def test_function_cfg_on_llvm_value(self):
|
| 2152 |
+
defined = self.module().get_function('sum')
|
| 2153 |
+
dot_showing_inst = llvm.get_function_cfg(defined, show_inst=True)
|
| 2154 |
+
dot_without_inst = llvm.get_function_cfg(defined, show_inst=False)
|
| 2155 |
+
# Check "digraph"
|
| 2156 |
+
prefix = 'digraph'
|
| 2157 |
+
self.assertIn(prefix, dot_showing_inst)
|
| 2158 |
+
self.assertIn(prefix, dot_without_inst)
|
| 2159 |
+
# Check function name
|
| 2160 |
+
fname = "CFG for 'sum' function"
|
| 2161 |
+
self.assertIn(fname, dot_showing_inst)
|
| 2162 |
+
self.assertIn(fname, dot_without_inst)
|
| 2163 |
+
# Check instruction
|
| 2164 |
+
inst = "%.3 = add i32 %.1, %.2"
|
| 2165 |
+
self.assertIn(inst, dot_showing_inst)
|
| 2166 |
+
self.assertNotIn(inst, dot_without_inst)
|
| 2167 |
+
|
| 2168 |
+
|
| 2169 |
+
class TestTypeParsing(BaseTest):
|
| 2170 |
+
@contextmanager
|
| 2171 |
+
def check_parsing(self):
|
| 2172 |
+
mod = ir.Module()
|
| 2173 |
+
# Yield to caller and provide the module for adding
|
| 2174 |
+
# new GV.
|
| 2175 |
+
yield mod
|
| 2176 |
+
# Caller yield back and continue with testing
|
| 2177 |
+
asm = str(mod)
|
| 2178 |
+
llvm.parse_assembly(asm)
|
| 2179 |
+
|
| 2180 |
+
def test_literal_struct(self):
|
| 2181 |
+
# Natural layout
|
| 2182 |
+
with self.check_parsing() as mod:
|
| 2183 |
+
typ = ir.LiteralStructType([ir.IntType(32)])
|
| 2184 |
+
gv = ir.GlobalVariable(mod, typ, "foo")
|
| 2185 |
+
# Also test constant text repr
|
| 2186 |
+
gv.initializer = ir.Constant(typ, [1])
|
| 2187 |
+
|
| 2188 |
+
# Packed layout
|
| 2189 |
+
with self.check_parsing() as mod:
|
| 2190 |
+
typ = ir.LiteralStructType([ir.IntType(32)],
|
| 2191 |
+
packed=True)
|
| 2192 |
+
gv = ir.GlobalVariable(mod, typ, "foo")
|
| 2193 |
+
# Also test constant text repr
|
| 2194 |
+
gv.initializer = ir.Constant(typ, [1])
|
| 2195 |
+
|
| 2196 |
+
|
| 2197 |
+
class TestGlobalConstructors(TestMCJit):
|
| 2198 |
+
def test_global_ctors_dtors(self):
|
| 2199 |
+
# test issue #303
|
| 2200 |
+
# (https://github.com/numba/llvmlite/issues/303)
|
| 2201 |
+
mod = self.module(asm_global_ctors)
|
| 2202 |
+
ee = self.jit(mod)
|
| 2203 |
+
ee.finalize_object()
|
| 2204 |
+
|
| 2205 |
+
ee.run_static_constructors()
|
| 2206 |
+
|
| 2207 |
+
# global variable should have been initialized
|
| 2208 |
+
ptr_addr = ee.get_global_value_address("A")
|
| 2209 |
+
ptr_t = ctypes.POINTER(ctypes.c_int32)
|
| 2210 |
+
ptr = ctypes.cast(ptr_addr, ptr_t)
|
| 2211 |
+
self.assertEqual(ptr.contents.value, 10)
|
| 2212 |
+
|
| 2213 |
+
foo_addr = ee.get_function_address("foo")
|
| 2214 |
+
foo = ctypes.CFUNCTYPE(ctypes.c_int32)(foo_addr)
|
| 2215 |
+
self.assertEqual(foo(), 12)
|
| 2216 |
+
|
| 2217 |
+
ee.run_static_destructors()
|
| 2218 |
+
|
| 2219 |
+
# destructor should have run
|
| 2220 |
+
self.assertEqual(ptr.contents.value, 20)
|
| 2221 |
+
|
| 2222 |
+
|
| 2223 |
+
class TestGlobalVariables(BaseTest):
|
| 2224 |
+
def check_global_variable_linkage(self, linkage, has_undef=True):
|
| 2225 |
+
# This test default initializer on global variables with different
|
| 2226 |
+
# linkages. Some linkages requires an initializer be present, while
|
| 2227 |
+
# it is optional for others. This test uses ``parse_assembly()``
|
| 2228 |
+
# to verify that we are adding an `undef` automatically if user didn't
|
| 2229 |
+
# specific one for certain linkages. It is a IR syntax error if the
|
| 2230 |
+
# initializer is not present for certain linkages e.g. "external".
|
| 2231 |
+
mod = ir.Module()
|
| 2232 |
+
typ = ir.IntType(32)
|
| 2233 |
+
gv = ir.GlobalVariable(mod, typ, "foo")
|
| 2234 |
+
gv.linkage = linkage
|
| 2235 |
+
asm = str(mod)
|
| 2236 |
+
# check if 'undef' is present
|
| 2237 |
+
if has_undef:
|
| 2238 |
+
self.assertIn('undef', asm)
|
| 2239 |
+
else:
|
| 2240 |
+
self.assertNotIn('undef', asm)
|
| 2241 |
+
# parse assembly to ensure correctness
|
| 2242 |
+
self.module(asm)
|
| 2243 |
+
|
| 2244 |
+
def test_internal_linkage(self):
|
| 2245 |
+
self.check_global_variable_linkage('internal')
|
| 2246 |
+
|
| 2247 |
+
def test_common_linkage(self):
|
| 2248 |
+
self.check_global_variable_linkage('common')
|
| 2249 |
+
|
| 2250 |
+
def test_external_linkage(self):
|
| 2251 |
+
self.check_global_variable_linkage('external', has_undef=False)
|
| 2252 |
+
|
| 2253 |
+
def test_available_externally_linkage(self):
|
| 2254 |
+
self.check_global_variable_linkage('available_externally')
|
| 2255 |
+
|
| 2256 |
+
def test_private_linkage(self):
|
| 2257 |
+
self.check_global_variable_linkage('private')
|
| 2258 |
+
|
| 2259 |
+
def test_linkonce_linkage(self):
|
| 2260 |
+
self.check_global_variable_linkage('linkonce')
|
| 2261 |
+
|
| 2262 |
+
def test_weak_linkage(self):
|
| 2263 |
+
self.check_global_variable_linkage('weak')
|
| 2264 |
+
|
| 2265 |
+
def test_appending_linkage(self):
|
| 2266 |
+
self.check_global_variable_linkage('appending')
|
| 2267 |
+
|
| 2268 |
+
def test_extern_weak_linkage(self):
|
| 2269 |
+
self.check_global_variable_linkage('extern_weak', has_undef=False)
|
| 2270 |
+
|
| 2271 |
+
def test_linkonce_odr_linkage(self):
|
| 2272 |
+
self.check_global_variable_linkage('linkonce_odr')
|
| 2273 |
+
|
| 2274 |
+
def test_weak_odr_linkage(self):
|
| 2275 |
+
self.check_global_variable_linkage('weak_odr')
|
| 2276 |
+
|
| 2277 |
+
|
| 2278 |
+
@unittest.skipUnless(platform.machine().startswith('x86'), "only on x86")
|
| 2279 |
+
class TestInlineAsm(BaseTest):
|
| 2280 |
+
def test_inlineasm(self):
|
| 2281 |
+
llvm.initialize_native_asmparser()
|
| 2282 |
+
m = self.module(asm=asm_inlineasm)
|
| 2283 |
+
tm = self.target_machine(jit=False)
|
| 2284 |
+
asm = tm.emit_assembly(m)
|
| 2285 |
+
self.assertIn('nop', asm)
|
| 2286 |
+
|
| 2287 |
+
|
| 2288 |
+
class TestObjectFile(BaseTest):
|
| 2289 |
+
|
| 2290 |
+
mod_asm = """
|
| 2291 |
+
;ModuleID = <string>
|
| 2292 |
+
target triple = "{triple}"
|
| 2293 |
+
|
| 2294 |
+
declare i32 @sum(i32 %.1, i32 %.2)
|
| 2295 |
+
|
| 2296 |
+
define i32 @sum_twice(i32 %.1, i32 %.2) {{
|
| 2297 |
+
%.3 = call i32 @sum(i32 %.1, i32 %.2)
|
| 2298 |
+
%.4 = call i32 @sum(i32 %.3, i32 %.3)
|
| 2299 |
+
ret i32 %.4
|
| 2300 |
+
}}
|
| 2301 |
+
"""
|
| 2302 |
+
|
| 2303 |
+
def test_object_file(self):
|
| 2304 |
+
target_machine = self.target_machine(jit=False)
|
| 2305 |
+
mod = self.module()
|
| 2306 |
+
obj_bin = target_machine.emit_object(mod)
|
| 2307 |
+
obj = llvm.ObjectFileRef.from_data(obj_bin)
|
| 2308 |
+
# Check that we have a text section, and that she has a name and data
|
| 2309 |
+
has_text = False
|
| 2310 |
+
last_address = -1
|
| 2311 |
+
for s in obj.sections():
|
| 2312 |
+
if s.is_text():
|
| 2313 |
+
has_text = True
|
| 2314 |
+
self.assertIsNotNone(s.name())
|
| 2315 |
+
self.assertTrue(s.size() > 0)
|
| 2316 |
+
self.assertTrue(len(s.data()) > 0)
|
| 2317 |
+
self.assertIsNotNone(s.address())
|
| 2318 |
+
self.assertTrue(last_address < s.address())
|
| 2319 |
+
last_address = s.address()
|
| 2320 |
+
break
|
| 2321 |
+
self.assertTrue(has_text)
|
| 2322 |
+
|
| 2323 |
+
def test_add_object_file(self):
|
| 2324 |
+
target_machine = self.target_machine(jit=False)
|
| 2325 |
+
mod = self.module()
|
| 2326 |
+
obj_bin = target_machine.emit_object(mod)
|
| 2327 |
+
obj = llvm.ObjectFileRef.from_data(obj_bin)
|
| 2328 |
+
|
| 2329 |
+
jit = llvm.create_mcjit_compiler(self.module(self.mod_asm),
|
| 2330 |
+
target_machine)
|
| 2331 |
+
|
| 2332 |
+
jit.add_object_file(obj)
|
| 2333 |
+
|
| 2334 |
+
sum_twice = CFUNCTYPE(c_int, c_int, c_int)(
|
| 2335 |
+
jit.get_function_address("sum_twice"))
|
| 2336 |
+
|
| 2337 |
+
self.assertEqual(sum_twice(2, 3), 10)
|
| 2338 |
+
|
| 2339 |
+
def test_add_object_file_from_filesystem(self):
|
| 2340 |
+
target_machine = self.target_machine(jit=False)
|
| 2341 |
+
mod = self.module()
|
| 2342 |
+
obj_bin = target_machine.emit_object(mod)
|
| 2343 |
+
temp_desc, temp_path = mkstemp()
|
| 2344 |
+
|
| 2345 |
+
try:
|
| 2346 |
+
try:
|
| 2347 |
+
f = os.fdopen(temp_desc, "wb")
|
| 2348 |
+
f.write(obj_bin)
|
| 2349 |
+
f.flush()
|
| 2350 |
+
finally:
|
| 2351 |
+
f.close()
|
| 2352 |
+
|
| 2353 |
+
jit = llvm.create_mcjit_compiler(self.module(self.mod_asm),
|
| 2354 |
+
target_machine)
|
| 2355 |
+
|
| 2356 |
+
jit.add_object_file(temp_path)
|
| 2357 |
+
finally:
|
| 2358 |
+
os.unlink(temp_path)
|
| 2359 |
+
|
| 2360 |
+
sum_twice = CFUNCTYPE(c_int, c_int, c_int)(
|
| 2361 |
+
jit.get_function_address("sum_twice"))
|
| 2362 |
+
|
| 2363 |
+
self.assertEqual(sum_twice(2, 3), 10)
|
| 2364 |
+
|
| 2365 |
+
def test_get_section_content(self):
|
| 2366 |
+
# See Issue #632 - section contents were getting truncated at null
|
| 2367 |
+
# bytes.
|
| 2368 |
+
elf = bytes.fromhex(issue_632_elf)
|
| 2369 |
+
obj = llvm.ObjectFileRef.from_data(elf)
|
| 2370 |
+
for s in obj.sections():
|
| 2371 |
+
if s.is_text():
|
| 2372 |
+
self.assertEqual(len(s.data()), 31)
|
| 2373 |
+
self.assertEqual(s.data().hex(), issue_632_text)
|
| 2374 |
+
|
| 2375 |
+
|
| 2376 |
+
class TestTimePasses(BaseTest):
|
| 2377 |
+
def test_reporting(self):
|
| 2378 |
+
mp = llvm.create_module_pass_manager()
|
| 2379 |
+
|
| 2380 |
+
pmb = llvm.create_pass_manager_builder()
|
| 2381 |
+
pmb.opt_level = 3
|
| 2382 |
+
pmb.populate(mp)
|
| 2383 |
+
|
| 2384 |
+
try:
|
| 2385 |
+
llvm.set_time_passes(True)
|
| 2386 |
+
mp.run(self.module())
|
| 2387 |
+
mp.run(self.module())
|
| 2388 |
+
mp.run(self.module())
|
| 2389 |
+
finally:
|
| 2390 |
+
report = llvm.report_and_reset_timings()
|
| 2391 |
+
llvm.set_time_passes(False)
|
| 2392 |
+
|
| 2393 |
+
self.assertIsInstance(report, str)
|
| 2394 |
+
self.assertEqual(report.count("Pass execution timing report"), 1)
|
| 2395 |
+
|
| 2396 |
+
def test_empty_report(self):
|
| 2397 |
+
# Returns empty str if no data is collected
|
| 2398 |
+
self.assertFalse(llvm.report_and_reset_timings())
|
| 2399 |
+
|
| 2400 |
+
|
| 2401 |
+
class TestLLVMLockCallbacks(BaseTest):
|
| 2402 |
+
def test_lock_callbacks(self):
|
| 2403 |
+
events = []
|
| 2404 |
+
|
| 2405 |
+
def acq():
|
| 2406 |
+
events.append('acq')
|
| 2407 |
+
|
| 2408 |
+
def rel():
|
| 2409 |
+
events.append('rel')
|
| 2410 |
+
|
| 2411 |
+
# register callback
|
| 2412 |
+
llvm.ffi.register_lock_callback(acq, rel)
|
| 2413 |
+
|
| 2414 |
+
# Check: events are initially empty
|
| 2415 |
+
self.assertFalse(events)
|
| 2416 |
+
# Call LLVM functions
|
| 2417 |
+
llvm.create_module_pass_manager()
|
| 2418 |
+
# Check: there must be at least one acq and one rel
|
| 2419 |
+
self.assertIn("acq", events)
|
| 2420 |
+
self.assertIn("rel", events)
|
| 2421 |
+
|
| 2422 |
+
# unregister callback
|
| 2423 |
+
llvm.ffi.unregister_lock_callback(acq, rel)
|
| 2424 |
+
|
| 2425 |
+
# Check: removing non-existent callbacks will trigger a ValueError
|
| 2426 |
+
with self.assertRaises(ValueError):
|
| 2427 |
+
llvm.ffi.unregister_lock_callback(acq, rel)
|
| 2428 |
+
|
| 2429 |
+
|
| 2430 |
+
if __name__ == "__main__":
|
| 2431 |
+
unittest.main()
|
lib/python3.11/site-packages/llvmlite/tests/test_ir.py
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
lib/python3.11/site-packages/llvmlite/tests/test_refprune.py
ADDED
|
@@ -0,0 +1,526 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import unittest
|
| 2 |
+
from llvmlite import ir
|
| 3 |
+
from llvmlite import binding as llvm
|
| 4 |
+
from llvmlite.tests import TestCase
|
| 5 |
+
|
| 6 |
+
from . import refprune_proto as proto
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
def _iterate_cases(generate_test):
|
| 10 |
+
def wrap(fn):
|
| 11 |
+
def wrapped(self):
|
| 12 |
+
return generate_test(self, fn)
|
| 13 |
+
wrapped.__doc__ = f"generated test for {fn.__module__}.{fn.__name__}"
|
| 14 |
+
return wrapped
|
| 15 |
+
|
| 16 |
+
for k, case_fn in proto.__dict__.items():
|
| 17 |
+
if k.startswith('case'):
|
| 18 |
+
yield f'test_{k}', wrap(case_fn)
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
class TestRefPrunePrototype(TestCase):
|
| 22 |
+
"""
|
| 23 |
+
Test that the prototype is working.
|
| 24 |
+
"""
|
| 25 |
+
def generate_test(self, case_gen):
|
| 26 |
+
nodes, edges, expected = case_gen()
|
| 27 |
+
got = proto.FanoutAlgorithm(nodes, edges).run()
|
| 28 |
+
self.assertEqual(expected, got)
|
| 29 |
+
|
| 30 |
+
# Generate tests
|
| 31 |
+
for name, case in _iterate_cases(generate_test):
|
| 32 |
+
locals()[name] = case
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
ptr_ty = ir.IntType(8).as_pointer()
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
class TestRefPrunePass(TestCase):
|
| 39 |
+
"""
|
| 40 |
+
Test that the C++ implementation matches the expected behavior as for
|
| 41 |
+
the prototype.
|
| 42 |
+
|
| 43 |
+
This generates a LLVM module for each test case, runs the pruner and checks
|
| 44 |
+
that the expected results are achieved.
|
| 45 |
+
"""
|
| 46 |
+
|
| 47 |
+
def make_incref(self, m):
|
| 48 |
+
fnty = ir.FunctionType(ir.VoidType(), [ptr_ty])
|
| 49 |
+
return ir.Function(m, fnty, name='NRT_incref')
|
| 50 |
+
|
| 51 |
+
def make_decref(self, m):
|
| 52 |
+
fnty = ir.FunctionType(ir.VoidType(), [ptr_ty])
|
| 53 |
+
return ir.Function(m, fnty, name='NRT_decref')
|
| 54 |
+
|
| 55 |
+
def make_switcher(self, m):
|
| 56 |
+
fnty = ir.FunctionType(ir.IntType(32), ())
|
| 57 |
+
return ir.Function(m, fnty, name='switcher')
|
| 58 |
+
|
| 59 |
+
def make_brancher(self, m):
|
| 60 |
+
fnty = ir.FunctionType(ir.IntType(1), ())
|
| 61 |
+
return ir.Function(m, fnty, name='brancher')
|
| 62 |
+
|
| 63 |
+
def generate_ir(self, nodes, edges):
|
| 64 |
+
# Build LLVM module for the CFG
|
| 65 |
+
m = ir.Module()
|
| 66 |
+
|
| 67 |
+
incref_fn = self.make_incref(m)
|
| 68 |
+
decref_fn = self.make_decref(m)
|
| 69 |
+
switcher_fn = self.make_switcher(m)
|
| 70 |
+
brancher_fn = self.make_brancher(m)
|
| 71 |
+
|
| 72 |
+
fnty = ir.FunctionType(ir.VoidType(), [ptr_ty])
|
| 73 |
+
fn = ir.Function(m, fnty, name='main')
|
| 74 |
+
[ptr] = fn.args
|
| 75 |
+
ptr.name = 'mem'
|
| 76 |
+
# populate the BB nodes
|
| 77 |
+
bbmap = {}
|
| 78 |
+
for bb in edges:
|
| 79 |
+
bbmap[bb] = fn.append_basic_block(bb)
|
| 80 |
+
# populate the BB
|
| 81 |
+
builder = ir.IRBuilder()
|
| 82 |
+
for bb, jump_targets in edges.items():
|
| 83 |
+
builder.position_at_end(bbmap[bb])
|
| 84 |
+
# Insert increfs and decrefs
|
| 85 |
+
for action in nodes[bb]:
|
| 86 |
+
if action == 'incref':
|
| 87 |
+
builder.call(incref_fn, [ptr])
|
| 88 |
+
elif action == 'decref':
|
| 89 |
+
builder.call(decref_fn, [ptr])
|
| 90 |
+
else:
|
| 91 |
+
raise AssertionError('unreachable')
|
| 92 |
+
|
| 93 |
+
# Insert the terminator.
|
| 94 |
+
# Switch base on the number of jump targets.
|
| 95 |
+
n_targets = len(jump_targets)
|
| 96 |
+
if n_targets == 0:
|
| 97 |
+
builder.ret_void()
|
| 98 |
+
elif n_targets == 1:
|
| 99 |
+
[dst] = jump_targets
|
| 100 |
+
builder.branch(bbmap[dst])
|
| 101 |
+
elif n_targets == 2:
|
| 102 |
+
[left, right] = jump_targets
|
| 103 |
+
sel = builder.call(brancher_fn, ())
|
| 104 |
+
builder.cbranch(sel, bbmap[left], bbmap[right])
|
| 105 |
+
elif n_targets > 2:
|
| 106 |
+
sel = builder.call(switcher_fn, ())
|
| 107 |
+
[head, *tail] = jump_targets
|
| 108 |
+
|
| 109 |
+
sw = builder.switch(sel, default=bbmap[head])
|
| 110 |
+
for i, dst in enumerate(tail):
|
| 111 |
+
sw.add_case(sel.type(i), bbmap[dst])
|
| 112 |
+
else:
|
| 113 |
+
raise AssertionError('unreachable')
|
| 114 |
+
|
| 115 |
+
return m
|
| 116 |
+
|
| 117 |
+
def apply_refprune(self, irmod):
|
| 118 |
+
mod = llvm.parse_assembly(str(irmod))
|
| 119 |
+
pm = llvm.ModulePassManager()
|
| 120 |
+
pm.add_refprune_pass()
|
| 121 |
+
pm.run(mod)
|
| 122 |
+
return mod
|
| 123 |
+
|
| 124 |
+
def check(self, mod, expected, nodes):
|
| 125 |
+
# preprocess incref/decref locations
|
| 126 |
+
d = {}
|
| 127 |
+
for k, vs in nodes.items():
|
| 128 |
+
n_incref = vs.count('incref')
|
| 129 |
+
n_decref = vs.count('decref')
|
| 130 |
+
d[k] = {'incref': n_incref, 'decref': n_decref}
|
| 131 |
+
for k, stats in d.items():
|
| 132 |
+
if expected.get(k):
|
| 133 |
+
stats['incref'] -= 1
|
| 134 |
+
for dec_bb in expected[k]:
|
| 135 |
+
d[dec_bb]['decref'] -= 1
|
| 136 |
+
|
| 137 |
+
# find the main function
|
| 138 |
+
for f in mod.functions:
|
| 139 |
+
if f.name == 'main':
|
| 140 |
+
break
|
| 141 |
+
# check each BB
|
| 142 |
+
for bb in f.blocks:
|
| 143 |
+
stats = d[bb.name]
|
| 144 |
+
text = str(bb)
|
| 145 |
+
n_incref = text.count('NRT_incref')
|
| 146 |
+
n_decref = text.count('NRT_decref')
|
| 147 |
+
self.assertEqual(stats['incref'], n_incref, msg=f'BB {bb}')
|
| 148 |
+
self.assertEqual(stats['decref'], n_decref, msg=f'BB {bb}')
|
| 149 |
+
|
| 150 |
+
def generate_test(self, case_gen):
|
| 151 |
+
nodes, edges, expected = case_gen()
|
| 152 |
+
irmod = self.generate_ir(nodes, edges)
|
| 153 |
+
outmod = self.apply_refprune(irmod)
|
| 154 |
+
self.check(outmod, expected, nodes)
|
| 155 |
+
|
| 156 |
+
# Generate tests
|
| 157 |
+
for name, case in _iterate_cases(generate_test):
|
| 158 |
+
locals()[name] = case
|
| 159 |
+
|
| 160 |
+
|
| 161 |
+
class BaseTestByIR(TestCase):
|
| 162 |
+
refprune_bitmask = 0
|
| 163 |
+
|
| 164 |
+
prologue = r"""
|
| 165 |
+
declare void @NRT_incref(i8* %ptr)
|
| 166 |
+
declare void @NRT_decref(i8* %ptr)
|
| 167 |
+
"""
|
| 168 |
+
|
| 169 |
+
def check(self, irmod, subgraph_limit=None):
|
| 170 |
+
mod = llvm.parse_assembly(f"{self.prologue}\n{irmod}")
|
| 171 |
+
pm = llvm.ModulePassManager()
|
| 172 |
+
if subgraph_limit is None:
|
| 173 |
+
pm.add_refprune_pass(self.refprune_bitmask)
|
| 174 |
+
else:
|
| 175 |
+
pm.add_refprune_pass(self.refprune_bitmask,
|
| 176 |
+
subgraph_limit=subgraph_limit)
|
| 177 |
+
before = llvm.dump_refprune_stats()
|
| 178 |
+
pm.run(mod)
|
| 179 |
+
after = llvm.dump_refprune_stats()
|
| 180 |
+
return mod, after - before
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
class TestPerBB(BaseTestByIR):
|
| 184 |
+
refprune_bitmask = llvm.RefPruneSubpasses.PER_BB
|
| 185 |
+
|
| 186 |
+
per_bb_ir_1 = r"""
|
| 187 |
+
define void @main(i8* %ptr) {
|
| 188 |
+
call void @NRT_incref(i8* %ptr)
|
| 189 |
+
call void @NRT_decref(i8* %ptr)
|
| 190 |
+
ret void
|
| 191 |
+
}
|
| 192 |
+
"""
|
| 193 |
+
|
| 194 |
+
def test_per_bb_1(self):
|
| 195 |
+
mod, stats = self.check(self.per_bb_ir_1)
|
| 196 |
+
self.assertEqual(stats.basicblock, 2)
|
| 197 |
+
|
| 198 |
+
per_bb_ir_2 = r"""
|
| 199 |
+
define void @main(i8* %ptr) {
|
| 200 |
+
call void @NRT_incref(i8* %ptr)
|
| 201 |
+
call void @NRT_incref(i8* %ptr)
|
| 202 |
+
call void @NRT_incref(i8* %ptr)
|
| 203 |
+
call void @NRT_decref(i8* %ptr)
|
| 204 |
+
call void @NRT_decref(i8* %ptr)
|
| 205 |
+
ret void
|
| 206 |
+
}
|
| 207 |
+
"""
|
| 208 |
+
|
| 209 |
+
def test_per_bb_2(self):
|
| 210 |
+
mod, stats = self.check(self.per_bb_ir_2)
|
| 211 |
+
self.assertEqual(stats.basicblock, 4)
|
| 212 |
+
# not pruned
|
| 213 |
+
self.assertIn("call void @NRT_incref(i8* %ptr)", str(mod))
|
| 214 |
+
|
| 215 |
+
per_bb_ir_3 = r"""
|
| 216 |
+
define void @main(i8* %ptr, i8* %other) {
|
| 217 |
+
call void @NRT_incref(i8* %ptr)
|
| 218 |
+
call void @NRT_incref(i8* %ptr)
|
| 219 |
+
call void @NRT_decref(i8* %ptr)
|
| 220 |
+
call void @NRT_decref(i8* %other)
|
| 221 |
+
ret void
|
| 222 |
+
}
|
| 223 |
+
"""
|
| 224 |
+
|
| 225 |
+
def test_per_bb_3(self):
|
| 226 |
+
mod, stats = self.check(self.per_bb_ir_3)
|
| 227 |
+
self.assertEqual(stats.basicblock, 2)
|
| 228 |
+
# not pruned
|
| 229 |
+
self.assertIn("call void @NRT_decref(i8* %other)", str(mod))
|
| 230 |
+
|
| 231 |
+
per_bb_ir_4 = r"""
|
| 232 |
+
; reordered
|
| 233 |
+
define void @main(i8* %ptr, i8* %other) {
|
| 234 |
+
call void @NRT_incref(i8* %ptr)
|
| 235 |
+
call void @NRT_decref(i8* %ptr)
|
| 236 |
+
call void @NRT_decref(i8* %ptr)
|
| 237 |
+
call void @NRT_decref(i8* %other)
|
| 238 |
+
call void @NRT_incref(i8* %ptr)
|
| 239 |
+
ret void
|
| 240 |
+
}
|
| 241 |
+
"""
|
| 242 |
+
|
| 243 |
+
def test_per_bb_4(self):
|
| 244 |
+
mod, stats = self.check(self.per_bb_ir_4)
|
| 245 |
+
self.assertEqual(stats.basicblock, 4)
|
| 246 |
+
# not pruned
|
| 247 |
+
self.assertIn("call void @NRT_decref(i8* %other)", str(mod))
|
| 248 |
+
|
| 249 |
+
|
| 250 |
+
class TestDiamond(BaseTestByIR):
|
| 251 |
+
refprune_bitmask = llvm.RefPruneSubpasses.DIAMOND
|
| 252 |
+
|
| 253 |
+
per_diamond_1 = r"""
|
| 254 |
+
define void @main(i8* %ptr) {
|
| 255 |
+
bb_A:
|
| 256 |
+
call void @NRT_incref(i8* %ptr)
|
| 257 |
+
br label %bb_B
|
| 258 |
+
bb_B:
|
| 259 |
+
call void @NRT_decref(i8* %ptr)
|
| 260 |
+
ret void
|
| 261 |
+
}
|
| 262 |
+
"""
|
| 263 |
+
|
| 264 |
+
def test_per_diamond_1(self):
|
| 265 |
+
mod, stats = self.check(self.per_diamond_1)
|
| 266 |
+
self.assertEqual(stats.diamond, 2)
|
| 267 |
+
|
| 268 |
+
per_diamond_2 = r"""
|
| 269 |
+
define void @main(i8* %ptr, i1 %cond) {
|
| 270 |
+
bb_A:
|
| 271 |
+
call void @NRT_incref(i8* %ptr)
|
| 272 |
+
br i1 %cond, label %bb_B, label %bb_C
|
| 273 |
+
bb_B:
|
| 274 |
+
br label %bb_D
|
| 275 |
+
bb_C:
|
| 276 |
+
br label %bb_D
|
| 277 |
+
bb_D:
|
| 278 |
+
call void @NRT_decref(i8* %ptr)
|
| 279 |
+
ret void
|
| 280 |
+
}
|
| 281 |
+
"""
|
| 282 |
+
|
| 283 |
+
def test_per_diamond_2(self):
|
| 284 |
+
mod, stats = self.check(self.per_diamond_2)
|
| 285 |
+
self.assertEqual(stats.diamond, 2)
|
| 286 |
+
|
| 287 |
+
per_diamond_3 = r"""
|
| 288 |
+
define void @main(i8* %ptr, i1 %cond) {
|
| 289 |
+
bb_A:
|
| 290 |
+
call void @NRT_incref(i8* %ptr)
|
| 291 |
+
br i1 %cond, label %bb_B, label %bb_C
|
| 292 |
+
bb_B:
|
| 293 |
+
br label %bb_D
|
| 294 |
+
bb_C:
|
| 295 |
+
call void @NRT_decref(i8* %ptr) ; reject because of decref in diamond
|
| 296 |
+
br label %bb_D
|
| 297 |
+
bb_D:
|
| 298 |
+
call void @NRT_decref(i8* %ptr)
|
| 299 |
+
ret void
|
| 300 |
+
}
|
| 301 |
+
"""
|
| 302 |
+
|
| 303 |
+
def test_per_diamond_3(self):
|
| 304 |
+
mod, stats = self.check(self.per_diamond_3)
|
| 305 |
+
self.assertEqual(stats.diamond, 0)
|
| 306 |
+
|
| 307 |
+
per_diamond_4 = r"""
|
| 308 |
+
define void @main(i8* %ptr, i1 %cond) {
|
| 309 |
+
bb_A:
|
| 310 |
+
call void @NRT_incref(i8* %ptr)
|
| 311 |
+
br i1 %cond, label %bb_B, label %bb_C
|
| 312 |
+
bb_B:
|
| 313 |
+
call void @NRT_incref(i8* %ptr) ; extra incref will not affect prune
|
| 314 |
+
br label %bb_D
|
| 315 |
+
bb_C:
|
| 316 |
+
br label %bb_D
|
| 317 |
+
bb_D:
|
| 318 |
+
call void @NRT_decref(i8* %ptr)
|
| 319 |
+
ret void
|
| 320 |
+
}
|
| 321 |
+
"""
|
| 322 |
+
|
| 323 |
+
def test_per_diamond_4(self):
|
| 324 |
+
mod, stats = self.check(self.per_diamond_4)
|
| 325 |
+
self.assertEqual(stats.diamond, 2)
|
| 326 |
+
|
| 327 |
+
per_diamond_5 = r"""
|
| 328 |
+
define void @main(i8* %ptr, i1 %cond) {
|
| 329 |
+
bb_A:
|
| 330 |
+
call void @NRT_incref(i8* %ptr)
|
| 331 |
+
call void @NRT_incref(i8* %ptr)
|
| 332 |
+
br i1 %cond, label %bb_B, label %bb_C
|
| 333 |
+
bb_B:
|
| 334 |
+
br label %bb_D
|
| 335 |
+
bb_C:
|
| 336 |
+
br label %bb_D
|
| 337 |
+
bb_D:
|
| 338 |
+
call void @NRT_decref(i8* %ptr)
|
| 339 |
+
call void @NRT_decref(i8* %ptr)
|
| 340 |
+
ret void
|
| 341 |
+
}
|
| 342 |
+
"""
|
| 343 |
+
|
| 344 |
+
def test_per_diamond_5(self):
|
| 345 |
+
mod, stats = self.check(self.per_diamond_5)
|
| 346 |
+
self.assertEqual(stats.diamond, 4)
|
| 347 |
+
|
| 348 |
+
|
| 349 |
+
class TestFanout(BaseTestByIR):
|
| 350 |
+
"""More complex cases are tested in TestRefPrunePass
|
| 351 |
+
"""
|
| 352 |
+
|
| 353 |
+
refprune_bitmask = llvm.RefPruneSubpasses.FANOUT
|
| 354 |
+
|
| 355 |
+
fanout_1 = r"""
|
| 356 |
+
define void @main(i8* %ptr, i1 %cond) {
|
| 357 |
+
bb_A:
|
| 358 |
+
call void @NRT_incref(i8* %ptr)
|
| 359 |
+
br i1 %cond, label %bb_B, label %bb_C
|
| 360 |
+
bb_B:
|
| 361 |
+
call void @NRT_decref(i8* %ptr)
|
| 362 |
+
ret void
|
| 363 |
+
bb_C:
|
| 364 |
+
call void @NRT_decref(i8* %ptr)
|
| 365 |
+
ret void
|
| 366 |
+
}
|
| 367 |
+
"""
|
| 368 |
+
|
| 369 |
+
def test_fanout_1(self):
|
| 370 |
+
mod, stats = self.check(self.fanout_1)
|
| 371 |
+
self.assertEqual(stats.fanout, 3)
|
| 372 |
+
|
| 373 |
+
fanout_2 = r"""
|
| 374 |
+
define void @main(i8* %ptr, i1 %cond, i8** %excinfo) {
|
| 375 |
+
bb_A:
|
| 376 |
+
call void @NRT_incref(i8* %ptr)
|
| 377 |
+
br i1 %cond, label %bb_B, label %bb_C
|
| 378 |
+
bb_B:
|
| 379 |
+
call void @NRT_decref(i8* %ptr)
|
| 380 |
+
ret void
|
| 381 |
+
bb_C:
|
| 382 |
+
call void @NRT_decref(i8* %ptr)
|
| 383 |
+
br label %bb_B ; illegal jump to other decref
|
| 384 |
+
}
|
| 385 |
+
"""
|
| 386 |
+
|
| 387 |
+
def test_fanout_2(self):
|
| 388 |
+
mod, stats = self.check(self.fanout_2)
|
| 389 |
+
self.assertEqual(stats.fanout, 0)
|
| 390 |
+
|
| 391 |
+
fanout_3 = r"""
|
| 392 |
+
define void @main(i8* %ptr, i1 %cond) {
|
| 393 |
+
bb_A:
|
| 394 |
+
call void @NRT_incref(i8* %ptr)
|
| 395 |
+
call void @NRT_incref(i8* %ptr)
|
| 396 |
+
br i1 %cond, label %bb_B, label %bb_C
|
| 397 |
+
bb_B:
|
| 398 |
+
call void @NRT_decref(i8* %ptr)
|
| 399 |
+
call void @NRT_decref(i8* %ptr)
|
| 400 |
+
call void @NRT_decref(i8* %ptr)
|
| 401 |
+
ret void
|
| 402 |
+
bb_C:
|
| 403 |
+
call void @NRT_decref(i8* %ptr)
|
| 404 |
+
call void @NRT_decref(i8* %ptr)
|
| 405 |
+
ret void
|
| 406 |
+
}
|
| 407 |
+
"""
|
| 408 |
+
|
| 409 |
+
def test_fanout_3(self):
|
| 410 |
+
mod, stats = self.check(self.fanout_3)
|
| 411 |
+
self.assertEqual(stats.fanout, 6)
|
| 412 |
+
|
| 413 |
+
def test_fanout_3_limited(self):
|
| 414 |
+
# With subgraph limit at 1, it is essentially turning off the fanout
|
| 415 |
+
# pruner.
|
| 416 |
+
mod, stats = self.check(self.fanout_3, subgraph_limit=1)
|
| 417 |
+
self.assertEqual(stats.fanout, 0)
|
| 418 |
+
|
| 419 |
+
|
| 420 |
+
class TestFanoutRaise(BaseTestByIR):
|
| 421 |
+
refprune_bitmask = llvm.RefPruneSubpasses.FANOUT_RAISE
|
| 422 |
+
|
| 423 |
+
fanout_raise_1 = r"""
|
| 424 |
+
define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
|
| 425 |
+
bb_A:
|
| 426 |
+
call void @NRT_incref(i8* %ptr)
|
| 427 |
+
br i1 %cond, label %bb_B, label %bb_C
|
| 428 |
+
bb_B:
|
| 429 |
+
call void @NRT_decref(i8* %ptr)
|
| 430 |
+
ret i32 0
|
| 431 |
+
bb_C:
|
| 432 |
+
store i8* null, i8** %excinfo, !numba_exception_output !0
|
| 433 |
+
ret i32 1
|
| 434 |
+
}
|
| 435 |
+
!0 = !{i1 true}
|
| 436 |
+
"""
|
| 437 |
+
|
| 438 |
+
def test_fanout_raise_1(self):
|
| 439 |
+
mod, stats = self.check(self.fanout_raise_1)
|
| 440 |
+
self.assertEqual(stats.fanout_raise, 2)
|
| 441 |
+
|
| 442 |
+
fanout_raise_2 = r"""
|
| 443 |
+
define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
|
| 444 |
+
bb_A:
|
| 445 |
+
call void @NRT_incref(i8* %ptr)
|
| 446 |
+
br i1 %cond, label %bb_B, label %bb_C
|
| 447 |
+
bb_B:
|
| 448 |
+
call void @NRT_decref(i8* %ptr)
|
| 449 |
+
ret i32 0
|
| 450 |
+
bb_C:
|
| 451 |
+
store i8* null, i8** %excinfo, !numba_exception_typo !0 ; bad metadata
|
| 452 |
+
ret i32 1
|
| 453 |
+
}
|
| 454 |
+
|
| 455 |
+
!0 = !{i1 true}
|
| 456 |
+
"""
|
| 457 |
+
|
| 458 |
+
def test_fanout_raise_2(self):
|
| 459 |
+
# This is ensuring that fanout_raise is not pruning when the metadata
|
| 460 |
+
# is incorrectly named.
|
| 461 |
+
mod, stats = self.check(self.fanout_raise_2)
|
| 462 |
+
self.assertEqual(stats.fanout_raise, 0)
|
| 463 |
+
|
| 464 |
+
fanout_raise_3 = r"""
|
| 465 |
+
define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
|
| 466 |
+
bb_A:
|
| 467 |
+
call void @NRT_incref(i8* %ptr)
|
| 468 |
+
br i1 %cond, label %bb_B, label %bb_C
|
| 469 |
+
bb_B:
|
| 470 |
+
call void @NRT_decref(i8* %ptr)
|
| 471 |
+
ret i32 0
|
| 472 |
+
bb_C:
|
| 473 |
+
store i8* null, i8** %excinfo, !numba_exception_output !0
|
| 474 |
+
ret i32 1
|
| 475 |
+
}
|
| 476 |
+
|
| 477 |
+
!0 = !{i32 1} ; ok; use i32
|
| 478 |
+
"""
|
| 479 |
+
|
| 480 |
+
def test_fanout_raise_3(self):
|
| 481 |
+
mod, stats = self.check(self.fanout_raise_3)
|
| 482 |
+
self.assertEqual(stats.fanout_raise, 2)
|
| 483 |
+
|
| 484 |
+
fanout_raise_4 = r"""
|
| 485 |
+
define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
|
| 486 |
+
bb_A:
|
| 487 |
+
call void @NRT_incref(i8* %ptr)
|
| 488 |
+
br i1 %cond, label %bb_B, label %bb_C
|
| 489 |
+
bb_B:
|
| 490 |
+
ret i32 1 ; BAD; all tails are raising without decref
|
| 491 |
+
bb_C:
|
| 492 |
+
ret i32 1 ; BAD; all tails are raising without decref
|
| 493 |
+
}
|
| 494 |
+
|
| 495 |
+
!0 = !{i1 1}
|
| 496 |
+
"""
|
| 497 |
+
|
| 498 |
+
def test_fanout_raise_4(self):
|
| 499 |
+
mod, stats = self.check(self.fanout_raise_4)
|
| 500 |
+
self.assertEqual(stats.fanout_raise, 0)
|
| 501 |
+
|
| 502 |
+
fanout_raise_5 = r"""
|
| 503 |
+
define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
|
| 504 |
+
bb_A:
|
| 505 |
+
call void @NRT_incref(i8* %ptr)
|
| 506 |
+
br i1 %cond, label %bb_B, label %bb_C
|
| 507 |
+
bb_B:
|
| 508 |
+
call void @NRT_decref(i8* %ptr)
|
| 509 |
+
br label %common.ret
|
| 510 |
+
bb_C:
|
| 511 |
+
store i8* null, i8** %excinfo, !numba_exception_output !0
|
| 512 |
+
br label %common.ret
|
| 513 |
+
common.ret:
|
| 514 |
+
%common.ret.op = phi i32 [ 0, %bb_B ], [ 1, %bb_C ]
|
| 515 |
+
ret i32 %common.ret.op
|
| 516 |
+
}
|
| 517 |
+
!0 = !{i1 1}
|
| 518 |
+
"""
|
| 519 |
+
|
| 520 |
+
def test_fanout_raise_5(self):
|
| 521 |
+
mod, stats = self.check(self.fanout_raise_5)
|
| 522 |
+
self.assertEqual(stats.fanout_raise, 2)
|
| 523 |
+
|
| 524 |
+
|
| 525 |
+
if __name__ == '__main__':
|
| 526 |
+
unittest.main()
|
lib/python3.11/site-packages/llvmlite/tests/test_valuerepr.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import math
|
| 2 |
+
import sys
|
| 3 |
+
import unittest
|
| 4 |
+
|
| 5 |
+
from llvmlite.ir import (
|
| 6 |
+
Constant, FloatType, DoubleType, LiteralStructType, IntType,
|
| 7 |
+
ArrayType, HalfType)
|
| 8 |
+
from llvmlite.tests import TestCase
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
int8 = IntType(8)
|
| 12 |
+
int16 = IntType(16)
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
PY36_OR_LATER = sys.version_info[:2] >= (3, 6)
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
class TestValueRepr(TestCase):
|
| 19 |
+
|
| 20 |
+
def test_double_repr(self):
|
| 21 |
+
def check_repr(val, expected):
|
| 22 |
+
c = Constant(DoubleType(), val)
|
| 23 |
+
self.assertEqual(str(c), expected)
|
| 24 |
+
check_repr(math.pi, "double 0x400921fb54442d18")
|
| 25 |
+
check_repr(float('inf'), "double 0x7ff0000000000000")
|
| 26 |
+
check_repr(float('-inf'), "double 0xfff0000000000000")
|
| 27 |
+
|
| 28 |
+
def test_float_repr(self):
|
| 29 |
+
def check_repr(val, expected):
|
| 30 |
+
c = Constant(FloatType(), val)
|
| 31 |
+
self.assertEqual(str(c), expected)
|
| 32 |
+
check_repr(math.pi, "float 0x400921fb60000000")
|
| 33 |
+
check_repr(float('inf'), "float 0x7ff0000000000000")
|
| 34 |
+
check_repr(float('-inf'), "float 0xfff0000000000000")
|
| 35 |
+
|
| 36 |
+
@unittest.skipUnless(PY36_OR_LATER, 'py36+ only')
|
| 37 |
+
def test_half_repr(self):
|
| 38 |
+
def check_repr(val, expected):
|
| 39 |
+
c = Constant(HalfType(), val)
|
| 40 |
+
self.assertEqual(str(c), expected)
|
| 41 |
+
check_repr(math.pi, "half 0x4009200000000000")
|
| 42 |
+
check_repr(float('inf'), "half 0x7ff0000000000000")
|
| 43 |
+
check_repr(float('-inf'), "half 0xfff0000000000000")
|
| 44 |
+
|
| 45 |
+
def test_struct_repr(self):
|
| 46 |
+
tp = LiteralStructType([int8, int16])
|
| 47 |
+
c = Constant(tp, (Constant(int8, 100), Constant(int16, 1000)))
|
| 48 |
+
self.assertEqual(str(c), "{i8, i16} {i8 100, i16 1000}")
|
| 49 |
+
|
| 50 |
+
def test_array_repr(self):
|
| 51 |
+
tp = ArrayType(int8, 3)
|
| 52 |
+
values = [Constant(int8, x) for x in (5, 10, -15)]
|
| 53 |
+
c = Constant(tp, values)
|
| 54 |
+
self.assertEqual(str(c), "[3 x i8] [i8 5, i8 10, i8 -15]")
|
| 55 |
+
c = Constant(tp, bytearray(b"\x01\x02\x03"))
|
| 56 |
+
self.assertEqual(str(c), '[3 x i8] c"\\01\\02\\03"')
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
if __name__ == "__main__":
|
| 60 |
+
unittest.main()
|
lib/python3.11/site-packages/llvmlite/utils.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import sys
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
# This module must be importable without loading the binding, to avoid
|
| 6 |
+
# bootstrapping issues in setup.py.
|
| 7 |
+
|
| 8 |
+
def get_library_name():
|
| 9 |
+
"""
|
| 10 |
+
Return the name of the llvmlite shared library file.
|
| 11 |
+
"""
|
| 12 |
+
if os.name == 'posix':
|
| 13 |
+
if sys.platform == 'darwin':
|
| 14 |
+
return 'libllvmlite.dylib'
|
| 15 |
+
else:
|
| 16 |
+
return 'libllvmlite.so'
|
| 17 |
+
else:
|
| 18 |
+
assert os.name == 'nt'
|
| 19 |
+
return 'llvmlite.dll'
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def get_library_files():
|
| 23 |
+
"""
|
| 24 |
+
Return the names of shared library files needed for this platform.
|
| 25 |
+
"""
|
| 26 |
+
files = [get_library_name()]
|
| 27 |
+
if os.name == 'nt':
|
| 28 |
+
files.extend(['msvcr120.dll', 'msvcp120.dll'])
|
| 29 |
+
return files
|
lib/python3.11/site-packages/markupsafe/__init__.py
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import functools
|
| 2 |
+
import re
|
| 3 |
+
import string
|
| 4 |
+
import sys
|
| 5 |
+
import typing as t
|
| 6 |
+
|
| 7 |
+
if t.TYPE_CHECKING:
|
| 8 |
+
import typing_extensions as te
|
| 9 |
+
|
| 10 |
+
class HasHTML(te.Protocol):
|
| 11 |
+
def __html__(self) -> str:
|
| 12 |
+
pass
|
| 13 |
+
|
| 14 |
+
_P = te.ParamSpec("_P")
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
__version__ = "2.1.3"
|
| 18 |
+
|
| 19 |
+
_strip_comments_re = re.compile(r"<!--.*?-->", re.DOTALL)
|
| 20 |
+
_strip_tags_re = re.compile(r"<.*?>", re.DOTALL)
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def _simple_escaping_wrapper(func: "t.Callable[_P, str]") -> "t.Callable[_P, Markup]":
|
| 24 |
+
@functools.wraps(func)
|
| 25 |
+
def wrapped(self: "Markup", *args: "_P.args", **kwargs: "_P.kwargs") -> "Markup":
|
| 26 |
+
arg_list = _escape_argspec(list(args), enumerate(args), self.escape)
|
| 27 |
+
_escape_argspec(kwargs, kwargs.items(), self.escape)
|
| 28 |
+
return self.__class__(func(self, *arg_list, **kwargs)) # type: ignore[arg-type]
|
| 29 |
+
|
| 30 |
+
return wrapped # type: ignore[return-value]
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
class Markup(str):
|
| 34 |
+
"""A string that is ready to be safely inserted into an HTML or XML
|
| 35 |
+
document, either because it was escaped or because it was marked
|
| 36 |
+
safe.
|
| 37 |
+
|
| 38 |
+
Passing an object to the constructor converts it to text and wraps
|
| 39 |
+
it to mark it safe without escaping. To escape the text, use the
|
| 40 |
+
:meth:`escape` class method instead.
|
| 41 |
+
|
| 42 |
+
>>> Markup("Hello, <em>World</em>!")
|
| 43 |
+
Markup('Hello, <em>World</em>!')
|
| 44 |
+
>>> Markup(42)
|
| 45 |
+
Markup('42')
|
| 46 |
+
>>> Markup.escape("Hello, <em>World</em>!")
|
| 47 |
+
Markup('Hello <em>World</em>!')
|
| 48 |
+
|
| 49 |
+
This implements the ``__html__()`` interface that some frameworks
|
| 50 |
+
use. Passing an object that implements ``__html__()`` will wrap the
|
| 51 |
+
output of that method, marking it safe.
|
| 52 |
+
|
| 53 |
+
>>> class Foo:
|
| 54 |
+
... def __html__(self):
|
| 55 |
+
... return '<a href="/foo">foo</a>'
|
| 56 |
+
...
|
| 57 |
+
>>> Markup(Foo())
|
| 58 |
+
Markup('<a href="/foo">foo</a>')
|
| 59 |
+
|
| 60 |
+
This is a subclass of :class:`str`. It has the same methods, but
|
| 61 |
+
escapes their arguments and returns a ``Markup`` instance.
|
| 62 |
+
|
| 63 |
+
>>> Markup("<em>%s</em>") % ("foo & bar",)
|
| 64 |
+
Markup('<em>foo & bar</em>')
|
| 65 |
+
>>> Markup("<em>Hello</em> ") + "<foo>"
|
| 66 |
+
Markup('<em>Hello</em> <foo>')
|
| 67 |
+
"""
|
| 68 |
+
|
| 69 |
+
__slots__ = ()
|
| 70 |
+
|
| 71 |
+
def __new__(
|
| 72 |
+
cls, base: t.Any = "", encoding: t.Optional[str] = None, errors: str = "strict"
|
| 73 |
+
) -> "te.Self":
|
| 74 |
+
if hasattr(base, "__html__"):
|
| 75 |
+
base = base.__html__()
|
| 76 |
+
|
| 77 |
+
if encoding is None:
|
| 78 |
+
return super().__new__(cls, base)
|
| 79 |
+
|
| 80 |
+
return super().__new__(cls, base, encoding, errors)
|
| 81 |
+
|
| 82 |
+
def __html__(self) -> "te.Self":
|
| 83 |
+
return self
|
| 84 |
+
|
| 85 |
+
def __add__(self, other: t.Union[str, "HasHTML"]) -> "te.Self":
|
| 86 |
+
if isinstance(other, str) or hasattr(other, "__html__"):
|
| 87 |
+
return self.__class__(super().__add__(self.escape(other)))
|
| 88 |
+
|
| 89 |
+
return NotImplemented
|
| 90 |
+
|
| 91 |
+
def __radd__(self, other: t.Union[str, "HasHTML"]) -> "te.Self":
|
| 92 |
+
if isinstance(other, str) or hasattr(other, "__html__"):
|
| 93 |
+
return self.escape(other).__add__(self)
|
| 94 |
+
|
| 95 |
+
return NotImplemented
|
| 96 |
+
|
| 97 |
+
def __mul__(self, num: "te.SupportsIndex") -> "te.Self":
|
| 98 |
+
if isinstance(num, int):
|
| 99 |
+
return self.__class__(super().__mul__(num))
|
| 100 |
+
|
| 101 |
+
return NotImplemented
|
| 102 |
+
|
| 103 |
+
__rmul__ = __mul__
|
| 104 |
+
|
| 105 |
+
def __mod__(self, arg: t.Any) -> "te.Self":
|
| 106 |
+
if isinstance(arg, tuple):
|
| 107 |
+
# a tuple of arguments, each wrapped
|
| 108 |
+
arg = tuple(_MarkupEscapeHelper(x, self.escape) for x in arg)
|
| 109 |
+
elif hasattr(type(arg), "__getitem__") and not isinstance(arg, str):
|
| 110 |
+
# a mapping of arguments, wrapped
|
| 111 |
+
arg = _MarkupEscapeHelper(arg, self.escape)
|
| 112 |
+
else:
|
| 113 |
+
# a single argument, wrapped with the helper and a tuple
|
| 114 |
+
arg = (_MarkupEscapeHelper(arg, self.escape),)
|
| 115 |
+
|
| 116 |
+
return self.__class__(super().__mod__(arg))
|
| 117 |
+
|
| 118 |
+
def __repr__(self) -> str:
|
| 119 |
+
return f"{self.__class__.__name__}({super().__repr__()})"
|
| 120 |
+
|
| 121 |
+
def join(self, seq: t.Iterable[t.Union[str, "HasHTML"]]) -> "te.Self":
|
| 122 |
+
return self.__class__(super().join(map(self.escape, seq)))
|
| 123 |
+
|
| 124 |
+
join.__doc__ = str.join.__doc__
|
| 125 |
+
|
| 126 |
+
def split( # type: ignore[override]
|
| 127 |
+
self, sep: t.Optional[str] = None, maxsplit: int = -1
|
| 128 |
+
) -> t.List["te.Self"]:
|
| 129 |
+
return [self.__class__(v) for v in super().split(sep, maxsplit)]
|
| 130 |
+
|
| 131 |
+
split.__doc__ = str.split.__doc__
|
| 132 |
+
|
| 133 |
+
def rsplit( # type: ignore[override]
|
| 134 |
+
self, sep: t.Optional[str] = None, maxsplit: int = -1
|
| 135 |
+
) -> t.List["te.Self"]:
|
| 136 |
+
return [self.__class__(v) for v in super().rsplit(sep, maxsplit)]
|
| 137 |
+
|
| 138 |
+
rsplit.__doc__ = str.rsplit.__doc__
|
| 139 |
+
|
| 140 |
+
def splitlines( # type: ignore[override]
|
| 141 |
+
self, keepends: bool = False
|
| 142 |
+
) -> t.List["te.Self"]:
|
| 143 |
+
return [self.__class__(v) for v in super().splitlines(keepends)]
|
| 144 |
+
|
| 145 |
+
splitlines.__doc__ = str.splitlines.__doc__
|
| 146 |
+
|
| 147 |
+
def unescape(self) -> str:
|
| 148 |
+
"""Convert escaped markup back into a text string. This replaces
|
| 149 |
+
HTML entities with the characters they represent.
|
| 150 |
+
|
| 151 |
+
>>> Markup("Main » <em>About</em>").unescape()
|
| 152 |
+
'Main » <em>About</em>'
|
| 153 |
+
"""
|
| 154 |
+
from html import unescape
|
| 155 |
+
|
| 156 |
+
return unescape(str(self))
|
| 157 |
+
|
| 158 |
+
def striptags(self) -> str:
|
| 159 |
+
""":meth:`unescape` the markup, remove tags, and normalize
|
| 160 |
+
whitespace to single spaces.
|
| 161 |
+
|
| 162 |
+
>>> Markup("Main »\t<em>About</em>").striptags()
|
| 163 |
+
'Main » About'
|
| 164 |
+
"""
|
| 165 |
+
# Use two regexes to avoid ambiguous matches.
|
| 166 |
+
value = _strip_comments_re.sub("", self)
|
| 167 |
+
value = _strip_tags_re.sub("", value)
|
| 168 |
+
value = " ".join(value.split())
|
| 169 |
+
return self.__class__(value).unescape()
|
| 170 |
+
|
| 171 |
+
@classmethod
|
| 172 |
+
def escape(cls, s: t.Any) -> "te.Self":
|
| 173 |
+
"""Escape a string. Calls :func:`escape` and ensures that for
|
| 174 |
+
subclasses the correct type is returned.
|
| 175 |
+
"""
|
| 176 |
+
rv = escape(s)
|
| 177 |
+
|
| 178 |
+
if rv.__class__ is not cls:
|
| 179 |
+
return cls(rv)
|
| 180 |
+
|
| 181 |
+
return rv # type: ignore[return-value]
|
| 182 |
+
|
| 183 |
+
__getitem__ = _simple_escaping_wrapper(str.__getitem__)
|
| 184 |
+
capitalize = _simple_escaping_wrapper(str.capitalize)
|
| 185 |
+
title = _simple_escaping_wrapper(str.title)
|
| 186 |
+
lower = _simple_escaping_wrapper(str.lower)
|
| 187 |
+
upper = _simple_escaping_wrapper(str.upper)
|
| 188 |
+
replace = _simple_escaping_wrapper(str.replace)
|
| 189 |
+
ljust = _simple_escaping_wrapper(str.ljust)
|
| 190 |
+
rjust = _simple_escaping_wrapper(str.rjust)
|
| 191 |
+
lstrip = _simple_escaping_wrapper(str.lstrip)
|
| 192 |
+
rstrip = _simple_escaping_wrapper(str.rstrip)
|
| 193 |
+
center = _simple_escaping_wrapper(str.center)
|
| 194 |
+
strip = _simple_escaping_wrapper(str.strip)
|
| 195 |
+
translate = _simple_escaping_wrapper(str.translate)
|
| 196 |
+
expandtabs = _simple_escaping_wrapper(str.expandtabs)
|
| 197 |
+
swapcase = _simple_escaping_wrapper(str.swapcase)
|
| 198 |
+
zfill = _simple_escaping_wrapper(str.zfill)
|
| 199 |
+
casefold = _simple_escaping_wrapper(str.casefold)
|
| 200 |
+
|
| 201 |
+
if sys.version_info >= (3, 9):
|
| 202 |
+
removeprefix = _simple_escaping_wrapper(str.removeprefix)
|
| 203 |
+
removesuffix = _simple_escaping_wrapper(str.removesuffix)
|
| 204 |
+
|
| 205 |
+
def partition(self, sep: str) -> t.Tuple["te.Self", "te.Self", "te.Self"]:
|
| 206 |
+
l, s, r = super().partition(self.escape(sep))
|
| 207 |
+
cls = self.__class__
|
| 208 |
+
return cls(l), cls(s), cls(r)
|
| 209 |
+
|
| 210 |
+
def rpartition(self, sep: str) -> t.Tuple["te.Self", "te.Self", "te.Self"]:
|
| 211 |
+
l, s, r = super().rpartition(self.escape(sep))
|
| 212 |
+
cls = self.__class__
|
| 213 |
+
return cls(l), cls(s), cls(r)
|
| 214 |
+
|
| 215 |
+
def format(self, *args: t.Any, **kwargs: t.Any) -> "te.Self":
|
| 216 |
+
formatter = EscapeFormatter(self.escape)
|
| 217 |
+
return self.__class__(formatter.vformat(self, args, kwargs))
|
| 218 |
+
|
| 219 |
+
def format_map( # type: ignore[override]
|
| 220 |
+
self, map: t.Mapping[str, t.Any]
|
| 221 |
+
) -> "te.Self":
|
| 222 |
+
formatter = EscapeFormatter(self.escape)
|
| 223 |
+
return self.__class__(formatter.vformat(self, (), map))
|
| 224 |
+
|
| 225 |
+
def __html_format__(self, format_spec: str) -> "te.Self":
|
| 226 |
+
if format_spec:
|
| 227 |
+
raise ValueError("Unsupported format specification for Markup.")
|
| 228 |
+
|
| 229 |
+
return self
|
| 230 |
+
|
| 231 |
+
|
| 232 |
+
class EscapeFormatter(string.Formatter):
|
| 233 |
+
__slots__ = ("escape",)
|
| 234 |
+
|
| 235 |
+
def __init__(self, escape: t.Callable[[t.Any], Markup]) -> None:
|
| 236 |
+
self.escape = escape
|
| 237 |
+
super().__init__()
|
| 238 |
+
|
| 239 |
+
def format_field(self, value: t.Any, format_spec: str) -> str:
|
| 240 |
+
if hasattr(value, "__html_format__"):
|
| 241 |
+
rv = value.__html_format__(format_spec)
|
| 242 |
+
elif hasattr(value, "__html__"):
|
| 243 |
+
if format_spec:
|
| 244 |
+
raise ValueError(
|
| 245 |
+
f"Format specifier {format_spec} given, but {type(value)} does not"
|
| 246 |
+
" define __html_format__. A class that defines __html__ must define"
|
| 247 |
+
" __html_format__ to work with format specifiers."
|
| 248 |
+
)
|
| 249 |
+
rv = value.__html__()
|
| 250 |
+
else:
|
| 251 |
+
# We need to make sure the format spec is str here as
|
| 252 |
+
# otherwise the wrong callback methods are invoked.
|
| 253 |
+
rv = string.Formatter.format_field(self, value, str(format_spec))
|
| 254 |
+
return str(self.escape(rv))
|
| 255 |
+
|
| 256 |
+
|
| 257 |
+
_ListOrDict = t.TypeVar("_ListOrDict", list, dict)
|
| 258 |
+
|
| 259 |
+
|
| 260 |
+
def _escape_argspec(
|
| 261 |
+
obj: _ListOrDict, iterable: t.Iterable[t.Any], escape: t.Callable[[t.Any], Markup]
|
| 262 |
+
) -> _ListOrDict:
|
| 263 |
+
"""Helper for various string-wrapped functions."""
|
| 264 |
+
for key, value in iterable:
|
| 265 |
+
if isinstance(value, str) or hasattr(value, "__html__"):
|
| 266 |
+
obj[key] = escape(value)
|
| 267 |
+
|
| 268 |
+
return obj
|
| 269 |
+
|
| 270 |
+
|
| 271 |
+
class _MarkupEscapeHelper:
|
| 272 |
+
"""Helper for :meth:`Markup.__mod__`."""
|
| 273 |
+
|
| 274 |
+
__slots__ = ("obj", "escape")
|
| 275 |
+
|
| 276 |
+
def __init__(self, obj: t.Any, escape: t.Callable[[t.Any], Markup]) -> None:
|
| 277 |
+
self.obj = obj
|
| 278 |
+
self.escape = escape
|
| 279 |
+
|
| 280 |
+
def __getitem__(self, item: t.Any) -> "te.Self":
|
| 281 |
+
return self.__class__(self.obj[item], self.escape)
|
| 282 |
+
|
| 283 |
+
def __str__(self) -> str:
|
| 284 |
+
return str(self.escape(self.obj))
|
| 285 |
+
|
| 286 |
+
def __repr__(self) -> str:
|
| 287 |
+
return str(self.escape(repr(self.obj)))
|
| 288 |
+
|
| 289 |
+
def __int__(self) -> int:
|
| 290 |
+
return int(self.obj)
|
| 291 |
+
|
| 292 |
+
def __float__(self) -> float:
|
| 293 |
+
return float(self.obj)
|
| 294 |
+
|
| 295 |
+
|
| 296 |
+
# circular import
|
| 297 |
+
try:
|
| 298 |
+
from ._speedups import escape as escape
|
| 299 |
+
from ._speedups import escape_silent as escape_silent
|
| 300 |
+
from ._speedups import soft_str as soft_str
|
| 301 |
+
except ImportError:
|
| 302 |
+
from ._native import escape as escape
|
| 303 |
+
from ._native import escape_silent as escape_silent # noqa: F401
|
| 304 |
+
from ._native import soft_str as soft_str # noqa: F401
|
lib/python3.11/site-packages/markupsafe/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (19.8 kB). View file
|
|
|
lib/python3.11/site-packages/markupsafe/__pycache__/_native.cpython-311.pyc
ADDED
|
Binary file (2.77 kB). View file
|
|
|
lib/python3.11/site-packages/markupsafe/_native.py
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import typing as t
|
| 2 |
+
|
| 3 |
+
from . import Markup
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
def escape(s: t.Any) -> Markup:
|
| 7 |
+
"""Replace the characters ``&``, ``<``, ``>``, ``'``, and ``"`` in
|
| 8 |
+
the string with HTML-safe sequences. Use this if you need to display
|
| 9 |
+
text that might contain such characters in HTML.
|
| 10 |
+
|
| 11 |
+
If the object has an ``__html__`` method, it is called and the
|
| 12 |
+
return value is assumed to already be safe for HTML.
|
| 13 |
+
|
| 14 |
+
:param s: An object to be converted to a string and escaped.
|
| 15 |
+
:return: A :class:`Markup` string with the escaped text.
|
| 16 |
+
"""
|
| 17 |
+
if hasattr(s, "__html__"):
|
| 18 |
+
return Markup(s.__html__())
|
| 19 |
+
|
| 20 |
+
return Markup(
|
| 21 |
+
str(s)
|
| 22 |
+
.replace("&", "&")
|
| 23 |
+
.replace(">", ">")
|
| 24 |
+
.replace("<", "<")
|
| 25 |
+
.replace("'", "'")
|
| 26 |
+
.replace('"', """)
|
| 27 |
+
)
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def escape_silent(s: t.Optional[t.Any]) -> Markup:
|
| 31 |
+
"""Like :func:`escape` but treats ``None`` as the empty string.
|
| 32 |
+
Useful with optional values, as otherwise you get the string
|
| 33 |
+
``'None'`` when the value is ``None``.
|
| 34 |
+
|
| 35 |
+
>>> escape(None)
|
| 36 |
+
Markup('None')
|
| 37 |
+
>>> escape_silent(None)
|
| 38 |
+
Markup('')
|
| 39 |
+
"""
|
| 40 |
+
if s is None:
|
| 41 |
+
return Markup()
|
| 42 |
+
|
| 43 |
+
return escape(s)
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def soft_str(s: t.Any) -> str:
|
| 47 |
+
"""Convert an object to a string if it isn't already. This preserves
|
| 48 |
+
a :class:`Markup` string rather than converting it back to a basic
|
| 49 |
+
string, so it will still be marked as safe and won't be escaped
|
| 50 |
+
again.
|
| 51 |
+
|
| 52 |
+
>>> value = escape("<User 1>")
|
| 53 |
+
>>> value
|
| 54 |
+
Markup('<User 1>')
|
| 55 |
+
>>> escape(str(value))
|
| 56 |
+
Markup('&lt;User 1&gt;')
|
| 57 |
+
>>> escape(soft_str(value))
|
| 58 |
+
Markup('<User 1>')
|
| 59 |
+
"""
|
| 60 |
+
if not isinstance(s, str):
|
| 61 |
+
return str(s)
|
| 62 |
+
|
| 63 |
+
return s
|
lib/python3.11/site-packages/markupsafe/_speedups.c
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <Python.h>
|
| 2 |
+
|
| 3 |
+
static PyObject* markup;
|
| 4 |
+
|
| 5 |
+
static int
|
| 6 |
+
init_constants(void)
|
| 7 |
+
{
|
| 8 |
+
PyObject *module;
|
| 9 |
+
|
| 10 |
+
/* import markup type so that we can mark the return value */
|
| 11 |
+
module = PyImport_ImportModule("markupsafe");
|
| 12 |
+
if (!module)
|
| 13 |
+
return 0;
|
| 14 |
+
markup = PyObject_GetAttrString(module, "Markup");
|
| 15 |
+
Py_DECREF(module);
|
| 16 |
+
|
| 17 |
+
return 1;
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
#define GET_DELTA(inp, inp_end, delta) \
|
| 21 |
+
while (inp < inp_end) { \
|
| 22 |
+
switch (*inp++) { \
|
| 23 |
+
case '"': \
|
| 24 |
+
case '\'': \
|
| 25 |
+
case '&': \
|
| 26 |
+
delta += 4; \
|
| 27 |
+
break; \
|
| 28 |
+
case '<': \
|
| 29 |
+
case '>': \
|
| 30 |
+
delta += 3; \
|
| 31 |
+
break; \
|
| 32 |
+
} \
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
#define DO_ESCAPE(inp, inp_end, outp) \
|
| 36 |
+
{ \
|
| 37 |
+
Py_ssize_t ncopy = 0; \
|
| 38 |
+
while (inp < inp_end) { \
|
| 39 |
+
switch (*inp) { \
|
| 40 |
+
case '"': \
|
| 41 |
+
memcpy(outp, inp-ncopy, sizeof(*outp)*ncopy); \
|
| 42 |
+
outp += ncopy; ncopy = 0; \
|
| 43 |
+
*outp++ = '&'; \
|
| 44 |
+
*outp++ = '#'; \
|
| 45 |
+
*outp++ = '3'; \
|
| 46 |
+
*outp++ = '4'; \
|
| 47 |
+
*outp++ = ';'; \
|
| 48 |
+
break; \
|
| 49 |
+
case '\'': \
|
| 50 |
+
memcpy(outp, inp-ncopy, sizeof(*outp)*ncopy); \
|
| 51 |
+
outp += ncopy; ncopy = 0; \
|
| 52 |
+
*outp++ = '&'; \
|
| 53 |
+
*outp++ = '#'; \
|
| 54 |
+
*outp++ = '3'; \
|
| 55 |
+
*outp++ = '9'; \
|
| 56 |
+
*outp++ = ';'; \
|
| 57 |
+
break; \
|
| 58 |
+
case '&': \
|
| 59 |
+
memcpy(outp, inp-ncopy, sizeof(*outp)*ncopy); \
|
| 60 |
+
outp += ncopy; ncopy = 0; \
|
| 61 |
+
*outp++ = '&'; \
|
| 62 |
+
*outp++ = 'a'; \
|
| 63 |
+
*outp++ = 'm'; \
|
| 64 |
+
*outp++ = 'p'; \
|
| 65 |
+
*outp++ = ';'; \
|
| 66 |
+
break; \
|
| 67 |
+
case '<': \
|
| 68 |
+
memcpy(outp, inp-ncopy, sizeof(*outp)*ncopy); \
|
| 69 |
+
outp += ncopy; ncopy = 0; \
|
| 70 |
+
*outp++ = '&'; \
|
| 71 |
+
*outp++ = 'l'; \
|
| 72 |
+
*outp++ = 't'; \
|
| 73 |
+
*outp++ = ';'; \
|
| 74 |
+
break; \
|
| 75 |
+
case '>': \
|
| 76 |
+
memcpy(outp, inp-ncopy, sizeof(*outp)*ncopy); \
|
| 77 |
+
outp += ncopy; ncopy = 0; \
|
| 78 |
+
*outp++ = '&'; \
|
| 79 |
+
*outp++ = 'g'; \
|
| 80 |
+
*outp++ = 't'; \
|
| 81 |
+
*outp++ = ';'; \
|
| 82 |
+
break; \
|
| 83 |
+
default: \
|
| 84 |
+
ncopy++; \
|
| 85 |
+
} \
|
| 86 |
+
inp++; \
|
| 87 |
+
} \
|
| 88 |
+
memcpy(outp, inp-ncopy, sizeof(*outp)*ncopy); \
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
static PyObject*
|
| 92 |
+
escape_unicode_kind1(PyUnicodeObject *in)
|
| 93 |
+
{
|
| 94 |
+
Py_UCS1 *inp = PyUnicode_1BYTE_DATA(in);
|
| 95 |
+
Py_UCS1 *inp_end = inp + PyUnicode_GET_LENGTH(in);
|
| 96 |
+
Py_UCS1 *outp;
|
| 97 |
+
PyObject *out;
|
| 98 |
+
Py_ssize_t delta = 0;
|
| 99 |
+
|
| 100 |
+
GET_DELTA(inp, inp_end, delta);
|
| 101 |
+
if (!delta) {
|
| 102 |
+
Py_INCREF(in);
|
| 103 |
+
return (PyObject*)in;
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
out = PyUnicode_New(PyUnicode_GET_LENGTH(in) + delta,
|
| 107 |
+
PyUnicode_IS_ASCII(in) ? 127 : 255);
|
| 108 |
+
if (!out)
|
| 109 |
+
return NULL;
|
| 110 |
+
|
| 111 |
+
inp = PyUnicode_1BYTE_DATA(in);
|
| 112 |
+
outp = PyUnicode_1BYTE_DATA(out);
|
| 113 |
+
DO_ESCAPE(inp, inp_end, outp);
|
| 114 |
+
return out;
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
static PyObject*
|
| 118 |
+
escape_unicode_kind2(PyUnicodeObject *in)
|
| 119 |
+
{
|
| 120 |
+
Py_UCS2 *inp = PyUnicode_2BYTE_DATA(in);
|
| 121 |
+
Py_UCS2 *inp_end = inp + PyUnicode_GET_LENGTH(in);
|
| 122 |
+
Py_UCS2 *outp;
|
| 123 |
+
PyObject *out;
|
| 124 |
+
Py_ssize_t delta = 0;
|
| 125 |
+
|
| 126 |
+
GET_DELTA(inp, inp_end, delta);
|
| 127 |
+
if (!delta) {
|
| 128 |
+
Py_INCREF(in);
|
| 129 |
+
return (PyObject*)in;
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
out = PyUnicode_New(PyUnicode_GET_LENGTH(in) + delta, 65535);
|
| 133 |
+
if (!out)
|
| 134 |
+
return NULL;
|
| 135 |
+
|
| 136 |
+
inp = PyUnicode_2BYTE_DATA(in);
|
| 137 |
+
outp = PyUnicode_2BYTE_DATA(out);
|
| 138 |
+
DO_ESCAPE(inp, inp_end, outp);
|
| 139 |
+
return out;
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
static PyObject*
|
| 144 |
+
escape_unicode_kind4(PyUnicodeObject *in)
|
| 145 |
+
{
|
| 146 |
+
Py_UCS4 *inp = PyUnicode_4BYTE_DATA(in);
|
| 147 |
+
Py_UCS4 *inp_end = inp + PyUnicode_GET_LENGTH(in);
|
| 148 |
+
Py_UCS4 *outp;
|
| 149 |
+
PyObject *out;
|
| 150 |
+
Py_ssize_t delta = 0;
|
| 151 |
+
|
| 152 |
+
GET_DELTA(inp, inp_end, delta);
|
| 153 |
+
if (!delta) {
|
| 154 |
+
Py_INCREF(in);
|
| 155 |
+
return (PyObject*)in;
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
out = PyUnicode_New(PyUnicode_GET_LENGTH(in) + delta, 1114111);
|
| 159 |
+
if (!out)
|
| 160 |
+
return NULL;
|
| 161 |
+
|
| 162 |
+
inp = PyUnicode_4BYTE_DATA(in);
|
| 163 |
+
outp = PyUnicode_4BYTE_DATA(out);
|
| 164 |
+
DO_ESCAPE(inp, inp_end, outp);
|
| 165 |
+
return out;
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
static PyObject*
|
| 169 |
+
escape_unicode(PyUnicodeObject *in)
|
| 170 |
+
{
|
| 171 |
+
if (PyUnicode_READY(in))
|
| 172 |
+
return NULL;
|
| 173 |
+
|
| 174 |
+
switch (PyUnicode_KIND(in)) {
|
| 175 |
+
case PyUnicode_1BYTE_KIND:
|
| 176 |
+
return escape_unicode_kind1(in);
|
| 177 |
+
case PyUnicode_2BYTE_KIND:
|
| 178 |
+
return escape_unicode_kind2(in);
|
| 179 |
+
case PyUnicode_4BYTE_KIND:
|
| 180 |
+
return escape_unicode_kind4(in);
|
| 181 |
+
}
|
| 182 |
+
assert(0); /* shouldn't happen */
|
| 183 |
+
return NULL;
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
static PyObject*
|
| 187 |
+
escape(PyObject *self, PyObject *text)
|
| 188 |
+
{
|
| 189 |
+
static PyObject *id_html;
|
| 190 |
+
PyObject *s = NULL, *rv = NULL, *html;
|
| 191 |
+
|
| 192 |
+
if (id_html == NULL) {
|
| 193 |
+
id_html = PyUnicode_InternFromString("__html__");
|
| 194 |
+
if (id_html == NULL) {
|
| 195 |
+
return NULL;
|
| 196 |
+
}
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
/* we don't have to escape integers, bools or floats */
|
| 200 |
+
if (PyLong_CheckExact(text) ||
|
| 201 |
+
PyFloat_CheckExact(text) || PyBool_Check(text) ||
|
| 202 |
+
text == Py_None)
|
| 203 |
+
return PyObject_CallFunctionObjArgs(markup, text, NULL);
|
| 204 |
+
|
| 205 |
+
/* if the object has an __html__ method that performs the escaping */
|
| 206 |
+
html = PyObject_GetAttr(text ,id_html);
|
| 207 |
+
if (html) {
|
| 208 |
+
s = PyObject_CallObject(html, NULL);
|
| 209 |
+
Py_DECREF(html);
|
| 210 |
+
if (s == NULL) {
|
| 211 |
+
return NULL;
|
| 212 |
+
}
|
| 213 |
+
/* Convert to Markup object */
|
| 214 |
+
rv = PyObject_CallFunctionObjArgs(markup, (PyObject*)s, NULL);
|
| 215 |
+
Py_DECREF(s);
|
| 216 |
+
return rv;
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
/* otherwise make the object unicode if it isn't, then escape */
|
| 220 |
+
PyErr_Clear();
|
| 221 |
+
if (!PyUnicode_Check(text)) {
|
| 222 |
+
PyObject *unicode = PyObject_Str(text);
|
| 223 |
+
if (!unicode)
|
| 224 |
+
return NULL;
|
| 225 |
+
s = escape_unicode((PyUnicodeObject*)unicode);
|
| 226 |
+
Py_DECREF(unicode);
|
| 227 |
+
}
|
| 228 |
+
else
|
| 229 |
+
s = escape_unicode((PyUnicodeObject*)text);
|
| 230 |
+
|
| 231 |
+
/* convert the unicode string into a markup object. */
|
| 232 |
+
rv = PyObject_CallFunctionObjArgs(markup, (PyObject*)s, NULL);
|
| 233 |
+
Py_DECREF(s);
|
| 234 |
+
return rv;
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
|
| 238 |
+
static PyObject*
|
| 239 |
+
escape_silent(PyObject *self, PyObject *text)
|
| 240 |
+
{
|
| 241 |
+
if (text != Py_None)
|
| 242 |
+
return escape(self, text);
|
| 243 |
+
return PyObject_CallFunctionObjArgs(markup, NULL);
|
| 244 |
+
}
|
| 245 |
+
|
| 246 |
+
|
| 247 |
+
static PyObject*
|
| 248 |
+
soft_str(PyObject *self, PyObject *s)
|
| 249 |
+
{
|
| 250 |
+
if (!PyUnicode_Check(s))
|
| 251 |
+
return PyObject_Str(s);
|
| 252 |
+
Py_INCREF(s);
|
| 253 |
+
return s;
|
| 254 |
+
}
|
| 255 |
+
|
| 256 |
+
|
| 257 |
+
static PyMethodDef module_methods[] = {
|
| 258 |
+
{
|
| 259 |
+
"escape",
|
| 260 |
+
(PyCFunction)escape,
|
| 261 |
+
METH_O,
|
| 262 |
+
"Replace the characters ``&``, ``<``, ``>``, ``'``, and ``\"`` in"
|
| 263 |
+
" the string with HTML-safe sequences. Use this if you need to display"
|
| 264 |
+
" text that might contain such characters in HTML.\n\n"
|
| 265 |
+
"If the object has an ``__html__`` method, it is called and the"
|
| 266 |
+
" return value is assumed to already be safe for HTML.\n\n"
|
| 267 |
+
":param s: An object to be converted to a string and escaped.\n"
|
| 268 |
+
":return: A :class:`Markup` string with the escaped text.\n"
|
| 269 |
+
},
|
| 270 |
+
{
|
| 271 |
+
"escape_silent",
|
| 272 |
+
(PyCFunction)escape_silent,
|
| 273 |
+
METH_O,
|
| 274 |
+
"Like :func:`escape` but treats ``None`` as the empty string."
|
| 275 |
+
" Useful with optional values, as otherwise you get the string"
|
| 276 |
+
" ``'None'`` when the value is ``None``.\n\n"
|
| 277 |
+
">>> escape(None)\n"
|
| 278 |
+
"Markup('None')\n"
|
| 279 |
+
">>> escape_silent(None)\n"
|
| 280 |
+
"Markup('')\n"
|
| 281 |
+
},
|
| 282 |
+
{
|
| 283 |
+
"soft_str",
|
| 284 |
+
(PyCFunction)soft_str,
|
| 285 |
+
METH_O,
|
| 286 |
+
"Convert an object to a string if it isn't already. This preserves"
|
| 287 |
+
" a :class:`Markup` string rather than converting it back to a basic"
|
| 288 |
+
" string, so it will still be marked as safe and won't be escaped"
|
| 289 |
+
" again.\n\n"
|
| 290 |
+
">>> value = escape(\"<User 1>\")\n"
|
| 291 |
+
">>> value\n"
|
| 292 |
+
"Markup('<User 1>')\n"
|
| 293 |
+
">>> escape(str(value))\n"
|
| 294 |
+
"Markup('&lt;User 1&gt;')\n"
|
| 295 |
+
">>> escape(soft_str(value))\n"
|
| 296 |
+
"Markup('<User 1>')\n"
|
| 297 |
+
},
|
| 298 |
+
{NULL, NULL, 0, NULL} /* Sentinel */
|
| 299 |
+
};
|
| 300 |
+
|
| 301 |
+
static struct PyModuleDef module_definition = {
|
| 302 |
+
PyModuleDef_HEAD_INIT,
|
| 303 |
+
"markupsafe._speedups",
|
| 304 |
+
NULL,
|
| 305 |
+
-1,
|
| 306 |
+
module_methods,
|
| 307 |
+
NULL,
|
| 308 |
+
NULL,
|
| 309 |
+
NULL,
|
| 310 |
+
NULL
|
| 311 |
+
};
|
| 312 |
+
|
| 313 |
+
PyMODINIT_FUNC
|
| 314 |
+
PyInit__speedups(void)
|
| 315 |
+
{
|
| 316 |
+
if (!init_constants())
|
| 317 |
+
return NULL;
|
| 318 |
+
|
| 319 |
+
return PyModule_Create(&module_definition);
|
| 320 |
+
}
|
lib/python3.11/site-packages/markupsafe/_speedups.cpython-311-darwin.so
ADDED
|
Binary file (117 kB). View file
|
|
|
lib/python3.11/site-packages/markupsafe/_speedups.pyi
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Any
|
| 2 |
+
from typing import Optional
|
| 3 |
+
|
| 4 |
+
from . import Markup
|
| 5 |
+
|
| 6 |
+
def escape(s: Any) -> Markup: ...
|
| 7 |
+
def escape_silent(s: Optional[Any]) -> Markup: ...
|
| 8 |
+
def soft_str(s: Any) -> str: ...
|
| 9 |
+
def soft_unicode(s: Any) -> str: ...
|
lib/python3.11/site-packages/markupsafe/py.typed
ADDED
|
File without changes
|
lib/python3.11/site-packages/mlx/__pycache__/_reprlib_fix.cpython-311.pyc
ADDED
|
Binary file (1.15 kB). View file
|
|
|
lib/python3.11/site-packages/mlx/__pycache__/extension.cpython-311.pyc
ADDED
|
Binary file (5.58 kB). View file
|
|
|
lib/python3.11/site-packages/mlx/__pycache__/optimizers.cpython-311.pyc
ADDED
|
Binary file (24.4 kB). View file
|
|
|
lib/python3.11/site-packages/mlx/__pycache__/utils.cpython-311.pyc
ADDED
|
Binary file (7.82 kB). View file
|
|
|
lib/python3.11/site-packages/mlx/_reprlib_fix.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright © 2023 Apple Inc.
|
| 2 |
+
|
| 3 |
+
import array
|
| 4 |
+
import reprlib
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
class FixedRepr(reprlib.Repr):
|
| 8 |
+
"""Only route python array instances to repr_array."""
|
| 9 |
+
|
| 10 |
+
def repr_array(self, x, maxlevel):
|
| 11 |
+
if isinstance(x, array.array):
|
| 12 |
+
return super().repr_array(x, maxlevel)
|
| 13 |
+
else:
|
| 14 |
+
return self.repr_instance(x, maxlevel)
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
# We need to monkey-patch reprlib so that we can use the debugger without
|
| 18 |
+
# renaming the array to something else
|
| 19 |
+
fixed_repr = FixedRepr()
|
| 20 |
+
reprlib.repr = fixed_repr.repr
|
lib/python3.11/site-packages/mlx/core.cpython-311-darwin.so
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e063225a72d2dac646b2b23007d980af2b9ee4bced7fe4adb409ff03369d9827
|
| 3 |
+
size 1098840
|
lib/python3.11/site-packages/mlx/extension.py
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright © 2023 Apple Inc.
|
| 2 |
+
|
| 3 |
+
import os
|
| 4 |
+
import re
|
| 5 |
+
import subprocess
|
| 6 |
+
import sys
|
| 7 |
+
from pathlib import Path
|
| 8 |
+
|
| 9 |
+
from setuptools import Extension, find_namespace_packages, setup
|
| 10 |
+
from setuptools.command.build_ext import build_ext
|
| 11 |
+
|
| 12 |
+
import mlx
|
| 13 |
+
|
| 14 |
+
_MLX_PATH = str(mlx.__path__[0])
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
# A CMakeExtension needs a sourcedir instead of a file list.
|
| 18 |
+
class CMakeExtension(Extension):
|
| 19 |
+
def __init__(self, name: str, sourcedir: str = "") -> None:
|
| 20 |
+
super().__init__(name, sources=[])
|
| 21 |
+
self.sourcedir = os.fspath(Path(sourcedir).resolve())
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
class CMakeBuild(build_ext):
|
| 25 |
+
def build_extension(self, ext: CMakeExtension) -> None:
|
| 26 |
+
# Must be in this form due to bug in .resolve() only fixed in Python 3.10+
|
| 27 |
+
ext_fullpath = Path.cwd() / self.get_ext_fullpath(ext.name) # type: ignore[no-untyped-call]
|
| 28 |
+
extdir = ext_fullpath.parent.resolve()
|
| 29 |
+
|
| 30 |
+
debug = int(os.environ.get("DEBUG", 0)) if self.debug is None else self.debug
|
| 31 |
+
cfg = "Debug" if debug else "Release"
|
| 32 |
+
|
| 33 |
+
# CMake lets you override the generator - we need to check this.
|
| 34 |
+
# Can be set with Conda-Build, for example.
|
| 35 |
+
cmake_generator = os.environ.get("CMAKE_GENERATOR", "")
|
| 36 |
+
|
| 37 |
+
# Set Python_EXECUTABLE instead if you use PYBIND11_FINDPYTHON
|
| 38 |
+
# EXAMPLE_VERSION_INFO shows you how to pass a value into the C++ code
|
| 39 |
+
# from Python.
|
| 40 |
+
cmake_args = [
|
| 41 |
+
f"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={extdir}{os.sep}",
|
| 42 |
+
f"-DCMAKE_BUILD_TYPE={cfg}",
|
| 43 |
+
"-DBUILD_SHARED_LIBS=ON",
|
| 44 |
+
]
|
| 45 |
+
build_args = []
|
| 46 |
+
# Adding CMake arguments set as environment variable
|
| 47 |
+
# (needed e.g. to build for ARM OSx on conda-forge)
|
| 48 |
+
if "CMAKE_ARGS" in os.environ:
|
| 49 |
+
cmake_args += [item for item in os.environ["CMAKE_ARGS"].split(" ") if item]
|
| 50 |
+
|
| 51 |
+
if sys.platform.startswith("darwin"):
|
| 52 |
+
# Cross-compile support for macOS - respect ARCHFLAGS if set
|
| 53 |
+
archs = re.findall(r"-arch (\S+)", os.environ.get("ARCHFLAGS", ""))
|
| 54 |
+
if archs:
|
| 55 |
+
cmake_args += ["-DCMAKE_OSX_ARCHITECTURES={}".format(";".join(archs))]
|
| 56 |
+
|
| 57 |
+
# Set CMAKE_BUILD_PARALLEL_LEVEL to control the parallel build level
|
| 58 |
+
# across all generators.
|
| 59 |
+
if "CMAKE_BUILD_PARALLEL_LEVEL" not in os.environ:
|
| 60 |
+
# self.parallel is a Python 3 only way to set parallel jobs by hand
|
| 61 |
+
# using -j in the build_ext call, not supported by pip or PyPA-build.
|
| 62 |
+
if hasattr(self, "parallel") and self.parallel:
|
| 63 |
+
# CMake 3.12+ only.
|
| 64 |
+
build_args += [f"-j{self.parallel}"]
|
| 65 |
+
|
| 66 |
+
build_temp = Path(self.build_temp) / ext.name
|
| 67 |
+
if not build_temp.exists():
|
| 68 |
+
build_temp.mkdir(parents=True)
|
| 69 |
+
|
| 70 |
+
# Make sure cmake can find MLX
|
| 71 |
+
os.environ["MLX_DIR"] = _MLX_PATH
|
| 72 |
+
|
| 73 |
+
subprocess.run(
|
| 74 |
+
["cmake", ext.sourcedir, *cmake_args], cwd=build_temp, check=True
|
| 75 |
+
)
|
| 76 |
+
subprocess.run(
|
| 77 |
+
["cmake", "--build", ".", *build_args], cwd=build_temp, check=True
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
def run(self):
|
| 81 |
+
super().run()
|
| 82 |
+
|
| 83 |
+
# Based on https://github.com/pypa/setuptools/blob/main/setuptools/command/build_ext.py#L102
|
| 84 |
+
if self.inplace:
|
| 85 |
+
for ext in self.extensions:
|
| 86 |
+
if isinstance(ext, CMakeExtension):
|
| 87 |
+
# Resolve inplace package dir
|
| 88 |
+
build_py = self.get_finalized_command("build_py")
|
| 89 |
+
inplace_file, regular_file = self._get_inplace_equivalent(
|
| 90 |
+
build_py, ext
|
| 91 |
+
)
|
| 92 |
+
|
| 93 |
+
inplace_dir = str(Path(inplace_file).parent.resolve())
|
| 94 |
+
regular_dir = str(Path(regular_file).parent.resolve())
|
| 95 |
+
|
| 96 |
+
self.copy_tree(regular_dir, inplace_dir)
|
lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/Foundation.hpp
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 2 |
+
//
|
| 3 |
+
// Foundation/Foundation.hpp
|
| 4 |
+
//
|
| 5 |
+
// Copyright 2020-2023 Apple Inc.
|
| 6 |
+
//
|
| 7 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
// you may not use this file except in compliance with the License.
|
| 9 |
+
// You may obtain a copy of the License at
|
| 10 |
+
//
|
| 11 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
//
|
| 13 |
+
// Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
// See the License for the specific language governing permissions and
|
| 17 |
+
// limitations under the License.
|
| 18 |
+
//
|
| 19 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 20 |
+
|
| 21 |
+
#pragma once
|
| 22 |
+
|
| 23 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 24 |
+
|
| 25 |
+
#include "NSArray.hpp"
|
| 26 |
+
#include "NSAutoreleasePool.hpp"
|
| 27 |
+
#include "NSBundle.hpp"
|
| 28 |
+
#include "NSData.hpp"
|
| 29 |
+
#include "NSDate.hpp"
|
| 30 |
+
#include "NSDefines.hpp"
|
| 31 |
+
#include "NSDictionary.hpp"
|
| 32 |
+
#include "NSEnumerator.hpp"
|
| 33 |
+
#include "NSError.hpp"
|
| 34 |
+
#include "NSLock.hpp"
|
| 35 |
+
#include "NSNotification.hpp"
|
| 36 |
+
#include "NSNumber.hpp"
|
| 37 |
+
#include "NSObject.hpp"
|
| 38 |
+
#include "NSPrivate.hpp"
|
| 39 |
+
#include "NSProcessInfo.hpp"
|
| 40 |
+
#include "NSRange.hpp"
|
| 41 |
+
#include "NSSet.hpp"
|
| 42 |
+
#include "NSSharedPtr.hpp"
|
| 43 |
+
#include "NSString.hpp"
|
| 44 |
+
#include "NSTypes.hpp"
|
| 45 |
+
#include "NSURL.hpp"
|
| 46 |
+
|
| 47 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSArray.hpp
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 2 |
+
//
|
| 3 |
+
// Foundation/NSArray.hpp
|
| 4 |
+
//
|
| 5 |
+
// Copyright 2020-2023 Apple Inc.
|
| 6 |
+
//
|
| 7 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
// you may not use this file except in compliance with the License.
|
| 9 |
+
// You may obtain a copy of the License at
|
| 10 |
+
//
|
| 11 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
//
|
| 13 |
+
// Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
// See the License for the specific language governing permissions and
|
| 17 |
+
// limitations under the License.
|
| 18 |
+
//
|
| 19 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 20 |
+
|
| 21 |
+
#pragma once
|
| 22 |
+
|
| 23 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 24 |
+
|
| 25 |
+
#include "NSObject.hpp"
|
| 26 |
+
#include "NSTypes.hpp"
|
| 27 |
+
|
| 28 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 29 |
+
|
| 30 |
+
namespace NS
|
| 31 |
+
{
|
| 32 |
+
class Array : public Copying<Array>
|
| 33 |
+
{
|
| 34 |
+
public:
|
| 35 |
+
static Array* array();
|
| 36 |
+
static Array* array(const Object* pObject);
|
| 37 |
+
static Array* array(const Object* const* pObjects, UInteger count);
|
| 38 |
+
|
| 39 |
+
static Array* alloc();
|
| 40 |
+
|
| 41 |
+
Array* init();
|
| 42 |
+
Array* init(const Object* const* pObjects, UInteger count);
|
| 43 |
+
Array* init(const class Coder* pCoder);
|
| 44 |
+
|
| 45 |
+
template <class _Object = Object>
|
| 46 |
+
_Object* object(UInteger index) const;
|
| 47 |
+
UInteger count() const;
|
| 48 |
+
};
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 52 |
+
|
| 53 |
+
_NS_INLINE NS::Array* NS::Array::array()
|
| 54 |
+
{
|
| 55 |
+
return Object::sendMessage<Array*>(_NS_PRIVATE_CLS(NSArray), _NS_PRIVATE_SEL(array));
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 59 |
+
|
| 60 |
+
_NS_INLINE NS::Array* NS::Array::array(const Object* pObject)
|
| 61 |
+
{
|
| 62 |
+
return Object::sendMessage<Array*>(_NS_PRIVATE_CLS(NSArray), _NS_PRIVATE_SEL(arrayWithObject_), pObject);
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 66 |
+
|
| 67 |
+
_NS_INLINE NS::Array* NS::Array::array(const Object* const* pObjects, UInteger count)
|
| 68 |
+
{
|
| 69 |
+
return Object::sendMessage<Array*>(_NS_PRIVATE_CLS(NSArray), _NS_PRIVATE_SEL(arrayWithObjects_count_), pObjects, count);
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 73 |
+
|
| 74 |
+
_NS_INLINE NS::Array* NS::Array::alloc()
|
| 75 |
+
{
|
| 76 |
+
return NS::Object::alloc<Array>(_NS_PRIVATE_CLS(NSArray));
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 80 |
+
|
| 81 |
+
_NS_INLINE NS::Array* NS::Array::init()
|
| 82 |
+
{
|
| 83 |
+
return NS::Object::init<Array>();
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 87 |
+
|
| 88 |
+
_NS_INLINE NS::Array* NS::Array::init(const Object* const* pObjects, UInteger count)
|
| 89 |
+
{
|
| 90 |
+
return Object::sendMessage<Array*>(this, _NS_PRIVATE_SEL(initWithObjects_count_), pObjects, count);
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 94 |
+
|
| 95 |
+
_NS_INLINE NS::Array* NS::Array::init(const class Coder* pCoder)
|
| 96 |
+
{
|
| 97 |
+
return Object::sendMessage<Array*>(this, _NS_PRIVATE_SEL(initWithCoder_), pCoder);
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 101 |
+
|
| 102 |
+
_NS_INLINE NS::UInteger NS::Array::count() const
|
| 103 |
+
{
|
| 104 |
+
return Object::sendMessage<UInteger>(this, _NS_PRIVATE_SEL(count));
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 108 |
+
|
| 109 |
+
template <class _Object>
|
| 110 |
+
_NS_INLINE _Object* NS::Array::object(UInteger index) const
|
| 111 |
+
{
|
| 112 |
+
return Object::sendMessage<_Object*>(this, _NS_PRIVATE_SEL(objectAtIndex_), index);
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSAutoreleasePool.hpp
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 2 |
+
//
|
| 3 |
+
// Foundation/NSAutoreleasePool.hpp
|
| 4 |
+
//
|
| 5 |
+
// Copyright 2020-2023 Apple Inc.
|
| 6 |
+
//
|
| 7 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
// you may not use this file except in compliance with the License.
|
| 9 |
+
// You may obtain a copy of the License at
|
| 10 |
+
//
|
| 11 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
//
|
| 13 |
+
// Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
// See the License for the specific language governing permissions and
|
| 17 |
+
// limitations under the License.
|
| 18 |
+
//
|
| 19 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 20 |
+
|
| 21 |
+
#pragma once
|
| 22 |
+
|
| 23 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 24 |
+
|
| 25 |
+
#include "NSDefines.hpp"
|
| 26 |
+
#include "NSObject.hpp"
|
| 27 |
+
#include "NSPrivate.hpp"
|
| 28 |
+
#include "NSTypes.hpp"
|
| 29 |
+
|
| 30 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 31 |
+
|
| 32 |
+
namespace NS
|
| 33 |
+
{
|
| 34 |
+
class AutoreleasePool : public Object
|
| 35 |
+
{
|
| 36 |
+
public:
|
| 37 |
+
static AutoreleasePool* alloc();
|
| 38 |
+
AutoreleasePool* init();
|
| 39 |
+
|
| 40 |
+
void drain();
|
| 41 |
+
|
| 42 |
+
void addObject(Object* pObject);
|
| 43 |
+
|
| 44 |
+
static void showPools();
|
| 45 |
+
};
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 49 |
+
|
| 50 |
+
_NS_INLINE NS::AutoreleasePool* NS::AutoreleasePool::alloc()
|
| 51 |
+
{
|
| 52 |
+
return NS::Object::alloc<AutoreleasePool>(_NS_PRIVATE_CLS(NSAutoreleasePool));
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 56 |
+
|
| 57 |
+
_NS_INLINE NS::AutoreleasePool* NS::AutoreleasePool::init()
|
| 58 |
+
{
|
| 59 |
+
return NS::Object::init<AutoreleasePool>();
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 63 |
+
|
| 64 |
+
_NS_INLINE void NS::AutoreleasePool::drain()
|
| 65 |
+
{
|
| 66 |
+
Object::sendMessage<void>(this, _NS_PRIVATE_SEL(drain));
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 70 |
+
|
| 71 |
+
_NS_INLINE void NS::AutoreleasePool::addObject(Object* pObject)
|
| 72 |
+
{
|
| 73 |
+
Object::sendMessage<void>(this, _NS_PRIVATE_SEL(addObject_), pObject);
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 77 |
+
|
| 78 |
+
_NS_INLINE void NS::AutoreleasePool::showPools()
|
| 79 |
+
{
|
| 80 |
+
Object::sendMessage<void>(_NS_PRIVATE_CLS(NSAutoreleasePool), _NS_PRIVATE_SEL(showPools));
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSBundle.hpp
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 2 |
+
//
|
| 3 |
+
// Foundation/NSBundle.hpp
|
| 4 |
+
//
|
| 5 |
+
// Copyright 2020-2023 Apple Inc.
|
| 6 |
+
//
|
| 7 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
// you may not use this file except in compliance with the License.
|
| 9 |
+
// You may obtain a copy of the License at
|
| 10 |
+
//
|
| 11 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
//
|
| 13 |
+
// Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
// See the License for the specific language governing permissions and
|
| 17 |
+
// limitations under the License.
|
| 18 |
+
//
|
| 19 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 20 |
+
|
| 21 |
+
#pragma once
|
| 22 |
+
|
| 23 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 24 |
+
|
| 25 |
+
#include "NSDefines.hpp"
|
| 26 |
+
#include "NSNotification.hpp"
|
| 27 |
+
#include "NSObject.hpp"
|
| 28 |
+
#include "NSTypes.hpp"
|
| 29 |
+
|
| 30 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 31 |
+
|
| 32 |
+
namespace NS
|
| 33 |
+
{
|
| 34 |
+
_NS_CONST(NotificationName, BundleDidLoadNotification);
|
| 35 |
+
_NS_CONST(NotificationName, BundleResourceRequestLowDiskSpaceNotification);
|
| 36 |
+
|
| 37 |
+
class String* LocalizedString(const String* pKey, const String*);
|
| 38 |
+
class String* LocalizedStringFromTable(const String* pKey, const String* pTbl, const String*);
|
| 39 |
+
class String* LocalizedStringFromTableInBundle(const String* pKey, const String* pTbl, const class Bundle* pBdle, const String*);
|
| 40 |
+
class String* LocalizedStringWithDefaultValue(const String* pKey, const String* pTbl, const class Bundle* pBdle, const String* pVal, const String*);
|
| 41 |
+
|
| 42 |
+
class Bundle : public Referencing<Bundle>
|
| 43 |
+
{
|
| 44 |
+
public:
|
| 45 |
+
static Bundle* mainBundle();
|
| 46 |
+
|
| 47 |
+
static Bundle* bundle(const class String* pPath);
|
| 48 |
+
static Bundle* bundle(const class URL* pURL);
|
| 49 |
+
|
| 50 |
+
static Bundle* alloc();
|
| 51 |
+
|
| 52 |
+
Bundle* init(const class String* pPath);
|
| 53 |
+
Bundle* init(const class URL* pURL);
|
| 54 |
+
|
| 55 |
+
class Array* allBundles() const;
|
| 56 |
+
class Array* allFrameworks() const;
|
| 57 |
+
|
| 58 |
+
bool load();
|
| 59 |
+
bool unload();
|
| 60 |
+
|
| 61 |
+
bool isLoaded() const;
|
| 62 |
+
|
| 63 |
+
bool preflightAndReturnError(class Error** pError) const;
|
| 64 |
+
bool loadAndReturnError(class Error** pError);
|
| 65 |
+
|
| 66 |
+
class URL* bundleURL() const;
|
| 67 |
+
class URL* resourceURL() const;
|
| 68 |
+
class URL* executableURL() const;
|
| 69 |
+
class URL* URLForAuxiliaryExecutable(const class String* pExecutableName) const;
|
| 70 |
+
|
| 71 |
+
class URL* privateFrameworksURL() const;
|
| 72 |
+
class URL* sharedFrameworksURL() const;
|
| 73 |
+
class URL* sharedSupportURL() const;
|
| 74 |
+
class URL* builtInPlugInsURL() const;
|
| 75 |
+
class URL* appStoreReceiptURL() const;
|
| 76 |
+
|
| 77 |
+
class String* bundlePath() const;
|
| 78 |
+
class String* resourcePath() const;
|
| 79 |
+
class String* executablePath() const;
|
| 80 |
+
class String* pathForAuxiliaryExecutable(const class String* pExecutableName) const;
|
| 81 |
+
|
| 82 |
+
class String* privateFrameworksPath() const;
|
| 83 |
+
class String* sharedFrameworksPath() const;
|
| 84 |
+
class String* sharedSupportPath() const;
|
| 85 |
+
class String* builtInPlugInsPath() const;
|
| 86 |
+
|
| 87 |
+
class String* bundleIdentifier() const;
|
| 88 |
+
class Dictionary* infoDictionary() const;
|
| 89 |
+
class Dictionary* localizedInfoDictionary() const;
|
| 90 |
+
class Object* objectForInfoDictionaryKey(const class String* pKey);
|
| 91 |
+
|
| 92 |
+
class String* localizedString(const class String* pKey, const class String* pValue = nullptr, const class String* pTableName = nullptr) const;
|
| 93 |
+
};
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 97 |
+
|
| 98 |
+
_NS_PRIVATE_DEF_CONST(NS::NotificationName, BundleDidLoadNotification);
|
| 99 |
+
_NS_PRIVATE_DEF_CONST(NS::NotificationName, BundleResourceRequestLowDiskSpaceNotification);
|
| 100 |
+
|
| 101 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 102 |
+
|
| 103 |
+
_NS_INLINE NS::String* NS::LocalizedString(const String* pKey, const String*)
|
| 104 |
+
{
|
| 105 |
+
return Bundle::mainBundle()->localizedString(pKey, nullptr, nullptr);
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 109 |
+
|
| 110 |
+
_NS_INLINE NS::String* NS::LocalizedStringFromTable(const String* pKey, const String* pTbl, const String*)
|
| 111 |
+
{
|
| 112 |
+
return Bundle::mainBundle()->localizedString(pKey, nullptr, pTbl);
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 116 |
+
|
| 117 |
+
_NS_INLINE NS::String* NS::LocalizedStringFromTableInBundle(const String* pKey, const String* pTbl, const Bundle* pBdl, const String*)
|
| 118 |
+
{
|
| 119 |
+
return pBdl->localizedString(pKey, nullptr, pTbl);
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 123 |
+
|
| 124 |
+
_NS_INLINE NS::String* NS::LocalizedStringWithDefaultValue(const String* pKey, const String* pTbl, const Bundle* pBdl, const String* pVal, const String*)
|
| 125 |
+
{
|
| 126 |
+
return pBdl->localizedString(pKey, pVal, pTbl);
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 130 |
+
|
| 131 |
+
_NS_INLINE NS::Bundle* NS::Bundle::mainBundle()
|
| 132 |
+
{
|
| 133 |
+
return Object::sendMessage<Bundle*>(_NS_PRIVATE_CLS(NSBundle), _NS_PRIVATE_SEL(mainBundle));
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 137 |
+
|
| 138 |
+
_NS_INLINE NS::Bundle* NS::Bundle::bundle(const class String* pPath)
|
| 139 |
+
{
|
| 140 |
+
return Object::sendMessage<Bundle*>(_NS_PRIVATE_CLS(NSBundle), _NS_PRIVATE_SEL(bundleWithPath_), pPath);
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 144 |
+
|
| 145 |
+
_NS_INLINE NS::Bundle* NS::Bundle::bundle(const class URL* pURL)
|
| 146 |
+
{
|
| 147 |
+
return Object::sendMessage<Bundle*>(_NS_PRIVATE_CLS(NSBundle), _NS_PRIVATE_SEL(bundleWithURL_), pURL);
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 151 |
+
|
| 152 |
+
_NS_INLINE NS::Bundle* NS::Bundle::alloc()
|
| 153 |
+
{
|
| 154 |
+
return Object::sendMessage<Bundle*>(_NS_PRIVATE_CLS(NSBundle), _NS_PRIVATE_SEL(alloc));
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 158 |
+
|
| 159 |
+
_NS_INLINE NS::Bundle* NS::Bundle::init(const String* pPath)
|
| 160 |
+
{
|
| 161 |
+
return Object::sendMessage<Bundle*>(this, _NS_PRIVATE_SEL(initWithPath_), pPath);
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 165 |
+
|
| 166 |
+
_NS_INLINE NS::Bundle* NS::Bundle::init(const URL* pURL)
|
| 167 |
+
{
|
| 168 |
+
return Object::sendMessage<Bundle*>(this, _NS_PRIVATE_SEL(initWithURL_), pURL);
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 172 |
+
|
| 173 |
+
_NS_INLINE NS::Array* NS::Bundle::allBundles() const
|
| 174 |
+
{
|
| 175 |
+
return Object::sendMessage<Array*>(this, _NS_PRIVATE_SEL(allBundles));
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 179 |
+
|
| 180 |
+
_NS_INLINE NS::Array* NS::Bundle::allFrameworks() const
|
| 181 |
+
{
|
| 182 |
+
return Object::sendMessage<Array*>(this, _NS_PRIVATE_SEL(allFrameworks));
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 186 |
+
|
| 187 |
+
_NS_INLINE bool NS::Bundle::load()
|
| 188 |
+
{
|
| 189 |
+
return Object::sendMessage<bool>(this, _NS_PRIVATE_SEL(load));
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 193 |
+
|
| 194 |
+
_NS_INLINE bool NS::Bundle::unload()
|
| 195 |
+
{
|
| 196 |
+
return Object::sendMessage<bool>(this, _NS_PRIVATE_SEL(unload));
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 200 |
+
|
| 201 |
+
_NS_INLINE bool NS::Bundle::isLoaded() const
|
| 202 |
+
{
|
| 203 |
+
return Object::sendMessage<bool>(this, _NS_PRIVATE_SEL(isLoaded));
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 207 |
+
|
| 208 |
+
_NS_INLINE bool NS::Bundle::preflightAndReturnError(Error** pError) const
|
| 209 |
+
{
|
| 210 |
+
return Object::sendMessage<bool>(this, _NS_PRIVATE_SEL(preflightAndReturnError_), pError);
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 214 |
+
|
| 215 |
+
_NS_INLINE bool NS::Bundle::loadAndReturnError(Error** pError)
|
| 216 |
+
{
|
| 217 |
+
return Object::sendMessage<bool>(this, _NS_PRIVATE_SEL(loadAndReturnError_), pError);
|
| 218 |
+
}
|
| 219 |
+
|
| 220 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 221 |
+
|
| 222 |
+
_NS_INLINE NS::URL* NS::Bundle::bundleURL() const
|
| 223 |
+
{
|
| 224 |
+
return Object::sendMessage<URL*>(this, _NS_PRIVATE_SEL(bundleURL));
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 228 |
+
|
| 229 |
+
_NS_INLINE NS::URL* NS::Bundle::resourceURL() const
|
| 230 |
+
{
|
| 231 |
+
return Object::sendMessage<URL*>(this, _NS_PRIVATE_SEL(resourceURL));
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 235 |
+
|
| 236 |
+
_NS_INLINE NS::URL* NS::Bundle::executableURL() const
|
| 237 |
+
{
|
| 238 |
+
return Object::sendMessage<URL*>(this, _NS_PRIVATE_SEL(executableURL));
|
| 239 |
+
}
|
| 240 |
+
|
| 241 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 242 |
+
|
| 243 |
+
_NS_INLINE NS::URL* NS::Bundle::URLForAuxiliaryExecutable(const String* pExecutableName) const
|
| 244 |
+
{
|
| 245 |
+
return Object::sendMessage<URL*>(this, _NS_PRIVATE_SEL(URLForAuxiliaryExecutable_), pExecutableName);
|
| 246 |
+
}
|
| 247 |
+
|
| 248 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 249 |
+
|
| 250 |
+
_NS_INLINE NS::URL* NS::Bundle::privateFrameworksURL() const
|
| 251 |
+
{
|
| 252 |
+
return Object::sendMessage<URL*>(this, _NS_PRIVATE_SEL(privateFrameworksURL));
|
| 253 |
+
}
|
| 254 |
+
|
| 255 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 256 |
+
|
| 257 |
+
_NS_INLINE NS::URL* NS::Bundle::sharedFrameworksURL() const
|
| 258 |
+
{
|
| 259 |
+
return Object::sendMessage<URL*>(this, _NS_PRIVATE_SEL(sharedFrameworksURL));
|
| 260 |
+
}
|
| 261 |
+
|
| 262 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 263 |
+
|
| 264 |
+
_NS_INLINE NS::URL* NS::Bundle::sharedSupportURL() const
|
| 265 |
+
{
|
| 266 |
+
return Object::sendMessage<URL*>(this, _NS_PRIVATE_SEL(sharedSupportURL));
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 270 |
+
|
| 271 |
+
_NS_INLINE NS::URL* NS::Bundle::builtInPlugInsURL() const
|
| 272 |
+
{
|
| 273 |
+
return Object::sendMessage<URL*>(this, _NS_PRIVATE_SEL(builtInPlugInsURL));
|
| 274 |
+
}
|
| 275 |
+
|
| 276 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 277 |
+
|
| 278 |
+
_NS_INLINE NS::URL* NS::Bundle::appStoreReceiptURL() const
|
| 279 |
+
{
|
| 280 |
+
return Object::sendMessage<URL*>(this, _NS_PRIVATE_SEL(appStoreReceiptURL));
|
| 281 |
+
}
|
| 282 |
+
|
| 283 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 284 |
+
|
| 285 |
+
_NS_INLINE NS::String* NS::Bundle::bundlePath() const
|
| 286 |
+
{
|
| 287 |
+
return Object::sendMessage<String*>(this, _NS_PRIVATE_SEL(bundlePath));
|
| 288 |
+
}
|
| 289 |
+
|
| 290 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 291 |
+
|
| 292 |
+
_NS_INLINE NS::String* NS::Bundle::resourcePath() const
|
| 293 |
+
{
|
| 294 |
+
return Object::sendMessage<String*>(this, _NS_PRIVATE_SEL(resourcePath));
|
| 295 |
+
}
|
| 296 |
+
|
| 297 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 298 |
+
|
| 299 |
+
_NS_INLINE NS::String* NS::Bundle::executablePath() const
|
| 300 |
+
{
|
| 301 |
+
return Object::sendMessage<String*>(this, _NS_PRIVATE_SEL(executablePath));
|
| 302 |
+
}
|
| 303 |
+
|
| 304 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 305 |
+
|
| 306 |
+
_NS_INLINE NS::String* NS::Bundle::pathForAuxiliaryExecutable(const String* pExecutableName) const
|
| 307 |
+
{
|
| 308 |
+
return Object::sendMessage<String*>(this, _NS_PRIVATE_SEL(pathForAuxiliaryExecutable_), pExecutableName);
|
| 309 |
+
}
|
| 310 |
+
|
| 311 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 312 |
+
|
| 313 |
+
_NS_INLINE NS::String* NS::Bundle::privateFrameworksPath() const
|
| 314 |
+
{
|
| 315 |
+
return Object::sendMessage<String*>(this, _NS_PRIVATE_SEL(privateFrameworksPath));
|
| 316 |
+
}
|
| 317 |
+
|
| 318 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 319 |
+
|
| 320 |
+
_NS_INLINE NS::String* NS::Bundle::sharedFrameworksPath() const
|
| 321 |
+
{
|
| 322 |
+
return Object::sendMessage<String*>(this, _NS_PRIVATE_SEL(sharedFrameworksPath));
|
| 323 |
+
}
|
| 324 |
+
|
| 325 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 326 |
+
|
| 327 |
+
_NS_INLINE NS::String* NS::Bundle::sharedSupportPath() const
|
| 328 |
+
{
|
| 329 |
+
return Object::sendMessage<String*>(this, _NS_PRIVATE_SEL(sharedSupportPath));
|
| 330 |
+
}
|
| 331 |
+
|
| 332 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 333 |
+
|
| 334 |
+
_NS_INLINE NS::String* NS::Bundle::builtInPlugInsPath() const
|
| 335 |
+
{
|
| 336 |
+
return Object::sendMessage<String*>(this, _NS_PRIVATE_SEL(builtInPlugInsPath));
|
| 337 |
+
}
|
| 338 |
+
|
| 339 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 340 |
+
|
| 341 |
+
_NS_INLINE NS::String* NS::Bundle::bundleIdentifier() const
|
| 342 |
+
{
|
| 343 |
+
return Object::sendMessage<String*>(this, _NS_PRIVATE_SEL(bundleIdentifier));
|
| 344 |
+
}
|
| 345 |
+
|
| 346 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 347 |
+
|
| 348 |
+
_NS_INLINE NS::Dictionary* NS::Bundle::infoDictionary() const
|
| 349 |
+
{
|
| 350 |
+
return Object::sendMessage<Dictionary*>(this, _NS_PRIVATE_SEL(infoDictionary));
|
| 351 |
+
}
|
| 352 |
+
|
| 353 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 354 |
+
|
| 355 |
+
_NS_INLINE NS::Dictionary* NS::Bundle::localizedInfoDictionary() const
|
| 356 |
+
{
|
| 357 |
+
return Object::sendMessage<Dictionary*>(this, _NS_PRIVATE_SEL(localizedInfoDictionary));
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 361 |
+
|
| 362 |
+
_NS_INLINE NS::Object* NS::Bundle::objectForInfoDictionaryKey(const String* pKey)
|
| 363 |
+
{
|
| 364 |
+
return Object::sendMessage<Object*>(this, _NS_PRIVATE_SEL(objectForInfoDictionaryKey_), pKey);
|
| 365 |
+
}
|
| 366 |
+
|
| 367 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 368 |
+
|
| 369 |
+
_NS_INLINE NS::String* NS::Bundle::localizedString(const String* pKey, const String* pValue /* = nullptr */, const String* pTableName /* = nullptr */) const
|
| 370 |
+
{
|
| 371 |
+
return Object::sendMessage<String*>(this, _NS_PRIVATE_SEL(localizedStringForKey_value_table_), pKey, pValue, pTableName);
|
| 372 |
+
}
|
| 373 |
+
|
| 374 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSData.hpp
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 2 |
+
//
|
| 3 |
+
// Foundation/NSData.hpp
|
| 4 |
+
//
|
| 5 |
+
// Copyright 2020-2023 Apple Inc.
|
| 6 |
+
//
|
| 7 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
// you may not use this file except in compliance with the License.
|
| 9 |
+
// You may obtain a copy of the License at
|
| 10 |
+
//
|
| 11 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
//
|
| 13 |
+
// Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
// See the License for the specific language governing permissions and
|
| 17 |
+
// limitations under the License.
|
| 18 |
+
//
|
| 19 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 20 |
+
|
| 21 |
+
#pragma once
|
| 22 |
+
|
| 23 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 24 |
+
|
| 25 |
+
#include "NSObject.hpp"
|
| 26 |
+
#include "NSTypes.hpp"
|
| 27 |
+
|
| 28 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 29 |
+
|
| 30 |
+
namespace NS
|
| 31 |
+
{
|
| 32 |
+
class Data : public Copying<Data>
|
| 33 |
+
{
|
| 34 |
+
public:
|
| 35 |
+
void* mutableBytes() const;
|
| 36 |
+
UInteger length() const;
|
| 37 |
+
};
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 41 |
+
|
| 42 |
+
_NS_INLINE void* NS::Data::mutableBytes() const
|
| 43 |
+
{
|
| 44 |
+
return Object::sendMessage<void*>(this, _NS_PRIVATE_SEL(mutableBytes));
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 48 |
+
|
| 49 |
+
_NS_INLINE NS::UInteger NS::Data::length() const
|
| 50 |
+
{
|
| 51 |
+
return Object::sendMessage<UInteger>(this, _NS_PRIVATE_SEL(length));
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSDate.hpp
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 2 |
+
//
|
| 3 |
+
// Foundation/NSDate.hpp
|
| 4 |
+
//
|
| 5 |
+
// Copyright 2020-2023 Apple Inc.
|
| 6 |
+
//
|
| 7 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
// you may not use this file except in compliance with the License.
|
| 9 |
+
// You may obtain a copy of the License at
|
| 10 |
+
//
|
| 11 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
//
|
| 13 |
+
// Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
// See the License for the specific language governing permissions and
|
| 17 |
+
// limitations under the License.
|
| 18 |
+
//
|
| 19 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
#pragma once
|
| 23 |
+
|
| 24 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 25 |
+
|
| 26 |
+
#include "NSDefines.hpp"
|
| 27 |
+
#include "NSObject.hpp"
|
| 28 |
+
#include "NSPrivate.hpp"
|
| 29 |
+
#include "NSTypes.hpp"
|
| 30 |
+
|
| 31 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 32 |
+
|
| 33 |
+
namespace NS
|
| 34 |
+
{
|
| 35 |
+
|
| 36 |
+
using TimeInterval = double;
|
| 37 |
+
|
| 38 |
+
class Date : public Copying<Date>
|
| 39 |
+
{
|
| 40 |
+
public:
|
| 41 |
+
static Date* dateWithTimeIntervalSinceNow(TimeInterval secs);
|
| 42 |
+
};
|
| 43 |
+
|
| 44 |
+
} // NS
|
| 45 |
+
|
| 46 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 47 |
+
|
| 48 |
+
_NS_INLINE NS::Date* NS::Date::dateWithTimeIntervalSinceNow(NS::TimeInterval secs)
|
| 49 |
+
{
|
| 50 |
+
return NS::Object::sendMessage<NS::Date*>(_NS_PRIVATE_CLS(NSDate), _NS_PRIVATE_SEL(dateWithTimeIntervalSinceNow_), secs);
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSDefines.hpp
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 2 |
+
//
|
| 3 |
+
// Foundation/NSDefines.hpp
|
| 4 |
+
//
|
| 5 |
+
// Copyright 2020-2023 Apple Inc.
|
| 6 |
+
//
|
| 7 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
// you may not use this file except in compliance with the License.
|
| 9 |
+
// You may obtain a copy of the License at
|
| 10 |
+
//
|
| 11 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
//
|
| 13 |
+
// Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
// See the License for the specific language governing permissions and
|
| 17 |
+
// limitations under the License.
|
| 18 |
+
//
|
| 19 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 20 |
+
|
| 21 |
+
#pragma once
|
| 22 |
+
|
| 23 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 24 |
+
|
| 25 |
+
#define _NS_WEAK_IMPORT __attribute__((weak_import))
|
| 26 |
+
#ifdef METALCPP_SYMBOL_VISIBILITY_HIDDEN
|
| 27 |
+
#define _NS_EXPORT __attribute__((visibility("hidden")))
|
| 28 |
+
#else
|
| 29 |
+
#define _NS_EXPORT __attribute__((visibility("default")))
|
| 30 |
+
#endif // METALCPP_SYMBOL_VISIBILITY_HIDDEN
|
| 31 |
+
#define _NS_EXTERN extern "C" _NS_EXPORT
|
| 32 |
+
#define _NS_INLINE inline __attribute__((always_inline))
|
| 33 |
+
#define _NS_PACKED __attribute__((packed))
|
| 34 |
+
|
| 35 |
+
#define _NS_CONST(type, name) _NS_EXTERN type const name
|
| 36 |
+
#define _NS_ENUM(type, name) enum name : type
|
| 37 |
+
#define _NS_OPTIONS(type, name) \
|
| 38 |
+
using name = type; \
|
| 39 |
+
enum : name
|
| 40 |
+
|
| 41 |
+
#define _NS_CAST_TO_UINT(value) static_cast<NS::UInteger>(value)
|
| 42 |
+
#define _NS_VALIDATE_SIZE(ns, name) static_assert(sizeof(ns::name) == sizeof(ns##name), "size mismatch " #ns "::" #name)
|
| 43 |
+
#define _NS_VALIDATE_ENUM(ns, name) static_assert(_NS_CAST_TO_UINT(ns::name) == _NS_CAST_TO_UINT(ns##name), "value mismatch " #ns "::" #name)
|
| 44 |
+
|
| 45 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSDictionary.hpp
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 2 |
+
//
|
| 3 |
+
// Foundation/NSDictionary.hpp
|
| 4 |
+
//
|
| 5 |
+
// Copyright 2020-2023 Apple Inc.
|
| 6 |
+
//
|
| 7 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
// you may not use this file except in compliance with the License.
|
| 9 |
+
// You may obtain a copy of the License at
|
| 10 |
+
//
|
| 11 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
//
|
| 13 |
+
// Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
// See the License for the specific language governing permissions and
|
| 17 |
+
// limitations under the License.
|
| 18 |
+
//
|
| 19 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 20 |
+
|
| 21 |
+
#pragma once
|
| 22 |
+
|
| 23 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 24 |
+
|
| 25 |
+
#include "NSEnumerator.hpp"
|
| 26 |
+
#include "NSObject.hpp"
|
| 27 |
+
#include "NSTypes.hpp"
|
| 28 |
+
|
| 29 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 30 |
+
|
| 31 |
+
namespace NS
|
| 32 |
+
{
|
| 33 |
+
class Dictionary : public NS::Copying<Dictionary>
|
| 34 |
+
{
|
| 35 |
+
public:
|
| 36 |
+
static Dictionary* dictionary();
|
| 37 |
+
static Dictionary* dictionary(const Object* pObject, const Object* pKey);
|
| 38 |
+
static Dictionary* dictionary(const Object* const* pObjects, const Object* const* pKeys, UInteger count);
|
| 39 |
+
|
| 40 |
+
static Dictionary* alloc();
|
| 41 |
+
|
| 42 |
+
Dictionary* init();
|
| 43 |
+
Dictionary* init(const Object* const* pObjects, const Object* const* pKeys, UInteger count);
|
| 44 |
+
Dictionary* init(const class Coder* pCoder);
|
| 45 |
+
|
| 46 |
+
template <class _KeyType = Object>
|
| 47 |
+
Enumerator<_KeyType>* keyEnumerator() const;
|
| 48 |
+
|
| 49 |
+
template <class _Object = Object>
|
| 50 |
+
_Object* object(const Object* pKey) const;
|
| 51 |
+
UInteger count() const;
|
| 52 |
+
};
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 56 |
+
|
| 57 |
+
_NS_INLINE NS::Dictionary* NS::Dictionary::dictionary()
|
| 58 |
+
{
|
| 59 |
+
return Object::sendMessage<Dictionary*>(_NS_PRIVATE_CLS(NSDictionary), _NS_PRIVATE_SEL(dictionary));
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 63 |
+
|
| 64 |
+
_NS_INLINE NS::Dictionary* NS::Dictionary::dictionary(const Object* pObject, const Object* pKey)
|
| 65 |
+
{
|
| 66 |
+
return Object::sendMessage<Dictionary*>(_NS_PRIVATE_CLS(NSDictionary), _NS_PRIVATE_SEL(dictionaryWithObject_forKey_), pObject, pKey);
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 70 |
+
|
| 71 |
+
_NS_INLINE NS::Dictionary* NS::Dictionary::dictionary(const Object* const* pObjects, const Object* const* pKeys, UInteger count)
|
| 72 |
+
{
|
| 73 |
+
return Object::sendMessage<Dictionary*>(_NS_PRIVATE_CLS(NSDictionary), _NS_PRIVATE_SEL(dictionaryWithObjects_forKeys_count_),
|
| 74 |
+
pObjects, pKeys, count);
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 78 |
+
|
| 79 |
+
_NS_INLINE NS::Dictionary* NS::Dictionary::alloc()
|
| 80 |
+
{
|
| 81 |
+
return NS::Object::alloc<Dictionary>(_NS_PRIVATE_CLS(NSDictionary));
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 85 |
+
|
| 86 |
+
_NS_INLINE NS::Dictionary* NS::Dictionary::init()
|
| 87 |
+
{
|
| 88 |
+
return NS::Object::init<Dictionary>();
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 92 |
+
|
| 93 |
+
_NS_INLINE NS::Dictionary* NS::Dictionary::init(const Object* const* pObjects, const Object* const* pKeys, UInteger count)
|
| 94 |
+
{
|
| 95 |
+
return Object::sendMessage<Dictionary*>(this, _NS_PRIVATE_SEL(initWithObjects_forKeys_count_), pObjects, pKeys, count);
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 99 |
+
|
| 100 |
+
_NS_INLINE NS::Dictionary* NS::Dictionary::init(const class Coder* pCoder)
|
| 101 |
+
{
|
| 102 |
+
return Object::sendMessage<Dictionary*>(this, _NS_PRIVATE_SEL(initWithCoder_), pCoder);
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 106 |
+
|
| 107 |
+
template <class _KeyType>
|
| 108 |
+
_NS_INLINE NS::Enumerator<_KeyType>* NS::Dictionary::keyEnumerator() const
|
| 109 |
+
{
|
| 110 |
+
return Object::sendMessage<Enumerator<_KeyType>*>(this, _NS_PRIVATE_SEL(keyEnumerator));
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 114 |
+
|
| 115 |
+
template <class _Object>
|
| 116 |
+
_NS_INLINE _Object* NS::Dictionary::object(const Object* pKey) const
|
| 117 |
+
{
|
| 118 |
+
return Object::sendMessage<_Object*>(this, _NS_PRIVATE_SEL(objectForKey_), pKey);
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 122 |
+
|
| 123 |
+
_NS_INLINE NS::UInteger NS::Dictionary::count() const
|
| 124 |
+
{
|
| 125 |
+
return Object::sendMessage<UInteger>(this, _NS_PRIVATE_SEL(count));
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSEnumerator.hpp
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 2 |
+
//
|
| 3 |
+
// Foundation/NSEnumerator.hpp
|
| 4 |
+
//
|
| 5 |
+
// Copyright 2020-2023 Apple Inc.
|
| 6 |
+
//
|
| 7 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
// you may not use this file except in compliance with the License.
|
| 9 |
+
// You may obtain a copy of the License at
|
| 10 |
+
//
|
| 11 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
//
|
| 13 |
+
// Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
// See the License for the specific language governing permissions and
|
| 17 |
+
// limitations under the License.
|
| 18 |
+
//
|
| 19 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 20 |
+
|
| 21 |
+
#pragma once
|
| 22 |
+
|
| 23 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 24 |
+
|
| 25 |
+
#include "NSObject.hpp"
|
| 26 |
+
#include "NSTypes.hpp"
|
| 27 |
+
|
| 28 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 29 |
+
|
| 30 |
+
namespace NS
|
| 31 |
+
{
|
| 32 |
+
struct FastEnumerationState
|
| 33 |
+
{
|
| 34 |
+
unsigned long state;
|
| 35 |
+
Object** itemsPtr;
|
| 36 |
+
unsigned long* mutationsPtr;
|
| 37 |
+
unsigned long extra[5];
|
| 38 |
+
} _NS_PACKED;
|
| 39 |
+
|
| 40 |
+
class FastEnumeration : public Referencing<FastEnumeration>
|
| 41 |
+
{
|
| 42 |
+
public:
|
| 43 |
+
NS::UInteger countByEnumerating(FastEnumerationState* pState, Object** pBuffer, NS::UInteger len);
|
| 44 |
+
};
|
| 45 |
+
|
| 46 |
+
template <class _ObjectType>
|
| 47 |
+
class Enumerator : public Referencing<Enumerator<_ObjectType>, FastEnumeration>
|
| 48 |
+
{
|
| 49 |
+
public:
|
| 50 |
+
_ObjectType* nextObject();
|
| 51 |
+
class Array* allObjects();
|
| 52 |
+
};
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 56 |
+
|
| 57 |
+
_NS_INLINE NS::UInteger NS::FastEnumeration::countByEnumerating(FastEnumerationState* pState, Object** pBuffer, NS::UInteger len)
|
| 58 |
+
{
|
| 59 |
+
return Object::sendMessage<UInteger>(this, _NS_PRIVATE_SEL(countByEnumeratingWithState_objects_count_), pState, pBuffer, len);
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 63 |
+
|
| 64 |
+
template <class _ObjectType>
|
| 65 |
+
_NS_INLINE _ObjectType* NS::Enumerator<_ObjectType>::nextObject()
|
| 66 |
+
{
|
| 67 |
+
return Object::sendMessage<_ObjectType*>(this, _NS_PRIVATE_SEL(nextObject));
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 71 |
+
|
| 72 |
+
template <class _ObjectType>
|
| 73 |
+
_NS_INLINE NS::Array* NS::Enumerator<_ObjectType>::allObjects()
|
| 74 |
+
{
|
| 75 |
+
return Object::sendMessage<Array*>(this, _NS_PRIVATE_SEL(allObjects));
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSError.hpp
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 2 |
+
//
|
| 3 |
+
// Foundation/NSError.hpp
|
| 4 |
+
//
|
| 5 |
+
// Copyright 2020-2023 Apple Inc.
|
| 6 |
+
//
|
| 7 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
// you may not use this file except in compliance with the License.
|
| 9 |
+
// You may obtain a copy of the License at
|
| 10 |
+
//
|
| 11 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
//
|
| 13 |
+
// Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
// See the License for the specific language governing permissions and
|
| 17 |
+
// limitations under the License.
|
| 18 |
+
//
|
| 19 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 20 |
+
|
| 21 |
+
#pragma once
|
| 22 |
+
|
| 23 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 24 |
+
|
| 25 |
+
#include "NSDefines.hpp"
|
| 26 |
+
#include "NSObject.hpp"
|
| 27 |
+
#include "NSPrivate.hpp"
|
| 28 |
+
#include "NSTypes.hpp"
|
| 29 |
+
|
| 30 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 31 |
+
|
| 32 |
+
namespace NS
|
| 33 |
+
{
|
| 34 |
+
using ErrorDomain = class String*;
|
| 35 |
+
|
| 36 |
+
_NS_CONST(ErrorDomain, CocoaErrorDomain);
|
| 37 |
+
_NS_CONST(ErrorDomain, POSIXErrorDomain);
|
| 38 |
+
_NS_CONST(ErrorDomain, OSStatusErrorDomain);
|
| 39 |
+
_NS_CONST(ErrorDomain, MachErrorDomain);
|
| 40 |
+
|
| 41 |
+
using ErrorUserInfoKey = class String*;
|
| 42 |
+
|
| 43 |
+
_NS_CONST(ErrorUserInfoKey, UnderlyingErrorKey);
|
| 44 |
+
_NS_CONST(ErrorUserInfoKey, LocalizedDescriptionKey);
|
| 45 |
+
_NS_CONST(ErrorUserInfoKey, LocalizedFailureReasonErrorKey);
|
| 46 |
+
_NS_CONST(ErrorUserInfoKey, LocalizedRecoverySuggestionErrorKey);
|
| 47 |
+
_NS_CONST(ErrorUserInfoKey, LocalizedRecoveryOptionsErrorKey);
|
| 48 |
+
_NS_CONST(ErrorUserInfoKey, RecoveryAttempterErrorKey);
|
| 49 |
+
_NS_CONST(ErrorUserInfoKey, HelpAnchorErrorKey);
|
| 50 |
+
_NS_CONST(ErrorUserInfoKey, DebugDescriptionErrorKey);
|
| 51 |
+
_NS_CONST(ErrorUserInfoKey, LocalizedFailureErrorKey);
|
| 52 |
+
_NS_CONST(ErrorUserInfoKey, StringEncodingErrorKey);
|
| 53 |
+
_NS_CONST(ErrorUserInfoKey, URLErrorKey);
|
| 54 |
+
_NS_CONST(ErrorUserInfoKey, FilePathErrorKey);
|
| 55 |
+
|
| 56 |
+
class Error : public Copying<Error>
|
| 57 |
+
{
|
| 58 |
+
public:
|
| 59 |
+
static Error* error(ErrorDomain domain, Integer code, class Dictionary* pDictionary);
|
| 60 |
+
|
| 61 |
+
static Error* alloc();
|
| 62 |
+
Error* init();
|
| 63 |
+
Error* init(ErrorDomain domain, Integer code, class Dictionary* pDictionary);
|
| 64 |
+
|
| 65 |
+
Integer code() const;
|
| 66 |
+
ErrorDomain domain() const;
|
| 67 |
+
class Dictionary* userInfo() const;
|
| 68 |
+
|
| 69 |
+
class String* localizedDescription() const;
|
| 70 |
+
class Array* localizedRecoveryOptions() const;
|
| 71 |
+
class String* localizedRecoverySuggestion() const;
|
| 72 |
+
class String* localizedFailureReason() const;
|
| 73 |
+
};
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 77 |
+
|
| 78 |
+
_NS_PRIVATE_DEF_CONST(NS::ErrorDomain, CocoaErrorDomain);
|
| 79 |
+
_NS_PRIVATE_DEF_CONST(NS::ErrorDomain, POSIXErrorDomain);
|
| 80 |
+
_NS_PRIVATE_DEF_CONST(NS::ErrorDomain, OSStatusErrorDomain);
|
| 81 |
+
_NS_PRIVATE_DEF_CONST(NS::ErrorDomain, MachErrorDomain);
|
| 82 |
+
|
| 83 |
+
_NS_PRIVATE_DEF_CONST(NS::ErrorUserInfoKey, UnderlyingErrorKey);
|
| 84 |
+
_NS_PRIVATE_DEF_CONST(NS::ErrorUserInfoKey, LocalizedDescriptionKey);
|
| 85 |
+
_NS_PRIVATE_DEF_CONST(NS::ErrorUserInfoKey, LocalizedFailureReasonErrorKey);
|
| 86 |
+
_NS_PRIVATE_DEF_CONST(NS::ErrorUserInfoKey, LocalizedRecoverySuggestionErrorKey);
|
| 87 |
+
_NS_PRIVATE_DEF_CONST(NS::ErrorUserInfoKey, LocalizedRecoveryOptionsErrorKey);
|
| 88 |
+
_NS_PRIVATE_DEF_CONST(NS::ErrorUserInfoKey, RecoveryAttempterErrorKey);
|
| 89 |
+
_NS_PRIVATE_DEF_CONST(NS::ErrorUserInfoKey, HelpAnchorErrorKey);
|
| 90 |
+
_NS_PRIVATE_DEF_CONST(NS::ErrorUserInfoKey, DebugDescriptionErrorKey);
|
| 91 |
+
_NS_PRIVATE_DEF_CONST(NS::ErrorUserInfoKey, LocalizedFailureErrorKey);
|
| 92 |
+
_NS_PRIVATE_DEF_CONST(NS::ErrorUserInfoKey, StringEncodingErrorKey);
|
| 93 |
+
_NS_PRIVATE_DEF_CONST(NS::ErrorUserInfoKey, URLErrorKey);
|
| 94 |
+
_NS_PRIVATE_DEF_CONST(NS::ErrorUserInfoKey, FilePathErrorKey);
|
| 95 |
+
|
| 96 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 97 |
+
|
| 98 |
+
_NS_INLINE NS::Error* NS::Error::error(ErrorDomain domain, Integer code, class Dictionary* pDictionary)
|
| 99 |
+
{
|
| 100 |
+
return Object::sendMessage<Error*>(_NS_PRIVATE_CLS(NSError), _NS_PRIVATE_SEL(errorWithDomain_code_userInfo_), domain, code, pDictionary);
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 104 |
+
|
| 105 |
+
_NS_INLINE NS::Error* NS::Error::alloc()
|
| 106 |
+
{
|
| 107 |
+
return Object::alloc<Error>(_NS_PRIVATE_CLS(NSError));
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 111 |
+
|
| 112 |
+
_NS_INLINE NS::Error* NS::Error::init()
|
| 113 |
+
{
|
| 114 |
+
return Object::init<Error>();
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 118 |
+
|
| 119 |
+
_NS_INLINE NS::Error* NS::Error::init(ErrorDomain domain, Integer code, class Dictionary* pDictionary)
|
| 120 |
+
{
|
| 121 |
+
return Object::sendMessage<Error*>(this, _NS_PRIVATE_SEL(initWithDomain_code_userInfo_), domain, code, pDictionary);
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 125 |
+
|
| 126 |
+
_NS_INLINE NS::Integer NS::Error::code() const
|
| 127 |
+
{
|
| 128 |
+
return Object::sendMessage<Integer>(this, _NS_PRIVATE_SEL(code));
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 132 |
+
|
| 133 |
+
_NS_INLINE NS::ErrorDomain NS::Error::domain() const
|
| 134 |
+
{
|
| 135 |
+
return Object::sendMessage<ErrorDomain>(this, _NS_PRIVATE_SEL(domain));
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 139 |
+
|
| 140 |
+
_NS_INLINE NS::Dictionary* NS::Error::userInfo() const
|
| 141 |
+
{
|
| 142 |
+
return Object::sendMessage<Dictionary*>(this, _NS_PRIVATE_SEL(userInfo));
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 146 |
+
|
| 147 |
+
_NS_INLINE NS::String* NS::Error::localizedDescription() const
|
| 148 |
+
{
|
| 149 |
+
return Object::sendMessage<String*>(this, _NS_PRIVATE_SEL(localizedDescription));
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 153 |
+
|
| 154 |
+
_NS_INLINE NS::Array* NS::Error::localizedRecoveryOptions() const
|
| 155 |
+
{
|
| 156 |
+
return Object::sendMessage<Array*>(this, _NS_PRIVATE_SEL(localizedRecoveryOptions));
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 160 |
+
|
| 161 |
+
_NS_INLINE NS::String* NS::Error::localizedRecoverySuggestion() const
|
| 162 |
+
{
|
| 163 |
+
return Object::sendMessage<String*>(this, _NS_PRIVATE_SEL(localizedRecoverySuggestion));
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 167 |
+
|
| 168 |
+
_NS_INLINE NS::String* NS::Error::localizedFailureReason() const
|
| 169 |
+
{
|
| 170 |
+
return Object::sendMessage<String*>(this, _NS_PRIVATE_SEL(localizedFailureReason));
|
| 171 |
+
}
|
| 172 |
+
|
| 173 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSLock.hpp
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 2 |
+
//
|
| 3 |
+
// Foundation/NSLock.hpp
|
| 4 |
+
//
|
| 5 |
+
// Copyright 2020-2023 Apple Inc.
|
| 6 |
+
//
|
| 7 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
// you may not use this file except in compliance with the License.
|
| 9 |
+
// You may obtain a copy of the License at
|
| 10 |
+
//
|
| 11 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
//
|
| 13 |
+
// Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
// See the License for the specific language governing permissions and
|
| 17 |
+
// limitations under the License.
|
| 18 |
+
//
|
| 19 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
#pragma once
|
| 23 |
+
|
| 24 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 25 |
+
|
| 26 |
+
#include "NSDefines.hpp"
|
| 27 |
+
#include "NSObject.hpp"
|
| 28 |
+
#include "NSPrivate.hpp"
|
| 29 |
+
#include "NSTypes.hpp"
|
| 30 |
+
#include "NSDate.hpp"
|
| 31 |
+
|
| 32 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 33 |
+
|
| 34 |
+
namespace NS
|
| 35 |
+
{
|
| 36 |
+
|
| 37 |
+
template <class _Class, class _Base = class Object>
|
| 38 |
+
class Locking : public _Base
|
| 39 |
+
{
|
| 40 |
+
public:
|
| 41 |
+
void lock();
|
| 42 |
+
void unlock();
|
| 43 |
+
};
|
| 44 |
+
|
| 45 |
+
class Condition : public Locking<Condition>
|
| 46 |
+
{
|
| 47 |
+
public:
|
| 48 |
+
static Condition* alloc();
|
| 49 |
+
|
| 50 |
+
Condition* init();
|
| 51 |
+
|
| 52 |
+
void wait();
|
| 53 |
+
bool waitUntilDate(Date* pLimit);
|
| 54 |
+
void signal();
|
| 55 |
+
void broadcast();
|
| 56 |
+
};
|
| 57 |
+
|
| 58 |
+
} // NS
|
| 59 |
+
|
| 60 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 61 |
+
|
| 62 |
+
template<class _Class, class _Base /* = NS::Object */>
|
| 63 |
+
_NS_INLINE void NS::Locking<_Class, _Base>::lock()
|
| 64 |
+
{
|
| 65 |
+
NS::Object::sendMessage<void>(this, _NS_PRIVATE_SEL(lock));
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 69 |
+
|
| 70 |
+
template<class _Class, class _Base /* = NS::Object */>
|
| 71 |
+
_NS_INLINE void NS::Locking<_Class, _Base>::unlock()
|
| 72 |
+
{
|
| 73 |
+
NS::Object::sendMessage<void>(this, _NS_PRIVATE_SEL(unlock));
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 77 |
+
|
| 78 |
+
_NS_INLINE NS::Condition* NS::Condition::alloc()
|
| 79 |
+
{
|
| 80 |
+
return NS::Object::alloc<NS::Condition>(_NS_PRIVATE_CLS(NSCondition));
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 84 |
+
|
| 85 |
+
_NS_INLINE NS::Condition* NS::Condition::init()
|
| 86 |
+
{
|
| 87 |
+
return NS::Object::init<NS::Condition>();
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 91 |
+
|
| 92 |
+
_NS_INLINE void NS::Condition::wait()
|
| 93 |
+
{
|
| 94 |
+
NS::Object::sendMessage<void>(this, _NS_PRIVATE_SEL(wait));
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 98 |
+
|
| 99 |
+
_NS_INLINE bool NS::Condition::waitUntilDate(NS::Date* pLimit)
|
| 100 |
+
{
|
| 101 |
+
return NS::Object::sendMessage<bool>(this, _NS_PRIVATE_SEL(waitUntilDate_), pLimit);
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 105 |
+
|
| 106 |
+
_NS_INLINE void NS::Condition::signal()
|
| 107 |
+
{
|
| 108 |
+
NS::Object::sendMessage<void>(this, _NS_PRIVATE_SEL(signal));
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 112 |
+
|
| 113 |
+
_NS_INLINE void NS::Condition::broadcast()
|
| 114 |
+
{
|
| 115 |
+
NS::Object::sendMessage<void>(this, _NS_PRIVATE_SEL(broadcast));
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSNotification.hpp
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 2 |
+
//
|
| 3 |
+
// Foundation/NSNotification.hpp
|
| 4 |
+
//
|
| 5 |
+
// Copyright 2020-2023 Apple Inc.
|
| 6 |
+
//
|
| 7 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
// you may not use this file except in compliance with the License.
|
| 9 |
+
// You may obtain a copy of the License at
|
| 10 |
+
//
|
| 11 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
//
|
| 13 |
+
// Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
// See the License for the specific language governing permissions and
|
| 17 |
+
// limitations under the License.
|
| 18 |
+
//
|
| 19 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 20 |
+
|
| 21 |
+
#pragma once
|
| 22 |
+
|
| 23 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 24 |
+
|
| 25 |
+
#include "NSDefines.hpp"
|
| 26 |
+
#include "NSDictionary.hpp"
|
| 27 |
+
#include "NSObject.hpp"
|
| 28 |
+
#include "NSString.hpp"
|
| 29 |
+
#include "NSTypes.hpp"
|
| 30 |
+
#include <functional>
|
| 31 |
+
|
| 32 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 33 |
+
|
| 34 |
+
namespace NS
|
| 35 |
+
{
|
| 36 |
+
using NotificationName = class String*;
|
| 37 |
+
|
| 38 |
+
class Notification : public NS::Referencing<Notification>
|
| 39 |
+
{
|
| 40 |
+
public:
|
| 41 |
+
NS::String* name() const;
|
| 42 |
+
NS::Object* object() const;
|
| 43 |
+
NS::Dictionary* userInfo() const;
|
| 44 |
+
};
|
| 45 |
+
|
| 46 |
+
using ObserverBlock = void(^)(Notification*);
|
| 47 |
+
using ObserverFunction = std::function<void(Notification*)>;
|
| 48 |
+
|
| 49 |
+
class NotificationCenter : public NS::Referencing<NotificationCenter>
|
| 50 |
+
{
|
| 51 |
+
public:
|
| 52 |
+
static class NotificationCenter* defaultCenter();
|
| 53 |
+
Object* addObserver(NotificationName name, Object* pObj, void* pQueue, ObserverBlock block);
|
| 54 |
+
Object* addObserver(NotificationName name, Object* pObj, void* pQueue, ObserverFunction &handler);
|
| 55 |
+
void removeObserver(Object* pObserver);
|
| 56 |
+
|
| 57 |
+
};
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 61 |
+
|
| 62 |
+
_NS_INLINE NS::String* NS::Notification::name() const
|
| 63 |
+
{
|
| 64 |
+
return Object::sendMessage<NS::String*>(this, _NS_PRIVATE_SEL(name));
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 68 |
+
|
| 69 |
+
_NS_INLINE NS::Object* NS::Notification::object() const
|
| 70 |
+
{
|
| 71 |
+
return Object::sendMessage<NS::Object*>(this, _NS_PRIVATE_SEL(object));
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 75 |
+
|
| 76 |
+
_NS_INLINE NS::Dictionary* NS::Notification::userInfo() const
|
| 77 |
+
{
|
| 78 |
+
return Object::sendMessage<NS::Dictionary*>(this, _NS_PRIVATE_SEL(userInfo));
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 82 |
+
|
| 83 |
+
_NS_INLINE NS::NotificationCenter* NS::NotificationCenter::defaultCenter()
|
| 84 |
+
{
|
| 85 |
+
return NS::Object::sendMessage<NS::NotificationCenter*>(_NS_PRIVATE_CLS(NSNotificationCenter), _NS_PRIVATE_SEL(defaultCenter));
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 89 |
+
|
| 90 |
+
_NS_INLINE NS::Object* NS::NotificationCenter::addObserver(NS::NotificationName name, Object* pObj, void* pQueue, NS::ObserverBlock block)
|
| 91 |
+
{
|
| 92 |
+
return NS::Object::sendMessage<Object*>(this, _NS_PRIVATE_SEL(addObserverName_object_queue_block_), name, pObj, pQueue, block);
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 96 |
+
|
| 97 |
+
_NS_INLINE NS::Object* NS::NotificationCenter::addObserver(NS::NotificationName name, Object* pObj, void* pQueue, NS::ObserverFunction &handler)
|
| 98 |
+
{
|
| 99 |
+
__block ObserverFunction blockFunction = handler;
|
| 100 |
+
|
| 101 |
+
return addObserver(name, pObj, pQueue, ^(NS::Notification* pNotif) {blockFunction(pNotif);});
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 105 |
+
|
| 106 |
+
_NS_INLINE void NS::NotificationCenter::removeObserver(Object* pObserver)
|
| 107 |
+
{
|
| 108 |
+
return NS::Object::sendMessage<void>(this, _NS_PRIVATE_SEL(removeObserver_), pObserver);
|
| 109 |
+
}
|
| 110 |
+
|
lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSNumber.hpp
ADDED
|
@@ -0,0 +1,501 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 2 |
+
//
|
| 3 |
+
// Foundation/NSNumber.hpp
|
| 4 |
+
//
|
| 5 |
+
// Copyright 2020-2023 Apple Inc.
|
| 6 |
+
//
|
| 7 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
// you may not use this file except in compliance with the License.
|
| 9 |
+
// You may obtain a copy of the License at
|
| 10 |
+
//
|
| 11 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
//
|
| 13 |
+
// Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
// See the License for the specific language governing permissions and
|
| 17 |
+
// limitations under the License.
|
| 18 |
+
//
|
| 19 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 20 |
+
|
| 21 |
+
#pragma once
|
| 22 |
+
|
| 23 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 24 |
+
|
| 25 |
+
#include "NSObjCRuntime.hpp"
|
| 26 |
+
#include "NSObject.hpp"
|
| 27 |
+
#include "NSTypes.hpp"
|
| 28 |
+
|
| 29 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 30 |
+
|
| 31 |
+
namespace NS
|
| 32 |
+
{
|
| 33 |
+
class Value : public Copying<Value>
|
| 34 |
+
{
|
| 35 |
+
public:
|
| 36 |
+
static Value* value(const void* pValue, const char* pType);
|
| 37 |
+
static Value* value(const void* pPointer);
|
| 38 |
+
|
| 39 |
+
static Value* alloc();
|
| 40 |
+
|
| 41 |
+
Value* init(const void* pValue, const char* pType);
|
| 42 |
+
Value* init(const class Coder* pCoder);
|
| 43 |
+
|
| 44 |
+
void getValue(void* pValue, UInteger size) const;
|
| 45 |
+
const char* objCType() const;
|
| 46 |
+
|
| 47 |
+
bool isEqualToValue(Value* pValue) const;
|
| 48 |
+
void* pointerValue() const;
|
| 49 |
+
};
|
| 50 |
+
|
| 51 |
+
class Number : public Copying<Number, Value>
|
| 52 |
+
{
|
| 53 |
+
public:
|
| 54 |
+
static Number* number(char value);
|
| 55 |
+
static Number* number(unsigned char value);
|
| 56 |
+
static Number* number(short value);
|
| 57 |
+
static Number* number(unsigned short value);
|
| 58 |
+
static Number* number(int value);
|
| 59 |
+
static Number* number(unsigned int value);
|
| 60 |
+
static Number* number(long value);
|
| 61 |
+
static Number* number(unsigned long value);
|
| 62 |
+
static Number* number(long long value);
|
| 63 |
+
static Number* number(unsigned long long value);
|
| 64 |
+
static Number* number(float value);
|
| 65 |
+
static Number* number(double value);
|
| 66 |
+
static Number* number(bool value);
|
| 67 |
+
|
| 68 |
+
static Number* alloc();
|
| 69 |
+
|
| 70 |
+
Number* init(const class Coder* pCoder);
|
| 71 |
+
Number* init(char value);
|
| 72 |
+
Number* init(unsigned char value);
|
| 73 |
+
Number* init(short value);
|
| 74 |
+
Number* init(unsigned short value);
|
| 75 |
+
Number* init(int value);
|
| 76 |
+
Number* init(unsigned int value);
|
| 77 |
+
Number* init(long value);
|
| 78 |
+
Number* init(unsigned long value);
|
| 79 |
+
Number* init(long long value);
|
| 80 |
+
Number* init(unsigned long long value);
|
| 81 |
+
Number* init(float value);
|
| 82 |
+
Number* init(double value);
|
| 83 |
+
Number* init(bool value);
|
| 84 |
+
|
| 85 |
+
char charValue() const;
|
| 86 |
+
unsigned char unsignedCharValue() const;
|
| 87 |
+
short shortValue() const;
|
| 88 |
+
unsigned short unsignedShortValue() const;
|
| 89 |
+
int intValue() const;
|
| 90 |
+
unsigned int unsignedIntValue() const;
|
| 91 |
+
long longValue() const;
|
| 92 |
+
unsigned long unsignedLongValue() const;
|
| 93 |
+
long long longLongValue() const;
|
| 94 |
+
unsigned long long unsignedLongLongValue() const;
|
| 95 |
+
float floatValue() const;
|
| 96 |
+
double doubleValue() const;
|
| 97 |
+
bool boolValue() const;
|
| 98 |
+
Integer integerValue() const;
|
| 99 |
+
UInteger unsignedIntegerValue() const;
|
| 100 |
+
class String* stringValue() const;
|
| 101 |
+
|
| 102 |
+
ComparisonResult compare(const Number* pOtherNumber) const;
|
| 103 |
+
bool isEqualToNumber(const Number* pNumber) const;
|
| 104 |
+
|
| 105 |
+
class String* descriptionWithLocale(const Object* pLocale) const;
|
| 106 |
+
};
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 110 |
+
|
| 111 |
+
_NS_INLINE NS::Value* NS::Value::value(const void* pValue, const char* pType)
|
| 112 |
+
{
|
| 113 |
+
return Object::sendMessage<Value*>(_NS_PRIVATE_CLS(NSValue), _NS_PRIVATE_SEL(valueWithBytes_objCType_), pValue, pType);
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 117 |
+
|
| 118 |
+
_NS_INLINE NS::Value* NS::Value::value(const void* pPointer)
|
| 119 |
+
{
|
| 120 |
+
return Object::sendMessage<Value*>(_NS_PRIVATE_CLS(NSValue), _NS_PRIVATE_SEL(valueWithPointer_), pPointer);
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 124 |
+
|
| 125 |
+
_NS_INLINE NS::Value* NS::Value::alloc()
|
| 126 |
+
{
|
| 127 |
+
return NS::Object::alloc<Value>(_NS_PRIVATE_CLS(NSValue));
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 131 |
+
|
| 132 |
+
_NS_INLINE NS::Value* NS::Value::init(const void* pValue, const char* pType)
|
| 133 |
+
{
|
| 134 |
+
return Object::sendMessage<Value*>(this, _NS_PRIVATE_SEL(initWithBytes_objCType_), pValue, pType);
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 138 |
+
|
| 139 |
+
_NS_INLINE NS::Value* NS::Value::init(const class Coder* pCoder)
|
| 140 |
+
{
|
| 141 |
+
return Object::sendMessage<Value*>(this, _NS_PRIVATE_SEL(initWithCoder_), pCoder);
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 145 |
+
|
| 146 |
+
_NS_INLINE void NS::Value::getValue(void* pValue, UInteger size) const
|
| 147 |
+
{
|
| 148 |
+
Object::sendMessage<void>(this, _NS_PRIVATE_SEL(getValue_size_), pValue, size);
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 152 |
+
|
| 153 |
+
_NS_INLINE const char* NS::Value::objCType() const
|
| 154 |
+
{
|
| 155 |
+
return Object::sendMessage<const char*>(this, _NS_PRIVATE_SEL(objCType));
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 159 |
+
|
| 160 |
+
_NS_INLINE bool NS::Value::isEqualToValue(Value* pValue) const
|
| 161 |
+
{
|
| 162 |
+
return Object::sendMessage<bool>(this, _NS_PRIVATE_SEL(isEqualToValue_), pValue);
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 166 |
+
|
| 167 |
+
_NS_INLINE void* NS::Value::pointerValue() const
|
| 168 |
+
{
|
| 169 |
+
return Object::sendMessage<void*>(this, _NS_PRIVATE_SEL(pointerValue));
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 173 |
+
|
| 174 |
+
_NS_INLINE NS::Number* NS::Number::number(char value)
|
| 175 |
+
{
|
| 176 |
+
return Object::sendMessage<Number*>(_NS_PRIVATE_CLS(NSNumber), _NS_PRIVATE_SEL(numberWithChar_), value);
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 180 |
+
|
| 181 |
+
_NS_INLINE NS::Number* NS::Number::number(unsigned char value)
|
| 182 |
+
{
|
| 183 |
+
return Object::sendMessage<Number*>(_NS_PRIVATE_CLS(NSNumber), _NS_PRIVATE_SEL(numberWithUnsignedChar_), value);
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 187 |
+
|
| 188 |
+
_NS_INLINE NS::Number* NS::Number::number(short value)
|
| 189 |
+
{
|
| 190 |
+
return Object::sendMessage<Number*>(_NS_PRIVATE_CLS(NSNumber), _NS_PRIVATE_SEL(numberWithShort_), value);
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 194 |
+
|
| 195 |
+
_NS_INLINE NS::Number* NS::Number::number(unsigned short value)
|
| 196 |
+
{
|
| 197 |
+
return Object::sendMessage<Number*>(_NS_PRIVATE_CLS(NSNumber), _NS_PRIVATE_SEL(numberWithUnsignedShort_), value);
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 201 |
+
|
| 202 |
+
_NS_INLINE NS::Number* NS::Number::number(int value)
|
| 203 |
+
{
|
| 204 |
+
return Object::sendMessage<Number*>(_NS_PRIVATE_CLS(NSNumber), _NS_PRIVATE_SEL(numberWithInt_), value);
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 208 |
+
|
| 209 |
+
_NS_INLINE NS::Number* NS::Number::number(unsigned int value)
|
| 210 |
+
{
|
| 211 |
+
return Object::sendMessage<Number*>(_NS_PRIVATE_CLS(NSNumber), _NS_PRIVATE_SEL(numberWithUnsignedInt_), value);
|
| 212 |
+
}
|
| 213 |
+
|
| 214 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 215 |
+
|
| 216 |
+
_NS_INLINE NS::Number* NS::Number::number(long value)
|
| 217 |
+
{
|
| 218 |
+
return Object::sendMessage<Number*>(_NS_PRIVATE_CLS(NSNumber), _NS_PRIVATE_SEL(numberWithLong_), value);
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 222 |
+
|
| 223 |
+
_NS_INLINE NS::Number* NS::Number::number(unsigned long value)
|
| 224 |
+
{
|
| 225 |
+
return Object::sendMessage<Number*>(_NS_PRIVATE_CLS(NSNumber), _NS_PRIVATE_SEL(numberWithUnsignedLong_), value);
|
| 226 |
+
}
|
| 227 |
+
|
| 228 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 229 |
+
|
| 230 |
+
_NS_INLINE NS::Number* NS::Number::number(long long value)
|
| 231 |
+
{
|
| 232 |
+
return Object::sendMessage<Number*>(_NS_PRIVATE_CLS(NSNumber), _NS_PRIVATE_SEL(numberWithLongLong_), value);
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 236 |
+
|
| 237 |
+
_NS_INLINE NS::Number* NS::Number::number(unsigned long long value)
|
| 238 |
+
{
|
| 239 |
+
return Object::sendMessage<Number*>(_NS_PRIVATE_CLS(NSNumber), _NS_PRIVATE_SEL(numberWithUnsignedLongLong_), value);
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 243 |
+
|
| 244 |
+
_NS_INLINE NS::Number* NS::Number::number(float value)
|
| 245 |
+
{
|
| 246 |
+
return Object::sendMessage<Number*>(_NS_PRIVATE_CLS(NSNumber), _NS_PRIVATE_SEL(numberWithFloat_), value);
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 250 |
+
|
| 251 |
+
_NS_INLINE NS::Number* NS::Number::number(double value)
|
| 252 |
+
{
|
| 253 |
+
return Object::sendMessage<Number*>(_NS_PRIVATE_CLS(NSNumber), _NS_PRIVATE_SEL(numberWithDouble_), value);
|
| 254 |
+
}
|
| 255 |
+
|
| 256 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 257 |
+
|
| 258 |
+
_NS_INLINE NS::Number* NS::Number::number(bool value)
|
| 259 |
+
{
|
| 260 |
+
return Object::sendMessage<Number*>(_NS_PRIVATE_CLS(NSNumber), _NS_PRIVATE_SEL(numberWithBool_), value);
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 264 |
+
|
| 265 |
+
_NS_INLINE NS::Number* NS::Number::alloc()
|
| 266 |
+
{
|
| 267 |
+
return NS::Object::alloc<Number>(_NS_PRIVATE_CLS(NSNumber));
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 271 |
+
|
| 272 |
+
_NS_INLINE NS::Number* NS::Number::init(const Coder* pCoder)
|
| 273 |
+
{
|
| 274 |
+
return Object::sendMessage<Number*>(this, _NS_PRIVATE_SEL(initWithCoder_), pCoder);
|
| 275 |
+
}
|
| 276 |
+
|
| 277 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 278 |
+
|
| 279 |
+
_NS_INLINE NS::Number* NS::Number::init(char value)
|
| 280 |
+
{
|
| 281 |
+
return Object::sendMessage<Number*>(this, _NS_PRIVATE_SEL(initWithChar_), value);
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 285 |
+
|
| 286 |
+
_NS_INLINE NS::Number* NS::Number::init(unsigned char value)
|
| 287 |
+
{
|
| 288 |
+
return Object::sendMessage<Number*>(this, _NS_PRIVATE_SEL(initWithUnsignedChar_), value);
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 292 |
+
|
| 293 |
+
_NS_INLINE NS::Number* NS::Number::init(short value)
|
| 294 |
+
{
|
| 295 |
+
return Object::sendMessage<Number*>(this, _NS_PRIVATE_SEL(initWithShort_), value);
|
| 296 |
+
}
|
| 297 |
+
|
| 298 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 299 |
+
|
| 300 |
+
_NS_INLINE NS::Number* NS::Number::init(unsigned short value)
|
| 301 |
+
{
|
| 302 |
+
return Object::sendMessage<Number*>(this, _NS_PRIVATE_SEL(initWithUnsignedShort_), value);
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 306 |
+
|
| 307 |
+
_NS_INLINE NS::Number* NS::Number::init(int value)
|
| 308 |
+
{
|
| 309 |
+
return Object::sendMessage<Number*>(this, _NS_PRIVATE_SEL(initWithInt_), value);
|
| 310 |
+
}
|
| 311 |
+
|
| 312 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 313 |
+
|
| 314 |
+
_NS_INLINE NS::Number* NS::Number::init(unsigned int value)
|
| 315 |
+
{
|
| 316 |
+
return Object::sendMessage<Number*>(this, _NS_PRIVATE_SEL(initWithUnsignedInt_), value);
|
| 317 |
+
}
|
| 318 |
+
|
| 319 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 320 |
+
|
| 321 |
+
_NS_INLINE NS::Number* NS::Number::init(long value)
|
| 322 |
+
{
|
| 323 |
+
return Object::sendMessage<Number*>(this, _NS_PRIVATE_SEL(initWithLong_), value);
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 327 |
+
|
| 328 |
+
_NS_INLINE NS::Number* NS::Number::init(unsigned long value)
|
| 329 |
+
{
|
| 330 |
+
return Object::sendMessage<Number*>(this, _NS_PRIVATE_SEL(initWithUnsignedLong_), value);
|
| 331 |
+
}
|
| 332 |
+
|
| 333 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 334 |
+
|
| 335 |
+
_NS_INLINE NS::Number* NS::Number::init(long long value)
|
| 336 |
+
{
|
| 337 |
+
return Object::sendMessage<Number*>(this, _NS_PRIVATE_SEL(initWithLongLong_), value);
|
| 338 |
+
}
|
| 339 |
+
|
| 340 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 341 |
+
|
| 342 |
+
_NS_INLINE NS::Number* NS::Number::init(unsigned long long value)
|
| 343 |
+
{
|
| 344 |
+
return Object::sendMessage<Number*>(this, _NS_PRIVATE_SEL(initWithUnsignedLongLong_), value);
|
| 345 |
+
}
|
| 346 |
+
|
| 347 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 348 |
+
|
| 349 |
+
_NS_INLINE NS::Number* NS::Number::init(float value)
|
| 350 |
+
{
|
| 351 |
+
return Object::sendMessage<Number*>(this, _NS_PRIVATE_SEL(initWithFloat_), value);
|
| 352 |
+
}
|
| 353 |
+
|
| 354 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 355 |
+
|
| 356 |
+
_NS_INLINE NS::Number* NS::Number::init(double value)
|
| 357 |
+
{
|
| 358 |
+
return Object::sendMessage<Number*>(this, _NS_PRIVATE_SEL(initWithDouble_), value);
|
| 359 |
+
}
|
| 360 |
+
|
| 361 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 362 |
+
|
| 363 |
+
_NS_INLINE NS::Number* NS::Number::init(bool value)
|
| 364 |
+
{
|
| 365 |
+
return Object::sendMessage<Number*>(this, _NS_PRIVATE_SEL(initWithBool_), value);
|
| 366 |
+
}
|
| 367 |
+
|
| 368 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 369 |
+
|
| 370 |
+
_NS_INLINE char NS::Number::charValue() const
|
| 371 |
+
{
|
| 372 |
+
return Object::sendMessage<char>(this, _NS_PRIVATE_SEL(charValue));
|
| 373 |
+
}
|
| 374 |
+
|
| 375 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 376 |
+
|
| 377 |
+
_NS_INLINE unsigned char NS::Number::unsignedCharValue() const
|
| 378 |
+
{
|
| 379 |
+
return Object::sendMessage<unsigned char>(this, _NS_PRIVATE_SEL(unsignedCharValue));
|
| 380 |
+
}
|
| 381 |
+
|
| 382 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 383 |
+
|
| 384 |
+
_NS_INLINE short NS::Number::shortValue() const
|
| 385 |
+
{
|
| 386 |
+
return Object::sendMessage<short>(this, _NS_PRIVATE_SEL(shortValue));
|
| 387 |
+
}
|
| 388 |
+
|
| 389 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 390 |
+
|
| 391 |
+
_NS_INLINE unsigned short NS::Number::unsignedShortValue() const
|
| 392 |
+
{
|
| 393 |
+
return Object::sendMessage<unsigned short>(this, _NS_PRIVATE_SEL(unsignedShortValue));
|
| 394 |
+
}
|
| 395 |
+
|
| 396 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 397 |
+
|
| 398 |
+
_NS_INLINE int NS::Number::intValue() const
|
| 399 |
+
{
|
| 400 |
+
return Object::sendMessage<int>(this, _NS_PRIVATE_SEL(intValue));
|
| 401 |
+
}
|
| 402 |
+
|
| 403 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 404 |
+
|
| 405 |
+
_NS_INLINE unsigned int NS::Number::unsignedIntValue() const
|
| 406 |
+
{
|
| 407 |
+
return Object::sendMessage<unsigned int>(this, _NS_PRIVATE_SEL(unsignedIntValue));
|
| 408 |
+
}
|
| 409 |
+
|
| 410 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 411 |
+
|
| 412 |
+
_NS_INLINE long NS::Number::longValue() const
|
| 413 |
+
{
|
| 414 |
+
return Object::sendMessage<long>(this, _NS_PRIVATE_SEL(longValue));
|
| 415 |
+
}
|
| 416 |
+
|
| 417 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 418 |
+
|
| 419 |
+
_NS_INLINE unsigned long NS::Number::unsignedLongValue() const
|
| 420 |
+
{
|
| 421 |
+
return Object::sendMessage<unsigned long>(this, _NS_PRIVATE_SEL(unsignedLongValue));
|
| 422 |
+
}
|
| 423 |
+
|
| 424 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 425 |
+
|
| 426 |
+
_NS_INLINE long long NS::Number::longLongValue() const
|
| 427 |
+
{
|
| 428 |
+
return Object::sendMessage<long long>(this, _NS_PRIVATE_SEL(longLongValue));
|
| 429 |
+
}
|
| 430 |
+
|
| 431 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 432 |
+
|
| 433 |
+
_NS_INLINE unsigned long long NS::Number::unsignedLongLongValue() const
|
| 434 |
+
{
|
| 435 |
+
return Object::sendMessage<unsigned long long>(this, _NS_PRIVATE_SEL(unsignedLongLongValue));
|
| 436 |
+
}
|
| 437 |
+
|
| 438 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 439 |
+
|
| 440 |
+
_NS_INLINE float NS::Number::floatValue() const
|
| 441 |
+
{
|
| 442 |
+
return Object::sendMessage<float>(this, _NS_PRIVATE_SEL(floatValue));
|
| 443 |
+
}
|
| 444 |
+
|
| 445 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 446 |
+
|
| 447 |
+
_NS_INLINE double NS::Number::doubleValue() const
|
| 448 |
+
{
|
| 449 |
+
return Object::sendMessage<double>(this, _NS_PRIVATE_SEL(doubleValue));
|
| 450 |
+
}
|
| 451 |
+
|
| 452 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 453 |
+
|
| 454 |
+
_NS_INLINE bool NS::Number::boolValue() const
|
| 455 |
+
{
|
| 456 |
+
return Object::sendMessage<bool>(this, _NS_PRIVATE_SEL(boolValue));
|
| 457 |
+
}
|
| 458 |
+
|
| 459 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 460 |
+
|
| 461 |
+
_NS_INLINE NS::Integer NS::Number::integerValue() const
|
| 462 |
+
{
|
| 463 |
+
return Object::sendMessage<Integer>(this, _NS_PRIVATE_SEL(integerValue));
|
| 464 |
+
}
|
| 465 |
+
|
| 466 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 467 |
+
|
| 468 |
+
_NS_INLINE NS::UInteger NS::Number::unsignedIntegerValue() const
|
| 469 |
+
{
|
| 470 |
+
return Object::sendMessage<UInteger>(this, _NS_PRIVATE_SEL(unsignedIntegerValue));
|
| 471 |
+
}
|
| 472 |
+
|
| 473 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 474 |
+
|
| 475 |
+
_NS_INLINE NS::String* NS::Number::stringValue() const
|
| 476 |
+
{
|
| 477 |
+
return Object::sendMessage<String*>(this, _NS_PRIVATE_SEL(stringValue));
|
| 478 |
+
}
|
| 479 |
+
|
| 480 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 481 |
+
|
| 482 |
+
_NS_INLINE NS::ComparisonResult NS::Number::compare(const Number* pOtherNumber) const
|
| 483 |
+
{
|
| 484 |
+
return Object::sendMessage<ComparisonResult>(this, _NS_PRIVATE_SEL(compare_), pOtherNumber);
|
| 485 |
+
}
|
| 486 |
+
|
| 487 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 488 |
+
|
| 489 |
+
_NS_INLINE bool NS::Number::isEqualToNumber(const Number* pNumber) const
|
| 490 |
+
{
|
| 491 |
+
return Object::sendMessage<bool>(this, _NS_PRIVATE_SEL(isEqualToNumber_), pNumber);
|
| 492 |
+
}
|
| 493 |
+
|
| 494 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 495 |
+
|
| 496 |
+
_NS_INLINE NS::String* NS::Number::descriptionWithLocale(const Object* pLocale) const
|
| 497 |
+
{
|
| 498 |
+
return Object::sendMessage<String*>(this, _NS_PRIVATE_SEL(descriptionWithLocale_), pLocale);
|
| 499 |
+
}
|
| 500 |
+
|
| 501 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSObjCRuntime.hpp
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 2 |
+
//
|
| 3 |
+
// Foundation/NSObjCRuntime.hpp
|
| 4 |
+
//
|
| 5 |
+
// Copyright 2020-2023 Apple Inc.
|
| 6 |
+
//
|
| 7 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
// you may not use this file except in compliance with the License.
|
| 9 |
+
// You may obtain a copy of the License at
|
| 10 |
+
//
|
| 11 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
//
|
| 13 |
+
// Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
// See the License for the specific language governing permissions and
|
| 17 |
+
// limitations under the License.
|
| 18 |
+
//
|
| 19 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 20 |
+
|
| 21 |
+
#pragma once
|
| 22 |
+
|
| 23 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 24 |
+
|
| 25 |
+
#include "NSDefines.hpp"
|
| 26 |
+
#include "NSTypes.hpp"
|
| 27 |
+
|
| 28 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 29 |
+
|
| 30 |
+
namespace NS
|
| 31 |
+
{
|
| 32 |
+
|
| 33 |
+
_NS_ENUM(Integer, ComparisonResult) {
|
| 34 |
+
OrderedAscending = -1L,
|
| 35 |
+
OrderedSame,
|
| 36 |
+
OrderedDescending
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
const Integer NotFound = IntegerMax;
|
| 40 |
+
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
lib/python3.11/site-packages/mlx/include/metal_cpp/Foundation/NSObject.hpp
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 2 |
+
//
|
| 3 |
+
// Foundation/NSObject.hpp
|
| 4 |
+
//
|
| 5 |
+
// Copyright 2020-2023 Apple Inc.
|
| 6 |
+
//
|
| 7 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
| 8 |
+
// you may not use this file except in compliance with the License.
|
| 9 |
+
// You may obtain a copy of the License at
|
| 10 |
+
//
|
| 11 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
| 12 |
+
//
|
| 13 |
+
// Unless required by applicable law or agreed to in writing, software
|
| 14 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
| 15 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 16 |
+
// See the License for the specific language governing permissions and
|
| 17 |
+
// limitations under the License.
|
| 18 |
+
//
|
| 19 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 20 |
+
|
| 21 |
+
#pragma once
|
| 22 |
+
|
| 23 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 24 |
+
|
| 25 |
+
#include "NSDefines.hpp"
|
| 26 |
+
#include "NSPrivate.hpp"
|
| 27 |
+
#include "NSTypes.hpp"
|
| 28 |
+
|
| 29 |
+
#include <objc/message.h>
|
| 30 |
+
#include <objc/runtime.h>
|
| 31 |
+
|
| 32 |
+
#include <type_traits>
|
| 33 |
+
|
| 34 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 35 |
+
|
| 36 |
+
namespace NS
|
| 37 |
+
{
|
| 38 |
+
template <class _Class, class _Base = class Object>
|
| 39 |
+
class _NS_EXPORT Referencing : public _Base
|
| 40 |
+
{
|
| 41 |
+
public:
|
| 42 |
+
_Class* retain();
|
| 43 |
+
void release();
|
| 44 |
+
|
| 45 |
+
_Class* autorelease();
|
| 46 |
+
|
| 47 |
+
UInteger retainCount() const;
|
| 48 |
+
};
|
| 49 |
+
|
| 50 |
+
template <class _Class, class _Base = class Object>
|
| 51 |
+
class Copying : public Referencing<_Class, _Base>
|
| 52 |
+
{
|
| 53 |
+
public:
|
| 54 |
+
_Class* copy() const;
|
| 55 |
+
};
|
| 56 |
+
|
| 57 |
+
template <class _Class, class _Base = class Object>
|
| 58 |
+
class SecureCoding : public Referencing<_Class, _Base>
|
| 59 |
+
{
|
| 60 |
+
};
|
| 61 |
+
|
| 62 |
+
class Object : public Referencing<Object, objc_object>
|
| 63 |
+
{
|
| 64 |
+
public:
|
| 65 |
+
UInteger hash() const;
|
| 66 |
+
bool isEqual(const Object* pObject) const;
|
| 67 |
+
|
| 68 |
+
class String* description() const;
|
| 69 |
+
class String* debugDescription() const;
|
| 70 |
+
|
| 71 |
+
protected:
|
| 72 |
+
friend class Referencing<Object, objc_object>;
|
| 73 |
+
|
| 74 |
+
template <class _Class>
|
| 75 |
+
static _Class* alloc(const char* pClassName);
|
| 76 |
+
template <class _Class>
|
| 77 |
+
static _Class* alloc(const void* pClass);
|
| 78 |
+
template <class _Class>
|
| 79 |
+
_Class* init();
|
| 80 |
+
|
| 81 |
+
template <class _Dst>
|
| 82 |
+
static _Dst bridgingCast(const void* pObj);
|
| 83 |
+
static class MethodSignature* methodSignatureForSelector(const void* pObj, SEL selector);
|
| 84 |
+
static bool respondsToSelector(const void* pObj, SEL selector);
|
| 85 |
+
template <typename _Type>
|
| 86 |
+
static constexpr bool doesRequireMsgSendStret();
|
| 87 |
+
template <typename _Ret, typename... _Args>
|
| 88 |
+
static _Ret sendMessage(const void* pObj, SEL selector, _Args... args);
|
| 89 |
+
template <typename _Ret, typename... _Args>
|
| 90 |
+
static _Ret sendMessageSafe(const void* pObj, SEL selector, _Args... args);
|
| 91 |
+
|
| 92 |
+
private:
|
| 93 |
+
Object() = delete;
|
| 94 |
+
Object(const Object&) = delete;
|
| 95 |
+
~Object() = delete;
|
| 96 |
+
|
| 97 |
+
Object& operator=(const Object&) = delete;
|
| 98 |
+
};
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 102 |
+
|
| 103 |
+
template <class _Class, class _Base /* = Object */>
|
| 104 |
+
_NS_INLINE _Class* NS::Referencing<_Class, _Base>::retain()
|
| 105 |
+
{
|
| 106 |
+
return Object::sendMessage<_Class*>(this, _NS_PRIVATE_SEL(retain));
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 110 |
+
|
| 111 |
+
template <class _Class, class _Base /* = Object */>
|
| 112 |
+
_NS_INLINE void NS::Referencing<_Class, _Base>::release()
|
| 113 |
+
{
|
| 114 |
+
Object::sendMessage<void>(this, _NS_PRIVATE_SEL(release));
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 118 |
+
|
| 119 |
+
template <class _Class, class _Base /* = Object */>
|
| 120 |
+
_NS_INLINE _Class* NS::Referencing<_Class, _Base>::autorelease()
|
| 121 |
+
{
|
| 122 |
+
return Object::sendMessage<_Class*>(this, _NS_PRIVATE_SEL(autorelease));
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 126 |
+
|
| 127 |
+
template <class _Class, class _Base /* = Object */>
|
| 128 |
+
_NS_INLINE NS::UInteger NS::Referencing<_Class, _Base>::retainCount() const
|
| 129 |
+
{
|
| 130 |
+
return Object::sendMessage<UInteger>(this, _NS_PRIVATE_SEL(retainCount));
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 134 |
+
|
| 135 |
+
template <class _Class, class _Base /* = Object */>
|
| 136 |
+
_NS_INLINE _Class* NS::Copying<_Class, _Base>::copy() const
|
| 137 |
+
{
|
| 138 |
+
return Object::sendMessage<_Class*>(this, _NS_PRIVATE_SEL(copy));
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 142 |
+
|
| 143 |
+
template <class _Dst>
|
| 144 |
+
_NS_INLINE _Dst NS::Object::bridgingCast(const void* pObj)
|
| 145 |
+
{
|
| 146 |
+
#ifdef __OBJC__
|
| 147 |
+
return (__bridge _Dst)pObj;
|
| 148 |
+
#else
|
| 149 |
+
return (_Dst)pObj;
|
| 150 |
+
#endif // __OBJC__
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 154 |
+
|
| 155 |
+
template <typename _Type>
|
| 156 |
+
_NS_INLINE constexpr bool NS::Object::doesRequireMsgSendStret()
|
| 157 |
+
{
|
| 158 |
+
#if (defined(__i386__) || defined(__x86_64__))
|
| 159 |
+
constexpr size_t kStructLimit = (sizeof(std::uintptr_t) << 1);
|
| 160 |
+
|
| 161 |
+
return sizeof(_Type) > kStructLimit;
|
| 162 |
+
#elif defined(__arm64__)
|
| 163 |
+
return false;
|
| 164 |
+
#elif defined(__arm__)
|
| 165 |
+
constexpr size_t kStructLimit = sizeof(std::uintptr_t);
|
| 166 |
+
|
| 167 |
+
return std::is_class(_Type) && (sizeof(_Type) > kStructLimit);
|
| 168 |
+
#else
|
| 169 |
+
#error "Unsupported architecture!"
|
| 170 |
+
#endif
|
| 171 |
+
}
|
| 172 |
+
|
| 173 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 174 |
+
|
| 175 |
+
template <>
|
| 176 |
+
_NS_INLINE constexpr bool NS::Object::doesRequireMsgSendStret<void>()
|
| 177 |
+
{
|
| 178 |
+
return false;
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 182 |
+
|
| 183 |
+
template <typename _Ret, typename... _Args>
|
| 184 |
+
_NS_INLINE _Ret NS::Object::sendMessage(const void* pObj, SEL selector, _Args... args)
|
| 185 |
+
{
|
| 186 |
+
#if (defined(__i386__) || defined(__x86_64__))
|
| 187 |
+
if constexpr (std::is_floating_point<_Ret>())
|
| 188 |
+
{
|
| 189 |
+
using SendMessageProcFpret = _Ret (*)(const void*, SEL, _Args...);
|
| 190 |
+
|
| 191 |
+
const SendMessageProcFpret pProc = reinterpret_cast<SendMessageProcFpret>(&objc_msgSend_fpret);
|
| 192 |
+
|
| 193 |
+
return (*pProc)(pObj, selector, args...);
|
| 194 |
+
}
|
| 195 |
+
else
|
| 196 |
+
#endif // ( defined( __i386__ ) || defined( __x86_64__ ) )
|
| 197 |
+
#if !defined(__arm64__)
|
| 198 |
+
if constexpr (doesRequireMsgSendStret<_Ret>())
|
| 199 |
+
{
|
| 200 |
+
using SendMessageProcStret = void (*)(_Ret*, const void*, SEL, _Args...);
|
| 201 |
+
|
| 202 |
+
const SendMessageProcStret pProc = reinterpret_cast<SendMessageProcStret>(&objc_msgSend_stret);
|
| 203 |
+
_Ret ret;
|
| 204 |
+
|
| 205 |
+
(*pProc)(&ret, pObj, selector, args...);
|
| 206 |
+
|
| 207 |
+
return ret;
|
| 208 |
+
}
|
| 209 |
+
else
|
| 210 |
+
#endif // !defined( __arm64__ )
|
| 211 |
+
{
|
| 212 |
+
using SendMessageProc = _Ret (*)(const void*, SEL, _Args...);
|
| 213 |
+
|
| 214 |
+
const SendMessageProc pProc = reinterpret_cast<SendMessageProc>(&objc_msgSend);
|
| 215 |
+
|
| 216 |
+
return (*pProc)(pObj, selector, args...);
|
| 217 |
+
}
|
| 218 |
+
}
|
| 219 |
+
|
| 220 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 221 |
+
|
| 222 |
+
_NS_INLINE NS::MethodSignature* NS::Object::methodSignatureForSelector(const void* pObj, SEL selector)
|
| 223 |
+
{
|
| 224 |
+
return sendMessage<MethodSignature*>(pObj, _NS_PRIVATE_SEL(methodSignatureForSelector_), selector);
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 228 |
+
|
| 229 |
+
_NS_INLINE bool NS::Object::respondsToSelector(const void* pObj, SEL selector)
|
| 230 |
+
{
|
| 231 |
+
return sendMessage<bool>(pObj, _NS_PRIVATE_SEL(respondsToSelector_), selector);
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 235 |
+
|
| 236 |
+
template <typename _Ret, typename... _Args>
|
| 237 |
+
_NS_INLINE _Ret NS::Object::sendMessageSafe(const void* pObj, SEL selector, _Args... args)
|
| 238 |
+
{
|
| 239 |
+
if ((respondsToSelector(pObj, selector)) || (nullptr != methodSignatureForSelector(pObj, selector)))
|
| 240 |
+
{
|
| 241 |
+
return sendMessage<_Ret>(pObj, selector, args...);
|
| 242 |
+
}
|
| 243 |
+
|
| 244 |
+
if constexpr (!std::is_void<_Ret>::value)
|
| 245 |
+
{
|
| 246 |
+
return 0;
|
| 247 |
+
}
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 251 |
+
|
| 252 |
+
template <class _Class>
|
| 253 |
+
_NS_INLINE _Class* NS::Object::alloc(const char* pClassName)
|
| 254 |
+
{
|
| 255 |
+
return sendMessage<_Class*>(objc_lookUpClass(pClassName), _NS_PRIVATE_SEL(alloc));
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 259 |
+
|
| 260 |
+
template <class _Class>
|
| 261 |
+
_NS_INLINE _Class* NS::Object::alloc(const void* pClass)
|
| 262 |
+
{
|
| 263 |
+
return sendMessage<_Class*>(pClass, _NS_PRIVATE_SEL(alloc));
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 267 |
+
|
| 268 |
+
template <class _Class>
|
| 269 |
+
_NS_INLINE _Class* NS::Object::init()
|
| 270 |
+
{
|
| 271 |
+
return sendMessage<_Class*>(this, _NS_PRIVATE_SEL(init));
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 275 |
+
|
| 276 |
+
_NS_INLINE NS::UInteger NS::Object::hash() const
|
| 277 |
+
{
|
| 278 |
+
return sendMessage<UInteger>(this, _NS_PRIVATE_SEL(hash));
|
| 279 |
+
}
|
| 280 |
+
|
| 281 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 282 |
+
|
| 283 |
+
_NS_INLINE bool NS::Object::isEqual(const Object* pObject) const
|
| 284 |
+
{
|
| 285 |
+
return sendMessage<bool>(this, _NS_PRIVATE_SEL(isEqual_), pObject);
|
| 286 |
+
}
|
| 287 |
+
|
| 288 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 289 |
+
|
| 290 |
+
_NS_INLINE NS::String* NS::Object::description() const
|
| 291 |
+
{
|
| 292 |
+
return sendMessage<String*>(this, _NS_PRIVATE_SEL(description));
|
| 293 |
+
}
|
| 294 |
+
|
| 295 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 296 |
+
|
| 297 |
+
_NS_INLINE NS::String* NS::Object::debugDescription() const
|
| 298 |
+
{
|
| 299 |
+
return sendMessageSafe<String*>(this, _NS_PRIVATE_SEL(debugDescription));
|
| 300 |
+
}
|
| 301 |
+
|
| 302 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|