◐ Shell
clean mode source ↗

gh-117139: Convert the evaluation stack to stack refs (#118450) · python/cpython@22b0de2

@@ -11,6 +11,7 @@ extern "C" {

1111

#include <stdbool.h>

1212

#include <stddef.h> // offsetof()

1313

#include "pycore_code.h" // STATS

14+

#include "pycore_stackref.h" // _PyStackRef

14151516

/* See Objects/frame_layout.md for an explanation of the frame stack

1617

* including explanation of the PyFrameObject and _PyInterpreterFrame

@@ -67,7 +68,7 @@ typedef struct _PyInterpreterFrame {

6768

uint16_t return_offset; /* Only relevant during a function call */

6869

char owner;

6970

/* Locals and stack */

70-

PyObject *localsplus[1];

71+

_PyStackRef localsplus[1];

7172

} _PyInterpreterFrame;

72737374

#define _PyInterpreterFrame_LASTI(IF) \

@@ -78,23 +79,23 @@ static inline PyCodeObject *_PyFrame_GetCode(_PyInterpreterFrame *f) {

7879

return (PyCodeObject *)f->f_executable;

7980

}

808181-

static inline PyObject **_PyFrame_Stackbase(_PyInterpreterFrame *f) {

82-

return f->localsplus + _PyFrame_GetCode(f)->co_nlocalsplus;

82+

static inline _PyStackRef *_PyFrame_Stackbase(_PyInterpreterFrame *f) {

83+

return (f->localsplus + _PyFrame_GetCode(f)->co_nlocalsplus);

8384

}

848585-

static inline PyObject *_PyFrame_StackPeek(_PyInterpreterFrame *f) {

86+

static inline _PyStackRef _PyFrame_StackPeek(_PyInterpreterFrame *f) {

8687

assert(f->stacktop > _PyFrame_GetCode(f)->co_nlocalsplus);

87-

assert(f->localsplus[f->stacktop-1] != NULL);

88+

assert(!PyStackRef_IsNull(f->localsplus[f->stacktop-1]));

8889

return f->localsplus[f->stacktop-1];

8990

}

909191-

static inline PyObject *_PyFrame_StackPop(_PyInterpreterFrame *f) {

92+

static inline _PyStackRef _PyFrame_StackPop(_PyInterpreterFrame *f) {

9293

assert(f->stacktop > _PyFrame_GetCode(f)->co_nlocalsplus);

9394

f->stacktop--;

9495

return f->localsplus[f->stacktop];

9596

}

969797-

static inline void _PyFrame_StackPush(_PyInterpreterFrame *f, PyObject *value) {

98+

static inline void _PyFrame_StackPush(_PyInterpreterFrame *f, _PyStackRef value) {

9899

f->localsplus[f->stacktop] = value;

99100

f->stacktop++;

100101

}

@@ -143,14 +144,14 @@ _PyFrame_Initialize(

143144

frame->owner = FRAME_OWNED_BY_THREAD;

144145145146

for (int i = null_locals_from; i < code->co_nlocalsplus; i++) {

146-

frame->localsplus[i] = NULL;

147+

frame->localsplus[i] = PyStackRef_NULL;

147148

}

148149

}

149150150151

/* Gets the pointer to the locals array

151152

* that precedes this frame.

152153

*/

153-

static inline PyObject**

154+

static inline _PyStackRef*

154155

_PyFrame_GetLocalsArray(_PyInterpreterFrame *frame)

155156

{

156157

return frame->localsplus;

@@ -160,16 +161,16 @@ _PyFrame_GetLocalsArray(_PyInterpreterFrame *frame)

160161

Having stacktop <= 0 ensures that invalid

161162

values are not visible to the cycle GC.

162163

We choose -1 rather than 0 to assist debugging. */

163-

static inline PyObject**

164+

static inline _PyStackRef*

164165

_PyFrame_GetStackPointer(_PyInterpreterFrame *frame)

165166

{

166-

PyObject **sp = frame->localsplus + frame->stacktop;

167+

_PyStackRef *sp = frame->localsplus + frame->stacktop;

167168

frame->stacktop = -1;

168169

return sp;

169170

}

170171171172

static inline void

172-

_PyFrame_SetStackPointer(_PyInterpreterFrame *frame, PyObject **stack_pointer)

173+

_PyFrame_SetStackPointer(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer)

173174

{

174175

frame->stacktop = (int)(stack_pointer - frame->localsplus);

175176

}

@@ -309,7 +310,7 @@ _PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int

309310310311

PyAPI_FUNC(_PyInterpreterFrame *)

311312

_PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func,

312-

PyObject *locals, PyObject* const* args,

313+

PyObject *locals, _PyStackRef const* args,

313314

size_t argcount, PyObject *kwnames);

314315315316

#ifdef __cplusplus