def Js(val, Clamped=False):
    '''Converts Py type to PyJs type'''
    if isinstance(val, PyJs):
        return val
    elif val is None:
        return undefined
    elif isinstance(val, basestring):
        return PyJsString(val, StringPrototype)
    elif isinstance(val, bool):
        return true if val else false
    elif isinstance(val, float) or isinstance(val, int) or isinstance(
            val, long) or (NUMPY_AVAILABLE and isinstance(
                val,
                (numpy.int8, numpy.uint8, numpy.int16, numpy.uint16,
                 numpy.int32, numpy.uint32, numpy.float32, numpy.float64))):
        # This is supposed to speed things up. may not be the case
        if val in NUM_BANK:
            return NUM_BANK[val]
        return PyJsNumber(float(val), NumberPrototype)
    elif isinstance(val, FunctionType):
        return PyJsFunction(val, FunctionPrototype)
    #elif isinstance(val, ModuleType):
    #    mod = {}
    #    for name in dir(val):
    #        value = getattr(val, name)
    #        if isinstance(value, ModuleType):
    #            continue  # prevent recursive module conversion
    #        try:
    #            jsval = HJs(value)
    #        except RuntimeError:
    #            print 'Could not convert %s to PyJs object!' % name
    #            continue
    #        mod[name] = jsval
    #    return Js(mod)
    #elif isintance(val, ClassType):

    elif isinstance(val, dict):  # convert to object
        temp = PyJsObject({}, ObjectPrototype)
        for k, v in six.iteritems(val):
            temp.put(Js(k), Js(v))
        return temp
    elif isinstance(val, (list, tuple)):  #Convert to array
        return PyJsArray(val, ArrayPrototype)
    # convert to typedarray
    elif isinstance(val, JsObjectWrapper):
        return val.__dict__['_obj']
    elif NUMPY_AVAILABLE and isinstance(val, numpy.ndarray):
        if val.dtype == numpy.int8:
            return PyJsInt8Array(val, Int8ArrayPrototype)
        elif val.dtype == numpy.uint8 and not Clamped:
            return PyJsUint8Array(val, Uint8ArrayPrototype)
        elif val.dtype == numpy.uint8 and Clamped:
            return PyJsUint8ClampedArray(val, Uint8ClampedArrayPrototype)
        elif val.dtype == numpy.int16:
            return PyJsInt16Array(val, Int16ArrayPrototype)
        elif val.dtype == numpy.uint16:
            return PyJsUint16Array(val, Uint16ArrayPrototype)

        elif val.dtype == numpy.int32:
            return PyJsInt32Array(val, Int32ArrayPrototype)
        elif val.dtype == numpy.uint32:
            return PyJsUint16Array(val, Uint32ArrayPrototype)

        elif val.dtype == numpy.float32:
            return PyJsFloat32Array(val, Float32ArrayPrototype)
        elif val.dtype == numpy.float64:
            return PyJsFloat64Array(val, Float64ArrayPrototype)
    else:  # try to convert to js object
        return py_wrap(val)

def Js ( val , Clamped = False ) : if isinstance ( val , PyJs ) : return val elif val is None : return undefined elif isinstance ( val , basestring ) : return PyJsString ( val , StringPrototype ) elif isinstance ( val , bool ) : return true if val else false elif isinstance ( val , float ) or isinstance ( val , int ) or isinstance ( val , long ) or ( NUMPY_AVAILABLE and isinstance ( val , ( numpy . int8 , numpy . uint8 , numpy . int16 , numpy . uint16 , numpy . int32 , numpy . uint32 , numpy . float32 , numpy . float64 ) ) ) : if val in NUM_BANK : return NUM_BANK [ val ] return PyJsNumber ( float ( val ) , NumberPrototype ) elif isinstance ( val , FunctionType ) : return PyJsFunction ( val , FunctionPrototype ) elif isinstance ( val , dict ) : temp = PyJsObject ( { } , ObjectPrototype ) for k , v in six . iteritems ( val ) : temp . put ( Js ( k ) , Js ( v ) ) return temp elif isinstance ( val , ( list , tuple ) ) : return PyJsArray ( val , ArrayPrototype ) elif isinstance ( val , JsObjectWrapper ) : return val . __dict__ [ '_obj' ] elif NUMPY_AVAILABLE and isinstance ( val , numpy . ndarray ) : if val . dtype == numpy . int8 : return PyJsInt8Array ( val , Int8ArrayPrototype ) elif val . dtype == numpy . uint8 and not Clamped : return PyJsUint8Array ( val , Uint8ArrayPrototype ) elif val . dtype == numpy . uint8 and Clamped : return PyJsUint8ClampedArray ( val , Uint8ClampedArrayPrototype ) elif val . dtype == numpy . int16 : return PyJsInt16Array ( val , Int16ArrayPrototype ) elif val . dtype == numpy . uint16 : return PyJsUint16Array ( val , Uint16ArrayPrototype ) elif val . dtype == numpy . int32 : return PyJsInt32Array ( val , Int32ArrayPrototype ) elif val . dtype == numpy . uint32 : return PyJsUint16Array ( val , Uint32ArrayPrototype ) elif val . dtype == numpy . float32 : return PyJsFloat32Array ( val , Float32ArrayPrototype ) elif val . dtype == numpy . float64 : return PyJsFloat64Array ( val , Float64ArrayPrototype ) else : return py_wrap ( val )


def _set_name(self, name):
        '''name is py type'''
        if self.own.get('name'):
            self.func_name = name
            self.own['name']['value'] = Js(name)

def _set_name ( self , name ) : if self . own . get ( 'name' ) : self . func_name = name self . own [ 'name' ] [ 'value' ] = Js ( name )


def ConstructArray(self, py_arr):
        ''' note py_arr elems are NOT converted to PyJs types!'''
        arr = self.NewArray(len(py_arr))
        arr._init(py_arr)
        return arr

def ConstructArray ( self , py_arr ) : arr = self . NewArray ( len ( py_arr ) ) arr . _init ( py_arr ) return arr


def ConstructObject(self, py_obj):
        ''' note py_obj items are NOT converted to PyJs types! '''
        obj = self.NewObject()
        for k, v in py_obj.items():
            obj.put(unicode(k), v)
        return obj

def ConstructObject ( self , py_obj ) : obj = self . NewObject ( ) for k , v in py_obj . items ( ) : obj . put ( unicode ( k ) , v ) return obj


def emit(self, op_code, *args):
        ''' Adds op_code with specified args to tape '''
        self.tape.append(OP_CODES[op_code](*args))

def emit ( self , op_code , * args ) : self . tape . append ( OP_CODES [ op_code ] ( * args ) )


def compile(self, start_loc=0):
        ''' Records locations of labels and compiles the code '''
        self.label_locs = {} if self.label_locs is None else self.label_locs
        loc = start_loc
        while loc < len(self.tape):
            if type(self.tape[loc]) == LABEL:
                self.label_locs[self.tape[loc].num] = loc
                del self.tape[loc]
                continue
            loc += 1
        self.compiled = True

def compile ( self , start_loc = 0 ) : self . label_locs = { } if self . label_locs is None else self . label_locs loc = start_loc while loc < len ( self . tape ) : if type ( self . tape [ loc ] ) == LABEL : self . label_locs [ self . tape [ loc ] . num ] = loc del self . tape [ loc ] continue loc += 1 self . compiled = True


def pad(num, n=2, sign=False):
    '''returns n digit string representation of the num'''
    s = unicode(abs(num))
    if len(s) < n:
        s = '0' * (n - len(s)) + s
    if not sign:
        return s
    if num >= 0:
        return '+' + s
    else:
        return '-' + s

def pad ( num , n = 2 , sign = False ) : s = unicode ( abs ( num ) ) if len ( s ) < n : s = '0' * ( n - len ( s ) ) + s if not sign : return s if num >= 0 : return '+' + s else : return '-' + s


def replacement_template(rep, source, span, npar):
    """Takes the replacement template and some info about the match and returns filled template
       """
    n = 0
    res = ''
    while n < len(rep) - 1:
        char = rep[n]
        if char == '$':
            if rep[n + 1] == '$':
                res += '$'
                n += 2
                continue
            elif rep[n + 1] == '`':
                # replace with string that is BEFORE match
                res += source[:span[0]]
                n += 2
                continue
            elif rep[n + 1] == '\'':
                # replace with string that is AFTER match
                res += source[span[1]:]
                n += 2
                continue
            elif rep[n + 1] in DIGS:
                dig = rep[n + 1]
                if n + 2 < len(rep) and rep[n + 2] in DIGS:
                    dig += rep[n + 2]
                num = int(dig)
                # we will not do any replacements if we dont have this npar or dig is 0
                if not num or num > len(npar):
                    res += '$' + dig
                else:
                    # None - undefined has to be replaced with ''
                    res += npar[num - 1] if npar[num - 1] else ''
                n += 1 + len(dig)
                continue
        res += char
        n += 1
    if n < len(rep):
        res += rep[-1]
    return res

def replacement_template ( rep , source , span , npar ) : n = 0 res = '' while n < len ( rep ) - 1 : char = rep [ n ] if char == '$' : if rep [ n + 1 ] == '$' : res += '$' n += 2 continue elif rep [ n + 1 ] == '`' : res += source [ : span [ 0 ] ] n += 2 continue elif rep [ n + 1 ] == '\'' : res += source [ span [ 1 ] : ] n += 2 continue elif rep [ n + 1 ] in DIGS : dig = rep [ n + 1 ] if n + 2 < len ( rep ) and rep [ n + 2 ] in DIGS : dig += rep [ n + 2 ] num = int ( dig ) if not num or num > len ( npar ) : res += '$' + dig else : res += npar [ num - 1 ] if npar [ num - 1 ] else '' n += 1 + len ( dig ) continue res += char n += 1 if n < len ( rep ) : res += rep [ - 1 ] return res


def fix_js_args(func):
    '''Use this function when unsure whether func takes this and arguments as its last 2 args.
       It will append 2 args if it does not.'''
    fcode = six.get_function_code(func)
    fargs = fcode.co_varnames[fcode.co_argcount - 2:fcode.co_argcount]
    if fargs == ('this', 'arguments') or fargs == ('arguments', 'var'):
        return func
    code = append_arguments(six.get_function_code(func), ('this', 'arguments'))

    return types.FunctionType(
        code,
        six.get_function_globals(func),
        func.__name__,
        closure=six.get_function_closure(func))

def fix_js_args ( func ) : fcode = six . get_function_code ( func ) fargs = fcode . co_varnames [ fcode . co_argcount - 2 : fcode . co_argcount ] if fargs == ( 'this' , 'arguments' ) or fargs == ( 'arguments' , 'var' ) : return func code = append_arguments ( six . get_function_code ( func ) , ( 'this' , 'arguments' ) ) return types . FunctionType ( code , six . get_function_globals ( func ) , func . __name__ , closure = six . get_function_closure ( func ) )

Use this function when unsure whether func takes this and arguments as its last 2 args . It will append 2 args if it does not .


def emit(self, what, *args):
        ''' what can be either name of the op, or node, or a list of statements.'''
        if isinstance(what, basestring):
            return self.exe.emit(what, *args)
        elif isinstance(what, list):
            self._emit_statement_list(what)
        else:
            return getattr(self, what['type'])(**what)

def emit ( self , what , * args ) : if isinstance ( what , basestring ) : return self . exe . emit ( what , * args ) elif isinstance ( what , list ) : self . _emit_statement_list ( what ) else : return getattr ( self , what [ 'type' ] ) ( ** what )

what can be either name of the op or node or a list of statements .


def trans(ele, standard=False):
    """Translates esprima syntax tree to python by delegating to appropriate translating node"""
    try:
        node = globals().get(ele['type'])
        if not node:
            raise NotImplementedError('%s is not supported!' % ele['type'])
        if standard:
            node = node.__dict__[
                'standard'] if 'standard' in node.__dict__ else node
        return node(**ele)
    except:
        #print ele
        raise

def
trans
(
ele
,
standard
=
False
)
:
try
:
node
=
globals
(
)
.
get
(
ele
[
'type'
]
)
if
not
node
:
raise
NotImplementedError
(
'%s is not supported!'
%
ele
[
'type'
]
)
if
standard
:
node
=
node
.
__dict__
[
'standard'
]
if
'standard'
in
node
.
__dict__
else
node
return
node
(
**
ele
)
except
:
raise


def limited(func):
    '''Decorator limiting resulting line length in order to avoid python parser stack overflow -
      If expression longer than LINE_LEN_LIMIT characters then it will be moved to upper line
     USE ONLY ON EXPRESSIONS!!! '''

    def f(standard=False, **args):
        insert_pos = len(
            inline_stack.names
        )  # in case line is longer than limit we will have to insert the lval at current position
        # this is because calling func will change inline_stack.
        # we cant use inline_stack.require here because we dont know whether line overflows yet
        res = func(**args)
        if len(res) > LINE_LEN_LIMIT:
            name = inline_stack.require('LONG')
            inline_stack.names.pop()
            inline_stack.names.insert(insert_pos, name)
            res = 'def %s(var=var):\n    return %s\n' % (name, res)
            inline_stack.define(name, res)
            return name + '()'
        else:
            return res

    f.__dict__['standard'] = func
    return f

def
limited
(
func
)
:
def
f
(
standard
=
False
,
**
args
)
:
insert_pos
=
len
(
inline_stack
.
names
)
res
=
func
(
**
args
)
if
len
(
res
)
>
LINE_LEN_LIMIT
:
name
=
inline_stack
.
require
(
'LONG'
)
inline_stack
.
names
.
pop
(
)
inline_stack
.
names
.
insert
(
insert_pos
,
name
)
res
=
'def %s(var=var):\n    return %s\n'
%
(
name
,
res
)
inline_stack
.
define
(
name
,
res
)
return
name
+
'()'
else
:
return
res
f
.
__dict__
[
'standard'
]
=
func
return
f


def is_lval(t):
    """Does not chceck whether t is not resticted or internal"""
    if not t:
        return False
    i = iter(t)
    if i.next() not in IDENTIFIER_START:
        return False
    return all(e in IDENTIFIER_PART for e in i)

def is_lval ( t ) : if not t : return False i = iter ( t ) if i . next ( ) not in IDENTIFIER_START : return False return all ( e in IDENTIFIER_PART for e in i )


def translate_file(input_path, output_path):
    '''
    Translates input JS file to python and saves the it to the output path.
    It appends some convenience code at the end so that it is easy to import JS objects.

    For example we have a file 'example.js' with:   var a = function(x) {return x}
    translate_file('example.js', 'example.py')

    Now example.py can be easily importend and used:
    >>> from example import example
    >>> example.a(30)
    30
    '''
    js = get_file_contents(input_path)

    py_code = translate_js(js)
    lib_name = os.path.basename(output_path).split('.')[0]
    head = '__all__ = [%s]\n\n# Don\'t look below, you will not understand this Python code :) I don\'t.\n\n' % repr(
        lib_name)
    tail = '\n\n# Add lib to the module scope\n%s = var.to_python()' % lib_name
    out = head + py_code + tail
    write_file_contents(output_path, out)

Translates input JS file to python and saves the it to the output path . It appends some convenience code at the end so that it is easy to import JS objects .


def execute(self, js=None, use_compilation_plan=False):
        """executes javascript js in current context

        During initial execute() the converted js is cached for re-use. That means next time you
        run the same javascript snippet you save many instructions needed to parse and convert the
        js code to python code.

        This cache causes minor overhead (a cache dicts is updated) but the Js=>Py conversion process
        is typically expensive compared to actually running the generated python code.

        Note that the cache is just a dict, it has no expiration or cleanup so when running this
        in automated situations with vast amounts of snippets it might increase memory usage.
        """
        try:
            cache = self.__dict__['cache']
        except KeyError:
            cache = self.__dict__['cache'] = {}
        hashkey = hashlib.md5(js.encode('utf-8')).digest()
        try:
            compiled = cache[hashkey]
        except KeyError:
            code = translate_js(
                js, '', use_compilation_plan=use_compilation_plan)
            compiled = cache[hashkey] = compile(code, '<EvalJS snippet>',
                                                'exec')
        exec (compiled, self._context)

def
execute
(
self
,
js
=
,
use_compilation_plan
=
False
)
:
try
:
cache
=
self
.
__dict__
[
'cache'
]
except
KeyError
:
cache
=
self
.
__dict__
[
'cache'
]
=
{
}
hashkey
=
hashlib
.
md5
(
js
.
encode
(
'utf-8'
)
)
.
digest
(
)
try
:
compiled
=
cache
[
hashkey
]
except
KeyError
:
code
=
translate_js
(
js
,
''
,
use_compilation_plan
=
use_compilation_plan
)
compiled
=
cache
[
hashkey
]
=
compile
(
code
,
'<EvalJS snippet>'
,
'exec'
)
exec
(
compiled
,
self
.
_context
)


def eval(self, expression, use_compilation_plan=False):
        """evaluates expression in current context and returns its value"""
        code = 'PyJsEvalResult = eval(%s)' % json.dumps(expression)
        self.execute(code, use_compilation_plan=use_compilation_plan)
        return self['PyJsEvalResult']

def
eval
(
self
,
expression
,
use_compilation_plan
=
False
)
:
code
=
'PyJsEvalResult = eval(%s)'
%
json
.
dumps
(
expression
)
self
.
execute
(
code
,
use_compilation_plan
=
use_compilation_plan
)
return
self
[
'PyJsEvalResult'
]


def except_token(source, start, token, throw=True):
    """Token can be only a single char. Returns position after token if found. Otherwise raises syntax error if throw
    otherwise returns None"""
    start = pass_white(source, start)
    if start < len(source) and source[start] == token:
        return start + 1
    if throw:
        raise SyntaxError('Missing token. Expected %s' % token)
    return None

def
except_token
(
source
,
start
,
token
,
throw
=
True
)
:
start
=
pass_white
(
source
,
start
)
if
start
<
len
(
source
)
and
source
[
start
]
==
token
:
return
start
+
1
if
throw
:
raise
SyntaxError
(
'Missing token. Expected %s'
%
token
)
return

Token can be only a single char . Returns position after token if found . Otherwise raises syntax error if throw otherwise returns None


def parse_identifier(source, start, throw=True):
    """passes white space from start and returns first identifier,
       if identifier invalid and throw raises SyntaxError otherwise returns None"""
    start = pass_white(source, start)
    end = start
    if not end < len(source):
        if throw:
            raise SyntaxError('Missing identifier!')
        return None
    if source[end] not in IDENTIFIER_START:
        if throw:
            raise SyntaxError('Invalid identifier start: "%s"' % source[end])
        return None
    end += 1
    while end < len(source) and source[end] in IDENTIFIER_PART:
        end += 1
    if not is_valid_lval(source[start:end]):
        if throw:
            raise SyntaxError(
                'Invalid identifier name: "%s"' % source[start:end])
        return None
    return source[start:end], end

def
parse_identifier
(
source
,
start
,
throw
=
True
)
:
start
=
pass_white
(
source
,
start
)
end
=
start
if
not
end
<
len
(
source
)
:
if
throw
:
raise
SyntaxError
(
'Missing identifier!'
)
return
if
source
[
end
]
not
in
IDENTIFIER_START
:
if
throw
:
raise
SyntaxError
(
'Invalid identifier start: "%s"'
%
source
[
end
]
)
return
end
+=
1
while
end
<
len
(
source
)
and
source
[
end
]
in
IDENTIFIER_PART
:
end
+=
1
if
not
is_valid_lval
(
source
[
start
:
end
]
)
:
if
throw
:
raise
SyntaxError
(
'Invalid identifier name: "%s"'
%
source
[
start
:
end
]
)
return
return
source
[
start
:
end
]
,
end

passes white space from start and returns first identifier if identifier invalid and throw raises SyntaxError otherwise returns None


def to_arr(this):
    """Returns Python array from Js array"""
    return [this.get(str(e)) for e in xrange(len(this))]

def to_arr ( this ) : return [ this . get ( str ( e ) ) for e in xrange ( len ( this ) ) ]


def do_statement(source, start):
    """returns none if not found other functions that begin with 'do_' raise
    also this do_ type function passes white space"""
    start = pass_white(source, start)
    # start is the fist position after initial start that is not a white space or \n
    if not start < len(source):  #if finished parsing return None
        return None, start
    if any(startswith_keyword(source[start:], e) for e in {'case', 'default'}):
        return None, start
    rest = source[start:]
    for key, meth in KEYWORD_METHODS.iteritems(
    ):  # check for statements that are uniquely defined by their keywords
        if rest.startswith(key):
            # has to startwith this keyword and the next letter after keyword must be either EOF or not in IDENTIFIER_PART
            if len(key) == len(rest) or rest[len(key)] not in IDENTIFIER_PART:
                return meth(source, start)
    if rest[0] == '{':  #Block
        return do_block(source, start)
    # Now only label and expression left
    cand = parse_identifier(source, start, False)
    if cand is not None:  # it can mean that its a label
        label, cand_start = cand
        cand_start = pass_white(source, cand_start)
        if source[cand_start] == ':':
            return do_label(source, start)
    return do_expression(source, start)

def do_statement ( source , start ) : start = pass_white ( source , start ) if not start < len ( source ) : return None , start if any ( startswith_keyword ( source [ start : ] , e ) for e in { 'case' , 'default' } ) : return None , start rest = source [ start : ] for key , meth in KEYWORD_METHODS . iteritems ( ) : if rest . startswith ( key ) : if len ( key ) == len ( rest ) or rest [ len ( key ) ] not in IDENTIFIER_PART : return meth ( source , start ) if rest [ 0 ] == '{' : return do_block ( source , start ) cand = parse_identifier ( source , start , False ) if cand is not None : label , cand_start = cand cand_start = pass_white ( source , cand_start ) if source [ cand_start ] == ':' : return do_label ( source , start ) return do_expression ( source , start )

returns none if not found other functions that begin with do_ raise also this do_ type function passes white space


def match(self, string, pos):
        '''string is of course a py string'''
        return self.pat.match(string, int(pos))

def match ( self , string , pos ) : return self . pat . match ( string , int ( pos ) )


def call(self, this, args=()):
        ''' Dont use this method from inside bytecode to call other bytecode. '''
        if self.is_native:
            _args = SpaceTuple(
                args
            )  # we have to do that unfortunately to pass all the necessary info to the funcs
            _args.space = self.space
            return self.code(
                this, _args
            )  # must return valid js object - undefined, null, float, unicode, bool, or PyJs
        else:
            return self.space.exe._call(self, this,
                                        args)

def call ( self , this , args = ( ) ) : if self . is_native : _args = SpaceTuple ( args ) _args . space = self . space return self . code ( this , _args ) else : return self . space . exe . _call ( self , this , args )

Dont use this method from inside bytecode to call other bytecode .


def is_empty_object(n, last):
    """n may be the inside of block or object"""
    if n.strip():
        return False
    # seems to be but can be empty code
    last = last.strip()
    markers = {
        ')',
        ';',
    }
    if not last or last[-1] in markers:
        return False
    return True

def is_empty_object ( n , last ) : if n . strip ( ) : return False last = last . strip ( ) markers = { ')' , ';' , } if not last or last [ - 1 ] in markers : return False return True


def is_object(n, last):
    """n may be the inside of block or object.
       last is the code before object"""
    if is_empty_object(n, last):
        return True
    if not n.strip():
        return False
    #Object contains lines of code so it cant be an object
    if len(argsplit(n, ';')) > 1:
        return False
    cands = argsplit(n, ',')
    if not cands[-1].strip():
        return True  # {xxxx,} empty after last , it must be an object
    for cand in cands:
        cand = cand.strip()
        # separate each candidate element at : in dict and check whether they are correct...
        kv = argsplit(cand, ':')
        if len(
                kv
        ) > 2:  # set the len of kv to 2 because of this stupid : expression
            kv = kv[0], ':'.join(kv[1:])

        if len(kv) == 2:
            # key value pair, check whether not label or ?:
            k, v = kv
            if not is_lval(k.strip()):
                return False
            v = v.strip()
            if v.startswith('function'):
                continue
            #will fail on label... {xxx: while {}}
            if v[0] == '{':  # value cant be a code block
                return False
            for e in KEYWORD_METHODS:
                # if v starts with any statement then return false
                if v.startswith(e) and len(e) < len(v) and v[len(
                        e)] not in IDENTIFIER_PART:
                    return False
        elif not (cand.startswith('set ') or cand.startswith('get ')):
            return False
    return True

def
is_object
(
n
,
last
)
:
if
is_empty_object
(
n
,
last
)
:
return
True
if
not
n
.
strip
(
)
:
return
False
if
len
(
argsplit
(
n
,
';'
)
)
>
1
:
return
False
cands
=
argsplit
(
n
,
','
)
if
not
cands
[
1
]
.
strip
(
)
:
return
True
for
cand
in
cands
:
cand
=
cand
.
strip
(
)
kv
=
argsplit
(
cand
,
':'
)
if
len
(
kv
)
>
2
:
kv
=
kv
[
0
]
,
':'
.
join
(
kv
[
1
:
]
)
if
len
(
kv
)
==
2
:
k
,
v
=
kv
if
not
is_lval
(
k
.
strip
(
)
)
:
return
False
v
=
v
.
strip
(
)
if
v
.
startswith
(
'function'
)
:
continue
if
v
[
0
]
==
'{'
:
return
False
for
e
in
KEYWORD_METHODS
:
if
v
.
startswith
(
e
)
and
len
(
e
)
<
len
(
v
)
and
v
[
len
(
e
)
]
not
in
IDENTIFIER_PART
:
return
False
elif
not
(
cand
.
startswith
(
'set '
)
or
cand
.
startswith
(
'get '
)
)
:
return
False
return
True

n may be the inside of block or object . last is the code before object


def remove_objects(code, count=1):
    """ This function replaces objects with OBJECTS_LVALS, returns new code, replacement dict and count.
        count arg is the number that should be added to the LVAL of the first replaced object
    """
    replacements = {}  #replacement dict
    br = bracket_split(code, ['{}', '[]'])
    res = ''
    last = ''
    for e in br:
        #test whether e is an object
        if e[0] == '{':
            n, temp_rep, cand_count = remove_objects(e[1:-1], count)
            # if e was not an object then n should not contain any :
            if is_object(n, last):
                #e was an object
                res += ' ' + OBJECT_LVAL % count
                replacements[OBJECT_LVAL % count] = e
                count += 1
            else:
                # e was just a code block but could contain objects inside
                res += '{%s}' % n
                count = cand_count
                replacements.update(temp_rep)
        elif e[0] == '[':
            if is_array(last):
                res += e  # will be translated later
            else:  # prop get
                n, rep, count = remove_objects(e[1:-1], count)
                res += '[%s]' % n
                replacements.update(rep)
        else:  # e does not contain any objects
            res += e
        last = e  #needed to test for this stipid empty object
    return res, replacements, count

def
remove_objects
(
code
,
count
=
1
)
:
replacements
=
{
}
br
=
bracket_split
(
code
,
[
'{}'
,
'[]'
]
)
res
=
''
last
=
''
for
e
in
br
:
if
e
[
0
]
==
'{'
:
n
,
temp_rep
,
cand_count
=
remove_objects
(
e
[
1
:
1
]
,
count
)
if
is_object
(
n
,
last
)
:
res
+=
' '
+
OBJECT_LVAL
%
count
replacements
[
OBJECT_LVAL
%
count
]
=
e
count
+=
1
else
:
res
+=
'{%s}'
%
n
count
=
cand_count
replacements
.
update
(
temp_rep
)
elif
e
[
0
]
==
'['
:
if
is_array
(
last
)
:
res
+=
e
else
:
n
,
rep
,
count
=
remove_objects
(
e
[
1
:
1
]
,
count
)
res
+=
'[%s]'
%
n
replacements
.
update
(
rep
)
else
:
res
+=
e
last
=
e
return
res
,
replacements
,
count

This function replaces objects with OBJECTS_LVALS returns new code replacement dict and count . count arg is the number that should be added to the LVAL of the first replaced object


def _ensure_regexp(source, n):  #<- this function has to be improved
    '''returns True if regexp starts at n else returns False
      checks whether it is not a division '''
    markers = '(+~"\'=[%:?!*^|&-,;/\\'
    k = 0
    while True:
        k += 1
        if n - k < 0:
            return True
        char = source[n - k]
        if char in markers:
            return True
        if char != ' ' and char != '\n':
            break
    return False

def
_ensure_regexp
(
source
,
n
)
:
markers
=
'(+~"\'=[%:?!*^|&-,;/\\'
k
=
0
while
True
:
k
+=
1
if
n
k
<
0
:
return
True
char
=
source
[
n
k
]
if
char
in
markers
:
return
True
if
char
!=
' '
and
char
!=
'\n'
:
break
return
False


def parse_num(source, start, charset):
    """Returns a first index>=start of chat not in charset"""
    while start < len(source) and source[start] in charset:
        start += 1
    return start

def parse_num ( source , start , charset ) : while start < len ( source ) and source [ start ] in charset : start += 1 return start

Returns a first index > = start of chat not in charset


def parse_exponent(source, start):
    """returns end of exponential, raises SyntaxError if failed"""
    if not source[start] in {'e', 'E'}:
        if source[start] in IDENTIFIER_PART:
            raise SyntaxError('Invalid number literal!')
        return start
    start += 1
    if source[start] in {'-', '+'}:
        start += 1
    FOUND = False
    # we need at least one dig after exponent
    while source[start] in NUMS:
        FOUND = True
        start += 1
    if not FOUND or source[start] in IDENTIFIER_PART:
        raise SyntaxError('Invalid number literal!')
    return start

def
parse_exponent
(
source
,
start
)
:
if
not
source
[
start
]
in
{
'e'
,
'E'
}
:
if
source
[
start
]
in
IDENTIFIER_PART
:
raise
SyntaxError
(
'Invalid number literal!'
)
return
start
start
+=
1
if
source
[
start
]
in
{
'-'
,
'+'
}
:
start
+=
1
FOUND
=
False
while
source
[
start
]
in
NUMS
:
FOUND
=
True
start
+=
1
if
not
FOUND
or
source
[
start
]
in
IDENTIFIER_PART
:
raise
SyntaxError
(
'Invalid number literal!'
)
return
start

returns end of exponential raises SyntaxError if failed


def unify_string_literals(js_string):
    """this function parses the string just like javascript
       for example literal '\d' in JavaScript would be interpreted
       as 'd' - backslash would be ignored and in Pyhon this
       would be interpreted as '\\d' This function fixes this problem."""
    n = 0
    res = ''
    limit = len(js_string)
    while n < limit:
        char = js_string[n]
        if char == '\\':
            new, n = do_escape(js_string, n)
            res += new
        else:
            res += char
            n += 1
    return res

def unify_string_literals ( js_string ) : n = 0 res = '' limit = len ( js_string ) while n < limit : char = js_string [ n ] if char == '\\' : new , n = do_escape ( js_string , n ) res += new else : res += char n += 1 return res

this function parses the string just like javascript for example literal \ d in JavaScript would be interpreted as d - backslash would be ignored and in Pyhon this would be interpreted as \\ d This function fixes this problem .


def in_op(self, other):
    '''checks if self is in other'''
    if not is_object(other):
        raise MakeError(
            'TypeError',
            "You can\'t use 'in' operator to search in non-objects")
    return other.has_property(to_string(self))


def maybe_download_and_extract():
  """Download and extract processed data and embeddings."""
  dest_directory = '.'
  filename = DATA_URL.split('/')[-1]
  filepath = os.path.join(dest_directory, filename)
  if not os.path.exists(filepath):
    def _progress(count, block_size, total_size):
      sys.stdout.write('\r>> Downloading %s %.1f%%' % (filename,
          float(count * block_size) / float(total_size) * 100.0))
      sys.stdout.flush()
    filepath, _ = urllib.request.urlretrieve(DATA_URL, filepath, _progress)
    print()
    statinfo = os.stat(filepath)
    print('Successfully downloaded', filename, statinfo.st_size, 'bytes.')
  extracted_dir_path = os.path.join(dest_directory, 'trees')
  if not os.path.exists(extracted_dir_path):
    zip_ref = zipfile.ZipFile(filepath, 'r')
    zip_ref.extractall(dest_directory)
    zip_ref.close()

def
maybe_download_and_extract
(
)
:
dest_directory
=
'.'
filename
=
DATA_URL
.
split
(
'/'
)
[
1
]
filepath
=
os
.
path
.
join
(
dest_directory
,
filename
)
if
not
os
.
path
.
exists
(
filepath
)
:
def
_progress
(
count
,
block_size
,
total_size
)
:
sys
.
stdout
.
write
(
'\r>> Downloading %s %.1f%%'
%
(
filename
,
float
(
count
*
block_size
)
/
float
(
total_size
)
*
100.0
)
)
sys
.
stdout
.
flush
(
)
filepath
,
_
=
urllib
.
request
.
urlretrieve
(
DATA_URL
,
filepath
,
_progress
)
print
(
)
statinfo
=
os
.
stat
(
filepath
)
print
(
'Successfully downloaded'
,
filename
,
statinfo
.
st_size
,
'bytes.'
)
extracted_dir_path
=
os
.
path
.
join
(
dest_directory
,
'trees'
)
if
not
os
.
path
.
exists
(
extracted_dir_path
)
:
zip_ref
=
zipfile
.
ZipFile
(
filepath
,
'r'
)
zip_ref
.
extractall
(
dest_directory
)
zip_ref
.
close
(
)

Download and extract processed data and embeddings .


def add_inputs(self, xs):
        """
        returns the list of states obtained by adding the given inputs
        to the current state, one by one.
        """
        states = []
        cur = self
        for x in xs:
            cur = cur.add_input(x)
            states.append(cur)
        return states

def add_inputs ( self , xs ) : states = [ ] cur = self for x in xs : cur = cur . add_input ( x ) states . append ( cur ) return states

returns the list of states obtained by adding the given inputs to the current state one by one .


def make_grid(tensor, nrow=8, padding=2, pad_value=0):
    """Make a grid of images, via numpy.

    Args:
        tensor (Tensor or list): 4D mini-batch Tensor of shape (B x C x H x W)
            or a list of images all of the same size.
        nrow (int, optional): Number of images displayed in each row of the grid.
            The Final grid size is (B / nrow, nrow). Default is 8.
        padding (int, optional): amount of padding. Default is 2.
        pad_value (float, optional): Value for the padded pixels.

    """
    if not (isinstance(tensor, np.ndarray) or
            (isinstance(tensor, list) and all(isinstance(t, np.ndarray) for t in tensor))):
        raise TypeError('tensor or list of tensors expected, got {}'.format(type(tensor)))

    # if list of tensors, convert to a 4D mini-batch Tensor
    if isinstance(tensor, list):
        tensor = np.stack(tensor, 0)

    if tensor.ndim == 2:  # single image H x W
        tensor = tensor.reshape((1, tensor.shape[0], tensor.shape[1]))

    if tensor.ndim == 3:
        if tensor.shape[0] == 1:  # if single-channel, single image, convert to 3-channel
            tensor = np.concatenate((tensor, tensor, tensor), 0)
        tensor = tensor.reshape((1, tensor.shape[0], tensor.shape[1], tensor.shape[2]))

    if tensor.ndim == 4 and tensor.shape[1] == 1:  # single-channel images
        tensor = np.concatenate((tensor, tensor, tensor), 1)

    if tensor.shape[0] == 1:
        return np.squeeze(tensor)

    # make the mini-batch of images into a grid
    nmaps = tensor.shape[0]
    xmaps = min(nrow, nmaps)
    ymaps = int(math.ceil(float(nmaps) / xmaps))
    height, width = int(tensor.shape[2] + padding), int(tensor.shape[3] + padding)
    grid = np.ones((3, height * ymaps + padding, width * xmaps + padding)) * pad_value
    k = 0
    for y in range(ymaps):
        for x in range(xmaps):
            if k >= nmaps:
                break
            grid[:, y * height + padding:(y+1) * height,\
                 x * width + padding:(x+1) * width] = tensor[k]
            k = k + 1
    return grid


def save_image(tensor, filename, nrow=8, padding=2, pad_value=0):
    """Save a given Tensor into an image file.

    Args:
        tensor (Tensor or list): Image to be saved. If given a mini-batch tensor,
            saves the tensor as a grid of images by calling ``make_grid``.
        **kwargs: Other arguments are documented in ``make_grid``.
    """
    from PIL import Image
    grid = make_grid(tensor, nrow=nrow, padding=padding, pad_value=pad_value)
    im = Image.fromarray(pre_pillow_float_img_process(grid))
    im.save(filename)

def save_image ( tensor , filename , nrow = 8 , padding = 2 , pad_value = 0 ) : from PIL import Image grid = make_grid ( tensor , nrow = nrow , padding = padding , pad_value = pad_value ) im = Image . fromarray ( pre_pillow_float_img_process ( grid ) ) im . save ( filename )

Save a given Tensor into an image file .


def pythonize_arguments(arg_str):
    """
    Remove types from function arguments in cython
    """
    out_args = []
    # If there aren't any arguments return the empty string
    if arg_str is None:
        return out_str
    args = arg_str.split(',')
    for arg in args:
        components = arg.split('=')
        name_and_type=components[0].split(' ')
        # There is probably type info
        if name_and_type[-1]=='' and len(name_and_type)>1:
            name=name_and_type[-2]
        else:
            name=name_and_type[-1]
        # if there are default parameters
        if len(components)>1:
            name+='='+components[1]

        out_args.append(name)
    return ','.join(out_args)

def
pythonize_arguments
(
arg_str
)
:
out_args
=
[
]
if
arg_str
is
:
return
out_str
args
=
arg_str
.
split
(
','
)
for
arg
in
args
:
components
=
arg
.
split
(
'='
)
name_and_type
=
components
[
0
]
.
split
(
' '
)
if
name_and_type
[
1
]
==
''
and
len
(
name_and_type
)
>
1
:
name
=
name_and_type
[
2
]
else
:
name
=
name_and_type
[
1
]
if
len
(
components
)
>
1
:
name
+=
'='
+
components
[
1
]
out_args
.
append
(
name
)
return
','
.
join
(
out_args
)


def _set_perms(self, perms):
        """
        Sets the access permissions of the map.

        :param perms: the new permissions.
        """
        assert isinstance(perms, str) and len(perms) <= 3 and perms.strip() in ['', 'r', 'w', 'x', 'rw', 'r x', 'rx', 'rwx', 'wx', ]
        self._perms = perms

def
_set_perms
(
self
,
perms
)
:
assert
isinstance
(
perms
,
str
)
and
len
(
perms
)
<=
3
and
perms
.
strip
(
)
in
[
''
,
'r'
,
'w'
,
'x'
,
'rw'
,
'r x'
,
'rx'
,
'rwx'
,
'wx'
,
]
self
.
_perms
=
perms

Sets the access permissions of the map .


def access_ok(self, access):
        """ Check if there is enough permissions for access """
        for c in access:
            if c not in self.perms:
                return False
        return True

def access_ok ( self , access ) : for c in access : if c not in self . perms : return False return True


def _in_range(self, index):
        """ Returns True if index is in range """
        if isinstance(index, slice):
            in_range = index.start < index.stop and \
                index.start >= self.start and \
                index.stop <= self.end
        else:
            in_range = index >= self.start and \
                index <= self.end
        return in_range

def _in_range ( self , index ) : if isinstance ( index , slice ) : in_range = index . start < index . stop and index . start >= self . start and index . stop <= self . end else : in_range = index >= self . start and index <= self . end return in_range


def _get_offset(self, index):
        """
        Translates the index to the internal offsets.

        self.start   -> 0
        self.start+1 -> 1
        ...
        self.end     -> len(self)
        """
        if not self._in_range(index):
            raise IndexError('Map index out of range')
        if isinstance(index, slice):
            index = slice(index.start - self.start, index.stop - self.start)
        else:
            index -= self.start
        return index

def
_get_offset
(
self
,
index
)
:
if
not
self
.
_in_range
(
index
)
:
raise
IndexError
(
'Map index out of range'
)
if
isinstance
(
index
,
slice
)
:
index
=
slice
(
index
.
start
self
.
start
,
index
.
stop
self
.
start
)
else
:
index
-=
self
.
start
return
index

Translates the index to the internal offsets .


def mmap(self, addr, size, perms, data_init=None, name=None):
        """
        Creates a new mapping in the memory address space.

        :param addr: the starting address (took as hint). If C{addr} is C{0} the first big enough
                     chunk of memory will be selected as starting address.
        :param size: the length of the mapping.
        :param perms: the access permissions to this memory.
        :param data_init: optional data to initialize this memory.
        :param name: optional name to give to this mapping
        :return: the starting address where the memory was mapped.
        :raises error:
                   - 'Address shall be concrete' if C{addr} is not an integer number.
                   - 'Address too big' if C{addr} goes beyond the limit of the memory.
                   - 'Map already used' if the piece of memory starting in C{addr} and with length C{size} isn't free.
        :rtype: int

        """
        # If addr is NULL, the system determines where to allocate the region.
        assert addr is None or isinstance(addr, int), 'Address shall be concrete'

        self.cpu._publish('will_map_memory', addr, size, perms, None, None)

        # address is rounded down to the nearest multiple of the allocation granularity
        if addr is not None:
            assert addr < self.memory_size, 'Address too big'
            addr = self._floor(addr)

        # size value is rounded up to the next page boundary
        size = self._ceil(size)

        # If zero search for a spot
        addr = self._search(size, addr)

        # It should not be allocated
        for i in range(self._page(addr), self._page(addr + size)):
            assert i not in self._page2map, 'Map already used'

        # Create the anonymous map
        m = AnonMap(start=addr, size=size, perms=perms, data_init=data_init, name=name)

        # Okay, ready to alloc
        self._add(m)

        logger.debug('New memory map @%x size:%x', addr, size)

        self.cpu._publish('did_map_memory', addr, size, perms, None, None, addr)
        return addr

def
mmap
(
self
,
addr
,
size
,
perms
,
data_init
=
,
name
=
)
:
assert
addr
is
or
isinstance
(
addr
,
int
)
,
'Address shall be concrete'
self
.
cpu
.
_publish
(
'will_map_memory'
,
addr
,
size
,
perms
,
,
)
if
addr
is
not
:
assert
addr
<
self
.
memory_size
,
'Address too big'
addr
=
self
.
_floor
(
addr
)
size
=
self
.
_ceil
(
size
)
addr
=
self
.
_search
(
size
,
addr
)
for
i
in
range
(
self
.
_page
(
addr
)
,
self
.
_page
(
addr
+
size
)
)
:
assert
i
not
in
self
.
_page2map
,
'Map already used'
m
=
AnonMap
(
start
=
addr
,
size
=
size
,
perms
=
perms
,
data_init
=
data_init
,
name
=
name
)
self
.
_add
(
m
)
logger
.
debug
(
'New memory map @%x size:%x'
,
addr
,
size
)
self
.
cpu
.
_publish
(
'did_map_memory'
,
addr
,
size
,
perms
,
,
,
addr
)
return
addr

Creates a new mapping in the memory address space .


def mappings(self):
        """
        Returns a sorted list of all the mappings for this memory.

        :return: a list of mappings.
        :rtype: list
        """
        result = []
        for m in self.maps:
            if isinstance(m, AnonMap):
                result.append((m.start, m.end, m.perms, 0, ''))
            elif isinstance(m, FileMap):
                result.append((m.start, m.end, m.perms, m._offset, m._filename))
            else:
                result.append((m.start, m.end, m.perms, 0, m.name))

        return sorted(result)

def mappings ( self ) : result = [ ] for m in self . maps : if isinstance ( m , AnonMap ) : result . append ( ( m . start , m . end , m . perms , 0 , '' ) ) elif isinstance ( m , FileMap ) : result . append ( ( m . start , m . end , m . perms , m . _offset , m . _filename ) ) else : result . append ( ( m . start , m . end , m . perms , 0 , m . name ) ) return sorted ( result )

Returns a sorted list of all the mappings for this memory .


def scan_mem(self, data_to_find):
        """
        Scan for concrete bytes in all mapped memory. Successively yield addresses of all matches.

        :param bytes data_to_find: String to locate
        :return:
        """

        # TODO: for the moment we just treat symbolic bytes as bytes that don't match.
        # for our simple test cases right now, the bytes we're interested in scanning
        # for will all just be there concretely
        # TODO: Can probably do something smarter here like Boyer-Moore, but unnecessary
        # if we're looking for short strings.

        # Querying mem with an index returns [bytes]
        if isinstance(data_to_find, bytes):
            data_to_find = [bytes([c]) for c in data_to_find]

        for mapping in sorted(self.maps):
            for ptr in mapping:
                if ptr + len(data_to_find) >= mapping.end:
                    break

                candidate = mapping[ptr:ptr + len(data_to_find)]

                # TODO: treat symbolic bytes as bytes that don't match. for our simple tests right now, the
                # bytes will be there concretely
                if issymbolic(candidate[0]):
                    break

                if candidate == data_to_find:
                    yield ptr

def scan_mem ( self , data_to_find ) : if isinstance ( data_to_find , bytes ) : data_to_find = [ bytes ( [ c ] ) for c in data_to_find ] for mapping in sorted ( self . maps ) : for ptr in mapping : if ptr + len ( data_to_find ) >= mapping . end : break candidate = mapping [ ptr : ptr + len ( data_to_find ) ] if issymbolic ( candidate [ 0 ] ) : break if candidate == data_to_find : yield ptr

Scan for concrete bytes in all mapped memory . Successively yield addresses of all matches .


def _reg_name(self, reg_id):
        """
        Translates a register ID from the disassembler object into the
        register name based on manticore's alias in the register file

        :param int reg_id: Register ID
        """
        if reg_id >= X86_REG_ENDING:
            logger.warning("Trying to get register name for a non-register")
            return None
        cs_reg_name = self.cpu.instruction.reg_name(reg_id)
        if cs_reg_name is None or cs_reg_name.lower() == '(invalid)':
            return None
        return self.cpu._regfile._alias(cs_reg_name.upper())

Translates a register ID from the disassembler object into the register name based on manticore s alias in the register file


def get_argument_values(self, model, prefix_args):
        """
        Extract arguments for model from the environment and return as a tuple that
        is ready to be passed to the model.

        :param callable model: Python model of the function
        :param tuple prefix_args: Parameters to pass to model before actual ones
        :return: Arguments to be passed to the model
        :rtype: tuple
        """
        spec = inspect.getfullargspec(model)

        if spec.varargs:
            logger.warning("ABI: A vararg model must be a unary function.")

        nargs = len(spec.args) - len(prefix_args)

        # If the model is a method, we need to account for `self`
        if inspect.ismethod(model):
            nargs -= 1

        def resolve_argument(arg):
            if isinstance(arg, str):
                return self._cpu.read_register(arg)
            else:
                return self._cpu.read_int(arg)

        # Create a stream of resolved arguments from argument descriptors
        descriptors = self.get_arguments()
        argument_iter = map(resolve_argument, descriptors)

        from ..models import isvariadic  # prevent circular imports

        if isvariadic(model):
            arguments = prefix_args + (argument_iter,)
        else:
            arguments = prefix_args + tuple(islice(argument_iter, nargs))

        return arguments

Extract arguments for model from the environment and return as a tuple that is ready to be passed to the model .


def write_register(self, register, value):
        """
        Dynamic interface for writing cpu registers

        :param str register: register name (as listed in `self.all_registers`)
        :param value: register value
        :type value: int or long or Expression
        """
        self._publish('will_write_register', register, value)
        value = self._regfile.write(register, value)
        self._publish('did_write_register', register, value)
        return value

def write_register ( self , register , value ) : self . _publish ( 'will_write_register' , register , value ) value = self . _regfile . write ( register , value ) self . _publish ( 'did_write_register' , register , value ) return value


def read_register(self, register):
        """
        Dynamic interface for reading cpu registers

        :param str register: register name (as listed in `self.all_registers`)
        :return: register value
        :rtype: int or long or Expression
        """
        self._publish('will_read_register', register)
        value = self._regfile.read(register)
        self._publish('did_read_register', register, value)
        return value

def read_register ( self , register ) : self . _publish ( 'will_read_register' , register ) value = self . _regfile . read ( register ) self . _publish ( 'did_read_register' , register , value ) return value


def emulate_until(self, target: int):
        """
        Tells the CPU to set up a concrete unicorn emulator and use it to execute instructions
        until target is reached.

        :param target: Where Unicorn should hand control back to Manticore. Set to 0 for all instructions.
        """
        self._concrete = True
        self._break_unicorn_at = target
        if self.emu:
            self.emu._stop_at = target

def emulate_until ( self , target : int ) : self . _concrete = True self . _break_unicorn_at = target if self . emu : self . emu . _stop_at = target

Tells the CPU to set up a concrete unicorn emulator and use it to execute instructions until target is reached .


def write_int(self, where, expression, size=None, force=False):
        """
        Writes int to memory

        :param int where: address to write to
        :param expr: value to write
        :type expr: int or BitVec
        :param size: bit size of `expr`
        :param force: whether to ignore memory permissions
        """
        if size is None:
            size = self.address_bit_size
        assert size in SANE_SIZES
        self._publish('will_write_memory', where, expression, size)

        data = [Operators.CHR(Operators.EXTRACT(expression, offset, 8)) for offset in range(0, size, 8)]
        self._memory.write(where, data, force)

        self._publish('did_write_memory', where, expression, size)

def write_int ( self , where , expression , size = None , force = False ) : if size is None : size = self . address_bit_size assert size in SANE_SIZES self . _publish ( 'will_write_memory' , where , expression , size ) data = [ Operators . CHR ( Operators . EXTRACT ( expression , offset , 8 ) ) for offset in range ( 0 , size , 8 ) ] self . _memory . write ( where , data , force ) self . _publish ( 'did_write_memory' , where , expression , size )


def _raw_read(self, where: int, size=1) -> bytes:
        """
        Selects bytes from memory. Attempts to do so faster than via read_bytes.

        :param where: address to read from
        :param size: number of bytes to read
        :return: the bytes in memory
        """
        map = self.memory.map_containing(where)
        start = map._get_offset(where)
        mapType = type(map)
        if mapType is FileMap:
            end = map._get_offset(where + size)

            if end > map._mapped_size:
                logger.warning(f"Missing {end - map._mapped_size} bytes at the end of {map._filename}")

            raw_data = map._data[map._get_offset(where): min(end, map._mapped_size)]
            if len(raw_data) < end:
                raw_data += b'\x00' * (end - len(raw_data))

            data = b''
            for offset in sorted(map._overlay.keys()):
                data += raw_data[len(data):offset]
                data += map._overlay[offset]
            data += raw_data[len(data):]

        elif mapType is AnonMap:
            data = bytes(map._data[start:start + size])
        else:
            data = b''.join(self.memory[where:where + size])
        assert len(data) == size, 'Raw read resulted in wrong data read which should never happen'
        return data

Selects bytes from memory . Attempts to do so faster than via read_bytes .


def read_int(self, where, size=None, force=False):
        """
        Reads int from memory

        :param int where: address to read from
        :param size: number of bits to read
        :return: the value read
        :rtype: int or BitVec
        :param force: whether to ignore memory permissions
        """
        if size is None:
            size = self.address_bit_size
        assert size in SANE_SIZES
        self._publish('will_read_memory', where, size)

        data = self._memory.read(where, size // 8, force)
        assert (8 * len(data)) == size
        value = Operators.CONCAT(size, *map(Operators.ORD, reversed(data)))

        self._publish('did_read_memory', where, value, size)
        return value

def read_int ( self , where , size = None , force = False ) : if size is None : size = self . address_bit_size assert size in SANE_SIZES self . _publish ( 'will_read_memory' , where , size ) data = self . _memory . read ( where , size // 8 , force ) assert ( 8 * len ( data ) ) == size value = Operators . CONCAT ( size , * map ( Operators . ORD , reversed ( data ) ) ) self . _publish ( 'did_read_memory' , where , value , size ) return value


def read_bytes(self, where, size, force=False):
        """
        Read from memory.

        :param int where: address to read data from
        :param int size: number of bytes
        :param force: whether to ignore memory permissions
        :return: data
        :rtype: list[int or Expression]
        """
        result = []
        for i in range(size):
            result.append(Operators.CHR(self.read_int(where + i, 8, force)))
        return result

def read_bytes ( self , where , size , force = False ) : result = [ ] for i in range ( size ) : result . append ( Operators . CHR ( self . read_int ( where + i , 8 , force ) ) ) return result


def read_string(self, where, max_length=None, force=False):
        """
        Read a NUL-terminated concrete buffer from memory. Stops reading at first symbolic byte.

        :param int where: Address to read string from
        :param int max_length:
            The size in bytes to cap the string at, or None [default] for no
            limit.
        :param force: whether to ignore memory permissions
        :return: string read
        :rtype: str
        """
        s = io.BytesIO()
        while True:
            c = self.read_int(where, 8, force)

            if issymbolic(c) or c == 0:
                break

            if max_length is not None:
                if max_length == 0:
                    break
                max_length = max_length - 1
            s.write(Operators.CHR(c))
            where += 1
        return s.getvalue().decode()

def read_string ( self , where , max_length = None , force = False ) : s = io . BytesIO ( ) while True : c = self . read_int ( where , 8 , force ) if issymbolic ( c ) or c == 0 : break if max_length is not None : if max_length == 0 : break max_length = max_length - 1 s . write ( Operators . CHR ( c ) ) where += 1 return s . getvalue ( ) . decode ( )

Read a NUL - terminated concrete buffer from memory . Stops reading at first symbolic byte .


def push_bytes(self, data, force=False):
        """
        Write `data` to the stack and decrement the stack pointer accordingly.

        :param str data: Data to write
        :param force: whether to ignore memory permissions
        """
        self.STACK -= len(data)
        self.write_bytes(self.STACK, data, force)
        return self.STACK

def push_bytes ( self , data , force = False ) : self . STACK -= len ( data ) self . write_bytes ( self . STACK , data , force ) return self . STACK

Write data to the stack and decrement the stack pointer accordingly .


def pop_bytes(self, nbytes, force=False):
        """
        Read `nbytes` from the stack, increment the stack pointer, and return
        data.

        :param int nbytes: How many bytes to read
        :param force: whether to ignore memory permissions
        :return: Data read from the stack
        """
        data = self.read_bytes(self.STACK, nbytes, force=force)
        self.STACK += nbytes
        return data

def pop_bytes ( self , nbytes , force = False ) : data = self . read_bytes ( self . STACK , nbytes , force = force ) self . STACK += nbytes return data

Read nbytes from the stack increment the stack pointer and return data .


def push_int(self, value, force=False):
        """
        Decrement the stack pointer and write `value` to the stack.

        :param int value: The value to write
        :param force: whether to ignore memory permissions
        :return: New stack pointer
        """
        self.STACK -= self.address_bit_size // 8
        self.write_int(self.STACK, value, force=force)
        return self.STACK

def push_int ( self , value , force = False ) : self . STACK -= self . address_bit_size // 8 self . write_int ( self . STACK , value , force = force ) return self . STACK

Decrement the stack pointer and write value to the stack .


def pop_int(self, force=False):
        """
        Read a value from the stack and increment the stack pointer.

        :param force: whether to ignore memory permissions
        :return: Value read
        """
        value = self.read_int(self.STACK, force=force)
        self.STACK += self.address_bit_size // 8
        return value

def pop_int ( self , force = False ) : value = self . read_int ( self . STACK , force = force ) self . STACK += self . address_bit_size // 8 return value

Read a value from the stack and increment the stack pointer .


def decode_instruction(self, pc):
        """
        This will decode an instruction from memory pointed by `pc`

        :param int pc: address of the instruction
        """
        # No dynamic code!!! #TODO!
        # Check if instruction was already decoded
        if pc in self._instruction_cache:
            return self._instruction_cache[pc]

        text = b''

        # Read Instruction from memory
        for address in range(pc, pc + self.max_instr_width):
            # This reads a byte from memory ignoring permissions
            # and concretize it if symbolic
            if not self.memory.access_ok(address, 'x'):
                break

            c = self.memory[address]

            if issymbolic(c):
                # In case of fully symbolic memory, eagerly get a valid ptr
                if isinstance(self.memory, LazySMemory):
                    try:
                        vals = visitors.simplify_array_select(c)
                        c = bytes([vals[0]])
                    except visitors.ArraySelectSimplifier.ExpressionNotSimple:
                        c = struct.pack('B', solver.get_value(self.memory.constraints, c))
                elif isinstance(c, Constant):
                    c = bytes([c.value])
                else:
                    logger.error('Concretize executable memory %r %r', c, text)
                    raise ConcretizeMemory(self.memory,
                                           address=pc,
                                           size=8 * self.max_instr_width,
                                           policy='INSTRUCTION')
            text += c

        # Pad potentially incomplete instruction with zeroes
        code = text.ljust(self.max_instr_width, b'\x00')

        try:
            # decode the instruction from code
            insn = self.disasm.disassemble_instruction(code, pc)
        except StopIteration as e:
            raise DecodeException(pc, code)

        # Check that the decoded instruction is contained in executable memory
        if not self.memory.access_ok(slice(pc, pc + insn.size), 'x'):
            logger.info("Trying to execute instructions from non-executable memory")
            raise InvalidMemoryAccess(pc, 'x')

        insn.operands = self._wrap_operands(insn.operands)
        self._instruction_cache[pc] = insn
        return insn

This will decode an instruction from memory pointed by pc


def execute(self):
        """
        Decode, and execute one instruction pointed by register PC
        """
        if issymbolic(self.PC):
            raise ConcretizeRegister(self, 'PC', policy='ALL')

        if not self.memory.access_ok(self.PC, 'x'):
            raise InvalidMemoryAccess(self.PC, 'x')

        self._publish('will_decode_instruction', self.PC)

        insn = self.decode_instruction(self.PC)
        self._last_pc = self.PC

        self._publish('will_execute_instruction', self.PC, insn)

        # FIXME (theo) why just return here?
        if insn.address != self.PC:
            return

        name = self.canonicalize_instruction_name(insn)

        if logger.level == logging.DEBUG:
            logger.debug(self.render_instruction(insn))
            for l in self.render_registers():
                register_logger.debug(l)

        try:
            if self._concrete and 'SYSCALL' in name:
                self.emu.sync_unicorn_to_manticore()
            if self._concrete and 'SYSCALL' not in name:
                self.emulate(insn)
                if self.PC == self._break_unicorn_at:
                    logger.debug("Switching from Unicorn to Manticore")
                    self._break_unicorn_at = None
                    self._concrete = False
            else:
                implementation = getattr(self, name, None)

                if implementation is not None:
                    implementation(*insn.operands)

                else:
                    text_bytes = ' '.join('%02x' % x for x in insn.bytes)
                    logger.warning("Unimplemented instruction: 0x%016x:\t%s\t%s\t%s",
                                   insn.address, text_bytes, insn.mnemonic, insn.op_str)
                    self.backup_emulate(insn)
        except (Interruption, Syscall) as e:
            e.on_handled = lambda: self._publish_instruction_as_executed(insn)
            raise e
        else:
            self._publish_instruction_as_executed(insn)

Decode and execute one instruction pointed by register PC


def _publish_instruction_as_executed(self, insn):
        """
        Notify listeners that an instruction has been executed.
        """
        self._icount += 1
        self._publish('did_execute_instruction', self._last_pc, self.PC, insn)

def _publish_instruction_as_executed ( self , insn ) : self . _icount += 1 self . _publish ( 'did_execute_instruction' , self . _last_pc , self . PC , insn )

Notify listeners that an instruction has been executed .


def concrete_emulate(self, insn):
        """
        Start executing in Unicorn from this point until we hit a syscall or reach break_unicorn_at

        :param capstone.CsInsn insn: The instruction object to emulate
        """

        if not self.emu:
            self.emu = ConcreteUnicornEmulator(self)
            self.emu._stop_at = self._break_unicorn_at
        try:
            self.emu.emulate(insn)
        except unicorn.UcError as e:
            if e.errno == unicorn.UC_ERR_INSN_INVALID:
                text_bytes = ' '.join('%02x' % x for x in insn.bytes)
                logger.error("Unimplemented instruction: 0x%016x:\t%s\t%s\t%s",
                             insn.address, text_bytes, insn.mnemonic, insn.op_str)
            raise InstructionEmulationError(str(e))


def backup_emulate(self, insn):
        """
        If we could not handle emulating an instruction, use Unicorn to emulate
        it.

        :param capstone.CsInsn instruction: The instruction object to emulate
        """

        if not hasattr(self, 'backup_emu'):
            self.backup_emu = UnicornEmulator(self)
        try:
            self.backup_emu.emulate(insn)
        except unicorn.UcError as e:
            if e.errno == unicorn.UC_ERR_INSN_INVALID:
                text_bytes = ' '.join('%02x' % x for x in insn.bytes)
                logger.error("Unimplemented instruction: 0x%016x:\t%s\t%s\t%s",
                             insn.address, text_bytes, insn.mnemonic, insn.op_str)
            raise InstructionEmulationError(str(e))
        finally:
            # We have been seeing occasional Unicorn issues with it not clearing
            # the backing unicorn instance. Saw fewer issues with the following
            # line present.
            del self.backup_emu

If we could not handle emulating an instruction use Unicorn to emulate it .


def visualize(self):
        """
        Given a Manticore workspace, or trace file, highlight the basic blocks.
        """
        if os.path.isfile(self.workspace):
            t = threading.Thread(target=self.highlight_from_file,
                                 args=(self.workspace,))
        elif os.path.isdir(self.workspace):
            t = threading.Thread(target=self.highlight_from_dir,
                                 args=(self.workspace,))
        t.start()

def visualize ( self ) : if os . path . isfile ( self . workspace ) : t = threading . Thread ( target = self . highlight_from_file , args = ( self . workspace , ) ) elif os . path . isdir ( self . workspace ) : t = threading . Thread ( target = self . highlight_from_dir , args = ( self . workspace , ) ) t . start ( )

Given a Manticore workspace or trace file highlight the basic blocks .


def push(cpu, value, size):
        """
        Writes a value in the stack.

        :param value: the value to put in the stack.
        :param size: the size of the value.
        """
        assert size in (8, 16, cpu.address_bit_size)
        cpu.STACK = cpu.STACK - size // 8
        base, _, _ = cpu.get_descriptor(cpu.read_register('SS'))
        address = cpu.STACK + base
        cpu.write_int(address, value, size)

def push ( cpu , value , size ) : assert size in ( 8 , 16 , cpu . address_bit_size ) cpu . STACK = cpu . STACK - size // 8 base , _ , _ = cpu . get_descriptor ( cpu . read_register ( 'SS' ) ) address = cpu . STACK + base cpu . write_int ( address , value , size )


def pop(cpu, size):
        """
        Gets a value from the stack.

        :rtype: int
        :param size: the size of the value to consume from the stack.
        :return: the value from the stack.
        """
        assert size in (16, cpu.address_bit_size)
        base, _, _ = cpu.get_descriptor(cpu.SS)
        address = cpu.STACK + base
        value = cpu.read_int(address, size)
        cpu.STACK = cpu.STACK + size // 8
        return value

def pop ( cpu , size ) : assert size in ( 16 , cpu . address_bit_size ) base , _ , _ = cpu . get_descriptor ( cpu . SS ) address = cpu . STACK + base value = cpu . read_int ( address , size ) cpu . STACK = cpu . STACK + size // 8 return value


def invalidate_cache(cpu, address, size):
        """ remove decoded instruction from instruction cache """
        cache = cpu.instruction_cache
        for offset in range(size):
            if address + offset in cache:
                del cache[address + offset]

def invalidate_cache ( cpu , address , size ) : cache = cpu . instruction_cache for offset in range ( size ) : if address + offset in cache : del cache [ address + offset ]


def CPUID(cpu):
        """
        CPUID instruction.

        The ID flag (bit 21) in the EFLAGS register indicates support for the
        CPUID instruction.  If a software procedure can set and clear this
        flag, the processor executing the procedure supports the CPUID
        instruction. This instruction operates the same in non-64-bit modes and
        64-bit mode.  CPUID returns processor identification and feature
        information in the EAX, EBX, ECX, and EDX registers.

        The instruction's output is dependent on the contents of the EAX
        register upon execution.

        :param cpu: current CPU.
        """
        # FIXME Choose conservative values and consider returning some default when eax not here
        conf = {0x0: (0x0000000d, 0x756e6547, 0x6c65746e, 0x49656e69),
                0x1: (0x000306c3, 0x05100800, 0x7ffafbff, 0xbfebfbff),
                0x2: (0x76035a01, 0x00f0b5ff, 0x00000000, 0x00c10000),
                0x4: {0x0: (0x1c004121, 0x01c0003f, 0x0000003f, 0x00000000),
                      0x1: (0x1c004122, 0x01c0003f, 0x0000003f, 0x00000000),
                      0x2: (0x1c004143, 0x01c0003f, 0x000001ff, 0x00000000),
                      0x3: (0x1c03c163, 0x03c0003f, 0x00000fff, 0x00000006)},
                0x7: (0x00000000, 0x00000000, 0x00000000, 0x00000000),
                0x8: (0x00000000, 0x00000000, 0x00000000, 0x00000000),
                0xb: {0x0: (0x00000001, 0x00000002, 0x00000100, 0x00000005),
                      0x1: (0x00000004, 0x00000004, 0x00000201, 0x00000003)},
                0xd: {0x0: (0x00000000, 0x00000000, 0x00000000, 0x00000000),
                      0x1: (0x00000000, 0x00000000, 0x00000000, 0x00000000)},
                }

        if cpu.EAX not in conf:
            logger.warning('CPUID with EAX=%x not implemented @ %x', cpu.EAX, cpu.PC)
            cpu.EAX, cpu.EBX, cpu.ECX, cpu.EDX = 0, 0, 0, 0
            return

        if isinstance(conf[cpu.EAX], tuple):
            cpu.EAX, cpu.EBX, cpu.ECX, cpu.EDX = conf[cpu.EAX]
            return

        if cpu.ECX not in conf[cpu.EAX]:
            logger.warning('CPUID with EAX=%x ECX=%x not implemented', cpu.EAX, cpu.ECX)
            cpu.EAX, cpu.EBX, cpu.ECX, cpu.EDX = 0, 0, 0, 0
            return

        cpu.EAX, cpu.EBX, cpu.ECX, cpu.EDX = conf[cpu.EAX][cpu.ECX]


def AND(cpu, dest, src):
        """
        Logical AND.

        Performs a bitwise AND operation on the destination (first) and source
        (second) operands and stores the result in the destination operand location.
        Each bit of the result is set to 1 if both corresponding bits of the first and
        second operands are 1; otherwise, it is set to 0.

        The OF and CF flags are cleared; the SF, ZF, and PF flags are set according to the result::

            DEST  =  DEST AND SRC;

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        # XXX bypass a capstone bug that incorrectly extends and computes operands sizes
        # the bug has been fixed since capstone 4.0.alpha2 (commit de8dd26)
        if src.size == 64 and src.type == 'immediate' and dest.size == 64:
            arg1 = Operators.SEXTEND(src.read(), 32, 64)
        else:
            arg1 = src.read()
        res = dest.write(dest.read() & arg1)
        # Defined Flags: szp
        cpu._calculate_logic_flags(dest.size, res)

def AND ( cpu , dest , src ) : if src . size == 64 and src . type == 'immediate' and dest . size == 64 : arg1 = Operators . SEXTEND ( src . read ( ) , 32 , 64 ) else : arg1 = src . read ( ) res = dest . write ( dest . read ( ) & arg1 ) cpu . _calculate_logic_flags ( dest . size , res )


def TEST(cpu, src1, src2):
        """
        Logical compare.

        Computes the bit-wise logical AND of first operand (source 1 operand)
        and the second operand (source 2 operand) and sets the SF, ZF, and PF
        status flags according to the result. The result is then discarded::

            TEMP  =  SRC1 AND SRC2;
            SF  =  MSB(TEMP);
            IF TEMP  =  0
            THEN ZF  =  1;
            ELSE ZF  =  0;
            FI:
            PF  =  BitwiseXNOR(TEMP[0:7]);
            CF  =  0;
            OF  =  0;
            (*AF is Undefined*)

        :param cpu: current CPU.
        :param src1: first operand.
        :param src2: second operand.
        """
        # Defined Flags: szp
        temp = src1.read() & src2.read()
        cpu.SF = (temp & (1 << (src1.size - 1))) != 0
        cpu.ZF = temp == 0
        cpu.PF = cpu._calculate_parity_flag(temp)
        cpu.CF = False
        cpu.OF = False

def TEST ( cpu , src1 , src2 ) : temp = src1 . read ( ) & src2 . read ( ) cpu . SF = ( temp & ( 1 << ( src1 . size - 1 ) ) ) != 0 cpu . ZF = temp == 0 cpu . PF = cpu . _calculate_parity_flag ( temp ) cpu . CF = False cpu . OF = False


def OR(cpu, dest, src):
        """
        Logical inclusive OR.

        Performs a bitwise inclusive OR operation between the destination (first)
        and source (second) operands and stores the result in the destination operand location.

        Each bit of the result of the OR instruction is set to 0 if both corresponding
        bits of the first and second operands are 0; otherwise, each bit is set
        to 1.

        The OF and CF flags are cleared; the SF, ZF, and PF flags are set according to the result::

            DEST  =  DEST OR SRC;

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        res = dest.write(dest.read() | src.read())
        # Defined Flags: szp
        cpu._calculate_logic_flags(dest.size, res)

def OR ( cpu , dest , src ) : res = dest . write ( dest . read ( ) | src . read ( ) ) cpu . _calculate_logic_flags ( dest . size , res )


def AAA(cpu):
        """
        ASCII adjust after addition.

        Adjusts the sum of two unpacked BCD values to create an unpacked BCD
        result. The AL register is the implied source and destination operand
        for this instruction. The AAA instruction is only useful when it follows
        an ADD instruction that adds (binary addition) two unpacked BCD values
        and stores a byte result in the AL register. The AAA instruction then
        adjusts the contents of the AL register to contain the correct 1-digit
        unpacked BCD result.
        If the addition produces a decimal carry, the AH register is incremented
        by 1, and the CF and AF flags are set. If there was no decimal carry,
        the CF and AF flags are cleared and the AH register is unchanged. In either
        case, bits 4 through 7 of the AL register are cleared to 0.

        This instruction executes as described in compatibility mode and legacy mode.
        It is not valid in 64-bit mode.
        ::
                IF ((AL AND 0FH) > 9) Operators.OR(AF  =  1)
                THEN
                    AL  =  (AL + 6);
                    AH  =  AH + 1;
                    AF  =  1;
                    CF  =  1;
                ELSE
                    AF  =  0;
                    CF  =  0;
                FI;
                AL  =  AL AND 0FH;
        :param cpu: current CPU.
        """
        cpu.AF = Operators.OR(cpu.AL & 0x0F > 9, cpu.AF)
        cpu.CF = cpu.AF
        cpu.AH = Operators.ITEBV(8, cpu.AF, cpu.AH + 1, cpu.AH)
        cpu.AL = Operators.ITEBV(8, cpu.AF, cpu.AL + 6, cpu.AL)
        """
        if (cpu.AL & 0x0F > 9) or cpu.AF == 1:
            cpu.AL = cpu.AL + 6
            cpu.AH = cpu.AH + 1
            cpu.AF = True
            cpu.CF = True
        else:
            cpu.AF = False
            cpu.CF = False
        """
        cpu.AL = cpu.AL & 0x0f

def AAA ( cpu ) : cpu . AF = Operators . OR ( cpu . AL & 0x0F > 9 , cpu . AF ) cpu . CF = cpu . AF cpu . AH = Operators . ITEBV ( 8 , cpu . AF , cpu . AH + 1 , cpu . AH ) cpu . AL = Operators . ITEBV ( 8 , cpu . AF , cpu . AL + 6 , cpu . AL ) cpu . AL = cpu . AL & 0x0f


def AAD(cpu, imm=None):
        """
        ASCII adjust AX before division.

        Adjusts two unpacked BCD digits (the least-significant digit in the
        AL register and the most-significant digit in the AH register) so that
        a division operation performed on the result will yield a correct unpacked
        BCD value. The AAD instruction is only useful when it precedes a DIV instruction
        that divides (binary division) the adjusted value in the AX register by
        an unpacked BCD value.
        The AAD instruction sets the value in the AL register to (AL + (10 * AH)), and then
        clears the AH register to 00H. The value in the AX register is then equal to the binary
        equivalent of the original unpacked two-digit (base 10) number in registers AH and AL.

        The SF, ZF, and PF flags are set according to the resulting binary value in the AL register.

        This instruction executes as described in compatibility mode and legacy mode.
        It is not valid in 64-bit mode.::

                tempAL  =  AL;
                tempAH  =  AH;
                AL  =  (tempAL + (tempAH * 10)) AND FFH;
                AH  =  0

        :param cpu: current CPU.
        """
        if imm is None:
            imm = 10
        else:
            imm = imm.read()

        cpu.AL += cpu.AH * imm
        cpu.AH = 0

        # Defined flags: ...sz.p.
        cpu._calculate_logic_flags(8, cpu.AL)

def AAD ( cpu , imm = None ) : if imm is None : imm = 10 else : imm = imm . read ( ) cpu . AL += cpu . AH * imm cpu . AH = 0 cpu . _calculate_logic_flags ( 8 , cpu . AL )


def AAM(cpu, imm=None):
        """
        ASCII adjust AX after multiply.

        Adjusts the result of the multiplication of two unpacked BCD values
        to create a pair of unpacked (base 10) BCD values. The AX register is
        the implied source and destination operand for this instruction. The AAM
        instruction is only useful when it follows a MUL instruction that multiplies
        (binary multiplication) two unpacked BCD values and stores a word result
        in the AX register. The AAM instruction then adjusts the contents of the
        AX register to contain the correct 2-digit unpacked (base 10) BCD result.

        The SF, ZF, and PF flags are set according to the resulting binary value in the AL register.

        This instruction executes as described in compatibility mode and legacy mode.
        It is not valid in 64-bit mode.::

                tempAL  =  AL;
                AH  =  tempAL / 10;
                AL  =  tempAL MOD 10;

        :param cpu: current CPU.
        """
        if imm is None:
            imm = 10
        else:
            imm = imm.read()

        cpu.AH = Operators.UDIV(cpu.AL, imm)
        cpu.AL = Operators.UREM(cpu.AL, imm)

        # Defined flags: ...sz.p.
        cpu._calculate_logic_flags(8, cpu.AL)

def AAM ( cpu , imm = None ) : if imm is None : imm = 10 else : imm = imm . read ( ) cpu . AH = Operators . UDIV ( cpu . AL , imm ) cpu . AL = Operators . UREM ( cpu . AL , imm ) cpu . _calculate_logic_flags ( 8 , cpu . AL )


def AAS(cpu):
        """
        ASCII Adjust AL after subtraction.

        Adjusts the result of the subtraction of two unpacked BCD values to  create a unpacked
        BCD result. The AL register is the implied source and destination operand for this instruction.
        The AAS instruction is only useful when it follows a SUB instruction that subtracts
        (binary subtraction) one unpacked BCD value from another and stores a byte result in the AL
        register. The AAA instruction then adjusts the contents of the AL register to contain the
        correct 1-digit unpacked BCD result. If the subtraction produced a decimal carry, the AH register
        is decremented by 1, and the CF and AF flags are set. If no decimal carry occurred, the CF and AF
        flags are cleared, and the AH register is unchanged. In either case, the AL register is left with
        its top nibble set to 0.

        The AF and CF flags are set to 1 if there is a decimal borrow; otherwise, they are cleared to 0.

        This instruction executes as described in compatibility mode and legacy mode.
        It is not valid in 64-bit mode.::

                IF ((AL AND 0FH) > 9) Operators.OR(AF  =  1)
                THEN
                    AX  =  AX - 6;
                    AH  =  AH - 1;
                    AF  =  1;
                    CF  =  1;
                ELSE
                    CF  =  0;
                    AF  =  0;
                FI;
                AL  =  AL AND 0FH;

        :param cpu: current CPU.
        """
        if (cpu.AL & 0x0F > 9) or cpu.AF == 1:
            cpu.AX = cpu.AX - 6
            cpu.AH = cpu.AH - 1
            cpu.AF = True
            cpu.CF = True
        else:
            cpu.AF = False
            cpu.CF = False
        cpu.AL = cpu.AL & 0x0f

def AAS ( cpu ) : if ( cpu . AL & 0x0F > 9 ) or cpu . AF == 1 : cpu . AX = cpu . AX - 6 cpu . AH = cpu . AH - 1 cpu . AF = True cpu . CF = True else : cpu . AF = False cpu . CF = False cpu . AL = cpu . AL & 0x0f


def ADC(cpu, dest, src):
        """
        Adds with carry.

        Adds the destination operand (first operand), the source operand (second operand),
        and the carry (CF) flag and stores the result in the destination operand. The state
        of the CF flag represents a carry from a previous addition. When an immediate value
        is used as an operand, it is sign-extended to the length of the destination operand
        format. The ADC instruction does not distinguish between signed or unsigned operands.
        Instead, the processor evaluates the result for both data types and sets the OF and CF
        flags to indicate a carry in the signed or unsigned result, respectively. The SF flag
        indicates the sign of the signed result. The ADC instruction is usually executed as
        part of a multibyte or multiword addition in which an ADD instruction is followed by an
        ADC instruction::

                DEST  =  DEST + SRC + CF;

        The OF, SF, ZF, AF, CF, and PF flags are set according to the result.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        cpu._ADD(dest, src, carry=True)

def ADC ( cpu , dest , src ) : cpu . _ADD ( dest , src , carry = True )


def CMP(cpu, src1, src2):
        """
        Compares two operands.

        Compares the first source operand with the second source operand and sets the status flags
        in the EFLAGS register according to the results. The comparison is performed by subtracting
        the second operand from the first operand and then setting the status flags in the same manner
        as the SUB instruction. When an immediate value is used as an operand, it is sign-extended to
        the length of the first operand::

                temp  =  SRC1 - SignExtend(SRC2);
                ModifyStatusFlags; (* Modify status flags in the same manner as the SUB instruction*)

        The CF, OF, SF, ZF, AF, and PF flags are set according to the result.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        arg0 = src1.read()
        arg1 = Operators.SEXTEND(src2.read(), src2.size, src1.size)

        # Affected Flags o..szapc
        cpu._calculate_CMP_flags(src1.size, arg0 - arg1, arg0, arg1)

def CMP ( cpu , src1 , src2 ) : arg0 = src1 . read ( ) arg1 = Operators . SEXTEND ( src2 . read ( ) , src2 . size , src1 . size ) cpu . _calculate_CMP_flags ( src1 . size , arg0 - arg1 , arg0 , arg1 )


def CMPXCHG(cpu, dest, src):
        """
        Compares and exchanges.

        Compares the value in the AL, AX, EAX or RAX register (depending on the
        size of the operand) with the first operand (destination operand). If
        the two values are equal, the second operand (source operand) is loaded
        into the destination operand. Otherwise, the destination operand is
        loaded into the AL, AX, EAX or RAX register.

        The ZF flag is set if the values in the destination operand and
        register AL, AX, or EAX are equal; otherwise it is cleared. The CF, PF,
        AF, SF, and OF flags are set according to the results of the comparison
        operation::

        (* accumulator  =  AL, AX, EAX or RAX,  depending on whether *)
        (* a byte, word, a doubleword or a 64bit comparison is being performed*)
        IF accumulator  ==  DEST
        THEN
            ZF  =  1
            DEST  =  SRC
        ELSE
            ZF  =  0
            accumulator  =  DEST
        FI;

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        size = dest.size
        reg_name = {8: 'AL', 16: 'AX', 32: 'EAX', 64: 'RAX'}[size]
        accumulator = cpu.read_register(reg_name)
        sval = src.read()
        dval = dest.read()

        cpu.write_register(reg_name, dval)
        dest.write(Operators.ITEBV(size, accumulator == dval, sval, dval))

        # Affected Flags o..szapc
        cpu._calculate_CMP_flags(size, accumulator - dval, accumulator, dval)

def CMPXCHG ( cpu , dest , src ) : size = dest . size reg_name = { 8 : 'AL' , 16 : 'AX' , 32 : 'EAX' , 64 : 'RAX' } [ size ] accumulator = cpu . read_register ( reg_name ) sval = src . read ( ) dval = dest . read ( ) cpu . write_register ( reg_name , dval ) dest . write ( Operators . ITEBV ( size , accumulator == dval , sval , dval ) ) cpu . _calculate_CMP_flags ( size , accumulator - dval , accumulator , dval )


def CMPXCHG8B(cpu, dest):
        """
        Compares and exchanges bytes.

        Compares the 64-bit value in EDX:EAX (or 128-bit value in RDX:RAX if
        operand size is 128 bits) with the operand (destination operand). If
        the values are equal, the 64-bit value in ECX:EBX (or 128-bit value in
        RCX:RBX) is stored in the destination operand.  Otherwise, the value in
        the destination operand is loaded into EDX:EAX (or RDX:RAX)::

                IF (64-Bit Mode and OperandSize = 64)
                THEN
                    IF (RDX:RAX = DEST)
                    THEN
                        ZF = 1;
                        DEST = RCX:RBX;
                    ELSE
                        ZF = 0;
                        RDX:RAX = DEST;
                    FI
                ELSE
                    IF (EDX:EAX = DEST)
                    THEN
                        ZF = 1;
                        DEST = ECX:EBX;
                    ELSE
                        ZF = 0;
                        EDX:EAX = DEST;
                    FI;
                FI;

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        size = dest.size
        cmp_reg_name_l = {64: 'EAX', 128: 'RAX'}[size]
        cmp_reg_name_h = {64: 'EDX', 128: 'RDX'}[size]
        src_reg_name_l = {64: 'EBX', 128: 'RBX'}[size]
        src_reg_name_h = {64: 'ECX', 128: 'RCX'}[size]

        # EDX:EAX or RDX:RAX
        cmph = cpu.read_register(cmp_reg_name_h)
        cmpl = cpu.read_register(cmp_reg_name_l)

        srch = cpu.read_register(src_reg_name_h)
        srcl = cpu.read_register(src_reg_name_l)

        cmp0 = Operators.CONCAT(size, cmph, cmpl)
        src0 = Operators.CONCAT(size, srch, srcl)
        arg_dest = dest.read()
        cpu.ZF = arg_dest == cmp0

        dest.write(
            Operators.ITEBV(size, cpu.ZF,
                            Operators.CONCAT(size, srch, srcl),
                            arg_dest)
        )
        cpu.write_register(cmp_reg_name_l, Operators.ITEBV(size // 2, cpu.ZF, cmpl,
                                                           Operators.EXTRACT(arg_dest, 0, size // 2)))
        cpu.write_register(cmp_reg_name_h, Operators.ITEBV(size // 2, cpu.ZF, cmph,
                                                           Operators.EXTRACT(arg_dest, size // 2, size // 2)))

def CMPXCHG8B ( cpu , dest ) : size = dest . size cmp_reg_name_l = { 64 : 'EAX' , 128 : 'RAX' } [ size ] cmp_reg_name_h = { 64 : 'EDX' , 128 : 'RDX' } [ size ] src_reg_name_l = { 64 : 'EBX' , 128 : 'RBX' } [ size ] src_reg_name_h = { 64 : 'ECX' , 128 : 'RCX' } [ size ] cmph = cpu . read_register ( cmp_reg_name_h ) cmpl = cpu . read_register ( cmp_reg_name_l ) srch = cpu . read_register ( src_reg_name_h ) srcl = cpu . read_register ( src_reg_name_l ) cmp0 = Operators . CONCAT ( size , cmph , cmpl ) src0 = Operators . CONCAT ( size , srch , srcl ) arg_dest = dest . read ( ) cpu . ZF = arg_dest == cmp0 dest . write ( Operators . ITEBV ( size , cpu . ZF , Operators . CONCAT ( size , srch , srcl ) , arg_dest ) ) cpu . write_register ( cmp_reg_name_l , Operators . ITEBV ( size // 2 , cpu . ZF , cmpl , Operators . EXTRACT ( arg_dest , 0 , size // 2 ) ) ) cpu . write_register ( cmp_reg_name_h , Operators . ITEBV ( size // 2 , cpu . ZF , cmph , Operators . EXTRACT ( arg_dest , size // 2 , size // 2 ) ) )


def DAA(cpu):
        """
        Decimal adjusts AL after addition.

        Adjusts the sum of two packed BCD values to create a packed BCD result. The AL register
        is the implied source and destination operand. If a decimal carry is detected, the CF
        and AF flags are set accordingly.
        The CF and AF flags are set if the adjustment of the value results in a decimal carry in
        either digit of the result. The SF, ZF, and PF flags are set according to the result.

        This instruction is not valid in 64-bit mode.::

                IF (((AL AND 0FH) > 9) or AF  =  1)
                THEN
                    AL  =  AL + 6;
                    CF  =  CF OR CarryFromLastAddition; (* CF OR carry from AL  =  AL + 6 *)
                    AF  =  1;
                ELSE
                    AF  =  0;
                FI;
                IF ((AL AND F0H) > 90H) or CF  =  1)
                THEN
                    AL  =  AL + 60H;
                    CF  =  1;
                ELSE
                    CF  =  0;
                FI;

        :param cpu: current CPU.
        """

        cpu.AF = Operators.OR((cpu.AL & 0x0f) > 9, cpu.AF)
        oldAL = cpu.AL
        cpu.AL = Operators.ITEBV(8, cpu.AF, cpu.AL + 6, cpu.AL)
        cpu.CF = Operators.ITE(cpu.AF, Operators.OR(cpu.CF, cpu.AL < oldAL), cpu.CF)

        cpu.CF = Operators.OR((cpu.AL & 0xf0) > 0x90, cpu.CF)
        cpu.AL = Operators.ITEBV(8, cpu.CF, cpu.AL + 0x60, cpu.AL)
        """
        #old not-symbolic aware version...
        if ((cpu.AL & 0x0f) > 9) or cpu.AF:
            oldAL = cpu.AL
            cpu.AL =  cpu.AL + 6
            cpu.CF = Operators.OR(cpu.CF, cpu.AL < oldAL)
            cpu.AF  =  True
        else:
            cpu.AF  =  False

        if ((cpu.AL & 0xf0) > 0x90) or cpu.CF:
            cpu.AL  = cpu.AL + 0x60
            cpu.CF  =  True
        else:
            cpu.CF  =  False
        """

        cpu.ZF = cpu.AL == 0
        cpu.SF = (cpu.AL & 0x80) != 0
        cpu.PF = cpu._calculate_parity_flag(cpu.AL)

def DAA ( cpu ) : cpu . AF = Operators . OR ( ( cpu . AL & 0x0f ) > 9 , cpu . AF ) oldAL = cpu . AL cpu . AL = Operators . ITEBV ( 8 , cpu . AF , cpu . AL + 6 , cpu . AL ) cpu . CF = Operators . ITE ( cpu . AF , Operators . OR ( cpu . CF , cpu . AL < oldAL ) , cpu . CF ) cpu . CF = Operators . OR ( ( cpu . AL & 0xf0 ) > 0x90 , cpu . CF ) cpu . AL = Operators . ITEBV ( 8 , cpu . CF , cpu . AL + 0x60 , cpu . AL ) cpu . ZF = cpu . AL == 0 cpu . SF = ( cpu . AL & 0x80 ) != 0 cpu . PF = cpu . _calculate_parity_flag ( cpu . AL )


def DAS(cpu):
        """
        Decimal adjusts AL after subtraction.

        Adjusts the result of the subtraction of two packed BCD values to create a packed BCD result.
        The AL register is the implied source and destination operand. If a decimal borrow is detected,
        the CF and AF flags are set accordingly. This instruction is not valid in 64-bit mode.

        The SF, ZF, and PF flags are set according to the result.::

                IF (AL AND 0FH) > 9 OR AF  =  1
                THEN
                    AL  =  AL - 6;
                    CF  =  CF OR BorrowFromLastSubtraction; (* CF OR borrow from AL  =  AL - 6 *)
                    AF  =  1;
                ELSE
                    AF  =  0;
                FI;
                IF ((AL > 99H) or OLD_CF  =  1)
                THEN
                    AL  =  AL - 60H;
                    CF  =  1;

        :param cpu: current CPU.
        """
        oldAL = cpu.AL
        oldCF = cpu.CF

        cpu.AF = Operators.OR((cpu.AL & 0x0f) > 9, cpu.AF)
        cpu.AL = Operators.ITEBV(8, cpu.AF, cpu.AL - 6, cpu.AL)
        cpu.CF = Operators.ITE(cpu.AF, Operators.OR(oldCF, cpu.AL > oldAL), cpu.CF)

        cpu.CF = Operators.ITE(Operators.OR(oldAL > 0x99, oldCF), True, cpu.CF)
        cpu.AL = Operators.ITEBV(8, Operators.OR(oldAL > 0x99, oldCF), cpu.AL - 0x60, cpu.AL)
        #
        """
        if (cpu.AL & 0x0f) > 9 or cpu.AF:
            cpu.AL = cpu.AL - 6;
            cpu.CF = Operators.OR(oldCF, cpu.AL > oldAL)
            cpu.AF = True
        else:
            cpu.AF  =  False

        if ((oldAL > 0x99) or oldCF):
            cpu.AL = cpu.AL - 0x60
            cpu.CF = True
        """
        cpu.ZF = cpu.AL == 0
        cpu.SF = (cpu.AL & 0x80) != 0
        cpu.PF = cpu._calculate_parity_flag(cpu.AL)

def DAS ( cpu ) : oldAL = cpu . AL oldCF = cpu . CF cpu . AF = Operators . OR ( ( cpu . AL & 0x0f ) > 9 , cpu . AF ) cpu . AL = Operators . ITEBV ( 8 , cpu . AF , cpu . AL - 6 , cpu . AL ) cpu . CF = Operators . ITE ( cpu . AF , Operators . OR ( oldCF , cpu . AL > oldAL ) , cpu . CF ) cpu . CF = Operators . ITE ( Operators . OR ( oldAL > 0x99 , oldCF ) , True , cpu . CF ) cpu . AL = Operators . ITEBV ( 8 , Operators . OR ( oldAL > 0x99 , oldCF ) , cpu . AL - 0x60 , cpu . AL ) cpu . ZF = cpu . AL == 0 cpu . SF = ( cpu . AL & 0x80 ) != 0 cpu . PF = cpu . _calculate_parity_flag ( cpu . AL )


def DIV(cpu, src):
        """
        Unsigned divide.

        Divides (unsigned) the value in the AX register, DX:AX register pair,
        or EDX:EAX or RDX:RAX register pair (dividend) by the source operand
        (divisor) and stores the result in the AX (AH:AL), DX:AX, EDX:EAX or
        RDX:RAX registers. The source operand can be a general-purpose register
        or a memory location. The action of this instruction depends of the
        operand size (dividend/divisor). Division using 64-bit operand is
        available only in 64-bit mode. Non-integral results are truncated
        (chopped) towards 0. The reminder is always less than the divisor in
        magnitude. Overflow is indicated with the #DE (divide error) exception
        rather than with the CF flag::

            IF SRC  =  0
                THEN #DE; FI;(* divide error *)
            IF OperandSize  =  8 (* word/byte operation *)
                THEN
                    temp  =  AX / SRC;
                    IF temp > FFH
                        THEN #DE; (* divide error *) ;
                        ELSE
                            AL  =  temp;
                            AH  =  AX MOD SRC;
                    FI;
                ELSE IF OperandSize  =  16 (* doubleword/word operation *)
                    THEN
                        temp  =  DX:AX / SRC;
                        IF temp > FFFFH
                            THEN #DE; (* divide error *) ;
                        ELSE
                            AX  =  temp;
                            DX  =  DX:AX MOD SRC;
                        FI;
                    FI;
                ELSE If OperandSize = 32 (* quadword/doubleword operation *)
                    THEN
                        temp  =  EDX:EAX / SRC;
                        IF temp > FFFFFFFFH
                            THEN #DE; (* divide error *) ;
                        ELSE
                            EAX  =  temp;
                            EDX  =  EDX:EAX MOD SRC;
                        FI;
                    FI;
                ELSE IF OperandSize = 64 (*Doublequadword/quadword operation*)
                    THEN
                        temp = RDX:RAX / SRC;
                        IF temp > FFFFFFFFFFFFFFFFH
                            THEN #DE; (* Divide error *)
                        ELSE
                            RAX = temp;
                            RDX = RDX:RAX MOD SRC;
                        FI;
                    FI;
            FI;

        :param cpu: current CPU.
        :param src: source operand.
        """
        size = src.size
        reg_name_h = {8: 'DL', 16: 'DX', 32: 'EDX', 64: 'RDX'}[size]
        reg_name_l = {8: 'AL', 16: 'AX', 32: 'EAX', 64: 'RAX'}[size]

        dividend = Operators.CONCAT(size * 2,
                                    cpu.read_register(reg_name_h),
                                    cpu.read_register(reg_name_l))
        divisor = Operators.ZEXTEND(src.read(), size * 2)

        # TODO make symbol friendly
        if isinstance(divisor, int) and divisor == 0:
            raise DivideByZeroError()
        quotient = Operators.UDIV(dividend, divisor)

        MASK = (1 << size) - 1

        # TODO make symbol friendly
        if isinstance(quotient, int) and quotient > MASK:
            raise DivideByZeroError()
        remainder = Operators.UREM(dividend, divisor)

        cpu.write_register(reg_name_l, Operators.EXTRACT(quotient, 0, size))
        cpu.write_register(reg_name_h, Operators.EXTRACT(remainder, 0, size))

def DIV ( cpu , src ) : size = src . size reg_name_h = { 8 : 'DL' , 16 : 'DX' , 32 : 'EDX' , 64 : 'RDX' } [ size ] reg_name_l = { 8 : 'AL' , 16 : 'AX' , 32 : 'EAX' , 64 : 'RAX' } [ size ] dividend = Operators . CONCAT ( size * 2 , cpu . read_register ( reg_name_h ) , cpu . read_register ( reg_name_l ) ) divisor = Operators . ZEXTEND ( src . read ( ) , size * 2 ) if isinstance ( divisor , int ) and divisor == 0 : raise DivideByZeroError ( ) quotient = Operators . UDIV ( dividend , divisor ) MASK = ( 1 << size ) - 1 if isinstance ( quotient , int ) and quotient > MASK : raise DivideByZeroError ( ) remainder = Operators . UREM ( dividend , divisor ) cpu . write_register ( reg_name_l , Operators . EXTRACT ( quotient , 0 , size ) ) cpu . write_register ( reg_name_h , Operators . EXTRACT ( remainder , 0 , size ) )