mirror of https://github.com/python/cpython
gh-107557: Setup abstract interpretation (#107847)
Co-authored-by: Guido van Rossum <gvanrossum@users.noreply.github.com> Co-authored-by: Jules <57632293+juliapoo@users.noreply.github.com>
This commit is contained in:
parent
34e1917912
commit
e28b0dc86d
|
@ -90,6 +90,7 @@ Programs/test_frozenmain.h generated
|
|||
Python/Python-ast.c generated
|
||||
Python/executor_cases.c.h generated
|
||||
Python/generated_cases.c.h generated
|
||||
Python/abstract_interp_cases.c.h generated
|
||||
Python/opcode_targets.h generated
|
||||
Python/stdlib_module_names.h generated
|
||||
Tools/peg_generator/pegen/grammar_parser.py generated
|
||||
|
|
|
@ -22,7 +22,7 @@ typedef struct _PyExecutorObject {
|
|||
typedef struct _PyOptimizerObject _PyOptimizerObject;
|
||||
|
||||
/* Should return > 0 if a new executor is created. O if no executor is produced and < 0 if an error occurred. */
|
||||
typedef int (*optimize_func)(_PyOptimizerObject* self, PyCodeObject *code, _Py_CODEUNIT *instr, _PyExecutorObject **);
|
||||
typedef int (*optimize_func)(_PyOptimizerObject* self, PyCodeObject *code, _Py_CODEUNIT *instr, _PyExecutorObject **, int curr_stackentries);
|
||||
|
||||
typedef struct _PyOptimizerObject {
|
||||
PyObject_HEAD
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#define _POP_JUMP_IF_FALSE 331
|
||||
#define _POP_JUMP_IF_TRUE 332
|
||||
#define JUMP_TO_TOP 333
|
||||
#define INSERT 334
|
||||
|
||||
extern int _PyOpcode_num_popped(int opcode, int oparg, bool jump);
|
||||
#ifdef NEED_OPCODE_METADATA
|
||||
|
@ -118,18 +119,38 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
|
|||
return 1;
|
||||
case UNARY_INVERT:
|
||||
return 1;
|
||||
case _GUARD_BOTH_INT:
|
||||
return 2;
|
||||
case _BINARY_OP_MULTIPLY_INT:
|
||||
return 2;
|
||||
case _BINARY_OP_ADD_INT:
|
||||
return 2;
|
||||
case _BINARY_OP_SUBTRACT_INT:
|
||||
return 2;
|
||||
case BINARY_OP_MULTIPLY_INT:
|
||||
return 2;
|
||||
case BINARY_OP_ADD_INT:
|
||||
return 2;
|
||||
case BINARY_OP_SUBTRACT_INT:
|
||||
return 2;
|
||||
case _GUARD_BOTH_FLOAT:
|
||||
return 2;
|
||||
case _BINARY_OP_MULTIPLY_FLOAT:
|
||||
return 2;
|
||||
case _BINARY_OP_ADD_FLOAT:
|
||||
return 2;
|
||||
case _BINARY_OP_SUBTRACT_FLOAT:
|
||||
return 2;
|
||||
case BINARY_OP_MULTIPLY_FLOAT:
|
||||
return 2;
|
||||
case BINARY_OP_ADD_FLOAT:
|
||||
return 2;
|
||||
case BINARY_OP_SUBTRACT_FLOAT:
|
||||
return 2;
|
||||
case _GUARD_BOTH_UNICODE:
|
||||
return 2;
|
||||
case _BINARY_OP_ADD_UNICODE:
|
||||
return 2;
|
||||
case BINARY_OP_ADD_UNICODE:
|
||||
return 2;
|
||||
case BINARY_OP_INPLACE_ADD_UNICODE:
|
||||
|
@ -226,14 +247,26 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
|
|||
return 1;
|
||||
case DELETE_GLOBAL:
|
||||
return 0;
|
||||
case _LOAD_LOCALS:
|
||||
return 0;
|
||||
case LOAD_LOCALS:
|
||||
return 0;
|
||||
case _LOAD_FROM_DICT_OR_GLOBALS:
|
||||
return 1;
|
||||
case LOAD_NAME:
|
||||
return 0;
|
||||
case LOAD_FROM_DICT_OR_GLOBALS:
|
||||
return 1;
|
||||
case LOAD_GLOBAL:
|
||||
return 0;
|
||||
case _GUARD_GLOBALS_VERSION:
|
||||
return 0;
|
||||
case _GUARD_BUILTINS_VERSION:
|
||||
return 0;
|
||||
case _LOAD_GLOBAL_MODULE:
|
||||
return 0;
|
||||
case _LOAD_GLOBAL_BUILTINS:
|
||||
return 0;
|
||||
case LOAD_GLOBAL_MODULE:
|
||||
return 0;
|
||||
case LOAD_GLOBAL_BUILTIN:
|
||||
|
@ -294,6 +327,12 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
|
|||
return 1;
|
||||
case LOAD_METHOD:
|
||||
return 1;
|
||||
case _GUARD_TYPE_VERSION:
|
||||
return 1;
|
||||
case _CHECK_MANAGED_OBJECT_HAS_VALUES:
|
||||
return 1;
|
||||
case _LOAD_ATTR_INSTANCE_VALUE:
|
||||
return 1;
|
||||
case LOAD_ATTR_INSTANCE_VALUE:
|
||||
return 1;
|
||||
case LOAD_ATTR_MODULE:
|
||||
|
@ -348,6 +387,8 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
|
|||
return 1;
|
||||
case POP_JUMP_IF_TRUE:
|
||||
return 1;
|
||||
case IS_NONE:
|
||||
return 1;
|
||||
case POP_JUMP_IF_NONE:
|
||||
return 1;
|
||||
case POP_JUMP_IF_NOT_NONE:
|
||||
|
@ -372,10 +413,28 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
|
|||
return 1;
|
||||
case INSTRUMENTED_FOR_ITER:
|
||||
return 0;
|
||||
case _ITER_CHECK_LIST:
|
||||
return 1;
|
||||
case _IS_ITER_EXHAUSTED_LIST:
|
||||
return 1;
|
||||
case _ITER_NEXT_LIST:
|
||||
return 1;
|
||||
case FOR_ITER_LIST:
|
||||
return 1;
|
||||
case _ITER_CHECK_TUPLE:
|
||||
return 1;
|
||||
case _IS_ITER_EXHAUSTED_TUPLE:
|
||||
return 1;
|
||||
case _ITER_NEXT_TUPLE:
|
||||
return 1;
|
||||
case FOR_ITER_TUPLE:
|
||||
return 1;
|
||||
case _ITER_CHECK_RANGE:
|
||||
return 1;
|
||||
case _IS_ITER_EXHAUSTED_RANGE:
|
||||
return 1;
|
||||
case _ITER_NEXT_RANGE:
|
||||
return 1;
|
||||
case FOR_ITER_RANGE:
|
||||
return 1;
|
||||
case FOR_ITER_GEN:
|
||||
|
@ -494,6 +553,18 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
|
|||
return 0;
|
||||
case RESERVED:
|
||||
return 0;
|
||||
case _POP_JUMP_IF_FALSE:
|
||||
return 1;
|
||||
case _POP_JUMP_IF_TRUE:
|
||||
return 1;
|
||||
case JUMP_TO_TOP:
|
||||
return 0;
|
||||
case SAVE_IP:
|
||||
return 0;
|
||||
case EXIT_TRACE:
|
||||
return 0;
|
||||
case INSERT:
|
||||
return oparg + 1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
@ -562,18 +633,38 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
|
|||
return 1;
|
||||
case UNARY_INVERT:
|
||||
return 1;
|
||||
case _GUARD_BOTH_INT:
|
||||
return 2;
|
||||
case _BINARY_OP_MULTIPLY_INT:
|
||||
return 1;
|
||||
case _BINARY_OP_ADD_INT:
|
||||
return 1;
|
||||
case _BINARY_OP_SUBTRACT_INT:
|
||||
return 1;
|
||||
case BINARY_OP_MULTIPLY_INT:
|
||||
return 1;
|
||||
case BINARY_OP_ADD_INT:
|
||||
return 1;
|
||||
case BINARY_OP_SUBTRACT_INT:
|
||||
return 1;
|
||||
case _GUARD_BOTH_FLOAT:
|
||||
return 2;
|
||||
case _BINARY_OP_MULTIPLY_FLOAT:
|
||||
return 1;
|
||||
case _BINARY_OP_ADD_FLOAT:
|
||||
return 1;
|
||||
case _BINARY_OP_SUBTRACT_FLOAT:
|
||||
return 1;
|
||||
case BINARY_OP_MULTIPLY_FLOAT:
|
||||
return 1;
|
||||
case BINARY_OP_ADD_FLOAT:
|
||||
return 1;
|
||||
case BINARY_OP_SUBTRACT_FLOAT:
|
||||
return 1;
|
||||
case _GUARD_BOTH_UNICODE:
|
||||
return 2;
|
||||
case _BINARY_OP_ADD_UNICODE:
|
||||
return 1;
|
||||
case BINARY_OP_ADD_UNICODE:
|
||||
return 1;
|
||||
case BINARY_OP_INPLACE_ADD_UNICODE:
|
||||
|
@ -670,14 +761,26 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
|
|||
return 0;
|
||||
case DELETE_GLOBAL:
|
||||
return 0;
|
||||
case _LOAD_LOCALS:
|
||||
return 1;
|
||||
case LOAD_LOCALS:
|
||||
return 1;
|
||||
case _LOAD_FROM_DICT_OR_GLOBALS:
|
||||
return 1;
|
||||
case LOAD_NAME:
|
||||
return 1;
|
||||
case LOAD_FROM_DICT_OR_GLOBALS:
|
||||
return 1;
|
||||
case LOAD_GLOBAL:
|
||||
return ((oparg & 1) ? 1 : 0) + 1;
|
||||
case _GUARD_GLOBALS_VERSION:
|
||||
return 0;
|
||||
case _GUARD_BUILTINS_VERSION:
|
||||
return 0;
|
||||
case _LOAD_GLOBAL_MODULE:
|
||||
return ((oparg & 1) ? 1 : 0) + 1;
|
||||
case _LOAD_GLOBAL_BUILTINS:
|
||||
return ((oparg & 1) ? 1 : 0) + 1;
|
||||
case LOAD_GLOBAL_MODULE:
|
||||
return (oparg & 1 ? 1 : 0) + 1;
|
||||
case LOAD_GLOBAL_BUILTIN:
|
||||
|
@ -738,6 +841,12 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
|
|||
return ((oparg & 1) ? 1 : 0) + 1;
|
||||
case LOAD_METHOD:
|
||||
return ((oparg & 1) ? 1 : 0) + 1;
|
||||
case _GUARD_TYPE_VERSION:
|
||||
return 1;
|
||||
case _CHECK_MANAGED_OBJECT_HAS_VALUES:
|
||||
return 1;
|
||||
case _LOAD_ATTR_INSTANCE_VALUE:
|
||||
return ((oparg & 1) ? 1 : 0) + 1;
|
||||
case LOAD_ATTR_INSTANCE_VALUE:
|
||||
return (oparg & 1 ? 1 : 0) + 1;
|
||||
case LOAD_ATTR_MODULE:
|
||||
|
@ -792,6 +901,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
|
|||
return 0;
|
||||
case POP_JUMP_IF_TRUE:
|
||||
return 0;
|
||||
case IS_NONE:
|
||||
return 1;
|
||||
case POP_JUMP_IF_NONE:
|
||||
return 0;
|
||||
case POP_JUMP_IF_NOT_NONE:
|
||||
|
@ -816,10 +927,28 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
|
|||
return 2;
|
||||
case INSTRUMENTED_FOR_ITER:
|
||||
return 0;
|
||||
case _ITER_CHECK_LIST:
|
||||
return 1;
|
||||
case _IS_ITER_EXHAUSTED_LIST:
|
||||
return 2;
|
||||
case _ITER_NEXT_LIST:
|
||||
return 2;
|
||||
case FOR_ITER_LIST:
|
||||
return 2;
|
||||
case _ITER_CHECK_TUPLE:
|
||||
return 1;
|
||||
case _IS_ITER_EXHAUSTED_TUPLE:
|
||||
return 2;
|
||||
case _ITER_NEXT_TUPLE:
|
||||
return 2;
|
||||
case FOR_ITER_TUPLE:
|
||||
return 2;
|
||||
case _ITER_CHECK_RANGE:
|
||||
return 1;
|
||||
case _IS_ITER_EXHAUSTED_RANGE:
|
||||
return 2;
|
||||
case _ITER_NEXT_RANGE:
|
||||
return 2;
|
||||
case FOR_ITER_RANGE:
|
||||
return 2;
|
||||
case FOR_ITER_GEN:
|
||||
|
@ -938,6 +1067,18 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
|
|||
return 0;
|
||||
case RESERVED:
|
||||
return 0;
|
||||
case _POP_JUMP_IF_FALSE:
|
||||
return 0;
|
||||
case _POP_JUMP_IF_TRUE:
|
||||
return 0;
|
||||
case JUMP_TO_TOP:
|
||||
return 0;
|
||||
case SAVE_IP:
|
||||
return 0;
|
||||
case EXIT_TRACE:
|
||||
return 0;
|
||||
case INSERT:
|
||||
return oparg + 1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
@ -1393,5 +1534,6 @@ const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE] = {
|
|||
[_POP_JUMP_IF_FALSE] = "_POP_JUMP_IF_FALSE",
|
||||
[_POP_JUMP_IF_TRUE] = "_POP_JUMP_IF_TRUE",
|
||||
[JUMP_TO_TOP] = "JUMP_TO_TOP",
|
||||
[INSERT] = "INSERT",
|
||||
};
|
||||
#endif // NEED_OPCODE_METADATA
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef Py_INTERNAL_OPTIMIZER_H
|
||||
#define Py_INTERNAL_OPTIMIZER_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#include "pycore_uops.h"
|
||||
|
||||
int _Py_uop_analyze_and_optimize(PyCodeObject *code,
|
||||
_PyUOpInstruction *trace, int trace_len, int curr_stackentries);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_OPTIMIZER_H */
|
|
@ -8,7 +8,7 @@ extern "C" {
|
|||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#define _Py_UOP_MAX_TRACE_LENGTH 32
|
||||
#define _Py_UOP_MAX_TRACE_LENGTH 64
|
||||
|
||||
typedef struct {
|
||||
uint32_t opcode;
|
||||
|
|
|
@ -405,6 +405,7 @@ PYTHON_OBJS= \
|
|||
Python/mysnprintf.o \
|
||||
Python/mystrtoul.o \
|
||||
Python/optimizer.o \
|
||||
Python/optimizer_analysis.o \
|
||||
Python/pathconfig.o \
|
||||
Python/preconfig.o \
|
||||
Python/pyarena.o \
|
||||
|
@ -1552,10 +1553,12 @@ regen-cases:
|
|||
-m $(srcdir)/Include/internal/pycore_opcode_metadata.h.new \
|
||||
-e $(srcdir)/Python/executor_cases.c.h.new \
|
||||
-p $(srcdir)/Lib/_opcode_metadata.py.new \
|
||||
-a $(srcdir)/Python/abstract_interp_cases.c.h.new \
|
||||
$(srcdir)/Python/bytecodes.c
|
||||
$(UPDATE_FILE) $(srcdir)/Python/generated_cases.c.h $(srcdir)/Python/generated_cases.c.h.new
|
||||
$(UPDATE_FILE) $(srcdir)/Include/internal/pycore_opcode_metadata.h $(srcdir)/Include/internal/pycore_opcode_metadata.h.new
|
||||
$(UPDATE_FILE) $(srcdir)/Python/executor_cases.c.h $(srcdir)/Python/executor_cases.c.h.new
|
||||
$(UPDATE_FILE) $(srcdir)/Python/abstract_interp_cases.c.h $(srcdir)/Python/abstract_interp_cases.c.h.new
|
||||
$(UPDATE_FILE) $(srcdir)/Lib/_opcode_metadata.py $(srcdir)/Lib/_opcode_metadata.py.new
|
||||
|
||||
Python/compile.o: $(srcdir)/Include/internal/pycore_opcode_metadata.h
|
||||
|
@ -1568,6 +1571,7 @@ Python/ceval.o: \
|
|||
|
||||
Python/executor.o: \
|
||||
$(srcdir)/Include/internal/pycore_opcode_metadata.h \
|
||||
$(srcdir)/Include/internal/pycore_optimizer.h \
|
||||
$(srcdir)/Python/ceval_macros.h \
|
||||
$(srcdir)/Python/executor_cases.c.h
|
||||
|
||||
|
@ -1576,7 +1580,12 @@ Python/flowgraph.o: \
|
|||
|
||||
Python/optimizer.o: \
|
||||
$(srcdir)/Python/executor_cases.c.h \
|
||||
$(srcdir)/Include/internal/pycore_opcode_metadata.h
|
||||
$(srcdir)/Include/internal/pycore_opcode_metadata.h \
|
||||
$(srcdir)/Include/internal/pycore_optimizer.h
|
||||
|
||||
Python/optimizer_analysis.o: \
|
||||
$(srcdir)/Include/internal/pycore_opcode_metadata.h \
|
||||
$(srcdir)/Include/internal/pycore_optimizer.h
|
||||
|
||||
Python/frozen.o: $(FROZEN_FILES_OUT)
|
||||
|
||||
|
@ -1786,6 +1795,7 @@ PYTHON_HEADERS= \
|
|||
$(srcdir)/Include/internal/pycore_obmalloc_init.h \
|
||||
$(srcdir)/Include/internal/pycore_opcode.h \
|
||||
$(srcdir)/Include/internal/pycore_opcode_utils.h \
|
||||
$(srcdir)/Include/internal/pycore_optimizer.h \
|
||||
$(srcdir)/Include/internal/pycore_pathconfig.h \
|
||||
$(srcdir)/Include/internal/pycore_pyarena.h \
|
||||
$(srcdir)/Include/internal/pycore_pyerrors.h \
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Generate the cases needed for the barebones tier 2 abstract interpreter for optimization passes in CPython.
|
|
@ -218,6 +218,7 @@
|
|||
<ClCompile Include="..\Python\mysnprintf.c" />
|
||||
<ClCompile Include="..\Python\mystrtoul.c" />
|
||||
<ClCompile Include="..\Python\optimizer.c" />
|
||||
<ClCompile Include="..\Python\optimizer_analysis.c" />
|
||||
<ClCompile Include="..\Python\pathconfig.c" />
|
||||
<ClCompile Include="..\Python\perf_trampoline.c" />
|
||||
<ClCompile Include="..\Python\preconfig.c" />
|
||||
|
|
|
@ -283,6 +283,9 @@
|
|||
<ClCompile Include="..\Python\optimizer.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Python\optimizer_analysis.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Parser\parser.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
@ -248,6 +248,7 @@
|
|||
<ClInclude Include="..\Include\internal\pycore_object_state.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_obmalloc.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_obmalloc_init.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_optimizer.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_pathconfig.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_pyarena.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_pyerrors.h" />
|
||||
|
@ -279,6 +280,7 @@
|
|||
<ClInclude Include="..\Include\internal\pycore_unionobject.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_unicodeobject.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_unicodeobject_generated.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_uops.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_warnings.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_weakref.h" />
|
||||
<ClInclude Include="..\Include\interpreteridobject.h" />
|
||||
|
@ -548,6 +550,7 @@
|
|||
<ClCompile Include="..\Python\mysnprintf.c" />
|
||||
<ClCompile Include="..\Python\mystrtoul.c" />
|
||||
<ClCompile Include="..\Python\optimizer.c" />
|
||||
<ClCompile Include="..\Python\optimizer_analysis.c" />
|
||||
<ClCompile Include="..\Python\pathconfig.c" />
|
||||
<ClCompile Include="..\Python\perf_trampoline.c" />
|
||||
<ClCompile Include="..\Python\preconfig.c" />
|
||||
|
|
|
@ -648,6 +648,9 @@
|
|||
<ClInclude Include="..\Include\internal\pycore_obmalloc_init.h">
|
||||
<Filter>Include\internal</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\internal\pycore_optimizer.h">
|
||||
<Filter>Include\internal</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\internal\pycore_pathconfig.h">
|
||||
<Filter>Include\internal</Filter>
|
||||
</ClInclude>
|
||||
|
@ -732,6 +735,9 @@
|
|||
<ClInclude Include="..\Include\internal\pycore_unionobject.h">
|
||||
<Filter>Include\internal</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\internal\pycore_uops.h">
|
||||
<Filter>Include\internal</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(zlibDir)\crc32.h">
|
||||
<Filter>Modules\zlib</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1223,6 +1229,9 @@
|
|||
<ClCompile Include="..\Python\optimizer.c">
|
||||
<Filter>Python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Python\optimizer_analysis.c">
|
||||
<Filter>Python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Python\pathconfig.c">
|
||||
<Filter>Python</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
@ -0,0 +1,761 @@
|
|||
// This file is generated by Tools/cases_generator/generate_cases.py
|
||||
// from:
|
||||
// Python/bytecodes.c
|
||||
// Do not edit!
|
||||
|
||||
case NOP: {
|
||||
break;
|
||||
}
|
||||
|
||||
case POP_TOP: {
|
||||
STACK_SHRINK(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case PUSH_NULL: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case END_SEND: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case UNARY_NEGATIVE: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case UNARY_NOT: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case TO_BOOL: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case TO_BOOL_BOOL: {
|
||||
break;
|
||||
}
|
||||
|
||||
case TO_BOOL_INT: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case TO_BOOL_LIST: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case TO_BOOL_NONE: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case TO_BOOL_STR: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case TO_BOOL_ALWAYS_TRUE: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case UNARY_INVERT: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case _GUARD_BOTH_INT: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _GUARD_BOTH_FLOAT: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _BINARY_OP_MULTIPLY_FLOAT: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case _BINARY_OP_ADD_FLOAT: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case _BINARY_OP_SUBTRACT_FLOAT: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case _GUARD_BOTH_UNICODE: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _BINARY_OP_ADD_UNICODE: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case BINARY_SUBSCR: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case BINARY_SLICE: {
|
||||
STACK_SHRINK(2);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case STORE_SLICE: {
|
||||
STACK_SHRINK(4);
|
||||
break;
|
||||
}
|
||||
|
||||
case BINARY_SUBSCR_LIST_INT: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case BINARY_SUBSCR_STR_INT: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case BINARY_SUBSCR_TUPLE_INT: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case BINARY_SUBSCR_DICT: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case LIST_APPEND: {
|
||||
STACK_SHRINK(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case SET_ADD: {
|
||||
STACK_SHRINK(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case STORE_SUBSCR: {
|
||||
STACK_SHRINK(3);
|
||||
break;
|
||||
}
|
||||
|
||||
case STORE_SUBSCR_LIST_INT: {
|
||||
STACK_SHRINK(3);
|
||||
break;
|
||||
}
|
||||
|
||||
case STORE_SUBSCR_DICT: {
|
||||
STACK_SHRINK(3);
|
||||
break;
|
||||
}
|
||||
|
||||
case DELETE_SUBSCR: {
|
||||
STACK_SHRINK(2);
|
||||
break;
|
||||
}
|
||||
|
||||
case CALL_INTRINSIC_1: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case CALL_INTRINSIC_2: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case GET_AITER: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case GET_ANEXT: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case GET_AWAITABLE: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case POP_EXCEPT: {
|
||||
STACK_SHRINK(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case LOAD_ASSERTION_ERROR: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case LOAD_BUILD_CLASS: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case STORE_NAME: {
|
||||
STACK_SHRINK(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case DELETE_NAME: {
|
||||
break;
|
||||
}
|
||||
|
||||
case UNPACK_SEQUENCE: {
|
||||
STACK_SHRINK(1);
|
||||
STACK_GROW(oparg);
|
||||
break;
|
||||
}
|
||||
|
||||
case UNPACK_SEQUENCE_TWO_TUPLE: {
|
||||
STACK_SHRINK(1);
|
||||
STACK_GROW(oparg);
|
||||
break;
|
||||
}
|
||||
|
||||
case UNPACK_SEQUENCE_TUPLE: {
|
||||
STACK_SHRINK(1);
|
||||
STACK_GROW(oparg);
|
||||
break;
|
||||
}
|
||||
|
||||
case UNPACK_SEQUENCE_LIST: {
|
||||
STACK_SHRINK(1);
|
||||
STACK_GROW(oparg);
|
||||
break;
|
||||
}
|
||||
|
||||
case UNPACK_EX: {
|
||||
STACK_GROW((oparg & 0xFF) + (oparg >> 8));
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg >> 8))), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case STORE_ATTR: {
|
||||
STACK_SHRINK(2);
|
||||
break;
|
||||
}
|
||||
|
||||
case DELETE_ATTR: {
|
||||
STACK_SHRINK(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case STORE_GLOBAL: {
|
||||
STACK_SHRINK(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case DELETE_GLOBAL: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _LOAD_LOCALS: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case _LOAD_FROM_DICT_OR_GLOBALS: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case LOAD_GLOBAL: {
|
||||
STACK_GROW(1);
|
||||
STACK_GROW(((oparg & 1) ? 1 : 0));
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case _GUARD_GLOBALS_VERSION: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _GUARD_BUILTINS_VERSION: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _LOAD_GLOBAL_MODULE: {
|
||||
STACK_GROW(1);
|
||||
STACK_GROW(((oparg & 1) ? 1 : 0));
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case _LOAD_GLOBAL_BUILTINS: {
|
||||
STACK_GROW(1);
|
||||
STACK_GROW(((oparg & 1) ? 1 : 0));
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case DELETE_FAST: {
|
||||
break;
|
||||
}
|
||||
|
||||
case DELETE_DEREF: {
|
||||
break;
|
||||
}
|
||||
|
||||
case LOAD_FROM_DICT_OR_DEREF: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case LOAD_DEREF: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case STORE_DEREF: {
|
||||
STACK_SHRINK(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case COPY_FREE_VARS: {
|
||||
break;
|
||||
}
|
||||
|
||||
case BUILD_STRING: {
|
||||
STACK_SHRINK(oparg);
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case BUILD_TUPLE: {
|
||||
STACK_SHRINK(oparg);
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case BUILD_LIST: {
|
||||
STACK_SHRINK(oparg);
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case LIST_EXTEND: {
|
||||
STACK_SHRINK(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case SET_UPDATE: {
|
||||
STACK_SHRINK(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case BUILD_SET: {
|
||||
STACK_SHRINK(oparg);
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case BUILD_MAP: {
|
||||
STACK_SHRINK(oparg*2);
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case SETUP_ANNOTATIONS: {
|
||||
break;
|
||||
}
|
||||
|
||||
case BUILD_CONST_KEY_MAP: {
|
||||
STACK_SHRINK(oparg);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case DICT_UPDATE: {
|
||||
STACK_SHRINK(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case DICT_MERGE: {
|
||||
STACK_SHRINK(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case MAP_ADD: {
|
||||
STACK_SHRINK(2);
|
||||
break;
|
||||
}
|
||||
|
||||
case LOAD_SUPER_ATTR_ATTR: {
|
||||
STACK_SHRINK(2);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(0)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case LOAD_SUPER_ATTR_METHOD: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-2)), true);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case LOAD_ATTR: {
|
||||
STACK_GROW(((oparg & 1) ? 1 : 0));
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case _GUARD_TYPE_VERSION: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _CHECK_MANAGED_OBJECT_HAS_VALUES: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _LOAD_ATTR_INSTANCE_VALUE: {
|
||||
STACK_GROW(((oparg & 1) ? 1 : 0));
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case COMPARE_OP: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case COMPARE_OP_FLOAT: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case COMPARE_OP_INT: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case COMPARE_OP_STR: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case IS_OP: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case CONTAINS_OP: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case CHECK_EG_MATCH: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-2)), true);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case CHECK_EXC_MATCH: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case IS_NONE: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case GET_LEN: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case MATCH_CLASS: {
|
||||
STACK_SHRINK(2);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case MATCH_MAPPING: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case MATCH_SEQUENCE: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case MATCH_KEYS: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case GET_ITER: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case GET_YIELD_FROM_ITER: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case _ITER_CHECK_LIST: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _IS_ITER_EXHAUSTED_LIST: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case _ITER_NEXT_LIST: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case _ITER_CHECK_TUPLE: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _IS_ITER_EXHAUSTED_TUPLE: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case _ITER_NEXT_TUPLE: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case _ITER_CHECK_RANGE: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _IS_ITER_EXHAUSTED_RANGE: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case _ITER_NEXT_RANGE: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case WITH_EXCEPT_START: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case PUSH_EXC_INFO: {
|
||||
STACK_GROW(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-2)), true);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case CALL_NO_KW_TYPE_1: {
|
||||
STACK_SHRINK(oparg);
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case CALL_NO_KW_STR_1: {
|
||||
STACK_SHRINK(oparg);
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case CALL_NO_KW_TUPLE_1: {
|
||||
STACK_SHRINK(oparg);
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case EXIT_INIT_CHECK: {
|
||||
STACK_SHRINK(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case CALL_NO_KW_BUILTIN_O: {
|
||||
STACK_SHRINK(oparg);
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case CALL_NO_KW_BUILTIN_FAST: {
|
||||
STACK_SHRINK(oparg);
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case CALL_NO_KW_LEN: {
|
||||
STACK_SHRINK(oparg);
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case CALL_NO_KW_ISINSTANCE: {
|
||||
STACK_SHRINK(oparg);
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case CALL_NO_KW_METHOD_DESCRIPTOR_O: {
|
||||
STACK_SHRINK(oparg);
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS: {
|
||||
STACK_SHRINK(oparg);
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case CALL_NO_KW_METHOD_DESCRIPTOR_FAST: {
|
||||
STACK_SHRINK(oparg);
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case MAKE_FUNCTION: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case SET_FUNCTION_ATTRIBUTE: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case BUILD_SLICE: {
|
||||
STACK_SHRINK(((oparg == 3) ? 1 : 0));
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case CONVERT_VALUE: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case FORMAT_SIMPLE: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case FORMAT_WITH_SPEC: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case BINARY_OP: {
|
||||
STACK_SHRINK(1);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case SWAP: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-2 - (oparg-2))), true);
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
|
||||
break;
|
||||
}
|
||||
|
||||
case _POP_JUMP_IF_FALSE: {
|
||||
STACK_SHRINK(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case _POP_JUMP_IF_TRUE: {
|
||||
STACK_SHRINK(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case JUMP_TO_TOP: {
|
||||
break;
|
||||
}
|
||||
|
||||
case SAVE_IP: {
|
||||
break;
|
||||
}
|
||||
|
||||
case EXIT_TRACE: {
|
||||
break;
|
||||
}
|
||||
|
||||
case INSERT: {
|
||||
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - oparg)), true);
|
||||
break;
|
||||
}
|
|
@ -3743,6 +3743,11 @@ dummy_func(
|
|||
return frame;
|
||||
}
|
||||
|
||||
op(INSERT, (unused[oparg], top -- top, unused[oparg])) {
|
||||
// Inserts TOS at position specified by oparg;
|
||||
memmove(&stack_pointer[-1 - oparg], &stack_pointer[-oparg], oparg * sizeof(stack_pointer[0]));
|
||||
}
|
||||
|
||||
|
||||
// END BYTECODES //
|
||||
|
||||
|
|
|
@ -2733,3 +2733,12 @@
|
|||
return frame;
|
||||
break;
|
||||
}
|
||||
|
||||
case INSERT: {
|
||||
PyObject *top;
|
||||
top = stack_pointer[-1];
|
||||
// Inserts TOS at position specified by oparg;
|
||||
memmove(&stack_pointer[-1 - oparg], &stack_pointer[-oparg], oparg * sizeof(stack_pointer[0]));
|
||||
stack_pointer[-1 - oparg] = top;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "pycore_opcode.h"
|
||||
#include "pycore_opcode_metadata.h"
|
||||
#include "pycore_opcode_utils.h"
|
||||
#include "pycore_optimizer.h"
|
||||
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
||||
#include "pycore_uops.h"
|
||||
#include "cpython/optimizer.h"
|
||||
|
@ -103,7 +104,8 @@ error_optimize(
|
|||
_PyOptimizerObject* self,
|
||||
PyCodeObject *code,
|
||||
_Py_CODEUNIT *instr,
|
||||
_PyExecutorObject **exec)
|
||||
_PyExecutorObject **exec,
|
||||
int Py_UNUSED(stack_entries))
|
||||
{
|
||||
PyErr_Format(PyExc_SystemError, "Should never call error_optimize");
|
||||
return -1;
|
||||
|
@ -164,7 +166,7 @@ _PyOptimizer_BackEdge(_PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNI
|
|||
}
|
||||
_PyOptimizerObject *opt = interp->optimizer;
|
||||
_PyExecutorObject *executor = NULL;
|
||||
int err = opt->optimize(opt, code, dest, &executor);
|
||||
int err = opt->optimize(opt, code, dest, &executor, (int)(stack_pointer - _PyFrame_Stackbase(frame)));
|
||||
if (err <= 0) {
|
||||
assert(executor == NULL);
|
||||
if (err < 0) {
|
||||
|
@ -254,7 +256,9 @@ counter_optimize(
|
|||
_PyOptimizerObject* self,
|
||||
PyCodeObject *code,
|
||||
_Py_CODEUNIT *instr,
|
||||
_PyExecutorObject **exec_ptr)
|
||||
_PyExecutorObject **exec_ptr,
|
||||
int Py_UNUSED(curr_stackentries)
|
||||
)
|
||||
{
|
||||
_PyCounterExecutorObject *executor = (_PyCounterExecutorObject *)_PyObject_New(&CounterExecutor_Type);
|
||||
if (executor == NULL) {
|
||||
|
@ -684,7 +688,8 @@ uop_optimize(
|
|||
_PyOptimizerObject *self,
|
||||
PyCodeObject *code,
|
||||
_Py_CODEUNIT *instr,
|
||||
_PyExecutorObject **exec_ptr)
|
||||
_PyExecutorObject **exec_ptr,
|
||||
int curr_stackentries)
|
||||
{
|
||||
_PyUOpInstruction trace[_Py_UOP_MAX_TRACE_LENGTH];
|
||||
int trace_length = translate_bytecode_to_trace(code, instr, trace, _Py_UOP_MAX_TRACE_LENGTH);
|
||||
|
@ -693,6 +698,10 @@ uop_optimize(
|
|||
return trace_length;
|
||||
}
|
||||
OBJECT_STAT_INC(optimization_traces_created);
|
||||
char *uop_optimize = Py_GETENV("PYTHONUOPSOPTIMIZE");
|
||||
if (uop_optimize != NULL && *uop_optimize > '0') {
|
||||
trace_length = _Py_uop_analyze_and_optimize(code, trace, trace_length, curr_stackentries);
|
||||
}
|
||||
_PyUOpExecutorObject *executor = PyObject_NewVar(_PyUOpExecutorObject, &UOpExecutor_Type, trace_length);
|
||||
if (executor == NULL) {
|
||||
return -1;
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#include "Python.h"
|
||||
#include "opcode.h"
|
||||
#include "pycore_interp.h"
|
||||
#include "pycore_opcode.h"
|
||||
#include "pycore_opcode_metadata.h"
|
||||
#include "pycore_opcode_utils.h"
|
||||
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
||||
#include "pycore_uops.h"
|
||||
#include "pycore_long.h"
|
||||
#include "cpython/optimizer.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "pycore_optimizer.h"
|
||||
|
||||
|
||||
int
|
||||
_Py_uop_analyze_and_optimize(
|
||||
PyCodeObject *co,
|
||||
_PyUOpInstruction *trace,
|
||||
int trace_len,
|
||||
int curr_stacklen
|
||||
)
|
||||
{
|
||||
return trace_len;
|
||||
}
|
|
@ -84,6 +84,7 @@ Python/deepfreeze/*.c
|
|||
Python/frozen_modules/*.h
|
||||
Python/generated_cases.c.h
|
||||
Python/executor_cases.c.h
|
||||
Python/abstract_interp_cases.c.h
|
||||
|
||||
# not actually source
|
||||
Python/bytecodes.c
|
||||
|
|
|
@ -716,3 +716,5 @@ Modules/expat/xmlrole.c - error -
|
|||
## other
|
||||
Modules/_io/_iomodule.c - _PyIO_Module -
|
||||
Modules/_sqlite/module.c - _sqlite3module -
|
||||
Python/optimizer_analysis.c - _Py_PartitionRootNode_Type -
|
||||
Python/optimizer_analysis.c - _Py_UOpsAbstractInterpContext_Type -
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 4.
|
|
@ -16,6 +16,7 @@ from formatting import Formatter, list_effect_size
|
|||
from flags import InstructionFlags, variable_used
|
||||
from instructions import (
|
||||
AnyInstruction,
|
||||
AbstractInstruction,
|
||||
Component,
|
||||
Instruction,
|
||||
MacroInstruction,
|
||||
|
@ -44,6 +45,9 @@ DEFAULT_PYMETADATA_OUTPUT = os.path.relpath(
|
|||
DEFAULT_EXECUTOR_OUTPUT = os.path.relpath(
|
||||
os.path.join(ROOT, "Python/executor_cases.c.h")
|
||||
)
|
||||
DEFAULT_ABSTRACT_INTERPRETER_OUTPUT = os.path.relpath(
|
||||
os.path.join(ROOT, "Python/abstract_interp_cases.c.h")
|
||||
)
|
||||
|
||||
# Constants used instead of size for macro expansions.
|
||||
# Note: 1, 2, 4 must match actual cache entry sizes.
|
||||
|
@ -58,6 +62,23 @@ OPARG_SIZES = {
|
|||
|
||||
INSTR_FMT_PREFIX = "INSTR_FMT_"
|
||||
|
||||
# TODO: generate all these after updating the DSL
|
||||
SPECIALLY_HANDLED_ABSTRACT_INSTR = {
|
||||
"LOAD_FAST",
|
||||
"LOAD_FAST_CHECK",
|
||||
"LOAD_FAST_AND_CLEAR",
|
||||
"LOAD_CONST",
|
||||
"STORE_FAST",
|
||||
"STORE_FAST_MAYBE_NULL",
|
||||
"COPY",
|
||||
|
||||
# Arithmetic
|
||||
"_BINARY_OP_MULTIPLY_INT",
|
||||
"_BINARY_OP_ADD_INT",
|
||||
"_BINARY_OP_SUBTRACT_INT",
|
||||
|
||||
}
|
||||
|
||||
arg_parser = argparse.ArgumentParser(
|
||||
description="Generate the code for the interpreter switch.",
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
|
@ -92,7 +113,13 @@ arg_parser.add_argument(
|
|||
help="Write executor cases to this file",
|
||||
default=DEFAULT_EXECUTOR_OUTPUT,
|
||||
)
|
||||
|
||||
arg_parser.add_argument(
|
||||
"-a",
|
||||
"--abstract-interpreter-cases",
|
||||
type=str,
|
||||
help="Write abstract interpreter cases to this file",
|
||||
default=DEFAULT_ABSTRACT_INTERPRETER_OUTPUT,
|
||||
)
|
||||
|
||||
class Generator(Analyzer):
|
||||
def get_stack_effect_info(
|
||||
|
@ -109,7 +136,7 @@ class Generator(Analyzer):
|
|||
pushed: str | None
|
||||
match thing:
|
||||
case parsing.InstDef():
|
||||
if thing.kind != "op":
|
||||
if thing.kind != "op" or self.instrs[thing.name].is_viable_uop():
|
||||
instr = self.instrs[thing.name]
|
||||
popped = effect_str(instr.input_effects)
|
||||
pushed = effect_str(instr.output_effects)
|
||||
|
@ -588,6 +615,35 @@ class Generator(Analyzer):
|
|||
file=sys.stderr,
|
||||
)
|
||||
|
||||
def write_abstract_interpreter_instructions(
|
||||
self, abstract_interpreter_filename: str, emit_line_directives: bool
|
||||
) -> None:
|
||||
"""Generate cases for the Tier 2 abstract interpreter/analzyer."""
|
||||
with open(abstract_interpreter_filename, "w") as f:
|
||||
self.out = Formatter(f, 8, emit_line_directives)
|
||||
self.write_provenance_header()
|
||||
for thing in self.everything:
|
||||
match thing:
|
||||
case OverriddenInstructionPlaceHolder():
|
||||
pass
|
||||
case parsing.InstDef():
|
||||
instr = AbstractInstruction(self.instrs[thing.name].inst)
|
||||
if instr.is_viable_uop() and instr.name not in SPECIALLY_HANDLED_ABSTRACT_INSTR:
|
||||
self.out.emit("")
|
||||
with self.out.block(f"case {thing.name}:"):
|
||||
instr.write(self.out, tier=TIER_TWO)
|
||||
self.out.emit("break;")
|
||||
case parsing.Macro():
|
||||
pass
|
||||
case parsing.Pseudo():
|
||||
pass
|
||||
case _:
|
||||
typing.assert_never(thing)
|
||||
print(
|
||||
f"Wrote some stuff to {abstract_interpreter_filename}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
def write_overridden_instr_place_holder(
|
||||
self, place_holder: OverriddenInstructionPlaceHolder
|
||||
) -> None:
|
||||
|
@ -629,6 +685,8 @@ def main():
|
|||
a.write_instructions(args.output, args.emit_line_directives)
|
||||
a.write_metadata(args.metadata, args.pymetadata)
|
||||
a.write_executor_instructions(args.executor_cases, args.emit_line_directives)
|
||||
a.write_abstract_interpreter_instructions(args.abstract_interpreter_cases,
|
||||
args.emit_line_directives)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -248,6 +248,25 @@ class Instruction:
|
|||
InstructionOrCacheEffect = Instruction | parsing.CacheEffect
|
||||
|
||||
|
||||
# Instruction used for abstract interpretation.
|
||||
class AbstractInstruction(Instruction):
|
||||
def __init__(self, inst: parsing.InstDef):
|
||||
super().__init__(inst)
|
||||
|
||||
def write(self, out: Formatter, tier: Tiers = TIER_ONE) -> None:
|
||||
"""Write one abstract instruction, sans prologue and epilogue."""
|
||||
stacking.write_single_instr_for_abstract_interp(self, out)
|
||||
|
||||
def write_body(
|
||||
self,
|
||||
out: Formatter,
|
||||
dedent: int,
|
||||
active_caches: list[ActiveCacheEffect],
|
||||
tier: Tiers = TIER_ONE,
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Component:
|
||||
instr: Instruction
|
||||
|
|
|
@ -391,3 +391,32 @@ def write_components(
|
|||
poke.as_stack_effect(),
|
||||
poke.effect,
|
||||
)
|
||||
|
||||
|
||||
def write_single_instr_for_abstract_interp(
|
||||
instr: Instruction, out: Formatter
|
||||
):
|
||||
try:
|
||||
_write_components_for_abstract_interp(
|
||||
[Component(instr, instr.active_caches)],
|
||||
out,
|
||||
)
|
||||
except AssertionError as err:
|
||||
raise AssertionError(f"Error writing abstract instruction {instr.name}") from err
|
||||
|
||||
|
||||
def _write_components_for_abstract_interp(
|
||||
parts: list[Component],
|
||||
out: Formatter,
|
||||
):
|
||||
managers = get_managers(parts)
|
||||
for mgr in managers:
|
||||
if mgr is managers[-1]:
|
||||
out.stack_adjust(mgr.final_offset.deep, mgr.final_offset.high)
|
||||
# Use clone() since adjust_inverse() mutates final_offset
|
||||
mgr.adjust_inverse(mgr.final_offset.clone())
|
||||
# NULL out the output stack effects
|
||||
for poke in mgr.pokes:
|
||||
if not poke.effect.size and poke.effect.name not in mgr.instr.unmoved_names:
|
||||
out.emit(f"PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)"
|
||||
f"PARTITIONNODE_NULLROOT, PEEK(-({poke.offset.as_index()})), true);")
|
||||
|
|
Loading…
Reference in New Issue