Skip to content

Commit c4f6e10

Browse files
committed
Regions: Generators are a mess
1 parent 79e54a6 commit c4f6e10

5 files changed

Lines changed: 33 additions & 24 deletions

File tree

Objects/genobject.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -187,16 +187,16 @@ gen_dealloc(PyObject *self)
187187
/* We have to handle this case for asynchronous generators
188188
right here, because this code has to be between UNTRACK
189189
and GC_Del. */
190-
Py_CLEAR(((PyAsyncGenObject*)gen)->ag_origin_or_finalizer);
190+
PyRegion_CLEAR(gen, ((PyAsyncGenObject*)gen)->ag_origin_or_finalizer);
191191
}
192192
if (PyCoro_CheckExact(gen)) {
193-
Py_CLEAR(((PyCoroObject *)gen)->cr_origin_or_finalizer);
193+
PyRegion_CLEAR(gen, ((PyCoroObject *)gen)->cr_origin_or_finalizer);
194194
}
195195
gen_clear_frame(gen);
196196
assert(gen->gi_exc_state.exc_value == NULL);
197197
PyStackRef_CLEAR(gen->gi_iframe.f_executable);
198-
Py_CLEAR(gen->gi_name);
199-
Py_CLEAR(gen->gi_qualname);
198+
PyRegion_CLEAR(gen, gen->gi_name);
199+
PyRegion_CLEAR(gen, gen->gi_qualname);
200200

201201
PyObject_GC_Del(gen);
202202
}
@@ -285,7 +285,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult,
285285
assert(result == Py_None || !PyAsyncGen_CheckExact(gen));
286286
if (result == Py_None && !PyAsyncGen_CheckExact(gen) && !arg) {
287287
/* Return NULL if called by gen_iternext() */
288-
Py_CLEAR(result);
288+
PyRegion_CLEARLOCAL(result);
289289
}
290290
}
291291
else {
@@ -322,7 +322,7 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing)
322322
else {
323323
_PyGen_SetStopIterationValue(result);
324324
}
325-
Py_CLEAR(result);
325+
PyRegion_CLEARLOCAL(result);
326326
}
327327
return result;
328328
}
@@ -648,7 +648,7 @@ gen_iternext(PyObject *self)
648648
if (result != Py_None) {
649649
_PyGen_SetStopIterationValue(result);
650650
}
651-
Py_CLEAR(result);
651+
PyRegion_CLEARLOCAL(result);
652652
}
653653
return result;
654654
}
@@ -908,6 +908,7 @@ PyTypeObject PyGen_Type = {
908908
offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */
909909
PyObject_SelfIter, /* tp_iter */
910910
gen_iternext, /* tp_iternext */
911+
// TODO: Migrate
911912
gen_methods, /* tp_methods */
912913
gen_memberlist, /* tp_members */
913914
gen_getsetlist, /* tp_getset */

Objects/object.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,7 @@ _PyObject_GetDictPtr(PyObject *obj)
16141614
PyObject *
16151615
PyObject_SelfIter(PyObject *obj)
16161616
{
1617-
return Py_NewRef(obj);
1617+
return PyRegion_NewRef(obj);
16181618
}
16191619

16201620
/* Helper used when the __next__ method is removed from a type:

Objects/typeobject.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6052,6 +6052,10 @@ find_name_in_mro(PyTypeObject *type, PyObject *name, int *error)
60526052
PyObject *res = NULL;
60536053
/* Keep a strong reference to mro because type->tp_mro can be replaced
60546054
during dict lookup, e.g. when comparing to non-string keys. */
6055+
if (PyRegion_AddLocalRef(mro)) {
6056+
*error = -1;
6057+
return NULL;
6058+
}
60556059
Py_INCREF(mro);
60566060
PyRegion_AddLocalRef(mro);
60576061
Py_ssize_t n = PyTuple_GET_SIZE(mro);
@@ -6069,8 +6073,7 @@ find_name_in_mro(PyTypeObject *type, PyObject *name, int *error)
60696073
}
60706074
*error = 0;
60716075
done:
6072-
PyRegion_RemoveLocalRef(mro);
6073-
Py_DECREF(mro);
6076+
PyRegion_CLEARLOCAL(mro);
60746077
return res;
60756078
}
60766079

@@ -6263,8 +6266,7 @@ _PyType_LookupStackRefAndVersion(PyTypeObject *type, PyObject *name, _PyStackRef
62636266
update_cache_gil_disabled(entry, name, assigned_version, res);
62646267
#else
62656268
PyObject *old_value = update_cache(entry, name, assigned_version, res);
6266-
PyRegion_RemoveLocalRef(old_value);
6267-
Py_DECREF(old_value);
6269+
PyRegion_CLEARLOCAL(old_value);
62686270
#endif
62696271
}
62706272
*out = res ? PyStackRef_FromPyObjectSteal(res) : PyStackRef_NULL;

Python/region.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,10 +1291,15 @@ int _add_to_region_check_obj(PyObject *obj, void *state_void) {
12911291
assert(_PyRegion_Get(obj) == ((AddRegionState*)state_void)->merge_region);
12921292
assert(_PyRegion_GetFollowPending(obj) == ((AddRegionState*)state_void)->subject_region);
12931293

1294-
if (PyFrame_Check(obj)) {
1294+
if (PyFrame_Check(obj)
1295+
|| PyGen_CheckExact(obj)
1296+
|| PyCoro_CheckExact(obj)
1297+
|| PyAsyncGen_CheckExact(obj)
1298+
|| PyAsyncGenASend_CheckExact(obj)
1299+
) {
12951300
throw_region_error(
1296-
"Frame objects are not movable and have to remain local",
1297-
NULL, NULL, obj);
1301+
"The given object is movable and has to remain local",
1302+
NULL, NULL, obj);
12981303
return Py_OWNERSHIP_TRAVERSE_ERR;
12991304
}
13001305

Python/specialize.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,7 @@ analyze_descriptor_load(PyTypeObject *type, PyObject *name, PyObject **descr, un
923923
/* Normal attribute lookup; */
924924
has_getattr = false;
925925
}
926+
// TODO(regions): xFrednet: Support slots getter and setter
926927
else if (getattro_slot == _Py_slot_tp_getattr_hook ||
927928
getattro_slot == _Py_slot_tp_getattro) {
928929
/* One or both of __getattribute__ or __getattr__ may have been
@@ -944,7 +945,7 @@ analyze_descriptor_load(PyTypeObject *type, PyObject *name, PyObject **descr, un
944945
}
945946
/* Potentially both __getattr__ and __getattribute__ are set.
946947
Too complicated */
947-
Py_DECREF(getattribute);
948+
PyRegion_CLEARLOCAL(getattribute);
948949
*descr = NULL;
949950
*tp_version = ga_version;
950951
return GETSET_OVERRIDDEN;
@@ -956,7 +957,7 @@ analyze_descriptor_load(PyTypeObject *type, PyObject *name, PyObject **descr, un
956957
raised. This means some specializations, e.g. specializing
957958
for property() isn't safe.
958959
*/
959-
Py_XDECREF(getattribute);
960+
PyRegion_CLEARLOCAL(getattribute);
960961
}
961962
else {
962963
*descr = NULL;
@@ -1337,7 +1338,7 @@ specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* na
13371338
PyTypeObject *type = Py_TYPE(owner);
13381339
DescriptorClassification kind = analyze_descriptor_load(type, name, &descr, &tp_version);
13391340
int result = do_specialize_instance_load_attr(owner, instr, name, shadow, shared_keys_version, kind, descr, tp_version);
1340-
Py_XDECREF(descr);
1341+
PyRegion_CLEARLOCAL(descr);
13411342
return result;
13421343
}
13431344

@@ -1523,7 +1524,7 @@ specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr,
15231524
unsigned int meta_version = 0;
15241525
PyObject *metadescriptor = _PyType_LookupRefAndVersion(Py_TYPE(cls), name, &meta_version);
15251526
DescriptorClassification metakind = classify_descriptor(metadescriptor, false);
1526-
Py_XDECREF(metadescriptor);
1527+
PyRegion_CLEARLOCAL(metadescriptor);
15271528
switch (metakind) {
15281529
case METHOD:
15291530
case NON_DESCRIPTOR:
@@ -1542,15 +1543,15 @@ specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr,
15421543
kind = analyze_descriptor_load(cls, name, &descr, &tp_version);
15431544
if (tp_version == 0) {
15441545
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
1545-
Py_XDECREF(descr);
1546+
PyRegion_CLEARLOCAL(descr);
15461547
return -1;
15471548
}
15481549
bool metaclass_check = false;
15491550
if ((Py_TYPE(cls)->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) {
15501551
metaclass_check = true;
15511552
if (meta_version == 0) {
15521553
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
1553-
Py_XDECREF(descr);
1554+
PyRegion_CLEARLOCAL(descr);
15541555
return -1;
15551556
}
15561557
}
@@ -1573,17 +1574,17 @@ specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr,
15731574
else {
15741575
specialize(instr, LOAD_ATTR_CLASS);
15751576
}
1576-
Py_XDECREF(descr);
1577+
PyRegion_CLEARLOCAL(descr);
15771578
return 0;
15781579
#ifdef Py_STATS
15791580
case ABSENT:
15801581
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR);
1581-
Py_XDECREF(descr);
1582+
PyRegion_CLEARLOCAL(descr);
15821583
return -1;
15831584
#endif
15841585
default:
15851586
SPECIALIZATION_FAIL(LOAD_ATTR, load_attr_fail_kind(kind));
1586-
Py_XDECREF(descr);
1587+
PyRegion_CLEARLOCAL(descr);
15871588
return -1;
15881589
}
15891590
}

0 commit comments

Comments
 (0)