Skip to content

Commit d383437

Browse files
Write to second slot on stack
1 parent ba19770 commit d383437

File tree

8 files changed

+39
-33
lines changed

8 files changed

+39
-33
lines changed

Include/internal/pycore_object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ PyAPI_FUNC(PyObject*) _PyObject_LookupSpecialMethod(PyObject *self, PyObject *at
882882
extern int _PyObject_IsAbstract(PyObject *);
883883

884884
PyAPI_FUNC(int) _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method);
885-
PyAPI_FUNC(int) _PyObject_GetMethodStackRef(PyObject *obj, PyObject *name, _PyStackRef *method);
885+
PyAPI_FUNC(int) _PyObject_GetMethodStackRef(PyObject *obj, PyObject *name, _PyStackRef *method, _PyStackRef *spare);
886886
extern PyObject* _PyObject_NextNotImplemented(PyObject *);
887887

888888
// Pickle support.

Include/internal/pycore_opcode_metadata.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Objects/object.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1621,7 +1621,7 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method)
16211621
}
16221622

16231623
int
1624-
_PyObject_GetMethodStackRef(PyObject *obj, PyObject *name, _PyStackRef *method)
1624+
_PyObject_GetMethodStackRef(PyObject *obj, PyObject *name, _PyStackRef *method, _PyStackRef *spare)
16251625
{
16261626
#ifdef Py_GIL_DISABLED
16271627
int meth_found = 0;
@@ -1647,6 +1647,7 @@ _PyObject_GetMethodStackRef(PyObject *obj, PyObject *name, _PyStackRef *method)
16471647
}
16481648

16491649
_PyType_LookupStackRef(tp, name, method);
1650+
*spare = *method;
16501651
_PyStackRef descr_st = *method;
16511652
descrgetfunc f = NULL;
16521653
if (!PyStackRef_IsNull(descr_st)) {

Python/bytecodes.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2054,19 +2054,19 @@ dummy_func(
20542054
#endif /* ENABLE_SPECIALIZATION */
20552055
}
20562056

2057-
op(_LOAD_ATTR, (owner -- attr[1], self_or_null if (oparg & 1))) {
2057+
op(_LOAD_ATTR, (owner -- attr[1], self_or_null[1] if (oparg & 1))) {
20582058
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
20592059
if (oparg & 1) {
20602060
/* Designed to work in tandem with CALL, pushes two values. */
20612061
*attr = PyStackRef_NULL;
2062-
int is_meth = _PyObject_GetMethodStackRef(PyStackRef_AsPyObjectBorrow(owner), name, attr);
2062+
int is_meth = _PyObject_GetMethodStackRef(PyStackRef_AsPyObjectBorrow(owner), name, attr, self_or_null);
20632063
if (is_meth) {
20642064
/* We can bypass temporary bound method object.
20652065
meth is unbound method and obj is self.
20662066
meth | self | arg1 | ... | argN
20672067
*/
20682068
assert(!PyStackRef_IsNull(*attr)); // No errors on this branch
2069-
self_or_null = owner; // Transfer ownership
2069+
*self_or_null = owner; // Transfer ownership
20702070
DEAD(owner);
20712071
}
20722072
else {
@@ -2078,7 +2078,7 @@ dummy_func(
20782078
*/
20792079
DECREF_INPUTS();
20802080
ERROR_IF(PyStackRef_IsNull(*attr), error);
2081-
self_or_null = PyStackRef_NULL;
2081+
*self_or_null = PyStackRef_NULL;
20822082
}
20832083
}
20842084
else {
@@ -2090,10 +2090,10 @@ dummy_func(
20902090
else {
20912091
*attr = PyStackRef_FromPyObjectSteal(attr_o);
20922092
}
2093+
/* We need to define self_or_null on all paths */
2094+
*self_or_null = PyStackRef_NULL;
20932095
DECREF_INPUTS();
20942096
ERROR_IF(PyStackRef_IsNull(*attr), error);
2095-
/* We need to define self_or_null on all paths */
2096-
self_or_null = PyStackRef_NULL;
20972097
}
20982098
}
20992099

Python/compile.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,6 +1335,11 @@ optimize_and_assemble_code_unit(struct compiler_unit *u, PyObject *const_cache,
13351335
goto error;
13361336
}
13371337

1338+
/* Reserve an extra word on the stack to ensure there is space for uops to
1339+
pass at least one item on the stack to a subsequent uop.
1340+
*/
1341+
stackdepth++;
1342+
13381343
/** Assembly **/
13391344
co = _PyAssemble_MakeCodeObject(&u->u_metadata, const_cache, consts,
13401345
stackdepth, &optimized_instrs, nlocalsplus,

Python/executor_cases.c.h

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/cases_generator/parsing.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -270,21 +270,15 @@ def cache_effect(self) -> CacheEffect | None:
270270

271271
@contextual
272272
def stack_effect(self) -> StackEffect | None:
273-
# IDENTIFIER [':' IDENTIFIER [TIMES]] ['if' '(' expression ')']
274-
# | IDENTIFIER '[' expression ']'
273+
# IDENTIFIER [':' IDENTIFIER [[TIMES]] ['if' '(' expression ')']
274+
# | IDENTIFIER '[' expression ']' ['if' '(' expression ')']
275275
if tkn := self.expect(lx.IDENTIFIER):
276276
type_text = ""
277277
if self.expect(lx.COLON):
278278
type_text = self.require(lx.IDENTIFIER).text.strip()
279279
if self.expect(lx.TIMES):
280280
type_text += " *"
281281
cond_text = ""
282-
if self.expect(lx.IF):
283-
self.require(lx.LPAREN)
284-
if not (cond := self.expression()):
285-
raise self.make_syntax_error("Expected condition")
286-
self.require(lx.RPAREN)
287-
cond_text = cond.text.strip()
288282
size_text = ""
289283
if self.expect(lx.LBRACKET):
290284
if type_text or cond_text:
@@ -293,6 +287,12 @@ def stack_effect(self) -> StackEffect | None:
293287
raise self.make_syntax_error("Expected expression")
294288
self.require(lx.RBRACKET)
295289
size_text = size.text.strip()
290+
if self.expect(lx.IF):
291+
self.require(lx.LPAREN)
292+
if not (cond := self.expression()):
293+
raise self.make_syntax_error("Expected condition")
294+
self.require(lx.RPAREN)
295+
cond_text = cond.text.strip()
296296
return StackEffect(tkn.text, type_text, cond_text, size_text)
297297
return None
298298

0 commit comments

Comments
 (0)