13
13
14
14
static PyMemberDef frame_memberlist [] = {
15
15
{"f_back" , T_OBJECT , OFF (f_back ), READONLY },
16
- {"f_code" , T_OBJECT , OFF (f_code ), READONLY |PY_AUDIT_READ },
17
- {"f_builtins" , T_OBJECT , OFF (f_builtins ), READONLY },
18
- {"f_globals" , T_OBJECT , OFF (f_globals ), READONLY },
19
16
{"f_trace_lines" , T_BOOL , OFF (f_trace_lines ), 0 },
20
17
{"f_trace_opcodes" , T_BOOL , OFF (f_trace_opcodes ), 0 },
21
18
{NULL } /* Sentinel */
@@ -38,6 +35,11 @@ frame_getlocals(PyFrameObject *f, void *closure)
38
35
return f -> f_locals ;
39
36
}
40
37
38
+ static inline PyObject * *
39
+ _PyFrame_Specials (PyFrameObject * f ) {
40
+ return & f -> f_valuestack [- FRAME_SPECIALS_SIZE ];
41
+ }
42
+
41
43
int
42
44
PyFrame_GetLineNumber (PyFrameObject * f )
43
45
{
@@ -71,6 +73,50 @@ frame_getlasti(PyFrameObject *f, void *closure)
71
73
return PyLong_FromLong (f -> f_lasti * 2 );
72
74
}
73
75
76
+ /* Returns a *borrowed* reference. Not part of the API. */
77
+ PyObject *
78
+ _PyFrame_GetGlobals (PyFrameObject * f )
79
+ {
80
+ return _PyFrame_Specials (f )[FRAME_SPECIALS_GLOBALS_OFFSET ];
81
+ }
82
+
83
+ /* Returns a *borrowed* reference. Not part of the API. */
84
+ PyObject *
85
+ _PyFrame_GetBuiltins (PyFrameObject * f )
86
+ {
87
+ return _PyFrame_Specials (f )[FRAME_SPECIALS_BUILTINS_OFFSET ];
88
+ }
89
+
90
+ static PyObject *
91
+ frame_getglobals (PyFrameObject * f , void * closure )
92
+ {
93
+ PyObject * globals = _PyFrame_GetGlobals (f );
94
+ if (globals == NULL ) {
95
+ globals = Py_None ;
96
+ }
97
+ Py_INCREF (globals );
98
+ return globals ;
99
+ }
100
+
101
+ static PyObject *
102
+ frame_getbuiltins (PyFrameObject * f , void * closure )
103
+ {
104
+ PyObject * builtins = _PyFrame_GetBuiltins (f );
105
+ if (builtins == NULL ) {
106
+ builtins = Py_None ;
107
+ }
108
+ Py_INCREF (builtins );
109
+ return builtins ;
110
+ }
111
+
112
+ static PyObject *
113
+ frame_getcode (PyFrameObject * f , void * closure )
114
+ {
115
+ if (PySys_Audit ("object.__getattr__" , "Os" , f , "f_code" ) < 0 ) {
116
+ return NULL ;
117
+ }
118
+ return (PyObject * )PyFrame_GetCode (f );
119
+ }
74
120
75
121
/* Given the index of the effective opcode,
76
122
scan back to construct the oparg with EXTENDED_ARG */
@@ -554,6 +600,9 @@ static PyGetSetDef frame_getsetlist[] = {
554
600
(setter )frame_setlineno , NULL },
555
601
{"f_trace" , (getter )frame_gettrace , (setter )frame_settrace , NULL },
556
602
{"f_lasti" , (getter )frame_getlasti , NULL , NULL },
603
+ {"f_globals" , (getter )frame_getglobals , NULL , NULL },
604
+ {"f_builtins" , (getter )frame_getbuiltins , NULL , NULL },
605
+ {"f_code" , (getter )frame_getcode , NULL , NULL },
557
606
{0 }
558
607
};
559
608
@@ -581,7 +630,7 @@ frame_dealloc(PyFrameObject *f)
581
630
582
631
/* Kill all local variables */
583
632
if (f -> f_own_locals_memory ) {
584
- for (int i = 0 ; i < co -> co_nlocalsplus ; i ++ ) {
633
+ for (int i = 0 ; i < co -> co_nlocalsplus + FRAME_SPECIALS_SIZE ; i ++ ) {
585
634
Py_CLEAR (f -> f_localsptr [i ]);
586
635
}
587
636
/* Free items on stack */
@@ -593,8 +642,6 @@ frame_dealloc(PyFrameObject *f)
593
642
}
594
643
f -> f_stackdepth = 0 ;
595
644
Py_XDECREF (f -> f_back );
596
- Py_DECREF (f -> f_builtins );
597
- Py_DECREF (f -> f_globals );
598
645
Py_CLEAR (f -> f_locals );
599
646
Py_CLEAR (f -> f_trace );
600
647
struct _Py_frame_state * state = get_frame_state ();
@@ -618,17 +665,13 @@ frame_dealloc(PyFrameObject *f)
618
665
static inline Py_ssize_t
619
666
frame_nslots (PyFrameObject * frame )
620
667
{
621
- PyCodeObject * code = frame -> f_code ;
622
- return code -> co_nlocalsplus ;
668
+ return frame -> f_valuestack - frame -> f_localsptr ;
623
669
}
624
670
625
671
static int
626
672
frame_traverse (PyFrameObject * f , visitproc visit , void * arg )
627
673
{
628
674
Py_VISIT (f -> f_back );
629
- Py_VISIT (f -> f_code );
630
- Py_VISIT (f -> f_builtins );
631
- Py_VISIT (f -> f_globals );
632
675
Py_VISIT (f -> f_locals );
633
676
Py_VISIT (f -> f_trace );
634
677
@@ -766,7 +809,8 @@ frame_alloc(PyCodeObject *code, PyObject **localsarray)
766
809
int owns ;
767
810
PyFrameObject * f ;
768
811
if (localsarray == NULL ) {
769
- localsarray = PyMem_Malloc (sizeof (PyObject * )* (code -> co_nlocalsplus + code -> co_stacksize ));
812
+ int size = code -> co_nlocalsplus + code -> co_stacksize + FRAME_SPECIALS_SIZE ;
813
+ localsarray = PyMem_Malloc (sizeof (PyObject * )* size );
770
814
if (localsarray == NULL ) {
771
815
PyErr_NoMemory ();
772
816
return NULL ;
@@ -803,29 +847,32 @@ frame_alloc(PyCodeObject *code, PyObject **localsarray)
803
847
}
804
848
f -> f_localsptr = localsarray ;
805
849
f -> f_own_locals_memory = owns ;
806
- f -> f_valuestack = f -> f_localsptr + code -> co_nlocalsplus ;
850
+ f -> f_valuestack = f -> f_localsptr + code -> co_nlocalsplus + FRAME_SPECIALS_SIZE ;
807
851
return f ;
808
852
}
809
853
810
854
int
811
- _PyFrame_MakeCopyOfLocals (PyFrameObject * f )
855
+ _PyFrame_StealLocals (PyFrameObject * f )
812
856
{
813
- if (f -> f_own_locals_memory ) {
814
- return 0 ;
815
- }
816
- PyObject * * copy = PyMem_Malloc (sizeof (PyObject * )* ( f -> f_code -> co_nlocalsplus + f -> f_code -> co_stacksize ) );
857
+ assert (f -> f_own_locals_memory == 0 );
858
+ assert ( f -> f_stackdepth == 0 ) ;
859
+ int size = frame_nslots ( f );
860
+ PyObject * * copy = PyMem_Malloc (sizeof (PyObject * )* size );
817
861
if (copy == NULL ) {
862
+ for (int i = 0 ; i < size ; i ++ ) {
863
+ PyObject * o = f -> f_localsptr [i ];
864
+ Py_XDECREF (o );
865
+ }
818
866
PyErr_NoMemory ();
819
867
return -1 ;
820
868
}
821
- for (int i = 0 ; i < f -> f_code -> co_nlocalsplus + f -> f_stackdepth ; i ++ ) {
869
+ for (int i = 0 ; i < size ; i ++ ) {
822
870
PyObject * o = f -> f_localsptr [i ];
823
- Py_XINCREF (o );
824
871
copy [i ] = o ;
825
872
}
826
873
f -> f_own_locals_memory = 1 ;
827
874
f -> f_localsptr = copy ;
828
- f -> f_valuestack = f -> f_localsptr + f -> f_code -> co_nlocalsplus ;
875
+ f -> f_valuestack = copy + size ;
829
876
return 0 ;
830
877
}
831
878
@@ -845,8 +892,8 @@ _PyFrame_New_NoTrack(PyThreadState *tstate, PyFrameConstructor *con, PyObject *l
845
892
846
893
f -> f_back = (PyFrameObject * )Py_XNewRef (tstate -> frame );
847
894
f -> f_code = (PyCodeObject * )Py_NewRef (con -> fc_code );
848
- f -> f_builtins = Py_NewRef (con -> fc_builtins );
849
- f -> f_globals = Py_NewRef (con -> fc_globals );
895
+ _PyFrame_Specials ( f )[ FRAME_SPECIALS_BUILTINS_OFFSET ] = Py_NewRef (con -> fc_builtins );
896
+ _PyFrame_Specials ( f )[ FRAME_SPECIALS_GLOBALS_OFFSET ] = Py_NewRef (con -> fc_globals );
850
897
f -> f_locals = Py_XNewRef (locals );
851
898
// f_valuestack initialized by frame_alloc()
852
899
f -> f_trace = NULL ;
0 commit comments