예제 #1
0
def convert(node):
    loop_node = node.loop_node
    parent_index = node.parent[1]  # index in the AST of the original loop
    node.parent[0].block_items.pop(
        parent_index)  # remove the original loop from AST
    body = []  # list of new AST nodes for each peel
    original_body = []
    if loop_node.stmt.block_items is not None:
        original_body = loop_node.stmt.block_items
    if isinstance(loop_node, c_ast.For):
        if loop_node.init is not None:
            body.append(
                loop_node.init.decls[0]
            )  # add the initialization of the loop var before the loop
        if loop_node.next is not None:
            loop_node.stmt = c_ast.Compound(
                original_body +
                [loop_node.next
                 ])  # add the inc/dec of the loop var at the end of the body
        body.append(c_ast.While(loop_node.cond, loop_node.stmt))
    if isinstance(
            loop_node, c_ast.DoWhile
    ):  # if loop is a DoWhile, add the commands of the first peel outside of the loop
        for i in original_body:  # add each command to the modified AST
            body.append(i)
        body.append(c_ast.While(loop_node.cond, c_ast.Compound(original_body)))
    for i in body:  # add new nodes to the modified AST
        node.parent[0].block_items.insert(parent_index, i)
        parent_index = parent_index + 1
    node.parent = (node.parent[0], parent_index - 1)  # update the parent
예제 #2
0
    def from_code(self, code: str, parser=None):
        """
		Takes (partial) C code as a string and returns the AST node that belongs to it. Wraps everything in a block.
		Note: This function may not understand all code strings and shall be used with care. But, it understands
		everything that is either directly valid C code, or partial code that can be put into a function body or as a
		condition block (e.g. if and while conditions).
		:param code: The C code.
		:param parser: If you have already created a parser, you can hint it here. No need to create multiple parsers.
		:return: The corresponding AST compound.
		:rtype: c_ast.Compound or None
		"""
        # TODO this is a bit hacky, trying to wrap the code s.t. it is hopefully valid to allow for partial parsing.
        if not parser: parser = GnuCParser()
        try:
            ast = parser.parse(code)
            return c_ast.Compound(ast.ext)
        except:
            try:
                wrapped_code = "void f() { " + code + " }"
                ast = parser.parse(wrapped_code)
                return ast.ext[0].body
            except:
                try:
                    wrapped_code = "void f() { if(" + code + ") {} }"
                    ast = parser.parse(wrapped_code)
                    return c_ast.Compound(
                        [ast.ext[0].body.block_items[0].cond])
                except Exception as e:
                    print(e)
                    return None
예제 #3
0
    def realProcess(self, astNode):
        typ = type(astNode)

        def checkCompound(node):
            """
            检查一个节点是否是大括号的语句块
            """
            return node and not isinstance(node, c_ast.Compound)

        # if 语句
        if typ == c_ast.If:
            if checkCompound(astNode.iftrue):
                newCompound = c_ast.Compound([astNode.iftrue])
                astNode.iftrue = newCompound
            if checkCompound(astNode.iffalse):
                newFCompound = c_ast.Compound([astNode.iffalse])
                astNode.iffalse = newFCompound
        # For
        if typ == c_ast.For:
            if checkCompound(astNode.stmt):
                newCompound = c_ast.Compound([astNode.stmt])
                astNode.stmt = newCompound
        # While
        if typ == c_ast.While:
            if checkCompound(astNode.stmt):
                newCompound = c_ast.Compound([astNode.stmt])
                astNode.stmt = newCompound
예제 #4
0
def optimize_new(graph, tabDeg, myWhile):
    maxdeg = max_deg_of_list(tabDeg)
    while_node = myWhile.node_while
    peeling_deg = maxdeg + 1
    if peeling_deg == 0:
        myWhile.isOpt = True
        return 0
    initial_indices = []
    tabDegs = []
    nodelists = []
    listIf = []
    for i in range(peeling_deg):
        nodelists.append([])
        tabDegs.append([])
        initial_indices.append([])
    for i in range(len(tabDeg)):
        for j in range(len(initial_indices)):
            initial_indices[j].append(i)
    for deg in tabDeg:
        for i in range(len(tabDegs)):
            tabDegs[i].append(deg)
    for node in while_node.stmt.block_items:
        for i in range(peeling_deg):
            nodelists[i].append(node)
    for i in range(maxdeg):
        tbrm = []
        for init_ind in initial_indices[i]:
            if init_ind != -1:
                if tabDeg[init_ind] == i + 1:
                    tbrm.append(init_ind)
        for init_ind in tbrm:
            curr_ind = initial_indices[i].index(init_ind)
            (capture_tab, recover_tab) = captures(init_ind, myWhile.node_while,
                                                  tabDeg, graph)
            for capture in capture_tab:
                if capture[1] == -1 or capture[1] > i + 1:
                    for k in range(len(capture[0])):
                        nodelists[i].insert(curr_ind + 1, capture[0][k])
                        initial_indices[i].insert(curr_ind + 1, -1)
            for j in range(i + 1, peeling_deg):
                curr_ind = initial_indices[j].index(init_ind)
                for (recover, deg) in recover_tab:
                    if deg == -1 or deg > j:
                        nodelists[j].insert(curr_ind + 1, recover)
                        initial_indices[j].insert(curr_ind + 1, -1)
                nodelists[j].pop(curr_ind)
                initial_indices[j].pop(curr_ind)
        if DEBUG_LEVEL >= 3:
            print(maxdeg, nodelists, initial_indices)
        listIf.append(
            c_ast.If(while_node.cond, c_ast.Compound(nodelists[i]), None))
    listIf.append(
        c_ast.While(while_node.cond, c_ast.Compound(nodelists[maxdeg]), None))
    myWhile.parent[0].block_items.pop(myWhile.parent[1])
    listIf.reverse()
    for node in listIf:
        myWhile.parent[0].block_items.insert(myWhile.parent[1], node)
    myWhile.show()
    myWhile.isOpt = True
예제 #5
0
    def merge_libs_calls(self, node):
        start = -1
        end = -1
        argumented_client = None
        argumented_lib = None
        LibCV = LibCallHunter(self.lib_name)
        if isinstance(node, c_ast.If):
            if isinstance(node.iftrue, c_ast.Compound):
                checking_blocks = node.iftrue.block_items
        elif isinstance(node, c_ast.FuncDef):
            checking_blocks = node.body.block_items
        elif isinstance(node, c_ast.Compound):
            checking_blocks = node.block_items
        else:
            checking_blocks = []

        new_leaf = set()
        mulitiple_call = False
        for index in range(len(checking_blocks)):
            LibCV.use_lib = False
            block = checking_blocks[index]
            LibCV.visit(block)
            if LibCV.use_lib:
                for lib in LibCV.lib_node:
                    l_object = self.node_dict.get(lib, None)
                    if l_object is None:
                        l_object, _ = self.create_ClientContextNode(
                            lib, lib, None, lib, None)
                        self.node_dict[node] = l_object
                    new_leaf.add(l_object)

                if (start == -1):
                    start = index
                if (end < index):
                    end = index
                if (len(LibCV.lib_node) > 1):
                    mulitiple_call = True

        if (end > start) or (start == end and mulitiple_call):
            argumented_lib = c_ast.Compound(
                block_items=checking_blocks[start:end + 1])
            argumented_client = copy.deepcopy(node)
            if isinstance(argumented_client, c_ast.If):
                if isinstance(argumented_client.iftrue, c_ast.Compound):
                    blocks = argumented_client.iftrue.block_items
                    argumented_client.iftrue.block_items = blocks[:start] + [
                        c_ast.FuncCall(name=c_ast.ID(name="CLEVER_DELETE"),
                                       args=None)
                    ] + blocks[end + 1:]
            elif isinstance(argumented_client, c_ast.FuncDef):
                blocks = argumented_client.body.block_items
                argumented_client.body.block_items = blocks[:start] + [
                    c_ast.Compound(block_items=[
                        c_ast.FuncCall(name=c_ast.ID(name="CLEVER_DELETE"),
                                       args=None)
                    ] + checking_blocks[start:end + 1])
                ] + blocks[end + 1:]

        return start, end, argumented_lib, argumented_client, new_leaf
예제 #6
0
    def visit_If(self, node):
        if type(node.iftrue) is not c_ast.Compound:
            node.iftrue = c_ast.Compound([node.iftrue])
        if type(node.iffalse) is not c_ast.Compound:
            node.iffalse = c_ast.Compound([node.iffalse])

        self.generic_visit(node.iftrue)
        self.generic_visit(node.iffalse)
예제 #7
0
 def visit_If(self, node):
     if node.iftrue is not None and not isinstance(node.iftrue,
                                                   c_ast.Compound):
         node.iftrue = c_ast.Compound([node.iftrue])
     if node.iffalse is not None and not isinstance(node.iffalse,
                                                    c_ast.Compound):
         node.iffalse = c_ast.Compound([node.iffalse])
     self.generic_visit(node)
  def visit_FuncDef(self, node):
    # Skip if no loop counters exist
    if self.loop_counter_size == 0:
      return

    # Create loop_counter declaration/initialization
    constants = [c_ast.Constant("int", '0') for i in range(self.loop_counter_size)]
    init_list = c_ast.InitList(constants)
    identifier_type = c_ast.IdentifierType(["int"])
    type_decl = c_ast.TypeDecl("loop_counter", [], identifier_type)
    dim = c_ast.Constant("int", str(self.loop_counter_size))
    array_decl = c_ast.ArrayDecl(type_decl, dim, [])
    decl = c_ast.Decl("loop_counter", [], [], [], array_decl, init_list, None) 
    node.body.block_items.insert(0, decl)

    # Label for return values to goto
    start_label = c_ast.Label("print_loop_counter", c_ast.EmptyStatement())
    # Start and end labels used for inserting preprocessor commands for #if DEBUG_EN
    end_label = c_ast.Label("print_loop_counter_end", c_ast.EmptyStatement())

    # Write to file
    if self.write_to_file:
      stmt = c_ast.ID("write_array(loop_counter, %d)\n" % (self.loop_counter_size))
      compound = c_ast.Compound([start_label, stmt, end_label])
    # Print to stdout
    else:
      # Add printf to the end of function
      # Start of printing
      stmt_start = c_ast.ID("printf(\"loop counter = (\")")

      # For loop
      # int i;
      identifier_type = c_ast.IdentifierType(["int"])
      type_decl = c_ast.TypeDecl("i", [], identifier_type)
      for_decl = c_ast.Decl("i", [], [], [], type_decl, [], None)
      # i = 0
      init = c_ast.Assignment("=", c_ast.ID("i"), c_ast.Constant("int", '0'))
      # i < self.loop_counter_size
      cond = c_ast.BinaryOp("<", c_ast.ID("i"), c_ast.Constant("int", str(self.loop_counter_size)))
      # i++
      next_stmt = c_ast.UnaryOp("p++", c_ast.ID("i"))
      # printf in for
      stmt = c_ast.ID("printf(\"%d, \", loop_counter[i])")
      # Cosntruct for loop
      stmt_for = c_ast.For(init, cond, next_stmt, stmt)

      # End of printing
      stmt_end = c_ast.ID("printf(\")\\n\")")
      
      # Put it all together
      body = c_ast.Compound([stmt_start, for_decl, stmt_for, stmt_end])
      # Surround with labels
      compound = c_ast.Compound([start_label, body, end_label])
    node.body.block_items.append(compound)
예제 #9
0
 def insertTest(self, block, functionName, varVals, varTypes, timer, preOut,
                testId):
     #Fork call
     cFork = c_ast.Assignment(lvalue=c_ast.ID(name='child_pid'),
                              op='=',
                              rvalue=c_ast.FuncCall(c_ast.ID(name='fork'),
                                                    args=None))
     #Child
     ##stdout = freopen("out.txt", "w", stdout);
     fileOut = c_ast.Constant(type="char",
                              value='"' + preOut + '.' + testId +
                              ".out.txt" + '"')
     fileW = c_ast.Constant(type="char", value='"' + "w" + '"')
     fileStdout = c_ast.ID(name='stdout')
     expressList = [fileOut, fileW, fileStdout]
     freopenC = c_ast.FuncCall(c_ast.ID(name="freopen"),
                               c_ast.ExprList(expressList))
     outReassign = c_ast.Assignment(lvalue=fileStdout,
                                    op='=',
                                    rvalue=freopenC)
     ##mainfake()
     expressList = list(
         c_ast.Constant(type=varTypes[i], value=str(varVals[i]))
         for i in range(len(varVals)))
     funcCall = c_ast.FuncCall(c_ast.ID(name=functionName),
                               c_ast.ExprList(expressList))
     funcCall = c_ast.FuncCall(c_ast.ID(name=functionName),
                               c_ast.ExprList(expressList))
     ##exit(0)
     funcCall2 = c_ast.FuncCall(
         c_ast.ID(name="exit"),
         c_ast.ExprList([c_ast.Constant(type='int', value='0')]))
     #Parent
     cAlarm = c_ast.FuncCall(
         c_ast.ID(name='alarm'),
         c_ast.ExprList([c_ast.Constant(type='int', value=str(timer))]))
     cWait = c_ast.FuncCall(c_ast.ID(name='wait'),
                            c_ast.ExprList([c_ast.ID(name='0')]))
     #IFs
     if_false = c_ast.If(c_ast.BinaryOp(left=c_ast.ID(name='child_pid'),
                                        op='==',
                                        right=c_ast.Constant(type='int',
                                                             value='0')),
                         c_ast.Compound([outReassign, funcCall, funcCall2]),
                         iffalse=None)
     if_ini = c_ast.If(c_ast.BinaryOp(left=c_ast.ID(name='child_pid'),
                                      op='>',
                                      right=c_ast.Constant(type='int',
                                                           value='0')),
                       c_ast.Compound([cAlarm, cWait]),
                       iffalse=if_false)
     block.body.block_items.insert(1, if_ini)
     block.body.block_items.insert(1, cFork)
예제 #10
0
 def generic_visit(self, node):
     #print(node.coord)
     if (isinstance(node, c_ast.If)):
         if (node.iftrue and not (isinstance(node.iftrue, c_ast.Compound))):
             node.iftrue = c_ast.Compound([node.iftrue])
         if (node.iffalse
                 and not (isinstance(node.iffalse, c_ast.Compound))):
             node.iffalse = c_ast.Compound([node.iffalse])
     elif (isinstance(node, c_ast.For)):
         if (node.stmt and not (isinstance(node.stmt, c_ast.Compound))):
             node.stmt = c_ast.Compound([node.stmt])
     for c_name, c in node.children():
         self.visit(c)
예제 #11
0
 def visit_Assignment(self, node):
     if self.inner_for:
         self.remove_node()
         if self.begin:
             if not self.inner_begin_block:
                 self.inner_begin_block = c_ast.Compound([])
                 code = c_ast.If(c_ast.BinaryOp("==", self.inner_index, c_ast.Constant('int', '0')), self.inner_begin_block, None)
                 self.inner_for.stmt.block_items.insert(0, code)
             self.inner_begin_block.block_items.append(node)
         else:
             if not self.inner_end_block:
                 self.inner_end_block = c_ast.Compound([])
                 code = c_ast.If(c_ast.BinaryOp("==", self.inner_index, c_ast.BinaryOp('-', self.inner_limit, c_ast.Constant('int', '1'))), self.inner_end_block, None)
                 self.inner_for.stmt.block_items.append(code)
             self.inner_end_block.block_items.append(node)
예제 #12
0
def merge_ast_tree(ast_tree, ext_index, bock_item_index, new_node, mode):

    ext_after = []
    block_items_after = []
    block_items_before = []
    ext_before = ast_tree.ext[:ext_index]
    if (len(ast_tree.ext) > 1):
        ext_after = ast_tree.ext[ext_index + 1:]

    func_def_decl = ast_tree.ext[ext_index].decl
    para_decl = ast_tree.ext[ext_index].param_decls
    if (bock_item_index + 1 <= len(ast_tree.ext[ext_index].body.block_items)):
        if (mode == "insert_after"):
            block_items_before = ast_tree.ext[
                ext_index].body.block_items[:bock_item_index + 1]
    if (mode == "insert_before"):
        block_items_before = ast_tree.ext[
            ext_index].body.block_items[:bock_item_index]

    if (len(ast_tree.ext[ext_index].body.block_items) > 1):
        if (mode == "insert_after"):
            block_items_after = ast_tree.ext[ext_index].body.block_items[
                bock_item_index + 1:]
    if (mode == "insert_before"):
        block_items_after = ast_tree.ext[ext_index].body.block_items[
            bock_item_index:]

    block_items_before.append(new_node)
    changed_body = c_ast.Compound(block_items_before + block_items_after)
    changed_ext = c_ast.FuncDef(func_def_decl, para_decl, changed_body)
    ext_before.append(changed_ext)
    ast_tree = c_ast.FileAST(ext_before + ext_after)
    return ast_tree
예제 #13
0
def check_value(ast_tree, ext_index, bock_item_index, var_name, func_name):
    Cast = c_ast.Cast(
        c_ast.Typename(
            None, [],
            c_ast.PtrDecl([],
                          c_ast.TypeDecl(None, [],
                                         c_ast.IdentifierType(['void'])))),
        c_ast.ID(var_name))

    func_call = c_ast.FuncCall(
        c_ast.ID('check_value'),
        c_ast.ExprList([
            c_ast.UnaryOp('&', c_ast.ID('global_log')), Cast,
            c_ast.Constant('string', '"' + var_name + '"'),
            c_ast.Constant('string', '"' + func_name + '"'),
            c_ast.Constant('int', str(len(var_name))),
            c_ast.Constant('int', str(len(func_name)))
        ]))

    new_node = c_ast.If(
        c_ast.BinaryOp('==', func_call, c_ast.Constant('int', '0')),
        c_ast.Compound([
            c_ast.FuncCall(
                c_ast.ID('printf'),
                c_ast.ExprList([
                    c_ast.Constant('string', '"%s\\n"'),
                    c_ast.Constant('string', '"Attack Detected"')
                ])),
            c_ast.FuncCall(c_ast.ID('exit'),
                           c_ast.ExprList([c_ast.Constant('int', '1')]))
        ]), None)
    return merge_ast_tree(ast_tree, ext_index, bock_item_index, new_node,
                          "insert_before")
예제 #14
0
 def visit_Switch(self, node):
     if type(node.stmt) is c_ast.Compound:
         declarations = []
         new_block_items = []
         for item in node.stmt.block_items:
             if type(item) is c_ast.Decl:
                 declarations.append(item)
             else:
                 new_block_items.append(item)
         if len(self.parents) > 0 and len(declarations) > 0:
             node.stmt.block_items = new_block_items
             new_switch_block = c_ast.Compound(declarations + [node])
             if hasattr(self.parents[-1], "block_items"):
                 index = self.parents[-1].block_items.index(node)
                 self.parents[-1].block_items.remove(node)
                 self.parents[-1].block_items.insert(
                     index, new_switch_block)
             elif hasattr(self.parents[-1],
                          "iftrue") and self.parents[-1].iftrue == node:
                 self.parents[-1].iftrue = new_switch_block
             elif hasattr(self.parents[-1],
                          "iffalse") and self.parents[-1].iffalse == node:
                 self.parents[-1].iffalse = new_switch_block
             else:
                 # TODO: The three cases above most likely don't cover all possible contexts in which a switch can
                 # occur. This works on both case studies, so sufficient as of now. But for future use, one might
                 # want to evaluate from the C standard which contexts are generaly possible!
                 sys.stderr.write(
                     "Can not identify the context of a switch statement that is contained in "
                     + str(type(self.parents[-1])))
예제 #15
0
def define_sizeof_modifier_type(t):
    # setup the toplevel call
    if t.get_typename():
        argument_ast = t.get_reference()("storage")
    else:
        argument_ast = t.define("storage")
    prefix = "fffc_get_sizeof_"
    desired_name = CGenerator().visit(argument_ast)
    suffix = encode_hash(desired_name)
    function_name = prefix + suffix

    # build the underlying function call
    underlying_call = get_sizeof_pointer_to_type(t.underlying_type,
                                                 c_ast.ID("storage"))

    # build this just as above, except with the call in place of the sizeof
    storage_tdecl = c_ast.Decl("storage", [], [], [],
                               c_ast.PtrDecl([], argument_ast), None, None)
    func_tdecl = c_ast.TypeDecl(
        function_name, [], c_ast.IdentifierType(["long", "long", "unsigned"]))
    funcdecl = c_ast.FuncDecl(c_ast.ParamList([storage_tdecl]), func_tdecl)
    funcdef = c_ast.FuncDef(
        c_ast.Decl(function_name, [], [], [], funcdecl, None, None),
        None,
        c_ast.Compound([c_ast.Return(underlying_call)]),
    )
    comment = "/* " + desired_name + "*/\n"
    kr_funcdecl = c_ast.FuncDecl(c_ast.ParamList([]), func_tdecl)
    return comment, kr_funcdecl, funcdef
예제 #16
0
def compile_node(lookup, decl_code, node):
    code = []
    stack = {}
    inargs = []
    pre = node.type + '_pre'
    post = node.type + '_post'

    compile_ast(lookup, stack, inargs, decl_code, code, pre)

    for word in node.quotation:
        compile_ast(lookup, stack, inargs, decl_code, code, word)
        compile_ast(lookup, stack, inargs, decl_code, code, node.type)
        call = code[-1]
        end_stack = deepcopy(stack)
        end_inargs = deepcopy(inargs)
        end_code = []
        compile_ast(lookup, end_stack, end_inargs, decl_code, end_code, post)
        outargs = [a for args in end_stack.values() for a in args]
        assign_results(outargs, end_code)
        end_code.append(c_ast.Return(None))
        end = c_ast.Compound(end_code)
        condition = c_ast.If(call, end, None)
        code[-1] = condition

    compile_ast(lookup, stack, inargs, decl_code, code, post)

    outargs = [a for args in stack.values() for a in args]
    name = gensym(node.type)
    fn = fndecl(name, inargs, outargs, code)
    decl_code.append(fn)
    lookup[name] = (inargs, outargs)
    return name
예제 #17
0
    def __for_loop(self, depth: int) -> c_ast.For:
        """
        A helper function to construct a for loop corresponding to allocating one dimension of an array.
        Recursively calls itself to generate next levels or generates an initialisation line if it is the last level.

        Example: for(i_2 = 0; i_2 < N; i_2++) { ... }

        :param depth:
        :return: C-ast.For
        """
        i = self.counter_prefix + str(depth)
        init = c_ast.DeclList([
            c_ast.Decl(c_ast.ID(i), [], [], [],
                       c_ast.TypeDecl(i, [], c_ast.IdentifierType(['int'])),
                       c_ast.Constant('int', '0'), '')
        ])
        cond = c_ast.BinaryOp('<', c_ast.ID(i), self.sizes[depth])
        nxt = c_ast.Assignment('++', c_ast.ID(i), None)
        stmt = c_ast.Compound([])

        if depth < len(self.sizes) - 1:
            stmt.block_items = [
                self.__malloc_assign(depth + 1),
                self.__for_loop(depth + 1)
            ]
        else:
            stmt.block_items = [self.initialiser(depth + 1)]

        return c_ast.For(init, cond, nxt, stmt)
예제 #18
0
    def createMain(self):
        #Main Function
        #Declaration
        z1 = c_ast.TypeDecl('args',[],c_ast.IdentifierType(['int']))
        args = c_ast.Decl('args',[],[],[],z1,None,None)
        z2= c_ast.PtrDecl([],c_ast.TypeDecl('argv',[],c_ast.IdentifierType(['char'])))
        z3=c_ast.ArrayDecl(z2,None,[])
        argv = c_ast.Decl('argv',[],[],[],z3,None,None)
        params=c_ast.ParamList([args,argv])
        mainDec=c_ast.FuncDecl(params,c_ast.TypeDecl('main',[],c_ast.IdentifierType(['int'])))
#        insertTest(functionName,varVals,varTypes)
        #Body
        ##Signal
        sigalrm=c_ast.ID(name="14")
        funcCast=c_ast.TypeDecl(declname = None,quals=[],type=c_ast.IdentifierType(['void']))
        paramCast=c_ast.ParamList([c_ast.Typename(name=None,quals=[],type=c_ast.TypeDecl(declname = None,quals=[],type=c_ast.IdentifierType(['int'])))])
        typeFunc=c_ast.PtrDecl(type=c_ast.FuncDecl(paramCast,funcCast),quals=[])        
        kchild=c_ast.Cast(to_type=c_ast.Typename(name=None, quals=[],type=typeFunc),expr=c_ast.ID(name="kill_child"))
        expressList = [sigalrm,kchild]
        signalStmt=c_ast.FuncCall(c_ast.ID(name="signal"),c_ast.ExprList(expressList))

        ##Return
        returnStmt=c_ast.Return(c_ast.Constant(type="int",value="0"))
        comp=c_ast.Compound([signalStmt,returnStmt])
        return c_ast.FuncDef(mainDec,None,comp)
예제 #19
0
def perm_refer_to_var(fn: ca.FuncDef, ast: ca.FileAST, indices: Indices,
                      region: Region, random: Random) -> bool:
    """Add `if (variable) {}` or `if (struct.member) {}` in a random place.
    This will get optimized away but may affect regalloc."""
    # Find expression to insert, searching within the randomization region.
    cands: List[Expression] = [
        expr for expr in get_block_expressions(fn.body, region)
        if isinstance(expr, (ca.StructRef, ca.ID))
    ]
    if not cands:
        return False
    expr = random.choice(cands)
    if ast_util.is_effectful(expr):
        return False
    type: SimpleType = decayed_expr_type(expr, build_typemap(ast))
    if isinstance(type, ca.TypeDecl) and isinstance(type.type,
                                                    (ca.Struct, ca.Union)):
        expr = ca.UnaryOp("&", expr)

    if random.choice([True, False]):
        expr = ca.UnaryOp("!", expr)

    # Insert it wherever -- possibly outside the randomization region, since regalloc
    # can act at a distance. (Except before a declaration.)
    ins_cands = get_insertion_points(fn, Region.unbounded())
    ins_cands = [c for c in ins_cands if not isinstance(c[2], ca.Decl)]
    if not ins_cands:
        return False

    cond = copy.deepcopy(expr)
    stmt = ca.If(cond=cond, iftrue=ca.Compound(block_items=[]), iffalse=None)
    tob, toi, _ = random.choice(ins_cands)
    ast_util.insert_statement(tob, toi, stmt)
    return True
예제 #20
0
def _DoPrintfSplitter(call: c_ast.FuncCall, parent, use_specialized_printf):
    args: List = call.args.exprs
    fmt_pieces = TokenizeFormatString(args[0].value[1:-1])
    assert len(fmt_pieces) >= 1
    if use_specialized_printf and len(fmt_pieces) == 1:
        s = fmt_pieces[0]
        if len(s) <= 1 or s[0] != "%":
            call.name.name = "write_s"
            args.insert(0, CONST_STDOUT)
            return
        else:
            call.name.name = GetSingleArgPrintForFormat(s)
            args[0] = CONST_STDOUT
            return

    stmts = common.GetStatementList(parent)
    if not stmts:
        stmts = [call]
        common.ReplaceNode(parent, call, c_ast.Compound(stmts))

    calls = []
    args = args[1:]  # skip the format string
    # note this has a small bug: we should evaluate all the
    # args and then print them instead of interleaaving
    # computation and printing.
    for f in fmt_pieces:
        arg = None
        if f[0] == '%' and len(f) > 1:
            arg = args.pop(0)
        c = MakePrintfCall(f, arg, use_specialized_printf)
        calls.append(c)
    pos = stmts.index(call)
    stmts[pos:pos + 1] = calls
예제 #21
0
파일: rpc.py 프로젝트: zhang12300/PYNQ
def _build_handle_function(functions):
    """ Wraps the switch statement in a function definition

    """
    case_statement = _build_case(functions)
    available_check = c_ast.If(
        c_ast.BinaryOp(
            '<', c_ast.FuncCall(
                c_ast.ID('mailbox_available'),
                c_ast.ExprList([c_ast.Constant('int', '2')])
            ),
            c_ast.Constant('int', '4')
        ),
        c_ast.Return(None),
        None
    )
    handle_decl = c_ast.FuncDecl(
        None, c_ast.TypeDecl('_handle_events', [],
                             c_ast.IdentifierType(['void'])),
    )
    command_decl = c_ast.Decl('command', [], [], [],
                              c_ast.TypeDecl('command', [],
                                             c_ast.IdentifierType(['int'])),
                              [], [])
    command_read = _generate_read('command')
    body = c_ast.Compound([available_check,
                           command_decl,
                           command_read,
                           case_statement])
    return c_ast.FuncDef(handle_decl, [], body)
예제 #22
0
def nested_for_loop(node, inner_loop_body, loop_iterator_base, rename_index=0):
    """
  Recursively create nested for loops for copying a multi-dimensional array.
  """
    if isinstance(node.type.type, c_ast.ArrayDecl):
        # Multi-dimensional array, recurse to generate inner loop
        for_loop_body = nested_for_loop(node.type, inner_loop_body,
                                        loop_iterator_base, rename_index + 1)
    else:
        # Single or last dimension of array
        for_loop_body = [inner_loop_body]

    # Declare iterator
    loop_iterator = c_ast.ID("%s_i%d" % (loop_iterator_base, rename_index))
    loop_iterator_decl = c_ast.Decl(
        loop_iterator.name, [], [], [],
        c_ast.TypeDecl(loop_iterator.name, [], c_ast.IdentifierType(["int"])),
        None, None)
    # For loop
    array_size = node.type.dim
    for_loop = c_ast.For(
        c_ast.Assignment('=', loop_iterator, c_ast.Constant("int", "0")),
        c_ast.BinaryOp('<', loop_iterator, array_size),
        c_ast.UnaryOp('p++', loop_iterator), c_ast.Compound(for_loop_body))
    return [loop_iterator_decl, for_loop]
예제 #23
0
def add_jump_guard(ast_to_guard, phase_var, round_var, label):

    guarded_ast = c_ast.If(
        c_ast.BinaryOp(
            '&&', c_ast.BinaryOp('==', c_ast.ID(phase_var), c_ast.ID('PHASE')),
            c_ast.BinaryOp('==', c_ast.ID(round_var), c_ast.ID(label))),
        ast_to_guard, None)

    return c_ast.Compound([guarded_ast])
 def visit_FuncDef(self, node):
   label = c_ast.Label("predict_exec_time", c_ast.EmptyStatement())
   decl = c_ast.Decl("exec_time", None, None, None,
       c_ast.TypeDecl("exec_time", None, c_ast.IdentifierType(["float"])), 
       None, None)
   assignment = c_ast.Assignment('=', c_ast.ID("exec_time"), c_ast.Constant("int", 0))
   ret = c_ast.Return(c_ast.ID("exec_time"))
   compound = c_ast.Compound([label, decl, assignment, ret])
   node.body.block_items.append(compound)
예제 #25
0
    def test_nested_else_if_line_breaks(self):
        generator = c_generator.CGenerator()
        test_ast1 = c_ast.If(None, None, None)
        test_ast2 = c_ast.If(None, None, c_ast.If(None, None, None))
        test_ast3 = c_ast.If(None, None,
                             c_ast.If(None, None, c_ast.If(None, None, None)))
        test_ast4 = c_ast.If(
            None, c_ast.Compound([]),
            c_ast.If(None, c_ast.Compound([]),
                     c_ast.If(None, c_ast.Compound([]), None)))

        self.assertEqual(generator.visit(test_ast1), 'if ()\n  \n')
        self.assertEqual(generator.visit(test_ast2),
                         'if ()\n  \nelse\n  if ()\n  \n')
        self.assertEqual(generator.visit(test_ast3),
                         'if ()\n  \nelse\n  if ()\n  \nelse\n  if ()\n  \n')
        self.assertEqual(
            generator.visit(test_ast4),
            'if ()\n{\n}\nelse\n  if ()\n{\n}\nelse\n  if ()\n{\n}\n')
예제 #26
0
 def createOutputIf(self, expr):
     expressList = [c_ast.Constant(type='int', value='0')]
     funcCall = c_ast.FuncCall(c_ast.ID(name="assert"),
                               c_ast.ExprList(expressList))
     if_all = c_ast.If(c_ast.BinaryOp(left=c_ast.ID(name='__out_var'),
                                      op='==',
                                      right=expr),
                       c_ast.Compound([funcCall]),
                       iffalse=None)
     return (if_all)
def addTestFunction(ast, expectedOutput, testFxn, initVars, initList):
    varList = []
    exprList = []
    fxnName = ''
    inFxn = False
    listi = 0
    for i in range(len(initVars)):
        v = initVars[i]
        if inFxn:
            exprList.append(c_ast.Constant('int', initList[listi]))
            listi += 1
            if (')' in v):
                inFxn = False
                newVar = c_ast.FuncCall(c_ast.ID(fxnName), c_ast.ExprList(exprList))
                varList.append(newVar)
                exprList = []
        else:
            if ('(' in v):
                fxnName = v[:v.index('(')]
                if (v[v.index('(')+1] != ')'):
                    inFxn = True
                    exprList.append(c_ast.Constant('int', initList[listi]))
                    listi += 1
                else:
                    newVar = c_ast.FuncCall(c_ast.ID(fxnName), c_ast.ExprList([]))
                    varList.append(newVar)
            else:
                newVar = c_ast.Assignment('=', c_ast.ID(v), c_ast.Constant('int', initList[listi]))
                listi += 1
                varList.append(newVar)
    fxnDecl = c_ast.FuncDecl(None, c_ast.TypeDecl('klee_test_entry', [], c_ast.IdentifierType(['void'])))
    fxnCall = c_ast.FuncCall(c_ast.ID(testFxn), c_ast.ExprList([]))
    binaryOp = c_ast.BinaryOp('==', fxnCall, c_ast.Constant('int', expectedOutput))
    ifFalse = c_ast.Compound([c_ast.FuncCall(c_ast.ID('klee_silent_exit'), c_ast.ExprList([c_ast.Constant('int', '0')]))])
    ifTrue = c_ast.Compound([])
    blockItems = []
    for v in varList:
        blockItems.append(v)
    blockItems.append(c_ast.If(binaryOp, ifTrue, ifFalse))
    fxnBody = c_ast.Compound(blockItems)
    fxnNode = c_ast.FuncDef(fxnDecl, None, fxnBody)
    ast.ext.append(fxnNode)
예제 #28
0
파일: rpc.py 프로젝트: yao-zl/PYNQ
    def __init__(self, decl, typedefs):
        self.return_interface = _type_to_interface(decl.type, typedefs)
        self.name = decl.type.declname
        self.docstring = _get_docstring(decl.coord)
        self.arg_interfaces = []
        self.args = []
        self.blocks = False
        self.coord = decl.coord
        block_contents = []
        post_block_contents = []
        func_args = []

        if decl.args:
            for i, arg in enumerate(decl.args.params):
                if type(arg) is c_ast.EllipsisParam:
                    raise RuntimeError("vararg functions not supported")
                interface = _type_to_interface(arg.type, typedefs)
                if type(interface) is VoidWrapper:
                    continue
                block_contents.extend(interface.pre_argument('arg' + str(i)))
                post_block_contents.extend(
                    interface.post_argument('arg' + str(i)))
                func_args.append(c_ast.ID('arg' + str(i)))
                self.arg_interfaces.append(interface)
                self.blocks = self.blocks | interface.blocks
                if arg.name:
                    self.args.append(arg.name)
                else:
                    self.args.append(f'arg{len(self.args)}')

        function_call = c_ast.FuncCall(c_ast.ID(self.name),
                                       c_ast.ExprList(func_args))

        self.returns = type(self.return_interface) is not VoidWrapper
        if self.returns:
            ret_assign = c_ast.Decl('ret', [], [], [],
                                    c_ast.TypeDecl('ret', [], decl.type.type),
                                    function_call, [])
            block_contents.append(ret_assign)
            block_contents.append(_generate_write('return_command'))
            block_contents.extend(post_block_contents)
            block_contents.append(_generate_write('ret'))
            self.blocks = True
        else:
            block_contents.append(function_call)
            if self.blocks:
                block_contents.append(_generate_write('return_command'))
            else:
                block_contents.append(_generate_write('void_command'))
            block_contents.extend(post_block_contents)

        self.call_ast = c_ast.Compound(block_contents)
        self.filename = decl.coord.file
예제 #29
0
 def work(self, new_stuffs):
     for parent, child in self.target_location:
         if isinstance(child, c_ast.Return):
             new_stuffs_copy = new_stuffs[:-1] + [
                 c_ast.FuncCall(
                     name=c_ast.ID(name="_RETTYPE"),
                     args=c_ast.ExprList(exprs=[
                         child.expr,
                         c_ast.Constant(type='int',
                                        value=str(len(new_stuffs) - 1))
                     ]))
             ] + new_stuffs[-1:]
         else:
             new_stuffs_copy = new_stuffs
         if isinstance(parent, c_ast.Compound):
             child_loc = parent.block_items.index(child)
             parent.block_items = parent.block_items[:
                                                     child_loc] + new_stuffs_copy + parent.block_items[
                                                         child_loc + 1:]
         elif isinstance(parent, c_ast.If):
             if parent.iftrue == child:
                 parent.iftrue = c_ast.Compound(block_items=new_stuffs_copy)
             elif parent.iffalse == child:
                 parent.iffalse = c_ast.Compound(
                     block_items=new_stuffs_copy)
         elif isinstance(parent, c_ast.While):
             parent.stmt = c_ast.Compound(block_items=new_stuffs_copy)
         elif isinstance(parent, c_ast.For):
             parent.stmt = c_ast.Compound(block_items=new_stuffs_copy)
         elif isinstance(parent, c_ast.DoWhile):
             parent.stmt = c_ast.Compound(block_items=new_stuffs_copy)
         elif isinstance(parent, c_ast.Label):
             parent.stmt = c_ast.Compound(block_items=new_stuffs_copy)
 def insert_in_If(self, node, stmt):
   # Insert at start of compound block
   if isinstance(node.iftrue, c_ast.Compound):
     if node.iftrue.block_items:
       node.iftrue.block_items.insert(0, stmt)
     else:
       node.iftrue.block_items = [stmt]
   # Replace empty statement
   elif isinstance(node.iftrue, c_ast.EmptyStatement):
     node.iftrue = stmt
   else:
     compound = c_ast.Compound([stmt, node.iftrue])
     node.iftrue = compound