コード例 #1
0
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('}')
コード例 #2
0
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()
コード例 #3
0
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()
コード例 #4
0
def generate_hash_wrapper(cl: ClassIR, fn: FuncIR, emitter: Emitter) -> str:
    """Generates a wrapper for native __hash__ methods."""
    name = '{}{}{}'.format(DUNDER_PREFIX, fn.name,
                           cl.name_prefix(emitter.names))
    emitter.emit_line(
        'static Py_ssize_t {name}(PyObject *self) {{'.format(name=name))
    emitter.emit_line('{}retval = {}{}(self);'.format(
        emitter.ctype_spaced(fn.ret_type), NATIVE_PREFIX,
        fn.cname(emitter.names)))
    emitter.emit_error_check('retval', fn.ret_type, 'return -1;')
    if is_int_rprimitive(fn.ret_type):
        emitter.emit_line('Py_ssize_t val = CPyTagged_AsLongLong(retval);')
    else:
        emitter.emit_line('Py_ssize_t val = PyLong_AsLongLong(retval);')
    emitter.emit_dec_ref('retval', fn.ret_type)
    emitter.emit_line('if (PyErr_Occurred()) return -1;')
    # We can't return -1 from a hash function..
    emitter.emit_line('if (val == -1) return -2;')
    emitter.emit_line('return val;')
    emitter.emit_line('}')

    return name
コード例 #5
0
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()
コード例 #6
0
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('}')