about summary refs log tree commit diff stats
path: root/miasm2/ir/translators/translator.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--miasm2/ir/translators/translator.py66
1 files changed, 36 insertions, 30 deletions
diff --git a/miasm2/ir/translators/translator.py b/miasm2/ir/translators/translator.py
index 2a971130..e3641843 100644
--- a/miasm2/ir/translators/translator.py
+++ b/miasm2/ir/translators/translator.py
@@ -1,4 +1,5 @@
 import miasm2.expression.expression as m2_expr
+from miasm2.core.utils import BoundedDict
 
 
 class Translator(object):
@@ -17,15 +18,15 @@ class Translator(object):
         cls.available_translators.append(translator)
 
     @classmethod
-    def to_language(cls, target_lang):
-        """Return the corresponding translator
+    def to_language(cls, target_lang, *args, **kwargs):
+        """Return the corresponding translator instance
         @target_lang: str (case insensitive) wanted language
         Raise a NotImplementedError in case of unmatched language
         """
         target_lang = target_lang.lower()
         for translator in cls.available_translators:
             if translator.__LANG__.lower() == target_lang:
-                return translator
+                return translator(*args, **kwargs)
 
         raise NotImplementedError("Unknown target language: %s" % target_lang)
 
@@ -34,78 +35,83 @@ class Translator(object):
         "Return the list of registered languages"
         return [translator.__LANG__ for translator in cls.available_translators]
 
-    @classmethod
-    def from_ExprInt(cls, expr):
+    def __init__(self, cache_size=1000):
+        """Instance a translator
+        @cache_size: (optional) Expr cache size
+        """
+        self._cache = BoundedDict(cache_size)
+
+    def from_ExprInt(self, expr):
         """Translate an ExprInt
         @expr: ExprInt to translate
         """
         raise NotImplementedError("Abstract method")
 
-    @classmethod
-    def from_ExprId(cls, expr):
+    def from_ExprId(self, expr):
         """Translate an ExprId
         @expr: ExprId to translate
         """
         raise NotImplementedError("Abstract method")
 
-    @classmethod
-    def from_ExprCompose(cls, expr):
+    def from_ExprCompose(self, expr):
         """Translate an ExprCompose
         @expr: ExprCompose to translate
         """
         raise NotImplementedError("Abstract method")
 
-    @classmethod
-    def from_ExprSlice(cls, expr):
+    def from_ExprSlice(self, expr):
         """Translate an ExprSlice
         @expr: ExprSlice to translate
         """
         raise NotImplementedError("Abstract method")
 
-    @classmethod
-    def from_ExprOp(cls, expr):
+    def from_ExprOp(self, expr):
         """Translate an ExprOp
         @expr: ExprOp to translate
         """
         raise NotImplementedError("Abstract method")
 
-    @classmethod
-    def from_ExprMem(cls, expr):
+    def from_ExprMem(self, expr):
         """Translate an ExprMem
         @expr: ExprMem to translate
         """
         raise NotImplementedError("Abstract method")
 
-    @classmethod
-    def from_ExprAff(cls, expr):
+    def from_ExprAff(self, expr):
         """Translate an ExprAff
         @expr: ExprAff to translate
         """
         raise NotImplementedError("Abstract method")
 
-    @classmethod
-    def from_ExprCond(cls, expr):
+    def from_ExprCond(self, expr):
         """Translate an ExprCond
         @expr: ExprCond to translate
         """
         raise NotImplementedError("Abstract method")
 
-    @classmethod
-    def from_expr(cls, expr):
+    def from_expr(self, expr):
         """Translate an expression according to its type
         @expr: expression to translate
         """
-        handlers = {m2_expr.ExprInt: cls.from_ExprInt,
-                    m2_expr.ExprId: cls.from_ExprId,
-                    m2_expr.ExprCompose: cls.from_ExprCompose,
-                    m2_expr.ExprSlice: cls.from_ExprSlice,
-                    m2_expr.ExprOp: cls.from_ExprOp,
-                    m2_expr.ExprMem: cls.from_ExprMem,
-                    m2_expr.ExprAff: cls.from_ExprAff,
-                    m2_expr.ExprCond: cls.from_ExprCond
+        # Use cache
+        if expr in self._cache:
+            return self._cache[expr]
+
+        # Handle Expr type
+        handlers = {m2_expr.ExprInt: self.from_ExprInt,
+                    m2_expr.ExprId: self.from_ExprId,
+                    m2_expr.ExprCompose: self.from_ExprCompose,
+                    m2_expr.ExprSlice: self.from_ExprSlice,
+                    m2_expr.ExprOp: self.from_ExprOp,
+                    m2_expr.ExprMem: self.from_ExprMem,
+                    m2_expr.ExprAff: self.from_ExprAff,
+                    m2_expr.ExprCond: self.from_ExprCond
                     }
         for target, handler in handlers.iteritems():
             if isinstance(expr, target):
-                return handler(expr)
+                ## Compute value and update the internal cache
+                ret = handler(expr)
+                self._cache[expr] = ret
+                return ret
         raise ValueError("Unhandled type for %s" % expr)