metadata: add is_dynamic to type objs and fix align
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Tue, 15 Mar 2016 19:41:57 +0000 (15:41 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Fri, 18 Mar 2016 21:54:59 +0000 (17:54 -0400)
The alignment of any type is None if it's not known statically,
i.e. if the type contains a variant containing more than one types
not having the same alignment, recursively.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
barectf/config.py
barectf/metadata.py

index ee86e78666af9145f53c9ffe0d3094cec5c8db5c..f8bbd018b582c194bc726624dd392b76a3705093 100644 (file)
@@ -813,7 +813,7 @@ class _MetadataDynamicTypesValidator:
         self._stack_pop()
 
     def _visit_array_type(self, t):
-        if not t.is_static:
+        if t.is_variable_length:
             # find length type
             try:
                 length_type = self._lookup_path(t.length, t)
index 5682582e003bc9b48a71f22fa51966882f9e8273..d225bdf0ee1d6bb8d3fcea99a55dfe2ec1ab679c 100644 (file)
@@ -40,15 +40,15 @@ class Encoding(enum.Enum):
 class Type:
     @property
     def align(self):
-        raise NotImplementedError()
+        return None
 
     @property
     def size(self):
-        raise NotImplementedError()
+        pass
 
-    @size.setter
-    def size(self, value):
-        self._size = value
+    @property
+    def is_dynamic(self):
+        raise NotImplementedError()
 
 
 class PropertyMapping:
@@ -119,7 +119,7 @@ class Integer(Type):
     def align(self):
         if self._align is None:
             if self._size is None:
-                return None
+                return
             else:
                 if self._size % 8 == 0:
                     return 8
@@ -144,6 +144,10 @@ class Integer(Type):
     def property_mappings(self):
         return self._property_mappings
 
+    @property
+    def is_dynamic(self):
+        return False
+
 
 class FloatingPoint(Type):
     def __init__(self):
@@ -188,6 +192,10 @@ class FloatingPoint(Type):
     def align(self, value):
         self._align = value
 
+    @property
+    def is_dynamic(self):
+        return False
+
 
 class Enum(Type):
     def __init__(self):
@@ -230,15 +238,15 @@ class Enum(Type):
 
         raise TypeError('wrong subscript type')
 
+    @property
+    def is_dynamic(self):
+        return False
+
 
 class String(Type):
     def __init__(self):
         self._encoding = Encoding.UTF8
 
-    @property
-    def size(self):
-        return None
-
     @property
     def align(self):
         return 8
@@ -251,6 +259,10 @@ class String(Type):
     def encoding(self, value):
         self._encoding = value
 
+    @property
+    def is_dynamic(self):
+        return True
+
 
 class Array(Type):
     def __init__(self):
@@ -278,21 +290,15 @@ class Array(Type):
         self._length = value
 
     @property
-    def is_static(self):
-        return type(self._length) is int
+    def is_variable_length(self):
+        return type(self._length) is not int
 
     @property
-    def size(self):
-        if self.length == 0:
-            return 0
+    def is_dynamic(self):
+        if self.is_variable_length:
+            return True
 
-        element_sz = self.element_type.size
-
-        if element_sz is None:
-            return None
-
-        # TODO: compute static size here
-        return None
+        return self.element_type.is_dynamic
 
 
 class Struct(Type):
@@ -310,14 +316,24 @@ class Struct(Type):
 
     @property
     def align(self):
-        fields_max = max([f.align for f in self.fields.values()] + [1])
+        align = self.min_align
+
+        for field in self.fields.values():
+            if field.align is None:
+                return
 
-        return max(fields_max, self._min_align)
+            if field.align > align:
+                align = field.align
+
+        return align
 
     @property
-    def size(self):
-        # TODO: compute static size here (if available)
-        return None
+    def is_dynamic(self):
+        for field in self.fields.values():
+            if field.is_dynamic:
+                return True
+
+        return False
 
     @property
     def fields(self):
@@ -334,14 +350,34 @@ class Variant(Type):
 
     @property
     def align(self):
-        return 1
+        single_type = self.get_single_type()
+
+        if single_type is not None:
+            return single_type.align
+
+        # if all the possible types have the same alignment, then
+        # there's only one possible alignment
+        align = None
+
+        for t in self.types.values():
+            if t.align is None:
+                return
+
+            if align is None:
+                # first
+                align = t.align
+            else:
+                if t.align != align:
+                    return
+
+        return align
 
     @property
     def size(self):
-        if len(self.members) == 1:
-            return list(self.members.values())[0].size
+        single_type = self.get_single_type()
 
-        return None
+        if single_type is not None:
+            return single_type.size
 
     @property
     def tag(self):
@@ -358,6 +394,19 @@ class Variant(Type):
     def __getitem__(self, key):
         return self.types[key]
 
+    def get_single_type(self):
+        if len(self.members) == 1:
+            return list(self.members.values())[0]
+
+    @property
+    def is_dynamic(self):
+        single_type = self.get_single_type()
+
+        if single_type is not None:
+            return single_type.is_dynamic
+
+        return True
+
 
 class Trace:
     def __init__(self):
This page took 0.029472 seconds and 4 git commands to generate.