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
|
@@ -34,7 +34,7 @@ _NO_RAISE_OPS = frozenset(
|
|
|
34
34
|
}
|
|
35
35
|
)
|
|
36
36
|
|
|
37
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
37
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
38
38
|
from enum import Enum
|
|
39
39
|
|
|
40
40
|
# Operands for CALL_INTRINSIC_1
|
|
@@ -161,7 +161,7 @@ class Flow(object):
|
|
|
161
161
|
self.block_infos[state.pc_initial] = si = adapt_state_infos(state)
|
|
162
162
|
_logger.debug("block_infos %s:\n%s", state, si)
|
|
163
163
|
|
|
164
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
164
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
165
165
|
|
|
166
166
|
def _run_handle_exception(self, runner, state):
|
|
167
167
|
if not state.in_with() and (
|
|
@@ -324,20 +324,29 @@ class Flow(object):
|
|
|
324
324
|
else:
|
|
325
325
|
return False
|
|
326
326
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
327
|
+
if PYVERSION in ((3, 14),):
|
|
328
|
+
|
|
329
|
+
def _guard_with_as(self, state):
|
|
330
|
+
# Handled as part of `LOAD_SPECIAL` as of 3.14.
|
|
331
|
+
pass
|
|
332
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
333
|
+
|
|
334
|
+
def _guard_with_as(self, state):
|
|
335
|
+
"""Checks if the next instruction after a SETUP_WITH is something
|
|
336
|
+
other than a POP_TOP, if it is something else it'll be some sort of
|
|
337
|
+
store which is not supported (this corresponds to `with CTXMGR as
|
|
338
|
+
VAR(S)`)."""
|
|
339
|
+
current_inst = state.get_inst()
|
|
340
|
+
if current_inst.opname in {"SETUP_WITH", "BEFORE_WITH"}:
|
|
341
|
+
next_op = self._bytecode[current_inst.next].opname
|
|
342
|
+
if next_op != "POP_TOP":
|
|
343
|
+
msg = (
|
|
344
|
+
"The 'with (context manager) as (variable):' "
|
|
345
|
+
"construct is not supported."
|
|
346
|
+
)
|
|
347
|
+
raise UnsupportedBytecodeError(msg)
|
|
348
|
+
else:
|
|
349
|
+
raise NotImplementedError(PYVERSION)
|
|
341
350
|
|
|
342
351
|
|
|
343
352
|
def _is_null_temp_reg(reg):
|
|
@@ -356,7 +365,7 @@ class TraceRunner(object):
|
|
|
356
365
|
return Loc(self.debug_filename, lineno)
|
|
357
366
|
|
|
358
367
|
def dispatch(self, state):
|
|
359
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
368
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
360
369
|
if state._blockstack:
|
|
361
370
|
state: State
|
|
362
371
|
while state._blockstack:
|
|
@@ -409,6 +418,14 @@ class TraceRunner(object):
|
|
|
409
418
|
def op_NOP(self, state, inst):
|
|
410
419
|
state.append(inst)
|
|
411
420
|
|
|
421
|
+
if PYVERSION in ((3, 14),):
|
|
422
|
+
# New in 3.14
|
|
423
|
+
op_NOT_TAKEN = op_NOP
|
|
424
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
425
|
+
pass
|
|
426
|
+
else:
|
|
427
|
+
raise NotImplementedError(PYVERSION)
|
|
428
|
+
|
|
412
429
|
def op_RESUME(self, state, inst):
|
|
413
430
|
state.append(inst)
|
|
414
431
|
|
|
@@ -435,15 +452,18 @@ class TraceRunner(object):
|
|
|
435
452
|
state.push(state.make_temp())
|
|
436
453
|
state.append(inst)
|
|
437
454
|
|
|
438
|
-
if PYVERSION in ((3, 13),):
|
|
455
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
439
456
|
|
|
440
457
|
def op_FORMAT_SIMPLE(self, state, inst):
|
|
441
|
-
assert PYVERSION == (3, 13)
|
|
442
458
|
value = state.pop()
|
|
443
459
|
strvar = state.make_temp()
|
|
444
460
|
res = state.make_temp()
|
|
445
461
|
state.append(inst, value=value, res=res, strvar=strvar)
|
|
446
462
|
state.push(res)
|
|
463
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12)):
|
|
464
|
+
pass
|
|
465
|
+
else:
|
|
466
|
+
raise NotImplementedError(PYVERSION)
|
|
447
467
|
|
|
448
468
|
def op_FORMAT_VALUE(self, state, inst):
|
|
449
469
|
"""
|
|
@@ -484,18 +504,27 @@ class TraceRunner(object):
|
|
|
484
504
|
def op_POP_TOP(self, state, inst):
|
|
485
505
|
state.pop()
|
|
486
506
|
|
|
487
|
-
if PYVERSION in ((3,
|
|
507
|
+
if PYVERSION in ((3, 14),):
|
|
508
|
+
# New in 3.14
|
|
509
|
+
op_POP_ITER = op_POP_TOP
|
|
510
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
511
|
+
pass
|
|
512
|
+
else:
|
|
513
|
+
raise NotImplementedError(PYVERSION)
|
|
514
|
+
|
|
515
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
488
516
|
|
|
489
517
|
def op_TO_BOOL(self, state, inst):
|
|
490
518
|
res = state.make_temp()
|
|
491
519
|
tos = state.pop()
|
|
492
520
|
state.append(inst, val=tos, res=res)
|
|
493
521
|
state.push(res)
|
|
494
|
-
|
|
495
|
-
elif PYVERSION < (3, 13):
|
|
522
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12)):
|
|
496
523
|
pass
|
|
524
|
+
else:
|
|
525
|
+
raise NotImplementedError(PYVERSION)
|
|
497
526
|
|
|
498
|
-
if PYVERSION in ((3, 13),):
|
|
527
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
499
528
|
|
|
500
529
|
def op_LOAD_GLOBAL(self, state, inst):
|
|
501
530
|
# Ordering of the global value and NULL is swapped in Py3.13
|
|
@@ -545,10 +574,22 @@ class TraceRunner(object):
|
|
|
545
574
|
state.push(res)
|
|
546
575
|
state.append(inst, res=res)
|
|
547
576
|
|
|
577
|
+
if PYVERSION in ((3, 14),):
|
|
578
|
+
# New in 3.14
|
|
579
|
+
def op_LOAD_SMALL_INT(self, state, inst):
|
|
580
|
+
assert 0 <= inst.arg < 256
|
|
581
|
+
res = state.make_temp("const") + f".{inst.arg}"
|
|
582
|
+
state.push(res)
|
|
583
|
+
state.append(inst, res=res)
|
|
584
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
585
|
+
pass
|
|
586
|
+
else:
|
|
587
|
+
raise NotImplementedError(PYVERSION)
|
|
588
|
+
|
|
548
589
|
def op_LOAD_ATTR(self, state, inst):
|
|
549
590
|
item = state.pop()
|
|
550
591
|
res = state.make_temp()
|
|
551
|
-
if PYVERSION in ((3, 13),):
|
|
592
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
552
593
|
state.push(res) # the attr
|
|
553
594
|
if inst.arg & 1:
|
|
554
595
|
state.push(state.make_null())
|
|
@@ -563,8 +604,7 @@ class TraceRunner(object):
|
|
|
563
604
|
state.append(inst, item=item, res=res)
|
|
564
605
|
|
|
565
606
|
def op_LOAD_FAST(self, state, inst):
|
|
566
|
-
|
|
567
|
-
if PYVERSION in ((3, 13),):
|
|
607
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
568
608
|
try:
|
|
569
609
|
name = state.get_varname(inst)
|
|
570
610
|
except IndexError: # oparg is out of range
|
|
@@ -583,13 +623,15 @@ class TraceRunner(object):
|
|
|
583
623
|
state.append(inst, res=res, as_load_deref=True)
|
|
584
624
|
state.push(res)
|
|
585
625
|
return
|
|
586
|
-
|
|
626
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12)):
|
|
587
627
|
name = state.get_varname(inst)
|
|
628
|
+
else:
|
|
629
|
+
raise NotImplementedError(PYVERSION)
|
|
588
630
|
res = state.make_temp(name)
|
|
589
631
|
state.append(inst, res=res)
|
|
590
632
|
state.push(res)
|
|
591
633
|
|
|
592
|
-
if PYVERSION in ((3, 13),):
|
|
634
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
593
635
|
|
|
594
636
|
def op_LOAD_FAST_LOAD_FAST(self, state, inst):
|
|
595
637
|
oparg = inst.arg
|
|
@@ -623,7 +665,7 @@ class TraceRunner(object):
|
|
|
623
665
|
else:
|
|
624
666
|
raise NotImplementedError(PYVERSION)
|
|
625
667
|
|
|
626
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
668
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
627
669
|
op_LOAD_FAST_CHECK = op_LOAD_FAST
|
|
628
670
|
op_LOAD_FAST_AND_CLEAR = op_LOAD_FAST
|
|
629
671
|
elif PYVERSION in ((3, 9), (3, 10), (3, 11)):
|
|
@@ -631,6 +673,15 @@ class TraceRunner(object):
|
|
|
631
673
|
else:
|
|
632
674
|
raise NotImplementedError(PYVERSION)
|
|
633
675
|
|
|
676
|
+
if PYVERSION in ((3, 14),):
|
|
677
|
+
# New in 3.14.
|
|
678
|
+
op_LOAD_FAST_BORROW = op_LOAD_FAST
|
|
679
|
+
op_LOAD_FAST_BORROW_LOAD_FAST_BORROW = op_LOAD_FAST_LOAD_FAST
|
|
680
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
681
|
+
pass
|
|
682
|
+
else:
|
|
683
|
+
raise NotImplementedError(PYVERSION)
|
|
684
|
+
|
|
634
685
|
def op_DELETE_FAST(self, state, inst):
|
|
635
686
|
state.append(inst)
|
|
636
687
|
|
|
@@ -889,7 +940,7 @@ class TraceRunner(object):
|
|
|
889
940
|
)
|
|
890
941
|
state.push(res)
|
|
891
942
|
|
|
892
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
943
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
893
944
|
|
|
894
945
|
def op_BINARY_SLICE(self, state, inst):
|
|
895
946
|
end = state.pop()
|
|
@@ -913,7 +964,7 @@ class TraceRunner(object):
|
|
|
913
964
|
else:
|
|
914
965
|
raise NotImplementedError(PYVERSION)
|
|
915
966
|
|
|
916
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
967
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
917
968
|
|
|
918
969
|
def op_STORE_SLICE(self, state, inst):
|
|
919
970
|
end = state.pop()
|
|
@@ -952,7 +1003,7 @@ class TraceRunner(object):
|
|
|
952
1003
|
op_POP_JUMP_IF_TRUE = _op_POP_JUMP_IF
|
|
953
1004
|
op_POP_JUMP_IF_FALSE = _op_POP_JUMP_IF
|
|
954
1005
|
|
|
955
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
1006
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
956
1007
|
op_POP_JUMP_IF_NONE = _op_POP_JUMP_IF
|
|
957
1008
|
op_POP_JUMP_IF_NOT_NONE = _op_POP_JUMP_IF
|
|
958
1009
|
elif PYVERSION in ((3, 9), (3, 10), (3, 11)):
|
|
@@ -1018,7 +1069,7 @@ class TraceRunner(object):
|
|
|
1018
1069
|
state.append(inst, retval=state.pop(), castval=state.make_temp())
|
|
1019
1070
|
state.terminate()
|
|
1020
1071
|
|
|
1021
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
1072
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
1022
1073
|
|
|
1023
1074
|
def op_RETURN_CONST(self, state, inst):
|
|
1024
1075
|
res = state.make_temp("const")
|
|
@@ -1035,7 +1086,7 @@ class TraceRunner(object):
|
|
|
1035
1086
|
state.append(inst, value=val, res=res)
|
|
1036
1087
|
state.push(res)
|
|
1037
1088
|
|
|
1038
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
1089
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
1039
1090
|
|
|
1040
1091
|
def op_RAISE_VARARGS(self, state, inst):
|
|
1041
1092
|
if inst.arg == 0:
|
|
@@ -1098,7 +1149,7 @@ class TraceRunner(object):
|
|
|
1098
1149
|
blk = state.pop_block()
|
|
1099
1150
|
state.reset_stack(blk["entry_stack"])
|
|
1100
1151
|
|
|
1101
|
-
if PYVERSION in ((3, 13),):
|
|
1152
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
1102
1153
|
|
|
1103
1154
|
def op_END_FOR(self, state, inst):
|
|
1104
1155
|
state.pop()
|
|
@@ -1146,35 +1197,43 @@ class TraceRunner(object):
|
|
|
1146
1197
|
)
|
|
1147
1198
|
)
|
|
1148
1199
|
|
|
1149
|
-
|
|
1150
|
-
#
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1200
|
+
if PYVERSION in ((3, 14),):
|
|
1201
|
+
# Replaced by LOAD_SPECIAL in 3.14.
|
|
1202
|
+
pass
|
|
1203
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
1204
|
+
|
|
1205
|
+
def op_BEFORE_WITH(self, state, inst):
|
|
1206
|
+
# Almost the same as py3.10 SETUP_WITH just lacking the finally
|
|
1207
|
+
# block.
|
|
1208
|
+
cm = state.pop() # the context-manager
|
|
1209
|
+
|
|
1210
|
+
yielded = state.make_temp()
|
|
1211
|
+
exitfn = state.make_temp(prefix="setup_with_exitfn")
|
|
1212
|
+
|
|
1213
|
+
state.push(exitfn)
|
|
1214
|
+
state.push(yielded)
|
|
1215
|
+
|
|
1216
|
+
# Gather all exception entries for this WITH. There maybe multiple
|
|
1217
|
+
# entries; esp. for nested WITHs.
|
|
1218
|
+
bc = state._bytecode
|
|
1219
|
+
ehhead = bc.find_exception_entry(inst.next)
|
|
1220
|
+
ehrelated = [ehhead]
|
|
1221
|
+
ehrelated.extend(
|
|
1222
|
+
eh for eh in bc.exception_entries if eh.target == ehhead.target
|
|
1223
|
+
)
|
|
1224
|
+
end = max(eh.end for eh in ehrelated)
|
|
1225
|
+
state.append(inst, contextmanager=cm, exitfn=exitfn, end=end)
|
|
1169
1226
|
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1227
|
+
state.push_block(
|
|
1228
|
+
state.make_block(
|
|
1229
|
+
kind="WITH",
|
|
1230
|
+
end=end,
|
|
1231
|
+
)
|
|
1174
1232
|
)
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1233
|
+
# Forces a new block
|
|
1234
|
+
state.fork(pc=inst.next)
|
|
1235
|
+
else:
|
|
1236
|
+
raise NotImplementedError(PYVERSION)
|
|
1178
1237
|
|
|
1179
1238
|
def op_SETUP_WITH(self, state, inst):
|
|
1180
1239
|
cm = state.pop() # the context-manager
|
|
@@ -1229,7 +1288,7 @@ class TraceRunner(object):
|
|
|
1229
1288
|
end=inst.get_jump_target(),
|
|
1230
1289
|
)
|
|
1231
1290
|
|
|
1232
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
1291
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
1233
1292
|
|
|
1234
1293
|
def op_POP_EXCEPT(self, state, inst):
|
|
1235
1294
|
state.pop()
|
|
@@ -1262,12 +1321,19 @@ class TraceRunner(object):
|
|
|
1262
1321
|
state.append(inst, kind="with")
|
|
1263
1322
|
state.fork(pc=inst.next)
|
|
1264
1323
|
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
state
|
|
1324
|
+
if PYVERSION in ((3, 14),):
|
|
1325
|
+
# Removed in 3.14 -- replaced with BINARY_OP and []
|
|
1326
|
+
pass
|
|
1327
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
1328
|
+
|
|
1329
|
+
def op_BINARY_SUBSCR(self, state, inst):
|
|
1330
|
+
index = state.pop()
|
|
1331
|
+
target = state.pop()
|
|
1332
|
+
res = state.make_temp()
|
|
1333
|
+
state.append(inst, index=index, target=target, res=res)
|
|
1334
|
+
state.push(res)
|
|
1335
|
+
else:
|
|
1336
|
+
raise NotImplementedError(PYVERSION)
|
|
1271
1337
|
|
|
1272
1338
|
def op_STORE_SUBSCR(self, state, inst):
|
|
1273
1339
|
index = state.pop()
|
|
@@ -1283,7 +1349,7 @@ class TraceRunner(object):
|
|
|
1283
1349
|
def op_CALL(self, state, inst):
|
|
1284
1350
|
narg = inst.arg
|
|
1285
1351
|
args = list(reversed([state.pop() for _ in range(narg)]))
|
|
1286
|
-
if PYVERSION
|
|
1352
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
1287
1353
|
null_or_self = state.pop()
|
|
1288
1354
|
# position of the callable is fixed
|
|
1289
1355
|
callable = state.pop()
|
|
@@ -1326,7 +1392,7 @@ class TraceRunner(object):
|
|
|
1326
1392
|
state.append(inst, func=func, args=args, names=names, res=res)
|
|
1327
1393
|
state.push(res)
|
|
1328
1394
|
|
|
1329
|
-
if PYVERSION in ((3, 13),):
|
|
1395
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
1330
1396
|
|
|
1331
1397
|
def op_CALL_KW(self, state, inst):
|
|
1332
1398
|
narg = inst.arg
|
|
@@ -1348,7 +1414,25 @@ class TraceRunner(object):
|
|
|
1348
1414
|
else:
|
|
1349
1415
|
raise NotImplementedError(PYVERSION)
|
|
1350
1416
|
|
|
1351
|
-
if PYVERSION in ((3,
|
|
1417
|
+
if PYVERSION in ((3, 14),):
|
|
1418
|
+
|
|
1419
|
+
def op_CALL_FUNCTION_EX(self, state, inst):
|
|
1420
|
+
# (func, unused, callargs, kwargs -- result))
|
|
1421
|
+
# In 3.14 CALL_FUNCTION_EX always take a kwargs argument
|
|
1422
|
+
# https://github.com/python/cpython/pull/129226
|
|
1423
|
+
varkwarg = state.pop()
|
|
1424
|
+
if _is_null_temp_reg(varkwarg):
|
|
1425
|
+
varkwarg = None
|
|
1426
|
+
vararg = state.pop()
|
|
1427
|
+
state.pop() # unused
|
|
1428
|
+
func = state.pop()
|
|
1429
|
+
|
|
1430
|
+
res = state.make_temp()
|
|
1431
|
+
state.append(
|
|
1432
|
+
inst, func=func, vararg=vararg, varkwarg=varkwarg, res=res
|
|
1433
|
+
)
|
|
1434
|
+
state.push(res)
|
|
1435
|
+
elif PYVERSION in ((3, 13),):
|
|
1352
1436
|
|
|
1353
1437
|
def op_CALL_FUNCTION_EX(self, state, inst):
|
|
1354
1438
|
# (func, unused, callargs, kwargs if (oparg & 1) -- result))
|
|
@@ -1408,7 +1492,7 @@ class TraceRunner(object):
|
|
|
1408
1492
|
for val in duped:
|
|
1409
1493
|
state.push(val)
|
|
1410
1494
|
|
|
1411
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
1495
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
1412
1496
|
|
|
1413
1497
|
def op_CALL_INTRINSIC_1(self, state, inst):
|
|
1414
1498
|
# See https://github.com/python/cpython/blob/v3.12.0rc2/Include/
|
|
@@ -1603,6 +1687,13 @@ class TraceRunner(object):
|
|
|
1603
1687
|
state.append(inst, items=items, res=res)
|
|
1604
1688
|
state.push(res)
|
|
1605
1689
|
|
|
1690
|
+
def op_SET_ADD(self, state, inst):
|
|
1691
|
+
value = state.pop()
|
|
1692
|
+
target = state.get_tos()
|
|
1693
|
+
addvar = state.make_temp()
|
|
1694
|
+
res = state.make_temp()
|
|
1695
|
+
state.append(inst, value=value, target=target, addvar=addvar, res=res)
|
|
1696
|
+
|
|
1606
1697
|
def op_SET_UPDATE(self, state, inst):
|
|
1607
1698
|
value = state.pop()
|
|
1608
1699
|
index = inst.arg
|
|
@@ -1639,7 +1730,7 @@ class TraceRunner(object):
|
|
|
1639
1730
|
)
|
|
1640
1731
|
state.push(indval)
|
|
1641
1732
|
end = inst.get_jump_target()
|
|
1642
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
1733
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
1643
1734
|
# Changed in version 3.12: Up until 3.11 the iterator was
|
|
1644
1735
|
# popped when it was exhausted. Now this is handled using END_FOR
|
|
1645
1736
|
# op code.
|
|
@@ -1665,10 +1756,17 @@ class TraceRunner(object):
|
|
|
1665
1756
|
op = dis._nb_ops[inst.arg][1]
|
|
1666
1757
|
rhs = state.pop()
|
|
1667
1758
|
lhs = state.pop()
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1759
|
+
if op == "[]":
|
|
1760
|
+
# Special case 3.14 -- body of BINARY_SUBSCR now here
|
|
1761
|
+
assert PYVERSION == (3, 14)
|
|
1762
|
+
res = state.make_temp()
|
|
1763
|
+
state.append(inst, op=op, lhs=lhs, rhs=rhs, res=res)
|
|
1764
|
+
state.push(res)
|
|
1765
|
+
else:
|
|
1766
|
+
op_name = ALL_BINOPS_TO_OPERATORS[op].__name__
|
|
1767
|
+
res = state.make_temp(prefix=f"binop_{op_name}")
|
|
1768
|
+
state.append(inst, op=op, lhs=lhs, rhs=rhs, res=res)
|
|
1769
|
+
state.push(res)
|
|
1672
1770
|
|
|
1673
1771
|
def _unaryop(self, state, inst):
|
|
1674
1772
|
val = state.pop()
|
|
@@ -1725,7 +1823,7 @@ class TraceRunner(object):
|
|
|
1725
1823
|
op_BINARY_XOR = _binaryop
|
|
1726
1824
|
|
|
1727
1825
|
def op_MAKE_FUNCTION(self, state, inst, MAKE_CLOSURE=False):
|
|
1728
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
1826
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
1729
1827
|
# https://github.com/python/cpython/commit/2f180ce
|
|
1730
1828
|
# name set via co_qualname
|
|
1731
1829
|
name = None
|
|
@@ -1738,7 +1836,7 @@ class TraceRunner(object):
|
|
|
1738
1836
|
raise NotImplementedError(PYVERSION)
|
|
1739
1837
|
code = state.pop()
|
|
1740
1838
|
closure = annotations = kwdefaults = defaults = None
|
|
1741
|
-
if PYVERSION in ((3, 13),):
|
|
1839
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
1742
1840
|
assert inst.arg is None
|
|
1743
1841
|
# SET_FUNCTION_ATTRIBUTE is responsible for setting
|
|
1744
1842
|
# closure, annotations, kwdefaults and defaults.
|
|
@@ -1765,7 +1863,7 @@ class TraceRunner(object):
|
|
|
1765
1863
|
state.push(res)
|
|
1766
1864
|
|
|
1767
1865
|
def op_SET_FUNCTION_ATTRIBUTE(self, state, inst):
|
|
1768
|
-
assert PYVERSION in ((3, 13),)
|
|
1866
|
+
assert PYVERSION in ((3, 13), (3, 14))
|
|
1769
1867
|
make_func_stack = state.pop()
|
|
1770
1868
|
data = state.pop()
|
|
1771
1869
|
if inst.arg == 0x1:
|
|
@@ -1793,10 +1891,17 @@ class TraceRunner(object):
|
|
|
1793
1891
|
state.append(inst, res=res)
|
|
1794
1892
|
state.push(res)
|
|
1795
1893
|
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1894
|
+
if PYVERSION in ((3, 14),):
|
|
1895
|
+
# Removed in 3.14
|
|
1896
|
+
pass
|
|
1897
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
1898
|
+
|
|
1899
|
+
def op_LOAD_ASSERTION_ERROR(self, state, inst):
|
|
1900
|
+
res = state.make_temp("assertion_error")
|
|
1901
|
+
state.append(inst, res=res)
|
|
1902
|
+
state.push(res)
|
|
1903
|
+
else:
|
|
1904
|
+
raise NotImplementedError(PYVERSION)
|
|
1800
1905
|
|
|
1801
1906
|
def op_CHECK_EXC_MATCH(self, state, inst):
|
|
1802
1907
|
pred = state.make_temp("predicate")
|
|
@@ -1815,7 +1920,7 @@ class TraceRunner(object):
|
|
|
1815
1920
|
state.fork(pc=inst.next)
|
|
1816
1921
|
state.fork(pc=inst.get_jump_target())
|
|
1817
1922
|
|
|
1818
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
1923
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
1819
1924
|
|
|
1820
1925
|
def op_RERAISE(self, state, inst):
|
|
1821
1926
|
# This isn't handled, but the state is set up anyway
|
|
@@ -1845,7 +1950,7 @@ class TraceRunner(object):
|
|
|
1845
1950
|
# NOTE: Please see notes in `interpreter.py` surrounding the implementation
|
|
1846
1951
|
# of LOAD_METHOD and CALL_METHOD.
|
|
1847
1952
|
|
|
1848
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
1953
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
1849
1954
|
# LOAD_METHOD has become a pseudo-instruction in 3.12
|
|
1850
1955
|
pass
|
|
1851
1956
|
elif PYVERSION in ((3, 11),):
|
|
@@ -1870,6 +1975,147 @@ class TraceRunner(object):
|
|
|
1870
1975
|
def op_CALL_METHOD(self, state, inst):
|
|
1871
1976
|
self.op_CALL_FUNCTION(state, inst)
|
|
1872
1977
|
|
|
1978
|
+
if PYVERSION in ((3, 14),):
|
|
1979
|
+
# New in 3.14, replaces BEFORE_WITH.
|
|
1980
|
+
def op_LOAD_SPECIAL(self, state, inst):
|
|
1981
|
+
# The "special" methods mapping for LOAD_SPECIAL is:
|
|
1982
|
+
#
|
|
1983
|
+
# special_methods = {
|
|
1984
|
+
# 0: '__enter__',
|
|
1985
|
+
# 1: '__exit__',
|
|
1986
|
+
# 2: '__aenter__',
|
|
1987
|
+
# 3: '__aexit__',
|
|
1988
|
+
# }
|
|
1989
|
+
if dis._special_method_names[inst.arg] not in [
|
|
1990
|
+
"__enter__",
|
|
1991
|
+
"__exit__",
|
|
1992
|
+
]:
|
|
1993
|
+
raise NotImplementedError("async special methods not supported")
|
|
1994
|
+
|
|
1995
|
+
# This implementation of LOAD_SPECIAL is somewhat unusual for a
|
|
1996
|
+
# Numba bytecode handler.
|
|
1997
|
+
#
|
|
1998
|
+
# Essentially this comes from the insight, that with Python 3.14
|
|
1999
|
+
# the bytecode `BEFORE_WITH` is replaced by `LOAD_SPECIAL`. But
|
|
2000
|
+
# this is not a simple replacement. In fact, the single
|
|
2001
|
+
# `BEFORE_WITH` is replaced by the following sequence of bytecodes:
|
|
2002
|
+
#
|
|
2003
|
+
# COPY(arg=1, lineno=X)
|
|
2004
|
+
# LOAD_SPECIAL(arg=1, lineno=X) -- loading __exit__ --
|
|
2005
|
+
# SWAP(arg=2, lineno=X)
|
|
2006
|
+
# SWAP(arg=3, lineno=X)
|
|
2007
|
+
# LOAD_SPECIAL(arg=0, lineno=X) -- loading __enter__ --
|
|
2008
|
+
# CALL(arg=0, lineno=X) -- calling __enter__ --
|
|
2009
|
+
# POP_TOP(arg=None, lineno=X)
|
|
2010
|
+
#
|
|
2011
|
+
# Basically, after seeing the first `LOAD_SPECIAL` we can consume
|
|
2012
|
+
# all the bytecodes up until the `POP_TOP` and leave the stack
|
|
2013
|
+
# with a single copy of current TOS + the temp var to denote the
|
|
2014
|
+
# `__exit__` function. We can also reject syntax of the form:
|
|
2015
|
+
#
|
|
2016
|
+
# with context as c:
|
|
2017
|
+
# pass
|
|
2018
|
+
#
|
|
2019
|
+
# Using the fact that the `CALL` to `__enter__` must be followed by
|
|
2020
|
+
# as POP_TOP, otherwise it's using `with as`.
|
|
2021
|
+
|
|
2022
|
+
# Pop top of stack once for first LOAD_SPECIAL
|
|
2023
|
+
tos = state.pop()
|
|
2024
|
+
# Pop top of stack second time for second LOAD_SPECIAL
|
|
2025
|
+
_ = state.pop()
|
|
2026
|
+
|
|
2027
|
+
# Fake an exit method, will not be called and removed from Numba IR
|
|
2028
|
+
# before final processing is complete. Only need this such that the
|
|
2029
|
+
# `CALL` op when closing the with-block can be simulated as a stack
|
|
2030
|
+
# effect.
|
|
2031
|
+
method = state.make_temp(prefix="setup_with_exitfn")
|
|
2032
|
+
# Cache current instruction (the LOAD_SPECIAL).
|
|
2033
|
+
old_inst = inst
|
|
2034
|
+
|
|
2035
|
+
# Now we need to consume the instructions in the known sequence.
|
|
2036
|
+
for i, a in (
|
|
2037
|
+
("SWAP", 2),
|
|
2038
|
+
("SWAP", 3),
|
|
2039
|
+
("LOAD_SPECIAL", 0),
|
|
2040
|
+
("CALL", 0),
|
|
2041
|
+
):
|
|
2042
|
+
state.advance_pc()
|
|
2043
|
+
inst = state.get_inst()
|
|
2044
|
+
if inst.opname != i or inst.arg != a:
|
|
2045
|
+
raise UnsupportedBytecodeError(
|
|
2046
|
+
"Unsupported bytecode pattern for 'LOAD_SPECIAL'."
|
|
2047
|
+
)
|
|
2048
|
+
|
|
2049
|
+
# POP_TOP
|
|
2050
|
+
state.advance_pc()
|
|
2051
|
+
inst = state.get_inst()
|
|
2052
|
+
# Special case, the `CALL` must be followed by a `POP_TOP`.
|
|
2053
|
+
# Otherwise this is an unsupported construct.
|
|
2054
|
+
#
|
|
2055
|
+
# See: `_guard_with_as` for how this is handled for 3.13 and below.
|
|
2056
|
+
if inst.opname != "POP_TOP":
|
|
2057
|
+
msg = (
|
|
2058
|
+
"The 'with (context manager) as "
|
|
2059
|
+
"(variable):' construct is not "
|
|
2060
|
+
"supported."
|
|
2061
|
+
)
|
|
2062
|
+
raise UnsupportedBytecodeError(msg)
|
|
2063
|
+
assert inst.arg is None
|
|
2064
|
+
|
|
2065
|
+
# Finished consuming bytecode pattern.
|
|
2066
|
+
|
|
2067
|
+
# Find the end of the with-block using the exception tables using
|
|
2068
|
+
# the instruction offset of the `POP_TOP` instruction.
|
|
2069
|
+
bc = state._bytecode
|
|
2070
|
+
ehhead = bc.find_exception_entry(inst.offset)
|
|
2071
|
+
ehrelated = [ehhead]
|
|
2072
|
+
ehrelated.extend(
|
|
2073
|
+
eh for eh in bc.exception_entries if eh.target == ehhead.target
|
|
2074
|
+
)
|
|
2075
|
+
end = max(eh.end for eh in ehrelated)
|
|
2076
|
+
|
|
2077
|
+
# Push the `__exit__` method (or null) to the stack,
|
|
2078
|
+
# followed by the original tos (which is the instatiated context
|
|
2079
|
+
# manager). This is such that the `CALL` after the with-block can
|
|
2080
|
+
# be simulated.
|
|
2081
|
+
state.push(method)
|
|
2082
|
+
state.push(tos)
|
|
2083
|
+
# Record the instruction.
|
|
2084
|
+
state.append(
|
|
2085
|
+
old_inst, contextmanager=tos, exit_method=method, block_end=end
|
|
2086
|
+
)
|
|
2087
|
+
|
|
2088
|
+
# Insert WITH-block.
|
|
2089
|
+
state.push_block(
|
|
2090
|
+
state.make_block(
|
|
2091
|
+
kind="WITH",
|
|
2092
|
+
end=end,
|
|
2093
|
+
)
|
|
2094
|
+
)
|
|
2095
|
+
# And fork to force a new block.
|
|
2096
|
+
state.fork(pc=inst.next)
|
|
2097
|
+
|
|
2098
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
2099
|
+
pass
|
|
2100
|
+
else:
|
|
2101
|
+
raise NotImplementedError(PYVERSION)
|
|
2102
|
+
|
|
2103
|
+
if PYVERSION in ((3, 14),):
|
|
2104
|
+
|
|
2105
|
+
def op_LOAD_COMMON_CONSTANT(self, state, inst):
|
|
2106
|
+
oparg = inst.arg
|
|
2107
|
+
if isinstance(dis._common_constants[oparg], AssertionError):
|
|
2108
|
+
name = "assertion_error"
|
|
2109
|
+
else:
|
|
2110
|
+
raise NotImplementedError
|
|
2111
|
+
res = state.make_temp(name)
|
|
2112
|
+
state.append(inst, res=res, idx=oparg)
|
|
2113
|
+
state.push(res)
|
|
2114
|
+
elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
|
|
2115
|
+
pass
|
|
2116
|
+
else:
|
|
2117
|
+
raise NotImplementedError(PYVERSION)
|
|
2118
|
+
|
|
1873
2119
|
|
|
1874
2120
|
@total_ordering
|
|
1875
2121
|
class _State(object):
|
|
@@ -2118,7 +2364,7 @@ class _State(object):
|
|
|
2118
2364
|
stack.append(self.make_temp())
|
|
2119
2365
|
# Handle changes on the blockstack
|
|
2120
2366
|
blockstack = list(self._blockstack)
|
|
2121
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
2367
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
2122
2368
|
# pop expired block in destination pc
|
|
2123
2369
|
while blockstack:
|
|
2124
2370
|
top = blockstack[-1]
|
|
@@ -2229,7 +2475,7 @@ class StatePy313(StatePy311):
|
|
|
2229
2475
|
return self._make_func_attrs[make_func_res]
|
|
2230
2476
|
|
|
2231
2477
|
|
|
2232
|
-
if PYVERSION in ((3, 13),):
|
|
2478
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
2233
2479
|
State = StatePy313
|
|
2234
2480
|
elif PYVERSION in ((3, 11), (3, 12)):
|
|
2235
2481
|
State = StatePy311
|
|
@@ -2273,7 +2519,7 @@ def adapt_state_infos(state):
|
|
|
2273
2519
|
data.update(state.get_function_attributes(data["res"]))
|
|
2274
2520
|
return offset, data
|
|
2275
2521
|
|
|
2276
|
-
if PYVERSION in ((3, 13),):
|
|
2522
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
2277
2523
|
insts = tuple(map(process_function_attributes, state.instructions))
|
|
2278
2524
|
elif PYVERSION in ((3, 9), (3, 10), (3, 11), (3, 12)):
|
|
2279
2525
|
insts = tuple(state.instructions)
|