summaryrefslogtreecommitdiff
path: root/Objects/codeobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/codeobject.c')
-rw-r--r--Objects/codeobject.c116
1 files changed, 110 insertions, 6 deletions
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index 2f1bef2cd1..0d8a675f9f 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -1,3 +1,5 @@
+#include <stdbool.h>
+
#include "Python.h"
#include "code.h"
#include "structmember.h"
@@ -5,6 +7,12 @@
#define NAME_CHARS \
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
+/* Holder for co_extra information */
+typedef struct {
+ Py_ssize_t ce_size;
+ void **ce_extras;
+} _PyCodeObjectExtra;
+
/* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */
static int
@@ -136,7 +144,7 @@ PyCode_New(int argcount, int kwonlyargcount,
Py_ssize_t total_args = argcount + kwonlyargcount +
((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0);
Py_ssize_t alloc_size = sizeof(unsigned char) * n_cellvars;
- int used_cell2arg = 0;
+ bool used_cell2arg = false;
cell2arg = PyMem_MALLOC(alloc_size);
if (cell2arg == NULL)
return NULL;
@@ -149,7 +157,7 @@ PyCode_New(int argcount, int kwonlyargcount,
PyObject *arg = PyTuple_GET_ITEM(varnames, j);
if (!PyUnicode_Compare(cell, arg)) {
cell2arg[i] = j;
- used_cell2arg = 1;
+ used_cell2arg = true;
break;
}
}
@@ -192,6 +200,7 @@ PyCode_New(int argcount, int kwonlyargcount,
co->co_lnotab = lnotab;
co->co_zombieframe = NULL;
co->co_weakreflist = NULL;
+ co->co_extra = NULL;
return co;
}
@@ -401,6 +410,21 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
static void
code_dealloc(PyCodeObject *co)
{
+ if (co->co_extra != NULL) {
+ PyThreadState *tstate = PyThreadState_Get();
+ _PyCodeObjectExtra *co_extra = co->co_extra;
+
+ for (Py_ssize_t i = 0; i < co_extra->ce_size; i++) {
+ freefunc free_extra = tstate->co_extra_freefuncs[i];
+
+ if (free_extra != NULL) {
+ free_extra(co_extra->ce_extras[i]);
+ }
+ }
+
+ PyMem_FREE(co->co_extra);
+ }
+
Py_XDECREF(co->co_code);
Py_XDECREF(co->co_consts);
Py_XDECREF(co->co_names);
@@ -734,7 +758,8 @@ PyCode_Addr2Line(PyCodeObject *co, int addrq)
addr += *p++;
if (addr > addrq)
break;
- line += *p++;
+ line += (signed char)*p;
+ p++;
}
return line;
}
@@ -769,17 +794,19 @@ _PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
if (addr + *p > lasti)
break;
addr += *p++;
- if (*p)
+ if ((signed char)*p)
bounds->ap_lower = addr;
- line += *p++;
+ line += (signed char)*p;
+ p++;
--size;
}
if (size > 0) {
while (--size >= 0) {
addr += *p++;
- if (*p++)
+ if ((signed char)*p)
break;
+ p++;
}
bounds->ap_upper = addr;
}
@@ -789,3 +816,80 @@ _PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
return line;
}
+
+
+int
+_PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
+{
+ assert(*extra == NULL);
+
+ if (!PyCode_Check(code)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+
+ PyCodeObject *o = (PyCodeObject*) code;
+ _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) o->co_extra;
+
+
+ if (co_extra == NULL || co_extra->ce_size <= index) {
+ return 0;
+ }
+
+ *extra = co_extra->ce_extras[index];
+ return 0;
+}
+
+
+int
+_PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
+{
+ PyThreadState *tstate = PyThreadState_Get();
+
+ if (!PyCode_Check(code) || index < 0 ||
+ index >= tstate->co_extra_user_count) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+
+ PyCodeObject *o = (PyCodeObject*) code;
+ _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra *) o->co_extra;
+
+ if (co_extra == NULL) {
+ o->co_extra = (_PyCodeObjectExtra*) PyMem_Malloc(
+ sizeof(_PyCodeObjectExtra));
+ if (o->co_extra == NULL) {
+ return -1;
+ }
+ co_extra = (_PyCodeObjectExtra *) o->co_extra;
+
+ co_extra->ce_extras = PyMem_Malloc(
+ tstate->co_extra_user_count * sizeof(void*));
+ if (co_extra->ce_extras == NULL) {
+ return -1;
+ }
+
+ co_extra->ce_size = tstate->co_extra_user_count;
+
+ for (Py_ssize_t i = 0; i < co_extra->ce_size; i++) {
+ co_extra->ce_extras[i] = NULL;
+ }
+ }
+ else if (co_extra->ce_size <= index) {
+ co_extra->ce_extras = PyMem_Realloc(
+ co_extra->ce_extras, tstate->co_extra_user_count * sizeof(void*));
+
+ if (co_extra->ce_extras == NULL) {
+ return -1;
+ }
+
+ co_extra->ce_size = tstate->co_extra_user_count;
+
+ for (Py_ssize_t i = co_extra->ce_size; i < co_extra->ce_size; i++) {
+ co_extra->ce_extras[i] = NULL;
+ }
+ }
+
+ co_extra->ce_extras[index] = extra;
+ return 0;
+}