numba-cuda 0.21.1__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/api.py +4 -1
- numba_cuda/numba/cuda/cext/_dispatcher.cp313-win_amd64.pyd +0 -0
- numba_cuda/numba/cuda/cext/_dispatcher.cpp +8 -40
- 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 -119
- 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 +46 -12
- numba_cuda/numba/cuda/compiler.py +15 -9
- numba_cuda/numba/cuda/core/analysis.py +29 -21
- numba_cuda/numba/cuda/core/annotations/pretty_annotate.py +1 -1
- numba_cuda/numba/cuda/core/annotations/type_annotations.py +4 -4
- numba_cuda/numba/cuda/core/base.py +12 -11
- 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/consts.py +1 -1
- numba_cuda/numba/cuda/core/controlflow.py +17 -9
- numba_cuda/numba/cuda/core/cuda_errors.py +917 -0
- numba_cuda/numba/cuda/core/errors.py +4 -912
- numba_cuda/numba/cuda/core/inline_closurecall.py +82 -67
- numba_cuda/numba/cuda/core/interpreter.py +334 -160
- numba_cuda/numba/cuda/core/ir.py +191 -119
- numba_cuda/numba/cuda/core/ir_utils.py +149 -128
- numba_cuda/numba/cuda/core/postproc.py +8 -8
- numba_cuda/numba/cuda/core/pythonapi.py +3 -0
- numba_cuda/numba/cuda/core/rewrites/ir_print.py +6 -3
- numba_cuda/numba/cuda/core/rewrites/static_binop.py +1 -1
- numba_cuda/numba/cuda/core/rewrites/static_getitem.py +5 -5
- numba_cuda/numba/cuda/core/rewrites/static_raise.py +3 -3
- numba_cuda/numba/cuda/core/ssa.py +5 -5
- numba_cuda/numba/cuda/core/transforms.py +29 -16
- numba_cuda/numba/cuda/core/typed_passes.py +10 -10
- numba_cuda/numba/cuda/core/typeinfer.py +42 -27
- numba_cuda/numba/cuda/core/untyped_passes.py +82 -65
- numba_cuda/numba/cuda/cpython/unicode.py +2 -2
- numba_cuda/numba/cuda/cpython/unicode_support.py +1 -3
- numba_cuda/numba/cuda/cudadecl.py +0 -13
- numba_cuda/numba/cuda/cudadrv/devicearray.py +10 -9
- numba_cuda/numba/cuda/cudadrv/driver.py +142 -519
- numba_cuda/numba/cuda/cudadrv/dummyarray.py +4 -0
- numba_cuda/numba/cuda/cudadrv/nvrtc.py +87 -32
- numba_cuda/numba/cuda/cudaimpl.py +0 -12
- numba_cuda/numba/cuda/debuginfo.py +25 -0
- numba_cuda/numba/cuda/descriptor.py +1 -1
- numba_cuda/numba/cuda/device_init.py +4 -7
- numba_cuda/numba/cuda/deviceufunc.py +3 -6
- numba_cuda/numba/cuda/dispatcher.py +39 -49
- numba_cuda/numba/cuda/intrinsics.py +150 -1
- numba_cuda/numba/cuda/libdeviceimpl.py +1 -2
- numba_cuda/numba/cuda/lowering.py +36 -29
- numba_cuda/numba/cuda/memory_management/nrt.py +10 -14
- numba_cuda/numba/cuda/np/arrayobj.py +61 -9
- numba_cuda/numba/cuda/np/numpy_support.py +32 -9
- numba_cuda/numba/cuda/np/polynomial/polynomial_functions.py +4 -3
- numba_cuda/numba/cuda/printimpl.py +20 -0
- numba_cuda/numba/cuda/serialize.py +10 -0
- numba_cuda/numba/cuda/stubs.py +0 -11
- numba_cuda/numba/cuda/testing.py +4 -8
- numba_cuda/numba/cuda/tests/benchmarks/test_kernel_launch.py +21 -4
- numba_cuda/numba/cuda/tests/cudadrv/test_context_stack.py +1 -2
- numba_cuda/numba/cuda/tests/cudadrv/test_cuda_driver.py +195 -51
- numba_cuda/numba/cuda/tests/cudadrv/test_cuda_memory.py +6 -2
- numba_cuda/numba/cuda/tests/cudadrv/test_emm_plugins.py +3 -1
- numba_cuda/numba/cuda/tests/cudadrv/test_events.py +1 -1
- numba_cuda/numba/cuda/tests/cudadrv/test_linker.py +6 -7
- numba_cuda/numba/cuda/tests/cudadrv/test_module_callbacks.py +11 -12
- numba_cuda/numba/cuda/tests/cudadrv/test_nvjitlink.py +53 -23
- 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_caching.py +47 -0
- numba_cuda/numba/cuda/tests/cudapy/test_compiler.py +22 -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 +94 -0
- numba_cuda/numba/cuda/tests/cudapy/test_device_array_capture.py +243 -0
- numba_cuda/numba/cuda/tests/cudapy/test_dispatcher.py +3 -3
- numba_cuda/numba/cuda/tests/cudapy/test_extending.py +1 -1
- numba_cuda/numba/cuda/tests/cudapy/test_numba_interop.py +35 -0
- numba_cuda/numba/cuda/tests/cudapy/test_print.py +51 -0
- numba_cuda/numba/cuda/tests/cudapy/test_vector_type.py +37 -35
- numba_cuda/numba/cuda/tests/cudapy/test_warp_ops.py +117 -1
- numba_cuda/numba/cuda/tests/doc_examples/test_globals.py +111 -0
- numba_cuda/numba/cuda/tests/nocuda/test_dummyarray.py +61 -0
- numba_cuda/numba/cuda/tests/nrt/test_nrt.py +31 -0
- 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/context.py +3 -1
- numba_cuda/numba/cuda/typing/typeof.py +51 -2
- {numba_cuda-0.21.1.dist-info → numba_cuda-0.24.0.dist-info}/METADATA +4 -13
- {numba_cuda-0.21.1.dist-info → numba_cuda-0.24.0.dist-info}/RECORD +106 -105
- numba_cuda/numba/cuda/cext/_devicearray.cp313-win_amd64.pyd +0 -0
- numba_cuda/numba/cuda/cext/_devicearray.cpp +0 -159
- numba_cuda/numba/cuda/cext/_devicearray.h +0 -29
- numba_cuda/numba/cuda/intrinsic_wrapper.py +0 -41
- {numba_cuda-0.21.1.dist-info → numba_cuda-0.24.0.dist-info}/WHEEL +0 -0
- {numba_cuda-0.21.1.dist-info → numba_cuda-0.24.0.dist-info}/licenses/LICENSE +0 -0
- {numba_cuda-0.21.1.dist-info → numba_cuda-0.24.0.dist-info}/licenses/LICENSE.numba +0 -0
- {numba_cuda-0.21.1.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)):
|
|
@@ -217,8 +217,8 @@ def _call_function_ex_replace_kws_large(
|
|
|
217
217
|
# The first value must be a constant.
|
|
218
218
|
const_stmt = old_body[search_start]
|
|
219
219
|
if not (
|
|
220
|
-
isinstance(const_stmt, ir.
|
|
221
|
-
and isinstance(const_stmt.value, ir.
|
|
220
|
+
isinstance(const_stmt, ir.assign_types)
|
|
221
|
+
and isinstance(const_stmt.value, ir.const_types)
|
|
222
222
|
):
|
|
223
223
|
# We cannot handle this format so raise the
|
|
224
224
|
# original error message.
|
|
@@ -231,8 +231,8 @@ def _call_function_ex_replace_kws_large(
|
|
|
231
231
|
while search_start <= search_end and not found_getattr:
|
|
232
232
|
getattr_stmt = old_body[search_start]
|
|
233
233
|
if (
|
|
234
|
-
isinstance(getattr_stmt, ir.
|
|
235
|
-
and isinstance(getattr_stmt.value, ir.
|
|
234
|
+
isinstance(getattr_stmt, ir.assign_types)
|
|
235
|
+
and isinstance(getattr_stmt.value, ir.expr_types)
|
|
236
236
|
and getattr_stmt.value.op == "getattr"
|
|
237
237
|
and (getattr_stmt.value.value.name == buildmap_name)
|
|
238
238
|
and getattr_stmt.value.attr == "__setitem__"
|
|
@@ -262,8 +262,8 @@ def _call_function_ex_replace_kws_large(
|
|
|
262
262
|
raise UnsupportedBytecodeError(errmsg)
|
|
263
263
|
setitem_stmt = old_body[search_start + 1]
|
|
264
264
|
if not (
|
|
265
|
-
isinstance(setitem_stmt, ir.
|
|
266
|
-
and isinstance(setitem_stmt.value, ir.
|
|
265
|
+
isinstance(setitem_stmt, ir.assign_types)
|
|
266
|
+
and isinstance(setitem_stmt.value, ir.expr_types)
|
|
267
267
|
and setitem_stmt.value.op == "call"
|
|
268
268
|
and (setitem_stmt.value.func.name == getattr_stmt.target.name)
|
|
269
269
|
and len(setitem_stmt.value.args) == 2
|
|
@@ -366,8 +366,8 @@ def _call_function_ex_replace_args_large(
|
|
|
366
366
|
# tuple.
|
|
367
367
|
search_start = 0
|
|
368
368
|
total_args = []
|
|
369
|
-
if isinstance(vararg_stmt, ir.
|
|
370
|
-
vararg_stmt.value, ir.
|
|
369
|
+
if isinstance(vararg_stmt, ir.assign_types) and isinstance(
|
|
370
|
+
vararg_stmt.value, ir.var_types
|
|
371
371
|
):
|
|
372
372
|
target_name = vararg_stmt.value.name
|
|
373
373
|
# If there is an initial assignment, delete it
|
|
@@ -387,9 +387,9 @@ def _call_function_ex_replace_args_large(
|
|
|
387
387
|
while search_end >= search_start:
|
|
388
388
|
concat_stmt = old_body[search_end]
|
|
389
389
|
if (
|
|
390
|
-
isinstance(concat_stmt, ir.
|
|
390
|
+
isinstance(concat_stmt, ir.assign_types)
|
|
391
391
|
and concat_stmt.target.name == target_name
|
|
392
|
-
and isinstance(concat_stmt.value, ir.
|
|
392
|
+
and isinstance(concat_stmt.value, ir.expr_types)
|
|
393
393
|
and concat_stmt.value.op == "build_tuple"
|
|
394
394
|
and not concat_stmt.value.items
|
|
395
395
|
):
|
|
@@ -404,9 +404,9 @@ def _call_function_ex_replace_args_large(
|
|
|
404
404
|
# We expect to find another arg to append.
|
|
405
405
|
# The first stmt must be a binop "add"
|
|
406
406
|
if (search_end == search_start) or not (
|
|
407
|
-
isinstance(concat_stmt, ir.
|
|
407
|
+
isinstance(concat_stmt, ir.assign_types)
|
|
408
408
|
and (concat_stmt.target.name == target_name)
|
|
409
|
-
and isinstance(concat_stmt.value, ir.
|
|
409
|
+
and isinstance(concat_stmt.value, ir.expr_types)
|
|
410
410
|
and concat_stmt.value.op == "binop"
|
|
411
411
|
and concat_stmt.value.fn == operator.add
|
|
412
412
|
):
|
|
@@ -418,8 +418,8 @@ def _call_function_ex_replace_args_large(
|
|
|
418
418
|
# build_tuple containing the arg.
|
|
419
419
|
arg_tuple_stmt = old_body[search_end - 1]
|
|
420
420
|
if not (
|
|
421
|
-
isinstance(arg_tuple_stmt, ir.
|
|
422
|
-
and isinstance(arg_tuple_stmt.value, ir.
|
|
421
|
+
isinstance(arg_tuple_stmt, ir.assign_types)
|
|
422
|
+
and isinstance(arg_tuple_stmt.value, ir.expr_types)
|
|
423
423
|
and (arg_tuple_stmt.value.op == "build_tuple")
|
|
424
424
|
and len(arg_tuple_stmt.value.items) == 1
|
|
425
425
|
):
|
|
@@ -448,7 +448,7 @@ def _call_function_ex_replace_args_large(
|
|
|
448
448
|
keep_looking = True
|
|
449
449
|
while search_end >= search_start and keep_looking:
|
|
450
450
|
next_stmt = old_body[search_end]
|
|
451
|
-
if isinstance(next_stmt, ir.
|
|
451
|
+
if isinstance(next_stmt, ir.assign_types) and (
|
|
452
452
|
next_stmt.target.name == target_name
|
|
453
453
|
):
|
|
454
454
|
keep_looking = False
|
|
@@ -522,8 +522,8 @@ def peep_hole_call_function_ex_to_call_function_kw(func_ir):
|
|
|
522
522
|
new_body = []
|
|
523
523
|
for i, stmt in enumerate(blk.body):
|
|
524
524
|
if (
|
|
525
|
-
isinstance(stmt, ir.
|
|
526
|
-
and isinstance(stmt.value, ir.
|
|
525
|
+
isinstance(stmt, ir.assign_types)
|
|
526
|
+
and isinstance(stmt.value, ir.expr_types)
|
|
527
527
|
and stmt.value.op == "call"
|
|
528
528
|
and stmt.value.varkwarg is not None
|
|
529
529
|
):
|
|
@@ -548,7 +548,7 @@ def peep_hole_call_function_ex_to_call_function_kw(func_ir):
|
|
|
548
548
|
while varkwarg_loc >= 0 and not found:
|
|
549
549
|
keyword_def = blk.body[varkwarg_loc]
|
|
550
550
|
if (
|
|
551
|
-
isinstance(keyword_def, ir.
|
|
551
|
+
isinstance(keyword_def, ir.assign_types)
|
|
552
552
|
and keyword_def.target.name == varkwarg.name
|
|
553
553
|
):
|
|
554
554
|
found = True
|
|
@@ -558,7 +558,7 @@ def peep_hole_call_function_ex_to_call_function_kw(func_ir):
|
|
|
558
558
|
kws
|
|
559
559
|
or not found
|
|
560
560
|
or not (
|
|
561
|
-
isinstance(keyword_def.value, ir.
|
|
561
|
+
isinstance(keyword_def.value, ir.expr_types)
|
|
562
562
|
and keyword_def.value.op == "build_map"
|
|
563
563
|
)
|
|
564
564
|
):
|
|
@@ -624,7 +624,7 @@ def peep_hole_call_function_ex_to_call_function_kw(func_ir):
|
|
|
624
624
|
while vararg_loc >= 0 and not found:
|
|
625
625
|
args_def = blk.body[vararg_loc]
|
|
626
626
|
if (
|
|
627
|
-
isinstance(args_def, ir.
|
|
627
|
+
isinstance(args_def, ir.assign_types)
|
|
628
628
|
and args_def.target.name == vararg.name
|
|
629
629
|
):
|
|
630
630
|
found = True
|
|
@@ -635,7 +635,7 @@ def peep_hole_call_function_ex_to_call_function_kw(func_ir):
|
|
|
635
635
|
# then we can't handle this format.
|
|
636
636
|
raise UnsupportedBytecodeError(errmsg)
|
|
637
637
|
if (
|
|
638
|
-
isinstance(args_def.value, ir.
|
|
638
|
+
isinstance(args_def.value, ir.expr_types)
|
|
639
639
|
and args_def.value.op == "build_tuple"
|
|
640
640
|
):
|
|
641
641
|
# n_args <= 30 case.
|
|
@@ -656,7 +656,7 @@ def peep_hole_call_function_ex_to_call_function_kw(func_ir):
|
|
|
656
656
|
already_deleted_defs,
|
|
657
657
|
)
|
|
658
658
|
elif (
|
|
659
|
-
isinstance(args_def.value, ir.
|
|
659
|
+
isinstance(args_def.value, ir.expr_types)
|
|
660
660
|
and args_def.value.op == "list_to_tuple"
|
|
661
661
|
):
|
|
662
662
|
# If there is a call with vararg we need to check
|
|
@@ -708,8 +708,8 @@ def peep_hole_call_function_ex_to_call_function_kw(func_ir):
|
|
|
708
708
|
# Update the definition
|
|
709
709
|
func_ir._definitions[stmt.target.name].append(new_call)
|
|
710
710
|
elif (
|
|
711
|
-
isinstance(stmt, ir.
|
|
712
|
-
and isinstance(stmt.value, ir.
|
|
711
|
+
isinstance(stmt, ir.assign_types)
|
|
712
|
+
and isinstance(stmt.value, ir.expr_types)
|
|
713
713
|
and stmt.value.op == "call"
|
|
714
714
|
and stmt.value.vararg is not None
|
|
715
715
|
):
|
|
@@ -725,7 +725,10 @@ def peep_hole_call_function_ex_to_call_function_kw(func_ir):
|
|
|
725
725
|
# If this value is still a list to tuple raise the
|
|
726
726
|
# exception.
|
|
727
727
|
expr = func_ir._definitions[vararg_name][0]
|
|
728
|
-
if
|
|
728
|
+
if (
|
|
729
|
+
isinstance(expr, ir.expr_types)
|
|
730
|
+
and expr.op == "list_to_tuple"
|
|
731
|
+
):
|
|
729
732
|
raise UnsupportedBytecodeError(errmsg)
|
|
730
733
|
|
|
731
734
|
new_body.append(stmt)
|
|
@@ -771,7 +774,7 @@ def peep_hole_list_to_tuple(func_ir):
|
|
|
771
774
|
_DEBUG = False
|
|
772
775
|
|
|
773
776
|
# For all blocks
|
|
774
|
-
for
|
|
777
|
+
for blk in func_ir.blocks.values():
|
|
775
778
|
# keep doing the peephole rewrite until nothing is left that matches
|
|
776
779
|
while True:
|
|
777
780
|
# first try and find a matching region
|
|
@@ -780,17 +783,17 @@ def peep_hole_list_to_tuple(func_ir):
|
|
|
780
783
|
found = False
|
|
781
784
|
for idx in reversed(range(len(blk.body))):
|
|
782
785
|
stmt = blk.body[idx]
|
|
783
|
-
if isinstance(stmt, ir.
|
|
786
|
+
if isinstance(stmt, ir.assign_types):
|
|
784
787
|
value = stmt.value
|
|
785
788
|
if (
|
|
786
|
-
isinstance(value, ir.
|
|
789
|
+
isinstance(value, ir.expr_types)
|
|
787
790
|
and value.op == "list_to_tuple"
|
|
788
791
|
):
|
|
789
792
|
target_list = value.info[0]
|
|
790
793
|
found = True
|
|
791
794
|
bt = (idx, stmt)
|
|
792
795
|
if found:
|
|
793
|
-
if isinstance(stmt, ir.
|
|
796
|
+
if isinstance(stmt, ir.assign_types):
|
|
794
797
|
if stmt.target.name == target_list:
|
|
795
798
|
region = (bt, (idx, stmt))
|
|
796
799
|
return region
|
|
@@ -812,8 +815,8 @@ def peep_hole_list_to_tuple(func_ir):
|
|
|
812
815
|
# Walk through the peep_hole and find things that are being
|
|
813
816
|
# "extend"ed and "append"ed to the BUILD_LIST
|
|
814
817
|
for x in peep_hole:
|
|
815
|
-
if isinstance(x, ir.
|
|
816
|
-
if isinstance(x.value, ir.
|
|
818
|
+
if isinstance(x, ir.assign_types):
|
|
819
|
+
if isinstance(x.value, ir.expr_types):
|
|
817
820
|
expr = x.value
|
|
818
821
|
if (
|
|
819
822
|
expr.op == "getattr"
|
|
@@ -857,8 +860,8 @@ def peep_hole_list_to_tuple(func_ir):
|
|
|
857
860
|
t2l_agn = region[0][1]
|
|
858
861
|
acc = the_build_list
|
|
859
862
|
for x in peep_hole:
|
|
860
|
-
if isinstance(x, ir.
|
|
861
|
-
if isinstance(x.value, ir.
|
|
863
|
+
if isinstance(x, ir.assign_types):
|
|
864
|
+
if isinstance(x.value, ir.expr_types):
|
|
862
865
|
expr = x.value
|
|
863
866
|
if expr.op == "getattr":
|
|
864
867
|
if (
|
|
@@ -877,7 +880,7 @@ def peep_hole_list_to_tuple(func_ir):
|
|
|
877
880
|
fname = expr.func.name
|
|
878
881
|
if fname in extends or fname in appends:
|
|
879
882
|
arg = expr.args[0]
|
|
880
|
-
if isinstance(arg, ir.
|
|
883
|
+
if isinstance(arg, ir.var_types):
|
|
881
884
|
tmp_name = "%s_var_%s" % (
|
|
882
885
|
fname,
|
|
883
886
|
arg.name,
|
|
@@ -997,14 +1000,15 @@ def peep_hole_delete_with_exit(func_ir):
|
|
|
997
1000
|
# Any assignment that uses any of the dead variable is considered
|
|
998
1001
|
# dead.
|
|
999
1002
|
if used & dead_vars:
|
|
1000
|
-
if isinstance(stmt, ir.
|
|
1003
|
+
if isinstance(stmt, ir.assign_types):
|
|
1001
1004
|
dead_vars.add(stmt.target)
|
|
1002
1005
|
|
|
1003
|
-
new_body = [
|
|
1004
|
-
|
|
1006
|
+
new_body = [
|
|
1007
|
+
stmt
|
|
1008
|
+
for stmt in blk.body
|
|
1005
1009
|
# Skip any statements that uses anyone of the dead variable.
|
|
1006
|
-
if not (set(stmt.list_vars()) & dead_vars)
|
|
1007
|
-
|
|
1010
|
+
if not (set(stmt.list_vars()) & dead_vars)
|
|
1011
|
+
]
|
|
1008
1012
|
blk.body.clear()
|
|
1009
1013
|
blk.body.extend(new_body)
|
|
1010
1014
|
|
|
@@ -1112,7 +1116,9 @@ def peep_hole_fuse_dict_add_updates(func_ir):
|
|
|
1112
1116
|
# vars in statement. This is always the lhs with
|
|
1113
1117
|
# a build_map.
|
|
1114
1118
|
stmt_build_map_out = None
|
|
1115
|
-
if isinstance(stmt, ir.
|
|
1119
|
+
if isinstance(stmt, ir.assign_types) and isinstance(
|
|
1120
|
+
stmt.value, ir.expr_types
|
|
1121
|
+
):
|
|
1116
1122
|
if stmt.value.op == "build_map":
|
|
1117
1123
|
# Skip the output build_map when looking for used vars.
|
|
1118
1124
|
stmt_build_map_out = stmt.target.name
|
|
@@ -1130,9 +1136,9 @@ def peep_hole_fuse_dict_add_updates(func_ir):
|
|
|
1130
1136
|
getattr_stmt = blk.body[i - 1]
|
|
1131
1137
|
args = stmt.value.args
|
|
1132
1138
|
if (
|
|
1133
|
-
isinstance(getattr_stmt, ir.
|
|
1139
|
+
isinstance(getattr_stmt, ir.assign_types)
|
|
1134
1140
|
and getattr_stmt.target.name == func_name
|
|
1135
|
-
and isinstance(getattr_stmt.value, ir.
|
|
1141
|
+
and isinstance(getattr_stmt.value, ir.expr_types)
|
|
1136
1142
|
and getattr_stmt.value.op == "getattr"
|
|
1137
1143
|
and getattr_stmt.value.attr
|
|
1138
1144
|
in ("__setitem__", "_update_from_bytecode")
|
|
@@ -1207,8 +1213,8 @@ def peep_hole_fuse_dict_add_updates(func_ir):
|
|
|
1207
1213
|
# will be removed when handling their call in the next
|
|
1208
1214
|
# iteration.
|
|
1209
1215
|
if not (
|
|
1210
|
-
isinstance(stmt, ir.
|
|
1211
|
-
and isinstance(stmt.value, ir.
|
|
1216
|
+
isinstance(stmt, ir.assign_types)
|
|
1217
|
+
and isinstance(stmt.value, ir.expr_types)
|
|
1212
1218
|
and stmt.value.op == "getattr"
|
|
1213
1219
|
and stmt.value.value.name in lit_map_use_idx
|
|
1214
1220
|
and stmt.value.attr in ("__setitem__", "_update_from_bytecode")
|
|
@@ -1249,7 +1255,7 @@ def peep_hole_split_at_pop_block(func_ir):
|
|
|
1249
1255
|
# Gather locations of PopBlock
|
|
1250
1256
|
pop_block_locs = []
|
|
1251
1257
|
for i, inst in enumerate(blk.body):
|
|
1252
|
-
if isinstance(inst, ir.
|
|
1258
|
+
if isinstance(inst, ir.popblock_types):
|
|
1253
1259
|
pop_block_locs.append(i)
|
|
1254
1260
|
# Rewrite block with PopBlock
|
|
1255
1261
|
if pop_block_locs:
|
|
@@ -1301,10 +1307,14 @@ def _build_new_build_map(func_ir, name, old_body, old_lineno, new_items):
|
|
|
1301
1307
|
for pair in new_items:
|
|
1302
1308
|
k, v = pair
|
|
1303
1309
|
key_def = ir_utils.guard(ir_utils.get_definition, func_ir, k)
|
|
1304
|
-
if isinstance(
|
|
1310
|
+
if isinstance(
|
|
1311
|
+
key_def, ir.const_types + ir.global_types + ir.freevar_types
|
|
1312
|
+
):
|
|
1305
1313
|
literal_keys.append(key_def.value)
|
|
1306
1314
|
value_def = ir_utils.guard(ir_utils.get_definition, func_ir, v)
|
|
1307
|
-
if isinstance(
|
|
1315
|
+
if isinstance(
|
|
1316
|
+
value_def, ir.const_types + ir.global_types + ir.freevar_types
|
|
1317
|
+
):
|
|
1308
1318
|
values.append(value_def.value)
|
|
1309
1319
|
else:
|
|
1310
1320
|
# Append unknown value if not a literal.
|
|
@@ -1314,8 +1324,7 @@ def _build_new_build_map(func_ir, name, old_body, old_lineno, new_items):
|
|
|
1314
1324
|
if len(literal_keys) == len(new_items):
|
|
1315
1325
|
# All keys must be literals to have any literal values.
|
|
1316
1326
|
literal_value = {x: y for x, y in zip(literal_keys, values)}
|
|
1317
|
-
for i, k in enumerate(literal_keys)
|
|
1318
|
-
value_indexes[k] = i
|
|
1327
|
+
value_indexes.update((k, i) for i, k in enumerate(literal_keys))
|
|
1319
1328
|
else:
|
|
1320
1329
|
literal_value = None
|
|
1321
1330
|
|
|
@@ -1381,14 +1390,14 @@ class Interpreter(object):
|
|
|
1381
1390
|
self.current_block = None
|
|
1382
1391
|
self.current_block_offset = None
|
|
1383
1392
|
last_active_offset = 0
|
|
1384
|
-
for
|
|
1393
|
+
for inst_blocks in self.cfa.blocks.values():
|
|
1385
1394
|
if inst_blocks.body:
|
|
1386
1395
|
last_active_offset = max(
|
|
1387
1396
|
last_active_offset, max(inst_blocks.body)
|
|
1388
1397
|
)
|
|
1389
1398
|
self.last_active_offset = last_active_offset
|
|
1390
1399
|
|
|
1391
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
1400
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
1392
1401
|
self.active_exception_entries = tuple(
|
|
1393
1402
|
[
|
|
1394
1403
|
entry
|
|
@@ -1408,7 +1417,7 @@ class Interpreter(object):
|
|
|
1408
1417
|
# Interpret loop
|
|
1409
1418
|
for inst, kws in self._iter_inst():
|
|
1410
1419
|
self._dispatch(inst, kws)
|
|
1411
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
1420
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
1412
1421
|
# Insert end of try markers
|
|
1413
1422
|
self._end_try_blocks()
|
|
1414
1423
|
elif PYVERSION in (
|
|
@@ -1436,12 +1445,12 @@ class Interpreter(object):
|
|
|
1436
1445
|
# post process the IR to rewrite opcodes/byte sequences that are too
|
|
1437
1446
|
# involved to risk handling as part of direct interpretation
|
|
1438
1447
|
peepholes = []
|
|
1439
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
1448
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
1440
1449
|
peepholes.append(peep_hole_split_at_pop_block)
|
|
1441
|
-
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)):
|
|
1442
1451
|
peepholes.append(peep_hole_list_to_tuple)
|
|
1443
1452
|
peepholes.append(peep_hole_delete_with_exit)
|
|
1444
|
-
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)):
|
|
1445
1454
|
# peep_hole_call_function_ex_to_call_function_kw
|
|
1446
1455
|
# depends on peep_hole_list_to_tuple converting
|
|
1447
1456
|
# any large number of arguments from a list to a
|
|
@@ -1474,7 +1483,7 @@ class Interpreter(object):
|
|
|
1474
1483
|
|
|
1475
1484
|
See also: _insert_try_block_end
|
|
1476
1485
|
"""
|
|
1477
|
-
assert PYVERSION in ((3, 11), (3, 12), (3, 13))
|
|
1486
|
+
assert PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14))
|
|
1478
1487
|
graph = self.cfa.graph
|
|
1479
1488
|
for offset, block in self.blocks.items():
|
|
1480
1489
|
# Get current blockstack
|
|
@@ -1514,7 +1523,7 @@ class Interpreter(object):
|
|
|
1514
1523
|
# Propagate the exception variables to LHS of assignment
|
|
1515
1524
|
for varname, defnvars in self.definitions.items():
|
|
1516
1525
|
for v in defnvars:
|
|
1517
|
-
if isinstance(v, ir.
|
|
1526
|
+
if isinstance(v, ir.var_types):
|
|
1518
1527
|
k = v.name
|
|
1519
1528
|
if k in excvars:
|
|
1520
1529
|
excvars.add(varname)
|
|
@@ -1582,12 +1591,12 @@ class Interpreter(object):
|
|
|
1582
1591
|
self.dfainfo = self.dfa.infos[self.current_block_offset]
|
|
1583
1592
|
self.assigner = Assigner()
|
|
1584
1593
|
# Check out-of-scope syntactic-block
|
|
1585
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
1594
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
1586
1595
|
# This is recreating pre-3.11 code structure
|
|
1587
1596
|
while self.syntax_blocks:
|
|
1588
1597
|
if offset >= self.syntax_blocks[-1].exit:
|
|
1589
1598
|
synblk = self.syntax_blocks.pop()
|
|
1590
|
-
if isinstance(synblk, ir.
|
|
1599
|
+
if isinstance(synblk, ir.with_types):
|
|
1591
1600
|
self.current_block.append(ir.PopBlock(self.loc))
|
|
1592
1601
|
else:
|
|
1593
1602
|
break
|
|
@@ -1684,11 +1693,11 @@ class Interpreter(object):
|
|
|
1684
1693
|
# like a = b[i] = 1, so need to handle replaced temporaries in
|
|
1685
1694
|
# later setitem/setattr nodes
|
|
1686
1695
|
if (
|
|
1687
|
-
isinstance(inst,
|
|
1696
|
+
isinstance(inst, ir.setitem_types + ir.setattr_types)
|
|
1688
1697
|
and inst.value.name in replaced_var
|
|
1689
1698
|
):
|
|
1690
1699
|
inst.value = replaced_var[inst.value.name]
|
|
1691
|
-
elif isinstance(inst, ir.
|
|
1700
|
+
elif isinstance(inst, ir.assign_types):
|
|
1692
1701
|
if (
|
|
1693
1702
|
inst.target.is_temp
|
|
1694
1703
|
and inst.target.name in self.assigner.unused_dests
|
|
@@ -1698,7 +1707,7 @@ class Interpreter(object):
|
|
|
1698
1707
|
# like a = b = 1, so need to handle replaced temporaries in
|
|
1699
1708
|
# later assignments
|
|
1700
1709
|
if (
|
|
1701
|
-
isinstance(inst.value, ir.
|
|
1710
|
+
isinstance(inst.value, ir.var_types)
|
|
1702
1711
|
and inst.value.name in replaced_var
|
|
1703
1712
|
):
|
|
1704
1713
|
inst.value = replaced_var[inst.value.name]
|
|
@@ -1707,7 +1716,7 @@ class Interpreter(object):
|
|
|
1707
1716
|
# chained unpack cases may reuse temporary
|
|
1708
1717
|
# e.g. a = (b, c) = (x, y)
|
|
1709
1718
|
if (
|
|
1710
|
-
isinstance(inst.value, ir.
|
|
1719
|
+
isinstance(inst.value, ir.expr_types)
|
|
1711
1720
|
and inst.value.op == "exhaust_iter"
|
|
1712
1721
|
and inst.value.value.name in replaced_var
|
|
1713
1722
|
):
|
|
@@ -1720,10 +1729,10 @@ class Interpreter(object):
|
|
|
1720
1729
|
# the temporary variable is not reused elsewhere since CPython
|
|
1721
1730
|
# bytecode is stack-based and this pattern corresponds to a pop
|
|
1722
1731
|
if (
|
|
1723
|
-
isinstance(inst.value, ir.
|
|
1732
|
+
isinstance(inst.value, ir.var_types)
|
|
1724
1733
|
and inst.value.is_temp
|
|
1725
1734
|
and new_body
|
|
1726
|
-
and isinstance(new_body[-1], ir.
|
|
1735
|
+
and isinstance(new_body[-1], ir.assign_types)
|
|
1727
1736
|
):
|
|
1728
1737
|
prev_assign = new_body[-1]
|
|
1729
1738
|
# _var_used_in_binop check makes sure we don't create a new
|
|
@@ -1753,7 +1762,7 @@ class Interpreter(object):
|
|
|
1753
1762
|
in it as an argument
|
|
1754
1763
|
"""
|
|
1755
1764
|
return (
|
|
1756
|
-
isinstance(expr, ir.
|
|
1765
|
+
isinstance(expr, ir.expr_types)
|
|
1757
1766
|
and expr.op in ("binop", "inplace_binop")
|
|
1758
1767
|
and (varname == expr.lhs.name or varname == expr.rhs.name)
|
|
1759
1768
|
)
|
|
@@ -1769,7 +1778,7 @@ class Interpreter(object):
|
|
|
1769
1778
|
val = self.get(varname)
|
|
1770
1779
|
except ir.NotDefinedError:
|
|
1771
1780
|
# Hack to make sure exception variables are defined
|
|
1772
|
-
assert PYVERSION in ((3, 11), (3, 12), (3, 13)), (
|
|
1781
|
+
assert PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)), (
|
|
1773
1782
|
"unexpected missing definition"
|
|
1774
1783
|
)
|
|
1775
1784
|
val = ir.Const(value=None, loc=self.loc)
|
|
@@ -1829,10 +1838,10 @@ class Interpreter(object):
|
|
|
1829
1838
|
if self._DEBUG_PRINT:
|
|
1830
1839
|
print(inst)
|
|
1831
1840
|
assert self.current_block is not None
|
|
1832
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
1841
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
1833
1842
|
if self.syntax_blocks:
|
|
1834
1843
|
top = self.syntax_blocks[-1]
|
|
1835
|
-
if isinstance(top, ir.
|
|
1844
|
+
if isinstance(top, ir.with_types):
|
|
1836
1845
|
if inst.offset >= top.exit:
|
|
1837
1846
|
self.current_block.append(ir.PopBlock(loc=self.loc))
|
|
1838
1847
|
self.syntax_blocks.pop()
|
|
@@ -1881,7 +1890,7 @@ class Interpreter(object):
|
|
|
1881
1890
|
)
|
|
1882
1891
|
else:
|
|
1883
1892
|
target = self.current_scope.get_or_define(name, loc=self.loc)
|
|
1884
|
-
if isinstance(value, ir.
|
|
1893
|
+
if isinstance(value, ir.var_types):
|
|
1885
1894
|
value = self.assigner.assign(value, target)
|
|
1886
1895
|
stmt = ir.Assign(value=value, target=target, loc=self.loc)
|
|
1887
1896
|
self.current_block.append(stmt)
|
|
@@ -1920,6 +1929,14 @@ class Interpreter(object):
|
|
|
1920
1929
|
def op_NOP(self, inst):
|
|
1921
1930
|
pass
|
|
1922
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
|
+
|
|
1923
1940
|
def op_RESUME(self, inst):
|
|
1924
1941
|
pass
|
|
1925
1942
|
|
|
@@ -2019,7 +2036,7 @@ class Interpreter(object):
|
|
|
2019
2036
|
)
|
|
2020
2037
|
self.store(value=sliceinst, name=res)
|
|
2021
2038
|
|
|
2022
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
2039
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
2023
2040
|
|
|
2024
2041
|
def op_BINARY_SLICE(
|
|
2025
2042
|
self, inst, start, end, container, res, slicevar, temp_res
|
|
@@ -2041,7 +2058,7 @@ class Interpreter(object):
|
|
|
2041
2058
|
else:
|
|
2042
2059
|
raise NotImplementedError(PYVERSION)
|
|
2043
2060
|
|
|
2044
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
2061
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
2045
2062
|
|
|
2046
2063
|
def op_STORE_SLICE(
|
|
2047
2064
|
self, inst, start, end, container, value, res, slicevar
|
|
@@ -2311,7 +2328,7 @@ class Interpreter(object):
|
|
|
2311
2328
|
srcname = self.code_locals[inst.arg]
|
|
2312
2329
|
self.store(value=self.get(srcname), name=res)
|
|
2313
2330
|
|
|
2314
|
-
if PYVERSION in ((3, 13),):
|
|
2331
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
2315
2332
|
|
|
2316
2333
|
def op_LOAD_FAST(self, inst, res, as_load_deref=False):
|
|
2317
2334
|
if as_load_deref:
|
|
@@ -2322,7 +2339,7 @@ class Interpreter(object):
|
|
|
2322
2339
|
else:
|
|
2323
2340
|
op_LOAD_FAST = _op_LOAD_FAST
|
|
2324
2341
|
|
|
2325
|
-
if PYVERSION in ((3, 13),):
|
|
2342
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
2326
2343
|
|
|
2327
2344
|
def op_LOAD_FAST_LOAD_FAST(self, inst, res1, res2):
|
|
2328
2345
|
oparg = inst.arg
|
|
@@ -2360,7 +2377,7 @@ class Interpreter(object):
|
|
|
2360
2377
|
else:
|
|
2361
2378
|
raise NotImplementedError(PYVERSION)
|
|
2362
2379
|
|
|
2363
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
2380
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
2364
2381
|
op_LOAD_FAST_CHECK = op_LOAD_FAST
|
|
2365
2382
|
|
|
2366
2383
|
def op_LOAD_FAST_AND_CLEAR(self, inst, res):
|
|
@@ -2378,6 +2395,16 @@ class Interpreter(object):
|
|
|
2378
2395
|
else:
|
|
2379
2396
|
raise NotImplementedError(PYVERSION)
|
|
2380
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
|
+
|
|
2381
2408
|
def op_STORE_FAST(self, inst, value):
|
|
2382
2409
|
dstname = self.code_locals[inst.arg]
|
|
2383
2410
|
value = self.get(value)
|
|
@@ -2411,7 +2438,7 @@ class Interpreter(object):
|
|
|
2411
2438
|
|
|
2412
2439
|
def op_LOAD_ATTR(self, inst, item, res):
|
|
2413
2440
|
item = self.get(item)
|
|
2414
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
2441
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
2415
2442
|
attr = self.code_names[inst.arg >> 1]
|
|
2416
2443
|
elif PYVERSION in ((3, 9), (3, 10), (3, 11)):
|
|
2417
2444
|
attr = self.code_names[inst.arg]
|
|
@@ -2421,28 +2448,85 @@ class Interpreter(object):
|
|
|
2421
2448
|
self.store(getattr, res)
|
|
2422
2449
|
|
|
2423
2450
|
def op_LOAD_CONST(self, inst, res):
|
|
2424
|
-
|
|
2425
|
-
|
|
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):
|
|
2426
2486
|
st = []
|
|
2427
2487
|
for x in value:
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
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)
|
|
2433
2510
|
elif isinstance(value, frozenset):
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
val_const = ir.Const(x, loc=self.loc)
|
|
2438
|
-
target = self.store(val_const, name=nm, redefine=True)
|
|
2439
|
-
st.append(target)
|
|
2440
|
-
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)
|
|
2441
2514
|
else:
|
|
2442
2515
|
const = ir.Const(value, loc=self.loc)
|
|
2443
2516
|
self.store(const, res)
|
|
2444
2517
|
|
|
2445
|
-
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)):
|
|
2446
2530
|
|
|
2447
2531
|
def op_LOAD_GLOBAL(self, inst, idx, res):
|
|
2448
2532
|
name = self.code_names[idx]
|
|
@@ -2465,7 +2549,7 @@ class Interpreter(object):
|
|
|
2465
2549
|
def op_COPY_FREE_VARS(self, inst):
|
|
2466
2550
|
pass
|
|
2467
2551
|
|
|
2468
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
2552
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
2469
2553
|
|
|
2470
2554
|
def op_LOAD_DEREF(self, inst, res):
|
|
2471
2555
|
name = self.func_id.func.__code__._varname_from_oparg(inst.arg)
|
|
@@ -2499,12 +2583,12 @@ class Interpreter(object):
|
|
|
2499
2583
|
else:
|
|
2500
2584
|
raise NotImplementedError(PYVERSION)
|
|
2501
2585
|
|
|
2502
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
2586
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
2503
2587
|
|
|
2504
2588
|
def op_MAKE_CELL(self, inst):
|
|
2505
2589
|
pass # ignored bytecode
|
|
2506
2590
|
|
|
2507
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
2591
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
2508
2592
|
|
|
2509
2593
|
def op_STORE_DEREF(self, inst, value):
|
|
2510
2594
|
name = self.func_id.func.__code__._varname_from_oparg(inst.arg)
|
|
@@ -2552,39 +2636,46 @@ class Interpreter(object):
|
|
|
2552
2636
|
exit_fn_obj = ir.Const(None, loc=self.loc)
|
|
2553
2637
|
self.store(value=exit_fn_obj, name=exitfn)
|
|
2554
2638
|
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
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,
|
|
2567
2671
|
)
|
|
2568
|
-
elif PYVERSION in ((3, 9), (3, 10), (3, 11)):
|
|
2569
|
-
pass
|
|
2570
|
-
else:
|
|
2571
|
-
raise NotImplementedError(PYVERSION)
|
|
2572
|
-
# Handle with
|
|
2573
|
-
wth = ir.With(inst.offset, exit=end)
|
|
2574
|
-
self.syntax_blocks.append(wth)
|
|
2575
|
-
ctxmgr = self.get(contextmanager)
|
|
2576
|
-
self.current_block.append(
|
|
2577
|
-
ir.EnterWith(
|
|
2578
|
-
contextmanager=ctxmgr,
|
|
2579
|
-
begin=inst.offset,
|
|
2580
|
-
end=end,
|
|
2581
|
-
loc=self.loc,
|
|
2582
2672
|
)
|
|
2583
|
-
)
|
|
2584
2673
|
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
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)
|
|
2588
2679
|
|
|
2589
2680
|
def op_SETUP_FINALLY(self, inst):
|
|
2590
2681
|
# Removed since python3.11
|
|
@@ -2623,7 +2714,7 @@ class Interpreter(object):
|
|
|
2623
2714
|
expr = ir.Expr.call(func, args, kwargs, loc=self.loc)
|
|
2624
2715
|
self.store(expr, res)
|
|
2625
2716
|
|
|
2626
|
-
if PYVERSION in ((3, 13),):
|
|
2717
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
2627
2718
|
|
|
2628
2719
|
def op_CALL_KW(self, inst, func, args, kw_names, res):
|
|
2629
2720
|
func = self.get(func)
|
|
@@ -2649,7 +2740,7 @@ class Interpreter(object):
|
|
|
2649
2740
|
# Find names const
|
|
2650
2741
|
names = self.get(names)
|
|
2651
2742
|
for inst in self.current_block.body:
|
|
2652
|
-
if isinstance(inst, ir.
|
|
2743
|
+
if isinstance(inst, ir.assign_types) and inst.target is names:
|
|
2653
2744
|
self.current_block.remove(inst)
|
|
2654
2745
|
# scan up the block looking for the values, remove them
|
|
2655
2746
|
# and find their name strings
|
|
@@ -2750,7 +2841,7 @@ class Interpreter(object):
|
|
|
2750
2841
|
keyvar = self.get(keys)
|
|
2751
2842
|
# TODO: refactor this pattern. occurred several times.
|
|
2752
2843
|
for inst in self.current_block.body:
|
|
2753
|
-
if isinstance(inst, ir.
|
|
2844
|
+
if isinstance(inst, ir.assign_types) and inst.target is keyvar:
|
|
2754
2845
|
self.current_block.remove(inst)
|
|
2755
2846
|
# scan up the block looking for the values, remove them
|
|
2756
2847
|
# and find their name strings
|
|
@@ -2776,7 +2867,7 @@ class Interpreter(object):
|
|
|
2776
2867
|
if len(defns) != 1:
|
|
2777
2868
|
break
|
|
2778
2869
|
defn = defns[0]
|
|
2779
|
-
if not isinstance(defn, ir.
|
|
2870
|
+
if not isinstance(defn, ir.const_types):
|
|
2780
2871
|
break
|
|
2781
2872
|
literal_items.append(defn.value)
|
|
2782
2873
|
|
|
@@ -2785,7 +2876,7 @@ class Interpreter(object):
|
|
|
2785
2876
|
if len(defns) != 1:
|
|
2786
2877
|
return _UNKNOWN_VALUE(self.get(v).name)
|
|
2787
2878
|
defn = defns[0]
|
|
2788
|
-
if not isinstance(defn, ir.
|
|
2879
|
+
if not isinstance(defn, ir.const_types):
|
|
2789
2880
|
return _UNKNOWN_VALUE(self.get(v).name)
|
|
2790
2881
|
return defn.value
|
|
2791
2882
|
|
|
@@ -2798,9 +2889,7 @@ class Interpreter(object):
|
|
|
2798
2889
|
# store the index of the actual used value for a given key, this is
|
|
2799
2890
|
# used when lowering to pull the right value out into the tuple repr
|
|
2800
2891
|
# of a mixed value type dictionary.
|
|
2801
|
-
value_indexes = {}
|
|
2802
|
-
for i, k in enumerate(keytup):
|
|
2803
|
-
value_indexes[k] = i
|
|
2892
|
+
value_indexes = {k: i for i, k in enumerate(keytup)}
|
|
2804
2893
|
|
|
2805
2894
|
expr = ir.Expr.build_map(
|
|
2806
2895
|
items=items,
|
|
@@ -2843,11 +2932,18 @@ class Interpreter(object):
|
|
|
2843
2932
|
)
|
|
2844
2933
|
self.current_block.append(br)
|
|
2845
2934
|
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
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)
|
|
2851
2947
|
|
|
2852
2948
|
def op_STORE_SUBSCR(self, inst, target, index, value):
|
|
2853
2949
|
index = self.get(index)
|
|
@@ -2880,6 +2976,14 @@ class Interpreter(object):
|
|
|
2880
2976
|
)
|
|
2881
2977
|
self.store(expr, res)
|
|
2882
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
|
+
|
|
2883
2987
|
def op_SET_UPDATE(self, inst, target, value, updatevar, res):
|
|
2884
2988
|
target = self.get(target)
|
|
2885
2989
|
value = self.get(value)
|
|
@@ -2921,7 +3025,7 @@ class Interpreter(object):
|
|
|
2921
3025
|
if len(defns) != 1:
|
|
2922
3026
|
break
|
|
2923
3027
|
defn = defns[0]
|
|
2924
|
-
if not isinstance(defn, ir.
|
|
3028
|
+
if not isinstance(defn, ir.const_types):
|
|
2925
3029
|
break
|
|
2926
3030
|
literal_items.append(defn.value)
|
|
2927
3031
|
return literal_items
|
|
@@ -2939,12 +3043,10 @@ class Interpreter(object):
|
|
|
2939
3043
|
literal_dict = {
|
|
2940
3044
|
x: _UNKNOWN_VALUE(y[1]) for x, y in zip(literal_keys, got_items)
|
|
2941
3045
|
}
|
|
2942
|
-
for i, k in enumerate(literal_keys)
|
|
2943
|
-
value_indexes[k] = i
|
|
3046
|
+
value_indexes.update((k, i) for i, k in enumerate(literal_keys))
|
|
2944
3047
|
else:
|
|
2945
3048
|
literal_dict = {x: y for x, y in zip(literal_keys, literal_values)}
|
|
2946
|
-
for i, k in enumerate(literal_keys)
|
|
2947
|
-
value_indexes[k] = i
|
|
3049
|
+
value_indexes.update((k, i) for i, k in enumerate(literal_keys))
|
|
2948
3050
|
|
|
2949
3051
|
expr = ir.Expr.build_map(
|
|
2950
3052
|
items=got_items,
|
|
@@ -3000,7 +3102,13 @@ class Interpreter(object):
|
|
|
3000
3102
|
self.store(expr, res)
|
|
3001
3103
|
|
|
3002
3104
|
def op_BINARY_OP(self, inst, op, lhs, rhs, res):
|
|
3003
|
-
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:
|
|
3004
3112
|
self._inplace_binop(op[:-1], lhs, rhs, res)
|
|
3005
3113
|
else:
|
|
3006
3114
|
self._binop(op, lhs, rhs, res)
|
|
@@ -3117,7 +3225,7 @@ class Interpreter(object):
|
|
|
3117
3225
|
ret = ir.Return(self.get(castval), loc=self.loc)
|
|
3118
3226
|
self.current_block.append(ret)
|
|
3119
3227
|
|
|
3120
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
3228
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
3121
3229
|
|
|
3122
3230
|
def op_RETURN_CONST(self, inst, retval, castval):
|
|
3123
3231
|
value = self.code_consts[inst.arg]
|
|
@@ -3131,7 +3239,7 @@ class Interpreter(object):
|
|
|
3131
3239
|
else:
|
|
3132
3240
|
raise NotImplementedError(PYVERSION)
|
|
3133
3241
|
|
|
3134
|
-
if PYVERSION in ((3, 13),):
|
|
3242
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
3135
3243
|
|
|
3136
3244
|
def op_TO_BOOL(self, inst, val, res):
|
|
3137
3245
|
self.store(self.get(val), res) # TODO: just a lazy hack
|
|
@@ -3142,7 +3250,7 @@ class Interpreter(object):
|
|
|
3142
3250
|
raise NotImplementedError(PYVERSION)
|
|
3143
3251
|
|
|
3144
3252
|
def op_COMPARE_OP(self, inst, lhs, rhs, res):
|
|
3145
|
-
if PYVERSION in ((3, 13),):
|
|
3253
|
+
if PYVERSION in ((3, 13), (3, 14)):
|
|
3146
3254
|
op = dis.cmp_op[inst.arg >> 5]
|
|
3147
3255
|
# TODO: fifth lowest bit now indicates a forced version to bool.
|
|
3148
3256
|
elif PYVERSION in ((3, 12),):
|
|
@@ -3196,7 +3304,7 @@ class Interpreter(object):
|
|
|
3196
3304
|
def op_BREAK_LOOP(self, inst, end=None):
|
|
3197
3305
|
if end is None:
|
|
3198
3306
|
loop = self.syntax_blocks[-1]
|
|
3199
|
-
assert isinstance(loop, ir.
|
|
3307
|
+
assert isinstance(loop, ir.loop_types)
|
|
3200
3308
|
end = loop.exit
|
|
3201
3309
|
jmp = ir.Jump(target=end, loc=self.loc)
|
|
3202
3310
|
self.current_block.append(jmp)
|
|
@@ -3271,7 +3379,7 @@ class Interpreter(object):
|
|
|
3271
3379
|
def op_POP_JUMP_FORWARD_IF_NOT_NONE(self, inst, pred):
|
|
3272
3380
|
self._jump_if_none(inst, pred, False)
|
|
3273
3381
|
|
|
3274
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
3382
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
3275
3383
|
|
|
3276
3384
|
def op_POP_JUMP_IF_NONE(self, inst, pred):
|
|
3277
3385
|
self._jump_if_none(inst, pred, True)
|
|
@@ -3408,7 +3516,7 @@ class Interpreter(object):
|
|
|
3408
3516
|
defaults = self.get(defaults)
|
|
3409
3517
|
|
|
3410
3518
|
assume_code_const = self.definitions[code][0]
|
|
3411
|
-
if not isinstance(assume_code_const, ir.
|
|
3519
|
+
if not isinstance(assume_code_const, ir.const_types):
|
|
3412
3520
|
msg = (
|
|
3413
3521
|
"Unsupported use of closure. "
|
|
3414
3522
|
"Probably caused by complex control-flow constructs; "
|
|
@@ -3430,7 +3538,7 @@ class Interpreter(object):
|
|
|
3430
3538
|
inst, name, code, closure, annotations, kwdefaults, defaults, res
|
|
3431
3539
|
)
|
|
3432
3540
|
|
|
3433
|
-
if PYVERSION in ((3, 11), (3, 12), (3, 13)):
|
|
3541
|
+
if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
|
|
3434
3542
|
|
|
3435
3543
|
def op_LOAD_CLOSURE(self, inst, res):
|
|
3436
3544
|
name = self.func_id.func.__code__._varname_from_oparg(inst.arg)
|
|
@@ -3504,23 +3612,29 @@ class Interpreter(object):
|
|
|
3504
3612
|
|
|
3505
3613
|
# is last emitted statement a build_tuple?
|
|
3506
3614
|
stmt = self.current_block.body[-1]
|
|
3507
|
-
ok =
|
|
3615
|
+
ok = (
|
|
3616
|
+
isinstance(stmt.value, ir.expr_types)
|
|
3617
|
+
and stmt.value.op == "build_tuple"
|
|
3618
|
+
)
|
|
3508
3619
|
# check statements from self.current_block.body[-1] through to target,
|
|
3509
3620
|
# make sure they are consts
|
|
3510
3621
|
build_empty_list = None
|
|
3511
3622
|
if ok:
|
|
3512
3623
|
for stmt in reversed(self.current_block.body[:-1]):
|
|
3513
|
-
if not isinstance(stmt, ir.
|
|
3624
|
+
if not isinstance(stmt, ir.assign_types):
|
|
3514
3625
|
ok = False
|
|
3515
3626
|
break
|
|
3516
3627
|
# if its not a const, it needs to be the `build_list` for the
|
|
3517
3628
|
# target, else it's something else we don't know about so just
|
|
3518
3629
|
# bail
|
|
3519
|
-
if isinstance(stmt.value, ir.
|
|
3630
|
+
if isinstance(stmt.value, ir.const_types):
|
|
3520
3631
|
continue
|
|
3521
3632
|
|
|
3522
3633
|
# it's not a const, check for target
|
|
3523
|
-
elif
|
|
3634
|
+
elif (
|
|
3635
|
+
isinstance(stmt.value, ir.expr_types)
|
|
3636
|
+
and stmt.target == target
|
|
3637
|
+
):
|
|
3524
3638
|
build_empty_list = stmt
|
|
3525
3639
|
# it's only ok to do this if the target has no initializer
|
|
3526
3640
|
# already
|
|
@@ -3566,9 +3680,16 @@ class Interpreter(object):
|
|
|
3566
3680
|
)
|
|
3567
3681
|
self.store(value=appendinst, name=res)
|
|
3568
3682
|
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
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)
|
|
3572
3693
|
|
|
3573
3694
|
# NOTE: The LOAD_METHOD opcode is implemented as a LOAD_ATTR for ease,
|
|
3574
3695
|
# however this means a new object (the bound-method instance) could be
|
|
@@ -3584,7 +3705,7 @@ class Interpreter(object):
|
|
|
3584
3705
|
def op_CALL_METHOD(self, *args, **kws):
|
|
3585
3706
|
self.op_CALL_FUNCTION(*args, **kws)
|
|
3586
3707
|
|
|
3587
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
3708
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
3588
3709
|
|
|
3589
3710
|
def op_CALL_INTRINSIC_1(self, inst, operand, **kwargs):
|
|
3590
3711
|
if operand == ci1op.INTRINSIC_STOPITERATION_ERROR:
|
|
@@ -3606,8 +3727,61 @@ class Interpreter(object):
|
|
|
3606
3727
|
else:
|
|
3607
3728
|
raise NotImplementedError(PYVERSION)
|
|
3608
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
|
+
|
|
3609
3783
|
|
|
3610
|
-
if PYVERSION in ((3, 12), (3, 13)):
|
|
3784
|
+
if PYVERSION in ((3, 12), (3, 13), (3, 14)):
|
|
3611
3785
|
|
|
3612
3786
|
class INTRINSIC_STOPITERATION_ERROR(AssertionError):
|
|
3613
3787
|
pass
|