numba-cuda 0.23.0__cp313-cp313-win_amd64.whl → 0.24.0__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- numba_cuda/VERSION +1 -1
- numba_cuda/numba/cuda/__init__.py +4 -1
- numba_cuda/numba/cuda/_compat.py +47 -0
- numba_cuda/numba/cuda/cext/_dispatcher.cp313-win_amd64.pyd +0 -0
- numba_cuda/numba/cuda/cext/_dispatcher.cpp +8 -2
- numba_cuda/numba/cuda/cext/_hashtable.cpp +5 -0
- numba_cuda/numba/cuda/cext/_helperlib.cp313-win_amd64.pyd +0 -0
- numba_cuda/numba/cuda/cext/_pymodule.h +1 -1
- numba_cuda/numba/cuda/cext/_typeconv.cp313-win_amd64.pyd +0 -0
- numba_cuda/numba/cuda/cext/_typeof.cpp +56 -8
- numba_cuda/numba/cuda/cext/mviewbuf.c +7 -1
- numba_cuda/numba/cuda/cext/mviewbuf.cp313-win_amd64.pyd +0 -0
- numba_cuda/numba/cuda/cloudpickle/cloudpickle.py +4 -5
- numba_cuda/numba/cuda/codegen.py +4 -2
- numba_cuda/numba/cuda/compiler.py +5 -5
- numba_cuda/numba/cuda/core/annotations/pretty_annotate.py +1 -1
- numba_cuda/numba/cuda/core/base.py +6 -10
- numba_cuda/numba/cuda/core/bytecode.py +21 -13
- numba_cuda/numba/cuda/core/byteflow.py +336 -90
- numba_cuda/numba/cuda/core/compiler.py +3 -4
- numba_cuda/numba/cuda/core/compiler_machinery.py +3 -3
- numba_cuda/numba/cuda/core/config.py +5 -7
- numba_cuda/numba/cuda/core/controlflow.py +17 -9
- numba_cuda/numba/cuda/core/inline_closurecall.py +11 -10
- numba_cuda/numba/cuda/core/interpreter.py +255 -96
- numba_cuda/numba/cuda/core/ir_utils.py +8 -17
- numba_cuda/numba/cuda/core/pythonapi.py +3 -0
- numba_cuda/numba/cuda/core/rewrites/static_binop.py +1 -1
- numba_cuda/numba/cuda/core/ssa.py +2 -2
- numba_cuda/numba/cuda/core/transforms.py +4 -6
- numba_cuda/numba/cuda/core/typed_passes.py +1 -1
- numba_cuda/numba/cuda/core/typeinfer.py +3 -3
- numba_cuda/numba/cuda/core/untyped_passes.py +11 -10
- numba_cuda/numba/cuda/cpython/unicode.py +2 -2
- numba_cuda/numba/cuda/cpython/unicode_support.py +1 -3
- numba_cuda/numba/cuda/cudadrv/devicearray.py +4 -4
- numba_cuda/numba/cuda/cudadrv/driver.py +13 -11
- numba_cuda/numba/cuda/cudadrv/nvrtc.py +71 -32
- numba_cuda/numba/cuda/debuginfo.py +10 -79
- numba_cuda/numba/cuda/deviceufunc.py +3 -6
- numba_cuda/numba/cuda/dispatcher.py +5 -19
- numba_cuda/numba/cuda/libdeviceimpl.py +1 -2
- numba_cuda/numba/cuda/lowering.py +0 -28
- numba_cuda/numba/cuda/memory_management/nrt.py +1 -1
- numba_cuda/numba/cuda/np/arrayobj.py +7 -9
- numba_cuda/numba/cuda/np/numpy_support.py +7 -10
- numba_cuda/numba/cuda/np/polynomial/polynomial_functions.py +4 -3
- numba_cuda/numba/cuda/testing.py +4 -8
- numba_cuda/numba/cuda/tests/cudadrv/test_cuda_driver.py +66 -4
- numba_cuda/numba/cuda/tests/cudadrv/test_events.py +1 -1
- numba_cuda/numba/cuda/tests/cudadrv/test_linker.py +2 -2
- numba_cuda/numba/cuda/tests/cudadrv/test_module_callbacks.py +1 -1
- numba_cuda/numba/cuda/tests/cudadrv/test_nvjitlink.py +26 -4
- numba_cuda/numba/cuda/tests/cudapy/test_analysis.py +61 -9
- numba_cuda/numba/cuda/tests/cudapy/test_atomics.py +6 -0
- numba_cuda/numba/cuda/tests/cudapy/test_compiler.py +12 -1
- numba_cuda/numba/cuda/tests/cudapy/test_complex.py +13 -0
- numba_cuda/numba/cuda/tests/cudapy/test_copy_propagate.py +1 -1
- numba_cuda/numba/cuda/tests/cudapy/test_debug.py +1 -1
- numba_cuda/numba/cuda/tests/cudapy/test_debuginfo.py +12 -7
- numba_cuda/numba/cuda/tests/cudapy/test_dispatcher.py +1 -1
- numba_cuda/numba/cuda/tests/cudapy/test_extending.py +1 -1
- numba_cuda/numba/cuda/tests/cudapy/test_vector_type.py +37 -35
- numba_cuda/numba/cuda/tests/cudapy/test_warp_ops.py +8 -7
- numba_cuda/numba/cuda/tests/support.py +11 -0
- numba_cuda/numba/cuda/types/cuda_functions.py +1 -1
- numba_cuda/numba/cuda/typing/asnumbatype.py +37 -2
- numba_cuda/numba/cuda/typing/typeof.py +9 -16
- {numba_cuda-0.23.0.dist-info → numba_cuda-0.24.0.dist-info}/METADATA +4 -13
- {numba_cuda-0.23.0.dist-info → numba_cuda-0.24.0.dist-info}/RECORD +74 -73
- {numba_cuda-0.23.0.dist-info → numba_cuda-0.24.0.dist-info}/WHEEL +0 -0
- {numba_cuda-0.23.0.dist-info → numba_cuda-0.24.0.dist-info}/licenses/LICENSE +0 -0
- {numba_cuda-0.23.0.dist-info → numba_cuda-0.24.0.dist-info}/licenses/LICENSE.numba +0 -0
- {numba_cuda-0.23.0.dist-info → numba_cuda-0.24.0.dist-info}/top_level.txt +0 -0
|
@@ -27,7 +27,7 @@ from numba.cuda.core.unsafe import eh
|
|
|
27
27
|
from numba.cuda.cpython.unsafe.tuple import unpack_single_tuple
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
30
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
31
31
|
# Operands for CALL_INTRINSIC_1
|
|
32
32
|
from numba.cuda.core.byteflow import CALL_INTRINSIC_1_Operand as ci1op
|
|
33
33
|
elif PYVERSION in ((3, 9), (3, 10), (3, 11)):
|
|
@@ -774,7 +774,7 @@ def peep_hole_list_to_tuple(func_ir):
|
|
|
774
774
|
_DEBUG = False
|
|
775
775
|
|
|
776
776
|
# For all blocks
|
|
777
|
-
for
|
|
777
|
+
for blk in func_ir.blocks.values():
|
|
778
778
|
# keep doing the peephole rewrite until nothing is left that matches
|
|
779
779
|
while True:
|
|
780
780
|
# first try and find a matching region
|
|
@@ -1003,11 +1003,12 @@ def peep_hole_delete_with_exit(func_ir):
|
|
|
1003
1003
|
if isinstance(stmt, ir.assign_types):
|
|
1004
1004
|
dead_vars.add(stmt.target)
|
|
1005
1005
|
|
|
1006
|
-
new_body = [
|
|
1007
|
-
|
|
1006
|
+
new_body = [
|
|
1007
|
+
stmt
|
|
1008
|
+
for stmt in blk.body
|
|
1008
1009
|
# Skip any statements that uses anyone of the dead variable.
|
|
1009
|
-
if not (set(stmt.list_vars()) & dead_vars)
|
|
1010
|
-
|
|
1010
|
+
if not (set(stmt.list_vars()) & dead_vars)
|
|
1011
|
+
]
|
|
1011
1012
|
blk.body.clear()
|
|
1012
1013
|
blk.body.extend(new_body)
|
|
1013
1014
|
|
|
@@ -1323,8 +1324,7 @@ def _build_new_build_map(func_ir, name, old_body, old_lineno, new_items):
|
|
|
1323
1324
|
if len(literal_keys) == len(new_items):
|
|
1324
1325
|
# All keys must be literals to have any literal values.
|
|
1325
1326
|
literal_value = {x: y for x, y in zip(literal_keys, values)}
|
|
1326
|
-
for i, k in enumerate(literal_keys)
|
|
1327
|
-
value_indexes[k] = i
|
|
1327
|
+
value_indexes.update((k, i) for i, k in enumerate(literal_keys))
|
|
1328
1328
|
else:
|
|
1329
1329
|
literal_value = None
|
|
1330
1330
|
|
|
@@ -1390,14 +1390,14 @@ class Interpreter(object):
|
|
|
1390
1390
|
self.current_block = None
|
|
1391
1391
|
self.current_block_offset = None
|
|
1392
1392
|
last_active_offset = 0
|
|
1393
|
-
for
|
|
1393
|
+
for inst_blocks in self.cfa.blocks.values():
|
|
1394
1394
|
if inst_blocks.body:
|
|
1395
1395
|
last_active_offset = max(
|
|
1396
1396
|
last_active_offset, max(inst_blocks.body)
|
|
1397
1397
|
)
|
|
1398
1398
|
self.last_active_offset = last_active_offset
|
|
1399
1399
|
|
|
1400
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
1400
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
1401
1401
|
self.active_exception_entries = tuple(
|
|
1402
1402
|
[
|
|
1403
1403
|
entry
|
|
@@ -1417,7 +1417,7 @@ class Interpreter(object):
|
|
|
1417
1417
|
# Interpret loop
|
|
1418
1418
|
for inst, kws in self._iter_inst():
|
|
1419
1419
|
self._dispatch(inst, kws)
|
|
1420
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
1420
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
1421
1421
|
# Insert end of try markers
|
|
1422
1422
|
self._end_try_blocks()
|
|
1423
1423
|
elif PYVERSION in (
|
|
@@ -1445,12 +1445,12 @@ class Interpreter(object):
|
|
|
1445
1445
|
# post process the IR to rewrite opcodes/byte sequences that are too
|
|
1446
1446
|
# involved to risk handling as part of direct interpretation
|
|
1447
1447
|
peepholes = []
|
|
1448
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
1448
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
1449
1449
|
peepholes.append(peep_hole_split_at_pop_block)
|
|
1450
|
-
if PYVERSION in ((3, 9), (3, 10), (3, 11), (3, 12), (3, 13)):
|
|
1450
|
+
if PYVERSION in ((3, 9), (3, 10), (3, 11), (3, 12), (3, 13), (3, 14)):
|
|
1451
1451
|
peepholes.append(peep_hole_list_to_tuple)
|
|
1452
1452
|
peepholes.append(peep_hole_delete_with_exit)
|
|
1453
|
-
if PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
1453
|
+
if PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13), (3, 14)):
|
|
1454
1454
|
# peep_hole_call_function_ex_to_call_function_kw
|
|
1455
1455
|
# depends on peep_hole_list_to_tuple converting
|
|
1456
1456
|
# any large number of arguments from a list to a
|
|
@@ -1483,7 +1483,7 @@ class Interpreter(object):
|
|
|
1483
1483
|
|
|
1484
1484
|
See also: _insert_try_block_end
|
|
1485
1485
|
"""
|
|
1486
|
-
assert PYVERSION in ((3, 11), (3, 12), (3, 13))
|
|
1486
|
+
assert PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14))
|
|
1487
1487
|
graph = self.cfa.graph
|
|
1488
1488
|
for offset, block in self.blocks.items():
|
|
1489
1489
|
# Get current blockstack
|
|
@@ -1591,7 +1591,7 @@ class Interpreter(object):
|
|
|
1591
1591
|
self.dfainfo = self.dfa.infos[self.current_block_offset]
|
|
1592
1592
|
self.assigner = Assigner()
|
|
1593
1593
|
# Check out-of-scope syntactic-block
|
|
1594
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
1594
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
1595
1595
|
# This is recreating pre-3.11 code structure
|
|
1596
1596
|
while self.syntax_blocks:
|
|
1597
1597
|
if offset >= self.syntax_blocks[-1].exit:
|
|
@@ -1778,7 +1778,7 @@ class Interpreter(object):
|
|
|
1778
1778
|
val = self.get(varname)
|
|
1779
1779
|
except ir.NotDefinedError:
|
|
1780
1780
|
# Hack to make sure exception variables are defined
|
|
1781
|
-
assert PYVERSION in ((3, 11), (3, 12), (3, 13)), (
|
|
1781
|
+
assert PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)), (
|
|
1782
1782
|
"unexpected missing definition"
|
|
1783
1783
|
)
|
|
1784
1784
|
val = ir.Const(value=None, loc=self.loc)
|
|
@@ -1838,7 +1838,7 @@ class Interpreter(object):
|
|
|
1838
1838
|
if self._DEBUG_PRINT:
|
|
1839
1839
|
print(inst)
|
|
1840
1840
|
assert self.current_block is not None
|
|
1841
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
1841
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
1842
1842
|
if self.syntax_blocks:
|
|
1843
1843
|
top = self.syntax_blocks[-1]
|
|
1844
1844
|
if isinstance(top, ir.with_types):
|
|
@@ -1929,6 +1929,14 @@ class Interpreter(object):
|
|
|
1929
1929
|
def op_NOP(self, inst):
|
|
1930
1930
|
pass
|
|
1931
1931
|
|
|
1932
|
+
if PYVERSION in ((3, 14),):
|
|
1933
|
+
# New in 3.14
|
|
1934
|
+
op_NOT_TAKEN = op_NOP
|
|
1935
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
1936
|
+
pass
|
|
1937
|
+
else:
|
|
1938
|
+
raise NotImplementedError(PYVERSION)
|
|
1939
|
+
|
|
1932
1940
|
def op_RESUME(self, inst):
|
|
1933
1941
|
pass
|
|
1934
1942
|
|
|
@@ -2028,7 +2036,7 @@ class Interpreter(object):
|
|
|
2028
2036
|
)
|
|
2029
2037
|
self.store(value=sliceinst, name=res)
|
|
2030
2038
|
|
|
2031
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
2039
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
2032
2040
|
|
|
2033
2041
|
def op_BINARY_SLICE(
|
|
2034
2042
|
self, inst, start, end, container, res, slicevar, temp_res
|
|
@@ -2050,7 +2058,7 @@ class Interpreter(object):
|
|
|
2050
2058
|
else:
|
|
2051
2059
|
raise NotImplementedError(PYVERSION)
|
|
2052
2060
|
|
|
2053
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
2061
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
2054
2062
|
|
|
2055
2063
|
def op_STORE_SLICE(
|
|
2056
2064
|
self, inst, start, end, container, value, res, slicevar
|
|
@@ -2320,7 +2328,7 @@ class Interpreter(object):
|
|
|
2320
2328
|
srcname = self.code_locals[inst.arg]
|
|
2321
2329
|
self.store(value=self.get(srcname), name=res)
|
|
2322
2330
|
|
|
2323
|
-
if PYVERSION in ((3, 13),):
|
|
2331
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
2324
2332
|
|
|
2325
2333
|
def op_LOAD_FAST(self, inst, res, as_load_deref=False):
|
|
2326
2334
|
if as_load_deref:
|
|
@@ -2331,7 +2339,7 @@ class Interpreter(object):
|
|
|
2331
2339
|
else:
|
|
2332
2340
|
op_LOAD_FAST = _op_LOAD_FAST
|
|
2333
2341
|
|
|
2334
|
-
if PYVERSION in ((3, 13),):
|
|
2342
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
2335
2343
|
|
|
2336
2344
|
def op_LOAD_FAST_LOAD_FAST(self, inst, res1, res2):
|
|
2337
2345
|
oparg = inst.arg
|
|
@@ -2369,7 +2377,7 @@ class Interpreter(object):
|
|
|
2369
2377
|
else:
|
|
2370
2378
|
raise NotImplementedError(PYVERSION)
|
|
2371
2379
|
|
|
2372
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
2380
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
2373
2381
|
op_LOAD_FAST_CHECK = op_LOAD_FAST
|
|
2374
2382
|
|
|
2375
2383
|
def op_LOAD_FAST_AND_CLEAR(self, inst, res):
|
|
@@ -2387,6 +2395,16 @@ class Interpreter(object):
|
|
|
2387
2395
|
else:
|
|
2388
2396
|
raise NotImplementedError(PYVERSION)
|
|
2389
2397
|
|
|
2398
|
+
if PYVERSION in ((3, 14),):
|
|
2399
|
+
# New in 3.14.
|
|
2400
|
+
op_LOAD_FAST_BORROW = op_LOAD_FAST
|
|
2401
|
+
op_LOAD_FAST_BORROW_LOAD_FAST_BORROW = op_LOAD_FAST_LOAD_FAST
|
|
2402
|
+
|
|
2403
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
2404
|
+
pass
|
|
2405
|
+
else:
|
|
2406
|
+
raise NotImplementedError(PYVERSION)
|
|
2407
|
+
|
|
2390
2408
|
def op_STORE_FAST(self, inst, value):
|
|
2391
2409
|
dstname = self.code_locals[inst.arg]
|
|
2392
2410
|
value = self.get(value)
|
|
@@ -2420,7 +2438,7 @@ class Interpreter(object):
|
|
|
2420
2438
|
|
|
2421
2439
|
def op_LOAD_ATTR(self, inst, item, res):
|
|
2422
2440
|
item = self.get(item)
|
|
2423
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
2441
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
2424
2442
|
attr = self.code_names[inst.arg >> 1]
|
|
2425
2443
|
elif PYVERSION in ((3, 9), (3, 10), (3, 11)):
|
|
2426
2444
|
attr = self.code_names[inst.arg]
|
|
@@ -2430,28 +2448,85 @@ class Interpreter(object):
|
|
|
2430
2448
|
self.store(getattr, res)
|
|
2431
2449
|
|
|
2432
2450
|
def op_LOAD_CONST(self, inst, res):
|
|
2433
|
-
|
|
2434
|
-
|
|
2451
|
+
# New in 3.14: slice is loaded via LOAD_CONST. The value is the
|
|
2452
|
+
# slice object itself, so we get the start, stop and step from it
|
|
2453
|
+
# directly and then proceed with the code in `BUILD_SLICE`. It may also
|
|
2454
|
+
# be a tuple containing a slice, so we need to account for that too.
|
|
2455
|
+
def process_slice(value):
|
|
2456
|
+
start = self.store(
|
|
2457
|
+
ir.Const(value.start, loc=self.loc),
|
|
2458
|
+
name=f"$const_{value.start}",
|
|
2459
|
+
redefine=True,
|
|
2460
|
+
)
|
|
2461
|
+
stop = self.store(
|
|
2462
|
+
ir.Const(value.stop, loc=self.loc),
|
|
2463
|
+
name=f"$const_{value.stop}",
|
|
2464
|
+
redefine=True,
|
|
2465
|
+
)
|
|
2466
|
+
|
|
2467
|
+
slicevar = self.store(
|
|
2468
|
+
value=ir.Global("slice", slice, loc=self.loc),
|
|
2469
|
+
name="$const_slice",
|
|
2470
|
+
redefine=True,
|
|
2471
|
+
)
|
|
2472
|
+
|
|
2473
|
+
if value.step is None:
|
|
2474
|
+
params = (start, stop)
|
|
2475
|
+
else:
|
|
2476
|
+
step = self.store(
|
|
2477
|
+
ir.Const(value.step, loc=self.loc),
|
|
2478
|
+
name=f"$const_{value.step}",
|
|
2479
|
+
redefine=True,
|
|
2480
|
+
)
|
|
2481
|
+
params = (start, stop, step)
|
|
2482
|
+
|
|
2483
|
+
return ir.Expr.call(slicevar, params, (), loc=self.loc)
|
|
2484
|
+
|
|
2485
|
+
def process_args(value):
|
|
2435
2486
|
st = []
|
|
2436
2487
|
for x in value:
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2488
|
+
if isinstance(x, slice):
|
|
2489
|
+
st.append(
|
|
2490
|
+
self.store(
|
|
2491
|
+
process_slice(x),
|
|
2492
|
+
name="$const_my_slice",
|
|
2493
|
+
redefine=True,
|
|
2494
|
+
)
|
|
2495
|
+
)
|
|
2496
|
+
else:
|
|
2497
|
+
st.append(
|
|
2498
|
+
self.store(
|
|
2499
|
+
ir.Const(x, loc=self.loc),
|
|
2500
|
+
name=f"$const_{x}",
|
|
2501
|
+
redefine=True,
|
|
2502
|
+
)
|
|
2503
|
+
)
|
|
2504
|
+
return st
|
|
2505
|
+
|
|
2506
|
+
value = self.code_consts[inst.arg]
|
|
2507
|
+
|
|
2508
|
+
if isinstance(value, tuple):
|
|
2509
|
+
const = ir.Expr.build_tuple(process_args(value), loc=self.loc)
|
|
2442
2510
|
elif isinstance(value, frozenset):
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
val_const = ir.Const(x, loc=self.loc)
|
|
2447
|
-
target = self.store(val_const, name=nm, redefine=True)
|
|
2448
|
-
st.append(target)
|
|
2449
|
-
const = ir.Expr.build_set(st, loc=self.loc)
|
|
2511
|
+
const = ir.Expr.build_set(process_args(value), loc=self.loc)
|
|
2512
|
+
elif isinstance(value, slice):
|
|
2513
|
+
const = process_slice(value)
|
|
2450
2514
|
else:
|
|
2451
2515
|
const = ir.Const(value, loc=self.loc)
|
|
2452
2516
|
self.store(const, res)
|
|
2453
2517
|
|
|
2454
|
-
if PYVERSION in ((3,
|
|
2518
|
+
if PYVERSION in ((3, 14),):
|
|
2519
|
+
# New in 3.14
|
|
2520
|
+
def op_LOAD_SMALL_INT(self, inst, res):
|
|
2521
|
+
value = inst.arg
|
|
2522
|
+
const = ir.Const(value, loc=self.loc)
|
|
2523
|
+
self.store(const, res)
|
|
2524
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
2525
|
+
pass
|
|
2526
|
+
else:
|
|
2527
|
+
raise NotImplementedError(PYVERSION)
|
|
2528
|
+
|
|
2529
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
2455
2530
|
|
|
2456
2531
|
def op_LOAD_GLOBAL(self, inst, idx, res):
|
|
2457
2532
|
name = self.code_names[idx]
|
|
@@ -2474,7 +2549,7 @@ class Interpreter(object):
|
|
|
2474
2549
|
def op_COPY_FREE_VARS(self, inst):
|
|
2475
2550
|
pass
|
|
2476
2551
|
|
|
2477
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
2552
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
2478
2553
|
|
|
2479
2554
|
def op_LOAD_DEREF(self, inst, res):
|
|
2480
2555
|
name = self.func_id.func.__code__._varname_from_oparg(inst.arg)
|
|
@@ -2508,12 +2583,12 @@ class Interpreter(object):
|
|
|
2508
2583
|
else:
|
|
2509
2584
|
raise NotImplementedError(PYVERSION)
|
|
2510
2585
|
|
|
2511
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
2586
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
2512
2587
|
|
|
2513
2588
|
def op_MAKE_CELL(self, inst):
|
|
2514
2589
|
pass # ignored bytecode
|
|
2515
2590
|
|
|
2516
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
2591
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
2517
2592
|
|
|
2518
2593
|
def op_STORE_DEREF(self, inst, value):
|
|
2519
2594
|
name = self.func_id.func.__code__._varname_from_oparg(inst.arg)
|
|
@@ -2561,39 +2636,46 @@ class Interpreter(object):
|
|
|
2561
2636
|
exit_fn_obj = ir.Const(None, loc=self.loc)
|
|
2562
2637
|
self.store(value=exit_fn_obj, name=exitfn)
|
|
2563
2638
|
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2639
|
+
if PYVERSION in ((3, 14),):
|
|
2640
|
+
# Replaced by LOAD_SPECIAL in 3.14.
|
|
2641
|
+
pass
|
|
2642
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
2643
|
+
|
|
2644
|
+
def op_BEFORE_WITH(self, inst, contextmanager, exitfn, end):
|
|
2645
|
+
assert self.blocks[inst.offset] is self.current_block
|
|
2646
|
+
if PYVERSION in ((3, 12), (3, 13)):
|
|
2647
|
+
# Python 3.12 hack for handling nested with blocks
|
|
2648
|
+
if end > self.last_active_offset:
|
|
2649
|
+
# Use exception entries to figure out end of syntax block
|
|
2650
|
+
end = max(
|
|
2651
|
+
[
|
|
2652
|
+
ex.end
|
|
2653
|
+
for ex in self.active_exception_entries
|
|
2654
|
+
if ex.target == end
|
|
2655
|
+
]
|
|
2656
|
+
)
|
|
2657
|
+
elif PYVERSION in ((3, 10), (3, 11)):
|
|
2658
|
+
pass
|
|
2659
|
+
else:
|
|
2660
|
+
raise NotImplementedError(PYVERSION)
|
|
2661
|
+
# Handle with
|
|
2662
|
+
wth = ir.With(inst.offset, exit=end)
|
|
2663
|
+
self.syntax_blocks.append(wth)
|
|
2664
|
+
ctxmgr = self.get(contextmanager)
|
|
2665
|
+
self.current_block.append(
|
|
2666
|
+
ir.EnterWith(
|
|
2667
|
+
contextmanager=ctxmgr,
|
|
2668
|
+
begin=inst.offset,
|
|
2669
|
+
end=end,
|
|
2670
|
+
loc=self.loc,
|
|
2576
2671
|
)
|
|
2577
|
-
elif PYVERSION in ((3, 9), (3, 10), (3, 11)):
|
|
2578
|
-
pass
|
|
2579
|
-
else:
|
|
2580
|
-
raise NotImplementedError(PYVERSION)
|
|
2581
|
-
# Handle with
|
|
2582
|
-
wth = ir.With(inst.offset, exit=end)
|
|
2583
|
-
self.syntax_blocks.append(wth)
|
|
2584
|
-
ctxmgr = self.get(contextmanager)
|
|
2585
|
-
self.current_block.append(
|
|
2586
|
-
ir.EnterWith(
|
|
2587
|
-
contextmanager=ctxmgr,
|
|
2588
|
-
begin=inst.offset,
|
|
2589
|
-
end=end,
|
|
2590
|
-
loc=self.loc,
|
|
2591
2672
|
)
|
|
2592
|
-
)
|
|
2593
2673
|
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2674
|
+
# Store exit function
|
|
2675
|
+
exit_fn_obj = ir.Const(None, loc=self.loc)
|
|
2676
|
+
self.store(value=exit_fn_obj, name=exitfn)
|
|
2677
|
+
else:
|
|
2678
|
+
raise NotImplementedError(PYVERSION)
|
|
2597
2679
|
|
|
2598
2680
|
def op_SETUP_FINALLY(self, inst):
|
|
2599
2681
|
# Removed since python3.11
|
|
@@ -2632,7 +2714,7 @@ class Interpreter(object):
|
|
|
2632
2714
|
expr = ir.Expr.call(func, args, kwargs, loc=self.loc)
|
|
2633
2715
|
self.store(expr, res)
|
|
2634
2716
|
|
|
2635
|
-
if PYVERSION in ((3, 13),):
|
|
2717
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
2636
2718
|
|
|
2637
2719
|
def op_CALL_KW(self, inst, func, args, kw_names, res):
|
|
2638
2720
|
func = self.get(func)
|
|
@@ -2807,9 +2889,7 @@ class Interpreter(object):
|
|
|
2807
2889
|
# store the index of the actual used value for a given key, this is
|
|
2808
2890
|
# used when lowering to pull the right value out into the tuple repr
|
|
2809
2891
|
# of a mixed value type dictionary.
|
|
2810
|
-
value_indexes = {}
|
|
2811
|
-
for i, k in enumerate(keytup):
|
|
2812
|
-
value_indexes[k] = i
|
|
2892
|
+
value_indexes = {k: i for i, k in enumerate(keytup)}
|
|
2813
2893
|
|
|
2814
2894
|
expr = ir.Expr.build_map(
|
|
2815
2895
|
items=items,
|
|
@@ -2852,11 +2932,18 @@ class Interpreter(object):
|
|
|
2852
2932
|
)
|
|
2853
2933
|
self.current_block.append(br)
|
|
2854
2934
|
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2935
|
+
if PYVERSION in ((3, 14),):
|
|
2936
|
+
# Removed in 3.14 -- replaced with BINARY_OP and []
|
|
2937
|
+
pass
|
|
2938
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
2939
|
+
|
|
2940
|
+
def op_BINARY_SUBSCR(self, inst, target, index, res):
|
|
2941
|
+
index = self.get(index)
|
|
2942
|
+
target = self.get(target)
|
|
2943
|
+
expr = ir.Expr.getitem(target, index=index, loc=self.loc)
|
|
2944
|
+
self.store(expr, res)
|
|
2945
|
+
else:
|
|
2946
|
+
raise NotImplementedError(PYVERSION)
|
|
2860
2947
|
|
|
2861
2948
|
def op_STORE_SUBSCR(self, inst, target, index, value):
|
|
2862
2949
|
index = self.get(index)
|
|
@@ -2889,6 +2976,14 @@ class Interpreter(object):
|
|
|
2889
2976
|
)
|
|
2890
2977
|
self.store(expr, res)
|
|
2891
2978
|
|
|
2979
|
+
def op_SET_ADD(self, inst, value, target, addvar, res):
|
|
2980
|
+
value = self.get(value)
|
|
2981
|
+
target = self.get(target)
|
|
2982
|
+
addattr = ir.Expr.getattr(target, "add", loc=self.loc)
|
|
2983
|
+
self.store(value=addattr, name=addvar)
|
|
2984
|
+
addinst = ir.Expr.call(self.get(addvar), (value,), (), loc=self.loc)
|
|
2985
|
+
self.store(value=addinst, name=res)
|
|
2986
|
+
|
|
2892
2987
|
def op_SET_UPDATE(self, inst, target, value, updatevar, res):
|
|
2893
2988
|
target = self.get(target)
|
|
2894
2989
|
value = self.get(value)
|
|
@@ -2948,12 +3043,10 @@ class Interpreter(object):
|
|
|
2948
3043
|
literal_dict = {
|
|
2949
3044
|
x: _UNKNOWN_VALUE(y[1]) for x, y in zip(literal_keys, got_items)
|
|
2950
3045
|
}
|
|
2951
|
-
for i, k in enumerate(literal_keys)
|
|
2952
|
-
value_indexes[k] = i
|
|
3046
|
+
value_indexes.update((k, i) for i, k in enumerate(literal_keys))
|
|
2953
3047
|
else:
|
|
2954
3048
|
literal_dict = {x: y for x, y in zip(literal_keys, literal_values)}
|
|
2955
|
-
for i, k in enumerate(literal_keys)
|
|
2956
|
-
value_indexes[k] = i
|
|
3049
|
+
value_indexes.update((k, i) for i, k in enumerate(literal_keys))
|
|
2957
3050
|
|
|
2958
3051
|
expr = ir.Expr.build_map(
|
|
2959
3052
|
items=got_items,
|
|
@@ -3009,7 +3102,13 @@ class Interpreter(object):
|
|
|
3009
3102
|
self.store(expr, res)
|
|
3010
3103
|
|
|
3011
3104
|
def op_BINARY_OP(self, inst, op, lhs, rhs, res):
|
|
3012
|
-
if "
|
|
3105
|
+
if op == "[]":
|
|
3106
|
+
# Special case 3.14 -- body of BINARY_SUBSCR now here
|
|
3107
|
+
lhs = self.get(lhs)
|
|
3108
|
+
rhs = self.get(rhs)
|
|
3109
|
+
expr = ir.Expr.getitem(lhs, index=rhs, loc=self.loc)
|
|
3110
|
+
self.store(expr, res)
|
|
3111
|
+
elif "=" in op:
|
|
3013
3112
|
self._inplace_binop(op[:-1], lhs, rhs, res)
|
|
3014
3113
|
else:
|
|
3015
3114
|
self._binop(op, lhs, rhs, res)
|
|
@@ -3126,7 +3225,7 @@ class Interpreter(object):
|
|
|
3126
3225
|
ret = ir.Return(self.get(castval), loc=self.loc)
|
|
3127
3226
|
self.current_block.append(ret)
|
|
3128
3227
|
|
|
3129
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
3228
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
3130
3229
|
|
|
3131
3230
|
def op_RETURN_CONST(self, inst, retval, castval):
|
|
3132
3231
|
value = self.code_consts[inst.arg]
|
|
@@ -3140,7 +3239,7 @@ class Interpreter(object):
|
|
|
3140
3239
|
else:
|
|
3141
3240
|
raise NotImplementedError(PYVERSION)
|
|
3142
3241
|
|
|
3143
|
-
if PYVERSION in ((3, 13),):
|
|
3242
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
3144
3243
|
|
|
3145
3244
|
def op_TO_BOOL(self, inst, val, res):
|
|
3146
3245
|
self.store(self.get(val), res) # TODO: just a lazy hack
|
|
@@ -3151,7 +3250,7 @@ class Interpreter(object):
|
|
|
3151
3250
|
raise NotImplementedError(PYVERSION)
|
|
3152
3251
|
|
|
3153
3252
|
def op_COMPARE_OP(self, inst, lhs, rhs, res):
|
|
3154
|
-
if PYVERSION in ((3, 13),):
|
|
3253
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
3155
3254
|
op = dis.cmp_op[inst.arg >> 5]
|
|
3156
3255
|
# TODO: fifth lowest bit now indicates a forced version to bool.
|
|
3157
3256
|
elif PYVERSION in ((3, 12),):
|
|
@@ -3280,7 +3379,7 @@ class Interpreter(object):
|
|
|
3280
3379
|
def op_POP_JUMP_FORWARD_IF_NOT_NONE(self, inst, pred):
|
|
3281
3380
|
self._jump_if_none(inst, pred, False)
|
|
3282
3381
|
|
|
3283
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
3382
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
3284
3383
|
|
|
3285
3384
|
def op_POP_JUMP_IF_NONE(self, inst, pred):
|
|
3286
3385
|
self._jump_if_none(inst, pred, True)
|
|
@@ -3439,7 +3538,7 @@ class Interpreter(object):
|
|
|
3439
3538
|
inst, name, code, closure, annotations, kwdefaults, defaults, res
|
|
3440
3539
|
)
|
|
3441
3540
|
|
|
3442
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
3541
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
3443
3542
|
|
|
3444
3543
|
def op_LOAD_CLOSURE(self, inst, res):
|
|
3445
3544
|
name = self.func_id.func.__code__._varname_from_oparg(inst.arg)
|
|
@@ -3581,9 +3680,16 @@ class Interpreter(object):
|
|
|
3581
3680
|
)
|
|
3582
3681
|
self.store(value=appendinst, name=res)
|
|
3583
3682
|
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3683
|
+
if PYVERSION in ((3, 14),):
|
|
3684
|
+
# Removed in 3.14
|
|
3685
|
+
pass
|
|
3686
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
3687
|
+
|
|
3688
|
+
def op_LOAD_ASSERTION_ERROR(self, inst, res):
|
|
3689
|
+
gv_fn = ir.Global("AssertionError", AssertionError, loc=self.loc)
|
|
3690
|
+
self.store(value=gv_fn, name=res)
|
|
3691
|
+
else:
|
|
3692
|
+
raise NotImplementedError(PYVERSION)
|
|
3587
3693
|
|
|
3588
3694
|
# NOTE: The LOAD_METHOD opcode is implemented as a LOAD_ATTR for ease,
|
|
3589
3695
|
# however this means a new object (the bound-method instance) could be
|
|
@@ -3599,7 +3705,7 @@ class Interpreter(object):
|
|
|
3599
3705
|
def op_CALL_METHOD(self, *args, **kws):
|
|
3600
3706
|
self.op_CALL_FUNCTION(*args, **kws)
|
|
3601
3707
|
|
|
3602
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
3708
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
3603
3709
|
|
|
3604
3710
|
def op_CALL_INTRINSIC_1(self, inst, operand, **kwargs):
|
|
3605
3711
|
if operand == ci1op.INTRINSIC_STOPITERATION_ERROR:
|
|
@@ -3621,8 +3727,61 @@ class Interpreter(object):
|
|
|
3621
3727
|
else:
|
|
3622
3728
|
raise NotImplementedError(PYVERSION)
|
|
3623
3729
|
|
|
3730
|
+
if PYVERSION in ((3, 14),):
|
|
3731
|
+
# New in 3.14, replaces BEFORE_WITH.
|
|
3732
|
+
def op_LOAD_SPECIAL(self, inst, contextmanager, exit_method, block_end):
|
|
3733
|
+
assert self.blocks[inst.offset] is self.current_block
|
|
3734
|
+
|
|
3735
|
+
# Python 3.12 hack for handling nested with blocks
|
|
3736
|
+
if block_end > self.last_active_offset:
|
|
3737
|
+
# Use exception entries to figure out end of syntax block
|
|
3738
|
+
block_end = max(
|
|
3739
|
+
[
|
|
3740
|
+
ex.end
|
|
3741
|
+
for ex in self.active_exception_entries
|
|
3742
|
+
if ex.target == block_end
|
|
3743
|
+
]
|
|
3744
|
+
)
|
|
3745
|
+
|
|
3746
|
+
# Handle with
|
|
3747
|
+
wth = ir.With(inst.offset, exit=block_end)
|
|
3748
|
+
self.syntax_blocks.append(wth)
|
|
3749
|
+
ctxmgr = self.get(contextmanager)
|
|
3750
|
+
self.current_block.append(
|
|
3751
|
+
ir.EnterWith(
|
|
3752
|
+
contextmanager=ctxmgr,
|
|
3753
|
+
begin=inst.offset,
|
|
3754
|
+
end=block_end,
|
|
3755
|
+
loc=self.loc,
|
|
3756
|
+
)
|
|
3757
|
+
)
|
|
3758
|
+
|
|
3759
|
+
# Store exit function
|
|
3760
|
+
exit_fn_obj = ir.Const(None, loc=self.loc)
|
|
3761
|
+
self.store(value=exit_fn_obj, name=exit_method)
|
|
3762
|
+
|
|
3763
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
3764
|
+
pass
|
|
3765
|
+
else:
|
|
3766
|
+
raise NotImplementedError(PYVERSION)
|
|
3767
|
+
|
|
3768
|
+
if PYVERSION in ((3, 14),):
|
|
3769
|
+
|
|
3770
|
+
def op_LOAD_COMMON_CONSTANT(self, inst, res, idx):
|
|
3771
|
+
if isinstance(dis._common_constants[idx], AssertionError):
|
|
3772
|
+
gv_fn = ir.Global(
|
|
3773
|
+
"AssertionError", AssertionError, loc=self.loc
|
|
3774
|
+
)
|
|
3775
|
+
self.store(value=gv_fn, name=res)
|
|
3776
|
+
else:
|
|
3777
|
+
raise NotImplementedError
|
|
3778
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
3779
|
+
pass
|
|
3780
|
+
else:
|
|
3781
|
+
raise NotImplementedError(PYVERSION)
|
|
3782
|
+
|
|
3624
3783
|
|
|
3625
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
3784
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
3626
3785
|
|
|
3627
3786
|
class INTRINSIC_STOPITERATION_ERROR(AssertionError):
|
|
3628
3787
|
pass
|
|
@@ -389,10 +389,7 @@ def get_name_var_table(blocks):
|
|
|
389
389
|
def replace_var_names(blocks, namedict):
|
|
390
390
|
"""replace variables (ir.Var to ir.Var) from dictionary (name -> name)"""
|
|
391
391
|
# remove identity values to avoid infinite loop
|
|
392
|
-
new_namedict = {}
|
|
393
|
-
for l, r in namedict.items():
|
|
394
|
-
if l != r:
|
|
395
|
-
new_namedict[l] = r
|
|
392
|
+
new_namedict = {l: r for l, r in namedict.items() if l != r}
|
|
396
393
|
|
|
397
394
|
def replace_name(var, namedict):
|
|
398
395
|
assert isinstance(var, ir.var_types)
|
|
@@ -415,10 +412,7 @@ def replace_var_callback(var, vardict):
|
|
|
415
412
|
def replace_vars(blocks, vardict):
|
|
416
413
|
"""replace variables (ir.Var to ir.Var) from dictionary (name -> ir.Var)"""
|
|
417
414
|
# remove identity values to avoid infinite loop
|
|
418
|
-
new_vardict = {}
|
|
419
|
-
for l, r in vardict.items():
|
|
420
|
-
if l != r.name:
|
|
421
|
-
new_vardict[l] = r
|
|
415
|
+
new_vardict = {l: r for l, r in vardict.items() if l != r.name}
|
|
422
416
|
visit_vars(blocks, replace_var_callback, new_vardict)
|
|
423
417
|
|
|
424
418
|
|
|
@@ -591,11 +585,9 @@ def flatten_labels(blocks):
|
|
|
591
585
|
def remove_dels(blocks):
|
|
592
586
|
"""remove ir.Del nodes"""
|
|
593
587
|
for block in blocks.values():
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
new_body.append(stmt)
|
|
598
|
-
block.body = new_body
|
|
588
|
+
block.body = [
|
|
589
|
+
stmt for stmt in block.body if not isinstance(stmt, ir.del_types)
|
|
590
|
+
]
|
|
599
591
|
return
|
|
600
592
|
|
|
601
593
|
|
|
@@ -1076,7 +1068,7 @@ def init_copy_propagate_data(blocks, entry, typemap):
|
|
|
1076
1068
|
gen_copies, extra_kill = get_block_copies(blocks, typemap)
|
|
1077
1069
|
# set of all program copies
|
|
1078
1070
|
all_copies = set()
|
|
1079
|
-
for l
|
|
1071
|
+
for l in gen_copies.keys():
|
|
1080
1072
|
all_copies |= gen_copies[l]
|
|
1081
1073
|
kill_copies = {}
|
|
1082
1074
|
for label, gen_set in gen_copies.items():
|
|
@@ -1122,8 +1114,7 @@ def get_block_copies(blocks, typemap):
|
|
|
1122
1114
|
for T, f in copy_propagate_extensions.items():
|
|
1123
1115
|
if isinstance(stmt, T):
|
|
1124
1116
|
gen_set, kill_set = f(stmt, typemap)
|
|
1125
|
-
|
|
1126
|
-
assign_dict[lhs] = rhs
|
|
1117
|
+
assign_dict.update(gen_set)
|
|
1127
1118
|
# if a=b is in dict and b is killed, a is also killed
|
|
1128
1119
|
new_assign_dict = {}
|
|
1129
1120
|
for l, r in assign_dict.items():
|
|
@@ -1933,7 +1924,7 @@ def compile_to_numba_ir(
|
|
|
1933
1924
|
# rename all variables to avoid conflict
|
|
1934
1925
|
var_table = get_name_var_table(f_ir.blocks)
|
|
1935
1926
|
new_var_dict = {}
|
|
1936
|
-
for name
|
|
1927
|
+
for name in var_table.keys():
|
|
1937
1928
|
new_var_dict[name] = mk_unique_var(name)
|
|
1938
1929
|
replace_var_names(f_ir.blocks, new_var_dict)
|
|
1939
1930
|
|