def generate_setter(cl: ClassIR, attr: str, rtype: RType, emitter: Emitter) -> None: emitter.emit_line('static int') emitter.emit_line('{}({} *self, PyObject *value, void *closure)'.format( setter_name(cl, attr, emitter.names), cl.struct_name(emitter.names))) emitter.emit_line('{') if rtype.is_refcounted: emit_undefined_check(rtype, emitter, attr, '!=') emitter.emit_dec_ref('self->{}'.format(attr), rtype) emitter.emit_line('}') emitter.emit_line('if (value != NULL) {') if rtype.is_unboxed: emitter.emit_unbox('value', 'tmp', rtype, custom_failure='return -1;', declare_dest=True) elif is_same_type(rtype, object_rprimitive): emitter.emit_line('PyObject *tmp = value;') else: emitter.emit_cast('value', 'tmp', rtype, declare_dest=True) emitter.emit_lines('if (!tmp)', ' return -1;') emitter.emit_inc_ref('tmp', rtype) emitter.emit_line('self->{} = tmp;'.format(attr)) emitter.emit_line('} else') emitter.emit_line(' self->{} = {};'.format( attr, emitter.c_undefined_value(rtype))) emitter.emit_line('return 0;') emitter.emit_line('}')
def generate_native_getters_and_setters(cl: ClassIR, emitter: Emitter) -> None: for attr, rtype in cl.attributes.items(): # Native getter emitter.emit_line('{}{}({} *self)'.format( emitter.ctype_spaced(rtype), native_getter_name(cl, attr, emitter.names), cl.struct_name(emitter.names))) emitter.emit_line('{') if rtype.is_refcounted: emit_undefined_check(rtype, emitter, attr, '==') emitter.emit_lines( 'PyErr_SetString(PyExc_AttributeError, "attribute {} of {} undefined");' .format(repr(attr), repr(cl.name)), '} else {') emitter.emit_inc_ref('self->{}'.format(attr), rtype) emitter.emit_line('}') emitter.emit_line('return self->{};'.format(attr)) emitter.emit_line('}') emitter.emit_line() # Native setter emitter.emit_line('bool {}({} *self, {}value)'.format( native_setter_name(cl, attr, emitter.names), cl.struct_name(emitter.names), emitter.ctype_spaced(rtype))) emitter.emit_line('{') if rtype.is_refcounted: emit_undefined_check(rtype, emitter, attr, '!=') emitter.emit_dec_ref('self->{}'.format(attr), rtype) emitter.emit_line('}') # This steal the reference to src, so we don't need to increment the arg emitter.emit_lines('self->{} = value;'.format(attr), 'return 1;', '}') emitter.emit_line()
def generate_native_getters_and_setters(cl: ClassIR, emitter: Emitter) -> None: for attr, rtype in cl.attributes: emitter.emit_line('{}{}({} *self)'.format(rtype.ctype_spaced, native_getter_name(cl.name, attr), cl.struct_name)) emitter.emit_line('{') if rtype.is_refcounted: emitter.emit_line('if (self->{} != {}) {{'.format(attr, rtype.c_undefined_value)) emitter.emit_inc_ref('self->{}'.format(attr), rtype) emitter.emit_line('}') emitter.emit_line('return self->{};'.format(attr)) emitter.emit_line('}') emitter.emit_line() emitter.emit_line('void {}({} *self, {}value)'.format(native_setter_name(cl.name, attr), cl.struct_name, rtype.ctype_spaced)) emitter.emit_line('{') if rtype.is_refcounted: emitter.emit_line('if (self->{} != {}) {{'.format(attr, rtype.c_undefined_value)) emitter.emit_dec_ref('self->{}'.format(attr), rtype) emitter.emit_line('}') emitter.emit_inc_ref('value'.format(attr), rtype) emitter.emit_line('self->{} = value;'.format(attr)) emitter.emit_line('}') emitter.emit_line()
def generate_getter(cl: ClassIR, attr: str, rtype: RType, emitter: Emitter) -> None: emitter.emit_line('static PyObject *') emitter.emit_line('{}({} *self, void *closure)'.format(getter_name(cl, attr, emitter.names), cl.struct_name(emitter.names))) emitter.emit_line('{') emitter.emit_line('if (self->{} == {}) {{'.format(attr, emitter.c_undefined_value(rtype))) emitter.emit_line('PyErr_SetString(PyExc_AttributeError,') emitter.emit_line(' "attribute {} of {} undefined");'.format(repr(attr), repr(cl.name))) emitter.emit_line('return NULL;') emitter.emit_line('}') emitter.emit_inc_ref('self->{}'.format(attr), rtype) emitter.emit_box('self->{}'.format(attr), 'retval', rtype, declare_dest=True) emitter.emit_line('return retval;') emitter.emit_line('}')
def generate_native_getters_and_setters(cl: ClassIR, emitter: Emitter) -> None: for attr, rtype in cl.attributes.items(): # Native getter emitter.emit_line('{}{}({} *self)'.format(emitter.ctype_spaced(rtype), native_getter_name(cl, attr, emitter.names), cl.struct_name(emitter.names))) emitter.emit_line('{') if rtype.is_refcounted: emitter.emit_lines( 'if (self->{} == {}) {{'.format(attr, emitter.c_undefined_value(rtype)), 'PyErr_SetString(PyExc_AttributeError, "attribute {} of {} undefined");'.format( repr(attr), repr(cl.name)), '} else {') emitter.emit_inc_ref('self->{}'.format(attr), rtype) emitter.emit_line('}') emitter.emit_line('return self->{};'.format(attr)) emitter.emit_line('}') emitter.emit_line() # Native setter emitter.emit_line( 'bool {}({} *self, {}value)'.format(native_setter_name(cl, attr, emitter.names), cl.struct_name(emitter.names), emitter.ctype_spaced(rtype))) emitter.emit_line('{') if rtype.is_refcounted: emitter.emit_line('if (self->{} != {}) {{'.format(attr, emitter.c_undefined_value(rtype))) emitter.emit_dec_ref('self->{}'.format(attr), rtype) emitter.emit_line('}') emitter.emit_inc_ref('value'.format(attr), rtype) emitter.emit_lines('self->{} = value;'.format(attr), 'return 1;', '}') emitter.emit_line()
def generate_setter(cl: ClassIR, attr: str, rtype: RType, emitter: Emitter) -> None: emitter.emit_line('static int') emitter.emit_line('{}({} *self, PyObject *value, void *closure)'.format( setter_name(cl.name, attr), cl.struct_name)) emitter.emit_line('{') if rtype.is_refcounted: emitter.emit_line('if (self->{} != {}) {{'.format(attr, rtype.c_undefined_value)) emitter.emit_dec_ref('self->{}'.format(attr), rtype) emitter.emit_line('}') emitter.emit_line('if (value != NULL) {') if rtype.supports_unbox: emitter.emit_unbox('value', 'tmp', rtype, 'abort();',declare_dest=True) else: emitter.emit_cast('value', 'tmp', rtype, 'abort();',declare_dest=True) emitter.emit_inc_ref('tmp', rtype) emitter.emit_line('self->{} = tmp;'.format(attr)) emitter.emit_line('} else') emitter.emit_line(' self->{} = {};'.format(attr, rtype.c_undefined_value)) emitter.emit_line('return 0;') emitter.emit_line('}')