Compute alignment correctly
The code previously assumed that everything has to be aligned to a 4 byte boundary. This assumption is wrong as e.g. the STR struct from xproto shows. Instead, each type has to be aligned to its natural alignment. So a char doesn't need any alignment, a INT16 gets aligned to a 2-byte-boundary and a INT32 gets the old 4 byte alignment. I'm not 100% sure that this commit is correct, but some quick tests with awesome and cairo-xcb went well. This commit causes lots of dead assignments to xcb_align_to since only the last field's alignment is actually used, but this simplified this patch a lot. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=34037 Signed-off-by: Uli Schlachter <psychon@znc.in> Signed-off-by: Peter Harris <pharris@opentext.com>
This commit is contained in:
parent
4f25ee1644
commit
aa02096b8e
|
@ -171,6 +171,7 @@ def c_open(self):
|
|||
_c('#include <stdlib.h>')
|
||||
_c('#include <string.h>')
|
||||
_c('#include <assert.h>')
|
||||
_c('#include <stddef.h> /* for offsetof() */')
|
||||
_c('#include "xcbext.h"')
|
||||
_c('#include "%s.h"', _ns.header)
|
||||
|
||||
|
@ -183,6 +184,9 @@ def c_open(self):
|
|||
_h('extern "C" {')
|
||||
_h('#endif')
|
||||
|
||||
_h('')
|
||||
_h('#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member)')
|
||||
|
||||
if _ns.is_ext:
|
||||
_h('')
|
||||
_h('#define XCB_%s_MAJOR_VERSION %s', _ns.ext_name.upper(), _ns.major_version)
|
||||
|
@ -637,7 +641,7 @@ def get_serialize_params(context, self, buffer_var='_buffer', aux_var='_aux'):
|
|||
|
||||
def _c_serialize_helper_insert_padding(context, code_lines, space, postpone):
|
||||
code_lines.append('%s /* insert padding */' % space)
|
||||
code_lines.append('%s xcb_pad = -xcb_block_len & 3;' % space)
|
||||
code_lines.append('%s xcb_pad = -xcb_block_len & (xcb_align_to - 1);' % space)
|
||||
# code_lines.append('%s printf("automatically inserting padding: %%%%d\\n", xcb_pad);' % space)
|
||||
code_lines.append('%s xcb_buffer_len += xcb_block_len + xcb_pad;' % space)
|
||||
|
||||
|
@ -993,6 +997,8 @@ def _c_serialize_helper_fields(context, self,
|
|||
code_lines.append('%s xcb_parts_idx++;' % space)
|
||||
count += 1
|
||||
|
||||
code_lines.append('%s xcb_align_to = ALIGNOF(%s);' % (space, 'char' if field.c_field_type == 'void' else field.c_field_type))
|
||||
|
||||
need_padding = True
|
||||
if self.var_followed_by_fixed_fields:
|
||||
need_padding = False
|
||||
|
@ -1100,9 +1106,11 @@ def _c_serialize(context, self):
|
|||
_c(' %s *xcb_out = *_buffer;', self.c_type)
|
||||
_c(' unsigned int xcb_out_pad = -sizeof(%s) & 3;', self.c_type)
|
||||
_c(' unsigned int xcb_buffer_len = sizeof(%s) + xcb_out_pad;', self.c_type)
|
||||
_c(' unsigned int xcb_align_to;')
|
||||
else:
|
||||
_c(' char *xcb_out = *_buffer;')
|
||||
_c(' unsigned int xcb_buffer_len = 0;')
|
||||
_c(' unsigned int xcb_align_to;')
|
||||
prefix = [('_aux', '->', self)]
|
||||
aux_ptr = 'xcb_out'
|
||||
|
||||
|
@ -1125,6 +1133,7 @@ def _c_serialize(context, self):
|
|||
_c(' unsigned int xcb_buffer_len = 0;')
|
||||
_c(' unsigned int xcb_block_len = 0;')
|
||||
_c(' unsigned int xcb_pad = 0;')
|
||||
_c(' unsigned int xcb_align_to;')
|
||||
|
||||
elif 'sizeof' == context:
|
||||
param_names = [p[2] for p in params]
|
||||
|
@ -1169,6 +1178,7 @@ def _c_serialize(context, self):
|
|||
_c(' unsigned int xcb_buffer_len = 0;')
|
||||
_c(' unsigned int xcb_block_len = 0;')
|
||||
_c(' unsigned int xcb_pad = 0;')
|
||||
_c(' unsigned int xcb_align_to;')
|
||||
|
||||
_c('')
|
||||
for t in temp_vars:
|
||||
|
|
Loading…
Reference in New Issue