about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorFlorent Monjalet <florent.monjalet@gmail.com>2015-12-14 11:12:42 +0100
committerFlorent Monjalet <florent.monjalet@gmail.com>2016-01-18 14:02:32 +0100
commit0379f8e91fa54fe641948f01bb98a76fab47033a (patch)
treecac94e8c737c1ebbecdc2e87c8252682ba242029
parente9ab0bd0f9c6dde642904cb473d57de9c81747b5 (diff)
downloadmiasm-0379f8e91fa54fe641948f01bb98a76fab47033a.tar.gz
miasm-0379f8e91fa54fe641948f01bb98a76fab47033a.zip
Types: adding the ("field", SomeMemType) syntax
Shorthand for ("field", SomeMemStruct.get_type()) in a Struct or
MemStruct fields definition.
-rw-r--r--miasm2/core/types.py23
-rw-r--r--test/core/types.py5
2 files changed, 21 insertions, 7 deletions
diff --git a/miasm2/core/types.py b/miasm2/core/types.py
index 03d23a5c..8d9687eb 100644
--- a/miasm2/core/types.py
+++ b/miasm2/core/types.py
@@ -507,19 +507,32 @@ class Struct(Type):
 
     def __init__(self, name, fields):
         self.name = name
-        # fields is immutable
-        self._fields = tuple(fields)
-        self._gen_fields()
+        # generates self._fields and self._fields_desc
+        self._gen_fields(fields)
 
-    def _gen_fields(self):
+    def _gen_fields(self, fields):
         """Precompute useful metadata on self.fields."""
         self._fields_desc = {}
         offset = 0
-        for name, field in self._fields:
+
+        # Build a proper (name, Field()) list, handling cases where the user
+        # supplies a MemType subclass instead of a Type instance
+        real_fields = []
+        for name, field in fields:
+            if isinstance(field, type) and issubclass(field, MemType):
+                if field._type is None:
+                    raise ValueError("%r has no static type; use a subclasses "
+                                     "with a non null _type or use a "
+                                     "Type instance")
+                field = field.get_type()
+            real_fields.append((name, field))
+
             # For reflexion
             field._set_self_type(self)
             self._fields_desc[name] = {"field": field, "offset": offset}
             offset += field.size
+        # fields is immutable
+        self._fields = tuple(real_fields)
 
     @property
     def fields(self):
diff --git a/test/core/types.py b/test/core/types.py
index 96765fe7..c59a68d6 100644
--- a/test/core/types.py
+++ b/test/core/types.py
@@ -256,7 +256,8 @@ class InStruct(MemStruct):
 class ContStruct(MemStruct):
     fields = [
         ("one", Num("B")),
-        ("instruct", InStruct.get_type()),
+        # Shorthand for: ("instruct", InStruct.get_type()),
+        ("instruct", InStruct),
         ("last", Num("B")),
     ]
 
@@ -290,7 +291,7 @@ class UniStruct(MemStruct):
     fields = [
         ("one", Num("B")),
         ("union", Union([
-            ("instruct", InStruct.get_type()),
+            ("instruct", InStruct),
             ("i", Num(">I")),
         ])),
         ("last", Num("B")),