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 |
+
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
|