예제 #1
0
    def visit_Return(self, node):
        align, _ = _DistanceGenerator(self._types).visit(node.expr)
        if align != '0':
            raise ReturnDistanceNotZero(node.coord, _code_generator.visit(node.expr), align)

        # insert assert(__SHADOWDP_v_epsilon <= epsilon);
        epsilon, *_ = self._parameters
        if self._set_epsilon and self._set_epsilon.isdigit():
            epsilon_node = c_ast.Constant(type='float', value=self._set_epsilon)
        elif self._set_epsilon and not self._set_epsilon.isdigit():
            epsilon_node = c_ast.ID(name=self._set_epsilon)
        else:
            epsilon_node = c_ast.ID(epsilon)

        if self._set_goal:
            assert_node = c_ast.FuncCall(
                c_ast.ID(self._func_map['assert']), args=c_ast.ExprList(
                    [c_ast.BinaryOp('<=', c_ast.ID(name='__SHADOWDP_v_epsilon'),
                                    c_ast.BinaryOp(op='*', left=epsilon_node, right=convert_to_ast(self._set_goal)))]))
        else:
            assert_node = c_ast.FuncCall(c_ast.ID(self._func_map['assert']),
                                         args=c_ast.ExprList([c_ast.BinaryOp('<=', c_ast.ID('__SHADOWDP_v_epsilon'),
                                                                             epsilon_node)]))
        self._parents[node].block_items.insert(self._parents[node].block_items.index(node), assert_node)
        self._inserted.add(assert_node)
        # because we have inserted a statement before Return statement while iterating, it will be a forever loop
        # add the current node to the set to not visit this same node again
        self._inserted.add(node)
예제 #2
0
    def __malloc(self, depth: int) -> c_ast.FuncCall:
        """
        A helper function to generate the call of malloc function with proper arguments.
        Note that a constant of 2 is added to the number of allocated cells. This is meant to compensate minor errors in
        size estimation.

        Example: malloc((N + 2) * sizeof(int*))

        :param depth: Which dimension of the array we want to allocate. Used to generate the argument of sizeof().
        :return: c_ast.FuncCall
        """
        size_expr = \
            c_ast.BinaryOp(
                '+',
                self.sizes[depth],
                c_ast.Constant('int', '2')
            )

        sizeof = \
            c_ast.FuncCall(
                c_ast.ID('sizeof'),
                c_ast.ExprList([c_ast.ID(self.dtype.name + '*' * (len(self.sizes) - depth - 1))])
            )

        arg = c_ast.BinaryOp('*', size_expr, sizeof)

        return c_ast.FuncCall(c_ast.ID('malloc'), c_ast.ExprList([arg]))
예제 #3
0
    def add_to_expression(self,
                          expression: c_ast.Node,
                          operator: str,
                          addition: c_ast.ExprList = None):
        """
		Adds the additional expression to the given expression, concatenated with the given operator. If the additional
		expression is None, the operator is assumed to be unary.
		:param expression: The expression to add to.
		:param operator: An operator on expression, e.g. "&&" or "!".
		:param addition: The expression to add.
		:return: The merged expression.
		:rtype: c_ast.ExprList
		"""
        expressions = []
        if type(expression) is c_ast.ExprList:
            for expr in expression.exprs:
                if addition is None:
                    expressions.append(
                        c_ast.UnaryOp(operator, copy.deepcopy(expr)))
                else:
                    expressions.append(
                        c_ast.BinaryOp(operator, copy.deepcopy(expr),
                                       addition))
        else:
            if addition is None:
                expressions.append(
                    c_ast.UnaryOp(operator, copy.deepcopy(expression)))
            else:
                expressions.append(
                    c_ast.BinaryOp(operator, copy.deepcopy(expression),
                                   addition))
        return c_ast.ExprList(expressions)
예제 #4
0
 def test_scalar_children(self):
     b1 = c_ast.BinaryOp(
         op='+', 
         left=c_ast.Constant(type='int', value='6'),
         right=c_ast.ID(name='joe'))
 
     cv = self.ConstantVisitor()
     cv.visit(b1)
     
     self.assertEqual(cv.values, ['6'])
     
     b2 = c_ast.BinaryOp(
         op='*',
         left=c_ast.Constant(type='int', value='111'),
         right=b1)
     
     b3 = c_ast.BinaryOp(
         op='^',
         left=b2,
         right=b1)
     
     cv = self.ConstantVisitor()
     cv.visit(b3)
     
     self.assertEqual(cv.values, ['111', '6', '6'])
예제 #5
0
def FixNodeRequiringBoolInt(ast: c_ast.Node, meta_info):
    candidates = common.FindMatchingNodesPostOrder(ast, ast,
                                                   IsNodeRequiringBoolInt)
    meta_info.type_links[CONST_ZERO] = meta.INT_IDENTIFIER_TYPE
    for node, parent in candidates:
        if isinstance(node, c_ast.If):
            if not IsExprOfTypeBoolInt(node.cond):
                node.cond = c_ast.BinaryOp("!=", node.cond, CONST_ZERO)
                meta_info.type_links[node.cond] = meta.INT_IDENTIFIER_TYPE
        elif isinstance(node, c_ast.For) and node.cond:
            if not IsExprOfTypeBoolInt(node.cond):
                node.cond = c_ast.BinaryOp("!=", node.cond, CONST_ZERO)
                meta_info.type_links[node.cond] = meta.INT_IDENTIFIER_TYPE
        elif isinstance(node, c_ast.UnaryOp) and node.op == "!":
            if not IsExprOfTypeBoolInt(node.expr):
                node = c_ast.BinaryOp(
                    "==", node.expr,
                    CONST_ZERO)  # note: we are replacing the "!" node
                meta_info.type_links[node] = meta.INT_IDENTIFIER_TYPE

        elif isinstance(
                node, c_ast.BinaryOp) and node.op in common.SHORT_CIRCUIT_OPS:
            if not IsExprOfTypeBoolInt(node.left):
                node.left = c_ast.BinaryOp("!=", node.left, CONST_ZERO)
                meta_info.type_links[node.left] = meta.INT_IDENTIFIER_TYPE
            if not IsExprOfTypeBoolInt(node.right):
                node.right = c_ast.BinaryOp("!=", node.right, CONST_ZERO)
                meta_info.type_links[node.right] = meta.INT_IDENTIFIER_TYPE
예제 #6
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);
     if self.functype=='int':
         printLeft=c_ast.Constant(type="char",value='"'+"%d" +'"')
     elif self.functype=='float' or self.functype=='double':
         printLeft=c_ast.Constant(type="char",value='"'+"%f" +'"')
     else:
         printLeft=c_ast.Constant(type="char",value='"'+"%d" +'"')
     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))
     expressList = [printLeft,funcCall]        
     funcCall = c_ast.FuncCall(c_ast.ID(name="printf"),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)
예제 #7
0
 def insertTest(self,block,functionName,varVals,varTypes,timer):
     #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
     if self.functype=='int' or self.functype=="bool":
         printLeft=c_ast.Constant(type="char",value='"'+"%d" +'"')
     elif self.functype=='float' or self.functype=='double':
         printLeft=c_ast.Constant(type="char",value='"'+"%f" +'"')
     else:
         printLeft=c_ast.Constant(type="char",value='"'+"%d" +'"')
     
     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))
     expressList = [printLeft,funcCall]        
     funcCall = c_ast.FuncCall(c_ast.ID(name="printf"),c_ast.ExprList(expressList))
     
     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([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)
예제 #8
0
    def _assign(self, variable: Union[c_ast.ID, c_ast.ArrayRef],
                expression: ExprType, node: c_ast.Node):
        """T-Asgn rule, which can be re-used both in Assignment node and Decl node"""
        # get new distance from the assignment expression (T-Asgn)
        variable_name = variable.name if isinstance(
            variable, c_ast.ID) else variable.name.name
        var_aligned, var_shadow, *_ = self._type_system.get_types(
            variable_name)
        aligned, shadow = DistanceGenerator(
            self._type_system).visit(expression)
        if self._loop_level == 0:
            # insert x^align = n^align if x^aligned is *
            if var_aligned == '*' or aligned != '0':
                self._insert_at(
                    node,
                    parse(
                        f'{constants.ALIGNED_DISTANCE}_{variable_name} = {aligned}'
                    ),
                    after=True)

            if self._enable_shadow:
                # generate x^shadow = x + x^shadow - e according to (T-Asgn)
                if self._pc:
                    if isinstance(variable, c_ast.ID):
                        shadow_distance = c_ast.ID(
                            name=f'{constants.SHADOW_DISTANCE}_{variable_name}'
                        )
                    elif isinstance(variable, c_ast.ArrayRef):
                        shadow_distance = c_ast.ArrayRef(
                            name=f'{constants.SHADOW_DISTANCE}_{variable_name}',
                            subscript=variable.subscript)
                    else:
                        raise NotImplementedError(
                            f'Assigned value type not supported {type(variable)}'
                        )
                    # insert x^shadow = x + x^shadow - e;
                    insert_node = c_ast.Assignment(
                        op='=',
                        lvalue=shadow_distance,
                        rvalue=c_ast.BinaryOp(op='-',
                                              left=c_ast.BinaryOp(
                                                  op='+',
                                                  left=variable,
                                                  right=shadow_distance),
                                              right=expression))
                    self._insert_at(node, insert_node, after=False)
                # insert x^shadow = n^shadow if n^shadow is not 0
                elif var_shadow == '*' or shadow != '0':
                    self._insert_at(
                        node,
                        parse(
                            f'{constants.SHADOW_DISTANCE}_{variable_name} = {shadow}'
                        ),
                        after=True)

        shadow_distance = '*' if self._pc or shadow != '0' or var_shadow == '*' else '0'
        aligned_distance = '*' if aligned != '0' or var_aligned == '*' else '0'
        self._type_system.update_distance(variable_name, aligned_distance,
                                          shadow_distance)
예제 #9
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])
예제 #10
0
    def tests_list_children(self):
        c1 = c_ast.Constant(type='float', value='5.6')
        c2 = c_ast.Constant(type='char', value='t')

        b1 = c_ast.BinaryOp(op='+', left=c1, right=c2)

        b2 = c_ast.BinaryOp(op='-', left=b1, right=c2)

        comp = c_ast.Compound(block_items=[b1, b2, c1, c2])

        cv = self.ConstantVisitor()
        cv.visit(comp)

        self.assertEqual(cv.values, ['5.6', 't', '5.6', 't', 't', '5.6', 't'])
예제 #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 _replace(self, node):
     if not isinstance(node, (c_ast.ArrayRef, c_ast.ID)):
         raise NotImplementedError('Expression type {} currently not supported.'.format(type(node)))
     varname = node.name.name if isinstance(node, c_ast.ArrayRef) else node.name
     alignd, shadow = self._types.get_distance(varname)
     distance = alignd if self._is_aligned else shadow
     if distance == '0':
         return node
     elif distance == '*':
         distance_varname = '__SHADOWDP_{}_DISTANCE_{}'.format('ALIGNED' if self._is_aligned else 'SHADOW', varname)
         distance_var = c_ast.ArrayRef(name=c_ast.ID(name=distance_varname), subscript=node.subscript) \
             if isinstance(node, c_ast.ArrayRef) else c_ast.ID(name=distance_varname)
         return c_ast.BinaryOp(op='+', left=node, right=distance_var)
     else:
         return c_ast.BinaryOp(op='+', left=node, right=convert_to_ast(distance))
예제 #13
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)
예제 #14
0
 def _replace(self, node):
     if not isinstance(node, (c_ast.ArrayRef, c_ast.ID)):
         raise NotImplementedError(f'Expression type {type(node)} currently not supported.')
     varname = node.name.name if isinstance(node, c_ast.ArrayRef) else node.name
     alignd, shadow, *_ = self._types.get_types(varname)
     distance = alignd if self._is_aligned else shadow
     if distance == '0':
         return node
     elif distance == '*':
         distance_varname = \
             f'{constants.ALIGNED_DISTANCE if self._is_aligned else constants.SHADOW_DISTANCE}_{varname}'
         distance_var = c_ast.ArrayRef(name=c_ast.ID(name=distance_varname), subscript=node.subscript) \
             if isinstance(node, c_ast.ArrayRef) else c_ast.ID(name=distance_varname)
         return c_ast.BinaryOp(op='+', left=node, right=distance_var)
     else:
         return c_ast.BinaryOp(op='+', left=node, right=parse(distance))
예제 #15
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")
예제 #16
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]
예제 #17
0
def astVeriNon():
    veryidt = c_ast.IdentifierType(['int'])
    verytype = c_ast.TypeDecl('rand', [], veryidt)
    bifunc = c_ast.FuncCall(c_ast.ID('__VERIFIER_nondet'), None)
    verybina = c_ast.BinaryOp('%', bifunc, c_ast.ID('N'))
    simdecl = c_ast.Decl('rand', [], [], [], verytype, verybina, None, None)
    return simdecl
예제 #18
0
def perm_add_mask(fn: ca.FuncDef, ast: ca.FileAST, indices: Indices,
                  region: Region, random: Random) -> bool:
    """Add a mask of 0xFF[FFFFFFFFFFFFFF] to a random expression of integer type.
    In some cases this mask is optimized out but affects regalloc."""
    typemap = build_typemap(ast)

    # Find expression to add the mask to
    cands: List[Expression] = get_block_expressions(fn.body, region)
    if not cands:
        return False

    expr = random.choice(cands)
    type: SimpleType = decayed_expr_type(expr, typemap)
    if not allowed_simple_type(
            type, typemap,
        ["int", "char", "long", "short", "signed", "unsigned"]):
        return False

    # Mask as if restricting the value to 8, 16, 32, or 64-bit width.
    # Sometimes use an unsigned mask like '0xFFu'
    masks: List[str] = ["0xFF", "0xFFFF", "0xFFFFFFFF", "0xFFFFFFFFFFFFFFFF"]
    mask = random.choice(masks) + random.choice(["", "u"])

    visit_replace(
        fn.body,
        lambda n, _: ca.BinaryOp("&", expr, ca.Constant("int", mask))
        if n is expr else None,
    )
    return True
예제 #19
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)
예제 #20
0
def unify_if_predicates(predicates):

    if len(predicates) == 1:
        return predicates[0]
    else:
        return c_ast.BinaryOp('&&', predicates[0],
                              unify_if_predicates(predicates[1:]))
예제 #21
0
def ConvertArrayIndexToPointerDereference(ast, meta_info):
    """
    Eliminates multi-dimensional arrays

    Phase 1:  a[1][2] = b; -> *(a + 1 * 10 + 2) = b;

    Phase 2: fun (int a[5][10]) -> fun (int a[][10])

    Phase 3:  int a[5][10]; -> int a[50];
    """

    def IsArrayRefChainHead(node, parent):
        if not isinstance(node, c_ast.ArrayRef): return False
        name_type = meta_info.type_links[node.name]
        #  int **b = a;
        #  printf("%d\n", b[1][1]);
        if not isinstance(name_type, c_ast.ArrayDecl): return True
        if not isinstance(parent, c_ast.ArrayRef): return True
        return False

    ref_chains = common.FindMatchingNodesPostOrder(ast, ast, IsArrayRefChainHead)
    for chain_head, parent in ref_chains:
        name, s = MakeCombinedSubscript(chain_head, meta_info)
        if s is None:
            addr = name
        else:
            addr = c_ast.BinaryOp("+", name, s)
        head_type = meta_info.type_links[chain_head]
        # TODO:  low confidence - double check this
        meta_info.type_links[addr] = meta_info.type_links[name]
        if isinstance(head_type, c_ast.ArrayDecl):
            # the array ref sequence only partially indexes the array, so the result is just an address
            common.ReplaceNode(parent, chain_head, addr)
        else:
            deref = c_ast.UnaryOp("*", addr)
            meta_info.type_links[deref] = meta_info.type_links[chain_head]  # expression has not changed
            common.ReplaceNode(parent, chain_head, deref)

    # Phase 2
    def IsArrayDeclParam(node, parent):
        if not isinstance(parent, c_ast.ParamList): return False
        if isinstance(node, c_ast.EllipsisParam): return False
        return isinstance(node.type, c_ast.ArrayDecl)

    decl_params = common.FindMatchingNodesPreOrder(
        ast, ast, IsArrayDeclParam)
    for param, _ in decl_params:
        t = param.type
        t.dim = None

    # Phase 3
    def IsArrayDeclChainHead(node, parent):
        if not isinstance(node, c_ast.ArrayDecl): return False
        return not isinstance(parent, c_ast.ArrayDecl)

    decl_chains = common.FindMatchingNodesPreOrder(
        ast, ast, IsArrayDeclChainHead)
    for chain_head, parent in decl_chains:
        CollapseArrayDeclChain(chain_head)
예제 #22
0
def exprs_prod(exprs: List[c_ast.Node]) -> c_ast.Node:
    """
    Product of a list of c_ast expressions
    :param exprs: Expressions
    :return: c_ast.Node representing the product
    """
    # noinspection PyTypeChecker
    return reduce(lambda a, b: c_ast.BinaryOp('*', a, b), exprs)
예제 #23
0
파일: types.py 프로젝트: neophack/epanos
def do_op(**kw):
    #{rd} = {rs} {subst} {rt}
    # XXX this is a mess
    lvalue = c_ast.BinaryOp(kw['subst'], kw['rs'], kw['rt'])
    try:
        cast_with = slot_to_typename[kw['result']]
    except KeyError:
        return do_assign(rt=kw['rd'], op=lvalue)
    else:
        return do_assign(rt=kw['rd'], op=simple_cast(cast_with, lvalue))
예제 #24
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)
예제 #25
0
    def test_repr(self):
        c1 = c_ast.Constant(type='float', value='5.6')
        c2 = c_ast.Constant(type='char', value='t')

        b1 = c_ast.BinaryOp(op='+', left=c1, right=c2)

        b2 = c_ast.BinaryOp(op='-', left=b1, right=c2)

        comp = c_ast.Compound(block_items=[b1, b2, c1, c2])

        expected = (
            "Compound(block_items=[BinaryOp(op='+',\n"
            "                               left=Constant(type='float',\n"
            "                                             value='5.6'\n"
            "                                             ),\n"
            "                               right=Constant(type='char',\n"
            "                                              value='t'\n"
            "                                              )\n"
            "                               ),\n"
            "                      BinaryOp(op='-',\n"
            "                               left=BinaryOp(op='+',\n"
            "                                             left=Constant(type='float',\n"
            "                                                           value='5.6'\n"
            "                                                           ),\n"
            "                                             right=Constant(type='char',\n"
            "                                                            value='t'\n"
            "                                                            )\n"
            "                                             ),\n"
            "                               right=Constant(type='char',\n"
            "                                              value='t'\n"
            "                                              )\n"
            "                               ),\n"
            "                      Constant(type='float',\n"
            "                               value='5.6'\n"
            "                               ),\n"
            "                      Constant(type='char',\n"
            "                               value='t'\n"
            "                               )\n"
            "                     ]\n"
            "         )")

        self.assertEqual(repr(comp), expected)
  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)
예제 #27
0
    def __polybench_init(self, depth: int) -> c_ast.Node:
        """
        Generates a polybench-style array element initialisation.
        :param depth:

        Example: A[i_0][i_1] = (double) (i_0 * i_1 + 1) / N;
        """
        subs = self.__subs(depth)
        left = self.__array_ref(subs)

        right = \
            c_ast.Cast(
                self.dtype,
                c_ast.BinaryOp('/',
                               c_ast.BinaryOp('+', exprs_prod(subs), c_ast.Constant('int', '1')),
                               self.sizes[0]
                               )
            )

        return c_ast.Assignment('=', left, right)
예제 #28
0
    def test_BinaryOp(self):
        b1 = c_ast.BinaryOp(op='+',
                            left=c_ast.Constant(type='int', value='6'),
                            right=c_ast.ID(name='joe'))

        self.failUnless(isinstance(b1.left, c_ast.Constant))
        self.assertEqual(b1.left.type, 'int')
        self.assertEqual(b1.left.value, '6')

        self.failUnless(isinstance(b1.right, c_ast.ID))
        self.assertEqual(b1.right.name, 'joe')
예제 #29
0
    def __init__(self, layout, start, end, stride, leading_dim):
        self.end = end
        self.stride = stride

        if layout == "fortran" and start is None:
            start = c_ast.Constant("int", 1)

        self.start = start

        if leading_dim is None and end is not None:
            if start is None:
                leading_dim = end
            else:
                if layout == "fortran":
                    leading_dim = c_ast.BinaryOp(
                        "+", c_ast.BinaryOp("-", end, start),
                        c_ast.Constant("int", 1))
                else:
                    leading_dim = c_ast.BinaryOp("-", end, start)

        self.leading_dim = leading_dim
예제 #30
0
def swap_compare_operands(cond):
    reversed_operator = {
        '>': '<',
        '<': '>',
        '>=': '<=',
        '<=': '>=',
        '==': '==',
        '!=': '!=',
    }
    new_op = reversed_operator[cond.op]
    # Normal order is (left, right), but we're swapping.
    return c_ast.BinaryOp(new_op, cond.right, cond.left, cond.coord)