diff options
author | Alex Plotnick <shrike@netaxs.com> | 2012-02-29 11:59:57 -0500 |
---|---|---|
committer | Julien Danjou <julien@danjou.info> | 2012-03-22 21:29:10 +0100 |
commit | 057b54d4bcd5b383343e00a3685e6b1ef343c2d2 (patch) | |
tree | d2c6b84efcd2c9ece3a1aaf45cf2e76e28887bd4 | |
parent | c5ff7fbf5a53cc20984a20d5461be2fc1f1eac39 (diff) |
Avoid reference cycles in response instances.
The issue is with fields that use self as the parent buffer; we end
up with cycles that the GC can't collect, since buffer objects aren't
GC-aware.
Also took the opportunity to replace separate "count" variables with
offsets wherever possible, and skip size calculations entirely for
fixed-size Unions.
Signed-off-by: Julien Danjou <julien@danjou.info>
-rwxr-xr-x | src/py_client.py | 67 |
1 files changed, 35 insertions, 32 deletions
diff --git a/src/py_client.py b/src/py_client.py index 61be2ae..d132f43 100755 --- a/src/py_client.py +++ b/src/py_client.py @@ -304,7 +304,6 @@ def _py_type_alignsize(field): def _py_complex(self, name): need_alignment = False - _py(' count = 0') for field in self.fields: if field.auto: @@ -319,33 +318,33 @@ def _py_complex(self, name): (format, size, list) = _py_flush_format() if len(list) > 0: - _py(' (%s,) = unpack_from(\'%s\', self, count)', list, format) + _py(' (%s,) = unpack_from(\'%s\', parent, offset)', list, format) if size > 0: - _py(' count += %d', size) + _py(' offset += %d', size) if need_alignment: - _py(' count += xcb.type_pad(%d, count)', _py_type_alignsize(field)) + _py(' offset += xcb.type_pad(%d, offset)', _py_type_alignsize(field)) need_alignment = True if field.type.is_list: - _py(' self.%s = xcb.List(self, count, %s, %s, %d)', _n(field.field_name), _py_get_expr(field.type.expr), field.py_listtype, field.py_listsize) - _py(' count += len(self.%s.buf())', _n(field.field_name)) + _py(' self.%s = xcb.List(parent, offset, %s, %s, %d)', _n(field.field_name), _py_get_expr(field.type.expr), field.py_listtype, field.py_listsize) + _py(' offset += len(self.%s.buf())', _n(field.field_name)) elif field.type.is_container and field.type.fixed_size(): - _py(' self.%s = %s(self, count, %s)', _n(field.field_name), field.py_type, field.type.size) - _py(' count += %s', field.type.size) + _py(' self.%s = %s(parent, offset, %s)', _n(field.field_name), field.py_type, field.type.size) + _py(' offset += %s', field.type.size) else: - _py(' self.%s = %s(self, count)', _n(field.field_name), field.py_type) - _py(' count += len(self.%s)', _n(field.field_name)) + _py(' self.%s = %s(parent, offset)', _n(field.field_name), field.py_type) + _py(' offset += len(self.%s)', _n(field.field_name)) (format, size, list) = _py_flush_format() if len(list) > 0: if need_alignment: - _py(' count += xcb.type_pad(4, count)') - _py(' (%s,) = unpack_from(\'%s\', self, count)', list, format) - _py(' count += %d', size) + _py(' offset += xcb.type_pad(4, offset)') + _py(' (%s,) = unpack_from(\'%s\', parent, offset)', list, format) + _py(' offset += %d', size) if self.fixed_size() or self.is_reply: - if len(self.fields) > 0: + if self.fields and not all(field.auto or field.type.is_pad for field in self.fields): _py_popline() def py_struct(self, name): @@ -363,11 +362,12 @@ def py_struct(self, name): else: _py(' def __init__(self, parent, offset):') _py(' xcb.Struct.__init__(self, parent, offset)') + _py(' base = offset') _py_complex(self, name) if not self.fixed_size(): - _py(' xcb._resize_obj(self, count)') + _py(' xcb._resize_obj(self, offset - base)') def py_union(self, name): ''' @@ -384,25 +384,28 @@ def py_union(self, name): else: _py(' def __init__(self, parent, offset):') _py(' xcb.Union.__init__(self, parent, offset)') - - _py(' count = 0') + _py(' size = 0') for field in self.fields: if field.type.is_simple: - _py(' self.%s = unpack_from(\'%s\', self)', _n(field.field_name), field.type.py_format_str) - _py(' count = max(count, %s)', field.type.size) + _py(' self.%s = unpack_from(\'%s\', parent, offset)', _n(field.field_name), field.type.py_format_str) + if not self.fixed_size(): + _py(' size = max(size, %s)', field.type.size) elif field.type.is_list: - _py(' self.%s = xcb.List(self, 0, %s, %s, %s)', _n(field.field_name), _py_get_expr(field.type.expr), field.py_listtype, field.py_listsize) - _py(' count = max(count, len(self.%s.buf()))', _n(field.field_name)) + _py(' self.%s = xcb.List(parent, offset, %s, %s, %s)', _n(field.field_name), _py_get_expr(field.type.expr), field.py_listtype, field.py_listsize) + if not self.fixed_size(): + _py(' size = max(size, len(self.%s.buf()))', _n(field.field_name)) elif field.type.is_container and field.type.fixed_size(): - _py(' self.%s = %s(self, 0, %s)', _n(field.field_name), field.py_type, field.type.size) - _py(' count = max(count, %s)', field.type.size) + _py(' self.%s = %s(parent, offset, %s)', _n(field.field_name), field.py_type, field.type.size) + if not self.fixed_size(): + _py(' size = max(size, %s)', field.type.size) else: - _py(' self.%s = %s(self, 0)', _n(field.field_name), field.py_type) - _py(' count = max(count, len(self.%s))', _n(field.field_name)) + _py(' self.%s = %s(parent, offset)', _n(field.field_name), field.py_type) + if not self.fixed_size(): + _py(' size = max(size, len(self.%s))', _n(field.field_name)) if not self.fixed_size(): - _py(' xcb._resize_obj(self, count)') + _py(' xcb._resize_obj(self, size)') def _py_reply(self, name): ''' @@ -413,8 +416,8 @@ def _py_reply(self, name): _py_setlevel(0) _py('') _py('class %s(xcb.Reply):', self.py_reply_name) - _py(' def __init__(self, parent):') - _py(' xcb.Reply.__init__(self, parent)') + _py(' def __init__(self, parent, offset=0):') + _py(' xcb.Reply.__init__(self, parent, offset)') _py_complex(self, name) @@ -541,8 +544,8 @@ def py_event(self, name): _py_setlevel(0) _py('') _py('class %s(xcb.Event):', self.py_event_name) - _py(' def __init__(self, parent):') - _py(' xcb.Event.__init__(self, parent)') + _py(' def __init__(self, parent, offset=0):') + _py(' xcb.Event.__init__(self, parent, offset)') _py_complex(self, name) @@ -560,8 +563,8 @@ def py_error(self, name): _py_setlevel(0) _py('') _py('class %s(xcb.Error):', self.py_error_name) - _py(' def __init__(self, parent):') - _py(' xcb.Error.__init__(self, parent)') + _py(' def __init__(self, parent, offset=0):') + _py(' xcb.Error.__init__(self, parent, offset)') _py_complex(self, name) |