about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorserpilliere <serpilliere@users.noreply.github.com>2016-11-07 14:54:10 +0100
committerGitHub <noreply@github.com>2016-11-07 14:54:10 +0100
commitbb40ee0a6f2b40251e9cdc4c68f05367ee554e1f (patch)
tree7bc4fe53a2d486b60cbceee8bb0836750868ad63
parent3af8c4a5a6668cc89a4df3fb66222f4147a896b9 (diff)
parent35d6240db3b265b16a5899cf953668aef806cd6b (diff)
downloadmiasm-bb40ee0a6f2b40251e9cdc4c68f05367ee554e1f.tar.gz
miasm-bb40ee0a6f2b40251e9cdc4c68f05367ee554e1f.zip
Merge pull request #447 from commial/fix/simplify_mergeslice2slice
Expression: one pass merge_sliceto_slice
-rw-r--r--miasm2/expression/expression_helper.py97
1 files changed, 34 insertions, 63 deletions
diff --git a/miasm2/expression/expression_helper.py b/miasm2/expression/expression_helper.py
index 8babba70..36e5f1d5 100644
--- a/miasm2/expression/expression_helper.py
+++ b/miasm2/expression/expression_helper.py
@@ -36,74 +36,45 @@ def parity(a):
 
 def merge_sliceto_slice(expr):
     """
-    Apply basic factorisation on ExprCompose sub compoenents
+    Apply basic factorisation on ExprCompose sub components
     @expr: ExprCompose
     """
 
-    slices_raw = []
-    other_raw = []
-    integers_raw = []
+    out_args = []
+    last_index = 0
     for index, arg in expr.iter_args():
-        if isinstance(arg, m2_expr.ExprInt):
-            integers_raw.append((index, arg))
-        elif isinstance(arg, m2_expr.ExprSlice):
-            slices_raw.append((index, arg))
-        else:
-            other_raw.append((index, arg))
-
-    # Find max stop to determine size
-    max_size = sum([arg.size for arg in expr.args])
-
-    integers_merged = []
-    # Merge consecutive integers
-    while integers_raw:
-        index, arg = integers_raw.pop()
-        new_size = arg.size
-        value = int(arg)
-        while integers_raw:
-            prev_index, prev_value = integers_raw[-1]
-            # Check if intergers are consecutive
-            if prev_index + prev_value.size != index:
-                break
-            # Merge integers
-            index = prev_index
-            new_size += prev_value.size
-            value = value << prev_value.size
-            value |= int(prev_value)
-            integers_raw.pop()
-        integers_merged.append((index, m2_expr.ExprInt(value, new_size)))
-
-
-    slices_merged = []
-    # Merge consecutive slices
-    while slices_raw:
-        index, arg = slices_raw.pop()
-        value, slice_start, slice_stop = arg.arg, arg.start, arg.stop
-        while slices_raw:
-            prev_index, prev_value = slices_raw[-1]
-            # Check if slices are consecutive
-            if prev_index + prev_value.size != index:
-                break
-            # Check if slices can ben merged
-            if prev_value.arg != value:
-                break
-            if prev_value.stop != slice_start:
-                break
-            # Merge slices
-            index = prev_index
-            slice_start = prev_value.start
-            slices_raw.pop()
-        slices_merged.append((index, value[slice_start:slice_stop]))
-
-
-    new_args = slices_merged + integers_merged + other_raw
-    new_args.sort()
-    for i, (index, arg) in enumerate(new_args[:-1]):
-        assert index + arg.size == new_args[i+1][0]
-    ret = [arg[1] for arg in new_args]
-
-    return ret
+        # Init
+        if len(out_args) == 0:
+            out_args.append(arg)
+            continue
+
+        last_value = out_args[-1]
+        # Consecutive
+
+        if last_index + last_value.size == index:
+            # Merge consecutive integers
+            if (isinstance(arg, m2_expr.ExprInt) and
+                isinstance(last_value, m2_expr.ExprInt)):
+                new_size = last_value.size + arg.size
+                value = int(arg) << last_value.size
+                value |= int(last_value)
+                out_args[-1] = m2_expr.ExprInt(value, size=new_size)
+                continue
+
+            # Merge consecuvite slice
+            elif (isinstance(arg, m2_expr.ExprSlice) and
+                  isinstance(last_value, m2_expr.ExprSlice)):
+                value = arg.arg
+                if (last_value.arg == value and
+                    last_value.stop == arg.start):
+                    out_args[-1] = value[last_value.start:arg.stop]
+                    continue
+
+        # Unmergeable
+        last_index = index
+        out_args.append(arg)
 
+    return out_args
 
 
 op_propag_cst = ['+', '*', '^', '&', '|', '>>',