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_arg_check(name: str, typ: RType, emitter: Emitter, error_code: str, optional: bool = False) -> None: """Insert a runtime check for argument and unbox if necessary. The object is named PyObject *obj_{}. This is expected to generate a value of name arg_{} (unboxed if necessary). For each primitive a runtime check ensures the correct type. """ if typ.is_unboxed: # Borrow when unboxing to avoid reference count manipulation. emitter.emit_unbox('obj_{}'.format(name), 'arg_{}'.format(name), typ, error_code, declare_dest=True, borrow=True, optional=optional) elif is_object_rprimitive(typ): # Object is trivial since any object is valid if optional: emitter.emit_line('PyObject *arg_{};'.format(name)) emitter.emit_line('if (obj_{} == NULL) {{'.format(name)) emitter.emit_line('arg_{} = {};'.format(name, emitter.c_error_value(typ))) emitter.emit_lines('} else {', 'arg_{} = obj_{}; '.format(name, name), '}') else: emitter.emit_line('PyObject *arg_{} = obj_{};'.format(name, name)) else: emitter.emit_cast('obj_{}'.format(name), 'arg_{}'.format(name), typ, declare_dest=True, optional=optional) if optional: emitter.emit_line('if (obj_{} != NULL && arg_{} == NULL) {}'.format( name, name, error_code)) else: emitter.emit_line('if (arg_{} == NULL) {}'.format(name, error_code))
def generate_arg_check(name: str, typ: RType, emitter: Emitter) -> None: """Insert a runtime check for argument and unbox if necessary. The object is named PyObject *obj_{}. This is expected to generate a value of name arg_{} (unboxed if necessary). For each primitive a runtime check ensures the correct type. """ if typ.is_unboxed: # Borrow when unboxing to avoid reference count manipulation. emitter.emit_unbox('obj_{}'.format(name), 'arg_{}'.format(name), typ, 'return NULL;', declare_dest=True, borrow=True) elif is_object_rprimitive(typ): # Trivial, since any object is valid. emitter.emit_line('PyObject *arg_{} = obj_{};'.format(name, name)) else: emitter.emit_cast('obj_{}'.format(name), 'arg_{}'.format(name), typ, declare_dest=True) emitter.emit_line('if (arg_{} == NULL) return NULL;'.format(name))
def generate_property_setter(cl: ClassIR, attr: str, arg_type: RType, func_ir: FuncIR, 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 arg_type.is_unboxed: emitter.emit_unbox('value', 'tmp', arg_type, custom_failure='return -1;', declare_dest=True) emitter.emit_line('{}{}((PyObject *) self, tmp);'.format( NATIVE_PREFIX, func_ir.cname(emitter.names))) else: emitter.emit_line('{}{}((PyObject *) self, value);'.format( NATIVE_PREFIX, func_ir.cname(emitter.names))) emitter.emit_line('return 0;') emitter.emit_line('}')
def generate_arg_check(name: str, typ: RType, emitter: Emitter) -> None: """Insert a runtime check for argument and unbox if necessary. The object is named PyObject *obj_{}. This is expected to generate a value of name arg_{} (unboxed if necessary). For each primitive a runtime check ensures the correct type. """ if typ.supports_unbox: # Borrow when unboxing to avoid reference count manipulation. emitter.emit_unbox('obj_{}'.format(name), 'arg_{}'.format(name), typ, 'return NULL;', declare_dest=True, borrow=True) else: emitter.emit_cast('obj_{}'.format(name), 'arg_{}'.format(name), typ, 'return NULL;', declare_dest=True)
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('}')