1 #include "Python.h"
2 #include "opcode.h"
3 #include "internal/pycore_code.h"
4 
5 /*[clinic input]
6 module _opcode
7 [clinic start generated code]*/
8 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=117442e66eb376e6]*/
9 
10 #include "clinic/_opcode.c.h"
11 
12 /*[clinic input]
13 
14 _opcode.stack_effect -> int
15 
16   opcode: int
17   oparg: object = None
18   /
19   *
20   jump: object = None
21 
22 Compute the stack effect of the opcode.
23 [clinic start generated code]*/
24 
25 static int
_opcode_stack_effect_impl(PyObject * module,int opcode,PyObject * oparg,PyObject * jump)26 _opcode_stack_effect_impl(PyObject *module, int opcode, PyObject *oparg,
27                           PyObject *jump)
28 /*[clinic end generated code: output=64a18f2ead954dbb input=461c9d4a44851898]*/
29 {
30     int effect;
31     int oparg_int = 0;
32     int jump_int;
33     if (HAS_ARG(opcode)) {
34         if (oparg == Py_None) {
35             PyErr_SetString(PyExc_ValueError,
36                     "stack_effect: opcode requires oparg but oparg was not specified");
37             return -1;
38         }
39         oparg_int = (int)PyLong_AsLong(oparg);
40         if ((oparg_int == -1) && PyErr_Occurred()) {
41             return -1;
42         }
43     }
44     else if (oparg != Py_None) {
45         PyErr_SetString(PyExc_ValueError,
46                 "stack_effect: opcode does not permit oparg but oparg was specified");
47         return -1;
48     }
49     if (jump == Py_None) {
50         jump_int = -1;
51     }
52     else if (jump == Py_True) {
53         jump_int = 1;
54     }
55     else if (jump == Py_False) {
56         jump_int = 0;
57     }
58     else {
59         PyErr_SetString(PyExc_ValueError,
60                 "stack_effect: jump must be False, True or None");
61         return -1;
62     }
63     if (IS_ARTIFICIAL(opcode)) {
64         effect = PY_INVALID_STACK_EFFECT;
65     }
66     else {
67         effect = PyCompile_OpcodeStackEffectWithJump(opcode, oparg_int, jump_int);
68     }
69     if (effect == PY_INVALID_STACK_EFFECT) {
70             PyErr_SetString(PyExc_ValueError,
71                     "invalid opcode or oparg");
72             return -1;
73     }
74     return effect;
75 }
76 
77 /*[clinic input]
78 
79 _opcode.get_specialization_stats
80 
81 Return the specialization stats
82 [clinic start generated code]*/
83 
84 static PyObject *
_opcode_get_specialization_stats_impl(PyObject * module)85 _opcode_get_specialization_stats_impl(PyObject *module)
86 /*[clinic end generated code: output=fcbc32fdfbec5c17 input=e1f60db68d8ce5f6]*/
87 {
88 #ifdef Py_STATS
89     return _Py_GetSpecializationStats();
90 #else
91     Py_RETURN_NONE;
92 #endif
93 }
94 
95 static PyMethodDef
96 opcode_functions[] =  {
97     _OPCODE_STACK_EFFECT_METHODDEF
98     _OPCODE_GET_SPECIALIZATION_STATS_METHODDEF
99     {NULL, NULL, 0, NULL}
100 };
101 
102 static struct PyModuleDef opcodemodule = {
103     PyModuleDef_HEAD_INIT,
104     .m_name = "_opcode",
105     .m_doc = "Opcode support module.",
106     .m_size = 0,
107     .m_methods = opcode_functions
108 };
109 
110 PyMODINIT_FUNC
PyInit__opcode(void)111 PyInit__opcode(void)
112 {
113     return PyModuleDef_Init(&opcodemodule);
114 }
115