diff options
Diffstat (limited to '')
| -rw-r--r-- | miasm2/ir/translators/translator.py | 66 |
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) |