diff options
author | Larry Hastings <larry@hastings.org> | 2013-11-23 22:49:22 (GMT) |
---|---|---|
committer | Larry Hastings <larry@hastings.org> | 2013-11-23 22:49:22 (GMT) |
commit | 3a9079742f2d71e6968823e155f3778473113538 (patch) | |
tree | 742dd59d633f184a06858baec56ab83c20192e59 /Modules | |
parent | 8d0d369067462080f5ea9d50416a12bee0ef3a6a (diff) | |
download | cpython-3a9079742f2d71e6968823e155f3778473113538.zip cpython-3a9079742f2d71e6968823e155f3778473113538.tar.gz cpython-3a9079742f2d71e6968823e155f3778473113538.tar.bz2 |
Issue #19722: Added opcode.stack_effect(), which accurately
computes the stack effect of bytecode instructions.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_opcode.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/Modules/_opcode.c b/Modules/_opcode.c new file mode 100644 index 0000000..c53f0e0 --- /dev/null +++ b/Modules/_opcode.c @@ -0,0 +1,116 @@ +#include "Python.h" +#include "opcode.h" + + +/*[clinic] + +module _opcode + +_opcode.stack_effect -> int + + opcode: int + + [ + oparg: int + ] + / + +Compute the stack effect of the opcode. +[clinic]*/ + +PyDoc_STRVAR(_opcode_stack_effect__doc__, +"Compute the stack effect of the opcode.\n" +"\n" +"_opcode.stack_effect(opcode, [oparg])"); + +#define _OPCODE_STACK_EFFECT_METHODDEF \ + {"stack_effect", (PyCFunction)_opcode_stack_effect, METH_VARARGS, _opcode_stack_effect__doc__}, + +static int +_opcode_stack_effect_impl(PyObject *module, int opcode, int group_right_1, int oparg); + +static PyObject * +_opcode_stack_effect(PyObject *module, PyObject *args) +{ + PyObject *return_value = NULL; + int opcode; + int group_right_1 = 0; + int oparg = 0; + int _return_value; + + switch (PyTuple_Size(args)) { + case 1: + if (!PyArg_ParseTuple(args, "i:stack_effect", &opcode)) + return NULL; + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:stack_effect", &opcode, &oparg)) + return NULL; + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_opcode.stack_effect requires 1 to 2 arguments"); + return NULL; + } + _return_value = _opcode_stack_effect_impl(module, opcode, group_right_1, oparg); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +_opcode_stack_effect_impl(PyObject *module, int opcode, int group_right_1, int oparg) +/*[clinic checksum: 2312ded40abc9bcbce718942de21f53e61a2dfd3]*/ +{ + int effect; + if (HAS_ARG(opcode)) { + if (!group_right_1) { + PyErr_SetString(PyExc_ValueError, + "stack_effect: opcode requires oparg but oparg was not specified"); + return -1; + } + } + else if (group_right_1) { + PyErr_SetString(PyExc_ValueError, + "stack_effect: opcode does not permit oparg but oparg was specified"); + return -1; + } + effect = PyCompile_OpcodeStackEffect(opcode, oparg); + if (effect == PY_INVALID_STACK_EFFECT) { + PyErr_SetString(PyExc_ValueError, + "invalid opcode or oparg"); + return -1; + } + return effect; +} + + + + +static PyMethodDef +opcode_functions[] = { + _OPCODE_STACK_EFFECT_METHODDEF + {NULL, NULL, 0, NULL} +}; + + +static struct PyModuleDef opcodemodule = { + PyModuleDef_HEAD_INIT, + "_opcode", + "Opcode support module.", + -1, + opcode_functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__opcode(void) +{ + return PyModule_Create(&opcodemodule); +} |