Skip to content

Commit c343ae7

Browse files
committed
Generators 2..
1 parent c4f6e10 commit c343ae7

7 files changed

Lines changed: 115 additions & 37 deletions

File tree

Objects/descrobject.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,6 @@ PyTypeObject PyGetSetDescr_Type = {
889889
getset_set, /* tp_descr_set */
890890
.tp_reachable = _PyObject_ReachableVisitType,
891891
.tp_flags2 = Py_TPFLAGS2_REGION_AWARE
892-
.tp_flags2 = Py_TPFLAGS2_REGION_AWARE,
893892
};
894893

895894
PyTypeObject PyWrapperDescr_Type = {

Objects/exceptions.c

Lines changed: 75 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ BaseException_args_get_impl(PyBaseExceptionObject *self)
345345
if (self->args == NULL) {
346346
Py_RETURN_NONE;
347347
}
348-
return Py_NewRef(self->args);
348+
return PyRegion_NewRef(self->args);
349349
}
350350

351351
/*[clinic input]
@@ -366,7 +366,9 @@ BaseException_args_set_impl(PyBaseExceptionObject *self, PyObject *value)
366366
seq = PySequence_Tuple(value);
367367
if (!seq)
368368
return -1;
369-
Py_XSETREF(self->args, seq);
369+
if (PyRegion_XSETREF(self, self->args, seq)) {
370+
return -1;
371+
}
370372
return 0;
371373
}
372374

@@ -383,7 +385,7 @@ BaseException___traceback___get_impl(PyBaseExceptionObject *self)
383385
if (self->traceback == NULL) {
384386
Py_RETURN_NONE;
385387
}
386-
return Py_NewRef(self->traceback);
388+
return PyRegion_NewRef(self->traceback);
387389
}
388390

389391

@@ -403,10 +405,12 @@ BaseException___traceback___set_impl(PyBaseExceptionObject *self,
403405
return -1;
404406
}
405407
if (PyTraceBack_Check(value)) {
406-
Py_XSETREF(self->traceback, Py_NewRef(value));
408+
if (PyRegion_XSETNEWREF(self, self->traceback, value)) {
409+
return -1;
410+
}
407411
}
408412
else if (value == Py_None) {
409-
Py_CLEAR(self->traceback);
413+
PyRegion_CLEAR(self, self->traceback);
410414
}
411415
else {
412416
PyErr_SetString(PyExc_TypeError,
@@ -429,7 +433,7 @@ BaseException___context___get_impl(PyBaseExceptionObject *self)
429433
if (self->context == NULL) {
430434
Py_RETURN_NONE;
431435
}
432-
return Py_NewRef(self->context);
436+
return PyRegion_NewRef(self->context);
433437
}
434438

435439
/*[clinic input]
@@ -453,9 +457,18 @@ BaseException___context___set_impl(PyBaseExceptionObject *self,
453457
"or derive from BaseException");
454458
return -1;
455459
} else {
460+
if (PyRegion_AddLocalRef(value)) {
461+
// Regions: This should never happen, since we have a reference to self.
462+
assert(false);
463+
PyRegion_DirtyObjectRegion(value);
464+
return -1;
465+
}
456466
Py_INCREF(value);
457467
}
458-
Py_XSETREF(self->context, value);
468+
if (PyRegion_XSETREF(self, self->context, value)) {
469+
Py_XDECREF(value);
470+
return -1;
471+
}
459472
return 0;
460473
}
461474

@@ -519,7 +532,15 @@ PyException_GetTraceback(PyObject *self)
519532
{
520533
PyObject *traceback;
521534
Py_BEGIN_CRITICAL_SECTION(self);
522-
traceback = Py_XNewRef(PyBaseExceptionObject_CAST(self)->traceback);
535+
traceback = PyBaseExceptionObject_CAST(self)->traceback;
536+
if (PyRegion_AddLocalRef(traceback)) {
537+
// Regions: This should never happen, since we have a reference to self.
538+
assert(false);
539+
PyRegion_DirtyObjectRegion(traceback);
540+
traceback = NULL;
541+
} else {
542+
Py_XINCREF(traceback);
543+
}
523544
Py_END_CRITICAL_SECTION();
524545
return traceback;
525546
}
@@ -540,7 +561,15 @@ PyException_GetCause(PyObject *self)
540561
{
541562
PyObject *cause;
542563
Py_BEGIN_CRITICAL_SECTION(self);
543-
cause = Py_XNewRef(PyBaseExceptionObject_CAST(self)->cause);
564+
cause = PyBaseExceptionObject_CAST(self)->cause;
565+
if (PyRegion_AddLocalRef(cause)) {
566+
// Regions: This should never happen, since we have a reference to self.
567+
assert(false);
568+
PyRegion_DirtyObjectRegion(cause);
569+
cause = NULL;
570+
} else {
571+
Py_XINCREF(cause);
572+
}
544573
Py_END_CRITICAL_SECTION();
545574
return cause;
546575
}
@@ -551,8 +580,11 @@ PyException_SetCause(PyObject *self, PyObject *cause)
551580
{
552581
Py_BEGIN_CRITICAL_SECTION(self);
553582
PyBaseExceptionObject *base_self = PyBaseExceptionObject_CAST(self);
554-
base_self->suppress_context = 1;
555-
Py_XSETREF(base_self->cause, cause);
583+
if (PyRegion_XSETREF(base_self, base_self->cause, cause)) {
584+
// FIXME(Regions): xFrednet: This function doesn't support failure.
585+
} else {
586+
base_self->suppress_context = 1;
587+
}
556588
Py_END_CRITICAL_SECTION();
557589
}
558590

@@ -561,7 +593,15 @@ PyException_GetContext(PyObject *self)
561593
{
562594
PyObject *context;
563595
Py_BEGIN_CRITICAL_SECTION(self);
564-
context = Py_XNewRef(PyBaseExceptionObject_CAST(self)->context);
596+
context = PyBaseExceptionObject_CAST(self)->context;
597+
if (PyRegion_AddLocalRef(context)) {
598+
// Regions: This should never happen, since we have a reference to self.
599+
assert(false);
600+
PyRegion_DirtyObjectRegion(context);
601+
context = NULL;
602+
} else {
603+
Py_XINCREF(context);
604+
}
565605
Py_END_CRITICAL_SECTION();
566606
return context;
567607
}
@@ -571,7 +611,9 @@ void
571611
PyException_SetContext(PyObject *self, PyObject *context)
572612
{
573613
Py_BEGIN_CRITICAL_SECTION(self);
574-
Py_XSETREF(PyBaseExceptionObject_CAST(self)->context, context);
614+
if (PyRegion_XSETREF(self, PyBaseExceptionObject_CAST(self)->context, context)) {
615+
// FIXME(Regions): xFrednet: This function doesn't support failure.
616+
}
575617
Py_END_CRITICAL_SECTION();
576618
}
577619

@@ -580,17 +622,34 @@ PyException_GetArgs(PyObject *self)
580622
{
581623
PyObject *args;
582624
Py_BEGIN_CRITICAL_SECTION(self);
583-
args = Py_NewRef(PyBaseExceptionObject_CAST(self)->args);
625+
args = PyBaseExceptionObject_CAST(self)->args;
626+
if (PyRegion_AddLocalRef(args)) {
627+
// This should never happen, since we have a reference to self.
628+
assert(false);
629+
PyRegion_DirtyObjectRegion(args);
630+
args = NULL;
631+
} else {
632+
Py_INCREF(args);
633+
}
584634
Py_END_CRITICAL_SECTION();
585635
return args;
586636
}
587637

588638
void
589639
PyException_SetArgs(PyObject *self, PyObject *args)
590640
{
591-
Py_BEGIN_CRITICAL_SECTION(self);
641+
// Regions: This should always succeed, since we have a reference to args
642+
if (PyRegion_AddLocalRef(args)) {
643+
assert(false);
644+
PyRegion_DirtyObjectRegion(args);
645+
return;
646+
}
592647
Py_INCREF(args);
593-
Py_XSETREF(PyBaseExceptionObject_CAST(self)->args, args);
648+
649+
Py_BEGIN_CRITICAL_SECTION(self);
650+
if (PyRegion_XSETREF(self, PyBaseExceptionObject_CAST(self)->args, args)) {
651+
// FIXME(Regions): xFrednet: This function doesn't support failure.
652+
}
594653
Py_END_CRITICAL_SECTION();
595654
}
596655

Objects/genobject.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ PyDoc_STRVAR(sizeof__doc__,
864864

865865
static PyMethodDef gen_methods[] = {
866866
{"send", gen_send, METH_O, send_doc},
867+
// TODO(regions): Migrate
867868
{"throw", _PyCFunction_CAST(gen_throw), METH_FASTCALL, throw_doc},
868869
{"close", gen_close, METH_NOARGS, close_doc},
869870
{"__sizeof__", gen_sizeof, METH_NOARGS, sizeof__doc__},
@@ -908,7 +909,7 @@ PyTypeObject PyGen_Type = {
908909
offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */
909910
PyObject_SelfIter, /* tp_iter */
910911
gen_iternext, /* tp_iternext */
911-
// TODO: Migrate
912+
// TODO(regions): Migrate
912913
gen_methods, /* tp_methods */
913914
gen_memberlist, /* tp_members */
914915
gen_getsetlist, /* tp_getset */

Objects/object.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,7 @@ PyObject_CallFinalizer(PyObject *self)
588588
if (_PyType_IS_GC(tp) && _PyGC_FINALIZED(self))
589589
return;
590590

591+
PyRegion_NotifyTypeUse(tp);
591592
tp->tp_finalize(self);
592593
if (_PyType_IS_GC(tp)) {
593594
_PyGC_SET_FINALIZED(self);
@@ -782,6 +783,7 @@ PyObject_Repr(PyObject *v)
782783
" while getting the repr of an object")) {
783784
return NULL;
784785
}
786+
PyRegion_NotifyTypeUse(Py_TYPE(v));
785787
res = (*Py_TYPE(v)->tp_repr)(v);
786788
_Py_LeaveRecursiveCallTstate(tstate);
787789

@@ -791,7 +793,7 @@ PyObject_Repr(PyObject *v)
791793
if (!PyUnicode_Check(res)) {
792794
_PyErr_Format(tstate, PyExc_TypeError,
793795
"%T.__repr__() must return a str, not %T", v, res);
794-
Py_DECREF(res);
796+
PyRegion_CLEARLOCAL(res);
795797
return NULL;
796798
}
797799
return res;
@@ -3271,6 +3273,7 @@ _Py_Dealloc(PyObject *op)
32713273
#ifdef Py_TRACE_REFS
32723274
_Py_ForgetReference(op);
32733275
#endif
3276+
PyRegion_NotifyTypeUse(type);
32743277
_PyReftracerTrack(op, PyRefTracer_DESTROY);
32753278
(*dealloc)(op);
32763279

Python/errors.c

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -70,31 +70,31 @@ _PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value,
7070
#ifdef Py_DEBUG
7171
PyObject *tb = PyException_GetTraceback(value);
7272
assert(tb != Py_None);
73-
Py_XDECREF(tb);
73+
PyRegion_CLEARLOCAL(tb);
7474
#endif
7575
}
7676
else {
7777
PyObject *exc = _PyErr_CreateException(type, value);
78-
Py_XDECREF(value);
78+
PyRegion_CLEARLOCAL(value);
7979
if (exc == NULL) {
80-
Py_DECREF(type);
81-
Py_XDECREF(traceback);
80+
PyRegion_CLEARLOCAL(type);
81+
PyRegion_CLEARLOCAL(traceback);
8282
return;
8383
}
8484
value = exc;
8585
}
8686
assert(PyExceptionInstance_Check(value));
8787
if (traceback != NULL) {
8888
if (PyException_SetTraceback(value, traceback) < 0) {
89-
Py_DECREF(traceback);
90-
Py_DECREF(value);
91-
Py_DECREF(type);
89+
PyRegion_CLEARLOCAL(traceback);
90+
PyRegion_CLEARLOCAL(value);
91+
PyRegion_CLEARLOCAL(type);
9292
return;
9393
}
94-
Py_DECREF(traceback);
94+
PyRegion_CLEARLOCAL(traceback);
9595
}
9696
_PyErr_SetRaisedException(tstate, value);
97-
Py_DECREF(type);
97+
PyRegion_CLEARLOCAL(type);
9898
}
9999

100100
void
@@ -142,7 +142,7 @@ get_normalization_failure_note(PyThreadState *tstate, PyObject *exception, PyObj
142142
else {
143143
note = PyUnicode_FromFormat("Normalization failed: type=%s args=%S",
144144
tpname, args);
145-
Py_DECREF(args);
145+
PyRegion_CLEARLOCAL(args);
146146
}
147147
return note;
148148
}
@@ -169,6 +169,10 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value)
169169
return;
170170
}
171171
}
172+
if (PyRegion_AddLocalRef(value)) {
173+
assert(false);
174+
return;
175+
}
172176
Py_XINCREF(value);
173177
if (!is_subclass) {
174178
/* We must normalize the value right now */
@@ -183,21 +187,25 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value)
183187
assert(PyExceptionInstance_Check(exc));
184188

185189
PyObject *note = get_normalization_failure_note(tstate, exception, value);
186-
Py_XDECREF(value);
190+
PyRegion_CLEARLOCAL(value);
187191
if (note != NULL) {
188192
/* ignore errors in _PyException_AddNote - they will be overwritten below */
189193
_PyException_AddNote(exc, note);
190-
Py_DECREF(note);
194+
PyRegion_CLEARLOCAL(note);
191195
}
192196
_PyErr_SetRaisedException(tstate, exc);
193197
return;
194198
}
195-
Py_XSETREF(value, fixed_value);
199+
PyRegion_XSETLOCALREF(value, fixed_value);
196200
}
197201

198202
exc_value = _PyErr_GetTopmostException(tstate)->exc_value;
199203
if (exc_value != NULL && exc_value != Py_None) {
200204
/* Implicit exception chaining */
205+
if (PyRegion_AddLocalRef(exc_value)) {
206+
PyRegion_CLEARLOCAL(value);
207+
return;
208+
}
201209
Py_INCREF(exc_value);
202210
/* Avoid creating new reference cycles through the
203211
context chain, while taking care not to hang on
@@ -210,6 +218,7 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value)
210218
PyObject *slow_o = o; /* Floyd's cycle detection algo */
211219
int slow_update_toggle = 0;
212220
while ((context = PyException_GetContext(o))) {
221+
PyRegion_RemoveLocalRef(context);
213222
Py_DECREF(context);
214223
if (context == value) {
215224
PyException_SetContext(o, NULL);
@@ -223,14 +232,14 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value)
223232
}
224233
if (slow_update_toggle) {
225234
slow_o = PyException_GetContext(slow_o);
226-
Py_DECREF(slow_o);
235+
PyRegion_CLEARLOCAL(slow_o);
227236
}
228237
slow_update_toggle = !slow_update_toggle;
229238
}
230239
PyException_SetContext(value, exc_value);
231240
}
232241
else {
233-
Py_DECREF(exc_value);
242+
PyRegion_CLEARLOCAL(exc_value);
234243
}
235244
}
236245
assert(value != NULL);
@@ -736,7 +745,7 @@ _PyErr_ChainStackItem(void)
736745

737746
/* _PyErr_SetObject sets the context from PyThreadState. */
738747
_PyErr_SetObject(tstate, (PyObject *) Py_TYPE(exc), exc);
739-
Py_DECREF(exc); // since _PyErr_Occurred was true
748+
PyRegion_CLEARLOCAL(exc); // since _PyErr_Occurred was true
740749
}
741750

742751
static PyObject *

Python/frame.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,11 @@ _PyFrame_ClearExceptCode(_PyInterpreterFrame *frame)
124124
frame->frame_obj = NULL;
125125
if (!_PyObject_IsUniquelyReferenced((PyObject *)f)) {
126126
take_ownership(f, frame);
127-
assert(PyRegion_IsLocal(f) && "No write barrier, since frames are always local");
127+
assert((PyRegion_IsLocal(f) || _Py_IsImmortalOrImmutable(f)) && "No write barrier, since frames are always local");
128128
Py_DECREF(f);
129129
return;
130130
}
131-
assert(PyRegion_IsLocal(f) && "No write barrier, since frames are always local");
131+
assert((PyRegion_IsLocal(f) || _Py_IsImmortalOrImmutable(f)) && "No write barrier, since frames are always local");
132132
Py_DECREF(f);
133133
}
134134
_PyFrame_ClearLocals(frame);

Python/region.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,13 @@ int _add_to_region_check_obj(PyObject *obj, void *state_void) {
12921292
assert(_PyRegion_GetFollowPending(obj) == ((AddRegionState*)state_void)->subject_region);
12931293

12941294
if (PyFrame_Check(obj)
1295+
// FIXME(regions): xFrednet: These objects are currently unmovable
1296+
// because they store a interpreter frame inside them. However,
1297+
// a pre-move-hook may enable moving of these. We would need to
1298+
// package the frame in a subregion for the move and then dissolve
1299+
// it into the local region before using the frame again.
1300+
// For now, I've added the write barriers in them as if these types
1301+
// support this suggested behavior.
12951302
|| PyGen_CheckExact(obj)
12961303
|| PyCoro_CheckExact(obj)
12971304
|| PyAsyncGen_CheckExact(obj)

0 commit comments

Comments
 (0)