mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
[3.11] gh-89811: Check for valid tp_version_tag in specializer (GH-115045)
* gh-89811: Check for valid tp_version_tag in specializer (GH-113558) * gh-113937 Fix failures in type cache tests due to re-running (GH-113953) * Update backported code for 3.11 specifically
This commit is contained in:
parent
2e99ba9e90
commit
a11312456d
4 changed files with 216 additions and 1 deletions
|
@ -481,6 +481,7 @@ miss_counter_start(void) {
|
|||
#define SPEC_FAIL_UNPACK_SEQUENCE_ITERATOR 8
|
||||
#define SPEC_FAIL_UNPACK_SEQUENCE_SEQUENCE 9
|
||||
|
||||
static uint32_t type_get_version(PyTypeObject *t, int opcode);
|
||||
|
||||
static int
|
||||
specialize_module_load_attr(PyObject *owner, _Py_CODEUNIT *instr,
|
||||
|
@ -673,6 +674,9 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
|
|||
}
|
||||
PyObject *descr;
|
||||
DescriptorClassification kind = analyze_descriptor(type, name, &descr, 0);
|
||||
if (type_get_version(type, LOAD_ATTR) == 0) {
|
||||
goto fail;
|
||||
}
|
||||
switch(kind) {
|
||||
case OVERRIDING:
|
||||
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR);
|
||||
|
@ -766,6 +770,9 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
|
|||
}
|
||||
PyObject *descr;
|
||||
DescriptorClassification kind = analyze_descriptor(type, name, &descr, 1);
|
||||
if (type_get_version(type, STORE_ATTR) == 0) {
|
||||
goto fail;
|
||||
}
|
||||
switch(kind) {
|
||||
case OVERRIDING:
|
||||
SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR);
|
||||
|
@ -889,6 +896,9 @@ specialize_class_load_method(PyObject *owner, _Py_CODEUNIT *instr,
|
|||
PyObject *descr = NULL;
|
||||
DescriptorClassification kind = 0;
|
||||
kind = analyze_descriptor((PyTypeObject *)owner, name, &descr, 0);
|
||||
if (type_get_version((PyTypeObject *)owner, LOAD_METHOD) == 0) {
|
||||
return -1;
|
||||
}
|
||||
switch (kind) {
|
||||
case METHOD:
|
||||
case NON_DESCRIPTOR:
|
||||
|
@ -950,6 +960,9 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
|
|||
PyObject *descr = NULL;
|
||||
DescriptorClassification kind = 0;
|
||||
kind = analyze_descriptor(owner_cls, name, &descr, 0);
|
||||
if (type_get_version(owner_cls, LOAD_METHOD) == 0) {
|
||||
goto fail;
|
||||
}
|
||||
assert(descr != NULL || kind == ABSENT || kind == GETSET_OVERRIDDEN);
|
||||
if (kind != METHOD) {
|
||||
SPECIALIZATION_FAIL(LOAD_METHOD, load_method_fail_kind(kind));
|
||||
|
@ -1183,6 +1196,18 @@ function_kind(PyCodeObject *code) {
|
|||
return SIMPLE_FUNCTION;
|
||||
}
|
||||
|
||||
/* Returning 0 indicates a failure. */
|
||||
static uint32_t
|
||||
type_get_version(PyTypeObject *t, int opcode)
|
||||
{
|
||||
uint32_t version = t->tp_version_tag;
|
||||
if (version == 0) {
|
||||
SPECIALIZATION_FAIL(opcode, SPEC_FAIL_OUT_OF_VERSIONS);
|
||||
return 0;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
int
|
||||
_Py_Specialize_BinarySubscr(
|
||||
PyObject *container, PyObject *sub, _Py_CODEUNIT *instr)
|
||||
|
@ -1231,6 +1256,9 @@ _Py_Specialize_BinarySubscr(
|
|||
SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS);
|
||||
goto fail;
|
||||
}
|
||||
if (type_get_version(cls, BINARY_SUBSCR) == 0) {
|
||||
goto fail;
|
||||
}
|
||||
assert(cls->tp_version_tag != 0);
|
||||
write_u32(cache->type_version, cls->tp_version_tag);
|
||||
int version = _PyFunction_GetVersionForCurrentState(func);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue