예제 #1
0
파일: xtypes.py 프로젝트: spkldr/rpi2
    def __init__(self, name):
        '''
        Default structure initializer.  Sets up default fields.

        Public fields:
        name is a tuple of strings specifying the full type name.
        size is the size of the datatype in bytes, or None if variable-sized.
        nmemb is 1 for non-list types, None for variable-sized lists, otherwise number of elts.
        booleans for identifying subclasses, because I can't figure out isinstance().
        '''
        self.name = name
        self.size = None
        self.nmemb = None
        self.resolved = False

        # Screw isinstance().
        self.is_simple = False
        self.is_list = False
        self.is_expr = False
        self.is_container = False
        self.is_reply = False
        self.is_union = False
        self.is_pad = False
        self.is_switch = False
        self.is_case_or_bitcase = False
        self.is_bitcase = False
        self.is_case = False
        self.required_start_align = Alignment()

        # the biggest align value of an align-pad contained in this type
        self.max_align_pad = 1
예제 #2
0
    def __init__(self, name, size):
        Type.__init__(self, name)
        self.size = size
        self.nmemb = 1

        # compute the required start_alignment based on the size of the type
        self.required_start_align = Alignment.for_primitive_type(self.size)
예제 #3
0
    def __init__(self, name):
        '''
        Default structure initializer.  Sets up default fields.

        Public fields:
        name is a tuple of strings specifying the full type name.
        size is the size of the datatype in bytes, or None if variable-sized.
        nmemb is 1 for non-list types, None for variable-sized lists, otherwise number of elts.
        booleans for identifying subclasses, because I can't figure out isinstance().
        '''
        self.name = name
        self.size = None
        self.nmemb = None
        self.resolved = False

        # Screw isinstance().
        self.is_simple = False
        self.is_list = False
        self.is_expr = False
        self.is_container = False
        self.is_reply = False
        self.is_union = False
        self.is_pad = False
        self.is_switch = False
        self.is_case_or_bitcase = False
        self.is_bitcase = False
        self.is_case = False
        self.required_start_align = Alignment()

        # the biggest align value of an align-pad contained in this type
        self.max_align_pad = 1
예제 #4
0
파일: xtypes.py 프로젝트: spkldr/rpi2
    def calc_minimally_required_start_align(self, callstack, log):
        # calculate the minimally required start_align that causes no
        # align errors
        best_log = None
        best_failed_align = None
        for align in [1, 2, 4, 8]:
            for offset in range(0, align):
                align_candidate = Alignment(align, offset)
                if verbose_align_log:
                    print("trying %s for %s" %
                          (str(align_candidate), str(self)))
                my_log = AlignmentLog()
                if self.is_possible_start_align(align_candidate, callstack,
                                                my_log):
                    log.append(my_log)
                    if verbose_align_log:
                        print("found start-align %s for %s" %
                              (str(align_candidate), str(self)))
                    return align_candidate
                else:
                    my_ok_count = my_log.ok_count()
                    if (best_log is None or my_ok_count > best_log.ok_count()
                            or
                        (my_ok_count == best_log.ok_count()
                         and align_candidate.align > best_failed_align.align)
                            and align_candidate.align != 8):
                        best_log = my_log
                        best_failed_align = align_candidate

        # none of the candidates applies
        # this type has illegal internal aligns for all possible start_aligns
        if verbose_align_log:
            print("didn't find start-align for %s" % str(self))
        log.append(best_log)
        return None
예제 #5
0
파일: xtypes.py 프로젝트: spkldr/rpi2
    def unchecked_get_alignment_after(self, start_align, callstack, log):
        if self.align <= 1:
            # fixed size pad
            after_align = start_align.align_after_fixed_size(
                self.get_total_size())
            if log is not None:
                if after_align is None:
                    log.fail(
                        start_align, "", self, callstack,
                        "align after fixed size pad of size %d failed" %
                        self.size)
                else:
                    log.ok(start_align, "", self, callstack, after_align)

            return after_align

        # align-pad
        assert self.align > 1
        assert self.size == 1
        assert self.nmemb == 1
        if (start_align.offset == 0 and self.align <= start_align.align
                and start_align.align % self.align == 0):
            # the alignment pad is size 0 because the start_align
            # is already sufficiently aligned -> return the start_align
            after_align = start_align
        else:
            # the alignment pad has nonzero size -> return the alignment
            # that is guaranteed by it, independently of the start_align
            after_align = Alignment(self.align, 0)

        if log is not None:
            log.ok(start_align, "", self, callstack, after_align)

        return after_align
예제 #6
0
파일: xtypes.py 프로젝트: spkldr/rpi2
    def __init__(self, name, size):
        Type.__init__(self, name)
        self.size = size
        self.nmemb = 1

        # compute the required start_alignment based on the size of the type
        self.required_start_align = Alignment.for_primitive_type(self.size)
예제 #7
0
파일: xtypes.py 프로젝트: spkldr/rpi2
    def __init__(self, name, elt):
        ComplexType.__init__(self, name, elt)
        self.is_reply = True
        self.doc = None
        if self.required_start_align is None:
            self.required_start_align = Alignment(4, 0)

        for child in list(elt):
            if child.tag == 'doc':
                self.doc = Doc(name, child)
예제 #8
0
파일: xtypes.py 프로젝트: spkldr/rpi2
    def __init__(self, name, elt):
        ComplexType.__init__(self, name, elt)
        self.reply = None
        self.doc = None
        self.opcode = elt.get('opcode')
        if self.required_start_align is None:
            self.required_start_align = Alignment(4, 0)

        for child in list(elt):
            if child.tag == 'reply':
                self.reply = Reply(name, child)
            if child.tag == 'doc':
                self.doc = Doc(name, child)
예제 #9
0
파일: xtypes.py 프로젝트: spkldr/rpi2
    def __init__(self, elt):
        Type.__init__(self, tcard8.name)
        self.is_pad = True
        self.size = 1
        self.nmemb = 1
        self.align = 1
        if elt != None:
            self.nmemb = int(elt.get('bytes', "1"), 0)
            self.align = int(elt.get('align', "1"), 0)
            self.serialize = elt.get('serialize',
                                     "false").lower() in true_values

        # pads don't require any alignment at their start
        self.required_start_align = Alignment(1, 0)
예제 #10
0
파일: xtypes.py 프로젝트: spkldr/rpi2
    def __init__(self, name, elt):
        ComplexType.__init__(self, name, elt)

        if self.required_start_align is None:
            self.required_start_align = Alignment(4, 0)

        self.opcodes = {}

        self.has_seq = not bool(elt.get('no-sequence-number'))

        self.is_ge_event = bool(elt.get('xge'))

        self.doc = None
        for item in list(elt):
            if item.tag == 'doc':
                self.doc = Doc(name, item)
예제 #11
0
파일: xtypes.py 프로젝트: spkldr/rpi2
    def __init__(self, name, elt):
        Type.__init__(self, name)
        self.is_container = True
        self.elt = elt
        self.fields = []
        self.nmemb = 1
        self.size = 0
        self.lenfield_parent = [self]
        self.fds = []

        # get required_start_alignment
        required_start_align_element = elt.find("required_start_align")
        if required_start_align_element is None:
            # unknown -> mark for autocompute
            self.required_start_align = None
        else:
            self.required_start_align = Alignment(
                int(required_start_align_element.get('align', "4"), 0),
                int(required_start_align_element.get('offset', "0"), 0))
            if verbose_align_log:
                print("Explicit start-align for %s: %s\n" %
                      (self, self.required_start_align))
예제 #12
0
class Type(object):
    '''
    Abstract base class for all XCB data types.
    Contains default fields, and some abstract methods.
    '''
    def __init__(self, name):
        '''
        Default structure initializer.  Sets up default fields.

        Public fields:
        name is a tuple of strings specifying the full type name.
        size is the size of the datatype in bytes, or None if variable-sized.
        nmemb is 1 for non-list types, None for variable-sized lists, otherwise number of elts.
        booleans for identifying subclasses, because I can't figure out isinstance().
        '''
        self.name = name
        self.size = None
        self.nmemb = None
        self.resolved = False

        # Screw isinstance().
        self.is_simple = False
        self.is_list = False
        self.is_expr = False
        self.is_container = False
        self.is_reply = False
        self.is_union = False
        self.is_pad = False
        self.is_switch = False
        self.is_case_or_bitcase = False
        self.is_bitcase = False
        self.is_case = False
        self.required_start_align = Alignment()

        # the biggest align value of an align-pad contained in this type
        self.max_align_pad = 1

    def resolve(self, module):
        '''
        Abstract method for resolving a type.
        This should make sure any referenced types are already declared.
        '''
        raise Exception('abstract resolve method not overridden!')

    def out(self, name):
        '''
        Abstract method for outputting code.
        These are declared in the language-specific modules, and
        there must be a dictionary containing them declared when this module is imported!
        '''
        raise Exception('abstract out method not overridden!')

    def fixed_size(self):
        '''
        Abstract method for determining if the data type is fixed-size.
        '''
        raise Exception('abstract fixed_size method not overridden!')

    def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum=None):
        '''
        Default method for making a data type a member of a structure.
        Extend this if the data type needs to add an additional length field or something.

        module is the global module object.
        complex_type is the structure object.
        see Field for the meaning of the other parameters.
        '''
        new_field = Field(self, field_type, field_name, visible, wire, auto, enum)

        # We dump the _placeholder_byte if any fields are added.
        for (idx, field) in enumerate(complex_type.fields):
            if field == _placeholder_byte:
                complex_type.fields[idx] = new_field
                return

        complex_type.fields.append(new_field)
        new_field.parent = complex_type

    def make_fd_of(self, module, complex_type, fd_name):
        '''
        Method for making a fd member of a structure.
        '''
        new_fd = Field(self, module.get_type_name('INT32'), fd_name, True, False, False, None, True)
        # We dump the _placeholder_byte if any fields are added.
        for (idx, field) in enumerate(complex_type.fields):
            if field == _placeholder_byte:
                complex_type.fields[idx] = new_fd
                return

        complex_type.fields.append(new_fd)


    def get_total_size(self):
        '''
        get the total size of this type if it is fixed-size, otherwise None
        '''
        if self.fixed_size():
            if self.nmemb is None:
                return self.size
            else:
                return self.size * self.nmemb
        else:
            return None

    def get_align_offset(self):
        if self.required_start_align is None:
            return 0
        else:
            return self.required_start_align.offset

    def is_acceptable_start_align(self, start_align, callstack, log):
        return self.get_alignment_after(start_align, callstack, log) is not None

    def get_alignment_after(self, start_align, callstack, log):
        '''
        get the alignment after this type based on the given start_align.
        the start_align is checked for compatibility with the
        internal start align. If it is not compatible, then None is returned
        '''
        if self.required_start_align is None or self.required_start_align.is_guaranteed_at(start_align):
            return self.unchecked_get_alignment_after(start_align, callstack, log)
        else:
            if log is not None:
                log.fail(start_align, "", self, callstack + [self],
                    "start_align is incompatible with required_start_align %s"
                    % (str(self.required_start_align)))
            return None

    def unchecked_get_alignment_after(self, start_align, callstack, log):
        '''
        Abstract method for geting the alignment after this type
        when the alignment at the start is given, and when this type
        has variable size.
        '''
        raise Exception('abstract unchecked_get_alignment_after method not overridden!')


    @staticmethod
    def type_name_to_str(type_name):
        if isinstance(type_name, str):
            #already a string
            return type_name
        else:
            return ".".join(type_name)


    def __str__(self):
        return type(self).__name__ + " \"" + Type.type_name_to_str(self.name) + "\""
예제 #13
0
파일: xtypes.py 프로젝트: spkldr/rpi2
 def __init__(self, name, elt):
     ComplexType.__init__(self, name, elt)
     self.opcodes = {}
     if self.required_start_align is None:
         self.required_start_align = Alignment(4, 0)
예제 #14
0
파일: xtypes.py 프로젝트: spkldr/rpi2
class Type(object):
    '''
    Abstract base class for all XCB data types.
    Contains default fields, and some abstract methods.
    '''
    def __init__(self, name):
        '''
        Default structure initializer.  Sets up default fields.

        Public fields:
        name is a tuple of strings specifying the full type name.
        size is the size of the datatype in bytes, or None if variable-sized.
        nmemb is 1 for non-list types, None for variable-sized lists, otherwise number of elts.
        booleans for identifying subclasses, because I can't figure out isinstance().
        '''
        self.name = name
        self.size = None
        self.nmemb = None
        self.resolved = False

        # Screw isinstance().
        self.is_simple = False
        self.is_list = False
        self.is_expr = False
        self.is_container = False
        self.is_reply = False
        self.is_union = False
        self.is_pad = False
        self.is_switch = False
        self.is_case_or_bitcase = False
        self.is_bitcase = False
        self.is_case = False
        self.required_start_align = Alignment()

        # the biggest align value of an align-pad contained in this type
        self.max_align_pad = 1

    def resolve(self, module):
        '''
        Abstract method for resolving a type.
        This should make sure any referenced types are already declared.
        '''
        raise Exception('abstract resolve method not overridden!')

    def out(self, name):
        '''
        Abstract method for outputting code.
        These are declared in the language-specific modules, and
        there must be a dictionary containing them declared when this module is imported!
        '''
        raise Exception('abstract out method not overridden!')

    def fixed_size(self):
        '''
        Abstract method for determining if the data type is fixed-size.
        '''
        raise Exception('abstract fixed_size method not overridden!')

    def make_member_of(self,
                       module,
                       complex_type,
                       field_type,
                       field_name,
                       visible,
                       wire,
                       auto,
                       enum=None):
        '''
        Default method for making a data type a member of a structure.
        Extend this if the data type needs to add an additional length field or something.

        module is the global module object.
        complex_type is the structure object.
        see Field for the meaning of the other parameters.
        '''
        new_field = Field(self, field_type, field_name, visible, wire, auto,
                          enum)

        # We dump the _placeholder_byte if any fields are added.
        for (idx, field) in enumerate(complex_type.fields):
            if field == _placeholder_byte:
                complex_type.fields[idx] = new_field
                return

        complex_type.fields.append(new_field)
        new_field.parent = complex_type

    def make_fd_of(self, module, complex_type, fd_name):
        '''
        Method for making a fd member of a structure.
        '''
        new_fd = Field(self, module.get_type_name('INT32'), fd_name, True,
                       False, False, None, True)
        # We dump the _placeholder_byte if any fields are added.
        for (idx, field) in enumerate(complex_type.fields):
            if field == _placeholder_byte:
                complex_type.fields[idx] = new_fd
                return

        complex_type.fields.append(new_fd)

    def get_total_size(self):
        '''
        get the total size of this type if it is fixed-size, otherwise None
        '''
        if self.fixed_size():
            if self.nmemb is None:
                return self.size
            else:
                return self.size * self.nmemb
        else:
            return None

    def get_align_offset(self):
        if self.required_start_align is None:
            return 0
        else:
            return self.required_start_align.offset

    def is_acceptable_start_align(self, start_align, callstack, log):
        return self.get_alignment_after(start_align, callstack,
                                        log) is not None

    def get_alignment_after(self, start_align, callstack, log):
        '''
        get the alignment after this type based on the given start_align.
        the start_align is checked for compatibility with the
        internal start align. If it is not compatible, then None is returned
        '''
        if self.required_start_align is None or self.required_start_align.is_guaranteed_at(
                start_align):
            return self.unchecked_get_alignment_after(start_align, callstack,
                                                      log)
        else:
            if log is not None:
                log.fail(
                    start_align, "", self, callstack + [self],
                    "start_align is incompatible with required_start_align %s"
                    % (str(self.required_start_align)))
            return None

    def unchecked_get_alignment_after(self, start_align, callstack, log):
        '''
        Abstract method for geting the alignment after this type
        when the alignment at the start is given, and when this type
        has variable size.
        '''
        raise Exception(
            'abstract unchecked_get_alignment_after method not overridden!')

    @staticmethod
    def type_name_to_str(type_name):
        if isinstance(type_name, str):
            #already a string
            return type_name
        else:
            return ".".join(type_name)

    def __str__(self):
        return type(self).__name__ + " \"" + Type.type_name_to_str(
            self.name) + "\""