Beispiel #1
0
    def exec_If(self, node, scope):
        '''
        In our implementation, we try to evaluate the if condition. If the value is known, then we execute the appropriate branch.
        Otherwise, we choose randomly a branch.
        '''
        from random import randint

        test_typez = self.eval_code(node.test,scope)
        if isinstance(test_typez,Typez):
            if test_typez.value is not None:
                if (not is_none(test_typez)) and test_typez.value!="" and test_typez.value!=0 and not (test_typez.scope['__class__']==self.extern_scope['bool'] and not test_typez.value):
                    for _node in node.body:
                        self.eval_code(_node, scope)
                else:
                    for _node in node.orelse:
                        self.eval_code(_node, scope)
            else:
                self.nondet=True
                bit = randint(0,1)
                if bit:
                    for _node in node.body:
                        self.eval_code(_node, scope)
                else:
                    for _node in node.orelse:
                        self.eval_code(_node, scope)
        else:
            self.warn(node, symbol = 'evaluation of condition failed', message = 'could not evaluate if condition')
Beispiel #2
0
    def _exec_fun(self, fun_type, args, keywords, scope, create_scope = True, node = None):
        """
        executes function with given args in the given scope. When create_scope is True, it creates new scope for the function
        executing with parameter scope as its parent. Otherwise, it executes function in the given
        scope.
        
        """
        #if we dont know the fun_type, return any_type
        if fun_type.kind=='any':
            return any_type

        from random import randint
        
        if fun_type == self.extern_scope['inf_hasattr']:
            a=args[0]
            b=args[1]
            if b.value is not None:
                res = a.resolve(b.value)
                if res is None:
                    return Typez(kind='const', value = False, __class__ = self.extern_scope['bool'])
                else:
                    return Typez(kind='const', value = True, __class__ = self.extern_scope['bool'])
            self.nondet=True
            bit = randint(0,1)
            if bit:
                return Typez(kind='const', value = True, __class__ = self.extern_scope['bool'])
            else:
                return Typez(kind='const', value = False, __class__ = self.extern_scope['bool'])
            
        
        if fun_type == self.extern_scope['inf_random']:
            self.nondet=True
            bit = randint(0,1)
            if bit:
                return Typez(kind='const', value = 1, __class__ = self.extern_scope['num'])
            else:
                return Typez(kind='const', value = 0, __class__ = self.extern_scope['num'])
        
        if fun_type == self.extern_scope['inf_equal']:
            a=args[0]
            b=args[1]
            if a.value is not None and b.value is not None:
                left = a.value
                right = b.value
                if isinstance(a.value, bool):
                    if a.value:
                        left = 1
                    else:
                        left = 0      
                if isinstance(b.value, bool):
                    if b.value:
                        right = 1
                    else:
                        right = 0
                if left==right:
                    return Typez(kind='const', value = True, __class__ = self.extern_scope['bool'])
                else:
                    return Typez(kind='const', value = False, __class__ = self.extern_scope['bool'])
            else:
                self.nondet=True
                bit = randint(0,1)
                if bit:
                    return Typez(kind='const', value = True, __class__ = self.extern_scope['bool'])
                else:
                    return Typez(kind='const', value = False, __class__ = self.extern_scope['bool'])
        
        if fun_type == self.extern_scope['inf_is']:
            #we truly determine only if the statement is in form - smth is None
            if is_none(args[1]): 
                if is_none(args[0]):
                    return Typez(kind='const', value = True, __class__ = self.extern_scope['bool'])
                else:
                    return Typez(kind='const', value = False, __class__ = self.extern_scope['bool'])
            else:
                self.nondet=True
                bit = randint(0,1)
                if bit:
                    return Typez(kind='const', value = True, __class__ = self.extern_scope['bool'])
                else:
                    return Typez(kind='const', value = False, __class__ = self.extern_scope['bool'])
        if fun_type == self.extern_scope['isinstance']:
            if isinstance(args[0],Typez) and isinstance(args[1],Typez):
                instance = args[0]
                clazz = args[1]
                
                res = instance.resolve_class(clazz)
                if not res is None:
                    return Typez(kind='const', value = True, __class__ = self.extern_scope['bool'])
                else:
                    return Typez(kind='const', value = False, __class__ = self.extern_scope['bool'])
            else:
                self.warn(node, symbol = 'isinstance error', message = 'isinstance bad arguments')

        if fun_type == self.extern_scope['inf_setattr']:
            attr = args[1]
            if isinstance(attr, Typez) and isinstance(attr.value, str):
                attr = attr.value
            if isinstance(attr, str):
                args[0].scope[attr] = args[2]
               
        if create_scope:
            fun_scope = Scope(parent = scope)
        else:
            fun_scope = scope
        def_args = fun_type.node.args.args
        def_default_args = fun_type.node.args.defaults
        def_args_names = [arg.arg for arg in def_args]
        count_given_args = len(args)+len(keywords)
        if count_given_args > len(def_args) or count_given_args+len(def_default_args)< len(def_args):
            symbol = not_none(safe_resolve(node, 'func.attr'), safe_resolve(node, 'func.id'))
            self.warn(node, symbol = symbol, message = 'bad number of arguments (%d given, %d expected)'%(len(args), len(def_args)))
        for keyword in keywords:
            if not keyword in def_args_names:
                symbol = not_none(safe_resolve(node, 'func.attr'), safe_resolve(node, 'func.id'))
                self.warn(node, symbol = symbol, message = 'unexpected keyword argument %s'%(keyword))
        
        for i,arg in enumerate(def_args):
            if i<len(args):
                if arg.arg in keywords:
                    symbol = not_none(safe_resolve(node, 'func.attr'), safe_resolve(node, 'func.id'))
                    self.warn(node, symbol = symbol, message = 'multiple arguments for keyword argument %s'%(arg.arg))
                fun_scope[arg.arg] = args[i]
            else:
                found=False
                for j,key in enumerate(keywords):
                    if key==arg.arg:
                        found=True
                        fun_scope[arg.arg]=keywords[key]
                if not found:
                    lengthFromEnd = len(def_args)-i
                    if len(def_default_args) >= lengthFromEnd:
                        fun_scope[arg.arg]=self.eval_code(def_default_args[-lengthFromEnd],scope)
                    else:
                        fun_scope[arg.arg] = any_type
        try:
            for _node in fun_type.node.body:
                self.eval_code(_node, fun_scope)
        except ReturnException as e:
            res=e.res
            if isinstance(res, Typez) and  "__class__" in res.scope and (res.scope["__class__"] == self.extern_scope['ProblemException']):    
                error = res.scope["error"]
                message = res.scope["message"]
                #symbol = res.scope["symbol"]
                symbol = None
                for key,val in scope.items():
                    if val==error:
                        symbol = key
                #when error is caused by constant, symbol is its type
                if symbol is None:
                    if hasattr(error.scope['__class__'].node, 'name'):
                        symbol = error.scope['__class__'].node.name
                    else:
                        #default symbol
                        symbol = 'Type error'
                if is_none(message):
                    #default message because it is very often used
                    message_value = "unsupported operand type"
                else:
                    message_value = message.value
                self.warn(node, message_value, symbol)
                return any_type
            
            if isinstance(res, Typez) and  "__class__" in res.scope and (res.scope["__class__"] == self.extern_scope['TypeContainer']):      
                gen_type=res.scope["T"]
                result = Typez(kind='const',__class__ = gen_type)
                return result
 
            return res
        
        if fun_type.kind == 'classdef':
            return args[0]