[Xcb-commit] src

Peter Harris peterh at kemper.freedesktop.org
Wed Aug 24 07:30:06 PDT 2011


 src/c_client.py |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

New commits:
commit aa02096b8e7f94ad3c998a8d5af54963ee860b13
Author: Uli Schlachter <psychon at znc.in>
Date:   Wed Aug 24 12:47:16 2011 +0200

    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 at znc.in>
    Signed-off-by: Peter Harris <pharris at opentext.com>

diff --git a/src/c_client.py b/src/c_client.py
index ef245c5..7a27c1f 100644
--- a/src/c_client.py
+++ b/src/c_client.py
@@ -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:


More information about the xcb-commit mailing list