+139
-3
lines changedFilter options
+139
-3
lines changed Original file line number Diff line number Diff line change
@@ -127,7 +127,8 @@ evaluation, etc.
127
127
128
128
This API is not part of the limited C API and is marked as private to
129
129
signal that usage of this API is expected to be limited and only
130
-
applicable to very select, low-level use-cases.
130
+
applicable to very select, low-level use-cases. Semantics of the
131
+
API will change with Python as necessary.
131
132
132
133
.. seealso::
133
134
Original file line number Diff line number Diff line change
@@ -187,6 +187,10 @@ PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds);
187
187
PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void);
188
188
#endif
189
189
190
+
#ifndef Py_LIMITED_API
191
+
PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc);
192
+
#endif
193
+
190
194
#define Py_BEGIN_ALLOW_THREADS { \
191
195
PyThreadState *_save; \
192
196
_save = PyEval_SaveThread();
Original file line number Diff line number Diff line change
@@ -7,6 +7,14 @@
7
7
extern "C" {
8
8
#endif
9
9
10
+
11
+
/* Holder for co_extra information */
12
+
typedef struct {
13
+
Py_ssize_t ce_size;
14
+
void **ce_extras;
15
+
} _PyCodeObjectExtra;
16
+
17
+
10
18
/* Bytecode object */
11
19
typedef struct {
12
20
PyObject_HEAD
@@ -15,6 +23,7 @@ typedef struct {
15
23
int co_nlocals; /* #local variables */
16
24
int co_stacksize; /* #entries needed for evaluation stack */
17
25
int co_flags; /* CO_..., see below */
26
+
int co_firstlineno; /* first source line number */
18
27
PyObject *co_code; /* instruction opcodes */
19
28
PyObject *co_consts; /* list (constants used) */
20
29
PyObject *co_names; /* list of strings (names used) */
@@ -30,11 +39,12 @@ typedef struct {
30
39
unsigned char *co_cell2arg; /* Maps cell vars which are arguments. */
31
40
PyObject *co_filename; /* unicode (where it was loaded from) */
32
41
PyObject *co_name; /* unicode (name, for reference) */
33
-
int co_firstlineno; /* first source line number */
34
42
PyObject *co_lnotab; /* string (encoding addr<->lineno mapping) See
35
43
Objects/lnotab_notes.txt for details. */
36
44
void *co_zombieframe; /* for optimization only (see frameobject.c) */
37
45
PyObject *co_weakreflist; /* to support weakrefs to code objects */
46
+
/* Scratch space for extra data relating to the code object */
47
+
_PyCodeObjectExtra *co_extra;
38
48
} PyCodeObject;
39
49
40
50
/* Masks for co_flags above */
@@ -128,6 +138,14 @@ PyAPI_FUNC(PyObject*) _PyCode_ConstantKey(PyObject *obj);
128
138
PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts,
129
139
PyObject *names, PyObject *lnotab);
130
140
141
+
142
+
#ifndef Py_LIMITED_API
143
+
PyAPI_FUNC(int) _PyCode_GetExtra(PyObject *code, Py_ssize_t index,
144
+
void **extra);
145
+
PyAPI_FUNC(int) _PyCode_SetExtra(PyObject *code, Py_ssize_t index,
146
+
void *extra);
147
+
#endif
148
+
131
149
#ifdef __cplusplus
132
150
}
133
151
#endif
Original file line number Diff line number Diff line change
@@ -8,6 +8,10 @@
8
8
extern "C" {
9
9
#endif
10
10
11
+
/* This limitation is for performance and simplicity. If needed it can be
12
+
removed (with effort). */
13
+
#define MAX_CO_EXTRA_USERS 255
14
+
11
15
/* State shared between threads */
12
16
13
17
struct _ts; /* Forward */
@@ -141,6 +145,9 @@ typedef struct _ts {
141
145
PyObject *coroutine_wrapper;
142
146
int in_coroutine_wrapper;
143
147
148
+
Py_ssize_t co_extra_user_count;
149
+
freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS];
150
+
144
151
/* XXX signal handlers should also be here */
145
152
146
153
} PyThreadState;
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ Core and Builtins
27
27
the braces (where the expressions are). This is a breaking change
28
28
from the 3.6 alpha releases.
29
29
30
-
- Implement the frame evaluation part of PEP 523.
30
+
- Implement PEP 523.
31
31
32
32
- Issue #27870: A left shift of zero by a large integer no longer attempts
33
33
to allocate large amounts of memory.
Original file line number Diff line number Diff line change
@@ -152,6 +152,7 @@ PyCode_New(int argcount, int kwonlyargcount,
152
152
co->co_lnotab = lnotab;
153
153
co->co_zombieframe = NULL;
154
154
co->co_weakreflist = NULL;
155
+
co->co_extra = NULL;
155
156
return co;
156
157
}
157
158
@@ -361,6 +362,20 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
361
362
static void
362
363
code_dealloc(PyCodeObject *co)
363
364
{
365
+
if (co->co_extra != NULL) {
366
+
PyThreadState *tstate = PyThreadState_Get();
367
+
368
+
for (Py_ssize_t i = 0; i < co->co_extra->ce_size; i++) {
369
+
freefunc free_extra = tstate->co_extra_freefuncs[i];
370
+
371
+
if (free_extra != NULL) {
372
+
free_extra(co->co_extra->ce_extras[i]);
373
+
}
374
+
}
375
+
376
+
PyMem_FREE(co->co_extra);
377
+
}
378
+
364
379
Py_XDECREF(co->co_code);
365
380
Py_XDECREF(co->co_consts);
366
381
Py_XDECREF(co->co_names);
@@ -752,3 +767,79 @@ _PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
752
767
753
768
return line;
754
769
}
770
+
771
+
772
+
int
773
+
_PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
774
+
{
775
+
PyCodeObject *o;
776
+
777
+
assert(*extra == NULL);
778
+
779
+
if (!PyCode_Check(code)) {
780
+
PyErr_BadInternalCall();
781
+
return 1;
782
+
}
783
+
784
+
o = (PyCodeObject*) code;
785
+
786
+
if (o->co_extra == NULL || o->co_extra->ce_size <= index) {
787
+
return 0;
788
+
}
789
+
790
+
*extra = o->co_extra->ce_extras[index];
791
+
return 0;
792
+
}
793
+
794
+
795
+
int
796
+
_PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
797
+
{
798
+
PyCodeObject *o;
799
+
PyThreadState *tstate = PyThreadState_Get();
800
+
801
+
if (!PyCode_Check(code) || index < 0 ||
802
+
index >= tstate->co_extra_user_count) {
803
+
PyErr_BadInternalCall();
804
+
return 1;
805
+
}
806
+
807
+
o = (PyCodeObject*) code;
808
+
809
+
if (o->co_extra == NULL) {
810
+
o->co_extra = (_PyCodeObjectExtra*) PyMem_Malloc(
811
+
sizeof(_PyCodeObjectExtra));
812
+
if (o->co_extra == NULL) {
813
+
return 1;
814
+
}
815
+
816
+
o->co_extra->ce_extras = PyMem_Malloc(
817
+
tstate->co_extra_user_count * sizeof(void*));
818
+
if (o->co_extra->ce_extras == NULL) {
819
+
return 1;
820
+
}
821
+
822
+
o->co_extra->ce_size = tstate->co_extra_user_count;
823
+
824
+
for (Py_ssize_t i = 0; i < o->co_extra->ce_size; i++) {
825
+
o->co_extra->ce_extras[i] = NULL;
826
+
}
827
+
}
828
+
else if (o->co_extra->ce_size <= index) {
829
+
o->co_extra->ce_extras = PyMem_Realloc(
830
+
o->co_extra->ce_extras, tstate->co_extra_user_count * sizeof(void*));
831
+
832
+
if (o->co_extra->ce_extras == NULL) {
833
+
return 1;
834
+
}
835
+
836
+
o->co_extra->ce_size = tstate->co_extra_user_count;
837
+
838
+
for (Py_ssize_t i = o->co_extra->ce_size; i < o->co_extra->ce_size; i++) {
839
+
o->co_extra->ce_extras[i] = NULL;
840
+
}
841
+
}
842
+
843
+
o->co_extra->ce_extras[index] = extra;
844
+
return 0;
845
+
}
Original file line number Diff line number Diff line change
@@ -5608,3 +5608,17 @@ _Py_GetDXProfile(PyObject *self, PyObject *args)
5608
5608
}
5609
5609
5610
5610
#endif
5611
+
5612
+
Py_ssize_t
5613
+
_PyEval_RequestCodeExtraIndex(freefunc free)
5614
+
{
5615
+
PyThreadState *tstate = PyThreadState_Get();
5616
+
Py_ssize_t new_index;
5617
+
5618
+
if (tstate->co_extra_user_count == MAX_CO_EXTRA_USERS - 1) {
5619
+
return -1;
5620
+
}
5621
+
new_index = tstate->co_extra_user_count++;
5622
+
tstate->co_extra_freefuncs[new_index] = free;
5623
+
return new_index;
5624
+
}
Original file line number Diff line number Diff line change
@@ -227,6 +227,7 @@ new_threadstate(PyInterpreterState *interp, int init)
227
227
228
228
tstate->coroutine_wrapper = NULL;
229
229
tstate->in_coroutine_wrapper = 0;
230
+
tstate->co_extra_user_count = 0;
230
231
231
232
if (init)
232
233
_PyThreadState_Init(tstate);
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4