Emit code for clearing a C attribute reference for GC. Assume that 'target' represents a C expression that refers to a struct member, such as 'self->x'.
(self, target: str, rtype: RType)
| 1314 | assert False, "emit_gc_visit() not implemented for %s" % repr(rtype) |
| 1315 | |
| 1316 | def emit_gc_clear(self, target: str, rtype: RType) -> None: |
| 1317 | """Emit code for clearing a C attribute reference for GC. |
| 1318 | |
| 1319 | Assume that 'target' represents a C expression that refers to a |
| 1320 | struct member, such as 'self->x'. |
| 1321 | """ |
| 1322 | if not rtype.is_refcounted: |
| 1323 | # Not refcounted -> no pointers -> no GC interaction. |
| 1324 | return |
| 1325 | elif isinstance(rtype, RPrimitive) and rtype.name == "builtins.int": |
| 1326 | self.emit_line(f"if (CPyTagged_CheckLong({target})) {{") |
| 1327 | self.emit_line(f"CPyTagged __tmp = {target};") |
| 1328 | self.emit_line(f"{target} = {self.c_undefined_value(rtype)};") |
| 1329 | self.emit_line("Py_XDECREF(CPyTagged_LongAsObject(__tmp));") |
| 1330 | self.emit_line("}") |
| 1331 | elif isinstance(rtype, RTuple): |
| 1332 | for i, item_type in enumerate(rtype.types): |
| 1333 | self.emit_gc_clear(f"{target}.f{i}", item_type) |
| 1334 | elif isinstance(rtype, RVec): |
| 1335 | prefix = VEC_MACRO_PREFIX[rtype._ctype] |
| 1336 | self.emit_line(f"if ({target}.items) {{") |
| 1337 | self.emit_line(f" Py_DECREF({prefix}_BUF({target}));") |
| 1338 | self.emit_line(f" {target}.items = NULL;") |
| 1339 | self.emit_line("}") |
| 1340 | elif self.ctype(rtype) == "PyObject *" and self.c_undefined_value(rtype) == "NULL": |
| 1341 | # The simplest case. |
| 1342 | self.emit_line(f"Py_CLEAR({target});") |
| 1343 | else: |
| 1344 | assert False, "emit_gc_clear() not implemented for %s" % repr(rtype) |
| 1345 | |
| 1346 | def emit_reuse_clear(self, target: str, rtype: RType) -> None: |
| 1347 | """Emit attribute clear before object is added into freelist. |
no test coverage detected