(self, op: SetAttr)
| 499 | return None |
| 500 | |
| 501 | def visit_set_attr(self, op: SetAttr) -> None: |
| 502 | if op.error_kind == ERR_FALSE: |
| 503 | dest = self.reg(op) |
| 504 | obj = self.reg(op.obj) |
| 505 | src = self.reg(op.src) |
| 506 | rtype = op.class_type |
| 507 | cl = rtype.class_ir |
| 508 | attr_rtype, decl_cl = cl.attr_details(op.attr) |
| 509 | if op.is_propset: |
| 510 | # Again, use vtable access for properties... |
| 511 | assert not op.is_init and op.error_kind == ERR_FALSE, "%s %d %d %s" % ( |
| 512 | op.attr, |
| 513 | op.is_init, |
| 514 | op.error_kind, |
| 515 | rtype, |
| 516 | ) |
| 517 | version = "_TRAIT" if cl.is_trait else "" |
| 518 | self.emit_line( |
| 519 | "%s = CPY_SET_ATTR%s(%s, %s, %d, %s, %s, %s); /* %s */" |
| 520 | % ( |
| 521 | dest, |
| 522 | version, |
| 523 | obj, |
| 524 | self.emitter.type_struct_name(rtype.class_ir), |
| 525 | rtype.setter_index(op.attr), |
| 526 | src, |
| 527 | rtype.struct_name(self.names), |
| 528 | self.ctype(rtype.attr_type(op.attr)), |
| 529 | op.attr, |
| 530 | ) |
| 531 | ) |
| 532 | else: |
| 533 | # ...and struct access for normal attributes. |
| 534 | attr_expr = self.get_attr_expr(obj, op, decl_cl) |
| 535 | if not op.is_init and attr_rtype.is_refcounted: |
| 536 | # This is not an initialization (where we know that the attribute was |
| 537 | # previously undefined), so decref the old value. |
| 538 | always_defined = cl.is_always_defined(op.attr) |
| 539 | if not always_defined: |
| 540 | self.emitter.emit_undefined_attr_check( |
| 541 | attr_rtype, attr_expr, "!=", obj, op.attr, cl |
| 542 | ) |
| 543 | self.emitter.emit_dec_ref(attr_expr, attr_rtype) |
| 544 | if not always_defined: |
| 545 | self.emitter.emit_line("}") |
| 546 | elif attr_rtype.error_overlap and not cl.is_always_defined(op.attr): |
| 547 | # If there is overlap with the error value, update bitmap to mark |
| 548 | # attribute as defined. |
| 549 | self.emitter.emit_attr_bitmap_set(src, obj, attr_rtype, cl, op.attr) |
| 550 | |
| 551 | # This steals the reference to src, so we don't need to increment the arg |
| 552 | self.emitter.emit_line(f"{attr_expr} = {src};") |
| 553 | if op.error_kind == ERR_FALSE: |
| 554 | self.emitter.emit_line(f"{dest} = 1;") |
| 555 | |
| 556 | def visit_load_static(self, op: LoadStatic) -> None: |
| 557 | dest = self.reg(op) |
nothing calls this directly
no test coverage detected